metanorma-document 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +231 -53
  3. data/README.adoc +59 -18
  4. data/data/stylesheets/components/bibliography.css +2 -2
  5. data/data/stylesheets/components/inline.css +11 -12
  6. data/docs/html-renderer.adoc +261 -0
  7. data/lib/metanorma/document/version.rb +1 -1
  8. data/lib/metanorma/html/base_renderer.rb +210 -257
  9. data/lib/metanorma/html/bipm_renderer.rb +0 -1
  10. data/lib/metanorma/html/cc_renderer.rb +0 -1
  11. data/lib/metanorma/html/drops/admonition_drop.rb +26 -0
  12. data/lib/metanorma/html/drops/block_element_drop.rb +20 -0
  13. data/lib/metanorma/html/drops/example_drop.rb +35 -0
  14. data/lib/metanorma/html/drops/figure_drop.rb +53 -0
  15. data/lib/metanorma/html/drops/formula_drop.rb +44 -0
  16. data/lib/metanorma/html/drops/note_drop.rb +32 -0
  17. data/lib/metanorma/html/drops/sourcecode_drop.rb +37 -0
  18. data/lib/metanorma/html/drops.rb +7 -0
  19. data/lib/metanorma/html/iec_renderer.rb +0 -1
  20. data/lib/metanorma/html/ieee_renderer.rb +0 -1
  21. data/lib/metanorma/html/ietf_renderer.rb +0 -1
  22. data/lib/metanorma/html/iho_renderer.rb +0 -1
  23. data/lib/metanorma/html/iso_renderer.rb +77 -209
  24. data/lib/metanorma/html/itu_renderer.rb +0 -1
  25. data/lib/metanorma/html/ogc_renderer.rb +5 -6
  26. data/lib/metanorma/html/oiml_renderer.rb +0 -1
  27. data/lib/metanorma/html/pdfa_renderer.rb +0 -1
  28. data/lib/metanorma/html/ribose_renderer.rb +0 -1
  29. data/lib/metanorma/html/standard_renderer.rb +63 -82
  30. data/lib/metanorma/html/templates/_admonition.html.liquid +4 -0
  31. data/lib/metanorma/html/templates/_doc_title.html.liquid +1 -1
  32. data/lib/metanorma/html/templates/_example.html.liquid +3 -0
  33. data/lib/metanorma/html/templates/_figure.html.liquid +6 -0
  34. data/lib/metanorma/html/templates/_formula.html.liquid +6 -0
  35. data/lib/metanorma/html/templates/_iso_doc_title.html.liquid +2 -2
  36. data/lib/metanorma/html/templates/_note.html.liquid +3 -0
  37. data/lib/metanorma/html/templates/_sourcecode.html.liquid +4 -0
  38. data/lib/metanorma/html.rb +0 -1
  39. metadata +16 -3
  40. data/lib/metanorma/html/component_registry.rb +0 -37
@@ -5,34 +5,34 @@ module Metanorma
5
5
  # Renders StandardDocument components to HTML.
6
6
  # Extends BaseRenderer with terms, bibliography, and standard sections.
7
7
  class StandardRenderer < BaseRenderer
8
- def render(node, **opts)
8
+ def render(node, **)
9
9
  case node
10
10
  when Metanorma::StandardDocument::Root
11
- render_standard_document(node, **opts)
11
+ render_standard_document(node, **)
12
12
  when Metanorma::StandardDocument::Terms::Term
13
- render_term(node, **opts)
13
+ render_term(node, **)
14
14
  when Metanorma::StandardDocument::Sections::TermsSection
15
- render_terms_section(node, **opts)
15
+ render_terms_section(node, **)
16
16
  when Metanorma::StandardDocument::Sections::StandardReferencesSection
17
- render_references_section(node, **opts)
17
+ render_references_section(node, **)
18
18
  when Metanorma::StandardDocument::Sections::BibliographySection
19
- render_bibliography(node, **opts)
19
+ render_bibliography(node, **)
20
20
  when Metanorma::StandardDocument::Sections::ClauseSection
21
- render_clause_section(node, **opts)
21
+ render_clause_section(node, **)
22
22
  when Metanorma::StandardDocument::Sections::AnnexSection
23
- render_annex_section(node, **opts)
23
+ render_annex_section(node, **)
24
24
  when Metanorma::StandardDocument::Sections::StandardSection
