prawn-html 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,29 +13,19 @@ 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
23
- @tag_styles ||= {
24
- 'margin-bottom' => MARGIN_BOTTOM.to_s,
25
- 'margin-top' => MARGIN_TOP.to_s,
26
- }
21
+ <<~STYLES
22
+ margin-bottom: #{MARGIN_BOTTOM}px;
23
+ margin-top: #{MARGIN_TOP}px;
24
+ STYLES
27
25
  end
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
@@ -6,9 +6,7 @@ module PrawnHtml
6
6
  ELEMENTS = [:i, :em].freeze
7
7
 
8
8
  def tag_styles
9
- {
10
- 'font-style' => 'italic'
11
- }
9
+ 'font-style: italic'
12
10
  end
13
11
  end
14
12
  end
@@ -12,16 +12,17 @@ module PrawnHtml
12
12
  def custom_render(pdf, context)
13
13
  parsed_styles = Attributes.parse_styles(attrs.style)
14
14
  block_styles = context.block_styles
15
- evaluated_styles = evaluate_styles(pdf, block_styles.merge(parsed_styles))
16
- pdf.image(@attrs.src, evaluated_styles) if @attrs.src
15
+ evaluated_styles = adjust_styles(pdf, block_styles.merge(parsed_styles))
16
+ pdf.image(@attrs.src, evaluated_styles)
17
17
  end
18
18
 
19
19
  private
20
20
 
21
- def evaluate_styles(pdf, img_styles)
21
+ def adjust_styles(pdf, img_styles)
22
22
  {}.tap do |result|
23
- result[:width] = Utils.convert_size(img_styles['width'], pdf.bounds.width) if img_styles.include?('width')
24
- result[:height] = Utils.convert_size(img_styles['height'], pdf.bounds.height) if img_styles.include?('height')
23
+ w, h = img_styles['width'], img_styles['height']
24
+ result[:width] = Utils.convert_size(w, options: pdf.page_width) if w
25
+ result[:height] = Utils.convert_size(h, options: pdf.page_height) if h
25
26
  result[:position] = img_styles[:align] if %i[left center right].include?(img_styles[:align])
26
27
  end
27
28
  end
@@ -5,19 +5,32 @@ module PrawnHtml
5
5
  class Li < Tag
6
6
  ELEMENTS = [:li].freeze
7
7
 
8
+ INDENT_OL = -12
9
+ INDENT_UL = -6
10
+
8
11
  def block?
9
12
  true
10
13
  end
11
14
 
12
- def on_context_add(_context)
13
- @counter = (parent.counter += 1) if parent.is_a? Ol
14
- @symbol = parent.styles[:list_style_type] || '&bullet;' if parent.is_a? Ul
15
+ def before_content
16
+ @counter ? "#{@counter}. " : "#{@symbol} "
15
17
  end
16
18
 
17
- def tag_styles
18
- {
19
- before_content: @counter ? "#{@counter}. " : "#{@symbol} "
20
- }
19
+ def block_styles
20
+ super.tap do |bs|
21
+ bs[:indent_paragraphs] = @indent
22
+ end
23
+ end
24
+
25
+ def on_context_add(_context)
26
+ case parent.class.to_s
27
+ when 'PrawnHtml::Tags::Ol'
28
+ @indent = INDENT_OL
29
+ @counter = (parent.counter += 1)
30
+ when 'PrawnHtml::Tags::Ul'
31
+ @indent = INDENT_UL
32
+ @symbol = parent.styles[:list_style_type] || '&bullet;'
33
+ end
21
34
  end
22
35
  end
23
36
  end
@@ -6,9 +6,7 @@ module PrawnHtml
6
6
  ELEMENTS = [:mark].freeze
7
7
 
8
8
  def tag_styles
9
- {
10
- 'callback' => Callbacks::Highlight
11
- }
9
+ 'background: #ff0'
12
10
  end
13
11
  end
14
12
  end
@@ -5,23 +5,38 @@ module PrawnHtml
5
5
  class Ol < Tag
6
6
  ELEMENTS = [:ol].freeze
7
7
 
8
- MARGIN_LEFT = 25
8
+ MARGIN_TOP = 15
9
+ MARGIN_LEFT = 40
10
+ MARGIN_BOTTOM = 15
9
11
 
10
12
  attr_accessor :counter
11
13
 
12
- def initialize(*_args)
14
+ def initialize(tag, attributes: {}, options: {})
13
15
  super
14
16
  @counter = 0
17
+ @first_level = false
15
18
  end
16
19
 
17
20
  def block?
18
21
  true
19
22
  end
20
23
 
24
+ def on_context_add(context)
25
+ return if context.map(&:tag).count { |el| el == :ol } > 1
26
+
27
+ @first_level = true
28
+ end
29
+
21
30
  def tag_styles
