metanorma-document 0.2.8 → 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 (418) 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/note_block.rb +1 -1
  118. data/lib/metanorma/document/components/blocks/permission_model.rb +28 -0
  119. data/lib/metanorma/document/components/blocks/recommendation_model.rb +28 -0
  120. data/lib/metanorma/document/components/blocks/requirement_base.rb +30 -0
  121. data/lib/metanorma/document/components/blocks/requirement_classification.rb +20 -0
  122. data/lib/metanorma/document/components/blocks/requirement_description.rb +43 -0
  123. data/lib/metanorma/document/components/blocks/requirement_inherit.rb +24 -0
  124. data/lib/metanorma/document/components/blocks/requirement_model.rb +0 -131
  125. data/lib/metanorma/document/components/blocks.rb +8 -7
  126. data/lib/metanorma/document/components/id_elements/image.rb +2 -0
  127. data/lib/metanorma/document/components/inline/asciimath_element.rb +2 -0
  128. data/lib/metanorma/document/components/inline/attribution_element.rb +2 -0
  129. data/lib/metanorma/document/components/inline/bcp14_element.rb +2 -0
  130. data/lib/metanorma/document/components/inline/biblio_tag_element.rb +2 -0
  131. data/lib/metanorma/document/components/inline/br_element.rb +2 -0
  132. data/lib/metanorma/document/components/inline/comma_element.rb +2 -0
  133. data/lib/metanorma/document/components/inline/concept_element.rb +2 -0
  134. data/lib/metanorma/document/components/inline/display_text_element.rb +2 -0
  135. data/lib/metanorma/document/components/inline/em_raw_element.rb +2 -0
  136. data/lib/metanorma/document/components/inline/enum_comma_element.rb +2 -0
  137. data/lib/metanorma/document/components/inline/eref_element.rb +3 -1
  138. data/lib/metanorma/document/components/inline/fmt_admitted_element.rb +4 -0
  139. data/lib/metanorma/document/components/inline/fmt_annotation_body_element.rb +4 -0
  140. data/lib/metanorma/document/components/inline/fmt_annotation_end_element.rb +4 -0
  141. data/lib/metanorma/document/components/inline/fmt_annotation_start_element.rb +4 -0
  142. data/lib/metanorma/document/components/inline/fmt_concept_element.rb +4 -0
  143. data/lib/metanorma/document/components/inline/fmt_definition_element.rb +4 -0
  144. data/lib/metanorma/document/components/inline/fmt_fn_body_element.rb +4 -0
  145. data/lib/metanorma/document/components/inline/fmt_fn_label_element.rb +4 -0
  146. data/lib/metanorma/document/components/inline/fmt_footnote_container_element.rb +4 -0
  147. data/lib/metanorma/document/components/inline/fmt_identifier_element.rb +4 -0
  148. data/lib/metanorma/document/components/inline/fmt_name_element.rb +4 -0
  149. data/lib/metanorma/document/components/inline/fmt_preferred_element.rb +4 -0
  150. data/lib/metanorma/document/components/inline/fmt_sourcecode_element.rb +4 -0
  151. data/lib/metanorma/document/components/inline/fmt_stem_element.rb +10 -0
  152. data/lib/metanorma/document/components/inline/fmt_termsource_element.rb +4 -0
  153. data/lib/metanorma/document/components/inline/fmt_title_element.rb +4 -0
  154. data/lib/metanorma/document/components/inline/fmt_xref_element.rb +4 -0
  155. data/lib/metanorma/document/components/inline/fmt_xref_label_element.rb +4 -0
  156. data/lib/metanorma/document/components/inline/fn_element.rb +3 -1
  157. data/lib/metanorma/document/components/inline/link_element.rb +2 -0
  158. data/lib/metanorma/document/components/inline/localized_string_element.rb +2 -0
  159. data/lib/metanorma/document/components/inline/localized_strings_element.rb +2 -0
  160. data/lib/metanorma/document/components/inline/location_element.rb +24 -0
  161. data/lib/metanorma/document/components/inline/math_element.rb +2 -0
  162. data/lib/metanorma/document/components/inline/name_with_id_element.rb +4 -0
  163. data/lib/metanorma/document/components/inline/rendered_display.rb +23 -0
  164. data/lib/metanorma/document/components/inline/rendered_math_element.rb +21 -0
  165. data/lib/metanorma/document/components/inline/semantic_content.rb +51 -0
  166. data/lib/metanorma/document/components/inline/semantic_math_element.rb +20 -0
  167. data/lib/metanorma/document/components/inline/semx_child_element.rb +2 -0
  168. data/lib/metanorma/document/components/inline/semx_element.rb +13 -1
  169. data/lib/metanorma/document/components/inline/small_cap_element.rb +2 -0
  170. data/lib/metanorma/document/components/inline/span_element.rb +10 -15
  171. data/lib/metanorma/document/components/inline/stem_inline_element.rb +7 -1
  172. data/lib/metanorma/document/components/inline/strong_raw_element.rb +2 -0
  173. data/lib/metanorma/document/components/inline/sub_element.rb +2 -0
  174. data/lib/metanorma/document/components/inline/sup_element.rb +2 -0
  175. data/lib/metanorma/document/components/inline/tab_element.rb +2 -0
  176. data/lib/metanorma/document/components/inline/title_with_annotation_element.rb +4 -0
  177. data/lib/metanorma/document/components/inline/tt_element.rb +2 -0
  178. data/lib/metanorma/document/components/inline/variant_title_element.rb +2 -0
  179. data/lib/metanorma/document/components/inline/vocabulary.rb +184 -0
  180. data/lib/metanorma/document/components/inline/xref_element.rb +10 -0
  181. data/lib/metanorma/document/components/inline.rb +12 -0
  182. data/lib/metanorma/document/components/lists/unordered_list.rb +2 -2
  183. data/lib/metanorma/document/components/multi_paragraph/admonition_block.rb +5 -2
  184. data/lib/metanorma/document/components/multi_paragraph/quote_author_element.rb +20 -0
  185. data/lib/metanorma/document/components/multi_paragraph/quote_block.rb +0 -29
  186. data/lib/metanorma/document/components/multi_paragraph.rb +2 -0
  187. data/lib/metanorma/document/components/paragraphs/paragraph_block.rb +2 -2
  188. data/lib/metanorma/document/components/reference_elements/source_element.rb +0 -31
  189. data/lib/metanorma/document/components/reference_elements/source_modification.rb +21 -0
  190. data/lib/metanorma/document/components/reference_elements/source_origin.rb +28 -0
  191. data/lib/metanorma/document/components/reference_elements.rb +2 -2
  192. data/lib/metanorma/document/components/tables/col_element.rb +18 -0
  193. data/lib/metanorma/document/components/tables/col_group_element.rb +18 -0
  194. data/lib/metanorma/document/components/tables/table_block.rb +0 -22
  195. data/lib/metanorma/document/components/tables/table_body_section.rb +16 -0
  196. data/lib/metanorma/document/components/tables/table_foot_section.rb +16 -0
  197. data/lib/metanorma/document/components/tables/table_head_section.rb +16 -0
  198. data/lib/metanorma/document/components/tables/table_section.rb +0 -25
  199. data/lib/metanorma/document/components/tables.rb +5 -3
  200. data/lib/metanorma/document/relaton/address.rb +0 -27
  201. data/lib/metanorma/document/relaton/bib_item_locality.rb +3 -12
  202. data/lib/metanorma/document/relaton/copyright_association.rb +0 -10
  203. data/lib/metanorma/document/relaton/copyright_owner.rb +16 -0
  204. data/lib/metanorma/document/relaton/edition.rb +4 -7
  205. data/lib/metanorma/document/relaton/formatted_address.rb +29 -0
  206. data/lib/metanorma/document/relaton/logo_element.rb +18 -0
  207. data/lib/metanorma/document/relaton/organization.rb +0 -14
  208. data/lib/metanorma/document/relaton/phone.rb +3 -9
  209. data/lib/metanorma/document/relaton/place_type.rb +0 -13
  210. data/lib/metanorma/document/relaton/price_type.rb +3 -9
  211. data/lib/metanorma/document/relaton/region_element.rb +18 -0
  212. data/lib/metanorma/document/relaton.rb +6 -1
  213. data/lib/metanorma/document/version.rb +1 -1
  214. data/lib/metanorma/document.rb +2 -0
  215. data/lib/metanorma/html/asset_pipeline.rb +1 -0
  216. data/lib/metanorma/html/base_renderer.rb +261 -1008
  217. data/lib/metanorma/html/bipm_renderer.rb +15 -144
  218. data/lib/metanorma/html/cc_renderer.rb +1 -45
  219. data/lib/metanorma/html/component/base.rb +2 -7
  220. data/lib/metanorma/html/component/index_section.rb +41 -43
  221. data/lib/metanorma/html/drops/admonition_drop.rb +1 -4
  222. data/lib/metanorma/html/drops/biblio_entry_drop.rb +50 -0
  223. data/lib/metanorma/html/drops/block_element_drop.rb +7 -2
  224. data/lib/metanorma/html/drops/example_drop.rb +1 -4
  225. data/lib/metanorma/html/drops/figure_drop.rb +31 -22
  226. data/lib/metanorma/html/drops/footnote_drop.rb +1 -1
  227. data/lib/metanorma/html/drops/formula_drop.rb +45 -16
  228. data/lib/metanorma/html/drops/note_drop.rb +9 -7
  229. data/lib/metanorma/html/drops/sourcecode_drop.rb +12 -5
  230. data/lib/metanorma/html/drops.rb +2 -0
  231. data/lib/metanorma/html/generator.rb +2 -2
  232. data/lib/metanorma/html/icc_renderer.rb +0 -39
  233. data/lib/metanorma/html/iec_renderer.rb +1 -44
  234. data/lib/metanorma/html/ieee_renderer.rb +1 -45
  235. data/lib/metanorma/html/ietf_renderer.rb +1 -48
  236. data/lib/metanorma/html/iho_renderer.rb +1 -46
  237. data/lib/metanorma/html/iso_renderer.rb +291 -321
  238. data/lib/metanorma/html/itu_renderer.rb +1 -45
  239. data/lib/metanorma/html/ogc_renderer.rb +15 -76
  240. data/lib/metanorma/html/oiml_renderer.rb +18 -38
  241. data/lib/metanorma/html/pdfa_renderer.rb +0 -39
  242. data/lib/metanorma/html/renderers/block_renderer.rb +372 -0
  243. data/lib/metanorma/html/renderers/inline_renderer.rb +655 -0
  244. data/lib/metanorma/html/renderers/pubid_renderer.rb +69 -0
  245. data/lib/metanorma/html/renderers/section_renderer.rb +193 -0
  246. data/lib/metanorma/html/renderers.rb +8 -0
  247. data/lib/metanorma/html/ribose_renderer.rb +1 -45
  248. data/lib/metanorma/html/standard_renderer.rb +341 -229
  249. data/lib/metanorma/html/templates/_audio.html.liquid +1 -0
  250. data/lib/metanorma/html/templates/_biblio_entry.html.liquid +1 -0
  251. data/lib/metanorma/html/templates/_bipm_cover.html.liquid +27 -0
  252. data/lib/metanorma/html/templates/_boilerplate.html.liquid +1 -0
  253. data/lib/metanorma/html/templates/_bookmark.html.liquid +1 -0
  254. data/lib/metanorma/html/templates/_br.html.liquid +1 -0
  255. data/lib/metanorma/html/templates/_definition_list.html.liquid +6 -0
  256. data/lib/metanorma/html/templates/_element.html.liquid +1 -0
  257. data/lib/metanorma/html/templates/_fn_marker.html.liquid +1 -0
  258. data/lib/metanorma/html/templates/_footnotes.html.liquid +6 -6
  259. data/lib/metanorma/html/templates/_formula.html.liquid +1 -1
  260. data/lib/metanorma/html/templates/_header.html.liquid +1 -1
  261. data/lib/metanorma/html/templates/_heading.html.liquid +1 -0
  262. data/lib/metanorma/html/templates/_image.html.liquid +1 -0
  263. data/lib/metanorma/html/templates/_inline_span.html.liquid +1 -0
  264. data/lib/metanorma/html/templates/_iso_cover.html.liquid +1 -1
  265. data/lib/metanorma/html/templates/_link.html.liquid +1 -0
  266. data/lib/metanorma/html/templates/_list.html.liquid +3 -0
  267. data/lib/metanorma/html/templates/_list_item.html.liquid +1 -0
  268. data/lib/metanorma/html/templates/_main_content.html.liquid +1 -0
  269. data/lib/metanorma/html/templates/_math_container.html.liquid +1 -0
  270. data/lib/metanorma/html/templates/_paragraph.html.liquid +1 -0
  271. data/lib/metanorma/html/templates/_prefatory_section.html.liquid +1 -0
  272. data/lib/metanorma/html/templates/_pubid_identifier.html.liquid +1 -0
  273. data/lib/metanorma/html/templates/_quote.html.liquid +4 -0
  274. data/lib/metanorma/html/templates/_ref_date.html.liquid +1 -0
  275. data/lib/metanorma/html/templates/_ref_title.html.liquid +1 -0
  276. data/lib/metanorma/html/templates/_section.html.liquid +5 -0
  277. data/lib/metanorma/html/templates/_standard_cover.html.liquid +31 -0
  278. data/lib/metanorma/html/templates/_standard_doc_title.html.liquid +3 -0
  279. data/lib/metanorma/html/templates/_stem_span.html.liquid +1 -0
  280. data/lib/metanorma/html/templates/_table.html.liquid +9 -0
  281. data/lib/metanorma/html/templates/_term_domain.html.liquid +1 -0
  282. data/lib/metanorma/html/templates/_term_example.html.liquid +1 -0
  283. data/lib/metanorma/html/templates/_term_note.html.liquid +1 -0
  284. data/lib/metanorma/html/templates/_term_number.html.liquid +1 -0
  285. data/lib/metanorma/html/templates/_term_source.html.liquid +1 -0
  286. data/lib/metanorma/html/templates/_term_text_note.html.liquid +1 -0
  287. data/lib/metanorma/html/templates/_video.html.liquid +1 -0
  288. data/lib/metanorma/html/templates/_wrapped_preface.html.liquid +1 -0
  289. data/lib/metanorma/html/templates/document.html.liquid +4 -0
  290. data/lib/metanorma/html/theme.rb +180 -107
  291. data/lib/metanorma/html.rb +13 -0
  292. data/lib/metanorma/ietf_document/metadata/ietf_bib_data_extension_type.rb +0 -25
  293. data/lib/metanorma/ietf_document/metadata/pi_settings.rb +32 -0
  294. data/lib/metanorma/ietf_document/metadata.rb +2 -0
  295. data/lib/metanorma/ietf_document/sections/ietf_annex_section.rb +1 -1
  296. data/lib/metanorma/ietf_document/sections/ietf_clause_section.rb +1 -1
  297. data/lib/metanorma/ietf_document/sections/ietf_content_section.rb +1 -1
  298. data/lib/metanorma/iso_document/metadata/doc_identifier.rb +1 -1
  299. data/lib/metanorma/iso_document/metadata/doctype_element.rb +20 -0
  300. data/lib/metanorma/iso_document/metadata/iso_bib_data_extension_type.rb +0 -48
  301. data/lib/metanorma/iso_document/metadata/iso_bibliographic_item.rb +0 -72
  302. data/lib/metanorma/iso_document/metadata/iso_document_status.rb +0 -30
  303. data/lib/metanorma/iso_document/metadata/iso_localized_title.rb +4 -1
  304. data/lib/metanorma/iso_document/metadata/language_element.rb +18 -0
  305. data/lib/metanorma/iso_document/metadata/project_number.rb +22 -0
  306. data/lib/metanorma/iso_document/metadata/script_element.rb +18 -0
  307. data/lib/metanorma/iso_document/metadata/stage_element.rb +26 -0
  308. data/lib/metanorma/iso_document/metadata/stagename_element.rb +18 -0
  309. data/lib/metanorma/iso_document/metadata/structured_identifier.rb +0 -17
  310. data/lib/metanorma/iso_document/metadata/title_collection.rb +1 -0
  311. data/lib/metanorma/iso_document/metadata.rb +9 -4
  312. data/lib/metanorma/iso_document/sections/iso_terms_section.rb +4 -3
  313. data/lib/metanorma/iso_document/terms/iso_term.rb +0 -13
  314. data/lib/metanorma/iso_document/terms/term_domain_element.rb +18 -0
  315. data/lib/metanorma/iso_document/terms/term_example.rb +2 -1
  316. data/lib/metanorma/iso_document/terms/term_note.rb +2 -1
  317. data/lib/metanorma/iso_document/terms/verbal_definition.rb +2 -1
  318. data/lib/metanorma/iso_document/terms.rb +1 -0
  319. data/lib/metanorma/iso_document.rb +0 -1
  320. data/lib/metanorma/itu_document/metadata/itu_bib_data_extension_type.rb +0 -37
  321. data/lib/metanorma/itu_document/metadata/meeting_date.rb +18 -0
  322. data/lib/metanorma/itu_document/metadata/meeting_element.rb +18 -0
  323. data/lib/metanorma/itu_document/metadata/study_period.rb +18 -0
  324. data/lib/metanorma/itu_document/metadata.rb +3 -4
  325. data/lib/metanorma/jis_document/sections/jis_annex_section.rb +1 -1
  326. data/lib/metanorma/mirror/default_registry.rb +170 -0
  327. data/lib/metanorma/mirror/handler_registry.rb +60 -0
  328. data/lib/metanorma/mirror/handler_result.rb +37 -0
  329. data/lib/metanorma/mirror/handlers/admonition.rb +18 -0
  330. data/lib/metanorma/mirror/handlers/example.rb +21 -0
  331. data/lib/metanorma/mirror/handlers/figure.rb +53 -0
  332. data/lib/metanorma/mirror/handlers/formula.rb +35 -0
  333. data/lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb +159 -0
  334. data/lib/metanorma/mirror/handlers/inline/text_extractor.rb +116 -0
  335. data/lib/metanorma/mirror/handlers/inline.rb +225 -0
  336. data/lib/metanorma/mirror/handlers/list.rb +110 -0
  337. data/lib/metanorma/mirror/handlers/note.rb +26 -0
  338. data/lib/metanorma/mirror/handlers/paragraph.rb +19 -0
  339. data/lib/metanorma/mirror/handlers/quote.rb +16 -0
  340. data/lib/metanorma/mirror/handlers/review.rb +19 -0
  341. data/lib/metanorma/mirror/handlers/section.rb +149 -0
  342. data/lib/metanorma/mirror/handlers/sourcecode.rb +27 -0
  343. data/lib/metanorma/mirror/handlers/structural.rb +68 -0
  344. data/lib/metanorma/mirror/handlers/table.rb +81 -0
  345. data/lib/metanorma/mirror/handlers/term.rb +100 -0
  346. data/lib/metanorma/mirror/handlers.rb +60 -0
  347. data/lib/metanorma/mirror/id_strategy/positional.rb +166 -0
  348. data/lib/metanorma/mirror/id_strategy/preserve.rb +12 -0
  349. data/lib/metanorma/mirror/id_strategy.rb +34 -0
  350. data/lib/metanorma/mirror/math_util.rb +53 -0
  351. data/lib/metanorma/mirror/metadata.rb +37 -0
  352. data/lib/metanorma/mirror/metanorma_to_mirror.rb +101 -0
  353. data/lib/metanorma/mirror/model/container.rb +47 -0
  354. data/lib/metanorma/mirror/model/factory.rb +52 -0
  355. data/lib/metanorma/mirror/model/guide.rb +25 -0
  356. data/lib/metanorma/mirror/model/leaf.rb +17 -0
  357. data/lib/metanorma/mirror/model/mark.rb +53 -0
  358. data/lib/metanorma/mirror/model/node.rb +47 -0
  359. data/lib/metanorma/mirror/model/soft_break.rb +33 -0
  360. data/lib/metanorma/mirror/model/text.rb +34 -0
  361. data/lib/metanorma/mirror/model.rb +16 -0
  362. data/lib/metanorma/mirror/output/builder.rb +39 -0
  363. data/lib/metanorma/mirror/output/formats/base_format.rb +90 -0
  364. data/lib/metanorma/mirror/output/formats/inline_format.rb +81 -0
  365. data/lib/metanorma/mirror/output/formats.rb +53 -0
  366. data/lib/metanorma/mirror/output/html_renderer.rb +95 -0
  367. data/lib/metanorma/mirror/output/html_renderers/block_renderers.rb +178 -0
  368. data/lib/metanorma/mirror/output/html_renderers/inline_renderer.rb +61 -0
  369. data/lib/metanorma/mirror/output/html_renderers/list_renderers.rb +96 -0
  370. data/lib/metanorma/mirror/output/html_renderers/mark_renderers.rb +64 -0
  371. data/lib/metanorma/mirror/output/html_renderers/section_renderers.rb +129 -0
  372. data/lib/metanorma/mirror/output/html_renderers/structural_renderers.rb +80 -0
  373. data/lib/metanorma/mirror/output/html_renderers/table_renderers.rb +87 -0
  374. data/lib/metanorma/mirror/output/html_renderers.rb +76 -0
  375. data/lib/metanorma/mirror/output/pipeline.rb +92 -0
  376. data/lib/metanorma/mirror/output/pipeline_context.rb +22 -0
  377. data/lib/metanorma/mirror/output.rb +14 -0
  378. data/lib/metanorma/mirror/rewriter.rb +121 -0
  379. data/lib/metanorma/mirror/safe_attr.rb +16 -0
  380. data/lib/metanorma/mirror/serialization/json_serializer.rb +25 -0
  381. data/lib/metanorma/mirror/serialization/yaml_serializer.rb +20 -0
  382. data/lib/metanorma/mirror/serialization.rb +10 -0
  383. data/lib/metanorma/mirror/transformer.rb +22 -0
  384. data/lib/metanorma/mirror.rb +32 -0
  385. data/lib/metanorma/standard_document/annotation.rb +37 -0
  386. data/lib/metanorma/standard_document/annotation_container.rb +25 -2
  387. data/lib/metanorma/standard_document/block_attributes.rb +15 -2
  388. data/lib/metanorma/standard_document/blocks/amend_content_block.rb +21 -3
  389. data/lib/metanorma/standard_document/blocks/block_source.rb +0 -23
  390. data/lib/metanorma/standard_document/blocks/source_origin_element.rb +23 -0
  391. data/lib/metanorma/standard_document/blocks/standard_block_no_notes.rb +2 -2
  392. data/lib/metanorma/standard_document/blocks.rb +1 -1
  393. data/lib/metanorma/standard_document/boilerplate.rb +20 -2
  394. data/lib/metanorma/standard_document/sections/annex_section.rb +2 -2
  395. data/lib/metanorma/standard_document/sections/clause_hierarchical_section.rb +1 -1
  396. data/lib/metanorma/standard_document/sections/clause_section.rb +2 -2
  397. data/lib/metanorma/standard_document/sections/definition_section.rb +2 -2
  398. data/lib/metanorma/standard_document/sections/standard_content_section.rb +2 -2
  399. data/lib/metanorma/standard_document/sections/standard_hierarchical_section.rb +1 -1
  400. data/lib/metanorma/standard_document/sections/standard_references_section.rb +2 -2
  401. data/lib/metanorma/standard_document/sections/standard_section.rb +1 -1
  402. data/lib/metanorma/standard_document/sections/terms_section.rb +2 -2
  403. data/lib/metanorma/standard_document/terms/term_expression.rb +0 -31
  404. data/lib/metanorma/standard_document/terms/term_name_element.rb +29 -0
  405. data/lib/metanorma/standard_document/terms.rb +1 -0
  406. data/script/render_both.rb +18 -0
  407. metadata +262 -14
  408. data/.github/workflows/rake.yml +0 -21
  409. data/.github/workflows/release.yml +0 -25
  410. data/.github/workflows/roundtrip-samples.yml +0 -132
  411. data/.gitignore +0 -19
  412. data/.rspec +0 -3
  413. data/.rubocop.yml +0 -22
  414. data/Gemfile +0 -28
  415. data/bin/console +0 -15
  416. data/bin/setup +0 -8
  417. data/lib/metanorma/iso_document/raw_paragraph.rb +0 -23
  418. data/metanorma-document.gemspec +0 -35
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ class MetanormaToMirror
6
+ attr_reader :registry, :id_strategy
7
+
8
+ def initialize(registry: Mirror.default_registry,
9
+ id_strategy: Mirror.DEFAULT_ID_STRATEGY)
10
+ @registry = registry
11
+ @id_strategy = id_strategy
12
+ end
13
+
14
+ def call(root)
15
+ attrs = {}
16
+ attrs[:flavor] = root.flavor if root.flavor
17
+ attrs[:type] = root.type if root.type
18
+ attrs[:schema_version] = root.schema_version if root.schema_version
19
+
20
+ title = extract_root_title(root)
21
+ attrs[:title] = title if title
22
+
23
+ content = []
24
+
25
+ preface = root.preface
26
+ if preface
27
+ result = @registry.handle(preface, context: self)
28
+ result.append_to(content)
29
+ end
30
+
31
+ sections = root.sections
32
+ if sections
33
+ result = @registry.handle(sections, context: self)
34
+ result.append_to(content)
35
+ end
36
+
37
+ annex = root.annex
38
+ annex&.each do |a|
39
+ result = @registry.handle(a, context: self)
40
+ result.append_to(content)
41
+ end
42
+
43
+ bibliography = root.bibliography
44
+ if bibliography
45
+ result = @registry.handle(bibliography, context: self)
46
+ result.append_to(content)
47
+ end
48
+
49
+ Handlers.build_node("doc", attrs: attrs, content: content)
50
+ end
51
+
52
+ def extract_blocks(element)
53
+ content = []
54
+
55
+ element.each_mixed_content do |node|
56
+ next if node.is_a?(String)
57
+
58
+ result = @registry.handle(node, context: self)
59
+ result.append_to(content)
60
+ end
61
+ content
62
+ end
63
+
64
+ def extract_section_children(element)
65
+ content = []
66
+ %i[clause terms definitions references floating_title].each do |attr|
67
+ collection = SafeAttr.read(element, attr)
68
+ next unless collection
69
+
70
+ collection.each do |child|
71
+ result = @registry.handle(child, context: self)
72
+ result.append_to(content)
73
+ end
74
+ end
75
+ content
76
+ end
77
+
78
+ def extract_named_collections(element, collection_attrs)
79
+ content = []
80
+ collection_attrs.each do |attr|
81
+ collection = SafeAttr.read(element, attr)
82
+ next unless collection
83
+
84
+ collection.each do |child|
85
+ result = @registry.handle(child, context: self)
86
+ result.append_to(content)
87
+ end
88
+ end
89
+ content
90
+ end
91
+
92
+ def text_node(text, marks: [])
93
+ Handlers.build_text(text, marks: marks)
94
+ end
95
+
96
+ def extract_root_title(root)
97
+ Metadata.title_from_bibdata(SafeAttr.read(root, :bibdata))
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class Container < Node
7
+ attr_reader :content
8
+
9
+ def initialize(type:, attrs: {}, content: [])
10
+ super(type: type, attrs: attrs)
11
+ @content = Array(content)
12
+ end
13
+
14
+ def container?
15
+ true
16
+ end
17
+
18
+ def to_h
19
+ h = super
20
+ unless @content.empty?
21
+ h["content"] = @content.map { |c| serialize_child(c) }
22
+ end
23
+ h
24
+ end
25
+
26
+ def text_content
27
+ @content.map do |item|
28
+ item.is_a?(String) ? item : item.text_content
29
+ end.join
30
+ end
31
+
32
+ def accept_rewriter(rewriter)
33
+ rewriter.rewrite_container(self)
34
+ end
35
+
36
+ private
37
+
38
+ def serialize_child(child)
39
+ case child
40
+ when String then child
41
+ else child.to_h
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class Factory
7
+ INVALID_INPUT = "Factory.from_h expects a Hash, got %<class>s"
8
+
9
+ def self.from_h(hash)
10
+ unless hash.is_a?(Hash)
11
+ raise ArgumentError,
12
+ format(INVALID_INPUT, class: hash.class)
13
+ end
14
+
15
+ type = hash["type"]
16
+
17
+ case type
18
+ when "text"
19
+ build_text(hash)
20
+ when "soft_break"
21
+ SoftBreak.new
22
+ when nil
23
+ raise ArgumentError,
24
+ "Factory.from_h requires a 'type' key, got #{hash.inspect}"
25
+ else
26
+ build_node(hash, type)
27
+ end
28
+ end
29
+
30
+ class << self
31
+ private
32
+
33
+ def build_text(hash)
34
+ marks = Array(hash["marks"]).map { |m| Mark.from_h(m) }
35
+ Text.new(text: hash["text"] || "", marks: marks)
36
+ end
37
+
38
+ def build_node(hash, type)
39
+ content = hash["content"]
40
+ if content.is_a?(Array)
41
+ children = content.map { |c| c.is_a?(Hash) ? from_h(c) : c }
42
+ Container.new(type: type, attrs: hash["attrs"] || {},
43
+ content: children)
44
+ else
45
+ Leaf.new(type: type, attrs: hash["attrs"] || {})
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class Guide
7
+ attr_reader :content, :meta, :title
8
+
9
+ def initialize(content:, meta: {}, title: nil)
10
+ @content = content
11
+ @meta = meta
12
+ @title = title
13
+ end
14
+
15
+ def to_h
16
+ h = {}
17
+ h["content"] = @content.is_a?(Container) ? @content.to_h : @content
18
+ h["meta"] = @meta unless @meta.nil? || @meta.empty?
19
+ h["title"] = @title if @title
20
+ h
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class Leaf < Node
7
+ def leaf?
8
+ true
9
+ end
10
+
11
+ def accept_rewriter(rewriter)
12
+ rewriter.rewrite_leaf(self)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class Mark
7
+ attr_reader :type, :attrs
8
+
9
+ def initialize(type:, attrs: {})
10
+ @type = type
11
+ @attrs = normalize_attrs(attrs)
12
+ end
13
+
14
+ def to_h
15
+ h = { "type" => type }
16
+ h["attrs"] = @attrs.dup unless @attrs.empty?
17
+ h
18
+ end
19
+
20
+ def [](key)
21
+ @attrs[key.to_s]
22
+ end
23
+
24
+ def []=(key, value)
25
+ @attrs[key.to_s] = value
26
+ end
27
+
28
+ def set_attr(key, value)
29
+ @attrs[key.to_s] = value
30
+ self
31
+ end
32
+
33
+ def fetch(key, default = nil, &)
34
+ @attrs.fetch(key.to_s, default, &)
35
+ end
36
+
37
+ def self.from_h(hash)
38
+ return nil unless hash
39
+
40
+ new(type: hash["type"], attrs: hash["attrs"] || {})
41
+ end
42
+
43
+ private
44
+
45
+ def normalize_attrs(attrs)
46
+ return {} if attrs.nil?
47
+
48
+ attrs.transform_keys(&:to_s)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class Node
7
+ attr_reader :type, :attrs
8
+
9
+ def initialize(type:, attrs: {})
10
+ @type = type
11
+ @attrs = normalize_attrs(attrs)
12
+ end
13
+
14
+ def to_h
15
+ h = { "type" => type }
16
+ h["attrs"] = @attrs.dup unless @attrs.empty?
17
+ h
18
+ end
19
+
20
+ def leaf?
21
+ false
22
+ end
23
+
24
+ def container?
25
+ false
26
+ end
27
+
28
+ def text_content
29
+ ""
30
+ end
31
+
32
+ def accept_rewriter(_rewriter)
33
+ raise NotImplementedError,
34
+ "#{self.class}#accept_rewriter not implemented"
35
+ end
36
+
37
+ private
38
+
39
+ def normalize_attrs(attrs)
40
+ return {} if attrs.nil?
41
+
42
+ attrs.transform_keys(&:to_s)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class SoftBreak
7
+ def type
8
+ "soft_break"
9
+ end
10
+
11
+ def to_h
12
+ { "type" => "soft_break" }
13
+ end
14
+
15
+ def attrs
16
+ {}
17
+ end
18
+
19
+ def content
20
+ []
21
+ end
22
+
23
+ def text_content
24
+ ""
25
+ end
26
+
27
+ def accept_rewriter(rewriter)
28
+ rewriter.rewrite_soft_break(self)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ class Text
7
+ attr_reader :text, :marks
8
+
9
+ def initialize(text:, marks: [])
10
+ @text = text.to_s
11
+ @marks = Array(marks)
12
+ end
13
+
14
+ def type
15
+ "text"
16
+ end
17
+
18
+ def to_h
19
+ h = { "type" => "text", "text" => @text }
20
+ h["marks"] = @marks.map(&:to_h) unless @marks.empty?
21
+ h
22
+ end
23
+
24
+ def text_content
25
+ @text
26
+ end
27
+
28
+ def accept_rewriter(rewriter)
29
+ rewriter.rewrite_text(self)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Model
6
+ autoload :Node, "#{__dir__}/model/node"
7
+ autoload :Container, "#{__dir__}/model/container"
8
+ autoload :Leaf, "#{__dir__}/model/leaf"
9
+ autoload :Text, "#{__dir__}/model/text"
10
+ autoload :SoftBreak, "#{__dir__}/model/soft_break"
11
+ autoload :Mark, "#{__dir__}/model/mark"
12
+ autoload :Guide, "#{__dir__}/model/guide"
13
+ autoload :Factory, "#{__dir__}/model/factory"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Metanorma
6
+ module Mirror
7
+ module Output
8
+ class Builder
9
+ attr_reader :xml_path, :output_path, :format, :options
10
+
11
+ def initialize(xml_path:, output_path:, format: :inline, **options)
12
+ @xml_path = xml_path
13
+ @output_path = output_path
14
+ @format = format
15
+ @options = options
16
+ end
17
+
18
+ def build
19
+ pipeline = Pipeline.new(
20
+ xml_path: @xml_path,
21
+ flavor: @options[:flavor],
22
+ title: @options[:title] || File.basename(@xml_path, ".*"),
23
+ id_strategy: @options[:id_strategy],
24
+ )
25
+
26
+ guide = pipeline.process
27
+
28
+ format_class = Formats.lookup(@format)
29
+ raise ArgumentError, "Unknown format: #{@format}" unless format_class
30
+
31
+ formatter = format_class.new(dist_dir: @options[:dist_dir])
32
+ formatter.write(@output_path, guide, title: @options[:title])
33
+
34
+ @output_path
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module Metanorma
6
+ module Mirror
7
+ module Output
8
+ module Formats
9
+ class BaseFormat
10
+ attr_reader :dist_dir
11
+
12
+ def initialize(dist_dir: nil)
13
+ @dist_dir = dist_dir || self.class.default_dist_dir
14
+ end
15
+
16
+ def write(output_path, guide, title: "Metanorma")
17
+ raise NotImplementedError, "#{self.class}#write not implemented"
18
+ end
19
+
20
+ class << self
21
+ attr_accessor :configured_dist_dir
22
+
23
+ def default_dist_dir
24
+ @configured_dist_dir || File.expand_path(
25
+ "../../../../../frontend/dist", __dir__
26
+ )
27
+ end
28
+ end
29
+
30
+ protected
31
+
32
+ def safe_json(data)
33
+ JSON.generate(data).gsub("</script", '<\\/script')
34
+ end
35
+
36
+ def html_boilerplate(title:, body_content:, head_extra: "",
37
+ script_data: nil, app_mount_id: nil)
38
+ Nokogiri::HTML5::Builder.new do |doc|
39
+ doc.html(lang: "en") do
40
+ build_head(doc, title:, head_extra:, script_data:)
41
+ build_body(doc, body_content:, app_mount_id:)
42
+ end
43
+ end.doc.to_html
44
+ end
45
+
46
+ def iife_bundle_path
47
+ File.join(@dist_dir, "app.iife.js")
48
+ end
49
+
50
+ def iife_css_path
51
+ File.join(@dist_dir, "app.css")
52
+ end
53
+
54
+ def iife_bundle_exists?
55
+ File.exist?(iife_bundle_path)
56
+ end
57
+
58
+ private
59
+
60
+ def build_head(doc, title:, head_extra:, script_data:)
61
+ doc.head do
62
+ doc.meta(charset: "UTF-8")
63
+ doc.meta(name: "viewport",
64
+ content: "width=device-width, initial-scale=1.0")
65
+ doc.title { doc.text title.to_s }
66
+ if script_data
67
+ doc.script { doc.text script_data }
68
+ end
69
+ next unless head_extra && !head_extra.empty?
70
+
71
+ doc << Nokogiri::HTML5::DocumentFragment.parse(head_extra)
72
+ end
73
+ end
74
+
75
+ def build_body(doc, body_content:, app_mount_id:)
76
+ doc.body do
77
+ if app_mount_id
78
+ doc.div(id: app_mount_id) do
79
+ doc << Nokogiri::HTML5::DocumentFragment.parse(body_content.to_s)
80
+ end
81
+ else
82
+ doc << Nokogiri::HTML5::DocumentFragment.parse(body_content.to_s)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "nokogiri"
5
+
6
+ module Metanorma
7
+ module Mirror
8
+ module Output
9
+ module Formats
10
+ class InlineFormat < BaseFormat
11
+ def write(output_path, guide, title: "Metanorma")
12
+ FileUtils.mkdir_p(File.dirname(output_path))
13
+
14
+ data_script = "window.METANORMA_DATA = #{safe_json(guide)};"
15
+ ssr_body = HtmlRenderer.new(guide).render
16
+ head_parts = []
17
+ css_inline = read_css_inline
18
+ if css_inline && !css_inline.empty?
19
+ head_parts << build_style(css_inline)
20
+ end
21
+ head_parts << build_script_src("app.iife.js") if iife_bundle_exists?
22
+ head_extra = head_parts.join("\n")
23
+
24
+ html = html_boilerplate(
25
+ title: title,
26
+ body_content: ssr_body,
27
+ head_extra: head_extra,
28
+ script_data: data_script,
29
+ app_mount_id: iife_bundle_exists? ? "metanorma-app" : nil,
30
+ )
31
+
32
+ File.write(output_path, html)
33
+
34
+ if iife_bundle_exists?
35
+ copy_if_exists(iife_bundle_path,
36
+ File.join(File.dirname(output_path),
37
+ "app.iife.js"))
38
+ end
39
+
40
+ output_path
41
+ end
42
+
43
+ private
44
+
45
+ def build_style(css)
46
+ Nokogiri::HTML5::Builder.new do |doc|
47
+ doc.style { doc.text css }
48
+ end.doc.root.to_html
49
+ end
50
+
51
+ def build_script_src(src)
52
+ Nokogiri::HTML5::Builder.new do |doc|
53
+ doc.script(src: src)
54
+ end.doc.root.to_html
55
+ end
56
+
57
+ def read_css_inline
58
+ path = iife_css_path
59
+ File.exist?(path) ? File.read(path) : ""
60
+ end
61
+
62
+ def copy_if_exists(src, dst)
63
+ return unless File.exist?(src)
64
+
65
+ unless File.exist?(dst) && FileUtils.identical?(
66
+ src, dst
67
+ )
68
+ FileUtils.cp(src,
69
+ dst)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ Metanorma::Mirror::Output::Formats.register(
79
+ :inline,
80
+ Metanorma::Mirror::Output::Formats::InlineFormat,
81
+ )
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Mirror
5
+ module Output
6
+ module Formats
7
+ autoload :BaseFormat, "#{__dir__}/formats/base_format"
8
+ autoload :InlineFormat, "#{__dir__}/formats/inline_format"
9
+
10
+ # All format modules that should be auto-registered. Adding a new
11
+ # format = adding one entry here. No edits to lookup logic.
12
+ REGISTERED = %i[InlineFormat].freeze
13
+
14
+ class << self
15
+ # Returns the format class registered under `name`, or nil.
16
+ # Triggers autoload of all known format modules on first call.
17
+ def lookup(name)
18
+ ensure_loaded
19
+ format_map[name]
20
+ end
21
+
22
+ def registered?(name)
23
+ ensure_loaded
24
+ format_map.key?(name)
25
+ end
26
+
27
+ def register(name, format_class)
28
+ format_map[name] = format_class
29
+ self
30
+ end
31
+
32
+ def unregister(name)
33
+ format_map.delete(name)
34
+ self
35
+ end
36
+
37
+ private
38
+
39
+ def format_map
40
+ @format_map ||= {}
41
+ end
42
+
43
+ def ensure_loaded
44
+ return if @loaded
45
+
46
+ REGISTERED.each { |mod_name| const_get(mod_name) }
47
+ @loaded = true
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end