diff --git a/.rubocop.yml b/.rubocop.yml
index 64b4698..9fede3e 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -16,8 +16,7 @@ AllCops:
NewCops: enable
Lint/UnusedMethodArgument:
- Exclude:
- - lib/prawn_html/utils.rb
+ Enabled: false
Naming/FileName:
Exclude:
diff --git a/examples/tables.html b/examples/tables.html
new file mode 100644
index 0000000..45223f2
--- /dev/null
+++ b/examples/tables.html
@@ -0,0 +1,26 @@
+
+
+
+ Tables
+
+
+ Tables
+
+
+ | A 1 |
+ A 2 |
+ A 3 |
+
+
+ | B 1 |
+ B 2 |
+ B 3 |
+
+
+ | C 1 |
+ C 2 |
+ C 3 |
+
+
+
+
diff --git a/examples/tables.pdf b/examples/tables.pdf
new file mode 100644
index 0000000..d42766f
Binary files /dev/null and b/examples/tables.pdf differ
diff --git a/lib/prawn_html/context.rb b/lib/prawn_html/context.rb
index c5250da..6ea340b 100644
--- a/lib/prawn_html/context.rb
+++ b/lib/prawn_html/context.rb
@@ -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
diff --git a/lib/prawn_html/document_renderer.rb b/lib/prawn_html/document_renderer.rb
index 32f5cb7..2f65590 100644
--- a/lib/prawn_html/document_renderer.rb
+++ b/lib/prawn_html/document_renderer.rb
@@ -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
@@ -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]
@@ -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)
diff --git a/lib/prawn_html/pdf_wrapper.rb b/lib/prawn_html/pdf_wrapper.rb
index 7a816ab..72a02d4 100644
--- a/lib/prawn_html/pdf_wrapper.rb
+++ b/lib/prawn_html/pdf_wrapper.rb
@@ -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
#
diff --git a/lib/prawn_html/tag.rb b/lib/prawn_html/tag.rb
index 1f0505f..533046f 100644
--- a/lib/prawn_html/tag.rb
+++ b/lib/prawn_html/tag.rb
@@ -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
@@ -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
diff --git a/lib/prawn_html/tags/table.rb b/lib/prawn_html/tags/table.rb
new file mode 100644
index 0000000..7c37f71
--- /dev/null
+++ b/lib/prawn_html/tags/table.rb
@@ -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
diff --git a/lib/prawn_html/tags/td.rb b/lib/prawn_html/tags/td.rb
new file mode 100644
index 0000000..29d29c9
--- /dev/null
+++ b/lib/prawn_html/tags/td.rb
@@ -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
diff --git a/lib/prawn_html/tags/tr.rb b/lib/prawn_html/tags/tr.rb
new file mode 100644
index 0000000..d065760
--- /dev/null
+++ b/lib/prawn_html/tags/tr.rb
@@ -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
diff --git a/prawn-html.gemspec b/prawn-html.gemspec
index 954d174..f4deede 100644
--- a/prawn-html.gemspec
+++ b/prawn-html.gemspec
@@ -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
diff --git a/spec/units/prawn_html/document_renderer_spec.rb b/spec/units/prawn_html/document_renderer_spec.rb
index e9b72d6..e9accd4 100644
--- a/spec/units/prawn_html/document_renderer_spec.rb
+++ b/spec/units/prawn_html/document_renderer_spec.rb
@@ -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
diff --git a/spec/units/prawn_html/tag_spec.rb b/spec/units/prawn_html/tag_spec.rb
index e6e4d89..87755fd 100644
--- a/spec/units/prawn_html/tag_spec.rb
+++ b/spec/units/prawn_html/tag_spec.rb
@@ -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