我正在寻找

我正在寻找

为了避免XY问题,我将描述我正在寻找的内容(X)以及我在尝试 X 时发现的问题(Y)。需要说明的是:我并不是想解决 Y 问题,只要能解决 X 问题,我就会非常感激。

我正在寻找

我想定义一个接受字符串作为参数的宏,并且它每页显示给定数量的字符(通过调用任意宏)直到字符串完全遍历。

以下是示例:假设字符串为abcdefghijk,每页显示字符数为 3 ,\foo每个字符调用一个宏。生成的文档应如下所示。

\documentclass{article}

\newcommand\foo[1]{Hello #1}

\begin{document}
\foo{a} \foo{b} \foo{c}
\newpage
\foo{d} \foo{e} \foo{f}
\newpage
\foo{g} \foo{h} \foo{i}
\newpage
\foo{j} \foo{k}
\newpage
\end{document}

我想出了以下伪代码:

1. While the original string is not empty:
  1.1. Create a substring from the first character to the third character.
  1.2. Remove the first three characters from the original string.
  1.3. For every character in the substring:
    1.3.1. Call \foo{character}
  1.4. Call \newpage

我的尝试

对于步骤 1.2,原始字符串需要设置为其自身的子字符串,因此我尝试使用包中的\mystring将其设置为其自身的子字符串,但出现了错误。\substringstringstringsUse of \\substring doesn't match its definition.

\documentclass{article}

\usepackage{stringstrings}
\usepackage{xstring}

\begin{document}
% An arbitrary string
\def\mystring{abcdef}
% We obtain the length so that we can create a substring from the 4th
% character to the end of the string.
\StrLen{\mystring}[\mystringlen]
% When I try to display the string, I get the following error:
% ! Use of \\substring doesn't match its definition.
% \kernel@ifnextchar ...rved@d =#1\def \reserved@a {
%                                                   #2}\def \reserved@b {#3}\f...
% l.14 \mystring
%
% ?
\def\mystring{\substring{\mystring}{4}{\mystringlen}}
\mystring
\end{document}

我觉得有一种更简单的方法来实现我上面解释的伪代码。

答案1

我将文本按字素逐个拆分成一个序列,然后使用索引映射该序列,因此在指定数量的项目之后\newpage会发出命令。每个项目都根据作为第三个参数指定的模板进行包装。

\documentclass{article}
\usepackage[paperwidth=3cm,paperheight=4cm]{geometry} % just for smaller pictures

\ExplSyntaxOn

\NewDocumentCommand{\partitionstring}{mm+m}
 {% #1 = number of characters in the substrings
  % #2 = string
  % #3 = what to do to each item
  \rdrg_partition:nnn { #1 } { #2 } { #3 }
 }

\seq_new:N \l_rdrg_partition_items_seq

\cs_new_protected:Nn \rdrg_partition:nnn
 {
  \seq_clear:N \l_rdrg_partition_items_seq
  \text_map_inline:nn { #2 } { \seq_put_right:Nn \l_rdrg_partition_items_seq { ##1 } }
  \cs_set:Nn \__rdrg_partition_do:n { #3 }
  \seq_map_indexed_inline:Nn \l_rdrg_partition_items_seq
   {
    \__rdrg_partition_do:n { ##2 }
    \bool_lazy_or:nnT
     { \int_compare_p:n { \int_mod:nn { ##1 } { #1 } == 0 } } % specified interval
     { \int_compare_p:n { ##1 == \seq_count:N \l_rdrg_partition_items_seq } } % end
     { \clearpage }
   }
 }

\ExplSyntaxOff

\begin{document}

\partitionstring{3}{abćdefghìjk}{\fbox{#1}\par}

\raggedright Text on a new page

\end{document}

在此处输入图片描述

答案2

假设您想要的是字素而不是字节/字符(例如保留重音符号、正确处理 8 位输入):

\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand \blockstring { O{3} m m }
  { \rdrg_block_string:nnN {#1} {#2} #3 }
\int_new:N \l__rdrg_block_int
\tl_new:N \l__rdrg_block_tl
\cs_new_protected:Npn \rdrg_block_string:nnN #1#2#3
  {
    \group_begin:
      \int_zero:N \l__rdrg_block_int
      \tl_clear:N \l__rdrg_block_tl
      \text_map_inline:nn {#2}
        {
          \int_incr:N \l__rdrg_block_int
          \tl_put_right:Nn \l__rdrg_block_tl {##1}
          \int_compare:nNnT \l__rdrg_block_int = {#1}
            {
              \int_zero:N \l__rdrg_block_int
              \exp_args:NV #3 \l__rdrg_block_tl
              \tl_clear:N \l__rdrg_block_tl
            }
        }
      \tl_if_empty:NF \l__rdrg_block_tl
        { \exp_args:NV #3 \l__rdrg_block_tl }
    \group_end:
  }
\begin{document}

\blockstring{abcdefghijklmnopqrstuvwxyz}\fbox

\end{document}

答案3

以下是我使用 TeX 原语的解决方案尝试:

\newcount\subnum 
\newcount\subnumA

\def\processdata#1{\subnum=#1 \subnumA=0 \expandafter\processdataA\data\end}

\def\processdataA#1{\ifx\end#1\newpage\else
   \foo{#1}\space
   \advance\subnumA by1
   \ifnum\subnumA<\subnum \else \newpage \subnumA=0 \fi
   \expandafter\processdataA \fi
}

\def\foo#1{Hello #1}
\def\data{abcdefghijk}

\processdata{3} % executes \foo{a} \foo{b} \foo{c} \newpage \foo{d} ... etc.

答案4

这是一个标记循环方法。虽然此 MWE 假设输入\data都是字符(没有空格、宏或组),但可以轻松修改该方法以将这些考虑在内。

这里,为了方便查看,我将其定义\triggeraction\par\hrulefill\par而不是。\newpage

\documentclass{article}
\usepackage{tokcycle}
%
\newcommand\foo[1]{\fbox{#1}}
\newcommand\triggerindex{3}
\newcommand\triggeraction{\par\hrulefill\par}
%
\newcounter{myindex}
\Characterdirective{\addcytoks{%
  \foo{#1}\stepcounter{myindex}\ifnum\value{myindex}=\triggerindex\relax
    \triggeraction\setcounter{myindex}{0}\fi
}}
\newcommand\processfoo[1]{%
  \setcounter{myindex}{0}%
  \expandafter\tokencyclexpress#1\endtokencyclexpress
  \clearpage
}
\begin{document}
\def\data{abcdefghijk}
\processfoo{\data}
After text
\end{document}

在此处输入图片描述

相关内容