Module: Coradoc::AsciiDoc::Transformer::TableCellBuilder
- Defined in:
- lib/coradoc/asciidoc/transformer/table_cell_builder.rb
Overview
Pure functions for parsing the cell-format prefix (‘2+^.^a`) and building a Model::TableCell from raw parser values.
Extracted from the Transformer god class. The format spec can come in two shapes from the parser — a Hash of named captures or a raw String from a capture group — and the layout/alignment/style parsing for each used to be inline in Transformer#build_table_cell.
Class Method Summary collapse
- .build(format, content) ⇒ Model::TableCell
-
.cell_content_to_string(content) ⇒ Object
Coerce the parser-supplied cell content into a plain String.
-
.normalize_cell(cell) ⇒ Model::TableCell
Coerce a raw parser cell value into a TableCell.
-
.parse_block_content(text) ⇒ Array
Parse block-level AsciiDoc content (for ‘a’ style cells).
-
.parse_format(format, cell_opts) ⇒ String?
Parse the cell-format prefix and populate cell_opts.
- .parse_format_hash(format, cell_opts) ⇒ Object
- .parse_format_string(format_str, cell_opts) ⇒ Object
-
.parse_inline_content(text, style = nil) ⇒ Array<Model::TextElement>
Parse inline content from raw text for a cell.
Class Method Details
.build(format, content) ⇒ Model::TableCell
19 20 21 22 23 24 25 26 27 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 19 def build(format, content) cell_opts = {} style = parse_format(format, cell_opts) unescaped_content = cell_content_to_string(content).gsub(/\\([|!,:;])/, '\1') cell_opts[:content] = parse_inline_content(unescaped_content, style) Model::TableCell.new(**cell_opts) end |
.cell_content_to_string(content) ⇒ Object
Coerce the parser-supplied cell content into a plain String. The cell parser emits ‘text:` as either a single Parslet::Slice or an Array of slices (from `.repeat(0)`). An empty Array must map to “” — Ruby’s ‘[].to_s` returns “[]”, which previously leaked into TableCell content as a phantom “[]” cell.
34 35 36 37 38 39 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 34 def cell_content_to_string(content) return '' if content.nil? return content.map(&:to_s).join if content.is_a?(Array) content.to_s end |
.normalize_cell(cell) ⇒ Model::TableCell
Coerce a raw parser cell value into a TableCell. Used by TableLayout.group_cells_into_rows when it encounters cells that the parser emitted as Hashes or plain strings.
46 47 48 49 50 51 52 53 54 55 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 46 def normalize_cell(cell) case cell when Model::TableCell then cell when Hash content = cell[:text] || cell[:content] || '' Model::TableCell.new(content: parse_inline_content(content)) else Model::TableCell.new(content: parse_inline_content(cell)) end end |
.parse_block_content(text) ⇒ Array
Parse block-level AsciiDoc content (for ‘a’ style cells).
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 81 def parse_block_content(text) return [Model::TextElement.new(content: '')] if text.nil? || text.to_s.strip.empty? parser = Coradoc::AsciiDoc::Parser::Base.new text_str = text.to_s if /^(\*+|-+|\d+\.)/m.match?(text_str) list_match = text_str.match(/\n(\*+|-+|\d+\.)(.*)$/m) if list_match list_text = list_match[1] + list_match[2] begin ast = parser.list.parse(list_text) transformed = Transformer.new.apply(ast) before_list = text_str[0, list_match.begin(1) - 1].strip before_elements = [] unless before_list.empty? begin before_ast = parser.text_any.parse(before_list) before_transformed = Transformer.new.apply(before_ast) before_array = before_transformed.is_a?(Array) ? before_transformed : [before_transformed] before_elements = [Model::TextElement.new(content: before_array)] rescue Parslet::ParseFailed before_elements = [Model::TextElement.new(content: before_list)] end end return before_elements + [transformed] rescue Parslet::ParseFailed # fall through to inline parsing end end end begin ast = parser.text_any.parse(text_str) transformed = Transformer.new.apply(ast) content_array = transformed.is_a?(Array) ? transformed : [transformed] [Model::TextElement.new(content: content_array)] rescue Parslet::ParseFailed [Model::TextElement.new(content: text_str)] end end |
.parse_format(format, cell_opts) ⇒ String?
Parse the cell-format prefix and populate cell_opts.
129 130 131 132 133 134 135 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 129 def parse_format(format, cell_opts) if format.is_a?(Hash) parse_format_hash(format, cell_opts) elsif format.is_a?(String) parse_format_string(format, cell_opts) end end |
.parse_format_hash(format, cell_opts) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 137 def parse_format_hash(format, cell_opts) cell_opts[:colspan] = format[:colspan].to_i if format[:colspan] if format[:rowspan] rowspan_str = format[:rowspan].to_s.sub(/^\./, '') cell_opts[:rowspan] = rowspan_str.to_i if rowspan_str.match?(/^\d+$/) end cell_opts[:halign] = format[:halign].to_s if format[:halign] if format[:valign] valign_str = format[:valign].to_s.sub(/^\./, '') cell_opts[:valign] = valign_str if %w[< ^ >].include?(valign_str) end style = format[:style].to_s if format[:style] cell_opts[:style] = style cell_opts[:repeat] = true if format[:repeat] style end |
.parse_format_string(format_str, cell_opts) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 158 def parse_format_string(format_str, cell_opts) cell_opts[:colspan] = Regexp.last_match(1).to_i if format_str =~ /^(\d+)\+/ cell_opts[:rowspan] = Regexp.last_match(1).to_i if format_str =~ /\.(\d+)/ cell_opts[:halign] = Regexp.last_match(0) if format_str =~ /[<>^]/ cell_opts[:valign] = Regexp.last_match(0)[1] if format_str =~ /\.[.^<>]/ style = Regexp.last_match(0) if format_str =~ /[dsemalhv]/ cell_opts[:style] = style cell_opts[:repeat] = true if format_str.include?('*') style end |
.parse_inline_content(text, style = nil) ⇒ Array<Model::TextElement>
Parse inline content from raw text for a cell.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/coradoc/asciidoc/transformer/table_cell_builder.rb', line 61 def parse_inline_content(text, style = nil) return [Model::TextElement.new(content: '')] if text.nil? || text.to_s.strip.empty? return parse_block_content(text) if style == 'a' return [Model::TextElement.new(content: text.to_s)] if style == 'l' parser = Coradoc::AsciiDoc::Parser::Base.new begin ast = parser.text_any.parse(text.to_s) transformed = Transformer.new.apply(ast) content_array = transformed.is_a?(Array) ? transformed : [transformed] [Model::TextElement.new(content: content_array)] rescue Parslet::ParseFailed [Model::TextElement.new(content: text.to_s)] end end |