asciidoctor 1.5.8 → 2.0.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+ module Asciidoctor
3
+ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
4
+ register_for 'rouge'
5
+
6
+ def initialize *args
7
+ super
8
+ @requires_stylesheet = nil
9
+ @style = nil
10
+ end
11
+
12
+ def highlight?
13
+ library_available?
14
+ end
15
+
16
+ def highlight node, source, lang, opts
17
+ lexer = (::Rouge::Lexer.find_fancy lang) || ::Rouge::Lexers::PlainText
18
+ lexer_opts = lexer.tag == 'php' && !(node.option? 'mixed') ? { start_inline: true } : {}
19
+ @style ||= (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE
20
+ if opts[:css_mode] == :class
21
+ @requires_stylesheet = true
22
+ formatter = ::Rouge::Formatters::HTML.new @style
23
+ else
24
+ formatter = ::Rouge::Formatters::HTMLInline.new @style
25
+ end
26
+ if (highlight_lines = opts[:highlight_lines])
27
+ formatter = RougeExt::Formatters::HTMLLineHighlighter.new formatter, lines: highlight_lines
28
+ end
29
+ if opts[:number_lines]
30
+ formatter = RougeExt::Formatters::HTMLTable.new formatter, start_line: opts[:start_line_number]
31
+ if opts[:callouts]
32
+ return [(highlighted = formatter.format lexer.lex source, lexer_opts), (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
33
+ end
34
+ end
35
+ formatter.format lexer.lex source, lexer_opts
36
+ end
37
+
38
+ def format node, lang, opts
39
+ if (query_idx = lang.index '?')
40
+ lang = lang.slice 0, query_idx
41
+ end
42
+ if opts[:css_mode] != :class && (@style = (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE) &&
43
+ (pre_style_attr_val = base_style @style)
44
+ opts[:transform] = proc {|pre| pre['style'] = pre_style_attr_val }
45
+ end
46
+ super
47
+ end
48
+
49
+ def docinfo? location
50
+ @requires_stylesheet && location == :footer
51
+ end
52
+
53
+ def docinfo location, doc, opts
54
+ if opts[:linkcss]
55
+ %(<link rel="stylesheet" href="#{doc.normalize_web_path (stylesheet_basename @style), (doc.attr 'stylesdir', ''), false}"#{opts[:self_closing_tag_slash]}>)
56
+ else
57
+ %(<style>
58
+ #{read_stylesheet @style}
59
+ </style>)
60
+ end
61
+ end
62
+
63
+ def write_stylesheet? doc
64
+ @requires_stylesheet
65
+ end
66
+
67
+ def write_stylesheet doc, to_dir
68
+ ::File.write (::File.join to_dir, (stylesheet_basename @style)), (read_stylesheet @style), mode: FILE_WRITE_MODE
69
+ end
70
+
71
+ module Loader
72
+ private
73
+
74
+ def library_available?
75
+ (@@library_status ||= load_library) == :loaded ? true : nil
76
+ end
77
+
78
+ def load_library
79
+ (defined? RougeExt) ? :loaded : (Helpers.require_library %(#{::File.dirname __dir__}/rouge_ext), 'rouge', :warn).nil? ? :unavailable : :loaded
80
+ end
81
+ end
82
+
83
+ module Styles
84
+ include Loader
85
+
86
+ def read_stylesheet style
87
+ library_available? ? @@stylesheet_cache[style || DEFAULT_STYLE] : '/* Rouge CSS disabled because Rouge is not available. */'
88
+ end
89
+
90
+ def stylesheet_basename style
91
+ %(rouge-#{style || DEFAULT_STYLE}.css)
92
+ end
93
+
94
+ private
95
+
96
+ def base_style style
97
+ library_available? ? @@base_style_cache[style || DEFAULT_STYLE] : nil
98
+ end
99
+
100
+ def style_available? style
101
+ (::Rouge::Theme.find style) && style
102
+ end
103
+
104
+ @@base_style_cache = ::Hash.new do |cache, key|
105
+ base_style = (theme = ::Rouge::Theme.find key).base_style
106
+ (val = base_style[:fg]) && ((style ||= []) << %(color: #{theme.palette val}))
107
+ (val = base_style[:bg]) && ((style ||= []) << %(background-color: #{theme.palette val}))
108
+ @@base_style_cache = cache.merge key => (resolved_base_style = style && (style.join ';'))
109
+ resolved_base_style
110
+ end
111
+ @@stylesheet_cache = ::Hash.new do |cache, key|
112
+ @@stylesheet_cache = cache.merge key => (stylesheet = ((::Rouge::Theme.find key).render scope: BASE_SELECTOR))
113
+ stylesheet
114
+ end
115
+
116
+ DEFAULT_STYLE = 'github'
117
+ BASE_SELECTOR = 'pre.rouge'
118
+
119
+ private_constant :BASE_SELECTOR
120
+ end
121
+
122
+ extend Styles # exports static methods
123
+ include Loader, Styles # adds methods to instance
124
+
125
+ CodeCellStartTagCs = '<td class="code">'
126
+
127
+ private_constant :CodeCellStartTagCs
128
+ end
129
+ end
@@ -1,10 +1,10 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
  module Asciidoctor
3
3
  # Public: Methods and constants for managing AsciiDoc table content in a document.
4
4
  # It supports all three of AsciiDoc's table formats: psv, dsv and csv.
5
5
  class Table < AbstractBlock
6
- # multipler / divisor for tuning precision of calculated result
7
- DEFAULT_PRECISION_FACTOR = 10000.0
6
+ # precision of column widths
7
+ DEFAULT_PRECISION = 4
8
8
 
9
9
  # Public: A data object that encapsulates the collection of rows (head, foot, body) for a table
10
10
  class Rows
@@ -18,7 +18,7 @@ class Table < AbstractBlock
18
18
 
19
19
  alias [] send
20
20
 
21
- # Public: Returns the rows grouped by section.
21
+ # Public: Retrieve the rows grouped by section as a nested Array.
22
22
  #
23
23
  # Creates a 2-dimensional array of two element entries. The first element
24
24
  # is the section name as a symbol. The second element is the Array of rows
@@ -28,6 +28,16 @@ class Table < AbstractBlock
28
28
  def by_section
29
29
  [[:head, @head], [:body, @body], [:foot, @foot]]
30
30
  end
31
+
32
+ # Public: Retrieve the rows as a Hash.
33
+ #
34
+ # The keys are the names of the section groups and the values are the Array of rows in that section.
35
+ # The keys are in document order (head, foot, body).
36
+ #
37
+ # Returns a Hash of rows grouped by section.
38
+ def to_h
39
+ { head: @head, body: @body, foot: @foot }
40
+ end
31
41
  end
32
42
 
33
43
  # Public: Get/Set the columns for this table
@@ -48,7 +58,7 @@ class Table < AbstractBlock
48
58
  @rows = Rows.new
49
59
  @columns = []
50
60
 
51
- @has_header_option = attributes.key? 'header-option'
61
+ @has_header_option = attributes['header-option'] ? true : false
52
62
 
53
63
  # smells like we need a utility method here
54
64
  # to resolve an integer width from potential bogus input
@@ -67,7 +77,7 @@ class Table < AbstractBlock
67
77
  ((@attributes['tablepcwidth'].to_f / 100) * @document.attributes['pagewidth']).round
68
78
  end
69
79
 
70
- attributes['orientation'] = 'landscape' if attributes.key? 'rotate-option'
80
+ attributes['orientation'] = 'landscape' if attributes['rotate-option']
71
81
  end
72
82
 
73
83
  # Internal: Returns whether the current row being processed is
@@ -111,7 +121,7 @@ class Table < AbstractBlock
111
121
  #
112
122
  # returns nothing
113
123
  def assign_column_widths width_base = nil, autowidth_cols = nil
114
- pf = DEFAULT_PRECISION_FACTOR
124
+ precision = DEFAULT_PRECISION
115
125
  total_width = col_pcwidth = 0
116
126
 
117
127
  if width_base
@@ -120,32 +130,22 @@ class Table < AbstractBlock
120
130
  autowidth = 0
121
131
  logger.warn %(total column width must not exceed 100% when using autowidth columns; got #{width_base}%)
122
132
  else
123
- autowidth = ((100.0 - width_base) / autowidth_cols.size * pf).to_i / pf
133
+ autowidth = ((100.0 - width_base) / autowidth_cols.size).truncate precision
124
134
  autowidth = autowidth.to_i if autowidth.to_i == autowidth
125
135
  width_base = 100
126
136
  end
127
137
  autowidth_attrs = { 'width' => autowidth, 'autowidth-option' => '' }
128
138
  autowidth_cols.each {|col| col.update_attributes autowidth_attrs }
129
139
  end
130
- @columns.each {|col| total_width += (col_pcwidth = col.assign_width nil, width_base, pf) }
140
+ @columns.each {|col| total_width += (col_pcwidth = col.assign_width nil, width_base, precision) }
131
141
  else
132
- col_pcwidth = ((100 * pf / @columns.size).to_i) / pf
133
- # or...
134
- #col_pcwidth = (100.0 / @columns.size).truncate 4
142
+ col_pcwidth = (100.0 / @columns.size).truncate precision
135
143
  col_pcwidth = col_pcwidth.to_i if col_pcwidth.to_i == col_pcwidth
136
- @columns.each {|col| total_width += col.assign_width col_pcwidth }
144
+ @columns.each {|col| total_width += col.assign_width col_pcwidth, nil, precision }
137
145
  end
138
146
 
139
147
  # donate balance, if any, to final column (using half up rounding)
140
- unless total_width == 100
141
- @columns[-1].assign_width(((100 - total_width + col_pcwidth) * pf).round / pf)
142
- # or (manual half up rounding)...
143
- #numerator = (raw_numerator = (100 - total_width + col_pcwidth) * pf).to_i
144
- #numerator += 1 if raw_numerator >= numerator + 0.5
145
- #@columns[-1].assign_width numerator / pf
146
- # or...
147
- #@columns[-1].assign_width((100 - total_width + col_pcwidth).round 4)
148
- end
148
+ @columns[-1].assign_width(((100 - total_width + col_pcwidth).round precision), nil, precision) unless total_width == 100
149
149
 
150
150
  nil
151
151
  end
@@ -169,7 +169,7 @@ class Table < AbstractBlock
169
169
  @rows.head = [head]
170
170
  end
171
171
 
172
- if num_body_rows > 0 && attrs.key?('footer-option')
172
+ if num_body_rows > 0 && attrs['footer-option']
173
173
  @rows.foot = [@rows.body.pop]
174
174
  end
175
175
 
@@ -180,11 +180,11 @@ end
180
180
  # Public: Methods to manage the columns of an AsciiDoc table. In particular, it
181
181
  # keeps track of the column specs
182
182
  class Table::Column < AbstractNode
183
- # Public: Get/Set the Symbol style for this column.
183
+ # Public: Get/Set the style Symbol for this column.
184
184
  attr_accessor :style
185
185
 
186
186
  def initialize table, index, attributes = {}
187
- super table, :column
187
+ super table, :table_column
188
188
  @style = attributes['style']
189
189
  attributes['colnumber'] = index + 1
190
190
  attributes['width'] ||= 1
@@ -201,11 +201,9 @@ class Table::Column < AbstractNode
201
201
  # This method assigns the colpcwidth and colabswidth attributes.
202
202
  #
203
203
  # returns the resolved colpcwidth value
204
- def assign_width col_pcwidth, width_base = nil, pf = 10000.0
204
+ def assign_width col_pcwidth, width_base, precision
205
205
  if width_base
206
- col_pcwidth = ((@attributes['width'].to_f / width_base) * 100 * pf).to_i / pf
207
- # or...
208
- #col_pcwidth = (@attributes['width'].to_f * 100.0 / width_base).truncate 4
206
+ col_pcwidth = (@attributes['width'].to_f * 100.0 / width_base).truncate precision
209
207
  col_pcwidth = col_pcwidth.to_i if col_pcwidth.to_i == col_pcwidth
210
208
  end
211
209
  @attributes['colpcwidth'] = col_pcwidth
@@ -215,18 +213,19 @@ class Table::Column < AbstractNode
215
213
  end
216
214
  col_pcwidth
217
215
  end
218
- end
219
216
 
220
- # Public: Methods for managing the a cell in an AsciiDoc table.
221
- class Table::Cell < AbstractNode
222
- # Public: Gets/Sets the location in the AsciiDoc source where this cell begins
223
- attr_reader :source_location
217
+ def block?
218
+ false
219
+ end
224
220
 
225
- # Public: Get/Set the Symbol style for this cell (default: nil)
226
- attr_accessor :style
221
+ def inline?
222
+ false
223
+ end
224
+ end
227
225
 
228
- # Public: Substitutions to be applied to content in this cell
229
- attr_accessor :subs
226
+ # Public: Methods for managing the a cell in an AsciiDoc table.
227
+ class Table::Cell < AbstractBlock
228
+ DOUBLE_LF = LF * 2
230
229
 
231
230
  # Public: An Integer of the number of columns this cell will span (default: nil)
232
231
  attr_accessor :colspan
@@ -237,11 +236,11 @@ class Table::Cell < AbstractNode
237
236
  # Public: An alias to the parent block (which is always a Column)
238
237
  alias column parent
239
238
 
240
- # Public: The internal Asciidoctor::Document for a cell that has the asciidoc style
239
+ # Internal: Returns the nested Document in an AsciiDoc table cell (only set when style is :asciidoc)
241
240
  attr_reader :inner_document
242
241
 
243
242
  def initialize column, cell_text, attributes = {}, opts = {}
244
- super column, :cell
243
+ super column, :table_cell
245
244
  @source_location = opts[:cursor].dup if @document.sourcemap
246
245
  if column
247
246
  cell_style = column.attributes['style'] unless (in_header_row = column.table.header_row?)
@@ -269,7 +268,8 @@ class Table::Cell < AbstractNode
269
268
  else
270
269
  cell_text = cell_text.lstrip
271
270
  end
272
- elsif (literal = cell_style == :literal) || cell_style == :verse
271
+ elsif cell_style == :literal
272
+ literal = true
273
273
  cell_text = cell_text.rstrip
274
274
  # QUESTION should we use same logic as :asciidoc cell? strip leading space if text doesn't start with newline?
275
275
  cell_text = cell_text.slice 1, cell_text.length while cell_text.start_with? LF
@@ -303,15 +303,17 @@ class Table::Cell < AbstractNode
303
303
  inner_document_lines.unshift(*preprocessed_lines) unless preprocessed_lines.empty?
304
304
  end
305
305
  end unless inner_document_lines.empty?
306
- @inner_document = Document.new(inner_document_lines, :header_footer => false, :parent => @document, :cursor => inner_document_cursor)
306
+ @inner_document = Document.new(inner_document_lines, header_footer: false, parent: @document, cursor: inner_document_cursor)
307
307
  @document.attributes['doctitle'] = parent_doctitle unless parent_doctitle.nil?
308
308
  @subs = nil
309
309
  elsif literal
310
+ @content_model = :verbatim
310
311
  @subs = BASIC_SUBS
311
312
  else
312
313
  if normal_psv && (cell_text.start_with? '[[') && LeadingInlineAnchorRx =~ cell_text
313
314
  Parser.catalog_inline_anchor $1, $2, self, opts[:cursor], @document
314
315
  end
316
+ @content_model = :simple
315
317
  @subs = NORMAL_SUBS
316
318
  end
317
319
  @text = cell_text
@@ -345,12 +347,18 @@ class Table::Cell < AbstractNode
345
347
  #
346
348
  # Returns the converted String for this Cell
347
349
  def content
348
- if @style == :asciidoc
350
+ if (cell_style = @style) == :asciidoc
349
351
  @inner_document.convert
350
- else
351
- text.split(BlankLineRx).map do |p|
352
- !@style || @style == :header ? p : Inline.new(parent, :quoted, p, :type => @style).convert
352
+ elsif @text.include? DOUBLE_LF
353
+ (text.split BlankLineRx).map do |para|
354
+ cell_style && cell_style != :header ? (Inline.new parent, :quoted, para, type: cell_style).convert : para
353
355
  end
356
+ elsif (subbed_text = text).empty?
357
+ []
358
+ elsif cell_style && cell_style != :header
359
+ [(Inline.new parent, :quoted, subbed_text, type: cell_style).convert]
360
+ else
361
+ [subbed_text]
354
362
  end
355
363
  end
356
364
 
@@ -388,8 +396,8 @@ class Table::ParserContext
388
396
  'psv' => ['|', /\|/],
389
397
  'csv' => [',', /,/],
390
398
  'dsv' => [':', /:/],
391
- 'tsv' => [%(\t), /\t/],
392
- '!sv' => ['!', /!/]
399
+ 'tsv' => [?\t, /\t/],
400
+ '!sv' => ['!', /!/],
393
401
  }
394
402
 
395
403
  # Public: The Table currently being parsed
@@ -427,7 +435,7 @@ class Table::ParserContext
427
435
  xsv = '!sv'
428
436
  end
429
437
  else
430
- logger.error message_with_context %(illegal table format: #{xsv}), :source_location => reader.cursor_at_prev_line
438
+ logger.error message_with_context %(illegal table format: #{xsv}), source_location: reader.cursor_at_prev_line
431
439
  @format, xsv = 'psv', (table.document.nested? ? '!sv' : 'psv')
432
440
  end
433
441
  else
@@ -436,15 +444,15 @@ class Table::ParserContext
436
444
 
437
445
  if attributes.key? 'separator'
438
446
  if (sep = attributes['separator']).nil_or_empty?
439
- @delimiter, @delimiter_re = DELIMITERS[xsv]
447
+ @delimiter, @delimiter_rx = DELIMITERS[xsv]
440
448
  # QUESTION should we support any other escape codes or multiple tabs?
441
449
  elsif sep == '\t'
442
- @delimiter, @delimiter_re = DELIMITERS['tsv']
450
+ @delimiter, @delimiter_rx = DELIMITERS['tsv']
443
451
  else
444
- @delimiter, @delimiter_re = sep, /#{::Regexp.escape sep}/
452
+ @delimiter, @delimiter_rx = sep, /#{::Regexp.escape sep}/
445
453
  end
446
454
  else
447
- @delimiter, @delimiter_re = DELIMITERS[xsv]
455
+ @delimiter, @delimiter_rx = DELIMITERS[xsv]
448
456
  end
449
457
 
450
458
  @colcount = table.columns.empty? ? -1 : table.columns.size
@@ -470,7 +478,7 @@ class Table::ParserContext
470
478
  #
471
479
  # returns Regexp MatchData if the line contains the delimiter, false otherwise
472
480
  def match_delimiter(line)
473
- @delimiter_re.match(line)
481
+ @delimiter_rx.match(line)
474
482
  end
475
483
 
476
484
  # Public: Skip past the matched delimiter because it's inside quoted text.
@@ -582,7 +590,7 @@ class Table::ParserContext
582
590
  if (cellspec = take_cellspec)
583
591
  repeat = cellspec.delete('repeatcol') || 1
584
592
  else
585
- logger.error message_with_context 'table missing leading separator; recovering automatically', :source_location => Reader::Cursor.new(*@start_cursor_data)
593
+ logger.error message_with_context 'table missing leading separator; recovering automatically', source_location: Reader::Cursor.new(*@start_cursor_data)
586
594
  cellspec = {}
587
595
  repeat = 1
588
596
  end
@@ -599,7 +607,7 @@ class Table::ParserContext
599
607
  # trim whitespace and collapse escaped quotes
600
608
  cell_text = cell_text.strip.squeeze('"')
601
609
  else
602
- logger.error message_with_context 'unclosed quote in CSV data; setting cell to empty', :source_location => @reader.cursor_at_prev_line
610
+ logger.error message_with_context 'unclosed quote in CSV data; setting cell to empty', source_location: @reader.cursor_at_prev_line
603
611
  cell_text = ''
604
612
  end
605
613
  else
@@ -622,12 +630,12 @@ class Table::ParserContext
622
630
  else
623
631
  # QUESTION is this right for cells that span columns?
624
632
  unless (column = @table.columns[@current_row.size])
625
- logger.error message_with_context 'dropping cell because it exceeds specified number of columns', :source_location => @reader.cursor_before_mark
633
+ logger.error message_with_context 'dropping cell because it exceeds specified number of columns', source_location: @reader.cursor_before_mark
626
634
  return
627
635
  end
628
636
  end
629
637
 
630
- cell = Table::Cell.new(column, cell_text, cellspec, :cursor => @reader.cursor_before_mark)
638
+ cell = Table::Cell.new(column, cell_text, cellspec, cursor: @reader.cursor_before_mark)
631
639
  @reader.mark
632
640
  unless !cell.rowspan || cell.rowspan == 1
633
641
  activate_rowspan(cell.rowspan, (cell.colspan || 1))
@@ -642,7 +650,9 @@ class Table::ParserContext
642
650
  nil
643
651
  end
644
652
 
645
- # Public: Close the row by adding it to the Table and resetting the row
653
+ private
654
+
655
+ # Internal: Close the row by adding it to the Table and resetting the row
646
656
  # Array and counter variables.
647
657
  #
648
658
  # returns nothing
@@ -658,24 +668,21 @@ class Table::ParserContext
658
668
  nil
659
669
  end
660
670
 
661
- # Public: Activate a rowspan. The rowspan Array is consulted when
671
+ # Internal: Activate a rowspan. The rowspan Array is consulted when
662
672
  # determining the effective number of cells in the current row.
663
673
  #
664
674
  # returns nothing
665
675
  def activate_rowspan(rowspan, colspan)
666
- 1.upto(rowspan - 1).each {|i|
667
- # longhand assignment used for Opal compatibility
668
- @active_rowspans[i] = (@active_rowspans[i] || 0) + colspan
669
- }
676
+ 1.upto(rowspan - 1) {|i| @active_rowspans[i] = (@active_rowspans[i] || 0) + colspan }
670
677
  nil
671
678
  end
672
679
 
673
- # Public: Check whether we've met the number of effective columns for the current row.
680
+ # Internal: Check whether we've met the number of effective columns for the current row.
674
681
  def end_of_row?
675
682
  @colcount == -1 || effective_column_visits == @colcount
676
683
  end
677
684
 
678
- # Public: Calculate the effective column visits, which consists of the number of
685
+ # Internal: Calculate the effective column visits, which consists of the number of
679
686
  # cells plus any active rowspans.
680
687
  def effective_column_visits
681
688
  @column_visits + @active_rowspans[0]