asciidoctor 1.5.6.2 → 1.5.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +330 -143
- data/README-fr.adoc +441 -0
- data/README-jp.adoc +418 -0
- data/README-zh_CN.adoc +430 -0
- data/README.adoc +454 -0
- data/Rakefile +57 -0
- data/asciidoctor.gemspec +7 -1
- data/data/locale/attributes-ar.adoc +22 -0
- data/data/locale/attributes-bg.adoc +22 -0
- data/data/locale/attributes-ca.adoc +22 -0
- data/data/locale/attributes-cs.adoc +22 -0
- data/data/locale/attributes-da.adoc +22 -0
- data/data/locale/attributes-de.adoc +22 -0
- data/data/locale/attributes-en.adoc +23 -0
- data/data/locale/attributes-es.adoc +22 -0
- data/data/locale/attributes-fa.adoc +22 -0
- data/data/locale/attributes-fi.adoc +22 -0
- data/data/locale/attributes-fr.adoc +22 -0
- data/data/locale/attributes-hu.adoc +22 -0
- data/data/locale/attributes-id.adoc +22 -0
- data/data/locale/attributes-it.adoc +22 -0
- data/data/locale/attributes-ja.adoc +22 -0
- data/data/locale/attributes-kr.adoc +22 -0
- data/data/locale/attributes-nb.adoc +22 -0
- data/data/locale/attributes-nl.adoc +22 -0
- data/data/locale/attributes-nn.adoc +22 -0
- data/data/locale/attributes-pl.adoc +22 -0
- data/data/locale/attributes-pt.adoc +22 -0
- data/data/locale/attributes-pt_BR.adoc +22 -0
- data/data/locale/attributes-ro.adoc +22 -0
- data/data/locale/attributes-ru.adoc +22 -0
- data/data/locale/attributes-sr.adoc +22 -0
- data/data/locale/attributes-sr_Latn.adoc +22 -0
- data/data/locale/attributes-tr.adoc +22 -0
- data/data/locale/attributes-uk.adoc +22 -0
- data/data/locale/attributes-zh_CN.adoc +22 -0
- data/data/locale/attributes-zh_TW.adoc +22 -0
- data/data/locale/attributes.adoc +8 -649
- data/data/stylesheets/asciidoctor-default.css +77 -72
- data/features/xref.feature +366 -7
- data/lib/asciidoctor.rb +107 -93
- data/lib/asciidoctor/abstract_block.rb +247 -239
- data/lib/asciidoctor/abstract_node.rb +56 -58
- data/lib/asciidoctor/block.rb +3 -3
- data/lib/asciidoctor/callouts.rb +1 -1
- data/lib/asciidoctor/cli/invoker.rb +36 -9
- data/lib/asciidoctor/cli/options.rb +63 -25
- data/lib/asciidoctor/converter.rb +23 -13
- data/lib/asciidoctor/converter/base.rb +4 -0
- data/lib/asciidoctor/converter/docbook45.rb +16 -9
- data/lib/asciidoctor/converter/docbook5.rb +115 -97
- data/lib/asciidoctor/converter/factory.rb +29 -31
- data/lib/asciidoctor/converter/html5.rb +229 -192
- data/lib/asciidoctor/converter/manpage.rb +72 -50
- data/lib/asciidoctor/converter/template.rb +12 -12
- data/lib/asciidoctor/core_ext.rb +5 -1
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +6 -0
- data/lib/asciidoctor/document.rb +168 -77
- data/lib/asciidoctor/extensions.rb +79 -47
- data/lib/asciidoctor/helpers.rb +33 -11
- data/lib/asciidoctor/inline.rb +3 -2
- data/lib/asciidoctor/list.rb +2 -1
- data/lib/asciidoctor/logging.rb +122 -0
- data/lib/asciidoctor/parser.rb +406 -382
- data/lib/asciidoctor/path_resolver.rb +169 -162
- data/lib/asciidoctor/reader.rb +166 -121
- data/lib/asciidoctor/section.rb +45 -28
- data/lib/asciidoctor/stylesheets.rb +13 -5
- data/lib/asciidoctor/substitutors.rb +328 -254
- data/lib/asciidoctor/table.rb +105 -48
- data/lib/asciidoctor/timings.rb +34 -6
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +41 -23
- data/man/asciidoctor.adoc +14 -8
- data/test/api_test.rb +1004 -0
- data/test/attributes_test.rb +241 -50
- data/test/blocks_test.rb +549 -124
- data/test/converter_test.rb +170 -78
- data/test/document_test.rb +208 -767
- data/test/extensions_test.rb +188 -53
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +1 -1
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +1 -1
- data/test/fixtures/file-with-missing-include.adoc +1 -0
- data/test/fixtures/include-file.jsx +8 -0
- data/test/fixtures/lists.adoc +96 -0
- data/test/fixtures/other-chapters.adoc +11 -0
- data/test/fixtures/outer-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +5 -1
- data/test/fixtures/subdir/index.adoc +3 -0
- data/test/fixtures/subdir/inner-include.adoc +3 -0
- data/test/fixtures/subdir/middle-include.adoc +5 -0
- data/test/fixtures/tagged-class-enclosed.rb +0 -1
- data/test/fixtures/unclosed-tag.adoc +3 -0
- data/test/fixtures/unexpected-end-tag.adoc +4 -0
- data/test/invoker_test.rb +101 -40
- data/test/links_test.rb +266 -72
- data/test/lists_test.rb +243 -45
- data/test/logger_test.rb +211 -0
- data/test/manpage_test.rb +124 -6
- data/test/options_test.rb +46 -1
- data/test/paragraphs_test.rb +23 -10
- data/test/parser_test.rb +30 -1
- data/test/paths_test.rb +115 -33
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +337 -81
- data/test/sections_test.rb +656 -72
- data/test/substitutions_test.rb +182 -57
- data/test/tables_test.rb +324 -57
- data/test/test_helper.rb +77 -32
- data/test/text_test.rb +7 -7
- metadata +67 -3
@@ -4,26 +4,26 @@ module Asciidoctor
|
|
4
4
|
# node of AsciiDoc content. The state and methods on this class are comment to
|
5
5
|
# all content segments in an AsciiDoc document.
|
6
6
|
class AbstractNode
|
7
|
-
|
7
|
+
include Logging
|
8
8
|
include Substitutors
|
9
9
|
|
10
|
-
# Public: Get the
|
11
|
-
attr_reader :
|
12
|
-
|
13
|
-
# Public: Get the Asciidoctor::Document to which this node belongs
|
14
|
-
attr_reader :document
|
10
|
+
# Public: Get the Hash of attributes for this node
|
11
|
+
attr_reader :attributes
|
15
12
|
|
16
13
|
# Public: Get the Symbol context for this node
|
17
14
|
attr_reader :context
|
18
15
|
|
19
|
-
# Public: Get the
|
20
|
-
attr_reader :
|
16
|
+
# Public: Get the Asciidoctor::Document to which this node belongs
|
17
|
+
attr_reader :document
|
21
18
|
|
22
19
|
# Public: Get/Set the id of this node
|
23
20
|
attr_accessor :id
|
24
21
|
|
25
|
-
# Public: Get the
|
26
|
-
attr_reader :
|
22
|
+
# Public: Get the String name of this node
|
23
|
+
attr_reader :node_name
|
24
|
+
|
25
|
+
# Public: Get the element which is the parent of this node
|
26
|
+
attr_reader :parent
|
27
27
|
|
28
28
|
def initialize parent, context, opts = {}
|
29
29
|
if context == :document
|
@@ -42,22 +42,6 @@ class AbstractNode
|
|
42
42
|
@passthroughs = {}
|
43
43
|
end
|
44
44
|
|
45
|
-
# Public: Associate this Block with a new parent Block
|
46
|
-
#
|
47
|
-
# parent - The Block to set as the parent of this Block
|
48
|
-
#
|
49
|
-
# Returns nothing
|
50
|
-
def parent=(parent)
|
51
|
-
@parent, @document = parent, parent.document
|
52
|
-
nil
|
53
|
-
end
|
54
|
-
|
55
|
-
# Public: Get the Asciidoctor::Converter instance being used to convert the
|
56
|
-
# current Asciidoctor::Document.
|
57
|
-
def converter
|
58
|
-
@document.converter
|
59
|
-
end
|
60
|
-
|
61
45
|
# Public: Returns whether this {AbstractNode} is an instance of {Block}
|
62
46
|
#
|
63
47
|
# Returns [Boolean]
|
@@ -76,6 +60,21 @@ class AbstractNode
|
|
76
60
|
# :nocov:
|
77
61
|
end
|
78
62
|
|
63
|
+
# Public: Get the Asciidoctor::Converter instance being used to convert the
|
64
|
+
# current Asciidoctor::Document.
|
65
|
+
def converter
|
66
|
+
@document.converter
|
67
|
+
end
|
68
|
+
|
69
|
+
# Public: Associate this Block with a new parent Block
|
70
|
+
#
|
71
|
+
# parent - The Block to set as the parent of this Block
|
72
|
+
#
|
73
|
+
# Returns the new parent Block associated with this Block
|
74
|
+
def parent= parent
|
75
|
+
@parent, @document = parent, parent.document
|
76
|
+
end
|
77
|
+
|
79
78
|
# Public: Get the value of the specified attribute
|
80
79
|
#
|
81
80
|
# Get the value for the specified attribute. First look in the attributes on
|
@@ -212,7 +211,7 @@ class AbstractNode
|
|
212
211
|
# in the list of roles on this node
|
213
212
|
def has_role?(name)
|
214
213
|
# NOTE center + include? is faster than split + include?
|
215
|
-
(val = @attributes['role'] || @document.attributes['role'])
|
214
|
+
(val = @attributes['role'] || @document.attributes['role']) ? %( #{val} ).include?(%( #{name} )) : false
|
216
215
|
end
|
217
216
|
|
218
217
|
# Public: A convenience method that adds the given role directly to this node
|
@@ -279,15 +278,14 @@ class AbstractNode
|
|
279
278
|
# Returns A String reference or data URI for an icon image
|
280
279
|
def icon_uri name
|
281
280
|
if attr? 'icon'
|
282
|
-
|
283
|
-
|
284
|
-
%(#{
|
285
|
-
else
|
286
|
-
uri
|
281
|
+
if ::File.extname(icon = (attr 'icon')).empty?
|
282
|
+
# QUESTION should we be adding the extension if the icon is an absolute URI?
|
283
|
+
icon = %(#{icon}.#{@document.attr 'icontype', 'png'})
|
287
284
|
end
|
288
285
|
else
|
289
|
-
|
286
|
+
icon = %(#{name}.#{@document.attr 'icontype', 'png'})
|
290
287
|
end
|
288
|
+
image_uri icon, 'iconsdir'
|
291
289
|
end
|
292
290
|
|
293
291
|
# Public: Construct a URI reference or data URI to the target image.
|
@@ -367,15 +365,15 @@ class AbstractNode
|
|
367
365
|
image_path = normalize_system_path(target_image)
|
368
366
|
end
|
369
367
|
|
370
|
-
|
371
|
-
|
372
|
-
|
368
|
+
if ::File.readable? image_path
|
369
|
+
# NOTE base64 is autoloaded by reference to ::Base64
|
370
|
+
%(data:#{mimetype};base64,#{::Base64.strict_encode64 ::IO.binread image_path})
|
371
|
+
else
|
372
|
+
logger.warn %(image to embed not found or not readable: #{image_path})
|
373
|
+
%(data:#{mimetype};base64,)
|
373
374
|
# uncomment to return 1 pixel white dot instead
|
374
|
-
#
|
375
|
+
#'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='
|
375
376
|
end
|
376
|
-
|
377
|
-
# NOTE base64 is autoloaded by reference to ::Base64
|
378
|
-
%(data:#{mimetype};base64,#{::Base64.encode64(::IO.binread image_path).delete LF})
|
379
377
|
end
|
380
378
|
|
381
379
|
# Public: Read the image data from the specified URI and generate a data URI
|
@@ -402,14 +400,14 @@ class AbstractNode
|
|
402
400
|
|
403
401
|
begin
|
404
402
|
mimetype = nil
|
405
|
-
bindata = open
|
403
|
+
bindata = open image_uri, 'rb' do |fd|
|
406
404
|
mimetype = fd.content_type
|
407
405
|
fd.read
|
408
|
-
|
406
|
+
end
|
409
407
|
# NOTE base64 is autoloaded by reference to ::Base64
|
410
|
-
%(data:#{mimetype};base64,#{::Base64.
|
408
|
+
%(data:#{mimetype};base64,#{::Base64.strict_encode64 bindata})
|
411
409
|
rescue
|
412
|
-
warn %(
|
410
|
+
logger.warn %(could not retrieve image data from URI: #{image_uri})
|
413
411
|
image_uri
|
414
412
|
# uncomment to return empty data (however, mimetype needs to be resolved)
|
415
413
|
#%(data:#{mimetype}:base64,)
|
@@ -442,8 +440,8 @@ class AbstractNode
|
|
442
440
|
# start - the String start (i.e., parent) path
|
443
441
|
# jail - the String jail path to confine the resolved path
|
444
442
|
# opts - an optional Hash of options to control processing (default: {}):
|
445
|
-
# * :recover is used to control whether the processor should
|
446
|
-
#
|
443
|
+
# * :recover is used to control whether the processor should
|
444
|
+
# automatically recover when an illegal path is encountered
|
447
445
|
# * :target_name is used in messages to refer to the path being resolved
|
448
446
|
#
|
449
447
|
# raises a SecurityError if a jail is specified and the resolved path is
|
@@ -453,10 +451,9 @@ class AbstractNode
|
|
453
451
|
# parent references resolved and self references removed. If a jail is provided,
|
454
452
|
# this path will be guaranteed to be contained within the jail.
|
455
453
|
def normalize_system_path target, start = nil, jail = nil, opts = {}
|
456
|
-
path_resolver = (@path_resolver ||= PathResolver.new)
|
457
454
|
if (doc = @document).safe < SafeMode::SAFE
|
458
455
|
if start
|
459
|
-
start = ::File.join doc.base_dir, start unless path_resolver.root? start
|
456
|
+
start = ::File.join doc.base_dir, start unless doc.path_resolver.root? start
|
460
457
|
else
|
461
458
|
start = doc.base_dir
|
462
459
|
end
|
@@ -464,7 +461,7 @@ class AbstractNode
|
|
464
461
|
start = doc.base_dir unless start
|
465
462
|
jail = doc.base_dir unless jail
|
466
463
|
end
|
467
|
-
path_resolver.system_path target, start, jail, opts
|
464
|
+
doc.path_resolver.system_path target, start, jail, opts
|
468
465
|
end
|
469
466
|
|
470
467
|
# Public: Normalize the web path using the PathResolver.
|
@@ -480,7 +477,7 @@ class AbstractNode
|
|
480
477
|
if preserve_uri_target && (Helpers.uriish? target)
|
481
478
|
uri_encode_spaces target
|
482
479
|
else
|
483
|
-
|
480
|
+
@document.path_resolver.web_path target, start
|
484
481
|
end
|
485
482
|
end
|
486
483
|
|
@@ -508,7 +505,8 @@ class AbstractNode
|
|
508
505
|
::IO.read path
|
509
506
|
end
|
510
507
|
elsif opts[:warn_on_failure]
|
511
|
-
warn %(
|
508
|
+
logger.warn %(#{(attr 'docfile') || '<stdin>'}: #{opts[:label] || 'file'} does not exist or cannot be read: #{path})
|
509
|
+
nil
|
512
510
|
end
|
513
511
|
end
|
514
512
|
|
@@ -531,25 +529,25 @@ class AbstractNode
|
|
531
529
|
def read_contents target, opts = {}
|
532
530
|
doc = @document
|
533
531
|
if (Helpers.uriish? target) || ((start = opts[:start]) && (Helpers.uriish? start) &&
|
534
|
-
(target =
|
532
|
+
(target = doc.path_resolver.web_path target, start))
|
535
533
|
if doc.attr? 'allow-uri-read'
|
536
534
|
Helpers.require_library 'open-uri/cached', 'open-uri-cached' if doc.attr? 'cache-uri'
|
537
535
|
begin
|
538
536
|
data = ::OpenURI.open_uri(target) {|fd| fd.read }
|
539
537
|
data = (Helpers.normalize_lines_from_string data) * LF if opts[:normalize]
|
538
|
+
return data
|
540
539
|
rescue
|
541
|
-
warn %(
|
542
|
-
|
540
|
+
logger.warn %(could not retrieve contents of #{opts[:label] || 'asset'} at URI: #{target}) if opts.fetch :warn_on_failure, true
|
541
|
+
return
|
543
542
|
end
|
544
543
|
else
|
545
|
-
warn %(
|
546
|
-
|
544
|
+
logger.warn %(cannot retrieve contents of #{opts[:label] || 'asset'} at URI: #{target} (allow-uri-read attribute not enabled)) if opts.fetch :warn_on_failure, true
|
545
|
+
return
|
547
546
|
end
|
548
547
|
else
|
549
548
|
target = normalize_system_path target, opts[:start], nil, :target_name => (opts[:label] || 'asset')
|
550
|
-
|
549
|
+
return read_asset target, :normalize => opts[:normalize], :warn_on_failure => (opts.fetch :warn_on_failure, true), :label => opts[:label]
|
551
550
|
end
|
552
|
-
data
|
553
551
|
end
|
554
552
|
|
555
553
|
# Internal: URI encode spaces in a String
|
data/lib/asciidoctor/block.rb
CHANGED
@@ -124,15 +124,15 @@ class Block < AbstractBlock
|
|
124
124
|
result * LF
|
125
125
|
end
|
126
126
|
else
|
127
|
-
warn %(Unknown content model '#{@content_model}' for block: #{to_s}) unless @content_model == :empty
|
127
|
+
logger.warn %(Unknown content model '#{@content_model}' for block: #{to_s}) unless @content_model == :empty
|
128
128
|
nil
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
132
|
# Public: Returns the preprocessed source of this block
|
133
133
|
#
|
134
|
-
# Returns the a String containing the lines joined together or
|
135
|
-
# are no lines
|
134
|
+
# Returns the a String containing the lines joined together or empty string
|
135
|
+
# if there are no lines
|
136
136
|
def source
|
137
137
|
@lines * LF
|
138
138
|
end
|
data/lib/asciidoctor/callouts.rb
CHANGED
@@ -59,7 +59,7 @@ class Callouts
|
|
59
59
|
#
|
60
60
|
# Returns A space-separated String of callout ids associated with the specified list item
|
61
61
|
def callout_ids li_ordinal
|
62
|
-
current_list.map {|
|
62
|
+
current_list.map {|it| it[:ordinal] == li_ordinal ? %(#{it[:id]} ) : '' }.join.chop
|
63
63
|
end
|
64
64
|
|
65
65
|
# Public: The current list for which callouts are being collected
|
@@ -3,6 +3,7 @@ module Asciidoctor
|
|
3
3
|
module Cli
|
4
4
|
# Public Invocation class for starting Asciidoctor via CLI
|
5
5
|
class Invoker
|
6
|
+
|
6
7
|
attr_reader :options
|
7
8
|
attr_reader :documents
|
8
9
|
attr_reader :code
|
@@ -29,13 +30,15 @@ module Asciidoctor
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def invoke!
|
32
|
-
old_verbose = -1
|
33
33
|
return unless @options
|
34
34
|
|
35
35
|
old_verbose = $VERBOSE
|
36
|
+
old_logger = old_logger_level = nil
|
36
37
|
opts = {}
|
37
38
|
infiles = []
|
38
39
|
outfile = nil
|
40
|
+
abs_srcdir_posix = nil
|
41
|
+
non_posix_env = ::File::ALT_SEPARATOR == RS
|
39
42
|
err = @err || $stderr
|
40
43
|
show_timings = false
|
41
44
|
|
@@ -45,6 +48,11 @@ module Asciidoctor
|
|
45
48
|
infiles = val
|
46
49
|
when :output_file
|
47
50
|
outfile = val
|
51
|
+
when :source_dir
|
52
|
+
if val
|
53
|
+
abs_srcdir_posix = ::File.expand_path val
|
54
|
+
abs_srcdir_posix = abs_srcdir_posix.tr RS, FS if non_posix_env && (abs_srcdir_posix.include? RS)
|
55
|
+
end
|
48
56
|
when :destination_dir
|
49
57
|
opts[:to_dir] = val if val
|
50
58
|
when :attributes
|
@@ -58,34 +66,36 @@ module Asciidoctor
|
|
58
66
|
case val
|
59
67
|
when 0
|
60
68
|
$VERBOSE = nil
|
69
|
+
old_logger = LoggerManager.logger
|
70
|
+
LoggerManager.logger = NullLogger.new
|
61
71
|
when 1
|
62
72
|
$VERBOSE = false
|
63
73
|
when 2
|
64
74
|
$VERBOSE = true
|
75
|
+
old_logger_level, LoggerManager.logger.level = LoggerManager.logger.level, ::Logger::Severity::DEBUG
|
65
76
|
end
|
66
77
|
else
|
67
78
|
opts[key] = val unless val.nil?
|
68
79
|
end
|
69
80
|
end
|
70
81
|
|
71
|
-
|
82
|
+
if infiles.size == 1
|
72
83
|
if (infile0 = infiles[0]) == '-'
|
73
84
|
outfile ||= infile0
|
74
|
-
true
|
85
|
+
stdin = true
|
75
86
|
elsif ::File.pipe? infile0
|
76
87
|
outfile ||= '-'
|
77
|
-
nil
|
78
88
|
end
|
79
89
|
end
|
80
90
|
|
81
|
-
|
82
|
-
@out || $stdout
|
91
|
+
if outfile == '-'
|
92
|
+
tofile = @out || $stdout
|
83
93
|
elsif outfile
|
84
94
|
opts[:mkdirs] = true
|
85
|
-
outfile
|
95
|
+
tofile = outfile
|
86
96
|
else
|
87
97
|
opts[:mkdirs] = true
|
88
|
-
|
98
|
+
# automatically calculate outfile based on infile
|
89
99
|
end
|
90
100
|
|
91
101
|
if stdin
|
@@ -101,6 +111,17 @@ module Asciidoctor
|
|
101
111
|
else
|
102
112
|
infiles.each do |infile|
|
103
113
|
input_opts = opts.merge :to_file => tofile
|
114
|
+
if abs_srcdir_posix && (input_opts.key? :to_dir)
|
115
|
+
abs_indir = ::File.dirname ::File.expand_path infile
|
116
|
+
if non_posix_env
|
117
|
+
abs_indir_posix = (abs_indir.include? RS) ? (abs_indir.tr RS, FS) : abs_indir
|
118
|
+
else
|
119
|
+
abs_indir_posix = abs_indir
|
120
|
+
end
|
121
|
+
if abs_indir_posix.start_with? %(#{abs_srcdir_posix}/)
|
122
|
+
input_opts[:to_dir] += abs_indir.slice abs_srcdir_posix.length, abs_indir.length
|
123
|
+
end
|
124
|
+
end
|
104
125
|
if show_timings
|
105
126
|
@documents << (::Asciidoctor.convert_file infile, (input_opts.merge :timings => (timings = Timings.new)))
|
106
127
|
timings.print_report err, infile
|
@@ -109,6 +130,7 @@ module Asciidoctor
|
|
109
130
|
end
|
110
131
|
end
|
111
132
|
end
|
133
|
+
@code = 1 if ((logger = LoggerManager.logger).respond_to? :max_severity) && logger.max_severity && logger.max_severity >= opts[:failure_level]
|
112
134
|
rescue ::Exception => e
|
113
135
|
if ::SignalException === e
|
114
136
|
@code = e.signo
|
@@ -129,7 +151,12 @@ module Asciidoctor
|
|
129
151
|
end
|
130
152
|
nil
|
131
153
|
ensure
|
132
|
-
$VERBOSE = old_verbose
|
154
|
+
$VERBOSE = old_verbose
|
155
|
+
if old_logger
|
156
|
+
LoggerManager.logger = old_logger
|
157
|
+
elsif old_logger_level
|
158
|
+
LoggerManager.logger.level = old_logger_level
|
159
|
+
end
|
133
160
|
end
|
134
161
|
|
135
162
|
def document
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
module Asciidoctor
|
3
3
|
module Cli
|
4
|
+
FS = '/'
|
5
|
+
RS = '\\'
|
4
6
|
|
5
7
|
# Public: List of options that can be specified on the command line
|
6
8
|
class Options < ::Hash
|
@@ -24,7 +26,9 @@ module Asciidoctor
|
|
24
26
|
self[:load_paths] = options[:load_paths] || nil
|
25
27
|
self[:requires] = options[:requires] || nil
|
26
28
|
self[:base_dir] = options[:base_dir]
|
29
|
+
self[:source_dir] = options[:source_dir] || nil
|
27
30
|
self[:destination_dir] = options[:destination_dir] || nil
|
31
|
+
self[:failure_level] = ::Logger::Severity::FATAL
|
28
32
|
self[:trace] = false
|
29
33
|
self[:timings] = false
|
30
34
|
end
|
@@ -75,8 +79,6 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
75
79
|
'specify eRuby implementation to use when rendering custom ERB templates: [erb, erubis] (default: erb)') do |eruby|
|
76
80
|
self[:eruby] = eruby
|
77
81
|
end
|
78
|
-
opts.on('-C', '--compact', 'compact the output by removing blank lines. (No longer in use)') do
|
79
|
-
end
|
80
82
|
opts.on('-a', '--attribute key[=value]', 'a document attribute to set in the form of key, key! or key=value pair',
|
81
83
|
'unless @ is appended to the value, this attributes takes precedence over attributes',
|
82
84
|
'defined in the source document') do |attr|
|
@@ -104,6 +106,9 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
104
106
|
opts.on('-B', '--base-dir DIR', 'base directory containing the document and resources (default: directory of source file)') do |base_dir|
|
105
107
|
self[:base_dir] = base_dir
|
106
108
|
end
|
109
|
+
opts.on('-R', '--source-dir DIR', 'source root directory (used for calculating path in destination directory)') do |src_dir|
|
110
|
+
self[:source_dir] = src_dir
|
111
|
+
end
|
107
112
|
opts.on('-D', '--destination-dir DIR', 'destination output directory (default: directory of source file)') do |dest_dir|
|
108
113
|
self[:destination_dir] = dest_dir
|
109
114
|
end
|
@@ -115,6 +120,10 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
115
120
|
'may be specified more than once') do |path|
|
116
121
|
(self[:requires] ||= []).concat(path.split ',')
|
117
122
|
end
|
123
|
+
opts.on('--failure-level LEVEL', %w(warning WARNING error ERROR), 'set minimum logging level that triggers a non-zero exit code: [WARN, ERROR] (default: FATAL)') do |level|
|
124
|
+
level = 'WARN' if (level = level.upcase) == 'WARNING'
|
125
|
+
self[:failure_level] = ::Logger::Severity.const_get level
|
126
|
+
end
|
118
127
|
opts.on('-q', '--quiet', 'suppress warnings (default: false)') do |verbose|
|
119
128
|
self[:verbose] = 0
|
120
129
|
end
|
@@ -132,11 +141,32 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
132
141
|
'show the command usage if TOPIC is not specified (or not recognized)',
|
133
142
|
'dump the Asciidoctor man page (in troff/groff format) if TOPIC is manpage') do |topic|
|
134
143
|
if topic == 'manpage'
|
135
|
-
if
|
136
|
-
|
144
|
+
if (manpage_path = ENV['ASCIIDOCTOR_MANPAGE_PATH'])
|
145
|
+
if ::File.exist? manpage_path
|
146
|
+
if manpage_path.end_with? '.gz'
|
147
|
+
require 'zlib' unless defined? ::Zlib::GzipReader
|
148
|
+
$stdout.puts ::Zlib::GzipReader.open(manpage_path) {|gz| gz.read }
|
149
|
+
else
|
150
|
+
$stdout.puts ::IO.read manpage_path
|
151
|
+
end
|
152
|
+
else
|
153
|
+
$stderr.puts %(asciidoctor: FAILED: manual page not found: #{manpage_path})
|
154
|
+
return 1
|
155
|
+
end
|
156
|
+
elsif ::File.exist?(manpage_path = (::File.join ::Asciidoctor::ROOT_PATH, 'man', 'asciidoctor.1'))
|
157
|
+
$stdout.puts ::IO.read manpage_path
|
137
158
|
else
|
138
|
-
|
139
|
-
|
159
|
+
require 'open3' unless defined? ::Open3.popen3
|
160
|
+
manpage_path = ::Open3.popen3('man -w asciidoctor') {|_, out| out.read }.chop rescue ''
|
161
|
+
if manpage_path.empty?
|
162
|
+
$stderr.puts 'asciidoctor: FAILED: manual page not found; try `man asciidoctor`'
|
163
|
+
return 1
|
164
|
+
elsif manpage_path.end_with? '.gz'
|
165
|
+
require 'zlib' unless defined? ::Zlib::GzipReader
|
166
|
+
$stdout.puts ::Zlib::GzipReader.open(manpage_path) {|gz| gz.read }
|
167
|
+
else
|
168
|
+
$stdout.puts ::IO.read manpage_path
|
169
|
+
end
|
140
170
|
end
|
141
171
|
else
|
142
172
|
$stdout.puts opts
|
@@ -171,31 +201,39 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
171
201
|
# warn, but don't panic; we may have enough to proceed, so we won't force a failure
|
172
202
|
$stderr.puts %(asciidoctor: WARNING: extra arguments detected (unparsed arguments: '#{args * "', '"}') or incorrect usage of stdin)
|
173
203
|
else
|
174
|
-
if ::File.
|
175
|
-
|
204
|
+
if ::File.file? file
|
205
|
+
infiles << file
|
206
|
+
# NOTE only attempt to glob if file is not found
|
176
207
|
else
|
177
208
|
# Tilt backslashes in Windows paths the Ruby-friendly way
|
178
|
-
if ::File::ALT_SEPARATOR ==
|
179
|
-
file = file.tr
|
209
|
+
if ::File::ALT_SEPARATOR == RS && (file.include? RS)
|
210
|
+
file = file.tr RS, FS
|
180
211
|
end
|
181
212
|
if (matches = ::Dir.glob file).empty?
|
182
|
-
|
183
|
-
|
213
|
+
# NOTE if no matches, assume it's just a missing file and proceed
|
214
|
+
infiles << file
|
215
|
+
else
|
216
|
+
infiles.concat matches
|
184
217
|
end
|
185
218
|
end
|
186
|
-
|
187
|
-
infiles.concat matches
|
188
219
|
end
|
189
220
|
end
|
190
221
|
end
|
191
222
|
|
192
|
-
infiles.each do |file|
|
193
|
-
|
194
|
-
|
195
|
-
|
223
|
+
infiles.reject {|file| file == '-' }.each do |file|
|
224
|
+
begin
|
225
|
+
fstat = ::File.stat file
|
226
|
+
if fstat.file? || fstat.pipe?
|
227
|
+
unless fstat.readable?
|
228
|
+
$stderr.puts %(asciidoctor: FAILED: input file #{file} is not readable)
|
229
|
+
return 1
|
230
|
+
end
|
196
231
|
else
|
197
|
-
$stderr.puts %(asciidoctor: FAILED: input
|
232
|
+
$stderr.puts %(asciidoctor: FAILED: input path #{file} is a #{fstat.ftype}, not a file)
|
233
|
+
return 1
|
198
234
|
end
|
235
|
+
rescue ::Errno::ENOENT
|
236
|
+
$stderr.puts %(asciidoctor: FAILED: input file #{file} is missing)
|
199
237
|
return 1
|
200
238
|
end
|
201
239
|
end
|
@@ -206,7 +244,7 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
206
244
|
|
207
245
|
if self[:template_dirs]
|
208
246
|
begin
|
209
|
-
require 'tilt' unless defined? ::Tilt
|
247
|
+
require 'tilt' unless defined? ::Tilt::VERSION
|
210
248
|
rescue ::LoadError
|
211
249
|
raise $! if self[:trace]
|
212
250
|
$stderr.puts 'asciidoctor: FAILED: \'tilt\' could not be loaded'
|
@@ -220,7 +258,7 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
220
258
|
|
221
259
|
if (load_paths = self[:load_paths])
|
222
260
|
(self[:load_paths] = load_paths.uniq).reverse_each do |path|
|
223
|
-
$:.unshift File.expand_path(path)
|
261
|
+
$:.unshift ::File.expand_path(path)
|
224
262
|
end
|
225
263
|
end
|
226
264
|
|
@@ -251,10 +289,10 @@ Example: asciidoctor -b html5 source.asciidoc
|
|
251
289
|
end
|
252
290
|
|
253
291
|
def print_version os = $stdout
|
254
|
-
os.puts %(Asciidoctor #{::Asciidoctor::VERSION} [
|
255
|
-
if
|
256
|
-
encoding_info = {'lc' => 'locale', 'fs' => 'filesystem', 'in' => 'internal', 'ex' => 'external'}.map do |k,v|
|
257
|
-
%(#{k}:#{::
|
292
|
+
os.puts %(Asciidoctor #{::Asciidoctor::VERSION} [https://asciidoctor.org])
|
293
|
+
if RUBY_MIN_VERSION_1_9
|
294
|
+
encoding_info = { 'lc' => 'locale', 'fs' => 'filesystem', 'in' => 'internal', 'ex' => 'external' }.map do |k, v|
|
295
|
+
%(#{k}:#{v == 'internal' ? (::File.open(__FILE__) {|f| f.getc }).encoding : (::Encoding.find v)})
|
258
296
|
end
|
259
297
|
os.puts %(Runtime Environment (#{RUBY_DESCRIPTION}) (#{encoding_info * ' '}))
|
260
298
|
else
|