asciidoctor-dita-topic 1.2.1 → 1.3.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +55 -6
  3. data/lib/dita-topic.rb +120 -66
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 648f69ba5e5ada330dd2f74e5b6421d37e74a5a87e74d8fcce2a06361cf4f356
4
- data.tar.gz: 3ba982932cab3253139ec969449584214db56e638f0bce7b1893685eeded2aed
3
+ metadata.gz: '092cfd1c5fc92f2f11a30182ae6032aa22aa873c233bc558267a4b19b574b70d'
4
+ data.tar.gz: 194768b17516a7194570e841f534f824c516c1e71d54a74d9099a866e0a32752
5
5
  SHA512:
6
- metadata.gz: 6aed474f0fdda4e30e85ae64cd8d2c532b6646d93713584bdffef7b00e875c2b9f12c94eae7c5c00ca00a364415fcb7d6a9da581eed88b036072f010a5de6b39
7
- data.tar.gz: 214b99142e2ca90f6e0ad5e5baf42de415127977cf585ca04017db57213c47cccbc2261a9a61a66e9f315d922210020d1c3f165233f4c904d6d1542452f270bd
6
+ metadata.gz: 6d702eb430079e5141f6f72d122498c6f8ae998ea46e6989f4461b8755eb2ea089ea4956442cf4a0ea15aa93de6972284b6547833ba049fc1792309118d94498
7
+ data.tar.gz: dd8ba09934fb425472cc3a91ee60a3e8d1fc5e16e2330a620c6ac8aa56114854d9af628aee29b5f777acdbd610c9f91386ee57189a52ecd9a60bd7d3fe6ae687
data/README.adoc CHANGED
@@ -2,27 +2,34 @@
2
2
 
3
3
  `dita-topic` is a custom converter for Asciidoctor that converts a single AsciiDoc file to a corresponding DITA 1.3 topic.
4
4
 
5
- In combination with link:https://github.com/jhradilek/asciidoctor-dita-vale[asciidoctor-dita-vale] and link:https://github.com/jhradilek/dita-custom-xslt#installation[dita-convert], this project can be used to rapidly convert AsciiDoc content to DITA:
5
+ In combination with link:https://github.com/jhradilek/asciidoctor-dita-vale[asciidoctor-dita-vale], link:https://github.com/jhradilek/dita-custom-xslt#installation[dita-convert], and link:https://github.com/jhradilek/fix-dita-links[dita-cleanup], this project can be used to rapidly convert AsciiDoc content to DITA:
6
6
 
7
7
  . Identify incompatible markup in the AsciiDoc source file:
8
8
  +
9
9
  [literal,subs="+quotes"]
10
10
  ....
11
- $ *vale source_file.adoc*
11
+ $ *vale _source_file.adoc_*
12
12
  ....
13
13
 
14
14
  . Convert the AsciiDoc file to a generic DITA topic:
15
15
  +
16
16
  [literal,subs="+quotes"]
17
17
  ....
18
- $ *asciidoctor -r dita-topic -b dita-topic source_file.adoc*
18
+ $ *asciidoctor -r dita-topic -b dita-topic _source_file.adoc_*
19
19
  ....
20
20
 
21
21
  . Convert the generic DITA topic to a specialized DITA concept, reference, or task:
22
22
  +
23
23
  [literal,subs="+quotes"]
24
24
  ....
25
- $ *dita-convert -gt task source_file.dita*
25
+ $ *dita-convert -g _source_file.dita_ -o _output_file.dita_*
26
+ ....
27
+
28
+ . _Optional:_ Clean up the resulting DITA file if necessary:
29
+ +
30
+ [literal,subs="+quotes"]
31
+ ....
32
+ $ *dita-cleanup -iI -D ../images -X . _output_file.dita_*
26
33
  ....
27
34
 
