asciidoctor 2.0.10 → 2.0.17

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +294 -30
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +16 -20
  5. data/README-fr.adoc +15 -22
  6. data/README-jp.adoc +15 -26
  7. data/README-zh_CN.adoc +21 -25
  8. data/README.adoc +161 -138
  9. data/asciidoctor.gemspec +6 -13
  10. data/data/locale/attributes-ar.adoc +4 -3
  11. data/data/locale/attributes-be.adoc +23 -0
  12. data/data/locale/attributes-bg.adoc +4 -3
  13. data/data/locale/attributes-ca.adoc +6 -5
  14. data/data/locale/attributes-cs.adoc +4 -3
  15. data/data/locale/attributes-da.adoc +6 -5
  16. data/data/locale/attributes-de.adoc +4 -4
  17. data/data/locale/attributes-en.adoc +4 -4
  18. data/data/locale/attributes-es.adoc +6 -5
  19. data/data/locale/attributes-fa.adoc +4 -3
  20. data/data/locale/attributes-fi.adoc +4 -3
  21. data/data/locale/attributes-fr.adoc +8 -7
  22. data/data/locale/attributes-hu.adoc +4 -3
  23. data/data/locale/attributes-id.adoc +4 -3
  24. data/data/locale/attributes-it.adoc +6 -5
  25. data/data/locale/attributes-ja.adoc +4 -3
  26. data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
  27. data/data/locale/attributes-nb.adoc +4 -3
  28. data/data/locale/attributes-nl.adoc +6 -5
  29. data/data/locale/attributes-nn.adoc +4 -3
  30. data/data/locale/attributes-pl.adoc +8 -7
  31. data/data/locale/attributes-pt.adoc +6 -5
  32. data/data/locale/attributes-pt_BR.adoc +6 -5
  33. data/data/locale/attributes-ro.adoc +4 -3
  34. data/data/locale/attributes-ru.adoc +6 -5
  35. data/data/locale/attributes-sr.adoc +4 -4
  36. data/data/locale/attributes-sr_Latn.adoc +4 -4
  37. data/data/locale/attributes-sv.adoc +4 -4
  38. data/data/locale/attributes-th.adoc +23 -0
  39. data/data/locale/attributes-tr.adoc +4 -3
  40. data/data/locale/attributes-uk.adoc +6 -5
  41. data/data/locale/attributes-vi.adoc +23 -0
  42. data/data/locale/attributes-zh_CN.adoc +4 -3
  43. data/data/locale/attributes-zh_TW.adoc +4 -3
  44. data/data/reference/syntax.adoc +14 -7
  45. data/data/stylesheets/asciidoctor-default.css +76 -76
  46. data/data/stylesheets/coderay-asciidoctor.css +9 -9
  47. data/lib/asciidoctor/abstract_block.rb +20 -13
  48. data/lib/asciidoctor/abstract_node.rb +23 -12
  49. data/lib/asciidoctor/attribute_list.rb +64 -72
  50. data/lib/asciidoctor/block.rb +6 -6
  51. data/lib/asciidoctor/cli/invoker.rb +3 -2
  52. data/lib/asciidoctor/cli/options.rb +32 -31
  53. data/lib/asciidoctor/convert.rb +168 -162
  54. data/lib/asciidoctor/converter/docbook5.rb +49 -34
  55. data/lib/asciidoctor/converter/html5.rb +180 -139
  56. data/lib/asciidoctor/converter/manpage.rb +118 -90
  57. data/lib/asciidoctor/converter/template.rb +15 -13
  58. data/lib/asciidoctor/converter.rb +19 -16
  59. data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
  60. data/lib/asciidoctor/document.rb +77 -86
  61. data/lib/asciidoctor/extensions.rb +22 -16
  62. data/lib/asciidoctor/helpers.rb +20 -15
  63. data/lib/asciidoctor/list.rb +2 -6
  64. data/lib/asciidoctor/load.rb +103 -101
  65. data/lib/asciidoctor/logging.rb +10 -8
  66. data/lib/asciidoctor/parser.rb +211 -220
  67. data/lib/asciidoctor/path_resolver.rb +17 -15
  68. data/lib/asciidoctor/reader.rb +87 -79
  69. data/lib/asciidoctor/rx.rb +9 -7
  70. data/lib/asciidoctor/section.rb +7 -0
  71. data/lib/asciidoctor/substitutors.rb +167 -148
  72. data/lib/asciidoctor/syntax_highlighter/coderay.rb +3 -2
  73. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +13 -5
  74. data/lib/asciidoctor/syntax_highlighter/prettify.rb +7 -4
  75. data/lib/asciidoctor/syntax_highlighter/pygments.rb +19 -11
  76. data/lib/asciidoctor/syntax_highlighter/rouge.rb +35 -20
  77. data/lib/asciidoctor/syntax_highlighter.rb +16 -16
  78. data/lib/asciidoctor/table.rb +70 -43
  79. data/lib/asciidoctor/timings.rb +3 -3
  80. data/lib/asciidoctor/version.rb +1 -1
  81. data/lib/asciidoctor.rb +45 -19
  82. data/man/asciidoctor.1 +29 -31
  83. data/man/asciidoctor.adoc +35 -29
  84. metadata +17 -70