25
- render_standard_section(node, **opts)
25
+ render_standard_section(node, **)
26
26
  when Metanorma::StandardDocument::Sections::Abstract
27
- render_abstract_section(node, **opts)
27
+ render_abstract_section(node, **)
28
28
  when Metanorma::StandardDocument::Sections::Foreword
29
- render_foreword_section(node, **opts)
29
+ render_foreword_section(node, **)
30
30
  when Metanorma::StandardDocument::Sections::Introduction
31
- render_introduction_section(node, **opts)
31
+ render_introduction_section(node, **)
32
32
  when Metanorma::StandardDocument::Sections::FloatingTitle
33
- render_floating_title(node, **opts)
33
+ render_floating_title(node, **)
34
34
  when Metanorma::StandardDocument::Blocks::AmendBlock
35
- render_amend_block(node, **opts)
35
+ render_amend_block(node, **)
36
36
  else
37
37
  super
38
38
  end
@@ -86,8 +86,10 @@ module Metanorma
86
86
  cover_id = nil
87
87
  bibdata.doc_identifier&.each do |di|
88
88
  next unless safe_attr(di, :type) == "iso-reference"
89
+
89
90
  id = extract_text_value(di)
90
91
  next if id.to_s.empty?
92
+
91
93
  cover_id = id
92
94
  break
93
95
  end
@@ -105,9 +107,9 @@ module Metanorma
105
107
  end
106
108
 
107
109
  @output << render_liquid("_cover.html.liquid", {
108
- "doc_id" => cover_id,
109
- "title" => title_text,
110
- })
110
+ "doc_id" => cover_id,
111
+ "title" => title_text,
112
+ })
111
113
  end
112
114
 
113
115
  def render_doc_title(doc)
@@ -120,77 +122,62 @@ module Metanorma
120
122
  elsif bibdata.is_a?(Metanorma::Document::Components::BibData::BibData)
121
123
  titles = bibdata.title
122
124
  return unless titles && !titles.empty?
125
+
123
126
  en_title = titles.find { |t| t.language == "en" }
124
127
  return unless en_title
128
+
125
129
  en_title = extract_text_value(en_title)
126
130
  else
127
131
  return
128
132
  end
129
133
 
130
134
  @output << render_liquid("_doc_title.html.liquid", {
131
- "title" => en_title,
132
- })
135
+ "title" => en_title,
136
+ })
133
137
  end
134
138
 
135
139
  # --- Section rendering ---
136
140
 
137
- def render_clause_section(clause, level: 1, **_opts)
138
- attrs = element_attrs(id: safe_attr(clause, :id), class: safe_attr(clause, :class_attr))
141
+ def render_section(section, level: 1, title_class: nil, with_subsections: false, with_terms: false)
142
+ attrs = element_attrs(id: safe_attr(section, :id))
139
143
  tag("div", attrs) do
140
- render_standard_title(clause, level)
141
- render_standard_section_blocks(clause, level)
142
- render_subsections(clause, level)
144
+ if title_class
145
+ render_standard_title(section, level, default_class: title_class)
146
+ else
147
+ render_standard_title(section, level)
148
+ end
149
+ render_standard_section_blocks(section, level)
150
+ render_subsections(section, level) if with_subsections
151
+ section.terms&.each { |term| render_term(term) } if with_terms
143
152
  end
144
153
  end
145
154
 
146
- def render_annex_section(annex, level: 1, **_opts)
147
- attrs = element_attrs(id: safe_attr(annex, :id))
148
- tag("div", attrs) do
149
- render_standard_title(annex, level)
150
- render_standard_section_blocks(annex, level)
151
- render_subsections(annex, level)
152
- end
155
+ def render_clause_section(section, level: 1, **)
156
+ render_section(section, level: level, with_subsections: true)
153
157
  end
154
158
 
155
- def render_standard_section(section, level: 1, **_opts)
156
- attrs = element_attrs(id: safe_attr(section, :id))
157
- tag("div", attrs) do
158
- render_standard_title(section, level)
159
- render_standard_section_blocks(section, level)
160
- end
159
+ def render_annex_section(section, level: 1, **)
160
+ render_section(section, level: level, with_subsections: true)
161
161
  end
162
162
 
163
- def render_terms_section(terms, level: 1, **_opts)
164
- attrs = element_attrs(id: safe_attr(terms, :id))
165
- tag("div", attrs) do
166
- render_standard_title(terms, level)
167
- render_standard_section_blocks(terms, level)
168
- terms.terms&.each { |term| render_term(term) }
169
- end
163
+ def render_standard_section(section, level: 1, **)
164
+ render_section(section, level: level)
170
165
  end
