coradoc-adoc 2.0.9 → 2.0.10

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coradoc/asciidoc/model/bibliography_entry.rb +18 -0
  3. data/lib/coradoc/asciidoc/model/document.rb +9 -0
  4. data/lib/coradoc/asciidoc/model/glossaries.rb +1 -1
  5. data/lib/coradoc/asciidoc/model/list/base.rb +41 -0
  6. data/lib/coradoc/asciidoc/model/list/core.rb +4 -24
  7. data/lib/coradoc/asciidoc/model/list/definition.rb +7 -0
  8. data/lib/coradoc/asciidoc/model/list/definition_item.rb +1 -1
  9. data/lib/coradoc/asciidoc/model/list/item.rb +1 -1
  10. data/lib/coradoc/asciidoc/model/list/nestable.rb +7 -3
  11. data/lib/coradoc/asciidoc/model/list.rb +4 -2
  12. data/lib/coradoc/asciidoc/parser/base.rb +10 -70
  13. data/lib/coradoc/asciidoc/parser/block.rb +3 -22
  14. data/lib/coradoc/asciidoc/parser/block_assembler.rb +37 -100
  15. data/lib/coradoc/asciidoc/parser/block_header.rb +55 -0
  16. data/lib/coradoc/asciidoc/parser/frontmatter_parser.rb +24 -0
  17. data/lib/coradoc/asciidoc/parser/paragraph.rb +1 -3
  18. data/lib/coradoc/asciidoc/parser/rule_dispatcher.rb +158 -0
  19. data/lib/coradoc/asciidoc/parser/section.rb +1 -3
  20. data/lib/coradoc/asciidoc/parser/table.rb +1 -4
  21. data/lib/coradoc/asciidoc/parser/text.rb +1 -3
  22. data/lib/coradoc/asciidoc/parser.rb +1 -0
  23. data/lib/coradoc/asciidoc/serializer/serializers/base.rb +1 -1
  24. data/lib/coradoc/asciidoc/serializer/serializers/document.rb +7 -0
  25. data/lib/coradoc/asciidoc/serializer/serializers/list/definition.rb +3 -1
  26. data/lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb +10 -1
  27. data/lib/coradoc/asciidoc/transform/element_transformers/document_transformer.rb +15 -1
  28. data/lib/coradoc/asciidoc/transform/element_transformers/other_transformer.rb +3 -1
  29. data/lib/coradoc/asciidoc/transform/from_core_model.rb +33 -3
  30. data/lib/coradoc/asciidoc/transform/from_core_model_registrations.rb +5 -1
  31. data/lib/coradoc/asciidoc/transform/frontmatter_attribute_map.rb +112 -0
  32. data/lib/coradoc/asciidoc/transform/text_extract_visitor.rb +33 -1
  33. data/lib/coradoc/asciidoc/transform/to_core_model.rb +10 -2
  34. data/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +15 -10
  35. data/lib/coradoc/asciidoc/transform.rb +1 -0
  36. data/lib/coradoc/asciidoc/transformer/attribute_list_normalizer.rb +69 -0
  37. data/lib/coradoc/asciidoc/transformer/block_rules.rb +4 -42
  38. data/lib/coradoc/asciidoc/transformer/block_type_classifier.rb +56 -0
  39. data/lib/coradoc/asciidoc/transformer/header_rules.rb +15 -53
  40. data/lib/coradoc/asciidoc/transformer/inline_rules.rb +39 -57
  41. data/lib/coradoc/asciidoc/transformer/misc_rules.rb +1 -24
  42. data/lib/coradoc/asciidoc/transformer/structural_rules.rb +18 -81
  43. data/lib/coradoc/asciidoc/transformer/table_cell_builder.rb +161 -0
  44. data/lib/coradoc/asciidoc/transformer/table_layout.rb +135 -0
  45. data/lib/coradoc/asciidoc/transformer/text_rules.rb +1 -25
  46. data/lib/coradoc/asciidoc/transformer.rb +38 -294
  47. data/lib/coradoc/asciidoc/version.rb +1 -1
  48. data/lib/coradoc/asciidoc.rb +6 -3
  49. metadata +10 -1
@@ -29,6 +29,10 @@ module Coradoc
29
29
  autoload :ListRules, "#{__dir__}/transformer/list_rules"
