asciidoctor-tabs 1.0.0.beta.4 → 1.0.0.beta.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e73997158c47ea046d9c2016a25cac989e0f0e12e013bdc17f0c3cde8128e55f
4
- data.tar.gz: 2dd6e9907c7c2498c1ff2226f25d00d654b872644063b02230882a2090f35e45
3
+ metadata.gz: d453d4bfdf6f6b92e7a098908890fb85643aaee9d4fde38bd94aeae1f9576139
4
+ data.tar.gz: 7a6d50452588a2785e201fd76aa7cd6b61294f507456ad10aeb2fab76e97b1fc
5
5
  SHA512:
6
- metadata.gz: d530e0bb402fd7aa9346c5dc747efe5224436ef8d2e1fd4139a64fb84ed3f3c044069ba0fb807f12ecfe78104d6665395d979aeb1aac77465cef6bb831b1e0ad
7
- data.tar.gz: c1c756f94280e8d70394c13abdfeb541f226b5eb39cfe86b514211781e5ab80bf1208e7faad6162db45571b26801ada288ae656143d074a7184ba40674afac32
6
+ metadata.gz: 4697b8dd5e29a82a88d2102cc9d983568416c8a4d14dbb54469e4f343fd1d0311c0d77e65ee4cecb2cd5446a4bb4431b6831b9a36d35927f1391e5125ac6b7da
7
+ data.tar.gz: 7ee4072275cf65f19d34715714e51e52d767830a278dd133b6eb9663a9c81c3f89f3eb9acbc4177562f65c6c6c3e5170547ba51f1991ff218d03b8e4226e0ec9
data/CHANGELOG.adoc CHANGED
@@ -4,6 +4,34 @@
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.6 (2023-08-01) - @mojavelinux
8
+
9
+ === Changed
10
+
11
+ * Repurpose example block as open block if filetype is not html
12
+
13
+ === Fixed
14
+
15
+ * Preserve attribute entries above tabs block (#64)
16
+
17
+ === Details
18
+
19
+ {url-repo}/releases/tag/v1.0.0-beta.6[git tag] | {url-repo}/compare/v1.0.0-beta.5\...v1.0.0-beta.6[full diff]
20
+
21
+ == 1.0.0-beta.5 (2023-05-28) - @mojavelinux
22
+
23
+ === Changed
24
+
25
+ * Ensure tab number sequence follows document order when tabs blocks are nested (#61)
26
+
27
+ === Fixed
28
+
29
+ * Only remove open block enclosure around tab content if it is anonymous; preserve nested tabs block (#59)
30
+
31
+ === Details
32
+
33
+ {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]
34
+
7
35
  == 1.0.0-beta.4 (2023-05-22) - @mojavelinux
8
36
 
9
37
  === 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.4, 2023-05-22
3
+ v1.0.0-beta.6, 2023-08-01
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 taken away and its contents (a dlist) is converted normally.
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 (aka a "`tabset`" or tabs block) is constructed from a description list (dlist) enclosed in an example block marked with the tabs style (i.e., `[tab]`).
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 marked with the tabs style.
60
+ A tabset is defined using a description list (dlist) enclosed in an example block annotated with the tabs style.
61
61
 
62
- .document-with-tabs.adoc
62
+ .tabs.adoc
63
63
  [,asciidoc]
64
64
  ----
65
65
  [tabs]
66
66
  ====
67
- Tab A:: Contents of tab A.
67
+ Tab A:: Contents of Tab A.
68
68
 
69
69
  Tab B::
70
70
  +
71
- Contents of tab B.
71
+ Contents of Tab B.
72
72
 
73
73
  Tab C::
74
74
  +
75
75
  --
76
- Contents of tab C.
76
+ Contents of Tab C.
77
77
 
78
78
  Contains more than one block.
79
79
  --
80
80
  ====
81
81
  ----
82
82
 
83
- The tabbed content is modeled as a dlist.
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 blocks are themselves enclosed in a single open block, the open block enclosure itself is discarded upon conversion.
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
- .document-with-tabs-sync.adoc
131
+ .tabs-sync.adoc
110
132
  [,asciidoc]
111
133
  ----
112
134
  :tabs-sync-option:
113
135
 
114
136
  [tabs]
115
137
  ====
116
- Tab A:: Contents of tab A in first tabset.
117
- Tab B:: Contents of tab B in first tabset.
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:: Contents of tab A in second tabset.
125
- Tab B:: Contents of tab B in second tabset.
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
- Only tabs blocks with congruent tablists are synchronized by default.
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
- Alternately, you can set the `sync` option on each tabs block.
135
- If you want to delist a tabs block from sync, set the `nosync` option on that block.
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
- By default, the sync selection will be assigned to the specified key in local storage.
139
- You can set the `data-sync-storage-scope` attribute on the `<script>` tag to `session` to use session storage instead.
140
- When using the extension on a standalone document, you can configure these options using the `tabs-sync-storage-key` and `tabs-sync-storage-scope` document attributes, respectively.
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 document-with-tabs.adoc
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 document-with-tabs.adoc
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 'document-with-tabs.adoc', safe: :safe
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 'document-with-tabs.adoc', extension_registry: registry, safe: :safe
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 'document-with-tabs.adoc', extensions: Asciidoctor::Tabs::Extensions.group, safe: :safe
308
+ Asciidoctor.convert_file 'tabs.adoc', extensions: Asciidoctor::Tabs::Extensions.group, safe: :safe
188
309
  ----
189
310
 
190
311
  == How it Works
@@ -7,21 +7,20 @@ module Asciidoctor
7
7
  on_context :example
8
8
 
9
9
  def process parent, reader, attrs
10
+ doc = parent.document
11
+ return create_open_block parent, nil, attrs unless doc.attr? 'filetype', 'html'
12
+ tabs_number = doc.counter 'tabs-number'
10
13
  block = create_block parent, attrs['cloaked-context'], nil, attrs, content_model: :compound
11
14
  children = (parse_content block, reader).blocks
12
- return block unless children.size == 1 && (seed_tabs = children[0]).context == :dlist && seed_tabs.items?
13
- unless (doc = parent.document).attr? 'filetype', 'html'
14
- (id = attrs['id']) && (doc.register :refs, [(seed_tabs.id = id), seed_tabs]) unless seed_tabs.id
15
- (reftext = attrs['reftext']) && (seed_tabs.set_attr 'reftext', reftext) unless seed_tabs.reftext?
16
- parent << seed_tabs
17
- return
18
- end
19
- tabs_number = doc.counter 'tabs-number'
15
+ return (reset_counter doc, 'tabs-number', (tabs_number - 1)) || block unless children.size == 1 &&
16
+ (seed_tabs = children[0]).context == :dlist && seed_tabs.items?
20
17
  tabs_id = attrs['id'] || (generate_id %(tabs #{tabs_number}), doc)
21
18
  tabs_role = 'tabs' + (!(block.option? 'nosync') && ((block.option? 'sync') || (doc.option? 'tabs-sync')) ?
22
19
  ((gid = attrs['sync-group-id']) ? %( is-sync data-sync-group-id=#{gid.gsub ' ', ?\u00a0}) : ' is-sync') : '')
23
20
  tabs_role += (tabs_user_role = attrs['role']) ? %( #{tabs_user_role} is-loading) : ' is-loading'
24
- (tabs = create_open_block parent, nil, { 'id' => tabs_id, 'role' => tabs_role }).title = attrs['title']
21
+ tabs_attrs = { 'id' => tabs_id, 'role' => tabs_role }
22
+ tabs_attrs[:attribute_entries] = attrs[:attribute_entries] if attrs.key? :attribute_entries
23
+ (tabs = create_open_block parent, nil, tabs_attrs).title = attrs['title']
25
24
  tablist = create_list parent, :ulist, { 'role' => 'tablist' }
26
25
  panes = {}
27
26
  set_id_on_tab = (doc.backend == 'html5') || (list_item_supports_id? doc)
@@ -39,7 +38,8 @@ module Asciidoctor
39
38
  tab_blocks = content.text? ?
40
39
  [(create_paragraph parent, (content.instance_variable_get :@text), nil, subs: :normal)] : []
41
40
  if content.blocks?
42
- if (block0 = (blocks = content.blocks)[0]).context == :open && blocks.size == 1 && block0.blocks?
41
+ if (block0 = (blocks = content.blocks)[0]).context == :open && block0.style == 'open' &&
42
+ blocks.size == 1 && !(block0.id || block0.title? || block0.attributes.keys.any? {|k| k != 'style' })
43
43
  blocks = block0.blocks
44
44
  end
45
45
  tab_blocks.push(*blocks)
@@ -81,6 +81,12 @@ module Asciidoctor
81
81
  converter.instance_variable_set :@list_item_supports_id, (output.include? ' id="name"')
82
82
  end
83
83
  end
84
+
85
+ def reset_counter doc, name, val
86
+ doc.counters[name] = val
87
+ doc.set_attr name, val unless doc.attribute_locked? name
88
+ nil
89
+ end
84
90
  end
85
91
  end
86
92
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module Tabs
5
- VERSION = '1.0.0.beta.4'
5
+ VERSION = '1.0.0.beta.6'
6
6
  end
7
7
  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
4
+ version: 1.0.0.beta.6
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-22 00:00:00.000000000 Z
11
+ date: 2023-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor