prawn-html 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c519c9608664ef77b5b4489752f49d29ae4dfda7ee42e43685ee5951524bd1e3
4
- data.tar.gz: c768fa73bc5601bec246a963153a3d20f0d6712fa72dea6441a27495dc374cee
3
+ metadata.gz: 998ac3f3429812cc60dfe2bdf0184a86c116b1b80c7522376f99e044f185207c
4
+ data.tar.gz: 1a4ce4f9055fa8dd8ed121665102698b6077d69986974c366098d69759555d80
5
5
  SHA512:
6
- metadata.gz: b62ed1e07608cdb62829fe50ae708c16d55b1510c49ff8e02eb47442dca105cfeb2b18e751dd5f84e421687ba970fecb3078db904d3fc867af93ecbe67361e07
7
- data.tar.gz: 503c65d6d22d496c634634dca3c57eda3e864ce91448ad2c119e0cb89857e7731cdef7fd209a1f48d8bda82ad0dc8eff724e407a957bd4d8323f410385ebc906
6
+ metadata.gz: d443116a4be710f698f02da8092b19b0d83f9b319c0e7b431ae9cfe67d11c208ddea48ff5c995057bd3b28056dafcb2ff8461c1ad3be8134f9dcaa926b96ef73
7
+ data.tar.gz: 530a30ff700f75312a5f72b38ef433f9f03a3eab9ac9d83297a3eacc20d680df4ab1f8a4bc3c5134146b3da71be6ffa23d151bc71824dc21022fe7c5aa592758
data/README.md CHANGED
@@ -62,6 +62,8 @@ HTML tags:
62
62
  CSS attributes (dimensional units are ignored and considered in pixel):
63
63
 
64
64
  - **background**: for *mark* tag (3/6 hex digits or RGB or color name), ex. `style="background: #FECD08"`
65
+ - **break-after**: go to a new page after some elements, ex. `style="break-after: auto"`
66
+ - **break-before**: go to a new page before some elements, ex. `style="break-before: auto"`
65
67
  - **color**: (3/6 hex digits or RGB or color name) ex. `style="color: #FB1"`
66
68
  - **font-family**: font must be registered, quotes are optional, ex. `style="font-family: Courier"`
67
69
  - **font-size**: ex. `style="font-size: 20px"`
data/lib/prawn-html.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'prawn'
4
-
5
3
  module PrawnHtml
6
4
  PX = 0.66 # conversion constant for pixel sixes
7
5
 
@@ -157,13 +155,17 @@ module PrawnHtml
157
155
  }.freeze
158
156
 
159
157
  def append_html(pdf, html)
160
- html_parser = PrawnHtml::HtmlParser.new(pdf)
158
+ pdf_wrapper = PdfWrapper.new(pdf)
159
+ renderer = DocumentRenderer.new(pdf_wrapper)
160
+ html_parser = PrawnHtml::HtmlParser.new(renderer)
161
161
  html_parser.process(html)
162
162
  end
163
163
 
164
164
  module_function :append_html
165
165
  end
166
166
 
167
+ require 'prawn'
168
+
167
169
  require 'prawn_html/utils'
168
170
 
169
171
  require 'prawn_html/tag'
@@ -172,5 +174,6 @@ Dir["#{__dir__}/prawn_html/callbacks/*.rb"].sort.each { |f| require f }
172
174
 
173
175
  require 'prawn_html/attributes'
174
176
  require 'prawn_html/context'
177
+ require 'prawn_html/pdf_wrapper'
175
178
  require 'prawn_html/document_renderer'
176
179
  require 'prawn_html/html_parser'
@@ -8,8 +8,8 @@ module PrawnHtml
8
8
 
9
9
  STYLES_APPLY = {
10
10
  block: %i[align leading left margin_left padding_left position top],
11
- tag_close: %i[margin_bottom padding_bottom],
12
- tag_open: %i[margin_top padding_top],
11
+ tag_close: %i[margin_bottom padding_bottom break_after],
12
+ tag_open: %i[margin_top padding_top break_before],
13
13
  text_node: %i[background callback character_spacing color font link list_style_type size styles]
14
14
  }.freeze
