나는 수식과 프로그램 조각을 나란히 사용하여 수학 논문을 작성하고 싶습니다. 그러나 나는 TeX에 의해 프로그램이 표시되거나 문서화되는 것을 원하지 않으며, 원하는 경우 파일로 추출할 수만 있습니다.
내 의도는 리터럴 프로그래밍과 아무 관련이 없지만 아마도 이러한 도구 중 일부를 내 목적에 맞게 (잘못) 사용할 수 있습니까? 예를 들어 사전 파서에 대한 특수 토큰 %#을 가정하면 이러한 파일은 다음과 같습니다.
\documentclass[]{article}
\begin{document}
The factorial is an important function:
\begin{equation}
n! = \prod_{k=1}^n k
\end{equation}
%# n := 1;
%# for k from 1 to n
%# n := n * k;
\end{document}
내 질문: TeX 문서를 준비하고 이를 다른 도구로 추가 처리하기 위해 두 개(또는 그 이상)의 다른 파일로 분할할 수 있는 도구(또는 편집기)가 있습니까? 아니면 TeX 기능을 사용하는 다른 아이디어가 있나요?
편집: jfbu의 탁월한 답변 확장: 코드 조각이 번호가 매겨진 방정식 바로 뒤에 있다고 가정하면 방정식의 번호도 코드 파일에 작성할 수 있습니까? 이는 두 출력 간의 상호 참조에 해당합니다. (이것이 가능하지 않다면 jfbu의 '정교한 답변'에 도입된 내부 스니펫 카운터를 어떻게 작성할 수 있습니까(# 또는 // ?와 같은 주석 기호가 앞에 추가됨).
답변1
외부 도구 없이 tex 내부에서 이 작업을 수행할 수 있습니다.
이 업데이트는 자동(사용자 정의 가능) 번호 매기기를 사용하여 각 코드 조각에 대해 하나의 파일을 생성합니다. 이 예에서는 4개의 코드 조각에 해당하는 filename-code-01.py
, filename-code-02.py
, filename-code-03.py
를 생성합니다 filename-code-04.py
(2개는 서문에 있음).
OP 편집에 대한 추가 업데이트: 각 출력 코드 조각의 첫 번째 줄은 이제 코드 조각 번호가 포함된 주석 줄입니다. 방정식 번호 사용에 대한 질문은 코드 조각 추출이 문서에 실제로 조판되기 전에 부분 또는 서문 코드로 수행되기 때문에 더 섬세합니다.
$ ls preparseC*
preparseC-code-01.py preparseC-code-04.py preparseC.log
preparseC-code-02.py preparseC.aux preparseC.tex
preparseC-code-03.py preparseC.dvi
내용 preparseC-code-01.py
:
# Code snippet 1
n := 1;
for k from 1 to n
n := n * k;
.tex
소스 파일 에서 코드 조각을 식별하는 데 사용되는 줄 태그 는 입니다 %#<space><space>
.
암호:
\documentclass{article}
\newcounter{snippetno}
% customize \thesnippetno as desired, for example this produces
% filename-code-01.py
% filename-code-02.py
% ...
% filename-code-10.py
% etc...
% This command should be expandable
\renewcommand{\thesnippetno}
{\jobname-code-\ifnum\value{snippetno}<10 %<- leave a space
0\fi
\arabic{snippetno}.py}
%%%%%%%% PREPARSING
\newread\parsein
\openin\parsein \jobname.tex
\newwrite\parseout
% this version will create one file for each code snippet
\newif\ifOutputtingLines
% adapt the following to the line tag you want to use
% the \detokenize is not needed here, but in case your tag
% uses letters, put them in it (do not use \catcode for letters
% a they may be in use in \def \endgroup etc..)
%
% THIS VERSION USES %#<space><space> AS LINE TAG
% (two spaces must be present and will be removed in the outputs)
\begingroup
%% ADDED DEFINITION OF \COMMENTTAG FOR USE IN FIRST LINE OF CODE SNIPPET FILES
\catcode`\% 12
\catcode`\# 12
\def\x{\endgroup\def\COMMENTTAG{#}\edef\LineTag{\detokenize{%#}\space\space}}
\x
%\show\LineTag % debugging
\begingroup
\edef\x{\endgroup
\unexpanded{\def\CheckLineAux #1}\LineTag\relax \unexpanded{{#1}}
\unexpanded{\def\CheckLine #1}\LineTag \unexpanded{#2}\relax
\unexpanded{{\if\relax #1\relax
\ifOutputtingLines\else
\stepcounter{snippetno}%
\immediate\openout\parseout \thesnippetno\relax
%% ------------------------ ADDED TO INSERT CODE SNIPPET NUMBER IN THE FILE
\immediate\write\parseout
{\COMMENTTAG\space Code snippet \arabic{snippetno}}%
%% ------------------------
\OutputtingLinestrue
\fi
\immediate\write\parseout {\CheckLineAux #2\relax}%
\else
\ifOutputtingLines
\immediate\closeout\parseout
\OutputtingLinesfalse
\fi
\fi}}%
}
\x
\begingroup\endlinechar-1
\loop
\ifeof\parsein
% if \end{document} is not missing no need to \closeout\parseout
% necessarily already done, and OutputtingLines toggle necessarily false
\closein\parsein
\else
\readline\parsein to \tmpline
\if\relax\tmpline\relax % found empty line
\ifOutputtingLines\immediate\closeout\parseout
\OutputtingLinesfalse
\fi
\else
\expandafter\expandafter\expandafter \CheckLine
\expandafter \tmpline\LineTag \relax
\fi
\repeat
\endgroup
%%%%%%%% END OF PREPARSING
% Some code snippets may already be put here in the preamble
%
%# n := 1;
%# for k from 1 to n
%# n := n * k;
%# y := 1;
%# for k from 1 to n
%# y := y * (x + k -1);
% Notice that in this variant the line tag is %#<space><space>
% and is removed on output
\begin{document}
The factorial is an important function:
\[
n! = \prod_{k=1}^n k
\]
%# n := 1;
%# for k from 1 to n
%# n := n * k;
The (so-called) Pochhammer coefficient also:
\[
(x)_n = \prod_{k=1}^n (x+k-1)
\]
%# y := 1;
%# for k from 1 to n
%# y := y * (x + k -1);
\end{document}
이것은 답변의 첫 번째 버전입니다. (쓸모없는 a를 제거하고 디버깅 라인 \makeatletter
을 주석 처리했습니다 \show\LineTag
.)
filename-code
다음은 컴파일 시 태그가 지정된 줄 에도 추출됩니다 .
n := 1;
for k from 1 to n
n := n * k;
암호:
\documentclass{article}
%%%%%%%% PREPARSING
\newread\parsein
\openin\parsein \jobname.tex
\newwrite\parseout
\immediate\openout\parseout \jobname-code
% adapt the following to the line tag you want to use
% the \detokenize is not needed here, but in case your tag
% uses letters, put them in it (do not use \catcode for letters
% a they may be in use in \def \endgroup etc..)
\begingroup
\catcode`\% 12
\catcode`\# 12
\def\x{\endgroup\edef\LineTag{\detokenize{%#}}}
\x
%\show\LineTag % debugging
\begingroup
\edef\x{\endgroup
\unexpanded{\def\CheckLineAux #1}\LineTag\relax \unexpanded{{#1}}
\unexpanded{\def\CheckLine #1}\LineTag \unexpanded{#2}\relax
\unexpanded{{\if\relax #1\relax
\immediate\write\parseout {\CheckLineAux #2\relax}%
\fi}}%
}
\x
\begingroup\endlinechar-1
\loop
\ifeof\parsein
\immediate\closeout\parseout
\closein\parsein
\else
\readline\parsein to \tmpline
\if\relax\tmpline\relax\else
\expandafter\expandafter\expandafter \CheckLine
\expandafter \tmpline\LineTag \relax
\fi
\repeat
\endgroup
%%%%%%%% END OF PREPARSING
\begin{document}
The factorial is an important function:
\[
n! = \prod_{k=1}^n k
\]
%# n := 1;
%# for k from 1 to n
%# n := n * k;
\end{document}
답변2
더 광범위한 도구가 있지만 fff.tex
그 안에 예제를 저장하면 필요한 전부입니다 grep
.sed
grep -v "^%#" fff.tex
생산하다
\documentclass[]{article}
\begin{document}
The factorial is an important function:
\[
n! = \prod_{k=1}^n k
\]
\end{document}
그리고
grep "^%#" fff.tex | sed "s/^%#//"
생산하다
n := 1;
for k from 1 to n
n := n * k;
답변3
grep
또한 옵션을 사용하는 것 보다 더 읽기 쉬운 간단한 Perl 스크립트를 사용하여 수행할 수도 있습니다 sed
.
#!/usr/bin/perl
while(<STDIN>)
{
if( (substr $_, 0, 2) eq "%#" )
{
print substr $_, 2;
}
}
에 저장된 문서 document.tex
및 에 저장된 Perl 코드 extractComments.pl
.
생산물:
hpek@melda:~/programming/perl$ cat document.tex |./extractComments.pl
n := 1;
for k from 1 to n
n := n * k;
hpek@melda:~/programming/perl$
답변4
내 생각: 코드 덩어리가 R(http://www.r-project.org/), 나는 knitr
,http://yihui.name/knitr/(또는 지금은 오히려 오래된 Sweave,http://www.stat.uni-muenchen.de/~leisch/Sweave/).
그렇지 않은 경우 패키지를 사용해 보겠습니다 extract
.http://ctan.org/pkg/extract, 귀하의 요구 사항에 맞는 경우.
개인적으로는 패키지로 갈 것 같아요 listings
.http://mirrors.nic.cz/tex-archive/macros/latex/contrib/listings/listings.pdf, 코드는 즉시 조판될 수 있고, 필요한 경우 환경을 켜거나 끌 수 있으며(그러면 주석으로 작동함) 즉시 추출하고 기본 TeX 내부 및 외부에 코드 청크를 가질 수 있습니다. 다른 프로그램에서 동시에 컴파일할 수 있는 파일입니다.