asciidoctor-dita-map 0.9.4 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4dd982c41b3653429b386ada97215adc7c1eaf82bfdd6415d116e974e3f2446c
4
- data.tar.gz: b547c896716b562ad96393b4802ceeaf87bf8af26270e4e8ad1ab8427d8aec3e
3
+ metadata.gz: cc9694104672b3a22efb305a08f2954941f8d91acf81d9fa9f0d5cb64380337b
4
+ data.tar.gz: 914fd13e2487bbde82996710386e54e877f7b95af72c48ab18a46542c8878c6f
5
5
  SHA512:
6
- metadata.gz: 647f898eac5920a8d976136683065acaa8ed6173bf4cf245bbebfaf9e75381f3a222866ffd1532c343900ec2508d80e800750b3ac8ecd8592141f09e5678c773
7
- data.tar.gz: be60464080a6f54e249dd3432e8313486d3afe9298c02a5448502e5ac9ecd33cf02d943268459698d8a2ed9f12d4962f53d7caf7d05f42026737e4af91a52067
6
+ metadata.gz: 5745079517ec9a0e9671cec8e89ddc617904de1bc407f2341383a213e31f6f185ee22c8c7a9cee30c07cc201e6928a073870f19d26b2843c5938c40883b4e5b0
7
+ data.tar.gz: b532bef1754789cb635e4731b1d8ecb292ce75e37261901dde755395f0d66616de7f12efe17f5ff661efeaaf8561153e3cb7b72273ce28fe072689ac7d527eb8
data/bin/dita-map CHANGED
@@ -26,11 +26,11 @@
26
26
  require (cli = File.absolute_path '../lib/dita-map/cli.rb', __dir__) ? cli : 'dita-map/cli'
27
27
 
28
28
  begin
29
- name = File.basename($0)
30
- converter = AsciidoctorDitaMap::Cli.new name, ARGV
29
+ converter = AsciidoctorDitaMap::Cli.new ARGV
31
30
  converter.run
32
- rescue OptionParser::InvalidArgument, OptionParser::InvalidOption, OptionParser::MissingArgument => error
33
- abort "#{name}: #{error.message}"
31
+ rescue OptionParser::InvalidArgument, OptionParser::InvalidOption,
32
+ OptionParser::AmbiguousOption, OptionParser::MissingArgument => error
33
+ abort "#{AsciidoctorDitaMap::NAME}: #{error.message}"
34
34
  rescue Interrupt
35
35
  exit 130
36
36
  end
@@ -29,16 +29,18 @@ class CatalogIncludeDirectives < Asciidoctor::Extensions::IncludeProcessor
29
29
  end
30
30
 
31
31
  def process doc, reader, target, attributes
32
- offset = attributes['leveloffset'].to_i
33
- chunk = attributes['chunk'] or nil
34
- toc = attributes['toc'] or nil
32
+ offset = attributes['leveloffset'].to_i
33
+ navtitle = attributes['navtitle'] or nil
34
+ chunk = attributes['chunk'] or nil
35
+ toc = attributes['toc'] or nil
35
36
 
36
37
  doc.catalog[:include_files] = [] unless doc.catalog[:include_files]
37
38
  doc.catalog[:include_files].append({
38
- :target => target,
39
- :offset => offset,
40
- :chunk => chunk,
41
- :toc => toc
39
+ :target => target,
40
+ :offset => offset,
41
+ :navtitle => navtitle,
42
+ :chunk => chunk,
43
+ :toc => toc
42
44
  })
43
45
 
44
46
  reader
data/lib/dita-map/cli.rb CHANGED
@@ -23,44 +23,28 @@
23
23
 
24
24
  require 'optparse'
25
25
  require 'pathname'
26
- require 'asciidoctor'
27
- require 'rexml/document'
28
- require_relative 'catalog'
26
+ require_relative 'convert'
29
27
  require_relative 'version'
30
28
 
31
29
  module AsciidoctorDitaMap
32
30
  class Cli
33
- def initialize name, argv
34
- @attr = []
35
- @opts = {
36
- :chunk => true,
37
- :id => true,
38
- :locktitle => true,
39
- :navtitle => true,
40
- :output => false,
41
- :title => true,
42
- :toc => true,
43
- :type => true,
44
- :self => false,
45
- :verbose => false,
46
- :zero_offset => false
47
- }
48
- @prep = []
49
- @name = name
50
- @args = self.parse_args argv
31
+ def initialize argv
32
+ @output = nil
33
+ @converter = Convert.new
34
+ @args = self.parse_args argv
51
35
  end
