asciidoctor-html 1.1.13 → 2.0.1
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +9 -0
- data/assets/css/styles.css +2 -2
- data/lib/asciidoctor/html/book.rb +24 -15
- data/lib/asciidoctor/html/{template.rb → book_template.rb} +42 -14
- data/lib/asciidoctor/html/converter.rb +2 -1
- data/lib/asciidoctor/html/flip.rb +72 -12
- data/lib/asciidoctor/html/pagination.rb +3 -3
- data/lib/asciidoctor/html/search.rb +2 -1
- data/lib/asciidoctor/html/sidebar.rb +12 -4
- data/lib/asciidoctor/html/subnav_block_macro.rb +34 -0
- data/lib/asciidoctor/html/table.rb +2 -0
- data/lib/asciidoctor/html/version.rb +1 -1
- data/lib/minitest/html_plugin.rb +1 -1
- metadata +3 -2
|
@@ -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 "
|
|
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"> </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 <<
|
|
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",
|
|
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:
|
|
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 <<
|
|
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 =
|
|
234
|
-
|
|
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(
|
|
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
|
-
|
|
249
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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(
|
|
51
|
-
|
|
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
|
-
<
|
|
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
|
-
# -
|
|
98
|
+
# - pagestyle: Symbol
|
|
82
99
|
def self.main(opts)
|
|
83
100
|
<<~HTML
|
|
84
101
|
<main id="main" class="main">
|
|
85
|
-
<div id="content-container" class="content-container dynamic-width">
|
|
102
|
+
<div id="content-container" class="content-container dynamic-width" tabindex="0">
|
|
86
103
|
#{chapheader opts[:chapheading], opts[:chapsubheading]}
|
|
87
104
|
<div class="chaphead d-block">
|
|
88
|
-
#{toggle_button opts[:
|
|
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">© <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
|
-
# -
|
|
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="
|
|
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
|
-
|
|
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
|
|
5
|
+
# Flip when pagestyle is multi or presentation
|
|
6
6
|
module Flip
|
|
7
7
|
FLIP = <<~JS
|
|
8
8
|
(function() {
|
|
@@ -17,6 +17,8 @@ module Asciidoctor
|
|
|
17
17
|
const sectsById = { "page": []};
|
|
18
18
|
|
|
19
19
|
const page = document.getElementById('page');
|
|
20
|
+
const focusEl = document.getElementById('content-container');
|
|
21
|
+
const searchForm = document.getElementById('search-form');
|
|
20
22
|
const chapheading = page.querySelector('.chapheading');
|
|
21
23
|
const chaptitle = page.querySelector('.chaptitle');
|
|
22
24
|
|
|
@@ -41,6 +43,16 @@ module Asciidoctor
|
|
|
41
43
|
el.dataset.withSect = currentId;
|
|
42
44
|
});
|
|
43
45
|
|
|
46
|
+
for(const sects of Object.values(sectsById)) {
|
|
47
|
+
sects[sects.length - 1].classList.add('last-section-multipage');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function focusOnLoad() {
|
|
51
|
+
if(searchForm) return;
|
|
52
|
+
|
|
53
|
+
focusEl.focus({preventScroll: true});
|
|
54
|
+
}
|
|
55
|
+
|
|
44
56
|
function updatePaginator(prev, next) {
|
|
45
57
|
const paginator = document.querySelector('.paginator');
|
|
46
58
|
if(!paginator) return;
|
|
@@ -64,7 +76,8 @@ module Asciidoctor
|
|
|
64
76
|
const prevH = prev.querySelector(':scope > h2');
|
|
65
77
|
const prevSectitle = prevH && (prevH.innerHTML + ' ');
|
|
66
78
|
const prevLink = document.createElement('a');
|
|
67
|
-
let prevSectText =
|
|
79
|
+
let prevSectText = prevSectitle || chapheading &&
|
|
80
|
+
('<span class="title-prefix">' + chapheading.textContent + '</span><br>');
|
|
68
81
|
if(!prevH) prevSectText += chaptitle.textContent;
|
|
69
82
|
prevLink.href = '#' + (prev.id ? prev.id : 'page');
|
|
70
83
|
prevLink.innerHTML = `
|
|
@@ -80,7 +93,10 @@ module Asciidoctor
|
|
|
80
93
|
}
|
|
81
94
|
|
|
82
95
|
function flip(e) {
|
|
83
|
-
if(!page.classList.contains('multi'))
|
|
96
|
+
if(!page.classList.contains('multi')) {
|
|
97
|
+
focusOnLoad();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
84
100
|
|
|
85
101
|
e && e.preventDefault();
|
|
86
102
|
|
|
@@ -90,7 +106,9 @@ module Asciidoctor
|
|
|
90
106
|
|
|
91
107
|
if(!target) id = 'page';
|
|
92
108
|
|
|
93
|
-
|
|
109
|
+
const isPresentation = page.classList.contains('presentation');
|
|
110
|
+
document.querySelector('.breadcrumb').classList.toggle('d-block', id != 'page' && !isPresentation);
|
|
111
|
+
document.querySelector('.chapauthors').classList.toggle('d-block', isPresentation);
|
|
94
112
|
|
|
95
113
|
let section = target && target.closest(sectSelector);
|
|
96
114
|
if(section) {
|
|
@@ -130,23 +148,65 @@ module Asciidoctor
|
|
|
130
148
|
left: 0
|
|
131
149
|
});
|
|
132
150
|
}
|
|
151
|
+
|
|
152
|
+
focusOnLoad();
|
|
133
153
|
}
|
|
134
154
|
flip();
|
|
135
|
-
addEventListener('hashchange', flip);
|
|
136
155
|
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
page.classList.toggle('
|
|
142
|
-
if(
|
|
143
|
-
// We have switched to Single Page
|
|
156
|
+
const dropdownItems = document.querySelectorAll('#viewmode-actions .dropdown-item');
|
|
157
|
+
const dropdownToggle = document.getElementById('btn-toggle');
|
|
158
|
+
function changeViewmode(viewmode) {
|
|
159
|
+
page.classList.toggle('multi', viewmode == 'multi' || viewmode == 'presentation');
|
|
160
|
+
page.classList.toggle('presentation', viewmode == 'presentation');
|
|
161
|
+
if(viewmode == 'single') {
|
|
144
162
|
ADHT.nudgeMenuBtn();
|
|
145
163
|
updatePaginator();
|
|
146
164
|
} else {
|
|
147
165
|
flip();
|
|
148
166
|
}
|
|
167
|
+
dropdownItems.forEach(el => {
|
|
168
|
+
const isActive = (el.dataset.viewmode == viewmode);
|
|
169
|
+
el.classList.toggle('active', isActive);
|
|
170
|
+
if(isActive) dropdownToggle.textContent = el.textContent;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function move(direction) {
|
|
174
|
+
const activeTopLevelLi = document.querySelector('#sidebar nav > ul > li.active');
|
|
175
|
+
if(!activeTopLevelLi) return;
|
|
176
|
+
|
|
177
|
+
const activeSubLi = activeTopLevelLi.querySelector('ul > li.active');
|
|
178
|
+
let href = '#page';
|
|
179
|
+
if(direction == 'left') {
|
|
180
|
+
const prevLi = activeSubLi && activeSubLi.previousElementSibling ||
|
|
181
|
+
!activeSubLi && activeTopLevelLi.previousElementSibling;
|
|
182
|
+
if(prevLi) href = prevLi.firstElementChild.href;
|
|
183
|
+
} else if(direction == 'right') {
|
|
184
|
+
const nextLi = !activeSubLi &&
|
|
185
|
+
(page.classList.contains('multi') && activeTopLevelLi.querySelector('ul > li') ||
|
|
186
|
+
activeTopLevelLi.nextElementSibling) ||
|
|
187
|
+
activeSubLi &&
|
|
188
|
+
(activeSubLi.nextElementSibling || activeTopLevelLi.nextElementSibling) ||
|
|
189
|
+
activeSubLi || activeTopLevelLi;
|
|
190
|
+
href = nextLi.firstElementChild.href;
|
|
191
|
+
}
|
|
192
|
+
navigation.navigate(href);
|
|
193
|
+
}
|
|
194
|
+
addEventListener('hashchange', flip);
|
|
195
|
+
addEventListener('keyup', function(e) {
|
|
196
|
+
switch(e.key) {
|
|
197
|
+
case 'ArrowLeft': move('left'); break;
|
|
198
|
+
case 'ArrowRight': move('right'); break;
|
|
199
|
+
case 'e':
|
|
200
|
+
case 'Escape':
|
|
201
|
+
page.classList.contains('presentation') && changeViewmode('multi');
|
|
202
|
+
}
|
|
149
203
|
});
|
|
204
|
+
|
|
205
|
+
dropdownItems && dropdownItems.forEach(link => link.addEventListener('click', function(e){
|
|
206
|
+
e.preventDefault();
|
|
207
|
+
const viewmode = link.dataset.viewmode;
|
|
208
|
+
changeViewmode(viewmode);
|
|
209
|
+
}));
|
|
150
210
|
})();
|
|
151
211
|
JS
|
|
152
212
|
end
|
|
@@ -10,7 +10,7 @@ module Asciidoctor
|
|
|
10
10
|
def display_paginator(prv, nxt)
|
|
11
11
|
blank = %(<span class="blank"> </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>#{"
|
|
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>#{"
|
|
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
|
-
|
|
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
|
data/lib/minitest/html_plugin.rb
CHANGED
|
@@ -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\
|
|
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:
|
|
4
|
+
version: 2.0.1
|
|
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
|