15
15
 
@@ -27,9 +27,11 @@ module PrawnHtml
27
27
  'list-style-type' => { key: :list_style_type, set: :unquote },
28
28
  'text-decoration' => { key: :styles, set: :append_symbol },
29
29
  # tag opening styles
30
+ 'break-before' => { key: :break_before, set: :convert_symbol },
30
31
  'margin-top' => { key: :margin_top, set: :convert_size },
31
32
  'padding-top' => { key: :padding_top, set: :convert_size },
32
33
  # tag closing styles
34
+ 'break-after' => { key: :break_after, set: :convert_symbol },
33
35
  'margin-bottom' => { key: :margin_bottom, set: :convert_size },
34
36
  'padding-bottom' => { key: :padding_bottom, set: :convert_size },
35
37
  # block styles
@@ -11,10 +11,8 @@ module PrawnHtml
11
11
  end
12
12
 
13
13
  def render_behind(fragment)
14
- original_color = @pdf.fill_color
15
- @pdf.fill_color = @color
16
- @pdf.fill_rectangle(fragment.top_left, fragment.width, fragment.height)
17
- @pdf.fill_color = original_color
14
+ top, left = fragment.top_left
15
+ @pdf.draw_rectangle(x: left, y: top, width: fragment.width, height: fragment.height, color: @color)
18
16
  end
19
17
  end
20
18
  end
@@ -8,10 +8,10 @@ module PrawnHtml
8
8
  end
9
9
 
10
10
  def render_in_front(fragment)
11
- y = (fragment.top_left[1] + fragment.bottom_left[1]) / 2
12
- @pdf.stroke do
13
- @pdf.line [fragment.top_left[0], y], [fragment.top_right[0], y]
14
- end
11
+ x1 = fragment.left
12
+ x2 = fragment.right
13
+ y = (fragment.top + fragment.bottom) / 2
14
+ @pdf.underline(x1: x1, x2: x2, y: y)
15
15
  end
16
16
  end
17
17
  end
@@ -7,7 +7,7 @@ module PrawnHtml
7
7
 
8
8
  # Init the DocumentRenderer
9
9
  #
10
- # @param pdf [Prawn::Document] target Prawn PDF document
10
+ # @param pdf [PdfWrapper] target PDF wrapper
11
11
  def initialize(pdf)
12
12
  @buffer = []
13
13
  @context = Context.new
@@ -103,14 +103,15 @@ module PrawnHtml
103
103
  def apply_tag_close_styles(element)
104
104
  tag_styles = element.tag_close_styles
105
105
  context.last_margin = tag_styles[:margin_bottom].to_f
106
- move_down = context.last_margin + tag_styles[:padding_bottom].to_f
107
- pdf.move_down(move_down) if move_down > 0
106
+ pdf.advance_cursor(context.last_margin + tag_styles[:padding_bottom].to_f)
107
+ pdf.start_new_page if tag_styles[:break_after]
108
108
  end
109
109
 
110
110
  def apply_tag_open_styles(element)
111
111
  tag_styles = element.tag_open_styles
112
112
  move_down = (tag_styles[:margin_top].to_f - context.last_margin) + tag_styles[:padding_top].to_f
113
- pdf.move_down(move_down) if move_down > 0
113
+ pdf.advance_cursor(move_down) if move_down > 0
114
+ pdf.start_new_page if tag_styles[:break_before]
114
115
  end
115
116
 
116
117
  def output_content(buffer, block_styles)
@@ -118,17 +119,7 @@ module PrawnHtml
118
119
  left_indent = block_styles[:margin_left].to_f + block_styles[:padding_left].to_f
119
120
  options = block_styles.slice(:align, :leading, :mode, :padding_left)
