Module: Hecks::Bluebook::Expression::CanonicalForm
- Defined in:
- lib/hecks/bluebook/expression/canonical_form.rb
Defined Under Namespace
Classes: Rule
Constant Summary collapse
- STRATEGIES =
Hecks::Vocabulary.fetch("NormalisationStrategy")
- RULES =
READ, NOT RESTATED — the admitted normalisation rules, projected from the grammar chapter by bin/expression_projection exactly as the evaluator's operator table is. See Evaluator::PROJECTION for why a projection rather than a boot.
JSON.parse( File.read(File.join(__dir__, "projection.json")), symbolize_names: true ).fetch(:normalisations).map { |row| Rule.new(**row) }.freeze
Class Method Summary collapse
Class Method Details
.apply(source) ⇒ Object
34 35 36 |
# File 'lib/hecks/bluebook/expression/canonical_form.rb', line 34 def apply(source) RULES.sort_by(&:position).reduce(source.to_s) { |text, rule| step(text, rule) }.strip end |
.replace(text, rule) ⇒ Object
47 48 49 50 51 |
# File 'lib/hecks/bluebook/expression/canonical_form.rb', line 47 def replace(text, rule) return text.gsub(rule.source_token, rule.replacement) if rule.boundary == "none" text.gsub(/#{Regexp.escape(rule.source_token)}(?![[:alnum:]_])/, rule.replacement) end |
.step(text, rule) ⇒ Object
38 39 40 41 42 43 44 45 |
# File 'lib/hecks/bluebook/expression/canonical_form.rb', line 38 def step(text, rule) case rule.strategy when "collapse_whitespace" then text.gsub(/\s+/, " ") when "replace" then replace(text, rule) else raise ArgumentError, "#{rule.strategy.inspect} is not a linked normalisation strategy" end end |
.table ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/hecks/bluebook/expression/canonical_form.rb', line 22 def table RULES.sort_by(&:position).map do |rule| { strategy: rule.strategy, source_token: rule.source_token, replacement: rule.replacement, boundary: rule.boundary, position: rule.position.to_s } end end |