namespaced_htmldoc 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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