artex 2.1.1

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.
@@ -0,0 +1,3 @@
1
+ v2.1.0
2
+
3
+ Forked from RTeX 2.1.0.
@@ -0,0 +1,25 @@
1
+ CHANGELOG
2
+ Manifest
3
+ README.rdoc
4
+ Rakefile
5
+ artex.gemspec
6
+ init.rb
7
+ lib/artex.rb
8
+ lib/artex/document.rb
9
+ lib/artex/escaping.rb
10
+ lib/artex/framework/merb.rb
11
+ lib/artex/framework/rails.rb
12
+ lib/artex/pdf.rb
13
+ lib/artex/tempdir.rb
14
+ lib/artex/version.rb
15
+ rails/init.rb
16
+ test/document_test.rb
17
+ test/filter_test.rb
18
+ test/fixtures/first.tex
19
+ test/fixtures/first.tex.erb
20
+ test/fixtures/fragment.tex.erb
21
+ test/fixtures/text.textile
22
+ test/tempdir_test.rb
23
+ test/test_helper.rb
24
+ vendor/instiki/LICENSE
25
+ vendor/instiki/redcloth_for_tex.rb
@@ -0,0 +1,46 @@
1
+ = ArTeX: TeX/PDF Generation for Ruby
2
+
3
+ Project homepage (FAQ, manual, documentation, contact info): http://github.com/avarteq/artex
4
+
5
+ Source repository at: http://github.com/avarteq/artex
6
+
7
+ == Dependencies
8
+
9
+ * pdflatex executable, available in modern teTeX distributions
10
+ * Requires Ruby
11
+
12
+ == Motivation
13
+ This gem has been forked from the rtex gem (http://github.com/bruce/rtex).
14
+ RTeX can be used either as stand alone executable or as a rails plugin.
15
+ Using it as rails plugin means to create PDF files using the rails rendering engine.
16
+ This will bring you in trouble if you don't want to generate your PDF files within controllers.
17
+ In contrast to that ArTeX has no dependencies on ActionPack and thus can also be used in models.
18
+
19
+ We'll keep on updating the gem and we'll try to provide some examples in the future.
20
+ Besides of that the code will be iteratively cut down, rewritten and enhanced.
21
+
22
+
23
+ == License
24
+
25
+ (The MIT License)
26
+
27
+ Copyright (c) 2006-2010 Bruce Williams, Wiebe Cazemier, Julian Fischer
28
+
29
+ Permission is hereby granted, free of charge, to any person obtaining
30
+ a copy of this software and associated documentation files (the
31
+ 'Software'), to deal in the Software without restriction, including
32
+ without limitation the rights to use, copy, modify, merge, publish,
33
+ distribute, sublicense, and/or sell copies of the Software, and to
34
+ permit persons to whom the Software is furnished to do so, subject to
35
+ the following conditions:
36
+
37
+ The above copyright notice and this permission notice shall be
38
+ included in all copies or substantial portions of the Software.
39
+
40
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
41
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
42
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
43
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
44
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
45
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
46
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'echoe'
3
+
4
+ require File.dirname(__FILE__) << "/lib/artex/version"
5
+
6
+ Echoe.new 'artex' do |p|
7
+ p.version = ArTeX::Version::STRING
8
+ p.author = ['Bruce Williams', 'Wiebe Cazemier', 'Julian Fischer']
9
+ p.email = 'artex@avarteq.de'
10
+ p.project = 'artex'
11
+ p.summary = "LaTeX preprocessor for PDF generation; Rails plugin"
12
+ p.url = "http://github.com/avarteq/artex"
13
+ p.include_rakefile = true
14
+ p.development_dependencies = %w(Shoulda echoe)
15
+ p.rcov_options = '--exclude gems --exclude version.rb --sort coverage --text-summary --html -o coverage'
16
+ p.ignore_pattern = /^(pkg|doc|site)|\.svn|CVS|\.bzr|\.DS|\.git/
17
+ p.rubygems_version = nil
18
+ end
19
+
20
+ task :coverage do
21
+ system "open coverage/index.html" if PLATFORM['darwin']
22
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{artex}
5
+ s.version = "2.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Bruce Williams, Wiebe Cazemier, Julian Fischer"]
9
+ s.date = %q{2010-04-19}
10
+ s.description = %q{LaTeX preprocessor for PDF generation; Rails plugin}
11
+ s.email = %q{artex@avarteq.de}
12
+ s.extra_rdoc_files = ["CHANGELOG", "README.rdoc", "lib/artex.rb", "lib/artex/document.rb", "lib/artex/escaping.rb", "lib/artex/framework/merb.rb", "lib/artex/framework/rails.rb", "lib/artex/pdf.rb", "lib/artex/tempdir.rb", "lib/artex/version.rb"]
13
+ s.files = ["CHANGELOG", "Manifest", "README.rdoc", "Rakefile", "artex.gemspec", "init.rb", "lib/artex.rb", "lib/artex/document.rb", "lib/artex/escaping.rb", "lib/artex/framework/merb.rb", "lib/artex/framework/rails.rb", "lib/artex/pdf.rb", "lib/artex/tempdir.rb", "lib/artex/version.rb", "rails/init.rb", "test/document_test.rb", "test/filter_test.rb", "test/fixtures/first.tex", "test/fixtures/first.tex.erb", "test/fixtures/fragment.tex.erb", "test/fixtures/text.textile", "test/tempdir_test.rb", "test/test_helper.rb", "vendor/instiki/LICENSE", "vendor/instiki/redcloth_for_tex.rb"]
14
+ s.homepage = %q{http://github.com/avarteq/artex}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Artex", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{artex}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{LaTeX preprocessor for PDF generation; Rails plugin}
20
+ s.test_files = ["test/document_test.rb", "test/filter_test.rb", "test/tempdir_test.rb", "test/test_helper.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<Shoulda>, [">= 0"])
28
+ s.add_development_dependency(%q<echoe>, [">= 0"])
29
+ else
30
+ s.add_dependency(%q<Shoulda>, [">= 0"])
31
+ s.add_dependency(%q<echoe>, [">= 0"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<Shoulda>, [">= 0"])
35
+ s.add_dependency(%q<echoe>, [">= 0"])
36
+ end
37
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) << "/rails/init"
@@ -0,0 +1,31 @@
1
+ $:.unshift(File.dirname(__FILE__) << '/artex')
2
+
3
+ require 'document'
4
+ require 'version'
5
+ require 'pdf'
6
+
7
+ module ArTeX
8
+
9
+ def self.filters #:nodoc:
10
+ @filters ||= {}
11
+ end
12
+
13
+ def self.basic_layout #:nodoc:
14
+ "\\documentclass[12pt]{article}\n\\begin{document}\n<%= yield %>\n\\end{document}"
15
+ end
16
+
17
+ # Define a processing filter
18
+ # call-seq:
19
+ # filter(:name) { |text_to_transform| ... } # => result
20
+ def self.filter(name, &block)
21
+ filters[name.to_s] = block
22
+ end
23
+
24
+ filter :textile do |source|
25
+ require File.dirname(__FILE__) << '/../vendor/instiki/redcloth_for_tex'
26
+ RedClothForTex.new(source).to_tex
27
+ end
28
+
29
+ end
30
+
31
+
@@ -0,0 +1,175 @@
1
+ require 'erb'
2
+ require 'ostruct'
3
+ require 'tmpdir'
4
+
5
+ require 'escaping'
6
+ require 'tempdir'
7
+
8
+ module ArTeX
9
+
10
+ class Document
11
+
12
+ extend Escaping
13
+
14
+ class FilterError < ::StandardError; end
15
+ class GenerationError < ::StandardError; end
16
+ class ExecutableNotFoundError < ::StandardError; end
17
+
18
+ # Default options
19
+ # [+:preprocess+] Are we preprocessing? Default is +false+
20
+ # [+:preprocessor+] Executable to use during preprocessing (generating TOCs, etc). Default is +latex+
21
+ # [+:shell_redirect+] Option redirection for shell output (eg, +"> /dev/null 2>&1"+ ). Default is +nil+.
22
+ # [+:tmpdir+] Location of temporary directory (default: +Dir.tmpdir+)
23
+ def self.options
24
+ @options ||= {
25
+ :preprocessor => 'latex',
26
+ :preprocess => false,
27
+ :processor => 'pdflatex',
28
+ #
29
+ :shell_redirect => nil,
30
+ # Temporary Directory
31
+ :tempdir => Dir.tmpdir
32
+ }
33
+ end
34
+
35
+ def initialize(content, options={})
36
+ @options = self.class.options.merge(options)
37
+ if @options[:processed]
38
+ @source = content
39
+ else
40
+ @erb = ERB.new(content)
41
+ end
42
+ end
43
+
44
+ # Get the source for the entire
45
+ def source(binding=nil) #:nodoc:
46
+ @source ||= wrap_in_layout do
47
+ filter @erb.result(binding)
48
+ end
49
+ end
50
+
51
+ # Process through defined filter
52
+ def filter(text) #:nodoc:
53
+ return text unless @options[:filter]
54
+ if (process = ArTeX.filters[@options[:filter]])
55
+ process[text]
56
+ else
57
+ raise FilterError, "No `#{@options[:filter]}' filter"
58
+ end
59
+ end
60
+
61
+ # Wrap content in optional layout
62
+ def wrap_in_layout #:nodoc:
63
+ if @options[:layout]
64
+ ERB.new(@options[:layout]).result(binding)
65
+ else
66
+ yield
67
+ end
68
+ end
69
+
70
+ # Generate PDF from
71
+ # call-seq:
72
+ # to_pdf # => PDF in a String
73
+ # to_pdf { |filename| ... }
74
+ def to_pdf(binding=nil, &file_handler)
75
+ process_pdf_from(source(binding), &file_handler)
76
+ end
77
+
78
+ def processor #:nodoc:
79
+ @processor ||= check_path_for @options[:processor]
80
+ end
81
+
82
+ def preprocessor #:nodoc:
83
+ @preprocessor ||= check_path_for @options[:preprocessor]
84
+ end
85
+
86
+ def system_path #:nodoc:
87
+ ENV['PATH']
88
+ end
89
+
90
+ #######
91
+ private
92
+ #######
93
+
94
+ # Verify existence of executable in search path
95
+ def check_path_for(command)
96
+ unless FileTest.executable?(command) || system_path.split(":").any?{ |path| FileTest.executable?(File.join(path, command))}
97
+ raise ExecutableNotFoundError, command
98
+ end
99
+ command
100
+ end
101
+
102
+ # Basic processing
103
+ def process_pdf_from(input, &file_handler)
104
+ Tempdir.open(@options[:tempdir]) do |tempdir|
105
+ prepare input
106
+ if generating?
107
+ preprocess! if preprocessing?
108
+ process!
109
+ verify!
110
+ end
111
+ if file_handler
112
+ yield full_path_in(tempdir.path)
113
+ else
114
+ result_as_string
115
+ end
116
+ end
117
+ end
118
+
119
+ def process!
120
+ unless `#{processor} --interaction=nonstopmode '#{source_file}' #{@options[:shell_redirect]}`
121
+ raise GenerationError, "Could not generate PDF using #{processor}"
122
+ end
123
+ end
124
+
125
+ def preprocess!
126
+ unless `#{preprocessor} --interaction=nonstopmode '#{source_file}' #{@options[:shell_redirect]}`
127
+ raise GenerationError, "Could not preprocess using #{preprocessor}"
128
+ end
129
+ end
130
+
131
+ def preprocessing?
132
+ @options[:preprocess]
133
+ end
134
+
135
+ def source_file
136
+ @source_file ||= file(:tex)
137
+ end
138
+
139
+ def log_file
140
+ @log_file ||= file(:log)
141
+ end
142
+
143
+ def result_file
144
+ @result_file ||= file(@options[:tex] ? :tex : :pdf)
145
+ end
146
+
147
+ def file(extension)
148
+ "document.#{extension}"
149
+ end
150
+
151
+ def generating?
152
+ !@options[:tex]
153
+ end
154
+
155
+ def verify!
156
+ unless File.exists?(result_file)
157
+ raise GenerationError, "Could not find result PDF #{result_file} after generation.\nCheck #{File.expand_path(log_file)}"
158
+ end
159
+ end
160
+
161
+ def prepare(input)
162
+ File.open(source_file, 'wb') { |f| f.puts input }
163
+ end
164
+
165
+ def result_as_string
166
+ File.open(result_file, 'rb') { |f| f.read }
167
+ end
168
+
169
+ def full_path_in(directory)
170
+ File.expand_path(File.join(directory, result_file))
171
+ end
172
+
173
+ end
174
+
175
+ end
@@ -0,0 +1,28 @@
1
+ module ArTeX
2
+
3
+ module Escaping
4
+
5
+ # Escape text using +replacements+
6
+ def escape(text)
7
+ replacements.inject(text.to_s) do |corpus, (pattern, replacement)|
8
+ corpus.gsub(pattern, replacement)
9
+ end
10
+ end
11
+
12
+ # List of replacements
13
+ def replacements
14
+ @replacements ||= [
15
+ [/([{}])/, '\\\\\1'],
16
+ [/\\/, '\textbackslash{}'],
17
+ [/\^/, '\textasciicircum{}'],
18
+ [/~/, '\textasciitilde{}'],
19
+ [/\|/, '\textbar{}'],
20
+ [/\</, '\textless{}'],
21
+ [/\>/, '\textgreater{}'],
22
+ [/([_$&%#])/, '\\\\\1']
23
+ ]
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,13 @@
1
+ module ArTeX
2
+
3
+ module Framework #:nodoc:
4
+
5
+ module Merb #:nodoc:
6
+
7
+ # TODO
8
+
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,28 @@
1
+ require 'tempfile'
2
+
3
+ module ArTeX
4
+ module Framework #:nodoc:
5
+ module Rails #:nodoc:
6
+
7
+ def self.setup
8
+ ArTeX::Document.options[:tempdir] = File.expand_path(File.join(RAILS_ROOT, 'tmp'))
9
+ end
10
+
11
+ module HelperMethods
12
+ # Similar to h()
13
+ def latex_escape(*args)
14
+ # Since Rails' I18n implementation aliases l() to localize(), LaTeX
15
+ # escaping should only be done if ArTeX is doing the rendering.
16
+ # Otherwise, control should be be passed to localize().
17
+ if Thread.current[:_rendering_rtex]
18
+ ArTeX::Document.escape(*args)
19
+ else
20
+ localize(*args)
21
+ end
22
+ end
23
+ alias :l :latex_escape
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,81 @@
1
+ #TODO Translate comments.
2
+ module ArTeX
3
+ class PDF
4
+
5
+ # Wir bilden das Verhalten von render :partial nach.
6
+ # So wird die Abhängigkeit zu ActionView aufgelöst.
7
+ # Dabei gehen sicherlich Möglichkeiten verloren, die hier aber auch nicht benötigt werden.
8
+ # Ziel ist die Verlagerung der PDF-Generierung aus dem Controller in Klassen bzw. Models,
9
+ # so dass dies auch im Hintergrund erfolgen kann.
10
+ #
11
+ # === Beispiele
12
+ # render :partial => "layouts/brandings/#{@bill.branding.template_name}"
13
+ # render :partial => 'bills/form/billing_position/_billing_position.pdf.rtex', :collection => @bill.billing_positions
14
+ def render(options = {})
15
+ content = ""
16
+
17
+ # Relativer Pfad zum Template
18
+ # z.B. 'bills/form/billing_position/_billing_position.pdf.rtex'
19
+ template_name = get_template_name_from_partial_name(options[:partial])
20
+
21
+ if is_collection?(options) then
22
+ content = render_collection(options[:collection], binding, template_name)
23
+ else
24
+ content = render_to_latex(binding, template_name)
25
+ end
26
+ return content
27
+ end
28
+
29
+ def is_collection?(options)
30
+ options[:collection] && options[:collection].is_a?(Array)
31
+ end
32
+
33
+ def render_collection(collection, binding, template_name)
34
+ content = ""
35
+
36
+ #TODO refactor
37
+ collection.each do |billing_position|
38
+ @billing_position = billing_position
39
+ latex = render_to_latex(binding, template_name)
40
+ content += latex
41
+ end
42
+ return content
43
+ end
44
+
45
+ # 'bills/form/billing_position/_billing_position.pdf.rtex' -> 'bills/form/billing_position/_billing_position.pdf.rtex'
46
+ def get_template_name_from_partial_name(partial_name)
47
+ parts = partial_name.split(/\//)
48
+
49
+ # "_" vor das letzte Element setzen.
50
+ parts[-1] = "_" + parts.last
51
+ template_name = parts.join("/")
52
+ template_name
53
+ end
54
+
55
+ def render_to_latex(binding, path)
56
+ template_path = get_template_path(path)
57
+ template = File.read(template_path)
58
+
59
+ latex_code = ERB.new(template).result(binding)
60
+ return latex_code
61
+ end
62
+
63
+ # Nimmt Latex und schreibt ein PDF. Gibt den Pfad zum PDF zurück.
64
+ def latex_to_pdf(latex_content)
65
+ pdf_file = ""
66
+ ::ArTeX::Document.new(latex_content, {:process => true} ).to_pdf do |filename|
67
+ pdf_file = Tempfile.new('artex-pdf')
68
+ FileUtils.mv filename, pdf_file.path
69
+ end
70
+ return pdf_file.path
71
+ end
72
+
73
+ def get_template_path(path)
74
+ raise "unimplemented"
75
+ end
76
+
77
+ def l(*args)
78
+ return ArTeX::Document.escape(*args)
79
+ end
80
+ end
81
+ end