Class: Metanorma::Html::BaseRenderer

Inherits:
Object
  • Object
show all
Includes:
Concerns::MetadataExtraction, Concerns::PresentationValidation, Concerns::SvgProcessing, Concerns::TextExtraction, Concerns::TocRegistry
Defined in:
lib/metanorma/html/base_renderer.rb

Direct Known Subclasses

StandardRenderer

Defined Under Namespace

Classes: RendererContext

Constant Summary collapse

LOGO_DIR =
File.expand_path("../../../data/logos", __dir__)
SPAN_ROLE_CLASSES =
{
  "boldtitle" => "title-text",
  "nonboldtitle" => "subtitle-text",
  "citeapp" => "xref-app",
  "citefig" => "xref-fig",
  "citesec" => "xref-section",
  "citetbl" => "xref-table",
  "fmt-autonum-delim" => "number-delim",
  "fmt-caption-label" => "caption-label",
  "fmt-caption-delim" => "caption-delim",
  "fmt-element-name" => "element-label",
  "fmt-comma" => "comma",
  "fmt-conn" => "connector",
  "fmt-label-delim" => "label-delim",
  "fmt-obligation" => "obligation-text",
  "fmt-xref-container" => "xref-container",
  "fmt-xref-label" => "xref-label",
  "std_publisher" => "ref-publisher",
  "stdpublisher" => "ref-publisher-name",
  "stddocNumber" => "ref-doc-number",
  "stddocTitle" => "ref-title",
  "stddocPartNumber" => "ref-part-number",
  "stdyear" => "ref-year",
  "date" => "date",
  "smallcap" => "small-caps",
}.freeze
METANORMA_LOGO =
"metanorma-logo.svg"
TEMPLATE_CACHE =

--- Document Assembly ---

{}
TEMPLATE_CACHE_MUTEX =

rubocop:disable Style/MutableConstant

Mutex.new
TRANSPARENT_INLINE_WRAPPERS =

Transparent inline wrappers: element classes whose render semantics are "iterate mixed_content and render each child". Grouped here so adding a new transparent wrapper is one entry, not another register_inline_render line. Classes with a more specific handler register themselves above.

