prawn-html 0.6.0 → 0.6.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: 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