如何重复字符串中的所有字符?

如何重复字符串中的所有字符?

我有一个格式化单个字符的命令,我们称之为\d{}。 (在我的例子中, \d{} 在中文字符下添加一个点,因为这是强调中文文本的习惯)。

我想定义一个新命令\ds{},使其适用\d{}于字符串的每个字母。

例如\ds{abc}相当于\d{a}\d{b}\d{c}

谢谢!

答案1

您可以使用\@tfor。我还根据您的意愿提供了下面的点的更好的重新定义:

\documentclass{article}
\usepackage{graphicx}

\let\d\relax
\DeclareRobustCommand{\d}[1]{%
  \oalign{#1\cr\hidewidth\scalebox{0.5}{\textbullet}\hidewidth\cr}%
}
\makeatletter
\newcommand{\ds}[1]{%
  \@tfor\next:=#1\do{\d{\next}}%
}
\makeatother

\begin{document}

x\d{d}\d{s}\d{a}x

x\ds{dsa}x

\end{document}

在此处输入图片描述

做什么\@tfor?它的语法是

\@tfor<scratch macro>:=<tokens>\do{<code>}

临时宏传统上是\next,但它可以是任何东西。<tokens>部分是任何(括号平衡)标记列表。在循环中,LaTeX 本质上是\def<scratch macro>{<next token>},因此

\@tfor\next:=dsa\do{\d{\next}}

将执行

\def\next{d}\d{\next}\def\next{s}\d{\next}\def\next{a}\d{\next}

然而,\@tfor\next:=d {sa}\do{\d{\next}}我们只会得到

\def\next{d}\d{\next}\def\next{sa}\d{\next}

显式空格标记将被忽略,并且括号内的标记组将被视为一个。

类似的例子expl3\tl_map_inline:nn

\documentclass{article}
\usepackage{xparse}
\usepackage{graphicx}

\let\d\relax
\DeclareRobustCommand{\d}[1]{%
  \oalign{#1\cr\hidewidth\scalebox{0.5}{\textbullet}\hidewidth\cr}%
}

\ExplSyntaxOn
\NewDocumentCommand{\ds}{m}
 {
  \tl_map_inline:nn { #1 } { \d { ##1 } }
 }
\ExplSyntaxOff

\begin{document}

x\d{d}\d{s}\d{a}x

x\ds{dsa}x

x\ds{d sa{bc}}x

\end{document}

#1没有使用临时宏:循环中的当前项由(像往常一样,成为##1定义主体中的一部分)表示。

在这种特殊情况下,仅应用一个命令并使用当前项目作为参数,可以使用\tl_map_function:nN

\NewDocumentCommand{\ds}{m}
 {
  \tl_map_function:n { #1 } \d
 }

效果相同,但更短。它也可以出现在完整扩展上下文中(由于 ,不适用于此特定情况\d)。

结果预览

答案2

此解决方案允许自动换行并处理单词之间的空格。此外,该[w]选项允许对每个单词而不是每个字符执行任务。'

在 MWE 中,我通过各种定义的任务进行了演示:

  1. 重打每个字符(2 种不同的设置)

  2. 在每个字符下放一个点

  3. 每个单词下加一个分号

  4. 应用额外的字符间距

  5. 应用额外的词间空间。

\charop{}任务在for 字符和\wordop{}for 单词中定义,而\chariterate[]{}宏执行迭代。以下是 MWE:

% WHILE THIS EXAMPLE IS SET UP FOR BOLDING A CALLIGRAPHIC FONT
% ITS GENERAL USE IS TO DO SOMETHING ON EACH char OF ITS ARGUMENT, ALLOWING LINE WRAP
% THE [W] OPTION TO \chariterate DOES SOMETHING TO EACH WORD.
\documentclass[10pt,a4paper,BCOR10mm,DIV11,toc=listof,parskip=full, openany]{scrbook}
\usepackage{stackengine}
\newcommand\chariterate[2][c]{\if w#1\worditeratehelper#2 \relax\relax\else
  \chariteratehelpA#2 \relax\relax\fi}
\def\chariteratehelpA#1 #2\relax{%
  \chariteratehelpB#1\relax\relax%
  \ifx\relax#2\else\ \chariteratehelpA#2\relax\fi
}
\def\chariteratehelpB#1#2\relax{%
  \charop{#1}%
  \ifx\relax#2\else
    \chariteratehelpB#2\relax%
  \fi
}
\def\worditeratehelper#1 #2\relax{%
  \wordop{#1}%
  \ifx\relax#2\else\ \worditeratehelper#2\relax\fi
}
\def\charop#1{#1}
\def\wordop#1{#1}
% THIS EXAMPLE ARTIFICIALLY BOLDS EACH char WITH A SHIFTED OVERSTRIKE
\def\charopA{%
  %\def\useanchorwidth{T}%
  \def\stacktype{L}%
  \def\stackalignment{l}%
  \def\calup{.2pt}%
  \def\calover{.15pt}%
  \renewcommand\charop[1]{\stackon[\calup]{##1}{\kern\calover##1}}%
}
% HERE'S AN EXAMPLE PLACING DOT UNDER EACH char
\def\charopB{%
  \def\useanchorwidth{T}%
  \def\stacktype{L}%
  \def\stackalignment{c}%
  \renewcommand\charop[1]{\stackunder[3pt]{##1}{.}}%
}
% EXTRA INTER-CHARACTER SPACE
\def\charopC{\renewcommand\charop[1]{##1\,}}
% HERE'S AN EXAMPLE PLACING DOT UNDER EACH WORD
\def\wordopA{%
  \renewcommand\wordop[1]{\def\stackalignment{c}\stackunder[3pt]{##1}{;}}
}
% EXTRA INTER-WORD SPACE
\def\wordopB{\renewcommand\wordop[1]{##1\ \ }}
%
\newenvironment{calligraphic}%
{\fontencoding{T1}\fontfamily{pzc}\fontseries{m}\fontshape{it}\fontsize{12pt}{12pt}\selectfont}{}%
\renewcommand*{\sectfont}{\normalcolor\usefont{T1}{pzc}{m}{it}}
\begin{document}
\charopA
   \begin{calligraphic}
   Test \textbf{this is not bold}\par
   Test \chariterate{this is bold with .2pt up shift and .15pt right shift}\par
 \def\calup{.0pt}
 \def\calover{.2pt}
   Test \chariterate{this is bold with .0pt up shift and .2pt right shift}\par
   \chariterate{cvxc This is a test. This is a test. This is a test. This is a test. 
    This is a test. This is a test. This is a test. This is a test. This is a 
    test. This is a test. This is a test. This fdsfsd is a test. This is a test. 
    This is a test. This is a test. This is adfsdf  test. This is a test.}\par
   \end{calligraphic}\par
\charopB
\wordopA
   \chariterate{This is doing something to each character.}\par
   \chariterate[w]{This is doing something to each word.}\par
   \chariterate{Ich bin m{\"u}de}.  
   \chariterate[w]{Ich bin m{\"u}de}.\par
\charopC
\wordopB
   \chariterate{This is doing something to each character.}\par
   \chariterate[w]{This is doing something to each word.}\par
\end{document}

在此处输入图片描述

在最简单的情况下,仅对字符执行下点操作,代码可以大大减少:

\documentclass{article}
\usepackage{stackengine}
\newcommand\chariterate[2][c]{\if w#1\worditeratehelper#2 \relax\relax\else
  \chariteratehelpA#2 \relax\relax\fi}
\def\chariteratehelpA#1 #2\relax{%
  \chariteratehelpB#1\relax\relax%
  \ifx\relax#2\else\ \chariteratehelpA#2\relax\fi
}
\def\chariteratehelpB#1#2\relax{%
  \charop{#1}%
  \ifx\relax#2\else
    \chariteratehelpB#2\relax%
  \fi
}
\def\worditeratehelper#1 #2\relax{%
  \wordop{#1}%
  \ifx\relax#2\else\ \worditeratehelper#2\relax\fi
}
  \def\useanchorwidth{T}%
  \def\stacktype{L}%
  \def\stackalignment{c}%
  \newcommand\charop[1]{\stackunder[3pt]{#1}{.}}%
  \def\wordop#1{#1}
\begin{document}
\chariterate{This is doing something to each character.
This is doing something to each character.
This is doing something to each character.}\par
\end{document}

答案3

这个问题非常适合我的新tokcycle包,所以我只需要添加另一个答案。这里的好处是,即使文本样式发生变化并且调用宏,它也可以应用下划线。\underdot仅适用于可打印的 cat-11 标记。

\documentclass{article}
\usepackage{tokcycle}
\newcommand\underdot[1]{\ooalign{#1\cr\hfil{\raisebox{-2.5pt}{.}}\hfil}}
\tokcycleenvironment\ds
  {\tctestifcatnx A##1{\addcytoks{\underdot{##1}}}{\addcytoks{##1}}}% CHARACTER DIRECTIVE
  {\processtoks{##1}}% GROUP-CONTENT DIRECTIVE
  {\addcytoks{##1}}% MACRO DIRECTIVE
  {\addcytoks{##1}}% SPACE DIRECTIVE
\begin{document}
\ds abc\endds

\ds This can work \textbf{across \bgroup\itshape changes in text
  style\egroup, and can |escape text, for example $y=2x+1$| and pick
  up where it left off}.  However, only catcode-11 tokens are underdotted.

It can continue across paragraphs.

This is from the new \textsf{tokcycle} package released on 2019/8/21.
\endds

\end{document}

在此处输入图片描述

相关内容