asciidoctor 1.5.8 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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]