Class: Metanorma::Mirror::Rewriter
- Inherits:
-
Object
- Object
- Metanorma::Mirror::Rewriter
- Defined in:
- lib/metanorma/mirror/rewriter.rb
Overview
Rewrites a mirror Model graph with configurable type-skipping and per-type customization. Despite living in the reverse-conversion namespace, this class produces a Model graph (not Metanorma XML) — the output is a fully model-driven representation that can be serialized via Model#to_h or rendered via Output::HtmlRenderer.
Instance API:
Rewriter.new(skip: Set.new(%w[review footnotes]))
rewriter.skip("my_type")
rewriter.register("my_type") { |n, r| ... }
Class API (seeds defaults copied into each new instance):
Rewriter.skip("review") # adds to defaults
Rewriter.register("my_type") { |n, r| ... }
Two Rewriter instances do not share state. Class-level mutation only
affects instances created afterwards (the default snapshot is copied
at new time).
Constant Summary collapse
- DEFAULT_SKIPPED_TYPES =
%w[review footnotes].freeze
Instance Attribute Summary collapse
-
#builders ⇒ Object
readonly
Returns the value of attribute builders.
-
#skipped_types ⇒ Object
readonly
Returns the value of attribute skipped_types.
Class Method Summary collapse
-
.default_builders ⇒ Object
Default builder map, copied into each new instance.
-
.default_skipped_types ⇒ Object
Default skip set, copied into each new instance.
-
.register(type, &block) ⇒ Object
Register a builder for a type at the default level.
-
.skip(type) ⇒ Object
Add a type to the default skip set.
Instance Method Summary collapse
- #build(node) ⇒ Object
- #build_children(content) ⇒ Object
- #call(mirror_node) ⇒ Object
-
#initialize(skip: nil, builders: nil) ⇒ Rewriter
constructor
A new instance of Rewriter.
- #register(type, &block) ⇒ Object
- #rewrite_container(node) ⇒ Object
- #rewrite_leaf(node) ⇒ Object
- #rewrite_soft_break(_node) ⇒ Object
- #rewrite_string(string) ⇒ Object
- #rewrite_text(node) ⇒ Object
- #skip(type) ⇒ Object
- #skipped?(type) ⇒ Boolean
Constructor Details
#initialize(skip: nil, builders: nil) ⇒ Rewriter
Returns a new instance of Rewriter.
52 53 54 55 |
# File 'lib/metanorma/mirror/rewriter.rb', line 52 def initialize(skip: nil, builders: nil) @skipped_types = skip || self.class.default_skipped_types.dup @builders = builders || self.class.default_builders.dup end |
Instance Attribute Details
#builders ⇒ Object (readonly)
Returns the value of attribute builders.
57 58 59 |
# File 'lib/metanorma/mirror/rewriter.rb', line 57 def builders @builders end |
#skipped_types ⇒ Object (readonly)
Returns the value of attribute skipped_types.
57 58 59 |
# File 'lib/metanorma/mirror/rewriter.rb', line 57 def skipped_types @skipped_types end |
Class Method Details
.default_builders ⇒ Object
Default builder map, copied into each new instance.
33 34 35 |
# File 'lib/metanorma/mirror/rewriter.rb', line 33 def default_builders @default_builders ||= {} end |
.default_skipped_types ⇒ Object
Default skip set, copied into each new instance.
28 29 30 |
# File 'lib/metanorma/mirror/rewriter.rb', line 28 def default_skipped_types @default_skipped_types ||= Set.new(DEFAULT_SKIPPED_TYPES) end |
.register(type, &block) ⇒ Object
Register a builder for a type at the default level. Affects instances created afterwards; existing instances are unchanged.
46 47 48 49 |
# File 'lib/metanorma/mirror/rewriter.rb', line 46 def register(type, &block) default_builders[type] = block self end |
.skip(type) ⇒ Object
Add a type to the default skip set. Affects instances created afterwards; existing instances are unchanged.
39 40 41 42 |
# File 'lib/metanorma/mirror/rewriter.rb', line 39 def skip(type) default_skipped_types << type self end |
Instance Method Details
#build(node) ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/metanorma/mirror/rewriter.rb', line 77 def build(node) return nil unless node return rewrite_string(node) if node.is_a?(String) node.accept_rewriter(self) end |
#build_children(content) ⇒ Object
116 117 118 |
# File 'lib/metanorma/mirror/rewriter.rb', line 116 def build_children(content) Array(content).filter_map { |child| build(child) } end |
#call(mirror_node) ⇒ Object
73 74 75 |
# File 'lib/metanorma/mirror/rewriter.rb', line 73 def call(mirror_node) build(mirror_node) end |
#register(type, &block) ⇒ Object
68 69 70 71 |
# File 'lib/metanorma/mirror/rewriter.rb', line 68 def register(type, &block) builders[type] = block self end |
#rewrite_container(node) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/metanorma/mirror/rewriter.rb', line 85 def rewrite_container(node) return nil if skipped?(node.type) builder = builders[node.type] return builder.call(node, self) if builder Model::Container.new( type: node.type, attrs: node.attrs, content: build_children(node.content), ) end |
#rewrite_leaf(node) ⇒ Object
98 99 100 101 102 |
# File 'lib/metanorma/mirror/rewriter.rb', line 98 def rewrite_leaf(node) return nil if skipped?(node.type) Model::Leaf.new(type: node.type, attrs: node.attrs) end |
#rewrite_soft_break(_node) ⇒ Object
108 109 110 |
# File 'lib/metanorma/mirror/rewriter.rb', line 108 def rewrite_soft_break(_node) Model::SoftBreak.new end |
#rewrite_string(string) ⇒ Object
112 113 114 |
# File 'lib/metanorma/mirror/rewriter.rb', line 112 def rewrite_string(string) Model::Text.new(text: string) end |
#rewrite_text(node) ⇒ Object
104 105 106 |
# File 'lib/metanorma/mirror/rewriter.rb', line 104 def rewrite_text(node) Model::Text.new(text: node.text, marks: node.marks) end |
#skip(type) ⇒ Object
59 60 61 62 |
# File 'lib/metanorma/mirror/rewriter.rb', line 59 def skip(type) skipped_types << type self end |
#skipped?(type) ⇒ Boolean
64 65 66 |
# File 'lib/metanorma/mirror/rewriter.rb', line 64 def skipped?(type) skipped_types.include?(type) end |