如何将长数字按自定义长度分组?

如何将长数字按自定义长度分组?

我有一个非常大的数字,它占了好几行。我想在数学模式下排版它,这样通过将数字分组为长度为 的块,它变得更易读n

的答案帖子不适用于我,因为

  • 我想从第一个数字开始分组,而不是从最后一个数字开始(即我想要 123 456 7 而不是 1 234 567)
  • 我还希望组的长度不是 3(即 1234 5678 而不是 12 345 678)

是否有一个简单且好的方法来实现这一点?

编辑:感谢@leandriis,我得到了这个代码(取自这里):

\usepackage{xstring}
\def\split#1#2{%
    \StrSplit{#2}{#1}\tempa\tempb
    \tempa\let\tempa\empty
    \unless\ifx\tempb\empty\def\tempa{\,\split{#1}\tempb}\fi
    \tempa
}

这让我可以使用

\split{4}{12345678}

但是,由于我的数字有数百位,因此我仍然需要自动插入换行符。也许甚至可以对齐新行中的数字,以便所有 \,-分隔符都对齐?

答案1

这是一个\groupify命令:

\groupify[<sep>]{<n>}{<tokens>}

它将分隔项目<tokens><n>(从左侧开始),并<sep>在每对组之间插入。默认值为<sep>\,\allowbreak允许换行的细空格)。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand \groupify { O{\,\allowbreak} m m }
  { \jakob_groupify:nnn {#1} {#2} {#3} }
\cs_new:Npn \jakob_groupify:nnn #1 #2 #3
  { \__jakob_groupify_loop:nnw { 1 } {#2} #3 \q_recursion_tail {#1} \q_recursion_stop }
\cs_new:Npn \__jakob_groupify_loop:nnw #1 #2 #3
  {
    \quark_if_recursion_tail_stop:n {#3}
    \exp_not:n {#3}
    \int_compare:nNnTF {#1} = {#2}
      { \__jakob_groupify_sep:n }
      { \exp_args:Nf \__jakob_groupify_loop:nnw { \int_eval:n { #1+1 } } }
          {#2}
  }
\cs_new:Npn \__jakob_groupify_sep:n #1 #2 \q_recursion_tail #3
  {
    \tl_if_empty:nF {#2} { \exp_not:n {#3} }
    \__jakob_groupify_loop:nnw { 1 } {#1}
    #2 \q_recursion_tail {#3}
  }
\ExplSyntaxOff
\begin{document}
\groupify{3}{01234567890123456789012345678901234567890123456789}

\groupify[ X ]{5}{01234567890123456789012345678901234567890123456789}
\end{document}

答案2

这是一个基于 LuaLaTeX 的解决方案。它由一个groupnum执行实际工作的 Lua 函数和一个名为的 LaTeX 宏组成\groupnum,该宏接受两个参数。第一个是可选的,用于设置分组长度;默认长度为 4。第二个是应该分组的数字。

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function groupnum ( s , n )
   while #s > n do
      tex.sprint ( s:sub(1,n) .. "\\mkern3mu\\allowbreak")
      s = s:sub(n+1) 
   end
   tex.sprint ( s )
end   
\end{luacode}
%% LaTeX utility macro:
\newcommand\groupnum[2][4]{\directlua{groupnum("#2",#1)}}

\begin{document}
\raggedright
$\groupnum{123456789012345}$

$\groupnum[5]{123456789012345}$

$\groupnum[7]{1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890}$
\end{document}

答案3

我可以提供一个\romannumeral0基于 -expansion 的解决方案,它不需要任何 ε-TeX 扩展或类似的东西,并且在两个扩展步骤/两次命中之后提供结果\expandafter

该例程\groupify处理应形成单个字符序列的非分隔参数序列,例如数字。

句法:

\groupify{⟨characters/non-delimited arguments to group⟩}%
         {⟨token for formatting a group of characters⟩}%
         {⟨separator-tokens to insert behind a formatted group of characters⟩}%
         {⟨remainder k⟩}%
         {⟨modulus n⟩}%

扩张将不是被应用于⟨characters/non-delimited arguments to group⟩

该例程的工作方式就像您从左到右计算非分隔参数/字符一样,从 1 开始。

⟨k⟩每个字符号与模数一致的字符后都会开始一个新的字符组⟨n⟩

如果⟨n⟩是非正整数,则不会进行字符分组。

每组字符将嵌套在花括号中,并以 开头⟨token for formatting a group of characters⟩和结尾⟨separator-tokens to insert behind a formatted group of characters⟩
最后一组字符不会以 结尾⟨separator-tokens to insert behind a formatted group of characters⟩

⟨k⟩和都⟨n⟩必须是⟨number⟩TeXbook 意义上的表示 - 数量的序列。如果不是,则可能会/将会发生各种错误。对此没有实现检查/错误捕获。(请注意,可靠地测试任意标记序列是否形成⟨number⟩TeXbook 意义上的 - 数量是不可行的。原因:任意标记序列可以形成任意基于扩展的算法。任意基于扩展的算法形成⟨number⟩TeXbook 意义上的 -quantitiy 的一个要求是算法终止(没有错误)。因此,这种测试需要找出任意基于扩展的算法是否终止(没有错误)。因此,实施这种测试的任务意味着面临停机问题。 艾伦·麦西森·图灵于 1936 年证明,不可能存在一种通用算法来解决所有可能的程序输入对的停机问题。

\documentclass[a4paper, landscape]{article}

\makeatletter
%%-----------------------------------------------------------------------------
%% Layout of example document
%%-----------------------------------------------------------------------------
\@ifundefined{pagewidth}{}{\pagewidth=\paperwidth}
\@ifundefined{pdfpagewidth}{}{\pdfpagewidth=\paperwidth}
\@ifundefined{pageheight}{}{\pageheight=\paperheight}
\@ifundefined{pdfpageheight}{}{\pdfpageheight=\paperheight}
\textwidth=\paperwidth
\oddsidemargin=1.25cm
\topmargin=\oddsidemargin
\advance\textwidth-2\oddsidemargin
\advance\oddsidemargin-1in
\evensidemargin=\oddsidemargin
\marginparwidth=1.5cm
\marginparsep=.5cm
\parindent=0ex
\parskip=.25\baselineskip
\textheight=\paperheight
\advance\textheight-2\topmargin
\footskip=.5\topmargin
\begingroup
\normalsize\normalfont\selectfont
\advance\footskip.5\ht\strutbox
\expandafter\endgroup
\expandafter\footskip\expandafter=\the\footskip
\begingroup
\normalsize\normalfont\selectfont
\expandafter\endgroup\expandafter\topskip\expandafter=\the\ht\strutbox
\advance\topmargin-1in
\headheight=0ex
\headsep=0ex
\pagestyle{plain}%
\makeatother

\makeatletter
%%-----------------------------------------------------------------------------
%% Code for \groupify
%%-----------------------------------------------------------------------------
%% Exchange things in the token-stream:
%%.............................................................................
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
  {\@firstoftwo\expandafter{} \@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument is blank (empty or only spaces):
%%-----------------------------------------------------------------------------
%% -- Take advantage of the fact that TeX discards space tokens when
%%    "fetching" _un_delimited arguments: --
%% \UD@CheckWhetherBlank{<Argument which is to be checked>}%
%%                      {<Tokens to be delivered in case that
%%                        argument which is to be checked is blank>}%
%%                      {<Tokens to be delivered in case that argument
%%                        which is to be checked is not blank>}%
\newcommand\UD@CheckWhetherBlank[1]{%
  \romannumeral\expandafter\expandafter\expandafter\@secondoftwo
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo#1{}.}%
}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%   \UD@ExtractFirstArg{ABCDE} yields  A
%%   \UD@ExtractFirstArg{{AB}CDE} yields  AB
%%-----------------------------------------------------------------------------
\newcommand\UD@RemoveTillUD@SelDOm{}%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
\newcommand\UD@ExtractFirstArg[1]{%
  \romannumeral0%
  \UD@ExtractFirstArgLoop{#1\UD@SelDOm}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
  {\@firstoftwo\expandafter{} \@secondoftwo{}#1}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%-----------------------------------------------------------------------------
\newcommand\groupify[5]{%
  % #1 = characters to group
  % #2 = tokens for formatting a group of characters
  % #3 = separator-tokens to insert behind a group of characters if the number 
  %      denoting the position of the current character is congruent k modulo n
  % #4 = remainder k
  % #5 = modulus n
  \romannumeral0%
  \expandafter\UD@CheckWhetherNull\expandafter{\romannumeral#5}{%
    \groupifynormalizeloop{#1}{#2}{}%
  }{%
    \expandafter\UD@CheckWhetherNull\expandafter{\romannumeral#4}{%
      \expandafter\UD@CheckWhetherNull\expandafter{\romannumeral-\number#4}{%
        \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
          \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
            \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
              \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
                \preparegroupifyloop
              }%
            }%
          }%
        }%
        {\@firstoftwo}%
      }{%
        \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
          \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number-\number#4 000}{%
            \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
              \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number-\number#4 000}{%
                \preparegroupifyloop
              }%
            }%
          }%
        }%
        {\@secondoftwo}%
      }%
    }{%
      \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
        \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#4 000}{%
          \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#5 000}{%
            \expandafter\UD@PassFirstToSecond\expandafter{\romannumeral\number\number#4 000}{%
              \preparegroupifyloop
            }%
          }%
        }%
      }%
      {\@firstoftwo}%
    }%
    {#1}{{#2}{#3}}{\@firstoftwo}%
  }%
}%
\newcommand\preparegroupifyloop[8]{%
  #8{%
    %#1 = characters m in the amount of remainder k
    %#2 = characters m in the amount of modulus n
    %#3 = characters m in the amount of remainder k
    %#4 = characters m in the amount of modulus n
    %#5 = positive/negative remainder \@firstoftwo/\@secondoftwo
    %#6 = number to group
    %#7 = formatting-tokens/separator-tokens
    %#8 = stage of loop / \@firstoftwo/\@secondoftwo
    \UD@CheckWhetherNull{#1}{%
      \UD@CheckWhetherNull{#2}{%
        \groupifyloop{#4}{#4}{#4}{#4}{#6}{#7}{}{\@firstoftwo}{}%
      }{%
        #5{%
          \preparegroupifyloop{}{#2}{#4}{#4}{}{#6}{#7}{\@secondoftwo}%
        }{%
          \groupifyloop{#2}{#4}{#2}{#4}{#6}{#7}{}{\@firstoftwo}{}%
        }%
      }%
    }{%
      \UD@CheckWhetherNull{#2}{%
        \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#4}%
      }{%
        \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#2}%
      }%
      {%
        \expandafter\preparegroupifyloop\expandafter{\@gobble#1}%
      }{#3}{#4}{#5}{#6}{#7}{#8}%
    }%
  }{%
    %#1 = empty/not needed in this stage
    %#2 = remainder of the modulus
    %#3 = difference between remainder of the modulus and modulus
    %#4 = characters m in the amount of modulus n
    %#5 = empty/not needed in this stage
    %#6 = number to group
    %#7 = formatting-tokens/separator-tokens
    %#8 = stage of loop / \@secondoftwo
    \UD@CheckWhetherNull{#2}{%
      \groupifyloop{#3}{#4}{#3}{#4}{#6}{#7}{}{\@firstoftwo}{}%
    }{%
      \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#3}{%
        \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#2}{\preparegroupifyloop{}}%
      }{#4}{#5}{#6}{#7}{#8}%
    }%
  }%
}%
\newcommand\groupifyloop[9]{%
  % #1 = remainder
  % #2 = module
  % #3 = remainder
  % #4 = module
  % #5 = characters to group
  % #6 = formatting-tokens/separator-tokens
  % #7 = characters grouped so far
  % #8 = indicator whether on start of interval (\@firstoftwo) or not (\@secondoftwo)
  % #9 = group collected so far
  \UD@CheckWhetherBlank{#5}{%
    \UD@CheckWhetherNull{#9}{ #7}{%
      \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo#6}%
      {\UD@Exchange}{\UD@PassFirstToSecond}{#9}{%
        \expandafter\UD@Exchange\expandafter{\@firstoftwo#6}{%
          \UD@CheckWhetherNull{#7}{ }{%
            \expandafter\UD@Exchange\expandafter{\@secondoftwo#6}{ #7}%
          }%
        }%
      }%
    }%
  }{%
    \expandafter\UD@PassFirstToSecond\expandafter{%
      \romannumeral0%
      \expandafter\expandafter\expandafter\UD@Exchange\expandafter\expandafter\expandafter{%
        \UD@ExtractFirstArg{#5}%
       }{%
         \UD@CheckWhetherNull{#1}{#8{ }{ #9}}{ #9}%
       }%
    }{%
      \UD@CheckWhetherNull{#1}{%
        \UD@CheckWhetherNull{#2}{%
          \UD@PassFirstToSecond{\@firstoftwo}%
        }{%
          \UD@PassFirstToSecond{\@secondoftwo}%
        }%
      }{%
        \UD@CheckWhetherNull{#2}{%
          \UD@PassFirstToSecond{\@firstoftwo}%
        }{%
          \UD@PassFirstToSecond{#8}%
        }%
      }%
      {%
        \expandafter\UD@PassFirstToSecond\expandafter{%
          \romannumeral0%
          \UD@CheckWhetherNull{#1}{#8{\@secondoftwo}{\@firstoftwo}}{\@firstoftwo}%
          { #7}%
          {%
            \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo#6}%
            {\UD@Exchange}{\UD@PassFirstToSecond}{#9}{%
              \expandafter\UD@Exchange\expandafter{%
                \@firstoftwo#6%
              }{%
                \UD@CheckWhetherNull{#7}{ }{%
                  \expandafter\UD@Exchange\expandafter{%
                    \@secondoftwo#6%
                  }{ #7}%
                }%
              }%
            }%
          }%
        }%
        {%
          \UD@PassFirstToSecond{#6}{%
            \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#5}{%
              \UD@Exchange{{#3}{#4}}{%
                \UD@CheckWhetherNull{#2}{%
                  \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#4}%
                  {\expandafter\UD@PassFirstToSecond\expandafter{\@gobble#3}{\groupifyloop}}%
                }{%
                  \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#2}%
                  {%
                    \UD@CheckWhetherNull{#1}{%
                      \groupifyloop{}%
                    }{%
                      \expandafter\groupifyloop\expandafter{\@gobble#1}%
                    }%
                  }%
                }%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
}%
\newcommand\groupifynormalizeloop[3]{%
  % #1 = characters to group
  % #2 = tokens for formatting a group of characters
  % #3 = sequence normalized so far
  \UD@CheckWhetherBlank{#1}{ #2{#3}}{%
    \expandafter\UD@PassFirstToSecond\expandafter{%
      \romannumeral0%
      \expandafter\expandafter\expandafter\UD@Exchange
      \expandafter\expandafter\expandafter{\UD@ExtractFirstArg{#1}}{ #3}%
    }{%
      \expandafter\groupifynormalizeloop\expandafter{\@gobble#1}{#2}%
    }%
  }%
}%
%%-----------------------------------------------------------------------------
%% End of code for \groupify
%%-----------------------------------------------------------------------------
\makeatother

\begin{document}

\begin{tabular}{|lll|}%
\hline
\textbf{\LaTeX-code:}&$\to$&\textbf{Result:}\\\hline
\verb|A\groupify{123 4 51 2 3 4 5 1 2 345123}{\textbf}{\,\allowbreak}{3}{0}B|&$\to$&
A\groupify{123 4 51 2 3 4 5 1 2 345123}{\textbf}{\,\allowbreak}{3}{0}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-5}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-5}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-4}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-4}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-3}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-3}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-2}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-2}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-1}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-1}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{0}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{0}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{1}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{1}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{2}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{2}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{3}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{3}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{4}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{4}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{5}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{5}{5}B\\
\verb|A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{6}{5}B|&$\to$&
A\groupify{123451234512345123}{\textbf}{\,\allowbreak}{6}{5}B\\
\hline
\end{tabular}%

\vfill

\verb|\groupify| requires two expansion-steps/two ``hits'' by \verb|\expandafter|
to deliver the result---\verb|\testdefiner| ``hits'' \verb|\groupify| by \verb|\expandafter|
twice before defining \verb|\test|:

\vfill

\newcommand\testdefiner[1]{%
  \expandafter\expandafter\expandafter\gdef
  \expandafter\expandafter\expandafter\test
  \expandafter\expandafter\expandafter{%
  \expandafter\expandafter\expandafter A%
   #1%
  B}%
}%

\newcommand\showtest{%
  $\to$ \texttt{\string\test\ \meaning\test}%
}%


\begin{tabular}{|l|}%
\hline
\verb|\testdefiner{\groupify{123 4 51 2 3 4 5 1 2 345123}{\textbf}{\,\allowbreak}{3}{0}}|%
\testdefiner{\groupify{123 4 51 2 3 4 5 1 2 345123}{\textbf}{\,\allowbreak}{3}{0}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-5}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-5}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-4}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-4}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-3}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-3}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-2}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-2}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-1}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{-1}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{0}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{0}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{1}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{1}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{2}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{2}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{3}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{3}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{4}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{4}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{5}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{5}{5}}\\
\showtest\\
\hline
\verb|\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{6}{5}}|%
\testdefiner{\groupify{123451234512345123}{\textbf}{\,\allowbreak}{6}{5}}\\
\showtest\\
\hline
\end{tabular}

\newpage

\newlength\chunkwidth
\newcommand\chunkbox[1]{%
  \ifvmode
    \sloppy\leavevmode
    \hbox to\chunkwidth{\hfil$#1$}%
  \else
    \hbox to\chunkwidth{$#1$\hfil}%
  \fi
}%

\newcommand\ChunkGroupifyParagraph[4]{%
  \begingroup
  \par
  \settowidth\chunkwidth{#1}%
  \groupify{#2}{\chunkbox}{\thinspace\allowbreak}{#3}{#4}%
  \par
  \endgroup
}%

\ChunkGroupifyParagraph
  {12345}{%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
  }{2}{5}%

\bigskip

\ChunkGroupifyParagraph
  {12345678}{%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
  }{3}{8}%

\bigskip

\ChunkGroupifyParagraph
  {000}{%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
    12345123451234512345123451234512345123451234512345%
  }{0}{3}%

\end{document}

在此处输入图片描述 在此处输入图片描述

答案4

一个更简单、更容易理解的例程:

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\printlargenumber}{O{3}m}
 {
  \jakob_largenumber_print:nn { #1 } { #2 }
 }

\seq_new:N \l__jakob_largenumber_input_seq

\cs_new_protected:Nn \jakob_largenumber_print:nn
 {
  \seq_set_split:Nnn \l__jakob_largenumber_input_seq { } { #2 }
  \seq_indexed_map_inline:Nn \l__jakob_largenumber_input_seq
   {
    ##2 % the current digit
    \int_compare:nT { \int_mod:nn { ##1 } { #1 } = 0 }
     {
      \hspace{0.16667em ~ plus 0.16667em ~ minus 0.08333em}
     }
   }
 }

\ExplSyntaxOff

\begin{document}

\printlargenumber{
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
}

\printlargenumber[6]{
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789
}

\end{document}

参数在“无”处被拆分,这样空格就会被忽略,因此这简化了输入,因为您不必担心结束行。之后,开始对序列进行循环;如果我们已完成可选参数中规定的步骤(默认为 3),则会添加一个灵活的空格,以帮助进行对齐。

在此处输入图片描述

相关内容