30
30
  autoload :StructuralRules, "#{__dir__}/transformer/structural_rules"
31
31
  autoload :MiscRules, "#{__dir__}/transformer/misc_rules"
32
+ autoload :AttributeListNormalizer, "#{__dir__}/transformer/attribute_list_normalizer"
33
+ autoload :BlockTypeClassifier, "#{__dir__}/transformer/block_type_classifier"
34
+ autoload :TableLayout, "#{__dir__}/transformer/table_layout"
35
+ autoload :TableCellBuilder, "#{__dir__}/transformer/table_cell_builder"
32
36
 
33
37
  # Apply all rule modules (triggers autoload)
34
38
  HeaderRules.apply(self)
@@ -76,319 +80,35 @@ module Coradoc
76
80
  end
77
81
  end
78
82
 
79
- # Helper method for parsing inline content from raw text
80
- # This is used for table cells where content is captured as raw text
81
- # @param text [String] Raw text to parse
82
- # @param style [String, nil] Cell style ('a' for AsciiDoc, 'l' for literal, etc.)
83
- # @return [Array<TextElement>] Parsed content as array of TextElement objects
83
+ # Helper method for parsing inline content from raw text.
84
+ # Kept as a thin delegator for backwards compatibility; implementation
85
+ # lives in TableCellBuilder (table cells are the primary consumer).
84
86
  def self.parse_inline_content(text, style = nil)
85
- return [Coradoc::AsciiDoc::Model::TextElement.new(content: '')] if text.nil? || text.to_s.strip.empty?
86
-
87
- # For AsciiDoc style cells, parse as block content
88
- return parse_block_content(text) if style == 'a'
89
-
90
- # For literal style cells, preserve text as-is
91
- return [Coradoc::AsciiDoc::Model::TextElement.new(content: text.to_s)] if style == 'l'
92
-
93
- # For default cells, parse inline content
94
- parser = Coradoc::AsciiDoc::Parser::Base.new
95
- begin
96
- ast = parser.text_any.parse(text.to_s)
97
- # Transform the AST to model objects
98
- transformed = new.apply(ast)
99
-
100
- # Wrap in TextElement
101
- content_array = transformed.is_a?(Array) ? transformed : [transformed]
102
- [Coradoc::AsciiDoc::Model::TextElement.new(content: content_array)]
103
- rescue Parslet::ParseFailed
104
- # If parsing fails, return the text as a simple TextElement
105
- [Coradoc::AsciiDoc::Model::TextElement.new(content: text.to_s)]
106
- end
87
+ TableCellBuilder.parse_inline_content(text, style)
107
88
  end
108
89
 
109
- # Parse block-level AsciiDoc content (for 'a' style cells)
110
- # @param text [String] Raw text containing AsciiDoc blocks
111
- # @return [Array] Parsed block content
112
90
  def self.parse_block_content(text)
113
- return [Coradoc::AsciiDoc::Model::TextElement.new(content: '')] if text.nil? || text.to_s.strip.empty?
114
-
115
- parser = Coradoc::AsciiDoc::Parser::Base.new
116
- text_str = text.to_s
117
-
118
- # Try parsing as a list if content contains list markers
119
- # List markers can appear after other content (e.g., "Title:\n\n* item")
120
- if /^(\*+|-+|\d+\.)/m.match?(text_str)
121
- # Extract just the list portion
122
- list_match = text_str.match(/\n(\*+|-+|\d+\.)(.*)$/m)
123
- if list_match
124
- list_text = list_match[1] + list_match[2]
125
- begin
126
- ast = parser.list.parse(list_text)
127
- transformed = new.apply(ast)
128
-
129
- # Parse the text before the list as inline content
130
- before_list = text_str[0, list_match.begin(1) - 1].strip
131
- before_elements = []
132
- unless before_list.empty?
133
- begin
134
- before_ast = parser.text_any.parse(before_list)
135
- before_transformed = new.apply(before_ast)
136
- before_array = before_transformed.is_a?(Array) ? before_transformed : [before_transformed]
137
- before_elements = [Coradoc::AsciiDoc::Model::TextElement.new(content: before_array)]
138
- rescue Parslet::ParseFailed
139
- before_elements = [Coradoc::AsciiDoc::Model::TextElement.new(content: before_list)]
140
- end
141
- end
142
-
143
- return before_elements + [transformed]
144
- rescue Parslet::ParseFailed
145
- # Fall through to inline parsing
146
- end
147
- end
148
- end
149
-
150
- # Try parsing as inline content
151
- begin
152
- ast = parser.text_any.parse(text_str)
153
- transformed = new.apply(ast)
154
- content_array = transformed.is_a?(Array) ? transformed : [transformed]
155
- [Coradoc::AsciiDoc::Model::TextElement.new(content: content_array)]
156
- rescue Parslet::ParseFailed
157
- # If parsing fails, return the text as a simple TextElement
158
- [Coradoc::AsciiDoc::Model::TextElement.new(content: text_str)]
159
- end
91
+ TableCellBuilder.parse_block_content(text)
160
92
  end
