Class: LatexToPdf

Inherits:
Object
  • Object
show all
Defined in:
lib/rails-latex/latex_to_pdf.rb

Class Method Summary collapse

Class Method Details

.configObject



3
4
5
# File 'lib/rails-latex/latex_to_pdf.rb', line 3

def self.config
  @config||={:command => 'pdflatex', :arguments => ['-halt-on-error'], :parse_twice => false, :parse_runs => 1}
end

.escape_latex(text) ⇒ Object

Escapes LaTex special characters in text so that they wont be interpreted as LaTex commands.

This method will use RedCloth to do the escaping if available.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rails-latex/latex_to_pdf.rb', line 61

def self.escape_latex(text)
  # :stopdoc:
  unless @latex_escaper
    if defined?(RedCloth::Formatters::LATEX)
      class << (@latex_escaper=RedCloth.new(''))
        include RedCloth::Formatters::LATEX
      end
    else
      class << (@latex_escaper=Object.new)
        ESCAPE_RE=/([{}_$&%#])|([\\^~|<>])/
        ESC_MAP={
          '\\' => 'backslash',
          '^' => 'asciicircum',
          '~' => 'asciitilde',
          '|' => 'bar',
          '<' => 'less',
          '>' => 'greater',
        }

        def latex_esc(text)   # :nodoc:
          text.gsub(ESCAPE_RE) {|m|
            if $1
              "\\#{m}"
            else
              "\\text#{ESC_MAP[m]}{}"
            end
          }
        end
      end
    end
    # :startdoc:
  end

  @latex_escaper.latex_esc(text.to_s).html_safe
end

.generate_pdf(code, config, parse_twice = nil) ⇒ Object

Converts a string of LaTeX code into a binary string of PDF.

pdflatex is used to convert the file and creates the directory #{Rails.root}/tmp/rails-latex/ to store intermediate files.

The config argument defaults to LatexToPdf.config but can be overridden using @latex_config.

The parse_twice argument and using config is deprecated in favor of using config instead.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rails-latex/latex_to_pdf.rb', line 15

def self.generate_pdf(code,config,parse_twice=nil)
  config=self.config.merge(config)
  parse_twice=config[:parse_twice] if parse_twice.nil? # deprecated
  parse_runs=[config[:parse_runs], (parse_twice ? 2 : config[:parse_runs])].max
  Rails.logger.info "Running Latex #{parse_runs} times..."
  dir=File.join(Rails.root,'tmp','rails-latex',"#{Process.pid}-#{Thread.current.hash}")
  input=File.join(dir,'input.tex')
  FileUtils.mkdir_p(dir)
  # copy any additional supporting files (.cls, .sty, ...)
  supporting = config[:supporting]
  if supporting.kind_of?(String) or supporting.kind_of?(Pathname) or (supporting.kind_of?(Array) and supporting.length > 0)
    FileUtils.cp_r(supporting, dir)
  end
  File.open(input,'wb') {|io| io.write(code) }
  Process.waitpid(
    fork do
      begin
        Dir.chdir dir
        args=config[:arguments] + %w[-shell-escape -interaction batchmode input.tex]
        kwargs={:out => ["input.log","a"]}
        (parse_runs-1).times do
          system config[:command],'-draftmode',*args,**kwargs
        end
        exec config[:command],*args,**kwargs
      rescue
        File.open("input.log",'a') {|io|
          io.write("#{$!.message}:\n#{$!.backtrace.join("\n")}\n")
        }
      ensure
        Process.exit! 1
      end
    end)
  if File.exist?(pdf_file=input.sub(/\.tex$/,'.pdf'))
    FileUtils.mv(input,File.join(dir,'..','input.tex'))
    FileUtils.mv(input.sub(/\.tex$/,'.log'),File.join(dir,'..','input.log'))
    result=File.read(pdf_file)
    FileUtils.rm_rf(dir)
  else
    raise "pdflatex failed: See #{input.sub(/\.tex$/,'.log')} for details"
  end
  result
end