htmldoc-hulihanapplications 0.2.4

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