161
93
 
162
- # Helper method for building table cells with format specification
163
- # @param format [Hash, String, Object] Cell format specification from parser
164
- # @param content [Object] Cell content
165
- # @return [Model::TableCell] Table cell model with parsed attributes
166
94
  def self.build_table_cell(format, content)
167
- cell_opts = {}
168
-
169
- # Extract style first for content parsing
170
- style = nil
171
-
172
- # Parse format specification if present
173
- if format.is_a?(Hash)
174
- # Colspan
175
- cell_opts[:colspan] = format[:colspan].to_i if format[:colspan]
176
-
177
- # Rowspan (remove leading dot)
178
- if format[:rowspan]
179
- rowspan_str = format[:rowspan].to_s
180
- rowspan_str = rowspan_str.sub(/^\./, '')
181
- cell_opts[:rowspan] = rowspan_str.to_i if rowspan_str.match?(/^\d+$/)
182
- end
183
-
184
- # Horizontal alignment
185
- cell_opts[:halign] = format[:halign].to_s if format[:halign]
186
-
187
- # Vertical alignment (remove leading dot)
188
- if format[:valign]
189
- valign_str = format[:valign].to_s
190
- valign_str = valign_str.sub(/^\./, '')
191
- cell_opts[:valign] = valign_str if %w[< ^ >].include?(valign_str)
192
- end
193
-
194
- # Style
195
- style = format[:style].to_s if format[:style]
196
- cell_opts[:style] = style
197
-
198
- # Repeat marker
199
- cell_opts[:repeat] = true if format[:repeat]
200
- elsif format.is_a?(String)
201
- # Parse format string like ".2+^.^" or "4+^" or ".3+a"
202
- # Format: [colspan][.rowspan][halign][valign][style][*]
203
- format_str = format.to_s
204
-
205
- # Parse colspan (digits before +)
206
- cell_opts[:colspan] = Regexp.last_match(1).to_i if format_str =~ /^(\d+)\+/
207
-
208
- # Parse rowspan (.digits)
209
- cell_opts[:rowspan] = Regexp.last_match(1).to_i if format_str =~ /\.(\d+)/
210
-
211
- # Parse horizontal alignment (^ < >)
212
- # Note: In AsciiDoc, ^ is center, < is left, > is right
213
- cell_opts[:halign] = Regexp.last_match(0) if format_str =~ /[<>^]/
214
-
215
- # Parse vertical alignment (.<. ^. >.)
216
- cell_opts[:valign] = Regexp.last_match(0)[1] if format_str =~ /\.[.^<>]/
217
-
218
- # Parse style (d=decimal, s=strong, e=emphasis, m=monospace, a=asciidoc, l=literal, h=header)
219
- style = Regexp.last_match(0) if format_str =~ /[dsemalhv]/
220
- cell_opts[:style] = style
221
-
222
- # Parse repeat marker
223
- cell_opts[:repeat] = true if format_str.include?('*')
224
- end
225
-
226
- # Strip escaped delimiters (\| → |) in cell content
227
- unescaped_content = content.to_s.gsub(/\\([|!,:;])/, '\1')
228
-
229
- # Parse content based on style
230
- parsed_content = parse_inline_content(unescaped_content, style)
231
- cell_opts[:content] = parsed_content
232
-
233
- Model::TableCell.new(**cell_opts)
95
+ TableCellBuilder.build(format, content)
234
96
  end
235
97
 
