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 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
@@ -1,2 +1,8 @@
1
+ 0.2.0
2
+ * Improved the way results are reported
3
+ * Added information about errors generated in the course of execution
4
+ * Refactored a couple of internal methods
5
+ * Improved the tests and documentation
6
+
1
7
  0.1.0
2
8
  * Initial release
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: http://www.htmldoc.org/
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 it's know, it will work on all platforms in which HTMLDOC is
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 to the report"
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:\Program Files\HTMLDOC\ghtmldoc.exe\""
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 vesion. It will avoid a DOS command window from
88
- popping-up in your application,
89
-
90
- * Keep in mind that HTMLDOC is not fast over large documents. If you
91
- need to generate very large documents, you be better off spawning an
92
- additional thread if your are in a traditional application or
93
- farming off the generation for a background deamon that will
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 = "htmldoc"
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
- @result = ""
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 passed back
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
- command = @@program_path + " " + get_command_options + " " + get_command_pages + " 2>&1"
142
- @result = IO.popen(command) { |s| s.read }
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
- tempfile.close if tempfile
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]
@@ -5,7 +5,7 @@ module PDF
5
5
  module VERSION #:nodoc:
6
6
 
7
7
  MAJOR = 0
8
- MINOR = 1
8
+ MINOR = 2
9
9
  TINY = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, TINY].join(".")
@@ -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
- begin
36
- pdf = PDF::HTMLDoc.new(format)
37
- pdf.set_option :outfile, path1
38
- pdf.add_page tempfile.path
39
- assert_equal true, pdf.generate
40
- assert_equal pdf.result, execute_htmldoc(path2, tempfile.path, "--format #{format}")
41
- ensure
42
- File.delete(path1)
43
- File.delete(path2)
44
- end
45
- begin
46
- pdf = PDF::HTMLDoc.new(format)
47
- pdf.set_option :outfile, path1
48
- pdf.set_option :webpage, true
49
- pdf.add_page tempfile.path
50
- assert_equal true, pdf.generate
51
- assert_equal pdf.result, execute_htmldoc(path2, tempfile.path, "--webpage --format #{format}")
52
- ensure
53
- File.delete(path1)
54
- File.delete(path2)
55
- end
56
- begin
57
- pdf = PDF::HTMLDoc.new(format)
58
- pdf.set_option :outfile, path1
59
- pdf.set_option :bodycolor, :black
60
- pdf.add_page tempfile.path
61
- assert_equal true, pdf.generate
62
- assert_equal pdf.result, execute_htmldoc(path2, tempfile.path, "--bodycolor black --format #{format}")
63
- ensure
64
- File.delete(path1)
65
- File.delete(path2)
66
- end
67
- begin
68
- pdf = PDF::HTMLDoc.new(format)
69
- pdf.add_page page
70
- pdf.generate
71
- assert_equal pdf.result, execute_htmldoc(path2, tempfile.path, "--format #{format}")
72
- ensure
73
- File.delete(path2)
74
- end
75
- begin
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.1.0
7
- date: 2007-03-05 00:00:00 -03:00
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