asciidoctor-html 0.1.5 → 0.1.7

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.
@@ -5,45 +5,42 @@ module Asciidoctor
5
5
  # Configure the popovers for footnotes and citations.
6
6
  module Popovers
7
7
  POPOVERS = <<~JS
8
- function initPopovers() {
9
- document.querySelectorAll(".btn-po[data-contentid]").forEach(el => {
10
- const id = el.dataset.contentid;
11
- let content = document.getElementById(id);
12
- if(content) {
13
- if(content.tagName == "A") {
14
- // This is an anchor of a bibitem
15
- const listItem = content.parentElement.cloneNode(true)
16
- listItem.removeChild(listItem.firstChild)
17
- content = listItem
8
+ (function() {
9
+ const popovers = []
10
+ function initPopovers() {
11
+ document.querySelectorAll('.btn-po[data-contentid]').forEach(el => {
12
+ const id = el.dataset.contentid;
13
+ let content = document.getElementById(id);
14
+ if(content) {
15
+ if(content.tagName == 'A') {
16
+ // This is an anchor of a bibitem
17
+ const listItem = content.parentElement.cloneNode(true)
18
+ listItem.removeChild(listItem.firstChild)
19
+ content = listItem
20
+ }
21
+ popovers.push(new bootstrap.Popover(el, {
22
+ content: content,
23
+ html: true,
24
+ sanitize: false
25
+ }));
18
26
  }
19
- new bootstrap.Popover(el, {
20
- trigger: "focus",
21
- content: content,
22
- html: true,
23
- sanitize: false
24
- });
25
- }
26
- });
27
- }
28
- MathJax = {
29
- startup: {
30
- pageReady: function() {
31
- return MathJax.startup.defaultPageReady().then(initPopovers);
32
- }
27
+ });
33
28
  }
34
- };
35
- JS
36
-
37
- TOOLTIPS = <<~JS
38
- // Only enable tooltips on images if not a touch screen device
39
- if(!touch) {
40
- document.querySelectorAll('img[data-bs-toggle="tooltip"]').forEach(el => {
41
- bootstrap.Tooltip.getOrCreateInstance(el);
29
+ addEventListener('click', e => {
30
+ const match = e.target.closest('.btn-po[aria-describedby],.popover');
31
+ if(!match) {
32
+ popovers.forEach(po => po.hide());
33
+ }
34
+ })
35
+ MathJax.startup.promise.then(initPopovers);
36
+ addEventListener('load', function() {
37
+ // Enable tooltips on images
38
+ document.querySelectorAll('img[data-bs-toggle="tooltip"]').forEach(el => {
39
+ bootstrap.Tooltip.getOrCreateInstance(el);
40
+ });
42
41
  });
43
- }
42
+ })();
44
43
  JS
45
-
46
- INIT = "#{TOOLTIPS}\n#{POPOVERS}".freeze
47
44
  end
48
45
  end
49
46
  end
@@ -43,12 +43,14 @@ module Asciidoctor
43
43
  block.set_attr("showcaption", true) unless context == :stem
44
44
  assign_numeral! block, document, NUMBERED_CONTEXTS[context]
45
45
  relative_numeral = relative_numeral block, document
46
+
46
47
  reftext = if context == :stem
47
48
  "(#{relative_numeral})"
48
49
  else
49
50
  "#{env.capitalize} #{relative_numeral}"
50
51
  end
51
- block.set_attr "reftext", reftext
52
+ block.set_attr "reftext", reftext unless block.reftext?
53
+ block.set_attr "title-prefix", reftext
52
54
  end
53
55
 
54
56
  def env(context, style)
@@ -91,15 +93,33 @@ module Asciidoctor
91
93
  end
92
94
 
93
95
  def ref_li_mark(mark, depth, style = nil)
94
- return "[#{mark}]" if style == "bibliography"
96
+ return mark.to_s unless style
95
97
 
96
- depth.even? ? mark.to_s : "(#{mark})"
98
+ case li_style depth, style
99
+ when "mark-square-brackets" then "[#{mark}]"
100
+ when "mark-round-brackets" then "(#{mark})"
101
+ else mark.to_s
102
+ end
103
+ end
104
+
105
+ def li_style(depth, list_style)
106
+ return "mark-square-brackets" if list_style == "bibliography"
107
+ return "mark-round-brackets" if list_style == "figlist"
108
+
109
+ case depth
110
+ when 1, 3 then "mark-round-brackets"
111
+ else "mark-dot"
112
+ end
97
113
  end
98
114
 
99
115
  def offset(list)
100
116
  list.attr?("start") ? (list.attr("start").to_i - 1) : 0
101
117
  end
102
118
 
119
+ def shift(list)
120
+ list.attr?("shift") ? list.attr("shift").to_i : 0
121
+ end
122
+
103
123
  # Finds an anchor at the start of item.text and updates
104
124
  # its reftext to that of item's if necessary.
105
125
  def register_reftext!(item, reftext)
@@ -121,11 +141,14 @@ module Asciidoctor
121
141
  block.set_attr("flat-style", true)
122
142
  else
123
143
  offset = offset block
144
+ shift = shift block
124
145
  style = block.style
146
+ d = (style == "figlist" ? 1 : depth) + shift
147
+ role = li_style d, style
125
148
  block.items.each_with_index do |item, idx|
126
- d = style == "figlist" ? 1 : depth
127
149
  mark = li_mark(d, idx + offset)
128
150
  item.set_attr "mark", mark
151
+ item.role = role
129
152
  item_reftext = "#{parent_reftext}#{ref_li_mark mark, d, style}"
130
153
  register_reftext! item, item_reftext
131
154
  end
@@ -135,9 +158,10 @@ module Asciidoctor
135
158
  def process_colist!(block)
136
159
  block.set_attr "list-depth", 0
137
160
  block.items.each_with_index do |item, idx|
138
- icon = %(<i class="bi bi-#{idx + 1}-circle"></i>)
161
+ icon_type = "#{idx + 1}-circle"
162
+ icon = %(<i class="bi bi-#{icon_type}"></i>)
139
163
  item.set_attr "mark", icon
140
- register_reftext! item, icon
164
+ register_reftext! item, "bi:#{icon_type}[]"
141
165
  end
142
166
  end
143
167
 
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "asciidoctor"
4
+
5
+ module Asciidoctor
6
+ module Html
7
+ # Convert text to small caps
8
+ class ScInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
9
+ use_dsl
10
+
11
+ named :sc
12
+ name_positional_attributes "text"
13
+ format :short
14
+
15
+ def process(parent, target, _attrs)
16
+ create_inline_pass parent, "[.smallcaps]##{target}#",
17
+ attributes: { "subs" => :normal }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module Html
5
+ # Due to mobile dynamic viewport heights, we need custom code for
6
+ # reliable anchor scrolling.
7
+ module Scroll
8
+ SCROLL = <<~JS
9
+ (function() {
10
+ const page = document.getElementById('page');
11
+ function scrollToElement(e) {
12
+ e.preventDefault();
13
+ const href = location.hash;
14
+ const id = href.substring(1);
15
+ const target = document.getElementById(id);
16
+ if(!target) return;
17
+
18
+ const rect = target.getBoundingClientRect()
19
+ page.scrollTo({
20
+ top: rect.top + page.scrollTop,
21
+ left: 0,
22
+ behavior: 'smooth'
23
+ });
24
+ }
25
+ addEventListener('hashchange', scrollToElement);
26
+ })();
27
+ JS
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module Html
5
+ # Toggle behaviour of sidebar
6
+ module Sidebar
7
+ TOGGLE = <<~JS
8
+ (function() {
9
+ const page = document.getElementById('page');
10
+ const sidebar = document.getElementById('sidebar');
11
+ const dismissBtn = document.getElementById('sidebar-dismiss-btn');
12
+ function hideSidebar() {
13
+ sidebar && sidebar.classList.remove('shown');
14
+ page.classList.remove('noscroll');
15
+ }
16
+
17
+ // Sidebar should be hidden on any local link click
18
+ document.querySelectorAll('a[href^="#"]').forEach(el => {
19
+ el.addEventListener('click', hideSidebar);
20
+ });
21
+ addEventListener('resize', hideSidebar);
22
+ dismissBtn && dismissBtn.addEventListener('click', hideSidebar);
23
+
24
+ const menuBtn = document.getElementById('menu-btn');
25
+ if(!menuBtn) return;
26
+
27
+ // Nudge menuBtn in case there is a scrollbar
28
+ const main = document.getElementById('main');
29
+ const scrollbarWidth = page.offsetWidth - main.offsetWidth;
30
+ menuBtn.style.right = (scrollbarWidth + 12) + 'px';
31
+
32
+ // Add click listener to toggle sidebar
33
+ menuBtn.addEventListener('click', function() {
34
+ sidebar && sidebar.classList.toggle('shown');
35
+ if(scrollbarWidth > 0) page.classList.toggle('noscroll');
36
+ });
37
+ })();
38
+ JS
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,40 @@
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(node, 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" : "td")
18
+ cell_attrs = []
19
+ cell_attrs << %(halign-#{cell.attr "halign"}) unless node.attr?("halign")
20
+ cell_attrs << %(align-#{cell.attr "valign"}) unless node.attr?("valign")
21
+ cell_class_attribute = %( class="#{cell_attrs.join " "}") unless cell_attrs.empty?
22
+ cell_colspan_attribute = cell.colspan ? %( colspan="#{cell.colspan}") : ""
23
+ cell_rowspan_attribute = cell.rowspan ? %( rowspan="#{cell.rowspan}") : ""
24
+ cell_attributes = "#{cell_class_attribute}#{cell_colspan_attribute}#{cell_rowspan_attribute}"
25
+ result << %(<#{cell_tag_name}#{cell_attributes}>#{cell_content}</#{cell_tag_name}>)
26
+ end
27
+ result << "</tr>"
28
+ result.join "\n"
29
+ end
30
+
31
+ def self.display_rows(node)
32
+ node.rows.to_h.map do |tsec, rows|
33
+ next if rows.empty?
34
+
35
+ "<t#{tsec}>\n#{rows.map { |row| display_row(node, tsec, row) }.join("\n")}\n</t#{tsec}>"
36
+ end.join("\n")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -3,11 +3,20 @@
3
3
  require "date"
4
4
  require_relative "highlightjs"
5
5
  require_relative "popovers"
6
+ require_relative "sidebar"
7
+ require_relative "scroll"
6
8
 
7
9
  module Asciidoctor
8
10
  module Html
9
11
  # The template for the book layout
10
12
  module Template
13
+ MENU_BTN = <<~HTML
14
+ <button type="button" id="menu-btn" class="btn menu"
15
+ aria-expanded="false" aria-controls="sidebar">
16
+ <i class="bi bi-list"></i>
17
+ </button>
18
+ HTML
19
+
11
20
  def self.nav_item(target, text, content = "", active: false)
12
21
  active_class = active ? %( class="active") : ""
13
22
  link = %(<a href="#{target}">#{text}</a>)
@@ -15,10 +24,10 @@ module Asciidoctor
15
24
  %(<li#{active_class}>#{link}#{subnav}</li>\n)
16
25
  end
17
26
 
18
- def self.nav_text(chapnum, chaptitle)
19
- return chaptitle if chapnum.empty?
27
+ def self.nav_text(chapprefix, chaptitle)
28
+ return chaptitle if chapprefix.empty?
20
29
 
21
- %(<span class="title-mark">#{chapnum}</span>#{chaptitle})
30
+ %(<span class="title-mark">#{chapprefix}</span>#{chaptitle})
22
31
  end
23
32
 
24
33
  def self.appendix_title(chapname, numeral, doctitle, num_appendices)
@@ -28,62 +37,85 @@ module Asciidoctor
28
37
 
29
38
  def self.sidebar(nav_items)
30
39
  <<~HTML
31
- <div id="sidebar" class="sidebar collapse collapse-horizontal">
32
- <nav id="sidenav"><ul>
40
+ <div id="sidebar" class="sidebar">
41
+ <button id="sidebar-dismiss-btn" class="btn dismiss"><i class="bi bi-x-lg"></i></button>
42
+ <nav><ul>
33
43
  #{nav_items.join "\n"}
34
44
  </ul></nav>
35
45
  </div> <!-- .sidebar -->
36
46
  HTML
37
47
  end
38
48
 
39
- def self.main(content, chapnum, chaptitle, author, year)
49
+ # opts:
50
+ # - chapheading: String
51
+ # - chapsubheading: String
52
+ # - content: String
53
+ # - author: String
54
+ # - date: Date
55
+ def self.main(opts)
40
56
  <<~HTML
41
- <main class="main">
42
- <div class="content-container">
43
- <h2>#{nav_text chapnum, chaptitle}</h2>
44
- #{content}
45
- #{footer author, year}
57
+ <main id="main" class="main">
58
+ <div id="content-container" class="content-container">
59
+ #{%(<h1 class="chapheading">#{opts[:chapheading]}</h1>) if opts[:chapheading]}
60
+ <h1 class="chaptitle">#{opts[:chapsubheading]}</h1>
61
+ #{opts[:content]}
62
+ #{footer opts[:author], opts[:date].year}
46
63
  </div>
47
64
  </main>
48
65
  HTML
49
66
  end
50
67
 
51
- def self.header(title, short_title, nav: true)
52
- nav_btn = if nav
53
- <<~HTML
54
- <button type="button" class="btn menu"
55
- data-bs-toggle="collapse" data-bs-target="#sidebar"
56
- aria-expanded="false" aria-controls="sidebar">
57
- <i class="bi bi-list"></i>
58
- </button>
59
- HTML
60
- else
61
- ""
62
- end
68
+ def self.sitemap(entries)
69
+ <<~XML
70
+ <?xml version="1.0" encoding="UTF-8"?>
71
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
72
+
73
+ #{entries.join "\n"}
74
+ </urlset>
75
+ XML
76
+ end
77
+
78
+ def self.sitemap_entry(url)
79
+ <<~XML
80
+ <url>
81
+ <loc>#{url}</loc>
82
+ </url>
83
+ XML
84
+ end
85
+
86
+ def self.header(title, short_title)
63
87
  <<~HTML
64
88
  <header class="header">
65
89
  <a class="home d-none d-sm-block" href="./">#{title}</a>
66
90
  <a class="home d-block d-sm-none" href="./">#{short_title}</a>
67
- #{nav_btn}
68
91
  </header>
69
92
  HTML
70
93
  end
71
94
 
72
95
  def self.footer(author, year)
73
- %(<footer class="footer">&#169; #{year} #{author}</footer>\n)
96
+ <<~HTML
97
+ <footer class="footer">
98
+ <div class="footer-left">&#169; #{year} #{author}</div>
99
+ <div class="footer-right">Built with
100
+ <a href="https://github.com/ravirajani/asciidoctor-html">asciidoctor-html</a>
101
+ </div>
102
+ </footer>
103
+ HTML
74
104
  end
75
105
 
76
106
  def self.highlightjs(langs)
77
107
  langs.map do |lang|
78
- %(<script src="#{Highlightjs::CDN_PATH}/languages/#{lang}.min.js"></script>)
108
+ %(<script defer src="#{Highlightjs::CDN_PATH}/languages/#{lang}.min.js"></script>)
79
109
  end.join("\n ")
80
110
  end
81
111
 
82
- def self.head(title, langs)
112
+ def self.head(title, description, author, langs)
83
113
  <<~HTML
84
114
  <head>
85
115
  <meta charset="utf-8">
86
116
  <meta name="viewport" content="width=device-width, initial-scale=1">
117
+ #{%(<meta name="description" content="#{description}">) if description}
118
+ #{%(<meta name="author" content="#{author}">) if author}
87
119
  <title>#{title}</title>
88
120
  <link rel="apple-touch-icon" sizes="180x180" href="#{FAVICON_PATH}/apple-touch-icon.png">
89
121
  <link rel="icon" type="image/png" sizes="32x32" href="#{FAVICON_PATH}/favicon-32x32.png">
@@ -91,9 +123,19 @@ module Asciidoctor
91
123
  <link rel="manifest" href="#{FAVICON_PATH}/site.webmanifest">
92
124
  <link rel="stylesheet" href="#{CSS_PATH}/styles.css">
93
125
  <link rel="stylesheet" href="#{Highlightjs::CDN_PATH}/styles/tomorrow-night-blue.min.css">
94
- <script src="#{Highlightjs::CDN_PATH}/highlight.min.js"></script>
126
+ <script defer src="#{Highlightjs::CDN_PATH}/highlight.min.js"></script>
95
127
  #{highlightjs langs}
96
- <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
128
+ <script>
129
+ MathJax = {
130
+ tex: {
131
+ inlineMath: {'[+]': [['$', '$']]}
132
+ }
133
+ };
134
+ </script>
135
+ <script defer src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js"></script>
136
+ <script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"
137
+ integrity="sha384-j1CDi7MgGQ12Z7Qab0qlWQ/Qqz24Gc6BM0thvEMVjHnfYGF0rmFCozFSxQBxwHKO"
138
+ crossorigin="anonymous"></script>
97
139
  </head>
98
140
  HTML
99
141
  end
@@ -102,39 +144,30 @@ module Asciidoctor
102
144
  # - title: String
103
145
  # - short_title: String
104
146
  # - author: String
147
+ # - description: String
105
148
  # - date: Date
106
- # - nav: Boolean
107
- # - chapnum: Int
149
+ # - chapheading: String
108
150
  # - chaptitle: String
109
151
  # - langs: Array[String]
110
152
  def self.html(content, nav_items, opts = {})
111
- hash_listener = if opts[:nav]
112
- <<~JS
113
- addEventListener('hashchange', function() {
114
- collapse = bootstrap.Collapse.getInstance('#sidebar');
115
- if(collapse) collapse.hide();
116
- });
117
- JS
118
- else
119
- ""
120
- end
153
+ nav = (nav_items.size > 1)
121
154
  <<~HTML
122
155
  <!DOCTYPE html>
123
156
  <html lang="en">
124
- #{head opts[:title], opts[:langs]}
157
+ #{head opts[:title], opts[:description], opts[:author], opts[:langs]}
125
158
  <body>
126
- #{header opts[:title], opts[:short_title], nav: opts[:nav]}
127
- #{sidebar(nav_items) if opts[:nav]}
128
- #{main content, opts[:chapnum], opts[:chaptitle], opts[:author], opts[:date].year}
129
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"
130
- integrity="sha384-j1CDi7MgGQ12Z7Qab0qlWQ/Qqz24Gc6BM0thvEMVjHnfYGF0rmFCozFSxQBxwHKO"
131
- crossorigin="anonymous"></script>
132
- <script>
133
- const touch = matchMedia('(hover: none)').matches;
159
+ #{sidebar(nav_items) if nav}
160
+ <div id="page" class="page">
161
+ #{MENU_BTN if nav}
162
+ #{header opts[:title], opts[:short_title]}
163
+ #{main content:, **opts}
164
+ </div> <!-- .page -->
165
+ <script type="module">
134
166
  #{Highlightjs::PLUGIN}
135
167
  hljs.highlightAll();
136
- #{hash_listener}
137
168
  #{Popovers::POPOVERS}
169
+ #{Sidebar::TOGGLE if nav}
170
+ #{Scroll::SCROLL}
138
171
  </script>
139
172
  </body>
140
173
  </html>
@@ -31,14 +31,23 @@ module Asciidoctor
31
31
  node.attr?("showcaption") || node.title?
32
32
  end
33
33
 
34
- def self.display_title(node, needs_prefix: true)
35
- prefix = needs_prefix ? display_title_prefix(node) : ""
36
- show_title?(node) ? %(<h6 class="block-title">#{prefix}#{node.title}</h6>\n) : ""
34
+ def self.display_title(node)
35
+ prefix = display_title_prefix node
36
+ suffix = display_title_suffix node
37
+ show_title?(node) ? %(<h6 class="block-title">#{prefix}#{node.title}#{suffix}</h6>\n) : ""
38
+ end
39
+
40
+ def self.display_title_suffix(node)
41
+ return "" unless node.attr?("title-suffix")
42
+
43
+ suffix = node.attr "title-suffix"
44
+ %(<span class="title-suffix">#{node.apply_subs suffix}</span>)
37
45
  end
38
46
 
39
47
  def self.display_title_prefix(node)
40
- prefix = node.reftext? ? node.reftext : ""
41
- node.title? && !node.title.empty? ? %(<span class="title-prefix">#{prefix}</span>) : prefix
48
+ prefix = node.attr?("title-prefix") ? node.attr("title-prefix") : ""
49
+ prefix = %(<span class="title-prefix">#{prefix}</span>) if node.title? && !node.title.empty? && !prefix.empty?
50
+ prefix
42
51
  end
43
52
 
44
53
  def self.wrap_id_classes(content, id, classes, tag_name = :div)
@@ -48,22 +57,18 @@ module Asciidoctor
48
57
 
49
58
  def self.wrap_node(content, node, tag_name = :div)
50
59
  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
60
+ mod = node.style
61
+ mod_class = "#{base_class}-#{mod}" if mod && mod != base_class.to_s
57
62
  classes = [base_class, mod_class, node.role].compact.map(&:to_s).uniq.join(" ").strip
58
63
  wrap_id_classes content, node.id, classes, tag_name
59
64
  end
60
65
 
61
- def self.wrap_node_with_title(content, node, tag_name = :div, needs_prefix: false)
62
- show_title?(node) ? wrap_node(display_title(node, needs_prefix:) + content, node, tag_name) : content
66
+ def self.wrap_node_with_title(content, node, tag_name = :div)
67
+ show_title?(node) ? wrap_node(display_title(node) + content, node, tag_name) : content
63
68
  end
64
69
 
65
- def self.wrap_id_classes_with_title(content, node, id, classes, needs_prefix: false)
66
- show_title?(node) ? wrap_id_classes(display_title(node, needs_prefix:) + content, id, classes) : content
70
+ def self.wrap_id_classes_with_title(content, node, id, classes)
71
+ show_title?(node) ? wrap_id_classes(display_title(node) + content, id, classes) : content
67
72
  end
68
73
 
69
74
  def self.popover_button(content, content_id, classes = nil)
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.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravi Rajani
@@ -98,8 +98,13 @@ files:
98
98
  - lib/asciidoctor/html/figure.rb
99
99
  - lib/asciidoctor/html/highlightjs.rb
100
100
  - lib/asciidoctor/html/list.rb
101
+ - lib/asciidoctor/html/pagination.rb
101
102
  - lib/asciidoctor/html/popovers.rb
102
103
  - lib/asciidoctor/html/ref_tree_processor.rb
104
+ - lib/asciidoctor/html/sc_inline_macro.rb
105
+ - lib/asciidoctor/html/scroll.rb
106
+ - lib/asciidoctor/html/sidebar.rb
107
+ - lib/asciidoctor/html/table.rb
103
108
  - lib/asciidoctor/html/template.rb
104
109
  - lib/asciidoctor/html/tree_walker.rb
105
110
  - lib/asciidoctor/html/utils.rb