236
- # Parse the cols attribute to determine column count
237
- # @param attrs [Model::AttributeList, nil] Table attributes
238
- # @return [Integer, nil] Column count or nil if not specified
239
98
  def self.parse_cols_attribute(attrs)
240
- return nil if attrs.nil?
241
-
242
- # Get the cols value from named attributes
243
- cols_value = if attrs.is_a?(Model::AttributeList)
244
- attrs.named.find { |n| n.name.to_s == 'cols' }&.value
245
- elsif attrs.is_a?(Hash)
246
- attrs['cols'] || attrs[:cols]
247
- end
248
-
249
- return nil if cols_value.nil?
250
-
251
- # cols can be:
252
- # - A single number: "3" -> 3 columns
253
- # - A list: "1,2,1" -> 3 columns
254
- # - With multipliers: "3*" -> 3 columns
255
- # - Quoted: "\"3\"" -> 3 columns
256
- cols_str = cols_value.is_a?(Array) ? cols_value.first.to_s : cols_value.to_s
257
-
258
- # Remove surrounding quotes if present
259
- cols_str = cols_str.gsub(/^["']|["']$/, '')
260
-
261
- # Handle multiplier syntax: "3*" means 3 columns
262
- return Regexp.last_match(1).to_i if cols_str =~ /^(\d+)\*$/
263
-
264
- # Handle comma-separated list: count the parts
265
- return cols_str.split(',').size if cols_str.include?(',')
266
-
267
- # Single number
268
- cols_str.to_i if /^\d+$/.match?(cols_str)
99
+ TableLayout.parse_cols_attribute(attrs)
269
100
  end
270
101
 
271
- # Group cells into rows based on column count
272
- #
273
- # AsciiDoc table row semantics:
274
- # - Column count is determined by cols attribute or first row
275
- # - A new row starts when previous row has `column_count` cells
276
- # - Cells with colspan > 1 take multiple column slots
277
- #
278
- # @param cells [Array<Model::TableCell>] Flat list of cells
279
- # @param explicit_col_count [Integer, nil] Column count from cols attribute
280
- # @return [Array<Model::TableRow>] Grouped rows
281
102
  def self.group_cells_into_rows(cells, explicit_col_count = nil)
282
- return [] if cells.nil? || cells.empty?
283
-
284
- # Normalize cells to ensure they're TableCell objects
285
- normalized_cells = cells.map do |cell|
286
- case cell
287
- when Model::TableCell
288
- cell
289
- when Hash
290
- content = cell[:text] || cell[:content] || ''
291
- Model::TableCell.new(content: parse_inline_content(content))
292
- else
293
- Model::TableCell.new(content: parse_inline_content(cell))
294
- end
295
- end
296
-
297
- # Determine column count
298
- # If explicit_col_count is provided, use it
299
- # Otherwise, count cells until we find a row boundary
300
- col_count = explicit_col_count
301
-
302
- if col_count.nil? || col_count.zero?
303
- # Infer from first row - count cells until we have a complete row
304
- # A complete row is when the total column slots equals a consistent number
305
- col_count = infer_column_count(normalized_cells)
306
- end
307
-
308
- # If still no column count, assume all cells are one row
309
- col_count = normalized_cells.size if col_count.nil? || col_count.zero?
310
-
311
- # Group cells into rows
312
- rows = []
313
- current_row_cells = []
314
- current_col_slots = 0
315
-
316
- normalized_cells.each do |cell|
317
- # Get colspan (default 1)
318
- colspan = cell.is_a?(Model::TableCell) && cell.colspan ? cell.colspan : 1
319
-
320
- current_row_cells << cell
321
- current_col_slots += colspan
322
-
323
- # Check if row is complete
324
- next unless current_col_slots >= col_count
325
-
326
- rows << Model::TableRow.new(columns: current_row_cells)
327
- current_row_cells = []
328
- current_col_slots = 0
329
- end
330
-
331
- # Handle remaining cells (incomplete last row)
332
- rows << Model::TableRow.new(columns: current_row_cells) if current_row_cells.any?
333
-
334
- rows
103
+ TableLayout.group_cells_into_rows(cells, explicit_col_count)
335
104
  end
336
105
 
337
- # Infer column count from cells
338
- # Look for patterns where rows have consistent cell counts
339
106
  def self.infer_column_count(cells)
340
- return nil if cells.nil? || cells.empty?
341
-
342
- col_slots = cells.map do |cell|
343
- cell.is_a?(Model::TableCell) && cell.colspan ? cell.colspan : 1
344
- end
345
-
346
- total_cells = col_slots.sum
347
-
348
- # Find all valid column counts
349
- possible_cols = (1..[total_cells, 12].min).select do |candidate|
350
- next false if candidate > total_cells
351
- next false if total_cells % candidate != 0
352
-
353
- slots_used = 0
354
- valid = true
355
-
356
- col_slots.each do |slots|
357
- slots_used += slots
358
- if slots_used == candidate
359
- slots_used = 0
360
- elsif slots_used > candidate
361
- valid = false
362
- break
363
- end
364
- end
365
-
366
- valid && slots_used.zero?
367
- end
368
-
369
- possible_cols.max || col_slots.first || 1
107
+ TableLayout.infer_column_count(cells)
370
108
  end
371
109
 
372
- # Regroup parser-level rows into proper AsciiDoc rows.
373
- # The parser produces one "row" per line; this flattens all cells
374
- # and regroups by the cols attribute, then marks the first row as header.
375
- #
376
- # @param rows [Array<Model::TableRow>] Parser-level rows
377
- # @param attrs [Model::AttributeList, nil] Table attributes containing cols
378
- # @return [Array<Model::TableRow>] Properly grouped rows with header flag
379
110
  def self.regroup_table_rows(rows, attrs = nil)
380
- return rows if rows.nil? || rows.empty?
381
-
382
- col_count = parse_cols_attribute(attrs)
383
- all_cells = rows.flat_map do |r|
384
- r.is_a?(Model::TableRow) ? r.columns : []
385
- end
386
-
387
- return rows if all_cells.empty?
388
-
389
- grouped = group_cells_into_rows(all_cells, col_count)
390
- grouped.first.header = true unless grouped.empty?
391
- grouped
111
+ TableLayout.regroup_table_rows(rows, attrs)
392
112
  end
393
113
 
394
114
  # Transform a syntax tree using this transformer's rules
@@ -399,6 +119,30 @@ module Coradoc
399
119
  new.apply(syntax_tree)
400
120
  end
401
121
 
122
+ # Convert parser-output "lines" into an array of TextElement model
123
+ # objects. Each line is one of:
124
+ # - { text: <Array or scalar>, line_break: <str> }
125
+ # - any other shape (passed through unchanged)
126
+ #
127
+ # Used by the paragraph and reviewer_note rules to share the same
128
+ # line-shape handling (DRY).
129
+ def self.lines_to_text_elements(lines)
130
+ Array(lines).map do |line|
131
+ next line unless line.is_a?(Hash) && line.key?(:text)
132
+
133
+ text_content = line[:text]
134
+ transformed = if text_content.is_a?(Array)
135
+ text_content.map do |item|
136
+ item.is_a?(Hash) ? new.apply(item) : item
137
+ end
138
+ else
139
+ text_content
140
+ end
141
+
142
+ Model::TextElement.new(content: transformed, line_break: line[:line_break])
143
+ end
144
+ end
145
+
402
146
  # Legacy transform method (deprecated)
403
147
  # @deprecated Use {.transform} instead
404
148
  def self.legacy_transform(syntax_tree)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Coradoc
4
4
  module AsciiDoc
5
- VERSION = '2.0.9'
5
+ VERSION = '2.0.10'
6
6
  end
7
7
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'parslet'
4
4
  require 'lutaml/model'
5
- require 'coradoc/core_model' # Required for CoreModel types in transformers
5
+ require 'coradoc'
6
6
 
7
7
  module Coradoc
8
8
  # Utility module autoload
@@ -46,8 +46,11 @@ module Coradoc
46
46
  # @param text [String] AsciiDoc content to parse
47
47
  # @return [Coradoc::AsciiDoc::Model::Document] Parsed document model
48
48
  def parse(text)
49
- ast = Coradoc::AsciiDoc::Parser::Base.parse(text)
50
- Coradoc::AsciiDoc::Transformer.transform(ast)
49
+ split = Parser::FrontmatterParser.call(text)
50
+ ast = Coradoc::AsciiDoc::Parser::Base.parse(split.body)
51
+ doc = Coradoc::AsciiDoc::Transformer.transform(ast)
52
+ doc.frontmatter = split.frontmatter if split.frontmatter?
53
+ doc
51
54
  end
52
55
 
53
56
  # Parse AsciiDoc text and convert to CoreModel
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coradoc-adoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.9
4
+ version: 2.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -175,6 +175,7 @@ files:
175
175
  - lib/coradoc/asciidoc/model/inline/underline.rb
176
176
  - lib/coradoc/asciidoc/model/line_break.rb
177
177
  - lib/coradoc/asciidoc/model/list.rb
178
+ - lib/coradoc/asciidoc/model/list/base.rb
178
179
  - lib/coradoc/asciidoc/model/list/core.rb
179
180
  - lib/coradoc/asciidoc/model/list/definition.rb
180
181
  - lib/coradoc/asciidoc/model/list/definition_item.rb
@@ -214,16 +215,19 @@ files:
214
215
  - lib/coradoc/asciidoc/parser/bibliography.rb
215
216
  - lib/coradoc/asciidoc/parser/block.rb
216
217
  - lib/coradoc/asciidoc/parser/block_assembler.rb
218
+ - lib/coradoc/asciidoc/parser/block_header.rb
217
219
  - lib/coradoc/asciidoc/parser/cache.rb
218
220
  - lib/coradoc/asciidoc/parser/citation.rb
219
221
  - lib/coradoc/asciidoc/parser/content.rb
220
222
  - lib/coradoc/asciidoc/parser/document_attributes.rb
221
223
  - lib/coradoc/asciidoc/parser/fix_files.rb
224
+ - lib/coradoc/asciidoc/parser/frontmatter_parser.rb
222
225
  - lib/coradoc/asciidoc/parser/header.rb
223
226
  - lib/coradoc/asciidoc/parser/inline.rb
224
227
  - lib/coradoc/asciidoc/parser/list.rb
225
228
  - lib/coradoc/asciidoc/parser/metadata_detector.rb
226
229
  - lib/coradoc/asciidoc/parser/paragraph.rb
230
+ - lib/coradoc/asciidoc/parser/rule_dispatcher.rb
227
231
  - lib/coradoc/asciidoc/parser/section.rb
228
232
  - lib/coradoc/asciidoc/parser/stem.rb
229
233
  - lib/coradoc/asciidoc/parser/table.rb
@@ -318,18 +322,23 @@ files:
318
322
  - lib/coradoc/asciidoc/transform/element_transformers/table_transformer.rb
319
323
  - lib/coradoc/asciidoc/transform/from_core_model.rb
320
324
  - lib/coradoc/asciidoc/transform/from_core_model_registrations.rb
325
+ - lib/coradoc/asciidoc/transform/frontmatter_attribute_map.rb
321
326
  - lib/coradoc/asciidoc/transform/inline_transform_visitor.rb
322
327
  - lib/coradoc/asciidoc/transform/text_extract_visitor.rb
323
328
  - lib/coradoc/asciidoc/transform/to_core_model.rb
324
329
  - lib/coradoc/asciidoc/transform/to_core_model_registrations.rb
325
330
  - lib/coradoc/asciidoc/transform/transformer_registry.rb
326
331
  - lib/coradoc/asciidoc/transformer.rb
332
+ - lib/coradoc/asciidoc/transformer/attribute_list_normalizer.rb
327
333
  - lib/coradoc/asciidoc/transformer/block_rules.rb
334
+ - lib/coradoc/asciidoc/transformer/block_type_classifier.rb
328
335
  - lib/coradoc/asciidoc/transformer/header_rules.rb
329
336
  - lib/coradoc/asciidoc/transformer/inline_rules.rb
330
337
  - lib/coradoc/asciidoc/transformer/list_rules.rb
331
338
  - lib/coradoc/asciidoc/transformer/misc_rules.rb
332
339
  - lib/coradoc/asciidoc/transformer/structural_rules.rb
340
+ - lib/coradoc/asciidoc/transformer/table_cell_builder.rb
341
+ - lib/coradoc/asciidoc/transformer/table_layout.rb
333
342
  - lib/coradoc/asciidoc/transformer/text_rules.rb
334
343
  - lib/coradoc/asciidoc/version.rb
335
344
  - lib/coradoc/util.rb