Class: Coradoc::Mirror::CoreModelToMirror
- Inherits:
-
Object
- Object
- Coradoc::Mirror::CoreModelToMirror
- Defined in:
- lib/coradoc/mirror/core_model_to_mirror.rb
Overview
Transforms CoreModel documents into ProseMirror-compatible Mirror nodes.
Uses a HandlerRegistry for OCP-compliant dispatch: each CoreModel type maps to a handler module/class that produces the corresponding Mirror node.
Defined Under Namespace
Classes: FootnoteData
Constant Summary collapse
- COLLECTION_ACCESSORS =
Maps element types to their children accessors.
{ CoreModel::ListBlock => :items, CoreModel::DefinitionList => :items, CoreModel::Table => :rows, CoreModel::Bibliography => :entries }.freeze
Instance Attribute Summary collapse
-
#partition_structural ⇒ Object
Read by Handlers::Structural.section to decide whether to emit generic ‘section` (legacy) or a JS SECTION_TYPE (`clause`, `annex`, etc.) when partition_structural mode is on.
-
#registry ⇒ Object
readonly
Returns the value of attribute registry.
Instance Method Summary collapse
- #call(document, partition_structural: false) ⇒ Object
- #extract_content(element) ⇒ Object
- #flush_footnotes ⇒ Object
-
#initialize(registry: Coradoc::Mirror.default_registry) ⇒ CoreModelToMirror
constructor
A new instance of CoreModelToMirror.
- #process_inline_content(element) ⇒ Object
- #register_footnote(footnote) ⇒ Object
- #resolve_footnote_reference(ref) ⇒ Object
- #text_node(text, marks: []) ⇒ Object
-
#wrap_structural(children) ⇒ Object
Partitions flat doc children into [preface?, sections?, *bibliography, *trailing] per the @metanorma/mirror JS structural contract.
Constructor Details
#initialize(registry: Coradoc::Mirror.default_registry) ⇒ CoreModelToMirror
Returns a new instance of CoreModelToMirror.
23 24 25 26 27 28 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 23 def initialize(registry: Coradoc::Mirror.default_registry) @registry = registry @footnote_counter = 0 @footnotes = [] @partition_structural = false end |
Instance Attribute Details
#partition_structural ⇒ Object
Read by Handlers::Structural.section to decide whether to emit generic ‘section` (legacy) or a JS SECTION_TYPE (`clause`, `annex`, etc.) when partition_structural mode is on.
33 34 35 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 33 def partition_structural @partition_structural end |
#registry ⇒ Object (readonly)
Returns the value of attribute registry.
10 11 12 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 10 def registry @registry end |
Instance Method Details
#call(document, partition_structural: false) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 35 def call(document, partition_structural: false) @footnote_counter = 0 @footnotes = [] @partition_structural = partition_structural content = extract_content(document) fn_block = flush_footnotes content << fn_block if fn_block attrs = build_document_attrs(document) Node::Document.new( attrs: Node::Document::Attrs.new(title: attrs[:title], id: attrs[:id]), content: partition_structural ? wrap_structural(content) : content ) end |
#extract_content(element) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 64 def extract_content(element) children = element_children(element) if children && !children.empty? content = [] children.each { |child| handle_element(child, content) } content.compact elsif element_has_text_content?(element) process_inline_content(element) else [] end end |
#flush_footnotes ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 121 def flush_footnotes return nil if @footnotes.empty? entries = @footnotes.map do |fn| Node::FootnoteEntry.new( attrs: Node::FootnoteEntry::Attrs.new( id: fn.id, ref_id: fn.ref_id, number: fn.number ), content: fn.content ) end @footnotes = [] Node::Footnotes.new(content: entries) end |
#process_inline_content(element) ⇒ Object
78 79 80 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 78 def process_inline_content(element) Handlers::Inline.process(element, context: self) end |
#register_footnote(footnote) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 86 def register_footnote(footnote) @footnote_counter += 1 num = @footnote_counter fn_id = footnote.id || "fn-#{num}" ref_id = "fn-ref-#{num}" fn_content = footnote.content ? [text_node(footnote.content)] : [] @footnotes << FootnoteData.new( id: fn_id, ref_id: ref_id, number: num, content: fn_content ) Node::FootnoteMarker.new( attrs: Node::FootnoteMarker::Attrs.new( id: fn_id, ref_id: ref_id, number: num ) ) end |
#resolve_footnote_reference(ref) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 104 def resolve_footnote_reference(ref) target_id = ref.id entry = @footnotes.find { |fn| fn.id == target_id } if target_id if entry Node::FootnoteMarker.new( attrs: Node::FootnoteMarker::Attrs.new( id: entry.id, ref_id: "fn-ref-#{entry.number}-dup-#{@footnote_counter}", number: entry.number ) ) else text_node("[#{target_id || 'footnote'}]") end end |
#text_node(text, marks: []) ⇒ Object
82 83 84 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 82 def text_node(text, marks: []) Node::Text.new(text: text, marks: marks) end |
#wrap_structural(children) ⇒ Object
Partitions flat doc children into [preface?, sections?, *bibliography, *trailing] per the @metanorma/mirror JS structural contract. See Partitioner for the bucketing rules.
54 55 56 57 58 59 60 61 62 |
# File 'lib/coradoc/mirror/core_model_to_mirror.rb', line 54 def wrap_structural(children) partitioned = Partitioner.partition(children) wrapped = [] wrapped << Node::Preamble.new(content: partitioned[:preface]) if partitioned[:preface].any? wrapped << Node::Sections.new(content: partitioned[:sections]) if partitioned[:sections].any? wrapped.concat(partitioned[:bibliography]) wrapped.concat(partitioned[:trailing]) wrapped end |