120
121
  options[:indent_paragraphs] = left_indent if left_indent > 0
121
- formatted_text(buffer, options, bounding_box: bounds(block_styles))
122
- end
123
-
124
- def formatted_text(buffer, options, bounding_box: nil)
125
- return pdf.formatted_text(buffer, options) unless bounding_box
126
-
127
- current_y = pdf.cursor
128
- pdf.bounding_box(*bounding_box) do
129
- pdf.formatted_text(buffer, options)
130
- end
131
- pdf.move_cursor_to(current_y)
122
+ pdf.puts(buffer, options, bounding_box: bounds(block_styles))
132
123
  end
133
124
 
134
125
  def bounds(block_styles)
@@ -6,13 +6,13 @@ module PrawnHtml
6
6
  class HtmlParser
7
7
  # Init the HtmlParser
8
8
  #
9
- # @param pdf [Prawn::Document] Target Prawn PDF document
10
- def initialize(pdf)
9
+ # @param renderer [DocumentRenderer] document renderer
10
+ def initialize(renderer)
11
11
  @processing = false
12
- @renderer = DocumentRenderer.new(pdf)
12
+ @renderer = renderer
13
13
  end
14
14
 
15
- # Processes HTML and renders it on the PDF document
15
+ # Processes HTML and renders it
16
16
  #
17
17
  # @param html [String] The HTML content to process
18
18
  def process(html)
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module PrawnHtml
6
+ class PdfWrapper
7
+ extend Forwardable
8
+
9
+ def_delegators :@pdf, :bounds, :start_new_page
10
+
11
+ # Wrapper for Prawn PDF Document
12
+ #
13
+ # @param pdf_document [Prawn::Document] PDF document to wrap
14
+ def initialize(pdf_document)
15
+ @pdf = pdf_document
16
+ end
17
+
18
+ # Advance the cursor
19
+ #
20
+ # @param move_down [Float] Quantity to advance (move down)
21
+ def advance_cursor(move_down)
22
+ return if !move_down || move_down == 0
23
+
24
+ pdf.move_down(move_down)
25
+ end
26
+
27
+ # Draw a rectangle
28
+ #
29
+ # @param x [Float] left position of the rectangle
30
+ # @param y [Float] top position of the rectangle
31
+ # @param width [Float] width of the rectangle
32
+ # @param height [Float] height of the rectangle
33
+ # @param color [String] fill color
34
+ def draw_rectangle(x:, y:, width:, height:, color:)
35
+ current_fill_color = pdf.fill_color
36
+ pdf.fill_color = color
37
+ pdf.fill_rectangle([y, x], width, height)
38
+ pdf.fill_color = current_fill_color
39
+ end
40
+
41
+ # Horizontal line
42
+ #
43
+ # @param color [String] line color
44
+ # @param dash [Integer|Array] integer or array of integer with dash options
45
+ def horizontal_rule(color:, dash:)
46
+ current_color = pdf.stroke_color
47
+ pdf.dash(dash) if dash
48
+ pdf.stroke_color = color if color
49
+ pdf.stroke_horizontal_rule
50
+ pdf.stroke_color = current_color if color
51
+ pdf.undash if dash
52
+ end
53
+
54
+ # Image
55
+ #
56
+ # @param src [String] image source path
57
+ # @param options [Hash] hash of options
58
+ def image(src, options = {})
59
+ return unless src
60
+
61
+ pdf.image(src, options)
62
+ end
63
+
64
+ # Output to the PDF document
65
+ #
66
+ # @param buffer [Array] array of text items
67
+ # @param options [Hash] hash of options
68
+ # @param bounding_box [Array] bounding box arguments, if bounded
69
+ def puts(buffer, options, bounding_box: nil)
70
+ return pdf.formatted_text(buffer, options) unless bounding_box
71
+
72
+ current_y = pdf.cursor
73
+ pdf.bounding_box(*bounding_box) do
74
+ pdf.formatted_text(buffer, options)
75
+ end
76
+ pdf.move_cursor_to(current_y)
77
+ end
78
+
79
+ # Underline
80
+ #
81
+ # @param x1 [Float] left position of the line
82
+ # @param x2 [Float] right position of the line
83
+ # @param y [Float] vertical position of the line
84
+ def underline(x1:, x2:, y:)
85
+ pdf.stroke do
86
+ pdf.line [x1, y], [x2, y]
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ attr_reader :pdf
93
+ end
94
+ end
@@ -5,7 +5,7 @@ module PrawnHtml
5
5
  class Br < Tag
