我正在编写一个宏,它将读取自定义格式的线性方程组并\begin{array}
以适当的格式调用。为此,我需要循环遍历每一行并计算要显示的内容。
这是我目前所拥有的。
\documentclass[10pt,a4paper]{article}
\usepackage{xstring}
\newcommand{\lineareqsys}[3]{
\noexpandarg
\StrCount{#3}{\\}[\rows] %check \rows = arg > 0
\newcounter{i} \setcounter{i}{0}
\def\str{#3}
\def\strout{}
\expandafter\StrSubstitute\expandafter{\str}{+}{+&}[\str]
\expandafter\StrSubstitute\expandafter{\str}{-}{-&}[\str]
\loop
\stepcounter{i}
\expandafter\def\csname strout\roman{i}\endcsname{}
\expandafter\StrCut\expandafter{\str}{\\}{\str}{\rest}
\expandafter\StrPosition\expandafter{\str}{x}[\xpos]
\expandafter\StrLeft\expandafter{\str}{\xpos}[\strappx]
\expandafter\def\expandafter\strout\expandafter{\strout \strappx &}
\expandafter\StrGobbleLeft\expandafter{\str}{\xpos}[\str]
\expandafter\StrPosition\expandafter{\str}{y}[\ypos]
\expandafter\StrLeft\expandafter{\str}{\ypos}[\strappy]
\expandafter\def\expandafter\strout\expandafter{\strout \strappy &}
\expandafter\StrGobbleLeft\expandafter{\str}{\ypos}[\str]
\expandafter\StrPosition\expandafter{\str}{=}[\eqpos]
\expandafter\StrLeft\expandafter{\str}{\eqpos}[\strappeq]
\expandafter\def\expandafter\strout\expandafter{\strout \strappeq &}
\expandafter\StrGobbleLeft\expandafter{\str}{\eqpos}[\str]
\expandafter\StrRight\expandafter{\str}{\eqpos}[\strapplb]
\expandafter\def\expandafter\strout\expandafter{\strout \strapplb \\}
\expandafter\def\expandafter\str\expandafter{\rest}
\expandafter\def\csname strout\roman{i}\endcsname{\strout}
\ifnum \thei < #1 \relax
\repeat
\newcounter{j} \setcounter{j}{0}
\def\alig{r}
\loop
\stepcounter{j}
\expandafter\def\expandafter\alig\expandafter{\alig cr}
\ifnum \thej < #2 \relax
\repeat
\left\lbrace
\begin{array}{\alig}
\strout
\end{array}
\right.
}
\begin{document}
$\lineareqsys{2}{2}{
x + y = 5 \\
x - y = 3 \\
}$
\end{document}
线路有问题
\expandafter\def\csname strout\roman{i}\endcsname{\strout}
因为\strout
没有完全展开,所以第二次循环后数据被替换,最后一行重复了两次。
我已经检查过其他线程,但还是没能解决问题。我该如何解决这个问题?
注1:代码尚未完成,因此它不能处理没有x
或y
或行以-
符号开头的情况。
注2:我指的格式很简单。
ax + by + cz = d \\
根据需要设置多行。
编辑:以前代码的更简单版本。
\documentclass{article}
\newcommand{\lineareqsys}{
\newcounter{i} \setcounter{i}{0}
\def\strout{}
\loop
\stepcounter{i}
\expandafter\def\expandafter\strout\expandafter{\strout \arabic{i} row \\}
\ifnum \thei < 2 \relax
\repeat
\begin{array}{l}
\strout
\end{array}
}
\begin{document}
$\lineareqsys$
\end{document}
这说明了同样的问题。\arabic{i}
当它的值为 2 时,最后会展开。不是动态的。
答案1
核心问题是你没有扩展事物。如你所见,这是\strout
一段时间后的意思
> \strout=macro:
->\strappx &\strappy &\strappeq &\strapplb \\\strappx &\strappy &\strappeq &\st
rapplb \\.
\iterate ... {\strout \strapplb \\} \show \strout
\expandafter \def \expanda...
l.57 }
$
你必须找到一种方法来添加\strout
到扩展内容等等...不管它们是什么\strappx
。\strappy
此外,您\newcounter
在命令调用中执行了这些操作,这是非常错误的。但这是另一个问题。
为了调试,我\show\strout
在各个地方添加了您的命令。
而且你很幸运只能在数学模式下调用这个宏,因为其中有大量的空间标记。
例如,这可以给出需要做什么的想法:
%\expandafter\def\expandafter\strout\expandafter{\strout \strapplb \\}
\expandafter\g@addto@macro\expandafter\strout\expandafter{\strapplb\\}
第一个方程的 RHS 是固定的。
答案2
正如您所看到的,存在着很大的扩展问题。
这是一个完全不同的解决方案,它使用expl3
,但与您的解决方案一样,存在缺少未知数会破坏结果的缺陷。
systeme
我还提供了与不存在缺陷的比较。
\documentclass[10pt,a4paper]{article}
\usepackage{xparse}
%\usepackage{array} % also works with this uncommented
\usepackage{systeme} % for comparison
\ExplSyntaxOn
\NewDocumentCommand{\lineareqsys}{mm}
{
\seq_set_split:Nnn \l__mendus_system_in_seq { \\ } { #2 }
\seq_clear:N \l__mendus_system_out_seq
\seq_map_inline:Nn \l__mendus_system_in_seq
{
\__mendus_system_make_row:nn { #1 } { ##1 }
}
\left\lbrace
\setlength{\arraycolsep}{0pt}
\renewcommand{\arraystretch}{1.2}
\exp_args:Nnx \begin{array}{r \prg_replicate:nn { \clist_count:n { #1 } } { c r } }
\seq_use:Nn \l__mendus_system_out_seq { \\ }
\end{array}
\right.
}
\cs_new_protected:Nn \__mendus_system_make_row:nn
{
\tl_set:Nn \l__mendus_system_row_tl { #2 }
\regex_replace_all:nnN { (.+?)(\+|\-|\=) } { \1\cB\{\cE\}\2\cB\{\cE\}\cT& } \l__mendus_system_row_tl
\clist_map_inline:nn { #1 }
{
\regex_replace_all:nnN { ##1 } { \cL##1 \cT& } \l__mendus_system_row_tl
}
\seq_put_right:NV \l__mendus_system_out_seq \l__mendus_system_row_tl
}
\cs_generate_variant:Nn \regex_count:nnN { nV }
\ExplSyntaxOff
\begin{document}
\[
\lineareqsys{x,y}{
x + y = 5 \\
x - y = 3 \\
}
\qquad
\lineareqsys{x,y,z}{
2x-3y+4z=0 \\
x+12y-z=0 \\
-x+8y+z=3
}
\]
\[
\systeme{
x + y = 5,
x - y = 3
}
\qquad
\systeme{
2x-3y+4z=0,
x+12y-z=0,
-x+8y+z=3
}
\]
\end{document}