coradoc-mirror 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coradoc/mirror/handler_registry.rb +19 -30
  3. data/lib/coradoc/mirror/handlers/code_block.rb +17 -24
  4. data/lib/coradoc/mirror/handlers/include.rb +48 -0
  5. data/lib/coradoc/mirror/handlers/inline.rb +14 -0
  6. data/lib/coradoc/mirror/handlers.rb +1 -0
  7. data/lib/coradoc/mirror/node.rb +73 -0
  8. data/lib/coradoc/mirror/reverse_builder/admonition.rb +20 -0
  9. data/lib/coradoc/mirror/reverse_builder/base.rb +42 -0
  10. data/lib/coradoc/mirror/reverse_builder/biblio_entry.rb +22 -0
  11. data/lib/coradoc/mirror/reverse_builder/bibliography.rb +18 -0
  12. data/lib/coradoc/mirror/reverse_builder/blockquote.rb +20 -0
  13. data/lib/coradoc/mirror/reverse_builder/bullet_list.rb +18 -0
  14. data/lib/coradoc/mirror/reverse_builder/caption.rb +19 -0
  15. data/lib/coradoc/mirror/reverse_builder/code_block.rb +22 -0
  16. data/lib/coradoc/mirror/reverse_builder/definition_list.rb +35 -0
  17. data/lib/coradoc/mirror/reverse_builder/document.rb +22 -0
  18. data/lib/coradoc/mirror/reverse_builder/example.rb +20 -0
  19. data/lib/coradoc/mirror/reverse_builder/figure.rb +35 -0
  20. data/lib/coradoc/mirror/reverse_builder/footnote_entry.rb +18 -0
  21. data/lib/coradoc/mirror/reverse_builder/footnote_marker.rb +24 -0
  22. data/lib/coradoc/mirror/reverse_builder/footnotes.rb +20 -0
  23. data/lib/coradoc/mirror/reverse_builder/frontmatter.rb +21 -0
  24. data/lib/coradoc/mirror/reverse_builder/generic_block.rb +26 -0
  25. data/lib/coradoc/mirror/reverse_builder/header.rb +22 -0
  26. data/lib/coradoc/mirror/reverse_builder/horizontal_rule.rb +17 -0
  27. data/lib/coradoc/mirror/reverse_builder/image.rb +25 -0
  28. data/lib/coradoc/mirror/reverse_builder/include.rb +46 -0
  29. data/lib/coradoc/mirror/reverse_builder/inline_text.rb +19 -0
  30. data/lib/coradoc/mirror/reverse_builder/list_item.rb +37 -0
  31. data/lib/coradoc/mirror/reverse_builder/literal_block.rb +22 -0
  32. data/lib/coradoc/mirror/reverse_builder/open_block.rb +17 -0
  33. data/lib/coradoc/mirror/reverse_builder/ordered_list.rb +18 -0
  34. data/lib/coradoc/mirror/reverse_builder/paragraph.rb +17 -0
  35. data/lib/coradoc/mirror/reverse_builder/pass_block.rb +22 -0
  36. data/lib/coradoc/mirror/reverse_builder/preamble.rb +17 -0
  37. data/lib/coradoc/mirror/reverse_builder/raw_inline.rb +17 -0
  38. data/lib/coradoc/mirror/reverse_builder/section.rb +28 -0
  39. data/lib/coradoc/mirror/reverse_builder/sections.rb +19 -0
  40. data/lib/coradoc/mirror/reverse_builder/sidebar.rb +20 -0
  41. data/lib/coradoc/mirror/reverse_builder/soft_break.rb +17 -0
  42. data/lib/coradoc/mirror/reverse_builder/stem_block.rb +22 -0
  43. data/lib/coradoc/mirror/reverse_builder/table.rb +27 -0
  44. data/lib/coradoc/mirror/reverse_builder/table_body.rb +17 -0
  45. data/lib/coradoc/mirror/reverse_builder/table_cell.rb +24 -0
  46. data/lib/coradoc/mirror/reverse_builder/table_head.rb +17 -0
  47. data/lib/coradoc/mirror/reverse_builder/table_row.rb +18 -0
  48. data/lib/coradoc/mirror/reverse_builder/text.rb +24 -0
  49. data/lib/coradoc/mirror/reverse_builder/toc.rb +17 -0
  50. data/lib/coradoc/mirror/reverse_builder/toc_entry.rb +18 -0
  51. data/lib/coradoc/mirror/reverse_builder/verse.rb +20 -0
  52. data/lib/coradoc/mirror/reverse_builder.rb +59 -537
  53. data/lib/coradoc/mirror/version.rb +1 -1
  54. data/lib/coradoc/mirror.rb +5 -0
  55. data/lib/coradoc-mirror.rb +0 -2
  56. metadata +46 -2
  57. data/lib/coradoc/mirror/output.rb +0 -62
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Coradoc
6
+ module Mirror
7
+ module ReverseBuilder
8
+ class TocEntry < Base
9
+ registers 'toc_entry'
10
+
11
+ def build(node)
12
+ attrs = node.attrs
13
+ CoreModel::TocEntry.new(id: attrs&.id, title: attrs&.title)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Coradoc
6
+ module Mirror
7
+ module ReverseBuilder
8
+ class Verse < Base
9
+ registers 'verse'
10
+
11
+ def build(node)
12
+ CoreModel::VerseBlock.new(
13
+ content: extract_text(node),
14
+ attribution: node.attrs&.attribution
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -6,25 +6,26 @@ module Coradoc
6
6
  #
7
7
  # Adding support for a new Mirror node type is purely additive:
8
8
  #
9
- # module ReverseBuilder
9
+ # # reverse_builder/<name>.rb
10
+ # require_relative 'base'
11
+ # module Coradoc::Mirror::ReverseBuilder
10
12
  # class Figure < Base
11
13
  # registers 'figure'
12
- #
13
- # def build(node)
14
- # CoreModel::Image.new(src: node.src, ...)
15
- # end
14
+ # def build(node) = CoreModel::Image.new(...)
16
15
  # end
17
16
  # end
18
17
  #
19
- # No edits to MirrorToCoreModel or any other existing class. The
20
- # registry is the single source of truth for "which type string maps
21
- # to which builder" (MECE).
18
+ # Then add a single `require_relative` for the new file below. No edits
19
+ # to MirrorToCoreModel or any other existing class the registry is
20
+ # the single source of truth for "which type string maps to which
21
+ # builder" (MECE).
22
22
  #
23
23
  # This file is the autoload target for the ReverseBuilder constant
24
- # (see coradoc/mirror.rb). All built-in Builder subclasses live here
25
- # so their `registers` calls run at load time and the REGISTRY is
26
- # full before any caller references it. Mirror-level mark dispatch
27
- # lives in MarkReverseBuilder (mark_reverse_builder.rb).
24
+ # (see coradoc/mirror.rb). Each Builder subclass lives in its own
25
+ # file under reverse_builder/; eager-requiring them here populates
26
+ # the REGISTRY at load time so every caller sees a full registry.
27
+ # Mirror-level mark dispatch lives in MarkReverseBuilder
28
+ # (mark_reverse_builder.rb).
28
29
  module ReverseBuilder
29
30
  # Not frozen: subclasses call `register` from their class body at
30
31
  # load time, and `registers` may fire late via autoload. Freezing
@@ -45,531 +46,52 @@ module Coradoc
45
46
  REGISTRY.keys
46
47
  end
47
48
 
48
- # Base class for all reverse builders. Subclasses register one or
49
- # more Mirror type strings via `registers` and implement `#build`.
50
- # Shared helpers (build_content, extract_text, apply_mark, ...) are
51
- # delegated to the context (a MirrorToCoreModel instance), keeping
52
- # each builder focused on the per-type mapping only (DRY).
53
- class Base
54
- attr_reader :context
55
-
56
- def initialize(context)
57
- @context = context
58
- end
59
-
60
- def build(_node)
61
- raise NotImplementedError,
62
- "#{self.class} must implement #build(node)"
63
- end
64
-
65
- # Shared helpers — all delegate to the context (DRY).
66
- def build_content(node) = context.build_content(node)
67
- def build_inline_children(node) = context.build_inline_children(node)
68
- def build_node(node) = context.build_node(node)
69
- def extract_text(node) = context.extract_text(node)
70
- def apply_mark(inner, mark) = context.apply_mark(inner, mark)
71
- def inline_content(element) = context.inline_content(element)
72
-
73
- class << self
74
- # DSL: declare which Mirror type strings this builder handles.
75
- # Multiple strings per builder are allowed (e.g. all JS
76
- # SECTION_TYPES route to the same SectionElement builder).
77
- def registers(*types)
78
- types.each { |t| ReverseBuilder.register(t, self) }
79
- end
80
- end
81
- end
82
-
83
- # ── Structural ──
84
-
85
- class Document < Base
86
- registers 'doc'
87
-
88
- def build(node)
89
- attrs = node.attrs
90
- CoreModel::DocumentElement.new(
91
- title: attrs&.title,
92
- id: attrs&.id,
93
- children: build_content(node)
94
- )
95
- end
96
- end
97
-
98
- # All JS SECTION_TYPES reverse to a generic SectionElement. Style
99
- # information lives in the original AsciiDoc and is preserved only
100
- # on the forward side; the reverse side collapses them.
101
- class Section < Base
102
- registers 'section', 'clause', 'annex', 'content_section',
103
- 'abstract', 'foreword', 'introduction',
104
- 'acknowledgements', 'terms', 'definitions', 'references'
105
-
106
- def build(node)
107
- attrs = node.attrs
108
- CoreModel::SectionElement.new(
109
- title: attrs&.title,
110
- level: attrs&.level,
111
- id: attrs&.id,
112
- children: build_content(node)
113
- )
114
- end
115
- end
116
-
117
- class Header < Base
118
- registers 'floating_title', 'heading'
119
-
120
- def build(node)
121
- attrs = node.attrs
122
- CoreModel::HeaderElement.new(
123
- title: attrs&.title,
124
- level: attrs&.level,
125
- children: build_content(node)
126
- )
127
- end
128
- end
129
-
130
- class Preamble < Base
131
- registers 'preface'
132
-
133
- def build(node)
134
- CoreModel::PreambleElement.new(children: build_content(node))
135
- end
136
- end
137
-
138
- # `sections` is a structural container only — unwrap directly into
139
- # an array. MirrorToCoreModel#build_content flattens arrays.
140
- class Sections < Base
141
- registers 'sections'
142
-
143
- def build(node)
144
- build_content(node)
145
- end
146
- end
147
-
148
- # ── Blocks ──
149
-
150
- class Paragraph < Base
151
- registers 'paragraph'
152
-
153
- def build(node)
154
- CoreModel::ParagraphBlock.new(children: build_inline_children(node))
155
- end
156
- end
157
-
158
- class CodeBlock < Base
159
- registers 'sourcecode'
160
-
161
- def build(node)
162
- attrs = node.attrs
163
- CoreModel::SourceBlock.new(
164
- content: attrs&.text || extract_text(node),
165
- language: attrs&.language,
166
- title: attrs&.title
167
- )
168
- end
169
- end
170
-
171
- class Blockquote < Base
172
- registers 'quote'
173
-
174
- def build(node)
175
- CoreModel::QuoteBlock.new(
176
- attribution: node.attrs&.attribution,
177
- children: build_content(node)
178
- )
179
- end
180
- end
181
-
182
- class Example < Base
183
- registers 'example'
184
-
185
- def build(node)
186
- CoreModel::ExampleBlock.new(
187
- title: node.attrs&.title,
188
- children: build_content(node)
189
- )
190
- end
191
- end
192
-
193
- class Sidebar < Base
194
- registers 'sidebar'
195
-
196
- def build(node)
197
- CoreModel::SidebarBlock.new(
198
- title: node.attrs&.title,
199
- children: build_content(node)
200
- )
201
- end
202
- end
203
-
204
- class OpenBlock < Base
205
- registers 'open_block'
206
-
207
- def build(node)
208
- CoreModel::OpenBlock.new(children: build_content(node))
209
- end
210
- end
211
-
212
- class Verse < Base
213
- registers 'verse'
214
-
215
- def build(node)
216
- CoreModel::VerseBlock.new(
217
- content: extract_text(node),
218
- attribution: node.attrs&.attribution
219
- )
220
- end
221
- end
222
-
223
- class HorizontalRule < Base
224
- registers 'horizontal_rule', 'thematic_break'
225
-
226
- def build(_node)
227
- CoreModel::HorizontalRuleBlock.new
228
- end
229
- end
230
-
231
- class Frontmatter < Base
232
- registers 'frontmatter'
233
-
234
- def build(node)
235
- attrs = node.attrs
236
- CoreModel::FrontmatterBlock.new(
237
- schema: attrs&.schema,
238
- data: FrontmatterTreeToHash.to_hash(attrs&.entries || [])
239
- )
240
- end
241
- end
242
-
243
- class Admonition < Base
244
- registers 'admonition'
245
-
246
- def build(node)
247
- CoreModel::AnnotationBlock.new(
248
- annotation_type: node.attrs&.admonition_type,
249
- content: extract_text(node)
250
- )
251
- end
252
- end
253
-
254
- # ── Lists ──
255
-
256
- class BulletList < Base
257
- registers 'bullet_list'
258
-
259
- def build(node)
260
- items = build_content(node).select { |c| c.is_a?(CoreModel::ListItem) }
261
- CoreModel::ListBlock.new(marker_type: 'unordered', items: items)
262
- end
263
- end
264
-
265
- class OrderedList < Base
266
- registers 'ordered_list'
267
-
268
- def build(node)
269
- items = build_content(node).select { |c| c.is_a?(CoreModel::ListItem) }
270
- CoreModel::ListBlock.new(marker_type: 'ordered', items: items)
271
- end
272
- end
273
-
274
- class ListItem < Base
275
- registers 'list_item'
276
-
277
- def build(node)
278
- children = build_inline_children(node)
279
- text = children.map { |c| c.is_a?(CoreModel::TextContent) ? c.text : '' }.join
280
-
281
- CoreModel::ListItem.new(
282
- content: text,
283
- children: children,
284
- nested_list: find_nested_list(node)
285
- )
286
- end
287
-
288
- private
289
-
290
- def find_nested_list(node)
291
- node.content&.each do |child|
292
- next unless child.is_a?(Node)
293
- return build_node(child) if LIST_TYPES.include?(child.type)
294
- end
295
- nil
296
- end
297
- end
298
-
299
- class DefinitionList < Base
300
- registers 'dl'
301
-
302
- def build(node)
303
- terms = []
304
- descriptions = []
305
- node.content&.each do |child|
306
- next unless child.is_a?(Node)
307
-
308
- case child.type
309
- when 'dt' then terms << build_node(child)
310
- when 'dd' then descriptions << build_node(child)
311
- end
312
- end
313
-
314
- items = terms.zip(descriptions).map do |term, desc|
315
- CoreModel::DefinitionItem.new(
316
- term: inline_content(term),
317
- definitions: [inline_content(desc)]
318
- )
319
- end
320
-
321
- CoreModel::DefinitionList.new(items: items)
322
- end
323
- end
324
-
325
- class InlineText < Base
326
- registers 'dt', 'dd'
327
-
328
- def build(node)
329
- children = build_inline_children(node)
330
- text = children.map { |c| c.is_a?(CoreModel::TextContent) ? c.text : '' }.join
331
- CoreModel::InlineElement.new(content: text)
332
- end
333
- end
334
-
335
- # ── Media ──
336
-
337
- class Image < Base
338
- registers 'image'
339
-
340
- def build(node)
341
- attrs = node.attrs
342
- CoreModel::Image.new(
343
- src: attrs&.src,
344
- alt: attrs&.alt,
345
- title: attrs&.title,
346
- caption: attrs&.caption,
347
- width: attrs&.width,
348
- height: attrs&.height
349
- )
350
- end
351
- end
352
-
353
- # JS @metanorma/mirror `figure` wraps an image plus an optional
354
- # caption. Reverse: collapse back to a single CoreModel::Image,
355
- # promoting the caption child to `caption:` if present.
356
- class Figure < Base
357
- registers 'figure'
358
-
359
- def build(node)
360
- image_child = node.content&.find { |c| c.is_a?(Node) && c.type == 'image' }
361
- return nil unless image_child
362
-
363
- image = build_node(image_child)
364
- caption = extract_caption(node)
365
- image.caption = caption if caption && !image.caption
366
- image
367
- end
368
-
369
- private
370
-
371
- def extract_caption(node)
372
- caption_node = node.content&.find { |c| c.is_a?(Node) && c.type == 'caption' }
373
- return nil unless caption_node
374
-
375
- extract_text(caption_node)
376
- end
377
- end
378
-
379
- # Caption only appears as a Figure child. If encountered standalone,
380
- # extract its text as an inline element so it isn't lost.
381
- class Caption < Base
382
- registers 'caption'
383
-
384
- def build(node)
385
- CoreModel::InlineElement.new(content: extract_text(node))
386
- end
387
- end
388
-
389
- # ── Tables ──
390
-
391
- class Table < Base
392
- registers 'table'
393
-
394
- def build(node)
395
- rows = []
396
- node.content&.each do |child|
397
- next unless child.is_a?(Node)
398
- next unless %w[table_head table_body].include?(child.type)
399
-
400
- child.content&.each do |row_node|
401
- rows << build_node(row_node) if row_node.is_a?(Node)
402
- end
403
- end
404
-
405
- CoreModel::Table.new(title: node.attrs&.title, rows: rows)
406
- end
407
- end
408
-
409
- class TableHead < Base
410
- registers 'table_head'
411
-
412
- def build(node)
413
- build_content(node).first || CoreModel::TableRow.new
414
- end
415
- end
416
-
417
- class TableBody < Base
418
- registers 'table_body'
419
-
420
- def build(node)
421
- build_content(node).first || CoreModel::TableRow.new
422
- end
423
- end
424
-
425
- class TableRow < Base
426
- registers 'table_row'
427
-
428
- def build(node)
429
- cells = build_content(node).select { |c| c.is_a?(CoreModel::TableCell) }
430
- CoreModel::TableRow.new(cells: cells)
431
- end
432
- end
433
-
434
- class TableCell < Base
435
- registers 'table_cell'
436
-
437
- def build(node)
438
- attrs = node.attrs
439
- CoreModel::TableCell.new(
440
- content: extract_text(node),
441
- header: attrs&.header || false,
442
- colspan: attrs&.colspan,
443
- rowspan: attrs&.rowspan,
444
- alignment: attrs&.alignment
445
- )
446
- end
447
- end
448
-
449
- # ── Bibliography ──
450
-
451
- class Bibliography < Base
452
- registers 'bibliography'
453
-
454
- def build(node)
455
- entries = build_content(node).select { |c| c.is_a?(CoreModel::BibliographyEntry) }
456
- CoreModel::Bibliography.new(title: node.attrs&.title, entries: entries)
457
- end
458
- end
459
-
460
- class BiblioEntry < Base
461
- registers 'biblio_entry'
462
-
463
- def build(node)
464
- attrs = node.attrs
465
- CoreModel::BibliographyEntry.new(
466
- anchor_name: attrs&.anchor_name,
467
- document_id: attrs&.document_id,
468
- ref_text: extract_text(node)
469
- )
470
- end
471
- end
472
-
473
- # ── Footnotes ──
474
-
475
- # The `footnotes` block is a structural trailing container; it has
476
- # no CoreModel equivalent (each entry is built separately). Returns
477
- # nil so build_content filters it out.
478
- class Footnotes < Base
479
- registers 'footnotes'
480
-
481
- def build(_node)
482
- nil
483
- end
484
- end
485
-
486
- class FootnoteEntry < Base
487
- registers 'footnote_entry'
488
-
489
- def build(node)
490
- attrs = node.attrs
491
- CoreModel::Footnote.new(id: attrs&.id, content: extract_text(node))
492
- end
493
- end
494
-
495
- # Inline footnote marker (JS `footnote_marker`). The CoreModel
496
- # FootnoteReference holds the same id/ref/number triple.
497
- class FootnoteMarker < Base
498
- registers 'footnote_marker'
499
-
500
- def build(node)
501
- attrs = node.attrs
502
- CoreModel::FootnoteReference.new(
503
- id: attrs&.id,
504
- reference: attrs&.ref_id,
505
- number: attrs&.number
506
- )
507
- end
508
- end
509
-
510
- # ── TOC ──
511
-
512
- class Toc < Base
513
- registers 'toc'
514
-
515
- def build(_node)
516
- CoreModel::Toc.new
517
- end
518
- end
519
-
520
- class TocEntry < Base
521
- registers 'toc_entry'
522
-
523
- def build(node)
524
- attrs = node.attrs
525
- CoreModel::TocEntry.new(id: attrs&.id, title: attrs&.title)
526
- end
527
- end
528
-
529
- # ── Inline ──
530
-
531
- class Text < Base
532
- registers 'text'
533
-
534
- def build(node)
535
- text = node.text || ''
536
- marks = node.marks || []
537
-
538
- return CoreModel::TextContent.new(text: text) if marks.empty?
539
-
540
- marks.reduce(CoreModel::TextContent.new(text: text)) do |current, mark|
541
- apply_mark(current, mark)
542
- end
543
- end
544
- end
545
-
546
- class SoftBreak < Base
547
- registers 'soft_break'
548
-
549
- def build(_node)
550
- CoreModel::LineBreakElement.new
551
- end
552
- end
553
-
554
- # Catch-all for unrecognized block types emitted by the forward
555
- # direction (`Node::GenericBlock`). Preserves the semantic_type so
556
- # downstream consumers can dispatch on it.
557
- class GenericBlock < Base
558
- registers 'generic_block'
559
-
560
- def build(node)
561
- attrs = node.attrs
562
- CoreModel::Block.new(
563
- block_semantic_type: attrs&.semantic_type || 'generic',
564
- title: attrs&.title,
565
- id: attrs&.id,
566
- content: extract_text(node)
567
- )
568
- end
569
- end
570
-
571
- LIST_TYPES = %w[bullet_list ordered_list].freeze
572
- private_constant :LIST_TYPES
49
+ # Base must load first every subclass inherits from it. Then
50
+ # eager-load each Builder so its `registers` call runs.
51
+ require_relative 'reverse_builder/base'
52
+ require_relative 'reverse_builder/document'
53
+ require_relative 'reverse_builder/section'
54
+ require_relative 'reverse_builder/header'
55
+ require_relative 'reverse_builder/preamble'
56
+ require_relative 'reverse_builder/sections'
57
+ require_relative 'reverse_builder/paragraph'
58
+ require_relative 'reverse_builder/code_block'
59
+ require_relative 'reverse_builder/literal_block'
60
+ require_relative 'reverse_builder/pass_block'
61
+ require_relative 'reverse_builder/stem_block'
62
+ require_relative 'reverse_builder/blockquote'
63
+ require_relative 'reverse_builder/example'
64
+ require_relative 'reverse_builder/sidebar'
65
+ require_relative 'reverse_builder/open_block'
66
+ require_relative 'reverse_builder/verse'
67
+ require_relative 'reverse_builder/horizontal_rule'
68
+ require_relative 'reverse_builder/frontmatter'
69
+ require_relative 'reverse_builder/admonition'
70
+ require_relative 'reverse_builder/bullet_list'
71
+ require_relative 'reverse_builder/ordered_list'
72
+ require_relative 'reverse_builder/list_item'
73
+ require_relative 'reverse_builder/definition_list'
74
+ require_relative 'reverse_builder/inline_text'
75
+ require_relative 'reverse_builder/image'
76
+ require_relative 'reverse_builder/figure'
77
+ require_relative 'reverse_builder/caption'
78
+ require_relative 'reverse_builder/include'
79
+ require_relative 'reverse_builder/table'
80
+ require_relative 'reverse_builder/table_head'
81
+ require_relative 'reverse_builder/table_body'
82
+ require_relative 'reverse_builder/table_row'
83
+ require_relative 'reverse_builder/table_cell'
84
+ require_relative 'reverse_builder/bibliography'
85
+ require_relative 'reverse_builder/biblio_entry'
86
+ require_relative 'reverse_builder/footnotes'
87
+ require_relative 'reverse_builder/footnote_entry'
88
+ require_relative 'reverse_builder/footnote_marker'
89
+ require_relative 'reverse_builder/toc'
90
+ require_relative 'reverse_builder/toc_entry'
91
+ require_relative 'reverse_builder/text'
92
+ require_relative 'reverse_builder/raw_inline'
93
+ require_relative 'reverse_builder/soft_break'
94
+ require_relative 'reverse_builder/generic_block'
573
95
  end
574
96
  end
575
97
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Coradoc
4
4
  module Mirror
5
- VERSION = '0.1.3'
5
+ VERSION = '0.1.5'
6
6
  end
7
7
  end
@@ -68,6 +68,8 @@ module Coradoc
68
68
  method_name: :literal)
