我有一个非常大的数字,它占了好几行。我想在数学模式下排版它,这样通过将数字分组为长度为 的块,它变得更易读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),则会添加一个灵活的空格,以帮助进行对齐。