Skip to content

Commit

Permalink
table outer border (overwrites cell borders on the outside of a table) (
Browse files Browse the repository at this point in the history
#19)

table outer border (overwrites cell borders on the outside of a table)
  • Loading branch information
as-op authored Jan 29, 2025
1 parent 6d63af6 commit 05986e9
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 41 deletions.
2 changes: 1 addition & 1 deletion demo/demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ var foo = function (bar) {

## HTML Table

<table><thead><tr><th>Header</th><th></th></tr></thead><tbody><tr><td style="background-color: #0fffff;">Cell Background Color</td><td></td></tr></tbody></table>
<table style="border:2px solid hsl(90, 75%, 60%);"><thead><tr><th>Header</th><th></th></tr></thead><tbody><tr><td style="background-color: #0fffff;">Cell Background Color</td><td style="border:4px solid hsl(0, 0%, 0%);">Cell border</td></tr></tbody></table>

<br-page/>

Expand Down
65 changes: 40 additions & 25 deletions lib/md_to_pdf/elements/html.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ def collect_html_table_tag_rows(tag, table_font_opts, opts)
end

def draw_html_table_tag(tag, opts)
current_opts = opts.merge({ is_in_table: true, is_html_table: true })
table_opts = tag.key?('style') ? parse_css_table_stylings(tag.get_attribute('style') || '') : nil
current_opts = opts.merge({ is_in_table: true, is_html_table: true, table_opts: table_opts }.compact)
table_font_opts = build_table_font_opts(current_opts)
rows = collect_html_table_tag_rows(tag, table_font_opts, current_opts)
column_count = 0
Expand Down Expand Up @@ -331,8 +332,7 @@ def collect_html_table_tag_cell(tag, opts)
cell_data = data_inlinehtml_tag(tag, nil, opts)
cell_styling =
if tag.key?('style')
style = tag.get_attribute('style') || ''
parse_css_stylings(style)
parse_css_cell_stylings(tag.get_attribute('style') || '')
else
{ cell_borders: [] }
end
Expand All @@ -341,34 +341,49 @@ def collect_html_table_tag_cell(tag, opts)
cell_data
end

def parse_css_cell_stylings(style)
css = parse_css_stylings(style)
{
cell_borders: css[:borders],
cell_background_color: css[:background_color],
cell_border_color: css[:border_color],
cell_border_width: css[:border_width],
cell_border_style: css[:border_style]
}.compact
end

def parse_css_table_stylings(style)
parse_css_stylings(style).compact
end

def parse_css_stylings(style)
cell_background_color = parse_html_color(style, /background-color:(.*?)(?:;|\z)/)
cell_border_color = parse_html_color(style, /border-color:(.*?)(?:;|\z)/)
cell_border_width = parse_html_pt(style, /border-width:(.*?)(?:;|\z)/)
cell_border_style = parse_html_border_style(style)
cell_border = style.scan(/border:(.*?)(?:;|\z)/)
unless cell_border.empty?
cell_border_compact = cell_border.last[0].split(' ', 3)
if cell_border_width.nil?
test_size = parse_pt(cell_border_compact[0])
cell_border_width = test_size unless test_size.nil?
background_color = parse_html_color(style, /background-color:(.*?)(?:;|\z)/)
border_color = parse_html_color(style, /border-color:(.*?)(?:;|\z)/)
border_width = parse_html_pt(style, /border-width:(.*?)(?:;|\z)/)
border_style = parse_html_border_style(style)
border = style.scan(/border:(.*?)(?:;|\z)/)
unless border.empty?
border_compact = border.last[0].split(' ', 3)
if border_width.nil?
test_size = parse_pt(border_compact[0])
border_width = test_size unless test_size.nil?
end
if cell_border_style.nil?
test_style = parse_border_style(cell_border_compact[1])
cell_border_style = test_style unless test_style.nil?
if border_style.nil?
test_style = parse_border_style(border_compact[1])
border_style = test_style unless test_style.nil?
end
if cell_border_color.nil?
test_color = parse_color(cell_border_compact[2])
cell_border_color = test_color unless test_color.nil?
if border_color.nil?
test_color = parse_color(border_compact[2])
border_color = test_color unless test_color.nil?
end
end
{
cell_borders: cell_border_color || cell_border_width || cell_border_style ? %i[left right top bottom] : [],
cell_background_color: cell_background_color,
cell_border_color: cell_border_color,
cell_border_width: cell_border_width,
cell_border_style: cell_border_style
}.compact
borders: border_color || border_width || border_style ? %i[left right top bottom] : [],
background_color: background_color,
border_color: border_color,
border_width: border_width,
border_style: border_style
}
end

def parse_html_border_style(style)
Expand Down
36 changes: 33 additions & 3 deletions lib/md_to_pdf/elements/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ def build_split_tables(table, data, column_alignments, opts)
end
new_column_alignments = column_alignments.slice(start, range)
new_column_alignments.unshift :left
pdf_table = build_pdf_table(table, table[:opts_cell], new_rows, new_column_alignments, opts)
pdf_table = build_pdf_table(table, new_rows, new_column_alignments, opts)
pdf_tables.push pdf_table
end
pdf_tables
end

def try_build_table(table, data, column_alignments, opts)
[build_pdf_table(table, table[:opts_cell], data, column_alignments, opts)]
[build_pdf_table(table, data, column_alignments, opts)]
rescue Prawn::Errors::CannotFit
build_split_tables(table, data, column_alignments, opts)
end
Expand All @@ -130,10 +130,12 @@ def optional_break_before_table(table, pdf_table)
end
end

def build_pdf_table(table, cell_style, data, column_alignments, opts)
def build_pdf_table(table, data, column_alignments, opts)
cell_style = table[:opts_cell]
column_count = column_alignments.length
column_widths = Array.new(column_count, @pdf.bounds.right / column_count)
default_cell_style = opts[:is_html_table] ? cell_style.except(:borders, :border_widths, :border_colors) : cell_style
table_opts = opts[:table_opts]
@pdf.make_table(
data,
width: @pdf.bounds.right,
Expand All @@ -154,6 +156,34 @@ def build_pdf_table(table, cell_style, data, column_alignments, opts)
cell.size = opts_header[:size] || table[:opts_cell][:size]
end
end
apply_prawn_table_outer_borders(prawn_table, table_opts) if table_opts && !table_opts.empty?
end
end

def apply_prawn_table_outer_borders(prawn_table, table_opts)
prawn_table.row(0).each do |cell|
cell.border_top_width = table_opts[:border_width] if table_opts[:border_width]
cell.border_top_color = table_opts[:border_color] if table_opts[:border_color]
cell.border_top_line = table_opts[:border_style] if table_opts[:border_style]
cell.borders = cell.borders + [:top]
end
prawn_table.row(-1).each do |cell|
cell.border_bottom_width = table_opts[:border_width] if table_opts[:border_width]
cell.border_bottom_color = table_opts[:border_color] if table_opts[:border_color]
cell.border_bottom_line = table_opts[:border_style] if table_opts[:border_style]
cell.borders = cell.borders + [:bottom]
end
prawn_table.column(0).each do |cell|
cell.border_left_width = table_opts[:border_width] if table_opts[:border_width]
cell.border_left_color = table_opts[:border_color] if table_opts[:border_color]
cell.border_left_line = table_opts[:border_style] if table_opts[:border_style]
cell.borders = cell.borders + [:left]
end
prawn_table.column(-1).each do |cell|
cell.border_right_width = table_opts[:border_width] if table_opts[:border_width]
cell.border_right_color = table_opts[:border_color] if table_opts[:border_color]
cell.border_right_line = table_opts[:border_style] if table_opts[:border_style]
cell.borders = cell.borders + [:right]
end
end

Expand Down
8 changes: 8 additions & 0 deletions spec/fixtures/table/html_outer_borders.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<table style="border:2px solid hsl(90, 75%, 60%);">
<tbody>
<tr>
<td>Outer</td>
<td>Borders!</td>
</tr>
</tbody>
</table>
59 changes: 47 additions & 12 deletions spec/markdown_to_pdf/table_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,34 +242,59 @@
{ x: 306.0, y: 744.756, text: "Borders!" }])
end

