Можно ли заставить последовательность управления \ newcommand обрабатывать свип-код? - PullRequest
1 голос
/ 04 ноября 2011

Я использую латекс, чтобы писать домашние задания. Мне нужно включить обе диаграммы и код R с моим назначением. До сих пор Sweave хорошо работал для меня, но я хотел бы упростить блоки общего кода, подобные этому ...

\begin{rcode}
<<label=sol1, include=FALSE>>=
plot(c(2,3,5,7,11))
@
\end{rcode}
\begin{figure}[H]
<<fig=TRUE,echo=FALSE>>=
<<sol1>>
@
\end{figure}

(где rcode - это просто пользовательское число с плавающей запятой ... код идет в конце документа, диаграмма неподвижна.)

Так что-то вроде этого ...

\chart{sol1}{plot(c(2,3,4,5,7,11))}

где \ диаграмма определяется

\newcommand{\chart}[2]{
  \begin{rcode}
  <<label=#1, include=FALSE>>=
  #2
  @
  \end{rcode}
  \begin{figure}[H]
  <<fig=TRUE,echo=FALSE>>=
  <<#1>>
  @
  \end{figure}
}

К сожалению, похоже, что sweave попадает в исходный код до того, как латексные процессы \ newcommand, и поэтому этот подход не работает. Есть ли способ настроить обработку источника, чтобы макросы обрабатывались до того, как свип увидит источник? Или есть лучший подход к этой проблеме?

Заранее спасибо за любые предложения.

Ответы [ 2 ]

1 голос
/ 04 ноября 2011

Я надеюсь, что следующее о том, что вы хотели решить проблему курицы / яйца.Я украл его из своего поста в R-списке

% ---------------------------------- 
\documentclass{article} %
\usepackage{Sweave} 
\SweaveOpts{echo=FALSE}

\newcommand\bloodp[3]{
  \subsection{Patient #1} For patient #1, the mean value of systolic pressure was #2~mmHg, the diastolic pressure was #3~mmHg. 
  \begin{figure}[!htb]% 
    \begin{center}% 
      \includegraphics{histo#1}%
      \caption{Histogram of systolic blood pressure for patient #1.}% 
      \label{fig:histo#1}% 
    \end{center}% 
  \end{figure}% 
  \clearpage % Better use FloatBarrier here 
}

\begin{document} 
\section{Blood Pressure}

<<results=tex>>= 
n=100 
dt = data.frame(
   subj=sample(1:3,n,TRUE), 
   syst=round(rnorm(n,120,10)),
   dia=round(rnorm(n,80,10))
   )
# could also use tapply here 
for (i in 1:3) { 
  dt1 = dt[dt$subj==i,] 
  cat("\\bloodp{",i,"}{", 
     round(mean(dt1$syst)),"}{", 
     round(mean(dt1$dia)),"}\n",sep="") 
   pdf(paste("histo",i,".pdf",sep="")) 
   hist(dt1$syst,main="",xlab="Blood pressure") 
   dev.off() } 
@

\end{document}
0 голосов
/ 05 ноября 2011

Я написал скрипт на python, который, кажется, работает достаточно хорошо ... Я уверен, что есть кто-то, кто может сказать мне, как сделать все это с помощью одной строки PERL ;-), пожалуйста, дайте мне знать.

\floatstyle{ruled}
\newfloat{rcode}{b}{R}
\floatname{rcode}{R Code}

\floatstyle{boxed}
\newfloat{rout}{b}{R}
\floatname{rout}{R Output}

\begin{document}

!@plot A very informative plot

a <- c(2,3,5,7)
plot(a)

@;

!@print Some output

a<-c(2,5,5,7)
print(a)

@;

\end{document}

Вот скрипт на python, который я вставил в ~ / Library / TexShop / Scripts / sweave_macros.py

import sys
if __name__ == "__main__":
    old = open(sys.argv[1])
    new = open(sys.argv[2],'w')
    old_lines = old.readlines()
    i = 0

    out_file = ""

    while i < len(old_lines):

        if old_lines[i].lstrip()[0:2] == '!@':
            line = old_lines[i]
            obj = line[2:line.index(' ')].strip()
            label = line[line.index(' ')+1:line.index('\n')].strip()

            obj_end = i
            while old_lines[obj_end].strip() != "@;":
                obj_end += 1

            out_file += "\\begin{rcode}[p]\n"
            out_file += "<<label="+ label +", include=FALSE>>=\n"

            i += 1
            while i < obj_end:
                out_file += old_lines[i]
                i += 1

            out_file += "@\n"
            out_file += "\\caption{"+label+"}\n"
            out_file += "\\end{rcode}\n"

            if obj == "plot":
                out_file += "\\begin{figure}[H]\setkeys{Gin}{width=3.5in}\n"
                out_file += "<<fig=TRUE, echo=FALSE>>=\n"
                out_file += "<<"+label+">>"
                out_file += "\n@\n"
                out_file += "\\caption{"+label+"}\n"
                out_file += "\\end{figure}"

            if obj == "print":
                out_file += "\\begin{rout}[H]\n"
                out_file += "<<echo=FALSE>>=\n"
                out_file += "<<"+label+">>"
                out_file += "\n@\n"
                out_file += "\\caption{"+label+"}\n"
                out_file += "\\end{rout}"
            i += 1

        else:
            out_file += old_lines[i]
            i += 1

    new.write(out_file)
    new.close()

Наконец, я обновил движок Sweave, используемый TexShop, найдите в ~ / Library / TexShop / Engines / Sweave.engine:

#!/bin/bash                                                               
export SWEAVE_STYLEPATH_DEFAULT="TRUE"
export PATH=$PATH:/usr/texbin:/usr/local/bin
python ~/Library/TexShop/Scripts/sweave_macros.py "$1" "fin_$1"
R CMD Sweave "fin_$1"
pdflatex "fin_${1%.*}"

Так что теперь, когда я запускаю движок sweave из TexShop, сначала вызывается скрипт на python, и он разбирает текст между @! а также @; разделители так, как вы хотите.

Я надеюсь, что это кому-нибудь пригодится ... теперь, чтобы начать эту домашнюю работу ...

...