28
35
  [#install]
@@ -183,25 +190,31 @@ An introductory paragraph.
183
190
 
184
191
  Unlike AsciiDoc, DITA provides a number of semantic elements for software components such as file names, commands, or command-line options. To replicate this behavior, the `dita-topic` converter recognizes the following link:https://docs.asciidoctor.org/asciidoc/latest/attributes/role/#assign-roles-to-formatted-inline-elements[roles] assigned to monospace (```) inline text:
185
192
 
186
- [cols="1,1"]
193
+ [cols="1,1,2"]
187
194
  |===
188
195
  | AsciiDoc Role
189
196
  | DITA Element
197
+ | Description
190
198
 
191
199
  | command
192
200
  | `<cmdname>`
201
+ | A command name.
193
202
 
194
203
  | directory
195
204
  | `<filepath>`
205
+ | A directory name.
196
206
 
197
207
  | filename
198
208
  | `<filepath>`
209
+ | A file name.
199
210
 
200
211
  | option
201
212
  | `<option>`
213
+ | An command-line option.
202
214
 
203
215
  | variable
204
216
  | `<varname>`
217
+ | A variable name.
205
218
  |===
206
219
 
207
220
  For example, to describe a file name, use the following AsciiDoc markup:
@@ -212,10 +225,46 @@ Read the [filename]`/etc/passwd` file to see the complete list of
212
225
  available user accounts.
213
226
  ----
214
227
 
228
+ [#metadata]
229
+ === Adding metadata
230
+
231
+ DITA provides four metadata attributes that can be used for conditional processing. To replicate this behavior, the `dita-topic` converter recognizes the following link:https://docs.asciidoctor.org/asciidoc/latest/attributes/role/#assign-roles-to-formatted-inline-elements[roles] assigned to inline and block elements:
232
+
233
+ [cols="1,1,2"]
234
+ |===
235
+ | AsciiDoc Role
236
+ | DITA Attribute
237
+ | Description
238
+
239
+ | `platform:__value__`
240
+ | `platform="_value_"`
241
+ | Operating system or hardware architecture.
242
+
243
+ | `product:__value__`
244
+ | `product="_value_"`
245
+ | Product name.
246
+
247
+ | `audience:__value__`
248
+ | `audience="_value_"`
249
+ | Target audience.
250
+
251
+ | `otherprops:__value__`
252
+ | `otherprops="_value_"`
253
+ | Additional properties.
254
+ |===
255
+
256
+ For example, to indicate that a particular paragraph is relevant for Linux and macOS and is intended for beginners, use the following AsciiDoc markup:
257
+
258
+ [source,asciidoc]
259
+ ----
260
+ [role="platform:linux platform:mac audience:beginner"]
261
+ For more information, see the *bash*(1) manual page.
262
+ ----
263
+
215
264
  [#warnings]
216
265
  == Warnings
217
266
 
218
- Despite aspiring to avoid losing content during conversion and produce a valid DITA output, there are limitations to what is possible because of the differences between the two markup languages. When the `dita-topic` converter encounters a possible problem, it prints a warning to standard error output in the following format:
267
+ Despite aspiring to avoid losing content during conversion and produce valid DITA output, there are limitations to what is possible because of the differences between the two markup languages. When the `dita-topic` converter encounters a possible problem, it prints a warning to standard error output in the following format:
219
268
 
220
269
  [literal,subs="+quotes"]
221
270
  ....
data/lib/dita-topic.rb CHANGED
@@ -46,6 +46,9 @@ class DitaTopic < Asciidoctor::Converter::Base
46
46
 
47
47
  # Enable sidebars by default:
48
48
  @sidebars_allowed = true
49
+
50
+ # Disable propagating the content type to sections by default:
51
+ @type_allowed = false
49
52
  end
50
53
 
51
54
  def convert_document node
@@ -61,6 +64,9 @@ class DitaTopic < Asciidoctor::Converter::Base
61
64
  # Check if sidebars are enabled:
62
65
  @sidebars_allowed = false if (node.attr 'dita-topic-sidebars') == 'off'
63
66
 
67
+ # Check if propagating the content type to sections is enabled:
68
+ @type_allowed = true if (node.attr 'dita-topic-type') == 'on'
69
+
64
70
  # Check if the file name is available (it is not for standard input):
65
71
  if node.attr? 'docname'
66
72
  file_name = node.attr 'docname'
@@ -68,13 +74,8 @@ class DitaTopic < Asciidoctor::Converter::Base
68
74
  @file_name = "#{file_name}#{file_suffix}"
69
75
  end
70
76
 
71
- # Check if the modular documentation content type is specified; both
72
- # _module-type and _content-type are deprecated, but still present in
73
- # some modules:
74
- outputclass = ''
75
- outputclass = %( outputclass="#{(node.attr '_module-type').downcase}") if node.attr? '_module-type'
76
- outputclass = %( outputclass="#{(node.attr '_content-type').downcase}") if node.attr? '_content-type'
77
- outputclass = %( outputclass="#{(node.attr '_mod-docs-content-type').downcase}") if node.attr? '_mod-docs-content-type'
77
+ # Check if the modular documentation content type is specified:
78
+ outputclass = compose_type_outputclass node
78
79
 
79
80
  # Open the document:
80
81
  result = ["<?xml version='1.0' encoding='utf-8' ?>"]
@@ -129,9 +130,7 @@ class DitaTopic < Asciidoctor::Converter::Base
129
130
 
130
131
  # Return the XML output:
131
132
  <<~EOF.chomp
132
- <note type="#{node.attr 'name'}">
133
- #{node.content}
134
- </note>
133
+ <note type="#{node.attr 'name'}"#{compose_metadata node}>#{node.content}</note>
135
134
  EOF
136
135
  end
137
136
 
@@ -139,12 +138,12 @@ class DitaTopic < Asciidoctor::Converter::Base
139
138
  # Check if the audio macro has a title specified:
140
139
  if node.title?
141
140
  <<~EOF.chomp
142
- <object data="#{node.media_uri(node.attr 'target')}">
141
+ <object data="#{node.media_uri(node.attr 'target')}"#{compose_metadata node}>
143
142
  <desc>#{node.title}</desc>
144
143
  </object>
145
144
  EOF
146
145
  else
147
- %(<object data="#{node.media_uri(node.attr 'target')}" />)
146
+ %(<object data="#{node.media_uri(node.attr 'target')}"#{compose_metadata node} />)
148
147
  end
149
148
  end
150
149
 
@@ -159,7 +158,7 @@ class DitaTopic < Asciidoctor::Converter::Base
159
158
  number = 0
160
159
 
161
160
  # Open the definition list:
162
- result = ['<dl outputclass="callout-list">']
161
+ result = [%(<dl outputclass="callout-list"#{compose_metadata node}>)]
163
162
 
164
163
  # Process individual list items:
165
164
  node.items.each do |item|
@@ -199,7 +198,7 @@ class DitaTopic < Asciidoctor::Converter::Base
199
198
  return compose_qanda_dlist node if node.style == 'qanda'
200
199
 
201
200
  # Open the definition list:
202
- result = ['<dl>']
201
+ result = [%(<dl#{compose_metadata node}>)]
203
202
 
204
203
  # Process individual list items:
205
204
  node.items.each do |terms, description|
@@ -229,10 +228,10 @@ class DitaTopic < Asciidoctor::Converter::Base
229
228
  end
230
229
 
231
230
  # Close the definition list:
232
- result << '</dl>'
231
+ result << %(</dl>)
233
232
 
234
233
  # Return the XML output:
235
- add_block_title (result.join LF), node.title
234
+ add_block_title (result.join LF), node
236
235
  end
237
236
 
238
237
  def convert_example node
@@ -243,7 +242,7 @@ class DitaTopic < Asciidoctor::Converter::Base
243
242
 
244
243
  # Return the XML output:
245
244
  <<~EOF.chomp
246
- <example#{compose_id node.id}>
245
+ <example#{compose_id node.id}#{compose_metadata node}>
247
246
  #{node.title ? %(<title>#{node.title}</title>\n) : ''}#{node.content}
248
247
  </example>
249
248
  EOF
@@ -261,7 +260,7 @@ class DitaTopic < Asciidoctor::Converter::Base
261
260
  end
262
261
 
263
262
  # Return the XML output:
264
- %(<p outputclass="title sect#{node.level}"><b>#{node.title}</b></p>)
263
+ %(<p outputclass="title sect#{node.level}"#{compose_metadata node}><b>#{node.title}</b></p>)
265
264
  end
266
265
 
267
266
  def convert_image node
@@ -277,7 +276,7 @@ class DitaTopic < Asciidoctor::Converter::Base
277
276
  # Check if the image has a title specified:
278
277
  if node.title?
279
278
  <<~EOF.chomp
280
- <fig>
279
+ <fig#{compose_metadata node}>
281
280
  <title>#{node.title}</title>
282
281
  <image href="#{node.image_uri(node.attr 'target')}"#{width}#{height}#{scale} placement="break">
283
282
  <alt>#{node.alt}</alt>
@@ -286,7 +285,7 @@ class DitaTopic < Asciidoctor::Converter::Base
286
285
  EOF
287
286
  else
288
287
  <<~EOF.chomp
289
- <image href="#{node.image_uri(node.attr 'target')}"#{width}#{height}#{scale} placement="break">
288
+ <image href="#{node.image_uri(node.attr 'target')}"#{width}#{height}#{scale} placement="break"#{compose_metadata node}>
290
289
  <alt>#{node.alt}</alt>
291
290
  </image>
292
291
  EOF
@@ -298,7 +297,7 @@ class DitaTopic < Asciidoctor::Converter::Base
298
297
  case node.type
299
298
  when :link
300
299
  # Compose an external link:
301
- %(<xref href="#{node.target}" scope="external">#{node.text}</xref>)
300
+ %(<xref href="#{node.target}" scope="external"#{compose_metadata node}>#{node.text}</xref>)
302
301
  when :xref
303
302
  # NOTE: While AsciiDoc is happy to reference an ID that is not
304
303
  # defined in the same AsciiDoc file, DITA requires the topic ID as
@@ -313,7 +312,7 @@ class DitaTopic < Asciidoctor::Converter::Base
313
312
  logger.warn format_message "Possible invalid reference: #{node.target}" if node.target.include? '#'
314
313
 
315
314
  # Compose a cross reference:
316
- return %(<xref href="#{node.target}">#{node.text || path}</xref>)
315
+ return %(<xref href="#{node.target}"#{compose_metadata node}>#{node.text || path}</xref>)
317
316
  end
318
317
 
319
318
  # Determine whether the ID reference target is in this document:
@@ -321,18 +320,18 @@ class DitaTopic < Asciidoctor::Converter::Base
321
320
  # Determine whether the ID reference target is the document id:
322
321
  if target == node.document.id
323
322
  # Compose the unchanged cross reference:
324
- return node.text ? %(<xref href="##{target}">#{node.text}</xref>) : %(<xref href="##{target}" />)
323
+ return node.text ? %(<xref href="##{target}"#{compose_metadata node}>#{node.text}</xref>) : %(<xref href="##{target}" />)
325
324
  end
326
325
 
327
326
  # Compose the adjusted cross reference:
328
- return node.text ? %(<xref href="#./#{target}">#{node.text}</xref>) : %(<xref href="#./#{target}" />)
327
+ return node.text ? %(<xref href="#./#{target}"#{compose_metadata node}>#{node.text}</xref>) : %(<xref href="#./#{target}" />)
329
328
  end
330
329
 
331
330
  # Issue a warning as the cross reference is unlikely to work:
332
331
  logger.warn format_message "Possible invalid reference: #{node.target}"
333
332
 
334
333
  # Compose the cross reference:
335
- node.text ? %(<xref href="#{node.target}">#{node.text}</xref>) : %(<xref href="#{node.target}" />)
334
+ node.text ? %(<xref href="#{node.target}"#{compose_metadata node}>#{node.text}</xref>) : %(<xref href="#{node.target}" />)
336
335
  when :ref
337
336
  # NOTE: DITA does not have a dedicated element for inline anchors or
338
337
  # a direct equivalent of the <span> element from HTML. The solution
@@ -404,7 +403,7 @@ class DitaTopic < Asciidoctor::Converter::Base
404
403
  height = '' if height.include? '%'
405
404
 
406
405
  # Return the XML output:
407
- %(<image href="#{node.image_uri node.target}"#{width}#{height} placement="inline"><alt>#{node.alt}</alt></image>)
406
+ %(<image href="#{node.image_uri node.target}"#{width}#{height} placement="inline"#{compose_metadata node}><alt>#{node.alt}</alt></image>)
408
407
  end
409
408
 
410
409
  def convert_inline_indexterm node
@@ -454,11 +453,14 @@ class DitaTopic < Asciidoctor::Converter::Base
454
453
  # Determine the inline markup type:
455
454
  case node.type
456
455
  when :emphasis
457
- %(<i>#{node.text}</i>)
456
+ %(<i#{compose_metadata node}>#{node.text}</i>)
458
457
  when :strong
459
- %(<b>#{node.text}</b>)
458
+ %(<b#{compose_metadata node}>#{node.text}</b>)
460
459
  when :monospaced
461
- # Check whether a role is provided:
460
+ # Set the default element value:
461
+ element = 'codeph'
462
+
463
+ # Check if the role is provided:
462
464
  if node.role
463
465
  # Define supported roles:
464
466
  semantic_markup = {
@@ -469,19 +471,19 @@ class DitaTopic < Asciidoctor::Converter::Base
469
471
  'variable' => 'varname'
470
472
  }
471
473
 
472
- # Select the appropriate semantic element:
473
- element = (semantic_markup.key? node.role) ? semantic_markup[node.role] : 'tt'
474
- else
475
- # Use the teletype element by default:
476
- element = 'tt'
474
+ # Process each role:
475
+ node.role.split.each do |role|
476
+ # Select the appropriate semantic element:
477
+ element = semantic_markup[role] if semantic_markup.key? role
478
+ end
477
479
  end
478
480
 
479
481
  # Return the result:
480
- %(<#{element}>#{node.text}</#{element}>)
482
+ %(<#{element}#{compose_metadata node}>#{node.text}</#{element}>)
481
483
  when :superscript
482
- %(<sup>#{node.text}</sup>)
484
+ %(<sup#{compose_metadata node}>#{node.text}</sup>)
483
485
  when :subscript
484
- %(<sub>#{node.text}</sub>)
486
+ %(<sub#{compose_metadata node}>#{node.text}</sub>)
485
487
  when :double
486
488
  %(&#8220;#{node.text}&#8221;)
487
489
  when :single
@@ -509,30 +511,30 @@ class DitaTopic < Asciidoctor::Converter::Base
509
511
 
510
512
  # Compose the XML output:
511
513
  result = <<~EOF.chomp
512
- <codeblock#{language}>
514
+ <codeblock#{language}#{compose_metadata node}>
513
515
  #{node.content}
514
516
  </codeblock>
515
517
  EOF
516
518
 
517
519
  # Return the XML output:
518
- add_block_title result, node.title
520
+ add_block_title result, node
519
521
  end
520
522
 
521
523
  def convert_literal node
522
524
  # Compose the XML output:
523
525
  result = <<~EOF.chomp
524
- <pre>
526
+ <pre#{compose_metadata node}>
525
527
  #{node.content}
526
528
  </pre>
527
529
  EOF
528
530
 
529
531
  # Return the XML output:
530
- add_block_title result, node.title
532
+ add_block_title result, node
531
533
  end
532
534
 
533
535
  def convert_olist node
534
536
  # Open the ordered list:
535
- result = ['<ol>']
537
+ result = [%(<ol#{compose_metadata node}>)]
536
538
 
537
539
  # Process individual list items:
538
540
  node.items.each do |item|
@@ -550,7 +552,7 @@ class DitaTopic < Asciidoctor::Converter::Base
550
552
  result << '</ol>'
551
553
 
552
554
  # Return the XML output:
553
- add_block_title (result.join LF), node.title
555
+ add_block_title (result.join LF), node
554
556
  end
555
557
 
556
558
  def convert_open node
@@ -564,12 +566,12 @@ class DitaTopic < Asciidoctor::Converter::Base
564
566
  node.content
565
567
  elsif node.content_model == :compound
566
568
  <<~EOF.chomp
567
- <div#{(node.style == 'abstract') ? ' outputclass="abstract"' : ''}>
569
+ <div#{(node.style == 'abstract') ? ' outputclass="abstract"' : ''}#{compose_metadata node}>
568
570
  #{compose_floating_title node.title}#{node.content}
569
571
  </div>
570
572
  EOF
571
573
  else
572
- %(#{compose_floating_title node.title}<p#{(node.style == 'abstract') ? ' outputclass="abstract"' : ''}>#{node.content}</p>)
574
+ %(#{compose_floating_title node.title}<p#{(node.style == 'abstract') ? ' outputclass="abstract"' : ''}#{compose_metadata node}>#{node.content}</p>)
573
575
  end
574
576
  end
575
577
 
@@ -584,10 +586,10 @@ class DitaTopic < Asciidoctor::Converter::Base
584
586
  end
585
587
 
586
588
  def convert_paragraph node
587
- if (node.attr 'role') == '_abstract'
588
- add_block_title %(<p outputclass="abstract">#{node.content}</p>), node.title
589
+ if (node.attr 'role') and (node.attr 'role').split.include? '_abstract'
590
+ add_block_title %(<p outputclass="abstract"#{compose_metadata node}>#{node.content}</p>), node
589
591
  else
590
- add_block_title %(<p>#{node.content}</p>), node.title
592
+ add_block_title %(<p#{compose_metadata node}>#{node.content}</p>), node
591
593
  end
592
594
  end
593
595
 
@@ -605,13 +607,13 @@ class DitaTopic < Asciidoctor::Converter::Base
605
607
  # Check if the content contains multiple block elements:
606
608
  if node.content_model == :compound
607
609
  <<~EOF.chomp
608
- <lq>
610
+ <lq#{compose_metadata node}>
609
611
  #{compose_floating_title node.title}#{node.content}#{author}#{source}
610
612
  </lq>
611
613
  EOF
612
614
  else
613
615
  <<~EOF.chomp
614
- <lq>
616
+ <lq#{compose_metadata node}>
615
617
  #{compose_floating_title node.title}<p>#{node.content}</p>#{author}#{source}
616
618
  </lq>
617
619
  EOF
@@ -632,9 +634,12 @@ class DitaTopic < Asciidoctor::Converter::Base
632
634
  # Issue a warning if there are nested sections:
633
635
  logger.warn format_message "Nesting of sections not supported in DITA" if node.level > 1
634
636
 
637
+ # Check if the modular documentation content type is specified:
638
+ outputclass = @type_allowed ? compose_type_outputclass(node.document) : ''
639
+
635
640
  # Return the XML output:
636
641
  <<~EOF.chomp
637
- <section#{compose_id node.id}>
642
+ <section#{compose_id node.id}#{outputclass}#{compose_metadata node}>
638
643
  <title>#{node.title}</title>
639
644
  #{node.content}
640
645
  </section>
@@ -654,13 +659,13 @@ class DitaTopic < Asciidoctor::Converter::Base
654
659
  # Check if the content contains multiple block elements:
655
660
  if node.content_model == :compound
656
661
  <<~EOF.chomp
657
- <div outputclass="sidebar">
662
+ <div outputclass="sidebar"#{compose_metadata node}>
658
663
  #{compose_floating_title node.title}#{node.content}
659
664
  </div>
660
665
  EOF
661
666
  else
662
667
  <<~EOF.chomp
663
- <div outputclass="sidebar">
668
+ <div outputclass="sidebar"#{compose_metadata node}>
664
669
  #{compose_floating_title node.title}<p>#{node.content}</p>
665
670
  </div>
666
671
  EOF
@@ -675,7 +680,7 @@ class DitaTopic < Asciidoctor::Converter::Base
675
680
 
676
681
  def convert_table node
677
682
  # Open the table:
678
- result = ['<table>']
683
+ result = [%(<table#{compose_metadata node}>)]
679
684
 
680
685
  # Check if the title is specified:
681
686
  result << %(<title>#{node.title}</title>) if node.title?
@@ -765,7 +770,7 @@ class DitaTopic < Asciidoctor::Converter::Base
765
770
 
766
771
  def convert_ulist node
767
772
  # Open the unordered list:
768
- result = ['<ul>']
773
+ result = [%(<ul#{compose_metadata node}>)]
769
774
 
770
775
  # Process individual list items:
771
776
  node.items.each do |item|
@@ -790,7 +795,7 @@ class DitaTopic < Asciidoctor::Converter::Base
790
795
  result << '</ul>'
791
796
 
792
797
  # Returned the XML output:
793
- add_block_title (result.join LF), node.title
798
+ add_block_title (result.join LF), node
794
799
  end
795
800
 
796
801
  def convert_verse node
@@ -802,7 +807,7 @@ class DitaTopic < Asciidoctor::Converter::Base
802
807
 
803
808
  # Return the XML output:
804
809
  <<~EOF.chomp
805
- <lines>
810
+ <lines#{compose_metadata node}>
806
811
  #{node.content}#{author}#{source}
807
812
  </lines>
808
813
  EOF
@@ -837,18 +842,18 @@ class DitaTopic < Asciidoctor::Converter::Base
837
842
  # Check if the audio macro has a title specified:
838
843
  if node.title?
839
844
  <<~EOF.chomp
840
- <object data="#{target_url}"#{width}#{height}>
845
+ <object data="#{target_url}"#{width}#{height}#{compose_metadata node}>
841
846
  <desc>#{node.title}</desc>
842
847
  </object>
843
848
  EOF
844
849
  else
845
- %(<object data="#{target_url}"#{width}#{height} />)
850
+ %(<object data="#{target_url}"#{width}#{height}#{compose_metadata node} />)
846
851
  end
847
852
  end
848
853
 
849
854
  def compose_qanda_dlist node
850
855
  # Open the ordered list:
851
- result = ['<ol>']
856
+ result = [%(<ol#{compose_metadata node}>)]
852
857
 
853
858
  # Process individual list items:
854
859
  node.items.each do |terms, description|
@@ -871,15 +876,15 @@ class DitaTopic < Asciidoctor::Converter::Base
871
876
  end
872
877
 
873
878
  # Close the ordered list:
874
- result << '</ol>'
879
+ result << %(</ol>)
875
880
 
876
881
  # Return the XML output:
877
- add_block_title (result.join LF), node.title
882
+ add_block_title (result.join LF), node
878
883
  end
879
884
 
880
885
  def compose_horizontal_dlist node
881
886
  # Open the table:
882
- result = ['<table outputclass="horizontal-dlist">']
887
+ result = [%(<table outputclass="horizontal-dlist"#{compose_metadata node}>)]
883
888
 
884
889
  # Check if the title is specified:
885
890
  result << %(<title>#{node.title}</title>) if node.title?
@@ -941,13 +946,13 @@ class DitaTopic < Asciidoctor::Converter::Base
941
946
 
942
947
  # Helper methods
943
948
 
944
- def add_block_title content, title
949
+ def add_block_title content, node
945
950
  # NOTE: Unlike AsciiDoc, DITA does not support titles assigned to
946
951
  # certain block elements. As a workaround, I decided to use a paragraph
947
952
  # with the outputclass attribute.
948
953
 
949
954
  # Check if the title is defined:
950
- return content unless title
955
+ return content unless node.title
951
956
 
952
957
  # Issue a warning if block titles are disabled:
953
958
  unless @titles_allowed
@@ -957,7 +962,7 @@ class DitaTopic < Asciidoctor::Converter::Base
957
962
 
958
963
  # Return the XML output:
959
964
  <<~EOF.chomp
960
- <p outputclass="title"><b>#{title}</b></p>
965
+ <p outputclass="title"#{compose_metadata node}><b>#{node.title}</b></p>
961
966
  #{content}
962
967
  EOF
963
968
  end
@@ -1007,6 +1012,55 @@ class DitaTopic < Asciidoctor::Converter::Base
1007
1012
  end
1008
1013
  end
1009
1014
 
1015
+ def compose_type_outputclass node
1016
+ # NOTE: _module-type and _content-type are deprecated, but still
1017
+ # present in some modules:
1018
+ outputclass = ''
1019
+ outputclass = %( outputclass="#{(node.attr '_module-type').downcase}") if node.attr? '_module-type'
1020
+ outputclass = %( outputclass="#{(node.attr '_content-type').downcase}") if node.attr? '_content-type'
1021
+ outputclass = %( outputclass="#{(node.attr '_mod-docs-content-type').downcase}") if node.attr? '_mod-docs-content-type'
1022
+
1023
+ # Return the outputclass attribute:
1024
+ return outputclass
1025
+ end
1026
+
1027
+ def compose_metadata node
1028
+ # Check if the role is defined:
1029
+ return '' unless node.role
1030
+
1031
+ # Set the initial value:
1032
+ result = {}
1033
+
1034
+ # Define supported metadata attributes:
1035
+ valid = ['platform', 'product', 'audience', 'otherprops']
1036
+
1037
+ # Process each role:
1038
+ node.role.split.each do |role|
1039
+ # Ignore roles that do not follow the attribute:value format:
1040
+ next unless role.include? ':'
1041
+
1042
+ # Separate the attribute name from its value:
1043
+ attribute, value = role.split ':'
1044
+
1045
+ # Ignore unsupported attribute names:
1046
+ next unless valid.include? attribute
1047
+
1048
+ # Append the value to the attribute:
1049
+ if result.key? attribute
1050
+ result[attribute] << %( #{value})
1051
+ else
1052
+ result[attribute] = %(#{value})
1053
+ end
1054
+ end
1055
+
1056
+ # Return the list of metadata attributes otherwise:
1057
+ if result.empty?
1058
+ return ''
1059
+ else
1060
+ return ' ' + result.map { |k, v| %(#{k}="#{v}") unless v.empty? }.join(' ')
1061
+ end
1062
+ end
1063
+
1010
1064
  def format_message message
1011
1065
  # Compose the warning or error message:
1012
1066
  file_name = (defined? @file_name) ? %( #{@file_name}:) : ''
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-dita-topic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaromir Hradilek
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  requirements: []
106
- rubygems_version: 3.6.7
106
+ rubygems_version: 3.6.9
107
107
  specification_version: 4
108
108
  summary: A custom AsciiDoc converter that generates individual DITA topics
109
109
  test_files: []