it 'creates a html table with outer table borders' do
generator.parse_file('table/html_outer_borders.html')
expect_pdf_borders(
[
[1.5, 0.6, 36.0, 306.0],
[[], 1.5, 0.6, 36.0, 306.0],
[[], 1.5, 0.6, 36.0, 36.0],
[1.5, 0.6, 306.0, 576.0],
[[], 1.5, 0.6, 306.0, 576.0],
[[], 1.5, 0.6, 576.0, 576.0]
]
)
expect_pdf([
{ x: 36.0, y: 744.756, text: "Outer" },
{ x: 306.0, y: 744.756, text: "Borders!" }])
end

it 'creates a html table with cell borders' do
generator.parse_file('table/html_borders.html')
expect_pdf_borders(
[
[[7.5, 15.0], 7.5, 0.0, 36.0, 36.0],
[1.5, 0.6, 36.0, 36.0],
[[], [7.5, 15.0], 7.5, 0.0, 144.0, 144.0],
[[], 1.5, 0.6, 36.0, 144.0],
[[], [7.5, 15.0], 7.5, 0.0, 36.0, 144.0],
[[], [7.5, 15.0], 7.5, 0.0, 36.0, 144.0],
[[], 1.5, 0.6, 36.0, 144.0],
[[], 1.5, 0.6, 36.0, 36.0],
[0.25, 0.0, 144.0, 144.0],
[[], 0.25, 0.0, 252.0, 252.0],
[[], 1.5, 0.6, 144.0, 252.0],
[[], 0.25, 0.0, 144.0, 252.0],
[[], 0.25, 0.0, 144.0, 252.0],
[[], 1.5, 0.6, 144.0, 252.0],
[0.25, 0.0, 252.0, 252.0],
[[], 0.25, 0.0, 360.0, 360.0],
[[], 1.5, 0.6, 252.0, 360.0],
[[], 0.25, 0.0, 252.0, 360.0],
[[], 0.25, 0.0, 252.0, 360.0],
[[], 1.5, 0.6, 252.0, 360.0],
[0.25, 0.0, 360.0, 360.0],
[[], 0.25, 0.0, 468.0, 468.0],
[[], 1.5, 0.6, 360.0, 468.0],
[[], 0.25, 0.0, 360.0, 468.0],
[[], 0.25, 0.0, 360.0, 468.0],
[[], 1.5, 0.6, 360.0, 468.0],
[0.25, 0.0, 468.0, 468.0],
[[], 0.25, 0.0, 576.0, 576.0],
[[], 0.25, 0.0, 468.0, 576.0],
[[], 1.5, 0.6, 576.0, 576.0],
[[], 1.5, 0.6, 468.0, 576.0],
[[], 0.25, 0.0, 468.0, 576.0],
[0.25, 0.0, 36.0, 36.0],
[[], 1.5, 0.6, 468.0, 576.0],
[[], 1.5, 0.6, 576.0, 576.0],
[1.5, 0.6, 36.0, 36.0],
[[], 0.25, 0.0, 144.0, 144.0],
[[], 0.25, 0.0, 36.0, 144.0],
[[], 0.25, 0.0, 36.0, 144.0],
[[], 1.5, 0.6, 36.0, 36.0],
[1.5, 0.0, 144.0, 144.0],
[[], 1.5, 0.0, 252.0, 252.0],
[[], 1.5, 0.0, 144.0, 252.0],
Expand All @@ -283,13 +308,15 @@
[[], 0.25, 0.0, 360.0, 468.0],
[[], 0.25, 0.0, 360.0, 468.0],
[2.25, 0.0, 468.0, 468.0],
[[], 2.25, 0.0, 576.0, 576.0],
[[], 1.5, 0.6, 576.0, 576.0],
[[], 2.25, 0.0, 468.0, 576.0],
[[], 2.25, 0.0, 468.0, 576.0],
[0.25, 0.0, 36.0, 36.0],
[[], 1.5, 0.6, 576.0, 576.0],
[1.5, 0.6, 36.0, 36.0],
[[], 0.25, 0.0, 144.0, 144.0],
[[], 0.25, 0.0, 36.0, 144.0],
[[], 0.25, 0.0, 36.0, 144.0],
[[], 1.5, 0.6, 36.0, 36.0],
[0.25, 0.0, 144.0, 144.0],
[[], 0.25, 0.0, 252.0, 252.0],
[[], 0.25, 0.0, 144.0, 252.0],
Expand All @@ -303,9 +330,17 @@
[[], 0.25, 1.0, 360.0, 468.0],
[[], 0.25, 1.0, 360.0, 468.0],
[3.0, 0.0, 468.0, 468.0],
[[], 3.0, 0.0, 576.0, 576.0],
[[], 1.5, 0.6, 576.0, 576.0],
[[], 3.0, 0.0, 468.0, 576.0],
[[], 3.0, 0.0, 468.0, 576.0],
[[], 3.0, 0.0, 468.0, 576.0]
[[], 1.5, 0.6, 576.0, 576.0],
[1.5, 0.6, 36.0, 144.0],
[[], 1.5, 0.6, 36.0, 36.0],
[1.5, 0.6, 144.0, 252.0],
[1.5, 0.6, 252.0, 360.0],
[1.5, 0.6, 360.0, 468.0],
[1.5, 0.6, 468.0, 576.0],
[[], 1.5, 0.6, 576.0, 576.0]
]
)
expect_pdf([
Expand Down

0 comments on commit 05986e9

Please sign in to comment.