171
166
 
172
- def render_abstract_section(section, level: 1, **_opts)
173
- attrs = element_attrs(id: safe_attr(section, :id))
174
- tag("div", attrs) do
175
- render_standard_title(section, level, default_class: "intro-title")
176
- render_standard_section_blocks(section, level)
177
- end
167
+ def render_terms_section(section, level: 1, **)
168
+ render_section(section, level: level, with_terms: true)
178
169
  end
179
170
 
180
- def render_foreword_section(section, level: 1, **_opts)
181
- attrs = element_attrs(id: safe_attr(section, :id))
182
- tag("div", attrs) do
183
- render_standard_title(section, level, default_class: "foreword-title")
184
- render_standard_section_blocks(section, level)
185
- end
171
+ def render_abstract_section(section, level: 1, **)
172
+ render_section(section, level: level, title_class: "intro-title")
186
173
  end
187
174
 
188
- def render_introduction_section(section, level: 1, **_opts)
189
- attrs = element_attrs(id: safe_attr(section, :id))
190
- tag("div", attrs) do
191
- render_standard_title(section, level, default_class: "intro-title")
192
- render_standard_section_blocks(section, level)
193
- end
175
+ def render_foreword_section(section, level: 1, **)
176
+ render_section(section, level: level, title_class: "foreword-title")
177
+ end
178
+
179
+ def render_introduction_section(section, level: 1, **)
180
+ render_section(section, level: level, title_class: "intro-title")
194
181
  end
195
182
 
196
183
  def render_floating_title(title_node, **_opts)
@@ -281,11 +268,7 @@ module Metanorma
281
268
  tag("div", attrs) do
282
269
  label = extract_termnote_label(note)
283
270
  @output << "<p><span class=\"term-note-label\">#{escape_html(label)}: </span>"
284
- if note.p && !note.p.empty?
285
- note.p.each do |para|
286
- render_mixed_inline(para)
287
- end
288
- end
271
+ note.p&.each { |para| render_mixed_inline(para) }
289
272
  @output << "</p>"
290
273
  note.ul&.each { |ul| render_unordered_list(ul) }
291
274
  note.ol&.each { |ol| render_ordered_list(ol) }
@@ -298,11 +281,7 @@ module Metanorma
298
281
  tag("div", attrs) do
299
282
  label = extract_block_label(example, "EXAMPLE")
300
283
  @output << "<p><span class=\"example-label\">#{escape_html(label)}</span>&nbsp;"
301
- if example.p && !example.p.empty?
302
- example.p.each do |para|
303
- render_mixed_inline(para)
304
- end
305
- end
284
+ example.p&.each { |para| render_mixed_inline(para) }
306
285
  @output << "</p>"
307
286
  example.ul&.each { |ul| render_unordered_list(ul) }
308
287
  example.ol&.each { |ol| render_ordered_list(ol) }
@@ -324,11 +303,11 @@ module Metanorma
324
303
  bibitemid = safe_attr(origin, :bibitemid)
325
304
 
326
305
  if citeas && !citeas.to_s.empty?
327
- if bibitemid && !bibitemid.to_s.empty?
328
- @output << "<a href=\"##{escape_html(bibitemid.to_s)}\" class=\"bibref\">#{escape_html(citeas.to_s)}</a>"
329
- else
330
- @output << escape_html(citeas.to_s)
331
- end
306
+ @output << if bibitemid && !bibitemid.to_s.empty?
307
+ "<a href=\"##{escape_html(bibitemid.to_s)}\" class=\"bibref\">#{escape_html(citeas.to_s)}</a>"
308
+ else
309
+ escape_html(citeas.to_s)
310
+ end
332
311
  else
333
312
  render_mixed_inline(origin)
334
313
  end
@@ -401,9 +380,11 @@ module Metanorma
401
380
  def bibitem_url(item)
402
381
  links = Array(item.link)
403
382
  return nil if links.empty?
383
+
404
384
  # Prefer src or citation type, skip RSS feeds
405
- preferred = links.find { |l| l.type == "src" || l.type == "citation" }
385
+ preferred = links.find { |l| ["src", "citation"].include?(l.type) }
406
386
  return preferred.content.to_s if preferred && !preferred.content.to_s.empty?
387
+
407
388
  # Fallback: first non-RSS link