22
- @tag_styles ||= {
23
- 'margin-left' => MARGIN_LEFT.to_s,
24
- }
31
+ if @first_level
32
+ <<~STYLES
33
+ margin-top: #{MARGIN_TOP}px;
34
+ margin-left: #{MARGIN_LEFT}px;
35
+ margin-bottom: #{MARGIN_BOTTOM}px;
36
+ STYLES
37
+ else
38
+ "margin-left: #{MARGIN_LEFT}px"
39
+ end
25
40
  end
26
41
  end
27
42
  end
@@ -5,18 +5,18 @@ module PrawnHtml
5
5
  class P < Tag
6
6
  ELEMENTS = [:p].freeze
7
7
 
8
- MARGIN_BOTTOM = 6
9
- MARGIN_TOP = 6
8
+ MARGIN_BOTTOM = 12.5
9
+ MARGIN_TOP = 12.5
10
10
 
11
11
  def block?
12
12
  true
13
13
  end
14
14
 
15
15
  def tag_styles
16
- @tag_styles ||= {
17
- 'margin-bottom' => MARGIN_BOTTOM.to_s,
18
- 'margin-top' => MARGIN_TOP.to_s
19
- }
16
+ <<~STYLES
17
+ margin-bottom: #{MARGIN_BOTTOM}px;
18
+ margin-top: #{MARGIN_TOP}px;
19
+ STYLES
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrawnHtml
4
+ module Tags
5
+ class Pre < Tag
6
+ ELEMENTS = [:pre].freeze
7
+
8
+ MARGIN_BOTTOM = 14
9
+ MARGIN_TOP = 14
10
+
11
+ def block?
12
+ true
13
+ end
14
+
15
+ def tag_styles
16
+ <<~STYLES
17
+ font-family: Courier;
18
+ margin-bottom: #{MARGIN_BOTTOM}px;
19
+ margin-top: #{MARGIN_TOP}px;
20
+ white-space: pre;
21
+ STYLES
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrawnHtml
4
+ module Tags
5
+ class Sub < Tag
6
+ ELEMENTS = [:sub].freeze
7
+
8
+ def tag_styles
9
+ 'vertical-align: sub'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrawnHtml
4
+ module Tags
5
+ class Sup < Tag
6
+ ELEMENTS = [:sup].freeze
7
+
8
+ def tag_styles
9
+ 'vertical-align: super'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -6,9 +6,7 @@ module PrawnHtml
6
6
  ELEMENTS = [:ins, :u].freeze
7
7
 
8
8
  def tag_styles
9
- {
10
- 'text-decoration' => 'underline'
11
- }
9
+ 'text-decoration: underline'
12
10
  end
13
11
  end
14
12
  end
@@ -5,16 +5,35 @@ module PrawnHtml
5
5
  class Ul < Tag
6
6
  ELEMENTS = [:ul].freeze
7
7
 
8
- MARGIN_LEFT = 25
8
+ MARGIN_TOP = 15
9
+ MARGIN_LEFT = 40
10
+ MARGIN_BOTTOM = 15
11
+
12
+ def initialize(tag, attributes: {}, options: {})
13
+ super
14
+ @first_level = false
15
+ end
9
16
 
10
17
  def block?
11
18
  true
12
19
  end
13
20
 
21
+ def on_context_add(context)
22
+ return if context.map(&:tag).count { |el| el == :ul } > 1
23
+
24
+ @first_level = true
25
+ end
26
+
14
27
  def tag_styles
15
- @tag_styles ||= {
16
- 'margin-left' => MARGIN_LEFT.to_s,
17
- }
28
+ if @first_level
29
+ <<~STYLES
30
+ margin-top: #{MARGIN_TOP}px;
31
+ margin-left: #{MARGIN_LEFT}px;
32
+ margin-bottom: #{MARGIN_BOTTOM}px;
33
+ STYLES
34
+ else
35
+ "margin-left: #{MARGIN_LEFT}px"
36
+ end
18
37
  end
19
38
  end
20
39
  end
@@ -2,6 +2,32 @@
2
2
 
3
3
  module PrawnHtml
4
4
  module Utils
5
+ NORMALIZE_STYLES = {
6
+ 'bold' => :bold,
7
+ 'italic' => :italic,
8
+ 'sub' => :subscript,
9
+ 'super' => :superscript,
10
+ 'underline' => :underline
11
+ }.freeze
12
+
13
+ # Setup a background callback
14
+ #
15
+ # @param value [String] HTML string color
16
+ #
17
+ # @return [Array] callback name and argument value
18
+ def callback_background(value, options: nil)
19
+ ['Background', convert_color(value, options: options)]
20
+ end
21
+
22
+ # Setup a strike through callback
23
+ #
24
+ # @param value [String] unused
25
+ #
26
+ # @return [Array] callback name and argument value
27
+ def callback_strike_through(value, options: nil)
28
+ ['StrikeThrough', nil]
29
+ end
30
+
5
31
  # Converts a color string
6
32
  #
