asciidoctor-dita-map 0.1.0 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 785383f1b9ac91dfff356c6ccfce6568a16af5c805715d24d294f8539d019d89
4
- data.tar.gz: 0be9258a03b8cff762cd30aae0657b6d105636b1a92334ed456ae68f57eabf1b
3
+ metadata.gz: 4eb319b4d8423d61539d7ec4816ccfac5499656cc15b739542ddb68023d210a0
4
+ data.tar.gz: 768371877af9214c0d80db4e19f29db88ab85c00821a5965480bd7f5304c3f2a
5
5
  SHA512:
6
- metadata.gz: d9dcb68378da10bd98c006524283da2741f32028988dcd2236ecaef3e5933e44a333f8502d8656e94c29dffff1373b542ed2efc75b48e6130d35cd5722395ac9
7
- data.tar.gz: c550422cc1932cc96c952c26a978d48d7788a8b5c9700ad3c51c1f544f29407d780fc5c13a25b06b11e78ae4b7b0751ab26caecf01020c449d94397b10b4d6db
6
+ metadata.gz: d251c66f265772f85a48aee4e8da5c4f9902870e991074dfe10c12977fcbb5921c3a6b695108bfa0025becb1d97bd8cb19bd92fbbeee958b3a5958ed8cfead5f
7
+ data.tar.gz: 0ed486763aa0b355ef4ec931ce87181ab2a6ca9c024e55d9ec03b2782c9ceed05f321ef396378e9421ad10a1ef13200fb05c954e30081af25397ab6905fe0846
data/README.md CHANGED
@@ -1,6 +1,100 @@
1
1
  # dita-map
2
2
 