408
389
  non_rss = links.find { |l| !l.content.to_s.include?(".rss") && !l.content.to_s.empty? }
409
390
  non_rss&.content&.to_s
@@ -421,13 +402,13 @@ module Metanorma
421
402
  docids = Array(item.docidentifier)
422
403
  # Skip bracket-number identifiers (e.g. "[1]") and iso-reference/URN variants;
423
404
  # render only the primary doc identifier
424
- primary = docids.find { |di|
405
+ primary = docids.find do |di|
425
406
  val = extract_text_value(di).to_s
426
407
  val.match?(/\A\[?\d+\]?\z/) ? false : !val.match?(/\A(?:iso-reference|URN)\s/)
427
- }
408
+ end
428
409
  if primary
429
410
  id_val = extract_text_value(primary)
430
- @output << "<span class=\"std-doc-number\">#{escape_html(id_val)}</span>" unless id_val.to_s.empty?
411
+ @output << "<span class=\"ref-doc-number\">#{escape_html(id_val)}</span>" unless id_val.to_s.empty?
431
412
  end
432
413
  end
433
414
 
@@ -436,7 +417,7 @@ module Metanorma
436
417
  date_on = date.is_a?(Metanorma::Document::Relaton::BibliographicDate) ? date.on : nil
437
418
  date_val = extract_text_value(date_on || safe_attr(date, :text))
438
419
  if date_val && !date_val.to_s.empty?
439
- @output << ":<span class=\"std-year\">#{escape_html(date_val.to_s)}</span>"
420
+ @output << ":<span class=\"ref-year\">#{escape_html(date_val.to_s)}</span>"
440
421
  end
441
422
  end
442
423
  end
@@ -0,0 +1,4 @@
1
+ <div{% if block.id %} id="{{ block.id }}"{% endif %} class="{{ block.css_class }}">
2
+ <p class="admonition-title">{{ block.label_html }}</p>
3
+ {{ block.content_html }}
4
+ </div>
@@ -1,3 +1,3 @@
1
1
  <p class="doc-title">
2
- <span class="bold-title">{{ title | escape }}</span>
2
+ <span class="title-text">{{ title | escape }}</span>
3
3
  </p>
@@ -0,0 +1,3 @@
1
+ <div{% if block.id %} id="{{ block.id }}"{% endif %} class="{{ block.css_class }}">
2
+ <span class="example-label">{{ block.label_html }}</span>&nbsp;{{ block.content_html }}
3
+ </div>
@@ -0,0 +1,6 @@
1
+ <figure{% if block.id %} id="{{ block.id }}"{% endif %} class="{{ block.css_class }}">
2
+ {{ block.image_html }}
3
+ {{ block.sub_figures_html }}
4
+ {% if block.caption_html %}<figcaption>{{ block.caption_html }}</figcaption>{% endif %}
5
+ {{ block.key_html }}
6
+ </figure>
@@ -0,0 +1,6 @@
1
+ <div{% if block.id %} id="{{ block.id }}"{% endif %} class="{{ block.css_class }}">
2
+ {{ block.stem_html }}
3
+ {% if block.where_html %}<p class="formula-where">where</p>{% endif %}
4
+ {{ block.where_html }}
5
+ {% if block.number_html %}<span class="formula-number">{{ block.number_html }}</span>{% endif %}
6
+ </div>
@@ -1,3 +1,3 @@
1
- <p class="zzSTDTitle1">
2
- <span class="boldtitle">{{ title | escape }}</span>
1
+ <p class="doc-title">
2
+ <span class="title-text">{{ title | escape }}</span>
3
3
  </p>
@@ -0,0 +1,3 @@
1
+ <div{% if block.id %} id="{{ block.id }}"{% endif %} class="{{ block.css_class }}">
2
+ <span class="note-label">{{ block.label_html }}</span>&nbsp;{{ block.content_html }}
3
+ </div>
@@ -0,0 +1,4 @@
1
+ <div{% if block.id %} id="{{ block.id }}"{% endif %} class="{{ block.css_class }}">
2
+ {% if block.name_html %}<p class="code-name">{{ block.name_html }}</p>{% endif %}
3
+ <pre><code{% if block.lang %} lang="{{ block.lang }}"{% endif %}>{{ block.code_html }}</code></pre>
4
+ </div>
@@ -8,7 +8,6 @@ module Metanorma
8
8
  autoload :Generator, "metanorma/html/generator"
