metanorma-document 0.2.12 → 0.2.13

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 (391) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +21 -0
  3. data/.github/workflows/release.yml +25 -0
  4. data/.github/workflows/roundtrip-samples.yml +132 -0
  5. data/.gitignore +19 -0
  6. data/.rspec +3 -0
  7. data/.rubocop.yml +22 -0
  8. data/.rubocop_todo.yml +66 -164
  9. data/CHANGELOG.md +1 -0
  10. data/Gemfile +32 -0
  11. data/README.adoc +0 -144
  12. data/Rakefile +2 -14
  13. data/bin/console +15 -0
  14. data/bin/setup +8 -0
  15. data/data/javascripts/components/mn-lightbox.js +2 -18
  16. data/data/javascripts/components/mn-shortcuts.js +0 -2
  17. data/data/javascripts/core/mn-navigation.js +0 -8
  18. data/data/javascripts/core/mn-theme.js +9 -9
  19. data/data/logos/pdfa-logo.svg +94 -31
  20. data/data/stylesheets/base/_layout.css +0 -3
  21. data/data/stylesheets/base/_reset.css +3 -3
  22. data/data/stylesheets/base/_typography.css +5 -0
  23. data/data/stylesheets/components/bibliography.css +3 -3
  24. data/data/stylesheets/components/cover.css +1 -3
  25. data/data/stylesheets/components/figure.css +1 -13
  26. data/data/stylesheets/components/footnote.css +5 -65
  27. data/data/stylesheets/components/formula.css +0 -44
  28. data/data/stylesheets/components/header.css +2 -17
  29. data/data/stylesheets/components/inline.css +1 -1
  30. data/data/stylesheets/components/table.css +2 -15
  31. data/data/stylesheets/components/term.css +1 -0
  32. data/lib/metanorma/bipm_document/metadata/bipm_bibliographic_item.rb +14 -0
  33. data/lib/metanorma/bipm_document/metadata.rb +1 -1
  34. data/lib/metanorma/document/components/ancillary_blocks/sourcecode_block.rb +65 -0
  35. data/lib/metanorma/document/components/ancillary_blocks.rb +0 -4
  36. data/lib/metanorma/document/components/bib_data/bib_data.rb +0 -7
  37. data/lib/metanorma/document/components/blocks/requirement_model.rb +131 -0
  38. data/lib/metanorma/document/components/blocks.rb +7 -8
  39. data/lib/metanorma/document/components/id_elements/image.rb +0 -2
  40. data/lib/metanorma/document/components/inline/asciimath_element.rb +0 -2
  41. data/lib/metanorma/document/components/inline/attribution_element.rb +0 -2
  42. data/lib/metanorma/document/components/inline/bcp14_element.rb +0 -2
  43. data/lib/metanorma/document/components/inline/biblio_tag_element.rb +0 -2
  44. data/lib/metanorma/document/components/inline/br_element.rb +0 -2
  45. data/lib/metanorma/document/components/inline/comma_element.rb +0 -2
  46. data/lib/metanorma/document/components/inline/concept_element.rb +0 -2
  47. data/lib/metanorma/document/components/inline/display_text_element.rb +0 -2
  48. data/lib/metanorma/document/components/inline/em_raw_element.rb +0 -2
  49. data/lib/metanorma/document/components/inline/enum_comma_element.rb +0 -2
  50. data/lib/metanorma/document/components/inline/eref_element.rb +0 -2
  51. data/lib/metanorma/document/components/inline/fmt_admitted_element.rb +0 -4
  52. data/lib/metanorma/document/components/inline/fmt_annotation_body_element.rb +0 -4
  53. data/lib/metanorma/document/components/inline/fmt_annotation_end_element.rb +0 -4
  54. data/lib/metanorma/document/components/inline/fmt_annotation_start_element.rb +0 -4
  55. data/lib/metanorma/document/components/inline/fmt_concept_element.rb +0 -4
  56. data/lib/metanorma/document/components/inline/fmt_definition_element.rb +0 -4
  57. data/lib/metanorma/document/components/inline/fmt_fn_body_element.rb +0 -4
  58. data/lib/metanorma/document/components/inline/fmt_fn_label_element.rb +0 -4
  59. data/lib/metanorma/document/components/inline/fmt_footnote_container_element.rb +0 -4
  60. data/lib/metanorma/document/components/inline/fmt_identifier_element.rb +0 -4
  61. data/lib/metanorma/document/components/inline/fmt_name_element.rb +0 -4
  62. data/lib/metanorma/document/components/inline/fmt_preferred_element.rb +0 -4
  63. data/lib/metanorma/document/components/inline/fmt_sourcecode_element.rb +0 -4
  64. data/lib/metanorma/document/components/inline/fmt_stem_element.rb +0 -10
  65. data/lib/metanorma/document/components/inline/fmt_termsource_element.rb +0 -4
  66. data/lib/metanorma/document/components/inline/fmt_title_element.rb +0 -4
  67. data/lib/metanorma/document/components/inline/fmt_xref_element.rb +0 -4
  68. data/lib/metanorma/document/components/inline/fmt_xref_label_element.rb +0 -4
  69. data/lib/metanorma/document/components/inline/fn_element.rb +0 -2
  70. data/lib/metanorma/document/components/inline/link_element.rb +0 -2
  71. data/lib/metanorma/document/components/inline/localized_string_element.rb +0 -2
  72. data/lib/metanorma/document/components/inline/localized_strings_element.rb +0 -2
  73. data/lib/metanorma/document/components/inline/math_element.rb +0 -2
  74. data/lib/metanorma/document/components/inline/name_with_id_element.rb +0 -4
  75. data/lib/metanorma/document/components/inline/semx_child_element.rb +0 -2
  76. data/lib/metanorma/document/components/inline/semx_element.rb +1 -13
  77. data/lib/metanorma/document/components/inline/small_cap_element.rb +0 -2
  78. data/lib/metanorma/document/components/inline/span_element.rb +15 -10
  79. data/lib/metanorma/document/components/inline/stem_inline_element.rb +1 -7
  80. data/lib/metanorma/document/components/inline/strong_raw_element.rb +0 -2
  81. data/lib/metanorma/document/components/inline/sub_element.rb +0 -2
  82. data/lib/metanorma/document/components/inline/sup_element.rb +0 -2
  83. data/lib/metanorma/document/components/inline/tab_element.rb +0 -2
  84. data/lib/metanorma/document/components/inline/title_with_annotation_element.rb +0 -4
  85. data/lib/metanorma/document/components/inline/tt_element.rb +0 -2
  86. data/lib/metanorma/document/components/inline/variant_title_element.rb +0 -2
  87. data/lib/metanorma/document/components/inline/xref_element.rb +0 -10
  88. data/lib/metanorma/document/components/inline.rb +0 -12
  89. data/lib/metanorma/document/components/multi_paragraph/quote_block.rb +29 -0
  90. data/lib/metanorma/document/components/multi_paragraph.rb +0 -2
  91. data/lib/metanorma/document/components/reference_elements/source_element.rb +31 -0
  92. data/lib/metanorma/document/components/reference_elements.rb +2 -2
  93. data/lib/metanorma/document/components/tables/table_block.rb +22 -0
  94. data/lib/metanorma/document/components/tables/table_section.rb +25 -0
  95. data/lib/metanorma/document/components/tables.rb +3 -5
  96. data/lib/metanorma/document/relaton/address.rb +27 -0
  97. data/lib/metanorma/document/relaton/bib_item_locality.rb +12 -3
  98. data/lib/metanorma/document/relaton/copyright_association.rb +10 -0
  99. data/lib/metanorma/document/relaton/edition.rb +7 -4
  100. data/lib/metanorma/document/relaton/organization.rb +14 -0
  101. data/lib/metanorma/document/relaton/phone.rb +9 -3
  102. data/lib/metanorma/document/relaton/place_type.rb +13 -0
  103. data/lib/metanorma/document/relaton/price_type.rb +9 -3
  104. data/lib/metanorma/document/relaton.rb +1 -6
  105. data/lib/metanorma/document/version.rb +1 -1
  106. data/lib/metanorma/document.rb +0 -2
  107. data/lib/metanorma/html/asset_pipeline.rb +0 -1
  108. data/lib/metanorma/html/base_renderer.rb +1008 -261
  109. data/lib/metanorma/html/bipm_renderer.rb +144 -15
  110. data/lib/metanorma/html/cc_renderer.rb +45 -1
  111. data/lib/metanorma/html/component/base.rb +7 -2
  112. data/lib/metanorma/html/component/index_section.rb +43 -41
  113. data/lib/metanorma/html/drops/admonition_drop.rb +4 -1
  114. data/lib/metanorma/html/drops/block_element_drop.rb +2 -7
  115. data/lib/metanorma/html/drops/example_drop.rb +4 -1
  116. data/lib/metanorma/html/drops/figure_drop.rb +22 -31
  117. data/lib/metanorma/html/drops/footnote_drop.rb +1 -1
  118. data/lib/metanorma/html/drops/formula_drop.rb +16 -45
  119. data/lib/metanorma/html/drops/note_drop.rb +7 -9
  120. data/lib/metanorma/html/drops/sourcecode_drop.rb +5 -12
  121. data/lib/metanorma/html/drops.rb +0 -2
  122. data/lib/metanorma/html/generator.rb +2 -2
  123. data/lib/metanorma/html/icc_renderer.rb +39 -0
  124. data/lib/metanorma/html/iec_renderer.rb +44 -1
  125. data/lib/metanorma/html/ieee_renderer.rb +45 -1
  126. data/lib/metanorma/html/ietf_renderer.rb +48 -1
  127. data/lib/metanorma/html/iho_renderer.rb +46 -1
  128. data/lib/metanorma/html/iso_renderer.rb +343 -290
  129. data/lib/metanorma/html/itu_renderer.rb +45 -1
  130. data/lib/metanorma/html/ogc_renderer.rb +76 -15
  131. data/lib/metanorma/html/oiml_renderer.rb +38 -18
  132. data/lib/metanorma/html/pdfa_renderer.rb +39 -0
  133. data/lib/metanorma/html/ribose_renderer.rb +45 -1
  134. data/lib/metanorma/html/standard_renderer.rb +229 -341
  135. data/lib/metanorma/html/templates/_footnotes.html.liquid +6 -6
  136. data/lib/metanorma/html/templates/_formula.html.liquid +1 -1
  137. data/lib/metanorma/html/templates/_header.html.liquid +1 -1
  138. data/lib/metanorma/html/templates/_iso_cover.html.liquid +1 -1
  139. data/lib/metanorma/html/templates/document.html.liquid +0 -4
  140. data/lib/metanorma/html/theme.rb +107 -180
  141. data/lib/metanorma/html.rb +3 -14
  142. data/lib/metanorma/ietf_document/metadata/ietf_bib_data_extension_type.rb +25 -0
  143. data/lib/metanorma/ietf_document/metadata.rb +0 -2
  144. data/lib/metanorma/iso_document/metadata/iso_bib_data_extension_type.rb +48 -0
  145. data/lib/metanorma/iso_document/metadata/iso_bibliographic_item.rb +72 -0
  146. data/lib/metanorma/iso_document/metadata/iso_document_status.rb +30 -0
  147. data/lib/metanorma/iso_document/metadata/iso_localized_title.rb +1 -4
  148. data/lib/metanorma/iso_document/metadata/structured_identifier.rb +17 -0
  149. data/lib/metanorma/iso_document/metadata/title_collection.rb +0 -1
  150. data/lib/metanorma/iso_document/metadata.rb +4 -9
  151. data/lib/metanorma/iso_document/terms/iso_term.rb +13 -0
  152. data/lib/metanorma/iso_document/terms.rb +0 -1
  153. data/lib/metanorma/itu_document/metadata/itu_bib_data_extension_type.rb +37 -0
  154. data/lib/metanorma/itu_document/metadata.rb +4 -3
  155. data/lib/metanorma/standard_document/block_attributes.rb +9 -5
  156. data/lib/metanorma/standard_document/blocks/block_source.rb +23 -0
  157. data/lib/metanorma/standard_document/blocks.rb +1 -1
  158. data/lib/metanorma/standard_document/terms/term_expression.rb +31 -0
  159. data/lib/metanorma/standard_document/terms.rb +0 -1
  160. data/metanorma-document.gemspec +35 -0
  161. metadata +13 -262
  162. data/CLAUDE.md +0 -26
  163. data/TODO.finalize/01-split-multi-class-files.md +0 -8
  164. data/TODO.finalize/02-remove-data-dist-iso-document-frontend.md +0 -6
  165. data/TODO.finalize/03-align-frontend-iife-and-gha-build.md +0 -11
  166. data/TODO.finalize/04-theme-per-flavor-config-driven.md +0 -9
  167. data/TODO.finalize/05-migrate-all-html-to-liquid.md +0 -16
  168. data/TODO.finalize/06-integrate-pubid-library.md +0 -16
  169. data/TODO.finalize/07-replace-relaton-models-with-relaton-bib.md +0 -39
  170. data/TODO.finalize/08-refactor-renderer-architecture.md +0 -25
  171. data/TODO.finalize/09-eliminate-code-smells.md +0 -14
  172. data/TODO.finalize/10-comprehensive-spec-coverage.md +0 -24
  173. data/TODO.finalize/11-config-driven-flavor-metadata.md +0 -20
  174. data/TODO.finalize/12-add-frozen-string-literal.md +0 -6
  175. data/TODO.finalize/13-extract-composition-from-god-class.md +0 -96
  176. data/TODO.finalize/14-config-driven-section-ordering.md +0 -31
  177. data/TODO.finalize/15-theme-directories-per-flavor.md +0 -46
  178. data/TODO.finalize/16-theme-lutaml-model-schema.md +0 -44
  179. data/data/javascripts/components/mn-footnotes.js +0 -68
  180. data/data/logos/oiml-logo-full-dark.svg +0 -1
  181. data/data/logos/oiml-logo-full-light.svg +0 -1
  182. data/data/logos/oiml-logo-icon-dark.svg +0 -1
  183. data/data/logos/oiml-logo-icon-light.svg +0 -1
  184. data/data/logos/oiml-logo.svg +0 -1
  185. data/data/themes/bipm.yaml +0 -60
  186. data/data/themes/cc.yaml +0 -43
  187. data/data/themes/icc.yaml +0 -39
  188. data/data/themes/iec.yaml +0 -44
  189. data/data/themes/ieee.yaml +0 -43
  190. data/data/themes/ietf.yaml +0 -45
  191. data/data/themes/iho.yaml +0 -46
  192. data/data/themes/iso.yaml +0 -40
  193. data/data/themes/itu.yaml +0 -45
  194. data/data/themes/ogc.yaml +0 -51
  195. data/data/themes/oiml.yaml +0 -56
  196. data/data/themes/pdfa.yaml +0 -44
  197. data/data/themes/ribose.yaml +0 -43
  198. data/exe/metanorma-document +0 -11
  199. data/frontend/e2e/sample-html.test.ts +0 -256
  200. data/frontend/index.html +0 -12
  201. data/frontend/package-lock.json +0 -4725
  202. data/frontend/package.json +0 -32
  203. data/frontend/postcss.config.js +0 -6
  204. data/frontend/src/App.vue +0 -79
  205. data/frontend/src/app.ts +0 -21
  206. data/frontend/src/components/AppSidebar.vue +0 -77
  207. data/frontend/src/components/DocumentReader.vue +0 -180
  208. data/frontend/src/components/MirrorRenderer.vue +0 -23
  209. data/frontend/src/components/ReadingProgressBar.vue +0 -29
  210. data/frontend/src/components/TextRenderer.vue +0 -131
  211. data/frontend/src/components/TocItem.vue +0 -57
  212. data/frontend/src/components/TopBar.vue +0 -49
  213. data/frontend/src/components/__tests__/MirrorRenderer.test.ts +0 -178
  214. data/frontend/src/components/blocks/AdmonitionBlock.vue +0 -74
  215. data/frontend/src/components/blocks/ClauseBlock.vue +0 -53
  216. data/frontend/src/components/blocks/ExampleBlock.vue +0 -21
  217. data/frontend/src/components/blocks/FallbackBlock.vue +0 -18
  218. data/frontend/src/components/blocks/FigureBlock.vue +0 -26
  219. data/frontend/src/components/blocks/FootnotesBlock.vue +0 -25
  220. data/frontend/src/components/blocks/ListBlocks.vue +0 -62
  221. data/frontend/src/components/blocks/NoteBlock.vue +0 -21
  222. data/frontend/src/components/blocks/ParagraphBlock.vue +0 -25
  223. data/frontend/src/components/blocks/QuoteBlock.vue +0 -25
  224. data/frontend/src/components/blocks/ReviewBlock.vue +0 -39
  225. data/frontend/src/components/blocks/SourcecodeBlock.vue +0 -52
  226. data/frontend/src/components/blocks/TableBlock.vue +0 -48
  227. data/frontend/src/components/blocks/index.ts +0 -36
  228. data/frontend/src/stores/__tests__/documentStore.fixture.test.ts +0 -272
  229. data/frontend/src/stores/__tests__/documentStore.test.ts +0 -143
  230. data/frontend/src/stores/__tests__/ebookStore.test.ts +0 -145
  231. data/frontend/src/stores/__tests__/uiStore.test.ts +0 -42
  232. data/frontend/src/stores/documentStore.ts +0 -153
  233. data/frontend/src/stores/ebookStore.ts +0 -179
  234. data/frontend/src/stores/uiStore.ts +0 -32
  235. data/frontend/src/styles.css +0 -156
  236. data/frontend/src/types/__tests__/rendering-contract.test.ts +0 -172
  237. data/frontend/src/types/rendering-contract.ts +0 -209
  238. data/frontend/src/utils/__tests__/typeMetadata.test.ts +0 -102
  239. data/frontend/src/utils/typeMetadata.ts +0 -121
  240. data/frontend/tailwind.config.js +0 -18
  241. data/frontend/test/fixtures/iso-document.json +0 -271
  242. data/frontend/tmp/debug_e2e.cjs +0 -46
  243. data/frontend/tsconfig.json +0 -25
  244. data/frontend/tsconfig.node.json +0 -11
  245. data/frontend/vite.config.ts +0 -37
  246. data/frontend/vitest.e2e.config.ts +0 -9
  247. data/lib/metanorma/bipm_document/metadata/depiction_element.rb +0 -18
  248. data/lib/metanorma/document/cli.rb +0 -116
  249. data/lib/metanorma/document/components/ancillary_blocks/callout_annotation.rb +0 -27
  250. data/lib/metanorma/document/components/ancillary_blocks/sourcecode_body.rb +0 -18
  251. data/lib/metanorma/document/components/blocks/classification_value.rb +0 -21
  252. data/lib/metanorma/document/components/blocks/permission_model.rb +0 -28
  253. data/lib/metanorma/document/components/blocks/recommendation_model.rb +0 -28
  254. data/lib/metanorma/document/components/blocks/requirement_base.rb +0 -30
  255. data/lib/metanorma/document/components/blocks/requirement_classification.rb +0 -20
  256. data/lib/metanorma/document/components/blocks/requirement_description.rb +0 -43
  257. data/lib/metanorma/document/components/blocks/requirement_inherit.rb +0 -24
  258. data/lib/metanorma/document/components/inline/location_element.rb +0 -24
  259. data/lib/metanorma/document/components/inline/rendered_display.rb +0 -23
  260. data/lib/metanorma/document/components/inline/rendered_math_element.rb +0 -21
  261. data/lib/metanorma/document/components/inline/semantic_content.rb +0 -51
  262. data/lib/metanorma/document/components/inline/semantic_math_element.rb +0 -20
  263. data/lib/metanorma/document/components/inline/vocabulary.rb +0 -184
  264. data/lib/metanorma/document/components/multi_paragraph/quote_author_element.rb +0 -20
  265. data/lib/metanorma/document/components/reference_elements/source_modification.rb +0 -21
  266. data/lib/metanorma/document/components/reference_elements/source_origin.rb +0 -28
  267. data/lib/metanorma/document/components/tables/col_element.rb +0 -18
  268. data/lib/metanorma/document/components/tables/col_group_element.rb +0 -18
  269. data/lib/metanorma/document/components/tables/table_body_section.rb +0 -16
  270. data/lib/metanorma/document/components/tables/table_foot_section.rb +0 -16
  271. data/lib/metanorma/document/components/tables/table_head_section.rb +0 -16
  272. data/lib/metanorma/document/relaton/copyright_owner.rb +0 -16
  273. data/lib/metanorma/document/relaton/formatted_address.rb +0 -29
  274. data/lib/metanorma/document/relaton/logo_element.rb +0 -18
  275. data/lib/metanorma/document/relaton/region_element.rb +0 -18
  276. data/lib/metanorma/html/drops/biblio_entry_drop.rb +0 -50
  277. data/lib/metanorma/html/renderers/block_renderer.rb +0 -372
  278. data/lib/metanorma/html/renderers/inline_renderer.rb +0 -655
  279. data/lib/metanorma/html/renderers/pubid_renderer.rb +0 -69
  280. data/lib/metanorma/html/renderers/section_renderer.rb +0 -193
  281. data/lib/metanorma/html/renderers.rb +0 -8
  282. data/lib/metanorma/html/templates/_audio.html.liquid +0 -1
  283. data/lib/metanorma/html/templates/_biblio_entry.html.liquid +0 -1
  284. data/lib/metanorma/html/templates/_bipm_cover.html.liquid +0 -27
  285. data/lib/metanorma/html/templates/_boilerplate.html.liquid +0 -1
  286. data/lib/metanorma/html/templates/_bookmark.html.liquid +0 -1
  287. data/lib/metanorma/html/templates/_br.html.liquid +0 -1
  288. data/lib/metanorma/html/templates/_definition_list.html.liquid +0 -6
  289. data/lib/metanorma/html/templates/_element.html.liquid +0 -1
  290. data/lib/metanorma/html/templates/_fn_marker.html.liquid +0 -1
  291. data/lib/metanorma/html/templates/_heading.html.liquid +0 -1
  292. data/lib/metanorma/html/templates/_image.html.liquid +0 -1
  293. data/lib/metanorma/html/templates/_inline_span.html.liquid +0 -1
  294. data/lib/metanorma/html/templates/_link.html.liquid +0 -1
  295. data/lib/metanorma/html/templates/_list.html.liquid +0 -3
  296. data/lib/metanorma/html/templates/_list_item.html.liquid +0 -1
  297. data/lib/metanorma/html/templates/_main_content.html.liquid +0 -1
  298. data/lib/metanorma/html/templates/_math_container.html.liquid +0 -1
  299. data/lib/metanorma/html/templates/_paragraph.html.liquid +0 -1
  300. data/lib/metanorma/html/templates/_prefatory_section.html.liquid +0 -1
  301. data/lib/metanorma/html/templates/_pubid_identifier.html.liquid +0 -1
  302. data/lib/metanorma/html/templates/_quote.html.liquid +0 -4
  303. data/lib/metanorma/html/templates/_ref_date.html.liquid +0 -1
  304. data/lib/metanorma/html/templates/_ref_title.html.liquid +0 -1
  305. data/lib/metanorma/html/templates/_section.html.liquid +0 -5
  306. data/lib/metanorma/html/templates/_standard_cover.html.liquid +0 -31
  307. data/lib/metanorma/html/templates/_standard_doc_title.html.liquid +0 -3
  308. data/lib/metanorma/html/templates/_stem_span.html.liquid +0 -1
  309. data/lib/metanorma/html/templates/_table.html.liquid +0 -9
  310. data/lib/metanorma/html/templates/_term_domain.html.liquid +0 -1
  311. data/lib/metanorma/html/templates/_term_example.html.liquid +0 -1
  312. data/lib/metanorma/html/templates/_term_note.html.liquid +0 -1
  313. data/lib/metanorma/html/templates/_term_number.html.liquid +0 -1
  314. data/lib/metanorma/html/templates/_term_source.html.liquid +0 -1
  315. data/lib/metanorma/html/templates/_term_text_note.html.liquid +0 -1
  316. data/lib/metanorma/html/templates/_video.html.liquid +0 -1
  317. data/lib/metanorma/html/templates/_wrapped_preface.html.liquid +0 -1
  318. data/lib/metanorma/ietf_document/metadata/pi_settings.rb +0 -32
  319. data/lib/metanorma/iso_document/metadata/doctype_element.rb +0 -20
  320. data/lib/metanorma/iso_document/metadata/language_element.rb +0 -18
  321. data/lib/metanorma/iso_document/metadata/project_number.rb +0 -22
  322. data/lib/metanorma/iso_document/metadata/script_element.rb +0 -18
  323. data/lib/metanorma/iso_document/metadata/stage_element.rb +0 -26
  324. data/lib/metanorma/iso_document/metadata/stagename_element.rb +0 -18
  325. data/lib/metanorma/iso_document/terms/term_domain_element.rb +0 -18
  326. data/lib/metanorma/itu_document/metadata/meeting_date.rb +0 -18
  327. data/lib/metanorma/itu_document/metadata/meeting_element.rb +0 -18
  328. data/lib/metanorma/itu_document/metadata/study_period.rb +0 -18
  329. data/lib/metanorma/mirror/default_registry.rb +0 -170
  330. data/lib/metanorma/mirror/handler_registry.rb +0 -60
  331. data/lib/metanorma/mirror/handler_result.rb +0 -37
  332. data/lib/metanorma/mirror/handlers/admonition.rb +0 -18
  333. data/lib/metanorma/mirror/handlers/example.rb +0 -21
  334. data/lib/metanorma/mirror/handlers/figure.rb +0 -53
  335. data/lib/metanorma/mirror/handlers/formula.rb +0 -35
  336. data/lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb +0 -159
  337. data/lib/metanorma/mirror/handlers/inline/text_extractor.rb +0 -116
  338. data/lib/metanorma/mirror/handlers/inline.rb +0 -225
  339. data/lib/metanorma/mirror/handlers/list.rb +0 -110
  340. data/lib/metanorma/mirror/handlers/note.rb +0 -26
  341. data/lib/metanorma/mirror/handlers/paragraph.rb +0 -19
  342. data/lib/metanorma/mirror/handlers/quote.rb +0 -16
  343. data/lib/metanorma/mirror/handlers/review.rb +0 -19
  344. data/lib/metanorma/mirror/handlers/section.rb +0 -149
  345. data/lib/metanorma/mirror/handlers/sourcecode.rb +0 -27
  346. data/lib/metanorma/mirror/handlers/structural.rb +0 -68
  347. data/lib/metanorma/mirror/handlers/table.rb +0 -81
  348. data/lib/metanorma/mirror/handlers/term.rb +0 -100
  349. data/lib/metanorma/mirror/handlers.rb +0 -60
  350. data/lib/metanorma/mirror/id_strategy/positional.rb +0 -166
  351. data/lib/metanorma/mirror/id_strategy/preserve.rb +0 -12
  352. data/lib/metanorma/mirror/id_strategy.rb +0 -34
  353. data/lib/metanorma/mirror/math_util.rb +0 -53
  354. data/lib/metanorma/mirror/metadata.rb +0 -37
  355. data/lib/metanorma/mirror/metanorma_to_mirror.rb +0 -101
  356. data/lib/metanorma/mirror/model/container.rb +0 -47
  357. data/lib/metanorma/mirror/model/factory.rb +0 -52
  358. data/lib/metanorma/mirror/model/guide.rb +0 -25
  359. data/lib/metanorma/mirror/model/leaf.rb +0 -17
  360. data/lib/metanorma/mirror/model/mark.rb +0 -53
  361. data/lib/metanorma/mirror/model/node.rb +0 -47
  362. data/lib/metanorma/mirror/model/soft_break.rb +0 -33
  363. data/lib/metanorma/mirror/model/text.rb +0 -34
  364. data/lib/metanorma/mirror/model.rb +0 -16
  365. data/lib/metanorma/mirror/output/builder.rb +0 -39
  366. data/lib/metanorma/mirror/output/formats/base_format.rb +0 -90
  367. data/lib/metanorma/mirror/output/formats/inline_format.rb +0 -81
  368. data/lib/metanorma/mirror/output/formats.rb +0 -53
  369. data/lib/metanorma/mirror/output/html_renderer.rb +0 -95
  370. data/lib/metanorma/mirror/output/html_renderers/block_renderers.rb +0 -178
  371. data/lib/metanorma/mirror/output/html_renderers/inline_renderer.rb +0 -61
  372. data/lib/metanorma/mirror/output/html_renderers/list_renderers.rb +0 -96
  373. data/lib/metanorma/mirror/output/html_renderers/mark_renderers.rb +0 -64
  374. data/lib/metanorma/mirror/output/html_renderers/section_renderers.rb +0 -129
  375. data/lib/metanorma/mirror/output/html_renderers/structural_renderers.rb +0 -80
  376. data/lib/metanorma/mirror/output/html_renderers/table_renderers.rb +0 -87
  377. data/lib/metanorma/mirror/output/html_renderers.rb +0 -76
  378. data/lib/metanorma/mirror/output/pipeline.rb +0 -92
  379. data/lib/metanorma/mirror/output/pipeline_context.rb +0 -22
  380. data/lib/metanorma/mirror/output.rb +0 -14
  381. data/lib/metanorma/mirror/rewriter.rb +0 -121
  382. data/lib/metanorma/mirror/safe_attr.rb +0 -16
  383. data/lib/metanorma/mirror/serialization/json_serializer.rb +0 -25
  384. data/lib/metanorma/mirror/serialization/yaml_serializer.rb +0 -20
  385. data/lib/metanorma/mirror/serialization.rb +0 -10
  386. data/lib/metanorma/mirror/transformer.rb +0 -22
  387. data/lib/metanorma/mirror.rb +0 -32
  388. data/lib/metanorma/standard_document/annotation.rb +0 -37
  389. data/lib/metanorma/standard_document/blocks/source_origin_element.rb +0 -23
  390. data/lib/metanorma/standard_document/terms/term_name_element.rb +0 -29
  391. data/script/render_both.rb +0 -18
