metanorma-document 0.2.9 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +72 -81
- data/CLAUDE.md +26 -0
- data/README.adoc +144 -0
- data/Rakefile +14 -2
- data/TODO.finalize/01-split-multi-class-files.md +8 -0
- data/TODO.finalize/02-remove-data-dist-iso-document-frontend.md +6 -0
- data/TODO.finalize/03-align-frontend-iife-and-gha-build.md +11 -0
- data/TODO.finalize/04-theme-per-flavor-config-driven.md +9 -0
- data/TODO.finalize/05-migrate-all-html-to-liquid.md +16 -0
- data/TODO.finalize/06-integrate-pubid-library.md +16 -0
- data/TODO.finalize/07-replace-relaton-models-with-relaton-bib.md +39 -0
- data/TODO.finalize/08-refactor-renderer-architecture.md +25 -0
- data/TODO.finalize/09-eliminate-code-smells.md +14 -0
- data/TODO.finalize/10-comprehensive-spec-coverage.md +24 -0
- data/TODO.finalize/11-config-driven-flavor-metadata.md +20 -0
- data/TODO.finalize/12-add-frozen-string-literal.md +6 -0
- data/TODO.finalize/13-extract-composition-from-god-class.md +96 -0
- data/TODO.finalize/14-config-driven-section-ordering.md +31 -0
- data/TODO.finalize/15-theme-directories-per-flavor.md +46 -0
- data/TODO.finalize/16-theme-lutaml-model-schema.md +44 -0
- data/data/javascripts/components/mn-footnotes.js +68 -0
- data/data/javascripts/components/mn-lightbox.js +18 -2
- data/data/javascripts/components/mn-shortcuts.js +2 -0
- data/data/javascripts/core/mn-navigation.js +8 -0
- data/data/javascripts/core/mn-theme.js +9 -9
- data/data/logos/oiml-logo-full-dark.svg +1 -0
- data/data/logos/oiml-logo-full-light.svg +1 -0
- data/data/logos/oiml-logo-icon-dark.svg +1 -0
- data/data/logos/oiml-logo-icon-light.svg +1 -0
- data/data/logos/oiml-logo.svg +1 -0
- data/data/logos/pdfa-logo.svg +31 -94
- data/data/stylesheets/base/_layout.css +3 -0
- data/data/stylesheets/base/_reset.css +3 -3
- data/data/stylesheets/base/_typography.css +0 -5
- data/data/stylesheets/components/bibliography.css +3 -3
- data/data/stylesheets/components/cover.css +3 -1
- data/data/stylesheets/components/figure.css +13 -1
- data/data/stylesheets/components/footnote.css +65 -5
- data/data/stylesheets/components/formula.css +44 -0
- data/data/stylesheets/components/header.css +17 -2
- data/data/stylesheets/components/inline.css +1 -1
- data/data/stylesheets/components/table.css +15 -2
- data/data/stylesheets/components/term.css +0 -1
- data/data/themes/bipm.yaml +60 -0
- data/data/themes/cc.yaml +43 -0
- data/data/themes/icc.yaml +39 -0
- data/data/themes/iec.yaml +44 -0
- data/data/themes/ieee.yaml +43 -0
- data/data/themes/ietf.yaml +45 -0
- data/data/themes/iho.yaml +46 -0
- data/data/themes/iso.yaml +40 -0
- data/data/themes/itu.yaml +45 -0
- data/data/themes/ogc.yaml +51 -0
- data/data/themes/oiml.yaml +56 -0
- data/data/themes/pdfa.yaml +44 -0
- data/data/themes/ribose.yaml +43 -0
- data/exe/metanorma-document +11 -0
- data/frontend/e2e/sample-html.test.ts +256 -0
- data/frontend/index.html +12 -0
- data/frontend/package-lock.json +4725 -0
- data/frontend/package.json +32 -0
- data/frontend/postcss.config.js +6 -0
- data/frontend/src/App.vue +79 -0
- data/frontend/src/app.ts +21 -0
- data/frontend/src/components/AppSidebar.vue +77 -0
- data/frontend/src/components/DocumentReader.vue +180 -0
- data/frontend/src/components/MirrorRenderer.vue +23 -0
- data/frontend/src/components/ReadingProgressBar.vue +29 -0
- data/frontend/src/components/TextRenderer.vue +131 -0
- data/frontend/src/components/TocItem.vue +57 -0
- data/frontend/src/components/TopBar.vue +49 -0
- data/frontend/src/components/__tests__/MirrorRenderer.test.ts +178 -0
- data/frontend/src/components/blocks/AdmonitionBlock.vue +74 -0
- data/frontend/src/components/blocks/ClauseBlock.vue +53 -0
- data/frontend/src/components/blocks/ExampleBlock.vue +21 -0
- data/frontend/src/components/blocks/FallbackBlock.vue +18 -0
- data/frontend/src/components/blocks/FigureBlock.vue +26 -0
- data/frontend/src/components/blocks/FootnotesBlock.vue +25 -0
- data/frontend/src/components/blocks/ListBlocks.vue +62 -0
- data/frontend/src/components/blocks/NoteBlock.vue +21 -0
- data/frontend/src/components/blocks/ParagraphBlock.vue +25 -0
- data/frontend/src/components/blocks/QuoteBlock.vue +25 -0
- data/frontend/src/components/blocks/ReviewBlock.vue +39 -0
- data/frontend/src/components/blocks/SourcecodeBlock.vue +52 -0
- data/frontend/src/components/blocks/TableBlock.vue +48 -0
- data/frontend/src/components/blocks/index.ts +36 -0
- data/frontend/src/stores/__tests__/documentStore.fixture.test.ts +272 -0
- data/frontend/src/stores/__tests__/documentStore.test.ts +143 -0
- data/frontend/src/stores/__tests__/ebookStore.test.ts +145 -0
- data/frontend/src/stores/__tests__/uiStore.test.ts +42 -0
- data/frontend/src/stores/documentStore.ts +153 -0
- data/frontend/src/stores/ebookStore.ts +179 -0
- data/frontend/src/stores/uiStore.ts +32 -0
- data/frontend/src/styles.css +156 -0
- data/frontend/src/types/__tests__/rendering-contract.test.ts +172 -0
- data/frontend/src/types/rendering-contract.ts +209 -0
- data/frontend/src/utils/__tests__/typeMetadata.test.ts +102 -0
- data/frontend/src/utils/typeMetadata.ts +121 -0
- data/frontend/tailwind.config.js +18 -0
- data/frontend/test/fixtures/iso-document.json +271 -0
- data/frontend/tmp/debug_e2e.cjs +46 -0
- data/frontend/tsconfig.json +25 -0
- data/frontend/tsconfig.node.json +11 -0
- data/frontend/vite.config.ts +37 -0
- data/frontend/vitest.e2e.config.ts +9 -0
- data/lib/metanorma/bipm_document/metadata/bipm_bibliographic_item.rb +0 -14
- data/lib/metanorma/bipm_document/metadata/depiction_element.rb +18 -0
- data/lib/metanorma/bipm_document/metadata.rb +1 -1
- data/lib/metanorma/document/cli.rb +116 -0
- data/lib/metanorma/document/components/ancillary_blocks/callout_annotation.rb +27 -0
- data/lib/metanorma/document/components/ancillary_blocks/sourcecode_block.rb +0 -65
- data/lib/metanorma/document/components/ancillary_blocks/sourcecode_body.rb +18 -0
- data/lib/metanorma/document/components/ancillary_blocks.rb +4 -0
- data/lib/metanorma/document/components/bib_data/bib_data.rb +7 -0
- data/lib/metanorma/document/components/blocks/classification_value.rb +21 -0
- data/lib/metanorma/document/components/blocks/permission_model.rb +28 -0
- data/lib/metanorma/document/components/blocks/recommendation_model.rb +28 -0
- data/lib/metanorma/document/components/blocks/requirement_base.rb +30 -0
- data/lib/metanorma/document/components/blocks/requirement_classification.rb +20 -0
- data/lib/metanorma/document/components/blocks/requirement_description.rb +43 -0
- data/lib/metanorma/document/components/blocks/requirement_inherit.rb +24 -0
- data/lib/metanorma/document/components/blocks/requirement_model.rb +0 -131
- data/lib/metanorma/document/components/blocks.rb +8 -7
- data/lib/metanorma/document/components/id_elements/image.rb +2 -0
- data/lib/metanorma/document/components/inline/asciimath_element.rb +2 -0
- data/lib/metanorma/document/components/inline/attribution_element.rb +2 -0
- data/lib/metanorma/document/components/inline/bcp14_element.rb +2 -0
- data/lib/metanorma/document/components/inline/biblio_tag_element.rb +2 -0
- data/lib/metanorma/document/components/inline/br_element.rb +2 -0
- data/lib/metanorma/document/components/inline/comma_element.rb +2 -0
- data/lib/metanorma/document/components/inline/concept_element.rb +2 -0
- data/lib/metanorma/document/components/inline/display_text_element.rb +2 -0
- data/lib/metanorma/document/components/inline/em_raw_element.rb +2 -0
- data/lib/metanorma/document/components/inline/enum_comma_element.rb +2 -0
- data/lib/metanorma/document/components/inline/eref_element.rb +2 -0
- data/lib/metanorma/document/components/inline/fmt_admitted_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_annotation_body_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_annotation_end_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_annotation_start_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_concept_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_definition_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_fn_body_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_fn_label_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_footnote_container_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_identifier_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_name_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_preferred_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_sourcecode_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_stem_element.rb +10 -0
- data/lib/metanorma/document/components/inline/fmt_termsource_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_title_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_xref_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fmt_xref_label_element.rb +4 -0
- data/lib/metanorma/document/components/inline/fn_element.rb +2 -0
- data/lib/metanorma/document/components/inline/link_element.rb +2 -0
- data/lib/metanorma/document/components/inline/localized_string_element.rb +2 -0
- data/lib/metanorma/document/components/inline/localized_strings_element.rb +2 -0
- data/lib/metanorma/document/components/inline/location_element.rb +24 -0
- data/lib/metanorma/document/components/inline/math_element.rb +2 -0
- data/lib/metanorma/document/components/inline/name_with_id_element.rb +4 -0
- data/lib/metanorma/document/components/inline/rendered_display.rb +23 -0
- data/lib/metanorma/document/components/inline/rendered_math_element.rb +21 -0
- data/lib/metanorma/document/components/inline/semantic_content.rb +51 -0
- data/lib/metanorma/document/components/inline/semantic_math_element.rb +20 -0
- data/lib/metanorma/document/components/inline/semx_child_element.rb +2 -0
- data/lib/metanorma/document/components/inline/semx_element.rb +12 -1
- data/lib/metanorma/document/components/inline/small_cap_element.rb +2 -0
- data/lib/metanorma/document/components/inline/span_element.rb +10 -15
- data/lib/metanorma/document/components/inline/stem_inline_element.rb +7 -1
- data/lib/metanorma/document/components/inline/strong_raw_element.rb +2 -0
- data/lib/metanorma/document/components/inline/sub_element.rb +2 -0
- data/lib/metanorma/document/components/inline/sup_element.rb +2 -0
- data/lib/metanorma/document/components/inline/tab_element.rb +2 -0
- data/lib/metanorma/document/components/inline/title_with_annotation_element.rb +4 -0
- data/lib/metanorma/document/components/inline/tt_element.rb +2 -0
- data/lib/metanorma/document/components/inline/variant_title_element.rb +2 -0
- data/lib/metanorma/document/components/inline/vocabulary.rb +184 -0
- data/lib/metanorma/document/components/inline/xref_element.rb +10 -0
- data/lib/metanorma/document/components/inline.rb +12 -0
- data/lib/metanorma/document/components/multi_paragraph/quote_author_element.rb +20 -0
- data/lib/metanorma/document/components/multi_paragraph/quote_block.rb +0 -29
- data/lib/metanorma/document/components/multi_paragraph.rb +2 -0
- data/lib/metanorma/document/components/reference_elements/source_element.rb +0 -31
- data/lib/metanorma/document/components/reference_elements/source_modification.rb +21 -0
- data/lib/metanorma/document/components/reference_elements/source_origin.rb +28 -0
- data/lib/metanorma/document/components/reference_elements.rb +2 -2
- data/lib/metanorma/document/components/tables/col_element.rb +18 -0
- data/lib/metanorma/document/components/tables/col_group_element.rb +18 -0
- data/lib/metanorma/document/components/tables/table_block.rb +0 -22
- data/lib/metanorma/document/components/tables/table_body_section.rb +16 -0
- data/lib/metanorma/document/components/tables/table_foot_section.rb +16 -0
- data/lib/metanorma/document/components/tables/table_head_section.rb +16 -0
- data/lib/metanorma/document/components/tables/table_section.rb +0 -25
- data/lib/metanorma/document/components/tables.rb +5 -3
- data/lib/metanorma/document/relaton/address.rb +0 -27
- data/lib/metanorma/document/relaton/bib_item_locality.rb +3 -12
- data/lib/metanorma/document/relaton/copyright_association.rb +0 -10
- data/lib/metanorma/document/relaton/copyright_owner.rb +16 -0
- data/lib/metanorma/document/relaton/edition.rb +4 -7
- data/lib/metanorma/document/relaton/formatted_address.rb +29 -0
- data/lib/metanorma/document/relaton/logo_element.rb +18 -0
- data/lib/metanorma/document/relaton/organization.rb +0 -14
- data/lib/metanorma/document/relaton/phone.rb +3 -9
- data/lib/metanorma/document/relaton/place_type.rb +0 -13
- data/lib/metanorma/document/relaton/price_type.rb +3 -9
- data/lib/metanorma/document/relaton/region_element.rb +18 -0
- data/lib/metanorma/document/relaton.rb +6 -1
- data/lib/metanorma/document/version.rb +1 -1
- data/lib/metanorma/document.rb +2 -0
- data/lib/metanorma/html/asset_pipeline.rb +1 -0
- data/lib/metanorma/html/base_renderer.rb +284 -1057
- data/lib/metanorma/html/bipm_renderer.rb +15 -144
- data/lib/metanorma/html/cc_renderer.rb +1 -45
- data/lib/metanorma/html/component/base.rb +2 -14
- data/lib/metanorma/html/component/index_section.rb +41 -43
- data/lib/metanorma/html/drops/admonition_drop.rb +1 -4
- data/lib/metanorma/html/drops/biblio_entry_drop.rb +50 -0
- data/lib/metanorma/html/drops/block_element_drop.rb +7 -2
- data/lib/metanorma/html/drops/example_drop.rb +1 -4
- data/lib/metanorma/html/drops/figure_drop.rb +31 -22
- data/lib/metanorma/html/drops/footnote_drop.rb +1 -1
- data/lib/metanorma/html/drops/formula_drop.rb +45 -16
- data/lib/metanorma/html/drops/note_drop.rb +9 -7
- data/lib/metanorma/html/drops/sourcecode_drop.rb +12 -5
- data/lib/metanorma/html/drops.rb +2 -0
- data/lib/metanorma/html/flavor.rb +45 -0
- data/lib/metanorma/html/flavor_registry.rb +49 -0
- data/lib/metanorma/html/generator.rb +108 -31
- data/lib/metanorma/html/icc_renderer.rb +0 -39
- data/lib/metanorma/html/iec_renderer.rb +1 -44
- data/lib/metanorma/html/ieee_renderer.rb +1 -45
- data/lib/metanorma/html/ietf_renderer.rb +1 -48
- data/lib/metanorma/html/iho_renderer.rb +1 -46
- data/lib/metanorma/html/iso_renderer.rb +290 -343
- data/lib/metanorma/html/itu_renderer.rb +1 -45
- data/lib/metanorma/html/ogc_renderer.rb +15 -76
- data/lib/metanorma/html/oiml_renderer.rb +18 -38
- data/lib/metanorma/html/pdfa_renderer.rb +0 -39
- data/lib/metanorma/html/renderer_delegation.rb +21 -0
- data/lib/metanorma/html/renderers/block_renderer.rb +372 -0
- data/lib/metanorma/html/renderers/element_order_traversal.rb +34 -0
- data/lib/metanorma/html/renderers/inline_renderer.rb +642 -0
- data/lib/metanorma/html/renderers/pubid_renderer.rb +47 -0
- data/lib/metanorma/html/renderers/section_renderer.rb +193 -0
- data/lib/metanorma/html/renderers.rb +10 -0
- data/lib/metanorma/html/ribose_renderer.rb +1 -45
- data/lib/metanorma/html/standard_renderer.rb +344 -230
- data/lib/metanorma/html/templates/_audio.html.liquid +1 -0
- data/lib/metanorma/html/templates/_biblio_entry.html.liquid +1 -0
- data/lib/metanorma/html/templates/_bipm_cover.html.liquid +27 -0
- data/lib/metanorma/html/templates/_boilerplate.html.liquid +1 -0
- data/lib/metanorma/html/templates/_bookmark.html.liquid +1 -0
- data/lib/metanorma/html/templates/_br.html.liquid +1 -0
- data/lib/metanorma/html/templates/_definition_list.html.liquid +6 -0
- data/lib/metanorma/html/templates/_element.html.liquid +1 -0
- data/lib/metanorma/html/templates/_fn_marker.html.liquid +1 -0
- data/lib/metanorma/html/templates/_footnotes.html.liquid +6 -6
- data/lib/metanorma/html/templates/_formula.html.liquid +1 -1
- data/lib/metanorma/html/templates/_header.html.liquid +1 -1
- data/lib/metanorma/html/templates/_heading.html.liquid +1 -0
- data/lib/metanorma/html/templates/_image.html.liquid +1 -0
- data/lib/metanorma/html/templates/_inline_span.html.liquid +1 -0
- data/lib/metanorma/html/templates/_iso_cover.html.liquid +1 -1
- data/lib/metanorma/html/templates/_link.html.liquid +1 -0
- data/lib/metanorma/html/templates/_list.html.liquid +3 -0
- data/lib/metanorma/html/templates/_list_item.html.liquid +1 -0
- data/lib/metanorma/html/templates/_main_content.html.liquid +1 -0
- data/lib/metanorma/html/templates/_math_container.html.liquid +1 -0
- data/lib/metanorma/html/templates/_paragraph.html.liquid +1 -0
- data/lib/metanorma/html/templates/_prefatory_section.html.liquid +1 -0
- data/lib/metanorma/html/templates/_pubid_identifier.html.liquid +1 -0
- data/lib/metanorma/html/templates/_quote.html.liquid +4 -0
- data/lib/metanorma/html/templates/_ref_date.html.liquid +1 -0
- data/lib/metanorma/html/templates/_ref_title.html.liquid +1 -0
- data/lib/metanorma/html/templates/_section.html.liquid +5 -0
- data/lib/metanorma/html/templates/_standard_cover.html.liquid +31 -0
- data/lib/metanorma/html/templates/_standard_doc_title.html.liquid +3 -0
- data/lib/metanorma/html/templates/_stem_span.html.liquid +1 -0
- data/lib/metanorma/html/templates/_table.html.liquid +9 -0
- data/lib/metanorma/html/templates/_term_domain.html.liquid +1 -0
- data/lib/metanorma/html/templates/_term_example.html.liquid +1 -0
- data/lib/metanorma/html/templates/_term_note.html.liquid +1 -0
- data/lib/metanorma/html/templates/_term_number.html.liquid +1 -0
- data/lib/metanorma/html/templates/_term_source.html.liquid +1 -0
- data/lib/metanorma/html/templates/_term_text_note.html.liquid +1 -0
- data/lib/metanorma/html/templates/_video.html.liquid +1 -0
- data/lib/metanorma/html/templates/_wrapped_preface.html.liquid +1 -0
- data/lib/metanorma/html/templates/document.html.liquid +4 -0
- data/lib/metanorma/html/theme.rb +180 -107
- data/lib/metanorma/html.rb +16 -0
- data/lib/metanorma/ietf_document/metadata/ietf_bib_data_extension_type.rb +0 -25
- data/lib/metanorma/ietf_document/metadata/pi_settings.rb +32 -0
- data/lib/metanorma/ietf_document/metadata.rb +2 -0
- data/lib/metanorma/iso_document/metadata/doctype_element.rb +20 -0
- data/lib/metanorma/iso_document/metadata/iso_bib_data_extension_type.rb +0 -48
- data/lib/metanorma/iso_document/metadata/iso_bibliographic_item.rb +0 -72
- data/lib/metanorma/iso_document/metadata/iso_document_status.rb +0 -30
- data/lib/metanorma/iso_document/metadata/iso_localized_title.rb +4 -1
- data/lib/metanorma/iso_document/metadata/language_element.rb +18 -0
- data/lib/metanorma/iso_document/metadata/project_number.rb +22 -0
- data/lib/metanorma/iso_document/metadata/script_element.rb +18 -0
- data/lib/metanorma/iso_document/metadata/stage_element.rb +26 -0
- data/lib/metanorma/iso_document/metadata/stagename_element.rb +18 -0
- data/lib/metanorma/iso_document/metadata/structured_identifier.rb +0 -17
- data/lib/metanorma/iso_document/metadata/title_collection.rb +1 -0
- data/lib/metanorma/iso_document/metadata.rb +9 -4
- data/lib/metanorma/iso_document/terms/iso_term.rb +0 -13
- data/lib/metanorma/iso_document/terms/term_domain_element.rb +18 -0
- data/lib/metanorma/iso_document/terms.rb +1 -0
- data/lib/metanorma/itu_document/metadata/itu_bib_data_extension_type.rb +0 -37
- data/lib/metanorma/itu_document/metadata/meeting_date.rb +18 -0
- data/lib/metanorma/itu_document/metadata/meeting_element.rb +18 -0
- data/lib/metanorma/itu_document/metadata/study_period.rb +18 -0
- data/lib/metanorma/itu_document/metadata.rb +3 -4
- data/lib/metanorma/mirror/default_registry.rb +170 -0
- data/lib/metanorma/mirror/handler_registry.rb +60 -0
- data/lib/metanorma/mirror/handler_result.rb +37 -0
- data/lib/metanorma/mirror/handlers/admonition.rb +18 -0
- data/lib/metanorma/mirror/handlers/example.rb +21 -0
- data/lib/metanorma/mirror/handlers/figure.rb +53 -0
- data/lib/metanorma/mirror/handlers/formula.rb +35 -0
- data/lib/metanorma/mirror/handlers/inline/catalog.rb +57 -0
- data/lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb +159 -0
- data/lib/metanorma/mirror/handlers/inline/text_extractor.rb +116 -0
- data/lib/metanorma/mirror/handlers/inline.rb +226 -0
- data/lib/metanorma/mirror/handlers/list.rb +110 -0
- data/lib/metanorma/mirror/handlers/note.rb +26 -0
- data/lib/metanorma/mirror/handlers/paragraph.rb +19 -0
- data/lib/metanorma/mirror/handlers/quote.rb +16 -0
- data/lib/metanorma/mirror/handlers/review.rb +19 -0
- data/lib/metanorma/mirror/handlers/section.rb +149 -0
- data/lib/metanorma/mirror/handlers/sourcecode.rb +27 -0
- data/lib/metanorma/mirror/handlers/structural.rb +68 -0
- data/lib/metanorma/mirror/handlers/table.rb +81 -0
- data/lib/metanorma/mirror/handlers/term.rb +100 -0
- data/lib/metanorma/mirror/handlers.rb +60 -0
- data/lib/metanorma/mirror/id_strategy/positional.rb +166 -0
- data/lib/metanorma/mirror/id_strategy/preserve.rb +12 -0
- data/lib/metanorma/mirror/id_strategy.rb +34 -0
- data/lib/metanorma/mirror/math_util.rb +53 -0
- data/lib/metanorma/mirror/metadata.rb +37 -0
- data/lib/metanorma/mirror/model/container.rb +47 -0
- data/lib/metanorma/mirror/model/factory.rb +52 -0
- data/lib/metanorma/mirror/model/guide.rb +25 -0
- data/lib/metanorma/mirror/model/leaf.rb +17 -0
- data/lib/metanorma/mirror/model/mark.rb +53 -0
- data/lib/metanorma/mirror/model/node.rb +47 -0
- data/lib/metanorma/mirror/model/soft_break.rb +33 -0
- data/lib/metanorma/mirror/model/text.rb +34 -0
- data/lib/metanorma/mirror/model.rb +16 -0
- data/lib/metanorma/mirror/output/builder.rb +39 -0
- data/lib/metanorma/mirror/output/formats/base_format.rb +90 -0
- data/lib/metanorma/mirror/output/formats/inline_format.rb +81 -0
- data/lib/metanorma/mirror/output/formats.rb +53 -0
- data/lib/metanorma/mirror/output/html_renderer.rb +95 -0
- data/lib/metanorma/mirror/output/html_renderers/block_renderers.rb +178 -0
- data/lib/metanorma/mirror/output/html_renderers/inline_renderer.rb +61 -0
- data/lib/metanorma/mirror/output/html_renderers/list_renderers.rb +96 -0
- data/lib/metanorma/mirror/output/html_renderers/mark_renderers.rb +41 -0
- data/lib/metanorma/mirror/output/html_renderers/section_renderers.rb +129 -0
- data/lib/metanorma/mirror/output/html_renderers/structural_renderers.rb +80 -0
- data/lib/metanorma/mirror/output/html_renderers/table_renderers.rb +87 -0
- data/lib/metanorma/mirror/output/html_renderers.rb +76 -0
- data/lib/metanorma/mirror/output/pipeline.rb +92 -0
- data/lib/metanorma/mirror/output/pipeline_context.rb +22 -0
- data/lib/metanorma/mirror/output.rb +14 -0
- data/lib/metanorma/mirror/rewriter.rb +121 -0
- data/lib/metanorma/mirror/safe_attr.rb +16 -0
- data/lib/metanorma/mirror/serialization/json_serializer.rb +25 -0
- data/lib/metanorma/mirror/serialization/yaml_serializer.rb +20 -0
- data/lib/metanorma/mirror/serialization.rb +10 -0
- data/lib/metanorma/mirror/transformer.rb +110 -0
- data/lib/metanorma/mirror.rb +31 -0
- data/lib/metanorma/standard_document/annotation.rb +37 -0
- data/lib/metanorma/standard_document/block_attributes.rb +15 -2
- data/lib/metanorma/standard_document/blocks/block_source.rb +0 -23
- data/lib/metanorma/standard_document/blocks/source_origin_element.rb +23 -0
- data/lib/metanorma/standard_document/blocks.rb +1 -1
- data/lib/metanorma/standard_document/terms/term_expression.rb +0 -31
- data/lib/metanorma/standard_document/terms/term_name_element.rb +29 -0
- data/lib/metanorma/standard_document/terms.rb +1 -0
- data/script/render_both.rb +18 -0
- metadata +272 -13
- data/.github/workflows/rake.yml +0 -21
- data/.github/workflows/release.yml +0 -25
- data/.github/workflows/roundtrip-samples.yml +0 -132
- data/.gitignore +0 -19
- data/.rspec +0 -3
- data/.rubocop.yml +0 -22
- data/Gemfile +0 -28
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/metanorma-document.gemspec +0 -35
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 05125b6d3a480509e630600c04a152707d7af1cf32423a3906b99032fbb18fcd
|
|
4
|
+
data.tar.gz: 1c45b49ac852306fca98f05fc59cb0f790a5b814a6a3b8b56cfd6960b9cc726c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ebfc36533344fd420cc2286357b77d4fe94213c8f31a0defdd7c4b06af6938e0258472bd279bd275f6a85f34a2c991a4fd12cd90d0b212e5ae9780506353600
|
|
7
|
+
data.tar.gz: 66b5e24551fd844cb8ad9368a10468509e0b3a7cc15836b5400d57024513da889c76f2571fc0d97cfdfacfacca7e72e6fe8d5d6f92c5bb54bc0a7d57d08d43ad
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-
|
|
3
|
+
# on 2026-07-18 16:00:24 UTC using RuboCop version 1.86.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
@@ -11,124 +11,102 @@ Gemspec/RequiredRubyVersion:
|
|
|
11
11
|
Exclude:
|
|
12
12
|
- 'metanorma-document.gemspec'
|
|
13
13
|
|
|
14
|
-
# Offense count:
|
|
15
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
16
|
-
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
17
|
-
# SupportedStyles: with_first_argument, with_fixed_indentation
|
|
18
|
-
Layout/ArgumentAlignment:
|
|
19
|
-
Exclude:
|
|
20
|
-
- 'lib/metanorma/standard_document.rb'
|
|
21
|
-
- 'spec/metanorma/flavor_roots/flavor_roots_spec.rb'
|
|
22
|
-
|
|
23
|
-
# Offense count: 666
|
|
14
|
+
# Offense count: 703
|
|
24
15
|
# This cop supports safe autocorrection (--autocorrect).
|
|
25
16
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
26
17
|
# URISchemes: http, https
|
|
27
18
|
Layout/LineLength:
|
|
28
19
|
Enabled: false
|
|
29
20
|
|
|
30
|
-
# Offense count:
|
|
31
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
32
|
-
# Configuration parameters: AllowInHeredoc.
|
|
33
|
-
Layout/TrailingWhitespace:
|
|
34
|
-
Exclude:
|
|
35
|
-
- 'lib/metanorma/standard_document.rb'
|
|
36
|
-
|
|
37
|
-
# Offense count: 1
|
|
21
|
+
# Offense count: 2
|
|
38
22
|
# Configuration parameters: AllowedMethods.
|
|
39
23
|
# AllowedMethods: enums
|
|
40
24
|
Lint/ConstantDefinitionInBlock:
|
|
41
25
|
Exclude:
|
|
42
26
|
- 'spec/metanorma/html/renderer/class_ownership_spec.rb'
|
|
27
|
+
- 'spec/metanorma/html/renderer/liquid_templates_spec.rb'
|
|
43
28
|
|
|
44
|
-
# Offense count:
|
|
29
|
+
# Offense count: 3
|
|
45
30
|
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
|
46
31
|
Lint/DuplicateBranch:
|
|
47
32
|
Exclude:
|
|
48
33
|
- 'lib/metanorma/html/base_renderer.rb'
|
|
34
|
+
- 'lib/metanorma/html/renderers/inline_renderer.rb'
|
|
35
|
+
- 'lib/metanorma/html/standard_renderer.rb'
|
|
49
36
|
|
|
50
|
-
# Offense count:
|
|
37
|
+
# Offense count: 2
|
|
51
38
|
# Configuration parameters: AllowComments, AllowEmptyLambdas.
|
|
52
39
|
Lint/EmptyBlock:
|
|
53
40
|
Exclude:
|
|
54
|
-
- 'lib/metanorma/html/drops/formula_drop.rb'
|
|
55
41
|
- 'spec/metanorma/iso_document/metadata/title_roundtrip_spec.rb'
|
|
56
42
|
|
|
57
43
|
# Offense count: 4
|
|
58
44
|
# Configuration parameters: AllowedParentClasses.
|
|
59
45
|
Lint/MissingSuper:
|
|
60
46
|
Exclude:
|
|
61
|
-
- 'lib/metanorma/html/drops/
|
|
62
|
-
- 'lib/metanorma/html/drops/
|
|
63
|
-
- 'lib/metanorma/html/drops/
|
|
64
|
-
- 'lib/metanorma/
|
|
47
|
+
- 'lib/metanorma/html/drops/figure_drop.rb'
|
|
48
|
+
- 'lib/metanorma/html/drops/formula_drop.rb'
|
|
49
|
+
- 'lib/metanorma/html/drops/sourcecode_drop.rb'
|
|
50
|
+
- 'lib/metanorma/mirror/id_strategy/positional.rb'
|
|
65
51
|
|
|
66
52
|
# Offense count: 1
|
|
67
53
|
Lint/StructNewOverride:
|
|
68
54
|
Exclude:
|
|
69
55
|
- 'lib/metanorma/html/component/index_term_collector.rb'
|
|
70
56
|
|
|
71
|
-
# Offense count:
|
|
57
|
+
# Offense count: 23
|
|
58
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
59
|
+
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
|
|
60
|
+
# NotImplementedExceptions: NotImplementedError
|
|
61
|
+
Lint/UnusedMethodArgument:
|
|
62
|
+
Exclude:
|
|
63
|
+
- 'lib/metanorma/mirror/handlers/formula.rb'
|
|
64
|
+
- 'lib/metanorma/mirror/handlers/sourcecode.rb'
|
|
65
|
+
- 'lib/metanorma/mirror/output/html_renderers/block_renderers.rb'
|
|
66
|
+
- 'lib/metanorma/mirror/output/html_renderers/list_renderers.rb'
|
|
67
|
+
- 'lib/metanorma/mirror/output/html_renderers/section_renderers.rb'
|
|
68
|
+
- 'lib/metanorma/mirror/output/html_renderers/structural_renderers.rb'
|
|
69
|
+
- 'lib/metanorma/mirror/output/html_renderers/table_renderers.rb'
|
|
70
|
+
- 'spec/metanorma/mirror/handler_registry_spec.rb'
|
|
71
|
+
- 'spec/metanorma/mirror/html_renderer_spec.rb'
|
|
72
|
+
|
|
73
|
+
# Offense count: 114
|
|
72
74
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
73
75
|
Metrics/AbcSize:
|
|
74
76
|
Enabled: false
|
|
75
77
|
|
|
76
|
-
# Offense count:
|
|
78
|
+
# Offense count: 12
|
|
77
79
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
|
78
80
|
# AllowedMethods: refine
|
|
79
81
|
Metrics/BlockLength:
|
|
80
|
-
Max:
|
|
82
|
+
Max: 76
|
|
81
83
|
|
|
82
|
-
# Offense count:
|
|
84
|
+
# Offense count: 3
|
|
83
85
|
# Configuration parameters: CountBlocks, CountModifierForms.
|
|
84
86
|
Metrics/BlockNesting:
|
|
85
87
|
Max: 4
|
|
86
88
|
|
|
87
|
-
# Offense count:
|
|
89
|
+
# Offense count: 84
|
|
88
90
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
89
91
|
Metrics/CyclomaticComplexity:
|
|
90
|
-
|
|
91
|
-
- 'lib/metanorma/document/components/lists/list_item.rb'
|
|
92
|
-
- 'lib/metanorma/html/base_renderer.rb'
|
|
93
|
-
- 'lib/metanorma/html/bipm_renderer.rb'
|
|
94
|
-
- 'lib/metanorma/html/component/index_term_collector.rb'
|
|
95
|
-
- 'lib/metanorma/html/drops/figure_drop.rb'
|
|
96
|
-
- 'lib/metanorma/html/drops/formula_drop.rb'
|
|
97
|
-
- 'lib/metanorma/html/generator.rb'
|
|
98
|
-
- 'lib/metanorma/html/iso_renderer.rb'
|
|
99
|
-
- 'lib/metanorma/html/ogc_renderer.rb'
|
|
100
|
-
- 'lib/metanorma/html/standard_renderer.rb'
|
|
101
|
-
- 'lib/metanorma/html/theme.rb'
|
|
102
|
-
- 'lib/metanorma/iso_document/metadata/iso_localized_title.rb'
|
|
92
|
+
Enabled: false
|
|
103
93
|
|
|
104
|
-
# Offense count:
|
|
94
|
+
# Offense count: 149
|
|
105
95
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
106
96
|
Metrics/MethodLength:
|
|
107
|
-
Max:
|
|
97
|
+
Max: 102
|
|
108
98
|
|
|
109
|
-
# Offense count:
|
|
99
|
+
# Offense count: 3
|
|
110
100
|
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
|
111
101
|
Metrics/ParameterLists:
|
|
112
102
|
Max: 7
|
|
113
103
|
|
|
114
|
-
# Offense count:
|
|
104
|
+
# Offense count: 68
|
|
115
105
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
116
106
|
Metrics/PerceivedComplexity:
|
|
117
|
-
|
|
118
|
-
- 'lib/metanorma/document/components/lists/list_item.rb'
|
|
119
|
-
- 'lib/metanorma/html/base_renderer.rb'
|
|
120
|
-
- 'lib/metanorma/html/bipm_renderer.rb'
|
|
121
|
-
- 'lib/metanorma/html/component/index_term_collector.rb'
|
|
122
|
-
- 'lib/metanorma/html/drops/figure_drop.rb'
|
|
123
|
-
- 'lib/metanorma/html/drops/formula_drop.rb'
|
|
124
|
-
- 'lib/metanorma/html/generator.rb'
|
|
125
|
-
- 'lib/metanorma/html/iso_renderer.rb'
|
|
126
|
-
- 'lib/metanorma/html/ogc_renderer.rb'
|
|
127
|
-
- 'lib/metanorma/html/standard_renderer.rb'
|
|
128
|
-
- 'lib/metanorma/html/theme.rb'
|
|
129
|
-
- 'lib/metanorma/iso_document/metadata/iso_localized_title.rb'
|
|
107
|
+
Enabled: false
|
|
130
108
|
|
|
131
|
-
# Offense count:
|
|
109
|
+
# Offense count: 52
|
|
132
110
|
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
|
133
111
|
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
|
|
134
112
|
Naming/MethodParameterName:
|
|
@@ -137,17 +115,21 @@ Naming/MethodParameterName:
|
|
|
137
115
|
- 'lib/metanorma/html/component/footnote_collector.rb'
|
|
138
116
|
- 'lib/metanorma/html/drops/sourcecode_drop.rb'
|
|
139
117
|
- 'lib/metanorma/html/iso_renderer.rb'
|
|
118
|
+
- 'lib/metanorma/html/renderers/block_renderer.rb'
|
|
119
|
+
- 'lib/metanorma/html/renderers/inline_renderer.rb'
|
|
140
120
|
- 'spec/metanorma/html/renderer/footnote_collector_spec.rb'
|
|
141
121
|
|
|
142
|
-
# Offense count:
|
|
122
|
+
# Offense count: 4
|
|
143
123
|
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
|
|
144
124
|
# AllowedMethods: call
|
|
145
125
|
# WaywardPredicates: infinite?, nonzero?
|
|
146
126
|
Naming/PredicateMethod:
|
|
147
127
|
Exclude:
|
|
148
128
|
- 'lib/metanorma/html/base_renderer.rb'
|
|
129
|
+
- 'lib/metanorma/html/drops/biblio_entry_drop.rb'
|
|
130
|
+
- 'lib/metanorma/html/renderers/inline_renderer.rb'
|
|
149
131
|
|
|
150
|
-
# Offense count:
|
|
132
|
+
# Offense count: 3
|
|
151
133
|
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
|
|
152
134
|
# NamePrefix: is_, has_, have_, does_
|
|
153
135
|
# ForbiddenPrefixes: is_, has_, have_, does_
|
|
@@ -155,7 +137,9 @@ Naming/PredicateMethod:
|
|
|
155
137
|
# MethodDefinitionMacros: define_method, define_singleton_method
|
|
156
138
|
Naming/PredicatePrefix:
|
|
157
139
|
Exclude:
|
|
158
|
-
- '
|
|
140
|
+
- 'spec/**/*'
|
|
141
|
+
- 'lib/metanorma/html/base_renderer.rb'
|
|
142
|
+
- 'lib/metanorma/html/drops/biblio_entry_drop.rb'
|
|
159
143
|
|
|
160
144
|
# Offense count: 1
|
|
161
145
|
Performance/MapMethodChain:
|
|
@@ -165,27 +149,42 @@ Performance/MapMethodChain:
|
|
|
165
149
|
# Offense count: 7
|
|
166
150
|
RSpec/BeforeAfterAll:
|
|
167
151
|
Exclude:
|
|
152
|
+
- '**/spec/spec_helper.rb'
|
|
153
|
+
- '**/spec/rails_helper.rb'
|
|
154
|
+
- '**/spec/support/**/*.rb'
|
|
168
155
|
- 'spec/metanorma/flavor_roots/flavor_roots_spec.rb'
|
|
169
156
|
|
|
170
|
-
# Offense count:
|
|
157
|
+
# Offense count: 14
|
|
158
|
+
# Configuration parameters: Prefixes, AllowedPatterns.
|
|
159
|
+
# Prefixes: when, with, without
|
|
160
|
+
RSpec/ContextWording:
|
|
161
|
+
Exclude:
|
|
162
|
+
- 'spec/metanorma/html/renderer/theme_spec.rb'
|
|
163
|
+
- 'spec/metanorma/mirror/html_renderer_spec.rb'
|
|
164
|
+
|
|
165
|
+
# Offense count: 32
|
|
171
166
|
# Configuration parameters: IgnoredMetadata.
|
|
172
167
|
RSpec/DescribeClass:
|
|
173
168
|
Enabled: false
|
|
174
169
|
|
|
175
|
-
# Offense count:
|
|
170
|
+
# Offense count: 234
|
|
176
171
|
# Configuration parameters: CountAsOne.
|
|
177
172
|
RSpec/ExampleLength:
|
|
178
|
-
Max:
|
|
173
|
+
Max: 37
|
|
179
174
|
|
|
180
|
-
# Offense count:
|
|
175
|
+
# Offense count: 2
|
|
181
176
|
RSpec/LeakyConstantDeclaration:
|
|
182
177
|
Exclude:
|
|
183
178
|
- 'spec/metanorma/html/renderer/class_ownership_spec.rb'
|
|
179
|
+
- 'spec/metanorma/html/renderer/liquid_templates_spec.rb'
|
|
184
180
|
|
|
185
|
-
# Offense count:
|
|
181
|
+
# Offense count: 5
|
|
186
182
|
RSpec/MultipleDescribes:
|
|
187
183
|
Exclude:
|
|
188
184
|
- 'spec/metanorma/document_spec.rb'
|
|
185
|
+
- 'spec/metanorma/html/flavor_registry_spec.rb'
|
|
186
|
+
- 'spec/metanorma/mirror/handlers/remaining_handlers_spec.rb'
|
|
187
|
+
- 'spec/metanorma/mirror/serialization_spec.rb'
|
|
189
188
|
- 'spec/metanorma/standard_document/sections_spec.rb'
|
|
190
189
|
|
|
191
190
|
# Offense count: 1
|
|
@@ -200,13 +199,13 @@ RSpec/NamedSubject:
|
|
|
200
199
|
Exclude:
|
|
201
200
|
- 'spec/metanorma/flavor_roots/flavor_roots_spec.rb'
|
|
202
201
|
|
|
203
|
-
# Offense count:
|
|
202
|
+
# Offense count: 1076
|
|
204
203
|
# Configuration parameters: AllowedPatterns.
|
|
205
204
|
# AllowedPatterns: ^expect_, ^assert_
|
|
206
205
|
RSpec/NoExpectationExample:
|
|
207
206
|
Enabled: false
|
|
208
207
|
|
|
209
|
-
# Offense count:
|
|
208
|
+
# Offense count: 29
|
|
210
209
|
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
|
|
211
210
|
# SupportedInflectors: default, active_support
|
|
212
211
|
RSpec/SpecFilePathFormat:
|
|
@@ -216,14 +215,6 @@ RSpec/SpecFilePathFormat:
|
|
|
216
215
|
# This cop supports safe autocorrection (--autocorrect).
|
|
217
216
|
Style/ComparableClamp:
|
|
218
217
|
Exclude:
|
|
219
|
-
- 'lib/metanorma/html/base_renderer.rb'
|
|
220
218
|
- 'lib/metanorma/html/iso_renderer.rb'
|
|
219
|
+
- 'lib/metanorma/html/renderers/section_renderer.rb'
|
|
221
220
|
- 'lib/metanorma/html/standard_renderer.rb'
|
|
222
|
-
|
|
223
|
-
# Offense count: 1
|
|
224
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
225
|
-
# Configuration parameters: EnforcedStyle.
|
|
226
|
-
# SupportedStyles: literals, strict
|
|
227
|
-
Style/MutableConstant:
|
|
228
|
-
Exclude:
|
|
229
|
-
- 'lib/metanorma/html/base_renderer.rb'
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# metanorma-document — Project Rules
|
|
2
|
+
|
|
3
|
+
## ABSOLUTE RULE: NEVER use Nokogiri on document model XML
|
|
4
|
+
|
|
5
|
+
Document XML (presentation XML) is parsed into lutaml-model objects. All access to document content MUST go through the model object graph — typed attributes, `element_order`, `each_mixed_content`, etc.
|
|
6
|
+
|
|
7
|
+
NEVER:
|
|
8
|
+
- Call `to_xml` on a model object and then parse that XML with Nokogiri
|
|
9
|
+
- Use Nokogiri to strip, transform, or manipulate document XML content
|
|
10
|
+
- Use Nokogiri CSS selectors on document XML to find elements
|
|
11
|
+
|
|
12
|
+
The HTML renderer must use the model's typed attributes and the rendering pipeline (`render_paragraph`, `render_mixed_inline`, etc.) to produce HTML. Nokogiri is only acceptable for processing non-document strings (e.g., SVG logo files).
|
|
13
|
+
|
|
14
|
+
## ABSOLUTE RULE: Use `each_mixed_content` for mixed content nodes
|
|
15
|
+
|
|
16
|
+
For any node with `mixed? == true`, you MUST use `each_mixed_content` to iterate children. This provides the full sequence of text nodes and elements in correct order.
|
|
17
|
+
|
|
18
|
+
Do NOT:
|
|
19
|
+
- Use only typed attributes (like `paragraphs`, `title`) for rendering — these only give mapped elements, not text nodes
|
|
20
|
+
- Use `element_order` for inline content — it only shows element children, not interleaved text
|
|
21
|
+
|
|
22
|
+
`render_ordered_content` uses `element_order` and is acceptable for block-level sections (which contain only element children like paragraphs and lists). But for paragraphs and inline content containers, `each_mixed_content` is mandatory.
|
|
23
|
+
|
|
24
|
+
## ABSOLUTE RULE: No regex for HTML stripping
|
|
25
|
+
|
|
26
|
+
Never use regex (`/<[^>]+>/`) to strip HTML tags from rendered output. Text extraction must work directly on model objects via `extract_plain_text` (which walks `element_order` and typed attributes). If you need plain text from a model element, use `extract_plain_text(element)`, not `strip_html(render(element))`.
|
data/README.adoc
CHANGED
|
@@ -210,6 +210,150 @@ This library targets the modern Metanorma XML format which uses `<metanorma>` as
|
|
|
210
210
|
|
|
211
211
|
Legacy XML formats that use flavor-specific root elements (e.g. `<iso-standard>`, `<m3d-standard>`, `<csa-standard>`, `<un-standard>`) are *not supported*.
|
|
212
212
|
|
|
213
|
+
== Mirror Format
|
|
214
|
+
|
|
215
|
+
The `Metanorma::Mirror` module is a ProseMirror-style document model that captures the structural and inline content of a Metanorma document. It serves as an intermediate representation suitable for serialization, round-tripping, alternate rendering pipelines, and editor integrations.
|
|
216
|
+
|
|
217
|
+
The mirror format is fully model-driven: every node, mark, and document is an instance of a `Model` class. There are no hashes at the API boundary.
|
|
218
|
+
|
|
219
|
+
=== Model Layer
|
|
220
|
+
|
|
221
|
+
[horizontal]
|
|
222
|
+
`Model::Container` :: A node with children (`#content`)
|
|
223
|
+
`Model::Leaf` :: A node without children (e.g. `image`, `sourcecode`)
|
|
224
|
+
`Model::Text` :: Inline text carrying a string and a list of `Mark`s
|
|
225
|
+
`Model::SoftBreak` :: A soft line break inside a paragraph
|
|
226
|
+
`Model::Mark` :: An inline decoration (`emphasis`, `strong`, `link`, `xref`, `eref`, `footnote`, `stem`, ...)
|
|
227
|
+
`Model::Guide` :: Output wrapper with `content`, `meta`, and `title`
|
|
228
|
+
`Model::Factory.from_h(hash)` :: Rebuilds a model graph from a serialized hash
|
|
229
|
+
|
|
230
|
+
Each model class encapsulates its attributes via bounded accessors. `Mark` exposes `[]`, `[]=`, `set_attr`, and `fetch` for safe attribute mutation. `#to_h` is the canonical serialization method.
|
|
231
|
+
|
|
232
|
+
=== Forward Conversion (Metanorma → Mirror)
|
|
233
|
+
|
|
234
|
+
[source,ruby]
|
|
235
|
+
require "metanorma/document"
|
|
236
|
+
require "metanorma/mirror"
|
|
237
|
+
|
|
238
|
+
xml = File.read("spec/fixtures/iso/is/document-en.presentation.xml")
|
|
239
|
+
doc = Metanorma::IsoDocument::Root.from_xml(xml)
|
|
240
|
+
|
|
241
|
+
transformer = Metanorma::Mirror::Transformer.new
|
|
242
|
+
document = transformer.from_metanorma(doc)
|
|
243
|
+
document.class # => Metanorma::Mirror::Model::Container
|
|
244
|
+
|
|
245
|
+
=== Reverse Conversion (Mirror → Mirror, with Rewriting)
|
|
246
|
+
|
|
247
|
+
The `Rewriter` walks a Model graph and produces a new Model graph, applying skip rules and optional per-type customization. (The historical name `MirrorToMetanorma` is no longer accurate: the output is a Model graph, not Metanorma XML. The class was renamed to `Rewriter` to reflect this.)
|
|
248
|
+
|
|
249
|
+
[source,ruby]
|
|
250
|
+
rewriter = Metanorma::Mirror::Rewriter.new
|
|
251
|
+
rebuilt = rewriter.call(document)
|
|
252
|
+
|
|
253
|
+
Each `Rewriter` instance seeds its skip set and builder map from class-level defaults at `new` time, so two instances never share state. Instance-level mutation does not leak back to the class, and class-level mutation does not retroactively affect existing instances.
|
|
254
|
+
|
|
255
|
+
[source,ruby]
|
|
256
|
+
# Instance API — only affects this instance
|
|
257
|
+
rewriter.skip("my_type")
|
|
258
|
+
rewriter.register("my_type") do |node, _rewriter|
|
|
259
|
+
Metanorma::Mirror::Model::Leaf.new(type: "customized")
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Class API — seeds defaults copied into future instances
|
|
263
|
+
Metanorma::Mirror::Rewriter.skip("always_skip")
|
|
264
|
+
Metanorma::Mirror::Rewriter.register("always_customize") { |n, _r| ... }
|
|
265
|
+
|
|
266
|
+
Model dispatch is polymorphic: each `Model::*` class implements `accept_rewriter(rewriter)`, which calls the matching `rewriter#rewrite_container` / `#rewrite_leaf` / `#rewrite_text` / `#rewrite_soft_break`. There is no `case/when` on node classes in the dispatch path.
|
|
267
|
+
|
|
268
|
+
=== Default Handler Registry
|
|
269
|
+
|
|
270
|
+
`Metanorma::Mirror::DefaultRegistry.build` returns a fresh `HandlerRegistry` pre-populated with the standard Metanorma → Mirror mappings (paragraphs, blocks, lists, sections, terms, structural containers). It is the single source of truth for the default handler set — adding a new model-to-handler mapping is a single `register` call here, with no edits to `HandlerRegistry` itself.
|
|
271
|
+
|
|
272
|
+
[source,ruby]
|
|
273
|
+
Metanorma::Mirror.build_default_registry
|
|
274
|
+
# => #<Metanorma::Mirror::HandlerRegistry> (fresh instance each call)
|
|
275
|
+
|
|
276
|
+
=== Metadata Service
|
|
277
|
+
|
|
278
|
+
`Metanorma::Mirror::Metadata` is a standalone service that extracts document metadata (title, etc.) from a parsed bibdata object. It is consumed by both the forward pipeline (`Output::Pipeline::AttachMetadata`) and the forward transformer (`Transformer#extract_root_title`), keeping title-extraction logic in one place rather than duplicated across the Handlers layer.
|
|
279
|
+
|
|
280
|
+
[source,ruby]
|
|
281
|
+
Metanorma::Mirror::Metadata.title_from_bibdata(doc.bibdata)
|
|
282
|
+
# => "First title string"
|
|
283
|
+
|
|
284
|
+
=== Serialization
|
|
285
|
+
|
|
286
|
+
Mirror documents round-trip cleanly through JSON and YAML:
|
|
287
|
+
|
|
288
|
+
[source,ruby]
|
|
289
|
+
json = Metanorma::Mirror::Serialization::JsonSerializer.serialize(document)
|
|
290
|
+
restored = Metanorma::Mirror::Serialization::JsonSerializer.deserialize(json)
|
|
291
|
+
|
|
292
|
+
=== ID Strategies
|
|
293
|
+
|
|
294
|
+
ID assignment is pluggable via `Metanorma::Mirror::IdStrategy`:
|
|
295
|
+
|
|
296
|
+
[horizontal]
|
|
297
|
+
`IdStrategy::Preserve` :: Default. Keeps element IDs as-is.
|
|
298
|
+
`IdStrategy::Positional` :: Rewrites UUID-style IDs to positional IDs (`sec-X.Y.Z`, `anx-X`, `fig-N`, `table-N`) and translates cross-reference targets.
|
|
299
|
+
|
|
300
|
+
The `Positional` strategy exposes `register_category(model_class, category)` so new flavors can declare their model classes without editing dispatch code.
|
|
301
|
+
|
|
302
|
+
=== HTML Rendering from Mirror
|
|
303
|
+
|
|
304
|
+
`Metanorma::Mirror::Output::HtmlRenderer` produces SSR-ready HTML directly from a mirror Model graph. Renderer behavior is split into pluggable modules registered by node type (`clause`, `paragraph`, `bullet_list`, `table`, ...) and by mark type (`emphasis`, `link`, `xref`, ...). All dispatch is registry-driven (no `case/when` on types), so new node and mark types can be added without modifying core rendering code.
|
|
305
|
+
|
|
306
|
+
All HTML construction goes through `Nokogiri::HTML4::Builder` (or `Nokogiri::HTML5::Builder` for full documents). String concatenation of HTML is not permitted anywhere in the renderer layer. The `HtmlRenderers` module exposes shared helpers (`build`, `build_fragment`, `embed`, `wrap`, `escape_text`) so each renderer stays declarative.
|
|
307
|
+
|
|
308
|
+
Node handlers are stored as `UnboundMethod`s bound to the renderer instance at dispatch time. Register a new node handler by passing an instance method reference:
|
|
309
|
+
|
|
310
|
+
[source,ruby]
|
|
311
|
+
module MyRenderers
|
|
312
|
+
def self.register(registry)
|
|
313
|
+
registry.register_node_handler("callout",
|
|
314
|
+
instance_method(:render_callout))
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def render_callout(node, depth: 0)
|
|
318
|
+
HtmlRenderers.build { |doc| doc.span(class: "callout") { doc.text node.attrs["text"] } }
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
MyRenderers.register(Metanorma::Mirror::Output::HtmlRenderer)
|
|
322
|
+
|
|
323
|
+
Mark handlers are stored as `Proc`s that receive the already-rendered inner HTML and the `Mark` instance:
|
|
324
|
+
|
|
325
|
+
[source,ruby]
|
|
326
|
+
Metanorma::Mirror::Output::HtmlRenderer.register_mark_handler("kbd",
|
|
327
|
+
->(inner_html, _mark) { HtmlRenderers.wrap(:kbd, inner_html) })
|
|
328
|
+
|
|
329
|
+
=== Output Pipeline
|
|
330
|
+
|
|
331
|
+
`Metanorma::Mirror::Output::Pipeline` runs the full conversion: parse XML → forward transform → attach metadata. `Metanorma::Mirror::Output::Builder` orchestrates the pipeline and writes through a pluggable `Formats` registry (default: `InlineFormat`).
|
|
332
|
+
|
|
333
|
+
[source,ruby]
|
|
334
|
+
builder = Metanorma::Mirror::Output::Builder.new(
|
|
335
|
+
xml_path: "document.presentation.xml",
|
|
336
|
+
output_path: "output.html",
|
|
337
|
+
format: :inline,
|
|
338
|
+
flavor: "iso",
|
|
339
|
+
id_strategy: Metanorma::Mirror::IdStrategy::Positional.new,
|
|
340
|
+
)
|
|
341
|
+
builder.build
|
|
342
|
+
|
|
343
|
+
New formats register themselves without editing lookup code:
|
|
344
|
+
|
|
345
|
+
[source,ruby]
|
|
346
|
+
Metanorma::Mirror::Output::Formats.register(:pdf, MyPdfFormat)
|
|
347
|
+
|
|
348
|
+
=== CLI
|
|
349
|
+
|
|
350
|
+
[source,bash]
|
|
351
|
+
# Convert presentation XML to mirror JSON
|
|
352
|
+
metanorma-document to-mirror document.presentation.xml \
|
|
353
|
+
-o document.mirror.json \
|
|
354
|
+
--id-strategy positional \
|
|
355
|
+
--title "My Document"
|
|
356
|
+
|
|
213
357
|
== Documentation
|
|
214
358
|
|
|
215
359
|
Detailed architecture documentation is in the `docs/` directory:
|
data/Rakefile
CHANGED
|
@@ -9,6 +9,18 @@ require "rubocop/rake_task"
|
|
|
9
9
|
|
|
10
10
|
RuboCop::RakeTask.new
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
# Load custom tasks
|
|
13
|
+
Dir.glob("lib/tasks/*.rake").each { |task| load task }
|
|
14
|
+
|
|
15
|
+
# Build the frontend SPA (frontend/dist/)
|
|
16
|
+
desc "Build frontend SPA assets"
|
|
17
|
+
task :build_frontend do
|
|
18
|
+
frontend_dir = File.join(__dir__, "frontend")
|
|
19
|
+
puts "Building frontend..."
|
|
20
|
+
system("cd #{frontend_dir} && npm install && npm run build") || raise("Frontend build failed")
|
|
21
|
+
end
|
|
13
22
|
|
|
14
|
-
|
|
23
|
+
# Hook into bundler's release task to ensure frontend is built
|
|
24
|
+
Rake::Task["release"].enhance(["build_frontend"]) if Rake::Task.task_defined?("release")
|
|
25
|
+
|
|
26
|
+
task default: %i[spec rubocop]
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# 01 — Split multi-class files into one-class-per-file — DONE
|
|
2
|
+
|
|
3
|
+
All model files now contain exactly one class per file. Verified: every file under `lib/metanorma/document/`, `lib/metanorma/standard_document/`, `lib/metanorma/iso_document/`, `lib/metanorma/bipm_document/`, `lib/metanorma/itu_document/`, `lib/metanorma/ietf_document/`, `lib/metanorma/cc_document/` is single-class.
|
|
4
|
+
|
|
5
|
+
Nested classes that are only used internally by their parent (e.g. `AnnotationContainer::Annotation`) are legitimate and NOT split.
|
|
6
|
+
|
|
7
|
+
## Code quality requirements
|
|
8
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# 02 — Remove misplaced `data/dist/iso_document/frontend/` artifacts — DONE
|
|
2
|
+
|
|
3
|
+
`data/dist/iso_document/frontend/` directory no longer exists. Frontend build artifacts are correctly placed in `frontend/dist/` and included in gemspec via `Dir.glob("frontend/dist/*")`.
|
|
4
|
+
|
|
5
|
+
## Code quality requirements
|
|
6
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# 03 — Align frontend IIFE build and GHA gem release with docbook pattern — DONE
|
|
2
|
+
|
|
3
|
+
Aligned with docbook project:
|
|
4
|
+
- `Rakefile` has `build_frontend` task + release hook
|
|
5
|
+
- `gemspec` includes `frontend/dist/*`
|
|
6
|
+
- `.github/workflows/rake.yml` has `after-setup-ruby: cd frontend && npm install && npm run build`
|
|
7
|
+
- `frontend/vite.config.ts` produces `app.iife.js` + `app.css`
|
|
8
|
+
- `.gitignore` has `frontend/node_modules/` and `frontend/dist/`
|
|
9
|
+
|
|
10
|
+
## Code quality requirements
|
|
11
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 04 — Data-centric theme system: config files per flavor — DONE
|
|
2
|
+
|
|
3
|
+
All 13 flavor themes extracted to `data/themes/{flavor}.yaml`. `Theme.load(:iso)` reads YAML and applies overrides. BaseRenderer provides default `Theme.new`. Every flavor renderer uses `Theme.load(:flavor_name)`.
|
|
4
|
+
|
|
5
|
+
### Remaining enhancement
|
|
6
|
+
Publisher metadata (publishers, publisher_name, logo_map, font_url) still hardcoded in flavor renderers. These should move into theme YAML config so flavor renderers can be auto-generated from config alone.
|
|
7
|
+
|
|
8
|
+
## Code quality requirements
|
|
9
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# 05 — Migrate all HTML generation to Liquid templates — DONE
|
|
2
|
+
|
|
3
|
+
All HTML element generation uses Liquid templates. Zero raw HTML string injection via `@output <<` remains. The `tag()` helper has been removed from `base_renderer.rb`. All remaining `@output <<` calls are text streaming (`escape_html`, whitespace, raw content passthrough) — not HTML element generation.
|
|
4
|
+
|
|
5
|
+
32+ Liquid templates exist in `lib/metanorma/html/templates/`. The generic `_element.html.liquid` handles most tag wrapping. Specialized templates exist for tables, lists, figures, headings, math, links, etc.
|
|
6
|
+
|
|
7
|
+
### OOP Liquid pattern
|
|
8
|
+
All rendering uses the `capture_output` + `render_liquid` pattern:
|
|
9
|
+
1. Capture child content into a Ruby string via `capture_output`
|
|
10
|
+
2. Pass captured content to `render_liquid("_template.html.liquid", assigns)`
|
|
11
|
+
3. Result is appended to `@output` by the caller
|
|
12
|
+
|
|
13
|
+
Drop classes (`Drops::*`) are used for complex objects that need pre-rendered HTML fields (e.g. `BiblioEntryDrop`, `FigureDrop`).
|
|
14
|
+
|
|
15
|
+
## Code quality requirements
|
|
16
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# 06 — Integrate pubid library for publication identifier handling — DONE
|
|
2
|
+
|
|
3
|
+
## What was done
|
|
4
|
+
1. Added `pubid ~> 2.0` to gemspec dependency
|
|
5
|
+
2. Added `gem "pubid", path: "../../mn/pubid"` to Gemfile for local dev
|
|
6
|
+
3. Created `lib/metanorma/html/concerns/pubid_rendering.rb` — `PubidRendering` module with:
|
|
7
|
+
- `FLAVOR_PUBID_MAP` mapping document class names to pubid modules
|
|
8
|
+
- `parse_pubid(docidentifier_string)` — flavor-aware pubid parsing
|
|
9
|
+
- `pubid_to_html(identifier)` — renders to semantic HTML with CSS classes
|
|
10
|
+
- `resolve_pubid_module` — auto-detects flavor from renderer class
|
|
11
|
+
4. Wired into `BaseRenderer` via `include PubidRendering`
|
|
12
|
+
5. Refactored `render_bibitem_content` in `standard_renderer.rb` to try pubid first
|
|
13
|
+
6. Created specs in `pubid_rendering_spec.rb`
|
|
14
|
+
|
|
15
|
+
## Code quality requirements
|
|
16
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 07 — Integrate relaton-bib library (partially complete)
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
- **Done**: relaton-bib dependency added, 4 models replaced via inheritance, `require` at module level
|
|
5
|
+
- **Blocked**: Most models have incompatible XML schemas (different attribute names/types, different XML mappings)
|
|
6
|
+
|
|
7
|
+
## What was done
|
|
8
|
+
1. Added `relaton-bib ~> 2.1` to gemspec dependency
|
|
9
|
+
2. Added `require "relaton/bib"` to `lib/metanorma/document/relaton.rb`
|
|
10
|
+
3. Replaced 4 models with inheritance from relaton-bib:
|
|
11
|
+
- `Phone` < `::Relaton::Bib::Phone` (exact match)
|
|
12
|
+
- `PriceType` < `::Relaton::Bib::Price` (exact match)
|
|
13
|
+
- `BibItemLocality` < `::Relaton::Bib::Locality` (exact match)
|
|
14
|
+
- `Edition` < `::Relaton::Bib::Edition` (inherits + adds `language` attribute)
|
|
15
|
+
|
|
16
|
+
## Why most models can't be directly replaced
|
|
17
|
+
The 53 relaton models in our project have different XML schemas from relaton-bib's models:
|
|
18
|
+
|
|
19
|
+
| Difference | Our models | relaton-bib |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| Attribute names | `on` (BibliographicDate), `bib_locality` (LocalityStack), `validity_begins` (ValidityType) | `at`, `locality`, `begins` |
|
|
22
|
+
| Attribute types | `Components::DataTypes::*` throughout | `LocalizedString`, `LocalizedMarkedUpString` |
|
|
23
|
+
| XML mapping | `map_attribute` for medium, `map_all_content` for logo | `map_element` for medium, `map_element "image"` for logo |
|
|
24
|
+
| Extra attributes | `language` on Edition, `id` on DocumentIdentifier, `stage_abbreviation` on DocumentStatus | Not present |
|
|
25
|
+
| Mixed content | Used in TypedTitleString (em/fn/stem/strong/sub/sup/tt/variant) | Plain content |
|
|
26
|
+
| Model nesting | `CopyrightOwner` wraps `Organization` | `Contributor` as owner |
|
|
27
|
+
|
|
28
|
+
A full replacement requires updating all 86 consuming references and adapting to relaton-bib's API. This is a separate project-level migration.
|
|
29
|
+
|
|
30
|
+
## Remaining work for full migration
|
|
31
|
+
1. Update consuming code (86 references) to use relaton-bib attribute names
|
|
32
|
+
2. For models with extra attributes: inherit from relaton-bib and add extras
|
|
33
|
+
3. For models with structural differences: create adapter classes
|
|
34
|
+
4. Remove `lib/metanorma/document/relaton/` once fully migrated
|
|
35
|
+
5. Update autoload configuration
|
|
36
|
+
6. Integration specs for relaton-bib model usage
|
|
37
|
+
|
|
38
|
+
## Code quality requirements
|
|
39
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 08 — Refactor renderer architecture for OCP and DRY — DONE
|
|
2
|
+
|
|
3
|
+
### Completed decomposition (Phase 1)
|
|
4
|
+
BaseRenderer originally included three concern modules:
|
|
5
|
+
- `InlineRendering` (~590 lines, 39 methods)
|
|
6
|
+
- `BlockRendering` (~295 lines, 24 methods)
|
|
7
|
+
- `SectionRendering` (~90 lines, 8 methods)
|
|
8
|
+
|
|
9
|
+
### Completed composition (Phase 2 — TODO 13)
|
|
10
|
+
Module includes replaced with composition. Each module became a standalone class:
|
|
11
|
+
- `Renderers::InlineRenderer` at `lib/metanorma/html/renderers/inline_renderer.rb`
|
|
12
|
+
- `Renderers::BlockRenderer` at `lib/metanorma/html/renderers/block_renderer.rb`
|
|
13
|
+
- `Renderers::SectionRenderer` at `lib/metanorma/html/renderers/section_renderer.rb`
|
|
14
|
+
- `Renderers::PubidRenderer` at `lib/metanorma/html/renderers/pubid_renderer.rb`
|
|
15
|
+
|
|
16
|
+
BaseRenderer is now a thin coordinator with delegation wrappers for backward compatibility.
|
|
17
|
+
Old concern modules at `lib/metanorma/html/concerns/` are no longer referenced and can be removed.
|
|
18
|
+
|
|
19
|
+
### Remaining enhancements
|
|
20
|
+
- Publisher metadata (flavor_publishers, flavor_publisher_name, publisher_logo_map) duplicated across 12+ flavor renderers. See TODO 11 for config-driven migration.
|
|
21
|
+
- Config-driven section ordering. See TODO 14.
|
|
22
|
+
- Theme directories per flavor. See TODO 15.
|
|
23
|
+
|
|
24
|
+
## Code quality requirements
|
|
25
|
+
Ensure code cleanliness and OOP and MECE and fully model-driven, semantically-driven and open/closed principle, DRY, performance. ultrathink. Always think about what can we improve here in architecture and code? Make sure we have good specs throughout. Never use private send methods (breaks encapsulation), instance_variable_set/get, and never use respond_to? (poor typing).
|