9
9
  autoload :Theme, "metanorma/html/theme"
10
10
  autoload :AssetPipeline, "metanorma/html/asset_pipeline"
11
- autoload :ComponentRegistry, "metanorma/html/component_registry"
12
11
  autoload :Component, "metanorma/html/component"
13
12
  autoload :Drops, "metanorma/html/drops"
14
13
  autoload :StandardRenderer, "metanorma/html/standard_renderer"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-document
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-04 00:00:00.000000000 Z
11
+ date: 2026-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -96,6 +96,7 @@ files:
96
96
  - data/stylesheets/components/table.css
97
97
  - data/stylesheets/components/term.css
98
98
  - data/stylesheets/components/toc.css
99
+ - docs/html-renderer.adoc
99
100
  - lib/data/dist/iso_document/frontend/assets/index-mwzbzmnK.js
100
101
  - lib/data/dist/iso_document/frontend/assets/index-pGvKTNid.css
101
102
  - lib/data/dist/iso_document/frontend/assets/iso-red.svg
@@ -480,9 +481,15 @@ files:
480
481
  - lib/metanorma/html/component/footnote_collector.rb
481
482
  - lib/metanorma/html/component/index_section.rb
482
483
  - lib/metanorma/html/component/index_term_collector.rb
483
- - lib/metanorma/html/component_registry.rb
484
484
  - lib/metanorma/html/drops.rb
485
+ - lib/metanorma/html/drops/admonition_drop.rb
486
+ - lib/metanorma/html/drops/block_element_drop.rb
487
+ - lib/metanorma/html/drops/example_drop.rb
488
+ - lib/metanorma/html/drops/figure_drop.rb
485
489
  - lib/metanorma/html/drops/footnote_drop.rb
490
+ - lib/metanorma/html/drops/formula_drop.rb
491
+ - lib/metanorma/html/drops/note_drop.rb
492
+ - lib/metanorma/html/drops/sourcecode_drop.rb
486
493
  - lib/metanorma/html/generator.rb
487
494
  - lib/metanorma/html/icc_renderer.rb
488
495
  - lib/metanorma/html/iec_renderer.rb
@@ -496,13 +503,19 @@ files:
496
503
  - lib/metanorma/html/pdfa_renderer.rb
497
504
  - lib/metanorma/html/ribose_renderer.rb
498
505
  - lib/metanorma/html/standard_renderer.rb
506
+ - lib/metanorma/html/templates/_admonition.html.liquid
499
507
  - lib/metanorma/html/templates/_cover.html.liquid
500
508
  - lib/metanorma/html/templates/_doc_title.html.liquid
509
+ - lib/metanorma/html/templates/_example.html.liquid
510
+ - lib/metanorma/html/templates/_figure.html.liquid
501
511
  - lib/metanorma/html/templates/_footer.html.liquid
502
512
  - lib/metanorma/html/templates/_footnotes.html.liquid
513
+ - lib/metanorma/html/templates/_formula.html.liquid
503
514
  - lib/metanorma/html/templates/_header.html.liquid
504
515
  - lib/metanorma/html/templates/_iso_cover.html.liquid
505
516
  - lib/metanorma/html/templates/_iso_doc_title.html.liquid
517
+ - lib/metanorma/html/templates/_note.html.liquid
518
+ - lib/metanorma/html/templates/_sourcecode.html.liquid
506
519
  - lib/metanorma/html/templates/document.html.liquid
507
520
  - lib/metanorma/html/theme.rb
508
521
  - lib/metanorma/html/whitespace_patch.rb
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metanorma
4
- module Html
5
- class ComponentRegistry
6
- def initialize
7
- @map = {}
8
- end
9
-
10
- def register(model_class, component_class)
11
- @map[model_class] = component_class
12
- end
13
-
14
- def lookup(model_class)
15
- @map[model_class] ||
16
- model_class.ancestors
17
- .drop(1)
18
- .filter_map { |a| @map[a] }
19
- .first ||
20
- nil
21
- end
22
-
23
- def component_for(renderer, model_class)
24
- component_class = lookup(model_class)
25
- component_class&.new(renderer)
26
- end
27
-
28
- def register_all(component_module)
29
- component_module.constants.each do |const|
30
- klass = component_module.const_get(const)
31
- next unless klass.is_a?(Class) && klass < Component::Base
32
- klass.register_in(self)
33
- end
34
- end
35
- end
36
- end
37
- end