namespaced_htmldoc 0.2.3

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/History.txt ADDED
@@ -0,0 +1,25 @@
1
+ 2010-12-21:
2
+ * Forked from github.com/craigw/htmldoc
3
+ * Only the main code and tests were updated; it is likely that the Rakefile is
4
+ now invalid/broken.
5
+
6
+ 0.2.3
7
+ * The htmldoc command sometimes uses \r in the output. [Jon Wood]
8
+
9
+ 0.2.2
10
+ * Move source code to GitHub: http://github.com/craigw/htmldoc
11
+ * Strings that have linebreaks in are probably not URLs.
12
+ * If a string has a line starting what matches /https?:\/\/ it's not an
13
+ URL, it's a string. [Tim Peters <http://rubyforge.org/users/tcp>]
14
+
15
+ 0.2.1
16
+ * Fixed a bug in set_option where the value false would be seen as nil instead of :no
17
+
18
+ 0.2.0
19
+ * Improved the way results are reported
20
+ * Added information about errors generated in the course of execution
21
+ * Refactored a couple of internal methods
22
+ * Improved the tests and documentation
23
+
24
+ 0.1.0
25
+ * Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 Craig R Webster <http://barkingiguana.com/>
2
+ Copyright (c) 2007 Ronaldo M. Ferraz
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,12 @@
1
+ History.txt
2
+ LICENSE.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ init.rb
7
+ lib/htmldoc.rb
8
+ lib/htmldoc/version.rb
9
+ setup.rb
10
+ test/basic_test.rb
11
+ test/generation_test.rb
12
+ test/test_helper.rb
data/README.txt ADDED
@@ -0,0 +1,145 @@
1
+ = HTMLDocPDF::HTMLDoc
2
+
3
+ HTMLDocPDF::HTMLDoc is a wrapper around HTMLDOC, an open-source application
4
+ that converts HTML input files into formatted HTML, PDF or PostScript
5
+ output.
6
+
7
+ It was forked from https://github.com/craigw/htmldoc specifically to change
8
+ the root namespace from PDF:: to HTMLDocPDF::, so that it will play nice with
9
+ other gems that use the PDF:: namespace.
10
+
11
+
12
+ Home:: http://rubyforge.org/projects/htmldoc/
13
+ HTMLDOC Home:: http://www.htmldoc.org/
14
+ Copyright:: 2007, Ronaldo M. Ferraz
15
+
16
+ This is a preview release, which means it had only limited testing. As
17
+ far as I know, it will work on all platforms in which HTMLDOC is
18
+ available. Comments, suggestions, and further tests are welcome.
19
+
20
+ == LICENSE NOTES
21
+
22
+ Please read the LICENCE.txt file for licensing information on this
23
+ library.
24
+
25
+ == USAGE
26
+
27
+ Using HTMLDocPDF::HTMLDoc is trivial. The example below illustrates a simple
28
+ use with an output file:
29
+
30
+ require "htmldoc"
31
+
32
+ pdf = HTMLDocPDF::HTMLDoc.new
33
+
34
+ pdf.set_option :outfile, "/tmp/outfile.pdf"
35
+ pdf.set_option :bodycolor, :black
36
+ pdf.set_option :links, true
37
+
38
+ pdf.header ".t."
39
+
40
+ pdf << "/var/doc/file1.html"
41
+ pdf << "/var/doc/file2.html"
42
+
43
+ pdf.footer ".1."
44
+
45
+ if pdf.generate
46
+ puts "Successfully generated a PDF file"
47
+ end
48
+
49
+ A similar approach can be used for inline generation:
50
+
51
+ require "htmldoc"
52
+
53
+ document = HTMLDocPDF::HTMLDoc.create(HTMLDocPDF::PS) do |p|
54
+
55
+ p.set_option :bodycolor, :black
56
+ p.set_option :links, true
57
+
58
+ p.header ".t."
59
+
60
+ p << "http://example.org/index.html"
61
+ p << "http://localhost/test/data"
62
+
63
+ p << "/var/doc/file1.html"
64
+ p << "/var/doc/file2.html"
65
+
66
+ p << @report.to_html
67
+ p << "Some other text that will be incorporated in the report"
68
+
69
+ p.footer ".1."
70
+
71
+ end
72
+
73
+ In the example above, it's not necessary to call the <tt>generate</tt>
74
+ method since it will be automatically invoked by the block.
75
+
76
+ You can also configure the program path for HTMLDOC if it differs in
77
+ your system.
78
+
79
+ require "htmldoc"
80
+
81
+ HTMLDocPDF::HTMLDoc.program_path = "\"C:\\Program Files\\HTMLDOC\\ghtmldoc.exe\""
82
+
83
+ See the notes below for usage considerations.
84
+
85
+ == COMMON OPTIONS
86
+
87
+ Here are a few of the common options that can be used to control
88
+ HTMLDOC's output (assuming that <tt>pdf</tt> is a valid instance of
89
+ HTMLDocPDF::HTMLDoc):
90
+
91
+ To change the orientation to portrait mode, use:
92
+ pdf.set_option :portrait, true
93
+
94
+ To change the orientation to landscape mode, use:
95
+ pdf.set_option :landscape, true
96
+
97
+ To set the margins use:
98
+ pdf.set_option :top, "15"
99
+ pdf.set_option :right, "3cm"
100
+ pdf.set_option :left, "0.25in"
101
+ pdf.set_option :bottom, "20mm"
102
+
103
+ To disable the automatic table of contents, use:
104
+ pdf.set_option :toc, false
105
+
106
+ To control the header and footer, use:
107
+ pdf.header "lcr"
108
+ pdf.footer "lcr"
109
+
110
+ In the code above, "lcr" is a thee-character string representing the
111
+ left, center, and right fields of the header or footer. A ".1."
112
+ string, for example, indicates that the left and right fields should
113
+ be blank, and that the center field should contain the current page
114
+ number in decimal format. You can find more information about the
115
+ possible options in the HTMLDOC
116
+ documentation[http://www.htmldoc.org/htmldoc.html#footer].
117
+
118
+ More information about other options can be found in the HTMLDOC
119
+ command-line reference[http://www.htmldoc.org/htmldoc.html#CMDREF].
120
+
121
+ == NOTES
122
+
123
+ * HTMLDocPDF::HTMLDoc is both a Rails plugin and a gem, which means it can be
124
+ installed system-wide, or just used on a Rails project without
125
+ further dependencies.
126
+
127
+ * Under Windows, it's better to point the program path for the HTMLDOC
128
+ executable to the GUI version. It will prevent a DOS command window
129
+ from popping-up in your application,
130
+
131
+ * Keep in mind that HTMLDOC is not very fast over large documents. If
132
+ you need to generate very large documents, you'll be better off
133
+ spawning an additional thread if you are developing a traditional
134
+ application or farming off the generation for a background deamon
135
+ that will communicate with your application using some RPC
136
+ mechanism. BackgrounDRb[http://backgroundrb.rubyforge.org] is a good
137
+ choice for that.
138
+
139
+ * HTMLDOC doesn't support CSS files in its current stable version
140
+ (1.8.27). The development version (1.9) does support CSS, but in a
141
+ limited way.
142
+
143
+ * HTMLDOC doesn't support UTF-8. Since HTMLDocPDF::HTMLDOC makes no attempt
144
+ to convert any input passed to it, it's the caller's responsibility
145
+ to provide any necessary conversions.
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+
12
+ include FileUtils
13
+ require File.join(File.dirname(__FILE__), 'lib', 'htmldoc', 'version')
14
+
15
+ AUTHOR = "Craig R Webster"
16
+ EMAIL = "craig@barkingiguana.com"
17
+ DESCRIPTION = "A wrapper around HTMLDOC, a PDF generation utility"
18
+ GEM_NAME = "htmldoc"
19
+ RUBYFORGE_PROJECT = "htmldoc"
20
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
21
+
22
+ NAME = "HTMLDOC"
23
+ RDOC_OPTS = ['--quiet', '--title', "htmldoc documentation",
24
+ "--opname", "index.html",
25
+ "--line-numbers",
26
+ "--main", "README",
27
+ "--inline-source"]
28
+
29
+ class Hoe
30
+ def extra_deps
31
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
32
+ end
33
+ end
34
+
35
+ # Generate all the Rake tasks
36
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
37
+ hoe = Hoe.new(GEM_NAME, HTMLDocPDF::HTMLDOC::VERSION::STRING) do |p|
38
+
39
+ p.author = AUTHOR
40
+ p.email = EMAIL
41
+ p.summary = DESCRIPTION
42
+ p.url = HOMEPATH
43
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
44
+ p.test_globs = ["test/**/*_test.rb"]
45
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
46
+ p.description = p.paragraphs_of('README.txt', 1..1).join("\n\n")
47
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
48
+
49
+ #p.extra_deps - An array of rubygem dependencies.
50
+ #p.spec_extras - A hash of extra values to set in the gemspec.
51
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "htmldoc"
@@ -0,0 +1,17 @@
1
+ module HTMLDocPDF
2
+
3
+ module HTMLDOC #:nodoc:
4
+
5
+ module VERSION #:nodoc:
6
+
7
+ MAJOR = 0
8
+ MINOR = 2
9
+ TINY = 3
10
+
11
+ STRING = [MAJOR, MINOR, TINY].join(".")
12
+
13
+ end
14
+
15
+ end
16
+
17
+ end
data/lib/htmldoc.rb ADDED
@@ -0,0 +1,248 @@
1
+ require "tempfile"
2
+
3
+ module HTMLDocPDF
4
+
5
+ HTML = "html"
6
+ HTMLSEP = "htmlsep"
7
+ PDF = "pdf"
8
+ PDF11 = "pdf11"
9
+ PDF12 = "pdf12"
10
+ PDF13 = "pdf13"
11
+ PDF14 = "pdf14"
12
+ PS = "ps"
13
+ PS1 = "ps1"
14
+ PS2 = "ps2"
15
+ PS3 = "ps3"
16
+
17
+ # Exception class representing an internal error in the HTMLDoc
18
+ # class.
19
+ class HTMLDocException < StandardError; end
20
+
21
+ # The wrapper class around HTMLDOC, providing methods for setting
22
+ # the options for the application and retriving the generate output
23
+ # either as a file, diretory or string.
24
+ class HTMLDoc
25
+
26
+ @@basic_options = [:bodycolor, :bodyfont, :bodyimage, :bottom, :browserwidth,
27
+ :charset, :continuous, :cookies, :datadir, :effectduration,
28
+ :firstpage, :fontsize, :fontspacing, :footer, :gray, :header,
29
+ :headerfontfoot, :headfontsize, :headingfont, :landscape,
30
+ :left, :linkcolor, :linkstyle, :logoimage, :nup, :outdir,
31
+ :outfile, :owner_password, :pageduration, :pageeffect,
32
+ :pagelayout, :pagemode, :path, :permissions, :portrait,
33
+ :referer, :right, :size, :textcolor, :textfont, :titlefile,
34
+ :titleimage, :tocfooter, :tocheader, :toclevels, :toctitle,
35
+ :user_password, :webpage]
36
+
37
+ @@extra_options = [:compression, :duplex, :embedfonts, :encryption, :jpeg,
38
+ :links, :localfiles, :numbered, :pscommands, :strict, :title,
39
+ :toc, :xrxcomments]
40
+
41
+ @@all_options = @@basic_options + @@extra_options
42
+
43
+ # The path to HTMLDOC in the system. E.g, <code>/usr/bin/html</code> or
44
+ # <code>"C:\Program Files\HTMLDOC\HTMLDOC.exe"</code>.
45
+ @@program_path = "htmldoc"
46
+
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
52
+ attr_reader :result
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
+
62
+ # Creates a blank HTMLDOC wrapper, using <tt>format</tt> to
63
+ # indicate whether the output will be HTML, PDF or PS. The format
64
+ # defaults to PDF, and can change using one of the module
65
+ # contants.
66
+ def initialize(format = PDF)
67
+ @format = format
68
+ @options = {}
69
+ @pages = []
70
+ @tempfiles = []
71
+ reset
72
+ end
73
+
74
+ # Creates a blank HTMLDOC wrapper and passes it to a block. When
75
+ # the block finishes running, the <tt>generate</tt> method is
76
+ # automatically called. The result of <tt>generate</tt> is then
77
+ # passed back to the application.
78
+ def self.create(format = PDF, &block)
79
+ pdf = HTMLDoc.new(format)
80
+ if block_given?
81
+ yield pdf
82
+ pdf.generate
83
+ end
84
+ end
85
+
86
+ # Gets the current path for the HTMLDOC executable. This is a
87
+ # class method.
88
+ def self.program_path
89
+ @@program_path
90
+ end
91
+
92
+ # Sets the current path for the HTMLDOC executable. This is a
93
+ # class method.
94
+ def self.program_path=(value)
95
+ @@program_path = value
96
+ end
97
+
98
+ # Sets an option for the wrapper. Only valid HTMLDOC options will
99
+ # be accepted. The name of the option is a symbol, but the value
100
+ # can be anything. Invalid options will throw an exception. To
101
+ # unset an option, use <tt>nil</tt> as the value. Options with
102
+ # negated counterparts, like <tt>:encryption</tt>, can be set
103
+ # using false, :no or :none as the value.
104
+ def set_option(option, value)
105
+ if @@all_options.include?(option)
106
+ if !value.nil?
107
+ @options[option] = value
108
+ else
109
+ @options.delete(option)
110
+ end
111
+ else
112
+ raise HTMLDocException.new("Invalid option #{option.to_s}")
113
+ end
114
+ end
115
+
116
+ # Sets the header. It's the same as set_option :header, value.
117
+ def header(value)
118
+ set_option :header, value
119
+ end
120
+
121
+ # Sets the footer. It's the same as set_option :footer, value.
122
+ def footer(value)
123
+ set_option :footer, value
124
+ end
125
+
126
+ # Adds a page for generation. The page can be a URL beginning with
127
+ # either <tt>http://</tt> or <tt>https://</tt>; a file, which will
128
+ # be verified for existence; or any text.
129
+ def add_page(page)
130
+ if /\A(http|https)/ =~ page && page !~ /\r|\n/
131
+ type = :url
132
+ elsif File.exists?(page)
133
+ type = :file
134
+ else
135
+ type = :text
136
+ end
137
+ @pages << { :type => type, :value => page }
138
+ end
139
+
140
+ alias :<< :add_page
141
+
142
+ # Invokes HTMLDOC and generates the output. If an output directory
143
+ # or file is provided, the method will return <tt>true</tt> or
144
+ # <tt>false</tt> to indicate completion. If no output directory or
145
+ # file is provided, it will return a string representing the
146
+ # entire output. Generate will raise a HTMLDocPDF::HTMLDocException if
147
+ # the program path can't be found.
148
+ def generate
149
+ tempfile = nil
150
+ unless @options[:outdir] || @options[:outfile]
151
+ tempfile = Tempfile.new("htmldoc.temp")
152
+ @options[:outfile] = tempfile.path
153
+ end
154
+ execute
155
+ if @result[:bytes]
156
+ if tempfile
157
+ File.open(tempfile.path, "rb") { |f| f.read }
158
+ else
159
+ true
160
+ end
161
+ else
162
+ false
163
+ end
164
+ ensure
165
+ if tempfile
166
+ tempfile.close
167
+ @options[:outfile] = nil
168
+ end
169
+ @tempfiles.each { |t| t.close }
170
+ end
171
+
172
+ private
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(/\r|\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
+
205
+ def get_command_pages
206
+ pages = @pages.collect do |page|
207
+ case page[:type]
208
+ when :file, :url
209
+ page[:value]
210
+ else
211
+ t = Tempfile.new("htmldoc.temp")
212
+ t.binmode
213
+ t.write(page[:value])
214
+ t.flush
215
+ @tempfiles << t
216
+ t.path
217
+ end
218
+ end
219
+ pages.join(" ")
220
+ end
221
+
222
+ def get_command_options
223
+ options = @options.dup.merge({ :format => @format })
224
+ options = options.collect { |key, value| get_final_value(key, value) }
225
+ options.sort.join(" ")
226
+ end
227
+
228
+ def get_final_value(option, value)
229
+ option_name = "--" + option.to_s.gsub("_", "-")
230
+ if value.kind_of?(TrueClass)
231
+ option_name
232
+ elsif value.kind_of?(Hash)
233
+ items = value.collect { |name, contents| "#{name.to_s}=#{contents.to_s}" }
234
+ option_name + " '" + items.sort.join(";") + "'"
235
+ elsif @@basic_options.include?(option)
236
+ option_name + " " + value.to_s
237
+ else
238
+ if [false, :no, :none].include?(value)
239
+ option_name.sub("--", "--no-")
240
+ else
241
+ option_name + " " + value.to_s
242
+ end
243
+ end
244
+ end
245
+
246
+ end
247
+
248
+ end