强制宏扩展

强制宏扩展

我正在编写一个宏,它将读取自定义格式的线性方程组并\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:代码尚未完成,因此它不能处理没有xy或行以-符号开头的情况。

注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}

在此处输入图片描述

相关内容