假设 A 编写了一小段 TeX 代码,并将其发送给 B,以便将其作为较大文档的一部分。A 编写的这段代码没有使用任何花哨的东西:没有交叉引用、引文、章节、脚注等。但它当然有数学运算,以及最少的文本格式化命令,如粗体、斜体、枚举列表、表格等。
问题在于 A 和 B 使用的 TeX 风格不同。我认为 A 使用 Plain TeX,而 B 使用 LaTeX,那么通常 B 只需粘贴 A 的代码即可,因为 Plain TeX 中的大多数文本格式化命令(例如{\bf bold}
)实际上都是 TeX 基元,因此即使不是“推荐”样式,也可以在 LaTeX 中使用。
如果 A 使用 LaTeX 而 B 使用 Plain TeX,则问题会更严重,因为例如\textbf{bold}
在 Plain TeX 中不存在。但当然在这种情况下,B 可以自己定义一个简单的版本。我的问题是我是否可以为 B 省去这项工作?我在哪里可以找到一个简短、快速且粗糙的宏定义集合,Plain TeX 用户可以将其粘贴在文档顶部,以便她能够粘贴简单的只使用基本的文本格式化命令和(比如)列表和表格环境来创建 LaTeX 的片段,并让它们看起来至少有点合理?显然,如果 LaTeX 代码使用任何相当复杂的东西,那么就没有答案了(除非粘贴或重新实现所有的 LaTeX),但对于非常简单的代码来说,这似乎是可能的,也许有人以前做过。
答案1
您始终可以复制定义。该文件miniltx.tex
会有所帮助(这已经允许在普通模式下使用 latex 颜色和图形命令,并定义了一些内部 latex 工具,但对 tabular 没有太大帮助。下面的文件添加了 tabular,只是基本版本,而不是来自array
包或tabularx
等的扩展版本,我也使用了\Lbegin
和\Lend
以避免与\end
使用的原始版本发生冲突\bye
。
\catcode`\@=11
\input miniltx
\def\@ignorefalse{\global\let\if@ignore\iffalse}
\def\@ignoretrue {\global\let\if@ignore\iftrue}
\@ignorefalse
\let\ignorespacesafterend\@ignoretrue
\let\@typeset@protect\relax
\def\set@display@protect{\let\protect\string}
\def\set@typeset@protect{\let\protect\@typeset@protect}
\def\protected@edef{%
\let\@@protect\protect
\let\protect\@unexpandable@protect
\afterassignment\restore@protect
\edef
}
\def\protected@xdef{%
\let\@@protect\protect
\let\protect\@unexpandable@protect
\afterassignment\restore@protect
\xdef
}
\def\unrestored@protected@xdef{%
\let\protect\@unexpandable@protect
\xdef
}
\def\restore@protect{\let\protect\@@protect}
\set@typeset@protect
\def\@endparenv{%
\addpenalty\@endparpenalty\addvspace\@topsepadd\@endpetrue}
\def\@doendpe{\@endpetrue
\def\par{\@restorepar
\clubpenalty\@clubpenalty
\everypar{}\par\@endpefalse}\everypar
{{\setbox\z@\lastbox}%
\everypar{}\@endpefalse}}
\newif\if@endpe
\@endpefalse
\def\Lbegin#1{%
\@ifundefined{#1}%
{\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}%
{\def\reserved@a{\def\@currenvir{#1}%
\edef\@currenvline{\on@line}%
\csname #1\endcsname}}%
\@ignorefalse
\begingroup\@endpefalse\reserved@a}
\def\Lend#1{%
\csname end#1\endcsname\@checkend{#1}%
\expandafter\endgroup\if@endpe\@doendpe\fi
\if@ignore\@ignorefalse\ignorespaces\fi}
\def\@checkend#1{\def\reserved@a{#1}\ifx
\reserved@a\@currenvir \else\@badend{#1}\fi}
\let\@currenvline\@empty
\def\extracolsep#1{\tabskip #1\relax}
\def\array{\let\@acol\@arrayacol \let\@classz\@arrayclassz
\let\@classiv\@arrayclassiv
\let\\\@arraycr\let\@halignto\@empty\@tabarray}
\def\endarray{\crcr\egroup\egroup}
\def\endtabular{\crcr\egroup\egroup $\egroup}
\expandafter \let \csname endtabular*\endcsname = \endtabular
\def\tabular{\let\@halignto\@empty\@tabular}
\@namedef{tabular*}#1{%
\setlength\dimen@{#1}%
\edef\@halignto{to\the\dimen@}\@tabular}
\def\@tabular{\leavevmode \hbox \bgroup $\let\@acol\@tabacol
\let\@classz\@tabclassz
\let\@classiv\@tabclassiv \let\\\@tabularcr\@tabarray}
\def\@tabarray{\m@th\@ifnextchar[\@array{\@array[c]}}
\def\@array[#1]#2{%
\if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi
\bgroup
\setbox\@arstrutbox\hbox{%
\vrule \@height\arraystretch\ht\strutbox
\@depth\arraystretch \dp\strutbox
\@width\z@}%
\@mkpream{#2}%
\edef\@preamble{%
\ialign \noexpand\@halignto
\bgroup \@arstrut \@preamble \tabskip\z@skip \cr}%
\let\@startpbox\@@startpbox \let\@endpbox\@@endpbox
\let\tabularnewline\\%
\let\par\@empty
\let\@sharp##%
\set@typeset@protect
\lineskip\z@skip\baselineskip\z@skip
\ifhmode \@preamerr\z@ \@@par\fi
\@preamble}
\def\@arraycr{%
${\ifnum0=`}\fi\@ifstar\@xarraycr\@xarraycr}
\def\@xarraycr{\@ifnextchar[\@argarraycr{\ifnum0=`{\fi}${}\cr}}
\def\@argarraycr[#1]{%
\ifnum0=`{\fi}${}\ifdim #1>\z@ \@xargarraycr{#1}\else
\@yargarraycr{#1}\fi}
\let\tabularnewline\relax
\def\@tabularcr{%
{\ifnum0=`}\fi\@ifstar\@xtabularcr\@xtabularcr}
\def\@xtabularcr{\@ifnextchar[\@argtabularcr{\ifnum0=`{\fi}\cr}}
\def\@argtabularcr[#1]{%
\ifnum0=`{\fi}%
\ifdim #1>\z@
\unskip\@xargarraycr{#1}%
\else
\@yargarraycr{#1}%
\fi}
\def\@xargarraycr#1{\@tempdima #1\advance\@tempdima \dp \@arstrutbox
\vrule \@height\z@ \@depth\@tempdima \@width\z@ \cr}
\def\@yargarraycr#1{\cr\noalign{\vskip #1}}
\long\def\multicolumn#1#2#3{\multispan{#1}\begingroup
\@mkpream{#2}%
\def\@sharp{#3}\set@typeset@protect
\let\@startpbox\@@startpbox\let\@endpbox\@@endpbox
\@arstrut \@preamble\hbox{}\endgroup\ignorespaces}
\def\@xexnoop #1\@@{}
\def\@expast#1{\@xexpast #1*0x\@@}
\def\@xexpast#1*#2#3#4\@@{%
\edef\reserved@a{#1}%
\@tempcnta#2\relax
\ifnum\@tempcnta>\z@
\@whilenum\@tempcnta>\z@\do
{\edef\reserved@a{\reserved@a#3}\advance\@tempcnta \m@ne}%
\let\reserved@b\@xexpast
\else
\let\reserved@b\@xexnoop
\fi
\expandafter\reserved@b\reserved@a #4\@@}
\newif\if@firstamp
\def\@addamp{%
\if@firstamp
\@firstampfalse
\else
\edef\@preamble{\@preamble &}%
\fi}
\def\@arrayacol{\edef\@preamble{\@preamble \hskip \arraycolsep}}
\def\@tabacol{\edef\@preamble{\@preamble \hskip \tabcolsep}}
\def\@ampacol{\@addamp \@acol}
\def\@acolampacol{\@acol\@addamp\@acol}
\def\@mkpream#1{\@firstamptrue\@lastchclass6
\let\@preamble\@empty
\let\protect\@unexpandable@protect
\let\@sharp\relax
\let\@startpbox\relax\let\@endpbox\relax
\@expast{#1}%
\expandafter\@tfor \expandafter
\@nextchar \expandafter:\expandafter=\reserved@a\do
{\@testpach\@nextchar
\ifcase \@chclass \@classz \or \@classi \or \@classii \or \@classiii
\or \@classiv \or\@classv \fi\@lastchclass\@chclass}%
\ifcase \@lastchclass \@acol
\or \or \@preamerr \@ne\or \@preamerr \tw@\or \or \@acol \fi}
\def\@arrayclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or
\or \or \@addamp \or
\@acolampacol \or \@firstampfalse \@acol \fi
\edef\@preamble{\@preamble
\ifcase \@chnum
\hfil$\relax\@sharp$\hfil \or $\relax\@sharp$\hfil
\or \hfil$\relax\@sharp$\fi}}
\def\@tabclassz{%
\ifcase\@lastchclass
\@acolampacol
\or
\@ampacol
\or
\or
\or
\@addamp
\or
\@acolampacol
\or
\@firstampfalse\@acol
\fi
\edef\@preamble{%
\@preamble{%
\ifcase\@chnum
\hfil\ignorespaces\@sharp\unskip\hfil
\or
\hskip1sp\ignorespaces\@sharp\unskip\hfil
\or
\hfil\hskip1sp\ignorespaces\@sharp\unskip
\fi}}}
\def\@classi{%
\ifcase\@lastchclass
\@acol\@arrayrule
\or
\@addtopreamble{\hskip \doublerulesep}\@arrayrule
\or
\or
\or
\@arrayrule
\or
\@acol\@arrayrule
\or
\@arrayrule
\fi}
\def\@classii{%
\ifcase\@lastchclass
\or
\@addtopreamble{\hskip .5\arrayrulewidth}%
\fi}
\def\@classiii{\ifcase \@lastchclass \@acolampacol \or
\@addamp\@acol \or
\or \or \@addamp \or
\@acolampacol \or \@ampacol \fi}
\def\@tabclassiv{\@addtopreamble\@nextchar}
\def\@arrayclassiv{\@addtopreamble{$\@nextchar$}}
\def\@classv{\@addtopreamble{\@startpbox{\@nextchar}\ignorespaces
\@sharp\@endpbox}}
\def\@addtopreamble#1{\edef\@preamble{\@preamble #1}}
\newcount\@chclass
\newcount\@lastchclass
\newcount\@chnum
\newdimen\arraycolsep
\newdimen\tabcolsep
\newdimen\arrayrulewidth
\newdimen\doublerulesep
\def\arraystretch{1} % Default value.
\newbox\@arstrutbox
\def\@arstrut{%
\relax\ifmmode\copy\@arstrutbox\else\unhcopy\@arstrutbox\fi}
\def\@arrayrule{\@addtopreamble{\hskip -.5\arrayrulewidth
\vrule \@width \arrayrulewidth\hskip -.5\arrayrulewidth}}
\def\@testpach#1{\@chclass \ifnum \@lastchclass=\tw@ 4 \else
\ifnum \@lastchclass=3 5 \else
\z@ \if #1c\@chnum \z@ \else
\if #1l\@chnum \@ne \else
\if #1r\@chnum \tw@ \else
\@chclass \if #1|\@ne \else
\if #1@\tw@ \else
\if #1p3 \else \z@ \@preamerr 0\fi
\fi \fi \fi \fi \fi \fi
\fi}
\def\hline{%
\noalign{\ifnum0=`}\fi\hrule \@height \arrayrulewidth \futurelet
\reserved@a\@xhline}
\def\@xhline{\ifx\reserved@a\hline
\vskip\doublerulesep
\vskip-\arrayrulewidth
\fi
\ifnum0=`{\fi}}
\def\vline{\vrule \@width \arrayrulewidth}
\def\cline#1{\@cline#1\@nil}
\def\@cline#1-#2\@nil{%
\omit
\@multicnt#1%
\advance\@multispan\m@ne
\ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi
\@multicnt#2%
\advance\@multicnt-#1%
\advance\@multispan\@ne
\leaders\hrule\@height\arrayrulewidth\hfill
\cr
\noalign{\vskip-\arrayrulewidth}}
\def\multispan{\omit\@multispan}
\def\@multispan#1{%
\@multicnt#1\relax
\loop\ifnum\@multicnt>\@ne \sp@n\repeat}
\def\sp@n{\span\omit\advance\@multicnt\m@ne}
\def\@startpbox#1{\vtop\bgroup \setlength\hsize{#1}\@arrayparboxrestore}
\def\@endpbox{\@finalstrut\@arstrutbox\par\egroup\hfil}
\let\@@startpbox=\@startpbox
\let\@@endpbox=\@endpbox
\catcode`\@=12
\tabcolsep 6pt
aaaaaaaaaaa
\Lbegin{tabular}[c]{lll}
aaa&bbb&ccc\\
1&2&3\\
\Lend{tabular}
\bye
答案2
这是我对问题剩余部分的解释:您想粘贴类似以下文本的内容:
\begin{enumerate}
\item January
\item February
\item March
\end{enumerate}
变成清楚的TeX 文档,得到一些模糊地像枚举列表的东西。
下面提供一种解决方法。
首先,在纯 TeX 中提供的某些宏包中查找如何输入枚举列表(或者实现你自己的宏包)。例如,埃普莱恩可以:
\input eplain
\numberedlist
\li January
\li February
\li March
\endnumberedlist
\bye
这就是奥普麦克可以:
\input opmac
\begitems \style n
* January
* February
* March
\enditems
\bye
接下来,进行必要的修改,将 LaTeX 语法转换为相应的带宏的纯 TeX 输入。例如,使用eplain
(请注意,我的宏可能还可以改进):
\input eplain
\def\begin#1{
\def\tmpenumerate{enumerate}
\def\tmpitemize{itemize}
\def\tmparg{#1}
\ifx\tmparg\tmpenumerate
\bgroup\def\item{\li}\numberedlist
% May want to implement error-checking here
\def\end##1{\endnumberedlist\egroup}
\else
\ifx\tmparg\tmpitemize
\bgroup\def\item{\li}\unorderedlist
\def\end##1{\endunorderedlist\egroup}
\else
\message{Unsupported environment #1}
\fi
\fi
}
\begin{enumerate}
\item January
\item February
\item March
\end{enumerate}
\begin{itemize}
\item April
\item May
\item June
\end{itemize}
\bye
在这里,我们将 LaTeX 片段粘贴\begin{enumerate} … \end{enumerate}
到\begin{itemize} … \end{itemize}
纯 TeX 文档中,并在输出中得到了合理的列表:
当然,你需要为你使用的每个环境提出类似的定义,如果你想支持更复杂的语法,比如可选参数enumerate
等等,你需要做更多的黑客工作。但你说
就我的目的而言,我很高兴能找到一个能够以非常简单的方式同时处理逐项列举和枚举的答案。
这当然是非常基本的。:-)