coradoc-mirror 0.1.1
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.
- checksums.yaml +7 -0
- data/lib/coradoc/mirror/core_model_to_mirror.rb +181 -0
- data/lib/coradoc/mirror/handler_registry.rb +105 -0
- data/lib/coradoc/mirror/handlers/admonition.rb +29 -0
- data/lib/coradoc/mirror/handlers/bibliography.rb +43 -0
- data/lib/coradoc/mirror/handlers/blockquote.rb +19 -0
- data/lib/coradoc/mirror/handlers/code_block.rb +69 -0
- data/lib/coradoc/mirror/handlers/comment.rb +14 -0
- data/lib/coradoc/mirror/handlers/definition_list.rb +69 -0
- data/lib/coradoc/mirror/handlers/example.rb +19 -0
- data/lib/coradoc/mirror/handlers/footnote.rb +18 -0
- data/lib/coradoc/mirror/handlers/frontmatter.rb +71 -0
- data/lib/coradoc/mirror/handlers/generic_block.rb +24 -0
- data/lib/coradoc/mirror/handlers/horizontal_rule.rb +14 -0
- data/lib/coradoc/mirror/handlers/image.rb +58 -0
- data/lib/coradoc/mirror/handlers/inline.rb +213 -0
- data/lib/coradoc/mirror/handlers/list.rb +80 -0
- data/lib/coradoc/mirror/handlers/open_block.rb +16 -0
- data/lib/coradoc/mirror/handlers/paragraph.rb +16 -0
- data/lib/coradoc/mirror/handlers/reviewer.rb +14 -0
- data/lib/coradoc/mirror/handlers/sidebar.rb +19 -0
- data/lib/coradoc/mirror/handlers/structural.rb +84 -0
- data/lib/coradoc/mirror/handlers/table.rb +82 -0
- data/lib/coradoc/mirror/handlers/toc.rb +48 -0
- data/lib/coradoc/mirror/handlers/verse.rb +22 -0
- data/lib/coradoc/mirror/handlers.rb +38 -0
- data/lib/coradoc/mirror/mark.rb +181 -0
- data/lib/coradoc/mirror/mark_reverse_builder.rb +142 -0
- data/lib/coradoc/mirror/mirror_json_format.rb +42 -0
- data/lib/coradoc/mirror/mirror_to_core_model.rb +73 -0
- data/lib/coradoc/mirror/mirror_yaml_format.rb +41 -0
- data/lib/coradoc/mirror/node.rb +856 -0
- data/lib/coradoc/mirror/output.rb +62 -0
- data/lib/coradoc/mirror/partitioner.rb +62 -0
- data/lib/coradoc/mirror/reverse_builder.rb +600 -0
- data/lib/coradoc/mirror/transformer.rb +41 -0
- data/lib/coradoc/mirror/version.rb +7 -0
- data/lib/coradoc/mirror.rb +161 -0
- data/lib/coradoc-mirror.rb +14 -0
- metadata +140 -0
|
@@ -0,0 +1,856 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'lutaml/model'
|
|
4
|
+
require_relative 'mark'
|
|
5
|
+
|
|
6
|
+
module Coradoc
|
|
7
|
+
module Mirror
|
|
8
|
+
# ProseMirror-compatible document node.
|
|
9
|
+
#
|
|
10
|
+
# Wire format:
|
|
11
|
+
#
|
|
12
|
+
# { "type": "paragraph", "attrs": {...}, "content": [...], "marks": [...] }
|
|
13
|
+
#
|
|
14
|
+
# All built-in Node subclasses live below in this file so the
|
|
15
|
+
# TYPE_TO_CLASS registry can see every PM_TYPE at load time. Adding
|
|
16
|
+
# a new node type = adding one subclass (+ optional Attrs sub-model)
|
|
17
|
+
# and letting the registry walker pick it up (OCP).
|
|
18
|
+
#
|
|
19
|
+
# The TYPE_TO_CLASS and POLYMORPHIC constants are declared up-front
|
|
20
|
+
# (empty) because subclass `key_value` blocks reference them at class
|
|
21
|
+
# load time. The table is populated and frozen after every subclass
|
|
22
|
+
# is defined at the bottom of this file.
|
|
23
|
+
class Node < Lutaml::Model::Serializable
|
|
24
|
+
PM_TYPE = 'node'
|
|
25
|
+
|
|
26
|
+
TYPE_TO_CLASS = {}
|
|
27
|
+
POLYMORPHIC = { attribute: 'type', class_map: TYPE_TO_CLASS }.freeze
|
|
28
|
+
|
|
29
|
+
attribute :type, :string, default: -> { self.class::PM_TYPE }
|
|
30
|
+
attribute :content, Node, collection: true
|
|
31
|
+
attribute :marks, Mark, collection: true
|
|
32
|
+
|
|
33
|
+
key_value do
|
|
34
|
+
map 'type', to: :type, render_default: true
|
|
35
|
+
map 'content', to: :content, polymorphic: POLYMORPHIC
|
|
36
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def text_content
|
|
40
|
+
return '' unless content
|
|
41
|
+
|
|
42
|
+
content.select { |c| c.is_a?(Node) }.map(&:text_content).join
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
module Coradoc
|
|
49
|
+
module Mirror
|
|
50
|
+
class Node
|
|
51
|
+
# ── Top-level ──
|
|
52
|
+
|
|
53
|
+
class Document < Node
|
|
54
|
+
PM_TYPE = 'doc'
|
|
55
|
+
|
|
56
|
+
class Attrs < Lutaml::Model::Serializable
|
|
57
|
+
attribute :title, :string
|
|
58
|
+
attribute :id, :string
|
|
59
|
+
|
|
60
|
+
key_value do
|
|
61
|
+
map 'title', to: :title
|
|
62
|
+
map 'id', to: :id
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
attribute :attrs, Attrs
|
|
67
|
+
|
|
68
|
+
key_value do
|
|
69
|
+
map 'type', to: :type, render_default: true
|
|
70
|
+
map 'attrs', to: :attrs
|
|
71
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# ── Structural containers ──
|
|
76
|
+
|
|
77
|
+
class Section < Node
|
|
78
|
+
# JS SECTION_TYPES — all deserialize to Section. The type string
|
|
79
|
+
# is preserved as the type attribute on the instance.
|
|
80
|
+
PM_TYPE = 'section'
|
|
81
|
+
PM_ALIASES = %w[
|
|
82
|
+
clause annex content_section abstract foreword introduction
|
|
83
|
+
acknowledgements terms definitions references
|
|
84
|
+
].freeze
|
|
85
|
+
|
|
86
|
+
class Attrs < Lutaml::Model::Serializable
|
|
87
|
+
attribute :title, :string
|
|
88
|
+
attribute :id, :string
|
|
89
|
+
attribute :level, :integer
|
|
90
|
+
|
|
91
|
+
key_value do
|
|
92
|
+
map 'title', to: :title
|
|
93
|
+
map 'id', to: :id
|
|
94
|
+
map 'level', to: :level
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
attribute :attrs, Attrs
|
|
99
|
+
|
|
100
|
+
key_value do
|
|
101
|
+
map 'type', to: :type, render_default: true
|
|
102
|
+
map 'attrs', to: :attrs
|
|
103
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
class Preamble < Node
|
|
108
|
+
PM_TYPE = 'preface'
|
|
109
|
+
|
|
110
|
+
key_value do
|
|
111
|
+
map 'type', to: :type, render_default: true
|
|
112
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
class Sections < Node
|
|
117
|
+
PM_TYPE = 'sections'
|
|
118
|
+
|
|
119
|
+
key_value do
|
|
120
|
+
map 'type', to: :type, render_default: true
|
|
121
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
class Header < Node
|
|
126
|
+
PM_TYPE = 'floating_title'
|
|
127
|
+
|
|
128
|
+
class Attrs < Lutaml::Model::Serializable
|
|
129
|
+
attribute :title, :string
|
|
130
|
+
attribute :level, :integer
|
|
131
|
+
|
|
132
|
+
key_value do
|
|
133
|
+
map 'title', to: :title
|
|
134
|
+
map 'level', to: :level
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
attribute :attrs, Attrs
|
|
139
|
+
|
|
140
|
+
key_value do
|
|
141
|
+
map 'type', to: :type, render_default: true
|
|
142
|
+
map 'attrs', to: :attrs
|
|
143
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# ── Text (special: text at top level, not under attrs) ──
|
|
148
|
+
|
|
149
|
+
class Text < Node
|
|
150
|
+
PM_TYPE = 'text'
|
|
151
|
+
|
|
152
|
+
attribute :text, :string
|
|
153
|
+
|
|
154
|
+
key_value do
|
|
155
|
+
map 'type', to: :type, render_default: true
|
|
156
|
+
map 'text', to: :text
|
|
157
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def text_content
|
|
161
|
+
text.to_s
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# ── Paragraph / block text ──
|
|
166
|
+
|
|
167
|
+
class Paragraph < Node
|
|
168
|
+
PM_TYPE = 'paragraph'
|
|
169
|
+
|
|
170
|
+
key_value do
|
|
171
|
+
map 'type', to: :type, render_default: true
|
|
172
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
173
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
class CodeBlock < Node
|
|
178
|
+
PM_TYPE = 'sourcecode'
|
|
179
|
+
|
|
180
|
+
class Attrs < Lutaml::Model::Serializable
|
|
181
|
+
attribute :language, :string
|
|
182
|
+
attribute :title, :string
|
|
183
|
+
attribute :passthrough, :boolean
|
|
184
|
+
attribute :text, :string
|
|
185
|
+
|
|
186
|
+
key_value do
|
|
187
|
+
map 'language', to: :language
|
|
188
|
+
map 'title', to: :title
|
|
189
|
+
map 'passthrough', to: :passthrough
|
|
190
|
+
map 'text', to: :text
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
attribute :attrs, Attrs
|
|
195
|
+
|
|
196
|
+
key_value do
|
|
197
|
+
map 'type', to: :type, render_default: true
|
|
198
|
+
map 'attrs', to: :attrs
|
|
199
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
class Blockquote < Node
|
|
204
|
+
PM_TYPE = 'quote'
|
|
205
|
+
|
|
206
|
+
class Attrs < Lutaml::Model::Serializable
|
|
207
|
+
attribute :attribution, :string
|
|
208
|
+
|
|
209
|
+
key_value do
|
|
210
|
+
map 'attribution', to: :attribution
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
attribute :attrs, Attrs
|
|
215
|
+
|
|
216
|
+
key_value do
|
|
217
|
+
map 'type', to: :type, render_default: true
|
|
218
|
+
map 'attrs', to: :attrs
|
|
219
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
class Example < Node
|
|
224
|
+
PM_TYPE = 'example'
|
|
225
|
+
|
|
226
|
+
class Attrs < Lutaml::Model::Serializable
|
|
227
|
+
attribute :title, :string
|
|
228
|
+
attribute :id, :string
|
|
229
|
+
|
|
230
|
+
key_value do
|
|
231
|
+
map 'title', to: :title
|
|
232
|
+
map 'id', to: :id
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
attribute :attrs, Attrs
|
|
237
|
+
|
|
238
|
+
key_value do
|
|
239
|
+
map 'type', to: :type, render_default: true
|
|
240
|
+
map 'attrs', to: :attrs
|
|
241
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
class Sidebar < Node
|
|
246
|
+
PM_TYPE = 'sidebar'
|
|
247
|
+
|
|
248
|
+
class Attrs < Lutaml::Model::Serializable
|
|
249
|
+
attribute :title, :string
|
|
250
|
+
attribute :id, :string
|
|
251
|
+
|
|
252
|
+
key_value do
|
|
253
|
+
map 'title', to: :title
|
|
254
|
+
map 'id', to: :id
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
attribute :attrs, Attrs
|
|
259
|
+
|
|
260
|
+
key_value do
|
|
261
|
+
map 'type', to: :type, render_default: true
|
|
262
|
+
map 'attrs', to: :attrs
|
|
263
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
class OpenBlock < Node
|
|
268
|
+
PM_TYPE = 'open_block'
|
|
269
|
+
|
|
270
|
+
key_value do
|
|
271
|
+
map 'type', to: :type, render_default: true
|
|
272
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
class Verse < Node
|
|
277
|
+
PM_TYPE = 'verse'
|
|
278
|
+
|
|
279
|
+
class Attrs < Lutaml::Model::Serializable
|
|
280
|
+
attribute :attribution, :string
|
|
281
|
+
|
|
282
|
+
key_value do
|
|
283
|
+
map 'attribution', to: :attribution
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
attribute :attrs, Attrs
|
|
288
|
+
|
|
289
|
+
key_value do
|
|
290
|
+
map 'type', to: :type, render_default: true
|
|
291
|
+
map 'attrs', to: :attrs
|
|
292
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
class HorizontalRule < Node
|
|
297
|
+
PM_TYPE = 'horizontal_rule'
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
class ThematicBreak < Node
|
|
301
|
+
PM_TYPE = 'thematic_break'
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
class SoftBreak < Node
|
|
305
|
+
PM_TYPE = 'soft_break'
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# ── Admonition (NOTE, TIP, WARNING, CAUTION, IMPORTANT) ──
|
|
309
|
+
#
|
|
310
|
+
# The Ruby attribute name is `admonition_type` (kept distinct from
|
|
311
|
+
# Node's built-in `type` discriminator). The wire attribute name is
|
|
312
|
+
# `type` per the @metanorma/mirror JS contract. The rename happens
|
|
313
|
+
# via a `map` declaration — no hand-rolled to_h/from_h.
|
|
314
|
+
|
|
315
|
+
class Admonition < Node
|
|
316
|
+
PM_TYPE = 'admonition'
|
|
317
|
+
|
|
318
|
+
class Attrs < Lutaml::Model::Serializable
|
|
319
|
+
attribute :admonition_type, :string
|
|
320
|
+
attribute :title, :string
|
|
321
|
+
attribute :label, :string
|
|
322
|
+
attribute :id, :string
|
|
323
|
+
|
|
324
|
+
key_value do
|
|
325
|
+
map 'type', to: :admonition_type # RENAME: Ruby ≠ wire
|
|
326
|
+
map 'title', to: :title
|
|
327
|
+
map 'label', to: :label
|
|
328
|
+
map 'id', to: :id
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
attribute :attrs, Attrs
|
|
333
|
+
|
|
334
|
+
key_value do
|
|
335
|
+
map 'type', to: :type, render_default: true
|
|
336
|
+
map 'attrs', to: :attrs
|
|
337
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# ── Lists ──
|
|
342
|
+
|
|
343
|
+
class BulletList < Node
|
|
344
|
+
PM_TYPE = 'bullet_list'
|
|
345
|
+
|
|
346
|
+
class Attrs < Lutaml::Model::Serializable
|
|
347
|
+
attribute :id, :string
|
|
348
|
+
attribute :start, :integer
|
|
349
|
+
|
|
350
|
+
key_value do
|
|
351
|
+
map 'id', to: :id
|
|
352
|
+
map 'start', to: :start
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
attribute :attrs, Attrs
|
|
357
|
+
|
|
358
|
+
key_value do
|
|
359
|
+
map 'type', to: :type, render_default: true
|
|
360
|
+
map 'attrs', to: :attrs
|
|
361
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
class OrderedList < Node
|
|
366
|
+
PM_TYPE = 'ordered_list'
|
|
367
|
+
|
|
368
|
+
class Attrs < Lutaml::Model::Serializable
|
|
369
|
+
attribute :id, :string
|
|
370
|
+
attribute :start, :integer
|
|
371
|
+
|
|
372
|
+
key_value do
|
|
373
|
+
map 'id', to: :id
|
|
374
|
+
map 'start', to: :start
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
attribute :attrs, Attrs
|
|
379
|
+
|
|
380
|
+
key_value do
|
|
381
|
+
map 'type', to: :type, render_default: true
|
|
382
|
+
map 'attrs', to: :attrs
|
|
383
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
class ListItem < Node
|
|
388
|
+
PM_TYPE = 'list_item'
|
|
389
|
+
|
|
390
|
+
class Attrs < Lutaml::Model::Serializable
|
|
391
|
+
attribute :id, :string
|
|
392
|
+
|
|
393
|
+
key_value do
|
|
394
|
+
map 'id', to: :id
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
attribute :attrs, Attrs
|
|
399
|
+
|
|
400
|
+
key_value do
|
|
401
|
+
map 'type', to: :type, render_default: true
|
|
402
|
+
map 'attrs', to: :attrs
|
|
403
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
404
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
class DefinitionList < Node
|
|
409
|
+
PM_TYPE = 'dl'
|
|
410
|
+
|
|
411
|
+
class Attrs < Lutaml::Model::Serializable
|
|
412
|
+
attribute :id, :string
|
|
413
|
+
|
|
414
|
+
key_value do
|
|
415
|
+
map 'id', to: :id
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
attribute :attrs, Attrs
|
|
420
|
+
|
|
421
|
+
key_value do
|
|
422
|
+
map 'type', to: :type, render_default: true
|
|
423
|
+
map 'attrs', to: :attrs
|
|
424
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
class DefinitionTerm < Node
|
|
429
|
+
PM_TYPE = 'dt'
|
|
430
|
+
|
|
431
|
+
key_value do
|
|
432
|
+
map 'type', to: :type, render_default: true
|
|
433
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
434
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
class DefinitionDescription < Node
|
|
439
|
+
PM_TYPE = 'dd'
|
|
440
|
+
|
|
441
|
+
key_value do
|
|
442
|
+
map 'type', to: :type, render_default: true
|
|
443
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
444
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# ── Media ──
|
|
449
|
+
|
|
450
|
+
class Image < Node
|
|
451
|
+
PM_TYPE = 'image'
|
|
452
|
+
|
|
453
|
+
class Attrs < Lutaml::Model::Serializable
|
|
454
|
+
attribute :src, :string
|
|
455
|
+
attribute :alt, :string
|
|
456
|
+
attribute :title, :string
|
|
457
|
+
attribute :caption, :string
|
|
458
|
+
attribute :width, :string
|
|
459
|
+
attribute :height, :string
|
|
460
|
+
attribute :inline, :boolean
|
|
461
|
+
|
|
462
|
+
key_value do
|
|
463
|
+
map 'src', to: :src
|
|
464
|
+
map 'alt', to: :alt
|
|
465
|
+
map 'title', to: :title
|
|
466
|
+
map 'caption', to: :caption
|
|
467
|
+
map 'width', to: :width
|
|
468
|
+
map 'height', to: :height
|
|
469
|
+
map 'inline', to: :inline
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
attribute :attrs, Attrs
|
|
474
|
+
|
|
475
|
+
key_value do
|
|
476
|
+
map 'type', to: :type, render_default: true
|
|
477
|
+
map 'attrs', to: :attrs
|
|
478
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
# JS @metanorma/mirror figure: wraps Image + optional Caption.
|
|
483
|
+
class Figure < Node
|
|
484
|
+
PM_TYPE = 'figure'
|
|
485
|
+
|
|
486
|
+
class Attrs < Lutaml::Model::Serializable
|
|
487
|
+
attribute :id, :string
|
|
488
|
+
attribute :title, :string
|
|
489
|
+
|
|
490
|
+
key_value do
|
|
491
|
+
map 'id', to: :id
|
|
492
|
+
map 'title', to: :title
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
attribute :attrs, Attrs
|
|
497
|
+
|
|
498
|
+
key_value do
|
|
499
|
+
map 'type', to: :type, render_default: true
|
|
500
|
+
map 'attrs', to: :attrs
|
|
501
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
class Caption < Node
|
|
506
|
+
PM_TYPE = 'caption'
|
|
507
|
+
|
|
508
|
+
key_value do
|
|
509
|
+
map 'type', to: :type, render_default: true
|
|
510
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
511
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# ── Tables ──
|
|
516
|
+
|
|
517
|
+
class Table < Node
|
|
518
|
+
PM_TYPE = 'table'
|
|
519
|
+
|
|
520
|
+
class Attrs < Lutaml::Model::Serializable
|
|
521
|
+
attribute :title, :string
|
|
522
|
+
attribute :id, :string
|
|
523
|
+
attribute :width, :string
|
|
524
|
+
|
|
525
|
+
key_value do
|
|
526
|
+
map 'title', to: :title
|
|
527
|
+
map 'id', to: :id
|
|
528
|
+
map 'width', to: :width
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
attribute :attrs, Attrs
|
|
533
|
+
|
|
534
|
+
key_value do
|
|
535
|
+
map 'type', to: :type, render_default: true
|
|
536
|
+
map 'attrs', to: :attrs
|
|
537
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
class TableHead < Node
|
|
542
|
+
PM_TYPE = 'table_head'
|
|
543
|
+
|
|
544
|
+
key_value do
|
|
545
|
+
map 'type', to: :type, render_default: true
|
|
546
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
class TableBody < Node
|
|
551
|
+
PM_TYPE = 'table_body'
|
|
552
|
+
|
|
553
|
+
key_value do
|
|
554
|
+
map 'type', to: :type, render_default: true
|
|
555
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
class TableRow < Node
|
|
560
|
+
PM_TYPE = 'table_row'
|
|
561
|
+
|
|
562
|
+
key_value do
|
|
563
|
+
map 'type', to: :type, render_default: true
|
|
564
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
class TableCell < Node
|
|
569
|
+
PM_TYPE = 'table_cell'
|
|
570
|
+
|
|
571
|
+
class Attrs < Lutaml::Model::Serializable
|
|
572
|
+
attribute :colspan, :integer
|
|
573
|
+
attribute :rowspan, :integer
|
|
574
|
+
attribute :alignment, :string
|
|
575
|
+
attribute :header, :boolean
|
|
576
|
+
|
|
577
|
+
key_value do
|
|
578
|
+
map 'colspan', to: :colspan
|
|
579
|
+
map 'rowspan', to: :rowspan
|
|
580
|
+
map 'alignment', to: :alignment
|
|
581
|
+
map 'header', to: :header
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
attribute :attrs, Attrs
|
|
586
|
+
|
|
587
|
+
key_value do
|
|
588
|
+
map 'type', to: :type, render_default: true
|
|
589
|
+
map 'attrs', to: :attrs
|
|
590
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
591
|
+
map 'marks', to: :marks, polymorphic: Mark::POLYMORPHIC
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
# ── Bibliography ──
|
|
596
|
+
|
|
597
|
+
class Bibliography < Node
|
|
598
|
+
PM_TYPE = 'bibliography'
|
|
599
|
+
|
|
600
|
+
class Attrs < Lutaml::Model::Serializable
|
|
601
|
+
attribute :title, :string
|
|
602
|
+
attribute :id, :string
|
|
603
|
+
attribute :level, :integer
|
|
604
|
+
|
|
605
|
+
key_value do
|
|
606
|
+
map 'title', to: :title
|
|
607
|
+
map 'id', to: :id
|
|
608
|
+
map 'level', to: :level
|
|
609
|
+
end
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
attribute :attrs, Attrs
|
|
613
|
+
|
|
614
|
+
key_value do
|
|
615
|
+
map 'type', to: :type, render_default: true
|
|
616
|
+
map 'attrs', to: :attrs
|
|
617
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
618
|
+
end
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
class BibliographyEntry < Node
|
|
622
|
+
PM_TYPE = 'biblio_entry'
|
|
623
|
+
|
|
624
|
+
class Attrs < Lutaml::Model::Serializable
|
|
625
|
+
attribute :anchor_name, :string
|
|
626
|
+
attribute :document_id, :string
|
|
627
|
+
attribute :url, :string
|
|
628
|
+
|
|
629
|
+
key_value do
|
|
630
|
+
map 'anchor_name', to: :anchor_name
|
|
631
|
+
map 'document_id', to: :document_id
|
|
632
|
+
map 'url', to: :url
|
|
633
|
+
end
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
attribute :attrs, Attrs
|
|
637
|
+
|
|
638
|
+
key_value do
|
|
639
|
+
map 'type', to: :type, render_default: true
|
|
640
|
+
map 'attrs', to: :attrs
|
|
641
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
642
|
+
end
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
# ── Footnotes ──
|
|
646
|
+
|
|
647
|
+
class Footnotes < Node
|
|
648
|
+
PM_TYPE = 'footnotes'
|
|
649
|
+
|
|
650
|
+
key_value do
|
|
651
|
+
map 'type', to: :type, render_default: true
|
|
652
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
653
|
+
end
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
class FootnoteMarker < Node
|
|
657
|
+
PM_TYPE = 'footnote_marker'
|
|
658
|
+
|
|
659
|
+
class Attrs < Lutaml::Model::Serializable
|
|
660
|
+
attribute :id, :string
|
|
661
|
+
attribute :ref_id, :string
|
|
662
|
+
attribute :number, :integer
|
|
663
|
+
|
|
664
|
+
key_value do
|
|
665
|
+
map 'id', to: :id
|
|
666
|
+
map 'ref_id', to: :ref_id
|
|
667
|
+
map 'number', to: :number
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
attribute :attrs, Attrs
|
|
672
|
+
|
|
673
|
+
key_value do
|
|
674
|
+
map 'type', to: :type, render_default: true
|
|
675
|
+
map 'attrs', to: :attrs
|
|
676
|
+
end
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
class FootnoteEntry < Node
|
|
680
|
+
PM_TYPE = 'footnote_entry'
|
|
681
|
+
|
|
682
|
+
class Attrs < Lutaml::Model::Serializable
|
|
683
|
+
attribute :id, :string
|
|
684
|
+
attribute :ref_id, :string
|
|
685
|
+
attribute :number, :integer
|
|
686
|
+
|
|
687
|
+
key_value do
|
|
688
|
+
map 'id', to: :id
|
|
689
|
+
map 'ref_id', to: :ref_id
|
|
690
|
+
map 'number', to: :number
|
|
691
|
+
end
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
attribute :attrs, Attrs
|
|
695
|
+
|
|
696
|
+
key_value do
|
|
697
|
+
map 'type', to: :type, render_default: true
|
|
698
|
+
map 'attrs', to: :attrs
|
|
699
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
700
|
+
end
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
# ── TOC ──
|
|
704
|
+
|
|
705
|
+
class Toc < Node
|
|
706
|
+
PM_TYPE = 'toc'
|
|
707
|
+
|
|
708
|
+
class Attrs < Lutaml::Model::Serializable
|
|
709
|
+
attribute :title, :string
|
|
710
|
+
|
|
711
|
+
key_value do
|
|
712
|
+
map 'title', to: :title
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
attribute :attrs, Attrs
|
|
717
|
+
|
|
718
|
+
key_value do
|
|
719
|
+
map 'type', to: :type, render_default: true
|
|
720
|
+
map 'attrs', to: :attrs
|
|
721
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
class TocEntry < Node
|
|
726
|
+
PM_TYPE = 'toc_entry'
|
|
727
|
+
|
|
728
|
+
class Attrs < Lutaml::Model::Serializable
|
|
729
|
+
attribute :id, :string
|
|
730
|
+
attribute :title, :string
|
|
731
|
+
attribute :level, :integer
|
|
732
|
+
|
|
733
|
+
key_value do
|
|
734
|
+
map 'id', to: :id
|
|
735
|
+
map 'title', to: :title
|
|
736
|
+
map 'level', to: :level
|
|
737
|
+
end
|
|
738
|
+
end
|
|
739
|
+
|
|
740
|
+
attribute :attrs, Attrs
|
|
741
|
+
|
|
742
|
+
key_value do
|
|
743
|
+
map 'type', to: :type, render_default: true
|
|
744
|
+
map 'attrs', to: :attrs
|
|
745
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
746
|
+
end
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
# ── Generic (catch-all) ──
|
|
750
|
+
|
|
751
|
+
class GenericBlock < Node
|
|
752
|
+
PM_TYPE = 'generic_block'
|
|
753
|
+
|
|
754
|
+
class Attrs < Lutaml::Model::Serializable
|
|
755
|
+
attribute :semantic_type, :string
|
|
756
|
+
attribute :title, :string
|
|
757
|
+
attribute :id, :string
|
|
758
|
+
|
|
759
|
+
key_value do
|
|
760
|
+
map 'semantic_type', to: :semantic_type
|
|
761
|
+
map 'title', to: :title
|
|
762
|
+
map 'id', to: :id
|
|
763
|
+
end
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
attribute :attrs, Attrs
|
|
767
|
+
|
|
768
|
+
key_value do
|
|
769
|
+
map 'type', to: :type, render_default: true
|
|
770
|
+
map 'attrs', to: :attrs
|
|
771
|
+
map 'content', to: :content, polymorphic: Node::POLYMORPHIC
|
|
772
|
+
end
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
# ── Frontmatter (typed tree — no hashes) ──
|
|
776
|
+
|
|
777
|
+
class FrontmatterValue < Lutaml::Model::Serializable; end
|
|
778
|
+
|
|
779
|
+
class FrontmatterEntry < Lutaml::Model::Serializable
|
|
780
|
+
attribute :key, :string
|
|
781
|
+
attribute :value, FrontmatterValue
|
|
782
|
+
|
|
783
|
+
key_value do
|
|
784
|
+
map 'key', to: :key, render_default: true
|
|
785
|
+
map 'value', to: :value
|
|
786
|
+
end
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
class FrontmatterValue
|
|
790
|
+
attribute :value_type, :string
|
|
791
|
+
attribute :string_value, :string
|
|
792
|
+
attribute :integer_value, :integer
|
|
793
|
+
attribute :float_value, :float
|
|
794
|
+
attribute :boolean_value, :boolean
|
|
795
|
+
attribute :date_value, :date
|
|
796
|
+
attribute :datetime_value, :date_time
|
|
797
|
+
attribute :symbol_value, :string
|
|
798
|
+
attribute :items, FrontmatterValue, collection: true
|
|
799
|
+
attribute :entries, FrontmatterEntry, collection: true
|
|
800
|
+
|
|
801
|
+
key_value do
|
|
802
|
+
map 'value_type', to: :value_type, render_default: true
|
|
803
|
+
map 'string_value', to: :string_value
|
|
804
|
+
map 'integer_value', to: :integer_value
|
|
805
|
+
map 'float_value', to: :float_value
|
|
806
|
+
map 'boolean_value', to: :boolean_value
|
|
807
|
+
map 'date_value', to: :date_value
|
|
808
|
+
map 'datetime_value', to: :datetime_value
|
|
809
|
+
map 'symbol_value', to: :symbol_value
|
|
810
|
+
map 'items', to: :items
|
|
811
|
+
map 'entries', to: :entries
|
|
812
|
+
end
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
class Frontmatter < Node
|
|
816
|
+
PM_TYPE = 'frontmatter'
|
|
817
|
+
|
|
818
|
+
class Attrs < Lutaml::Model::Serializable
|
|
819
|
+
attribute :schema, :string
|
|
820
|
+
attribute :entries, FrontmatterEntry, collection: true
|
|
821
|
+
|
|
822
|
+
key_value do
|
|
823
|
+
map 'schema', to: :schema
|
|
824
|
+
map 'entries', to: :entries
|
|
825
|
+
end
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
attribute :attrs, Attrs
|
|
829
|
+
|
|
830
|
+
key_value do
|
|
831
|
+
map 'type', to: :type, render_default: true
|
|
832
|
+
map 'attrs', to: :attrs
|
|
833
|
+
end
|
|
834
|
+
end
|
|
835
|
+
end
|
|
836
|
+
end
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
module Coradoc
|
|
840
|
+
module Mirror
|
|
841
|
+
class Node
|
|
842
|
+
# Populate the polymorphic class map now that every subclass is
|
|
843
|
+
# defined. Maps each PM_TYPE wire string to its Ruby class name.
|
|
844
|
+
# Section's PM_ALIASES are added on top so all JS SECTION_TYPES
|
|
845
|
+
# route to Section on reverse parse.
|
|
846
|
+
Node.constants.each do |name|
|
|
847
|
+
k = Node.const_get(name)
|
|
848
|
+
next unless k.is_a?(Class) && k < Node && k::PM_TYPE != 'node'
|
|
849
|
+
|
|
850
|
+
TYPE_TO_CLASS[k::PM_TYPE] = k.name
|
|
851
|
+
Array(k::PM_ALIASES).each { |a| TYPE_TO_CLASS[a] = k.name } if k.const_defined?(:PM_ALIASES, false)
|
|
852
|
+
end
|
|
853
|
+
TYPE_TO_CLASS.freeze
|
|
854
|
+
end
|
|
855
|
+
end
|
|
856
|
+
end
|