clamsy 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.txt +7 -0
- data/README.rdoc +56 -15
- data/VERSION +1 -1
- data/clamsy.gemspec +51 -16
- data/clamsy.png +0 -0
- data/lib/clamsy.rb +26 -123
- data/lib/clamsy.yml +8 -0
- data/lib/clamsy/base_printer.rb +64 -0
- data/lib/clamsy/configuration.rb +128 -0
- data/lib/clamsy/cups_pdf_printer.rb +26 -0
- data/lib/clamsy/file_system_support.rb +36 -0
- data/lib/clamsy/template_open_doc.rb +122 -0
- data/spec/clamsy/base_printer_spec.rb +19 -0
- data/spec/clamsy/configuration_spec.rb +290 -0
- data/spec/clamsy/cups_pdf_printer_spec.rb +40 -0
- data/spec/{data → clamsy/data}/clamsy.png +0 -0
- data/spec/{data → clamsy/data}/clamsy2.png +0 -0
- data/spec/clamsy/data/embedded_ruby_after.odt +0 -0
- data/spec/clamsy/data/embedded_ruby_before.odt +0 -0
- data/spec/clamsy/data/escaped_text_after.odt +0 -0
- data/spec/{data/escaped_text_example.odt → clamsy/data/escaped_text_before.odt} +0 -0
- data/spec/clamsy/data/invalid_content_example.odt +0 -0
- data/spec/clamsy/data/invalid_zip_example.odt +0 -0
- data/spec/{data/multiple_contexts_example.odt → clamsy/data/multiple_contexts_after.odt} +0 -0
- data/spec/{data/plain_text_example.odt → clamsy/data/multiple_contexts_before.odt} +0 -0
- data/spec/clamsy/data/picture_after.odt +0 -0
- data/spec/{data/picture_example.odt → clamsy/data/picture_before.odt} +0 -0
- data/spec/clamsy/data/plain_text_after.odt +0 -0
- data/spec/clamsy/data/plain_text_before.odt +0 -0
- data/spec/clamsy/file_system_support_spec.rb +93 -0
- data/spec/clamsy/invalid_printer_spec.rb +21 -0
- data/spec/clamsy/template_open_doc_spec.rb +95 -0
- data/spec/{clamsy_spec.rb → integration/cups_pdf_printer_spec.rb} +12 -6
- data/spec/{data → integration/data}/embedded_ruby_example.odt +0 -0
- data/spec/{data → integration/data}/embedded_ruby_example.pdf +0 -0
- data/spec/integration/data/escaped_text_example.odt +0 -0
- data/spec/{data → integration/data}/escaped_text_example.pdf +0 -0
- data/spec/integration/data/multiple_contexts_example.odt +0 -0
- data/spec/{data → integration/data}/multiple_contexts_example.pdf +0 -0
- data/spec/integration/data/norm_clamsy.png +0 -0
- data/spec/integration/data/picture_example.odt +0 -0
- data/spec/integration/data/picture_example.pdf +0 -0
- data/spec/integration/data/plain_text_example.odt +0 -0
- data/spec/{data → integration/data}/plain_text_example.pdf +0 -0
- data/spec/integration/data/sunny_clamsy.png +0 -0
- data/spec/integration/has_stardand_integration_support_shared_spec.rb +27 -0
- data/spec/spec_helper.rb +1 -25
- metadata +52 -17
- data/spec/data/picture_example.pdf +0 -0
data/HISTORY.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.0.4 (May 04, 2010)
|
2
|
+
|
3
|
+
* fixed bug in multiple pictures replacement [#ngty]
|
4
|
+
* support for configuring clamsy (see README section 3) [#jasonong & #ngty]
|
5
|
+
* clamsy now has a logo (<PROJECT_ROOT>/clamsy.png) [#zhenyi]
|
6
|
+
* well-prepared for alternative printers support [#ngty]
|
7
|
+
|
1
8
|
=== 0.0.3 (Apr 25, 2010)
|
2
9
|
|
3
10
|
* support to replace pictures (useful for inserting digital signatures) [#ngty]
|
data/README.rdoc
CHANGED
@@ -22,9 +22,9 @@ template engine (http://www.kuwata-lab.com/tenjin) to do the rendering. The foll
|
|
22
22
|
is all u need to know to write odt templates:
|
23
23
|
|
24
24
|
* '{? ... ?}' represents embedded Ruby statement (this differs from vanilla tenjin)
|
25
|
-
* '#{ ... }' represents embedded Ruby expression
|
26
25
|
* '${ ... }' represents embedded Ruby expression which is to be escaped
|
27
26
|
(eg. '& < > "' are escaped to '& < > "')
|
27
|
+
* '#{ ... }' represents embedded Ruby expression (u should really avoid using this)
|
28
28
|
|
29
29
|
== 2. Examples
|
30
30
|
|
@@ -33,15 +33,15 @@ is all u need to know to write odt templates:
|
|
33
33
|
Template Odt:
|
34
34
|
|
35
35
|
--------------------------------------------
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
${@company_full_name}
|
37
|
+
${@company_address_line_1}
|
38
|
+
${@company_address_line_2}
|
39
39
|
|
40
40
|
S/N Item Description Amount (SGD)
|
41
41
|
{? @items.each_with_index do |item, i| ?}
|
42
|
-
|
42
|
+
${i+1} ${item.description} ${amount}
|
43
43
|
{? end ?}
|
44
|
-
Total
|
44
|
+
Total ${total}
|
45
45
|
----------------------------------- Page 1 -
|
46
46
|
|
47
47
|
Code:
|
@@ -180,9 +180,50 @@ code does the appropriate replacing of images:
|
|
180
180
|
path_to_final_pdf # eg. '/tmp/confession.pdf'
|
181
181
|
)
|
182
182
|
|
183
|
-
== 3.
|
183
|
+
== 3. Configuration
|
184
|
+
|
185
|
+
=== 3.1. User-defined ~/.clamsy.yml
|
186
|
+
|
187
|
+
printer: cups_pdf
|
188
|
+
cups_pdf:
|
189
|
+
cups_output_dir: /var/spool/cups-pdf/${USER}
|
190
|
+
cups_output_file:
|
191
|
+
ooffice_cmd: ooffice -norestore -nofirststartwizard -nologo -headless -pt Cups-PDF
|
192
|
+
|
193
|
+
NOTES:
|
194
|
+
* ${...} gets replaced by the corresponding ENV variable, eg. ${USER} gets replaced
|
195
|
+
by ENV['USER']
|
196
|
+
* printer ... describes which printer to use (currently, we ONLY have 'cups_pdf')
|
197
|
+
* cups_output_dir ... the directory where cups-pdf places the intermediate working pdf,
|
198
|
+
in linux box, it is specifed by the 'Out' variable in /etc/cups/cups-pdf.conf
|
199
|
+
* cups_output_file ... specifies the exact intermediate working pdf, when this is
|
200
|
+
specified, cups_output_dir is ignored
|
201
|
+
* ooffice_cmd ... the openoffice command & arguments to use
|
202
|
+
|
203
|
+
=== 3.2. Clamsy\.configure {|config| ... }
|
204
|
+
|
205
|
+
Clamsy.configure do |config|
|
206
|
+
config.printer = 'another_printer'
|
207
|
+
config.config_file = '/path/to/alternative/clamsy.yml'
|
208
|
+
config.cups_output_dir = '/another/output/dir'
|
209
|
+
config.cups_output_file = lambda { Dir.glob('/yet/another/output/dir/*.pdf').sort.last }
|
210
|
+
end
|
211
|
+
|
212
|
+
NOTES:
|
213
|
+
* config_file ... alternative user-defined config file, when specified, ~/.clamsy.yml will
|
214
|
+
be ignored (whatever is supported in this config file is exactly the same as 3.1)
|
215
|
+
* cups_output_file ... unlike what we have in the yaml config file, this can be either a
|
216
|
+
proc or a string
|
184
217
|
|
185
|
-
=== 3.
|
218
|
+
=== 3.3. Clamsy\.process(...) {|config| ... }
|
219
|
+
|
220
|
+
Clamsy.process(contexts, template_odt, final_pdf) do |config|
|
221
|
+
# the rest is the same as 3.2
|
222
|
+
end
|
223
|
+
|
224
|
+
== 4. Pre-requisites
|
225
|
+
|
226
|
+
=== 4.1. Archlinux
|
186
227
|
|
187
228
|
* Installing packages:
|
188
229
|
$ sudo pacman -S ghostscript cups cups-pdf go-openoffice
|
@@ -193,17 +234,15 @@ code does the appropriate replacing of images:
|
|
193
234
|
* Making sure cups is running:
|
194
235
|
$ sudo /etc/rc.d/cups start
|
195
236
|
|
196
|
-
===
|
237
|
+
=== 4.2. Ubuntu (to-be-updated)
|
197
238
|
|
198
|
-
===
|
239
|
+
=== 4.3. Mac (to-be-updated)
|
199
240
|
|
200
241
|
== TODO
|
201
242
|
|
202
|
-
*
|
203
|
-
|
204
|
-
* automate cups-pdf printer setup or have ooffice directly export odt to pdf
|
243
|
+
* automate cups-pdf printer setup
|
205
244
|
|
206
|
-
*
|
245
|
+
* more printers support (currently, we ONLY have Clamsy::CupsPdfPrinter)
|
207
246
|
|
208
247
|
== Note on Patches/Pull Requests
|
209
248
|
|
@@ -219,7 +258,9 @@ code does the appropriate replacing of images:
|
|
219
258
|
|
220
259
|
Written 2010 by:
|
221
260
|
|
222
|
-
|
261
|
+
1. NgTzeYang, contact http://github.com/ngty
|
262
|
+
2. JasonOng, contact http://github.com/jasonong
|
263
|
+
3. ZhenyiTan, contact http://github.com/zhenyi
|
223
264
|
|
224
265
|
Released under the MIT license
|
225
266
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
data/clamsy.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{clamsy}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["NgTzeYang"]
|
12
|
-
s.date = %q{2010-04
|
12
|
+
s.date = %q{2010-05-04}
|
13
13
|
s.description = %q{}
|
14
14
|
s.email = %q{ngty77@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,21 +25,49 @@ Gem::Specification.new do |s|
|
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
27
|
"clamsy.gemspec",
|
28
|
+
"clamsy.png",
|
28
29
|
"lib/clamsy.rb",
|
30
|
+
"lib/clamsy.yml",
|
31
|
+
"lib/clamsy/base_printer.rb",
|
32
|
+
"lib/clamsy/configuration.rb",
|
33
|
+
"lib/clamsy/cups_pdf_printer.rb",
|
34
|
+
"lib/clamsy/file_system_support.rb",
|
35
|
+
"lib/clamsy/template_open_doc.rb",
|
29
36
|
"lib/clamsy/tenjin.rb",
|
30
|
-
"spec/
|
31
|
-
"spec/
|
32
|
-
"spec/
|
33
|
-
"spec/data/
|
34
|
-
"spec/data/
|
35
|
-
"spec/data/
|
36
|
-
"spec/data/
|
37
|
-
"spec/data/
|
38
|
-
"spec/data/
|
39
|
-
"spec/data/
|
40
|
-
"spec/data/
|
41
|
-
"spec/data/
|
42
|
-
"spec/data/
|
37
|
+
"spec/clamsy/base_printer_spec.rb",
|
38
|
+
"spec/clamsy/configuration_spec.rb",
|
39
|
+
"spec/clamsy/cups_pdf_printer_spec.rb",
|
40
|
+
"spec/clamsy/data/clamsy.png",
|
41
|
+
"spec/clamsy/data/clamsy2.png",
|
42
|
+
"spec/clamsy/data/embedded_ruby_after.odt",
|
43
|
+
"spec/clamsy/data/embedded_ruby_before.odt",
|
44
|
+
"spec/clamsy/data/escaped_text_after.odt",
|
45
|
+
"spec/clamsy/data/escaped_text_before.odt",
|
46
|
+
"spec/clamsy/data/invalid_content_example.odt",
|
47
|
+
"spec/clamsy/data/invalid_zip_example.odt",
|
48
|
+
"spec/clamsy/data/multiple_contexts_after.odt",
|
49
|
+
"spec/clamsy/data/multiple_contexts_before.odt",
|
50
|
+
"spec/clamsy/data/picture_after.odt",
|
51
|
+
"spec/clamsy/data/picture_before.odt",
|
52
|
+
"spec/clamsy/data/plain_text_after.odt",
|
53
|
+
"spec/clamsy/data/plain_text_before.odt",
|
54
|
+
"spec/clamsy/file_system_support_spec.rb",
|
55
|
+
"spec/clamsy/invalid_printer_spec.rb",
|
56
|
+
"spec/clamsy/template_open_doc_spec.rb",
|
57
|
+
"spec/integration/cups_pdf_printer_spec.rb",
|
58
|
+
"spec/integration/data/embedded_ruby_example.odt",
|
59
|
+
"spec/integration/data/embedded_ruby_example.pdf",
|
60
|
+
"spec/integration/data/escaped_text_example.odt",
|
61
|
+
"spec/integration/data/escaped_text_example.pdf",
|
62
|
+
"spec/integration/data/multiple_contexts_example.odt",
|
63
|
+
"spec/integration/data/multiple_contexts_example.pdf",
|
64
|
+
"spec/integration/data/norm_clamsy.png",
|
65
|
+
"spec/integration/data/picture_example.odt",
|
66
|
+
"spec/integration/data/picture_example.pdf",
|
67
|
+
"spec/integration/data/plain_text_example.odt",
|
68
|
+
"spec/integration/data/plain_text_example.pdf",
|
69
|
+
"spec/integration/data/sunny_clamsy.png",
|
70
|
+
"spec/integration/has_stardand_integration_support_shared_spec.rb",
|
43
71
|
"spec/spec_helper.rb"
|
44
72
|
]
|
45
73
|
s.homepage = %q{http://github.com/ngty/clamsy}
|
@@ -48,7 +76,14 @@ Gem::Specification.new do |s|
|
|
48
76
|
s.rubygems_version = %q{1.3.6}
|
49
77
|
s.summary = %q{A clumsily shellish way to generate a single pdf for multiple contexts from an odt template}
|
50
78
|
s.test_files = [
|
51
|
-
"spec/
|
79
|
+
"spec/integration/cups_pdf_printer_spec.rb",
|
80
|
+
"spec/integration/has_stardand_integration_support_shared_spec.rb",
|
81
|
+
"spec/clamsy/file_system_support_spec.rb",
|
82
|
+
"spec/clamsy/base_printer_spec.rb",
|
83
|
+
"spec/clamsy/cups_pdf_printer_spec.rb",
|
84
|
+
"spec/clamsy/invalid_printer_spec.rb",
|
85
|
+
"spec/clamsy/configuration_spec.rb",
|
86
|
+
"spec/clamsy/template_open_doc_spec.rb",
|
52
87
|
"spec/spec_helper.rb"
|
53
88
|
]
|
54
89
|
|
data/clamsy.png
ADDED
Binary file
|
data/lib/clamsy.rb
CHANGED
@@ -1,142 +1,45 @@
|
|
1
|
-
require 'ftools'
|
2
|
-
require 'digest/md5'
|
3
|
-
require 'tempfile'
|
4
|
-
require 'nokogiri'
|
5
|
-
require 'zip/zip'
|
6
1
|
require 'clamsy/tenjin'
|
7
|
-
require '
|
2
|
+
require 'clamsy/file_system_support'
|
3
|
+
require 'clamsy/base_printer'
|
4
|
+
require 'clamsy/template_open_doc'
|
5
|
+
require 'clamsy/configuration'
|
8
6
|
|
9
7
|
module Clamsy
|
10
8
|
|
11
|
-
class MissingFileError < Exception ; end
|
12
|
-
|
13
9
|
class << self
|
14
10
|
|
15
|
-
|
16
|
-
begin
|
17
|
-
@template_odt = TemplateOdt.new(template_odt)
|
18
|
-
odts = [contexts].flatten.map {|ctx| @template_odt.render(ctx) }
|
19
|
-
Shell.print_odts_to_pdf(odts, final_pdf)
|
20
|
-
ensure
|
21
|
-
@template_odt.trash_tmp_files
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
module HasTrashableTempFiles
|
30
|
-
|
31
|
-
def trash_tmp_files
|
32
|
-
(@trashable_tmp_files || []).select {|f| f.path }.map(&:unlink)
|
33
|
-
end
|
34
|
-
|
35
|
-
def tmp_file(file_name)
|
36
|
-
((@trashable_tmp_files ||= []) << Tempfile.new(file_name))[-1]
|
37
|
-
end
|
11
|
+
include FileSystemSupport
|
38
12
|
|
13
|
+
def configure(&blk)
|
14
|
+
yield(config)
|
39
15
|
end
|
40
16
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
def initialize(template_odt)
|
46
|
-
@template_odt = template_odt
|
47
|
-
end
|
48
|
-
|
49
|
-
def render(context)
|
50
|
-
@context_id = Digest::MD5.hexdigest(context.to_s)
|
51
|
-
Zip::ZipFile.open(working_odt.path) do |@zip|
|
52
|
-
@zip.select {|entry| entry.file? && entry.to_s =~ /\.xml$/ }.each do |entry|
|
53
|
-
@zip.get_output_stream(entry.to_s) {|io| io.write(workers[entry].render(context)) }
|
54
|
-
replace_pictures(entry, context[:_pictures] || {})
|
55
|
-
end
|
56
|
-
end
|
57
|
-
working_odt
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def replace_pictures(entry, pictures)
|
63
|
-
xpaths = lambda {|name| %\//drawframe[@drawname="#{name}"]/drawimage/@xlinkhref\ }
|
64
|
-
doc = Nokogiri::XML(entry.get_input_stream.read.gsub(':','')) # Hack to avoid namespace error
|
65
|
-
pictures.each do |name, path|
|
66
|
-
(node = doc.xpath(xpaths[name])[0]) && @zip.replace(node.value, path)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def working_odt
|
71
|
-
(@working_odts ||= {})[@context_id] ||=
|
72
|
-
begin
|
73
|
-
dest_odt = tmp_file(@context_id)
|
74
|
-
File.copy(@template_odt, dest_odt.path) ; dest_odt
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def workers
|
79
|
-
lambda do |entry|
|
80
|
-
(@workers ||= {})[entry.to_s] ||=
|
81
|
-
begin
|
82
|
-
tmp_file = tmp_file("#{@context_id}.#{File.basename(entry.to_s)}")
|
83
|
-
tmp_file.write(entry.get_input_stream.read)
|
84
|
-
tmp_file.close
|
85
|
-
Tenjin::Template.new(tmp_file.path)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
17
|
+
def process(contexts, template_doc, final_pdf, &blk)
|
18
|
+
block_given? && configure(&blk)
|
19
|
+
generate_pdf(contexts, template_doc, final_pdf)
|
90
20
|
end
|
91
21
|
|
92
|
-
|
93
|
-
|
94
|
-
# The folder where cups-pdf generated pdfs are stored:
|
95
|
-
# * in archlinux, this is specified in /etc/cups/cups-pdf.conf
|
96
|
-
PDF_OUTPUT_DIR = "/tmp/cups-pdf/#{`whoami`.strip}"
|
97
|
-
|
98
|
-
# The openoffice command to print odt to pdf, requires package cups-pdf & 'Cups-PDF' printer
|
99
|
-
# to be set up in cups.
|
100
|
-
ODT_TO_PDF_CMD = "ooffice -norestore -nofirststartwizard -nologo -headless -pt Cups-PDF"
|
22
|
+
private
|
101
23
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
from_odts.map {|odt| tmp_ps << odt_to_ps_stream(odt) }
|
110
|
-
tmp_ps.close
|
111
|
-
gs_convert(:pdf, tmp_ps.path, to_pdf)
|
112
|
-
ensure
|
113
|
-
trash_tmp_files
|
114
|
-
end
|
24
|
+
def generate_pdf(contexts, template_doc, final_pdf)
|
25
|
+
begin
|
26
|
+
@template_doc = TemplateOpenDoc.new(template_doc)
|
27
|
+
docs = [contexts].flatten.map {|ctx| @template_doc.render(ctx) }
|
28
|
+
printer.docs_to_pdf(docs, final_pdf)
|
29
|
+
ensure
|
30
|
+
@template_doc.trash_tmp_files
|
115
31
|
end
|
32
|
+
end
|
116
33
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
pdf_path = File.join(PDF_OUTPUT_DIR, File.basename(odt_path, '.odt')) + '.pdf'
|
122
|
-
system("#{ODT_TO_PDF_CMD} #{odt_path}")
|
123
|
-
gs_convert(:ps, pdf_path)
|
124
|
-
end
|
125
|
-
|
126
|
-
def gs_convert(format, src_path, dest_path=nil)
|
127
|
-
ensure_file_exists!(src_path)
|
128
|
-
method, opts = dest_path ? [:path, {:filename => dest_path}] : [:read, {}]
|
129
|
-
RGhost::Convert.new(src_path).to(format, opts).send(method)
|
130
|
-
end
|
131
|
-
|
132
|
-
def ensure_file_exists!(file_path)
|
133
|
-
exist_flg = false
|
134
|
-
0.upto(10) {|i| File.exists?(file_path) ? (exist_flg = true; break) : sleep(1) }
|
135
|
-
exist_flg or raise MissingFileError.new(file_path)
|
136
|
-
end
|
34
|
+
def config
|
35
|
+
@config ||=
|
36
|
+
Configuration.new(File.join(File.dirname(__FILE__), 'clamsy.yml'), true)
|
37
|
+
end
|
137
38
|
|
39
|
+
def printer
|
40
|
+
Clamsy::BasePrinter.get(config.printer, config)
|
138
41
|
end
|
139
42
|
|
140
|
-
|
43
|
+
end
|
141
44
|
|
142
45
|
end
|
data/lib/clamsy.yml
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rghost'
|
2
|
+
|
3
|
+
module Clamsy
|
4
|
+
|
5
|
+
class ImplementationNotFoundError < Exception ; end
|
6
|
+
class PrinterNotFoundError < Exception ; end
|
7
|
+
|
8
|
+
class BasePrinter
|
9
|
+
class << self
|
10
|
+
|
11
|
+
include Clamsy::FileSystemSupport
|
12
|
+
attr_reader :subclasses, :config
|
13
|
+
|
14
|
+
def docs_to_pdf(from_docs, to_pdf)
|
15
|
+
begin
|
16
|
+
tmp_ps = tmp_file(File.basename(to_pdf, '.pdf'))
|
17
|
+
from_docs.map {|doc| tmp_ps << doc_to_ps_stream(doc.path) }
|
18
|
+
tmp_ps.close
|
19
|
+
gs_convert(:pdf, tmp_ps.path, to_pdf)
|
20
|
+
ensure
|
21
|
+
trash_tmp_files
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(name, config)
|
26
|
+
begin
|
27
|
+
require File.join(File.dirname(__FILE__), "#{name}_printer.rb")
|
28
|
+
printer = self.subclasses[name.gsub(/[^a-zA-Z0-9]/,'').downcase]
|
29
|
+
printer.configure(config) ; printer
|
30
|
+
rescue Exception
|
31
|
+
raise PrinterNotFoundError.new("Printer '#{name}' cannot be found.")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def doc_to_ps_stream(doc_path)
|
38
|
+
file_must_exist!(doc_path)
|
39
|
+
gs_convert(:ps, doc_to_pdf(doc_path))
|
40
|
+
end
|
41
|
+
|
42
|
+
def configure(config)
|
43
|
+
@config = config
|
44
|
+
end
|
45
|
+
|
46
|
+
def doc_to_pdf(doc_path)
|
47
|
+
raise Clamsy::ImplementationNotFoundError.new("#{self.to_s}.doc_to_pdf not implemented.")
|
48
|
+
end
|
49
|
+
|
50
|
+
def gs_convert(format, src_path, dest_path=nil)
|
51
|
+
file_must_exist!(src_path)
|
52
|
+
method, opts = dest_path ? [:path, {:filename => dest_path}] : [:read, {}]
|
53
|
+
RGhost::Convert.new(src_path).to(format, opts).send(method)
|
54
|
+
end
|
55
|
+
|
56
|
+
def inherited(subclass)
|
57
|
+
key = "#{subclass}".sub(/Clamsy::(\w+)Printer/,'\1').downcase
|
58
|
+
(@subclasses ||= {})[key] = subclass
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|