metanorma-document 0.2.12 → 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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +3 -2
  3. data/README.adoc +1 -1
  4. data/Rakefile +30 -5
  5. data/frontend/dist/app.css +1 -0
  6. data/frontend/dist/app.iife.js +24 -0
  7. data/frontend/package-lock.json +7 -505
  8. data/frontend/tailwind.config.js +5 -0
  9. data/lib/metanorma/csa_document/root.rb +27 -0
  10. data/lib/metanorma/csa_document.rb +9 -0
  11. data/lib/metanorma/document/cli.rb +52 -0
  12. data/lib/metanorma/document/components/ancillary_blocks/sourcecode_body.rb +14 -0
  13. data/lib/metanorma/document/components/inline/comma_element.rb +3 -0
  14. data/lib/metanorma/document/components/inline/enum_comma_element.rb +3 -0
  15. data/lib/metanorma/document/components/inline/eref_element.rb +4 -1
  16. data/lib/metanorma/document/components/inline/fmt_termsource_element.rb +4 -2
  17. data/lib/metanorma/document/components/inline/math_element.rb +13 -7
  18. data/lib/metanorma/document/components/inline/semx_element.rb +7 -8
  19. data/lib/metanorma/document/components/inline/vocabulary.rb +4 -0
  20. data/lib/metanorma/document/components/multi_paragraph/admonition_block.rb +6 -1
  21. data/lib/metanorma/document/components/paragraphs/paragraph_block.rb +3 -0
  22. data/lib/metanorma/document/components/reference_elements/callout.rb +3 -2
  23. data/lib/metanorma/document/components/tables/table_cell.rb +3 -0
  24. data/lib/metanorma/document/elements/input.rb +44 -0
  25. data/lib/metanorma/document/elements.rb +1 -0
  26. data/lib/metanorma/document/relaton/address.rb +5 -0
  27. data/lib/metanorma/document/relaton/affiliation.rb +3 -0
  28. data/lib/metanorma/document/relaton/bib_item_size.rb +8 -9
  29. data/lib/metanorma/document/relaton/bib_item_type.rb +3 -0
  30. data/lib/metanorma/document/relaton/bibliographic_date.rb +5 -0
  31. data/lib/metanorma/document/relaton/contact_method.rb +5 -0
  32. data/lib/metanorma/document/relaton/contribution_info.rb +6 -2
  33. data/lib/metanorma/document/relaton/contributor.rb +4 -0
  34. data/lib/metanorma/document/relaton/contributor_role.rb +3 -0
  35. data/lib/metanorma/document/relaton/copyright_association.rb +3 -0
  36. data/lib/metanorma/document/relaton/copyright_owner.rb +3 -0
  37. data/lib/metanorma/document/relaton/date_time.rb +3 -0
  38. data/lib/metanorma/document/relaton/document_identifier.rb +4 -0
  39. data/lib/metanorma/document/relaton/document_relation.rb +8 -0
  40. data/lib/metanorma/document/relaton/document_status.rb +4 -0
  41. data/lib/metanorma/document/relaton/formatted_address.rb +4 -0
  42. data/lib/metanorma/document/relaton/full_name.rb +14 -3
  43. data/lib/metanorma/document/relaton/keyword_type.rb +3 -0
  44. data/lib/metanorma/document/relaton/locality_stack.rb +6 -9
  45. data/lib/metanorma/document/relaton/localized_name.rb +8 -5
  46. data/lib/metanorma/document/relaton/logo_element.rb +5 -0
  47. data/lib/metanorma/document/relaton/medium_type.rb +5 -16
  48. data/lib/metanorma/document/relaton/org_identifier.rb +2 -0
  49. data/lib/metanorma/document/relaton/org_subdivision.rb +2 -0
  50. data/lib/metanorma/document/relaton/org_subdivision_identifier.rb +2 -0
  51. data/lib/metanorma/document/relaton/organization.rb +3 -0
  52. data/lib/metanorma/document/relaton/person.rb +7 -1
  53. data/lib/metanorma/document/relaton/person_identifier.rb +3 -0
  54. data/lib/metanorma/document/relaton/place_type.rb +5 -0
  55. data/lib/metanorma/document/relaton/region_element.rb +3 -9
  56. data/lib/metanorma/document/relaton/relaton_collection.rb +2 -0
  57. data/lib/metanorma/document/relaton/series_type.rb +7 -0
  58. data/lib/metanorma/document/relaton/typed_note.rb +4 -0
  59. data/lib/metanorma/document/relaton/typed_title_string.rb +4 -0
  60. data/lib/metanorma/document/relaton/typed_uri.rb +3 -8
  61. data/lib/metanorma/document/relaton/validity_type.rb +8 -10
  62. data/lib/metanorma/document/relaton/variant_full_name.rb +3 -0
  63. data/lib/metanorma/document/relaton/variant_org_name.rb +3 -0
  64. data/lib/metanorma/document/relaton/version_info.rb +5 -0
  65. data/lib/metanorma/document/relaton/vocab_id_type.rb +6 -12
  66. data/lib/metanorma/document/relaton.rb +0 -14
  67. data/lib/metanorma/document/version.rb +1 -1
  68. data/lib/metanorma/document.rb +1 -0
  69. data/lib/metanorma/html/base_renderer.rb +133 -307
  70. data/lib/metanorma/html/component/base.rb +2 -9
  71. data/lib/metanorma/html/concerns/metadata_extraction.rb +61 -0
  72. data/lib/metanorma/html/concerns/presentation_validation.rb +61 -0
  73. data/lib/metanorma/html/concerns/svg_processing.rb +32 -0
  74. data/lib/metanorma/html/concerns/text_extraction.rb +93 -0
  75. data/lib/metanorma/html/concerns/toc_registry.rb +47 -0
  76. data/lib/metanorma/html/csa_renderer.rb +9 -0
  77. data/lib/metanorma/html/drops/figure_drop.rb +33 -10
  78. data/lib/metanorma/html/drops/sourcecode_drop.rb +3 -6
  79. data/lib/metanorma/html/flavor.rb +50 -0
  80. data/lib/metanorma/html/flavor_registry.rb +49 -0
  81. data/lib/metanorma/html/generator.rb +113 -29
  82. data/lib/metanorma/html/iso_renderer.rb +0 -142
  83. data/lib/metanorma/html/renderer_delegation.rb +21 -0
  84. data/lib/metanorma/html/renderers/block_renderer.rb +10 -0
  85. data/lib/metanorma/html/renderers/element_order_traversal.rb +48 -0
  86. data/lib/metanorma/html/renderers/inline_renderer.rb +49 -124
  87. data/lib/metanorma/html/renderers/pubid_renderer.rb +4 -26
  88. data/lib/metanorma/html/renderers.rb +2 -0
  89. data/lib/metanorma/html/standard_renderer.rb +198 -36
  90. data/lib/metanorma/html.rb +4 -51
  91. data/lib/metanorma/iso_document/sections/iso_preface.rb +27 -13
  92. data/lib/metanorma/mirror/default_registry.rb +21 -0
  93. data/lib/metanorma/mirror/handlers/inline/catalog.rb +52 -0
  94. data/lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb +34 -35
  95. data/lib/metanorma/mirror/handlers/inline.rb +1 -0
  96. data/lib/metanorma/mirror/handlers/sourcecode.rb +1 -1
  97. data/lib/metanorma/mirror/model/guide.rb +3 -2
  98. data/lib/metanorma/mirror/output/formats/inline_format.rb +64 -3
  99. data/lib/metanorma/mirror/output/pipeline.rb +1 -0
  100. data/lib/metanorma/mirror/output.rb +0 -2
  101. data/lib/metanorma/mirror/rewriter.rb +3 -1
  102. data/lib/metanorma/mirror/transformer.rb +91 -3
  103. data/lib/metanorma/mirror.rb +0 -1
  104. data/lib/metanorma/registers/setup.rb +10 -0
  105. data/lib/metanorma/standard_document/annotation_container.rb +2 -0
  106. data/lib/metanorma/standard_document/elements/input.rb +4 -25
  107. data/lib/metanorma/standard_document/metadata/metanorma_extension.rb +12 -2
  108. data/lib/metanorma/standard_document/metadata/presentation_metadata.rb +107 -0
  109. data/lib/metanorma/standard_document/metadata/semantic_metadata.rb +18 -0
  110. data/lib/metanorma/standard_document/metadata/unitsml/amount_of_substance.rb +19 -0
  111. data/lib/metanorma/standard_document/metadata/unitsml/base_quantity.rb +34 -0
  112. data/lib/metanorma/standard_document/metadata/unitsml/dimension.rb +39 -0
  113. data/lib/metanorma/standard_document/metadata/unitsml/dimension_set.rb +19 -0
  114. data/lib/metanorma/standard_document/metadata/unitsml/electric_current.rb +19 -0
  115. data/lib/metanorma/standard_document/metadata/unitsml/enumerated_root_unit.rb +23 -0
  116. data/lib/metanorma/standard_document/metadata/unitsml/length.rb +19 -0
  117. data/lib/metanorma/standard_document/metadata/unitsml/luminous_intensity.rb +19 -0
  118. data/lib/metanorma/standard_document/metadata/unitsml/mass.rb +19 -0
  119. data/lib/metanorma/standard_document/metadata/unitsml/namespace.rb +17 -0
  120. data/lib/metanorma/standard_document/metadata/unitsml/plane_angle.rb +19 -0
  121. data/lib/metanorma/standard_document/metadata/unitsml/prefix.rb +30 -0
  122. data/lib/metanorma/standard_document/metadata/unitsml/prefix_name.rb +21 -0
  123. data/lib/metanorma/standard_document/metadata/unitsml/prefix_set.rb +19 -0
  124. data/lib/metanorma/standard_document/metadata/unitsml/prefix_symbol.rb +21 -0
  125. data/lib/metanorma/standard_document/metadata/unitsml/quantity.rb +28 -0
  126. data/lib/metanorma/standard_document/metadata/unitsml/quantity_name.rb +21 -0
  127. data/lib/metanorma/standard_document/metadata/unitsml/quantity_set.rb +19 -0
  128. data/lib/metanorma/standard_document/metadata/unitsml/root_units.rb +19 -0
  129. data/lib/metanorma/standard_document/metadata/unitsml/thermodynamic_temperature.rb +19 -0
  130. data/lib/metanorma/standard_document/metadata/unitsml/time.rb +19 -0
  131. data/lib/metanorma/standard_document/metadata/unitsml/unit.rb +32 -0
  132. data/lib/metanorma/standard_document/metadata/unitsml/unit_name.rb +21 -0
  133. data/lib/metanorma/standard_document/metadata/unitsml/unit_set.rb +19 -0
  134. data/lib/metanorma/standard_document/metadata/unitsml/unit_symbol.rb +36 -0
  135. data/lib/metanorma/standard_document/metadata/unitsml/unit_system.rb +23 -0
  136. data/lib/metanorma/standard_document/metadata/unitsml/unitsml_root.rb +28 -0
  137. data/lib/metanorma/standard_document/metadata/unitsml.rb +39 -0
  138. data/lib/metanorma/standard_document/metadata.rb +4 -0
  139. data/lib/metanorma/standard_document/sections/misc_container.rb +8 -6
  140. data/lib/metanorma/standard_document/sections/sections.rb +7 -0
  141. data/lib/metanorma/un_document/blocks/un_admonition_block.rb +86 -0
  142. data/lib/metanorma/un_document/blocks.rb +9 -0
  143. data/lib/metanorma/un_document/root.rb +8 -0
  144. data/lib/metanorma/un_document/sections/un_abstract_section.rb +48 -0
  145. data/lib/metanorma/un_document/sections/un_preface.rb +19 -2
  146. data/lib/metanorma/un_document/sections.rb +1 -0
  147. data/lib/metanorma/un_document/un_text_element.rb +116 -0
  148. data/lib/metanorma/un_document.rb +2 -0
  149. data/script/benchmark_render.rb +35 -0
  150. data/tasks/roundtrip_samples.rake +1 -1
  151. metadata +78 -50
  152. data/.rubocop_todo.yml +0 -327
  153. data/TODO.finalize/01-split-multi-class-files.md +0 -8
  154. data/TODO.finalize/02-remove-data-dist-iso-document-frontend.md +0 -6
  155. data/TODO.finalize/03-align-frontend-iife-and-gha-build.md +0 -11
  156. data/TODO.finalize/04-theme-per-flavor-config-driven.md +0 -9
  157. data/TODO.finalize/05-migrate-all-html-to-liquid.md +0 -16
  158. data/TODO.finalize/06-integrate-pubid-library.md +0 -16
  159. data/TODO.finalize/07-replace-relaton-models-with-relaton-bib.md +0 -39
  160. data/TODO.finalize/08-refactor-renderer-architecture.md +0 -25
  161. data/TODO.finalize/09-eliminate-code-smells.md +0 -14
  162. data/TODO.finalize/10-comprehensive-spec-coverage.md +0 -24
  163. data/TODO.finalize/11-config-driven-flavor-metadata.md +0 -20
  164. data/TODO.finalize/12-add-frozen-string-literal.md +0 -6
  165. data/TODO.finalize/13-extract-composition-from-god-class.md +0 -96
  166. data/TODO.finalize/14-config-driven-section-ordering.md +0 -31
  167. data/TODO.finalize/15-theme-directories-per-flavor.md +0 -46
  168. data/TODO.finalize/16-theme-lutaml-model-schema.md +0 -44
  169. data/docs/html-renderer.adoc +0 -261
  170. data/lib/data/dist/iso_document/frontend/assets/index-mwzbzmnK.js +0 -22
  171. data/lib/data/dist/iso_document/frontend/assets/index-pGvKTNid.css +0 -1
  172. data/lib/data/dist/iso_document/frontend/assets/iso-red.svg +0 -53
  173. data/lib/data/dist/iso_document/frontend/index.html +0 -13
  174. data/lib/metanorma/document/relaton/bib_item_size_type.rb +0 -21
  175. data/lib/metanorma/document/relaton/bibliographic_date_type.rb +0 -22
  176. data/lib/metanorma/document/relaton/document_relation_type.rb +0 -31
  177. data/lib/metanorma/document/relaton/iso4217_code.rb +0 -17
  178. data/lib/metanorma/document/relaton/iso8601_date.rb +0 -17
  179. data/lib/metanorma/document/relaton/personal_identifier_type.rb +0 -21
  180. data/lib/metanorma/document/relaton/region_type.rb +0 -20
  181. data/lib/metanorma/document/relaton/series_type_type.rb +0 -21
  182. data/lib/metanorma/document/relaton/specific_locality_type.rb +0 -25
  183. data/lib/metanorma/document/relaton/title_type.rb +0 -21
  184. data/lib/metanorma/mirror/metanorma_to_mirror.rb +0 -101
  185. data/lib/metanorma/mirror/output/html_renderer.rb +0 -95
  186. data/lib/metanorma/mirror/output/html_renderers/block_renderers.rb +0 -178
  187. data/lib/metanorma/mirror/output/html_renderers/inline_renderer.rb +0 -61
  188. data/lib/metanorma/mirror/output/html_renderers/list_renderers.rb +0 -96
  189. data/lib/metanorma/mirror/output/html_renderers/mark_renderers.rb +0 -64
  190. data/lib/metanorma/mirror/output/html_renderers/section_renderers.rb +0 -129
  191. data/lib/metanorma/mirror/output/html_renderers/structural_renderers.rb +0 -80
  192. data/lib/metanorma/mirror/output/html_renderers/table_renderers.rb +0 -87
  193. data/lib/metanorma/mirror/output/html_renderers.rb +0 -76
  194. data/lib/metanorma/standard_document/annotation.rb +0 -37
