asciidoctor-html 1.1.13 → 2.0.0

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.
@@ -2,14 +2,14 @@
2
2
 
3
3
  require "pathname"
4
4
  require "erb"
5
- require "date"
6
5
  require "asciidoctor"
7
6
  require_relative "converter"
8
7
  require_relative "ref_tree_processor"
9
8
  require_relative "cref_inline_macro"
10
9
  require_relative "bi_inline_macro"
11
10
  require_relative "text_inline_macro"
12
- require_relative "template"
11
+ require_relative "subnav_block_macro"
12
+ require_relative "book_template"
13
13
  require_relative "pagination"
14
14
  require_relative "search"
15
15
  require_relative "utils"
@@ -26,6 +26,7 @@ module Asciidoctor
26
26
  inline_macro CrefInlineMacro
27
27
  inline_macro TextInlineMacro
28
28
  inline_macro BiInlineMacro
29
+ block_macro SubnavBlockMacro
29
30
  end
30
31
 
31
32
  DOCATTRS = {
@@ -35,7 +36,8 @@ module Asciidoctor
35
36
  "source-highlighter" => "highlight.js",
36
37
  "imagesdir" => IMG_PATH,
37
38
  "dollar" => "$",
38
- "parskip" => %(<span class="parskip"></span><br>)
39
+ "parskip" => %(<span class="parskip"></span><br>),
40
+ "notitle" => %(<span class="notitle">&nbsp;</span>)
39
41
  }.freeze
40
42
 
