Class: Coradoc::Html::Converters::Admonition

Inherits:
Base
  • Object
show all
Defined in:
lib/coradoc/html/converters/admonition.rb

Overview

Converter for CoreModel::AnnotationBlock to HTML admonition block

Class Method Summary collapse

Methods inherited from Base

build_class_attribute, build_element, build_html_attributes, convert_content_to_html, convert_element_to_core, convert_node_to_core, escape_attribute, escape_html, extract_model_attributes, extract_node_attributes, extract_text_fallback, find_converter_class_by_name, find_converter_for_model, handle_unknown_content, render_core_abbreviation, render_core_annotation_block, render_core_bibliography, render_core_bibliography_entry, render_core_block, render_core_block_image, render_core_definition_item, render_core_definition_list, render_core_footnote, render_core_footnote_reference, render_core_inline_element, render_core_inline_image, render_core_list_block, render_core_list_item, render_core_span, render_core_structural_element, render_core_table_cell, render_core_table_row, render_core_term, render_core_toc, render_core_toc_entry, resolve_block_semantic_type, resolve_format_specific_semantic, transform_to_coremodel, treat_children

Class Method Details

.build_attributes(admonition, type) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/coradoc/html/converters/admonition.rb', line 69

def self.build_attributes(admonition, type)
  attrs = [%( class="admonition admonition-#{type.downcase}")]

  # Add ID if present
  attrs << %( id="#{escape_attribute(admonition.id)}") if admonition.id

  attrs.join
end

.build_label(type) ⇒ Object



78
79
80
# File 'lib/coradoc/html/converters/admonition.rb', line 78

def self.build_label(type)
  %(<div class="admonition-label">#{escape_html(type)}</div>)
end

.build_paragraph(items) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/coradoc/html/converters/admonition.rb', line 124

def self.build_paragraph(items)
  return nil if items.nil? || items.empty?

  # Convert all items to HTML and join them
  content_html = items.map do |item|
    case item
    when String
      escape_html(item)
    else
      convert_content_to_html(item)
    end
  end.join

  return nil if content_html.empty?

  "<p>#{content_html}</p>"
end

.build_title(admonition) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/coradoc/html/converters/admonition.rb', line 82

def self.build_title(admonition)
  return nil unless admonition.title

  title_text = admonition.title.to_s
  return nil if title_text.empty?

  %(<div class="admonition-title">#{escape_html(title_text)}</div>)
end

.convert_item(item) ⇒ Object



142
143
144
145
146
147
148
149
# File 'lib/coradoc/html/converters/admonition.rb', line 142

def self.convert_item(item)
  case item
  when String
    "<p>#{escape_html(item)}</p>"
  else
    convert_content_to_html(item)
  end
end

.extract_content(nodes) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/coradoc/html/converters/admonition.rb', line 162

def self.extract_content(nodes)
  # Extract and convert content nodes
  nodes.map do |node|
    if node.text? && !node.text.strip.empty?
      node.text.strip
    elsif node.element?
      case node.name
      when 'p'
        Paragraph.to_coradoc(node)
      else
        node.text.strip
      end
    end
  end.compact
end

.extract_type(element) ⇒ Object



151
152
153
154
155
156
157
158
159
160
# File 'lib/coradoc/html/converters/admonition.rb', line 151

def self.extract_type(element)
  return nil unless element['class']

  # Extract type from class like "admonition-note", "admonition-warning", etc.
  classes = element['class'].split
  type_class = classes.find { |c| c.start_with?('admonition-') && c != 'admonition' }
  return nil unless type_class

  type_class.sub(/^admonition-/, '').upcase
end

.process_content(content) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/coradoc/html/converters/admonition.rb', line 91

def self.process_content(content)
  return '' if content.nil?

  if content.is_a?(Array)
    # Group consecutive lines into paragraphs, handling inline elements
    result = []
    current_para = []

    content.each do |item|
      case item
      when String
        current_para << item
      else
        # End current paragraph and start a new one
        if current_para.any?
          result << build_paragraph(current_para)
          current_para = []
        end
        result << convert_item(item)
      end
    end

    # Don't forget the last paragraph
    result << build_paragraph(current_para) if current_para.any?

    result.compact.join("\n")
  elsif content.is_a?(String)
    "<p>#{escape_html(content)}</p>"
  else
    convert_item(content)
  end
end

.to_coradoc(element, _options = {}) ⇒ Object

Convert HTML admonition div to CoreModel::AnnotationBlock



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/coradoc/html/converters/admonition.rb', line 37

def self.to_coradoc(element, _options = {})
  return nil unless element.name == 'div'
  return nil unless element['class']&.include?('admonition')

  # Extract admonition type from class
  type = extract_type(element)
  return nil unless type

  # Extract title if present
  title_elem = element.at_css('.admonition-title')
  title = title_elem&.text&.strip

  # Extract content - all children except label and title
  content_nodes = element.children.reject do |node|
    node == element.at_css('.admonition-label') ||
      node == title_elem ||
      (node.text? && node.text.strip.empty?)
  end

  content = extract_content(content_nodes)

  # Extract ID if present
  id = element['id']

  Coradoc::CoreModel::AnnotationBlock.new(
    annotation_type: type.downcase,
    content: content,
    title: title,
    id: id
  )
end

.to_html(admonition, _options = {}) ⇒ Object

Convert CoreModel::AnnotationBlock to HTML admonition block



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/coradoc/html/converters/admonition.rb', line 9

def self.to_html(admonition, _options = {})
  return '' unless admonition

  # Get admonition type (NOTE, TIP, IMPORTANT, WARNING, CAUTION)
  type = admonition.annotation_type ? admonition.annotation_type.to_s.upcase : 'NOTE'

  # Build div attributes
  attrs = build_attributes(admonition, type)

  # Build title if present
  title_html = build_title(admonition)

  # Build admonition label
  label = build_label(type)

  # Process admonition content
  content = process_content(admonition.content)

  # Combine label, title, and content
  admonition_html = ''
  admonition_html += "#{label}\n"
  admonition_html += "#{title_html}\n" if title_html
  admonition_html += content

  %(<div#{attrs}>\n#{admonition_html}\n</div>)
end