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.
Constant Summary collapse
- COMPLEX_RENDERERS =
Complex element handlers — these have per-instance attrs or multi-step rendering and bypass the shared Catalog.
{ Metanorma::Document::Components::Inline::StemInlineElement => ->(el) { for_stem(el) }, Metanorma::Document::Components::TextElements::StemElement => ->(el) { for_stem(el) }, Metanorma::Document::Components::Inline::XrefElement => ->(el) { for_xref(el) }, Metanorma::Document::Components::Inline::LinkElement => ->(el) { for_link(el) }, Metanorma::Document::Components::Inline::ErefElement => ->(el) { for_eref(el) }, Metanorma::Document::Components::Inline::FnElement => ->(el) { for_fn(el) }, Metanorma::Document::Components::Inline::SpanElement => ->(el) { for_span(el) }, Metanorma::Document::Components::Inline::BrElement => ->(_el) { wrap(&:br) }, }.freeze
Class Method Summary collapse
- .extract(element) ⇒ Object
- .for_eref(element) ⇒ Object
- .for_fn(element) ⇒ Object
- .for_link(element) ⇒ Object
- .for_span(element) ⇒ Object
- .for_stem(element) ⇒ Object
- .for_xref(element) ⇒ Object
- .raw(html_string) ⇒ Object
- .render_element(element) ⇒ Object
- .render_node(node) ⇒ Object
- .render_simple(mark_type, element) ⇒ Object
- .wrap ⇒ Object
Class Method Details
.extract(element) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 47 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
121 122 123 124 125 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 121 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
127 128 129 130 131 132 133 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 127 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 |
.for_link(element) ⇒ Object
114 115 116 117 118 119 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 114 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
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 135 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
93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 93 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
107 108 109 110 111 112 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 107 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
151 152 153 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 151 def self.raw(html_string) Nokogiri::HTML5::DocumentFragment.parse(html_string.to_s) end |
.render_element(element) ⇒ Object
71 72 73 74 75 76 77 78 79 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 71 def self.render_element(element) complex = COMPLEX_RENDERERS[element.class] return complex.call(element) if complex mark_type = Catalog::SIMPLE_ELEMENTS[element.class] return render_simple(mark_type, element) if mark_type extract(element) end |
.render_node(node) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 60 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
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 81 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
147 148 149 |
# File 'lib/metanorma/mirror/handlers/inline/rich_html_renderer.rb', line 147 def self.wrap(&) Nokogiri::HTML5::Builder.new(&).doc.root.to_html end |