htmldoc 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +24 -0
- data/History.txt +6 -0
- data/README.txt +56 -12
- data/Rakefile +1 -1
- data/lib/htmldoc.rb +55 -9
- data/lib/htmldoc/version.rb +1 -1
- data/test/generation_test.rb +92 -49
- metadata +2 -2
data/CHANGELOG.txt
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
2007-03-07 ronaldo <ronaldo@reflectivesurface.com>
|
2
|
+
|
3
|
+
* Changed the instance variable result to a hash of information
|
4
|
+
about the generation, including bytes and pages generated, and the
|
5
|
+
raw result of the program's execution
|
6
|
+
|
7
|
+
* Added an errors instance variable to register all the errors
|
8
|
+
generated in the course of the program's execution
|
9
|
+
|
10
|
+
* Refactored generate
|
11
|
+
|
12
|
+
* Changed generate so it now raises an exception if the program
|
13
|
+
path cannot be found
|
14
|
+
|
15
|
+
* Improved the tests
|
16
|
+
|
17
|
+
* Improved the documentation
|
18
|
+
|
19
|
+
2007-03-06 ronaldo <ronaldo@reflectivesurface.com>
|
20
|
+
|
21
|
+
* Fixed spelling and grammatical error in README.txt
|
22
|
+
|
23
|
+
* Fixed a couple of naming issues in Rakefile
|
24
|
+
|
1
25
|
2007-03-05 ronaldo <ronaldo@reflectivesurface.com>
|
2
26
|
|
3
27
|
* Initial release
|
data/History.txt
CHANGED
data/README.txt
CHANGED
@@ -5,11 +5,11 @@ that converts HTML input files into formatted HTML, PDF or PostScript
|
|
5
5
|
output.
|
6
6
|
|
7
7
|
Home:: http://rubyforge.org/projects/pdf-htmldoc/
|
8
|
-
HTMLDOC Home
|
8
|
+
HTMLDOC Home:: http://www.htmldoc.org/
|
9
9
|
Copyright:: 2007, Ronaldo M. Ferraz
|
10
10
|
|
11
11
|
This is a preview release, which means it had only limited testing. As
|
12
|
-
far as
|
12
|
+
far as I know, it will work on all platforms in which HTMLDOC is
|
13
13
|
available. Comments, suggestions, and further tests are welcome.
|
14
14
|
|
15
15
|
== LICENSE NOTES
|
@@ -59,7 +59,7 @@ A similar approach can be used for inline generation:
|
|
59
59
|
p << "/var/doc/file2.html"
|
60
60
|
|
61
61
|
p << @report.to_html
|
62
|
-
p << "Some other text that will be incorporated
|
62
|
+
p << "Some other text that will be incorporated in the report"
|
63
63
|
|
64
64
|
p.footer ".1."
|
65
65
|
|
@@ -73,10 +73,46 @@ your system.
|
|
73
73
|
|
74
74
|
require "htmldoc"
|
75
75
|
|
76
|
-
PDF::HTMLDoc.program_path = "\"C
|
76
|
+
PDF::HTMLDoc.program_path = "\"C:\\Program Files\\HTMLDOC\\ghtmldoc.exe\""
|
77
77
|
|
78
78
|
See the notes below for usage considerations.
|
79
79
|
|
80
|
+
== COMMON OPTIONS
|
81
|
+
|
82
|
+
Here are a few of the common options that can be used to control
|
83
|
+
HTMLDOC's output (assuming that <tt>pdf</tt> is a valid instance of
|
84
|
+
PDF::HTMLDoc):
|
85
|
+
|
86
|
+
To change the orientation to portrait mode, use:
|
87
|
+
pdf.set_option :portrait, true
|
88
|
+
|
89
|
+
To change the orientation to landscape mode, use:
|
90
|
+
pdf.set_option :landscape, true
|
91
|
+
|
92
|
+
To set the margins use:
|
93
|
+
pdf.set_option :top, "15"
|
94
|
+
pdf.set_option :right, "3cm"
|
95
|
+
pdf.set_option :left, "0.25in"
|
96
|
+
pdf.set_option :bottom, "20mm"
|
97
|
+
|
98
|
+
To disable the automatic table of contents, use:
|
99
|
+
pdf.set_option :toc, false
|
100
|
+
|
101
|
+
To control the header and footer, use:
|
102
|
+
pdf.header "lcr"
|
103
|
+
pdf.footer "lcr"
|
104
|
+
|
105
|
+
In the code above, "lcr" is a thee-character string representing the
|
106
|
+
left, center, and right fields of the header or footer. A ".1."
|
107
|
+
string, for example, indicates that the left and right fields should
|
108
|
+
be blank, and that the center field should contain the current page
|
109
|
+
number in decimal format. You can find more information about the
|
110
|
+
possible options in the HTMLDOC
|
111
|
+
documentation[http://www.htmldoc.org/htmldoc.html#footer].
|
112
|
+
|
113
|
+
More information about other options can be found in the HTMLDOC
|
114
|
+
command-line reference[http://www.htmldoc.org/htmldoc.html#CMDREF].
|
115
|
+
|
80
116
|
== NOTES
|
81
117
|
|
82
118
|
* PDF::HTMLDoc is both a Rails plugin and a gem, which means it can be
|
@@ -84,13 +120,21 @@ See the notes below for usage considerations.
|
|
84
120
|
further dependencies.
|
85
121
|
|
86
122
|
* Under Windows, it's better to point the program path for the HTMLDOC
|
87
|
-
executable to the GUI
|
88
|
-
popping-up in your application,
|
89
|
-
|
90
|
-
* Keep in mind that HTMLDOC is not fast over large documents. If
|
91
|
-
need to generate very large documents, you be better off
|
92
|
-
additional thread if
|
93
|
-
farming off the generation for a background deamon
|
94
|
-
communicate with your application using some RPC
|
123
|
+
executable to the GUI version. It will prevent a DOS command window
|
124
|
+
from popping-up in your application,
|
125
|
+
|
126
|
+
* Keep in mind that HTMLDOC is not very fast over large documents. If
|
127
|
+
you need to generate very large documents, you'll be better off
|
128
|
+
spawning an additional thread if you are developing a traditional
|
129
|
+
application or farming off the generation for a background deamon
|
130
|
+
that will communicate with your application using some RPC
|
95
131
|
mechanism. BackgrounDRb[http://backgroundrb.rubyforge.org] is a good
|
96
132
|
choice for that.
|
133
|
+
|
134
|
+
* HTMLDOC doesn't support CSS files in its current stable version
|
135
|
+
(1.8.27). The development version (1.9) does support CSS, but in a
|
136
|
+
limited way.
|
137
|
+
|
138
|
+
* HTMLDOC doesn't support UTF-8. Since PDF::HTMLDOC makes no attempt
|
139
|
+
to convert any input passed to it, it's the caller's responsibility
|
140
|
+
to provide any necessary conversions.
|
data/Rakefile
CHANGED
@@ -19,7 +19,7 @@ GEM_NAME = "htmldoc"
|
|
19
19
|
RUBYFORGE_PROJECT = "htmldoc"
|
20
20
|
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
21
21
|
|
22
|
-
NAME = "
|
22
|
+
NAME = "HTMLDOC"
|
23
23
|
REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
24
24
|
VERS = ENV['VERSION'] || (PDF::HTMLDOC::VERSION::STRING + (REV ? ".#{REV}" : ""))
|
25
25
|
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
data/lib/htmldoc.rb
CHANGED
@@ -44,9 +44,21 @@ module PDF
|
|
44
44
|
# <code>"C:\Program Files\HTMLDOC\HTMLDOC.exe"</code>.
|
45
45
|
@@program_path = "htmldoc"
|
46
46
|
|
47
|
-
# The last result from the generation of the output file(s).
|
47
|
+
# The last result from the generation of the output file(s). It's
|
48
|
+
# a hash comprising three pairs:
|
49
|
+
# <tt>bytes</tt>:: The number of bytes generated in the last request or <tt>nil</tt>
|
50
|
+
# <tt>pages</tt>:: The number of pages generated in the last request or <tt>nil</tt>
|
51
|
+
# <tt>output</tt>:: The raw output of the command
|
48
52
|
attr_reader :result
|
49
53
|
|
54
|
+
# The last error messages generate by the command. It's a hash
|
55
|
+
# where they key represents the error number, and the value
|
56
|
+
# represents the error message. If the error number is zero,
|
57
|
+
# HTMLDOC was called with invalid parameters. Errors can happen
|
58
|
+
# even if generation succeeds, for example, if an image can't be
|
59
|
+
# found in the course of the generation.
|
60
|
+
attr_reader :errors
|
61
|
+
|
50
62
|
# Creates a blank HTMLDOC wrapper, using <tt>format</tt> to
|
51
63
|
# indicate whether the output will be HTML, PDF or PS. The format
|
52
64
|
# defaults to PDF, and can change using one of the module
|
@@ -56,13 +68,13 @@ module PDF
|
|
56
68
|
@options = {}
|
57
69
|
@pages = []
|
58
70
|
@tempfiles = []
|
59
|
-
|
71
|
+
reset
|
60
72
|
end
|
61
73
|
|
62
74
|
# Creates a blank HTMLDOC wrapper and passes it to a block. When
|
63
75
|
# the block finishes running, the <tt>generate</tt> method is
|
64
|
-
# automatically called. The result of generate is then
|
65
|
-
# to the application.
|
76
|
+
# automatically called. The result of <tt>generate</tt> is then
|
77
|
+
# passed back to the application.
|
66
78
|
def self.create(format = PDF, &block)
|
67
79
|
pdf = HTMLDoc.new(format)
|
68
80
|
if block_given?
|
@@ -131,16 +143,16 @@ module PDF
|
|
131
143
|
# or file is provided, the method will return <tt>true</tt> or
|
132
144
|
# <tt>false</tt> to indicate completion. If no output directory or
|
133
145
|
# file is provided, it will return a string representing the
|
134
|
-
# entire output.
|
146
|
+
# entire output. Generate will raise a PDF::HTMLDocException if
|
147
|
+
# the program path can't be found.
|
135
148
|
def generate
|
136
149
|
tempfile = nil
|
137
150
|
unless @options[:outdir] || @options[:outfile]
|
138
151
|
tempfile = Tempfile.new("htmldoc.temp")
|
139
152
|
@options[:outfile] = tempfile.path
|
140
153
|
end
|
141
|
-
|
142
|
-
@result
|
143
|
-
if (/BYTES/ =~ @result)
|
154
|
+
execute
|
155
|
+
if @result[:bytes]
|
144
156
|
if tempfile
|
145
157
|
File.open(tempfile.path, "rb") { |f| f.read }
|
146
158
|
else
|
@@ -150,12 +162,46 @@ module PDF
|
|
150
162
|
false
|
151
163
|
end
|
152
164
|
ensure
|
153
|
-
|
165
|
+
if tempfile
|
166
|
+
tempfile.close
|
167
|
+
@options[:outfile] = nil
|
168
|
+
end
|
154
169
|
@tempfiles.each { |t| t.close }
|
155
170
|
end
|
156
171
|
|
157
172
|
private
|
158
173
|
|
174
|
+
def execute
|
175
|
+
# Reset internal variables
|
176
|
+
reset
|
177
|
+
# Execute
|
178
|
+
command = @@program_path + " " + get_command_options + " " + get_command_pages + " 2>&1"
|
179
|
+
result = IO.popen(command) { |s| s.read }
|
180
|
+
# Check whether the program really was executed
|
181
|
+
if $?.exitstatus == 127
|
182
|
+
raise HTMLDocException.new("Invalid program path: #{@@program_path}")
|
183
|
+
else
|
184
|
+
@result[:output] = result
|
185
|
+
result.split("\n").each do |line|
|
186
|
+
case line
|
187
|
+
when /^BYTES: (\d+)/
|
188
|
+
@result[:bytes] = $1.to_i
|
189
|
+
when /^PAGES: (\d+)/
|
190
|
+
@result[:pages] = $1.to_i
|
191
|
+
when /^ERROR: (.*)$/
|
192
|
+
@errors[0] = $1.strip
|
193
|
+
when /^ERR(\d+): (.*)$/
|
194
|
+
@errors[$1.to_i] = $2.strip
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def reset
|
201
|
+
@result = { :bytes => nil, :pages => nil, :output => nil }
|
202
|
+
@errors = { }
|
203
|
+
end
|
204
|
+
|
159
205
|
def get_command_pages
|
160
206
|
pages = @pages.collect do |page|
|
161
207
|
case page[:type]
|
data/lib/htmldoc/version.rb
CHANGED
data/test/generation_test.rb
CHANGED
@@ -23,65 +23,101 @@ class GenerationTest < Test::Unit::TestCase
|
|
23
23
|
basic_test(PDF::PDF)
|
24
24
|
end
|
25
25
|
|
26
|
+
def test_generation_results
|
27
|
+
pdf = PDF::HTMLDoc.new
|
28
|
+
pdf.set_option :webpage, true
|
29
|
+
pdf.set_option :toc, false
|
30
|
+
pdf << "<h1>Random title</h1>"
|
31
|
+
assert_kind_of String, pdf.generate
|
32
|
+
assert_not_nil pdf.result[:bytes]
|
33
|
+
assert_not_nil pdf.result[:pages]
|
34
|
+
assert_equal 0, pdf.errors.size
|
35
|
+
assert_equal 1, pdf.result[:pages]
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_invalid_program_path
|
39
|
+
PDF::HTMLDoc.program_path = @program_path + "-non-existing-path"
|
40
|
+
assert_raise(PDF::HTMLDocException) { PDF::HTMLDoc.new.generate }
|
41
|
+
ensure
|
42
|
+
PDF::HTMLDoc.program_path = @program_path
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_generation_errors
|
46
|
+
# This test can fail if the collapsing wavefront of the Internet
|
47
|
+
# somehow becomes random.
|
48
|
+
# Test invalid input
|
49
|
+
pdf = PDF::HTMLDoc.new
|
50
|
+
pdf.set_option :outfile, "test.pdf"
|
51
|
+
pdf << "http://#{simple_uid(".com")}:12345/#{simple_uid(".html")}"
|
52
|
+
pdf.generate
|
53
|
+
assert_not_equal 0, pdf.errors.size
|
54
|
+
assert_nil pdf.result[:bytes]
|
55
|
+
assert_nil pdf.result[:pages]
|
56
|
+
# Test an invalid option
|
57
|
+
pdf = PDF::HTMLDoc.new
|
58
|
+
pdf.set_option :outfile, "test.pdf"
|
59
|
+
pdf << "http://#{simple_uid(".com")}:12345/#{simple_uid(".html")} --non-existing-option"
|
60
|
+
pdf.generate
|
61
|
+
assert_not_equal 0, pdf.errors.size
|
62
|
+
assert_nil pdf.result[:bytes]
|
63
|
+
assert_nil pdf.result[:pages]
|
64
|
+
end
|
65
|
+
|
26
66
|
private
|
27
67
|
|
28
68
|
def basic_test(format)
|
69
|
+
# Temporary files
|
29
70
|
path1, path2 = (1..2).collect { |i| Dir.tmpdir + "/#{i}.#{format}" }
|
71
|
+
# Create a temporary file for the duration of the test
|
30
72
|
Tempfile.open("htmldoc.test") do |tempfile|
|
73
|
+
# Load the temporary file with some test datas
|
31
74
|
page = "<h1>Page 1</h1><p>Test.</p><h1>Page 2</h1><p>Test.</p>"
|
32
75
|
tempfile.binmode
|
33
76
|
tempfile.write(page)
|
34
77
|
tempfile.flush
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
result = PDF::HTMLDoc.create(format) do |p|
|
77
|
-
p.set_option :outfile, path1
|
78
|
-
p.set_option :bodycolor, :black
|
79
|
-
p.add_page tempfile.path
|
80
|
-
end
|
81
|
-
assert_equal true, result
|
82
|
-
ensure
|
83
|
-
File.delete(path1)
|
78
|
+
# Simple format test
|
79
|
+
pdf = PDF::HTMLDoc.new(format)
|
80
|
+
pdf.set_option :outfile, path1
|
81
|
+
pdf.add_page tempfile.path
|
82
|
+
assert_equal true, pdf.generate
|
83
|
+
assert_equal pdf.result[:output], execute_htmldoc(path2, tempfile.path, "--format #{format}")
|
84
|
+
# Delete temporary files
|
85
|
+
File.delete(path1) if File.exists?(path1)
|
86
|
+
File.delete(path2) if File.exists?(path2)
|
87
|
+
# Simple webpag format test
|
88
|
+
pdf = PDF::HTMLDoc.new(format)
|
89
|
+
pdf.set_option :outfile, path1
|
90
|
+
pdf.set_option :webpage, true
|
91
|
+
pdf.add_page tempfile.path
|
92
|
+
assert_equal true, pdf.generate
|
93
|
+
assert_equal pdf.result[:output], execute_htmldoc(path2, tempfile.path, "--webpage --format #{format}")
|
94
|
+
# Delete temporary files
|
95
|
+
File.delete(path1) if File.exists?(path1)
|
96
|
+
File.delete(path2) if File.exists?(path2)
|
97
|
+
# Simple options test
|
98
|
+
pdf = PDF::HTMLDoc.new(format)
|
99
|
+
pdf.set_option :outfile, path1
|
100
|
+
pdf.set_option :bodycolor, :black
|
101
|
+
pdf.add_page tempfile.path
|
102
|
+
assert_equal true, pdf.generate
|
103
|
+
assert_equal pdf.result[:output], execute_htmldoc(path2, tempfile.path, "--bodycolor black --format #{format}")
|
104
|
+
# Delete temporary files
|
105
|
+
File.delete(path1) if File.exists?(path1)
|
106
|
+
File.delete(path2) if File.exists?(path2)
|
107
|
+
# Free text generate test
|
108
|
+
pdf = PDF::HTMLDoc.new(format)
|
109
|
+
pdf.add_page page
|
110
|
+
pdf.generate
|
111
|
+
assert_equal pdf.result[:output], execute_htmldoc(path2, tempfile.path, "--format #{format}")
|
112
|
+
# Delete temporary files
|
113
|
+
File.delete(path2) if File.exists?(path2)
|
114
|
+
# Inline generation test
|
115
|
+
result = PDF::HTMLDoc.create(format) do |p|
|
116
|
+
p.set_option :outfile, path1
|
117
|
+
p.set_option :bodycolor, :black
|
118
|
+
p.add_page tempfile.path
|
84
119
|
end
|
120
|
+
assert_equal true, result
|
85
121
|
end
|
86
122
|
end
|
87
123
|
|
@@ -89,4 +125,11 @@ class GenerationTest < Test::Unit::TestCase
|
|
89
125
|
IO.popen("#{@program_path} #{options} -f #{output} #{input} 2>&1") { |s| s.read }
|
90
126
|
end
|
91
127
|
|
128
|
+
def simple_uid(extension)
|
129
|
+
chars = ('A'..'Z').to_a + ('0'..'9').to_a
|
130
|
+
(1..100).inject("") { |r, i| r + chars[rand(chars.length)] }
|
131
|
+
end
|
132
|
+
|
92
133
|
end
|
134
|
+
|
135
|
+
# LocalWords: HTMLDOC
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: htmldoc
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-03-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2007-03-07 00:00:00 -03:00
|
8
8
|
summary: A wrapper around HTMLDOC, a PDF generation utility
|
9
9
|
require_paths:
|
10
10
|
- lib
|