@@ -1,117 +1,119 @@
1
+ # frozen_string_literal: true
1
2
  module Asciidoctor
2
- module_function
3
+ class << self
4
+ # Public: Parse the AsciiDoc source input into a {Document}
5
+ #
6
+ # Accepts input as an IO (or StringIO), String or String Array object. If the
7
+ # input is a File, the object is expected to be opened for reading and is not
8
+ # closed afterwards by this method. Information about the file (filename,
9
+ # directory name, etc) gets assigned to attributes on the Document object.
10
+ #
11
+ # input - the AsciiDoc source as a IO, String or Array.
12
+ # options - a String, Array or Hash of options to control processing (default: {})
13
+ # String and Array values are converted into a Hash.
14
+ # See {Document#initialize} for details about these options.
15
+ #
16
+ # Returns the Document
17
+ def load input, options = {}
18
+ options = options.merge
3
19
 
4
- # Public: Parse the AsciiDoc source input into a {Document}
5
- #
6
- # Accepts input as an IO (or StringIO), String or String Array object. If the
7
- # input is a File, the object is expected to be opened for reading and is not
8
- # closed afterwards by this method. Information about the file (filename,
9
- # directory name, etc) gets assigned to attributes on the Document object.
10
- #
11
- # input - the AsciiDoc source as a IO, String or Array.
12
- # options - a String, Array or Hash of options to control processing (default: {})
13
- # String and Array values are converted into a Hash.
14
- # See {Document#initialize} for details about these options.
15
- #
16
- # Returns the Document
17
- def load input, options = {}
18
- options = options.merge
19
-
20
- if (timings = options[:timings])
21
- timings.start :read
22
- end
20
+ if (timings = options[:timings])
21
+ timings.start :read
22
+ end
23
23
 
24
- if (logger = options[:logger]) && logger != LoggerManager.logger
25
- LoggerManager.logger = logger
26
- end
24
+ if (options.key? :logger) && (logger = options[:logger]) != LoggerManager.logger
25
+ LoggerManager.logger = logger || NullLogger.new
26
+ end
27
27
 
28
- if !(attrs = options[:attributes])
29
- attrs = {}
30
- elsif ::Hash === attrs
31
- attrs = attrs.merge
32
- elsif (defined? ::Java::JavaUtil::Map) && ::Java::JavaUtil::Map === attrs
33
- attrs = attrs.dup
34
- elsif ::Array === attrs
35
- attrs = {}.tap do |accum|
36
- attrs.each do |entry|
37
- k, _, v = entry.partition '='
38
- accum[k] = v
28
+ if !(attrs = options[:attributes])
29
+ attrs = {}
30
+ elsif ::Hash === attrs
31
+ attrs = attrs.merge
32
+ elsif (defined? ::Java::JavaUtil::Map) && ::Java::JavaUtil::Map === attrs
33
+ attrs = attrs.dup
34
+ elsif ::Array === attrs
35
+ attrs = {}.tap do |accum|
36
+ attrs.each do |entry|
37
+ k, _, v = entry.partition '='
38
+ accum[k] = v
39
+ end
39
40
  end
40
- end
41
- elsif ::String === attrs
42
- # condense and convert non-escaped spaces to null, unescape escaped spaces, then split on null
43
- attrs = {}.tap do |accum|
44
- attrs.gsub(SpaceDelimiterRx, '\1' + NULL).gsub(EscapedSpaceRx, '\1').split(NULL).each do |entry|
45
- k, _, v = entry.partition '='
46
- accum[k] = v
41
+ elsif ::String === attrs
42
+ # condense and convert non-escaped spaces to null, unescape escaped spaces, then split on null
43
+ attrs = {}.tap do |accum|
44
+ attrs.gsub(SpaceDelimiterRx, '\1' + NULL).gsub(EscapedSpaceRx, '\1').split(NULL).each do |entry|
45
+ k, _, v = entry.partition '='
46
+ accum[k] = v
47
+ end
47
48
  end
