asciidoctor-html 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
Binary file
Binary file
@@ -55,6 +55,7 @@ module Asciidoctor
55
55
  @author = ERB::Escape.html_escape opts[:author]
56
56
  @date = opts.include?(:date) ? Date.parse(opts[:date]) : Date.today
57
57
  @se_id = opts[:se_id]
58
+ @base_url = opts[:base_url]
58
59
  @chapname = opts[:chapname]
59
60
  @refs = {} # Hash(docname => Hash(id => reftext))
60
61
  @templates = {} # Hash(docname => TData)
@@ -81,11 +82,16 @@ module Asciidoctor
81
82
  # - chapters: array of filenames
82
83
  # - appendices: array of filenames
83
84
  # - outdir: directory to write the converted html files to
84
- def write(chapters, appendices, outdir)
85
+ def write(chapters, appendices, outdir, sitemap: false)
86
+ needs_sitemap = sitemap && @base_url
87
+ entries = [] # for sitemap
85
88
  read(chapters, appendices).each do |name, html|
86
- File.write("#{outdir}/#{name}.html", html)
89
+ filename = "#{name}.html"
90
+ File.write("#{outdir}/#{filename}", html)
91
+ entries << Template.sitemap_entry("#{@base_url}#{filename}") if needs_sitemap
87
92
  end
88
93
  File.write("#{outdir}/#{SEARCH_PAGE}", search_page(@se_id)) if @se_id
94
+ File.write("#{outdir}/sitemap.xml", Template.sitemap(entries)) if needs_sitemap
89
95
  end
90
96
 
91
97
  private
@@ -217,10 +223,10 @@ module Asciidoctor
217
223
  short_title: @short_title,
218
224
  author: @author,
219
225
  date: @date,
226
+ description: doc.attr("description"),
220
227
  chapnum: tdata.chapnum,
221
228
  chaptitle: tdata.chaptitle,
222
- langs: langs(doc),
223
- nav: (nav_items.size > 1)
229
+ langs: langs(doc)
224
230
  )
225
231
  end
226
232
  end
@@ -74,7 +74,7 @@ module Asciidoctor
74
74
 
75
75
  def self.generate_bookopts(config)
76
76
  book_opts = {}
77
- %i[title short_title author date se_id chapname].each do |opt|
77
+ %i[title short_title author date se_id base_url chapname].each do |opt|
78
78
  key = opt.to_s
79
79
  book_opts[opt] = config[key] if config.include?(key)
80
80
  end
@@ -91,7 +91,7 @@ module Asciidoctor
91
91
  generate_webmanifest outdir, book_opts[:title], book_opts[:short_title]
92
92
  book = Book.new book_opts
93
93
  puts "Writing book to #{outdir}"
94
- book.write config["chapters"], config["appendices"], config["outdir"]
94
+ book.write config["chapters"], config["appendices"], config["outdir"], sitemap: true
95
95
  return unless opts[:watch]
96
96
 
97
97
  Filewatcher.new("#{config["srcdir"]}/*.adoc").watch do |changes|
@@ -4,6 +4,7 @@ require "asciidoctor"
4
4
  require_relative "list"
5
5
  require_relative "utils"
6
6
  require_relative "figure"
7
+ require_relative "table"
7
8
 
8
9
  module Asciidoctor
9
10
  module Html
@@ -33,7 +34,8 @@ module Asciidoctor
33
34
  document = node.document
34
35
  level = node.level
35
36
  show_sectnum = node.numbered && level <= (document.attr("sectnumlevels") || 1).to_i
