我想为自然演绎证明定义一个自定义环境,打印如下表格:
目前,我使用表格环境来编写这些证明:
\documentclass{article}
\begin{document}
Some random text.
\begin{center}
\begin{tabular}{|c|c|c|c|c|c|}
\hline
\multicolumn{2}{|c|}{Stars} & Line & Formula & Reference & Rule \\ \hline
$\star$ && 1 & $p \to q$ & -- & Hyp \\ \hline
&$\star$& 2 & $p$ & -- & Hyp \\ \hline
$\star$~~&$\star$ & 3 & $q$ & 1, 2 & E$\to$\\ \hline
\end{tabular}
\end{center}
\noindent
Yet again some random text.
\end{document}
可以想象,以这种方式编写证明非常麻烦,所以我想拥有自己的环境。以下是我希望实现的一些功能:
- 你可以通过参数指定星形列的数量
- 每当你输入“*”时,LaTeX 都会打印
\star
- 水平线会自动添加,因此您无需
\hline
每次都使用 - 行列会自动编号,因此您可以忽略它
- 如果指定的星形单元少于要求的星形单元,则剩余的星形单元将添加为空单元
- 环境默认居中
- 表格后的段落没有缩进。
例如,上面的证明在新环境中可能看起来像这样:
\begin{ndproof}{2} % two star columns
*& $p \to q$ & -- & Hyp \\ % just one star cell specified, so second star cell empty
&*& $p$ & -- & Hyp \\
*&*&$p$ & 1, 2 & E$\to$
\end{ndproof}
我是 LaTeX 新手,这个项目对我来说太大了。你们有人能帮我吗?也许你们还有让环境变得更好的想法!
答案1
这是一种可能的方法:
\documentclass{article}
\usepackage{array}
\ExplSyntaxOn
\newcounter{LN}
\newcommand{\LN}{\stepcounter{LN}\theLN}
\NewDocumentEnvironment{ndproof}{m}
{
\[
\setcounter{LN}{0}
\begin{tabular}
{
*{#1}{|c} | % stars
>{\LN}c | % line
>{$}c<{$} | % formula
c | % reference
c | % rule
}
\hline
\multicolumn{#1}{|c|}{Stars} &
\multicolumn{1}{c|}{Line} &
\multicolumn{1}{c|}{Formula} &
Reference &
Rule \\
\hline
}
{
\end{tabular}
\]
\ignorespacesafterend
}
\NewDocumentCommand{\ndline}{mmmm}
{
\vitus_addstars:n { #1 } & & #2 & #3 & #4 \\ \hline
}
\cs_new_protected:Nn \vitus_addstars:n
{
\seq_set_split:Nnn \l_tmpa_seq { } { #1 }
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \__vitus_star:n { ##1 } }
\seq_use:Nn \l_tmpb_seq { & }
}
\cs_new_protected:Nn \__vitus_star:n
{
\str_case:nn { #1 } { {-}{} {*}{$\star$} }
}
\ExplSyntaxOff
\begin{document}
Some words preceding the proof, let's make it long enough so that
it splits across lines in order to well present the job.
\begin{ndproof}{2}
\ndline{*-}{p\to q}{--}{Hyp}
\ndline{-*}{p}{--}{Hyp}
\ndline{**}{q}{1, 2}{E$\to$}
\end{ndproof}
Some words following the proof, let's make it long enough so that
it splits across lines in order to well present the job.
\end{document}
对于星星,我认为有必要指定-
是否不想将其排成一行。这也使输入更加一致。
修复了“星星”标题对于两列来说有点长的情况。
\documentclass{article}
\usepackage{array}
\ExplSyntaxOn
\newcounter{LN}
\NewDocumentCommand{\LN}{}{\stepcounter{LN}\theLN}
\NewDocumentEnvironment{ndproof}{m}
{
\[
\setcounter{LN}{0}
\settowidth{\dimen0}{Sterne}
\setlength{\dimen0}{\dim_eval:n { \dimen0/2-\tabcolsep }}
\use:x
{
\noexpand\begin{tabular}
{
*{#1}{|\int_compare:nTF{ #1=2 }{w{c}{\dimen0}}{c}} | % stars
>{\LN}c | % line
>{$}c<{$} | % formula
c | % reference
c | % rule
}
}
\hline
\multicolumn{#1}{|c|}{Sterne} &
\multicolumn{1}{c|}{Linie} &
\multicolumn{1}{c|}{Formel} &
Referenz &
Regel \\
\hline
}
{
\end{tabular}
\]
\ignorespacesafterend
}
\NewDocumentCommand{\ndline}{mmmm}
{
\vitus_addstars:n { #1 } & & #2 & #3 & #4 \\ \hline
}
\cs_new_protected:Nn \vitus_addstars:n
{
\seq_set_split:Nnn \l_tmpa_seq { } { #1 }
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \__vitus_star:n { ##1 } }
\seq_use:Nn \l_tmpb_seq { & }
}
\cs_new_protected:Nn \__vitus_star:n
{
\str_case:nn { #1 } { {-}{} {*}{$\star$} }
}
\ExplSyntaxOff
\begin{document}
Some words preceding the proof, let's make it long enough so that
it splits across lines in order to well present the job.
\begin{ndproof}{1}
\ndline{-}{p\to q}{--}{Hyp}
\ndline{-}{p}{--}{Hyp}
\ndline{*}{q}{1, 2}{E$\to$}
\end{ndproof}
Some words following the proof, let's make it long enough so that
it splits across lines in order to well present the job.
\begin{ndproof}{2}
\ndline{*-}{p\to q}{--}{Hyp}
\ndline{-*}{p}{--}{Hyp}
\ndline{**}{q}{1, 2}{E$\to$}
\end{ndproof}
Some words following the proof, let's make it long enough so that
it splits across lines in order to well present the job.
\begin{ndproof}{3}
\ndline{*--}{p\to q}{--}{Hyp}
\ndline{-*-}{p}{--}{Hyp}
\ndline{***}{q}{1, 2}{E$\to$}
\end{ndproof}
Some words following the proof, let's make it long enough so that
it splits across lines in order to well present the job.
\end{document}