R, Sweave, LaTeX - экранирующие переменные, которые будут напечатаны в LaTeX? - PullRequest
12 голосов
/ 23 марта 2011

Я искал последние 2 дня, и хотя я нашел похожие вопросы о переполнении стека и других обсуждениях в Google, я не нашел ничего, соответствующего моему запросу.

У меня есть уже существующее приложение, которое я поддерживаю, которое построено на основе R. Шаблонные файлы Sweave Rnw используются для генерации файлов .tex, которые используются для генерации файлов .pdf.

В Rnw существует такой код:

\begin{tabular}{lll}
& {\bf \textcolor{TitlesColor}{Report name:}} & \Sexpr{print(myReport$report_name)}\\
& {\bf \textcolor{TitlesColor}{Report date:}} & \today \\
& {\bf \textcolor{TitlesColor}{Course name:}} & \Sexpr{print(myReport$courseInfo$shortname)}\\
& {\bf \textcolor{TitlesColor}{Start date:}}  & \Sexpr{print(myReport$courseInfo$startdate_readable)}\\
& {\bf \textcolor{TitlesColor}{Instructor:}} & \Sexpr{print(paste(myReport$instructor$lastname, collapse="| "))}\\
\end{tabular}

Проблема в том, что у myReport $ courseInfo $ shortname есть значения, которые необходимо экранировать для LaTeX, поскольку он включает такие символы, как & (что вынуждает LaTeX выдавать ошибку о столбцах таблицы). Я попытался включить библиотеку seqinr и использовать stresc для всего объекта данных, но все же сгенерированный файл .tex показывает неперерезанный & короткий имя.

Я пока не совсем знаком с R, но, поиграв с шаблоном, я обнаружил, что вызовы "print ()" выше даже не нужны, просто указание переменных непосредственно в результатах \ Sexpr в печатных значениях, но все же мои экранированные значения не экранируются при записи в .tex.

Я также пытался поместить stresc непосредственно в \ Sexpr (вместо print), без разницы.

Так что, похоже, что собственный процесс R / Sweave удаляет косые черты, что означает, что мне, вероятно, нужно двойные косые черты, но я недостаточно знаком с R, чтобы знать, как это сделать.

Как правильно печатать динамические данные в файл .tex?


UPDATE : Основываясь на ответе @ Аарона, вот функция, которую я создал:

# Sanitizes variables for displaying within LaTeX via Sexpr
# Adds slashes to LaTeX special characters, which results in single-slash in tex output
sanitizeLatexS <- function(str) {
    gsub('([#$%&~_\\^\\\\{}])', '\\\\\\\\\\1', str, perl = TRUE);
}

Мой обновленный шаблон (как указано в моем исходном сообщении выше) теперь выглядит так:

\begin{tabular}{lll}
& {\bf \textcolor{TitlesColor}{Report name:}} & \Sexpr{sanitizeLatexS(myReport$report_name)}\\
& {\bf \textcolor{TitlesColor}{Report date:}} & \today \\
& {\bf \textcolor{TitlesColor}{Course name:}} & \Sexpr{sanitizeLatexS(myReport$courseInfo$shortname)}\\
& {\bf \textcolor{TitlesColor}{Start date:}}  & \Sexpr{sanitizeLatexS(myReport$courseInfo$startdate_readable)}\\
& {\bf \textcolor{TitlesColor}{Instructor(s):}} & \Sexpr{sanitizeLatexS(paste(myReport$instructorList$lastname, collapse="| "))}\\
\end{tabular}

Таким образом, строка с символом & теперь правильно отображается в сгенерированном файле LaTeX как:

Некоторая строка \ & Некоторая другая строка

Ответы [ 4 ]

8 голосов
/ 23 марта 2011

Вы можете использовать \verb или вставить четырехслойную обратную косую черту, которая необходима для получения единицы в конечном текстовом файле, потому что она проходит две операции печати, которые преобразуют двойной «\» в один «\».

\documentclass{article}
\begin{document}
<<echo=FALSE, results=hide>>=
sanitize <- function(str) {
  result <- str
  result <- gsub("&", "\\\\&", result, fixed = TRUE)
  result <- gsub("_", "\\\\_", result, fixed = TRUE)
  result
}
@ 

<<>>=
(foo <- "test & _")
sanitize(foo)
@ 

My string is ``\verb+\Sexpr{foo}+''.  When sanitized, it's ``\Sexpr{sanitize(foo)}''.

\end{document}
7 голосов
/ 23 марта 2011

Пакет Hmisc имеет функцию latexTranslate, предназначенную для подготовки строк для латекса.Из его справочного файла:

latexTranslate переводит определенные элементы в символьных строках в формат LaTeX, например, создает ^ 2 = a $ $ 2 \ $ для верхнего индекса в переменных метках.В латексных именах греческих букв (например, «альфа») будут добавлены обратные слеши, если греческий == ИСТИНА.Математический режим вставляется по мере необходимости.latexTranslate предполагает, что у входного текста всегда есть совпадения, например [) [] (] (), и что окружение \ $ \ $ в порядке.

1 голос
/ 23 марта 2011

Может ли команда \verb помочь вам?

0 голосов
/ 23 марта 2011

Или вы также можете использовать Sweave для создания стола; при использовании вывода tex вместо Sexpr требуется только двойной обратный слеш, как это делает мой sanitize1, или stresc делает более полно.

Вы бы заполнили d своими значениями (например, myReport$report_name вместо "My_Report_Name") вместо тех, которые я составил.

<<echo=FALSE, results=tex>>=
sanitize1 <- function(str) {
  result <- str
  result <- gsub("&", "\\&", result, fixed = TRUE)
  result <- gsub("_", "\\_", result, fixed = TRUE)
  result
}
d <- rbind(c("Report name:","My_Report_Name"),
           c("Report date:","\\today"),
           c("Course name:","STAT101"),
           c("Start date:", "23 Mar 2011"),
           c("Instructor:", "Aaron & Jon L."))
cat("\\begin{tabular}{lll}\n")
for(i in 1:nrow(d)) {
  cat("& {\\textbf{",d[i,1],"}} &", sanitize1(d[i,2]), "\\\\\n", sep="")
}
cat("\\end{tabular}\n")
@ 
...