69
69
  registry.register(CoreModel::PassBlock, Handlers::CodeBlock,
70
70
  method_name: :pass)
71
+ registry.register(CoreModel::StemBlock, Handlers::CodeBlock,
72
+ method_name: :stem)
71
73
 
72
74
  # ── Blocks ──
73
75
  registry.register(CoreModel::QuoteBlock, Handlers::Blockquote)
@@ -111,6 +113,9 @@ module Coradoc
111
113
  # ── Frontmatter ──
112
114
  registry.register(CoreModel::FrontmatterBlock, Handlers::Frontmatter)
113
115
 
116
+ # ── Include directive (text-graph edge) ──
117
+ registry.register(CoreModel::Include, Handlers::Include)
118
+
114
119
  # ── Generic Block (catch-all for unrecognized block types) ──
115
120
  registry.register(CoreModel::Block, Handlers::GenericBlock)
116
121
 
@@ -3,10 +3,8 @@
3
3
  require 'coradoc'
4
4
  require_relative 'coradoc/mirror'
5
5
 
6
- # Side-effect: registers output processors with Coradoc::Output pipeline.
7
6
  # Side-effect: registers format modules with Coradoc registry.
8
7
  # These must use require (not autoload) because they have load-time side effects.
9
- require_relative 'coradoc/mirror/output'
10
8
  require_relative 'coradoc/mirror/mirror_json_format'
11
9
  require_relative 'coradoc/mirror/mirror_yaml_format'
12
10