Class: Asciidoctor::Html::Converter

Inherits:
Object
  • Object
show all
Includes:
Figure
Defined in:
lib/asciidoctor/html/converter.rb

Overview

A custom HTML5 converter that plays nicely with Bootstrap CSS

Instance Method Summary collapse

Methods included from Figure

#convert_figlist, #display_figure, #display_image, #image_attrs

Instance Method Details

#convert_admonition(node) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/asciidoctor/html/converter.rb', line 64

def convert_admonition(node)
  name = node.attr "name"
  icon_class = case name
               when "note" then "info-lg"
               when "tip" then "lightbulb"
               else "exclamation-lg"
               end
  icon = %(<div class="icon"><i class="bi bi-#{icon_class}"></i></div>)
  content = node.blocks? ? node.content : "<p>#{node.content}</p>"
  content = %(#{icon}\n#{Utils.display_title node}#{content})
  Utils.wrap_id_classes content, node.id, "admonition admonition-#{name}"
end

#convert_colist(node) ⇒ Object



182
183
184
# File 'lib/asciidoctor/html/converter.rb', line 182

def convert_colist(node)
  List.convert node
end

#convert_dlist(node) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/asciidoctor/html/converter.rb', line 190

def convert_dlist(node)
  classes = ["dlist", node.style, node.role].compact.join(" ")
  result = [%(<dl#{Utils.dyn_id_class_attr_str node, classes}>)]
  node.items.each do |terms, dd|
    terms.each do |dt|
      result << %(<dt>#{dt.text}</dt>)
    end
    next unless dd

    result << "<dd>"
    result << %(<p>#{dd.text}</p>) if dd.text?
    result << dd.content if dd.blocks?
    result << "</dd>"
  end
  result << "</dl>\n"
  Utils.wrap_id_classes_with_title result.join("\n"), node, node.id, "dlist-wrapper"
end

#convert_embedded(node) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/asciidoctor/html/converter.rb', line 17

def convert_embedded(node)
  result = [node.content]
  if node.footnotes?
    result << %(<div class="footnote-separator"></div><div class="footnotes">)
    node.footnotes.each do |fn|
      result << %(<div class="fn-row"><div class="fn-mark">#{fn.index}</div>)
      result << %(<div class="footnote" id="_footnotedef_#{fn.index}">#{fn.text}</div></div>)
    end
    result << %(</div>)
  end
  result.join("\n")
end

#convert_example(node) ⇒ Object



152
153
154
# File 'lib/asciidoctor/html/converter.rb', line 152

def convert_example(node)
  Utils.wrap_node_with_title node.content, node
end

#convert_image(node) ⇒ Object



156
157
158
159
# File 'lib/asciidoctor/html/converter.rb', line 156

def convert_image(node)
  content = display_figure node
  Utils.wrap_id_classes content, node.id, ["figbox", node.role].compact.join(" ")
end

#convert_inline_anchor(node) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/asciidoctor/html/converter.rb', line 208

def convert_inline_anchor(node)
  node_text = node.text
  if node.type == :xref
    target = node.document.catalog[:refs][node.attr("refid")]
    if target&.inline? && target.parent&.parent&.style == "bibliography"
      reftext = target.reftext
      if node_text
        /\A\[(?<numeral>\d+)\]\z/ =~ reftext
        reftext = if numeral
                    "[#{numeral}, #{node_text}]"
                  else
                    "#{reftext}, #{node_text}"
                  end
      end
      return Utils.popover_button(reftext, target.id, "bibref")
    end

    if !node_text && (text = target&.inline? ? target&.text : target&.attr("reftext"))
      subs = i[specialcharacters quotes replacements macros]
      return %(<a href="#{node.target}">#{node.apply_subs text, subs}</a>)
    end
  end
  super
end

#convert_inline_callout(node) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/asciidoctor/html/converter.rb', line 98

def convert_inline_callout(node)
  i = node.text.to_i
  case i
  when 1..20
    (i + 9311).chr(Encoding::UTF_8)
  when 21..50
    (i + 3230).chr(Encoding::UTF_8)
  else
    "[#{node.text}]"
  end
end

#convert_inline_footnote(node) ⇒ Object



110
111
112
113
114
115
116
# File 'lib/asciidoctor/html/converter.rb', line 110

def convert_inline_footnote(node)
  if (index = node.attr "index")
    %(<sup>#{Utils.popover_button index, "_footnotedef_#{index}", "fnref"}</sup>)
  else
    %(<sup class="text-danger">[??]</sup>)
  end
end

#convert_inline_image(node) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/asciidoctor/html/converter.rb', line 161

def convert_inline_image(node)
  target = node.target
  return read_svg_contents(node, target) if node.option?("inline")

  mark = node.parent.attr "mark"
  title_attr = node.attr? "title"
  if mark # The image is part of a figlist
    title = node.attr("title") if title_attr
    %(    #{display_image node, target}
    <figcaption><span class="li-mark">#{mark}</span>#{title}</figcaption>).gsub(/^      /, "")
  else
    display_image node, target, title_attr:
  end
end

#convert_listing(node) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/asciidoctor/html/converter.rb', line 118

def convert_listing(node)
  nowrap = (node.option? "nowrap") || !(node.document.attr? "prewrap")
  if node.style == "source"
    lang = node.attr "language"
    code_open = %(<code#{%( class="language-#{lang}") if lang}>)
    pre_open = %(<pre#{%( class="nowrap") if nowrap}>#{code_open})
    pre_close = "</code></pre>"
  else
    pre_open = %(<pre#{%( class="nowrap") if nowrap}>)
    pre_close = "</pre>"
  end
  title = Utils.display_title(node)
  content = title + pre_open + node.content + pre_close
  Utils.wrap_node content, node
end

#convert_literal(node) ⇒ Object



134
135
136
137
138
139
# File 'lib/asciidoctor/html/converter.rb', line 134

def convert_literal(node)
  nowrap = !(node.document.attr? "prewrap") || (node.option? "nowrap")
  pre = %(<pre#{%( class="nowrap") if nowrap}>#{node.content}</pre>)
  title = Utils.display_title(node)
  Utils.wrap_node "#{title}#{pre}", node
end

#convert_olist(node) ⇒ Object



176
177
178
179
180
# File 'lib/asciidoctor/html/converter.rb', line 176

def convert_olist(node)
  return convert_figlist(node) if node.style == "figlist"

  List.convert node
end

#convert_open(node) ⇒ Object



141
142
143
144
145
146
147
148
149
150
# File 'lib/asciidoctor/html/converter.rb', line 141

def convert_open(node)
  collapsible = node.option? "collapsible"
  title = if collapsible
            %(<summary>#{node.title || "Details"}</summary>\n)
          else
            Utils.display_title(node)
          end
  tag_name = collapsible ? :details : :div
  Utils.wrap_node(title + node.content, node, tag_name)
end

#convert_paragraph(node) ⇒ Object



45
46
47
48
# File 'lib/asciidoctor/html/converter.rb', line 45

def convert_paragraph(node)
  content = %(<p#{Utils.dyn_id_class_attr_str node, node.role}>#{node.content}</p>\n)
  Utils.wrap_node_with_title content, node
end

#convert_preamble(node) ⇒ Object



30
31
32
# File 'lib/asciidoctor/html/converter.rb', line 30

def convert_preamble(node)
  %(<div class="preamble">\n#{node.content}</div> <!-- .preamble -->\n)
end

#convert_quote(node) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/asciidoctor/html/converter.rb', line 50

def convert_quote(node)
  attribution = node.attr?("attribution") ? node.attr("attribution") : nil
  citetitle = node.attr?("citetitle") ? node.attr("citetitle") : nil
  classes = ["blockquote", node.role].compact.join(" ")
  cite_element = citetitle ? %(<cite>#{citetitle}</cite>) : ""
  attr_element = attribution ? %(<span class="attribution">#{attribution}</span>) : ""
  content = %(<blockquote#{Utils.dyn_id_class_attr_str node, classes}>\n#{node.content}\n</blockquote>)
  if attribution || citetitle
    caption = %(<figcaption class="blockquote-footer">\n#{attr_element}#{cite_element}\n</figcaption>)
    content = %(<figure>\n#{content}\n#{caption}\n</figure>\n)
  end
  Utils.wrap_node_with_title content, node
end

#convert_section(node) ⇒ Object



34
35
36
37
38
39
40
41
42
43
# File 'lib/asciidoctor/html/converter.rb', line 34

def convert_section(node)
  document = node.document
  level = node.level
  show_sectnum = node.numbered && level <= (document.attr("sectnumlevels") || 1).to_i
  tag_level = [level == 1 ? level + 1 : level + 2, 6].min
  tag_name = %(h#{tag_level})
  display_sectnum = Utils.display_sectnum(node, level) if show_sectnum
  content = %(<#{tag_name}>#{display_sectnum}#{node.title}</#{tag_name}>\n#{node.content})
  Utils.wrap_node content, node, :section
end

#convert_sidebar(node) ⇒ Object



77
78
79
80
81
82
# File 'lib/asciidoctor/html/converter.rb', line 77

def convert_sidebar(node)
  classes = ["aside", node.role].compact.join(" ")
  title = node.title? ? %(<h5 class="aside-title">#{node.title}</h5>\n) : ""
  content = "#{title}#{node.content}"
  %(<aside#{Utils.id_class_attr_str node.id, classes}>\n#{content}\n</aside>\n)
end

#convert_stem(node) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/asciidoctor/html/converter.rb', line 84

def convert_stem(node)
  open, close = BLOCK_MATH_DELIMITERS[node.style.to_sym]
  equation = node.content || ""
  equation = "#{open}#{equation}#{close}" unless (equation.start_with? open) && (equation.end_with? close)
  classes = ["stem", node.role].compact
  if node.option? "numbered"
    equation = %(<div class="equation">\n#{equation}\n</div> <!-- .equation -->)
    equation = %(#{equation}\n<div class="equation-number">#{node.reftext}</div>)
    classes << "stem-equation"
  end
  content = %(<div#{Utils.dyn_id_class_attr_str node, classes.join(" ")}>\n#{equation}\n</div>\n)
  Utils.wrap_id_classes_with_title content, node, node.id, "stem-wrapper"
end

#convert_table(node) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/asciidoctor/html/converter.rb', line 233

def convert_table(node)
  classes = ["table", node.role].compact
  classes << "table-striped" if node.option? "striped"
  classes << "table-bordered" if node.option? "bordered"
  classes << "table-sm" if node.option? "compact"
  classes << "align-#{node.attr "valign"}" if node.attr?("valign")
  classes << "table-h#{node.attr "halign"}" if node.attr?("halign")
  width_attribute = ""
  if (autowidth = node.option? "autowidth") && !(node.attr? "width")
    classes << "table-fit"
  elsif (tablewidth = node.attr "width")
    width_attribute = %( width="#{tablewidth}%")
  end
  result = [%(<table#{Utils.id_class_attr_str node.id, classes.join(" ")}#{width_attribute}>)]
  result << %(<caption class="table-title">#{Utils.display_title_prefix node}#{node.title}</caption>)
  if node.attr("rowcount").positive? && node.attr?("cols")
    result << "<colgroup>"
    if autowidth
      result += (Array.new node.columns.size, %(<col>))
    else
      node.columns.each do |col|
        result << (col.option?("autowidth") ? %(<col>) : %(<col style="width:#{col.attr "colpcwidth"}%;">))
      end
    end
    result << "</colgroup>"
  end
  result << "#{Table.display_rows(node)}</table>"
  Utils.wrap_id_classes result.join("\n"), nil, "table-responsive"
end

#convert_ulist(node) ⇒ Object



186
187
188
# File 'lib/asciidoctor/html/converter.rb', line 186

def convert_ulist(node)
  List.convert node, :ul
end