rtex 1.99.0

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.rdoc ADDED
@@ -0,0 +1,29 @@
1
+ 2008-04-20
2
+
3
+ Released RTeX v1.99.0 as a Rubygem, with a standalone executable for PDF generation
4
+ and support for plugin installation from the executable.
5
+
6
+ This release requires Rails >= 2.0.1
7
+
8
+ Thanks to:
9
+ * Jonas Bähr for a patch with additional LaTeX escaping
10
+ * Fouad Mardini for a TemplateHandler patch
11
+
12
+ 2007
13
+
14
+ No active development, maintenance primarily by Wiebe Cazemier
15
+
16
+ 2006-07-27
17
+
18
+ Added quite a few *long* overdue fixes & enhancements sent in by various people.
19
+
20
+ * Added latex escaping 'l' method (Thanks, Benjamin Quorning)
21
+ * Added support for @options_for_rtex hash for configuration:
22
+ * Added :tempdir option, and changed default temporary directory
23
+ (Thanks, Francesco Levorato)
24
+ * Added :preprocess option to support running through latex before pdflatex
25
+ (Thanks Charles Lesburg, Benjamin Quorning)
26
+ * Moved old @filename setting to :filename option in this hash
27
+
28
+ If you're using the same settings for @options_for_rtex often, you might want to
29
+ put your assignment in a before_filter (perhaps overriding :filename, etc in your actions).
data/Manifest.txt ADDED
@@ -0,0 +1,33 @@
1
+ HISTORY.rdoc
2
+ Manifest.txt
3
+ README.rdoc
4
+ README_RAILS.rdoc
5
+ Rakefile
6
+ bin/rtex
7
+ init.rb
8
+ lib/rtex.rb
9
+ lib/rtex/document.rb
10
+ lib/rtex/escaping.rb
11
+ lib/rtex/framework/merb.rb
12
+ lib/rtex/framework/rails.rb
13
+ lib/rtex/tempdir.rb
14
+ lib/rtex/version.rb
15
+ tasks/doc.rake
16
+ tasks/gem.rake
17
+ tasks/manifest.rake
18
+ tasks/post_load.rake
19
+ tasks/setup.rb
20
+ tasks/test.rake
21
+ test/document_test.rb
22
+ test/filter_test.rb
23
+ test/fixtures/first.tex
24
+ test/fixtures/first.tex.erb
25
+ test/fixtures/fragment.tex.erb
26
+ test/fixtures/text.textile
27
+ test/tempdir_test.rb
28
+ test/test_helper.rb
29
+ test/tmp/rtex-071EE944-B2FA-4A3B-9764-1B5143833EB7/document.tex
30
+ test/tmp/rtex-592F93A7-6198-4B00-B638-33855344A29B/document.tex
31
+ test/tmp/rtex-96736595-5175-4602-9DC1-ABA096CC0E3D/document.tex
32
+ vendor/instiki/LICENSE
33
+ vendor/instiki/redcloth_for_tex.rb
data/README.rdoc ADDED
@@ -0,0 +1,47 @@
1
+ = RTeX: TeX/PDF Generation for Ruby
2
+
3
+ Project homepage: http://rtex.rubyforge.org
4
+
5
+ Please file comments and bug reports at http://rubyforge.org/projects/rtex
6
+ (in the Forum and the Tracker, respectively).
7
+
8
+ == Dependencies
9
+
10
+ * pdflatex executable, available in modern teTeX distributions
11
+ * Requires Rails >= 2.0.1 if used as a plugin.
12
+
13
+ == Usage
14
+
15
+ For use as a standalone executable, see `rtex --help'
16
+
17
+ For use as a Rails plugin, see README_RAILS.rdoc
18
+
19
+ == More Information
20
+
21
+ Additional help may be available at the project homepage,
22
+ http://rtex.rubyforge.org
23
+
24
+ == License
25
+
26
+ (The MIT License)
27
+
28
+ Copyright (c) 2006-2008 Bruce Williams, Wiebe Cazemier
29
+
30
+ Permission is hereby granted, free of charge, to any person obtaining
31
+ a copy of this software and associated documentation files (the
32
+ 'Software'), to deal in the Software without restriction, including
33
+ without limitation the rights to use, copy, modify, merge, publish,
34
+ distribute, sublicense, and/or sell copies of the Software, and to
35
+ permit persons to whom the Software is furnished to do so, subject to
36
+ the following conditions:
37
+
38
+ The above copyright notice and this permission notice shall be
39
+ included in all copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
42
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
44
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
45
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
46
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
47
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README_RAILS.rdoc ADDED
@@ -0,0 +1,45 @@
1
+ = RTeX Rails plugin
2
+
3
+ == Installation
4
+
5
+ sudo gem install rtex
6
+ rtex --install /path/to/rails/app
7
+
8
+ == Dependencies
9
+
10
+ * Rails >= 2.0.1
11
+
12
+ == Usage
13
+
14
+ Create files +pdf.rtex+ extensions (eg, +index.pdf.rtex+) using standard LaTeX markup.
15
+
16
+ * Layouts are supported, eg: +application.pdf.rtex+
17
+ * Partials are supported, eg: +_item.pdf.rtex+
18
+
19
+ === Example
20
+
21
+ With the following:
22
+
23
+ # app/controllers/items_controller.rb
24
+ def index
25
+ @items = Item.find(:all)
26
+ end
27
+
28
+ # app/views/items/index.pdf.rtex
29
+ \section*{Items}
30
+ \begin{itemize}
31
+ <%= render :partial => @items %>
32
+ \end{itemize}
33
+
34
+ # app/views/items/_item.pdf.rtex
35
+ \item <%=l item.name %> \\
36
+
37
+ # app/layouts/application.pdf.rtex
38
+ \documentclass[12pt]{article}
39
+ \begin{document}
40
+ <%= yield %>
41
+ \end{document}
42
+
43
+ If you hit +http://the.server.url/items.pdf+, you end up with a nice PDF listing of items.
44
+
45
+ Obviously a simplistic example.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) << "/lib/rtex/version"
2
+
3
+ load 'tasks/setup.rb'
4
+
5
+ PROJ.name = 'rtex'
6
+ PROJ.authors = ['Bruce Williams', 'Wiebe Cazemier']
7
+ PROJ.email = ['bruce@codefluency.com']
8
+ PROJ.url = 'http://rtex.rubyforge.org'
9
+ PROJ.rubyforge_name = 'rtex'
10
+
11
+ PROJ.libs = %w[]
12
+ PROJ.ruby_opts = []
13
+ PROJ.test_opts = []
14
+
15
+ PROJ.description = "LaTeX preprocessor for PDF generation; Rails plugin"
16
+ PROJ.summary = PROJ.description
17
+
18
+ PROJ.version = RTeX::Version::STRING
19
+
20
+ task 'gem:package' => 'manifest:assert'
data/bin/rtex ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'fileutils'
5
+
6
+ require File.dirname(__FILE__) << '/../lib/rtex'
7
+
8
+ options = {}
9
+
10
+ opts = OptionParser.new do |opts|
11
+
12
+ opts.banner = [
13
+ "RTeX v#{RTeX::Version::STRING} (c) 2006-2007 Bruce Williams, Wiebe Cazemier",
14
+ "USAGE: rtex [OPTIONS]"
15
+ ].join("\n")
16
+
17
+ opts.on_tail('-h', '--help', "Show this message") do
18
+ STDERR.puts opts
19
+ exit
20
+ end
21
+
22
+ opts.on('-l LAYOUT', '--layout LAYOUT', 'Path to layout file (use <%= yield %>)') do |layout|
23
+ if File.exists?(layout)
24
+ options[:layout] = File.read(layout)
25
+ else
26
+ STDERR.puts "Layout file not found: #{layout}"
27
+ exit 1
28
+ end
29
+ end
30
+
31
+ opts.on('-o OUTFILE', '--output OUTFILE', "Output to file (defaults to STDOUT)") do |path|
32
+ options[:outfile] = path
33
+ end
34
+
35
+ filters = RTeX.filters.keys.map { |k| k.to_s }.sort.join(', ')
36
+ opts.on('-f FILTER', '--filter FILTER', "Filter input (supported: #{filters})", "(Wraps in a basic `article' document; use --layout to customize)") do |filter|
37
+ options[:filter] = filter
38
+ end
39
+
40
+ opts.on('--no-pdf', "Don't generate PDF (just output TeX)") do
41
+ options[:tex] = true
42
+ end
43
+
44
+ opts.on('-i PATH', '--install PATH', "Install as plugin into Rails app at PATH") do |path|
45
+ unless Dir[plugins = File.join(path, 'vendor/plugins')].any?
46
+ STDERR.puts "Could not find application at #{path}"
47
+ exit 1
48
+ end
49
+ plugin_path = File.join(plugins, 'rtex')
50
+ FileUtils.cp_r(File.dirname(__FILE__) << '/..', plugin_path)
51
+ %w(Rakefile Manifest.txt bin tasks).each do |prune|
52
+ FileUtils.rm_rf(File.join(plugin_path, prune)) rescue nil
53
+ end
54
+ STDERR.puts "Installed at #{plugin_path}"
55
+ exit
56
+ end
57
+
58
+ end
59
+ opts.parse!(ARGV)
60
+
61
+ if options[:filter] && !options[:layout]
62
+ STDERR.puts "Warning: Using default `article' layout (see --help on '--layout')"
63
+ options[:layout] = RTeX.basic_layout
64
+ end
65
+
66
+ document = RTeX::Document.new(ARGF.read, options)
67
+ location = File.expand_path(options[:outfile]) rescue nil
68
+ document.to_pdf(nil) do |filename|
69
+ if location
70
+ FileUtils.move filename, location
71
+ else
72
+ STDOUT.print File.read(filename)
73
+ end
74
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'rtex'
2
+ RTeX.framework :rails
data/lib/rtex.rb ADDED
@@ -0,0 +1,33 @@
1
+ $:.unshift(File.dirname(__FILE__) << '/rtex')
2
+
3
+ require 'document'
4
+ require 'version'
5
+
6
+ module RTeX
7
+
8
+ def self.framework(name)
9
+ require File.dirname(__FILE__) << "/rtex/framework/#{name}"
10
+ framework = ::RTeX::Framework.const_get(name.to_s.capitalize)
11
+ framework.setup
12
+ end
13
+
14
+ def self.basic_layout #:nodoc:
15
+ "\\documentclass[12pt]{article}\n\\begin{document}\n<%= yield %>\n\\end{document}"
16
+ end
17
+
18
+ def self.filter(name, &block)
19
+ filters[name.to_s] = block
20
+ end
21
+
22
+ def self.filters #:nodoc:
23
+ @filters ||= {}
24
+ end
25
+
26
+ filter :textile do |source|
27
+ require File.dirname(__FILE__) << '/../vendor/instiki/redcloth_for_tex'
28
+ RedClothForTex.new(source).to_tex
29
+ end
30
+
31
+ end
32
+
33
+
@@ -0,0 +1,162 @@
1
+ require 'erb'
2
+ require 'ostruct'
3
+ require 'tmpdir'
4
+
5
+ require 'escaping'
6
+ require 'tempdir'
7
+
8
+
9
+ module RTeX
10
+
11
+ class Document
12
+
13
+ extend Escaping
14
+
15
+ class FilterError < ::StandardError; end
16
+ class GenerationError < ::StandardError; end
17
+ class ExecutableNotFoundError < ::StandardError; end
18
+
19
+ def self.options
20
+ @options ||= {
21
+ :preprocessor => 'latex',
22
+ :preprocess => false,
23
+ :processor => 'pdflatex',
24
+ # Option redirection for shell output (eg, set to '> /dev/null 2>&1' )
25
+ :shell_redirect => nil,
26
+ # Temporary Directory
27
+ :tempdir => Dir.tmpdir
28
+ }
29
+ end
30
+
31
+ def initialize(content, options={})
32
+ @options = self.class.options.merge(options)
33
+ if @options[:processed]
34
+ @source = content
35
+ else
36
+ @erb = ERB.new(content)
37
+ end
38
+ end
39
+
40
+ def source(binding=nil)
41
+ @source ||= wrap_in_layout do
42
+ filter @erb.result(binding)
43
+ end
44
+ end
45
+
46
+ def filter(text)
47
+ return text unless @options[:filter]
48
+ if (process = RTeX.filters[@options[:filter]])
49
+ process[text]
50
+ else
51
+ raise FilterError, "No `#{@options[:filter]}' filter"
52
+ end
53
+ end
54
+
55
+ def wrap_in_layout
56
+ if @options[:layout]
57
+ ERB.new(@options[:layout]).result(binding)
58
+ else
59
+ yield
60
+ end
61
+ end
62
+
63
+ def to_pdf(binding=nil, &file_handler)
64
+ process_pdf_from(source(binding), &file_handler)
65
+ end
66
+
67
+ def processor
68
+ @processor ||= check_path_for @options[:processor]
69
+ end
70
+
71
+ def preprocessor
72
+ @preprocessor ||= check_path_for @options[:preprocessor]
73
+ end
74
+
75
+ def system_path
76
+ ENV['PATH']
77
+ end
78
+
79
+ #######
80
+ private
81
+ #######
82
+
83
+ def check_path_for(command)
84
+ unless FileTest.executable?(command) || system_path.split(":").any?{ |path| FileTest.executable?(File.join(path, command))}
85
+ raise ExecutableNotFoundError, command
86
+ end
87
+ command
88
+ end
89
+
90
+ def process_pdf_from(input, &file_handler)
91
+ Tempdir.open(@options[:tempdir]) do |tempdir|
92
+ prepare input
93
+ if generating?
94
+ preprocess! if preprocessing?
95
+ process!
96
+ verify!
97
+ end
98
+ if file_handler
99
+ yield full_path_in(tempdir.path)
100
+ else
101
+ result_as_string
102
+ end
103
+ end
104
+ end
105
+
106
+ def process! #:nodoc:
107
+ unless `#{processor} --interaction=nonstopmode '#{source_file}' #{@options[:shell_redirect]}`
108
+ raise GenerationError, "Could not generate PDF using #{processor}"
109
+ end
110
+ end
111
+
112
+ def preprocess!
113
+ unless `#{preprocessor} --interaction=nonstopmode '#{source_file}' #{@options[:shell_redirect]}`
114
+ raise GenerationError, "Could not preprocess using #{preprocessor}"
115
+ end
116
+ end
117
+
118
+ def preprocessing?
119
+ @options[:preprocess]
120
+ end
121
+
122
+ def source_file
123
+ @source_file ||= file(:tex)
124
+ end
125
+
126
+ def log_file
127
+ @log_file ||= file(:log)
128
+ end
129
+
130
+ def result_file
131
+ @result_file ||= file(@options[:tex] ? :tex : :pdf)
132
+ end
133
+
134
+ def file(extension)
135
+ "document.#{extension}"
136
+ end
137
+
138
+ def generating?
139
+ !@options[:tex]
140
+ end
141
+
142
+ def verify!
143
+ unless File.exists?(result_file)
144
+ raise GenerationError, "Could not find result PDF #{result_file} after generation.\nCheck #{File.expand_path(log_file)}"
145
+ end
146
+ end
147
+
148
+ def prepare(input)
149
+ File.open(source_file, 'wb') { |f| f.puts input }
150
+ end
151
+
152
+ def result_as_string
153
+ File.open(result_file, 'rb') { |f| f.read }
154
+ end
155
+
156
+ def full_path_in(directory)
157
+ File.expand_path(File.join(directory, result_file))
158
+ end
159
+
160
+ end
161
+
162
+ end