Module: Metanorma::Mirror::Handlers::Inline::RichHtmlRenderer

Defined in:
lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb

Overview

Renders inline Metanorma elements as HTML strings. Used when an HTML representation of inline content is required (e.g., attribute values, fallback rendering). All HTML construction goes through Nokogiri::HTML5::Builder to guarantee well-formed, escaped output.

Simple-wrap elements (em, strong, sub, sup, code, u, s, smallcap, bcp14, concept) take their tag-and-attrs mapping from the shared Inline::Catalog table.

Class Method Summary collapse

Class Method Details

.extract(element) ⇒ Object

Complex element handlers — these have per-instance attrs or multi-step rendering and bypass the shared Catalog.



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 21

def self.extract(element)
  return "" unless element

  unless element.is_a?(Lutaml::Model::Serializable)
    return CGI.escapeHTML(element.to_s)
  end

  parts = []
  element.each_mixed_content { |node| parts << render_node(node) }
  result = parts.join.strip
  result.empty? ? TextExtractor.extract_element_text(element) : result
end

.for_eref(element) ⇒ Object



95
96
97
98
99
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 95

def self.for_eref(element)
  citeas = SafeAttr.read(element, :citeas) || ""
  label = TextExtractor.extract_formatted_text(element)
  wrap { |d| d.a(class: "eref", cite: citeas) { d.text label } }
end

.for_fn(element) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 101

def self.for_fn(element)
  reference = SafeAttr.read(element, :reference) || ""
  spec = Catalog::SIMPLE_WRAPS["footnote"]
  wrap do |d|
    d.public_send(spec[:tag], spec.except(:tag)) { d.text reference }
  end
end


88
89
90
91
92
93
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 88

def self.for_link(element)
  href = SafeAttr.read(element,
                       :target) || SafeAttr.read(element, :href) || ""
  label = TextExtractor.extract_formatted_text(element)
  wrap { |d| d.a(href: href) { d.text label } }
end

.for_span(element) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 109

def self.for_span(element)
  cls = SafeAttr.read(element, :class_attr)
  inner = extract(element)
  wrap do |d|
    if cls
      d.span(class: cls) { d << raw(inner) }
    else
      d.span { d << raw(inner) }
    end
  end
end

.for_stem(element) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 67

def self.for_stem(element)
  math = SafeAttr.read(element, :math)
  return TextExtractor.extract_element_text(element) unless math

  mathml = MathUtil.mathml_from_math(math)
    .sub(/\s*xmlns(:\w+)?="[^"]*"\s*/, " ")
    .gsub(/\s+/, " ")
    .strip
  spec = Catalog::SIMPLE_WRAPS["stem"]
  wrap do |d|
    d.public_send(spec[:tag], spec.except(:tag)) { d << raw(mathml) }
  end
end

.for_xref(element) ⇒ Object



81
82
83
84
85
86
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 81

def self.for_xref(element)
  target = SafeAttr.read(element, :target) || ""
  label = TextExtractor.extract_formatted_text(element)
  label = target if label.strip.empty?
  wrap { |d| d.a(href: "##{target}") { d.text label } }
end

.raw(html_string) ⇒ Object



125
126
127
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 125

def self.raw(html_string)
  Nokogiri::HTML5::DocumentFragment.parse(html_string.to_s)
end

.render_element(element) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 45

def self.render_element(element)
  complex = Mirror.rich_html_renderers.lookup(element)
  return complex.call(element) if complex

  mark_type = Mirror.simple_inline_elements.lookup(element)
  return render_simple(mark_type, element) if mark_type

  extract(element)
end

.render_node(node) ⇒ Object



34
35
36
37
38
39
40
41
42
43
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 34

def self.render_node(node)
  case node
  when String
    CGI.escapeHTML(node)
  when Lutaml::Model::Serializable
    render_element(node)
  else
    ""
  end
end

.render_simple(mark_type, element) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 55

def self.render_simple(mark_type, element)
  spec = Catalog::SIMPLE_WRAPS[mark_type]
  attrs = spec.except(:tag)
  wrap do |d|
    if attrs.empty?
      d.public_send(spec[:tag]) { d << raw(extract(element)) }
    else
      d.public_send(spec[:tag], attrs) { d << raw(extract(element)) }
    end
  end
end

.wrap ⇒ Object



121
122
123
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 121

def self.wrap(&)
  Nokogiri::HTML5::Builder.new(&).doc.root.to_html
end