prawn-html 0.1.4 → 0.4.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 +51 -8
- data/lib/prawn-html.rb +170 -14
- data/lib/prawn_html/attributes.rb +71 -110
- data/lib/prawn_html/callbacks/highlight.rb +2 -4
- data/lib/prawn_html/callbacks/strike_through.rb +4 -4
- data/lib/prawn_html/context.rb +29 -12
- data/lib/prawn_html/document_renderer.rb +45 -50
- data/lib/prawn_html/html_parser.rb +95 -0
- data/lib/prawn_html/pdf_wrapper.rb +94 -0
- data/lib/prawn_html/tag.rb +86 -0
- data/lib/prawn_html/tags/a.rb +3 -5
- data/lib/prawn_html/tags/b.rb +3 -7
- data/lib/prawn_html/tags/blockquote.rb +25 -0
- data/lib/prawn_html/tags/body.rb +1 -3
- data/lib/prawn_html/tags/br.rb +3 -6
- data/lib/prawn_html/tags/del.rb +3 -7
- data/lib/prawn_html/tags/div.rb +1 -3
- data/lib/prawn_html/tags/h.rb +8 -10
- data/lib/prawn_html/tags/hr.rb +19 -9
- data/lib/prawn_html/tags/i.rb +3 -7
- data/lib/prawn_html/tags/img.rb +11 -13
- data/lib/prawn_html/tags/li.rb +8 -7
- data/lib/prawn_html/tags/mark.rb +3 -7
- data/lib/prawn_html/tags/ol.rb +26 -0
- data/lib/prawn_html/tags/p.rb +6 -8
- data/lib/prawn_html/tags/small.rb +1 -3
- data/lib/prawn_html/tags/span.rb +1 -3
- data/lib/prawn_html/tags/u.rb +3 -5
- data/lib/prawn_html/tags/ul.rb +3 -7
- data/lib/prawn_html/utils.rb +107 -0
- data/lib/prawn_html/version.rb +1 -1
- metadata +8 -4
- data/lib/prawn_html/html_handler.rb +0 -68
- data/lib/prawn_html/tags/base.rb +0 -54
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrawnHtml
|
4
|
+
class Tag
|
5
|
+
CALLBACKS = {
|
6
|
+
'Highlight' => Callbacks::Highlight,
|
7
|
+
'StrikeThrough' => Callbacks::StrikeThrough
|
8
|
+
}.freeze
|
9
|
+
TAG_CLASSES = %w[A B Blockquote Body Br Del Div H Hr I Img Li Mark Ol P Small Span U Ul].freeze
|
10
|
+
|
11
|
+
attr_accessor :parent
|
12
|
+
attr_reader :attrs, :tag
|
13
|
+
|
14
|
+
# Init the Tag
|
15
|
+
#
|
16
|
+
# @param tag [Symbol] tag name
|
17
|
+
# @param attributes [Hash] hash of element attributes
|
18
|
+
# @param element_styles [String] document styles tp apply to the element
|
19
|
+
def initialize(tag, attributes: {}, element_styles: '')
|
20
|
+
@tag = tag
|
21
|
+
@attrs = Attributes.new(attributes)
|
22
|
+
process_styles(element_styles, attributes['style'])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Is a block tag?
|
26
|
+
#
|
27
|
+
# @return [Boolean] true if the type of the tag is block, false otherwise
|
28
|
+
def block?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
# Styles to apply to the block
|
33
|
+
#
|
34
|
+
# @return [Hash] hash of styles to apply
|
35
|
+
def block_styles
|
36
|
+
block_styles = styles.slice(*Attributes::STYLES_APPLY[:block])
|
37
|
+
block_styles[:mode] = attrs.data['mode'].to_sym if attrs.data.include?('mode')
|
38
|
+
block_styles
|
39
|
+
end
|
40
|
+
|
41
|
+
# Styles to apply on tag closing
|
42
|
+
#
|
43
|
+
# @return [Hash] hash of styles to apply
|
44
|
+
def tag_close_styles
|
45
|
+
styles.slice(*Attributes::STYLES_APPLY[:tag_close])
|
46
|
+
end
|
47
|
+
|
48
|
+
# Styles hash
|
49
|
+
#
|
50
|
+
# @return [Hash] hash of styles
|
51
|
+
def styles
|
52
|
+
attrs.styles
|
53
|
+
end
|
54
|
+
|
55
|
+
# Styles to apply on tag opening
|
56
|
+
#
|
57
|
+
# @return [Hash] hash of styles to apply
|
58
|
+
def tag_open_styles
|
59
|
+
styles.slice(*Attributes::STYLES_APPLY[:tag_open])
|
60
|
+
end
|
61
|
+
|
62
|
+
class << self
|
63
|
+
# Evaluate the Tag class from a tag name
|
64
|
+
#
|
65
|
+
# @params tag_name [Symbol] the tag name
|
66
|
+
#
|
67
|
+
# @return [Tag] the class for the tag if available or nil
|
68
|
+
def class_for(tag_name)
|
69
|
+
@tag_classes ||= TAG_CLASSES.each_with_object({}) do |tag_class, res|
|
70
|
+
klass = const_get("PrawnHtml::Tags::#{tag_class}")
|
71
|
+
k = [klass] * klass::ELEMENTS.size
|
72
|
+
res.merge!(klass::ELEMENTS.zip(k).to_h)
|
73
|
+
end
|
74
|
+
@tag_classes[tag_name]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def process_styles(element_styles, inline_styles)
|
81
|
+
attrs.merge_text_styles!(tag_styles) if respond_to?(:tag_styles)
|
82
|
+
attrs.merge_text_styles!(element_styles)
|
83
|
+
attrs.merge_text_styles!(inline_styles)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/prawn_html/tags/a.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class A <
|
5
|
+
class A < Tag
|
8
6
|
ELEMENTS = [:a].freeze
|
9
7
|
|
10
|
-
def
|
11
|
-
attrs.
|
8
|
+
def tag_styles
|
9
|
+
"href: #{attrs.href}" if attrs.href
|
12
10
|
end
|
13
11
|
end
|
14
12
|
end
|
data/lib/prawn_html/tags/b.rb
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class B <
|
5
|
+
class B < Tag
|
8
6
|
ELEMENTS = [:b, :strong].freeze
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
'font-weight' => 'bold'
|
13
|
-
}
|
8
|
+
def tag_styles
|
9
|
+
'font-weight: bold'
|
14
10
|
end
|
15
11
|
end
|
16
12
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrawnHtml
|
4
|
+
module Tags
|
5
|
+
class Blockquote < Tag
|
6
|
+
ELEMENTS = [:blockquote].freeze
|
7
|
+
|
8
|
+
MARGIN_BOTTOM = 10
|
9
|
+
MARGIN_LEFT = 25
|
10
|
+
MARGIN_TOP = 10
|
11
|
+
|
12
|
+
def block?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def tag_styles
|
17
|
+
<<~STYLES
|
18
|
+
margin-bottom: #{MARGIN_BOTTOM}px;
|
19
|
+
margin-left: #{MARGIN_LEFT}px;
|
20
|
+
margin-top: #{MARGIN_TOP}px;
|
21
|
+
STYLES
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/prawn_html/tags/body.rb
CHANGED
data/lib/prawn_html/tags/br.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class Br <
|
5
|
+
class Br < Tag
|
8
6
|
ELEMENTS = [:br].freeze
|
9
7
|
|
10
|
-
BR_SPACING = 12
|
8
|
+
BR_SPACING = Utils.convert_size('12')
|
11
9
|
|
12
10
|
def block?
|
13
11
|
true
|
@@ -16,8 +14,7 @@ module PrawnHtml
|
|
16
14
|
def custom_render(pdf, context)
|
17
15
|
return if context.last_text_node
|
18
16
|
|
19
|
-
|
20
|
-
pdf.move_down(@spacing)
|
17
|
+
pdf.advance_cursor(BR_SPACING)
|
21
18
|
end
|
22
19
|
end
|
23
20
|
end
|
data/lib/prawn_html/tags/del.rb
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class Del <
|
5
|
+
class Del < Tag
|
8
6
|
ELEMENTS = [:del, :s].freeze
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
callback: Callbacks::StrikeThrough
|
13
|
-
)
|
8
|
+
def tag_styles
|
9
|
+
'callback: StrikeThrough'
|
14
10
|
end
|
15
11
|
end
|
16
12
|
end
|
data/lib/prawn_html/tags/div.rb
CHANGED
data/lib/prawn_html/tags/h.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class H <
|
5
|
+
class H < Tag
|
8
6
|
ELEMENTS = [:h1, :h2, :h3, :h4, :h5, :h6].freeze
|
9
7
|
|
10
8
|
MARGINS_TOP = {
|
@@ -38,13 +36,13 @@ module PrawnHtml
|
|
38
36
|
true
|
39
37
|
end
|
40
38
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
39
|
+
def tag_styles
|
40
|
+
<<~STYLES
|
41
|
+
font-size: #{SIZES[tag]}px;
|
42
|
+
font-weight: bold;
|
43
|
+
margin-bottom: #{MARGINS_BOTTOM[tag]}px;
|
44
|
+
margin-top: #{MARGINS_TOP[tag]}px;
|
45
|
+
STYLES
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
data/lib/prawn_html/tags/hr.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class Hr <
|
5
|
+
class Hr < Tag
|
8
6
|
ELEMENTS = [:hr].freeze
|
9
7
|
|
10
8
|
MARGIN_BOTTOM = 12
|
@@ -15,14 +13,26 @@ module PrawnHtml
|
|
15
13
|
end
|
16
14
|
|
17
15
|
def custom_render(pdf, _context)
|
18
|
-
|
16
|
+
dash = attrs.data.include?('dash') ? parse_dash_value(attrs.data['dash']) : nil
|
17
|
+
pdf.horizontal_rule(color: attrs.styles[:color], dash: dash)
|
18
|
+
end
|
19
|
+
|
20
|
+
def tag_styles
|
21
|
+
<<~STYLES
|
22
|
+
margin-bottom: #{MARGIN_BOTTOM}px;
|
23
|
+
margin-top: #{MARGIN_TOP}px;
|
24
|
+
STYLES
|
19
25
|
end
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
private
|
28
|
+
|
29
|
+
def parse_dash_value(dash_string)
|
30
|
+
if dash_string.match? /\A\d+\Z/
|
31
|
+
dash_string.to_i
|
32
|
+
else
|
33
|
+
dash_array = dash_string.split(',')
|
34
|
+
dash_array.map(&:to_i) if dash_array.any?
|
35
|
+
end
|
26
36
|
end
|
27
37
|
end
|
28
38
|
end
|
data/lib/prawn_html/tags/i.rb
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class I <
|
5
|
+
class I < Tag
|
8
6
|
ELEMENTS = [:i, :em].freeze
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
'font-style' => 'italic'
|
13
|
-
}
|
8
|
+
def tag_styles
|
9
|
+
'font-style: italic'
|
14
10
|
end
|
15
11
|
end
|
16
12
|
end
|
data/lib/prawn_html/tags/img.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class Img <
|
5
|
+
class Img < Tag
|
8
6
|
ELEMENTS = [:img].freeze
|
9
7
|
|
10
8
|
def block?
|
@@ -12,20 +10,20 @@ module PrawnHtml
|
|
12
10
|
end
|
13
11
|
|
14
12
|
def custom_render(pdf, context)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
pdf.image(@attrs.
|
13
|
+
parsed_styles = Attributes.parse_styles(attrs.style)
|
14
|
+
block_styles = context.block_styles
|
15
|
+
evaluated_styles = evaluate_styles(pdf, block_styles.merge(parsed_styles))
|
16
|
+
pdf.image(@attrs.src, evaluated_styles)
|
19
17
|
end
|
20
18
|
|
21
19
|
private
|
22
20
|
|
23
|
-
def evaluate_styles(pdf,
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
def evaluate_styles(pdf, img_styles)
|
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')
|
25
|
+
result[:position] = img_styles[:align] if %i[left center right].include?(img_styles[:align])
|
26
|
+
end
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|
data/lib/prawn_html/tags/li.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class Li <
|
5
|
+
class Li < Tag
|
8
6
|
ELEMENTS = [:li].freeze
|
9
7
|
|
10
8
|
def block?
|
11
9
|
true
|
12
10
|
end
|
13
11
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def before_content
|
13
|
+
@counter ? "#{@counter}. " : "#{@symbol} "
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_context_add(_context)
|
17
|
+
@counter = (parent.counter += 1) if parent.is_a? Ol
|
18
|
+
@symbol = parent.styles[:list_style_type] || '•' if parent.is_a? Ul
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
data/lib/prawn_html/tags/mark.rb
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
3
|
module PrawnHtml
|
6
4
|
module Tags
|
7
|
-
class Mark <
|
5
|
+
class Mark < Tag
|
8
6
|
ELEMENTS = [:mark].freeze
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
callback: Callbacks::Highlight
|
13
|
-
)
|
8
|
+
def tag_styles
|
9
|
+
'callback: Highlight'
|
14
10
|
end
|
15
11
|
end
|
16
12
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrawnHtml
|
4
|
+
module Tags
|
5
|
+
class Ol < Tag
|
6
|
+
ELEMENTS = [:ol].freeze
|
7
|
+
|
8
|
+
MARGIN_LEFT = 25
|
9
|
+
|
10
|
+
attr_accessor :counter
|
11
|
+
|
12
|
+
def initialize(tag, attributes: {}, element_styles: '')
|
13
|
+
super
|
14
|
+
@counter = 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def block?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def tag_styles
|
22
|
+
"margin-left: #{MARGIN_LEFT}px"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|