Skip to content
Draft
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
3 changes: 1 addition & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ AllCops:
NewCops: enable

Lint/UnusedMethodArgument:
Exclude:
- lib/prawn_html/utils.rb
Enabled: false

Naming/FileName:
Exclude:
Expand Down
26 changes: 26 additions & 0 deletions examples/tables.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<title>Tables</title>
</head>
<body style="font-family: 'Times-Roman';">
<div class="title">Tables</div>
<table>
<tr>
<td>A 1</td>
<td>A 2</td>
<td>A 3</td>
</tr>
<tr>
<td>B 1</td>
<td>B 2</td>
<td>B 3</td>
</tr>
<tr>
<td>C 1</td>
<td>C 2</td>
<td>C 3</td>
</tr>
</table>
</body>
</html>
Binary file added examples/tables.pdf
Binary file not shown.
3 changes: 2 additions & 1 deletion lib/prawn_html/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ class Context < Array
}.freeze

attr_reader :previous_tag
attr_accessor :last_text_node
attr_accessor :last_text_node, :current_table

# Init the Context
def initialize(*_args)
super
@current_table = nil
@last_text_node = false
@merged_styles = nil
@previous_tag = nil
Expand Down
17 changes: 12 additions & 5 deletions lib/prawn_html/document_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,13 @@ def on_text_node(content)
def render
return if buffer.empty?

output_content(buffer.dup, context.block_styles)
content = prepare_content(buffer.dup, context.block_styles)
if context.current_table
td_content = content.dig(:buffer, 0, :text)
context.current_table.update_content(td_content)
else
pdf.puts(content[:buffer], content[:options], left_indent: content[:left_indent], bounding_box: content[:bounds])
end
buffer.clear
@last_margin = 0
end
Expand Down Expand Up @@ -94,14 +100,15 @@ def render_if_needed(element)
end

def apply_tag_close_styles(element)
tag_styles = element.tag_close_styles
tag_styles = element.tag_closing(context: context)
pdf.table(element.table_data) if element.is_a?(Tags::Table)
@last_margin = tag_styles[:margin_bottom].to_f
pdf.advance_cursor(last_margin + tag_styles[:padding_bottom].to_f)
pdf.start_new_page if tag_styles[:break_after]
end

def apply_tag_open_styles(element)
tag_styles = element.tag_open_styles
tag_styles = element.tag_opening(context: context)
move_down = (tag_styles[:margin_top].to_f - last_margin) + tag_styles[:padding_top].to_f
pdf.advance_cursor(move_down) if move_down > 0
pdf.start_new_page if tag_styles[:break_before]
Expand All @@ -118,12 +125,12 @@ def prepare_text(content)
@last_text = text
end

def output_content(buffer, block_styles)
def prepare_content(buffer, block_styles)
apply_callbacks(buffer)
left_indent = block_styles[:margin_left].to_f + block_styles[:padding_left].to_f
options = block_styles.slice(:align, :indent_paragraphs, :leading, :mode, :padding_left)
options[:leading] = adjust_leading(buffer, options[:leading])
pdf.puts(buffer, options, bounding_box: bounds(buffer, options, block_styles), left_indent: left_indent)
{ buffer: buffer, options: options, left_indent: left_indent, bounds: bounds(buffer, options, block_styles) }
end

def apply_callbacks(buffer)
Expand Down
3 changes: 2 additions & 1 deletion lib/prawn_html/pdf_wrapper.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# frozen_string_literal: true

require 'forwardable'
require 'prawn/table'

module PrawnHtml
class PdfWrapper
extend Forwardable

def_delegators :@pdf, :start_new_page
def_delegators :@pdf, :start_new_page, :table

# Wrapper for Prawn PDF Document
#
Expand Down
10 changes: 5 additions & 5 deletions lib/prawn_html/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Tag
'StrikeThrough' => Callbacks::StrikeThrough
}.freeze

TAG_CLASSES = %w[A B Blockquote Body Br Code Del Div H Hr I Img Li Mark Ol P Pre Small Span Sub Sup U Ul].freeze
TAG_CLASSES = %w[A B Blockquote Body Br Code Del Div H Hr I Img Li Mark Ol P Pre Small Span Sub Sup Table Td Tr U Ul].freeze

def_delegators :@attrs, :styles, :update_styles

Expand Down Expand Up @@ -53,17 +53,17 @@ def process_styles(element_styles: nil)
attrs.merge_text_styles!(extra_styles, options: options) if respond_to?(:extra_styles)
end

# Styles to apply on tag closing
# Tag closing callback that applies tag's specific styles
#
# @return [Hash] hash of styles to apply
def tag_close_styles
def tag_closing(context: nil)
styles.slice(*Attributes::STYLES_APPLY[:tag_close])
end

# Styles to apply on tag opening
# Tag opening callback that applies tag's specific styles
#
# @return [Hash] hash of styles to apply
def tag_open_styles
def tag_opening(context: nil)
styles.slice(*Attributes::STYLES_APPLY[:tag_open])
end

Expand Down
44 changes: 44 additions & 0 deletions lib/prawn_html/tags/table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module PrawnHtml
module Tags
class Table < Tag
ELEMENTS = [:table].freeze

attr_reader :table_data

def block?
true
end

def new_cell
@col_index += 1
@table_data[@row_index] << ''
end

def new_row
@row_index += 1
@col_index = -1
@table_data << []
end

def update_content(content)
@table_data[@row_index][@col_index] = content
end

def tag_opening(context: nil)
super.tap do
context.current_table = self
@row_index = -1
@table_data = []
end
end

def tag_closing(context: nil)
super.tap do
context.current_table = nil
end
end
end
end
end
19 changes: 19 additions & 0 deletions lib/prawn_html/tags/td.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module PrawnHtml
module Tags
class Td < Tag
ELEMENTS = [:td].freeze

def block?
true
end

def tag_opening(context: nil)
super.tap do
context.current_table&.new_cell
end
end
end
end
end
19 changes: 19 additions & 0 deletions lib/prawn_html/tags/tr.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module PrawnHtml
module Tags
class Tr < Tag
ELEMENTS = [:tr].freeze

def block?
true
end

def tag_opening(context: nil)
super.tap do
context.current_table&.new_row
end
end
end
end
end
1 change: 1 addition & 0 deletions prawn-html.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ Gem::Specification.new do |spec|

spec.add_runtime_dependency 'oga', '~> 3.3'
spec.add_runtime_dependency 'prawn', '~> 2.4'
spec.add_runtime_dependency 'prawn-table', '~> 0.2.2'
end
4 changes: 2 additions & 2 deletions spec/units/prawn_html/document_renderer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

before do
allow(context).to receive(:remove_last)
allow(element).to receive(:tag_close_styles).and_call_original
allow(element).to receive(:tag_closing).and_call_original
end

it 'handles tag closing', :aggregate_failures do
on_tag_close
expect(element).to have_received(:tag_close_styles)
expect(element).to have_received(:tag_closing)
expect(context).to have_received(:remove_last)
end
end
Expand Down
8 changes: 4 additions & 4 deletions spec/units/prawn_html/tag_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ def tag_styles
it { is_expected.to eq(color: '0088ff') }
end

describe '#tag_close_styles' do
subject(:tag_close_styles) { tag.tag_close_styles }
describe '#tag_closing' do
subject(:tag_closing) { tag.tag_closing }

it { is_expected.to eq({}) }
end

describe '#tag_open_styles' do
subject(:tag_open_styles) { tag.tag_open_styles }
describe '#tag_opening' do
subject(:tag_opening) { tag.tag_opening }

it { is_expected.to eq({}) }
end
Expand Down