Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

table outer border (overwrites cell borders on the outside of a table) #19

Merged
merged 2 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading