rtex 1.99.0
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.rdoc +29 -0
- data/Manifest.txt +33 -0
- data/README.rdoc +47 -0
- data/README_RAILS.rdoc +45 -0
- data/Rakefile +20 -0
- data/bin/rtex +74 -0
- data/init.rb +2 -0
- data/lib/rtex.rb +33 -0
- data/lib/rtex/document.rb +162 -0
- data/lib/rtex/escaping.rb +26 -0
- data/lib/rtex/framework/merb.rb +13 -0
- data/lib/rtex/framework/rails.rb +56 -0
- data/lib/rtex/tempdir.rb +52 -0
- data/lib/rtex/version.rb +79 -0
- data/tasks/doc.rake +48 -0
- data/tasks/gem.rake +110 -0
- data/tasks/manifest.rake +49 -0
- data/tasks/post_load.rake +26 -0
- data/tasks/setup.rb +205 -0
- data/tasks/test.rake +38 -0
- data/test/document_test.rb +70 -0
- data/test/filter_test.rb +20 -0
- data/test/fixtures/first.tex +50 -0
- data/test/fixtures/first.tex.erb +48 -0
- data/test/fixtures/fragment.tex.erb +1 -0
- data/test/fixtures/text.textile +4 -0
- data/test/tempdir_test.rb +63 -0
- data/test/test_helper.rb +23 -0
- data/test/tmp/rtex-071EE944-B2FA-4A3B-9764-1B5143833EB7/document.tex +48 -0
- data/test/tmp/rtex-592F93A7-6198-4B00-B638-33855344A29B/document.tex +48 -0
- data/test/tmp/rtex-96736595-5175-4602-9DC1-ABA096CC0E3D/document.tex +48 -0
- data/vendor/instiki/LICENSE +3 -0
- data/vendor/instiki/redcloth_for_tex.rb +736 -0
- metadata +90 -0
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
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
|