7
33
  # Supported formats:
@@ -13,7 +39,7 @@ module PrawnHtml
13
39
  # @param value [String] HTML string color
14
40
  #
15
41
  # @return [String] adjusted string color or nil if value is invalid
16
- def convert_color(value)
42
+ def convert_color(value, options: nil)
17
43
  val = value.to_s.strip.downcase
18
44
  return Regexp.last_match[1] if val.match /\A#([a-f0-9]{6})\Z/ # rubocop:disable Performance/RedundantMatch
19
45
 
@@ -34,7 +60,7 @@ module PrawnHtml
34
60
  # @param value [String] string decimal
35
61
  #
36
62
  # @return [Float] converted and rounded float number
37
- def convert_float(value)
63
+ def convert_float(value, options: nil)
38
64
  val = value&.gsub(/[^0-9.]/, '') || ''
39
65
  val.to_f.round(4)
40
66
  end
@@ -42,16 +68,16 @@ module PrawnHtml
42
68
  # Converts a size string
43
69
  #
44
70
  # @param value [String] size string
45
- # @param container_size [Numeric] container size
71
+ # @param options [Numeric] container size
46
72
  #
47
73
  # @return [Float] converted and rounded size
48
- def convert_size(value, container_size = nil)
74
+ def convert_size(value, options: nil)
49
75
  val = value&.gsub(/[^0-9.]/, '') || ''
50
76
  val =
51
- if container_size && value.include?('%')
52
- val.to_f * container_size * 0.01
77
+ if options && value&.include?('%')
78
+ val.to_f * options * 0.01
53
79
  else
54
- val.to_f * PX
80
+ val.to_f * PrawnHtml::PX
55
81
  end
56
82
  val.round(4)
57
83
  end
@@ -61,7 +87,7 @@ module PrawnHtml
61
87
  # @param value [String] string
62
88
  #
63
89
  # @return [Symbol] symbol
64
- def convert_symbol(value)
90
+ def convert_symbol(value, options: nil)
65
91
  value.to_sym if value && !value.match?(/\A\s*\Z/)
66
92
  end
67
93
 
@@ -70,21 +96,32 @@ module PrawnHtml
70
96
  # @param value
71
97
  #
72
98
  # @return value
73
- def copy_value(value)
99
+ def copy_value(value, options: nil)
74
100
  value
75
101
  end
76
102
 
103
+ # Normalize a style value
104
+ #
105
+ # @param value [String] string value
106
+ #
107
+ # @return [Symbol] style value or nil
108
+ def normalize_style(value)
109
+ val = value&.strip&.downcase
110
+ NORMALIZE_STYLES[val]
111
+ end
112
+
77
113
  # Unquotes a string
78
114
  #
79
115
  # @param value [String] string
80
116
  #
81
117
  # @return [String] string without quotes at the beginning/ending
82
- def unquote(value)
118
+ def unquote(value, options: nil)
83
119
  (value&.strip || +'').tap do |val|
84
120
  val.gsub!(/\A['"]|["']\Z/, '')
85
121
  end
86
122
  end
87
123
 
88
- module_function :convert_color, :convert_float, :convert_size, :convert_symbol, :copy_value, :unquote
124
+ module_function :callback_background, :callback_strike_through, :convert_color, :convert_float, :convert_size,
125
+ :convert_symbol, :copy_value, :normalize_style, :unquote
89
126
  end
90
127
  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.5.0'
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.5.0
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-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oga
@@ -48,16 +48,19 @@ files:
48
48
  - README.md
49
49
  - lib/prawn-html.rb
50
50
  - lib/prawn_html/attributes.rb
51
- - lib/prawn_html/callbacks/highlight.rb
51
+ - lib/prawn_html/callbacks/background.rb
52
52
  - lib/prawn_html/callbacks/strike_through.rb
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
60
+ - lib/prawn_html/tags/blockquote.rb
59
61
  - lib/prawn_html/tags/body.rb
60
62
  - lib/prawn_html/tags/br.rb
63
+ - lib/prawn_html/tags/code.rb
61
64
  - lib/prawn_html/tags/del.rb
62
65
  - lib/prawn_html/tags/div.rb
63
66
  - lib/prawn_html/tags/h.rb
@@ -68,8 +71,11 @@ files:
68
71
  - lib/prawn_html/tags/mark.rb
69
72
  - lib/prawn_html/tags/ol.rb
70
73
  - lib/prawn_html/tags/p.rb
74
+ - lib/prawn_html/tags/pre.rb
71
75
  - lib/prawn_html/tags/small.rb
72
76
  - lib/prawn_html/tags/span.rb
77
+ - lib/prawn_html/tags/sub.rb
78
+ - lib/prawn_html/tags/sup.rb
73
79
  - lib/prawn_html/tags/u.rb
74
80
  - lib/prawn_html/tags/ul.rb
75
81
  - lib/prawn_html/utils.rb