metanorma-document 0.2.9 → 0.2.12

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 (390) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +164 -66
  3. data/CLAUDE.md +26 -0
  4. data/README.adoc +144 -0
  5. data/Rakefile +14 -2
  6. data/TODO.finalize/01-split-multi-class-files.md +8 -0
  7. data/TODO.finalize/02-remove-data-dist-iso-document-frontend.md +6 -0
  8. data/TODO.finalize/03-align-frontend-iife-and-gha-build.md +11 -0
  9. data/TODO.finalize/04-theme-per-flavor-config-driven.md +9 -0
  10. data/TODO.finalize/05-migrate-all-html-to-liquid.md +16 -0
  11. data/TODO.finalize/06-integrate-pubid-library.md +16 -0
  12. data/TODO.finalize/07-replace-relaton-models-with-relaton-bib.md +39 -0
  13. data/TODO.finalize/08-refactor-renderer-architecture.md +25 -0
  14. data/TODO.finalize/09-eliminate-code-smells.md +14 -0
  15. data/TODO.finalize/10-comprehensive-spec-coverage.md +24 -0
  16. data/TODO.finalize/11-config-driven-flavor-metadata.md +20 -0
  17. data/TODO.finalize/12-add-frozen-string-literal.md +6 -0
  18. data/TODO.finalize/13-extract-composition-from-god-class.md +96 -0
  19. data/TODO.finalize/14-config-driven-section-ordering.md +31 -0
  20. data/TODO.finalize/15-theme-directories-per-flavor.md +46 -0
  21. data/TODO.finalize/16-theme-lutaml-model-schema.md +44 -0
  22. data/data/javascripts/components/mn-footnotes.js +68 -0
  23. data/data/javascripts/components/mn-lightbox.js +18 -2
  24. data/data/javascripts/components/mn-shortcuts.js +2 -0
  25. data/data/javascripts/core/mn-navigation.js +8 -0
  26. data/data/javascripts/core/mn-theme.js +9 -9
  27. data/data/logos/oiml-logo-full-dark.svg +1 -0
  28. data/data/logos/oiml-logo-full-light.svg +1 -0
  29. data/data/logos/oiml-logo-icon-dark.svg +1 -0
  30. data/data/logos/oiml-logo-icon-light.svg +1 -0
  31. data/data/logos/oiml-logo.svg +1 -0
  32. data/data/logos/pdfa-logo.svg +31 -94
  33. data/data/stylesheets/base/_layout.css +3 -0
  34. data/data/stylesheets/base/_reset.css +3 -3
  35. data/data/stylesheets/base/_typography.css +0 -5
  36. data/data/stylesheets/components/bibliography.css +3 -3
  37. data/data/stylesheets/components/cover.css +3 -1
  38. data/data/stylesheets/components/figure.css +13 -1
  39. data/data/stylesheets/components/footnote.css +65 -5
  40. data/data/stylesheets/components/formula.css +44 -0
  41. data/data/stylesheets/components/header.css +17 -2
  42. data/data/stylesheets/components/inline.css +1 -1
  43. data/data/stylesheets/components/table.css +15 -2
  44. data/data/stylesheets/components/term.css +0 -1
  45. data/data/themes/bipm.yaml +60 -0
  46. data/data/themes/cc.yaml +43 -0
  47. data/data/themes/icc.yaml +39 -0
  48. data/data/themes/iec.yaml +44 -0
  49. data/data/themes/ieee.yaml +43 -0
  50. data/data/themes/ietf.yaml +45 -0
  51. data/data/themes/iho.yaml +46 -0
  52. data/data/themes/iso.yaml +40 -0
  53. data/data/themes/itu.yaml +45 -0
  54. data/data/themes/ogc.yaml +51 -0
  55. data/data/themes/oiml.yaml +56 -0
  56. data/data/themes/pdfa.yaml +44 -0
  57. data/data/themes/ribose.yaml +43 -0
  58. data/exe/metanorma-document +11 -0
  59. data/frontend/e2e/sample-html.test.ts +256 -0
  60. data/frontend/index.html +12 -0
  61. data/frontend/package-lock.json +4725 -0
  62. data/frontend/package.json +32 -0
  63. data/frontend/postcss.config.js +6 -0
  64. data/frontend/src/App.vue +79 -0
  65. data/frontend/src/app.ts +21 -0
  66. data/frontend/src/components/AppSidebar.vue +77 -0
  67. data/frontend/src/components/DocumentReader.vue +180 -0
  68. data/frontend/src/components/MirrorRenderer.vue +23 -0
  69. data/frontend/src/components/ReadingProgressBar.vue +29 -0
  70. data/frontend/src/components/TextRenderer.vue +131 -0
  71. data/frontend/src/components/TocItem.vue +57 -0
  72. data/frontend/src/components/TopBar.vue +49 -0
  73. data/frontend/src/components/__tests__/MirrorRenderer.test.ts +178 -0
  74. data/frontend/src/components/blocks/AdmonitionBlock.vue +74 -0
  75. data/frontend/src/components/blocks/ClauseBlock.vue +53 -0
  76. data/frontend/src/components/blocks/ExampleBlock.vue +21 -0
  77. data/frontend/src/components/blocks/FallbackBlock.vue +18 -0
  78. data/frontend/src/components/blocks/FigureBlock.vue +26 -0
  79. data/frontend/src/components/blocks/FootnotesBlock.vue +25 -0
  80. data/frontend/src/components/blocks/ListBlocks.vue +62 -0
  81. data/frontend/src/components/blocks/NoteBlock.vue +21 -0
  82. data/frontend/src/components/blocks/ParagraphBlock.vue +25 -0
  83. data/frontend/src/components/blocks/QuoteBlock.vue +25 -0
  84. data/frontend/src/components/blocks/ReviewBlock.vue +39 -0
  85. data/frontend/src/components/blocks/SourcecodeBlock.vue +52 -0
  86. data/frontend/src/components/blocks/TableBlock.vue +48 -0
  87. data/frontend/src/components/blocks/index.ts +36 -0
  88. data/frontend/src/stores/__tests__/documentStore.fixture.test.ts +272 -0
  89. data/frontend/src/stores/__tests__/documentStore.test.ts +143 -0
  90. data/frontend/src/stores/__tests__/ebookStore.test.ts +145 -0
  91. data/frontend/src/stores/__tests__/uiStore.test.ts +42 -0
  92. data/frontend/src/stores/documentStore.ts +153 -0
  93. data/frontend/src/stores/ebookStore.ts +179 -0
  94. data/frontend/src/stores/uiStore.ts +32 -0
  95. data/frontend/src/styles.css +156 -0
  96. data/frontend/src/types/__tests__/rendering-contract.test.ts +172 -0
  97. data/frontend/src/types/rendering-contract.ts +209 -0
  98. data/frontend/src/utils/__tests__/typeMetadata.test.ts +102 -0
  99. data/frontend/src/utils/typeMetadata.ts +121 -0
  100. data/frontend/tailwind.config.js +18 -0
  101. data/frontend/test/fixtures/iso-document.json +271 -0
  102. data/frontend/tmp/debug_e2e.cjs +46 -0
  103. data/frontend/tsconfig.json +25 -0
  104. data/frontend/tsconfig.node.json +11 -0
  105. data/frontend/vite.config.ts +37 -0
  106. data/frontend/vitest.e2e.config.ts +9 -0
  107. data/lib/metanorma/bipm_document/metadata/bipm_bibliographic_item.rb +0 -14
  108. data/lib/metanorma/bipm_document/metadata/depiction_element.rb +18 -0
  109. data/lib/metanorma/bipm_document/metadata.rb +1 -1
  110. data/lib/metanorma/document/cli.rb +116 -0
  111. data/lib/metanorma/document/components/ancillary_blocks/callout_annotation.rb +27 -0
  112. data/lib/metanorma/document/components/ancillary_blocks/sourcecode_block.rb +0 -65
  113. data/lib/metanorma/document/components/ancillary_blocks/sourcecode_body.rb +18 -0
  114. data/lib/metanorma/document/components/ancillary_blocks.rb +4 -0
  115. data/lib/metanorma/document/components/bib_data/bib_data.rb +7 -0
  116. data/lib/metanorma/document/components/blocks/classification_value.rb +21 -0
  117. data/lib/metanorma/document/components/blocks/permission_model.rb +28 -0
  118. data/lib/metanorma/document/components/blocks/recommendation_model.rb +28 -0
  119. data/lib/metanorma/document/components/blocks/requirement_base.rb +30 -0
  120. data/lib/metanorma/document/components/blocks/requirement_classification.rb +20 -0
  121. data/lib/metanorma/document/components/blocks/requirement_description.rb +43 -0
  122. data/lib/metanorma/document/components/blocks/requirement_inherit.rb +24 -0
  123. data/lib/metanorma/document/components/blocks/requirement_model.rb +0 -131
  124. data/lib/metanorma/document/components/blocks.rb +8 -7
  125. data/lib/metanorma/document/components/id_elements/image.rb +2 -0
  126. data/lib/metanorma/document/components/inline/asciimath_element.rb +2 -0
  127. data/lib/metanorma/document/components/inline/attribution_element.rb +2 -0
  128. data/lib/metanorma/document/components/inline/bcp14_element.rb +2 -0
  129. data/lib/metanorma/document/components/inline/biblio_tag_element.rb +2 -0
  130. data/lib/metanorma/document/components/inline/br_element.rb +2 -0
  131. data/lib/metanorma/document/components/inline/comma_element.rb +2 -0
  132. data/lib/metanorma/document/components/inline/concept_element.rb +2 -0
  133. data/lib/metanorma/document/components/inline/display_text_element.rb +2 -0
  134. data/lib/metanorma/document/components/inline/em_raw_element.rb +2 -0
  135. data/lib/metanorma/document/components/inline/enum_comma_element.rb +2 -0
  136. data/lib/metanorma/document/components/inline/eref_element.rb +2 -0
  137. data/lib/metanorma/document/components/inline/fmt_admitted_element.rb +4 -0
  138. data/lib/metanorma/document/components/inline/fmt_annotation_body_element.rb +4 -0
  139. data/lib/metanorma/document/components/inline/fmt_annotation_end_element.rb +4 -0
  140. data/lib/metanorma/document/components/inline/fmt_annotation_start_element.rb +4 -0
  141. data/lib/metanorma/document/components/inline/fmt_concept_element.rb +4 -0
  142. data/lib/metanorma/document/components/inline/fmt_definition_element.rb +4 -0
  143. data/lib/metanorma/document/components/inline/fmt_fn_body_element.rb +4 -0
  144. data/lib/metanorma/document/components/inline/fmt_fn_label_element.rb +4 -0
  145. data/lib/metanorma/document/components/inline/fmt_footnote_container_element.rb +4 -0
  146. data/lib/metanorma/document/components/inline/fmt_identifier_element.rb +4 -0
  147. data/lib/metanorma/document/components/inline/fmt_name_element.rb +4 -0
  148. data/lib/metanorma/document/components/inline/fmt_preferred_element.rb +4 -0
  149. data/lib/metanorma/document/components/inline/fmt_sourcecode_element.rb +4 -0
  150. data/lib/metanorma/document/components/inline/fmt_stem_element.rb +10 -0
  151. data/lib/metanorma/document/components/inline/fmt_termsource_element.rb +4 -0
  152. data/lib/metanorma/document/components/inline/fmt_title_element.rb +4 -0
  153. data/lib/metanorma/document/components/inline/fmt_xref_element.rb +4 -0
  154. data/lib/metanorma/document/components/inline/fmt_xref_label_element.rb +4 -0
  155. data/lib/metanorma/document/components/inline/fn_element.rb +2 -0
  156. data/lib/metanorma/document/components/inline/link_element.rb +2 -0
  157. data/lib/metanorma/document/components/inline/localized_string_element.rb +2 -0
  158. data/lib/metanorma/document/components/inline/localized_strings_element.rb +2 -0
  159. data/lib/metanorma/document/components/inline/location_element.rb +24 -0
  160. data/lib/metanorma/document/components/inline/math_element.rb +2 -0
  161. data/lib/metanorma/document/components/inline/name_with_id_element.rb +4 -0
  162. data/lib/metanorma/document/components/inline/rendered_display.rb +23 -0
  163. data/lib/metanorma/document/components/inline/rendered_math_element.rb +21 -0
  164. data/lib/metanorma/document/components/inline/semantic_content.rb +51 -0
  165. data/lib/metanorma/document/components/inline/semantic_math_element.rb +20 -0
  166. data/lib/metanorma/document/components/inline/semx_child_element.rb +2 -0
  167. data/lib/metanorma/document/components/inline/semx_element.rb +13 -1
  168. data/lib/metanorma/document/components/inline/small_cap_element.rb +2 -0
  169. data/lib/metanorma/document/components/inline/span_element.rb +10 -15
  170. data/lib/metanorma/document/components/inline/stem_inline_element.rb +7 -1
  171. data/lib/metanorma/document/components/inline/strong_raw_element.rb +2 -0
  172. data/lib/metanorma/document/components/inline/sub_element.rb +2 -0
  173. data/lib/metanorma/document/components/inline/sup_element.rb +2 -0
  174. data/lib/metanorma/document/components/inline/tab_element.rb +2 -0
  175. data/lib/metanorma/document/components/inline/title_with_annotation_element.rb +4 -0
  176. data/lib/metanorma/document/components/inline/tt_element.rb +2 -0
  177. data/lib/metanorma/document/components/inline/variant_title_element.rb +2 -0
  178. data/lib/metanorma/document/components/inline/vocabulary.rb +184 -0
  179. data/lib/metanorma/document/components/inline/xref_element.rb +10 -0
  180. data/lib/metanorma/document/components/inline.rb +12 -0
  181. data/lib/metanorma/document/components/multi_paragraph/quote_author_element.rb +20 -0
  182. data/lib/metanorma/document/components/multi_paragraph/quote_block.rb +0 -29
  183. data/lib/metanorma/document/components/multi_paragraph.rb +2 -0
  184. data/lib/metanorma/document/components/reference_elements/source_element.rb +0 -31
  185. data/lib/metanorma/document/components/reference_elements/source_modification.rb +21 -0
  186. data/lib/metanorma/document/components/reference_elements/source_origin.rb +28 -0
  187. data/lib/metanorma/document/components/reference_elements.rb +2 -2
  188. data/lib/metanorma/document/components/tables/col_element.rb +18 -0
  189. data/lib/metanorma/document/components/tables/col_group_element.rb +18 -0
  190. data/lib/metanorma/document/components/tables/table_block.rb +0 -22
  191. data/lib/metanorma/document/components/tables/table_body_section.rb +16 -0
  192. data/lib/metanorma/document/components/tables/table_foot_section.rb +16 -0
  193. data/lib/metanorma/document/components/tables/table_head_section.rb +16 -0
  194. data/lib/metanorma/document/components/tables/table_section.rb +0 -25
  195. data/lib/metanorma/document/components/tables.rb +5 -3
  196. data/lib/metanorma/document/relaton/address.rb +0 -27
  197. data/lib/metanorma/document/relaton/bib_item_locality.rb +3 -12
  198. data/lib/metanorma/document/relaton/copyright_association.rb +0 -10
  199. data/lib/metanorma/document/relaton/copyright_owner.rb +16 -0
  200. data/lib/metanorma/document/relaton/edition.rb +4 -7
  201. data/lib/metanorma/document/relaton/formatted_address.rb +29 -0
  202. data/lib/metanorma/document/relaton/logo_element.rb +18 -0
  203. data/lib/metanorma/document/relaton/organization.rb +0 -14
  204. data/lib/metanorma/document/relaton/phone.rb +3 -9
  205. data/lib/metanorma/document/relaton/place_type.rb +0 -13
  206. data/lib/metanorma/document/relaton/price_type.rb +3 -9
  207. data/lib/metanorma/document/relaton/region_element.rb +18 -0
  208. data/lib/metanorma/document/relaton.rb +6 -1
  209. data/lib/metanorma/document/version.rb +1 -1
  210. data/lib/metanorma/document.rb +2 -0
  211. data/lib/metanorma/html/asset_pipeline.rb +1 -0
  212. data/lib/metanorma/html/base_renderer.rb +261 -1008
  213. data/lib/metanorma/html/bipm_renderer.rb +15 -144
  214. data/lib/metanorma/html/cc_renderer.rb +1 -45
  215. data/lib/metanorma/html/component/base.rb +2 -7
  216. data/lib/metanorma/html/component/index_section.rb +41 -43
  217. data/lib/metanorma/html/drops/admonition_drop.rb +1 -4
  218. data/lib/metanorma/html/drops/biblio_entry_drop.rb +50 -0
  219. data/lib/metanorma/html/drops/block_element_drop.rb +7 -2
  220. data/lib/metanorma/html/drops/example_drop.rb +1 -4
  221. data/lib/metanorma/html/drops/figure_drop.rb +31 -22
  222. data/lib/metanorma/html/drops/footnote_drop.rb +1 -1
  223. data/lib/metanorma/html/drops/formula_drop.rb +45 -16
  224. data/lib/metanorma/html/drops/note_drop.rb +9 -7
  225. data/lib/metanorma/html/drops/sourcecode_drop.rb +12 -5
  226. data/lib/metanorma/html/drops.rb +2 -0
  227. data/lib/metanorma/html/generator.rb +2 -2
  228. data/lib/metanorma/html/icc_renderer.rb +0 -39
  229. data/lib/metanorma/html/iec_renderer.rb +1 -44
  230. data/lib/metanorma/html/ieee_renderer.rb +1 -45
  231. data/lib/metanorma/html/ietf_renderer.rb +1 -48
  232. data/lib/metanorma/html/iho_renderer.rb +1 -46
  233. data/lib/metanorma/html/iso_renderer.rb +290 -343
  234. data/lib/metanorma/html/itu_renderer.rb +1 -45
  235. data/lib/metanorma/html/ogc_renderer.rb +15 -76
  236. data/lib/metanorma/html/oiml_renderer.rb +18 -38
  237. data/lib/metanorma/html/pdfa_renderer.rb +0 -39
  238. data/lib/metanorma/html/renderers/block_renderer.rb +372 -0
  239. data/lib/metanorma/html/renderers/inline_renderer.rb +655 -0
  240. data/lib/metanorma/html/renderers/pubid_renderer.rb +69 -0
  241. data/lib/metanorma/html/renderers/section_renderer.rb +193 -0
  242. data/lib/metanorma/html/renderers.rb +8 -0
  243. data/lib/metanorma/html/ribose_renderer.rb +1 -45
  244. data/lib/metanorma/html/standard_renderer.rb +341 -229
  245. data/lib/metanorma/html/templates/_audio.html.liquid +1 -0
  246. data/lib/metanorma/html/templates/_biblio_entry.html.liquid +1 -0
  247. data/lib/metanorma/html/templates/_bipm_cover.html.liquid +27 -0
  248. data/lib/metanorma/html/templates/_boilerplate.html.liquid +1 -0
  249. data/lib/metanorma/html/templates/_bookmark.html.liquid +1 -0
  250. data/lib/metanorma/html/templates/_br.html.liquid +1 -0
  251. data/lib/metanorma/html/templates/_definition_list.html.liquid +6 -0
  252. data/lib/metanorma/html/templates/_element.html.liquid +1 -0
  253. data/lib/metanorma/html/templates/_fn_marker.html.liquid +1 -0
  254. data/lib/metanorma/html/templates/_footnotes.html.liquid +6 -6
  255. data/lib/metanorma/html/templates/_formula.html.liquid +1 -1
  256. data/lib/metanorma/html/templates/_header.html.liquid +1 -1
  257. data/lib/metanorma/html/templates/_heading.html.liquid +1 -0
  258. data/lib/metanorma/html/templates/_image.html.liquid +1 -0
  259. data/lib/metanorma/html/templates/_inline_span.html.liquid +1 -0
  260. data/lib/metanorma/html/templates/_iso_cover.html.liquid +1 -1
  261. data/lib/metanorma/html/templates/_link.html.liquid +1 -0
  262. data/lib/metanorma/html/templates/_list.html.liquid +3 -0
  263. data/lib/metanorma/html/templates/_list_item.html.liquid +1 -0
  264. data/lib/metanorma/html/templates/_main_content.html.liquid +1 -0
  265. data/lib/metanorma/html/templates/_math_container.html.liquid +1 -0
  266. data/lib/metanorma/html/templates/_paragraph.html.liquid +1 -0
  267. data/lib/metanorma/html/templates/_prefatory_section.html.liquid +1 -0
  268. data/lib/metanorma/html/templates/_pubid_identifier.html.liquid +1 -0
  269. data/lib/metanorma/html/templates/_quote.html.liquid +4 -0
  270. data/lib/metanorma/html/templates/_ref_date.html.liquid +1 -0
  271. data/lib/metanorma/html/templates/_ref_title.html.liquid +1 -0
  272. data/lib/metanorma/html/templates/_section.html.liquid +5 -0
  273. data/lib/metanorma/html/templates/_standard_cover.html.liquid +31 -0
  274. data/lib/metanorma/html/templates/_standard_doc_title.html.liquid +3 -0
  275. data/lib/metanorma/html/templates/_stem_span.html.liquid +1 -0
  276. data/lib/metanorma/html/templates/_table.html.liquid +9 -0
  277. data/lib/metanorma/html/templates/_term_domain.html.liquid +1 -0
  278. data/lib/metanorma/html/templates/_term_example.html.liquid +1 -0
  279. data/lib/metanorma/html/templates/_term_note.html.liquid +1 -0
  280. data/lib/metanorma/html/templates/_term_number.html.liquid +1 -0
  281. data/lib/metanorma/html/templates/_term_source.html.liquid +1 -0
  282. data/lib/metanorma/html/templates/_term_text_note.html.liquid +1 -0
  283. data/lib/metanorma/html/templates/_video.html.liquid +1 -0
  284. data/lib/metanorma/html/templates/_wrapped_preface.html.liquid +1 -0
  285. data/lib/metanorma/html/templates/document.html.liquid +4 -0
  286. data/lib/metanorma/html/theme.rb +180 -107
  287. data/lib/metanorma/html.rb +13 -0
  288. data/lib/metanorma/ietf_document/metadata/ietf_bib_data_extension_type.rb +0 -25
  289. data/lib/metanorma/ietf_document/metadata/pi_settings.rb +32 -0
  290. data/lib/metanorma/ietf_document/metadata.rb +2 -0
  291. data/lib/metanorma/iso_document/metadata/doctype_element.rb +20 -0
  292. data/lib/metanorma/iso_document/metadata/iso_bib_data_extension_type.rb +0 -48
  293. data/lib/metanorma/iso_document/metadata/iso_bibliographic_item.rb +0 -72
  294. data/lib/metanorma/iso_document/metadata/iso_document_status.rb +0 -30
  295. data/lib/metanorma/iso_document/metadata/iso_localized_title.rb +4 -1
  296. data/lib/metanorma/iso_document/metadata/language_element.rb +18 -0
  297. data/lib/metanorma/iso_document/metadata/project_number.rb +22 -0
  298. data/lib/metanorma/iso_document/metadata/script_element.rb +18 -0
  299. data/lib/metanorma/iso_document/metadata/stage_element.rb +26 -0
  300. data/lib/metanorma/iso_document/metadata/stagename_element.rb +18 -0
  301. data/lib/metanorma/iso_document/metadata/structured_identifier.rb +0 -17
  302. data/lib/metanorma/iso_document/metadata/title_collection.rb +1 -0
  303. data/lib/metanorma/iso_document/metadata.rb +9 -4
  304. data/lib/metanorma/iso_document/terms/iso_term.rb +0 -13
  305. data/lib/metanorma/iso_document/terms/term_domain_element.rb +18 -0
  306. data/lib/metanorma/iso_document/terms.rb +1 -0
  307. data/lib/metanorma/itu_document/metadata/itu_bib_data_extension_type.rb +0 -37
  308. data/lib/metanorma/itu_document/metadata/meeting_date.rb +18 -0
  309. data/lib/metanorma/itu_document/metadata/meeting_element.rb +18 -0
  310. data/lib/metanorma/itu_document/metadata/study_period.rb +18 -0
  311. data/lib/metanorma/itu_document/metadata.rb +3 -4
  312. data/lib/metanorma/mirror/default_registry.rb +170 -0
  313. data/lib/metanorma/mirror/handler_registry.rb +60 -0
  314. data/lib/metanorma/mirror/handler_result.rb +37 -0
  315. data/lib/metanorma/mirror/handlers/admonition.rb +18 -0
  316. data/lib/metanorma/mirror/handlers/example.rb +21 -0
  317. data/lib/metanorma/mirror/handlers/figure.rb +53 -0
  318. data/lib/metanorma/mirror/handlers/formula.rb +35 -0
  319. data/lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb +159 -0
  320. data/lib/metanorma/mirror/handlers/inline/text_extractor.rb +116 -0
  321. data/lib/metanorma/mirror/handlers/inline.rb +225 -0
  322. data/lib/metanorma/mirror/handlers/list.rb +110 -0
  323. data/lib/metanorma/mirror/handlers/note.rb +26 -0
  324. data/lib/metanorma/mirror/handlers/paragraph.rb +19 -0
  325. data/lib/metanorma/mirror/handlers/quote.rb +16 -0
  326. data/lib/metanorma/mirror/handlers/review.rb +19 -0
  327. data/lib/metanorma/mirror/handlers/section.rb +149 -0
  328. data/lib/metanorma/mirror/handlers/sourcecode.rb +27 -0
  329. data/lib/metanorma/mirror/handlers/structural.rb +68 -0
  330. data/lib/metanorma/mirror/handlers/table.rb +81 -0
  331. data/lib/metanorma/mirror/handlers/term.rb +100 -0
  332. data/lib/metanorma/mirror/handlers.rb +60 -0
  333. data/lib/metanorma/mirror/id_strategy/positional.rb +166 -0
  334. data/lib/metanorma/mirror/id_strategy/preserve.rb +12 -0
  335. data/lib/metanorma/mirror/id_strategy.rb +34 -0
  336. data/lib/metanorma/mirror/math_util.rb +53 -0
  337. data/lib/metanorma/mirror/metadata.rb +37 -0
  338. data/lib/metanorma/mirror/metanorma_to_mirror.rb +101 -0
  339. data/lib/metanorma/mirror/model/container.rb +47 -0
  340. data/lib/metanorma/mirror/model/factory.rb +52 -0
  341. data/lib/metanorma/mirror/model/guide.rb +25 -0
  342. data/lib/metanorma/mirror/model/leaf.rb +17 -0
  343. data/lib/metanorma/mirror/model/mark.rb +53 -0
  344. data/lib/metanorma/mirror/model/node.rb +47 -0
  345. data/lib/metanorma/mirror/model/soft_break.rb +33 -0
  346. data/lib/metanorma/mirror/model/text.rb +34 -0
  347. data/lib/metanorma/mirror/model.rb +16 -0
  348. data/lib/metanorma/mirror/output/builder.rb +39 -0
  349. data/lib/metanorma/mirror/output/formats/base_format.rb +90 -0
  350. data/lib/metanorma/mirror/output/formats/inline_format.rb +81 -0
  351. data/lib/metanorma/mirror/output/formats.rb +53 -0
  352. data/lib/metanorma/mirror/output/html_renderer.rb +95 -0
  353. data/lib/metanorma/mirror/output/html_renderers/block_renderers.rb +178 -0
  354. data/lib/metanorma/mirror/output/html_renderers/inline_renderer.rb +61 -0
  355. data/lib/metanorma/mirror/output/html_renderers/list_renderers.rb +96 -0
  356. data/lib/metanorma/mirror/output/html_renderers/mark_renderers.rb +64 -0
  357. data/lib/metanorma/mirror/output/html_renderers/section_renderers.rb +129 -0
  358. data/lib/metanorma/mirror/output/html_renderers/structural_renderers.rb +80 -0
  359. data/lib/metanorma/mirror/output/html_renderers/table_renderers.rb +87 -0
  360. data/lib/metanorma/mirror/output/html_renderers.rb +76 -0
  361. data/lib/metanorma/mirror/output/pipeline.rb +92 -0
  362. data/lib/metanorma/mirror/output/pipeline_context.rb +22 -0
  363. data/lib/metanorma/mirror/output.rb +14 -0
  364. data/lib/metanorma/mirror/rewriter.rb +121 -0
  365. data/lib/metanorma/mirror/safe_attr.rb +16 -0
  366. data/lib/metanorma/mirror/serialization/json_serializer.rb +25 -0
  367. data/lib/metanorma/mirror/serialization/yaml_serializer.rb +20 -0
  368. data/lib/metanorma/mirror/serialization.rb +10 -0
  369. data/lib/metanorma/mirror/transformer.rb +22 -0
  370. data/lib/metanorma/mirror.rb +32 -0
  371. data/lib/metanorma/standard_document/annotation.rb +37 -0
  372. data/lib/metanorma/standard_document/block_attributes.rb +15 -2
  373. data/lib/metanorma/standard_document/blocks/block_source.rb +0 -23
  374. data/lib/metanorma/standard_document/blocks/source_origin_element.rb +23 -0
  375. data/lib/metanorma/standard_document/blocks.rb +1 -1
  376. data/lib/metanorma/standard_document/terms/term_expression.rb +0 -31
  377. data/lib/metanorma/standard_document/terms/term_name_element.rb +29 -0
  378. data/lib/metanorma/standard_document/terms.rb +1 -0
  379. data/script/render_both.rb +18 -0
  380. metadata +262 -13
  381. data/.github/workflows/rake.yml +0 -21
  382. data/.github/workflows/release.yml +0 -25
  383. data/.github/workflows/roundtrip-samples.yml +0 -132
  384. data/.gitignore +0 -19
  385. data/.rspec +0 -3
  386. data/.rubocop.yml +0 -22
  387. data/Gemfile +0 -28
  388. data/bin/console +0 -15
  389. data/bin/setup +0 -8
  390. data/metanorma-document.gemspec +0 -35
