metanorma-document 0.3.0 → 0.4.0

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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +3 -2
  3. data/Rakefile +30 -5
  4. data/frontend/dist/app.css +1 -0
  5. data/frontend/dist/app.iife.js +24 -0
  6. data/frontend/package-lock.json +7 -505
  7. data/frontend/tailwind.config.js +5 -0
  8. data/lib/metanorma/csa_document/root.rb +27 -0
  9. data/lib/metanorma/csa_document.rb +9 -0
  10. data/lib/metanorma/document/cli.rb +52 -0
  11. data/lib/metanorma/document/components/ancillary_blocks/sourcecode_body.rb +14 -0
  12. data/lib/metanorma/document/components/inline/comma_element.rb +3 -0
  13. data/lib/metanorma/document/components/inline/enum_comma_element.rb +3 -0
  14. data/lib/metanorma/document/components/inline/eref_element.rb +4 -1
  15. data/lib/metanorma/document/components/inline/fmt_termsource_element.rb +4 -2
  16. data/lib/metanorma/document/components/inline/math_element.rb +13 -7
  17. data/lib/metanorma/document/components/inline/vocabulary.rb +4 -0
  18. data/lib/metanorma/document/components/multi_paragraph/admonition_block.rb +6 -1
  19. data/lib/metanorma/document/components/paragraphs/paragraph_block.rb +3 -0
  20. data/lib/metanorma/document/components/reference_elements/callout.rb +3 -2
  21. data/lib/metanorma/document/components/tables/table_cell.rb +3 -0
  22. data/lib/metanorma/document/elements/input.rb +44 -0
  23. data/lib/metanorma/document/elements.rb +1 -0
  24. data/lib/metanorma/document/relaton/address.rb +5 -0
  25. data/lib/metanorma/document/relaton/affiliation.rb +3 -0
  26. data/lib/metanorma/document/relaton/bib_item_size.rb +8 -9
  27. data/lib/metanorma/document/relaton/bib_item_type.rb +3 -0
  28. data/lib/metanorma/document/relaton/bibliographic_date.rb +5 -0
  29. data/lib/metanorma/document/relaton/contact_method.rb +5 -0
  30. data/lib/metanorma/document/relaton/contribution_info.rb +6 -2
  31. data/lib/metanorma/document/relaton/contributor.rb +4 -0
  32. data/lib/metanorma/document/relaton/contributor_role.rb +3 -0
  33. data/lib/metanorma/document/relaton/copyright_association.rb +3 -0
  34. data/lib/metanorma/document/relaton/copyright_owner.rb +3 -0
  35. data/lib/metanorma/document/relaton/date_time.rb +3 -0
  36. data/lib/metanorma/document/relaton/document_identifier.rb +4 -0
  37. data/lib/metanorma/document/relaton/document_relation.rb +8 -0
  38. data/lib/metanorma/document/relaton/document_status.rb +4 -0
  39. data/lib/metanorma/document/relaton/formatted_address.rb +4 -0
  40. data/lib/metanorma/document/relaton/full_name.rb +14 -3
  41. data/lib/metanorma/document/relaton/keyword_type.rb +3 -0
  42. data/lib/metanorma/document/relaton/locality_stack.rb +6 -9
  43. data/lib/metanorma/document/relaton/localized_name.rb +8 -5
  44. data/lib/metanorma/document/relaton/logo_element.rb +5 -0
  45. data/lib/metanorma/document/relaton/medium_type.rb +5 -16
  46. data/lib/metanorma/document/relaton/org_identifier.rb +2 -0
  47. data/lib/metanorma/document/relaton/org_subdivision.rb +2 -0
  48. data/lib/metanorma/document/relaton/org_subdivision_identifier.rb +2 -0
  49. data/lib/metanorma/document/relaton/organization.rb +3 -0
  50. data/lib/metanorma/document/relaton/person.rb +7 -1
  51. data/lib/metanorma/document/relaton/person_identifier.rb +3 -0
  52. data/lib/metanorma/document/relaton/place_type.rb +5 -0
  53. data/lib/metanorma/document/relaton/region_element.rb +3 -9
  54. data/lib/metanorma/document/relaton/relaton_collection.rb +2 -0
  55. data/lib/metanorma/document/relaton/series_type.rb +7 -0
  56. data/lib/metanorma/document/relaton/typed_note.rb +4 -0
  57. data/lib/metanorma/document/relaton/typed_title_string.rb +4 -0
  58. data/lib/metanorma/document/relaton/typed_uri.rb +3 -8
  59. data/lib/metanorma/document/relaton/validity_type.rb +8 -10
  60. data/lib/metanorma/document/relaton/variant_full_name.rb +3 -0
  61. data/lib/metanorma/document/relaton/variant_org_name.rb +3 -0
  62. data/lib/metanorma/document/relaton/version_info.rb +5 -0
  63. data/lib/metanorma/document/relaton/vocab_id_type.rb +6 -12
  64. data/lib/metanorma/document/relaton.rb +0 -14
  65. data/lib/metanorma/document/version.rb +1 -1
  66. data/lib/metanorma/document.rb +1 -0
  67. data/lib/metanorma/html/base_renderer.rb +86 -234
  68. data/lib/metanorma/html/concerns/metadata_extraction.rb +61 -0
  69. data/lib/metanorma/html/concerns/presentation_validation.rb +61 -0
  70. data/lib/metanorma/html/concerns/svg_processing.rb +32 -0
  71. data/lib/metanorma/html/concerns/text_extraction.rb +93 -0
  72. data/lib/metanorma/html/concerns/toc_registry.rb +47 -0
  73. data/lib/metanorma/html/csa_renderer.rb +9 -0
  74. data/lib/metanorma/html/drops/figure_drop.rb +33 -10
  75. data/lib/metanorma/html/drops/sourcecode_drop.rb +3 -6
  76. data/lib/metanorma/html/flavor.rb +6 -1
  77. data/lib/metanorma/html/generator.rb +8 -1
  78. data/lib/metanorma/html/iso_renderer.rb +0 -142
  79. data/lib/metanorma/html/renderers/block_renderer.rb +10 -0
  80. data/lib/metanorma/html/renderers/element_order_traversal.rb +15 -1
  81. data/lib/metanorma/html/renderers/inline_renderer.rb +13 -75
  82. data/lib/metanorma/html/standard_renderer.rb +195 -35
  83. data/lib/metanorma/html.rb +1 -51
  84. data/lib/metanorma/iso_document/sections/iso_preface.rb +27 -13
  85. data/lib/metanorma/mirror/default_registry.rb +21 -0
  86. data/lib/metanorma/mirror/handlers/inline/catalog.rb +7 -12
  87. data/lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb +2 -3
  88. data/lib/metanorma/mirror/handlers/sourcecode.rb +1 -1
  89. data/lib/metanorma/mirror/model/guide.rb +3 -2
  90. data/lib/metanorma/mirror/output/formats/inline_format.rb +64 -3
  91. data/lib/metanorma/mirror/output/pipeline.rb +1 -0
  92. data/lib/metanorma/mirror/output.rb +0 -2
  93. data/lib/metanorma/mirror/rewriter.rb +3 -1
  94. data/lib/metanorma/registers/setup.rb +10 -0
  95. data/lib/metanorma/standard_document/annotation_container.rb +2 -0
  96. data/lib/metanorma/standard_document/elements/input.rb +4 -25
  97. data/lib/metanorma/standard_document/metadata/metanorma_extension.rb +12 -2
  98. data/lib/metanorma/standard_document/metadata/presentation_metadata.rb +107 -0
  99. data/lib/metanorma/standard_document/metadata/semantic_metadata.rb +18 -0
  100. data/lib/metanorma/standard_document/metadata/unitsml/amount_of_substance.rb +19 -0
  101. data/lib/metanorma/standard_document/metadata/unitsml/base_quantity.rb +34 -0
  102. data/lib/metanorma/standard_document/metadata/unitsml/dimension.rb +39 -0
  103. data/lib/metanorma/standard_document/metadata/unitsml/dimension_set.rb +19 -0
  104. data/lib/metanorma/standard_document/metadata/unitsml/electric_current.rb +19 -0
  105. data/lib/metanorma/standard_document/metadata/unitsml/enumerated_root_unit.rb +23 -0
  106. data/lib/metanorma/standard_document/metadata/unitsml/length.rb +19 -0
  107. data/lib/metanorma/standard_document/metadata/unitsml/luminous_intensity.rb +19 -0
  108. data/lib/metanorma/standard_document/metadata/unitsml/mass.rb +19 -0
  109. data/lib/metanorma/standard_document/metadata/unitsml/namespace.rb +17 -0
  110. data/lib/metanorma/standard_document/metadata/unitsml/plane_angle.rb +19 -0
  111. data/lib/metanorma/standard_document/metadata/unitsml/prefix.rb +30 -0
  112. data/lib/metanorma/standard_document/metadata/unitsml/prefix_name.rb +21 -0
  113. data/lib/metanorma/standard_document/metadata/unitsml/prefix_set.rb +19 -0
  114. data/lib/metanorma/standard_document/metadata/unitsml/prefix_symbol.rb +21 -0
  115. data/lib/metanorma/standard_document/metadata/unitsml/quantity.rb +28 -0
  116. data/lib/metanorma/standard_document/metadata/unitsml/quantity_name.rb +21 -0
  117. data/lib/metanorma/standard_document/metadata/unitsml/quantity_set.rb +19 -0
  118. data/lib/metanorma/standard_document/metadata/unitsml/root_units.rb +19 -0
  119. data/lib/metanorma/standard_document/metadata/unitsml/thermodynamic_temperature.rb +19 -0
  120. data/lib/metanorma/standard_document/metadata/unitsml/time.rb +19 -0
  121. data/lib/metanorma/standard_document/metadata/unitsml/unit.rb +32 -0
  122. data/lib/metanorma/standard_document/metadata/unitsml/unit_name.rb +21 -0
  123. data/lib/metanorma/standard_document/metadata/unitsml/unit_set.rb +19 -0
  124. data/lib/metanorma/standard_document/metadata/unitsml/unit_symbol.rb +36 -0
  125. data/lib/metanorma/standard_document/metadata/unitsml/unit_system.rb +23 -0
  126. data/lib/metanorma/standard_document/metadata/unitsml/unitsml_root.rb +28 -0
  127. data/lib/metanorma/standard_document/metadata/unitsml.rb +39 -0
  128. data/lib/metanorma/standard_document/metadata.rb +4 -0
  129. data/lib/metanorma/standard_document/sections/misc_container.rb +8 -6
  130. data/lib/metanorma/standard_document/sections/sections.rb +7 -0
  131. data/lib/metanorma/un_document/blocks/un_admonition_block.rb +86 -0
  132. data/lib/metanorma/un_document/blocks.rb +9 -0
  133. data/lib/metanorma/un_document/root.rb +8 -0
  134. data/lib/metanorma/un_document/sections/un_abstract_section.rb +48 -0
  135. data/lib/metanorma/un_document/sections/un_preface.rb +19 -2
  136. data/lib/metanorma/un_document/sections.rb +1 -0
  137. data/lib/metanorma/un_document/un_text_element.rb +116 -0
  138. data/lib/metanorma/un_document.rb +2 -0
  139. data/script/benchmark_render.rb +35 -0
  140. data/tasks/roundtrip_samples.rake +1 -1
  141. metadata +63 -45
  142. data/.rubocop_todo.yml +0 -220
  143. data/TODO.finalize/01-split-multi-class-files.md +0 -8
  144. data/TODO.finalize/02-remove-data-dist-iso-document-frontend.md +0 -6
  145. data/TODO.finalize/03-align-frontend-iife-and-gha-build.md +0 -11
  146. data/TODO.finalize/04-theme-per-flavor-config-driven.md +0 -9
  147. data/TODO.finalize/05-migrate-all-html-to-liquid.md +0 -16
  148. data/TODO.finalize/06-integrate-pubid-library.md +0 -16
  149. data/TODO.finalize/07-replace-relaton-models-with-relaton-bib.md +0 -39
  150. data/TODO.finalize/08-refactor-renderer-architecture.md +0 -25
  151. data/TODO.finalize/09-eliminate-code-smells.md +0 -14
  152. data/TODO.finalize/10-comprehensive-spec-coverage.md +0 -24
  153. data/TODO.finalize/11-config-driven-flavor-metadata.md +0 -20
  154. data/TODO.finalize/12-add-frozen-string-literal.md +0 -6
  155. data/TODO.finalize/13-extract-composition-from-god-class.md +0 -96
  156. data/TODO.finalize/14-config-driven-section-ordering.md +0 -31
  157. data/TODO.finalize/15-theme-directories-per-flavor.md +0 -46
  158. data/TODO.finalize/16-theme-lutaml-model-schema.md +0 -44
  159. data/docs/html-renderer.adoc +0 -261
  160. data/lib/data/dist/iso_document/frontend/assets/index-mwzbzmnK.js +0 -22
  161. data/lib/data/dist/iso_document/frontend/assets/index-pGvKTNid.css +0 -1
  162. data/lib/data/dist/iso_document/frontend/assets/iso-red.svg +0 -53
  163. data/lib/data/dist/iso_document/frontend/index.html +0 -13
  164. data/lib/metanorma/document/relaton/bib_item_size_type.rb +0 -21
  165. data/lib/metanorma/document/relaton/bibliographic_date_type.rb +0 -22
  166. data/lib/metanorma/document/relaton/document_relation_type.rb +0 -31
  167. data/lib/metanorma/document/relaton/iso4217_code.rb +0 -17
  168. data/lib/metanorma/document/relaton/iso8601_date.rb +0 -17
  169. data/lib/metanorma/document/relaton/personal_identifier_type.rb +0 -21
  170. data/lib/metanorma/document/relaton/region_type.rb +0 -20
  171. data/lib/metanorma/document/relaton/series_type_type.rb +0 -21
  172. data/lib/metanorma/document/relaton/specific_locality_type.rb +0 -25
  173. data/lib/metanorma/document/relaton/title_type.rb +0 -21
  174. data/lib/metanorma/mirror/output/html_renderer.rb +0 -95
  175. data/lib/metanorma/mirror/output/html_renderers/block_renderers.rb +0 -178
  176. data/lib/metanorma/mirror/output/html_renderers/inline_renderer.rb +0 -61
  177. data/lib/metanorma/mirror/output/html_renderers/list_renderers.rb +0 -96
  178. data/lib/metanorma/mirror/output/html_renderers/mark_renderers.rb +0 -41
  179. data/lib/metanorma/mirror/output/html_renderers/section_renderers.rb +0 -129
  180. data/lib/metanorma/mirror/output/html_renderers/structural_renderers.rb +0 -80
  181. data/lib/metanorma/mirror/output/html_renderers/table_renderers.rb +0 -87
  182. data/lib/metanorma/mirror/output/html_renderers.rb +0 -76
  183. data/lib/metanorma/standard_document/annotation.rb +0 -37
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Mirror
5
- module Output
6
- class HtmlRenderer
7
- include HtmlRenderers::StructuralRenderers
8
- include HtmlRenderers::SectionRenderers
9
- include HtmlRenderers::BlockRenderers
10
- include HtmlRenderers::ListRenderers
11
- include HtmlRenderers::TableRenderers
12
- include HtmlRenderers::InlineRenderer
13
- include HtmlRenderers::MarkRenderers
14
-
15
- class << self
16
- def node_handlers
17
- @node_handlers ||= {}
18
- end
19
-
20
- def mark_handlers
21
- @mark_handlers ||= {}
22
- end
23
-
24
- def register_node_handler(type, unbound_method)
25
- node_handlers[type] = unbound_method
26
- end
27
-
28
- def register_mark_handler(mark_type, handler)
29
- mark_handlers[mark_type] = handler
30
- end
31
- end
32
-
33
- def initialize(guide, numbering: {})
34
- @content = extract_content(guide)
35
- @numbering = numbering
36
- end
37
-
38
- def render
39
- render_nodes(@content)
40
- end
41
-
42
- def render_nodes(nodes, depth: 0)
43
- nodes.filter_map { |node| render_node(node, depth:) }.join("\n")
44
- end
45
-
46
- def render_node(node, depth: 0)
47
- case node
48
- when String
49
- HtmlRenderers.escape_text(node)
50
- when Model::Text
51
- render_text_node(node)
52
- when Model::Container, Model::Leaf, Model::SoftBreak
53
- render_typed_node(node, depth:)
54
- else
55
- ""
56
- end
57
- end
58
-
59
- def render_typed_node(node, depth: 0)
60
- unbound = self.class.node_handlers[node.type]
61
- return unbound.bind_call(self, node, depth:) if unbound
62
-
63
- render_generic(node, depth:)
64
- end
65
-
66
- def render_generic(node, depth: 0)
67
- children = node.content if node.is_a?(Model::Container)
68
- return "" unless children && !children.empty?
69
-
70
- render_children(node, depth:)
71
- end
72
-
73
- def render_children(node, depth: 0)
74
- children = node.is_a?(Model::Container) ? node.content : []
75
- render_nodes(children, depth:)
76
- end
77
-
78
- private
79
-
80
- def extract_content(guide)
81
- case guide
82
- when Model::Guide
83
- guide.content.is_a?(Model::Container) ? guide.content.content : Array(guide.content)
84
- when Model::Container
85
- guide.content
86
- else
87
- raise ArgumentError, "Unsupported guide type: #{guide.class}"
88
- end
89
- end
90
- end
91
-
92
- HtmlRenderers.register_all(HtmlRenderer)
93
- end
94
- end
95
- end
@@ -1,178 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Mirror
5
- module Output
6
- module HtmlRenderers
7
- module BlockRenderers
8
- ADMONITION_TITLES = {
9
- "danger" => "Danger", "caution" => "Caution",
10
- "warning" => "Warning", "important" => "Important",
11
- "safety precautions" => "Safety Precautions",
12
- "editorial" => "Editorial",
13
- "tip" => "Tip", "note" => "Note",
14
- "commentary" => "Commentary"
15
- }.freeze
16
-
17
- def self.register(registry)
18
- registry.register_node_handler("paragraph",
19
- instance_method(:render_paragraph))
20
- registry.register_node_handler("note",
21
- instance_method(:render_note))
22
- registry.register_node_handler("admonition",
23
- instance_method(:render_admonition))
24
- registry.register_node_handler("example",
25
- instance_method(:render_example))
26
- registry.register_node_handler("figure",
27
- instance_method(:render_figure))
28
- registry.register_node_handler("image",
29
- instance_method(:render_image))
30
- registry.register_node_handler("sourcecode",
31
- instance_method(:render_sourcecode))
32
- registry.register_node_handler("formula",
33
- instance_method(:render_formula))
34
- registry.register_node_handler("quote",
35
- instance_method(:render_quote))
36
- registry.register_node_handler("review",
37
- instance_method(:render_review))
38
- registry.register_node_handler("term",
39
- instance_method(:render_term))
40
- end
41
-
42
- def render_paragraph(node, depth: 0)
43
- HtmlRenderers.build do |doc|
44
- attrs = { class: "mn-paragraph" }
45
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
46
- doc.p(attrs) do
47
- HtmlRenderers.embed(doc, render_inline(node.content))
48
- end
49
- end
50
- end
51
-
52
- def render_note(node, depth: 0)
53
- HtmlRenderers.build do |doc|
54
- attrs = { class: "mn-note" }
55
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
56
- doc.div(attrs) do
57
- doc.div(class: "note-title") { doc.text "Note" }
58
- HtmlRenderers.embed(doc, render_children(node, depth:))
59
- end
60
- end
61
- end
62
-
63
- def render_admonition(node, depth: 0)
64
- adm_type = node.attrs["type"] || "note"
65
- title = ADMONITION_TITLES[adm_type] || adm_type.capitalize
66
-
67
- HtmlRenderers.build do |doc|
68
- attrs = { class: "mn-admonition mn-admonition--#{adm_type}" }
69
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
70
- doc.div(attrs) do
71
- doc.div(class: "admonition-content") do
72
- doc.div(class: "admonition-title") { doc.text title }
73
- HtmlRenderers.embed(doc, render_children(node, depth:))
74
- end
75
- end
76
- end
77
- end
78
-
79
- def render_example(node, depth: 0)
80
- HtmlRenderers.build do |doc|
81
- attrs = { class: "mn-example" }
82
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
83
- doc.div(attrs) do
84
- HtmlRenderers.embed(doc, render_children(node, depth:))
85
- end
86
- end
87
- end
88
-
89
- def render_figure(node, depth: 0)
90
- HtmlRenderers.build do |doc|
91
- attrs = { class: "mn-figure" }
92
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
93
- doc.figure(attrs) do
94
- HtmlRenderers.embed(doc, render_children(node, depth:))
95
- if node.attrs["title"]
96
- doc.figcaption { doc.text node.attrs["title"] }
97
- end
98
- end
99
- end
100
- end
101
-
102
- def render_image(node, depth: 0)
103
- HtmlRenderers.build do |doc|
104
- attrs = {
105
- src: node.attrs["src"] || "",
106
- alt: node.attrs["alt"] || "",
107
- loading: "lazy",
108
- }
109
- attrs[:height] = node.attrs["height"] if node.attrs["height"]
110
- attrs[:width] = node.attrs["width"] if node.attrs["width"]
111
- doc.img(attrs)
112
- end
113
- end
114
-
115
- def render_sourcecode(node, depth: 0)
116
- lang = node.attrs["language"]
117
- lang_class = lang ? " language-#{lang}" : ""
118
-
119
- HtmlRenderers.build do |doc|
120
- attrs = { class: "mn-sourcecode#{lang_class}" }
121
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
122
- doc.div(attrs) do
123
- doc.span(class: "code-language-badge") { doc.text lang } if lang
124
- doc.pre(class: "code-block") do
125
- doc.code { doc.text node.attrs["text"] || "" }
126
- end
127
- end
128
- end
129
- end
130
-
131
- def render_formula(node, depth: 0)
132
- HtmlRenderers.build do |doc|
133
- attrs = { class: "mn-formula" }
134
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
135
- doc.div(attrs) do
136
- doc.span(class: "formula-math") do
137
- math = node.attrs["mathml"]
138
- if math
139
- HtmlRenderers.embed(doc, math)
140
- elsif node.attrs["asciimath"]
141
- doc.text node.attrs["asciimath"]
142
- else
143
- doc.text node.attrs["math_text"] || ""
144
- end
145
- end
146
- end
147
- end
148
- end
149
-
150
- def render_quote(node, depth: 0)
151
- HtmlRenderers.build do |doc|
152
- attrs = { class: "mn-quote" }
153
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
154
- doc.blockquote(attrs) do
155
- HtmlRenderers.embed(doc, render_children(node))
156
- end
157
- end
158
- end
159
-
160
- def render_review(_node, depth: 0)
161
- ""
162
- end
163
-
164
- def render_term(node, depth: 0)
165
- HtmlRenderers.build do |doc|
166
- attrs = { class: "mn-term" }
167
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
168
- doc.div(attrs) do
169
- HtmlRenderers.embed(doc,
170
- render_children(node, depth: depth + 1))
171
- end
172
- end
173
- end
174
- end
175
- end
176
- end
177
- end
178
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Mirror
5
- module Output
6
- module HtmlRenderers
7
- module InlineRenderer
8
- def self.register(registry); end
9
-
10
- def render_inline(content)
11
- return "" unless content
12
- return "" if content.empty?
13
-
14
- HtmlRenderers.build_fragment do |doc|
15
- content.each do |node|
16
- case node
17
- when String
18
- doc.text node
19
- when Model::Text
20
- HtmlRenderers.embed(doc, render_text_node(node))
21
- when Model::SoftBreak
22
- doc.br
23
- when Model::Container
24
- if node.type == "footnote_marker"
25
- HtmlRenderers.embed(doc, render_footnote_marker(node))
26
- else
27
- HtmlRenderers.embed(doc, render_node(node))
28
- end
29
- end
30
- end
31
- end
32
- end
33
-
34
- def render_text_node(node)
35
- inner_html = HtmlRenderers.escape_text(node.text)
36
- node.marks.reduce(inner_html) do |current, mark|
37
- apply_mark(current, mark)
38
- end
39
- end
40
-
41
- def apply_mark(inner_html, mark)
42
- handler = self.class.mark_handlers[mark.type]
43
- handler ? handler.call(inner_html, mark) : inner_html
44
- end
45
-
46
- def render_footnote_marker(node)
47
- HtmlRenderers.build do |doc|
48
- doc.sup(class: "footnote-marker") do
49
- attrs = {}
50
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
51
- doc.a(attrs.merge(href: "##{node.attrs['ref_id'] || ''}")) do
52
- doc.text node.attrs["number"] || "*"
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Mirror
5
- module Output
6
- module HtmlRenderers
7
- module ListRenderers
8
- def self.register(registry)
9
- registry.register_node_handler("bullet_list",
10
- instance_method(:render_bullet_list))
11
- registry.register_node_handler("ordered_list",
12
- instance_method(:render_ordered_list))
13
- registry.register_node_handler("dl", instance_method(:render_dl))
14
- registry.register_node_handler("list_item",
15
- instance_method(:render_list_item))
16
- registry.register_node_handler("dt", instance_method(:render_dt))
17
- registry.register_node_handler("dd", instance_method(:render_dd))
18
- end
19
-
20
- def render_bullet_list(node, depth: 0)
21
- render_list(node, "ul", "mn-bullet-list")
22
- end
23
-
24
- def render_ordered_list(node, depth: 0)
25
- render_list(node, "ol", "mn-ordered-list")
26
- end
27
-
28
- def render_list_item(node, depth: 0)
29
- HtmlRenderers.build do |doc|
30
- doc.li(class: "mn-list-item") do
31
- HtmlRenderers.embed(doc, render_inline(node.content))
32
- end
33
- end
34
- end
35
-
36
- def render_dl(node, depth: 0)
37
- HtmlRenderers.build do |doc|
38
- doc.dl(class: "mn-definition-list") do
39
- node.content.each do |item|
40
- next unless item.is_a?(Model::Container) || item.is_a?(Model::Leaf)
41
-
42
- case item.type
43
- when "dt"
44
- doc.dt(class: "mn-dt") do
45
- HtmlRenderers.embed(doc, render_inline(item.content))
46
- end
47
- when "dd"
48
- doc.dd(class: "mn-dd") do
49
- HtmlRenderers.embed(doc, render_children(item))
50
- end
51
- else
52
- HtmlRenderers.embed(doc, render_node(item))
53
- end
54
- end
55
- end
56
- end
57
- end
58
-
59
- def render_dt(node, depth: 0)
60
- HtmlRenderers.build do |doc|
61
- doc.dt(class: "mn-dt") do
62
- HtmlRenderers.embed(doc, render_inline(node.content))
63
- end
64
- end
65
- end
66
-
67
- def render_dd(node, depth: 0)
68
- HtmlRenderers.build do |doc|
69
- doc.dd(class: "mn-dd") do
70
- HtmlRenderers.embed(doc, render_children(node))
71
- end
72
- end
73
- end
74
-
75
- private
76
-
77
- def render_list(node, tag, css_class)
78
- HtmlRenderers.build do |doc|
79
- doc.public_send(tag, class: css_class) do
80
- node.content.each do |item|
81
- if item.is_a?(Model::Container) && item.type == "list_item"
82
- doc.li(class: "mn-list-item") do
83
- HtmlRenderers.embed(doc, render_inline(item.content))
84
- end
85
- else
86
- HtmlRenderers.embed(doc, render_node(item))
87
- end
88
- end
89
- end
90
- end
91
- end
92
- end
93
- end
94
- end
95
- end
96
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Mirror
5
- module Output
6
- module HtmlRenderers
7
- module MarkRenderers
8
- def self.register(registry)
9
- # Simple-wrap marks: tag and attrs come from the shared Catalog
10
- # so the Model-side renderer and the XML-side RichHtmlRenderer
11
- # agree on HTML output.
12
- Handlers::Inline::Catalog::SIMPLE_WRAPS.each do |mark_type, spec|
13
- tag = spec[:tag]
14
- attrs = spec.except(:tag)
15
- registry.register_mark_handler(mark_type, ->(inner, _mark) {
16
- HtmlRenderers.wrap(tag, inner, **attrs)
17
- })
18
- end
19
-
20
- # Dynamic marks: attrs come from mark.attrs per instance.
21
- registry.register_mark_handler("link", ->(inner, mark) {
22
- HtmlRenderers.wrap(:a, inner, href: mark.attrs["href"] || "#")
23
- })
24
- registry.register_mark_handler("xref", ->(inner, mark) {
25
- HtmlRenderers.wrap(:a, inner, href: "##{mark.attrs['target'] || ''}")
26
- })
27
- registry.register_mark_handler("eref", ->(inner, mark) {
28
- HtmlRenderers.wrap(:a, inner, class: "eref",
29
- cite: mark.attrs["citeas"] || "")
30
- })
31
- registry.register_mark_handler("span", ->(inner, mark) {
32
- cls = mark.attrs["class_attr"]
33
- attrs = cls ? { class: cls } : {}
34
- HtmlRenderers.wrap(:span, inner, **attrs)
35
- })
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,129 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Mirror
5
- module Output
6
- module HtmlRenderers
7
- module SectionRenderers
8
- def self.register(registry)
9
- registry.register_node_handler("clause",
10
- instance_method(:render_clause))
11
- registry.register_node_handler("annex",
12
- instance_method(:render_annex))
13
- registry.register_node_handler("content_section",
14
- instance_method(:render_content_section))
15
- registry.register_node_handler("abstract",
16
- instance_method(:render_content_section))
17
- registry.register_node_handler("foreword",
18
- instance_method(:render_content_section))
19
- registry.register_node_handler("introduction",
20
- instance_method(:render_content_section))
21
- registry.register_node_handler("acknowledgements",
22
- instance_method(:render_content_section))
23
- registry.register_node_handler("terms",
24
- instance_method(:render_terms))
25
- registry.register_node_handler("definitions",
26
- instance_method(:render_definitions))
27
- registry.register_node_handler("references",
28
- instance_method(:render_references))
29
- registry.register_node_handler("floating_title",
30
- instance_method(:render_floating_title))
31
- end
32
-
33
- def render_clause(node, depth: 0)
34
- title = node.attrs["title"]
35
- number = node.attrs["number"] || @numbering[node.attrs["id"]]
36
-
37
- HtmlRenderers.build do |doc|
38
- attrs = { class: "mn-clause" }
39
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
40
- doc.section(attrs) do
41
- if title
42
- heading_attrs = { class: "mn-clause__title" }
43
- heading_attrs[:id] = node.attrs["id"] if node.attrs["id"]
44
- render_heading(doc, depth + 2, heading_attrs) do
45
- doc.text "#{number} " if number
46
- doc.text title
47
- end
48
- end
49
- HtmlRenderers.embed(doc,
50
- render_children(node, depth: depth + 1))
51
- end
52
- end
53
- end
54
-
55
- def render_annex(node, depth: 0)
56
- title = node.attrs["title"]
57
-
58
- HtmlRenderers.build do |doc|
59
- attrs = { class: "mn-annex" }
60
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
61
- doc.section(attrs) do
62
- if title
63
- heading_attrs = { class: "mn-annex__title" }
64
- heading_attrs[:id] = node.attrs["id"] if node.attrs["id"]
65
- doc.h2(heading_attrs) { doc.text title }
66
- end
67
- HtmlRenderers.embed(doc,
68
- render_children(node, depth: depth + 1))
69
- end
70
- end
71
- end
72
-
73
- def render_content_section(node, depth: 0)
74
- title = node.attrs["title"]
75
- css_class = "mn-#{node.type}"
76
-
77
- HtmlRenderers.build do |doc|
78
- attrs = { class: css_class }
79
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
80
- doc.section(attrs) do
81
- if title
82
- heading_attrs = { class: "#{css_class}__title" }
83
- heading_attrs[:id] = node.attrs["id"] if node.attrs["id"]
84
- doc.h2(heading_attrs) { doc.text title }
85
- end
86
- HtmlRenderers.embed(doc, render_children(node, depth:))
87
- end
88
- end
89
- end
90
-
91
- def render_terms(node, depth: 0)
92
- render_content_section(node, depth:)
93
- end
94
-
95
- def render_definitions(node, depth: 0)
96
- render_content_section(node, depth:)
97
- end
98
-
99
- def render_references(node, depth: 0)
100
- render_content_section(node, depth:)
101
- end
102
-
103
- def render_floating_title(node, depth: 0)
104
- title = node.attrs["title"]
105
- heading_depth = node.attrs["depth"] || 2
106
-
107
- return "" unless title
108
-
109
- HtmlRenderers.build do |doc|
110
- attrs = { class: "mn-floating-title" }
111
- attrs[:id] = node.attrs["id"] if node.attrs["id"]
112
- render_heading(doc, heading_depth, attrs) { doc.text title }
113
- end
114
- end
115
-
116
- def render_heading(doc, level, attrs, &)
117
- case level.to_i
118
- when 3 then doc.h3(attrs, &)
119
- when 4 then doc.h4(attrs, &)
120
- when 5 then doc.h5(attrs, &)
121
- when 6 then doc.h6(attrs, &)
122
- else doc.h2(attrs, &)
123
- end
124
- end
125
- end
126
- end
127
- end
128
- end
129
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Mirror
5
- module Output
6
- module HtmlRenderers
7
- module StructuralRenderers
8
- def self.register(registry)
9
- registry.register_node_handler("doc", instance_method(:render_doc))
10
- registry.register_node_handler("preface",
11
- instance_method(:render_preface))
12
- registry.register_node_handler("sections",
13
- instance_method(:render_sections))
14
- registry.register_node_handler("bibliography",
15
- instance_method(:render_bibliography))
16
- registry.register_node_handler("footnotes",
17
- instance_method(:render_footnotes))
18
- registry.register_node_handler("soft_break",
19
- instance_method(:render_soft_break))
20
- end
21
-
22
- def render_doc(node, depth: 0)
23
- HtmlRenderers.build do |doc|
24
- HtmlRenderers.embed(doc, render_children(node, depth:))
25
- end
26
- end
27
-
28
- def render_preface(node, depth: 0)
29
- HtmlRenderers.build do |doc|
30
- doc.section(class: "mn-preface") do
31
- HtmlRenderers.embed(doc, render_children(node, depth:))
32
- end
33
- end
34
- end
35
-
36
- def render_sections(node, depth: 0)
37
- HtmlRenderers.build do |doc|
38
- doc.section(class: "mn-sections") do
39
- HtmlRenderers.embed(doc, render_children(node, depth:))
40
- end
41
- end
42
- end
43
-
44
- def render_bibliography(node, depth: 0)
45
- HtmlRenderers.build do |doc|
46
- doc.section(class: "mn-bibliography") do
47
- HtmlRenderers.embed(doc, render_children(node, depth:))
48
- end
49
- end
50
- end
51
-
52
- def render_footnotes(node, depth: 0)
53
- HtmlRenderers.build do |doc|
54
- doc.div(class: "footnotes") do
55
- doc.ol do
56
- node.content.each do |fn|
57
- next unless fn.is_a?(Model::Container)
58
-
59
- fn_attrs = {}
60
- fn_attrs[:id] = fn.attrs["id"] if fn.attrs["id"]
61
- doc.li(fn_attrs) do
62
- HtmlRenderers.embed(doc, render_children(fn))
63
- if fn.attrs["ref_id"]
64
- doc.a(href: "##{fn.attrs['ref_id']}") { doc.text "↩" }
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
72
-
73
- def render_soft_break(_node, depth: 0)
74
- HtmlRenderers.build(&:br)
75
- end
76
- end
77
- end
78
- end
79
- end
80
- end