41
43
  DEFAULT_OPTS = {
@@ -96,10 +98,10 @@ module Asciidoctor
96
98
  filename = "#{name}.html"
97
99
  File.write("#{outdir}/#{filename}", html)
98
100
  build_index(name, html) unless omit_search?
99
- entries << Template.sitemap_entry("#{@base_url}#{filename}") if needs_sitemap
101
+ entries << BookTemplate.sitemap_entry("#{@base_url}#{filename}") if needs_sitemap
100
102
  end
101
103
  File.write "#{outdir}/#{SEARCH_PAGE}", search_page unless omit_search?
102
- File.write("#{outdir}/sitemap.xml", Template.sitemap(entries)) if needs_sitemap
104
+ File.write("#{outdir}/sitemap.xml", BookTemplate.sitemap(entries)) if needs_sitemap
103
105
  end
104
106
 
105
107
  private
@@ -147,7 +149,7 @@ module Asciidoctor
147
149
  chapref = num_appendices == 1 ? chapname : chapref_default(chapname, chapnum)
148
150
  tdata = TData.new(
149
151
  chapprefix: "",
150
- chaptitle: Template.appendix_title(chapname, chapnum, chapsubheading, num_appendices),
152
+ chaptitle: BookTemplate.appendix_title(chapname, chapnum, chapsubheading, num_appendices),
151
153
  chapheading: chapref,
152
154
  chapsubheading:,
153
155
  index:
@@ -201,17 +203,21 @@ module Asciidoctor
201
203
  end
202
204
 
203
205
  def outline(doc)
206
+ return doc.attr("outline") if doc.attr?("outline")
207
+
204
208
  items = []
205
209
  doc.sections.each do |section|
206
210
  next unless section.id && section.level == 1
207
211
 
208
212
  prefix = Utils.display_sectnum(section) if section.numbered
209
- items << Template.nav_item("##{section.id}", "#{prefix}#{section.title}")
213
+ items << BookTemplate.nav_item("##{section.id}", "#{prefix}#{section.title}")
210
214
  end
211
215
  return "" unless items.size > 1
212
216
 
213
217
  doc.set_attr("has-subnav", true)
214
- "<ul>#{items.join "\n"}</ul>"
218
+ outline = "<ul>#{items.join "\n"}</ul>"
219
+ doc.set_attr("outline", outline)
220
+ outline
215
221
  end
216
222
 
217
223
  def html(docs)
@@ -230,12 +236,12 @@ module Asciidoctor
230
236
  items = @templates.map do |k, td|
231
237
  active = (k == active_key)
232
238
  subnav = active && doc ? outline(doc) : ""
233
- navtext = Template.nav_text td.chapprefix, td.chaptitle
234
- Template.nav_item "#{k}.html", navtext, subnav, active:
239
+ navtext = BookTemplate.nav_text td.chapprefix, td.chaptitle
240
+ BookTemplate.nav_item "#{k}.html", navtext, subnav, active:
235
241
  end
236
242
  return items if omit_search?
237
243
 
238
- items.unshift(Template.nav_item(
244
+ items.unshift(BookTemplate.nav_item(
239
245
  SEARCH_PAGE,
240
246
  %(<i class="bi bi-search"></i> Search),
241
247
  active: (active_key == -1)
@@ -245,11 +251,13 @@ module Asciidoctor
245
251
  def build_template(key, doc)
246
252
  tdata = @templates[key]
247
253
  nav_items = nav_items key, doc
248
- content = "#{ERB.new(doc.convert).result(binding)}\n#{pagination key}"
249
- Template.html(
254
+ has_subnav = doc.attr?("has-subnav")
255
+ subnav = has_subnav ? outline(doc) : ""
256
+ content = ERB.new(doc.convert).result(binding)
257
+ BookTemplate.html(
250
258
  content,
251
259
  nav_items,
252
- has_subnav: doc.attr?("has-subnav"),
260
+ has_subnav:,
253
261
  title: @title,
254
262
  short_title: @short_title,
255
263
  authors: display_authors(doc),
@@ -258,7 +266,8 @@ module Asciidoctor
258
266
  chapheading: tdata.chapheading,
259
267
  chapsubheading: tdata.chapsubheading,
260
268
  langs: langs(doc),
261
- multipage: doc.attr("pagestyle") == "multi"
269
+ paginator: pagination(key),
270
+ pagestyle: doc.attr?("pagestyle") ? doc.attr("pagestyle").to_sym : :single
262
271
  )
263
272
  end
264
273
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "date"
4
3
  require_relative "highlightjs"
5
4
  require_relative "popovers"
6
5
  require_relative "sidebar"
@@ -10,7 +9,7 @@ require_relative "flip"
10
9
  module Asciidoctor
11
10
  module Html
12
11
  # The template for the book layout
13
- module Template
12
+ module BookTemplate
14
13
  MENU_BTN = <<~HTML
15
14
  <button type="button" id="menu-btn" class="btn menu"
16
15
  aria-expanded="false" aria-controls="sidebar">
@@ -47,11 +46,29 @@ module Asciidoctor
47
46
  HTML
48
47
  end
49
48
 
50
- def self.toggle_button(multipage)
51
- toggle_text = multipage ? "single page" : "multiple pages"
49
+ def self.toggle_button(pagestyle)
50
+ states = {
51
+ single: "single page view",
52
+ multi: "multipage view",
53
+ presentation: "presentation view (ESC to exit)"
54
+ }
55
+ alternate_states = states.map do |key, value|
56
+ <<~HTML
57
+ <li>
58
+ <a class="dropdown-item#{" active" if pagestyle == key}" href="#page" data-viewmode="#{key}">#{value}</a>
59
+ </li>
60
+ HTML
61
+ end
52
62
  <<~HTML
53
63
  <div class="layout-toggle">
54
- <label for="btn-layout">View as</label> <button id="btn-layout" type="button" class="btn btn-link">#{toggle_text}</button>
64
+ <div class="dropdown">
65
+ <button class="btn btn-link dropdown-toggle" id="btn-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
66
+ #{states[pagestyle]}
67
+ </button>
68
+ <ul id="viewmode-actions" class="dropdown-menu">
69
+ #{alternate_states.join "\n"}
70
+ </ul>
71
+ </div>
55
72
  </div>
56
73
  HTML
57
74
  end
@@ -78,20 +95,22 @@ module Asciidoctor
78
95
  # - has_subnav: Boolean
79
96
  # - authors: String
80
97
  # - date: Date
81
- # - multipage: Boolean|Null
98
+ # - pagestyle: Symbol
82
99
  def self.main(opts)
83
100
  <<~HTML
84
101
  <main id="main" class="main">
85
102
  <div id="content-container" class="content-container dynamic-width">
86
103
  #{chapheader opts[:chapheading], opts[:chapsubheading]}
87
104
  <div class="chaphead d-block">
88
- #{toggle_button opts[:multipage] if opts[:has_subnav]}
105
+ #{toggle_button opts[:pagestyle] if opts[:has_subnav]}
89
106
  #{chapheading opts[:chapheading]}
90
107
  <h1 class="chaptitle">#{opts[:chapsubheading]}</h1>
108
+ <p class="lead chapauthors#{%( d-block) if opts[:pagestyle] == :presentation}">#{opts[:authors]}</p>
91
109
  </div>
92
110
  #{opts[:content]}
93
- #{footer opts[:authors]}
94
111
  </div>
112
+ #{opts[:paginator]}
113
+ #{footer opts[:authors]}
95
114
  </main>
96
115
  HTML
97
116
  end
@@ -114,13 +133,17 @@ module Asciidoctor
114
133
  XML
115
134
  end
116
135
 
117
- def self.header(title, short_title, has_subnav)
136
+ def self.header(title, short_title, chapheading, has_subnav)
137
+ sublink = <<~HTML
138
+ <span id="header-chapheading" class="home-sublink"><a class="home" href="#page">#{chapheading}</a></span>
139
+ HTML
118
140
  <<~HTML
119
141
  <header class="header#{" with-margin" unless has_subnav}">
120
142
  <div class="dynamic-width">
121
143
  <div class="home-container">
122
144
  <a class="home d-none d-sm-block" href="./">#{title}</a>
123
145
  <a class="home d-block d-sm-none" href="./">#{short_title}</a>
146
+ #{sublink if chapheading}
124
147
  </div>
125
148
  </div>
126
149
  </header>
@@ -129,7 +152,7 @@ module Asciidoctor
129
152
 
130
153
  def self.footer(authors)
131
154
  <<~HTML
132
- <footer class="footer">
155
+ <footer class="footer dynamic-width">
133
156
  <div class="footer-left">&#169; <span id="cr-year"></span> #{authors}</div>
134
157
  <div class="footer-right">Built with
135
158
  <a href="https://github.com/ravirajani/asciidoctor-html">asciidoctor-html</a>
@@ -188,9 +211,14 @@ module Asciidoctor
188
211
  # - langs: Array[String]
189
212
  # - at_head_end: String
190
213
  # - at_body_end: String
191
- # - multipage: Boolean|Null
214
+ # - paginator: String
215
+ # - pagestyle: Symbol(single|multi|presentation)
192
216
  def self.html(content, nav_items, opts = {})
193
217
  nav = !nav_items.empty? && (nav_items.size > 1 || opts[:has_subnav])
218
+ page_classes = ["page"]
219
+ page_classes << "multi" unless opts[:pagestyle] == :single
220
+ page_classes << "presentation" if opts[:pagestyle] == :presentation
221
+ page_classname = page_classes.join " "
194
222
  <<~HTML
195
223
  <!DOCTYPE html>
196
224
  <html lang="en">
@@ -200,9 +228,9 @@ module Asciidoctor
200
228
  </head>
201
229
  <body>
202
230
  #{sidebar(nav_items) if nav}
203
- <div id="page" class="page#{" multi" if opts[:multipage]}">
231
+ <div id="page" class="#{page_classname}">
204
232
  #{MENU_BTN if nav}
205
- #{header opts[:title], opts[:short_title], opts[:has_subnav]}
233
+ #{header opts[:title], opts[:short_title], opts[:chapheading], opts[:has_subnav]}
206
234
  #{main content:, **opts}
207
235
  </div> <!-- .page -->
208
236
  <script>document.getElementById("cr-year").textContent = (new Date()).getFullYear();</script>
@@ -72,7 +72,8 @@ module Asciidoctor
72
72
  icon = %(<div class="icon"><i class="bi bi-#{icon_class}"></i></div>)
73
73
  content = node.blocks? ? node.content : "<p>#{node.content}</p>"
74
74
  content = %(#{icon}\n#{Utils.display_title node}#{content})
75
- Utils.wrap_id_classes content, node.id, "admonition admonition-#{name}"
75
+ classes = %(admonition admonition-#{name}#{" #{node.role}" if node.role})
76
+ Utils.wrap_id_classes content, node.id, classes
76
77
  end
77
78
 
78
79
  def convert_sidebar(node)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module Html
5
- # Flip when pagestyle=multipage
5
+ # Flip when pagestyle is multi or presentation
6
6
  module Flip
7
7
  FLIP = <<~JS
8
8
  (function() {
@@ -41,6 +41,10 @@ module Asciidoctor
41
41
  el.dataset.withSect = currentId;
42
42
  });
43
43
 
44
+ for(const sects of Object.values(sectsById)) {
45
+ sects[sects.length - 1].classList.add('last-section-multipage');
46
+ }
47
+
44
48
  function updatePaginator(prev, next) {
45
49
  const paginator = document.querySelector('.paginator');
46
50
  if(!paginator) return;
@@ -64,7 +68,8 @@ module Asciidoctor
64
68
  const prevH = prev.querySelector(':scope > h2');
65
69
  const prevSectitle = prevH && (prevH.innerHTML + ' ');
66
70
  const prevLink = document.createElement('a');
67
- let prevSectText = (prevSectitle || chapheading && chapheading.textContent + '<br>');
71
+ let prevSectText = prevSectitle || chapheading &&
72
+ ('<span class="title-prefix">' + chapheading.textContent + '</span><br>');
68
73
  if(!prevH) prevSectText += chaptitle.textContent;
69
74
  prevLink.href = '#' + (prev.id ? prev.id : 'page');
70
75
  prevLink.innerHTML = `
@@ -90,7 +95,9 @@ module Asciidoctor
90
95
 
91
96
  if(!target) id = 'page';
92
97
 
93
- document.querySelector('.breadcrumb').classList.toggle('d-block', id != 'page');
98
+ const isPresentation = page.classList.contains('presentation');
99
+ document.querySelector('.breadcrumb').classList.toggle('d-block', id != 'page' && !isPresentation);
100
+ document.querySelector('.chapauthors').classList.toggle('d-block', isPresentation);
94
101
 
95
102
  let section = target && target.closest(sectSelector);
96
103
  if(section) {
@@ -132,21 +139,61 @@ module Asciidoctor
132
139
  }
133
140
  }
134
141
  flip();
135
- addEventListener('hashchange', flip);
136
142
 
137
- const layoutButton = document.getElementById('btn-layout');
138
- layoutButton && layoutButton.addEventListener('click', function(){
139
- const multi = page.classList.contains('multi');
140
- layoutButton.textContent = (multi ? 'multiple pages' : 'single page');
141
- page.classList.toggle('multi');
142
- if(multi) {
143
- // We have switched to Single Page
143
+ const dropdownItems = document.querySelectorAll('#viewmode-actions .dropdown-item');
144
+ const dropdownToggle = document.getElementById('btn-toggle');
145
+ function changeViewmode(viewmode) {
146
+ page.classList.toggle('multi', viewmode == 'multi' || viewmode == 'presentation');
147
+ page.classList.toggle('presentation', viewmode == 'presentation');
148
+ if(viewmode == 'single') {
144
149
  ADHT.nudgeMenuBtn();
145
150
  updatePaginator();
146
151
  } else {
147
152
  flip();
148
153
  }
154
+ dropdownItems.forEach(el => {
155
+ const isActive = (el.dataset.viewmode == viewmode);
156
+ el.classList.toggle('active', isActive);
157
+ if(isActive) dropdownToggle.textContent = el.textContent;
158
+ });
159
+ }
160
+ function move(direction) {
161
+ const activeTopLevelLi = document.querySelector('#sidebar nav > ul > li.active');
162
+ if(!activeTopLevelLi) return;
163
+
164
+ const activeSubLi = activeTopLevelLi.querySelector('ul > li.active');
165
+ let href = '#page';
166
+ if(direction == 'left') {
167
+ const prevLi = activeSubLi && activeSubLi.previousElementSibling ||
168
+ !activeSubLi && activeTopLevelLi.previousElementSibling;
169
+ if(prevLi) href = prevLi.firstElementChild.href;
170
+ } else if(direction == 'right') {
171
+ const nextLi = !activeSubLi &&
172
+ (page.classList.contains('multi') && activeTopLevelLi.querySelector('ul > li') ||
173
+ activeTopLevelLi.nextElementSibling) ||
174
+ activeSubLi &&
175
+ (activeSubLi.nextElementSibling || activeTopLevelLi.nextElementSibling) ||
176
+ activeSubLi || activeTopLevelLi;
177
+ href = nextLi.firstElementChild.href;
178
+ }
179
+ navigation.navigate(href);
180
+ }
181
+ addEventListener('hashchange', flip);
182
+ addEventListener('keyup', function(e) {
183
+ switch(e.key) {
184
+ case 'ArrowLeft': move('left'); break;
185
+ case 'ArrowRight': move('right'); break;
186
+ case 'e':
187
+ case 'Escape':
188
+ page.classList.contains('presentation') && changeViewmode('multi');
189
+ }
149
190
  });
191
+
192
+ dropdownItems && dropdownItems.forEach(link => link.addEventListener('click', function(e){
193
+ e.preventDefault();
194
+ const viewmode = link.dataset.viewmode;
195
+ changeViewmode(viewmode);
196
+ }));
150
197
  })();
151
198
  JS
152
199
  end
@@ -10,7 +10,7 @@ module Asciidoctor
10
10
  def display_paginator(prv, nxt)
11
11
  blank = %(<span class="blank">&nbsp;</span>)
12
12
  html = [<<~HTML
13
- <div class="paginator-wrapper">
13
+ <div class="paginator-wrapper dynamic-width">
14
14
  <div class="paginator">
15
15
  HTML
16
16
  ]
@@ -18,7 +18,7 @@ module Asciidoctor
18
18
  <<~HTML
19
19
  <a href="#{prv.url}">
20
20
  <div><i class="bi bi-chevron-compact-left"></i></div>
21
- <div>#{"#{prv.title}<br>" if prv.title}#{prv.text}</div>
21
+ <div>#{%(<span class="title-prefix">#{prv.title}</span><br>) if prv.title}#{prv.text}</div>
22
22
  </a>
23
23
  HTML
24
24
  else
@@ -27,7 +27,7 @@ module Asciidoctor
27
27
  html << if nxt
28
28
  <<~HTML
29
29
  <a href="#{nxt.url}">
30
- <div>#{"#{nxt.title}<br>" if nxt.title}#{nxt.text}</div>
30
+ <div>#{%(<span class="title-prefix">#{nxt.title}</span><br>) if nxt.title}#{nxt.text}</div>
31
31
  <div><i class="bi bi-chevron-compact-right"></i></div>
32
32
  </a>
33
33
  HTML
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "nokogiri"
4
+ require_relative "book_template"
4
5
 
5
6
  module Asciidoctor
6
7
  module Html
@@ -26,7 +27,7 @@ module Asciidoctor
26
27
  <ul id="search-results" class="search-results list-group list-group-flush"></ul>
27
28
  </div>
28
29
  HTML
29
- Template.html(
30
+ BookTemplate.html(
30
31
  content,
31
32
  nav_items,
32
33
  title: @title,
@@ -8,15 +8,23 @@ module Asciidoctor
8
8
  ADHT.nudgeMenuBtn = function() {
9
9
  const menuBtn = document.getElementById('menu-btn');
10
10
  if(!menuBtn) return;
11
+
12
+ const isPresentation = page.classList.contains('presentation')
13
+ if(isPresentation) {
14
+ menuBtn.getAnimations().forEach(anim => anim.cancel());
15
+ return menuBtn;
16
+ }
17
+
18
+ const scrollbarWidth = page.offsetWidth - page.clientWidth;
19
+
11
20
  // Nudge menuBtn in case there is a scrollbar
12
- const main = document.getElementById('main');
13
- const scrollbarWidth = page.offsetWidth - main.offsetWidth;
14
21
  menuBtn.animate(
15
22
  { transform: 'translateX(' + (-scrollbarWidth) + 'px)' },
16
23
  { fill: 'forwards', duration: 150 }
17
24
  );
25
+
18
26
  // Cache scrollbar width
19
- ADHT.scrollbarWidth = scrollbarWidth
27
+ ADHT.scrollbarWidth = scrollbarWidth;
20
28
  return menuBtn;
21
29
  };
22
30
  (function() {
@@ -35,7 +43,7 @@ module Asciidoctor
35
43
  addEventListener('resize', hideSidebar);
36
44
  dismissBtn && dismissBtn.addEventListener('click', hideSidebar);
37
45
 
38
- const menuBtn = ADHT.nudgeMenuBtn()
46
+ const menuBtn = ADHT.nudgeMenuBtn();
39
47
  if(!menuBtn) return;
40
48
  // Add click listener to toggle sidebar
41
49
  menuBtn.addEventListener('click', function() {
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "asciidoctor"
4
+
5
+ module Asciidoctor
6
+ module Html
7
+ # Inserts a subnav for current chapter
8
+ class SubnavBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
9
+ use_dsl
10
+
11
+ named :subnav
12
+ name_positional_attributes "title"
13
+
14
+ def process(parent, _target, attrs)
15
+ title = %(<h5 class="block-title">#{attrs["title"]}</h5>) if attrs.include?("title")
16
+ bordered_class = " bordered" if attrs.include?("border")
17
+ border_width = attrs["border"].to_i if bordered_class
18
+ style = %( style="border-top-width: #{border_width}px; border-bottom-width: #{border_width}px;") if border_width
19
+ roles = attrs["role"] if attrs.include?("role")
20
+ roles = attrs["roles"] if attrs.include?("roles")
21
+ role = " #{roles.tr ",", " "}" if roles
22
+ content = <<~HTML
23
+ <div class="subnav#{bordered_class}#{role}"#{style}>
24
+ #{title}
25
+ <nav>
26
+ <%= subnav %>
27
+ </nav>
28
+ </div>
29
+ HTML
30
+ create_pass_block parent, content, attrs, subs: nil
31
+ end
32
+ end
33
+ end
34
+ end
@@ -11,6 +11,8 @@ module Asciidoctor
11
11
  cell.text
12
12
  elsif cell.style == :literal
13
13
  "<pre>#{cell.text}</pre>"
14
+ elsif cell.style == :asciidoc
15
+ cell.content
14
16
  else
15
17
  cell.content.join "\n"
16
18
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module Html
5
- VERSION = "1.1.13"
5
+ VERSION = "2.0.0"
6
6
  end
7
7
  end
@@ -55,7 +55,7 @@ module Minitest
55
55
  Pathname(TESTS_DIR).children.reject { |f| f.file? || f.basename.to_s.start_with?("_") }.sort.each do |pn|
56
56
  report_files results, pn
57
57
  end
58
- adoc = %(= Test Results\nRavi Rajani\n#{time}\n#{results.join "\n"})
58
+ adoc = %(= Test Results\n:pagestyle: multi\n\n#{time}\n\nsubnav::[border=1]\n\n#{results.join "\n"})
59
59
  File.write("#{DOCS_DIR}/tests.adoc", adoc)
60
60
  Asciidoctor::Html::CLI.run({ "config-file": CONFIG_FILE, watch: false })
61
61
  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: 1.1.13
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravi Rajani
@@ -106,6 +106,7 @@ files:
106
106
  - lib/asciidoctor/html.rb
107
107
  - lib/asciidoctor/html/bi_inline_macro.rb
108
108
  - lib/asciidoctor/html/book.rb
109
+ - lib/asciidoctor/html/book_template.rb
109
110
  - lib/asciidoctor/html/cli.rb
110
111
  - lib/asciidoctor/html/converter.rb
111
112
  - lib/asciidoctor/html/cref_inline_macro.rb
@@ -119,8 +120,8 @@ files:
119
120
  - lib/asciidoctor/html/scroll.rb
120
121
  - lib/asciidoctor/html/search.rb
121
122
  - lib/asciidoctor/html/sidebar.rb
123
+ - lib/asciidoctor/html/subnav_block_macro.rb
122
124
  - lib/asciidoctor/html/table.rb
123
- - lib/asciidoctor/html/template.rb
124
125
  - lib/asciidoctor/html/text_inline_macro.rb
125
126
  - lib/asciidoctor/html/tree_walker.rb
126
127
  - lib/asciidoctor/html/utils.rb