prawn-html 0.6.0 → 0.6.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: 3b659b809526c4c961782f613e6946613232dd836ac056ca48d3dabebdbf9a02
4
- data.tar.gz: 2549b8b8b872b44f3d6f424236249e7795f97afeadf95299bf06836fb979a13a
3
+ metadata.gz: 105884df1bf42d6aa44ff0a102a025960740c0d5a771c27e75949113cd7b9b70
4
+ data.tar.gz: abe3998f3f65cd2b421280d99151f18e321ac650dd8abed26260062e6f8e455a
5
5
  SHA512:
6
- metadata.gz: b58a21e4424c89db5ff388ab2507ec502ea283ba9e6234d46f3688e477ba21944ee72f813cc9ddb4454426f5e4cc7397531ffa34c74eeb7795a0bbbeaa8d34ed
7
- data.tar.gz: 0e3cfad427968577135c8c8791f698b3c5d6e95463b9364d0630d9caf87407f378c3fb725bfe11349cad210d1d0c3bba1a90555ebb9219c620e674fff0413ff8
6
+ metadata.gz: 0dc20b1ee2c6bd1321b4359e31e217cea923c68f5f3af242b097d56d9492f198e1df6af263cadcf75978c83700a90cad3cfbae08d25e9b0ebb39ddea6ad2c059
7
+ data.tar.gz: 88180bff0e1aac88d566911fafac9c6b6ae799eee6c1f77948f0bc811825f03c2e7ca2c8b1bf8962dc60e27ba355904d77289e3870e1c3faecd8c362e6536237
data/README.md CHANGED
@@ -35,34 +35,34 @@ To check some examples with the PDF output see [examples](examples/) folder.
35
35
 
36
36
  ## Supported tags & attributes
37
37
 
38
- HTML tags:
39
-
40
- - **a**: link
41
- - **b**: bold
42
- - **blockquote**: block quotation element
43
- - **br**: new line
44
- - **code**: inline code element
45
- - **del**: strike-through
46
- - **div**: block element
47
- - **em**: italic
48
- - **h1** - **h6**: headings
49
- - **hr**: horizontal line
50
- - **i**: italic
51
- - **ins**: underline
52
- - **img**: image
53
- - **li**: list item
54
- - **mark**: highlight
55
- - **ol**: ordered list
56
- - **p**: block element
57
- - **pre**: preformatted text element
58
- - **s**: strike-through
59
- - **small**: smaller text
60
- - **span**: inline element
61
- - **strong**: bold
62
- - **sub**: subscript element
63
- - **sup**: superscript element
64
- - **u**: underline
65
- - **ul**: unordered list
38
+ HTML tags (using MDN definitions):
39
+
40
+ - **a**: the Anchor element
41
+ - **b**: the Bring Attention To element
42
+ - **blockquote**: the Block Quotation element
43
+ - **br**: the Line Break element
44
+ - **code**: the Inline Code element
45
+ - **del**: the Deleted Text element
46
+ - **div**: the Content Division element
47
+ - **em**: the Emphasis element
48
+ - **h1** - **h6**: the HTML Section Heading elements
49
+ - **hr**: the Thematic Break (Horizontal Rule) element
50
+ - **i**: the Idiomatic Text element
51
+ - **ins**: the added text element
52
+ - **img**: the Image Embed element
53
+ - **li**: the list item element
54
+ - **mark**: the Mark Text element
55
+ - **ol**: the Ordered List element
56
+ - **p**: the Paragraph element
57
+ - **pre**: the Preformatted Text element
58
+ - **s**: the strike-through text element
59
+ - **small**: the side comment element
60
+ - **span**: the generic inline element
61
+ - **strong**: the Strong Importance element
62
+ - **sub**: the Subscript element
63
+ - **sup**: the Superscript element
64
+ - **u**: the Unarticulated Annotation (Underline) element
65
+ - **ul**: the Unordered List element
66
66
 
67
67
  CSS attributes (dimensional units are ignored and considered in pixel):
68
68
 
data/lib/prawn-html.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrawnHtml
4
+ ADJUST_LEADING = { nil => 0.18, 'Courier' => -0.07, 'Helvetica' => -0.17, 'Times-Roman' => 0.03 }.freeze
4
5
  PX = 0.6 # conversion constant for pixel sixes
5
6
 
