asciidoctor-tabs 1.0.0.beta.4 → 1.0.0.beta.5
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/CHANGELOG.adoc +14 -0
- data/README.adoc +151 -30
- data/lib/asciidoctor/tabs/block.rb +14 -5
- data/lib/asciidoctor/tabs/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 917cc515ced6b0c7599132ddab2d1f72da09b6af4bf7e62774fed3be43363377
|
4
|
+
data.tar.gz: f72d696d910cd046e05acdec439da2f2d407088e2972bbc2a5259049cd3626a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 500f6ee93e370b09e404531abad5d9fae5eea8cbb81ea1bf3b5a5c599dac1a48c961922fe88b9260bf8cf5a536e2db91378314433b5c35eeefff348016313f40
|
7
|
+
data.tar.gz: e0c6683a932a88629d79d72b38bc3c9ff0fd8ac7446a16d264e7579b13b91ebfd83032ab1193e4c389b649c418b680d5790f52e00d7e8ba2e6c6fccf847c8915
|
data/CHANGELOG.adoc
CHANGED
@@ -4,6 +4,20 @@
|
|
4
4
|
This document provides a curated view of the changes to Asciidoctor Tabs per release.
|
5
5
|
For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub.
|
6
6
|
|
7
|
+
== 1.0.0-beta.5 (2023-05-28) - @mojavelinux
|
8
|
+
|
9
|
+
=== Changed
|
10
|
+
|
11
|
+
* Ensure tab number sequence follows document order when tabs blocks are nested (#61)
|
12
|
+
|
13
|
+
=== Fixed
|
14
|
+
|
15
|
+
* Only remove open block enclosure around tab content if it is anonymous; preserve nested tabs block (#59)
|
16
|
+
|
17
|
+
=== Details
|
18
|
+
|
19
|
+
{url-repo}/releases/tag/v1.0.0-beta.5[git tag] | {url-repo}/compare/v1.0.0-beta.4\...v1.0.0-beta.5[full diff]
|
20
|
+
|
7
21
|
== 1.0.0-beta.4 (2023-05-22) - @mojavelinux
|
8
22
|
|
9
23
|
=== Changed
|
data/README.adoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Asciidoctor Tabs
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>
|
3
|
-
v1.0.0-beta.
|
3
|
+
v1.0.0-beta.5, 2023-05-28
|
4
4
|
:idprefix:
|
5
5
|
:idseparator: -
|
6
6
|
ifndef::env-github[:icons: font]
|
@@ -12,14 +12,14 @@ endif::[]
|
|
12
12
|
An Asciidoctor extension that adds a tabs block to the AsciiDoc syntax.
|
13
13
|
|
14
14
|
NOTE: This extension is intended to be used with HTML backends (e.g., `html5`).
|
15
|
-
For all other backends (i.e., the filetype is not html), the custom block enclosure is
|
15
|
+
For all other backends (i.e., the filetype is not html), the custom block enclosure is discarded and its contents (a dlist) is converted normally.
|
16
16
|
|
17
17
|
TIP: This extension is also published as an npm package named `@asciidoctor/tabs` for use with Asciidoctor.js.
|
18
18
|
See the xref:js/README.adoc[README in the js folder] for details.
|
19
19
|
|
20
20
|
== Overview
|
21
21
|
|
22
|
-
Each set of tabs (
|
22
|
+
Each set of tabs (i.e., a "`tabset`" or tabs block) is constructed from a description list (dlist) enclosed in an example block annotated with the tabs style (i.e., `[tab]`).
|
23
23
|
That nested combination of blocks gets translated by this extension into a single tabs block that is a specialization of an open block.
|
24
24
|
|
25
25
|
The tabbed interface produced from this block can help organize information by code language, operating system, or product variant.
|
@@ -57,37 +57,38 @@ Then use Bundler to install the gem:
|
|
57
57
|
|
58
58
|
== Syntax
|
59
59
|
|
60
|
-
A tabset is defined using a description list (dlist) enclosed in an example block
|
60
|
+
A tabset is defined using a description list (dlist) enclosed in an example block annotated with the tabs style.
|
61
61
|
|
62
|
-
.
|
62
|
+
.tabs.adoc
|
63
63
|
[,asciidoc]
|
64
64
|
----
|
65
65
|
[tabs]
|
66
66
|
====
|
67
|
-
Tab A:: Contents of
|
67
|
+
Tab A:: Contents of Tab A.
|
68
68
|
|
69
69
|
Tab B::
|
70
70
|
+
|
71
|
-
Contents of
|
71
|
+
Contents of Tab B.
|
72
72
|
|
73
73
|
Tab C::
|
74
74
|
+
|
75
75
|
--
|
76
|
-
Contents of
|
76
|
+
Contents of Tab C.
|
77
77
|
|
78
78
|
Contains more than one block.
|
79
79
|
--
|
80
80
|
====
|
81
81
|
----
|
82
82
|
|
83
|
-
The
|
83
|
+
The tabs themselves are modeled as a dlist.
|
84
84
|
Each item in the dlist becomes a separate tab.
|
85
85
|
The term is used as the tab's label and the description is used as the tab's contents.
|
86
86
|
The contents can be defined as primary text, attached blocks, or both.
|
87
|
-
If the attached
|
87
|
+
If the tab has a single attached block, and that block is an open block with no attributes, the open block enclosure itself is discarded upon conversion.
|
88
88
|
|
89
89
|
You may choose to extend the block delimiter length from the typical 4 characters to 6 in order to avoid conflicts with any example blocks inside the tabs block (or just as a matter of style).
|
90
90
|
|
91
|
+
.tab-with-example-block.adoc
|
91
92
|
[,asciidoc]
|
92
93
|
----
|
93
94
|
[tabs]
|
@@ -102,52 +103,172 @@ Tab B:: Just text.
|
|
102
103
|
======
|
103
104
|
----
|
104
105
|
|
106
|
+
Using this technique, you can also create nested tabsets.
|
107
|
+
|
108
|
+
.tab-with-nested-tabs.adoc
|
109
|
+
[,asciidoc]
|
110
|
+
----
|
111
|
+
[tabs]
|
112
|
+
======
|
113
|
+
Tab A::
|
114
|
+
+
|
115
|
+
Selecting Tab A reveals a tabset with Tab Y and Tab Z.
|
116
|
+
+
|
117
|
+
[tabs]
|
118
|
+
====
|
119
|
+
Tab Y:: Contents of Tab Y, nested inside Tab A.
|
120
|
+
Tab Z:: Contents of Tab Z, nested inside Tab A.
|
121
|
+
====
|
122
|
+
|
123
|
+
Tab B:: Just text.
|
124
|
+
======
|
125
|
+
----
|
126
|
+
|
105
127
|
== Tabs Sync
|
106
128
|
|
107
|
-
If you want to synchronize the tab selection across tabsets, set the `tabs-sync-option` on the document.
|
129
|
+
If you want to synchronize (i.e., sync) the tab selection across tabsets, set the `tabs-sync-option` on the document.
|
108
130
|
|
109
|
-
.
|
131
|
+
.tabs-sync.adoc
|
110
132
|
[,asciidoc]
|
111
133
|
----
|
112
134
|
:tabs-sync-option:
|
113
135
|
|
114
136
|
[tabs]
|
115
137
|
====
|
116
|
-
Tab A::
|
117
|
-
Tab B::
|
138
|
+
Tab A:: Triggers selection of Tab A in other congruent tabsets.
|
139
|
+
Tab B:: Triggers selection of Tab B in other congruent tabsets.
|
118
140
|
====
|
119
141
|
|
120
142
|
...
|
121
143
|
|
122
144
|
[tabs]
|
123
145
|
====
|
124
|
-
Tab A::
|
125
|
-
Tab B::
|
146
|
+
Tab A:: Triggers selection of Tab A in other congruent tabsets.
|
147
|
+
Tab B:: Triggers selection of Tab B in other congruent tabsets.
|
148
|
+
====
|
149
|
+
----
|
150
|
+
|
151
|
+
Only tabsets that have the same sync group ID are synchronized.
|
152
|
+
By default, the sync group ID is computed by taking the text of each tab, sorting that list, and joining it on `|` (e.g., `A|B`).
|
153
|
+
Each unique combination of tabs--or congruent tablist--implicitly creates a new sync group.
|
154
|
+
|
155
|
+
You can override the sync group ID of a tabset using the `sync-group-id` attribute on the block.
|
156
|
+
This allows you to control the scope of the sync or to force a tabset to participate in a sync group even if its not congruent.
|
157
|
+
|
158
|
+
.tabs-with-custom-sync-groups.adoc
|
159
|
+
[,asciidoc]
|
160
|
+
----
|
161
|
+
:tabs-sync-option:
|
162
|
+
|
163
|
+
[tabs,sync-group-id=group-1]
|
164
|
+
====
|
165
|
+
Tab A:: Triggers selection of Tab A in second tabset.
|
166
|
+
Tab B:: Triggers selection of Tab B in second tabset.
|
167
|
+
====
|
168
|
+
|
169
|
+
[tabs,sync-group-id=group-1]
|
170
|
+
====
|
171
|
+
Tab A:: Triggers selection of Tab A in first tabset.
|
172
|
+
Tab B:: Triggers selection of Tab B in first tabset.
|
173
|
+
====
|
174
|
+
|
175
|
+
[tabs,sync-group-id=group-2]
|
176
|
+
====
|
177
|
+
Tab A:: Triggers selection of Tab A in fourth tabset.
|
178
|
+
Tab B:: Triggers selection of Tab B in fourth tabset.
|
179
|
+
====
|
180
|
+
|
181
|
+
[tabs,sync-group-id=group-2]
|
182
|
+
====
|
183
|
+
Tab A:: Triggers selection of Tab A in third tabset.
|
184
|
+
Tab B:: Triggers selection of Tab B in third tabset.
|
126
185
|
====
|
127
186
|
----
|
128
187
|
|
129
|
-
|
130
|
-
Each unique combination of tabs implicitly creates a new sync group.
|
131
|
-
You can override the sync group ID using the `sync-group-id` attribute on a tabs block to force it to participate in a sync group.
|
132
|
-
By default, the sync group ID is derived from the text of each tab, sorted, then joined on `|` (e.g., `A|B`).
|
188
|
+
Instead of enabling tabs sync globally, you can set the `sync` option on individual tabs blocks.
|
133
189
|
|
134
|
-
|
135
|
-
|
190
|
+
.tabs-with-sync-option.adoc
|
191
|
+
[,asciidoc]
|
192
|
+
----
|
193
|
+
[tabs%sync]
|
194
|
+
====
|
195
|
+
Tab A:: Triggers selection of Tab A in third tabset.
|
196
|
+
Tab B:: Triggers selection of Tab B in third tabset.
|
197
|
+
====
|
198
|
+
|
199
|
+
[tabs]
|
200
|
+
====
|
201
|
+
Tab A:: Does not trigger selection of Tab A in other tabsets.
|
202
|
+
Tab B:: Does not trigger selection of Tab B in other tabsets.
|
203
|
+
====
|
204
|
+
|
205
|
+
[tabs%sync]
|
206
|
+
====
|
207
|
+
Tab A:: Triggers selection of Tab A in first tabset.
|
208
|
+
Tab B:: Triggers selection of Tab B in first tabset.
|
209
|
+
====
|
210
|
+
----
|
211
|
+
|
212
|
+
Conversely, if you want to delist a tabs block from the global sync, set the `nosync` option on that block.
|
213
|
+
|
214
|
+
.tabs-with-nosync-option.adoc
|
215
|
+
[,asciidoc]
|
216
|
+
----
|
217
|
+
:tabs-sync-option:
|
218
|
+
|
219
|
+
[tabs]
|
220
|
+
====
|
221
|
+
Tab A:: Triggers selection of Tab A in third tabset.
|
222
|
+
Tab B:: Triggers selection of Tab B in third tabset.
|
223
|
+
====
|
224
|
+
|
225
|
+
[tabs%nosync]
|
226
|
+
====
|
227
|
+
Tab A:: Does not trigger selection of Tab A in other tabsets.
|
228
|
+
Tab B:: Does not trigger selection of Tab B in other tabsets.
|
229
|
+
====
|
230
|
+
|
231
|
+
[tabs]
|
232
|
+
====
|
233
|
+
Tab A:: Triggers selection of Tab A in first tabset.
|
234
|
+
Tab B:: Triggers selection of Tab B in first tabset.
|
235
|
+
====
|
236
|
+
----
|
136
237
|
|
137
238
|
If you want to persist the sync selection, assign a value to the `data-sync-storage-key` attribute on the `<script>` tag.
|
138
|
-
|
139
|
-
|
140
|
-
|
239
|
+
|
240
|
+
[,js]
|
241
|
+
----
|
242
|
+
<script data-sync-storage-key="preferred-tab">
|
243
|
+
----
|
244
|
+
|
245
|
+
By default, the sync selection (per group) will be persisted to local storage (i.e., `data-sync-storage-scope="local"`) using the specified key.
|
246
|
+
You can set the `data-sync-storage-scope` attribute on the `<script>` tag to `session` to use session storage instead of local storage.
|
247
|
+
|
248
|
+
[,js]
|
249
|
+
----
|
250
|
+
<script data-sync-storage-key="preferred-tab" data-sync-storage-scope="session">
|
251
|
+
----
|
252
|
+
|
253
|
+
When using the extension on a standalone document (which will automatically embed the supporting script), you can configure these options using the `tabs-sync-storage-key` and `tabs-sync-storage-scope` document attributes, respectively.
|
254
|
+
|
255
|
+
[,asciidoc]
|
256
|
+
----
|
257
|
+
:tabs-sync-storage-key: tabs
|
258
|
+
:tabs-sync-storage-scope: session
|
259
|
+
----
|
260
|
+
|
261
|
+
In this case, the converter will set the corresponding attributes on the `<script>` tag automatically.
|
141
262
|
|
142
263
|
== Usage
|
143
264
|
|
144
265
|
=== CLI
|
145
266
|
|
146
|
-
$ asciidoctor -r asciidoctor-tabs
|
267
|
+
$ asciidoctor -r asciidoctor-tabs tabs.adoc
|
147
268
|
|
148
269
|
You can specify an alternate stylesheet for tabs using the `tabs-stylesheet` document attribute.
|
149
270
|
|
150
|
-
$ asciidoctor -r asciidoctor-tabs -a tabs-stylesheet=my-tabs.css
|
271
|
+
$ asciidoctor -r asciidoctor-tabs -a tabs-stylesheet=my-tabs.css tabs.adoc
|
151
272
|
|
152
273
|
The value of the `tabs-stylesheet` attribute is handled in the same way as the built-in `stylesheet` document attribute.
|
153
274
|
A relative path is resolved starting from the value of the `stylesdir` document attribute, which defaults to the directory of the document.
|
@@ -164,7 +285,7 @@ You can require `asciidoctor/tabs` to register the extension as a global extensi
|
|
164
285
|
require 'asciidoctor'
|
165
286
|
require 'asciidoctor/tabs'
|
166
287
|
|
167
|
-
Asciidoctor.convert_file '
|
288
|
+
Asciidoctor.convert_file 'tabs.adoc', safe: :safe
|
168
289
|
----
|
169
290
|
|
170
291
|
Or you can pass a registry instance to the `Extensions.register` method to register the extension with a scoped registry.
|
@@ -177,14 +298,14 @@ require 'asciidoctor/tabs/extensions'
|
|
177
298
|
registry = Asciidoctor::Extensions.create
|
178
299
|
Asciidoctor::Tabs::Extensions.register registry
|
179
300
|
|
180
|
-
Asciidoctor.convert_file '
|
301
|
+
Asciidoctor.convert_file 'tabs.adoc', extension_registry: registry, safe: :safe
|
181
302
|
----
|
182
303
|
|
183
304
|
If you're not using other scoped extensions, you can pass in the extensions group without first creating a registry instance:
|
184
305
|
|
185
306
|
[,js]
|
186
307
|
----
|
187
|
-
Asciidoctor.convert_file '
|
308
|
+
Asciidoctor.convert_file 'tabs.adoc', extensions: Asciidoctor::Tabs::Extensions.group, safe: :safe
|
188
309
|
----
|
189
310
|
|
190
311
|
== How it Works
|
@@ -7,16 +7,18 @@ module Asciidoctor
|
|
7
7
|
on_context :example
|
8
8
|
|
9
9
|
def process parent, reader, attrs
|
10
|
+
tabs_number = (doc = parent.document).counter 'tabs-number'
|
10
11
|
block = create_block parent, attrs['cloaked-context'], nil, attrs, content_model: :compound
|
11
12
|
children = (parse_content block, reader).blocks
|
12
|
-
|
13
|
-
|
13
|
+
unless children.size == 1 && (seed_tabs = children[0]).context == :dlist && seed_tabs.items?
|
14
|
+
return (reset_counter doc, 'tabs-number', (tabs_number - 1)) || block
|
15
|
+
end
|
16
|
+
unless doc.attr? 'filetype', 'html'
|
14
17
|
(id = attrs['id']) && (doc.register :refs, [(seed_tabs.id = id), seed_tabs]) unless seed_tabs.id
|
15
18
|
(reftext = attrs['reftext']) && (seed_tabs.set_attr 'reftext', reftext) unless seed_tabs.reftext?
|
16
19
|
parent << seed_tabs
|
17
|
-
return
|
20
|
+
return reset_counter doc, 'tabs-number', (tabs_number - 1)
|
18
21
|
end
|
19
|
-
tabs_number = doc.counter 'tabs-number'
|
20
22
|
tabs_id = attrs['id'] || (generate_id %(tabs #{tabs_number}), doc)
|
21
23
|
tabs_role = 'tabs' + (!(block.option? 'nosync') && ((block.option? 'sync') || (doc.option? 'tabs-sync')) ?
|
22
24
|
((gid = attrs['sync-group-id']) ? %( is-sync data-sync-group-id=#{gid.gsub ' ', ?\u00a0}) : ' is-sync') : '')
|
@@ -39,7 +41,8 @@ module Asciidoctor
|
|
39
41
|
tab_blocks = content.text? ?
|
40
42
|
[(create_paragraph parent, (content.instance_variable_get :@text), nil, subs: :normal)] : []
|
41
43
|
if content.blocks?
|
42
|
-
if (block0 = (blocks = content.blocks)[0]).context == :open &&
|
44
|
+
if (block0 = (blocks = content.blocks)[0]).context == :open && block0.style == 'open' &&
|
45
|
+
blocks.size == 1 && !(block0.id || block0.title? || block0.attributes.keys.any? {|k| k != 'style' })
|
43
46
|
blocks = block0.blocks
|
44
47
|
end
|
45
48
|
tab_blocks.push(*blocks)
|
@@ -81,6 +84,12 @@ module Asciidoctor
|
|
81
84
|
converter.instance_variable_set :@list_item_supports_id, (output.include? ' id="name"')
|
82
85
|
end
|
83
86
|
end
|
87
|
+
|
88
|
+
def reset_counter doc, name, val
|
89
|
+
doc.counters[name] = val
|
90
|
+
doc.set_attr name, val unless doc.attribute_locked? name
|
91
|
+
nil
|
92
|
+
end
|
84
93
|
end
|
85
94
|
end
|
86
95
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-tabs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.beta.
|
4
|
+
version: 1.0.0.beta.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Allen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|