36
- tag_name = %(h#{[level + 2, 6].min})
37
+ tag_level = [level == 1 ? level + 1 : level + 2, 6].min
38
+ tag_name = %(h#{tag_level})
37
39
  sectnum = show_sectnum ? %(<span class="title-mark">#{node.sectnum ""}</span>) : ""
38
40
  content = %(<#{tag_name}>#{sectnum}#{node.title}</#{tag_name}>\n#{node.content})
39
41
  Utils.wrap_node content, node, :section
@@ -66,7 +68,8 @@ module Asciidoctor
66
68
  else "exclamation-lg"
67
69
  end
68
70
  icon = %(<div class="icon"><i class="bi bi-#{icon_class}"></i></div>)
69
- content = %(#{icon}\n#{Utils.display_title node, needs_prefix: false}#{node.content})
71
+ content = node.blocks? ? node.content : "<p>#{node.content}</p>"
72
+ content = %(#{icon}\n#{Utils.display_title node, needs_prefix: false}#{content})
70
73
  Utils.wrap_id_classes content, node.id, "admonition admonition-#{name}"
71
74
  end
72
75
 
@@ -129,6 +132,13 @@ module Asciidoctor
129
132
  Utils.wrap_node content, node
130
133
  end
131
134
 
135
+ def convert_literal(node)
136
+ nowrap = !(node.document.attr? "prewrap") || (node.option? "nowrap")
137
+ pre = %(<pre#{%( class="nowrap") if nowrap}>#{node.content}</pre>)
138
+ title = Utils.display_title(node, needs_prefix: false)
139
+ Utils.wrap_node "#{title}#{pre}", node
140
+ end
141
+
132
142
  def convert_open(node)
133
143
  collapsible = node.option? "collapsible"
134
144
  title = if collapsible
@@ -208,6 +218,34 @@ module Asciidoctor
208
218
  end
209
219
  super
210
220
  end
221
+
222
+ def convert_table(node)
223
+ classes = ["table", node.role].compact
224
+ classes << "table-striped" if node.option? "striped"
225
+ classes << "table-bordered" if node.option? "bordered"
226
+ classes << "table-sm" if node.option? "compact"
227
+ width_attribute = ""
228
+ if (autowidth = node.option? "autowidth") && !(node.attr? "width")
229
+ classes << "table-fit"
230
+ elsif (tablewidth = node.attr "width")
231
+ width_attribute = %( width="#{tablewidth}%")
232
+ end
233
+ result = [%(<table#{Utils.id_class_attr_str node.id, classes.join(" ")}#{width_attribute}>)]
234
+ result << %(<caption class="table-title">#{Utils.display_title_prefix node}#{node.title}</caption>)
235
+ if node.attr("rowcount").positive?
236
+ result << "<colgroup>"
237
+ if autowidth
238
+ result += (Array.new node.columns.size, %(<col>))
239
+ else
240
+ node.columns.each do |col|
241
+ result << (col.option?("autowidth") ? %(<col>) : %(<col style="width:#{col.attr "colpcwidth"}%;">))
242
+ end
243
+ end
244
+ result << "</colgroup>"
245
+ end
246
+ result << "#{Table.display_rows(node)}</table>"
247
+ Utils.wrap_id_classes result.join("\n"), nil, "table-responsive"
248
+ end
211
249
  end
212
250
  end
213
251
  end
@@ -29,9 +29,9 @@ module Asciidoctor
29
29
 
30
30
  def convert_figlist(node)
31
31
  result = node.items.map do |item|
32
- %(<li#{Utils.id_class_attr_str item.id}><figure>\n#{item.text}\n</figure></li>)
32
+ %(<li#{Utils.id_class_attr_str item.id, item.role}><figure>\n#{item.text}\n</figure></li>)
33
33
  end
34
- content = Utils.wrap_id_classes result.join("\n"), nil, "figlist loweralpha", :ol
34
+ content = Utils.wrap_id_classes result.join("\n"), nil, "figlist", :ol
35
35
  title = %(<div class="figlist-title">#{Utils.display_title_prefix(node)}#{node.title}</div>)
36
36
  classes = ["figlist-wrapper", node.role].compact.join(" ")
37
37
  Utils.wrap_id_classes %(#{content}#{title}), node.id, classes
@@ -88,7 +88,7 @@ module Asciidoctor
88
88
  if(text.match(rgx)) {
89
89
  text = text.replaceAll(rgx, "");
90
90
  el.innerHTML = el.innerHTML.replaceAll(rgx, (match) => {
91
- return '<i class="bi bi-' + (match.charCodeAt() - 9311) + '-circle"></i>';
91
+ return '<i class="hljs-comment bi bi-' + (match.charCodeAt() - 9311) + '-circle"></i>';
92
92
  });
93
93
  }
94
94
  }
@@ -91,15 +91,33 @@ module Asciidoctor
91
91
  end
92
92
 
93
93
  def ref_li_mark(mark, depth, style = nil)
94
- return "[#{mark}]" if style == "bibliography"
94
+ return mark.to_s unless style
95
95
 
96
- depth.even? ? mark.to_s : "(#{mark})"
96
+ case li_style depth, style
97
+ when "mark-square-brackets" then "[#{mark}]"
98
+ when "mark-round-brackets" then "(#{mark})"
99
+ else mark.to_s
100
+ end
101
+ end
102
+
103
+ def li_style(depth, list_style)
104
+ return "mark-square-brackets" if list_style == "bibliography"
105
+ return "mark-round-brackets" if list_style == "figlist"
106
+
107
+ case depth
108
+ when 1, 3 then "mark-round-brackets"
109
+ else "mark-dot"
110
+ end
97
111
  end
98
112
 
99
113
  def offset(list)
100
114
  list.attr?("start") ? (list.attr("start").to_i - 1) : 0
101
115
  end
102
116
 
117
+ def shift(list)
118
+ list.attr?("shift") ? list.attr("shift").to_i : 0
119
+ end
120
+
103
121
  # Finds an anchor at the start of item.text and updates
104
122
  # its reftext to that of item's if necessary.
105
123
  def register_reftext!(item, reftext)
@@ -121,11 +139,14 @@ module Asciidoctor
121
139
  block.set_attr("flat-style", true)
122
140
  else
123
141
  offset = offset block
142
+ shift = shift block
124
143
  style = block.style
144
+ d = (style == "figlist" ? 1 : depth) + shift
145
+ role = li_style d, style
125
146
  block.items.each_with_index do |item, idx|
126
- d = style == "figlist" ? 1 : depth
127
147
  mark = li_mark(d, idx + offset)
128
148
  item.set_attr "mark", mark
149
+ item.role = role
129
150
  item_reftext = "#{parent_reftext}#{ref_li_mark mark, d, style}"
130
151
  register_reftext! item, item_reftext
131
152
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module Html
5
+ # Helpers for the table conversion
6
+ module Table
7
+ def self.display_row(tsec, row)
8
+ result = ["<tr>"]
9
+ row.each do |cell|
10
+ cell_content = if tsec == :head
11
+ cell.text
12
+ elsif cell.style == :literal
13
+ "<pre>#{cell.text}</pre>"
14
+ else
15
+ cell.content.join "\n"
16
+ end
17
+ cell_tag_name = (tsec == :head || cell.style == :header ? %(th scope="col") : "td")
18
+ cell_class_attribute = %( class="halign-#{cell.attr "halign"} align-#{cell.attr "valign"}")
19
+ cell_colspan_attribute = cell.colspan ? %( colspan="#{cell.colspan}") : ""
20
+ cell_rowspan_attribute = cell.rowspan ? %( rowspan="#{cell.rowspan}") : ""
21
+ cell_attributes = "#{cell_class_attribute}#{cell_colspan_attribute}#{cell_rowspan_attribute}"
22
+ result << %(<#{cell_tag_name}#{cell_attributes}>#{cell_content}</#{cell_tag_name}>)
23
+ end
24
+ result << "</tr>"
25
+ result.join "\n"
26
+ end
27
+
28
+ def self.display_rows(node)
29
+ node.rows.to_h.map do |tsec, rows|
30
+ next if rows.empty?
31
+
32
+ "<t#{tsec}>\n#{rows.map { |row| display_row(tsec, row) }.join("\n")}\n</t#{tsec}>"
33
+ end.join("\n")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -40,7 +40,7 @@ module Asciidoctor
40
40
  <<~HTML
41
41
  <main class="main">
42
42
  <div class="content-container">
43
- <h2>#{nav_text chapnum, chaptitle}</h2>
43
+ <h1>#{nav_text chapnum, chaptitle}</h1>
44
44
  #{content}
45
45
  #{footer author, year}
46
46
  </div>
@@ -48,6 +48,24 @@ module Asciidoctor
48
48
  HTML
49
49
  end
50
50
 
51
+ def self.sitemap(entries)
52
+ <<~XML
53
+ <?xml version="1.0" encoding="UTF-8"?>
54
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
55
+
56
+ #{entries.join "\n"}
57
+ </urlset>
58
+ XML
59
+ end
60
+
61
+ def self.sitemap_entry(url)
62
+ <<~XML
63
+ <url>
64
+ <loc>#{url}</loc>
65
+ </url>
66
+ XML
67
+ end
68
+
51
69
  def self.header(title, short_title, nav: true)
52
70
  nav_btn = if nav
53
71
  <<~HTML
@@ -70,7 +88,14 @@ module Asciidoctor
70
88
  end
71
89
 
72
90
  def self.footer(author, year)
73
- %(<footer class="footer">&#169; #{year} #{author}</footer>\n)
91
+ <<~HTML
92
+ <footer class="footer">
93
+ <div class="footer-left">&#169; #{year} #{author}</div>
94
+ <div class="footer-right">Built with
95
+ <a href="https://github.com/ravirajani/asciidoctor-html">asciidoctor-html</a>
96
+ </div>
97
+ </footer>
98
+ HTML
74
99
  end
75
100
 
76
101
  def self.highlightjs(langs)
@@ -79,11 +104,13 @@ module Asciidoctor
79
104
  end.join("\n ")
80
105
  end
81
106
 
82
- def self.head(title, langs)
107
+ def self.head(title, description, author, langs)
83
108
  <<~HTML
84
109
  <head>
85
110
  <meta charset="utf-8">
86
111
  <meta name="viewport" content="width=device-width, initial-scale=1">
112
+ #{%(<meta name="description" content="#{description}">) if description}
113
+ #{%(<meta name="author" content="#{author}">) if author}
87
114
  <title>#{title}</title>
88
115
  <link rel="apple-touch-icon" sizes="180x180" href="#{FAVICON_PATH}/apple-touch-icon.png">
89
116
  <link rel="icon" type="image/png" sizes="32x32" href="#{FAVICON_PATH}/favicon-32x32.png">
@@ -102,13 +129,14 @@ module Asciidoctor
102
129
  # - title: String
103
130
  # - short_title: String
104
131
  # - author: String
132
+ # - description: String
105
133
  # - date: Date
106
- # - nav: Boolean
107
134
  # - chapnum: Int
108
135
  # - chaptitle: String
109
136
  # - langs: Array[String]
110
137
  def self.html(content, nav_items, opts = {})
111
- hash_listener = if opts[:nav]
138
+ nav = (nav_items.size > 1)
139
+ hash_listener = if nav
112
140
  <<~JS
113
141
  addEventListener('hashchange', function() {
114
142
  collapse = bootstrap.Collapse.getInstance('#sidebar');
@@ -121,10 +149,10 @@ module Asciidoctor
121
149
  <<~HTML
122
150
  <!DOCTYPE html>
123
151
  <html lang="en">
124
- #{head opts[:title], opts[:langs]}
152
+ #{head opts[:title], opts[:description], opts[:author], opts[:langs]}
125
153
  <body>
126
- #{header opts[:title], opts[:short_title], nav: opts[:nav]}
127
- #{sidebar(nav_items) if opts[:nav]}
154
+ #{header opts[:title], opts[:short_title], nav:}
155
+ #{sidebar(nav_items) if nav}
128
156
  #{main content, opts[:chapnum], opts[:chaptitle], opts[:author], opts[:date].year}
129
157
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"
130
158
  integrity="sha384-j1CDi7MgGQ12Z7Qab0qlWQ/Qqz24Gc6BM0thvEMVjHnfYGF0rmFCozFSxQBxwHKO"
@@ -48,12 +48,8 @@ module Asciidoctor
48
48
 
49
49
  def self.wrap_node(content, node, tag_name = :div)
50
50
  base_class = node.context
51
- mod = node.attr?("env") ? node.attr("env") : node.style
52
- mod_class = if mod && mod != base_class.to_s
53
- "#{base_class}-#{mod}"
54
- else
55
- ""
56
- end
51
+ mod = node.style
52
+ mod_class = "#{base_class}-#{mod}" if mod && mod != base_class.to_s
57
53
  classes = [base_class, mod_class, node.role].compact.map(&:to_s).uniq.join(" ").strip
58
54
  wrap_id_classes content, node.id, classes, tag_name
59
55
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-html
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravi Rajani
@@ -100,6 +100,7 @@ files:
100
100
  - lib/asciidoctor/html/list.rb
101
101
  - lib/asciidoctor/html/popovers.rb
102
102
  - lib/asciidoctor/html/ref_tree_processor.rb
103
+ - lib/asciidoctor/html/table.rb
103
104
  - lib/asciidoctor/html/template.rb
104
105
  - lib/asciidoctor/html/tree_walker.rb
105
106
  - lib/asciidoctor/html/utils.rb