49
+ elsif (attrs.respond_to? :keys) && (attrs.respond_to? :[])
50
+ # coerce attrs to a real Hash
51
+ attrs = {}.tap {|accum| attrs.keys.each {|k| accum[k] = attrs[k] } }
52
+ else
53
+ raise ::ArgumentError, %(illegal type for attributes option: #{attrs.class.ancestors.join ' < '})
48
54
  end
49
- elsif (attrs.respond_to? :keys) && (attrs.respond_to? :[])
50
- # coerce attrs to a real Hash
51
- attrs = {}.tap {|accum| attrs.keys.each {|k| accum[k] = attrs[k] } }
52
- else
53
- raise ::ArgumentError, %(illegal type for attributes option: #{attrs.class.ancestors.join ' < '})
54
- end
55
55
 
56
- if ::File === input
57
- options[:input_mtime] = input.mtime
58
- # NOTE defer setting infile and indir until we get a better sense of their purpose
59
- # TODO cli checks if input path can be read and is file, but might want to add check to API too
60
- attrs['docfile'] = input_path = ::File.absolute_path input.path
61
- attrs['docdir'] = ::File.dirname input_path
62
- attrs['docname'] = Helpers.basename input_path, (attrs['docfilesuffix'] = Helpers.extname input_path)
63
- source = input.read
64
- elsif input.respond_to? :read
65
- # NOTE tty, pipes & sockets can't be rewound, but can't be sniffed easily either
66
- # just fail the rewind operation silently to handle all cases
67
- input.rewind rescue nil
68
- source = input.read
69
- elsif ::String === input
70
- source = input
71
- elsif ::Array === input
72
- source = input.drop 0
73
- elsif input
74
- raise ::ArgumentError, %(unsupported input type: #{input.class})
75
- end
56
+ if ::File === input
57
+ # File#mtime on JRuby 9.1 for Windows doesn't honor TZ environment variable; see https://github.com/jruby/jruby/issues/6659
58
+ options[:input_mtime] = RUBY_ENGINE == 'jruby' ? (::Time.at input.mtime.to_i) : input.mtime
59
+ # NOTE defer setting infile and indir until we get a better sense of their purpose
60
+ # TODO cli checks if input path can be read and is file, but might want to add check to API too
61
+ attrs['docfile'] = input_path = ::File.absolute_path input.path
62
+ attrs['docdir'] = ::File.dirname input_path
63
+ attrs['docname'] = Helpers.basename input_path, (attrs['docfilesuffix'] = Helpers.extname input_path)
64
+ source = input.read
65
+ elsif input.respond_to? :read
66
+ # NOTE tty, pipes & sockets can't be rewound, but can't be sniffed easily either
67
+ # just fail the rewind operation silently to handle all cases
68
+ input.rewind rescue nil
69
+ source = input.read
70
+ elsif ::String === input
71
+ source = input
72
+ elsif ::Array === input
73
+ source = input.drop 0
74
+ elsif input
75
+ raise ::ArgumentError, %(unsupported input type: #{input.class})
76
+ end
76
77
 
77
- if timings
78
- timings.record :read
79
- timings.start :parse
80
- end
78
+ if timings
79
+ timings.record :read
80
+ timings.start :parse
81
+ end
81
82
 
82
- options[:attributes] = attrs
83
- doc = options[:parse] == false ? (Document.new source, options) : (Document.new source, options).parse
83
+ options[:attributes] = attrs
84
+ doc = options[:parse] == false ? (Document.new source, options) : (Document.new source, options).parse
84
85
 
85
- timings.record :parse if timings
86
- doc
87
- rescue => ex
88
- begin
89
- context = %(asciidoctor: FAILED: #{attrs['docfile'] || '<stdin>'}: Failed to load AsciiDoc document)
90
- if ex.respond_to? :exception
91
- # The original message must be explicitly preserved when wrapping a Ruby exception
92
- wrapped_ex = ex.exception %(#{context} - #{ex.message})
93
- # JRuby automatically sets backtrace; MRI did not until 2.6
94
- wrapped_ex.set_backtrace ex.backtrace
95
- else
96
- # Likely a Java exception class
97
- wrapped_ex = ex.class.new context, ex
98
- wrapped_ex.stack_trace = ex.stack_trace
86
+ timings.record :parse if timings
87
+ doc
88
+ rescue => e
89
+ begin
90
+ context = %(asciidoctor: FAILED: #{attrs['docfile'] || '<stdin>'}: Failed to load AsciiDoc document)
91
+ if e.respond_to? :exception
92
+ # The original message must be explicitly preserved when wrapping a Ruby exception
93
+ wrapped_e = e.exception %(#{context} - #{e.message})
94
+ # JRuby automatically sets backtrace; MRI did not until 2.6
95
+ wrapped_e.set_backtrace e.backtrace
96
+ else
97
+ # Likely a Java exception class
98
+ wrapped_e = e.class.new context, e
99
+ wrapped_e.stack_trace = e.stack_trace
100
+ end
101
+ rescue
102
+ wrapped_e = e
99
103
  end
100
- rescue
101
- wrapped_ex = ex
104
+ raise wrapped_e
102
105
  end
103
- raise wrapped_ex
104
- end
105
106
 
106
- # Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
107
- #
108
- # input - the String AsciiDoc source filename
109
- # options - a String, Array or Hash of options to control processing (default: {})
110
- # String and Array values are converted into a Hash.
111
- # See Asciidoctor::Document#initialize for details about options.
112
- #
113
- # Returns the Asciidoctor::Document
114
- def load_file filename, options = {}
115
- ::File.open(filename, FILE_READ_MODE) {|file| load file, options }
107
+ # Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
108
+ #
109
+ # input - the String AsciiDoc source filename
110
+ # options - a String, Array or Hash of options to control processing (default: {})
111
+ # String and Array values are converted into a Hash.
112
+ # See Asciidoctor::Document#initialize for details about options.
113
+ #
114
+ # Returns the Asciidoctor::Document
115
+ def load_file filename, options = {}
116
+ ::File.open(filename, FILE_READ_MODE) {|file| load file, options }
117
+ end
116
118
  end
117
119
  end
@@ -20,10 +20,10 @@ class Logger < ::Logger
20
20
  end
21
21
 
22
22
  class BasicFormatter < Formatter
23
- SEVERITY_LABELS = { 'WARN' => 'WARNING', 'FATAL' => 'FAILED' }
23
+ SEVERITY_LABEL_SUBSTITUTES = { 'WARN' => 'WARNING', 'FATAL' => 'FAILED' }
24
24
 
25
25
  def call severity, _, progname, msg
26
- %(#{progname}: #{SEVERITY_LABELS[severity] || severity}: #{::String === msg ? msg : msg.inspect}#{LF})
26
+ %(#{progname}: #{SEVERITY_LABEL_SUBSTITUTES[severity] || severity}: #{::String === msg ? msg : msg.inspect}#{LF})
27
27
  end
28
28
  end
29
29
 
@@ -35,7 +35,7 @@ class Logger < ::Logger
35
35
  end
36
36
 
37
37
  class MemoryLogger < ::Logger
38
- SEVERITY_LABELS = {}.tap {|accum| (Severity.constants false).each {|c| accum[Severity.const_get c, false] = c } }
38
+ SEVERITY_SYMBOL_BY_VALUE = (Severity.constants false).map {|c| [(Severity.const_get c), c] }.to_h
39
39
 
40
40
  attr_reader :messages
41
41
 
@@ -45,8 +45,8 @@ class MemoryLogger < ::Logger
45
45
  end
46
46
 
47
47
  def add severity, message = nil, progname = nil
48
- message = block_given? ? yield : progname unless message
49
- @messages << { severity: SEVERITY_LABELS[severity || UNKNOWN], message: message }
48
+ message ||= block_given? ? yield : progname
49
+ @messages << { severity: SEVERITY_SYMBOL_BY_VALUE[severity || UNKNOWN], message: message }
50
50
  true
51
51
  end
52
52
 
@@ -59,7 +59,7 @@ class MemoryLogger < ::Logger
59
59
  end
60
60
 
61
61
  def max_severity
62
- empty? ? nil : @messages.map {|m| Severity.const_get m[:severity], false }.max
62
+ empty? ? nil : @messages.map {|m| Severity.const_get m[:severity] }.max
63
63
  end
64
64
  end
65
65
 
@@ -89,6 +89,7 @@ module LoggerManager
89
89
  @logger ||= (@logger_class.new pipe)
90
90
  end
91
91
 
92
+ # Returns the specified Logger
92
93
  def logger= new_logger
93
94
  @logger = new_logger || (@logger_class.new $stderr)
94
95
  end
@@ -110,9 +111,10 @@ module Logging
110
111
  # into - The Class that includes the {Logging} module
111
112
  #
112
113
  # Returns nothing
113
- private_class_method def self.included into
114
+ def self.included into
114
115
  into.extend Logging
115
- end || :included
116
+ end
117
+ private_class_method :included # use separate declaration for Ruby 2.0.x
116
118
 
117
119
  def logger
118
120
  LoggerManager.logger