prawn-styled-text 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +36 -13
- data/examples/test.html +6 -6
- data/lib/prawn-styled-text/prawn-document.rb +4 -9
- data/lib/prawn-styled-text/prawn-styled-text.rb +24 -10
- data/lib/prawn-styled-text/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ba40b18a996a3e69cc3f7de86b848f47bc60cdf
|
4
|
+
data.tar.gz: 0d81d2354ab51749b9e71d1bd5ae940a8da1422f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d6de625118e03cd18abd32d1fed3b76f1f65d4e16548c11c255b5f7c439dce5eaea9fde269e5f57db6f87f2cfe5e3e8d90c48ee483fc790abc6f392b574bae7
|
7
|
+
data.tar.gz: 7f8a022711c08293aba2d950128dd959b0f39d259a9a227cb994a9046d4bcc80fe022f75a3cf37a9abe16a1fb0d5a140aac2787da5ee4ec468dfb632c8b478ae
|
data/README.md
CHANGED
@@ -4,6 +4,19 @@ A Prawn PDF component which adds basic HTML support.
|
|
4
4
|
|
5
5
|
**Important**: render HTML documents is not an easy task; only a small set of tags and attributes are supported and complex layouts will not render correctly; if you look for real HTML to PDF convertion please try other gems like WickedPDF
|
6
6
|
|
7
|
+
Install with `gem install prawn-styled-text` or using bundler `gem 'prawn-styled-text'`
|
8
|
+
|
9
|
+
## Examples
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'prawn-styled-text'
|
13
|
+
pdf = Prawn::Document.new
|
14
|
+
pdf.styled_text '<h1 style="text-align: center">Just a test</h1>'
|
15
|
+
pdf.render_file 'test.pdf'
|
16
|
+
```
|
17
|
+
|
18
|
+
For more examples see this [folder](https://github.com/blocknotes/prawn-styled-text/tree/master/examples).
|
19
|
+
|
7
20
|
## Supported tags & attributes
|
8
21
|
|
9
22
|
HTML tags:
|
@@ -11,30 +24,40 @@ HTML tags:
|
|
11
24
|
- b
|
12
25
|
- br
|
13
26
|
- div
|
27
|
+
- em
|
14
28
|
- h1 - h6
|
15
29
|
- hr
|
16
30
|
- i
|
17
31
|
- img
|
32
|
+
- p
|
18
33
|
- span
|
34
|
+
- strong
|
19
35
|
- u
|
20
36
|
- ul / li
|
21
37
|
|
22
38
|
CSS attributes:
|
23
|
-
- color (
|
24
|
-
- font-family
|
25
|
-
- font-size (
|
26
|
-
- font-style (
|
27
|
-
-
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
31
|
-
- margin-
|
32
|
-
-
|
33
|
-
-
|
39
|
+
- color (only 6 hex digits format, # is ignored - ex. `style="color: #FFBB11"`)
|
40
|
+
- font-family (ex. `style="font: Courier"`)
|
41
|
+
- font-size (units are ignored - ex. `style="font-size: 20px"`)
|
42
|
+
- font-style (accepts list of values - ex. `style="font-style: bold, italic"`)
|
43
|
+
- height (for *img* tag, ex. `<img src="test.jpg" style="width: 50%; height: 200"/>`)
|
44
|
+
- href (for *a* tag, ex. `<a href="http://www.google.com/">Google</a>`)
|
45
|
+
- letter-spacing (ex. `style="letter-spacing: 1.5"`)
|
46
|
+
- line-height (heading, units are ignored - ex. `style="line-height: 10"`)
|
47
|
+
- margin-left (units are ignored - ex. `style="margin-left: 15"`)
|
48
|
+
- margin-top (units are ignored - ex. `style="margin-top: 20"`)
|
49
|
+
- src (for *img* tag, ex. `<img src="test.jpg"/>`)
|
50
|
+
- text-align (ex. `style="text-align: center"`)
|
51
|
+
- width (for *img* tag, ex. `<img src="test.jpg" style="width: 50%; height: 200"/>`)
|
34
52
|
|
35
|
-
|
53
|
+
Olther attributes:
|
54
|
+
- dash (for *hr* tag, ex. `<hr style="dash: 4"/>`)
|
55
|
+
- image-position (for *img* tag, ex. `<img src="image.jpg" style="image-position: center" />`)
|
56
|
+
- image-scale (for *img* tag, ex. `<img src="image.jpg" style="image-scale: 0.3" />`)
|
57
|
+
- list-symbol (for *ul* tag, ex. `<ul style="list-symbol: -">`)
|
58
|
+
- mode (ex. `<h3 style="mode: stroke">Stroke text</h3>`)
|
36
59
|
|
37
|
-
See [
|
60
|
+
See [Prawn documentation](https://github.com/prawnpdf/prawn-table#documentation) for PDF options details.
|
38
61
|
|
39
62
|
## Contributors
|
40
63
|
|
data/examples/test.html
CHANGED
@@ -17,10 +17,10 @@ This is <i style="color: #888888">italic</i>, <u>underline</u> and <b>bold, <i>b
|
|
17
17
|
<ul>
|
18
18
|
<li>Level 1a</li>
|
19
19
|
<li>Level 1b
|
20
|
-
<ul style="margin-left: 8px;
|
20
|
+
<ul style="margin-left: 8px; list-symbol: '+ ';">
|
21
21
|
<li>Level 2a</li>
|
22
22
|
<li>Level 2b
|
23
|
-
<ul style="
|
23
|
+
<ul style="list-symbol: ''">
|
24
24
|
<li>Level 3a</li>
|
25
25
|
<li>Level 3b</li>
|
26
26
|
</ul>
|
@@ -30,14 +30,14 @@ This is <i style="color: #888888">italic</i>, <u>underline</u> and <b>bold, <i>b
|
|
30
30
|
</ul>
|
31
31
|
<br/>
|
32
32
|
|
33
|
-
Some HTML entities: € × ÷ ½ « » ©
|
34
|
-
|
33
|
+
Some HTML entities: € × ÷ ½ « » ©
|
34
|
+
<p>A paragraph</p><p>Another paragraph</p>
|
35
35
|
<hr style="color: #FFBB11; dash: 1" />
|
36
36
|
<br/>
|
37
37
|
|
38
|
-
A span with a color: <span style="color: #4488CC">this is <span style="color: #ff0000; font-family: Courier; font-size: 20px">courier red 20</span>, this is <span style="color: #008800; font-style: bold, italic">green bold italic</span>, this is <span style="letter-spacing: 2">character spacing 2</span>, this is <a href="http://www.google.com">a Google link</a></span>
|
38
|
+
A span with a color: <span style="color: #4488CC">this is <span style="color: #ff0000; font-family: 'Courier'; font-size: 20px">courier red 20</span>, this is <span style="color: #008800; font-style: bold, italic">green bold italic</span>, this is <span style="letter-spacing: 2">character spacing 2</span>, this is <a href="http://www.google.com">a Google link</a></span>
|
39
39
|
<h3 style="mode: stroke">Stroke mode</h3>
|
40
|
-
<div style="font-size: 14px; line-height: 12px">line-height test... Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
|
40
|
+
<div style="font-size: 14px; line-height: 12px; text-align: justify">line-height test... Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod <em>tempor</em> incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure <strong>dolor</strong> in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
|
41
41
|
<hr/>
|
42
42
|
<br/>
|
43
43
|
|
@@ -21,7 +21,7 @@ Prawn::Document.class_eval do
|
|
21
21
|
parts[-1][:text] = parts[-1][:text].rstrip
|
22
22
|
parts.pop if parts[-1][:text].empty?
|
23
23
|
end
|
24
|
-
# p '###', parts
|
24
|
+
# p '###', parts ### DEBUG
|
25
25
|
if parts.any?
|
26
26
|
parts[0][:text] = extra_options[:pre] + parts[0][:text] if extra_options[:pre]
|
27
27
|
self.indent( extra_options[:margin_left] ) do
|
@@ -33,6 +33,7 @@ Prawn::Document.class_eval do
|
|
33
33
|
extra_options = { margin_left: 0 }
|
34
34
|
end
|
35
35
|
options = context[:options]
|
36
|
+
# p '@@@', options ### DEBUG
|
36
37
|
if type == :text_node
|
37
38
|
# prepare options
|
38
39
|
text_options[:align] = options[:'text-align'].to_sym if options[:'text-align']
|
@@ -63,19 +64,13 @@ Prawn::Document.class_eval do
|
|
63
64
|
if options[:'image-at']
|
64
65
|
xy = options[:'image-at'].split( ',' ).map &:to_i
|
65
66
|
image_options[:at] = xy if xy.count == 2
|
66
|
-
# p image_options[:at]
|
67
67
|
end
|
68
68
|
if options[:'image-position']
|
69
69
|
pos = options[:'image-position'].to_i
|
70
70
|
image_options[:position] = pos > 0 ? pos : options[:'image-position']
|
71
71
|
end
|
72
|
-
if options[:
|
73
|
-
|
74
|
-
if w > 0
|
75
|
-
image_options[:width] = options[:'width'].include?( '%' ) ? ( w * self.bounds.width * 0.01 ) : w
|
76
|
-
end
|
77
|
-
end
|
78
|
-
image_options[:height] = options[:'height'].to_i if options[:'height']
|
72
|
+
image_options[:width] = options[:width] if options[:width]
|
73
|
+
image_options[:height] = options[:height] if options[:height]
|
79
74
|
self.image context[:src], image_options
|
80
75
|
end
|
81
76
|
end
|
@@ -2,18 +2,18 @@ require 'oga'
|
|
2
2
|
require_relative 'prawn-document'
|
3
3
|
|
4
4
|
module PrawnStyledText
|
5
|
-
BLOCK_TAGS = [ :br, :div, :h1, :h2, :h3, :h4, :h5, :h6, :hr, :li, :ul ]
|
5
|
+
BLOCK_TAGS = [ :br, :div, :h1, :h2, :h3, :h4, :h5, :h6, :hr, :li, :p, :ul ]
|
6
6
|
DEF_HEADING_T = 16
|
7
7
|
DEF_HEADING_H = 8
|
8
8
|
DEF_MARGIN_UL = 15
|
9
|
-
DEF_SYMBOL_UL = "\x95"
|
9
|
+
DEF_SYMBOL_UL = "\x95 "
|
10
10
|
HEADINGS = { h1: 32, h2: 24, h3: 20, h4: 16, h5: 14, h6: 13 }
|
11
11
|
RENAME = { 'font-family': :font, 'font-size': :size, 'font-style': :styles, 'letter-spacing': :character_spacing }
|
12
12
|
|
13
13
|
@@margin_ul = 0
|
14
14
|
@@symbol_ul = ''
|
15
15
|
|
16
|
-
def self.adjust_values( values )
|
16
|
+
def self.adjust_values( pdf, values )
|
17
17
|
ret = {}
|
18
18
|
values.each do |k, v|
|
19
19
|
key = k.to_sym
|
@@ -23,10 +23,19 @@ module PrawnStyledText
|
|
23
23
|
v.to_f
|
24
24
|
when :color
|
25
25
|
v.delete '#'
|
26
|
+
when :font
|
27
|
+
matches = v.match /'([^']*)'|"([^"]*)"|(.*)/
|
28
|
+
matches[3] || matches[2] || matches[1] || ''
|
29
|
+
when :height
|
30
|
+
i = v.to_i
|
31
|
+
v.include?( '%' ) ? ( i * pdf.bounds.height * 0.01 ) : i
|
26
32
|
when :size
|
27
33
|
v.to_i
|
28
34
|
when :styles
|
29
35
|
v.split( ',' ).map { |s| s.strip.to_sym }
|
36
|
+
when :width
|
37
|
+
i = v.to_i
|
38
|
+
v.include?( '%' ) ? ( i * pdf.bounds.width * 0.01 ) : i
|
30
39
|
else
|
31
40
|
v
|
32
41
|
end
|
@@ -49,7 +58,7 @@ module PrawnStyledText
|
|
49
58
|
end
|
50
59
|
# Evalutate attributes
|
51
60
|
attributes = data[:node].get 'style'
|
52
|
-
context[:options] = adjust_values( attributes.scan( /\s*([^:]+):\s*([^;]+)[;]*/ ) ) if attributes
|
61
|
+
context[:options] = adjust_values( pdf, attributes.scan( /\s*([^:]+):\s*([^;]+)[;]*/ ) ) if attributes
|
53
62
|
context
|
54
63
|
end
|
55
64
|
|
@@ -58,10 +67,15 @@ module PrawnStyledText
|
|
58
67
|
context[:flush] ||= true if BLOCK_TAGS.include? data[:name]
|
59
68
|
# Evalutate attributes
|
60
69
|
attributes = data[:node].get 'style'
|
61
|
-
context[:options].merge!( adjust_values( attributes.scan( /\s*([^:]+):\s*([^;]+)[;]*/ ) ) ) if attributes
|
70
|
+
context[:options].merge!( adjust_values( pdf, attributes.scan( /\s*([^:]+):\s*([^;]+)[;]*/ ) ) ) if attributes
|
62
71
|
if data[:name] == :ul
|
63
72
|
@@margin_ul += ( context[:options][:'margin-left'] ? context[:options][:'margin-left'].to_i : DEF_MARGIN_UL )
|
64
|
-
@@symbol_ul =
|
73
|
+
@@symbol_ul = if context[:options][:'list-symbol']
|
74
|
+
matches = context[:options][:'list-symbol'].match /'([^']*)'|"([^"]*)"|(.*)/
|
75
|
+
matches[3] || matches[2] || matches[1] || ''
|
76
|
+
else
|
77
|
+
DEF_SYMBOL_UL
|
78
|
+
end
|
65
79
|
end
|
66
80
|
context
|
67
81
|
end
|
@@ -76,24 +90,24 @@ module PrawnStyledText
|
|
76
90
|
when :a # link
|
77
91
|
link = part[:node].get 'href'
|
78
92
|
context[:options][:link] = link if link
|
79
|
-
when :b # bold
|
93
|
+
when :b, :strong # bold
|
80
94
|
styles.push :bold
|
81
95
|
when :h1, :h2, :h3, :h4, :h5, :h6
|
82
96
|
context[:options][:size] = HEADINGS[tag]
|
83
97
|
context[:options][:'margin-top'] = DEF_HEADING_T
|
84
98
|
context[:options][:'line-height'] = DEF_HEADING_H
|
85
|
-
when :i # italic
|
99
|
+
when :i, :em # italic
|
86
100
|
styles.push :italic
|
87
101
|
when :li # list item
|
88
102
|
context[:options][:'margin-left'] = @@margin_ul
|
89
|
-
context[:pre] = @@symbol_ul.force_encoding( 'windows-1252' ).encode( 'UTF-8' )
|
103
|
+
context[:pre] = @@symbol_ul.force_encoding( 'windows-1252' ).encode( 'UTF-8' )
|
90
104
|
when :u # underline
|
91
105
|
styles.push :underline
|
92
106
|
end
|
93
107
|
context[:options][:styles] = styles if styles.any?
|
94
108
|
# Evalutate attributes
|
95
109
|
attributes = part[:node].get 'style'
|
96
|
-
context[:options].merge!( adjust_values( attributes.scan( /\s*([^:]+):\s*([^;]+)[;]*/ ) ) ) if attributes
|
110
|
+
context[:options].merge!( adjust_values( pdf, attributes.scan( /\s*([^:]+):\s*([^;]+)[;]*/ ) ) ) if attributes
|
97
111
|
end
|
98
112
|
context
|
99
113
|
end
|