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
@@ -0,0 +1,26 @@
|
|
1
|
+
module RTeX
|
2
|
+
|
3
|
+
module Escaping
|
4
|
+
|
5
|
+
def escape(text)
|
6
|
+
replacements.inject(text) do |corpus, (pattern, replacement)|
|
7
|
+
corpus.gsub(pattern, replacement)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def replacements
|
12
|
+
@replacements ||= [
|
13
|
+
[/([{}])/, '\\\1'],
|
14
|
+
[/\\/, '\textbackslash{}'],
|
15
|
+
[/\^/, '\textasciicircum{}'],
|
16
|
+
[/~/, '\textasciitilde{}'],
|
17
|
+
[/\|/, '\textbar{}'],
|
18
|
+
[/\</, '\textless{}'],
|
19
|
+
[/\>/, '\textgreater{}'],
|
20
|
+
[/([_$&%#])/, '\\\1']
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module RTeX
|
4
|
+
module Framework
|
5
|
+
module Rails
|
6
|
+
|
7
|
+
def self.setup
|
8
|
+
RTeX::Document.options[:tempdir] = File.expand_path(File.join(RAILS_ROOT, 'tmp'))
|
9
|
+
ActionView::Base.register_template_handler(:rtex, Template)
|
10
|
+
ActionController::Base.send(:include, ControllerMethods)
|
11
|
+
ActionView::Base.send(:include, HelperMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
class Template < ::ActionView::TemplateHandlers::ERB
|
15
|
+
def initialize(*args)
|
16
|
+
super
|
17
|
+
@view.template_format = :pdf
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module ControllerMethods
|
22
|
+
def self.included(base)
|
23
|
+
base.alias_method_chain :render, :rtex
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_with_rtex(options=nil, *args, &block)
|
27
|
+
result = render_without_rtex(options, *args, &block)
|
28
|
+
if result.is_a?(String) && @template.template_format == :pdf
|
29
|
+
options ||= {}
|
30
|
+
::RTeX::Document.new(result, options.merge(:processed => true)).to_pdf do |filename|
|
31
|
+
serve_file = Tempfile.new('rtex-pdf')
|
32
|
+
FileUtils.mv filename, serve_file.path
|
33
|
+
send_file serve_file.path,
|
34
|
+
:disposition => (options[:disposition] rescue nil) || 'inline',
|
35
|
+
:url_based_filename => true,
|
36
|
+
:filename => (options[:filename] rescue nil),
|
37
|
+
:type => "application/pdf",
|
38
|
+
:length => File.size(serve_file.path)
|
39
|
+
serve_file.close
|
40
|
+
end
|
41
|
+
else
|
42
|
+
result
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
module HelperMethods
|
48
|
+
def latex_escape(s)
|
49
|
+
RTeX::Document.escape(s)
|
50
|
+
end
|
51
|
+
alias :l :latex_escape
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/rtex/tempdir.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module RTeX
|
4
|
+
|
5
|
+
class Tempdir
|
6
|
+
|
7
|
+
def self.open(parent_path=RTeX::Document.options[:tempdir])
|
8
|
+
tempdir = new(parent_path)
|
9
|
+
FileUtils.mkdir_p tempdir.path
|
10
|
+
result = Dir.chdir(tempdir.path) do
|
11
|
+
yield tempdir
|
12
|
+
end
|
13
|
+
# We don't remove the temporary directory when exceptions occur,
|
14
|
+
# so that the source of the exception can be dubbed (logfile kept)
|
15
|
+
tempdir.remove!
|
16
|
+
result
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(parent_path, basename='rtex')
|
20
|
+
@parent_path = parent_path
|
21
|
+
@basename = basename
|
22
|
+
@removed = false
|
23
|
+
end
|
24
|
+
|
25
|
+
def path
|
26
|
+
@path ||= File.expand_path(File.join(@parent_path, 'rtex', "#{@basename}-#{uuid}"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove!
|
30
|
+
return false if @removed
|
31
|
+
FileUtils.rm_rf path
|
32
|
+
@removed = true
|
33
|
+
end
|
34
|
+
|
35
|
+
#######
|
36
|
+
private
|
37
|
+
#######
|
38
|
+
|
39
|
+
# Try using uuidgen, but if that doesn't work drop down to
|
40
|
+
# a poor-man's UUID; timestamp, thread & object hashes
|
41
|
+
# Note: I don't want to add any dependencies (so no UUID library)
|
42
|
+
def uuid
|
43
|
+
if (result = `uuidgen`.strip rescue nil).empty?
|
44
|
+
"#{Time.now.to_i}-#{Thread.current.hash}-#{hash}"
|
45
|
+
else
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/rtex/version.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# (The MIT License)
|
2
|
+
#
|
3
|
+
# Copyright (c) 2008 Jamis Buck <jamis@37signals.com>,
|
4
|
+
# with modifications by Bruce Williams <bruce@codefluency.com>
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
# a copy of this software and associated documentation files (the
|
8
|
+
# 'Software'), to deal in the Software without restriction, including
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
# the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be
|
15
|
+
# included in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
module RTeX
|
25
|
+
|
26
|
+
|
27
|
+
# A class for describing the current version of a library. The version
|
28
|
+
# consists of three parts: the +major+ number, the +minor+ number, and the
|
29
|
+
# +tiny+ (or +patch+) number.
|
30
|
+
class Version
|
31
|
+
|
32
|
+
# A convenience method for instantiating a new Version instance with the
|
33
|
+
# given +major+, +minor+, and +tiny+ components.
|
34
|
+
def self.[](major, minor, tiny)
|
35
|
+
new(major, minor, tiny)
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_reader :major, :minor, :tiny
|
39
|
+
|
40
|
+
# Create a new Version object with the given components.
|
41
|
+
def initialize(major, minor, tiny)
|
42
|
+
@major, @minor, @tiny = major, minor, tiny
|
43
|
+
end
|
44
|
+
|
45
|
+
# Compare this version to the given +version+ object.
|
46
|
+
def <=>(version)
|
47
|
+
to_i <=> version.to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
# Converts this version object to a string, where each of the three
|
51
|
+
# version components are joined by the '.' character. E.g., 2.0.0.
|
52
|
+
def to_s
|
53
|
+
@to_s ||= [@major, @minor, @tiny].join(".")
|
54
|
+
end
|
55
|
+
|
56
|
+
# Converts this version to a canonical integer that may be compared
|
57
|
+
# against other version objects.
|
58
|
+
def to_i
|
59
|
+
@to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_a
|
63
|
+
[@major, @minor, @tiny]
|
64
|
+
end
|
65
|
+
|
66
|
+
MAJOR = 1
|
67
|
+
MINOR = 99
|
68
|
+
TINY = 0
|
69
|
+
|
70
|
+
DESCRIPTION = '2.0 Preview 1'
|
71
|
+
|
72
|
+
# The current version as a Version instance
|
73
|
+
CURRENT = new(MAJOR, MINOR, TINY)
|
74
|
+
# The current version as a String
|
75
|
+
STRING = CURRENT.to_s
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
data/tasks/doc.rake
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# $Id$
|
2
|
+
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
namespace :doc do
|
6
|
+
|
7
|
+
desc 'Generate RDoc documentation'
|
8
|
+
Rake::RDocTask.new do |rd|
|
9
|
+
rd.main = PROJ.rdoc_main
|
10
|
+
rd.rdoc_dir = PROJ.rdoc_dir
|
11
|
+
|
12
|
+
incl = Regexp.new(PROJ.rdoc_include.join('|'))
|
13
|
+
excl = Regexp.new(PROJ.rdoc_exclude.join('|'))
|
14
|
+
files = PROJ.files.find_all do |fn|
|
15
|
+
case fn
|
16
|
+
when excl; false
|
17
|
+
when incl; true
|
18
|
+
else false end
|
19
|
+
end
|
20
|
+
rd.rdoc_files.push(*files)
|
21
|
+
|
22
|
+
title = "#{PROJ.name}-#{PROJ.version} Documentation"
|
23
|
+
title = "#{PROJ.rubyforge_name}'s " + title if PROJ.rubyforge_name != title
|
24
|
+
|
25
|
+
rd.options << "-t #{title}"
|
26
|
+
rd.options.concat(PROJ.rdoc_opts)
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Generate ri locally for testing'
|
30
|
+
task :ri => :clobber_ri do
|
31
|
+
sh "#{RDOC} --ri -o ri ."
|
32
|
+
end
|
33
|
+
|
34
|
+
task :clobber_ri do
|
35
|
+
rm_r 'ri' rescue nil
|
36
|
+
end
|
37
|
+
|
38
|
+
end # namespace :doc
|
39
|
+
|
40
|
+
desc 'Alias to doc:rdoc'
|
41
|
+
task :doc => 'doc:rdoc'
|
42
|
+
|
43
|
+
desc 'Remove all build products'
|
44
|
+
task :clobber => %w(doc:clobber_rdoc doc:clobber_ri)
|
45
|
+
|
46
|
+
remove_desc_for_task %w(doc:clobber_rdoc)
|
47
|
+
|
48
|
+
# EOF
|
data/tasks/gem.rake
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# $Id$
|
2
|
+
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
|
5
|
+
namespace :gem do
|
6
|
+
|
7
|
+
PROJ.spec = Gem::Specification.new do |s|
|
8
|
+
s.name = PROJ.name
|
9
|
+
s.version = PROJ.version
|
10
|
+
s.summary = PROJ.summary
|
11
|
+
s.authors = Array(PROJ.authors)
|
12
|
+
s.email = PROJ.email
|
13
|
+
s.homepage = Array(PROJ.url).first
|
14
|
+
s.rubyforge_project = PROJ.rubyforge_name
|
15
|
+
s.post_install_message = PROJ.post_install_message
|
16
|
+
|
17
|
+
s.description = PROJ.description
|
18
|
+
|
19
|
+
PROJ.dependencies.each do |dep|
|
20
|
+
s.add_dependency(*dep)
|
21
|
+
end
|
22
|
+
|
23
|
+
s.files = PROJ.files
|
24
|
+
s.executables = PROJ.executables.map {|fn| File.basename(fn)}
|
25
|
+
s.extensions = PROJ.files.grep %r/extconf\.rb$/
|
26
|
+
|
27
|
+
s.bindir = 'bin'
|
28
|
+
dirs = Dir["{#{PROJ.libs.join(',')}}"]
|
29
|
+
s.require_paths = dirs unless dirs.empty?
|
30
|
+
|
31
|
+
incl = Regexp.new(PROJ.rdoc_include.join('|'))
|
32
|
+
excl = PROJ.rdoc_exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
|
33
|
+
excl = Regexp.new(excl.join('|'))
|
34
|
+
rdoc_files = PROJ.files.find_all do |fn|
|
35
|
+
case fn
|
36
|
+
when excl; false
|
37
|
+
when incl; true
|
38
|
+
else false end
|
39
|
+
end
|
40
|
+
s.rdoc_options = PROJ.rdoc_opts + ['--main', PROJ.rdoc_main]
|
41
|
+
s.extra_rdoc_files = rdoc_files
|
42
|
+
s.has_rdoc = true
|
43
|
+
|
44
|
+
if test ?f, PROJ.test_file
|
45
|
+
s.test_file = PROJ.test_file
|
46
|
+
else
|
47
|
+
s.test_files = PROJ.tests.to_a
|
48
|
+
end
|
49
|
+
|
50
|
+
# Do any extra stuff the user wants
|
51
|
+
# spec_extras.each do |msg, val|
|
52
|
+
# case val
|
53
|
+
# when Proc
|
54
|
+
# val.call(s.send(msg))
|
55
|
+
# else
|
56
|
+
# s.send "#{msg}=", val
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
end
|
60
|
+
|
61
|
+
desc 'Show information about the gem'
|
62
|
+
task :debug do
|
63
|
+
puts PROJ.spec.to_ruby
|
64
|
+
end
|
65
|
+
|
66
|
+
pkg = Rake::PackageTask.new(PROJ.name, PROJ.version) do |pkg|
|
67
|
+
pkg.need_tar = PROJ.need_tar
|
68
|
+
pkg.need_zip = PROJ.need_zip
|
69
|
+
pkg.package_files += PROJ.spec.files
|
70
|
+
end
|
71
|
+
Rake::Task['gem:package'].instance_variable_set(:@full_comment, nil)
|
72
|
+
|
73
|
+
gem_file = if PROJ.spec.platform == Gem::Platform::RUBY
|
74
|
+
"#{pkg.package_name}.gem"
|
75
|
+
else
|
76
|
+
"#{pkg.package_name}-#{PROJ.spec.platform}.gem"
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Build the gem file #{gem_file}"
|
80
|
+
task :package => "#{pkg.package_dir}/#{gem_file}"
|
81
|
+
|
82
|
+
file "#{pkg.package_dir}/#{gem_file}" => [pkg.package_dir] + PROJ.spec.files do
|
83
|
+
when_writing("Creating GEM") {
|
84
|
+
Gem::Builder.new(PROJ.spec).build
|
85
|
+
verbose(true) {
|
86
|
+
mv gem_file, "#{pkg.package_dir}/#{gem_file}"
|
87
|
+
}
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
desc 'Install the gem'
|
92
|
+
task :install => [:clobber, :package] do
|
93
|
+
sh "#{SUDO} #{GEM} install pkg/#{PROJ.spec.full_name}"
|
94
|
+
end
|
95
|
+
|
96
|
+
desc 'Uninstall the gem'
|
97
|
+
task :uninstall do
|
98
|
+
sh "#{SUDO} #{GEM} uninstall -v '#{PROJ.version}' -x #{PROJ.name}"
|
99
|
+
end
|
100
|
+
|
101
|
+
end # namespace :gem
|
102
|
+
|
103
|
+
desc 'Alias to gem:package'
|
104
|
+
task :gem => 'gem:package'
|
105
|
+
|
106
|
+
task :clobber => 'gem:clobber_package'
|
107
|
+
|
108
|
+
remove_desc_for_task %w(gem:clobber_package)
|
109
|
+
|
110
|
+
# EOF
|
data/tasks/manifest.rake
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# $Id$
|
2
|
+
|
3
|
+
require 'find'
|
4
|
+
|
5
|
+
namespace :manifest do
|
6
|
+
|
7
|
+
desc 'Verify the manifest'
|
8
|
+
task :check do
|
9
|
+
fn = PROJ.manifest_file + '.tmp'
|
10
|
+
files = manifest_files
|
11
|
+
|
12
|
+
File.open(fn, 'w') {|fp| fp.puts files}
|
13
|
+
lines = %x(#{DIFF} -du #{PROJ.manifest_file} #{fn}).split("\n")
|
14
|
+
if HAVE_FACETS_ANSICODE and ENV.has_key?('TERM')
|
15
|
+
lines.map! do |line|
|
16
|
+
case line
|
17
|
+
when %r/^(-{3}|\+{3})/; nil
|
18
|
+
when %r/^@/; Console::ANSICode.blue line
|
19
|
+
when %r/^\+/; Console::ANSICode.green line
|
20
|
+
when %r/^\-/; Console::ANSICode.red line
|
21
|
+
else line end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
puts lines.compact
|
25
|
+
rm fn rescue nil
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Create a new manifest'
|
29
|
+
task :create do
|
30
|
+
files = manifest_files
|
31
|
+
unless test(?f, PROJ.manifest_file)
|
32
|
+
files << PROJ.manifest_file
|
33
|
+
files.sort!
|
34
|
+
end
|
35
|
+
File.open(PROJ.manifest_file, 'w') {|fp| fp.puts files}
|
36
|
+
end
|
37
|
+
|
38
|
+
task :assert do
|
39
|
+
files = manifest_files
|
40
|
+
manifest = File.read(PROJ.manifest_file).split($/)
|
41
|
+
raise "ERROR: #{PROJ.manifest_file} is out of date" unless files == manifest
|
42
|
+
end
|
43
|
+
|
44
|
+
end # namespace :manifest
|
45
|
+
|
46
|
+
desc 'Alias to manifest:check'
|
47
|
+
task :manifest => 'manifest:check'
|
48
|
+
|
49
|
+
# EOF
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# $Id$
|
2
|
+
|
3
|
+
# This file does not define any rake tasks. It is used to load some project
|
4
|
+
# settings if they are not defined by the user.
|
5
|
+
|
6
|
+
PROJ.rdoc_exclude << "^#{Regexp.escape(PROJ.manifest_file)}$"
|
7
|
+
PROJ.exclude << "^#{Regexp.escape(PROJ.ann_file)}$"
|
8
|
+
|
9
|
+
PROJ.changes ||= paragraphs_of(PROJ.history_file, 0..1).join("\n\n")
|
10
|
+
|
11
|
+
PROJ.description ||= paragraphs_of(PROJ.readme_file, 'description').join("\n\n")
|
12
|
+
|
13
|
+
PROJ.summary ||= PROJ.description.split('.').first
|
14
|
+
|
15
|
+
PROJ.files ||=
|
16
|
+
if test(?f, PROJ.manifest_file)
|
17
|
+
files = File.readlines(PROJ.manifest_file).map {|fn| fn.chomp.strip}
|
18
|
+
files.delete ''
|
19
|
+
files
|
20
|
+
else [] end
|
21
|
+
|
22
|
+
PROJ.executables ||= PROJ.files.find_all {|fn| fn =~ %r/^bin/}
|
23
|
+
|
24
|
+
PROJ.rdoc_main ||= PROJ.readme_file
|
25
|
+
|
26
|
+
# EOF
|