asciidoctor-html 0.1.6 → 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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +12 -0
- data/assets/css/styles.css +2 -2
- data/assets/css/styles.css.map +1 -1
- data/assets/favicon/android-chrome-192x192.png +0 -0
- data/assets/favicon/android-chrome-512x512.png +0 -0
- data/assets/favicon/apple-touch-icon.png +0 -0
- data/assets/favicon/favicon-16x16.png +0 -0
- data/assets/favicon/favicon-32x32.png +0 -0
- data/assets/favicon/favicon.ico +0 -0
- data/lib/asciidoctor/html/bi_inline_macro.rb +0 -1
- data/lib/asciidoctor/html/book.rb +53 -32
- data/lib/asciidoctor/html/cli.rb +29 -14
- data/lib/asciidoctor/html/converter.rb +28 -15
- data/lib/asciidoctor/html/figure.rb +2 -0
- data/lib/asciidoctor/html/highlightjs.rb +46 -39
- data/lib/asciidoctor/html/list.rb +2 -3
- data/lib/asciidoctor/html/pagination.rb +50 -0
- data/lib/asciidoctor/html/popovers.rb +32 -35
- data/lib/asciidoctor/html/ref_tree_processor.rb +6 -3
- data/lib/asciidoctor/html/sc_inline_macro.rb +21 -0
- data/lib/asciidoctor/html/scroll.rb +30 -0
- data/lib/asciidoctor/html/sidebar.rb +41 -0
- data/lib/asciidoctor/html/table.rb +7 -4
- data/lib/asciidoctor/html/template.rb +51 -46
- data/lib/asciidoctor/html/utils.rb +18 -9
- metadata +5 -1
@@ -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)
|
@@ -156,9 +158,10 @@ module Asciidoctor
|
|
156
158
|
def process_colist!(block)
|
157
159
|
block.set_attr "list-depth", 0
|
158
160
|
block.items.each_with_index do |item, idx|
|
159
|
-
|
161
|
+
icon_type = "#{idx + 1}-circle"
|
162
|
+
icon = %(<i class="bi bi-#{icon_type}"></i>)
|
160
163
|
item.set_attr "mark", icon
|
161
|
-
register_reftext! item,
|
164
|
+
register_reftext! item, "bi:#{icon_type}[]"
|
162
165
|
end
|
163
166
|
end
|
164
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
|
@@ -4,7 +4,7 @@ module Asciidoctor
|
|
4
4
|
module Html
|
5
5
|
# Helpers for the table conversion
|
6
6
|
module Table
|
7
|
-
def self.display_row(tsec, row)
|
7
|
+
def self.display_row(node, tsec, row)
|
8
8
|
result = ["<tr>"]
|
9
9
|
row.each do |cell|
|
10
10
|
cell_content = if tsec == :head
|
@@ -14,8 +14,11 @@ module Asciidoctor
|
|
14
14
|
else
|
15
15
|
cell.content.join "\n"
|
16
16
|
end
|
17
|
-
cell_tag_name = (tsec == :head || cell.style == :header ?
|
18
|
-
|
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?
|
19
22
|
cell_colspan_attribute = cell.colspan ? %( colspan="#{cell.colspan}") : ""
|
20
23
|
cell_rowspan_attribute = cell.rowspan ? %( rowspan="#{cell.rowspan}") : ""
|
21
24
|
cell_attributes = "#{cell_class_attribute}#{cell_colspan_attribute}#{cell_rowspan_attribute}"
|
@@ -29,7 +32,7 @@ module Asciidoctor
|
|
29
32
|
node.rows.to_h.map do |tsec, rows|
|
30
33
|
next if rows.empty?
|
31
34
|
|
32
|
-
"<t#{tsec}>\n#{rows.map { |row| display_row(tsec, row) }.join("\n")}\n</t#{tsec}>"
|
35
|
+
"<t#{tsec}>\n#{rows.map { |row| display_row(node, tsec, row) }.join("\n")}\n</t#{tsec}>"
|
33
36
|
end.join("\n")
|
34
37
|
end
|
35
38
|
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(
|
19
|
-
return chaptitle if
|
27
|
+
def self.nav_text(chapprefix, chaptitle)
|
28
|
+
return chaptitle if chapprefix.empty?
|
20
29
|
|
21
|
-
%(<span class="title-mark">#{
|
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,21 +37,29 @@ module Asciidoctor
|
|
28
37
|
|
29
38
|
def self.sidebar(nav_items)
|
30
39
|
<<~HTML
|
31
|
-
<div id="sidebar" class="sidebar
|
32
|
-
<
|
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
|
-
|
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
|
-
<h1>#{
|
44
|
-
|
45
|
-
#{
|
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
|
@@ -66,23 +83,11 @@ module Asciidoctor
|
|
66
83
|
XML
|
67
84
|
end
|
68
85
|
|
69
|
-
def self.header(title, short_title
|
70
|
-
nav_btn = if nav
|
71
|
-
<<~HTML
|
72
|
-
<button type="button" class="btn menu"
|
73
|
-
data-bs-toggle="collapse" data-bs-target="#sidebar"
|
74
|
-
aria-expanded="false" aria-controls="sidebar">
|
75
|
-
<i class="bi bi-list"></i>
|
76
|
-
</button>
|
77
|
-
HTML
|
78
|
-
else
|
79
|
-
""
|
80
|
-
end
|
86
|
+
def self.header(title, short_title)
|
81
87
|
<<~HTML
|
82
88
|
<header class="header">
|
83
89
|
<a class="home d-none d-sm-block" href="./">#{title}</a>
|
84
90
|
<a class="home d-block d-sm-none" href="./">#{short_title}</a>
|
85
|
-
#{nav_btn}
|
86
91
|
</header>
|
87
92
|
HTML
|
88
93
|
end
|
@@ -100,7 +105,7 @@ module Asciidoctor
|
|
100
105
|
|
101
106
|
def self.highlightjs(langs)
|
102
107
|
langs.map do |lang|
|
103
|
-
%(<script src="#{Highlightjs::CDN_PATH}/languages/#{lang}.min.js"></script>)
|
108
|
+
%(<script defer src="#{Highlightjs::CDN_PATH}/languages/#{lang}.min.js"></script>)
|
104
109
|
end.join("\n ")
|
105
110
|
end
|
106
111
|
|
@@ -118,9 +123,19 @@ module Asciidoctor
|
|
118
123
|
<link rel="manifest" href="#{FAVICON_PATH}/site.webmanifest">
|
119
124
|
<link rel="stylesheet" href="#{CSS_PATH}/styles.css">
|
120
125
|
<link rel="stylesheet" href="#{Highlightjs::CDN_PATH}/styles/tomorrow-night-blue.min.css">
|
121
|
-
<script src="#{Highlightjs::CDN_PATH}/highlight.min.js"></script>
|
126
|
+
<script defer src="#{Highlightjs::CDN_PATH}/highlight.min.js"></script>
|
122
127
|
#{highlightjs langs}
|
123
|
-
<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>
|
124
139
|
</head>
|
125
140
|
HTML
|
126
141
|
end
|
@@ -131,38 +146,28 @@ module Asciidoctor
|
|
131
146
|
# - author: String
|
132
147
|
# - description: String
|
133
148
|
# - date: Date
|
134
|
-
# -
|
149
|
+
# - chapheading: String
|
135
150
|
# - chaptitle: String
|
136
151
|
# - langs: Array[String]
|
137
152
|
def self.html(content, nav_items, opts = {})
|
138
153
|
nav = (nav_items.size > 1)
|
139
|
-
hash_listener = if nav
|
140
|
-
<<~JS
|
141
|
-
addEventListener('hashchange', function() {
|
142
|
-
collapse = bootstrap.Collapse.getInstance('#sidebar');
|
143
|
-
if(collapse) collapse.hide();
|
144
|
-
});
|
145
|
-
JS
|
146
|
-
else
|
147
|
-
""
|
148
|
-
end
|
149
154
|
<<~HTML
|
150
155
|
<!DOCTYPE html>
|
151
156
|
<html lang="en">
|
152
157
|
#{head opts[:title], opts[:description], opts[:author], opts[:langs]}
|
153
158
|
<body>
|
154
|
-
#{header opts[:title], opts[:short_title], nav:}
|
155
159
|
#{sidebar(nav_items) if nav}
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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">
|
162
166
|
#{Highlightjs::PLUGIN}
|
163
167
|
hljs.highlightAll();
|
164
|
-
#{hash_listener}
|
165
168
|
#{Popovers::POPOVERS}
|
169
|
+
#{Sidebar::TOGGLE if nav}
|
170
|
+
#{Scroll::SCROLL}
|
166
171
|
</script>
|
167
172
|
</body>
|
168
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
|
35
|
-
prefix =
|
36
|
-
|
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.
|
41
|
-
|
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)
|
@@ -54,12 +63,12 @@ module Asciidoctor
|
|
54
63
|
wrap_id_classes content, node.id, classes, tag_name
|
55
64
|
end
|
56
65
|
|
57
|
-
def self.wrap_node_with_title(content, node, tag_name = :div
|
58
|
-
show_title?(node) ? wrap_node(display_title(node
|
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
|
59
68
|
end
|
60
69
|
|
61
|
-
def self.wrap_id_classes_with_title(content, node, id, classes
|
62
|
-
show_title?(node) ? wrap_id_classes(display_title(node
|
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
|
63
72
|
end
|
64
73
|
|
65
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.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ravi Rajani
|
@@ -98,8 +98,12 @@ 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
|
103
107
|
- lib/asciidoctor/html/table.rb
|
104
108
|
- lib/asciidoctor/html/template.rb
|
105
109
|
- lib/asciidoctor/html/tree_walker.rb
|