htmldoc-hulihanapplications 0.2.4

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/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+
9
+ group :development do
10
+ gem "shoulda", ">= 0"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "jeweler", "~> 1.6.4"
13
+ gem "rcov", ">= 0"
14
+ end
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.4)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rake (0.9.2)
10
+ rcov (0.9.10)
11
+ shoulda (2.11.3)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.0.0)
18
+ jeweler (~> 1.6.4)
19
+ rcov
20
+ shoulda
@@ -0,0 +1,20 @@
1
+ 0.2.3
2
+ * The htmldoc command sometimes uses \r in the output. [Jon Wood]
3
+
4
+ 0.2.2
5
+ * Move source code to GitHub: http://github.com/craigw/htmldoc
6
+ * Strings that have linebreaks in are probably not URLs.
7
+ * If a string has a line starting what matches /https?:\/\/ it's not an
8
+ URL, it's a string. [Tim Peters <http://rubyforge.org/users/tcp>]
9
+
10
+ 0.2.1
11
+ * Fixed a bug in set_option where the value false would be seen as nil instead of :no
12
+
13
+ 0.2.0
14
+ * Improved the way results are reported
15
+ * Added information about errors generated in the course of execution
16
+ * Refactored a couple of internal methods
17
+ * Improved the tests and documentation
18
+
19
+ 0.1.0
20
+ * Initial release
@@ -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.
@@ -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
@@ -0,0 +1,140 @@
1
+ = PDF::HTMLDoc
2
+
3
+ PDF::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
+ Home:: http://rubyforge.org/projects/htmldoc/
8
+ HTMLDOC Home:: http://www.htmldoc.org/
9
+ Copyright:: 2007, Ronaldo M. Ferraz
10
+
11
+ This is a preview release, which means it had only limited testing. As
12
+ far as I know, it will work on all platforms in which HTMLDOC is
13
+ available. Comments, suggestions, and further tests are welcome.
14
+
15
+ == LICENSE NOTES
16
+
17
+ Please read the LICENCE.txt file for licensing information on this
18
+ library.
19
+
20
+ == USAGE
21
+
22
+ Using PDF::HTMLDoc is trivial. The example below illustrates a simple
23
+ use with an output file:
24
+
25
+ require "htmldoc"
26
+
27
+ pdf = PDF::HTMLDoc.new
28
+
29
+ pdf.set_option :outfile, "/tmp/outfile.pdf"
30
+ pdf.set_option :bodycolor, :black
31
+ pdf.set_option :links, true
32
+
33
+ pdf.header ".t."
34
+
35
+ pdf << "/var/doc/file1.html"
36
+ pdf << "/var/doc/file2.html"
37
+
38
+ pdf.footer ".1."
39
+
40
+ if pdf.generate
41
+ puts "Successfully generated a PDF file"
42
+ end
43
+
44
+ A similar approach can be used for inline generation:
45
+
46
+ require "htmldoc"
47
+
48
+ document = PDF::HTMLDoc.create(PDF::PS) do |p|
49
+
50
+ p.set_option :bodycolor, :black
51
+ p.set_option :links, true
52
+
53
+ p.header ".t."
54
+
55
+ p << "http://example.org/index.html"
56
+ p << "http://localhost/test/data"
57
+
58
+ p << "/var/doc/file1.html"
59
+ p << "/var/doc/file2.html"
60
+
61
+ p << @report.to_html
62
+ p << "Some other text that will be incorporated in the report"
63
+
64
+ p.footer ".1."
65
+
66
+ end
67
+
68
+ In the example above, it's not necessary to call the <tt>generate</tt>
69
+ method since it will be automatically invoked by the block.
70
+
71
+ You can also configure the program path for HTMLDOC if it differs in
72
+ your system.
73
+
74
+ require "htmldoc"
75
+
76
+ PDF::HTMLDoc.program_path = "\"C:\\Program Files\\HTMLDOC\\ghtmldoc.exe\""
77
+
78
+ See the notes below for usage considerations.
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
+
116
+ == NOTES
117
+
118
+ * PDF::HTMLDoc is both a Rails plugin and a gem, which means it can be
119
+ installed system-wide, or just used on a Rails project without
120
+ further dependencies.
121
+
122
+ * Under Windows, it's better to point the program path for the HTMLDOC
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
131
+ mechanism. BackgrounDRb[http://backgroundrb.rubyforge.org] is a good
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.
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "htmldoc-hulihanapplications"
18
+ gem.homepage = "http://github.com/hulihanapplications/htmldoc"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Wrapper around HTMLDOC (canonical repository)}
21
+ gem.description = %Q{A fork of the craigw's htmldoc: https://github.com/craigw/htmldoc.}
22
+ gem.email = "dave@hulihanapplications.com"
23
+ gem.authors = ["Hulihan Applications", "Dave Hulihan"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "lablr #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.4
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{htmldoc-hulihanapplications}
8
+ s.version = "0.2.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Hulihan Applications", "Dave Hulihan"]
12
+ s.date = %q{2011-09-09}
13
+ s.description = %q{A fork of the craigw's htmldoc: https://github.com/craigw/htmldoc.}
14
+ s.email = %q{dave@hulihanapplications.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.txt"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "History.txt",
23
+ "LICENSE.txt",
24
+ "Manifest.txt",
25
+ "README.txt",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "htmldoc-hulihanapplications.gemspec",
29
+ "init.rb",
30
+ "lib/htmldoc.rb",
31
+ "lib/htmldoc/version.rb",
32
+ "setup.rb",
33
+ "test/basic_test.rb",
34
+ "test/generation_test.rb",
35
+ "test/test_helper.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/hulihanapplications/htmldoc}
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.6.2}
41
+ s.summary = %q{Wrapper around HTMLDOC (canonical repository)}
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
50
+ s.add_development_dependency(%q<rcov>, [">= 0"])
51
+ else
52
+ s.add_dependency(%q<shoulda>, [">= 0"])
53
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
54
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
55
+ s.add_dependency(%q<rcov>, [">= 0"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<shoulda>, [">= 0"])
59
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
61
+ s.add_dependency(%q<rcov>, [">= 0"])
62
+ end
63
+ end
64
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "htmldoc"
@@ -0,0 +1,248 @@
1
+ require "tempfile"
2
+
3
+ module PDF
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
+ :top, :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 PDF::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