3
- **dita-map** is a command line utility that converts a single AsciiDoc file to a DITA map.
3
+ **dita-map** is a command line utility that converts a single AsciiDoc file to a DITA map. It recognizes the [document title](https://docs.asciidoctor.org/asciidoc/latest/sections/titles-and-levels/#section-level-syntax) as the map title and uses the [include directives](https://docs.asciidoctor.org/asciidoc/latest/directives/include/) and their respective [leveloffset](https://docs.asciidoctor.org/asciidoc/latest/directives/include-with-leveloffset/#manipulate-heading-levels-with-leveloffset) values to compose the tree of `<mapref>` and `<topicref>` elements.
4
+
5
+ ## Installation
6
+
7
+ Install the `asciidoctor-dita-map` Ruby gem:
8
+
9
+ ```console
10
+ gem install asciidoctor-dita-map
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ To convert a single AsciiDoc file to a DITA map, supply it as an argument to the `dita-map` command:
16
+
17
+ ```console
18
+ $ dita-map your_file.adoc
19
+ ```
20
+
21
+ By default, `dita-map` creates a new file, `your_file.ditamap`, in the same directory as the source file. You can supply multiple files at the same time or use wildcards:
22
+
23
+ ```console
24
+ $ dita-map *.adoc
25
+ ```
26
+
27
+ When you do not supply any file names or specify `-` as the first argument, `dita-map` reads from standard input and prints the result to standard output. For example:
28
+
29
+ ```console
30
+ $ echo 'include::task.adoc[leveloffset=+1]' | dita-map
31
+ <?xml version='1.0' encoding='UTF-8'?>
32
+ <!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
33
+ <map>
34
+ <topicref href="task.dita" navtitle="A topic title" type="task" />
35
+ </map>
36
+ ```
37
+
38
+ ### Changing the output file name
39
+
40
+ To change the output file name or location, use the `-o` or `--out-file` command-line option:
41
+
42
+ ```console
43
+ $ dita-map input_file.adoc -o output_file.ditamap
44
+ ```
45
+
46
+ To print the result to standard output, use `-` as the output file name. For example:
47
+
48
+ ```console
49
+ $ dita-map input_file.adoc -o -
50
+ <?xml version='1.0' encoding='UTF-8'?>
51
+ <!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
52
+ <map>
53
+ <title>A map title</title>
54
+ <mapref href="another_map.ditamap" format="ditamap" type="map" />
55
+ <topicref href="concept.dita" navtitle="A concept title" type="concept">
56
+ <topicref href="task.dita" navtitle="A task title" type="task" />
57
+ </topicref>
58
+ </map>
59
+ ```
60
+
61
+ ### Supplying individual attribute definitions
62
+
63
+ If your AsciiDoc files use custom attributes that are defined externally, you can supply the attribute definitions with the `-a` or `--attribute` command-line option:
64
+
65
+ ```console
66
+ $ dita-map -a attribute_name=attribute_value your_file.adoc
67
+ ```
68
+
69
+ You can supply multiple `-a`/`--attribute` options at the same time.
70
+
71
+ ### Supplying attribute definition files
72
+
73
+ If listing individual attribute definitions is impractical, you can supply AsciiDoc files that contain the attribute definitions with the `-p` or `--prepend-file` command-line option:
74
+
75
+ ```console
76
+ $ dita-map -p definition_file.adoc your_file.adoc
77
+ ```
78
+
79
+ The supplied file is prepended to each AsciiDoc file during conversion. You can supply multiple `-p`/`--prepend-file` options at the same time or combine them with the `-a`/`--attribute` options to construct your attribute definitions. If you define the same attribute twice this way, the value defined by the `-a`/`--attribute` option takes precedence.
80
+
81
+ ## Recognized content types
82
+
83
+ To correctly recognize when to use the `<topicref>` and `<mapref>` elements and what values to assign to their `type` attributes, `dita-map` recognizes the following `:_mod-docs-content-type:` attribute definition values in included AsciiDoc files:
84
+
85
+ | AsciiDoc attribute | Output element | Output type value |
86
+ | --- | --- | --- |
87
+ | `ASSEMBLY` | `<topicref>` | `concept` |
88
+ | `CONCEPT` | `<topicref>` | `concept` |
89
+ | `PROCEDURE` | `<topicref>` | `task` |
90
+ | `REFERENCE` | `<topicref>` | `reference` |
91
+ | `MAP` | `<mapref>` | `map` |
92
+
93
+ For example, to ensure an included AsciiDoc file is recognized as a DITA map, add the following line at the top of the file:
94
+
95
+ ```asciidoc
96
+ :_mod-docs-content-type: MAP
97
+ ```
4
98
 
5
99
  ## Copyright
6
100
 
data/lib/dita-map/cli.rb CHANGED
@@ -37,7 +37,9 @@ module AsciidoctorDitaMap
37
37
  :navtitle => true,
38
38
  :output => false,
39
39
  :title => true,
40
- :type => true
40
+ :type => true,
41
+ :self => false,
42
+ :verbose => false
41
43
  }
42
44
  @prep = []
43
45
  @name = name
@@ -66,6 +68,10 @@ module AsciidoctorDitaMap
66
68
  @prep.append file
67
69
  end
68
70
 
71
+ opt.on('-i', '--include-self', 'make the supplied file the toplevel topicref') do
72
+ @opts[:self] = true
73
+ end
74
+
69
75
  opt.separator ''
70
76
 
71
77
  opt.on('-I', '--no-id', 'do not generate the map id attribute') do
@@ -86,12 +92,18 @@ module AsciidoctorDitaMap
86
92
 
87
93
  opt.separator ''
88
94
 
95
+ opt.on('-v', '--verbose', 'report additional problems in the supplied files') do
96
+ @opts[:verbose] = true
97
+ end
98
+
99
+ opt.separator ''
100
+
89
101
  opt.on('-h', '--help', 'display this help and exit') do
90
102
  puts opt
91
103
  exit
92
104
  end
93
105
 
94
- opt.on('-v', '--version', 'display version information and exit') do
106
+ opt.on('-V', '--version', 'display version information and exit') do
95
107
  puts "#{@name} #{VERSION}"
96
108
  exit
97
109
  end
@@ -111,27 +123,49 @@ module AsciidoctorDitaMap
111
123
  return args
112
124
  end
113
125
 
114
- def parse_topic input
115
- doc = Asciidoctor.load input, safe: :secure, attributes: @attr
116
- att = doc.attributes
126
+ def compose_mapref_attributes file_name, type
127
+ target_file = file_name.sub(/\.adoc$/, '.ditamap')
128
+ attributes = { 'href' => target_file, 'format' => 'ditamap' }
129
+ attributes['type'] = type if @opts[:type]
117
130
 
118
- document_title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
119
- document_type = att['_mod-docs-content-type'] ? att['_mod-docs-content-type'].downcase : nil
120
- document_type = att['_content-type'] ? att['_content-type'].downcase : nil unless document_type
121
- document_type = att['_module-type'] ? att['_module-type'].downcase : nil unless document_type
131
+ return attributes
132
+ end
133
+
134
+ def compose_topicref_attributes file_name, title, type
135
+ target_file = file_name.sub(/\.adoc$/, '.dita')
136
+
137
+ attributes = { 'href' => target_file }
138
+ attributes['navtitle'] = title if @opts[:navtitle] and title
139
+ attributes['type'] = type if @opts[:type] and type and ['concept', 'reference', 'task'].include? type
140
+
141
+ return attributes
142
+ end
143
+
144
+ def get_content_type attributes
145
+ document_type = attributes['_mod-docs-content-type'] ? attributes['_mod-docs-content-type'].downcase : nil
146
+ document_type = attributes['_content-type'] ? attributes['_content-type'].downcase : nil unless document_type
147
+ document_type = attributes['_module-type'] ? attributes['_module-type'].downcase : nil unless document_type
122
148
 
123
149
  if document_type
124
150
  document_type.sub!(/^assembly$/, 'concept')
125
151
  document_type.sub!(/^procedure$/, 'task')
126
152
  end
127
153
 
128
- unless ['concept', 'reference', 'task', 'map'].include? document_type
129
- document_type = nil
154
+ unless ['concept', 'reference', 'task', 'map', 'attributes', 'snippet'].include? document_type
155
+ return nil
130
156
  end
131
157
 
132
- return document_title, document_type
158
+ return document_type
133
159
  end
134
160
 
161
+ def parse_topic input
162
+ doc = Asciidoctor.load input, safe: :secure, attributes: @attr
163
+
164
+ document_title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
165
+ document_type = get_content_type doc.attributes
166
+
167
+ return document_title, document_type
168
+ end
135
169
 
136
170
  def parse_map input, base_dir
137
171
  Asciidoctor::Extensions.register do
@@ -141,76 +175,85 @@ module AsciidoctorDitaMap
141
175
  doc = Asciidoctor.load input, safe: :safe, catalog_assets: true, attributes: @attr, base_dir: base_dir
142
176
 
143
177
  include_files = doc.catalog[:include_files] ? doc.catalog[:include_files] : []
144
- document_title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
145
- document_id = doc.id ? doc.id.gsub(/["']/, '') : nil
178
+ map_id = doc.id ? doc.id.gsub(/["']/, '') : nil
179
+ map_title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
180
+ map_type = get_content_type doc.attributes
181
+
182
+ info = {
183
+ :id => map_id,
184
+ :title => map_title,
185
+ :type => map_type
186
+ }
146
187
 
147
- return include_files, document_title, document_id
188
+ return include_files, info
148
189
  end
149
190
 
150
- def convert_map input, base_dir, prepended = ''
191
+ def convert_map input, base_dir, prepended = '', file = nil
151
192
  result = ''
152
193
 
153
- include_files, map_title, document_id = parse_map prepended + input, base_dir
194
+ include_files, map = parse_map prepended + input, base_dir
154
195
 
155
196
  xml = REXML::Document.new
156
197
  xml.context[:attribute_quote] = :quote
157
198
  xml << REXML::XMLDecl.new('1.0', 'utf-8')
158
199
  xml << REXML::DocType.new('map', 'PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd"')
159
200
 
160
- if document_id and @opts[:id]
161
- xml_root = xml.add_element('map', { 'id' => document_id })
201
+ if map[:id] and @opts[:id]
202
+ xml_root = xml.add_element('map', { 'id' => map[:id] })
162
203
  else
163
204
  xml_root = xml.add_element('map')
164
205
  end
165
206
 
166
- if map_title and @opts[:title]
167
- xml_title = xml_root.add_element('title')
168
- xml_title.text = map_title
207
+ if map[:title] and @opts[:title]
208
+ xml_title = xml_root.add_element('title')
209
+ xml_title.text = map[:title]
169
210
  end
170
211
 
171
- stack = [{ :offset => 0, :element => xml_root }]
212
+ if @opts[:self] and file
213
+ attributes = compose_topicref_attributes file, map[:title], map[:type]
214
+ xml_self = xml_root.add_element('topicref', attributes)
215
+ stack = [{ :offset => 0, :element => xml_self }]
216
+ else
217
+ stack = [{ :offset => 0, :element => xml_root }]
218
+ end
172
219
 
173
220
  include_files.each do |file|
174
221
  target = file[:target]
175
222
  offset = file[:offset]
176
223
  last_offset = stack.last[:offset]
224
+ full_path = base_dir + target
225
+
226
+ if not File.exist? full_path and @opts[:verbose]
227
+ warn "#{@name}: warning: file not found: #{target}"
228
+ end
229
+
230
+ begin
231
+ include_title, include_type = parse_topic prepended + File.read(full_path)
232
+ next if ['attributes', 'snippet'].include? include_type
233
+ rescue
234
+ warn "#{@name}: warning: unable to read included file: #{target}"
235
+ include_title, include_type = nil, nil
236
+ end
177
237
 
178
238
  if offset == 0
179
- warn "#{@name}: warning: Invalid leveloffset - expected 1, got 0: #{target}"
239
+ warn "#{@name}: warning: invalid leveloffset - expected 1, got 0: #{target}"
180
240
  offset = 1
181
241
  elsif offset > last_offset and offset - last_offset > 1
182
242
  expected_offset = last_offset + 1
183
- warn "#{@name}: warning: Invalid leveloffset - expected #{expected_offset}, got #{offset}: #{target}"
184
- offset = expected_offset
243
+ warn "#{@name}: warning: invalid leveloffset - expected #{expected_offset}, got #{offset}: #{target}"
185
244
  end
186
245
 
187
246
  while stack.last[:offset] >= offset
188
247
  stack.pop
189
248
  end
190
249
 
191
- xml_parent = stack.last[:element]
192
-
193
- if @opts[:navtitle] or @opts[:type]
194
- begin
195
- include_title, include_type = parse_topic prepended + File.read(base_dir + target)
196
- rescue
197
- warn "#{@name}: warning: Unable to read included file: #{base_dir + target}"
198
- include_title, include_type = nil, nil
199
- end
200
- end
250
+ xml_parent = stack.last[:element]
201
251
 
202
252
  if include_type == 'map'
203
- file_name = target.sub(/\.adoc$/, '.ditamap')
204
- attributes = { 'href' => file_name, 'format' => 'ditamap' }
205
- attributes['type'] = include_type if @opts[:type]
206
-
253
+ attributes = compose_mapref_attributes target, include_type
207
254
  xml_element = xml_parent.add_element('mapref', attributes)
208
255
  else
209
- file_name = target.sub(/\.adoc$/, '.dita')
210
- attributes = { 'href' => file_name }
211
- attributes['navtitle'] = include_title if include_title and @opts[:navtitle]
212
- attributes['type'] = include_type if include_type and @opts[:type]
213
-
256
+ attributes = compose_topicref_attributes target, include_title, include_type
214
257
  xml_element = xml_parent.add_element('topicref', attributes)
215
258
  end
216
259
 
@@ -245,7 +288,11 @@ module AsciidoctorDitaMap
245
288
  output = @opts[:output] ? @opts[:output] : Pathname.new(file).sub_ext('.ditamap').to_s
246
289
  end
247
290
 
248
- result = convert_map input, base_dir, prepended
291
+ if @opts[:self] and file != $stdin
292
+ result = convert_map input, base_dir, prepended, file
293
+ else
294
+ result = convert_map input, base_dir, prepended
295
+ end
249
296
 
250
297
  if output == $stdout
251
298
  $stdout.write result
@@ -24,5 +24,5 @@
24
24
  # frozen_string_literal: true
25
25
 
26
26
  module AsciidoctorDitaMap
27
- VERSION = '0.1.0'
27
+ VERSION = '0.9.1'
28
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-dita-map
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaromir Hradilek
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  requirements: []
142
- rubygems_version: 3.6.9
142
+ rubygems_version: 4.0.6
143
143
  specification_version: 4
144
144
  summary: Convert an AsciiDoc file to a DITA map
145
145
  test_files: []