wisepdf 1.0.3 → 1.1.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.
- data/VERSION +1 -1
- data/lib/wisepdf/configuration.rb +6 -1
- data/lib/wisepdf/writer.rb +54 -112
- data/test/writer_test.rb +92 -92
- data/wisepdf.gemspec +1 -1
- metadata +14 -14
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
@@ -32,7 +32,12 @@ module Wisepdf
|
|
32
32
|
(defined?(::Rails) && ::Rails.env == 'development') ||
|
33
33
|
(defined?(RAILS_ENV) && RAILS_ENV == 'development')
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
def test?
|
37
|
+
(defined?(::Rails) && ::Rails.env == 'test') ||
|
38
|
+
(defined?(RAILS_ENV) && RAILS_ENV == 'test')
|
39
|
+
end
|
40
|
+
|
36
41
|
def windows?
|
37
42
|
RbConfig::CONFIG['target_os'] == 'mingw32'
|
38
43
|
end
|
data/lib/wisepdf/writer.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/class/attribute_accessors'
|
2
|
-
require 'active_support/core_ext/object/blank'
|
3
|
-
|
4
1
|
module Wisepdf
|
5
2
|
class Writer
|
6
3
|
def initialize(path=nil)
|
@@ -8,148 +5,93 @@ module Wisepdf
|
|
8
5
|
end
|
9
6
|
|
10
7
|
def to_pdf(string, options={})
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
options = { :encoding => "UTF-8" }.merge(options)
|
9
|
+
@options = normalize_options(options)
|
10
|
+
|
11
|
+
invoke = self.command.join(' ')
|
12
|
+
log(invoke) if Wisepdf::Configuration.development? || Wisepdf::Configuration.test?
|
13
|
+
|
14
|
+
result = IO.popen(invoke, "wb+") do |pdf|
|
15
15
|
pdf.puts(string)
|
16
16
|
pdf.close_write
|
17
17
|
pdf.gets(nil)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
raise Wisepdf::WriteError if result.to_s.strip.empty?
|
21
|
-
|
21
|
+
|
22
22
|
return result
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def wkhtmltopdf
|
26
26
|
return @wkhtmltopdf if @wkhtmltopdf.present?
|
27
27
|
|
28
28
|
@wkhtmltopdf = Wisepdf::Configuration.wkhtmltopdf
|
29
29
|
raise Wisepdf::NoExecutableError.new(@wkhtmltopdf) if @wkhtmltopdf.nil? || !File.exists?(@wkhtmltopdf)
|
30
|
-
|
30
|
+
|
31
31
|
return @wkhtmltopdf
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def wkhtmltopdf=(value)
|
35
35
|
@wkhtmltopdf = value
|
36
36
|
raise Wisepdf::NoExecutableError.new(@wkhtmltopdf) if @wkhtmltopdf.nil? || !File.exists?(@wkhtmltopdf)
|
37
37
|
end
|
38
|
-
|
39
|
-
private
|
40
|
-
def print_command(cmd)
|
41
|
-
puts "*"*15
|
42
|
-
puts cmd
|
43
|
-
puts "*"*15
|
44
|
-
end
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
parse_toc(options.delete(:toc)),
|
52
|
-
parse_outline(options.delete(:outline)),
|
53
|
-
parse_margins(options.delete(:margin)),
|
54
|
-
parse_others(options),
|
55
|
-
parse_basic_auth(options)
|
56
|
-
].join(' ')
|
57
|
-
end
|
39
|
+
protected
|
40
|
+
def command
|
41
|
+
args = [self.wkhtmltopdf]
|
42
|
+
args += @options.to_a.flatten.compact
|
43
|
+
args << '--quiet'
|
58
44
|
|
59
|
-
|
60
|
-
|
61
|
-
user, passwd = Base64.decode64(options[:basic_auth]).split(":")
|
62
|
-
"--username '#{user}' --password '#{passwd}'"
|
63
|
-
else
|
64
|
-
""
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def make_option(name, value, type=:string)
|
69
|
-
if value.is_a?(Array)
|
70
|
-
return value.collect { |v| make_option(name, v, type) }.join('')
|
71
|
-
end
|
72
|
-
"--#{name.gsub('_', '-')} " + case type
|
73
|
-
when :boolean then ""
|
74
|
-
when :numeric then value.to_s
|
75
|
-
when :name_value then value.to_s
|
76
|
-
else "\"#{value}\""
|
77
|
-
end + " "
|
78
|
-
end
|
45
|
+
args << '-'
|
46
|
+
args << '-'
|
79
47
|
|
80
|
-
|
81
|
-
names.collect {|o| make_option("#{prefix.blank? ? "" : prefix + "-"}#{o.to_s}", options[o], type) unless options[o].blank?}.join
|
48
|
+
args.map {|arg| %Q{"#{arg.gsub('"', '\"')}"}}
|
82
49
|
end
|
83
50
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
unless options[hf].blank?
|
88
|
-
opt_hf = options[hf]
|
89
|
-
r += make_options(opt_hf, [:center, :font_name, :left, :right], "#{hf.to_s}")
|
90
|
-
r += make_options(opt_hf, [:font_size, :spacing], "#{hf.to_s}", :numeric)
|
91
|
-
r += make_options(opt_hf, [:line], "#{hf.to_s}", :boolean)
|
92
|
-
unless opt_hf[:html].blank?
|
93
|
-
r += make_option("#{hf.to_s}-html", opt_hf[:html][:url]) unless opt_hf[:html][:url].blank?
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end unless options.blank?
|
97
|
-
r
|
98
|
-
end
|
51
|
+
def normalize_options(options)
|
52
|
+
options = self.flatten(options)
|
53
|
+
normalized_options = {}
|
99
54
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
r += make_options(options, [ :text_size_shrink], "toc", :numeric)
|
105
|
-
r += make_options(options, [ :disable_toc_links, :disable_dotted_lines], "", :boolean)
|
55
|
+
options.each do |key, value|
|
56
|
+
next if !value
|
57
|
+
normalized_key = "--#{self.normalize_arg(key)}"
|
58
|
+
normalized_options[normalized_key] = self.normalize_value(value)
|
106
59
|
end
|
107
|
-
|
60
|
+
normalized_options
|
108
61
|
end
|
109
62
|
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
|
63
|
+
def flatten(options, prefix = nil)
|
64
|
+
hash = {}
|
65
|
+
options.each do |k,v|
|
66
|
+
key = prefix.nil? ? k : "#{prefix.to_s}-#{k}"
|
67
|
+
|
68
|
+
if v.is_a?(Hash)
|
69
|
+
hash.delete(k)
|
70
|
+
hash.merge!(self.flatten(v, key))
|
71
|
+
else
|
72
|
+
hash[key.to_s] = v
|
73
|
+
end
|
114
74
|
end
|
75
|
+
return hash
|
115
76
|
end
|
116
77
|
|
117
|
-
def
|
118
|
-
|
78
|
+
def normalize_arg(arg)
|
79
|
+
arg.to_s.downcase.gsub(/[^a-z0-9]/,'-')
|
119
80
|
end
|
120
81
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
:proxy,
|
128
|
-
:username,
|
129
|
-
:password,
|
130
|
-
:cover,
|
131
|
-
:dpi,
|
132
|
-
:encoding,
|
133
|
-
:user_style_sheet])
|
134
|
-
r +=make_options(options, [ :cookie,
|
135
|
-
:post], "", :name_value)
|
136
|
-
r +=make_options(options, [ :redirect_delay,
|
137
|
-
:zoom,
|
138
|
-
:page_offset,
|
139
|
-
:javascript_delay], "", :numeric)
|
140
|
-
r +=make_options(options, [ :book,
|
141
|
-
:default_header,
|
142
|
-
:disable_javascript,
|
143
|
-
:greyscale,
|
144
|
-
:lowquality,
|
145
|
-
:enable_plugins,
|
146
|
-
:disable_internal_links,
|
147
|
-
:disable_external_links,
|
148
|
-
:print_media_type,
|
149
|
-
:disable_smart_shrinking,
|
150
|
-
:use_xserver,
|
151
|
-
:no_background], "", :boolean)
|
82
|
+
def normalize_value(value)
|
83
|
+
case value
|
84
|
+
when TrueClass
|
85
|
+
nil
|
86
|
+
else
|
87
|
+
value.to_s
|
152
88
|
end
|
153
89
|
end
|
90
|
+
|
91
|
+
def log(command)
|
92
|
+
puts "*"*15
|
93
|
+
puts command
|
94
|
+
puts "*"*15
|
95
|
+
end
|
154
96
|
end
|
155
97
|
end
|
data/test/writer_test.rb
CHANGED
@@ -3,9 +3,9 @@ require 'helper'
|
|
3
3
|
HTML_DOCUMENT = "<html><body>Hello World</body></html>"
|
4
4
|
|
5
5
|
# Provide a public accessor to the normally-private parse_options function
|
6
|
-
class Wisepdf::Writer
|
7
|
-
|
8
|
-
end
|
6
|
+
# class Wisepdf::Writer
|
7
|
+
# public :parse_options
|
8
|
+
# end
|
9
9
|
|
10
10
|
class WriterTest < Test::Unit::TestCase
|
11
11
|
context "Default configuration" do
|
@@ -59,95 +59,95 @@ class WriterTest < Test::Unit::TestCase
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
context "Option parsing" do
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
62
|
+
# context "Option parsing" do
|
63
|
+
# setup do
|
64
|
+
# Wisepdf::Configuration.reset!
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# should "parse header and footer options" do
|
68
|
+
# wp = Wisepdf::Writer.new
|
69
|
+
#
|
70
|
+
# [:header, :footer].each do |hf|
|
71
|
+
# [:center, :font_name, :left, :right].each do |o|
|
72
|
+
# assert_equal "--#{hf.to_s}-#{o.to_s.gsub('_', '-')} \"header_footer\"",
|
73
|
+
# wp.parse_options(hf => {o => "header_footer"}).strip
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# [:font_size, :spacing].each do |o|
|
77
|
+
# assert_equal "--#{hf.to_s}-#{o.to_s.gsub('_', '-')} 12",
|
78
|
+
# wp.parse_options(hf => {o => "12"}).strip
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# assert_equal "--#{hf.to_s}-line",
|
82
|
+
# wp.parse_options(hf => {:line => true}).strip
|
83
|
+
# assert_equal "--#{hf.to_s}-html \"http://www.abc.com\"",
|
84
|
+
# wp.parse_options(hf => {:html => {:url => 'http://www.abc.com'}}).strip
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# should "parse toc options" do
|
89
|
+
# wp = Wisepdf::Writer.new
|
90
|
+
#
|
91
|
+
# [:level_indentation, :header_text].each do |o|
|
92
|
+
# assert_equal "toc --toc-#{o.to_s.gsub('_', '-')} \"toc\"",
|
93
|
+
# wp.parse_options(:toc => {o => "toc"}).strip
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# [:text_size_shrink].each do |o|
|
97
|
+
# assert_equal "toc --toc-#{o.to_s.gsub('_', '-')} 5",
|
98
|
+
# wp.parse_options(:toc => {o => 5}).strip
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# [:disable_toc_links, :disable_dotted_lines].each do |o|
|
102
|
+
# assert_equal "toc --#{o.to_s.gsub('_', '-')}",
|
103
|
+
# wp.parse_options(:toc => {o => true}).strip
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# should "parse outline options" do
|
108
|
+
# wp = Wisepdf::Writer.new
|
109
|
+
#
|
110
|
+
# assert_equal "--outline", wp.parse_options(:outline => {:outline => true}).strip
|
111
|
+
# assert_equal "--outline-depth 5", wp.parse_options(:outline => {:outline_depth => 5}).strip
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# should "parse margins options" do
|
115
|
+
# wp = Wisepdf::Writer.new
|
116
|
+
#
|
117
|
+
# [:top, :bottom, :left, :right].each do |o|
|
118
|
+
# assert_equal "--margin-#{o.to_s} 12", wp.parse_options(:margin => {o => "12"}).strip
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# should "parse other options" do
|
123
|
+
# wp = Wisepdf::Writer.new
|
124
|
+
#
|
125
|
+
# [ :orientation, :page_size, :proxy, :username, :password, :cover, :dpi,
|
126
|
+
# :encoding, :user_style_sheet
|
127
|
+
# ].each do |o|
|
128
|
+
# assert_equal "--#{o.to_s.gsub('_', '-')} \"opts\"", wp.parse_options(o => "opts").strip
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# [:cookie, :post].each do |o|
|
132
|
+
# assert_equal "--#{o.to_s.gsub('_', '-')} name value", wp.parse_options(o => "name value").strip
|
133
|
+
#
|
134
|
+
# nv_formatter = ->(number){ "--#{o.to_s.gsub('_', '-')} par#{number} val#{number}" }
|
135
|
+
# assert_equal "#{nv_formatter.call(1)} #{nv_formatter.call(2)}", wp.parse_options(o => ['par1 val1', 'par2 val2']).strip
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# [:redirect_delay, :zoom, :page_offset].each do |o|
|
139
|
+
# assert_equal "--#{o.to_s.gsub('_', '-')} 5", wp.parse_options(o => 5).strip
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# [ :book, :default_header, :disable_javascript, :greyscale, :lowquality,
|
143
|
+
# :enable_plugins, :disable_internal_links, :disable_external_links,
|
144
|
+
# :print_media_type, :disable_smart_shrinking, :use_xserver, :no_background
|
145
|
+
# ].each do |o|
|
146
|
+
# assert_equal "--#{o.to_s.gsub('_', '-')}", wp.parse_options(o => true).strip
|
147
|
+
# end
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
# end
|
151
151
|
|
152
152
|
context "PDF generation" do
|
153
153
|
should "generate PDF from html document" do
|
data/wisepdf.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wisepdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-04-26 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &70255372627820 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70255372627820
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sqlite3
|
27
|
-
requirement: &
|
27
|
+
requirement: &70255372626060 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70255372626060
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: wkhtmltopdf-binary
|
38
|
-
requirement: &
|
38
|
+
requirement: &70255372624980 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70255372624980
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: shoulda
|
49
|
-
requirement: &
|
49
|
+
requirement: &70255372623580 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70255372623580
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: bundler
|
60
|
-
requirement: &
|
60
|
+
requirement: &70255372622720 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.0.0
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70255372622720
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: jeweler
|
71
|
-
requirement: &
|
71
|
+
requirement: &70255372621920 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: 1.6.4
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70255372621920
|
80
80
|
description: wisepdf uses the shell utility wkhtmltopdf to serve a PDF file to a user
|
81
81
|
from HTML. In other words, rather than dealing with a PDF generation DSL of some
|
82
82
|
sort, you simply write an HTML view as you would normally, and let pdf take care
|
@@ -172,7 +172,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
172
|
version: '0'
|
173
173
|
segments:
|
174
174
|
- 0
|
175
|
-
hash:
|
175
|
+
hash: 585500770691807734
|
176
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
177
|
none: false
|
178
178
|
requirements:
|