@@ -2,151 +2,22 @@
2
2
 
3
3
  module Metanorma
4
4
  module Html
5
- # Renders BipmDocument components to HTML.
6
- # Extends IsoRenderer with BIPM-specific branding (institutional navy, scientific precision).
7
5
  class BipmRenderer < IsoRenderer
8
- def flavor_publishers(_doc_id)
9
- ["BIPM"]
10
- end
11
-
12
- def flavor_publisher_name
13
- "BIPM"
14
- end
15
-
16
- def publisher_logo_map
17
- { "BIPM" => "bipm-logo.svg" }
18
- end
19
-
20
- # Strip redundant publisher prefix from doc identifiers.
21
- # XML has "BIPM BIPM-2015/02" but we already show the BIPM logo.
22
- def clean_doc_id(raw_id)
23
- raw_id.to_s.gsub(/\ABIPM\s+/, "").strip
24
- end
25
-
26
- # BIPM logo: white fill for dark header
27
- def load_logo_svg(filename, **opts)
28
- svg = super
29
- svg = svg.gsub("fill:#0f3c80", "fill:white") if svg
30
- svg
31
- end
32
-
33
- # Strip BIPM prefix from doc IDs shown in header
34
- def extract_primary_doc_id
35
- raw = super
36
- clean_doc_id(raw)
37
- end
38
-
39
- # Override cover page to show clean doc ID (without redundant "BIPM " prefix)
40
- def render_coverpage(doc)
41
- bibdata = doc.bibdata
42
- return unless bibdata
43
-
44
- @output << "<div class=\"title-section\">"
45
- @output << "<div class=\"cover-grid\">"
46
- @output << "<div class=\"cover-meta\">"
47
-
48
- # Publisher logos
49
- logos = publisher_logos_html(doc)
50
- if logos && !logos.empty?
51
- @output << "<div class=\"cover-publishers\">"
52
- logos.each do |svg|
53
- @output << "<span class=\"cover-logo\">#{svg}</span>"
54
- end
55
- @output << "</div>"
56
- end
57
-
58
- identifiers = Array(bibdata.doc_identifier).compact
59
- cover_ids = identifiers.select do |di|
60
- safe_attr(di, :type) == "iso-reference"
61
- end
62
- cover_ids = [identifiers.first].compact if cover_ids.empty?
63
-
64
- cover_ids.each do |di|
65
- id = clean_doc_id(extract_text_value(di))
66
- next if id.to_s.empty?
67
-
68
- @output << "<p class=\"cover-doc-id\">#{escape_html(id)}</p>"
69
- end
70
-
71
- bibdata.date&.each do |date|
72
- date_type = extract_text_value(safe_attr(date,
73
- :type_attr) || safe_attr(
74
- date, :type
75
- ))
76
- date_val = extract_text_value(date.is_a?(Metanorma::Document::Relaton::BibliographicDate) ? date.on : safe_attr(
77
- date, :text
78
- ))
79
- if date_type == "published" && date_val
80
- @output << "<p class=\"cover-date\">#{escape_html(date_val)}</p>"
81
- end
82
- end
83
-
84
- @output << "</div>"
85
- @output << "<div class=\"cover-body\">"
86
-
87
- title_text = extract_display_title(bibdata)
88
- if title_text && !title_text.empty?
89
- @output << "<div class=\"cover-title\"><span>#{escape_html(title_text)}</span></div>"
90
- end
91
-
92
- if bibdata.status&.stage
93
- stages = Array(bibdata.status.stage)
94
- stage_text = stages.map { |s| Array(s.value).join }.join(" ")
95
- unless stage_text.empty?
96
- @output << "<div class=\"cover-stage\"><p>#{escape_html(stage_text)}</p></div>"
97
- end
98
- end
99
-
100
- @output << "</div>"
101
- @output << "</div>"
102
- @output << "</div><hr class=\"cover-separator\" />"
103
- end
104
-
105
- def theme
106
- @theme ||= Theme.new.tap do |t|
107
- t.primary = "#0f3c80"
108
- t.accent = "#3d7ec7"
109
- t.accent_deep = "#1a5a9e"
110
- t.gradient = "linear-gradient(135deg, #082247 0%, #0f3c80 50%, #1a5a9e 100%)"
111
- t.primary_light = "#edf1f7"
112
- t.accent_light = "#e8f0fa"
113
- t.warm = "#7a6952"
114
- t.warm_light = "#f5f0e8"
115
- t.sidebar_bg = "#f4f6fa"
116
- t.font_body = '"Crimson Pro", "Georgia", "Times New Roman", serif'
117
- t.font_sans = '"IBM Plex Sans", "Helvetica Neue", Arial, sans-serif'
118
- t.font_mono = '"IBM Plex Mono", "Fira Code", "Courier New", monospace'
119
- t.font_url = "https://fonts.googleapis.com/css2?family=Crimson+Pro:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Mono:wght@400;500&display=swap"
120
- t.header_background = "linear-gradient(135deg, #082247 0%, #0f3c80 50%, #1a5a9e 100%)"
121
- t.cover_background = "linear-gradient(175deg, #04122a 0%, #0a2e5c 25%, #0f3c80 55%, #1a5a9e 80%, #3d7ec7 100%)"
122
- t.cover_before_bg = "background: radial-gradient(ellipse at 25% 15%, rgba(61,126,199,0.15) 0%, transparent 50%), radial-gradient(ellipse at 75% 85%, rgba(15,60,128,0.18) 0%, transparent 40%), radial-gradient(circle at 50% 50%, rgba(255,255,255,0.02) 0%, transparent 70%)"
123
- t.cover_after_bg = "height: 3px; background: linear-gradient(90deg, transparent, #3d7ec7 20%, #0f3c80 50%, #3d7ec7 80%, transparent)"
124
- t.progress_bar_color = "#3d7ec7"
125
- t.note_border = "#3d7ec7"
126
- t.note_bg = "#edf1f7"
127
- t.note_color = "#3d7ec7"
128
- t.example_border = "#0f3c80"
129
- t.example_bg = "#f5f0e8"
130
- t.example_color = "#7a6952"
131
- t.admonition_border = "#7a6952"
132
- t.admonition_bg = "#f5f0e8"
133
- t.admonition_color = "#7a6952"
134
- t.footer_border_color = "#3d7ec7"
135
- t.cover_separator_color = "rgba(61,126,199,0.25)"
136
- t.dark_note_bg = "#0d1520"
137
- t.dark_example_bg = "#14100e"
138
- t.dark_admonition_bg = "#141210"
139
- t.extra_css = <<~CSS
140
- .sourcecode pre { background: #0a1628; border-color: #1a2d4a; }
141
- .reading-progress { box-shadow: 0 0 10px rgba(61,126,199,0.4); }
142
- mark.search-match { background: #edf1f7; box-shadow: 0 0 0 1px rgba(15,60,128,0.25); }
143
- mark.search-match.search-current { background: #3d7ec7; color: #fff; }
144
- [data-theme="dark"] .sourcecode pre { background: #060a14; border-color: #1a2040; }
145
- [data-theme="dark"] mark.search-match { background: #0d1a30; box-shadow: 0 0 0 1px rgba(61,126,199,0.4); }
146
- [data-theme="dark"] mark.search-match.search-current { background: #1a5a9e; }
147
- CSS
148
- end
149
- end
6
+ register_render Metanorma::BipmDocument::Root, :render_document
7
+ register_render Metanorma::StandardDocument::Sections::Preface,
8
+ :render_preface
9
+ register_render Metanorma::StandardDocument::Sections::ClauseSection,
10
+ :render_clause
11
+ register_render Metanorma::StandardDocument::Sections::AnnexSection,
12
+ :render_annex
13
+ register_render Metanorma::StandardDocument::Sections::ContentSection,
14
+ :render_clause
15
+ register_render Metanorma::StandardDocument::Sections::TermsSection,
16
+ :render_terms_section
17
+ register_render Metanorma::StandardDocument::Sections::BibliographySection,
18
+ :render_clause
19
+ register_render Metanorma::StandardDocument::Sections::DefinitionSection,
20
+ :render_clause
150
21
  end
151
22
  end
152
23
  end
@@ -2,52 +2,8 @@
2
2
 
3
3
  module Metanorma
4
4
  module Html
5
- # Renders CcDocument (CalConnect) components to HTML.
6
- # Extends IsoRenderer with CalConnect branding.
7
5
  class CcRenderer < IsoRenderer
8
- def flavor_publishers(_doc_id)
9
- ["CalConnect"]
10
- end
11
-
12
- def flavor_publisher_name
13
- "CalConnect"
14
- end
15
-
16
- def publisher_logo_map
17
- {}
18
- end
19
-
20
- def theme
21
- @theme ||= Theme.new.tap do |t|
22
- t.font_body = '"Lora", "Georgia", serif'
23
- t.font_sans = '"Karla", "Helvetica Neue", Arial, sans-serif'
24
- t.font_mono = '"JetBrains Mono", "Fira Code", monospace'
25
- t.font_url = "https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Karla:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
26
- t.primary = "#003d7c"
27
- t.accent = "#0078d4"
28
- t.accent_deep = "#005fa3"
29
- t.gradient = "linear-gradient(135deg, #002244 0%, #003d7c 50%, #0078d4 100%)"
30
- t.primary_light = "#edf3fa"
31
- t.accent_light = "#e0effc"
32
- t.warm = "#c9982e"
33
- t.warm_light = "#fdf8ec"
34
- t.header_background = "linear-gradient(135deg, #002244 0%, #003d7c 50%, #0078d4 100%)"
35
- t.cover_background = "linear-gradient(175deg, #001a33 0%, #003d7c 40%, #0078d4 80%, #0092d6 100%)"
36
- t.cover_before_bg = "background: radial-gradient(ellipse at 25% 15%, rgba(0,120,212,0.2) 0%, transparent 50%), radial-gradient(ellipse at 75% 85%, rgba(201,152,46,0.15) 0%, transparent 40%)"
37
- t.cover_after_bg = "height: 3px; background: linear-gradient(90deg, transparent, #c9982e, transparent)"
38
- t.progress_bar_color = "#0078d4"
39
- t.note_border = "#0078d4"
40
- t.note_bg = "#e0effc"
41
- t.note_color = "#0078d4"
42
- t.example_border = "#003d7c"
43
- t.example_bg = "#edf3fa"
44
- t.example_color = "#003d7c"
45
- t.admonition_border = "#c9982e"
46
- t.admonition_color = "#c9982e"
47
- t.footer_border_color = "#0078d4"
48
- t.cover_separator_color = "rgba(0,120,212,0.25)"
49
- end
50
- end
6
+ register_render Metanorma::CcDocument::Root, :render_document
51
7
  end
52
8
  end
53
9
  end
@@ -38,11 +38,6 @@ module Metanorma
38
38
  raise NotImplementedError, "#{self.class}#render not implemented"
39
39
  end
40
40
 
41
- def output
42
- renderer.instance_variable_get(:@output)
43
- end
44
-
45
- def tag(...) = renderer.tag(...)
46
41
  def escape_html(...) = renderer.escape_html(...)
47
42
  def render_mixed_inline(...) = renderer.render_mixed_inline(...)
48
43
  def render_mixed_content_in_order(...) = renderer.render_mixed_content_in_order(...)
@@ -50,9 +45,9 @@ module Metanorma
50
45
  def safe_attr(obj, method_name) = renderer.safe_attr(obj, method_name)
51
46
  def extract_plain_text(node) = renderer.extract_plain_text(node)
52
47
  def extract_text_value(val) = renderer.extract_text_value(val)
48
+ def render_liquid(...) = renderer.render_liquid(...)
53
49
 
54
- def extract_block_label(block,
55
- default)
50
+ def extract_block_label(block, default)
56
51
  renderer.extract_block_label(block, default)
57
52
  end
58
53
 
@@ -7,24 +7,28 @@ module Metanorma
7
7
  def render(collector, **_opts)
8
8
  return if collector.nil? || collector.empty?
9
9
 
10
- output << tag(:div,
11
- %( id="index" class="index-section" data-component="index")) do
12
- html = tag(:h2) { "Index" }
13
- html << render_quicknav(collector.sorted_groups)
14
- html << render_letter_groups(collector.sorted_groups)
15
- html
16
- end
10
+ quicknav = render_quicknav(collector.sorted_groups)
11
+ letter_groups = render_letter_groups(collector.sorted_groups)
12
+ content = quicknav + letter_groups
13
+
14
+ attrs = %( id="index" class="index-section" data-component="index")
15
+ index_html = render_liquid("_element.html.liquid", "tag" => "div",
16
+ "extra_attrs" => attrs, "content" => content)
17
17
 
18
18
  renderer.register_toc_entry(id: "index", level: 1, text: "Index")
19
+ index_html
19
20
  end
20
21
 
21
22
  private
22
23
 
23
24
  def render_quicknav(groups)
24
25
  links = groups.filter_map do |g|
25
- %(<a href="#index-letter-#{escape_html(g.letter)}">#{escape_html(g.letter)}</a>)
26
+ letter = escape_html(g.letter)
27
+ render_liquid("_link.html.liquid",
28
+ "attrs" => %( href="#index-letter-#{letter}"), "display_text" => letter)
26
29
  end.join
27
- %(<div class="index-quicknav">#{links}</div>)
30
+ render_liquid("_element.html.liquid", "tag" => "div",
31
+ "extra_attrs" => " class=\"index-quicknav\"", "content" => links)
28
32
  end
29
33
 
30
34
  def render_letter_groups(groups)
@@ -32,54 +36,48 @@ module Metanorma
32
36
  end
33
37
 
34
38
  def render_letter_group(group)
35
- tag(:div,
36
- %( class="index-letter-group" id="index-letter-#{escape_html(group.letter)}")) do
37
- html = tag(:h3, %( class="index-letter")) { group.letter }
38
- html << group.entries.map { |e| render_entry(e, "primary") }.join
39
- html
40
- end
39
+ letter = escape_html(group.letter)
40
+ heading = render_liquid("_heading.html.liquid", "tag" => "h3",
41
+ "class_attr" => " class=\"index-letter\"", "content" => letter)
42
+ entries = group.entries.map { |e| render_entry(e, "primary") }.join
43
+ render_liquid("_element.html.liquid", "tag" => "div",
44
+ "extra_attrs" => %( class="index-letter-group" id="index-letter-#{letter}"), "content" => "#{heading}#{entries}")
41
45
  end
42
46
 
43
47
  def render_entry(entry, level)
44
- tag(:div, %( class="index-entry index-entry--#{level}")) do
45
- html = +""
46
- html << tag(:span, %( class="index-term")) do
47
- escape_html(entry.term)
48
- end
49
- html << render_locators(entry.locators)
50
- html << render_see(entry.see) if entry.see
51
- html << render_see_also(entry.see_also_entries) unless entry.see_also_entries.empty?
52
- unless entry.children.empty?
53
- html << entry.children.map { |c|
54
- render_entry(c, next_level(level))
55
- }.join
56
- end
57
- html
48
+ term_html = render_liquid("_element.html.liquid", "tag" => "span",
49
+ "extra_attrs" => " class=\"index-term\"", "content" => escape_html(entry.term))
50
+ locators_html = render_locators(entry.locators)
51
+ inner = term_html + locators_html
52
+ inner << render_see(entry.see) if entry.see
53
+ inner << render_see_also(entry.see_also_entries) unless entry.see_also_entries.empty?
54
+ unless entry.children.empty?
55
+ inner << entry.children.map { |c|
56
+ render_entry(c, next_level(level))
57
+ }.join
58
58
  end
59
+ render_liquid("_element.html.liquid", "tag" => "div",
60
+ "extra_attrs" => %( class="index-entry index-entry--#{level}"), "content" => inner)
59
61
  end
60
62
 
61
63
  def render_locators(locators)
62
64
  links = locators.map do |loc|
63
- tag(:a, %( href="##{escape_html(loc.id)}")) do
64
- escape_html(loc.text)
65
- end
66
- end
67
- tag(:span, %( class="index-locator")) { links.join(", ") }
65
+ render_liquid("_link.html.liquid",
66
+ "attrs" => %( href="##{escape_html(loc.id)}"), "display_text" => escape_html(loc.text))
67
+ end.join(", ")
68
+ render_liquid("_element.html.liquid", "tag" => "span",
69
+ "extra_attrs" => " class=\"index-locator\"", "content" => links)
68
70
  end
69
71
 
70
72
  def render_see(term)
71
- tag(:div, %( class="index-see")) do
72
- "<em>see</em> #{escape_html(term)}"
73
- end
73
+ render_liquid("_element.html.liquid", "tag" => "div",
74
+ "extra_attrs" => " class=\"index-see\"", "content" => "<em>see</em> #{escape_html(term)}")
74
75
  end
75
76
 
76
77
  def render_see_also(terms)
77
- tag(:div,
78
- %( class="index-see-also")) do
79
- "<em>see also</em> #{terms.map do |t|
80
- escape_html(t)
81
- end.join(', ')}"
82
- end
78
+ text = terms.map { |t| escape_html(t) }.join(", ")
79
+ render_liquid("_element.html.liquid", "tag" => "div",
80
+ "extra_attrs" => " class=\"index-see-also\"", "content" => "<em>see also</em> #{text}")
83
81
  end
84
82
 
85
83
  def next_level(level)
@@ -8,10 +8,7 @@ module Metanorma
8
8
  type = renderer.safe_attr(admonition, :type) || "note"
9
9
  id = renderer.safe_attr(admonition, :id)
10
10
 
11
- content_html = renderer.capture_output do
12
- renderer.render_block_children(admonition,
13
- children: BaseRenderer::SIMPLE_CHILDREN)
14
- end
11
+ content_html = renderer.render_simple_children(admonition) || ""
15
12
 
16
13
  new(
17
14
  id: id,
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Html
5
+ module Drops
6
+ class BiblioEntryDrop < Liquid::Drop
7
+ def initialize(attrs)
8
+ @id = attrs[:id]
9
+ @css_class = attrs[:css_class]
10
+ @ordinal_html = attrs[:ordinal_html]
11
+ @pubid_html = attrs[:pubid_html]
12
+ @url = attrs[:url]
13
+ @content_html = attrs[:content_html]
14
+ end
15
+
16
+ def id
17
+ @id
18
+ end
19
+
20
+ def css_class
21
+ @css_class
22
+ end
23
+
24
+ def ordinal_html
25
+ @ordinal_html
26
+ end
27
+
28
+ def pubid_html
29
+ @pubid_html
30
+ end
31
+
32
+ def url
33
+ @url
34
+ end
35
+
36
+ def content_html
37
+ @content_html
38
+ end
39
+
40
+ def has_ordinal
41
+ !@ordinal_html.nil? && !@ordinal_html.empty?
42
+ end
43
+
44
+ def has_url
45
+ !@url.nil? && !@url.empty?
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -6,8 +6,13 @@ module Metanorma
6
6
  class BlockElementDrop < Liquid::Drop
7
7
  attr_reader :id, :type, :label_html, :content_html, :css_class
8
8
 
9
- def initialize(attrs = {})
10
- attrs.each { |k, v| instance_variable_set(:"@#{k}", v) }
9
+ def initialize(id: nil, type: nil, label_html: nil, content_html: nil,
10
+ css_class: nil)
11
+ @id = id
12
+ @type = type
13
+ @label_html = label_html
14
+ @content_html = content_html
15
+ @css_class = css_class
11
16
  end
12
17
 
13
18
  # Subclasses override to build from model + RendererContext
@@ -8,10 +8,7 @@ module Metanorma
8
8
  id = renderer.safe_attr(example, :id)
9
9
  label = renderer.extract_block_label(example, "EXAMPLE")
10
10
 
11
- content_html = renderer.capture_output do
12
- renderer.render_block_children(example,
13
- children: BaseRenderer::BLOCK_CHILDREN)
14
- end
11
+ content_html = renderer.render_full_block_children(example) || ""
15
12
 
16
13
  new(
17
14
  id: id,
@@ -6,6 +6,16 @@ module Metanorma
6
6
  class FigureDrop < BlockElementDrop
7
7
  attr_reader :image_html, :caption_html, :key_html, :sub_figures_html
8
8
 
9
+ def initialize(id: nil, image_html: nil, caption_html: nil, key_html: nil,
10
+ sub_figures_html: nil, css_class: nil)
11
+ @id = id
12
+ @image_html = image_html
13
+ @caption_html = caption_html
14
+ @key_html = key_html
15
+ @sub_figures_html = sub_figures_html
16
+ @css_class = css_class
17
+ end
18
+
9
19
  def self.from_model(figure, renderer:)
10
20
  id = renderer.safe_attr(figure, :id)
11
21
  fig_name = renderer.safe_attr(figure,
@@ -17,35 +27,34 @@ module Metanorma
17
27
  text: renderer.extract_plain_text(fig_name))
18
28
  end
19
29
 
20
- image_html = renderer.capture_output do
21
- if figure.image
22
- renderer.render_image(figure.image)
23
- elsif renderer.safe_attr(figure, :source)
24
- src = renderer.safe_attr(figure, :source)
25
- @output << %(<img src="#{renderer.escape_html(src)}" />)
26
- end
27
- end
30
+ image_html = if figure.image
31
+ renderer.render_image(figure.image)
32
+ elsif renderer.safe_attr(figure, :source)
33
+ src = renderer.safe_attr(figure, :source)
34
+ renderer.render_liquid("_image.html.liquid",
35
+ "attrs" => %( src="#{renderer.escape_html(src)}"))
36
+ end
28
37
 
29
38
  caption_html = if fig_name || renderer.safe_attr(figure, :name)
30
- renderer.capture_output do
31
- el = renderer.safe_attr(figure,
32
- :fmt_name) || figure.name
33
- renderer.render_inline_element(el)
34
- end
39
+ el = renderer.safe_attr(figure,
40
+ :fmt_name) || figure.name
41
+ renderer.render_inline_element(el)
35
42
  end
36
43
 
37
- sub_figures_html = renderer.capture_output do
38
- figure.figure&.each { |sub| renderer.render_figure(sub) }
44
+ sub_figures_parts = []
45
+ figure.figure&.each do |sub|
46
+ sub_figures_parts << (renderer.render_figure(sub) || "")
39
47
  end
48
+ sub_figures_html = sub_figures_parts.join
40
49
 
41
- key_html = renderer.capture_output do
42
- renderer.safe_attr(figure, :note)&.each do |n|
43
- renderer.render_note(n)
44
- end
45
- renderer.safe_attr(figure, :dl)&.then do |dl|
46
- renderer.render_definition_list(dl)
47
- end
50
+ key_parts = []
51
+ renderer.safe_attr(figure, :note)&.each do |n|
52
+ key_parts << (renderer.render_note(n) || "")
53
+ end
54
+ renderer.safe_attr(figure, :dl)&.then do |dl|
55
+ key_parts << (renderer.render_definition_list(dl) || "")
48
56
  end
57
+ key_html = key_parts.join
49
58
 
50
59
  new(
51
60
  id: id,
@@ -13,7 +13,7 @@ module Metanorma
13
13
  @entry.number
14
14
  end
15
15
 
16
- def reference
16
+ def label
17
17
  @entry.reference
18
18
  end
19
19
 
@@ -4,45 +4,74 @@ module Metanorma
4
4
  module Html
5
5
  module Drops
6
6
  class FormulaDrop < BlockElementDrop
7
- attr_reader :stem_html, :where_html, :number_html
7
+ attr_reader :stem_html, :where_html, :where_label, :number_html
8
+
9
+ def initialize(id: nil, stem_html: nil, where_html: nil, where_label: nil,
10
+ number_html: nil, css_class: nil)
11
+ @id = id
12
+ @stem_html = stem_html
13
+ @where_html = where_html
14
+ @where_label = where_label
15
+ @number_html = number_html
16
+ @css_class = css_class
17
+ end
8
18
 
9
19
  def self.from_model(formula, renderer:)
10
20
  id = renderer.safe_attr(formula, :id)
11
21
 
12
- stem_html = renderer.capture_output do
13
- renderer.render_stem_content(formula.stem) if formula.stem
14
- end
22
+ stem_html = if formula.stem
23
+ renderer.render_stem_content(formula.stem)
24
+ end
15
25
 
16
- where_html = renderer.capture_output do
17
- if formula.key
18
- if formula.key.dl
19
- @output = renderer.capture_output {}
20
- # "where" label rendered in template, just render the dl
21
- renderer.render_definition_list(formula.key.dl)
22
- end
23
- formula.key.p&.each { |para| renderer.render_paragraph(para) }
26
+ where_parts = []
27
+ if formula.key
28
+ if formula.key.dl
29
+ where_parts << (renderer.render_definition_list(formula.key.dl) || "")
30
+ end
31
+ formula.key.p&.each do |para|
32
+ where_parts << (renderer.render_paragraph(para) || "")
24
33
  end
25
- formula.dl&.then { |dl| renderer.render_definition_list(dl) }
26
34
  end
35
+ formula.dl&.then do |dl|
36
+ where_parts << (renderer.render_definition_list(dl) || "")
37
+ end
38
+ formula.p&.each do |para|
39
+ next if renderer.safe_attr(para, :keep_with_next)
40
+
41
+ where_parts << (renderer.render_paragraph(para) || "")
42
+ end
43
+ where_html = where_parts.join
44
+
45
+ needs_where_label = !formula.key.nil? || !formula.dl.nil? ||
46
+ has_where_paragraph?(formula, renderer)
27
47
 
28
48
  name_el = renderer.safe_attr(formula,
29
49
  :fmt_name) || renderer.safe_attr(
30
50
  formula, :name
31
51
  )
32
52
  number_html = if name_el
33
- renderer.capture_output do
34
- renderer.render_inline_element(name_el)
35
- end
53
+ renderer.render_inline_element(name_el)
36
54
  end
37
55
 
38
56
  new(
39
57
  id: id,
40
58
  stem_html: stem_html,
41
59
  where_html: where_html,
60
+ where_label: needs_where_label,
42
61
  number_html: number_html,
43
62
  css_class: "formula",
44
63
  )
45
64
  end
65
+
66
+ class << self
67
+ private
68
+
69
+ def has_where_paragraph?(formula, renderer)
70
+ Array(formula.p).any? do |para|
71
+ renderer.safe_attr(para, :keep_with_next)
72
+ end
73
+ end
74
+ end
46
75
  end
47
76
  end
48
77
  end