htmldoc 0.1.0 → 0.2.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/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
|