prawn-html 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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