写入数字序列的命令

写入数字序列的命令

在编写包含许多数字序列(以及各种下限和上限)的文档时,我想定义一个命令,如下\myscale{1}{6}所示:

1  2  3  4  5  6 

我想知道如何创建while循环来写入数字直到达到第二个参数给出的值...有什么想法吗?

答案1

没有任何包,只有经典的 TeX:

\newcount\tmpnum
\def\myscale#1#2{%
   \tmpnum=#1 \the\tmpnum
   \loop
      \ifnum\tmpnum<#2
         \advance\tmpnum by1
         \quad\the\tmpnum
      \repeat
}

使用 eTeX 扩展和 axpandable 解决方案:

\def\myscale#1#2{#1%
   \ifnum#1<#2 \space \expandafter\myscale\expandafter{\the\numexpr#1+1\relax}{#2}\fi
}

编辑:第三个版本添加了下面评论中 jfbu 描述的功能。即首先评估参数,然后\if...\fi解决嵌套问题。

\def\myscale#1#2{\expandafter\myscaleA\expandafter{\the\numexpr#1\expandafter}%
                                      \expandafter{\the\numexpr#2}% evaluate params
}
\def\myscaleA#1#2{#1\ifnum#1<#2 \space \myscaleB{\the\numexpr#1+1\relax}{#2}\fi}
\def\myscaleB#1\fi{\fi \expandafter\myscaleA\expandafter#1}

答案2

无需任何软件包(但需要 e-TeX),完全可扩展的解决方案:

\documentclass{article}

\makeatletter
\newcommand{\myscale}[2]{%
  \ifnum#1=#2
    $#1$\expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {\myscale@aux{#1}{#2}}%
}
\newcommand{\myscale@aux}[2]{%
  \ifnum#1>#2
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\myscale@neg{#1}{#2}}%
  {\myscale@pos{#1}{#2}}%
}
\newcommand{\myscale@neg}[2]{%
  $#1$\expandafter\myscale@neg@aux\expandafter{\the\numexpr#1-1}{#2}%
}
\newcommand{\myscale@neg@aux}[2]{%
  \ifnum#1<#2
    \expandafter\@gobble
  \else
    \space$#1$\expandafter\@firstofone
  \fi
  {\expandafter\myscale@neg@aux\expandafter{\the\numexpr#1-1}{#2}}%
}
\newcommand{\myscale@pos}[2]{%
  $#1$\expandafter\myscale@pos@aux\expandafter{\the\numexpr#1+1}{#2}%
}
\newcommand{\myscale@pos@aux}[2]{%
  \ifnum#1>#2
    \expandafter\@gobble
  \else
    \space$#1$\expandafter\@firstofone
  \fi
  {\expandafter\myscale@pos@aux\expandafter{\the\numexpr#1+1}{#2}}%
}
\makeatother

\begin{document}

\myscale{1}{6}

\myscale{1}{1}

\myscale{6}{1}

\myscale{1}{-1}

\edef\temp{\myscale{1}{6}}

\texttt{\meaning\temp}

\end{document}

在此处输入图片描述

带有用于不同格式的可选参数(当然不可扩展)。第一个可选参数\myscale是分隔符(默认为空格);第二个参数是最后两个项目之间的分隔符(默认与第一个参数相同);如果指定,则第三个参数将用于多个项目中的最后两个项目之间,如果只有两个项目(例如牛津逗号),则使用第二个参数。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\myscale}{O{~}oomm}
 {
  \IfNoValueTF{#2}
   {
    \alain_myscale:nnnnn { #1 } { #1 } { #1 } { #4 } { #5 }
   }
   {
    \IfNoValueTF{#3}
     { \alain_myscale:nnnnn { #2 } { #1 } { #2 } { #4 } { #5 } }
     { \alain_myscale:nnnnn { #2 } { #1 } { #3 } { #4 } { #5 } }
   }
 }

\seq_new:N \l_alain_myscale_seq

\cs_new_protected:Nn \alain_myscale:nnnnn
 {
  \seq_clear:N \l_alain_myscale_seq
  \int_step_inline:nnnn { #4 } { \int_compare:nTF { #4 > #5 } { -1 } { 1 } } { #5 }
   {
    \seq_put_right:Nn \l_alain_myscale_seq { $##1$ }
   }
  \seq_use:Nnnn \l_alain_myscale_seq { #1 } { #2 } { #3 }
 }
\ExplSyntaxOff

\begin{document}

\myscale{1}{6}

\myscale[, ]{1}{6}

\myscale[, ][ and ]{1}{6}

\myscale[, ][ and ][, and ]{1}{6}

\myscale{1}{1}

\myscale{6}{1}

\myscale{1}{-1}

\end{document}

在此处输入图片描述

答案3

这是一个基于 LuaLaTeX 的解决方案。 的两个参数\myscale可以是任何在 TeX 和 Lua 的组合规则下求值为数字的表达式。 如果宏的第二个参数小于第一个参数,则不会打印任何内容。

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\newcommand{\myscale}[2]{\directlua{%
     for i = #1, #2 do tex.print(i) end}}
\newcommand\myvar{1}
\begin{document}
\myscale{1}{6}            % integers from 1 to 6

\myscale{1+\myvar}{2*2^3} % integers from 2 to 16

\myscale{1}{0}            % nothing is printed
\end{document}

附录: 如果减少允许算术序列(在这种情况下的第二个参数\myscale小于第一个参数),需要将Luafor循环的可选第三个参数——控制增量的步长——设置为-1

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\newcommand\myscale[2]{\directlua{%
         local incr = 1
         if #1 > #2 then incr = -1 end % set to -1 if decreasing sequence
         for i = #1, #2, incr do tex.print(i) end}}
\newcommand\myvar{1}  % a dummy macro
\begin{document}
\myscale{1}{6}

\myscale{math.log(1)}{2^3-\myvar}

\myscale{\myvar+2^math.exp(0)}{math.log(\myvar)}
\end{document}

答案4

\whiledo包装的 使用 ifthen

平均能量损失

    \documentclass{article}
    \usepackage{ifthen}    
    \newcounter{mycount}
    \newcommand{\myscale}[2]{
    \setcounter{mycount}{#1}
    \whiledo{\value{mycount}<#2}
    {\arabic{mycount}, \stepcounter{mycount}}%
    \arabic{mycount}.}
    \begin{document}
    \myscale{1}{6}\par
    \myscale{-4}{4}
    \end{document}

或者使用以下forloop包:

\documentclass{article}
\usepackage{forloop}    
\newcounter{mycount}
\newcommand{\myscale}[2]{
\setcounter{mycount}{#1}
\forloop{mycount}{#1}{\value{mycount} < #2}%
{\arabic{mycount}, }%
\arabic{mycount}.}
\begin{document}
\myscale{1}{6}\par
\myscale{-4}{4}
\end{document}

相关内容