平均能量损失

平均能量损失

这是我的项目的简化版本。我有一个名为 的宏\CreateMacro,它需要 2 个输入,即要创建的宏名称及其主体。例如,调用\CreateMacro{Newton}{$F=ma$.}将创建一个\Newton带有主体的新宏$F=ma$。在幕后,有一个辅助宏\Newtonprivate被创建。 的目的\Newtonprivate是用不同的样式格式化主体,在此示例中,将主体设为红色。

每次\Newton调用时,\Newtonprivate都必须将其推送到类似数组的列表中。\Render然后打印与推送\Newtonprivate次数相同的次数。\Newtonprivate

平均能量损失

\documentclass{book}

\usepackage{xcolor}

\makeatletter
\newcommand\CreateMacro[2]{%
    \expandafter\@ifdefinable\csname#1private\endcsname{\global\@namedef{#1private}{\textcolor{red}{#2}}}% auxiliary private macro
    \expandafter\@ifdefinable\csname#1\endcsname{\global\@namedef{#1}{#2\expandafter\addjword{\csname #1private\endcsname}}}%
}




\usepackage{etoolbox}

% Array for words

\newcounter{jwordcount}%
\newcommand\setjword[2]{\csdef{jword#1}{#2}}%
\newcommand\addjword[1]{\stepcounter{jwordcount}\setjword{\thejwordcount}{#1}}%
\newcommand\getjword[1]{\csuse{jword#1}}%

%%% Basic Loop
%Taken from the aloop pof David Salomon's The Advanced TeXbook pg 191
%Use:
%\newcount\temp
%\loop\temp=1 step 1 until 10 do {something} \endloop\temp
\def\loop#1=#2 {%
    \long\def\next step ##1 until ##2 do ##3 \endloop#1{%
        ##3%
    \advance#1 by ##1
    \ifnum#1>##2\relax\else\next step ##1 until ##2 do ##3 \endloop#1 \fi%
    }%end of \next
    #1=#2 \next}%end of \loop

%Return the table containing the current words, reset the counter
\newcommand\render{%
        \newcount\temp\loop\temp=1 step 1 until {\thejwordcount} do {\expandafter\getjword{\@arabic\temp}\ifnum\temp<\thejwordcount\else\fi} \endloop\temp%
        \setcounter{jwordcount}{0}%reset for the next group of words
}


\makeatother


\parindent=0pt


\begin{document}
\CreateMacro{Newton}{$F=ma$.}


\chapter{\protect\Newton}
\render

\Newton\\
\render

\Newton\\
\render

\end{document}

问题

当我调用Newtoninside时\chapter,列表似乎仍然是空的。不应该这样。如何解决这个问题?

答案1

章节标题按组排版,并且列表不会全局更新。使用\csgdef

一些其他怪癖。

  1. \expandafter\addjword{\csname #1private\endcsname}尝试扩展{,完全无用。要么删除\expandafter,要么执行

    \expandafter\addjword\expandafter{\csname #1private\endcsname}
    
  2. 同样\expandafter\getjword{\@arabic\temp}地,应该

    \expandafter\getjword\expandafter{\the\temp}
    

    \the比 更有效\@arabic)。

  3. \newcount\temp应该超出定义范围\render,否则每次调用都会浪费一个计数器。

  4. 你正在进行的循环非常麻烦。

以下是 的一个版本expl3

\documentclass{book}

\usepackage{xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\CreateMacro}{mm}
 {
  \cs_new_protected:cpn { #1 }
   {
    #2
    \seq_gput_right:Nn \g_eirian_push_seq { \eirian_format:n { #2 } }
   }
 }

\NewDocumentCommand{\render}{ }
 {
  \seq_use:Nn \g_eirian_push_seq {}
  \seq_gclear:N \g_eirian_push_seq
 }

\seq_new:N \g_eirian_push_seq

\cs_new_protected:Nn \eirian_format:n
 {
  \textcolor{red}{#1}
 }
\ExplSyntaxOff

\parindent=0pt


\begin{document}
\CreateMacro{Newton}{$F=ma$.}

\chapter{\Newton}
\render

\Newton\Newton\\
\render

\Newton\\
\render

\end{document}

由于\Newton是“受保护的”,所以您不需要\protect在它前面。

在此处输入图片描述

“传统”版本,灵活性较差。

\documentclass{book}

\usepackage{xcolor}
\usepackage{etoolbox}

\newcommand{\CreateMacro}[2]{%
  \expandafter\newrobustcmd\csname #1\endcsname{%
    #2\gappto\pushed{\format{#2}}%
  }%
}
\newcommand{\format}[1]{\textcolor{red}{#1}}
\newcommand{\render}{\pushed\gdef\pushed{}}

\parindent=0pt

\begin{document}
\CreateMacro{Newton}{$F=ma$.}

\chapter{\Newton}
\render

\Newton\Newton\\
\render

\Newton\\
\render

\end{document}

您可以推送多个内容并独立呈现它们的版本(当然,\render需要有一个参数)。

\documentclass{book}
\usepackage{xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\CreateMacro}{mm}
 {
  \seq_new:c { g_eirian_push_#1_seq }
  \cs_new_protected:cpn { #1 }
   {
    #2
    \seq_gput_right:cn { g_eirian_push_#1_seq } { \eirian_format:n { #2 } }
   }
 }

\NewDocumentCommand{\render}{m}
 {
  \seq_use:cn { g_eirian_push_#1_seq } {~}
  \seq_gclear:c { g_eirian_push_#1_seq }
 }

\cs_new_protected:Nn \eirian_format:n
 {
  \textcolor{red}{#1}
 }
\ExplSyntaxOff

\parindent=0pt


\begin{document}
\CreateMacro{Newton}{$F=ma$.}
\CreateMacro{Einstein}{$E=mc^2$.}

\chapter{\Newton}
\render{Newton}

\Newton\Einstein\Newton\\
\render{Newton}\render{Einstein}

\end{document}

答案2

你的\csdefin\setjword未能在该组中存活,但我\csgdef存活了下来。

但说实话,我觉得代码可以重新整理一下。我会尝试在以后改进它。

\documentclass{book}

\usepackage{xcolor}

\usepackage{etoolbox}

\makeatletter
\newcommand\CreateMacro[2]{%
    \expandafter\@ifdefinable\csname#1private\endcsname{\global\@namedef{#1private}{\textcolor{red}{#2}}}% auxiliary private macro
    \expandafter\@ifdefinable\csname#1\endcsname{\global\@namedef{#1}{#2\expandafter\addjword{\csname #1private\endcsname}}}%
}




\usepackage{etoolbox}

% Array for words

\newcounter{jwordcount}%
\newcommand\setjword[2]{\csgdef{jword#1}{#2}}%
\newcommand\addjword[1]{\stepcounter{jwordcount}\setjword{\thejwordcount}{#1}}%
\newcommand\getjword[1]{\csuse{jword#1}}%

%%% Basic Loop
%Taken from the aloop pof David Salomon's The Advanced TeXbook pg 191
%Use:
%\newcount\temp
%\loop\temp=1 step 1 until 10 do {something} \endloop\temp
\def\loop#1=#2 {%
    \long\def\next step ##1 until ##2 do ##3 \endloop#1{%
        ##3%
    \advance#1 by ##1
    \ifnum#1>##2\relax\else\next step ##1 until ##2 do ##3 \endloop#1 \fi%
    }%end of \next
    #1=#2 \next}%end of \loop

%Return the table containing the current words, reset the counter
\newcommand\render{%
        \newcount\temp\loop\temp=1 step 1 until {\thejwordcount} do {\expandafter\getjword{\@arabic\temp}\ifnum\temp<\thejwordcount\else\fi} \endloop\temp%
        \setcounter{jwordcount}{0}%reset for the next group of words
}


\makeatother


\parindent=0pt


\begin{document}
\CreateMacro{Newton}{$F=ma$.}


\chapter{\protect\Newton}
Render here: \render


Again: \Newton\\
\render

\Newton\\
\render

\end{document}

答案3

似乎这里有些事情过于复杂了。在纯 TeX 中,可以通过以下方式解决您的任务:

\input opmac

\def\renderlist{}
\def\createmacro#1#2{\addprotect#1%
   \def#1{#2\global\addto\renderlist{\formatmacro{#2}}}}
\def\render{\renderlist\gdef\renderlist{}}
\def\formatmacro#1{{\localcolor\Red#1}}

\createmacro\Newton{$F=ma$.}

\chap \Newton

\render

\Newton:
\render

\Newton, \Newton:
\render

\end

如果你的环境是 LaTeX,那么使用包xcolor并尝试

\def\renderlist{}
\def\createmacro#1#2{%
   \protected\def#1{#2%
      \expandafter\gdef\expandafter\renderlist\expandafter
         {\renderlist\formatmacro{#2}}}}
\def\render{\renderlist\gdef\renderlist{}}
\def\formatmacro#1{\textcolor{red}{#1}}

\createmacro\Newton{$F=ma$.}
...

相关内容