metanorma-document 0.2.12 → 0.4.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/CLAUDE.md +3 -2
- data/README.adoc +1 -1
- data/Rakefile +30 -5
- data/frontend/dist/app.css +1 -0
- data/frontend/dist/app.iife.js +24 -0
- data/frontend/package-lock.json +7 -505
- data/frontend/tailwind.config.js +5 -0
- data/lib/metanorma/csa_document/root.rb +27 -0
- data/lib/metanorma/csa_document.rb +9 -0
- data/lib/metanorma/document/cli.rb +52 -0
- data/lib/metanorma/document/components/ancillary_blocks/sourcecode_body.rb +14 -0
- data/lib/metanorma/document/components/inline/comma_element.rb +3 -0
- data/lib/metanorma/document/components/inline/enum_comma_element.rb +3 -0
- data/lib/metanorma/document/components/inline/eref_element.rb +4 -1
- data/lib/metanorma/document/components/inline/fmt_termsource_element.rb +4 -2
- data/lib/metanorma/document/components/inline/math_element.rb +13 -7
- data/lib/metanorma/document/components/inline/semx_element.rb +7 -8
- data/lib/metanorma/document/components/inline/vocabulary.rb +4 -0
- data/lib/metanorma/document/components/multi_paragraph/admonition_block.rb +6 -1
- data/lib/metanorma/document/components/paragraphs/paragraph_block.rb +3 -0
- data/lib/metanorma/document/components/reference_elements/callout.rb +3 -2
- data/lib/metanorma/document/components/tables/table_cell.rb +3 -0
- data/lib/metanorma/document/elements/input.rb +44 -0
- data/lib/metanorma/document/elements.rb +1 -0
- data/lib/metanorma/document/relaton/address.rb +5 -0
- data/lib/metanorma/document/relaton/affiliation.rb +3 -0
- data/lib/metanorma/document/relaton/bib_item_size.rb +8 -9
- data/lib/metanorma/document/relaton/bib_item_type.rb +3 -0
- data/lib/metanorma/document/relaton/bibliographic_date.rb +5 -0
- data/lib/metanorma/document/relaton/contact_method.rb +5 -0
- data/lib/metanorma/document/relaton/contribution_info.rb +6 -2
- data/lib/metanorma/document/relaton/contributor.rb +4 -0
- data/lib/metanorma/document/relaton/contributor_role.rb +3 -0
- data/lib/metanorma/document/relaton/copyright_association.rb +3 -0
- data/lib/metanorma/document/relaton/copyright_owner.rb +3 -0
- data/lib/metanorma/document/relaton/date_time.rb +3 -0
- data/lib/metanorma/document/relaton/document_identifier.rb +4 -0
- data/lib/metanorma/document/relaton/document_relation.rb +8 -0
- data/lib/metanorma/document/relaton/document_status.rb +4 -0
- data/lib/metanorma/document/relaton/formatted_address.rb +4 -0
- data/lib/metanorma/document/relaton/full_name.rb +14 -3
- data/lib/metanorma/document/relaton/keyword_type.rb +3 -0
- data/lib/metanorma/document/relaton/locality_stack.rb +6 -9
- data/lib/metanorma/document/relaton/localized_name.rb +8 -5
- data/lib/metanorma/document/relaton/logo_element.rb +5 -0
- data/lib/metanorma/document/relaton/medium_type.rb +5 -16
- data/lib/metanorma/document/relaton/org_identifier.rb +2 -0
- data/lib/metanorma/document/relaton/org_subdivision.rb +2 -0
- data/lib/metanorma/document/relaton/org_subdivision_identifier.rb +2 -0
- data/lib/metanorma/document/relaton/organization.rb +3 -0
- data/lib/metanorma/document/relaton/person.rb +7 -1
- data/lib/metanorma/document/relaton/person_identifier.rb +3 -0
- data/lib/metanorma/document/relaton/place_type.rb +5 -0
- data/lib/metanorma/document/relaton/region_element.rb +3 -9
- data/lib/metanorma/document/relaton/relaton_collection.rb +2 -0
- data/lib/metanorma/document/relaton/series_type.rb +7 -0
- data/lib/metanorma/document/relaton/typed_note.rb +4 -0
- data/lib/metanorma/document/relaton/typed_title_string.rb +4 -0
- data/lib/metanorma/document/relaton/typed_uri.rb +3 -8
- data/lib/metanorma/document/relaton/validity_type.rb +8 -10
- data/lib/metanorma/document/relaton/variant_full_name.rb +3 -0
- data/lib/metanorma/document/relaton/variant_org_name.rb +3 -0
- data/lib/metanorma/document/relaton/version_info.rb +5 -0
- data/lib/metanorma/document/relaton/vocab_id_type.rb +6 -12
- data/lib/metanorma/document/relaton.rb +0 -14
- data/lib/metanorma/document/version.rb +1 -1
- data/lib/metanorma/document.rb +1 -0
- data/lib/metanorma/html/base_renderer.rb +133 -307
- data/lib/metanorma/html/component/base.rb +2 -9
- data/lib/metanorma/html/concerns/metadata_extraction.rb +61 -0
- data/lib/metanorma/html/concerns/presentation_validation.rb +61 -0
- data/lib/metanorma/html/concerns/svg_processing.rb +32 -0
- data/lib/metanorma/html/concerns/text_extraction.rb +93 -0
- data/lib/metanorma/html/concerns/toc_registry.rb +47 -0
- data/lib/metanorma/html/csa_renderer.rb +9 -0
- data/lib/metanorma/html/drops/figure_drop.rb +33 -10
- data/lib/metanorma/html/drops/sourcecode_drop.rb +3 -6
- data/lib/metanorma/html/flavor.rb +50 -0
- data/lib/metanorma/html/flavor_registry.rb +49 -0
- data/lib/metanorma/html/generator.rb +113 -29
- data/lib/metanorma/html/iso_renderer.rb +0 -142
- data/lib/metanorma/html/renderer_delegation.rb +21 -0
- data/lib/metanorma/html/renderers/block_renderer.rb +10 -0
- data/lib/metanorma/html/renderers/element_order_traversal.rb +48 -0
- data/lib/metanorma/html/renderers/inline_renderer.rb +49 -124
- data/lib/metanorma/html/renderers/pubid_renderer.rb +4 -26
- data/lib/metanorma/html/renderers.rb +2 -0
- data/lib/metanorma/html/standard_renderer.rb +198 -36
- data/lib/metanorma/html.rb +4 -51
- data/lib/metanorma/iso_document/sections/iso_preface.rb +27 -13
- data/lib/metanorma/mirror/default_registry.rb +21 -0
- data/lib/metanorma/mirror/handlers/inline/catalog.rb +52 -0
- data/lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb +34 -35
- data/lib/metanorma/mirror/handlers/inline.rb +1 -0
- data/lib/metanorma/mirror/handlers/sourcecode.rb +1 -1
- data/lib/metanorma/mirror/model/guide.rb +3 -2
- data/lib/metanorma/mirror/output/formats/inline_format.rb +64 -3
- data/lib/metanorma/mirror/output/pipeline.rb +1 -0
- data/lib/metanorma/mirror/output.rb +0 -2
- data/lib/metanorma/mirror/rewriter.rb +3 -1
- data/lib/metanorma/mirror/transformer.rb +91 -3
- data/lib/metanorma/mirror.rb +0 -1
- data/lib/metanorma/registers/setup.rb +10 -0
- data/lib/metanorma/standard_document/annotation_container.rb +2 -0
- data/lib/metanorma/standard_document/elements/input.rb +4 -25
- data/lib/metanorma/standard_document/metadata/metanorma_extension.rb +12 -2
- data/lib/metanorma/standard_document/metadata/presentation_metadata.rb +107 -0
- data/lib/metanorma/standard_document/metadata/semantic_metadata.rb +18 -0
- data/lib/metanorma/standard_document/metadata/unitsml/amount_of_substance.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/base_quantity.rb +34 -0
- data/lib/metanorma/standard_document/metadata/unitsml/dimension.rb +39 -0
- data/lib/metanorma/standard_document/metadata/unitsml/dimension_set.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/electric_current.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/enumerated_root_unit.rb +23 -0
- data/lib/metanorma/standard_document/metadata/unitsml/length.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/luminous_intensity.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/mass.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/namespace.rb +17 -0
- data/lib/metanorma/standard_document/metadata/unitsml/plane_angle.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/prefix.rb +30 -0
- data/lib/metanorma/standard_document/metadata/unitsml/prefix_name.rb +21 -0
- data/lib/metanorma/standard_document/metadata/unitsml/prefix_set.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/prefix_symbol.rb +21 -0
- data/lib/metanorma/standard_document/metadata/unitsml/quantity.rb +28 -0
- data/lib/metanorma/standard_document/metadata/unitsml/quantity_name.rb +21 -0
- data/lib/metanorma/standard_document/metadata/unitsml/quantity_set.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/root_units.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/thermodynamic_temperature.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/time.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/unit.rb +32 -0
- data/lib/metanorma/standard_document/metadata/unitsml/unit_name.rb +21 -0
- data/lib/metanorma/standard_document/metadata/unitsml/unit_set.rb +19 -0
- data/lib/metanorma/standard_document/metadata/unitsml/unit_symbol.rb +36 -0
- data/lib/metanorma/standard_document/metadata/unitsml/unit_system.rb +23 -0
- data/lib/metanorma/standard_document/metadata/unitsml/unitsml_root.rb +28 -0
- data/lib/metanorma/standard_document/metadata/unitsml.rb +39 -0
- data/lib/metanorma/standard_document/metadata.rb +4 -0
- data/lib/metanorma/standard_document/sections/misc_container.rb +8 -6
- data/lib/metanorma/standard_document/sections/sections.rb +7 -0
- data/lib/metanorma/un_document/blocks/un_admonition_block.rb +86 -0
- data/lib/metanorma/un_document/blocks.rb +9 -0
- data/lib/metanorma/un_document/root.rb +8 -0
- data/lib/metanorma/un_document/sections/un_abstract_section.rb +48 -0
- data/lib/metanorma/un_document/sections/un_preface.rb +19 -2
- data/lib/metanorma/un_document/sections.rb +1 -0
- data/lib/metanorma/un_document/un_text_element.rb +116 -0
- data/lib/metanorma/un_document.rb +2 -0
- data/script/benchmark_render.rb +35 -0
- data/tasks/roundtrip_samples.rake +1 -1
- metadata +78 -50
- data/.rubocop_todo.yml +0 -327
- data/TODO.finalize/01-split-multi-class-files.md +0 -8
- data/TODO.finalize/02-remove-data-dist-iso-document-frontend.md +0 -6
- data/TODO.finalize/03-align-frontend-iife-and-gha-build.md +0 -11
- data/TODO.finalize/04-theme-per-flavor-config-driven.md +0 -9
- data/TODO.finalize/05-migrate-all-html-to-liquid.md +0 -16
- data/TODO.finalize/06-integrate-pubid-library.md +0 -16
- data/TODO.finalize/07-replace-relaton-models-with-relaton-bib.md +0 -39
- data/TODO.finalize/08-refactor-renderer-architecture.md +0 -25
- data/TODO.finalize/09-eliminate-code-smells.md +0 -14
- data/TODO.finalize/10-comprehensive-spec-coverage.md +0 -24
- data/TODO.finalize/11-config-driven-flavor-metadata.md +0 -20
- data/TODO.finalize/12-add-frozen-string-literal.md +0 -6
- data/TODO.finalize/13-extract-composition-from-god-class.md +0 -96
- data/TODO.finalize/14-config-driven-section-ordering.md +0 -31
- data/TODO.finalize/15-theme-directories-per-flavor.md +0 -46
- data/TODO.finalize/16-theme-lutaml-model-schema.md +0 -44
- data/docs/html-renderer.adoc +0 -261
- data/lib/data/dist/iso_document/frontend/assets/index-mwzbzmnK.js +0 -22
- data/lib/data/dist/iso_document/frontend/assets/index-pGvKTNid.css +0 -1
- data/lib/data/dist/iso_document/frontend/assets/iso-red.svg +0 -53
- data/lib/data/dist/iso_document/frontend/index.html +0 -13
- data/lib/metanorma/document/relaton/bib_item_size_type.rb +0 -21
- data/lib/metanorma/document/relaton/bibliographic_date_type.rb +0 -22
- data/lib/metanorma/document/relaton/document_relation_type.rb +0 -31
- data/lib/metanorma/document/relaton/iso4217_code.rb +0 -17
- data/lib/metanorma/document/relaton/iso8601_date.rb +0 -17
- data/lib/metanorma/document/relaton/personal_identifier_type.rb +0 -21
- data/lib/metanorma/document/relaton/region_type.rb +0 -20
- data/lib/metanorma/document/relaton/series_type_type.rb +0 -21
- data/lib/metanorma/document/relaton/specific_locality_type.rb +0 -25
- data/lib/metanorma/document/relaton/title_type.rb +0 -21
- data/lib/metanorma/mirror/metanorma_to_mirror.rb +0 -101
- data/lib/metanorma/mirror/output/html_renderer.rb +0 -95
- data/lib/metanorma/mirror/output/html_renderers/block_renderers.rb +0 -178
- data/lib/metanorma/mirror/output/html_renderers/inline_renderer.rb +0 -61
- data/lib/metanorma/mirror/output/html_renderers/list_renderers.rb +0 -96
- data/lib/metanorma/mirror/output/html_renderers/mark_renderers.rb +0 -64
- data/lib/metanorma/mirror/output/html_renderers/section_renderers.rb +0 -129
- data/lib/metanorma/mirror/output/html_renderers/structural_renderers.rb +0 -80
- data/lib/metanorma/mirror/output/html_renderers/table_renderers.rb +0 -87
- data/lib/metanorma/mirror/output/html_renderers.rb +0 -76
- data/lib/metanorma/standard_document/annotation.rb +0 -37
|
@@ -330,148 +330,6 @@ module Metanorma
|
|
|
330
330
|
|
|
331
331
|
# --- ISO Term rendering ---
|
|
332
332
|
|
|
333
|
-
def render_term(term, **_opts)
|
|
334
|
-
term_name = extract_term_name(term)
|
|
335
|
-
term_def = extract_term_definition(term)
|
|
336
|
-
data_attrs = {}
|
|
337
|
-
if term_name && !term_name.empty?
|
|
338
|
-
data_attrs["data-term-name"] = term_name
|
|
339
|
-
end
|
|
340
|
-
if term_def && !term_def.empty?
|
|
341
|
-
data_attrs["data-term-definition"] = term_def
|
|
342
|
-
end
|
|
343
|
-
attrs = element_attrs(id: safe_attr(term, :id), **data_attrs)
|
|
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)
|
|
359
|
-
|
|
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) || "") }
|
|
378
|
-
end
|
|
379
|
-
elsif term.preferred && !term.preferred.empty?
|
|
380
|
-
term.preferred&.each do |designation|
|
|
381
|
-
parts << (render_term_designation(designation, "preferred") || "")
|
|
382
|
-
end
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
if fmt_admitted && !fmt_admitted.empty?
|
|
386
|
-
fmt_admitted.each do |fa|
|
|
387
|
-
fa.p&.each { |para| parts << (render_paragraph(para) || "") }
|
|
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
|
|
394
|
-
|
|
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") || "")
|
|
402
|
-
end
|
|
403
|
-
end
|
|
404
|
-
|
|
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
|
-
})
|
|
411
|
-
end
|
|
412
|
-
end
|
|
413
|
-
|
|
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
|
|
422
|
-
|
|
423
|
-
term_note&.each { |note| parts << (render_term_note(note) || "") }
|
|
424
|
-
term_example&.each { |ex| parts << (render_term_example(ex) || "") }
|
|
425
|
-
|
|
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) || "")
|
|
438
|
-
end
|
|
439
|
-
end
|
|
440
|
-
|
|
441
|
-
term_admonition&.each { |adm| parts << (render_admonition(adm) || "") }
|
|
442
|
-
term_nested&.each { |sub| parts << (render_term(sub) || "") }
|
|
443
|
-
|
|
444
|
-
render_liquid("_element.html.liquid", "tag" => "div",
|
|
445
|
-
"extra_attrs" => attrs, "content" => parts.join)
|
|
446
|
-
end
|
|
447
|
-
|
|
448
|
-
def extract_term_name(term)
|
|
449
|
-
fmt_pref = safe_attr(term, :fmt_preferred)
|
|
450
|
-
if fmt_pref && !fmt_pref.empty?
|
|
451
|
-
fp = fmt_pref.first
|
|
452
|
-
if fp.p && !fp.p.empty?
|
|
453
|
-
return extract_plain_text(fp.p.first)
|
|
454
|
-
end
|
|
455
|
-
end
|
|
456
|
-
if term.preferred && !term.preferred.empty?
|
|
457
|
-
return extract_designation_name(term.preferred.first).to_s
|
|
458
|
-
end
|
|
459
|
-
|
|
460
|
-
safe_attr(term, :id).to_s.delete_prefix("term-")
|
|
461
|
-
end
|
|
462
|
-
|
|
463
|
-
def extract_term_definition(term)
|
|
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?
|
|
471
|
-
end
|
|
472
|
-
nil
|
|
473
|
-
end
|
|
474
|
-
|
|
475
333
|
def render_term_designation(designation, type)
|
|
476
334
|
css_class = type == "deprecated" ? "term-deprecated" : "term-name"
|
|
477
335
|
name = extract_designation_name(designation)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Metanorma
|
|
4
|
+
module Html
|
|
5
|
+
# Shared forwarding methods for narrowing wrappers around a
|
|
6
|
+
# renderer. Both RendererContext (used by Drop factories) and
|
|
7
|
+
# Component::Base (used by Component renderers) include this
|
|
8
|
+
# module so the shared forwarding surface is declared in one
|
|
9
|
+
# place. Adding a new shared method is one edit here, not two.
|
|
10
|
+
#
|
|
11
|
+
# Per-class-specific forwarders stay declared in each wrapper.
|
|
12
|
+
module RendererDelegation
|
|
13
|
+
def safe_attr(...) = @renderer.safe_attr(...)
|
|
14
|
+
def escape_html(...) = @renderer.escape_html(...)
|
|
15
|
+
def extract_block_label(...)= @renderer.extract_block_label(...)
|
|
16
|
+
def extract_plain_text(...) = @renderer.extract_plain_text(...)
|
|
17
|
+
def render_mixed_inline(...)= @renderer.render_mixed_inline(...)
|
|
18
|
+
def render_liquid(...) = @renderer.render_liquid(...)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -271,6 +271,16 @@ module Metanorma
|
|
|
271
271
|
render_liquid("_example.html.liquid", { "block" => drop })
|
|
272
272
|
end
|
|
273
273
|
|
|
274
|
+
def render_form(form, **_opts)
|
|
275
|
+
attrs = element_attrs(id: safe_attr(form, :id), class: "form")
|
|
276
|
+
content = coordinator.render_ordered_content(form)
|
|
277
|
+
render_liquid("_element.html.liquid", {
|
|
278
|
+
"tag" => "div",
|
|
279
|
+
"extra_attrs" => attrs,
|
|
280
|
+
"content" => content,
|
|
281
|
+
})
|
|
282
|
+
end
|
|
283
|
+
|
|
274
284
|
def render_sourcecode(sc, **_opts)
|
|
275
285
|
drop = Drops::SourcecodeDrop.from_model(sc,
|
|
276
286
|
renderer: coordinator.renderer_context)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Metanorma
|
|
4
|
+
module Html
|
|
5
|
+
module Renderers
|
|
6
|
+
# Builds the reverse lookup `{ xml_element_name => attribute_name }`
|
|
7
|
+
# from a node's xml mapping. Shared between walkers that iterate
|
|
8
|
+
# element_order: InlineRenderer#walk_ordered (renders in document
|
|
9
|
+
# order) and BaseRenderer#extract_plain_text (extracts text).
|
|
10
|
+
#
|
|
11
|
+
# Both walkers previously reimplemented this hash construction
|
|
12
|
+
# inline; the construction is the genuinely-shared traversal
|
|
13
|
+
# concern. Per-element handling (recursion, span emission, tab/br
|
|
14
|
+
# spacing) differs and stays in each walker.
|
|
15
|
+
module ElementOrderTraversal
|
|
16
|
+
module_function
|
|
17
|
+
|
|
18
|
+
# The map depends only on the model class's xml mapping, which is
|
|
19
|
+
# immutable after class definition — cache one map per mapping
|
|
20
|
+
# object instead of rebuilding it for every rendered node.
|
|
21
|
+
@cache = {}.compare_by_identity
|
|
22
|
+
|
|
23
|
+
def element_to_attr_map(xml_mapping)
|
|
24
|
+
@cache[xml_mapping] ||= build_map(xml_mapping)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Test/benchmark hook: drop all memoized maps.
|
|
28
|
+
def reset_cache!
|
|
29
|
+
@cache.clear
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns `{ xml_element_name => attr_name }` including both
|
|
33
|
+
# symbol and string keys for each mapped element, so callers
|
|
34
|
+
# can look up by either el.name form.
|
|
35
|
+
def build_map(xml_mapping)
|
|
36
|
+
{}.tap do |map|
|
|
37
|
+
xml_mapping.mapping_elements_hash.each_value do |rule_or_array|
|
|
38
|
+
Array(rule_or_array).each do |rule|
|
|
39
|
+
map[rule.name] = rule.to
|
|
40
|
+
map[rule.name.to_s] = rule.to if rule.name.is_a?(Symbol)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -15,16 +15,8 @@ module Metanorma
|
|
|
15
15
|
xml_mapping = node.class.mappings_for(:xml, node.lutaml_register)
|
|
16
16
|
return false unless xml_mapping
|
|
17
17
|
|
|
18
|
-
element_to_attr =
|
|
19
|
-
|
|
20
|
-
Array(rule_or_array).each do |rule|
|
|
21
|
-
element_to_attr[rule.name] = rule.to
|
|
22
|
-
if rule.name.is_a?(Symbol)
|
|
23
|
-
element_to_attr[rule.name.to_s] =
|
|
24
|
-
rule.to
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
18
|
+
element_to_attr =
|
|
19
|
+
Renderers::ElementOrderTraversal.element_to_attr_map(xml_mapping)
|
|
28
20
|
|
|
29
21
|
skip_indices = build_semx_skip_set(node)
|
|
30
22
|
|
|
@@ -112,13 +104,6 @@ module Metanorma
|
|
|
112
104
|
end
|
|
113
105
|
|
|
114
106
|
def render_mixed_inline(node)
|
|
115
|
-
if raw_content_node?(node)
|
|
116
|
-
raw = node.content
|
|
117
|
-
if raw.is_a?(String) && !raw.strip.empty?
|
|
118
|
-
return render_raw_content(raw)
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
107
|
if node.is_a?(Lutaml::Model::Serializable) && node.element_order && !node.element_order.empty?
|
|
123
108
|
render_ordered_inline(node)
|
|
124
109
|
elsif node.is_a?(Lutaml::Model::Serializable)
|
|
@@ -137,13 +122,6 @@ module Metanorma
|
|
|
137
122
|
end
|
|
138
123
|
end
|
|
139
124
|
|
|
140
|
-
def raw_content_node?(node)
|
|
141
|
-
node.is_a?(Lutaml::Model::Serializable) &&
|
|
142
|
-
node.content.is_a?(String)
|
|
143
|
-
rescue NoMethodError
|
|
144
|
-
false
|
|
145
|
-
end
|
|
146
|
-
|
|
147
125
|
def render_ordered_inline(node)
|
|
148
126
|
parts = []
|
|
149
127
|
walked = walk_ordered(node) do |type, obj|
|
|
@@ -251,8 +229,19 @@ module Metanorma
|
|
|
251
229
|
", "
|
|
252
230
|
end
|
|
253
231
|
|
|
232
|
+
# Form inputs render as disabled HTML inputs — this is a document
|
|
233
|
+
# rendering, not an interactive form.
|
|
234
|
+
def render_input(el)
|
|
235
|
+
attrs = element_attrs(
|
|
236
|
+
type: safe_attr(el, :type) || "text",
|
|
237
|
+
disabled: "disabled",
|
|
238
|
+
checked: safe_attr(el, :checked) ? "checked" : nil,
|
|
239
|
+
)
|
|
240
|
+
"<input#{attrs}>"
|
|
241
|
+
end
|
|
242
|
+
|
|
254
243
|
def render_math(el)
|
|
255
|
-
el.
|
|
244
|
+
el.to_xml
|
|
256
245
|
end
|
|
257
246
|
|
|
258
247
|
def render_asciimath(el)
|
|
@@ -299,13 +288,14 @@ module Metanorma
|
|
|
299
288
|
parts << escape_html(texts)
|
|
300
289
|
end
|
|
301
290
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
291
|
+
# Derive the element-mapped attribute list from the node's own
|
|
292
|
+
# xml_mapping rather than maintaining a parallel hardcoded list.
|
|
293
|
+
# The model is the single source of truth; adding a new inline
|
|
294
|
+
# element type via map_element on the model class is enough.
|
|
295
|
+
node.class.mappings[:xml].elements.each do |rule|
|
|
296
|
+
next if rule.to == :text
|
|
297
|
+
|
|
298
|
+
values = safe_attr(node, rule.to)
|
|
309
299
|
next if values.nil?
|
|
310
300
|
|
|
311
301
|
Array(values).each { |v| parts << (render_inline_element(v) || "") }
|
|
@@ -381,65 +371,6 @@ module Metanorma
|
|
|
381
371
|
})
|
|
382
372
|
end
|
|
383
373
|
|
|
384
|
-
def render_raw_content(raw_xml)
|
|
385
|
-
doc = Nokogiri::XML.fragment(raw_xml)
|
|
386
|
-
doc.css("fmt-link").each do |el|
|
|
387
|
-
target = el["target"] || el["href"]
|
|
388
|
-
if target
|
|
389
|
-
display_text = target.delete_prefix("mailto:")
|
|
390
|
-
a = doc.document.create_element("a", display_text,
|
|
391
|
-
"href" => target)
|
|
392
|
-
el.replace(a)
|
|
393
|
-
else
|
|
394
|
-
el.replace(el.children)
|
|
395
|
-
end
|
|
396
|
-
end
|
|
397
|
-
doc.traverse do |node|
|
|
398
|
-
next unless node.element?
|
|
399
|
-
next unless %w[xref eref stem link].include?(node.name)
|
|
400
|
-
|
|
401
|
-
next_sib = node.next_sibling
|
|
402
|
-
while next_sib.is_a?(Nokogiri::XML::Text) && next_sib.text.strip.empty?
|
|
403
|
-
next_sib = next_sib.next_sibling
|
|
404
|
-
end
|
|
405
|
-
next unless next_sib&.element? && next_sib.name == "semx"
|
|
406
|
-
|
|
407
|
-
deduplicate_semx_label(node, next_sib)
|
|
408
|
-
node.remove
|
|
409
|
-
end
|
|
410
|
-
%w[semx fmt-xref].each do |tag|
|
|
411
|
-
doc.css(tag).each { |el| el.replace(el.children) }
|
|
412
|
-
end
|
|
413
|
-
doc.css("[class]").each do |el|
|
|
414
|
-
el["class"] = el["class"].split(/\s+/).map do |c|
|
|
415
|
-
html_class_for_span(c)
|
|
416
|
-
end.join(" ")
|
|
417
|
-
end
|
|
418
|
-
doc.inner_html
|
|
419
|
-
end
|
|
420
|
-
|
|
421
|
-
def deduplicate_semx_label(source_node, semx_node)
|
|
422
|
-
first_text = semx_node.children.find do |c|
|
|
423
|
-
c.text? && !c.text.strip.empty?
|
|
424
|
-
end
|
|
425
|
-
return unless first_text
|
|
426
|
-
|
|
427
|
-
semx_prefix = first_text.text[/\A(\s*\S+)/, 1]
|
|
428
|
-
return unless semx_prefix && !semx_prefix.strip.empty?
|
|
429
|
-
|
|
430
|
-
prev = source_node.previous_sibling
|
|
431
|
-
return unless prev.is_a?(Nokogiri::XML::Text)
|
|
432
|
-
|
|
433
|
-
label = semx_prefix.strip
|
|
434
|
-
prev_text = prev.text.rstrip
|
|
435
|
-
return unless prev_text.end_with?(label)
|
|
436
|
-
|
|
437
|
-
prev.content = prev_text.sub(/#{Regexp.escape(label)}\s*\z/, "")
|
|
438
|
-
first_text.content = first_text.text.sub(
|
|
439
|
-
/\A\s*#{Regexp.escape(label)}\s*/, ""
|
|
440
|
-
)
|
|
441
|
-
end
|
|
442
|
-
|
|
443
374
|
def render_link(link)
|
|
444
375
|
target = safe_attr(link, :target) || safe_attr(link, :href)
|
|
445
376
|
attrs = element_attrs(href: target, id: safe_attr(link, :id))
|
|
@@ -524,7 +455,7 @@ module Metanorma
|
|
|
524
455
|
end
|
|
525
456
|
|
|
526
457
|
if math_items.any?
|
|
527
|
-
content = math_items.map
|
|
458
|
+
content = math_items.map(&:to_xml).join
|
|
528
459
|
unless content.empty?
|
|
529
460
|
return render_liquid("_math_container.html.liquid", {
|
|
530
461
|
"data_attrs" => data_attrs,
|
|
@@ -541,50 +472,44 @@ module Metanorma
|
|
|
541
472
|
nil
|
|
542
473
|
end
|
|
543
474
|
|
|
475
|
+
# Stem content formats in priority order. Each entry binds an
|
|
476
|
+
# attribute reader on the stem element to the value-render path
|
|
477
|
+
# (raw XML when serializable, escaped text otherwise). Adding a
|
|
478
|
+
# new format = one entry here.
|
|
479
|
+
STEM_FORMATS = [
|
|
480
|
+
{ attr: :math, raw_xml: true },
|
|
481
|
+
{ attr: :asciimath },
|
|
482
|
+
{ attr: :latexmath },
|
|
483
|
+
].freeze
|
|
484
|
+
|
|
544
485
|
def render_stem_content(stem)
|
|
545
486
|
return nil if stem.nil?
|
|
546
487
|
|
|
547
|
-
if stem.is_a?(Metanorma::Document::Components::Inline::StemInlineElement)
|
|
548
|
-
|
|
549
|
-
end
|
|
550
|
-
|
|
551
|
-
if stem.is_a?(Metanorma::Document::Components::Inline::FmtStemElement)
|
|
552
|
-
return nil
|
|
553
|
-
end
|
|
554
|
-
|
|
555
|
-
if stem.is_a?(Metanorma::Document::Components::TextElements::StemElement)
|
|
556
|
-
if stem.math
|
|
557
|
-
math_val = stem.math
|
|
558
|
-
if math_val.is_a?(Lutaml::Model::Serializable)
|
|
559
|
-
return math_val.to_xml
|
|
560
|
-
end
|
|
488
|
+
return nil if stem.is_a?(Metanorma::Document::Components::Inline::StemInlineElement) ||
|
|
489
|
+
stem.is_a?(Metanorma::Document::Components::Inline::FmtStemElement)
|
|
561
490
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
"text" => text,
|
|
566
|
-
})
|
|
567
|
-
elsif stem.asciimath
|
|
568
|
-
text = escape_html(coordinator.extract_text_value(stem.asciimath))
|
|
569
|
-
return render_liquid("_stem_span.html.liquid", {
|
|
570
|
-
"data_attrs" => "",
|
|
571
|
-
"text" => text,
|
|
572
|
-
})
|
|
573
|
-
end
|
|
574
|
-
if stem.latexmath
|
|
575
|
-
text = escape_html(coordinator.extract_text_value(stem.latexmath))
|
|
491
|
+
unless stem.is_a?(Metanorma::Document::Components::TextElements::StemElement)
|
|
492
|
+
text = coordinator.extract_text_value(stem)
|
|
493
|
+
unless text.empty?
|
|
576
494
|
return render_liquid("_stem_span.html.liquid", {
|
|
577
495
|
"data_attrs" => "",
|
|
578
|
-
"text" => text,
|
|
496
|
+
"text" => escape_html(text),
|
|
579
497
|
})
|
|
580
498
|
end
|
|
499
|
+
return nil
|
|
581
500
|
end
|
|
582
501
|
|
|
583
|
-
|
|
584
|
-
|
|
502
|
+
STEM_FORMATS.each do |format|
|
|
503
|
+
value = stem.public_send(format[:attr])
|
|
504
|
+
next unless value
|
|
505
|
+
|
|
506
|
+
if format[:raw_xml] && value.is_a?(Lutaml::Model::Serializable)
|
|
507
|
+
return value.to_xml
|
|
508
|
+
end
|
|
509
|
+
|
|
585
510
|
return render_liquid("_stem_span.html.liquid", {
|
|
586
511
|
"data_attrs" => "",
|
|
587
|
-
"text" => escape_html(
|
|
512
|
+
"text" => escape_html(coordinator.extract_text_value(value)),
|
|
588
513
|
})
|
|
589
514
|
end
|
|
590
515
|
nil
|
|
@@ -4,15 +4,6 @@ module Metanorma
|
|
|
4
4
|
module Html
|
|
5
5
|
module Renderers
|
|
6
6
|
class PubidRenderer
|
|
7
|
-
FLAVOR_PUBID_MAP = {
|
|
8
|
-
"IsoDocument" => :"Pubid::Iso",
|
|
9
|
-
"IecDocument" => :"Pubid::Iec",
|
|
10
|
-
"IeeeDocument" => :"Pubid::Ieee",
|
|
11
|
-
"IhoDocument" => :"Pubid::Iho",
|
|
12
|
-
"ItuDocument" => :"Pubid::Ithu",
|
|
13
|
-
"OimlDocument" => :"Pubid::Oiml",
|
|
14
|
-
}.freeze
|
|
15
|
-
|
|
16
7
|
def initialize(coordinator)
|
|
17
8
|
@coordinator = coordinator
|
|
18
9
|
end
|
|
@@ -44,24 +35,11 @@ module Metanorma
|
|
|
44
35
|
@coordinator.escape_html(text)
|
|
45
36
|
end
|
|
46
37
|
|
|
38
|
+
# Flavor identity comes from the shared FlavorRegistry via the
|
|
39
|
+
# coordinator — no local duplicate of the flavor-to-pubid-module
|
|
40
|
+
# map.
|
|
47
41
|
def resolve_pubid_module
|
|
48
|
-
|
|
49
|
-
return nil unless flavor_name
|
|
50
|
-
|
|
51
|
-
@coordinator.class.ancestors.each do |ancestor|
|
|
52
|
-
next unless ancestor.is_a?(Class)
|
|
53
|
-
|
|
54
|
-
ns = ancestor.name&.split("::")&.detect do |n|
|
|
55
|
-
FLAVOR_PUBID_MAP.key?(n)
|
|
56
|
-
end
|
|
57
|
-
next unless ns
|
|
58
|
-
|
|
59
|
-
mod = FLAVOR_PUBID_MAP[ns]
|
|
60
|
-
return Object.const_get(mod.to_s)
|
|
61
|
-
end
|
|
62
|
-
nil
|
|
63
|
-
rescue NameError
|
|
64
|
-
nil
|
|
42
|
+
@coordinator.pubid_module
|
|
65
43
|
end
|
|
66
44
|
end
|
|
67
45
|
end
|