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.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +294 -30
- data/LICENSE +1 -1
- data/README-de.adoc +16 -20
- data/README-fr.adoc +15 -22
- data/README-jp.adoc +15 -26
- data/README-zh_CN.adoc +21 -25
- data/README.adoc +161 -138
- data/asciidoctor.gemspec +6 -13
- data/data/locale/attributes-ar.adoc +4 -3
- data/data/locale/attributes-be.adoc +23 -0
- data/data/locale/attributes-bg.adoc +4 -3
- data/data/locale/attributes-ca.adoc +6 -5
- data/data/locale/attributes-cs.adoc +4 -3
- data/data/locale/attributes-da.adoc +6 -5
- data/data/locale/attributes-de.adoc +4 -4
- data/data/locale/attributes-en.adoc +4 -4
- data/data/locale/attributes-es.adoc +6 -5
- data/data/locale/attributes-fa.adoc +4 -3
- data/data/locale/attributes-fi.adoc +4 -3
- data/data/locale/attributes-fr.adoc +8 -7
- data/data/locale/attributes-hu.adoc +4 -3
- data/data/locale/attributes-id.adoc +4 -3
- data/data/locale/attributes-it.adoc +6 -5
- data/data/locale/attributes-ja.adoc +4 -3
- data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
- data/data/locale/attributes-nb.adoc +4 -3
- data/data/locale/attributes-nl.adoc +6 -5
- data/data/locale/attributes-nn.adoc +4 -3
- data/data/locale/attributes-pl.adoc +8 -7
- data/data/locale/attributes-pt.adoc +6 -5
- data/data/locale/attributes-pt_BR.adoc +6 -5
- data/data/locale/attributes-ro.adoc +4 -3
- data/data/locale/attributes-ru.adoc +6 -5
- data/data/locale/attributes-sr.adoc +4 -4
- data/data/locale/attributes-sr_Latn.adoc +4 -4
- data/data/locale/attributes-sv.adoc +4 -4
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-tr.adoc +4 -3
- data/data/locale/attributes-uk.adoc +6 -5
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/locale/attributes-zh_CN.adoc +4 -3
- data/data/locale/attributes-zh_TW.adoc +4 -3
- data/data/reference/syntax.adoc +14 -7
- data/data/stylesheets/asciidoctor-default.css +76 -76
- data/data/stylesheets/coderay-asciidoctor.css +9 -9
- data/lib/asciidoctor/abstract_block.rb +20 -13
- data/lib/asciidoctor/abstract_node.rb +23 -12
- data/lib/asciidoctor/attribute_list.rb +64 -72
- data/lib/asciidoctor/block.rb +6 -6
- data/lib/asciidoctor/cli/invoker.rb +3 -2
- data/lib/asciidoctor/cli/options.rb +32 -31
- data/lib/asciidoctor/convert.rb +168 -162
- data/lib/asciidoctor/converter/docbook5.rb +49 -34
- data/lib/asciidoctor/converter/html5.rb +180 -139
- data/lib/asciidoctor/converter/manpage.rb +118 -90
- data/lib/asciidoctor/converter/template.rb +15 -13
- data/lib/asciidoctor/converter.rb +19 -16
- data/lib/asciidoctor/core_ext/hash/merge.rb +1 -1
- data/lib/asciidoctor/document.rb +77 -86
- data/lib/asciidoctor/extensions.rb +22 -16
- data/lib/asciidoctor/helpers.rb +20 -15
- data/lib/asciidoctor/list.rb +2 -6
- data/lib/asciidoctor/load.rb +103 -101
- data/lib/asciidoctor/logging.rb +10 -8
- data/lib/asciidoctor/parser.rb +211 -220
- data/lib/asciidoctor/path_resolver.rb +17 -15
- data/lib/asciidoctor/reader.rb +87 -79
- data/lib/asciidoctor/rx.rb +9 -7
- data/lib/asciidoctor/section.rb +7 -0
- data/lib/asciidoctor/substitutors.rb +167 -148
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +3 -2
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +13 -5
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +7 -4
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +19 -11
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +35 -20
- data/lib/asciidoctor/syntax_highlighter.rb +16 -16
- data/lib/asciidoctor/table.rb +70 -43
- data/lib/asciidoctor/timings.rb +3 -3
- data/lib/asciidoctor/version.rb +1 -1
- data/lib/asciidoctor.rb +45 -19
- data/man/asciidoctor.1 +29 -31
- data/man/asciidoctor.adoc +35 -29
- metadata +17 -70
@@ -32,7 +32,7 @@ class SyntaxHighlighter::CodeRayAdapter < SyntaxHighlighter::Base
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def docinfo? location
|
35
|
-
@requires_stylesheet && location == :
|
35
|
+
@requires_stylesheet && location == :head
|
36
36
|
end
|
37
37
|
|
38
38
|
def docinfo location, doc, opts
|
@@ -78,7 +78,8 @@ class SyntaxHighlighter::CodeRayAdapter < SyntaxHighlighter::Base
|
|
78
78
|
end
|
79
79
|
|
80
80
|
extend Styles # exports static methods
|
81
|
-
include
|
81
|
+
include Styles # adds methods to instance
|
82
|
+
include Loader # adds methods to instance
|
82
83
|
|
83
84
|
CodeCellStartTagCs = '<td class="code"><pre>'
|
84
85
|
|
@@ -9,18 +9,26 @@ class SyntaxHighlighter::HighlightJsAdapter < SyntaxHighlighter::Base
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def format node, lang, opts
|
12
|
-
super node, lang, (opts.merge transform: proc {|_, code| code['class'] = %(language-#{lang || 'none'} hljs) }
|
12
|
+
super node, lang, (opts.merge transform: proc {|_, code| code['class'] = %(language-#{lang || 'none'} hljs) })
|
13
13
|
end
|
14
14
|
|
15
15
|
def docinfo? location
|
16
|
-
|
16
|
+
true
|
17
17
|
end
|
18
18
|
|
19
19
|
def docinfo location, doc, opts
|
20
20
|
base_url = doc.attr 'highlightjsdir', %(#{opts[:cdn_base_url]}/highlight.js/#{HIGHLIGHT_JS_VERSION})
|
21
|
-
|
22
|
-
<
|
23
|
-
|
21
|
+
if location == :head
|
22
|
+
%(<link rel="stylesheet" href="#{base_url}/styles/#{doc.attr 'highlightjs-theme', 'github'}.min.css"#{opts[:self_closing_tag_slash]}>)
|
23
|
+
else # :footer
|
24
|
+
%(<script src="#{base_url}/highlight.min.js"></script>
|
25
|
+
#{(doc.attr? 'highlightjs-languages') ? ((doc.attr 'highlightjs-languages').split ',').map {|lang| %[<script src="#{base_url}/languages/#{lang.lstrip}.min.js"></script>\n] }.join : ''}<script>
|
26
|
+
if (!hljs.initHighlighting.called) {
|
27
|
+
hljs.initHighlighting.called = true
|
28
|
+
;[].slice.call(document.querySelectorAll('pre.highlight > code')).forEach(function (el) { hljs.highlightBlock(el) })
|
29
|
+
}
|
30
|
+
</script>)
|
31
|
+
end
|
24
32
|
end
|
25
33
|
end
|
26
34
|
end
|
@@ -14,14 +14,17 @@ class SyntaxHighlighter::PrettifyAdapter < SyntaxHighlighter::Base
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def docinfo? location
|
17
|
-
|
17
|
+
true
|
18
18
|
end
|
19
19
|
|
20
20
|
def docinfo location, doc, opts
|
21
21
|
base_url = doc.attr 'prettifydir', %(#{opts[:cdn_base_url]}/prettify/r298)
|
22
|
-
|
23
|
-
|
24
|
-
<
|
22
|
+
if location == :head
|
23
|
+
prettify_theme_url = ((prettify_theme = doc.attr 'prettify-theme', 'prettify').start_with? 'http://', 'https://') ? prettify_theme : %(#{base_url}/#{prettify_theme}.min.css)
|
24
|
+
%(<link rel="stylesheet" href="#{prettify_theme_url}"#{opts[:self_closing_tag_slash]}>)
|
25
|
+
else # :footer
|
26
|
+
%(<script src="#{base_url}/run_prettify.min.js"></script>)
|
27
|
+
end
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
@@ -5,8 +5,7 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
5
5
|
|
6
6
|
def initialize *args
|
7
7
|
super
|
8
|
-
@requires_stylesheet = nil
|
9
|
-
@style = nil
|
8
|
+
@requires_stylesheet = @style = nil
|
10
9
|
end
|
11
10
|
|
12
11
|
def highlight?
|
@@ -34,13 +33,19 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
34
33
|
highlighted = highlighted.sub WrapperTagRx, PreTagCs
|
35
34
|
opts[:callouts] ? [highlighted, (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil] : highlighted
|
36
35
|
else
|
37
|
-
node.
|
36
|
+
node.sub_source source, false # handles nil response from ::Pygments::Lexer#highlight
|
38
37
|
end
|
39
38
|
elsif (highlighted = lexer.highlight source, options: highlight_opts)
|
40
|
-
|
39
|
+
if linenos
|
40
|
+
if noclasses
|
41
|
+
highlighted = highlighted.gsub StyledLinenoSpanTagRx, LinenoSpanTagCs
|
42
|
+
elsif highlighted.include? LegacyLinenoSpanStartTagCs
|
43
|
+
highlighted = highlighted.gsub LegacyLinenoSpanTagRx, LinenoSpanTagCs
|
44
|
+
end
|
45
|
+
end
|
41
46
|
highlighted.sub WrapperTagRx, '\1'
|
42
47
|
else
|
43
|
-
node.
|
48
|
+
node.sub_source source, false # handles nil response from ::Pygments::Lexer#highlight
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
@@ -53,7 +58,7 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
53
58
|
end
|
54
59
|
|
55
60
|
def docinfo? location
|
56
|
-
@requires_stylesheet && location == :
|
61
|
+
@requires_stylesheet && location == :head
|
57
62
|
end
|
58
63
|
|
59
64
|
def docinfo location, doc, opts
|
@@ -115,6 +120,7 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
115
120
|
end
|
116
121
|
@@stylesheet_cache = ::Hash.new do |cache, key|
|
117
122
|
if (stylesheet = ::Pygments.css BASE_SELECTOR, classprefix: TOKEN_CLASS_PREFIX, style: key)
|
123
|
+
stylesheet = stylesheet.slice (stylesheet.index BASE_SELECTOR), stylesheet.length unless stylesheet.start_with? BASE_SELECTOR
|
118
124
|
@@stylesheet_cache = cache.merge key => stylesheet
|
119
125
|
stylesheet
|
120
126
|
end
|
@@ -123,27 +129,29 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
|
|
123
129
|
DEFAULT_STYLE = 'default'
|
124
130
|
BASE_SELECTOR = 'pre.pygments'
|
125
131
|
TOKEN_CLASS_PREFIX = 'tok-'
|
126
|
-
|
127
132
|
BaseStyleRx = /^#{BASE_SELECTOR.gsub '.', '\\.'} +\{([^}]+?)\}/
|
128
133
|
|
129
134
|
private_constant :BASE_SELECTOR, :TOKEN_CLASS_PREFIX, :BaseStyleRx
|
130
135
|
end
|
131
136
|
|
132
137
|
extend Styles # exports static methods
|
133
|
-
include
|
138
|
+
include Styles # adds methods to instance
|
139
|
+
include Loader # adds methods to instance
|
134
140
|
|
135
141
|
CodeCellStartTagCs = '<td class="code">'
|
142
|
+
LegacyLinenoSpanStartTagCs = '<span class="lineno">'
|
143
|
+
LegacyLinenoSpanTagRx = %r(#{LegacyLinenoSpanStartTagCs}( *\d+) ?</span>)
|
136
144
|
LinenoColumnStartTagsCs = '<td class="linenos"><div class="linenodiv"><pre>'
|
137
|
-
LinenoSpanTagCs = '<span class="
|
145
|
+
LinenoSpanTagCs = '<span class="linenos">\1</span>'
|
138
146
|
PreTagCs = '<pre>\1</pre>'
|
139
147
|
StyledLinenoColumnStartTagsRx = /<td><div class="linenodiv" style="[^"]+?"><pre style="[^"]+?">/
|
140
|
-
StyledLinenoSpanTagRx = %r(<span style="
|
148
|
+
StyledLinenoSpanTagRx = %r((?<=^|<span></span>)<span style="[^"]+">( *\d+) ?</span>)
|
141
149
|
WRAPPER_CLASS = 'lineno' # doesn't appear in output; Pygments appends "table" to this value to make nested table class
|
142
150
|
# NOTE <pre> has style attribute when pygments-css=style
|
143
151
|
# NOTE <div> has trailing newline when pygments-linenums-mode=table
|
144
152
|
# NOTE initial <span></span> preserves leading blank lines
|
145
153
|
WrapperTagRx = %r(<div class="#{WRAPPER_CLASS}"><pre\b[^>]*?>(.*)</pre></div>\n*)m
|
146
154
|
|
147
|
-
private_constant :CodeCellStartTagCs, :LinenoColumnStartTagsCs, :LinenoSpanTagCs, :PreTagCs, :StyledLinenoColumnStartTagsRx, :StyledLinenoSpanTagRx, :WrapperTagRx, :WRAPPER_CLASS
|
155
|
+
private_constant :CodeCellStartTagCs, :LegacyLinenoSpanStartTagCs, :LegacyLinenoSpanTagRx, :LinenoColumnStartTagsCs, :LinenoSpanTagCs, :PreTagCs, :StyledLinenoColumnStartTagsRx, :StyledLinenoSpanTagRx, :WrapperTagRx, :WRAPPER_CLASS
|
148
156
|
end
|
149
157
|
end
|
@@ -13,40 +13,30 @@ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def highlight node, source, lang, opts
|
16
|
-
lexer = (::Rouge::Lexer.find_fancy lang) || ::Rouge::Lexers::PlainText
|
17
|
-
lexer_opts = lexer.tag == 'php' && !(node.option? 'mixed') ? { start_inline: true } : {}
|
18
16
|
@style ||= (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE
|
19
|
-
if opts[:css_mode] == :class
|
20
|
-
|
21
|
-
|
17
|
+
@requires_stylesheet = true if opts[:css_mode] == :class
|
18
|
+
lexer = create_lexer node, source, lang, opts
|
19
|
+
formatter = create_formatter node, source, lang, opts
|
20
|
+
highlighted = formatter.format lexer.lex source
|
21
|
+
if opts[:number_lines] && opts[:callouts]
|
22
|
+
[highlighted, (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
|
22
23
|
else
|
23
|
-
|
24
|
+
highlighted
|
24
25
|
end
|
25
|
-
if (highlight_lines = opts[:highlight_lines])
|
26
|
-
formatter = RougeExt::Formatters::HTMLLineHighlighter.new formatter, lines: highlight_lines
|
27
|
-
end
|
28
|
-
if opts[:number_lines]
|
29
|
-
formatter = RougeExt::Formatters::HTMLTable.new formatter, start_line: opts[:start_line_number]
|
30
|
-
if opts[:callouts]
|
31
|
-
return [(highlighted = formatter.format lexer.lex source, lexer_opts), (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
formatter.format lexer.lex source, lexer_opts
|
35
26
|
end
|
36
27
|
|
37
28
|
def format node, lang, opts
|
38
29
|
if (query_idx = lang && (lang.index '?'))
|
39
30
|
lang = lang.slice 0, query_idx
|
40
31
|
end
|
41
|
-
if opts[:css_mode] != :class && (@style = (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE) &&
|
42
|
-
(pre_style_attr_val = base_style @style)
|
32
|
+
if opts[:css_mode] != :class && (@style = (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE) && (pre_style_attr_val = base_style @style)
|
43
33
|
opts[:transform] = proc {|pre| pre['style'] = pre_style_attr_val }
|
44
34
|
end
|
45
35
|
super
|
46
36
|
end
|
47
37
|
|
48
38
|
def docinfo? location
|
49
|
-
@requires_stylesheet && location == :
|
39
|
+
@requires_stylesheet && location == :head
|
50
40
|
end
|
51
41
|
|
52
42
|
def docinfo location, doc, opts
|
@@ -67,6 +57,30 @@ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
|
|
67
57
|
::File.write (::File.join to_dir, (stylesheet_basename @style)), (read_stylesheet @style), mode: FILE_WRITE_MODE
|
68
58
|
end
|
69
59
|
|
60
|
+
def create_lexer node, source, lang, opts
|
61
|
+
if lang.include? '?'
|
62
|
+
# NOTE cgi-style options only properly supported in Rouge >= 2.1
|
63
|
+
if (lexer = ::Rouge::Lexer.find_fancy lang)
|
64
|
+
unless lexer.tag != 'php' || (node.option? 'mixed') || ((lexer_opts = lexer.options).key? 'start_inline')
|
65
|
+
lexer = lexer.class.new lexer_opts.merge 'start_inline' => true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
elsif (lexer = ::Rouge::Lexer.find lang)
|
69
|
+
lexer = lexer.tag == 'php' && !(node.option? 'mixed') ? (lexer.new start_inline: true) : lexer.new
|
70
|
+
end if lang
|
71
|
+
lexer || ::Rouge::Lexers::PlainText.new
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_formatter node, source, lang, opts
|
75
|
+
formatter = opts[:css_mode] == :class ?
|
76
|
+
(::Rouge::Formatters::HTML.new inline_theme: @style) :
|
77
|
+
(::Rouge::Formatters::HTMLInline.new (::Rouge::Theme.find @style).new)
|
78
|
+
if (highlight_lines = opts[:highlight_lines])
|
79
|
+
formatter = RougeExt::Formatters::HTMLLineHighlighter.new formatter, lines: highlight_lines
|
80
|
+
end
|
81
|
+
opts[:number_lines] ? (RougeExt::Formatters::HTMLTable.new formatter, start_line: opts[:start_line_number]) : formatter
|
82
|
+
end
|
83
|
+
|
70
84
|
module Loader
|
71
85
|
private
|
72
86
|
|
@@ -119,7 +133,8 @@ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
|
|
119
133
|
end
|
120
134
|
|
121
135
|
extend Styles # exports static methods
|
122
|
-
include
|
136
|
+
include Styles # adds methods to instance
|
137
|
+
include Loader # adds methods to instance
|
123
138
|
|
124
139
|
CodeCellStartTagCs = '<td class="code">'
|
125
140
|
|
@@ -20,7 +20,7 @@ module SyntaxHighlighter
|
|
20
20
|
end
|
21
21
|
|
22
22
|
# Public: Indicates whether this syntax highlighter has docinfo (i.e., markup) to insert into the output document at
|
23
|
-
# the specified location.
|
23
|
+
# the specified location. Should be called by converter after main content has been converted.
|
24
24
|
#
|
25
25
|
# location - The Symbol representing the location slot (:head or :footer).
|
26
26
|
#
|
@@ -28,6 +28,7 @@ module SyntaxHighlighter
|
|
28
28
|
def docinfo? location; end
|
29
29
|
|
30
30
|
# Public: Generates docinfo markup for this syntax highlighter to insert at the specified location in the output document.
|
31
|
+
# Should be called by converter after main content has been converted.
|
31
32
|
#
|
32
33
|
# location - The Symbol representing the location slot (:head or :footer).
|
33
34
|
# doc - The Document in which this syntax highlighter is being used.
|
@@ -98,9 +99,10 @@ module SyntaxHighlighter
|
|
98
99
|
raise ::NotImplementedError, %(#{SyntaxHighlighter} subclass #{self.class} must implement the ##{__method__} method since #write_stylesheet? returns true)
|
99
100
|
end
|
100
101
|
|
101
|
-
|
102
|
+
def self.included into
|
102
103
|
into.extend Config
|
103
|
-
end
|
104
|
+
end
|
105
|
+
private_class_method :included # use separate declaration for Ruby 2.0.x
|
104
106
|
|
105
107
|
module Config
|
106
108
|
# Public: Statically register the current class in the registry for the specified names.
|
@@ -139,7 +141,7 @@ module SyntaxHighlighter
|
|
139
141
|
# name - The String name of the syntax highlighter to create.
|
140
142
|
# backend - The String name of the backend for which this syntax highlighter is being used (default: 'html5').
|
141
143
|
# opts - A Hash of options providing information about the context in which this syntax highlighter is used:
|
142
|
-
# :
|
144
|
+
# :document - The Document for which this syntax highlighter was created.
|
143
145
|
#
|
144
146
|
# Returns a [SyntaxHighlighter] instance for the specified name.
|
145
147
|
def create name, backend = 'html5', opts = {}
|
@@ -151,7 +153,7 @@ module SyntaxHighlighter
|
|
151
153
|
end
|
152
154
|
|
153
155
|
private
|
154
|
-
|
156
|
+
|
155
157
|
def registry
|
156
158
|
raise ::NotImplementedError, %(#{Factory} subclass #{self.class} must implement the ##{__method__} method)
|
157
159
|
end
|
@@ -165,19 +167,17 @@ module SyntaxHighlighter
|
|
165
167
|
end
|
166
168
|
|
167
169
|
private
|
168
|
-
|
169
|
-
|
170
|
-
@registry
|
171
|
-
end
|
170
|
+
|
171
|
+
attr_reader :registry
|
172
172
|
end
|
173
173
|
|
174
174
|
module DefaultFactory
|
175
175
|
include Factory
|
176
176
|
|
177
|
-
private
|
178
|
-
|
179
177
|
@@registry = {}
|
180
178
|
|
179
|
+
private
|
180
|
+
|
181
181
|
def registry
|
182
182
|
@@registry
|
183
183
|
end
|
@@ -215,8 +215,6 @@ module SyntaxHighlighter
|
|
215
215
|
'rouge' => %(#{__dir__}/syntax_highlighter/rouge),
|
216
216
|
}
|
217
217
|
|
218
|
-
private
|
219
|
-
|
220
218
|
@@mutex = ::Mutex.new
|
221
219
|
end
|
222
220
|
end
|
@@ -235,9 +233,11 @@ module SyntaxHighlighter
|
|
235
233
|
def format node, lang, opts
|
236
234
|
class_attr_val = opts[:nowrap] ? %(#{@pre_class} highlight nowrap) : %(#{@pre_class} highlight)
|
237
235
|
if (transform = opts[:transform])
|
238
|
-
pre = { 'class' => class_attr_val }
|
239
|
-
|
240
|
-
|
236
|
+
transform[(pre = { 'class' => class_attr_val }), (code = lang ? { 'data-lang' => lang } : {})]
|
237
|
+
# NOTE: make sure data-lang is the last attribute on the code tag to remain consistent with 1.5.x
|
238
|
+
if (lang = code.delete 'data-lang')
|
239
|
+
code['data-lang'] = lang
|
240
|
+
end
|
241
241
|
%(<pre#{pre.map {|k, v| %[ #{k}="#{v}"] }.join}><code#{code.map {|k, v| %[ #{k}="#{v}"] }.join}>#{node.content}</code></pre>)
|
242
242
|
else
|
243
243
|
%(<pre class="#{class_attr_val}"><code#{lang ? %[ data-lang="#{lang}"] : ''}>#{node.content}</code></pre>)
|
data/lib/asciidoctor/table.rb
CHANGED
@@ -58,7 +58,7 @@ class Table < AbstractBlock
|
|
58
58
|
@rows = Rows.new
|
59
59
|
@columns = []
|
60
60
|
|
61
|
-
@has_header_option =
|
61
|
+
@has_header_option = false
|
62
62
|
|
63
63
|
# smells like we need a utility method here
|
64
64
|
# to resolve an integer width from potential bogus input
|
@@ -78,10 +78,10 @@ class Table < AbstractBlock
|
|
78
78
|
@attributes['orientation'] = 'landscape' if attributes['rotate-option']
|
79
79
|
end
|
80
80
|
|
81
|
-
# Internal: Returns
|
82
|
-
# the header row
|
81
|
+
# Internal: Returns the current state of the header option (true or :implicit) if
|
82
|
+
# the row being processed is (or is assumed to be) the header row, otherwise nil
|
83
83
|
def header_row?
|
84
|
-
@has_header_option && @rows.body.empty?
|
84
|
+
(val = @has_header_option) && @rows.body.empty? ? val : nil
|
85
85
|
end
|
86
86
|
|
87
87
|
# Internal: Creates the Column objects from the column spec
|
@@ -154,22 +154,19 @@ class Table < AbstractBlock
|
|
154
154
|
# returns nothing
|
155
155
|
def partition_header_footer(attrs)
|
156
156
|
# set rowcount before splitting up body rows
|
157
|
-
@attributes['rowcount'] = @rows.body.size
|
158
|
-
|
159
|
-
num_body_rows
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
@rows.head = [head]
|
157
|
+
num_body_rows = @attributes['rowcount'] = (body = @rows.body).size
|
158
|
+
|
159
|
+
if num_body_rows > 0
|
160
|
+
if @has_header_option
|
161
|
+
@rows.head = [body.shift.map {|cell| cell.reinitialize true }]
|
162
|
+
num_body_rows -= 1
|
163
|
+
elsif @has_header_option.nil?
|
164
|
+
@has_header_option = false
|
165
|
+
body.unshift(body.shift.map {|cell| cell.reinitialize false })
|
166
|
+
end
|
168
167
|
end
|
169
168
|
|
170
|
-
if num_body_rows > 0 && attrs['footer-option']
|
171
|
-
@rows.foot = [@rows.body.pop]
|
172
|
-
end
|
169
|
+
@rows.foot = [body.pop] if num_body_rows > 0 && attrs['footer-option']
|
173
170
|
|
174
171
|
nil
|
175
172
|
end
|
@@ -232,14 +229,23 @@ class Table::Cell < AbstractBlock
|
|
232
229
|
# Public: An alias to the parent block (which is always a Column)
|
233
230
|
alias column parent
|
234
231
|
|
235
|
-
#
|
232
|
+
# Public: Returns the nested Document in an AsciiDoc table cell (only set when style is :asciidoc)
|
236
233
|
attr_reader :inner_document
|
237
234
|
|
238
235
|
def initialize column, cell_text, attributes = {}, opts = {}
|
239
236
|
super column, :table_cell
|
237
|
+
@cursor = @reinitialize_args = nil
|
240
238
|
@source_location = opts[:cursor].dup if @document.sourcemap
|
239
|
+
# NOTE: column is always set when parsing; may not be set when building table from the API
|
241
240
|
if column
|
242
|
-
|
241
|
+
if (in_header_row = column.table.header_row?)
|
242
|
+
if in_header_row == :implicit && (cell_style = column.style || (attributes && attributes['style']))
|
243
|
+
@reinitialize_args = [column, cell_text, attributes && attributes.merge, opts] if cell_style == :asciidoc || cell_style == :literal
|
244
|
+
cell_style = nil
|
245
|
+
end
|
246
|
+
else
|
247
|
+
cell_style = column.style
|
248
|
+
end
|
243
249
|
# REVIEW feels hacky to inherit all attributes from column
|
244
250
|
update_attributes column.attributes
|
245
251
|
end
|
@@ -253,7 +259,8 @@ class Table::Cell < AbstractBlock
|
|
253
259
|
cell_style = attributes['style'] || cell_style unless in_header_row
|
254
260
|
update_attributes attributes
|
255
261
|
end
|
256
|
-
|
262
|
+
case cell_style
|
263
|
+
when :asciidoc
|
257
264
|
asciidoc = true
|
258
265
|
inner_document_cursor = opts[:cursor]
|
259
266
|
if (cell_text = cell_text.rstrip).start_with? LF
|
@@ -264,7 +271,7 @@ class Table::Cell < AbstractBlock
|
|
264
271
|
else
|
265
272
|
cell_text = cell_text.lstrip
|
266
273
|
end
|
267
|
-
|
274
|
+
when :literal
|
268
275
|
literal = true
|
269
276
|
cell_text = cell_text.rstrip
|
270
277
|
# QUESTION should we use same logic as :asciidoc cell? strip leading space if text doesn't start with newline?
|
@@ -306,8 +313,12 @@ class Table::Cell < AbstractBlock
|
|
306
313
|
@content_model = :verbatim
|
307
314
|
@subs = BASIC_SUBS
|
308
315
|
else
|
309
|
-
if normal_psv
|
310
|
-
|
316
|
+
if normal_psv
|
317
|
+
if in_header_row
|
318
|
+
@cursor = opts[:cursor] # used in deferred catalog_inline_anchor call
|
319
|
+
else
|
320
|
+
catalog_inline_anchor cell_text, opts[:cursor]
|
321
|
+
end
|
311
322
|
end
|
312
323
|
@content_model = :simple
|
313
324
|
@subs = NORMAL_SUBS
|
@@ -316,6 +327,25 @@ class Table::Cell < AbstractBlock
|
|
316
327
|
@style = cell_style
|
317
328
|
end
|
318
329
|
|
330
|
+
def reinitialize has_header
|
331
|
+
if has_header
|
332
|
+
@reinitialize_args = nil
|
333
|
+
elsif @reinitialize_args
|
334
|
+
return Table::Cell.new(*@reinitialize_args)
|
335
|
+
else
|
336
|
+
@style = @attributes['style']
|
337
|
+
end
|
338
|
+
catalog_inline_anchor if @cursor
|
339
|
+
self
|
340
|
+
end
|
341
|
+
|
342
|
+
def catalog_inline_anchor cell_text = @text, cursor = nil
|
343
|
+
cursor, @cursor = @cursor, nil unless cursor
|
344
|
+
if (cell_text.start_with? '[[') && LeadingInlineAnchorRx =~ cell_text
|
345
|
+
Parser.catalog_inline_anchor $1, $2, self, cursor, @document
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
319
349
|
# Public: Get the String text of this cell with substitutions applied.
|
320
350
|
#
|
321
351
|
# Used for cells in the head row as well as text-only (non-AsciiDoc) cells in
|
@@ -328,18 +358,14 @@ class Table::Cell < AbstractBlock
|
|
328
358
|
apply_subs @text, @subs
|
329
359
|
end
|
330
360
|
|
331
|
-
# Public: Set the String text.
|
361
|
+
# Public: Set the String text for this cell.
|
332
362
|
#
|
333
363
|
# This method shouldn't be used for cells that have the AsciiDoc style.
|
334
|
-
|
335
|
-
# Returns the new String text assigned to this Cell
|
336
|
-
def text= val
|
337
|
-
@text = val
|
338
|
-
end
|
364
|
+
attr_writer :text
|
339
365
|
|
340
366
|
# Public: Handles the body data (tbody, tfoot), applying styles and partitioning into paragraphs
|
341
367
|
#
|
342
|
-
# This method should not be used for cells in the head row or that have the literal
|
368
|
+
# This method should not be used for cells in the head row or that have the literal style.
|
343
369
|
#
|
344
370
|
# Returns the converted String for this Cell
|
345
371
|
def content
|
@@ -377,7 +403,7 @@ class Table::Cell < AbstractBlock
|
|
377
403
|
end
|
378
404
|
|
379
405
|
def to_s
|
380
|
-
|
406
|
+
%(#{super} - [text: #{@text}, colspan: #{@colspan || 1}, rowspan: #{@rowspan || 1}, attributes: #{@attributes}])
|
381
407
|
end
|
382
408
|
end
|
383
409
|
|
@@ -385,7 +411,7 @@ end
|
|
385
411
|
# class are primarily responsible for tracking the buffer of a cell as the parser
|
386
412
|
# moves through the lines of the table using tail recursion. When a cell boundary
|
387
413
|
# is located, the previous cell is closed, an instance of Table::Cell is
|
388
|
-
# instantiated, the row is closed if the cell
|
414
|
+
# instantiated, the row is closed if the cell satisfies the column count and,
|
389
415
|
# finally, a new buffer is allocated to track the next cell.
|
390
416
|
class Table::ParserContext
|
391
417
|
include Logging
|
@@ -505,12 +531,13 @@ class Table::ParserContext
|
|
505
531
|
#
|
506
532
|
# returns true if the buffer has unclosed quotes, false if it doesn't or it
|
507
533
|
# isn't quoted data
|
508
|
-
def buffer_has_unclosed_quotes? append = nil
|
509
|
-
if (record = append ? (@buffer + append).strip : @buffer.strip) ==
|
534
|
+
def buffer_has_unclosed_quotes? append = nil, q = '"'
|
535
|
+
if (record = append ? (@buffer + append).strip : @buffer.strip) == q
|
510
536
|
true
|
511
|
-
elsif record.start_with?
|
512
|
-
|
513
|
-
|
537
|
+
elsif record.start_with? q
|
538
|
+
qq = q + q
|
539
|
+
if ((trailing_quote = record.end_with? q) && (record.end_with? qq)) || (record.start_with? qq)
|
540
|
+
((record = record.gsub qq, '').start_with? q) && !(record.end_with? q)
|
514
541
|
else
|
515
542
|
!trailing_quote
|
516
543
|
end
|
@@ -603,20 +630,20 @@ class Table::ParserContext
|
|
603
630
|
@buffer = ''
|
604
631
|
cellspec = nil
|
605
632
|
repeat = 1
|
606
|
-
if @format == 'csv' && !cell_text.empty? && cell_text.include?('"')
|
633
|
+
if @format == 'csv' && !cell_text.empty? && (cell_text.include? (q = '"'))
|
607
634
|
# this may not be perfect logic, but it hits the 99%
|
608
|
-
if cell_text.start_with?
|
635
|
+
if (cell_text.start_with? q) && (cell_text.end_with? q)
|
609
636
|
# unquote
|
610
637
|
if (cell_text = cell_text.slice(1, cell_text.length - 2))
|
611
638
|
# trim whitespace and collapse escaped quotes
|
612
|
-
cell_text = cell_text.strip.squeeze
|
639
|
+
cell_text = cell_text.strip.squeeze q
|
613
640
|
else
|
614
641
|
logger.error message_with_context 'unclosed quote in CSV data; setting cell to empty', source_location: @reader.cursor_at_prev_line
|
615
642
|
cell_text = ''
|
616
643
|
end
|
617
644
|
else
|
618
645
|
# collapse escaped quotes
|
619
|
-
cell_text = cell_text.squeeze
|
646
|
+
cell_text = cell_text.squeeze q
|
620
647
|
end
|
621
648
|
end
|
622
649
|
end
|
@@ -635,7 +662,7 @@ class Table::ParserContext
|
|
635
662
|
# QUESTION is this right for cells that span columns?
|
636
663
|
unless (column = @table.columns[@current_row.size])
|
637
664
|
logger.error message_with_context 'dropping cell because it exceeds specified number of columns', source_location: @reader.cursor_before_mark
|
638
|
-
return
|
665
|
+
return nil
|
639
666
|
end
|
640
667
|
end
|
641
668
|
|
data/lib/asciidoctor/timings.rb
CHANGED
@@ -49,9 +49,9 @@ module Asciidoctor
|
|
49
49
|
|
50
50
|
def print_report to = $stdout, subject = nil
|
51
51
|
to.puts %(Input file: #{subject}) if subject
|
52
|
-
to.puts %( Time to read and parse source: #{'%05.5f'
|
53
|
-
to.puts %( Time to convert document: #{'%05.5f'
|
54
|
-
to.puts %( Total time (read, parse and convert): #{'%05.5f'
|
52
|
+
to.puts %( Time to read and parse source: #{sprintf '%05.5f', read_parse.to_f})
|
53
|
+
to.puts %( Time to convert document: #{sprintf '%05.5f', convert.to_f})
|
54
|
+
to.puts %( Total time (read, parse and convert): #{sprintf '%05.5f', read_parse_convert.to_f})
|
55
55
|
end
|
56
56
|
|
57
57
|
private
|
data/lib/asciidoctor/version.rb
CHANGED