[
  Metanorma::Document::Components::Inline::FmtNameElement,
  Metanorma::Document::Components::Inline::FmtTitleElement,
  Metanorma::Document::Components::Inline::FmtXrefLabelElement,
  Metanorma::Document::Components::Inline::FmtFnLabelElement,
  Metanorma::Document::Components::Inline::FmtConceptElement,
  Metanorma::Document::Components::Inline::FmtAnnotationStartElement,
  Metanorma::Document::Components::Inline::FmtAnnotationEndElement,
  Metanorma::Document::Components::Inline::FmtAnnotationBodyElement,
  Metanorma::Document::Components::Inline::VariantTitleElement,
  Metanorma::Document::Components::Inline::LocalizedStringElement,
  Metanorma::Document::Components::Inline::TitleWithAnnotationElement,
  Metanorma::Document::Components::Inline::BiblioTagElement,
  Metanorma::Document::Components::Inline::NameWithIdElement,
  Metanorma::Document::Components::Inline::DisplayTextElement,
  Metanorma::Document::Components::Inline::FmtFootnoteContainerElement,
  Metanorma::Document::Components::Inline::FmtFnBodyElement,
  Metanorma::Document::Components::Inline::FmtPreferredElement,
  Metanorma::Document::Components::Inline::FmtDefinitionElement,
  Metanorma::Document::Components::Inline::FmtTermsourceElement,
  Metanorma::Document::Components::Inline::FmtAdmittedElement,
  Metanorma::Document::Components::Inline::FmtIdentifierElement,
  Metanorma::Document::Components::Inline::FmtSourcecodeElement,
].freeze
BLOCK_TYPES =
{
  Metanorma::Document::Components::Paragraphs::ParagraphBlock => true,
  Metanorma::Document::Components::Tables::TableBlock => true,
  Metanorma::Document::Components::Lists::UnorderedList => true,
  Metanorma::Document::Components::Lists::OrderedList => true,
  Metanorma::Document::Components::Lists::DefinitionList => true,
  Metanorma::Document::Components::AncillaryBlocks::FigureBlock => true,
  Metanorma::Document::Components::Blocks::NoteBlock => true,
  Metanorma::Document::Components::AncillaryBlocks::ExampleBlock => true,
  Metanorma::Document::Components::AncillaryBlocks::SourcecodeBlock => true,
  Metanorma::Document::Components::AncillaryBlocks::FormulaBlock => true,
  Metanorma::Document::Components::MultiParagraph::QuoteBlock => true,
  Metanorma::Document::Components::MultiParagraph::AdmonitionBlock => true,
  Metanorma::Document::Components::Sections::HierarchicalSection => true,
  Metanorma::Document::Components::Sections::BasicSection => true,
  Metanorma::Document::Components::Sections::ContentSection => true,
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Concerns::TocRegistry

#build_toc_html, #figure_entries, #register_figure_entry, #register_table_entry, #register_toc_entry, #toc_entries

Methods included from Concerns::TextExtraction

#extract_plain_text, #extract_text_value

Methods included from Concerns::SvgProcessing

#load_logo_svg

Methods included from Concerns::PresentationValidation

#check_presentation_markers, #validate_presentation_xml!

Methods included from Concerns::MetadataExtraction

#extract_display_title, #extract_primary_doc_id, #html_title, #language

Constructor Details

#initializeBaseRenderer

Returns a new instance of BaseRenderer.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/metanorma/html/base_renderer.rb', line 89

def initialize
  @toc_entries = []
  @figure_entries = []
  @table_entries = []
  @index_term_collector = Component::IndexTermCollector.new
  @footnote_collector = Component::FootnoteCollector.new
  @current_section_id = nil
  @current_section_number = nil

  @inline_renderer = Renderers::InlineRenderer.new(self)
  @block_renderer = Renderers::BlockRenderer.new(self)
  @section_renderer = Renderers::SectionRenderer.new(self)
  @pubid_renderer = Renderers::PubidRenderer.new(self)
end

Instance Attribute Details

#document=(value) ⇒ Object (writeonly)

Sets the attribute document

Parameters:

  • value

    the value to set the attribute document to.



134
135
136
# File 'lib/metanorma/html/base_renderer.rb', line 134

def document=(value)
  @document = value
end

#footnote_collectorObject (readonly)

Returns the value of attribute footnote_collector.



84
85
86
# File 'lib/metanorma/html/base_renderer.rb', line 84

def footnote_collector
  @footnote_collector
end

#index_term_collectorObject (readonly)

Returns the value of attribute index_term_collector.



84
85
86
# File 'lib/metanorma/html/base_renderer.rb', line 84

def index_term_collector
  @index_term_collector
end

#themeObject

--- Flavor configuration hooks ---



156
157
158
# File 'lib/metanorma/html/base_renderer.rb', line 156

def theme
  @theme ||= resolve_theme
end

Class Method Details

.inline_registryObject



75
76
77
# File 'lib/metanorma/html/base_renderer.rb', line 75

def inline_registry
  @inline_registry ||= {}
end

.register_inline_render(type_class, method_name) ⇒ Object



79
80
81
# File 'lib/metanorma/html/base_renderer.rb', line 79

def register_inline_render(type_class, method_name)
  inline_registry[type_class] = method_name
end

.register_render(type_class, method_name) ⇒ Object



71
72
73
# File 'lib/metanorma/html/base_renderer.rb', line 71

def register_render(type_class, method_name)
  render_registry[type_class] = method_name
end

.render_registryObject



67
68
69
# File 'lib/metanorma/html/base_renderer.rb', line 67

def render_registry
  @render_registry ||= {}
end

Instance Method Details

#alignment_style(alignment) ⇒ Object



798
799
800
801
802
# File 'lib/metanorma/html/base_renderer.rb', line 798

def alignment_style(alignment)
  return nil if alignment.nil? || alignment.to_s.empty?

  "text-align: #{alignment}"
end

#assemble_document(body) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/metanorma/html/base_renderer.rb', line 226

def assemble_document(body)
  toc_html = build_toc_html(@toc_entries)
  header = build_header
  footer = build_footer

  render_liquid("document.html.liquid", {
                  "lang" => language,
                  "title" => html_title,
                  "font_url" => flavor_font_url,
                  "styles" => build_styles,
                  "header" => header,
                  "toc" => toc_html,
                  "body" => body,
                  "footer" => footer,
                  "scripts" => build_scripts,
                })
end

#block_element?(obj) ⇒ Boolean

Returns:

  • (Boolean)


746
747
748
# File 'lib/metanorma/html/base_renderer.rb', line 746

def block_element?(obj)
  BLOCK_TYPES[obj.class] || BLOCK_TYPES.any? { |type, _| obj.is_a?(type) }
end


298
299
300
301
302
303
304
# File 'lib/metanorma/html/base_renderer.rb', line 298

def build_footer
   = load_logo_svg(METANORMA_LOGO, height: 20)
  render_liquid("_footer.html.liquid", {
                  "mn_logo" => ,
                  "generated_at" => Time.now.strftime("%Y-%m-%d %H:%M"),
                })
end

#build_headerObject

--- Header and Footer ---



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/metanorma/html/base_renderer.rb', line 246

def build_header
  doc_id = extract_primary_doc_id
  pub_logos = build_publisher_logos
  pub_name = flavor_publisher_name
  display_id = if pub_name && doc_id && !doc_id.start_with?(pub_name)
                 "#{pub_name} #{doc_id}"
               else
                 doc_id
               end

  render_liquid("_header.html.liquid", {
                  "publisher_logos" => pub_logos,
                  "doc_id" => display_id,
                  "doc_title" => header_title_text,
                })
end

#build_publisher_logosObject



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/metanorma/html/base_renderer.rb', line 268

def build_publisher_logos
  publishers = flavor_publishers(extract_primary_doc_id)
  logo_map = publisher_logo_map
  return "" if publishers.empty? && logo_map.empty?

  dark_logo_map = theme.logos_dark
  display_pubs = publishers.empty? ? logo_map.keys : publishers

  display_pubs.filter_map do |pub|
    filename = logo_map[pub]
    next unless filename

    svg = load_logo_svg(filename, height: 26)
    next unless svg

    light_span = "<span class=\"brand-logo brand-logo-light\" aria-label=\"#{pub} logo\">#{svg}</span>"

    dark_span = ""
    dark_filename = dark_logo_map[pub]
    if dark_filename
      dark_svg = load_logo_svg(dark_filename, height: 26)
      if dark_svg
        dark_span = "<span class=\"brand-logo brand-logo-dark\" aria-label=\"#{pub} logo\">#{dark_svg}</span>"
      end
    end

    "#{light_span}\n#{dark_span}"
  end.join("\n")
end

#build_scriptsObject

--- Scripts ---



308
309
310
311
312
# File 'lib/metanorma/html/base_renderer.rb', line 308

def build_scripts
  pipeline = AssetPipeline.new
  compiled = pipeline.compile_js(flavor_js: flavor_js_module)
  "<script>\n#{compiled}\n</script>"
end

#build_stylesObject



322
323
324
325
326
327
328
329
# File 'lib/metanorma/html/base_renderer.rb', line 322

def build_styles
  pipeline = AssetPipeline.new
  css = pipeline.compile_css(flavor_css: flavor_css_module)
  parts = [theme.to_css_root, css, theme.to_css_extras]
  custom_css_path = theme.theme_css_path
  parts << File.read(custom_css_path) if custom_css_path
  parts.join("\n")
end

#collect_index_term(element) ⇒ Object



765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
# File 'lib/metanorma/html/base_renderer.rb', line 765

def collect_index_term(element)
  primary = safe_attr(element, :primary)
  return unless primary && !primary.to_s.strip.empty?

  @index_term_collector.add(
    primary: primary.to_s.strip,
    secondary: safe_attr(element, :secondary)&.to_s&.strip,
    tertiary: safe_attr(element, :tertiary)&.to_s&.strip,
    target_id: @current_section_id,
    target_text: @current_section_number,
  )
rescue StandardError => e
  record_render_warning("index term dropped: #{e.class}: #{e.message}")
  nil
end

#collect_ordered_children(section) ⇒ Object



700
# File 'lib/metanorma/html/base_renderer.rb', line 700

def collect_ordered_children(section) = @section_renderer.collect_ordered_children(section)

#element_attrs(**attrs) ⇒ Object

--- Helper methods ---



714
715
716
717
718
719
720
721
722
# File 'lib/metanorma/html/base_renderer.rb', line 714

def element_attrs(**attrs)
  parts = []
  attrs.each do |k, v|
    next if v.nil? || v == false || (v.is_a?(String) && v.empty?)

    parts << %( #{k}="#{escape_html(v.to_s)}")
  end
  parts.join
end

#escape_html(text) ⇒ Object



813
814
815
# File 'lib/metanorma/html/base_renderer.rb', line 813

def escape_html(text)
  CGI.escapeHTML(text.to_s)
end

#extract_block_label(block, default) ⇒ Object



781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
# File 'lib/metanorma/html/base_renderer.rb', line 781

def extract_block_label(block, default)
  names = safe_attr(block, :name)
  if names && !names.empty?
    name = names.is_a?(Array) ? names.first : names
    text = extract_text_value(name)
    return text unless text.to_s.strip.empty?
  end

  autonum = safe_attr(block, :autonum)
  if autonum && !autonum.to_s.empty?
    number = autonum.to_s
    return "#{default} #{number}"
  end

  default
end

#extract_title_text(titles) ⇒ Object



804
805
806
807
808
809
810
811
# File 'lib/metanorma/html/base_renderer.rb', line 804

def extract_title_text(titles)
  return "" if titles.nil?
  return extract_text_value(titles).to_s unless titles.is_a?(Array)
  return "" if titles.empty?

  title = titles.first
  extract_text_value(title).to_s
end

#flavor_css_moduleObject



318
319
320
# File 'lib/metanorma/html/base_renderer.rb', line 318

def flavor_css_module
  nil
end

#flavor_font_urlObject



208
209
210
# File 'lib/metanorma/html/base_renderer.rb', line 208

def flavor_font_url
  theme.font_url
end

#flavor_js_moduleObject



314
315
316
# File 'lib/metanorma/html/base_renderer.rb', line 314

def flavor_js_module
  nil
end

#flavor_nameObject



182
183
184
185
186
# File 'lib/metanorma/html/base_renderer.rb', line 182

def flavor_name
  return nil unless defined?(@document) && @document

  Metanorma::Html::Generator.flavors.name_for(@document.class)
end

#flavor_publisher_nameObject



200
201
202
# File 'lib/metanorma/html/base_renderer.rb', line 200

def flavor_publisher_name
  theme.publisher_name
end

#flavor_publishers(_doc_id) ⇒ Object



196
197
198
# File 'lib/metanorma/html/base_renderer.rb', line 196

def flavor_publishers(_doc_id)
  theme.publishers
end

#generate_body(document) ⇒ Object

Renders only the document body content (no html/head/styles assembly) — for embedding classic-rendered content into a host page.



148
149
150
151
152
# File 'lib/metanorma/html/base_renderer.rb', line 148

def generate_body(document, **)
  @document = document
  validate_presentation_xml!
  render(@document) || ""
end

#generate_full_document(document, theme: nil) ⇒ Object



136
137
138
139
140
141
142
143
144
# File 'lib/metanorma/html/base_renderer.rb', line 136

def generate_full_document(document, theme: nil, **)
  @document = document
  @theme_override = theme
  validate_presentation_xml!

  body = render(@document) || ""

  assemble_document(body)
end

#header_title_textObject



263
264
265
266
# File 'lib/metanorma/html/base_renderer.rb', line 263

def header_title_text
  raw = html_title.to_s.split("").first.to_s
  raw.length > 60 ? "#{raw[0, 57]}..." : raw
end

#html_class_for_span(xml_class) ⇒ Object



742
743
744
# File 'lib/metanorma/html/base_renderer.rb', line 742

def html_class_for_span(xml_class)
  SPAN_ROLE_CLASSES[xml_class] || "span-#{xml_class}"
end

#is_title_element?(node, section) ⇒ Boolean

Returns:

  • (Boolean)


359
360
361
362
363
364
# File 'lib/metanorma/html/base_renderer.rb', line 359

def is_title_element?(node, section)
  title = safe_attr(section, :title)
  return false unless title

  node.equal?(title)
end

#load_theme_override(override) ⇒ Object

A theme override given to Generator.generate: a Theme instance, a path to a theme directory (theme.yaml with assets/, templates/ and custom.css alongside), or a path to a bare theme.yaml file. This is how an organization customizes the output without changing any code.



172
173
174
175
176
177
178
179
180
# File 'lib/metanorma/html/base_renderer.rb', line 172

def load_theme_override(override)
  return override if override.is_a?(Theme)

  if File.directory?(override)
    Theme.from_theme_dir(override)
  else
    Theme.from_file(override)
  end
end

#lookup_dispatch(type_class, registry_method) ⇒ Object



517
518
519
520
521
522
523
524
525
526
# File 'lib/metanorma/html/base_renderer.rb', line 517

def lookup_dispatch(type_class, registry_method)
  # Registry contents are fixed once renderer classes are loaded, so
  # the resolved method per (registry, node class) is memoized for
  # the lifetime of this renderer instance.
  cache = (@dispatch_cache ||= {})
  key = [registry_method, type_class]
  return cache[key] if cache.key?(key)

  cache[key] = resolve_dispatch(type_class, registry_method)
end

#parse_pubid(docidentifier_string) ⇒ Object

Pubid rendering delegation



709
# File 'lib/metanorma/html/base_renderer.rb', line 709

def parse_pubid(docidentifier_string) = @pubid_renderer.parse_pubid(docidentifier_string)

#pubid_moduleObject

Pubid module for the current document's flavor, or nil if the flavor has no Pubid support. Queries the shared FlavorRegistry.



190
191
192
193
194
# File 'lib/metanorma/html/base_renderer.rb', line 190

def pubid_module
  return nil unless defined?(@document) && @document

  Metanorma::Html::Generator.flavors.pubid_module_for(@document.class)
end

#pubid_to_html(identifier) ⇒ Object



710
# File 'lib/metanorma/html/base_renderer.rb', line 710

def pubid_to_html(identifier) = @pubid_renderer.pubid_to_html(identifier)

#publisher_logo_mapObject



204
205
206
# File 'lib/metanorma/html/base_renderer.rb', line 204

def publisher_logo_map
  theme.logos_light
end

#record_render_warning(message) ⇒ Object

Emit a render warning once per distinct message. Warnings mark content that was skipped or degraded rather than rendered.



347
348
349
350
351
352
353
# File 'lib/metanorma/html/base_renderer.rb', line 347

def record_render_warning(message)
  @render_warnings ||= {}
  return if @render_warnings.key?(message)

  @render_warnings[message] = true
  warn "metanorma-document: #{message}"
end

#render(node) ⇒ Object

--- Dispatch ---



333
334
335
336
337
338
339
340
341
342
343
# File 'lib/metanorma/html/base_renderer.rb', line 333

def render(node, **)
  return escape_html(node) if node.is_a?(String)

  method = lookup_dispatch(node.class, :render_registry)
  return public_send(method, node, **) if method

  record_render_warning(
    "no renderer registered for #{node.class} — content skipped",
  )
  ""
end

#render_admonition(admonition) ⇒ Object



660
661
662
663
# File 'lib/metanorma/html/base_renderer.rb', line 660

def render_admonition(admonition,
**)
  @block_renderer.render_admonition(admonition, **)
end

#render_asciimath(el) ⇒ Object



584
# File 'lib/metanorma/html/base_renderer.rb', line 584

def render_asciimath(el) = @inline_renderer.render_asciimath(el)

#render_audio(audio) ⇒ Object



635
# File 'lib/metanorma/html/base_renderer.rb', line 635

def render_audio(audio) = @block_renderer.render_audio(audio)

#render_basic_section(section) ⇒ Object

Section rendering delegation



680
681
682
683
# File 'lib/metanorma/html/base_renderer.rb', line 680

def render_basic_section(section,
**)
  @section_renderer.render_basic_section(section, **)
end

#render_block_children(model, children:) ⇒ Object



670
671
672
673
# File 'lib/metanorma/html/base_renderer.rb', line 670

def render_block_children(model,
children:)
  @block_renderer.render_block_children(model, children: children)
end

#render_block_inline_content(el) ⇒ Object

Block-dispatch entry point for inline content reached as a direct child of a block container (render passes keyword args; the inline pipeline does not accept them).



546
547
548
# File 'lib/metanorma/html/base_renderer.rb', line 546

def render_block_inline_content(el, **)
  render_mixed_inline(el)
end

#render_bookmark(bookmark) ⇒ Object



665
666
667
668
# File 'lib/metanorma/html/base_renderer.rb', line 665

def render_bookmark(bookmark,
**)
  @block_renderer.render_bookmark(bookmark, **)
end

#render_brObject



574
# File 'lib/metanorma/html/base_renderer.rb', line 574

def render_br(*) = @inline_renderer.render_br

#render_cell_content(cell) ⇒ Object



565
# File 'lib/metanorma/html/base_renderer.rb', line 565

def render_cell_content(cell) = @inline_renderer.render_cell_content(cell)

#render_commaObject



581
# File 'lib/metanorma/html/base_renderer.rb', line 581

def render_comma(*) = @inline_renderer.render_comma

#render_concept(concept) ⇒ Object



598
# File 'lib/metanorma/html/base_renderer.rb', line 598

def render_concept(concept) = @inline_renderer.render_concept(concept)

#render_content_section(section) ⇒ Object



690
691
692
693
# File 'lib/metanorma/html/base_renderer.rb', line 690

def render_content_section(section,
**)
  @section_renderer.render_content_section(section, **)
end

#render_definition_list(dl) ⇒ Object



623
624
625
626
# File 'lib/metanorma/html/base_renderer.rb', line 623

def render_definition_list(dl,
**)
  @block_renderer.render_definition_list(dl, **)
end

#render_em(el) ⇒ Object



566
# File 'lib/metanorma/html/base_renderer.rb', line 566

def render_em(el) = @inline_renderer.render_em(el)

#render_eref(eref) ⇒ Object



596
# File 'lib/metanorma/html/base_renderer.rb', line 596

def render_eref(eref) = @inline_renderer.render_eref(eref)

#render_example(example) ⇒ Object



638
639
640
641
# File 'lib/metanorma/html/base_renderer.rb', line 638

def render_example(example,
**)
  @block_renderer.render_example(example, **)
end

#render_figure(figure) ⇒ Object



628
629
630
631
# File 'lib/metanorma/html/base_renderer.rb', line 628

def render_figure(figure,
**)
  @block_renderer.render_figure(figure, **)
end

#render_fmt_stem(fmt_stem) ⇒ Object



599
# File 'lib/metanorma/html/base_renderer.rb', line 599

def render_fmt_stem(fmt_stem) = @inline_renderer.render_fmt_stem(fmt_stem)

#render_fmt_xref(el) ⇒ Object



580
# File 'lib/metanorma/html/base_renderer.rb', line 580

def render_fmt_xref(el) = @inline_renderer.render_fmt_xref(el)

#render_fn(fn) ⇒ Object



597
# File 'lib/metanorma/html/base_renderer.rb', line 597

def render_fn(fn) = @inline_renderer.render_fn(fn)

#render_fn_inline(el) ⇒ Object



577
# File 'lib/metanorma/html/base_renderer.rb', line 577

def render_fn_inline(el) = @inline_renderer.render_fn_inline(el)

#render_footnotes_sectionObject



817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
# File 'lib/metanorma/html/base_renderer.rb', line 817

def render_footnotes_section
  return nil if @footnote_collector.empty?

  drops = @footnote_collector.to_a.map do |entry|
    content_html = ""
    if entry.content && !entry.content.empty?
      content_html = Array(entry.content).filter_map do |p|
        render_paragraph(p)
      end.join
    end
    Drops::FootnoteDrop.new(entry, content_html)
  end

  render_liquid("_footnotes.html.liquid",
                { "footnotes" => drops })
end

#render_form(form) ⇒ Object



643
# File 'lib/metanorma/html/base_renderer.rb', line 643

def render_form(form, **) = @block_renderer.render_form(form, **)

#render_formula(formula) ⇒ Object



650
651
652
653
# File 'lib/metanorma/html/base_renderer.rb', line 650

def render_formula(formula,
**)
  @block_renderer.render_formula(formula, **)
end

#render_full_block_children(model) ⇒ Object



677
# File 'lib/metanorma/html/base_renderer.rb', line 677

def render_full_block_children(model) = @block_renderer.render_full_block_children(model)

#render_hierarchical_section(section) ⇒ Object



685
686
687
688
# File 'lib/metanorma/html/base_renderer.rb', line 685

def render_hierarchical_section(section,
**)
  @section_renderer.render_hierarchical_section(section, **)
end

#render_image(image) ⇒ Object



633
# File 'lib/metanorma/html/base_renderer.rb', line 633

def render_image(image) = @block_renderer.render_image(image)

#render_index(el) ⇒ Object



585
# File 'lib/metanorma/html/base_renderer.rb', line 585

def render_index(el) = @inline_renderer.render_index(el)

#render_inline_element(element) ⇒ Object



355
356
357
# File 'lib/metanorma/html/base_renderer.rb', line 355

def render_inline_element(element, **)
  @inline_renderer.render_inline_element(element)
end

#render_input(el) ⇒ Object



582
# File 'lib/metanorma/html/base_renderer.rb', line 582

def render_input(el) = @inline_renderer.render_input(el)


594
# File 'lib/metanorma/html/base_renderer.rb', line 594

def render_link(link) = @inline_renderer.render_link(link)

#render_liquid(template_name, assigns) ⇒ Object



217
218
219
220
221
222
223
224
# File 'lib/metanorma/html/base_renderer.rb', line 217

def render_liquid(template_name, assigns)
  template_path = theme.resolve_template(template_name)
  template = TEMPLATE_CACHE_MUTEX.synchronize do
    TEMPLATE_CACHE[template_path] ||= Liquid::Template.parse(File.read(template_path))
  end
  assigns = assigns.transform_keys(&:to_s) if assigns.is_a?(Hash)
  template.render(assigns)
end

#render_math(el) ⇒ Object



583
# File 'lib/metanorma/html/base_renderer.rb', line 583

def render_math(el) = @inline_renderer.render_math(el)

#render_mixed_content_in_order(node) ⇒ Object



600
# File 'lib/metanorma/html/base_renderer.rb', line 600

def render_mixed_content_in_order(node, **) = @inline_renderer.render_mixed_content_in_order(node, **)

#render_mixed_inline(node) ⇒ Object



561
562
563
# File 'lib/metanorma/html/base_renderer.rb', line 561

def render_mixed_inline(node)
  @inline_renderer.render_mixed_inline(node)
end

#render_noopObject



539
540
541
# File 'lib/metanorma/html/base_renderer.rb', line 539

def render_noop(*)
  ""
end

#render_noop_inlineObject



550
551
552
# File 'lib/metanorma/html/base_renderer.rb', line 550

def render_noop_inline(*)
  nil
end

#render_note(note) ⇒ Object



636
# File 'lib/metanorma/html/base_renderer.rb', line 636

def render_note(note, **) = @block_renderer.render_note(note, **)

#render_note_children(model) ⇒ Object



675
# File 'lib/metanorma/html/base_renderer.rb', line 675

def render_note_children(model) = @block_renderer.render_note_children(model)

#render_note_inline(el) ⇒ Object



586
# File 'lib/metanorma/html/base_renderer.rb', line 586

def render_note_inline(el) = @inline_renderer.render_note_inline(el)

#render_ordered_content(section, level = 1) ⇒ Object



695
696
697
698
# File 'lib/metanorma/html/base_renderer.rb', line 695

def render_ordered_content(section,
level = 1)
  @section_renderer.render_ordered_content(section, level)
end

#render_ordered_list(ol) ⇒ Object



618
619
620
621
# File 'lib/metanorma/html/base_renderer.rb', line 618

def render_ordered_list(ol,
**)
  @block_renderer.render_ordered_list(ol, **)
end

#render_paragraph(p) ⇒ Object

Block rendering delegation



603
604
605
606
# File 'lib/metanorma/html/base_renderer.rb', line 603

def render_paragraph(p,
**)
  @block_renderer.render_paragraph(p, **)
end

#render_preface(preface) ⇒ Object



703
704
705
706
# File 'lib/metanorma/html/base_renderer.rb', line 703

def render_preface(preface,
**)
  @section_renderer.render_preface(preface, **)
end

#render_quote(quote) ⇒ Object



655
656
657
658
# File 'lib/metanorma/html/base_renderer.rb', line 655

def render_quote(quote,
**)
  @block_renderer.render_quote(quote, **)
end

#render_semx_content(el) ⇒ Object



588
589
590
591
# File 'lib/metanorma/html/base_renderer.rb', line 588

def render_semx_content(el,
**)
  @inline_renderer.render_semx_content(el, **)
end

#render_semx_inline(el) ⇒ Object



579
# File 'lib/metanorma/html/base_renderer.rb', line 579

def render_semx_inline(el) = @inline_renderer.render_semx_inline(el)

#render_simple_children(model) ⇒ Object



676
# File 'lib/metanorma/html/base_renderer.rb', line 676

def render_simple_children(model) = @block_renderer.render_simple_children(model)

#render_small_caps(el) ⇒ Object



571
# File 'lib/metanorma/html/base_renderer.rb', line 571

def render_small_caps(el) = @inline_renderer.render_small_caps(el)

#render_sourcecode(sc) ⇒ Object



645
646
647
648
# File 'lib/metanorma/html/base_renderer.rb', line 645

def render_sourcecode(sc,
**)
  @block_renderer.render_sourcecode(sc, **)
end

#render_span(el) ⇒ Object



576
# File 'lib/metanorma/html/base_renderer.rb', line 576

def render_span(el) = @inline_renderer.render_span(el)

#render_stem(el) ⇒ Object



578
# File 'lib/metanorma/html/base_renderer.rb', line 578

def render_stem(el) = @inline_renderer.render_stem(el)

#render_stem_content(stem) ⇒ Object



593
# File 'lib/metanorma/html/base_renderer.rb', line 593

def render_stem_content(stem) = @inline_renderer.render_stem_content(stem)

#render_strike(el) ⇒ Object



573
# File 'lib/metanorma/html/base_renderer.rb', line 573

def render_strike(el) = @inline_renderer.render_strike(el)

#render_strong(el) ⇒ Object



567
# File 'lib/metanorma/html/base_renderer.rb', line 567

def render_strong(el) = @inline_renderer.render_strong(el)

#render_sub(el) ⇒ Object



569
# File 'lib/metanorma/html/base_renderer.rb', line 569

def render_sub(el) = @inline_renderer.render_sub(el)

#render_sup(el) ⇒ Object



570
# File 'lib/metanorma/html/base_renderer.rb', line 570

def render_sup(el) = @inline_renderer.render_sup(el)

#render_tabObject



575
# File 'lib/metanorma/html/base_renderer.rb', line 575

def render_tab(*) = @inline_renderer.render_tab

#render_table(table) ⇒ Object



608
609
610
611
# File 'lib/metanorma/html/base_renderer.rb', line 608

def render_table(table,
**)
  @block_renderer.render_table(table, **)
end

#render_tt(el) ⇒ Object



568
# File 'lib/metanorma/html/base_renderer.rb', line 568

def render_tt(el) = @inline_renderer.render_tt(el)

#render_underline(el) ⇒ Object



572
# File 'lib/metanorma/html/base_renderer.rb', line 572

def render_underline(el) = @inline_renderer.render_underline(el)

#render_unordered_list(ul) ⇒ Object



613
614
615
616
# File 'lib/metanorma/html/base_renderer.rb', line 613

def render_unordered_list(ul,
**)
  @block_renderer.render_unordered_list(ul, **)
end

#render_video(video) ⇒ Object



634
# File 'lib/metanorma/html/base_renderer.rb', line 634

def render_video(video) = @block_renderer.render_video(video)

#render_xref(xref) ⇒ Object



595
# File 'lib/metanorma/html/base_renderer.rb', line 595

def render_xref(xref) = @inline_renderer.render_xref(xref)

#renderer_contextObject



130
131
132
# File 'lib/metanorma/html/base_renderer.rb', line 130

def renderer_context
  @renderer_context ||= RendererContext.new(self)
end

#resolve_dispatch(type_class, registry_method) ⇒ Object



528
529
530
531
532
533
534
535
536
537
# File 'lib/metanorma/html/base_renderer.rb', line 528

def resolve_dispatch(type_class, registry_method)
  self.class.ancestors.each do |ancestor|
    next unless ancestor.is_a?(Class) && (ancestor == BaseRenderer || ancestor < BaseRenderer)

    registry = ancestor.public_send(registry_method)
    method_name = registry[type_class]
    return method_name if method_name
  end
  nil
end

#resolve_themeObject



160
161
162
163
164
165
# File 'lib/metanorma/html/base_renderer.rb', line 160

def resolve_theme
  return load_theme_override(@theme_override) if @theme_override

  flavor = flavor_name
  flavor ? Theme.load(flavor) : Theme.new
end

#safe_attr(obj, method_name) ⇒ Object



750
751
752
753
754
755
756
757
758
759
760
761
762
763
# File 'lib/metanorma/html/base_renderer.rb', line 750

def safe_attr(obj, method_name)
  if obj.is_a?(Lutaml::Model::Serializable) && !obj.class.attributes.key?(method_name)
    return nil
  end

  obj.public_send(method_name)
rescue NoMethodError => e
  # Only swallow "method missing on this object" (duck-typing across
  # model classes). A NoMethodError raised *inside* the getter is a
  # real bug — let it surface.
  raise unless e.receiver.equal?(obj)

  nil
end

#sort_by_displayorder(children) ⇒ Object



701
# File 'lib/metanorma/html/base_renderer.rb', line 701

def sort_by_displayorder(children) = @section_renderer.sort_by_displayorder(children)

#walk_ordered(node, allow_filter: nil) ⇒ Object

Inline rendering delegation



557
558
559
# File 'lib/metanorma/html/base_renderer.rb', line 557

def walk_ordered(node, allow_filter: nil, &)
  @inline_renderer.walk_ordered(node, allow_filter: allow_filter, &)
end