52
36
 
53
37
  def parse_args argv
54
38
  parser = OptionParser.new do |opt|
55
- opt.banner = "Usage: #{@name} [OPTION...] [FILE...]\n"
56
- opt.banner += " #{@name} -h|-v\n\n"
39
+ opt.banner = "Usage: #{NAME} [OPTION...] [FILE...]\n"
40
+ opt.banner += " #{NAME} -h|-v\n\n"
57
41
 
58
42
  opt.on('-o', '--out-file FILE', 'specify the output file; by default, the output file name is based on the input file') do |output|
59
- @opts[:output] = (output.strip == '-') ? $stdout : output
43
+ @output = (output.strip == '-') ? $stdout : output
60
44
  end
61
45
 
62
46
  opt.on('-a', '--attribute ATTRIBUTE', 'set a document attribute in the form of name, name!, or name=value pair; can be supplied multiple times') do |value|
63
- @attr.append value
47
+ @converter.attr.append value
64
48
  end
65
49
 
66
50
  opt.separator ''
@@ -69,51 +53,56 @@ module AsciidoctorDitaMap
69
53
  raise OptionParser::InvalidArgument, "not a file: #{file}" unless File.exist? file and File.file? file
70
54
  raise OptionParser::InvalidArgument, "file not readable: #{file}" unless File.readable? file
71
55
 
72
- @prep.append file
56
+ @converter.prep << File.read(file)
57
+ @converter.prep << "\n"
73
58
  end
74
59
 
75
60
  opt.on('-i', '--include-self', 'make the supplied file the toplevel topicref') do
76
- @opts[:self] = true
61
+ @converter.opts[:self] = true
77
62
  end
78
63
 
79
64
  opt.separator ''
80
65
 
81
66
  opt.on('-I', '--no-id', 'do not generate the map id attribute') do
82
- @opts[:id] = false
67
+ @converter.opts[:id] = false
83
68
  end
84
69
 
85
70
  opt.on('-M', '--no-maptitle', 'do not generate the map title') do
86
- @opts[:title] = false
71
+ @converter.opts[:title] = false
72
+ end
73
+
74
+ opt.on('-A', '--no-assembly', 'do treat assemblies as maps') do
75
+ @converter.opts[:assembly] = false
87
76
  end
88
77
 
89
78
  opt.on('-C', '--no-chunk', 'do not generate the chunk attribute') do
90
- @opts[:chunk] = false
79
+ @converter.opts[:chunk] = false
91
80
  end
92
81
 
93
82
  opt.on('-L', '--no-locktitle', 'do not generate the locktitle attribute') do
94
- @opts[:locktitle] = false
83
+ @converter.opts[:locktitle] = false
95
84
  end
96
85
 
97
86
  opt.on('-N', '--no-navtitle', 'do not generate the navtitle attribute') do
98
- @opts[:navtitle] = false
87
+ @converter.opts[:navtitle] = false
99
88
  end
100
89
 
101
90
  opt.on('-O', '--no-toc', 'do not generate the toc attribute') do
102
- @opts[:toc] = false
91
+ @converter.opts[:toc] = false
103
92
  end
104
93
 
105
94
  opt.on('-T', '--no-type', 'do not generate the type attribute') do
106
- @opts[:type] = false
95
+ @converter.opts[:type] = false
107
96
  end
108
97
 
109
98
  opt.separator ''
110
99
 
111
100
  opt.on('-v', '--verbose', 'report additional problems in the supplied files') do
112
- @opts[:verbose] = true
101
+ @converter.opts[:verbose] = true
113
102
  end
114
103
 
115
104
  opt.on('-z', '--zero-offset', 'allow include directives with zero leveloffset') do
116
- @opts[:zero_offset] = true
105
+ @converter.opts[:zero_offset] = true
117
106
  end
118
107
 
119
108
  opt.separator ''
@@ -124,7 +113,7 @@ module AsciidoctorDitaMap
124
113
  end
125
114
 
126
115
  opt.on('-V', '--version', 'display version information and exit') do
127
- puts "#{@name} #{VERSION}"
116
+ puts "#{NAME} #{VERSION}"
128
117
  exit
129
118
  end
130
119
  end
