metanorma-document 0.2.9 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +164 -66
- 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 +13 -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 +261 -1008
- 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 -7
- 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/generator.rb +2 -2
- 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/renderers/block_renderer.rb +372 -0
- data/lib/metanorma/html/renderers/inline_renderer.rb +655 -0
- data/lib/metanorma/html/renderers/pubid_renderer.rb +69 -0
- data/lib/metanorma/html/renderers/section_renderer.rb +193 -0
- data/lib/metanorma/html/renderers.rb +8 -0
- data/lib/metanorma/html/ribose_renderer.rb +1 -45
- data/lib/metanorma/html/standard_renderer.rb +341 -229
- 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 +13 -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/rich_html_renderer.rb +159 -0
- data/lib/metanorma/mirror/handlers/inline/text_extractor.rb +116 -0
- data/lib/metanorma/mirror/handlers/inline.rb +225 -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/metanorma_to_mirror.rb +101 -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 +64 -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 +22 -0
- data/lib/metanorma/mirror.rb +32 -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 +262 -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
|
@@ -10,47 +10,6 @@ module Metanorma
|
|
|
10
10
|
class IsoRenderer < StandardRenderer
|
|
11
11
|
# --- Public hooks for flavor customization ---
|
|
12
12
|
|
|
13
|
-
def flavor_publishers(_doc_id)
|
|
14
|
-
["ISO"]
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def flavor_publisher_name
|
|
18
|
-
"ISO"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def publisher_logo_map
|
|
22
|
-
{ "ISO" => "iso-logo.svg" }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# ISO brand: #e3000f red from logo
|
|
26
|
-
def theme
|
|
27
|
-
@theme ||= Theme.new.tap do |t|
|
|
28
|
-
t.primary = "#b3000c"
|
|
29
|
-
t.accent = "#e3000f"
|
|
30
|
-
t.accent_deep = "#b3000c"
|
|
31
|
-
t.gradient = "linear-gradient(135deg, #8a0009 0%, #b3000c 50%, #e3000f 100%)"
|
|
32
|
-
t.primary_light = "#fef0f1"
|
|
33
|
-
t.accent_light = "#fde8ea"
|
|
34
|
-
t.warm = "#1a1a1a"
|
|
35
|
-
t.warm_light = "#f5f5f5"
|
|
36
|
-
t.header_background = "linear-gradient(135deg, #8a0009 0%, #b3000c 40%, #e3000f 100%)"
|
|
37
|
-
t.cover_background = "linear-gradient(175deg, #5a0006 0%, #8a0009 25%, #b3000c 50%, #e3000f 80%, #ff4d4d 100%)"
|
|
38
|
-
t.cover_before_bg = "background: radial-gradient(ellipse at 25% 20%, rgba(255,77,77,0.15) 0%, transparent 50%), radial-gradient(ellipse at 75% 80%, rgba(26,26,26,0.1) 0%, transparent 40%)"
|
|
39
|
-
t.cover_after_bg = "height: 3px; background: linear-gradient(90deg, transparent, #e3000f, #1a1a1a, transparent)"
|
|
40
|
-
t.progress_bar_color = "#e3000f"
|
|
41
|
-
t.note_border = "#e3000f"
|
|
42
|
-
t.note_bg = "#fde8ea"
|
|
43
|
-
t.note_color = "#e3000f"
|
|
44
|
-
t.example_border = "#b3000c"
|
|
45
|
-
t.example_bg = "#fef0f1"
|
|
46
|
-
t.example_color = "#b3000c"
|
|
47
|
-
t.admonition_border = "#1a1a1a"
|
|
48
|
-
t.admonition_color = "#1a1a1a"
|
|
49
|
-
t.footer_border_color = "#e3000f"
|
|
50
|
-
t.cover_separator_color = "rgba(227,0,15,0.25)"
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
13
|
register_render Metanorma::IsoDocument::Root, :render_document
|
|
55
14
|
register_render Metanorma::IsoDocument::Sections::IsoPreface,
|
|
56
15
|
:render_preface
|
|
@@ -77,9 +36,12 @@ module Metanorma
|
|
|
77
36
|
|
|
78
37
|
def render_term_origin(element)
|
|
79
38
|
text = extract_text_value(element)
|
|
80
|
-
return unless text
|
|
39
|
+
return nil unless text
|
|
81
40
|
|
|
82
|
-
|
|
41
|
+
render_liquid("_inline_span.html.liquid", {
|
|
42
|
+
"attrs" => " class=\"term-source\"",
|
|
43
|
+
"content" => escape_html(text),
|
|
44
|
+
})
|
|
83
45
|
end
|
|
84
46
|
|
|
85
47
|
def extract_display_title(bibdata)
|
|
@@ -107,6 +69,7 @@ module Metanorma
|
|
|
107
69
|
raw_id = extract_text_value(identifiers.first).to_s.strip
|
|
108
70
|
return nil if raw_id.empty?
|
|
109
71
|
|
|
72
|
+
raw_id = strip_doc_id_prefix(raw_id)
|
|
110
73
|
pub = flavor_publisher_name
|
|
111
74
|
if pub && !raw_id.start_with?(pub)
|
|
112
75
|
"#{pub} #{raw_id}"
|
|
@@ -115,21 +78,25 @@ module Metanorma
|
|
|
115
78
|
end
|
|
116
79
|
end
|
|
117
80
|
|
|
118
|
-
|
|
81
|
+
def strip_doc_id_prefix(raw_id)
|
|
82
|
+
prefix = theme.doc_id_strip_prefix
|
|
83
|
+
return raw_id unless prefix
|
|
84
|
+
|
|
85
|
+
raw_id.to_s.gsub(/\A#{Regexp.escape(prefix)}\s+/, "").strip
|
|
86
|
+
end
|
|
87
|
+
|
|
119
88
|
def extract_stage(bibdata)
|
|
120
89
|
return nil unless bibdata.status&.stage
|
|
121
90
|
|
|
122
91
|
stages = Array(bibdata.status.stage)
|
|
123
92
|
return nil if stages.empty?
|
|
124
93
|
|
|
125
|
-
# Prefer English-language stage
|
|
126
94
|
en_stage = stages.find do |s|
|
|
127
95
|
lang = safe_attr(s, :language)
|
|
128
96
|
lang == "en" if lang
|
|
129
97
|
end
|
|
130
98
|
return Array(en_stage.value).join.strip if en_stage&.value
|
|
131
99
|
|
|
132
|
-
# Fallback: first non-empty, deduplicated
|
|
133
100
|
seen = Set.new
|
|
134
101
|
stage_text = stages.filter_map do |s|
|
|
135
102
|
val = Array(s.value).join.strip
|
|
@@ -142,7 +109,6 @@ module Metanorma
|
|
|
142
109
|
stage_text.empty? ? nil : stage_text
|
|
143
110
|
end
|
|
144
111
|
|
|
145
|
-
# Extract document type from ext.doctype.
|
|
146
112
|
def extract_doctype(bibdata)
|
|
147
113
|
return nil unless bibdata.is_a?(Metanorma::IsoDocument::Metadata::IsoBibliographicItem)
|
|
148
114
|
|
|
@@ -152,14 +118,12 @@ module Metanorma
|
|
|
152
118
|
doctypes = ext.doctype
|
|
153
119
|
return nil unless doctypes && !doctypes.empty?
|
|
154
120
|
|
|
155
|
-
# Prefer English-language doctype
|
|
156
121
|
en_dt = doctypes.find do |d|
|
|
157
122
|
lang = safe_attr(d, :language)
|
|
158
123
|
lang == "en" if lang
|
|
159
124
|
end
|
|
160
125
|
return en_dt.value.to_s if en_dt&.value
|
|
161
126
|
|
|
162
|
-
# Fallback: first doctype
|
|
163
127
|
dt = doctypes.first
|
|
164
128
|
val = dt&.value.to_s
|
|
165
129
|
val.strip.empty? ? nil : val
|
|
@@ -168,38 +132,33 @@ module Metanorma
|
|
|
168
132
|
# --- Top-level document rendering ---
|
|
169
133
|
|
|
170
134
|
def render_document(doc, **_opts)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
@output << "<main class=\"main-section\">"
|
|
175
|
-
|
|
176
|
-
# Preface sections
|
|
177
|
-
render(doc.preface) if doc.preface
|
|
135
|
+
parts = []
|
|
136
|
+
parts << (render_coverpage(doc) || "")
|
|
137
|
+
parts << (render_boilerplate_section(doc) || "")
|
|
178
138
|
|
|
179
|
-
|
|
180
|
-
render_doc_title(doc)
|
|
139
|
+
parts << (render(doc.preface) || "") if doc.preface
|
|
140
|
+
parts << (render_doc_title(doc) || "")
|
|
181
141
|
|
|
182
|
-
# Collect ALL top-level content (sections + normative refs + annexes + bibliography)
|
|
183
|
-
# and render in displayorder for correct document order.
|
|
184
142
|
all_items = collect_document_children(doc)
|
|
185
|
-
|
|
186
143
|
all_items.each do |node|
|
|
187
144
|
next if node.is_a?(String)
|
|
188
145
|
next if is_title_element?(node, doc.sections)
|
|
189
146
|
|
|
190
|
-
render(node)
|
|
147
|
+
parts << (render(node) || "")
|
|
191
148
|
end
|
|
192
149
|
|
|
193
|
-
render_footnotes_section
|
|
150
|
+
parts << (render_footnotes_section || "")
|
|
194
151
|
|
|
195
|
-
|
|
152
|
+
render_liquid("_main_content.html.liquid", {
|
|
153
|
+
"content" => parts.join,
|
|
154
|
+
})
|
|
196
155
|
end
|
|
197
156
|
|
|
198
157
|
# --- Cover page ---
|
|
199
158
|
|
|
200
159
|
def render_coverpage(doc)
|
|
201
160
|
bibdata = doc.bibdata
|
|
202
|
-
return unless bibdata
|
|
161
|
+
return "" unless bibdata
|
|
203
162
|
|
|
204
163
|
logos = publisher_logos_html(doc) || []
|
|
205
164
|
doc_id = formatted_doc_id(bibdata)
|
|
@@ -223,141 +182,150 @@ module Metanorma
|
|
|
223
182
|
title_text = nil
|
|
224
183
|
if bibdata.titles
|
|
225
184
|
en_title = bibdata.title_for("en")
|
|
226
|
-
|
|
185
|
+
if en_title
|
|
186
|
+
title_text = if en_title.is_a?(Metanorma::IsoDocument::Metadata::AbstractTitle) && en_title.value
|
|
187
|
+
en_title.value.to_s
|
|
188
|
+
else
|
|
189
|
+
en_title.to_s
|
|
190
|
+
end
|
|
191
|
+
end
|
|
227
192
|
end
|
|
228
193
|
|
|
229
194
|
stage_text = extract_stage(bibdata)
|
|
230
195
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
196
|
+
render_liquid("_standard_cover.html.liquid", {
|
|
197
|
+
"publisher_logos" => logos,
|
|
198
|
+
"doc_id" => doc_id,
|
|
199
|
+
"pub_date" => pub_date,
|
|
200
|
+
"doctype" => doctype,
|
|
201
|
+
"title" => title_text,
|
|
202
|
+
"stage" => stage_text,
|
|
203
|
+
})
|
|
239
204
|
end
|
|
240
205
|
|
|
241
206
|
def render_doc_title(doc)
|
|
242
207
|
bibdata = doc.bibdata
|
|
243
|
-
return unless bibdata
|
|
208
|
+
return nil unless bibdata
|
|
244
209
|
|
|
245
210
|
titles = bibdata.titles
|
|
246
|
-
return unless titles
|
|
211
|
+
return nil unless titles
|
|
247
212
|
|
|
248
213
|
en_title = bibdata.title_for("en")
|
|
249
|
-
return unless en_title
|
|
214
|
+
return nil unless en_title
|
|
250
215
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
216
|
+
render_liquid("_standard_doc_title.html.liquid", {
|
|
217
|
+
"title" => en_title.to_s,
|
|
218
|
+
})
|
|
254
219
|
end
|
|
255
220
|
|
|
256
221
|
def render_boilerplate_section(doc)
|
|
257
|
-
return unless doc.boilerplate
|
|
222
|
+
return nil unless doc.boilerplate
|
|
258
223
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
def render_preface(preface, **_opts)
|
|
265
|
-
render(preface.foreword) if preface.foreword
|
|
266
|
-
render(preface.introduction) if preface.introduction
|
|
267
|
-
render(preface.abstract) if preface.abstract
|
|
268
|
-
preface.clause&.each { |cl| render(cl, level: 1) }
|
|
269
|
-
render(preface.acknowledgements) if preface.acknowledgements
|
|
270
|
-
render(preface.executivesummary) if preface.executivesummary
|
|
224
|
+
content = render(doc.boilerplate)
|
|
225
|
+
render_liquid("_prefatory_section.html.liquid", {
|
|
226
|
+
"content" => content,
|
|
227
|
+
})
|
|
271
228
|
end
|
|
272
229
|
|
|
273
230
|
def render_foreword(fw, level: 1, **_opts)
|
|
274
231
|
attrs = element_attrs(id: safe_attr(fw, :id))
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
232
|
+
title = safe_attr(fw, :fmt_title) || safe_attr(fw, :title)
|
|
233
|
+
parts = []
|
|
234
|
+
if title
|
|
235
|
+
fw_id = safe_attr(fw, :id)
|
|
236
|
+
title_content = render_mixed_inline(title)
|
|
237
|
+
register_toc_entry(id: fw_id, level: level,
|
|
238
|
+
text: extract_plain_text(title))
|
|
239
|
+
parts << render_liquid("_heading.html.liquid", {
|
|
240
|
+
"tag" => "h1",
|
|
241
|
+
"class_attr" => " class=\"foreword-title\"",
|
|
242
|
+
"content" => title_content,
|
|
243
|
+
})
|
|
286
244
|
end
|
|
245
|
+
parts << (render_ordered_content(fw) || "")
|
|
246
|
+
render_liquid("_element.html.liquid", "tag" => "div",
|
|
247
|
+
"extra_attrs" => attrs, "content" => parts.join)
|
|
287
248
|
end
|
|
288
249
|
|
|
289
250
|
def render_abstract(section, level: 1, **_opts)
|
|
290
251
|
attrs = element_attrs(id: safe_attr(section, :id))
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
252
|
+
title = safe_attr(section, :fmt_title) || safe_attr(section, :title)
|
|
253
|
+
parts = []
|
|
254
|
+
if title
|
|
255
|
+
sec_id = safe_attr(section, :id)
|
|
256
|
+
title_content = render_mixed_inline(title)
|
|
257
|
+
register_toc_entry(id: sec_id, level: level,
|
|
258
|
+
text: extract_plain_text(title))
|
|
259
|
+
parts << render_liquid("_heading.html.liquid", {
|
|
260
|
+
"tag" => "h1",
|
|
261
|
+
"class_attr" => " class=\"intro-title\"",
|
|
262
|
+
"content" => title_content,
|
|
263
|
+
})
|
|
302
264
|
end
|
|
265
|
+
parts << (render_ordered_content(section) || "")
|
|
266
|
+
render_liquid("_element.html.liquid", "tag" => "div",
|
|
267
|
+
"extra_attrs" => attrs, "content" => parts.join)
|
|
303
268
|
end
|
|
304
269
|
|
|
305
270
|
# --- Main sections rendering ---
|
|
306
271
|
|
|
307
272
|
def render_sections(sections, **_opts)
|
|
308
|
-
# Collect ALL section-level children (from mixed content AND typed attributes)
|
|
309
|
-
# then sort by displayorder for correct document order.
|
|
310
273
|
children = collect_ordered_children(sections)
|
|
274
|
+
parts = []
|
|
311
275
|
children.each do |node|
|
|
312
276
|
next if node.is_a?(String)
|
|
313
277
|
next if is_title_element?(node, sections)
|
|
314
278
|
|
|
315
|
-
render(node, level: 1)
|
|
279
|
+
parts << (render(node, level: 1) || "")
|
|
316
280
|
end
|
|
281
|
+
parts.join
|
|
317
282
|
end
|
|
318
283
|
|
|
319
284
|
# --- Clause rendering ---
|
|
320
285
|
|
|
321
286
|
def render_clause(clause, level: 1, **_opts)
|
|
322
287
|
attrs = element_attrs(id: safe_attr(clause, :id))
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
288
|
+
title = render_title(clause, level)
|
|
289
|
+
content = render_ordered_content(clause, level)
|
|
290
|
+
render_liquid("_element.html.liquid", "tag" => "div",
|
|
291
|
+
"extra_attrs" => attrs, "content" => "#{title}#{content}")
|
|
327
292
|
end
|
|
328
293
|
|
|
329
294
|
# --- Annex rendering ---
|
|
330
295
|
|
|
331
296
|
def render_annex(annex, level: 1, **_opts)
|
|
332
297
|
attrs = element_attrs(id: safe_attr(annex, :id), class: "section-sub")
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
298
|
+
title = render_annex_title(annex, level)
|
|
299
|
+
content = render_ordered_content(annex, level)
|
|
300
|
+
render_liquid("_element.html.liquid", "tag" => "div",
|
|
301
|
+
"extra_attrs" => attrs, "content" => "#{title}#{content}")
|
|
337
302
|
end
|
|
338
303
|
|
|
339
304
|
def render_annex_title(annex, level)
|
|
340
305
|
title_element = safe_attr(annex, :fmt_title) || safe_attr(annex, :title)
|
|
341
|
-
return unless title_element
|
|
306
|
+
return nil unless title_element
|
|
342
307
|
|
|
343
308
|
annex_id = safe_attr(annex, :id)
|
|
344
|
-
|
|
345
|
-
register_toc_entry(id: annex_id, level: level,
|
|
309
|
+
title_content = render_mixed_inline(title_element)
|
|
310
|
+
register_toc_entry(id: annex_id, level: level,
|
|
311
|
+
text: extract_plain_text(title_element))
|
|
346
312
|
|
|
347
313
|
h = "h#{[[level, 6].min, 1].max}"
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
314
|
+
render_liquid("_heading.html.liquid", {
|
|
315
|
+
"tag" => h,
|
|
316
|
+
"class_attr" => " class=\"annex-title\"",
|
|
317
|
+
"content" => title_content,
|
|
318
|
+
})
|
|
351
319
|
end
|
|
352
320
|
|
|
353
321
|
# --- Terms section rendering ---
|
|
354
322
|
|
|
355
323
|
def render_terms_section(terms, level: 1, **_opts)
|
|
356
324
|
attrs = element_attrs(id: safe_attr(terms, :id))
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
325
|
+
title = render_title(terms, level)
|
|
326
|
+
content = render_ordered_content(terms, level)
|
|
327
|
+
render_liquid("_element.html.liquid", "tag" => "div",
|
|
328
|
+
"extra_attrs" => attrs, "content" => "#{title}#{content}")
|
|
361
329
|
end
|
|
362
330
|
|
|
363
331
|
# --- ISO Term rendering ---
|
|
@@ -367,112 +335,120 @@ module Metanorma
|
|
|
367
335
|
term_def = extract_term_definition(term)
|
|
368
336
|
data_attrs = {}
|
|
369
337
|
if term_name && !term_name.empty?
|
|
370
|
-
data_attrs["data-term-name"] =
|
|
371
|
-
term_name
|
|
338
|
+
data_attrs["data-term-name"] = term_name
|
|
372
339
|
end
|
|
373
340
|
if term_def && !term_def.empty?
|
|
374
|
-
data_attrs["data-term-definition"] =
|
|
375
|
-
term_def
|
|
341
|
+
data_attrs["data-term-definition"] = term_def
|
|
376
342
|
end
|
|
377
343
|
attrs = element_attrs(id: safe_attr(term, :id), **data_attrs)
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
end
|
|
344
|
+
fmt_name = safe_attr(term, :fmt_name)
|
|
345
|
+
fmt_preferred = safe_attr(term, :fmt_preferred)
|
|
346
|
+
fmt_admitted = safe_attr(term, :fmt_admitted)
|
|
347
|
+
fmt_deprecates = safe_attr(term, :fmt_deprecates)
|
|
348
|
+
fmt_definition = safe_attr(term, :fmt_definition)
|
|
349
|
+
fmt_termsource = safe_attr(term, :fmt_termsource)
|
|
350
|
+
term_number = safe_attr(term, :term_number)
|
|
351
|
+
term_p = safe_attr(term, :p)
|
|
352
|
+
term_note = safe_attr(term, :termnote) || Array(safe_attr(term, :note))
|
|
353
|
+
term_example = safe_attr(term,
|
|
354
|
+
:termexample) || Array(safe_attr(term,
|
|
355
|
+
:example))
|
|
356
|
+
term_termsource = safe_attr(term, :termsource)
|
|
357
|
+
term_admonition = safe_attr(term, :admonition)
|
|
358
|
+
term_nested = safe_attr(term, :term)
|
|
394
359
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
360
|
+
parts = []
|
|
361
|
+
if fmt_name
|
|
362
|
+
tn_content = render_inline_element(fmt_name)
|
|
363
|
+
parts << render_liquid("_term_number.html.liquid",
|
|
364
|
+
{ "content" => tn_content })
|
|
365
|
+
elsif term_number
|
|
366
|
+
tn_text = if term_number.is_a?(String)
|
|
367
|
+
term_number
|
|
368
|
+
else
|
|
369
|
+
extract_text_value(term_number)
|
|
370
|
+
end
|
|
371
|
+
parts << render_liquid("_term_number.html.liquid",
|
|
372
|
+
{ "content" => escape_html(tn_text) })
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
if fmt_preferred && !fmt_preferred.empty?
|
|
376
|
+
fmt_preferred.each do |fp|
|
|
377
|
+
fp.p&.each { |para| parts << (render_paragraph(para) || "") }
|
|
406
378
|
end
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
term.fmt_admitted.each do |fa|
|
|
411
|
-
fa.p&.each do |para|
|
|
412
|
-
render_paragraph(para)
|
|
413
|
-
end
|
|
414
|
-
end
|
|
415
|
-
elsif term.admitted && !term.admitted.empty?
|
|
416
|
-
term.admitted&.each do |designation|
|
|
417
|
-
render_term_designation(designation, "admitted")
|
|
418
|
-
end
|
|
379
|
+
elsif term.preferred && !term.preferred.empty?
|
|
380
|
+
term.preferred&.each do |designation|
|
|
381
|
+
parts << (render_term_designation(designation, "preferred") || "")
|
|
419
382
|
end
|
|
383
|
+
end
|
|
420
384
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
elsif term.deprecates && !term.deprecates.empty?
|
|
425
|
-
term.deprecates&.each do |designation|
|
|
426
|
-
render_term_designation(designation, "deprecated")
|
|
427
|
-
end
|
|
385
|
+
if fmt_admitted && !fmt_admitted.empty?
|
|
386
|
+
fmt_admitted.each do |fa|
|
|
387
|
+
fa.p&.each { |para| parts << (render_paragraph(para) || "") }
|
|
428
388
|
end
|
|
389
|
+
elsif term.admitted && !term.admitted.empty?
|
|
390
|
+
term.admitted&.each do |designation|
|
|
391
|
+
parts << (render_term_designation(designation, "admitted") || "")
|
|
392
|
+
end
|
|
393
|
+
end
|
|
429
394
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
395
|
+
if fmt_deprecates
|
|
396
|
+
fmt_deprecates.p&.each do |para|
|
|
397
|
+
parts << (render_paragraph(para) || "")
|
|
398
|
+
end
|
|
399
|
+
elsif term.deprecates && !term.deprecates.empty?
|
|
400
|
+
term.deprecates&.each do |designation|
|
|
401
|
+
parts << (render_term_designation(designation, "deprecated") || "")
|
|
435
402
|
end
|
|
403
|
+
end
|
|
436
404
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
# Structured definitions
|
|
444
|
-
term.definition&.each { |defn| render_term_definition(defn) }
|
|
405
|
+
if term.domain && !fmt_definition
|
|
406
|
+
domain_text = safe_attr(term.domain, :text)
|
|
407
|
+
if domain_text
|
|
408
|
+
parts << render_liquid("_term_domain.html.liquid", {
|
|
409
|
+
"text" => escape_html(domain_text),
|
|
410
|
+
})
|
|
445
411
|
end
|
|
412
|
+
end
|
|
446
413
|
|
|
447
|
-
|
|
448
|
-
|
|
414
|
+
if fmt_definition
|
|
415
|
+
parts << (render_ordered_content(fmt_definition) || "")
|
|
416
|
+
else
|
|
417
|
+
term_p&.each { |para| parts << (render_paragraph(para) || "") }
|
|
418
|
+
term.definition&.each do |defn|
|
|
419
|
+
parts << (render_term_definition(defn) || "")
|
|
420
|
+
end
|
|
421
|
+
end
|
|
449
422
|
|
|
450
|
-
|
|
451
|
-
|
|
423
|
+
term_note&.each { |note| parts << (render_term_note(note) || "") }
|
|
424
|
+
term_example&.each { |ex| parts << (render_term_example(ex) || "") }
|
|
452
425
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
426
|
+
if fmt_termsource && !fmt_termsource.empty?
|
|
427
|
+
fmt_termsource.each do |fts|
|
|
428
|
+
src_content = render_mixed_inline(fts)
|
|
429
|
+
parts << render_liquid("_paragraph.html.liquid", {
|
|
430
|
+
"attrs" => " class=\"term-source\"",
|
|
431
|
+
"content" => src_content,
|
|
432
|
+
})
|
|
433
|
+
end
|
|
434
|
+
else
|
|
435
|
+
term.source&.each { |src| parts << (render_term_source(src) || "") }
|
|
436
|
+
term_termsource&.each do |src|
|
|
437
|
+
parts << (render_term_source_element(src) || "")
|
|
463
438
|
end
|
|
439
|
+
end
|
|
464
440
|
|
|
465
|
-
|
|
466
|
-
|
|
441
|
+
term_admonition&.each { |adm| parts << (render_admonition(adm) || "") }
|
|
442
|
+
term_nested&.each { |sub| parts << (render_term(sub) || "") }
|
|
467
443
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
end
|
|
444
|
+
render_liquid("_element.html.liquid", "tag" => "div",
|
|
445
|
+
"extra_attrs" => attrs, "content" => parts.join)
|
|
471
446
|
end
|
|
472
447
|
|
|
473
448
|
def extract_term_name(term)
|
|
474
|
-
|
|
475
|
-
|
|
449
|
+
fmt_pref = safe_attr(term, :fmt_preferred)
|
|
450
|
+
if fmt_pref && !fmt_pref.empty?
|
|
451
|
+
fp = fmt_pref.first
|
|
476
452
|
if fp.p && !fp.p.empty?
|
|
477
453
|
return extract_plain_text(fp.p.first)
|
|
478
454
|
end
|
|
@@ -485,49 +461,47 @@ module Metanorma
|
|
|
485
461
|
end
|
|
486
462
|
|
|
487
463
|
def extract_term_definition(term)
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
rendered = capture_output do
|
|
496
|
-
term.p.each do |para|
|
|
497
|
-
render_paragraph(para)
|
|
498
|
-
end
|
|
499
|
-
end
|
|
500
|
-
return strip_html(rendered).gsub(/\s+/, " ").strip
|
|
464
|
+
fmt_def = safe_attr(term, :fmt_definition)
|
|
465
|
+
return extract_plain_text(fmt_def) if fmt_def
|
|
466
|
+
|
|
467
|
+
term_p = safe_attr(term, :p)
|
|
468
|
+
if term_p && !term_p.empty?
|
|
469
|
+
text = term_p.map { |para| extract_plain_text(para) }.join(" ")
|
|
470
|
+
return text.strip unless text.strip.empty?
|
|
501
471
|
end
|
|
502
472
|
nil
|
|
503
473
|
end
|
|
504
474
|
|
|
505
|
-
def strip_html(html)
|
|
506
|
-
html.gsub(/<[^>]+>/, "").gsub("<", "<").gsub(">", ">")
|
|
507
|
-
.gsub("&", "&").gsub(" ", " ")
|
|
508
|
-
end
|
|
509
|
-
|
|
510
475
|
def render_term_designation(designation, type)
|
|
511
476
|
css_class = type == "deprecated" ? "term-deprecated" : "term-name"
|
|
512
|
-
@output << "<p class=\"#{css_class}\" style=\"text-align:left;\">"
|
|
513
|
-
@output << "<del>" if type == "deprecated"
|
|
514
|
-
@output << "<b><dfn>"
|
|
515
|
-
|
|
516
477
|
name = extract_designation_name(designation)
|
|
517
|
-
if name
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
478
|
+
inner = if name
|
|
479
|
+
escape_html(name)
|
|
480
|
+
else
|
|
481
|
+
render_mixed_inline(designation) || ""
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
dfn_content = render_liquid("_element.html.liquid",
|
|
485
|
+
{ "tag" => "dfn", "extra_attrs" => "",
|
|
486
|
+
"content" => inner })
|
|
487
|
+
b_content = render_liquid("_element.html.liquid",
|
|
488
|
+
{ "tag" => "b", "extra_attrs" => "",
|
|
489
|
+
"content" => dfn_content })
|
|
490
|
+
|
|
491
|
+
if type == "deprecated"
|
|
492
|
+
b_content = render_liquid("_element.html.liquid",
|
|
493
|
+
{ "tag" => "del", "extra_attrs" => "",
|
|
494
|
+
"content" => b_content })
|
|
522
495
|
end
|
|
523
496
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
497
|
+
render_liquid("_element.html.liquid", {
|
|
498
|
+
"tag" => "p",
|
|
499
|
+
"extra_attrs" => " class=\"#{css_class}\" style=\"text-align:left;\"",
|
|
500
|
+
"content" => b_content,
|
|
501
|
+
})
|
|
527
502
|
end
|
|
528
503
|
|
|
529
504
|
def extract_designation_name(designation)
|
|
530
|
-
# Try expression.name first (TermNameElement objects with text)
|
|
531
505
|
expr = designation.expression
|
|
532
506
|
if expr.is_a?(Metanorma::IsoDocument::Terms::TermExpression) && expr.name
|
|
533
507
|
names = Array(expr.name)
|
|
@@ -535,7 +509,6 @@ module Metanorma
|
|
|
535
509
|
return text unless text.strip.empty?
|
|
536
510
|
end
|
|
537
511
|
|
|
538
|
-
# Try text attribute from mixed content
|
|
539
512
|
texts = safe_attr(designation, :text)
|
|
540
513
|
if texts
|
|
541
514
|
joined = texts.is_a?(Array) ? texts.join : texts.to_s
|
|
@@ -558,113 +531,82 @@ module Metanorma
|
|
|
558
531
|
end
|
|
559
532
|
|
|
560
533
|
def render_term_definition(definition)
|
|
561
|
-
return unless definition
|
|
534
|
+
return nil unless definition
|
|
562
535
|
|
|
536
|
+
parts = []
|
|
563
537
|
rendered = false
|
|
564
538
|
|
|
565
|
-
|
|
566
|
-
|
|
539
|
+
vd = safe_attr(definition,
|
|
540
|
+
:verbal_definition) || safe_attr(definition,
|
|
541
|
+
:verbalexpression)
|
|
567
542
|
if vd
|
|
568
|
-
vd
|
|
569
|
-
|
|
570
|
-
vd.
|
|
543
|
+
vd_p = safe_attr(vd, :p) || safe_attr(vd, :paragraph)
|
|
544
|
+
vd_p&.each { |para| parts << (render_paragraph(para) || "") }
|
|
545
|
+
vd.ul&.each { |ul| parts << (render_unordered_list(ul) || "") }
|
|
546
|
+
vd.ol&.each { |ol| parts << (render_ordered_list(ol) || "") }
|
|
571
547
|
rendered = true
|
|
572
548
|
end
|
|
573
549
|
|
|
574
|
-
# Try direct p (presentation XML format where <p> is inside <definition>)
|
|
575
550
|
p_children = safe_attr(definition, :p)
|
|
576
551
|
if !rendered && p_children && !p_children.empty?
|
|
577
|
-
p_children.each { |para| render_paragraph(para) }
|
|
552
|
+
p_children.each { |para| parts << (render_paragraph(para) || "") }
|
|
578
553
|
rendered = true
|
|
579
554
|
end
|
|
580
555
|
|
|
581
|
-
# Fallback: render via element_order
|
|
582
556
|
unless rendered
|
|
583
|
-
render_ordered_content(definition)
|
|
557
|
+
parts << (render_ordered_content(definition) || "")
|
|
584
558
|
end
|
|
559
|
+
parts.join
|
|
585
560
|
end
|
|
586
561
|
|
|
587
562
|
# --- Boilerplate rendering ---
|
|
588
563
|
|
|
589
564
|
def render_boilerplate(boilerplate, **_opts)
|
|
590
|
-
return unless boilerplate
|
|
591
|
-
|
|
592
|
-
content = boilerplate_to_xml(boilerplate)
|
|
593
|
-
return unless content
|
|
594
|
-
|
|
595
|
-
@output << "<div class=\"boilerplate-copyright\">"
|
|
565
|
+
return nil unless boilerplate
|
|
596
566
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
.gsub(/<variant-title[^>]*>.*?<\/variant-title>/m, "")
|
|
604
|
-
.gsub(/<\/?(?:copyright-statement|clause)[^>]*>/, "")
|
|
567
|
+
parts = []
|
|
568
|
+
parts << (render_boilerplate_items(boilerplate.copyright_statement) || "")
|
|
569
|
+
parts << (render_boilerplate_items(boilerplate.license_statement) || "")
|
|
570
|
+
parts << (render_boilerplate_items(boilerplate.legal_statement) || "")
|
|
571
|
+
parts << (render_boilerplate_items(boilerplate.feedback_statement) || "")
|
|
572
|
+
parts << (render_boilerplate_items(boilerplate.clause) || "")
|
|
605
573
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
boilerplate_doc.css("[class]").each do |el|
|
|
609
|
-
el["class"] = el["class"].split(/\s+/).map do |c|
|
|
610
|
-
html_class_for_span(c)
|
|
611
|
-
end.join(" ")
|
|
612
|
-
end
|
|
574
|
+
render_liquid("_boilerplate.html.liquid", content: parts.join)
|
|
575
|
+
end
|
|
613
576
|
|
|
614
|
-
|
|
577
|
+
def render_boilerplate_items(items)
|
|
578
|
+
return nil unless items
|
|
615
579
|
|
|
616
|
-
|
|
580
|
+
Array(items).filter_map { |item| render_boilerplate_clause(item) }.join
|
|
617
581
|
end
|
|
618
582
|
|
|
619
|
-
def
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
feedback_statement clause].each do |attr|
|
|
623
|
-
items = boilerplate.public_send(attr)
|
|
624
|
-
next unless items
|
|
625
|
-
|
|
626
|
-
tag = attr.to_s.gsub("_", "-")
|
|
627
|
-
items.each do |item|
|
|
628
|
-
inner = item.to_xml
|
|
629
|
-
next if !inner || inner.strip.empty?
|
|
630
|
-
|
|
631
|
-
# Strip the outer <clause> wrapper — the inner content is what matters
|
|
632
|
-
stripped = inner.strip
|
|
633
|
-
stripped = stripped.sub(%r{^<clause[^>]*>\n?}, "").sub(%r{\n?</clause>$}, "")
|
|
634
|
-
parts << "<#{tag}>#{stripped}</#{tag}>"
|
|
635
|
-
end
|
|
636
|
-
end
|
|
637
|
-
return nil if parts.empty?
|
|
583
|
+
def render_boilerplate_clause(item)
|
|
584
|
+
return nil unless item
|
|
585
|
+
return nil unless item.is_a?(Lutaml::Model::Serializable)
|
|
638
586
|
|
|
639
|
-
|
|
640
|
-
|
|
587
|
+
inner = safe_attr(item, :subsection)
|
|
588
|
+
targets = if inner && !Array(inner).empty?
|
|
589
|
+
Array(inner)
|
|
590
|
+
else
|
|
591
|
+
[item]
|
|
592
|
+
end
|
|
641
593
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
next_sib = link.next_sibling
|
|
647
|
-
while next_sib.is_a?(Nokogiri::XML::Text) && next_sib.text.strip.empty?
|
|
648
|
-
next_sib = next_sib.next_sibling
|
|
649
|
-
end
|
|
594
|
+
targets.filter_map do |section|
|
|
595
|
+
render_boilerplate_clause_content(section)
|
|
596
|
+
end.join
|
|
597
|
+
end
|
|
650
598
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
end
|
|
659
|
-
end
|
|
599
|
+
def render_boilerplate_clause_content(section)
|
|
600
|
+
fmt_title = safe_attr(section, :fmt_title)
|
|
601
|
+
parts = []
|
|
602
|
+
section.each_mixed_content do |child|
|
|
603
|
+
next if child.is_a?(String)
|
|
604
|
+
next if is_title_element?(child, section)
|
|
605
|
+
next if child.equal?(fmt_title)
|
|
660
606
|
|
|
661
|
-
|
|
662
|
-
a_tag = Nokogiri::HTML::DocumentFragment.parse(
|
|
663
|
-
"<a href=\"#{CGI.escapeHTML(target.to_s)}\">#{CGI.escapeHTML(display_text)}</a>",
|
|
664
|
-
)
|
|
665
|
-
link.replace(a_tag)
|
|
607
|
+
parts << (render(child) || "")
|
|
666
608
|
end
|
|
667
|
-
|
|
609
|
+
parts.join
|
|
668
610
|
end
|
|
669
611
|
|
|
670
612
|
# --- Helpers ---
|
|
@@ -672,22 +614,18 @@ module Metanorma
|
|
|
672
614
|
def render_title(section, level)
|
|
673
615
|
title_element = safe_attr(section,
|
|
674
616
|
:fmt_title) || safe_attr(section, :title)
|
|
675
|
-
return unless title_element
|
|
617
|
+
return nil unless title_element
|
|
676
618
|
|
|
677
619
|
section_id = safe_attr(section, :id)
|
|
678
|
-
|
|
679
|
-
register_toc_entry(id: section_id, level: level,
|
|
620
|
+
title_content = render_mixed_inline(title_element)
|
|
621
|
+
register_toc_entry(id: section_id, level: level,
|
|
622
|
+
text: extract_plain_text(title_element))
|
|
680
623
|
|
|
681
624
|
h = "h#{[[level, 6].min, 1].max}"
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
@output << "</#{h}>"
|
|
625
|
+
render_liquid("_heading.html.liquid", tag: h, class_attr: "",
|
|
626
|
+
content: title_content)
|
|
685
627
|
end
|
|
686
628
|
|
|
687
|
-
# Collect all document-level children (sections, normative refs, annexes,
|
|
688
|
-
# bibliography) sorted by displayorder for correct document order.
|
|
689
|
-
# Top-level paragraphs in sections (title paragraphs) are excluded —
|
|
690
|
-
# they are rendered separately by render_doc_title.
|
|
691
629
|
def collect_document_children(doc)
|
|
692
630
|
items = []
|
|
693
631
|
|
|
@@ -711,6 +649,7 @@ module Metanorma
|
|
|
711
649
|
logo_map = publisher_logo_map
|
|
712
650
|
return [] if publishers.empty? && logo_map.empty?
|
|
713
651
|
|
|
652
|
+
dark_logo_map = theme.logos_dark
|
|
714
653
|
display_pubs = publishers.empty? ? logo_map.keys : publishers
|
|
715
654
|
display_pubs.filter_map do |pub|
|
|
716
655
|
filename = logo_map[pub]
|
|
@@ -719,10 +658,18 @@ module Metanorma
|
|
|
719
658
|
svg = load_logo_svg(filename, height: 48)
|
|
720
659
|
next unless svg
|
|
721
660
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
661
|
+
light_span = "<span class=\"cover-logo cover-logo-light\">#{svg}</span>"
|
|
662
|
+
|
|
663
|
+
dark_span = ""
|
|
664
|
+
dark_filename = dark_logo_map[pub]
|
|
665
|
+
if dark_filename
|
|
666
|
+
dark_svg = load_logo_svg(dark_filename, height: 48)
|
|
667
|
+
if dark_svg
|
|
668
|
+
dark_span = "<span class=\"cover-logo cover-logo-dark\">#{dark_svg}</span>"
|
|
669
|
+
end
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
dark_span.empty? ? light_span : "#{light_span}\n#{dark_span}"
|
|
726
673
|
end
|
|
727
674
|
end
|
|
728
675
|
end
|