@@ -1,32 +0,0 @@
1
- {
2
- "name": "metanorma-frontend",
3
- "version": "1.0.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "build": "vite build",
8
- "dev": "vite",
9
- "test": "vitest run",
10
- "test:watch": "vitest",
11
- "typecheck": "vue-tsc --noEmit"
12
- },
13
- "dependencies": {
14
- "@types/prismjs": "^1.26.6",
15
- "pinia": "^2.1.7",
16
- "prismjs": "^1.30.0",
17
- "vue": "^3.4.21"
18
- },
19
- "devDependencies": {
20
- "@vitejs/plugin-vue": "^5.0.4",
21
- "@vue/test-utils": "^2.4.8",
22
- "autoprefixer": "^10.5.0",
23
- "happy-dom": "^20.9.0",
24
- "postcss": "^8.5.9",
25
- "puppeteer": "^25.1.0",
26
- "tailwindcss": "^3.4.19",
27
- "typescript": "^5.4.0",
28
- "vite": "^5.2.0",
29
- "vitest": "^4.1.5",
30
- "vue-tsc": "^2.0.6"
31
- }
32
- }
@@ -1,6 +0,0 @@
1
- export default {
2
- plugins: {
3
- tailwindcss: {},
4
- autoprefixer: {},
5
- },
6
- }
data/frontend/src/App.vue DELETED
@@ -1,79 +0,0 @@
1
- <template>
2
- <div :class="['h-screen overflow-hidden', ebookStore.getThemeClass()]" :style="ebookStore.getCssVariables()">
3
- <div id="metanorma-error" class="error-fallback" style="display:none">
4
- <div class="error-content">
5
- <svg class="error-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
6
- <h2>Something went wrong</h2>
7
- <p class="error-message">An error occurred while rendering this document.</p>
8
- <button @click="reload" class="error-retry">Reload page</button>
9
- </div>
10
- </div>
11
- <DocumentReader />
12
- </div>
13
- </template>
14
-
15
- <script setup lang="ts">
16
- import { onMounted } from 'vue'
17
- import { useEbookStore } from '@/stores/ebookStore'
18
- import { useDocumentStore } from '@/stores/documentStore'
19
- import DocumentReader from '@/components/DocumentReader.vue'
20
-
21
- const ebookStore = useEbookStore()
22
- const documentStore = useDocumentStore()
23
-
24
- documentStore.loadFromWindow()
25
-
26
- onMounted(() => {
27
- ebookStore.applyTheme()
28
- })
29
-
30
- function reload() {
31
- window.location.reload()
32
- }
33
- </script>
34
-
35
- <style>
36
- .error-fallback {
37
- position: fixed;
38
- inset: 0;
39
- z-index: 9999;
40
- background: #fefce8;
41
- color: #1a1a1a;
42
- display: flex;
43
- align-items: center;
44
- justify-content: center;
45
- }
46
- .error-content {
47
- text-align: center;
48
- max-width: 400px;
49
- padding: 2rem;
50
- }
51
- .error-icon {
52
- width: 48px;
53
- height: 48px;
54
- margin: 0 auto 1rem;
55
- color: #f59e0b;
56
- }
57
- .error-content h2 {
58
- font-size: 1.25rem;
59
- font-weight: 700;
60
- margin-bottom: 0.5rem;
61
- }
62
- .error-message {
63
- font-size: 0.9rem;
64
- color: #6b7280;
65
- margin-bottom: 1.5rem;
66
- }
67
- .error-retry {
68
- padding: 8px 20px;
69
- font-size: 0.85rem;
70
- font-weight: 600;
71
- border-radius: 8px;
72
- background: #0d9488;
73
- color: #fff;
74
- cursor: pointer;
75
- }
76
- .error-retry:hover {
77
- background: #0f766e;
78
- }
79
- </style>
data/frontend/src/app.ts DELETED
@@ -1,21 +0,0 @@
1
- import { createApp } from 'vue'
2
- import { createPinia } from 'pinia'
3
- import App from './App.vue'
4
- import './styles.css'
5
-
6
- const pinia = createPinia()
7
-
8
- const app = createApp(App)
9
- app.use(pinia)
10
-
11
- app.config.errorHandler = (err, _instance, info) => {
12
- console.error(`[Metanorma] ${info}:`, err)
13
- const el = document.getElementById('metanorma-error')
14
- if (el) {
15
- el.style.display = 'flex'
16
- const msg = el.querySelector('.error-message')
17
- if (msg) msg.textContent = err instanceof Error ? err.message : String(err)
18
- }
19
- }
20
-
21
- app.mount('#metanorma-app')
@@ -1,77 +0,0 @@
1
- <template>
2
- <aside :class="['sidebar', { 'sidebar-open': uiStore.sidebarOpen }]">
3
- <div class="sidebar-header">
4
- <h2 class="sidebar-title">{{ documentStore.title }}</h2>
5
- <button @click="uiStore.closeSidebar" class="sidebar-close" title="Close sidebar">
6
- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
7
- </button>
8
- </div>
9
- <nav class="sidebar-nav">
10
- <ul class="toc-list">
11
- <TocItem v-for="item in documentStore.sections" :key="item.id" :item="item" />
12
- </ul>
13
- </nav>
14
- </aside>
15
- </template>
16
-
17
- <script setup lang="ts">
18
- import { useDocumentStore } from '@/stores/documentStore'
19
- import { useUiStore } from '@/stores/uiStore'
20
- import TocItem from './TocItem.vue'
21
-
22
- const documentStore = useDocumentStore()
23
- const uiStore = useUiStore()
24
- </script>
25
-
26
- <style scoped>
27
- .sidebar {
28
- position: fixed;
29
- top: 0;
30
- left: 0;
31
- width: 280px;
32
- height: 100vh;
33
- background: var(--chrome-bg);
34
- border-right: 1px solid var(--chrome-border);
35
- transform: translateX(-100%);
36
- transition: transform 0.2s ease;
37
- z-index: 50;
38
- display: flex;
39
- flex-direction: column;
40
- overflow: hidden;
41
- }
42
- .sidebar-open {
43
- transform: translateX(0);
44
- }
45
- @media (min-width: 1024px) {
46
- .sidebar-open { transform: translateX(0); }
47
- }
48
- .sidebar-header {
49
- display: flex;
50
- align-items: center;
51
- justify-content: space-between;
52
- padding: 12px 16px;
53
- border-bottom: 1px solid var(--chrome-border);
54
- min-height: 56px;
55
- }
56
- .sidebar-title {
57
- font-size: 0.85rem;
58
- font-weight: 700;
59
- color: var(--chrome-text);
60
- overflow: hidden;
61
- text-overflow: ellipsis;
62
- white-space: nowrap;
63
- max-width: 200px;
64
- }
65
- .sidebar-close {
66
- display: flex;
67
- align-items: center;
68
- justify-content: center;
69
- color: var(--chrome-text-dim);
70
- padding: 4px;
71
- border-radius: 6px;
72
- cursor: pointer;
73
- }
74
- .sidebar-close:hover { background: var(--chrome-bg-hover); }
75
- .sidebar-nav { flex: 1; overflow-y: auto; padding: 8px 0; }
76
- .toc-list { list-style: none; padding: 0; margin: 0; }
77
- </style>
@@ -1,180 +0,0 @@
1
- <template>
2
- <a href="#main-content" class="skip-link" @click.prevent="skipToContent">Skip to content</a>
3
-
4
- <ReadingProgressBar :progress="readingProgress" :visible="ebookStore.showProgress" />
5
-
6
- <div v-if="uiStore.sidebarOpen" @click="uiStore.closeSidebar" class="fixed inset-0 bg-black/50 z-40 lg:hidden"></div>
7
-
8
- <AppSidebar v-show="!ebookStore.focusMode || uiStore.sidebarOpen" />
9
-
10
- <div :class="['focus-mode-topbar', { 'focus-mode-topbar--hidden': ebookStore.focusMode && !uiStore.sidebarOpen }]">
11
- <TopBar
12
- :title="documentStore.title"
13
- :sidebar-open="uiStore.sidebarOpen"
14
- @toggle-toc="ebookStore.toggleToc"
15
- @toggle-settings="ebookStore.toggleSettings"
16
- />
17
- </div>
18
-
19
- <main ref="mainContent" id="main-content" role="main" :class="[
20
- 'h-screen overflow-y-auto transition-all duration-200',
21
- !ebookStore.focusMode ? 'pt-14' : 'pt-0',
22
- uiStore.sidebarOpen ? 'lg:pl-[280px]' : '',
23
- ]" @scroll="onScroll">
24
- <div class="px-6 py-10 lg:px-8 lg:py-12 mx-auto transition-[max-width] duration-300 ease-out" :style="contentStyle">
25
- <div v-if="documentStore.loadError" class="error-state">
26
- <svg class="error-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
27
- <h2>Failed to load document</h2>
28
- <p class="error-detail">{{ documentStore.loadError }}</p>
29
- <button @click="retryLoad" class="error-retry">Retry</button>
30
- </div>
31
-
32
- <div v-else-if="!documentStore.mirrorDocument" class="loading-state">
33
- <div class="loading-skeleton">
34
- <div class="skeleton-title"></div>
35
- <div class="skeleton-line w-3/4"></div>
36
- <div class="skeleton-line w-full"></div>
37
- <div class="skeleton-line w-5/6"></div>
38
- </div>
39
- </div>
40
-
41
- <template v-else>
42
- <div v-if="documentStore.mirrorDocument" class="mn-content" :class="{ 'mn-content--reveal': contentRevealed }">
43
- <MirrorRenderer :blocks="documentStore.mirrorDocument.content || []" :top="true" />
44
- </div>
45
-
46
- <footer class="doc-fin">
47
- <div class="doc-fin-rule"></div>
48
- <h3 class="doc-fin-title">End of document</h3>
49
- <button @click="scrollToTop" class="doc-fin-btn">Back to top</button>
50
- <p class="doc-fin-credit">Generated by <a href="https://github.com/metanorma" class="doc-fin-credit-link">Metanorma</a></p>
51
- </footer>
52
- </template>
53
- </div>
54
- </main>
55
-
56
- <Transition name="back-to-top-fade">
57
- <button v-if="showBackToTop" class="back-to-top" @click="scrollToTop" title="Back to top">
58
- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
59
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"/>
60
- </svg>
61
- </button>
62
- </Transition>
63
- </template>
64
-
65
- <script setup lang="ts">
66
- import { onMounted, onUnmounted, computed, ref, watch, nextTick } from 'vue'
67
- import { useDocumentStore } from '@/stores/documentStore'
68
- import { useUiStore } from '@/stores/uiStore'
69
- import { useEbookStore } from '@/stores/ebookStore'
70
- import AppSidebar from '@/components/AppSidebar.vue'
71
- import MirrorRenderer from '@/components/MirrorRenderer.vue'
72
- import TopBar from '@/components/TopBar.vue'
73
- import ReadingProgressBar from '@/components/ReadingProgressBar.vue'
74
-
75
- const documentStore = useDocumentStore()
76
- const uiStore = useUiStore()
77
- const ebookStore = useEbookStore()
78
- const mainContent = ref<HTMLElement | null>(null)
79
-
80
- const contentRevealed = ref(false)
81
- const readingProgress = ref(0)
82
- const showBackToTop = ref(false)
83
-
84
- const contentStyle = computed(() => {
85
- const vars = ebookStore.getCssVariables()
86
- return { maxWidth: vars['--ebook-max-width'], margin: '0 auto' }
87
- })
88
-
89
- watch(() => documentStore.mirrorDocument, (doc) => {
90
- if (doc) {
91
- nextTick(() => { contentRevealed.value = true })
92
- }
93
- }, { immediate: true })
94
-
95
- function onScroll() {
96
- if (!mainContent.value) return
97
- const el = mainContent.value
98
- const progress = el.scrollTop / (el.scrollHeight - el.clientHeight) * 100
99
- readingProgress.value = Math.min(100, Math.max(0, progress))
100
- showBackToTop.value = el.scrollTop > 400
101
-
102
- const sections = el.querySelectorAll('[id]')
103
- for (let i = sections.length - 1; i >= 0; i--) {
104
- const section = sections[i] as HTMLElement
105
- if (section.getBoundingClientRect().top <= 120) {
106
- uiStore.setActiveSection(section.id)
107
- break
108
- }
109
- }
110
- }
111
-
112
- function scrollToTop() {
113
- mainContent.value?.scrollTo({ top: 0, behavior: 'smooth' })
114
- }
115
-
116
- function skipToContent() {
117
- mainContent.value?.focus()
118
- mainContent.value?.scrollTo({ top: 0 })
119
- }
120
-
121
- function retryLoad() {
122
- documentStore.loadFromWindow()
123
- }
124
-
125
- onMounted(() => {
126
- document.addEventListener('keydown', handleKeydown)
127
- if (window.innerWidth >= 1024) uiStore.openSidebar()
128
- })
129
-
130
- onUnmounted(() => {
131
- document.removeEventListener('keydown', handleKeydown)
132
- })
133
-
134
- function handleKeydown(e: KeyboardEvent) {
135
- if (e.key === 'Escape') {
136
- ebookStore.closeAll()
137
- } else if (e.key === 'f' && !e.ctrlKey && !e.metaKey) {
138
- const tag = (e.target as HTMLElement).tagName
139
- if (tag !== 'INPUT' && tag !== 'TEXTAREA') {
140
- ebookStore.toggleFocusMode()
141
- }
142
- }
143
- }
144
- </script>
145
-
146
- <style scoped>
147
- .skip-link { position: absolute; top: -100px; left: 0; background: var(--chrome-accent, #0d9488); color: #fff; padding: 8px 16px; z-index: 100; font-size: 0.85rem; font-weight: 600; border-radius: 0 0 8px 0; text-decoration: none; transition: top 0.1s; }
148
- .skip-link:focus { top: 0; }
149
- :deep(.mn-content--reveal) { animation: content-reveal 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
150
- @keyframes content-reveal { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
151
-
152
- .doc-fin { margin-top: 6rem; padding: 3rem 1rem 2rem; display: flex; flex-direction: column; align-items: center; text-align: center; }
153
- .doc-fin-rule { width: 100px; height: 1px; background: linear-gradient(to right, transparent, color-mix(in srgb, var(--ebook-accent) 40%, var(--ebook-border)), transparent); margin-bottom: 2rem; }
154
- .doc-fin-title { font-family: ui-monospace, monospace; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; color: var(--ebook-text-muted); margin: 0 0 1.5rem; }
155
- .doc-fin-btn { padding: 9px 20px; font-size: 0.78rem; font-weight: 500; border-radius: 8px; border: 1px solid var(--ebook-border); color: var(--ebook-text); background: transparent; cursor: pointer; }
156
- .doc-fin-btn:hover { background: var(--ebook-bg-secondary); }
157
- .doc-fin-credit { font-size: 0.6rem; color: var(--ebook-text-muted); opacity: 0.4; margin: 1rem 0 0; }
158
- .doc-fin-credit-link { color: var(--ebook-text-muted); text-decoration: none; }
159
- .doc-fin-credit-link:hover { text-decoration: underline; }
160
-
161
- .error-state { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 50vh; gap: 0.75rem; text-align: center; }
162
- .error-icon { width: 40px; height: 40px; color: #f59e0b; }
163
- .error-state h2 { font-size: 1.1rem; font-weight: 600; color: var(--chrome-text); }
164
- .error-detail { font-size: 0.85rem; color: var(--chrome-text-dim); max-width: 300px; }
165
- .error-retry { margin-top: 0.5rem; padding: 8px 20px; font-size: 0.8rem; font-weight: 600; border-radius: 8px; background: var(--chrome-accent, #0d9488); color: #fff; cursor: pointer; }
166
- .error-retry:hover { opacity: 0.9; }
167
-
168
- .loading-skeleton { max-width: 500px; margin: 0 auto; padding-top: 2rem; }
169
- .skeleton-title { height: 32px; width: 60%; border-radius: 6px; background: var(--chrome-bg-hover); margin-bottom: 1.5rem; animation: skeleton-pulse 1.5s ease-in-out infinite; }
170
- .skeleton-line { height: 14px; border-radius: 4px; background: var(--chrome-bg-hover); margin-bottom: 0.6rem; animation: skeleton-pulse 1.5s ease-in-out infinite; }
171
- @keyframes skeleton-pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
172
-
173
- .focus-mode-topbar { transition: opacity 0.2s ease; }
174
- .focus-mode-topbar--hidden { opacity: 0; pointer-events: none; }
175
-
176
- .back-to-top { position: fixed; bottom: 24px; right: 24px; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--chrome-bg-glass); color: var(--chrome-text); border: 1px solid var(--chrome-border); backdrop-filter: blur(8px); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); cursor: pointer; z-index: 35; transition: background 0.15s ease, transform 0.15s ease; }
177
- .back-to-top:hover { background: var(--chrome-bg-hover); transform: translateY(-2px); }
178
- .back-to-top-fade-enter-active, .back-to-top-fade-leave-active { transition: opacity 0.2s ease, transform 0.2s ease; }
179
- .back-to-top-fade-enter-from, .back-to-top-fade-leave-to { opacity: 0; transform: translateY(16px); }
180
- </style>
@@ -1,23 +0,0 @@
1
- <template>
2
- <div class="content-blocks">
3
- <template v-for="(block, index) in blocks" :key="index">
4
- <MirrorRenderer v-if="block.type === 'doc'" :blocks="block.content || []" />
5
- <TextRenderer v-else-if="block.type === 'text'" :node="block as any" />
6
- <ClauseBlock v-else-if="isSectionType(block.type)" :block="block" />
7
- <br v-else-if="block.type === 'soft_break'" />
8
- <component v-else :is="getBlockComponent(block.type)" :block="block" />
9
- </template>
10
- </div>
11
- </template>
12
-
13
- <script setup lang="ts">
14
- import type { MirrorBlockNode, MirrorTextNode } from '@/stores/documentStore'
15
- import ClauseBlock from './blocks/ClauseBlock.vue'
16
- import TextRenderer from './TextRenderer.vue'
17
- import { getBlockComponent } from './blocks'
18
- import { isSectionType } from '@/utils/typeMetadata'
19
-
20
- defineProps<{
21
- blocks: (MirrorBlockNode | MirrorTextNode)[]
22
- }>()
23
- </script>
@@ -1,29 +0,0 @@
1
- <template>
2
- <div v-if="visible" class="reading-progress">
3
- <div class="reading-progress-bar" :style="{ width: `${progress}%` }"></div>
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- defineProps<{
9
- progress: number
10
- visible: boolean
11
- }>()
12
- </script>
13
-
14
- <style scoped>
15
- .reading-progress {
16
- position: fixed;
17
- top: 56px;
18
- left: 0;
19
- right: 0;
20
- height: 3px;
21
- background: var(--chrome-border);
22
- z-index: 39;
23
- }
24
- .reading-progress-bar {
25
- height: 100%;
26
- background: var(--chrome-accent, #0d9488);
27
- transition: width 0.1s ease-out;
28
- }
29
- </style>
@@ -1,131 +0,0 @@
1
- <template>
2
- <component :is="wrapInMarks(node.marks || [])">
3
- {{ node.text }}
4
- </component>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { h, type VNode, type Component } from 'vue'
9
-
10
- interface Mark {
11
- type: string
12
- attrs?: Record<string, any>
13
- }
14
-
15
- interface MirrorTextNode {
16
- type: 'text'
17
- text: string
18
- marks?: Mark[]
19
- }
20
-
21
- defineProps<{
22
- node: MirrorTextNode
23
- }>()
24
-
25
- function markToTag(mark: Mark): string {
26
- switch (mark.type) {
27
- case 'emphasis':
28
- return 'em'
29
- case 'strong':
30
- return 'strong'
31
- case 'subscript':
32
- return 'sub'
33
- case 'superscript':
34
- return 'sup'
35
- case 'code':
36
- return 'code'
37
- case 'underline':
38
- return 'u'
39
- case 'strike':
40
- return 's'
41
- case 'link':
42
- case 'xref':
43
- case 'eref':
44
- return 'a'
45
- case 'footnote':
46
- return 'sup'
47
- case 'stem':
48
- case 'concept':
49
- case 'bcp14':
50
- case 'span':
51
- default:
52
- return 'span'
53
- }
54
- }
55
-
56
- function markAttrs(mark: Mark): Record<string, any> {
57
- switch (mark.type) {
58
- case 'link':
59
- return {
60
- href: mark.attrs?.href || '#',
61
- class: 'link-text hover:underline',
62
- target: '_blank',
63
- rel: 'noopener noreferrer',
64
- }
65
- case 'xref':
66
- return {
67
- href: `#${mark.attrs?.target || ''}`,
68
- class: 'xref link-text',
69
- }
70
- case 'eref':
71
- return {
72
- class: 'eref link-text',
73
- cite: mark.attrs?.citeas || '',
74
- }
75
- case 'emphasis':
76
- return { class: 'italic ebook-text' }
77
- case 'strong':
78
- return { class: 'font-bold heading-text' }
79
- case 'code':
80
- return { class: 'inline-code px-1.5 py-0.5 rounded text-sm font-mono border' }
81
- case 'footnote':
82
- return { class: 'footnote-inline' }
83
- case 'smallcap':
84
- return { class: 'smallcap' }
85
- case 'span': {
86
- const cls = mark.attrs?.class_attr
87
- return cls ? { class: cls } : {}
88
- }
89
- default:
90
- return {}
91
- }
92
- }
93
-
94
- function wrapInMarks(marks: Mark[]): Component {
95
- return {
96
- setup(_, { slots }) {
97
- return () => {
98
- if (marks.length === 0) {
99
- return h('span', {}, slots.default?.())
100
- }
101
-
102
- let inner: VNode | null = null
103
- for (let i = marks.length - 1; i >= 0; i--) {
104
- const mark = marks[i]
105
- const tag = markToTag(mark)
106
- const attrs = markAttrs(mark)
107
-
108
- if (inner) {
109
- inner = h(tag, attrs, inner)
110
- } else {
111
- inner = h(tag, attrs, slots.default?.())
112
- }
113
- }
114
-
115
- return inner || h('span', {}, slots.default?.())
116
- }
117
- },
118
- }
119
- }
120
- </script>
121
-
122
- <style scoped>
123
- .ebook-text { color: var(--ebook-text); }
124
- .heading-text { color: var(--ebook-text-heading); }
125
- .link-text { color: var(--ebook-link-color); transition: color 0.15s ease; }
126
- .xref { text-decoration: none; border-bottom: 1px dashed color-mix(in srgb, var(--ebook-link-color) 40%, transparent); }
127
- .xref:hover { border-bottom-color: var(--ebook-link-color); border-bottom-style: solid; }
128
- .inline-code { background: var(--ebook-inline-code-bg); color: var(--ebook-inline-code-text); border-color: var(--ebook-inline-code-border); }
129
- .footnote-inline { font-size: 0.75em; }
130
- .smallcap { font-variant: small-caps; }
131
- </style>
@@ -1,57 +0,0 @@
1
- <template>
2
- <li>
3
- <a
4
- :href="`#${item.id}`"
5
- :class="['toc-link', { 'toc-active': isActive }]"
6
- @click.prevent="navigate"
7
- >
8
- <span v-if="number" class="toc-number">{{ number }}</span>
9
- {{ item.title }}
10
- </a>
11
- <ul v-if="item.children.length > 0" class="toc-list">
12
- <TocItem v-for="child in item.children" :key="child.id" :item="child" />
13
- </ul>
14
- </li>
15
- </template>
16
-
17
- <script setup lang="ts">
18
- import { computed } from 'vue'
19
- import { useDocumentStore, type TocItem as TocItemType } from '@/stores/documentStore'
20
- import { useUiStore } from '@/stores/uiStore'
21
-
22
- const props = defineProps<{ item: TocItemType }>()
23
-
24
- const documentStore = useDocumentStore()
25
- const uiStore = useUiStore()
26
-
27
- const isActive = computed(() => uiStore.activeSectionId === props.item.id)
28
- const number = computed(() => documentStore.getNumbering(props.item.id))
29
-
30
- function navigate() {
31
- const el = document.getElementById(props.item.id)
32
- if (el) {
33
- el.scrollIntoView({ behavior: 'smooth', block: 'start' })
34
- history.replaceState(null, '', `#${props.item.id}`)
35
- }
36
- if (window.innerWidth < 1024) uiStore.closeSidebar()
37
- }
38
- </script>
39
-
40
- <style scoped>
41
- .toc-list { list-style: none; padding-left: 12px; margin: 0; }
42
- .toc-link {
43
- display: flex;
44
- align-items: baseline;
45
- gap: 6px;
46
- padding: 6px 16px;
47
- font-size: 0.82rem;
48
- color: var(--chrome-text-dim);
49
- text-decoration: none;
50
- border-radius: 6px;
51
- transition: background 0.1s ease, color 0.1s ease;
52
- cursor: pointer;
53
- }
54
- .toc-link:hover { background: var(--chrome-bg-hover); color: var(--chrome-text); }
55
- .toc-active { color: var(--chrome-accent, #0d9488); background: color-mix(in srgb, var(--chrome-accent, #0d9488) 15%, transparent); }
56
- .toc-number { font-family: ui-monospace, monospace; font-size: 0.75rem; color: var(--chrome-text-muted); min-width: 2em; }
57
- </style>