data/.rubocop_todo.yml DELETED
@@ -1,327 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2026-07-17 09:09:03 UTC using RuboCop version 1.86.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 1
10
- Gemspec/RequiredRubyVersion:
11
- Exclude:
12
- - 'metanorma-document.gemspec'
13
-
14
- # Offense count: 2
15
- # This cop supports safe autocorrection (--autocorrect).
16
- # Configuration parameters: EnforcedStyle, IndentationWidth.
17
- # SupportedStyles: with_first_argument, with_fixed_indentation
18
- Layout/ArgumentAlignment:
19
- Exclude:
20
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
21
-
22
- # Offense count: 2
23
- # This cop supports safe autocorrection (--autocorrect).
24
- # Configuration parameters: EnforcedStyle, IndentationWidth.
25
- # SupportedStyles: with_first_element, with_fixed_indentation
26
- Layout/ArrayAlignment:
27
- Exclude:
28
- - 'spec/metanorma/document/components/inline/span_element_bug01_spec.rb'
29
-
30
- # Offense count: 1
31
- # This cop supports safe autocorrection (--autocorrect).
32
- # Configuration parameters: EnforcedStyleAlignWith.
33
- # SupportedStylesAlignWith: either, start_of_block, start_of_line
34
- Layout/BlockAlignment:
35
- Exclude:
36
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
37
-
38
- # Offense count: 1
39
- # This cop supports safe autocorrection (--autocorrect).
40
- Layout/BlockEndNewline:
41
- Exclude:
42
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
43
-
44
- # Offense count: 2
45
- # This cop supports safe autocorrection (--autocorrect).
46
- # Configuration parameters: EnforcedStyle, IndentationWidth.
47
- # SupportedStyles: special_inside_parentheses, consistent, align_brackets
48
- Layout/FirstArrayElementIndentation:
49
- Exclude:
50
- - 'spec/metanorma/document/components/inline/span_element_bug01_spec.rb'
51
-
52
- # Offense count: 2
53
- # This cop supports safe autocorrection (--autocorrect).
54
- # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
55
- # SupportedStylesAlignWith: start_of_line, relative_to_receiver
56
- Layout/IndentationWidth:
57
- Exclude:
58
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
59
-
60
- # Offense count: 700
61
- # This cop supports safe autocorrection (--autocorrect).
62
- # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
63
- # URISchemes: http, https
64
- Layout/LineLength:
65
- Enabled: false
66
-
67
- # Offense count: 1
68
- # This cop supports safe autocorrection (--autocorrect).
69
- # Configuration parameters: EnforcedStyle, IndentationWidth.
70
- # SupportedStyles: aligned, indented, indented_relative_to_receiver
71
- Layout/MultilineMethodCallIndentation:
72
- Exclude:
73
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
74
-
75
- # Offense count: 2
76
- # Configuration parameters: AllowedMethods.
77
- # AllowedMethods: enums
78
- Lint/ConstantDefinitionInBlock:
79
- Exclude:
80
- - 'spec/metanorma/html/renderer/class_ownership_spec.rb'
81
- - 'spec/metanorma/html/renderer/liquid_templates_spec.rb'
82
-
83
- # Offense count: 3
84
- # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
85
- Lint/DuplicateBranch:
86
- Exclude:
87
- - 'lib/metanorma/html/base_renderer.rb'
88
- - 'lib/metanorma/html/renderers/inline_renderer.rb'
89
- - 'lib/metanorma/html/standard_renderer.rb'
90
-
91
- # Offense count: 2
92
- # Configuration parameters: AllowComments, AllowEmptyLambdas.
93
- Lint/EmptyBlock:
94
- Exclude:
95
- - 'spec/metanorma/iso_document/metadata/title_roundtrip_spec.rb'
96
-
97
- # Offense count: 4
98
- # Configuration parameters: AllowedParentClasses.
99
- Lint/MissingSuper:
100
- Exclude:
101
- - 'lib/metanorma/html/drops/figure_drop.rb'
102
- - 'lib/metanorma/html/drops/formula_drop.rb'
103
- - 'lib/metanorma/html/drops/sourcecode_drop.rb'
104
- - 'lib/metanorma/mirror/id_strategy/positional.rb'
105
-
106
- # Offense count: 1
107
- Lint/StructNewOverride:
108
- Exclude:
109
- - 'lib/metanorma/html/component/index_term_collector.rb'
110
-
111
- # Offense count: 23
112
- # This cop supports safe autocorrection (--autocorrect).
113
- # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
114
- # NotImplementedExceptions: NotImplementedError
115
- Lint/UnusedMethodArgument:
116
- Exclude:
117
- - 'lib/metanorma/mirror/handlers/formula.rb'
118
- - 'lib/metanorma/mirror/handlers/sourcecode.rb'
119
- - 'lib/metanorma/mirror/output/html_renderers/block_renderers.rb'
120
- - 'lib/metanorma/mirror/output/html_renderers/list_renderers.rb'
121
- - 'lib/metanorma/mirror/output/html_renderers/section_renderers.rb'
122
- - 'lib/metanorma/mirror/output/html_renderers/structural_renderers.rb'
123
- - 'lib/metanorma/mirror/output/html_renderers/table_renderers.rb'
124
- - 'spec/metanorma/mirror/handler_registry_spec.rb'
125
- - 'spec/metanorma/mirror/html_renderer_spec.rb'
126
-
127
- # Offense count: 114
128
- # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
129
- Metrics/AbcSize:
130
- Enabled: false
131
-
132
- # Offense count: 11
133
- # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
134
- # AllowedMethods: refine
135
- Metrics/BlockLength:
136
- Max: 47
137
-
138
- # Offense count: 3
139
- # Configuration parameters: CountBlocks, CountModifierForms.
140
- Metrics/BlockNesting:
141
- Max: 4
142
-
143
- # Offense count: 86
144
- # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
145
- Metrics/CyclomaticComplexity:
146
- Enabled: false
147
-
148
- # Offense count: 149
149
- # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
150
- Metrics/MethodLength:
151
- Max: 102
152
-
153
- # Offense count: 3
154
- # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
155
- Metrics/ParameterLists:
156
- Max: 7
157
-
158
- # Offense count: 69
159
- # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
160
- Metrics/PerceivedComplexity:
161
- Enabled: false
162
-
163
- # Offense count: 52
164
- # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
165
- # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
166
- Naming/MethodParameterName:
167
- Exclude:
168
- - 'lib/metanorma/html/base_renderer.rb'
169
- - 'lib/metanorma/html/component/footnote_collector.rb'
170
- - 'lib/metanorma/html/drops/sourcecode_drop.rb'
171
- - 'lib/metanorma/html/iso_renderer.rb'
172
- - 'lib/metanorma/html/renderers/block_renderer.rb'
173
- - 'lib/metanorma/html/renderers/inline_renderer.rb'
174
- - 'spec/metanorma/html/renderer/footnote_collector_spec.rb'
175
-
176
- # Offense count: 4
177
- # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
178
- # AllowedMethods: call
179
- # WaywardPredicates: infinite?, nonzero?
180
- Naming/PredicateMethod:
181
- Exclude:
182
- - 'lib/metanorma/html/base_renderer.rb'
183
- - 'lib/metanorma/html/drops/biblio_entry_drop.rb'
184
- - 'lib/metanorma/html/renderers/inline_renderer.rb'
185
-
186
- # Offense count: 3
187
- # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
188
- # NamePrefix: is_, has_, have_, does_
189
- # ForbiddenPrefixes: is_, has_, have_, does_
190
- # AllowedMethods: is_a?
191
- # MethodDefinitionMacros: define_method, define_singleton_method
192
- Naming/PredicatePrefix:
193
- Exclude:
194
- - 'spec/**/*'
195
- - 'lib/metanorma/html/base_renderer.rb'
196
- - 'lib/metanorma/html/drops/biblio_entry_drop.rb'
197
-
198
- # Offense count: 1
199
- # Configuration parameters: MinSize.
200
- Performance/CollectionLiteralInLoop:
201
- Exclude:
202
- - 'lib/metanorma/html/standard_renderer.rb'
203
-
204
- # Offense count: 1
205
- Performance/MapMethodChain:
206
- Exclude:
207
- - 'spec/metanorma/flavor_roots/flavor_roots_spec.rb'
208
-
209
- # Offense count: 1
210
- # This cop supports unsafe autocorrection (--autocorrect-all).
211
- # Configuration parameters: AllowRegexpMatch.
212
- Performance/RedundantEqualityComparisonBlock:
213
- Exclude:
214
- - 'spec/metanorma/document/components/inline/fmt_stem_element_bug03_spec.rb'
215
-
216
- # Offense count: 7
217
- RSpec/BeforeAfterAll:
218
- Exclude:
219
- - '**/spec/spec_helper.rb'
220
- - '**/spec/rails_helper.rb'
221
- - '**/spec/support/**/*.rb'
222
- - 'spec/metanorma/flavor_roots/flavor_roots_spec.rb'
223
-
224
- # Offense count: 14
225
- # Configuration parameters: Prefixes, AllowedPatterns.
226
- # Prefixes: when, with, without
227
- RSpec/ContextWording:
228
- Exclude:
229
- - 'spec/metanorma/html/renderer/theme_spec.rb'
230
- - 'spec/metanorma/mirror/html_renderer_spec.rb'
231
-
232
- # Offense count: 32
233
- # Configuration parameters: IgnoredMetadata.
234
- RSpec/DescribeClass:
235
- Enabled: false
236
-
237
- # Offense count: 8
238
- # This cop supports unsafe autocorrection (--autocorrect-all).
239
- # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
240
- # SupportedStyles: described_class, explicit
241
- RSpec/DescribedClass:
242
- Exclude:
243
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
244
- - 'spec/metanorma/document/components/inline/xref_element_bug04_spec.rb'
245
-
246
- # Offense count: 234
247
- # Configuration parameters: CountAsOne.
248
- RSpec/ExampleLength:
249
- Max: 37
250
-
251
- # Offense count: 2
252
- RSpec/LeakyConstantDeclaration:
253
- Exclude:
254
- - 'spec/metanorma/html/renderer/class_ownership_spec.rb'
255
- - 'spec/metanorma/html/renderer/liquid_templates_spec.rb'
256
-
257
- # Offense count: 4
258
- RSpec/MultipleDescribes:
259
- Exclude:
260
- - 'spec/metanorma/document_spec.rb'
261
- - 'spec/metanorma/mirror/handlers/remaining_handlers_spec.rb'
262
- - 'spec/metanorma/mirror/serialization_spec.rb'
263
- - 'spec/metanorma/standard_document/sections_spec.rb'
264
-
265
- # Offense count: 1
266
- # Configuration parameters: AllowSubject.
267
- RSpec/MultipleMemoizedHelpers:
268
- Max: 7
269
-
270
- # Offense count: 30
271
- # Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
272
- # SupportedStyles: always, named_only
273
- RSpec/NamedSubject:
274
- Exclude:
275
- - 'spec/metanorma/flavor_roots/flavor_roots_spec.rb'
276
-
277
- # Offense count: 1061
278
- # Configuration parameters: AllowedPatterns.
279
- # AllowedPatterns: ^expect_, ^assert_
280
- RSpec/NoExpectationExample:
281
- Enabled: false
282
-
283
- # Offense count: 29
284
- # Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
285
- # SupportedInflectors: default, active_support
286
- RSpec/SpecFilePathFormat:
287
- Enabled: false
288
-
289
- # Offense count: 1
290
- # This cop supports safe autocorrection (--autocorrect).
291
- # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
292
- # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
293
- # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
294
- # FunctionalMethods: let, let!, subject, watch
295
- # AllowedMethods: lambda, proc, it
296
- Style/BlockDelimiters:
297
- Exclude:
298
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
299
-
300
- # Offense count: 5
301
- # This cop supports safe autocorrection (--autocorrect).
302
- Style/ComparableClamp:
303
- Exclude:
304
- - 'lib/metanorma/html/iso_renderer.rb'
305
- - 'lib/metanorma/html/renderers/section_renderer.rb'
306
- - 'lib/metanorma/html/standard_renderer.rb'
307
-
308
- # Offense count: 1
309
- # This cop supports unsafe autocorrection (--autocorrect-all).
310
- Style/PredicateWithKind:
311
- Exclude:
312
- - 'spec/metanorma/document/components/inline/fmt_stem_element_bug03_spec.rb'
313
-
314
- # Offense count: 2
315
- # This cop supports unsafe autocorrection (--autocorrect-all).
316
- Style/SelectByKind:
317
- Exclude:
318
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
319
-
320
- # Offense count: 3
321
- # This cop supports safe autocorrection (--autocorrect).
322
- # Configuration parameters: EnforcedStyleForMultiline.
323
- # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
324
- Style/TrailingCommaInArguments:
325
- Exclude:
326
- - 'spec/metanorma/document/components/inline/semantic_content_bug05_spec.rb'
327
- - 'spec/metanorma/document/components/inline/xref_element_bug04_spec.rb'
@@ -1,8 +0,0 @@
1
- # 01 — Split multi-class files into one-class-per-file — DONE
2
-
3
- All model files now contain exactly one class per file. Verified: every file under `lib/metanorma/document/`, `lib/metanorma/standard_document/`, `lib/metanorma/iso_document/`, `lib/metanorma/bipm_document/`, `lib/metanorma/itu_document/`, `lib/metanorma/ietf_document/`, `lib/metanorma/cc_document/` is single-class.
4
-
5
- Nested classes that are only used internally by their parent (e.g. `AnnotationContainer::Annotation`) are legitimate and NOT split.
6
-
7
- ## Code quality requirements
8
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,6 +0,0 @@
1
- # 02 — Remove misplaced `data/dist/iso_document/frontend/` artifacts — DONE
2
-
3
- `data/dist/iso_document/frontend/` directory no longer exists. Frontend build artifacts are correctly placed in `frontend/dist/` and included in gemspec via `Dir.glob("frontend/dist/*")`.
4
-
5
- ## Code quality requirements
6
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,11 +0,0 @@
1
- # 03 — Align frontend IIFE build and GHA gem release with docbook pattern — DONE
2
-
3
- Aligned with docbook project:
4
- - `Rakefile` has `build_frontend` task + release hook
5
- - `gemspec` includes `frontend/dist/*`
6
- - `.github/workflows/rake.yml` has `after-setup-ruby: cd frontend && npm install && npm run build`
7
- - `frontend/vite.config.ts` produces `app.iife.js` + `app.css`
8
- - `.gitignore` has `frontend/node_modules/` and `frontend/dist/`
9
-
10
- ## Code quality requirements
11
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,9 +0,0 @@
1
- # 04 — Data-centric theme system: config files per flavor — DONE
2
-
3
- All 13 flavor themes extracted to `data/themes/{flavor}.yaml`. `Theme.load(:iso)` reads YAML and applies overrides. BaseRenderer provides default `Theme.new`. Every flavor renderer uses `Theme.load(:flavor_name)`.
4
-
5
- ### Remaining enhancement
6
- Publisher metadata (publishers, publisher_name, logo_map, font_url) still hardcoded in flavor renderers. These should move into theme YAML config so flavor renderers can be auto-generated from config alone.
7
-
8
- ## Code quality requirements
9
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,16 +0,0 @@
1
- # 05 — Migrate all HTML generation to Liquid templates — DONE
2
-
3
- All HTML element generation uses Liquid templates. Zero raw HTML string injection via `@output <<` remains. The `tag()` helper has been removed from `base_renderer.rb`. All remaining `@output <<` calls are text streaming (`escape_html`, whitespace, raw content passthrough) — not HTML element generation.
4
-
5
- 32+ Liquid templates exist in `lib/metanorma/html/templates/`. The generic `_element.html.liquid` handles most tag wrapping. Specialized templates exist for tables, lists, figures, headings, math, links, etc.
6
-
7
- ### OOP Liquid pattern
8
- All rendering uses the `capture_output` + `render_liquid` pattern:
9
- 1. Capture child content into a Ruby string via `capture_output`
10
- 2. Pass captured content to `render_liquid("_template.html.liquid", assigns)`
11
- 3. Result is appended to `@output` by the caller
12
-
13
- Drop classes (`Drops::*`) are used for complex objects that need pre-rendered HTML fields (e.g. `BiblioEntryDrop`, `FigureDrop`).
14
-
15
- ## Code quality requirements
16
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,16 +0,0 @@
1
- # 06 — Integrate pubid library for publication identifier handling — DONE
2
-
3
- ## What was done
4
- 1. Added `pubid ~> 2.0` to gemspec dependency
5
- 2. Added `gem "pubid", path: "../../mn/pubid"` to Gemfile for local dev
6
- 3. Created `lib/metanorma/html/concerns/pubid_rendering.rb` — `PubidRendering` module with:
7
- - `FLAVOR_PUBID_MAP` mapping document class names to pubid modules
8
- - `parse_pubid(docidentifier_string)` — flavor-aware pubid parsing
9
- - `pubid_to_html(identifier)` — renders to semantic HTML with CSS classes
10
- - `resolve_pubid_module` — auto-detects flavor from renderer class
11
- 4. Wired into `BaseRenderer` via `include PubidRendering`
12
- 5. Refactored `render_bibitem_content` in `standard_renderer.rb` to try pubid first
13
- 6. Created specs in `pubid_rendering_spec.rb`
14
-
15
- ## Code quality requirements
16
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,39 +0,0 @@
1
- # 07 — Integrate relaton-bib library (partially complete)
2
-
3
- ## Status
4
- - **Done**: relaton-bib dependency added, 4 models replaced via inheritance, `require` at module level
5
- - **Blocked**: Most models have incompatible XML schemas (different attribute names/types, different XML mappings)
6
-
7
- ## What was done
8
- 1. Added `relaton-bib ~> 2.1` to gemspec dependency
9
- 2. Added `require "relaton/bib"` to `lib/metanorma/document/relaton.rb`
10
- 3. Replaced 4 models with inheritance from relaton-bib:
11
- - `Phone` < `::Relaton::Bib::Phone` (exact match)
12
- - `PriceType` < `::Relaton::Bib::Price` (exact match)
13
- - `BibItemLocality` < `::Relaton::Bib::Locality` (exact match)
14
- - `Edition` < `::Relaton::Bib::Edition` (inherits + adds `language` attribute)
15
-
16
- ## Why most models can't be directly replaced
17
- The 53 relaton models in our project have different XML schemas from relaton-bib's models:
18
-
19
- | Difference | Our models | relaton-bib |
20
- |---|---|---|
21
- | Attribute names | `on` (BibliographicDate), `bib_locality` (LocalityStack), `validity_begins` (ValidityType) | `at`, `locality`, `begins` |
22
- | Attribute types | `Components::DataTypes::*` throughout | `LocalizedString`, `LocalizedMarkedUpString` |
23
- | XML mapping | `map_attribute` for medium, `map_all_content` for logo | `map_element` for medium, `map_element "image"` for logo |
24
- | Extra attributes | `language` on Edition, `id` on DocumentIdentifier, `stage_abbreviation` on DocumentStatus | Not present |
25
- | Mixed content | Used in TypedTitleString (em/fn/stem/strong/sub/sup/tt/variant) | Plain content |
26
- | Model nesting | `CopyrightOwner` wraps `Organization` | `Contributor` as owner |
27
-
28
- A full replacement requires updating all 86 consuming references and adapting to relaton-bib's API. This is a separate project-level migration.
29
-
30
- ## Remaining work for full migration
31
- 1. Update consuming code (86 references) to use relaton-bib attribute names
32
- 2. For models with extra attributes: inherit from relaton-bib and add extras
33
- 3. For models with structural differences: create adapter classes
34
- 4. Remove `lib/metanorma/document/relaton/` once fully migrated
35
- 5. Update autoload configuration
36
- 6. Integration specs for relaton-bib model usage
37
-
38
- ## Code quality requirements
39
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,25 +0,0 @@
1
- # 08 — Refactor renderer architecture for OCP and DRY — DONE
2
-
3
- ### Completed decomposition (Phase 1)
4
- BaseRenderer originally included three concern modules:
5
- - `InlineRendering` (~590 lines, 39 methods)
6
- - `BlockRendering` (~295 lines, 24 methods)
7
- - `SectionRendering` (~90 lines, 8 methods)
8
-
9
- ### Completed composition (Phase 2 — TODO 13)
10
- Module includes replaced with composition. Each module became a standalone class:
11
- - `Renderers::InlineRenderer` at `lib/metanorma/html/renderers/inline_renderer.rb`
12
- - `Renderers::BlockRenderer` at `lib/metanorma/html/renderers/block_renderer.rb`
13
- - `Renderers::SectionRenderer` at `lib/metanorma/html/renderers/section_renderer.rb`
14
- - `Renderers::PubidRenderer` at `lib/metanorma/html/renderers/pubid_renderer.rb`
15
-
16
- BaseRenderer is now a thin coordinator with delegation wrappers for backward compatibility.
17
- Old concern modules at `lib/metanorma/html/concerns/` are no longer referenced and can be removed.
18
-
19
- ### Remaining enhancements
20
- - Publisher metadata (flavor_publishers, flavor_publisher_name, publisher_logo_map) duplicated across 12+ flavor renderers. See TODO 11 for config-driven migration.
21
- - Config-driven section ordering. See TODO 14.
22
- - Theme directories per flavor. See TODO 15.
23
-
24
- ## Code quality requirements
25
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,14 +0,0 @@
1
- # 09 — Eliminate code smells and enforce project constraints — DONE
2
-
3
- ## Fixed
4
- - `respond_to?` duck-typing eliminated from inline_rendering.rb (replaced with `is_a?`)
5
- - `tag()` helper removed from base_renderer (replaced with Liquid `_element.html.liquid`)
6
- - All `@output <<` raw HTML generation eliminated
7
- - `method_missing` + `respond_to_missing?` eliminated from RendererContext (replaced with explicit `def` methods)
8
- - `public_send(attr)` in boilerplate_to_xml replaced with explicit `collect_boilerplate_part` helper
9
- - `public_send(setter)` in Theme.load is acceptable — setter list validated via `VALID_KEYS`/`SETTERS` constants
10
- - `instance_variable_get`/`instance_variable_set` eliminated from Drops and Component::Base (replaced with `OutputProxy` wrapper)
11
- - `# frozen_string_literal: true` added to all 48 inline component files
12
-
13
- ## Code quality requirements
14
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,24 +0,0 @@
1
- # 10 — Comprehensive spec coverage for HTML rendering pipeline — DONE
2
-
3
- ## Status
4
- All HTML renderer specs use real model instances (zero doubles). Coverage spans theme loading, config-driven ordering, composition, pubid, metadata, CSS generation, and Liquid templates.
5
-
6
- ## Spec count
7
- - Current: 159+ examples passing (0 failures) — ~40 pre-existing moxml failures excluded (upstream lutaml-model issue)
8
-
9
- ## Spec files
10
- 1. `theme_spec.rb` — 111 specs: defaults, all 13 flavor loading, publisher metadata, directory-based themes, lutaml-model schema validation
11
- 2. `config_metadata_spec.rb` — 8 specs: theme auto-resolution, publisher/logo config from YAML
12
- 3. `config_preface_spec.rb` — 8 specs: config-driven preface ordering (ordered mode, wrapped mode, clause filtering, delegation) using real IsoPreface models
13
- 4. `composition_spec.rb` — 10 specs: sub-renderer composition, delegation wrappers, theme resolution using real IsoClauseSection models
14
- 5. `pubid_rendering_spec.rb` — 3 specs: pubid parsing and HTML generation via composition using real IsoDocument::Root
15
- 6. `base_renderer_spec.rb` — 19 specs: escape_html, element_attrs, utility methods
16
- 7. `liquid_templates_spec.rb` — 62 specs: all 48 templates + 12 individual template tests
17
- 8. `relaton_bib_spec.rb` — relaton-bib model inheritance verification
18
-
19
- ## Key decisions
20
- - **Zero doubles**: All specs use real lutaml-model instances (IsoPreface, IsoClauseSection, IsoForewordSection, IsoDocument::Root, Theme)
21
- - **Zero instance_variable_set**: Only used in pubid_rendering_spec for setting @document (coordinator's required state) — acceptable for test setup
22
-
23
- ## Code quality requirements
24
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. Never use private send methods (breaks encapsulation), instance_variable_set/get, never use respond_to? (poor typing). NEVER use RSpec doubles — use real model instances.
@@ -1,20 +0,0 @@
1
- # 11 — Config-driven flavor metadata: eliminate boilerplate renderers — DONE
2
-
3
- ## What was done
4
- All 13 theme YAML files contain publisher metadata:
5
- ```yaml
6
- publishers:
7
- - "ISO"
8
- publisher_name: "ISO"
9
- logos:
10
- "ISO": "iso-logo.svg"
11
- ```
12
-
13
- BaseRenderer reads publishers/logos from theme via `theme.publishers`, `theme.publisher_name`, `theme.logos`. No renderer code overrides these.
14
-
15
- 10 flavor renderers are empty shells (0 methods, just inherit IsoRenderer). They exist because `Generator` maps document classes to renderer classes, but all customization comes from theme YAML config.
16
-
17
- Theme auto-resolves from document type via `FLAVOR_MAP` — no manual `theme` override needed in any renderer.
18
-
19
- ## Code quality requirements
20
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,6 +0,0 @@
1
- # 12 — Add frozen_string_literal to all Ruby files — DONE
2
-
3
- All `lib/` and `spec/` Ruby files already have `# frozen_string_literal: true` on line 1. No changes needed.
4
-
5
- ## Code quality requirements
6
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
@@ -1,96 +0,0 @@
1
- # 13 — Extract module includes into composition — DONE
2
-
3
- ## Problem
4
- BaseRenderer is a God class with 180+ public methods from 4 mixed-in modules:
5
- - `InlineRendering` (~590 lines, 39 methods)
6
- - `BlockRendering` (~295 lines, 24 methods)
7
- - `SectionRendering` (~90 lines, 8 methods)
8
- - `PubidRendering` (~55 lines, 2 methods)
9
-
10
- Module includes break OCP and encapsulation — all module methods become public on the single class, making it impossible to reason about responsibilities in isolation.
11
-
12
- ## Architecture
13
-
14
- Replace `include` with composition. Each module becomes a standalone class that receives a reference to the coordinator for cross-concern calls:
15
-
16
- ```
17
- BaseRenderer (coordinator, ~50 methods)
18
- ├── InlineRenderer (inline elements, 39 methods)
19
- ├── BlockRenderer (block elements, 24 methods)
20
- ├── SectionRenderer (sections, 8 methods)
21
- └── PubidRenderer (pubid parsing, 2 methods)
22
- ```
23
-
24
- ### Cross-concern dependencies (one-way, clean extraction)
25
-
26
- InlineRenderer needs from coordinator:
27
- - `escape_html`, `safe_attr`, `element_attrs`, `capture_output`, `render_liquid`
28
- - `render_paragraph`, `render_inline_element` (recursive dispatch)
29
- - `@output`, `@footnote_collector`, `@index_term_collector`
30
-
31
- BlockRenderer needs from coordinator:
32
- - `escape_html`, `safe_attr`, `element_attrs`, `capture_output`, `render_liquid`
33
- - `render_mixed_inline`, `render_inline_element`, `render_mixed_content_in_order`
34
- - `walk_ordered`, `block_element?`, `render` (recursive dispatch)
35
- - `@output`, `renderer_context`
36
-
37
- SectionRenderer needs from coordinator:
38
- - `escape_html`, `safe_attr`, `element_attrs`, `capture_output`, `render_liquid`
39
- - `walk_ordered`, `render`, `render_note`, `extract_plain_text`
40
- - `@output`
41
-
42
- PubidRenderer needs from coordinator:
43
- - `escape_html`, `flavor_name`
44
-
45
- ### Implementation plan
46
-
47
- 1. Create `InlineRenderer` class at `lib/metanorma/html/renderers/inline_renderer.rb`
48
- - Receives `coordinator` in constructor
49
- - Moves all methods from `InlineRendering` module
50
- - Delegates shared utility calls to coordinator
51
- 2. Create `BlockRenderer` class at `lib/metanorma/html/renderers/block_renderer.rb`
52
- - Same pattern
53
- 3. Create `SectionRenderer` class at `lib/metanorma/html/renderers/section_renderer.rb`
54
- - Same pattern
55
- 4. Create `PubidRenderer` class at `lib/metanorma/html/renderers/pubid_renderer.rb`
56
- - Same pattern
57
- 5. Update `BaseRenderer` to instantiate sub-renderers and delegate
58
- 6. Update `RendererContext` to delegate through coordinator's sub-renderers
59
- 7. Update all flavor renderers (IsoRenderer, StandardRenderer, etc.) for new API
60
- 8. Update all Drop classes that call `renderer.method_name`
61
- 9. Ensure all existing specs pass
62
-
63
- ### Delegation pattern
64
-
65
- ```ruby
66
- class BaseRenderer
67
- attr_reader :inline_renderer, :block_renderer, :section_renderer, :pubid_renderer
68
-
69
- def initialize
70
- @inline_renderer = InlineRenderer.new(self)
71
- @block_renderer = BlockRenderer.new(self)
72
- @section_renderer = SectionRenderer.new(self)
73
- @pubid_renderer = PubidRenderer.new(self)
74
- # ...
75
- end
76
-
77
- # Delegate for backward compatibility during migration
78
- def render_paragraph(...) = @block_renderer.render_paragraph(...)
79
- def render_em(...) = @inline_renderer.render_em(...)
80
- # etc.
81
- end
82
- ```
83
-
84
- ### Flavor renderers
85
-
86
- Sub-renderers can be extended per flavor:
87
- ```ruby
88
- class IsoSectionRenderer < SectionRenderer
89
- def render_preface(preface, **)
90
- # ISO-specific preface ordering
91
- end
92
- end
93
- ```
94
-
95
- ## Code quality requirements
96
- Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).