prawn-html 0.3.0 → 0.5.0
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 +4 -4
- data/README.md +8 -2
- data/lib/prawn-html.rb +9 -5
- data/lib/prawn_html/attributes.rb +45 -33
- data/lib/prawn_html/callbacks/background.rb +19 -0
- data/lib/prawn_html/callbacks/strike_through.rb +4 -4
- data/lib/prawn_html/context.rb +22 -11
- data/lib/prawn_html/document_renderer.rb +56 -45
- data/lib/prawn_html/html_parser.rb +38 -13
- data/lib/prawn_html/pdf_wrapper.rb +141 -0
- data/lib/prawn_html/tag.rb +18 -23
- data/lib/prawn_html/tags/a.rb +7 -1
- data/lib/prawn_html/tags/b.rb +1 -3
- data/lib/prawn_html/tags/blockquote.rb +25 -0
- data/lib/prawn_html/tags/body.rb +4 -0
- data/lib/prawn_html/tags/br.rb +3 -4
- data/lib/prawn_html/tags/code.rb +13 -0
- data/lib/prawn_html/tags/del.rb +1 -3
- data/lib/prawn_html/tags/h.rb +21 -21
- data/lib/prawn_html/tags/hr.rb +6 -16
- data/lib/prawn_html/tags/i.rb +1 -3
- data/lib/prawn_html/tags/img.rb +6 -5
- data/lib/prawn_html/tags/li.rb +20 -7
- data/lib/prawn_html/tags/mark.rb +1 -3
- data/lib/prawn_html/tags/ol.rb +20 -5
- data/lib/prawn_html/tags/p.rb +6 -6
- data/lib/prawn_html/tags/pre.rb +25 -0
- data/lib/prawn_html/tags/sub.rb +13 -0
- data/lib/prawn_html/tags/sup.rb +13 -0
- data/lib/prawn_html/tags/u.rb +1 -3
- data/lib/prawn_html/tags/ul.rb +23 -4
- data/lib/prawn_html/utils.rb +48 -11
- data/lib/prawn_html/version.rb +1 -1
- metadata +9 -3
- data/lib/prawn_html/callbacks/highlight.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e82e0a464e39fd4c47c399cb043ceefe090524b29ead1c06795a484d4c648388
|
4
|
+
data.tar.gz: e124a7fb9800a434f42d403b478c6a6cb30b4e7d1e7e540d015028dec6daaa59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c08e1252e2c9c8f1591840179549d3e14483d91361b1a9f56d96f23cfa30829b98d8d2ace33808a73a9467e1ff37054d7f462d1c7170db273a4ff83b203d807f
|
7
|
+
data.tar.gz: '0979bd9a66e463ee8e4ea3c141a2d4e2fcc0e3b1bc82397aeda2e357c10c4518b00b1e1e4fc3f2ec786070c6d229241423cd5933a89fbc9137bdccc211d22a44'
|
data/README.md
CHANGED
@@ -39,7 +39,9 @@ HTML tags:
|
|
39
39
|
|
40
40
|
- **a**: link
|
41
41
|
- **b**: bold
|
42
|
+
- **blockquote**: block quotation element
|
42
43
|
- **br**: new line
|
44
|
+
- **code**: inline code element
|
43
45
|
- **del**: strike-through
|
44
46
|
- **div**: block element
|
45
47
|
- **em**: italic
|
@@ -52,16 +54,21 @@ HTML tags:
|
|
52
54
|
- **mark**: highlight
|
53
55
|
- **ol**: ordered list
|
54
56
|
- **p**: block element
|
57
|
+
- **pre**: preformatted text element
|
55
58
|
- **s**: strike-through
|
56
59
|
- **small**: smaller text
|
57
60
|
- **span**: inline element
|
58
61
|
- **strong**: bold
|
62
|
+
- **sub**: subscript element
|
63
|
+
- **sup**: superscript element
|
59
64
|
- **u**: underline
|
60
65
|
- **ul**: unordered list
|
61
66
|
|
62
67
|
CSS attributes (dimensional units are ignored and considered in pixel):
|
63
68
|
|
64
69
|
- **background**: for *mark* tag (3/6 hex digits or RGB or color name), ex. `style="background: #FECD08"`
|
70
|
+
- **break-after**: go to a new page after some elements, ex. `style="break-after: auto"`
|
71
|
+
- **break-before**: go to a new page before some elements, ex. `style="break-before: auto"`
|
65
72
|
- **color**: (3/6 hex digits or RGB or color name) ex. `style="color: #FB1"`
|
66
73
|
- **font-family**: font must be registered, quotes are optional, ex. `style="font-family: Courier"`
|
67
74
|
- **font-size**: ex. `style="font-size: 20px"`
|
@@ -98,8 +105,7 @@ Some custom data attributes are used to pass options:
|
|
98
105
|
|
99
106
|
## Document styles
|
100
107
|
|
101
|
-
|
102
|
-
Only single CSS selectors and basic ones are supported. Example:
|
108
|
+
You can define document CSS rules inside an _head_ tag. Example:
|
103
109
|
|
104
110
|
```html
|
105
111
|
<!DOCTYPE html>
|
data/lib/prawn-html.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'prawn'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
|
-
PX = 0.
|
4
|
+
PX = 0.6 # conversion constant for pixel sixes
|
7
5
|
|
8
6
|
COLORS = {
|
9
7
|
'aliceblue' => 'f0f8ff',
|
@@ -157,20 +155,26 @@ module PrawnHtml
|
|
157
155
|
}.freeze
|
158
156
|
|
159
157
|
def append_html(pdf, html)
|
160
|
-
|
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
|
|
171
|
+
Dir["#{__dir__}/prawn_html/callbacks/*.rb"].sort.each { |f| require f }
|
172
|
+
|
169
173
|
require 'prawn_html/tag'
|
170
174
|
Dir["#{__dir__}/prawn_html/tags/*.rb"].sort.each { |f| require f }
|
171
|
-
Dir["#{__dir__}/prawn_html/callbacks/*.rb"].sort.each { |f| require f }
|
172
175
|
|
173
176
|
require 'prawn_html/attributes'
|
174
177
|
require 'prawn_html/context'
|
178
|
+
require 'prawn_html/pdf_wrapper'
|
175
179
|
require 'prawn_html/document_renderer'
|
176
180
|
require 'prawn_html/html_parser'
|
@@ -7,39 +7,44 @@ module PrawnHtml
|
|
7
7
|
attr_reader :styles
|
8
8
|
|
9
9
|
STYLES_APPLY = {
|
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],
|
13
|
-
text_node: %i[
|
10
|
+
block: %i[align bottom leading left margin_left padding_left position right top],
|
11
|
+
tag_close: %i[margin_bottom padding_bottom break_after],
|
12
|
+
tag_open: %i[margin_top padding_top break_before],
|
13
|
+
text_node: %i[callback character_spacing color font link list_style_type size styles white_space]
|
14
14
|
}.freeze
|
15
15
|
|
16
16
|
STYLES_LIST = {
|
17
17
|
# text node styles
|
18
|
-
'background' => { key: :
|
19
|
-
'callback' => { key: :callback, set: :copy_value },
|
18
|
+
'background' => { key: :callback, set: :callback_background },
|
20
19
|
'color' => { key: :color, set: :convert_color },
|
21
20
|
'font-family' => { key: :font, set: :unquote },
|
22
21
|
'font-size' => { key: :size, set: :convert_size },
|
23
|
-
'font-style' => { key: :styles, set: :
|
24
|
-
'font-weight' => { key: :styles, set: :
|
22
|
+
'font-style' => { key: :styles, set: :append_styles },
|
23
|
+
'font-weight' => { key: :styles, set: :append_styles },
|
25
24
|
'href' => { key: :link, set: :copy_value },
|
26
25
|
'letter-spacing' => { key: :character_spacing, set: :convert_float },
|
27
26
|
'list-style-type' => { key: :list_style_type, set: :unquote },
|
28
|
-
'text-decoration' => { key: :styles, set: :
|
27
|
+
'text-decoration' => { key: :styles, set: :append_text_decoration },
|
28
|
+
'vertical-align' => { key: :styles, set: :append_styles },
|
29
|
+
'white-space' => { key: :white_space, set: :convert_symbol },
|
29
30
|
# tag opening styles
|
31
|
+
'break-before' => { key: :break_before, set: :convert_symbol },
|
30
32
|
'margin-top' => { key: :margin_top, set: :convert_size },
|
31
33
|
'padding-top' => { key: :padding_top, set: :convert_size },
|
32
34
|
# tag closing styles
|
35
|
+
'break-after' => { key: :break_after, set: :convert_symbol },
|
33
36
|
'margin-bottom' => { key: :margin_bottom, set: :convert_size },
|
34
37
|
'padding-bottom' => { key: :padding_bottom, set: :convert_size },
|
35
38
|
# block styles
|
36
|
-
'
|
39
|
+
'bottom' => { key: :bottom, set: :convert_size, options: :height },
|
40
|
+
'left' => { key: :left, set: :convert_size, options: :width },
|
37
41
|
'line-height' => { key: :leading, set: :convert_size },
|
38
42
|
'margin-left' => { key: :margin_left, set: :convert_size },
|
39
43
|
'padding-left' => { key: :padding_left, set: :convert_size },
|
40
44
|
'position' => { key: :position, set: :convert_symbol },
|
45
|
+
'right' => { key: :right, set: :convert_size, options: :width },
|
41
46
|
'text-align' => { key: :align, set: :convert_symbol },
|
42
|
-
'top' => { key: :top, set: :convert_size }
|
47
|
+
'top' => { key: :top, set: :convert_size, options: :height }
|
43
48
|
}.freeze
|
44
49
|
|
45
50
|
STYLES_MERGE = %i[margin_left padding_left].freeze
|
@@ -48,10 +53,6 @@ module PrawnHtml
|
|
48
53
|
def initialize(attributes = {})
|
49
54
|
super
|
50
55
|
@styles = {} # result styles
|
51
|
-
return unless style
|
52
|
-
|
53
|
-
styles_hash = Attributes.parse_styles(style)
|
54
|
-
process_styles(styles_hash)
|
55
56
|
end
|
56
57
|
|
57
58
|
# Processes the data attributes
|
@@ -64,21 +65,13 @@ module PrawnHtml
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
67
|
-
# Merge
|
68
|
+
# Merge text styles
|
68
69
|
#
|
69
|
-
# @param
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
# Processes the styles attributes
|
75
|
-
#
|
76
|
-
# @param styles_hash [Hash] hash of styles attributes
|
77
|
-
def process_styles(styles_hash)
|
78
|
-
styles_hash.each do |key, value|
|
79
|
-
apply_rule!(@styles, STYLES_LIST[key], value)
|
80
|
-
end
|
81
|
-
@styles
|
70
|
+
# @param text_styles [String] styles to parse and process
|
71
|
+
# @param options [Hash] options (container width/height/etc.)
|
72
|
+
def merge_text_styles!(text_styles, options: {})
|
73
|
+
hash_styles = Attributes.parse_styles(text_styles)
|
74
|
+
process_styles(hash_styles, options: options) unless hash_styles.empty?
|
82
75
|
end
|
83
76
|
|
84
77
|
class << self
|
@@ -109,13 +102,32 @@ module PrawnHtml
|
|
109
102
|
|
110
103
|
private
|
111
104
|
|
112
|
-
def
|
105
|
+
def process_styles(hash_styles, options:)
|
106
|
+
hash_styles.each do |key, value|
|
107
|
+
rule = evaluate_rule(key, value)
|
108
|
+
apply_rule!(merged_styles: @styles, rule: rule, value: value, options: options)
|
109
|
+
end
|
110
|
+
@styles
|
111
|
+
end
|
112
|
+
|
113
|
+
def evaluate_rule(rule_key, attr_value)
|
114
|
+
rule = STYLES_LIST[rule_key]
|
115
|
+
if rule && rule[:set] == :append_text_decoration
|
116
|
+
return { key: :callback, set: :callback_strike_through } if attr_value == 'line-through'
|
117
|
+
|
118
|
+
return { key: :styles, set: :append_styles }
|
119
|
+
end
|
120
|
+
rule
|
121
|
+
end
|
122
|
+
|
123
|
+
def apply_rule!(merged_styles:, rule:, value:, options:)
|
113
124
|
return unless rule
|
114
125
|
|
115
|
-
if rule[:set] == :
|
116
|
-
(
|
126
|
+
if rule[:set] == :append_styles
|
127
|
+
(merged_styles[rule[:key]] ||= []) << Utils.normalize_style(value)
|
117
128
|
else
|
118
|
-
|
129
|
+
opts = rule[:options] ? options[rule[:options]] : nil
|
130
|
+
merged_styles[rule[:key]] = Utils.send(rule[:set], value, options: opts)
|
119
131
|
end
|
120
132
|
end
|
121
133
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrawnHtml
|
4
|
+
module Callbacks
|
5
|
+
class Background
|
6
|
+
DEF_HIGHLIGHT = 'ffff00'
|
7
|
+
|
8
|
+
def initialize(pdf, color = nil)
|
9
|
+
@pdf = pdf
|
10
|
+
@color = color || DEF_HIGHLIGHT
|
11
|
+
end
|
12
|
+
|
13
|
+
def render_behind(fragment)
|
14
|
+
top, left = fragment.top_left
|
15
|
+
@pdf.draw_rectangle(x: left, y: top, width: fragment.width, height: fragment.height, color: @color)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -8,10 +8,10 @@ module PrawnHtml
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def render_in_front(fragment)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
data/lib/prawn_html/context.rb
CHANGED
@@ -2,15 +2,17 @@
|
|
2
2
|
|
3
3
|
module PrawnHtml
|
4
4
|
class Context < Array
|
5
|
-
DEF_FONT_SIZE =
|
5
|
+
DEF_FONT_SIZE = 16 * PX
|
6
6
|
|
7
|
-
|
7
|
+
attr_reader :previous_tag
|
8
|
+
attr_accessor :last_text_node
|
8
9
|
|
9
10
|
# Init the Context
|
10
11
|
def initialize(*_args)
|
11
12
|
super
|
12
|
-
@last_margin = 0
|
13
13
|
@last_text_node = false
|
14
|
+
@merged_styles = nil
|
15
|
+
@previous_tag = nil
|
14
16
|
end
|
15
17
|
|
16
18
|
# Add an element to the context
|
@@ -25,6 +27,7 @@ module PrawnHtml
|
|
25
27
|
element.parent = last
|
26
28
|
push(element)
|
27
29
|
element.on_context_add(self) if element.respond_to?(:on_context_add)
|
30
|
+
@merged_styles = nil
|
28
31
|
self
|
29
32
|
end
|
30
33
|
|
@@ -32,9 +35,7 @@ module PrawnHtml
|
|
32
35
|
#
|
33
36
|
# @return [String] before content string
|
34
37
|
def before_content
|
35
|
-
|
36
|
-
|
37
|
-
last.tag_styles[:before_content].to_s
|
38
|
+
(last.respond_to?(:before_content) && last.before_content) || ''
|
38
39
|
end
|
39
40
|
|
40
41
|
# Merges the context block styles
|
@@ -51,11 +52,21 @@ module PrawnHtml
|
|
51
52
|
# Merge the context styles for text nodes
|
52
53
|
#
|
53
54
|
# @return [Hash] the hash of merged styles
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
def merged_styles
|
56
|
+
@merged_styles ||=
|
57
|
+
each_with_object(base_styles) do |element, res|
|
58
|
+
evaluate_element_styles(element, res)
|
59
|
+
element.update_styles(res) if element.respond_to?(:update_styles)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Remove the last element from the context
|
64
|
+
def remove_last
|
65
|
+
last.on_context_remove(self) if last.respond_to?(:on_context_remove)
|
66
|
+
@merged_styles = nil
|
67
|
+
@last_text_node = false
|
68
|
+
@previous_tag = last.tag
|
69
|
+
pop
|
59
70
|
end
|
60
71
|
|
61
72
|
private
|
@@ -7,47 +7,37 @@ module PrawnHtml
|
|
7
7
|
|
8
8
|
# Init the DocumentRenderer
|
9
9
|
#
|
10
|
-
# @param pdf [
|
10
|
+
# @param pdf [PdfWrapper] target PDF wrapper
|
11
11
|
def initialize(pdf)
|
12
12
|
@buffer = []
|
13
13
|
@context = Context.new
|
14
|
-
@
|
14
|
+
@last_margin = 0
|
15
15
|
@pdf = pdf
|
16
16
|
end
|
17
17
|
|
18
|
-
# Evaluate the document styles and store the internally
|
19
|
-
#
|
20
|
-
# @param styles [Hash] styles hash with CSS selectors as keys and rules as values
|
21
|
-
def assign_document_styles(styles)
|
22
|
-
@document_styles.merge!(
|
23
|
-
styles.transform_values do |style_rules|
|
24
|
-
Attributes.new(style: style_rules).styles
|
25
|
-
end
|
26
|
-
)
|
27
|
-
end
|
28
|
-
|
29
18
|
# On tag close callback
|
30
19
|
#
|
31
20
|
# @param element [Tag] closing element wrapper
|
32
21
|
def on_tag_close(element)
|
33
22
|
render_if_needed(element)
|
34
23
|
apply_tag_close_styles(element)
|
35
|
-
context.
|
36
|
-
context.pop
|
24
|
+
context.remove_last
|
37
25
|
end
|
38
26
|
|
39
27
|
# On tag open callback
|
40
28
|
#
|
41
29
|
# @param tag_name [String] the tag name of the opening element
|
42
30
|
# @param attributes [Hash] an hash of the element attributes
|
31
|
+
# @param element_styles [String] document styles to apply to the element
|
43
32
|
#
|
44
33
|
# @return [Tag] the opening element wrapper
|
45
|
-
def on_tag_open(tag_name, attributes)
|
34
|
+
def on_tag_open(tag_name, attributes:, element_styles: '')
|
46
35
|
tag_class = Tag.class_for(tag_name)
|
47
36
|
return unless tag_class
|
48
37
|
|
49
|
-
|
50
|
-
|
38
|
+
options = { width: pdf.page_width, height: pdf.page_height }
|
39
|
+
tag_class.new(tag_name, attributes: attributes, options: options).tap do |element|
|
40
|
+
setup_element(element, element_styles: element_styles)
|
51
41
|
end
|
52
42
|
end
|
53
43
|
|
@@ -59,9 +49,7 @@ module PrawnHtml
|
|
59
49
|
def on_text_node(content)
|
60
50
|
return if content.match?(/\A\s*\Z/)
|
61
51
|
|
62
|
-
|
63
|
-
text += content.gsub(/\A\s*\n\s*|\s*\n\s*\Z/, '').delete("\n").squeeze(' ')
|
64
|
-
buffer << context.text_node_styles.merge(text: text)
|
52
|
+
buffer << context.merged_styles.merge(text: prepare_text(content))
|
65
53
|
context.last_text_node = true
|
66
54
|
nil
|
67
55
|
end
|
@@ -72,19 +60,20 @@ module PrawnHtml
|
|
72
60
|
|
73
61
|
output_content(buffer.dup, context.block_styles)
|
74
62
|
buffer.clear
|
75
|
-
|
63
|
+
@last_margin = 0
|
76
64
|
end
|
77
65
|
|
78
66
|
alias_method :flush, :render
|
79
67
|
|
80
68
|
private
|
81
69
|
|
82
|
-
attr_reader :buffer, :context, :
|
70
|
+
attr_reader :buffer, :context, :last_margin, :pdf
|
83
71
|
|
84
|
-
def setup_element(element)
|
72
|
+
def setup_element(element, element_styles:)
|
85
73
|
add_space_if_needed unless render_if_needed(element)
|
86
|
-
apply_tag_open_styles(element)
|
87
74
|
context.add(element)
|
75
|
+
element.process_styles(element_styles: element_styles)
|
76
|
+
apply_tag_open_styles(element)
|
88
77
|
element.custom_render(pdf, context) if element.respond_to?(:custom_render)
|
89
78
|
end
|
90
79
|
|
@@ -102,41 +91,63 @@ module PrawnHtml
|
|
102
91
|
|
103
92
|
def apply_tag_close_styles(element)
|
104
93
|
tag_styles = element.tag_close_styles
|
105
|
-
|
106
|
-
|
107
|
-
pdf.
|
94
|
+
@last_margin = tag_styles[:margin_bottom].to_f
|
95
|
+
pdf.advance_cursor(last_margin + tag_styles[:padding_bottom].to_f)
|
96
|
+
pdf.start_new_page if tag_styles[:break_after]
|
108
97
|
end
|
109
98
|
|
110
99
|
def apply_tag_open_styles(element)
|
111
100
|
tag_styles = element.tag_open_styles
|
112
|
-
move_down = (tag_styles[:margin_top].to_f -
|
113
|
-
pdf.
|
101
|
+
move_down = (tag_styles[:margin_top].to_f - last_margin) + tag_styles[:padding_top].to_f
|
102
|
+
pdf.advance_cursor(move_down) if move_down > 0
|
103
|
+
pdf.start_new_page if tag_styles[:break_before]
|
104
|
+
end
|
105
|
+
|
106
|
+
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
|
114
111
|
end
|
115
112
|
|
116
113
|
def output_content(buffer, block_styles)
|
117
|
-
buffer
|
114
|
+
apply_callbacks(buffer)
|
118
115
|
left_indent = block_styles[:margin_left].to_f + block_styles[:padding_left].to_f
|
119
|
-
options = block_styles.slice(:align, :leading, :mode, :padding_left)
|
120
|
-
options[:
|
121
|
-
|
116
|
+
options = block_styles.slice(:align, :indent_paragraphs, :leading, :mode, :padding_left)
|
117
|
+
options[:leading] = adjust_leading(buffer, options[:leading])
|
118
|
+
pdf.puts(buffer, options, bounding_box: bounds(buffer, options, block_styles), left_indent: left_indent)
|
122
119
|
end
|
123
120
|
|
124
|
-
def
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
pdf.formatted_text(buffer, options)
|
121
|
+
def apply_callbacks(buffer)
|
122
|
+
buffer.select { |item| item[:callback] }.each do |item|
|
123
|
+
callback, arg = item[:callback]
|
124
|
+
callback_class = Tag::CALLBACKS[callback]
|
125
|
+
item[:callback] = callback_class.new(pdf, arg)
|
130
126
|
end
|
131
|
-
pdf.move_cursor_to(current_y)
|
132
127
|
end
|
133
128
|
|
134
|
-
def
|
129
|
+
def adjust_leading(buffer, leading)
|
130
|
+
return leading if leading
|
131
|
+
|
132
|
+
(buffer.map { |item| item[:size] || Context::DEF_FONT_SIZE }.max * 0.055).round(4)
|
133
|
+
end
|
134
|
+
|
135
|
+
def bounds(buffer, options, block_styles)
|
135
136
|
return unless block_styles[:position] == :absolute
|
136
137
|
|
137
|
-
|
138
|
-
|
139
|
-
|
138
|
+
x = if block_styles.include?(:right)
|
139
|
+
x1 = pdf.calc_buffer_width(buffer) + block_styles[:right]
|
140
|
+
x1 < pdf.page_width ? (pdf.page_width - x1) : 0
|
141
|
+
else
|
142
|
+
block_styles[:left] || 0
|
143
|
+
end
|
144
|
+
y = if block_styles.include?(:bottom)
|
145
|
+
pdf.calc_buffer_height(buffer, options) + block_styles[:bottom]
|
146
|
+
else
|
147
|
+
pdf.page_height - (block_styles[:top] || 0)
|
148
|
+
end
|
149
|
+
|
150
|
+
[[x, y], { width: pdf.page_width - x }]
|
140
151
|
end
|
141
152
|
end
|
142
153
|
end
|