6
6
  ELEMENTS = [:br].freeze
7
7
 
8
- BR_SPACING = 12
8
+ BR_SPACING = Utils.convert_size('12')
9
9
 
10
10
  def block?
11
11
  true
@@ -14,8 +14,7 @@ module PrawnHtml
14
14
  def custom_render(pdf, context)
15
15
  return if context.last_text_node
16
16
 
17
- @spacing ||= Utils.convert_size(BR_SPACING.to_s)
18
- pdf.move_down(@spacing)
17
+ pdf.advance_cursor(BR_SPACING)
19
18
  end
20
19
  end
21
20
  end
@@ -13,10 +13,8 @@ module PrawnHtml
13
13
  end
14
14
 
15
15
  def custom_render(pdf, _context)
16
- dash = parse_dash_value(attrs.data['dash']) if attrs.data.include?('dash')
17
- around_stroke(pdf, old_color: pdf.stroke_color, new_color: attrs.styles[:color], dash: dash) do
18
- pdf.stroke_horizontal_rule
19
- end
16
+ dash = attrs.data.include?('dash') ? parse_dash_value(attrs.data['dash']) : nil
17
+ pdf.horizontal_rule(color: attrs.styles[:color], dash: dash)
20
18
  end
21
19
 
22
20
  def tag_styles
@@ -28,14 +26,6 @@ module PrawnHtml
28
26
 
29
27
  private
30
28
 
31
- def around_stroke(pdf, old_color:, new_color:, dash:)
32
- pdf.dash(dash) if dash
33
- pdf.stroke_color = new_color if new_color
34
- yield
35
- pdf.stroke_color = old_color if new_color
36
- pdf.undash if dash
37
- end
38
-
39
29
  def parse_dash_value(dash_string)
40
30
  if dash_string.match? /\A\d+\Z/
41
31
  dash_string.to_i
@@ -13,7 +13,7 @@ module PrawnHtml
13
13
  parsed_styles = Attributes.parse_styles(attrs.style)
14
14
  block_styles = context.block_styles
15
15
  evaluated_styles = evaluate_styles(pdf, block_styles.merge(parsed_styles))
16
- pdf.image(@attrs.src, evaluated_styles) if @attrs.src
16
+ pdf.image(@attrs.src, evaluated_styles)
17
17
  end
18
18
 
19
19
  private
@@ -51,7 +51,7 @@ module PrawnHtml
51
51
  if container_size && value.include?('%')
52
52
  val.to_f * container_size * 0.01
53
53
  else
54
- val.to_f * PX
54
+ val.to_f * PrawnHtml::PX
55
55
  end
56
56
  val.round(4)
57
57
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrawnHtml # :nodoc:
4
- VERSION = '0.3.0'
4
+ VERSION = '0.3.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prawn-html
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattia Roccoberton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-22 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oga
@@ -53,6 +53,7 @@ files:
53
53
  - lib/prawn_html/context.rb
54
54
  - lib/prawn_html/document_renderer.rb
55
55
  - lib/prawn_html/html_parser.rb
56
+ - lib/prawn_html/pdf_wrapper.rb
56
57
  - lib/prawn_html/tag.rb
57
58
  - lib/prawn_html/tags/a.rb
58
59
  - lib/prawn_html/tags/b.rb