@@ -143,183 +132,22 @@ module AsciidoctorDitaMap
143
132
  return args
144
133
  end
145
134
 
146
- def compose_mapref_attributes file_info, type
147
- target_file = file_info[:target].sub(/\.adoc$/, '.ditamap')
148
- attributes = { 'href' => target_file, 'format' => 'ditamap' }
149
- attributes['type'] = type if @opts[:type]
150
- attributes['chunk'] = file_info[:chunk] if @opts[:chunk] and file_info[:chunk]
151
- attributes['toc'] = file_info[:toc] if @opts[:toc] and file_info[:toc]
152
-
153
- return attributes
154
- end
155
-
156
- def compose_topicref_attributes file_info, title, type
157
- target_file = file_info[:target].sub(/\.adoc$/, '.dita')
158
- attributes = { 'href' => target_file }
159
- attributes['navtitle'] = title if @opts[:navtitle] and title
160
- attributes['locktitle'] = 'yes' if @opts[:locktitle] and attributes['navtitle']
161
- attributes['type'] = type if @opts[:type] and type and ['concept', 'reference', 'task'].include? type
162
- attributes['chunk'] = file_info[:chunk] if @opts[:chunk] and file_info[:chunk]
163
- attributes['toc'] = file_info[:toc] if @opts[:toc] and file_info[:toc]
164
-
165
- return attributes
166
- end
167
-
168
- def get_content_type attributes
169
- document_type = attributes['_mod-docs-content-type'] ? attributes['_mod-docs-content-type'].downcase : nil
170
- document_type = attributes['_content-type'] ? attributes['_content-type'].downcase : nil unless document_type
171
- document_type = attributes['_module-type'] ? attributes['_module-type'].downcase : nil unless document_type
172
-
173
- if document_type
174
- document_type.sub!(/^assembly$/, 'concept')
175
- document_type.sub!(/^procedure$/, 'task')
176
- end
177
-
178
- unless ['concept', 'reference', 'task', 'map', 'attributes', 'snippet'].include? document_type
179
- return nil
180
- end
181
-
182
- return document_type
183
- end
184
-
185
- def parse_topic input
186
- doc = Asciidoctor.load input, safe: :secure, attributes: @attr
187
-
188
- document_title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
189
- document_type = get_content_type doc.attributes
190
-
191
- return document_title, document_type
192
- end
193
-
194
- def parse_map input, base_dir
195
- Asciidoctor::Extensions.register do
196
- include_processor CatalogIncludeDirectives
197
- end
198
-
199
- doc = Asciidoctor.load input, safe: :safe, catalog_assets: true, attributes: @attr, base_dir: base_dir
200
-
201
- include_files = doc.catalog[:include_files] ? doc.catalog[:include_files] : []
202
- map_id = doc.id ? doc.id.gsub(/["']/, '') : nil
203
- map_title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
204
- map_type = get_content_type doc.attributes
205
-
206
- info = {
207
- :id => map_id,
208
- :title => map_title,
209
- :type => map_type
210
- }
211
-
212
- return include_files, info
213
- end
214
-
215
- def convert_map input, base_dir, prepended = '', file = nil
216
- result = ''
217
-
218
- include_files, map = parse_map prepended + input, base_dir
219
-
220
- xml = REXML::Document.new
221
- xml.context[:attribute_quote] = :quote
222
- xml << REXML::XMLDecl.new('1.0', 'utf-8')
223
- xml << REXML::DocType.new('map', 'PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd"')
224
-
225
- if map[:id] and @opts[:id]
226
- xml_root = xml.add_element('map', { 'id' => map[:id] })
227
- else
228
- xml_root = xml.add_element('map')
229
- end
230
-
231
- if map[:title] and @opts[:title]
232
- xml_title = xml_root.add_element('title')
233
- xml_title.text = map[:title]
234
- end
235
-
236
- if @opts[:self] and file
237
- attributes = compose_topicref_attributes({ :target => file }, map[:title], map[:type])
238
- xml_self = xml_root.add_element('topicref', attributes)
239
- stack = [{ :offset => 0, :element => xml_self }]
240
- else
241
- stack = [{ :offset => 0, :element => xml_root }]
242
- end
243
-
244
- include_files.each do |file_info|
245
- target = file_info[:target]
246
- offset = file_info[:offset]
247
- last_offset = stack.last[:offset]
248
- full_path = base_dir + target
249
-
250
- if not File.exist? full_path and @opts[:verbose]
251
- warn "#{@name}: warning: file not found: #{target}"
252
- end
253
-
254
- begin
255
- include_title, include_type = parse_topic prepended + File.read(full_path)
256
- next if ['attributes', 'snippet'].include? include_type
257
- rescue
258
- warn "#{@name}: warning: unable to read included file: #{target}"
259
- include_title, include_type = nil, nil
260
- end
261
-
262
- if offset == 0
263
- if @opts[:zero_offset]
264
- offset = 0
265
- else
266
- warn "#{@name}: warning: invalid leveloffset - expected 1, got 0: #{target}"
267
- offset = 1
268
- end
269
- elsif offset > last_offset and offset - last_offset > 1
270
- expected_offset = last_offset + 1
271
- warn "#{@name}: warning: invalid leveloffset - expected #{expected_offset}, got #{offset}: #{target}"
272
- end
273
-
274
- while stack.length > 1 and stack.last[:offset] >= offset
275
- stack.pop
276
- end
277
-
278
- xml_parent = stack.last[:element]
279
-
280
- if include_type == 'map'
281
- attributes = compose_mapref_attributes file_info, include_type
282
- xml_element = xml_parent.add_element('mapref', attributes)
283
- else
284
- attributes = compose_topicref_attributes file_info, include_title, include_type
285
- xml_element = xml_parent.add_element('topicref', attributes)
286
- end
287
-
288
- stack.push ({ :offset => offset, :element => xml_element })
289
- end
290
-
291
- formatter = REXML::Formatters::Pretty.new(2, true)
292
- formatter.compact = true
293
- formatter.write(xml, result)
294
-
295
- result << "\n"
296
-
297
- return result
298
- end
299
-
300
135
  def run
301
- prepended = ''
302
-
303
- @prep.each do |file|
304
- prepended << File.read(file)
305
- prepended << "\n"
306
- end
307
-
308
136
  @args.each do |file|
309
137
  if file == $stdin
310
138
  base_dir = Pathname.new(Dir.pwd).expand_path
311
139
  input = $stdin.read
312
- output = @opts[:output] ? @opts[:output] : $stdout
140
+ output = @output ? @output : $stdout
313
141
  else
314
142
  base_dir = Pathname.new(file).dirname.expand_path
315
143
  input = File.read(file)
316
- output = @opts[:output] ? @opts[:output] : Pathname.new(file).sub_ext('.ditamap').to_s
144
+ output = @output ? @output : Pathname.new(file).sub_ext('.ditamap').to_s
317
145
  end
318
146
 
319
- if @opts[:self] and file != $stdin
320
- result = convert_map input, base_dir, prepended, file
147
+ if @converter.opts[:self] and file != $stdin
148
+ result = @converter.run input, base_dir, file
321
149
  else
322
- result = convert_map input, base_dir, prepended
150
+ result = @converter.run input, base_dir
323
151
  end
324
152
 
325
153
  if output == $stdout
@@ -0,0 +1,164 @@
1
+ # Copyright (C) 2026 Jaromir Hradilek
2
+
3
+ # MIT License
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the "Soft-
7
+ # ware"), to deal in the Software without restriction, including without
8
+ # limitation the rights to use, copy, modify, merge, publish, distribute,
9
+ # sublicense, and/or sell copies of the Software, and to permit persons to
10
+ # whom the Software is furnished to do so, subject to the following condi-
11
+ # tions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included
14
+ # in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABI-
18
+ # LITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19
+ # SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
20
+ # OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ # OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'rexml/document'
25
+ require_relative 'topic'
26
+ require_relative 'map'
27
+
28
+ module AsciidoctorDitaMap
29
+ class Convert
30
+ attr_accessor :attr, :opts, :prep
31
+
32
+ def initialize
33
+ @attr = []
34
+ @opts = {
35
+ :chunk => true,
36
+ :id => true,
37
+ :assembly => true,
38
+ :locktitle => true,
39
+ :navtitle => true,
40
+ :title => true,
41
+ :toc => true,
42
+ :type => true,
43
+ :self => false,
44
+ :verbose => false,
45
+ :zero_offset => false
46
+ }
47
+ @prep = ''
48
+ end
49
+
50
+ def compose_mapref_attributes element, file_info, type
51
+ target_file = file_info[:target].sub(/\.adoc$/, '.ditamap')
52
+
53
+ element.add_attribute 'href', target_file
54
+ element.add_attribute 'format', 'ditamap'
55
+ element.add_attribute 'type', type if @opts[:type]
56
+ element.add_attribute 'chunk', file_info[:chunk] if @opts[:chunk] and file_info[:chunk]
57
+ element.add_attribute 'toc', file_info[:toc] if @opts[:toc] and file_info[:toc]
58
+ end
59
+
60
+ def compose_topicref_attributes element, file_info, title, type
61
+ target_file = file_info[:target].sub(/\.adoc$/, '.dita')
62
+
63
+ element.add_attribute 'href', target_file
64
+
65
+ if file_info[:navtitle]
66
+ element.add_attribute REXML::Attribute.new('navtitle', file_info[:navtitle]) if @opts[:navtitle]
67
+ else
68
+ element.add_attribute REXML::Attribute.new('navtitle', title) if @opts[:navtitle] and title
69
+ end
70
+
71
+ element.add_attribute 'locktitle', 'yes' if @opts[:locktitle] and element['navtitle']
72
+ element.add_attribute 'type', type if @opts[:type] and type and ['concept', 'reference', 'task'].include? type
73
+ element.add_attribute 'chunk', file_info[:chunk] if @opts[:chunk] and file_info[:chunk]
74
+ element.add_attribute 'toc', file_info[:toc] if @opts[:toc] and file_info[:toc]
75
+ end
76
+
77
+ def run input, base_dir, file = nil
78
+ result = ''
79
+
80
+ map = Map.new @prep + input, base_dir, @attr
81
+
82
+ xml = REXML::Document.new
83
+ xml.context[:attribute_quote] = :quote
84
+ xml << REXML::XMLDecl.new('1.0', 'utf-8')
85
+ xml << REXML::DocType.new('map', 'PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd"')
86
+
87
+ if map.id and @opts[:id]
88
+ xml_root = xml.add_element('map', { 'id' => map.id })
89
+ else
90
+ xml_root = xml.add_element('map')
91
+ end
92
+
93
+ if map.title and @opts[:title]
94
+ xml_title = xml_root.add_element('title')
95
+ xml_title.add REXML::Text.new(map.title, false, nil, true)
96
+ end
97
+
98
+ if @opts[:self] and file
99
+ xml_self = xml_root.add_element('topicref')
100
+ compose_topicref_attributes(xml_self, { :target => file }, map.title, map.type)
101
+ stack = [{ :offset => 0, :element => xml_self }]
102
+ else
103
+ stack = [{ :offset => 0, :element => xml_root }]
104
+ end
105
+
106
+ map.includes.each do |file_info|
107
+ target = file_info[:target]
108
+ offset = file_info[:offset]
109
+ last_offset = stack.last[:offset]
110
+ full_path = base_dir + target
111
+
112
+ if not File.exist? full_path and @opts[:verbose]
113
+ warn "#{NAME}: warning: file not found: #{target}"
114
+ end
115
+
116
+ begin
117
+ topic = Topic.new @prep + File.read(full_path), @attr
118
+ next if ['attributes', 'snippet'].include? topic.type
119
+ rescue
120
+ warn "#{NAME}: warning: unable to read included file: #{target}"
121
+ topic = Topic.new ''
122
+ end
123
+
124
+ if offset == 0
125
+ if @opts[:zero_offset]
126
+ offset = 0
127
+ else
128
+ warn "#{NAME}: warning: invalid leveloffset - expected 1, got 0: #{target}"
129
+ offset = 1
130
+ end
131
+ elsif offset > last_offset and offset - last_offset > 1
132
+ expected_offset = last_offset + 1
133
+ warn "#{NAME}: warning: invalid leveloffset - expected #{expected_offset}, got #{offset}: #{target}"
134
+ end
135
+
136
+ while stack.length > 1 and stack.last[:offset] >= offset
137
+ stack.pop
138
+ end
139
+
140
+ xml_parent = stack.last[:element]
141
+
142
+ topic.type.sub!(/^assembly$/, 'concept') if not @opts[:assembly]
143
+
144
+ if topic.type == 'map' or topic.type == 'assembly'
145
+ xml_element = xml_parent.add_element('mapref')
146
+ compose_mapref_attributes xml_element, file_info, 'map'
147
+ else
148
+ xml_element = xml_parent.add_element('topicref')
149
+ compose_topicref_attributes xml_element, file_info, topic.title, topic.type
150
+ end
151
+
152
+ stack.push ({ :offset => offset, :element => xml_element })
153
+ end
154
+
155
+ formatter = REXML::Formatters::Pretty.new(2, true)
156
+ formatter.compact = true
157
+ formatter.write(xml, result)
158
+
159
+ result << "\n"
160
+
161
+ return result
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,52 @@
1
+ # Copyright (C) 2026 Jaromir Hradilek
2
+
3
+ # MIT License
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the "Soft-
7
+ # ware"), to deal in the Software without restriction, including without
8
+ # limitation the rights to use, copy, modify, merge, publish, distribute,
9
+ # sublicense, and/or sell copies of the Software, and to permit persons to
10
+ # whom the Software is furnished to do so, subject to the following condi-
11
+ # tions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included
14
+ # in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABI-
18
+ # LITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19
+ # SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
20
+ # OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ # OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'asciidoctor'
25
+ require_relative 'catalog'
26
+ require_relative 'topic'
27
+
28
+ module AsciidoctorDitaMap
29
+ class Map < Topic
30
+ attr_accessor :id, :includes
31
+
32
+ def initialize input, base_dir, attributes = []
33
+ if input.empty?
34
+ @id = nil
35
+ @title = nil
36
+ @type = nil
37
+ @includes = []
38
+ else
39
+ Asciidoctor::Extensions.register do
40
+ include_processor CatalogIncludeDirectives
41
+ end
42
+
43
+ doc = Asciidoctor.load input, safe: :safe, catalog_assets: true, attributes: attributes, base_dir: base_dir
44
+
45
+ @includes = doc.catalog[:include_files] ? doc.catalog[:include_files] : []
46
+ @id = doc.id ? doc.id.gsub(/["']/, '') : nil
47
+ @title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
48
+ @type = get_content_type doc.attributes
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,60 @@
1
+ # Copyright (C) 2026 Jaromir Hradilek
2
+
3
+ # MIT License
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the "Soft-
7
+ # ware"), to deal in the Software without restriction, including without
8
+ # limitation the rights to use, copy, modify, merge, publish, distribute,
9
+ # sublicense, and/or sell copies of the Software, and to permit persons to
10
+ # whom the Software is furnished to do so, subject to the following condi-
11
+ # tions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included
14
+ # in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABI-
18
+ # LITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19
+ # SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
20
+ # OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ # OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'asciidoctor'
25
+
26
+ module AsciidoctorDitaMap
27
+ class Topic
28
+ attr_accessor :title, :type
29
+
30
+ def initialize input, attributes = []
31
+ if input.empty?
32
+ @title = nil
33
+ @type = nil
34
+ else
35
+ doc = Asciidoctor.load input, safe: :secure, attributes: attributes
36
+
37
+ @title = doc.title ? doc.title.gsub(/<[^>]*>/, '') : nil
38
+ @type = get_content_type doc.attributes
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def get_content_type attributes
45
+ type = attributes['_mod-docs-content-type'] ? attributes['_mod-docs-content-type'].downcase : nil
46
+ type = attributes['_content-type'] ? attributes['_content-type'].downcase : nil unless type
47
+ type = attributes['_module-type'] ? attributes['_module-type'].downcase : nil unless type
48
+
49
+ if type
50
+ type.sub!(/^procedure$/, 'task')
51
+ end
52
+
53
+ unless ['assembly', 'concept', 'reference', 'task', 'map', 'attributes', 'snippet'].include? type
54
+ return nil
55
+ end
56
+
57
+ return type
58
+ end
59
+ end
60
+ end
@@ -24,5 +24,6 @@
24
24
  # frozen_string_literal: true
25
25
 
26
26
  module AsciidoctorDitaMap
27
- VERSION = '0.9.4'
27
+ NAME = 'dita-map'
28
+ VERSION = '0.9.5'
28
29
  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.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaromir Hradilek
@@ -117,6 +117,9 @@ files:
117
117
  - bin/dita-map
118
118
  - lib/dita-map/catalog.rb
119
119
  - lib/dita-map/cli.rb
120
+ - lib/dita-map/convert.rb
121
+ - lib/dita-map/map.rb
122
+ - lib/dita-map/topic.rb
120
123
  - lib/dita-map/version.rb
121
124
  homepage: https://github.com/jhradilek/asciidoctor-dita-map
122
125
  licenses: