Выполнение системной команды (pdflatex) в моем Rails Controller - PullRequest
1 голос
/ 07 марта 2012

Итак, у меня есть приложение Rails, которое после отправки пользователем должно сгенерировать какой-нибудь файл .tex на основе ввода пользователя, скомпилировать его в pdf и доставить pdf. Через процесс исключения я довольно уверен, что все работает за исключением одной линии; тот, где pdflatex называется.

Вот жизненно важный фрагмент кода: (Если это имеет значение, он находится в контроллере вопросов под действием генерирования, которое вызывается после того, как форма отправляет соответствующую информацию. Хотя это может быть не лучшим способом, я уверен, что это не причина ошибки)

texHeader = 'app\assets\tex\QuestionsFront.txt' 
texOut = 'app\assets\tex\Questions.tex'

#copy latex header to new file
FileUtils.cp(texHeader, texOut)

File.open(texOut, 'a+') do |fout|
      fout.write("\n")
         # a loop writes some more code to fout (its quite lengthy)
      fout.write("\\end{enumerate}\n")
      fout.write("\\end{document}")
      #The problem line:
      puts `pdflatex app/assets/tex/Questions.tex --output-directory=app/assets/tex`
    end

    filename = 'Questions.pdf'
    filelocation = "app\\assets\\tex\\" + filename

    File.open(filelocation, 'r') do |file|
      send_file file, :filename => filename, :type => "application/pdf", :disposition => "attachment"
    end
end

Вот мои рассуждения: он генерирует файл .tex правильно, и с учетом предварительно созданного файла Questions.pdf отправляет его просто отлично. Когда команда в путах копируется в терминал, она запускается без помех (файл начинается с \ nonstopmode, поэтому не стоит беспокоиться о небольших ошибках). Но по какой-то причине, когда я запускаю вышеуказанный скрипт, даже файл журнала не создается с ошибкой.

Что я пропускаю? Есть идеи? Любой способ увидеть, какой вывод создает строка пут?

Большое спасибо заранее!

Ответы [ 2 ]

1 голос
/ 08 марта 2012

Разобрался с собственной проблемой. Ошибка довольно интересная. Вы увидите, я звоню

 puts `pdflatex app/assets/tex/Questions.tex --output-directory=app/assets/tex`

внутри блока

File.open(texOut, 'a+') do |fout|

, где всего несколько строк до

texOut = 'app\assets\tex\Questions.tex'

По сути, я пытаюсь получить латекс для компиляции документа , пока файл еще открыт . Пока я нахожусь в блоке File.open, файл открыт, и его автоматически закрывается в конце блока. Вырезание и вставка строки кода ниже конца блока заставили его работать так, как я хотел. Однако, для ясности и в редком случае, когда у кого-то еще есть эта проблема, на самом деле лучше открыть отдельную системную оболочку, перейти в каталог, где находится латексный документ, и выполнить его компиляцию. Итак, мой обновленный код выглядит так:

  fout.write("\\end{document}")
end

system 'runlatex.bat'

где этот пакетный файл выглядит следующим образом:

cd app/assets/tex
pdflatex Questions.tex

Таким образом, будут найдены любые дополнительные файлы в каталоге tex, там будет создан файл журнала и т. Д.

Причина, по которой я так и не получил файл журнала? Pdflatex никогда не выполнялся - ОС остановила его с ошибкой прав доступа до того, как он запустился.

Надеюсь, это поможет!

0 голосов
/ 07 марта 2012

Backticks (и %x{}) предоставляют тот же контекст синтаксического анализа, что и строка в двойных кавычках.Это означает, что обычные escape-последовательности с обратной косой чертой интерпретируются внутри обратных галочек;в частности, \t является вкладкой, так что это:

puts `pdflatex app\assets\tex\Questions.tex --output-directory=app\assets\tex`

в конечном итоге с двумя вкладками, и это ломает все.Вы можете начать экранировать обратную косую черту (я думаю, что вам понадобится две или три обратных косых черты, чтобы перенести одну в оболочку) или переключиться на обычную косую черту (которую Windows обычно принимает в путях):

puts `pdflatex app/assets/tex/Questions.tex --output-directory=app/assets/tex`

В качестве альтернативы,Вы можете переключиться на open3, чтобы избежать проблем с экранированием и цитированием, а также получить лучшие возможности обработки ошибок.

...