6
7
  COLORS = {
@@ -154,7 +154,7 @@ module PrawnHtml
154
154
  return (@initial << rule) if value == 'initial'
155
155
 
156
156
  if rule[:set] == :append_styles
157
- val = Utils.normalize_style(value)
157
+ val = Utils.normalize_style(value, rule[:values])
158
158
  (merged_styles[rule[:key]] ||= []) << val if val
159
159
  else
160
160
  opts = rule[:options] ? options[rule[:options]] : nil
@@ -67,10 +67,17 @@ module PrawnHtml
67
67
  last.on_context_remove(self) if last.respond_to?(:on_context_remove)
68
68
  @merged_styles = nil
69
69
  @last_text_node = false
70
- @previous_tag = last.tag
70
+ @previous_tag = last
71
71
  pop
72
72
  end
73
73
 
74
+ # White space is equal to 'pre'?
75
+ #
76
+ # @return [boolean] white space property of the last element is equal to 'pre'
77
+ def white_space_pre?
78
+ last && last.styles[:white_space] == :pre
79
+ end
80
+
74
81
  private
75
82
 
76
83
  def evaluate_element_styles(element, res)
@@ -12,6 +12,8 @@ module PrawnHtml
12
12
  @buffer = []
13
13
  @context = Context.new
14
14
  @last_margin = 0
15
+ @last_text = ''
16
+ @last_tag_open = false
15
17
  @pdf = pdf
16
18
  end
17
19
 
@@ -22,6 +24,8 @@ module PrawnHtml
22
24
  render_if_needed(element)
23
25
  apply_tag_close_styles(element)
24
26
  context.remove_last
27
+ @last_tag_open = false
28
+ @last_text = ''
25
29
  end
26
30
 
27
31
  # On tag open callback
@@ -38,6 +42,7 @@ module PrawnHtml
38
42
  options = { width: pdf.page_width, height: pdf.page_height }
39
43
  tag_class.new(tag_name, attributes: attributes, options: options).tap do |element|
40
44
  setup_element(element, element_styles: element_styles)
45
+ @last_tag_open = true
41
46
  end
42
47
  end
43
48
 
@@ -47,9 +52,10 @@ module PrawnHtml
47
52
  #
48
53
  # @return [NilClass] nil value (=> no element)
49
54
  def on_text_node(content)
50
- return if content.match?(/\A\s*\Z/)
55
+ return if context.previous_tag&.block? && content.match?(/\A\s*\Z/)
51
56
 
52
- buffer << context.merged_styles.merge(text: prepare_text(content))
57
+ text = prepare_text(content)
58
+ buffer << context.merged_styles.merge(text: text) unless text.empty?
53
59
  context.last_text_node = true
54
60
  nil
55
61
  end
@@ -70,17 +76,13 @@ module PrawnHtml
70
76
  attr_reader :buffer, :context, :last_margin, :pdf
71
77
 
72
78
  def setup_element(element, element_styles:)
73
- add_space_if_needed unless render_if_needed(element)
79
+ render_if_needed(element)
74
80
  context.add(element)
75
81
  element.process_styles(element_styles: element_styles)
76
82
  apply_tag_open_styles(element)
77
83
  element.custom_render(pdf, context) if element.respond_to?(:custom_render)
78
84
  end
79
85
 
80
- def add_space_if_needed
81
- buffer << SPACE if buffer.any? && !context.last_text_node && ![NEW_LINE, SPACE].include?(buffer.last)
82
- end
83
-
84
86
  def render_if_needed(element)
85
87
  render_needed = element&.block? && buffer.any? && buffer.last != NEW_LINE
86
88
  return false unless render_needed
@@ -104,10 +106,12 @@ module PrawnHtml
104
106
  end
105
107
 
106
108
  def prepare_text(content)
107
- white_space_pre = context.last && context.last.styles[:white_space] == :pre
108
- text = ::Oga::HTML::Entities.decode(context.before_content)
109
- text += white_space_pre ? content : content.gsub(/\A\s*\n\s*|\s*\n\s*\Z/, '').delete("\n").squeeze(' ')
110
- text
109
+ text = context.before_content ? ::Oga::HTML::Entities.decode(context.before_content) : ''
110
+ return (@last_text = text + content) if context.white_space_pre?
111
+
112
+ content = content.lstrip if @last_text[-1] == ' ' || @last_tag_open
113
+ text += content.tr("\n", ' ').squeeze(' ')
114
+ @last_text = text
111
115
  end
112
116
 
113
117
  def output_content(buffer, block_styles)
@@ -129,7 +133,10 @@ module PrawnHtml
129
133
  def adjust_leading(buffer, leading)
130
134
  return leading if leading
131
135
 
132
- (buffer.map { |item| item[:size] || Context::DEFAULT_STYLES[:size] }.max * 0.055).round(4)
136
+ leadings = buffer.map do |item|
137
+ (item[:size] || Context::DEFAULT_STYLES[:size]) * (ADJUST_LEADING[item[:font]] || ADJUST_LEADING[nil])
138
+ end
139
+ leadings.max.round(4)
133
140
  end
134
141
 
135
142
  def bounds(buffer, options, block_styles)
@@ -12,7 +12,7 @@ module PrawnHtml
12
12
  end
13
13
 
14
14
  def custom_render(pdf, context)
15
- return if context.last_text_node || context.previous_tag != :br
15
+ return if context.last_text_node || !context.previous_tag.is_a?(Br)
16
16
 
17
17
  pdf.advance_cursor(BR_SPACING)
18
18
  end
@@ -103,11 +103,13 @@ module PrawnHtml
103
103
  # Normalize a style value
104
104
  #
105
105
  # @param value [String] string value
106
+ # @param accepted_values [Array] allowlist of valid values (symbols)
106
107
  #
107
108
  # @return [Symbol] style value or nil
108
- def normalize_style(value)
109
+ def normalize_style(value, accepted_values)
109
110
  val = value&.strip&.downcase
110
- NORMALIZE_STYLES[val]
111
+ ret = NORMALIZE_STYLES[val]
112
+ accepted_values.include?(ret) ? ret : nil
111
113
  end
112
114
 
113
115
  # Unquotes a string
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrawnHtml # :nodoc:
4
- VERSION = '0.6.0'
4
+ VERSION = '0.6.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.6.0
4
+ version: 0.6.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-09-14 00:00:00.000000000 Z
11
+ date: 2021-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oga