5

I would like a command \initials that takes a string and inserts another string (e.g., ~) between each character. So \initials{GRRM} would be typeset as G~R~R~M.

4 Answers 4

7

An expandable solution that works correctly for umlauts and other non-ASCII characters in 8bit engines:

\documentclass{article}

% unexpanded will tokenize the `~` before \ExplSyntaxOn, making it the active
% tilde
\unexpanded{\ExplSyntaxOn\NewExpandableDocumentCommand\initials{O{~}m}}
  { \fredrik_initials:nn {#1} {#2} }
\cs_new:Npn \fredrik_initials:nn #1#2
  {
    \exp_not:e
      {
        \use:e
          {
            \exp_not:N \use_none:nn
            \text_map_function:nN {#2} \__fredrik_initials:nw
            \use_none:nnn \q_stop \use_none:n {#1}
          }
      }
  }
\cs_new:Npn \__fredrik_initials:nw #1 #2 \q_stop \use_none:n #3
  {
    \exp_not:n { \exp_not:n {#3} } \exp_not:n { \exp_not:n {#1} }
    #2 \q_stop \use_none:n {#3}
  }
\ExplSyntaxOff

\begin{document}
\initials{FOOBÄR}

\initials[*]{FOOBÄR}
\end{document}

enter image description here

5

Using * rather than ~ so it is visible for debugging.

enter image description here

\documentclass{article}

\def\initials#1{\xinitials#1\relax}
\def\xinitials#1#2{#1\ifx\relax#2\else*\expandafter\xinitials\expandafter#2\fi}


\begin{document}

\initials{GRRM}

\end{document}

5

Maybe your initials aren't just ASCII characters. In this case you need something deeper than just processing byte by byte: the text is split grapheme by grapheme into a sequence which is “used” adding the desired tokens in between each item.

Since ~ cannot easily be used in the expl3 programming environment, I take an indirect approach, defining a generic command and specializing it for inserting ~ when it has the usual meaning.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\insertbetween}{mm}
 {% #1 = text, #2 = what to insert
  \fredrik_initials:nn { #1 } { #2 }
 }

\seq_new:N \l__fredrik_initials_in_seq

\cs_new_protected:Nn \fredrik_initials:nn
 {
  \seq_clear:N \l__fredrik_initials_in_seq
  \text_map_inline:nn { #1 }
   {
    \seq_put_right:Nn \l__fredrik_initials_in_seq { ##1 }
   }
  \seq_use:Nn \l__fredrik_initials_in_seq { #2 }
 }

\ExplSyntaxOff

\NewDocumentCommand{\initials}{m}{\insertbetween{#1}{~}}

\begin{document}

\initials{ČÉABÔ}

\insertbetween{ČÉABÔ}{*}

\end{document}

enter image description here

2

Here, I use a token cycle to accomplish the task. After each "character" that is read from the input stream, a check is performed to see if it is the last token in the stream (when the next 'peeked' token is \empty while the group depth \tcdepth is 0).

If it is not the end of the stream, the tokens that comprise the user-defined \myfill are added after the echoed token itself.

This approach has the added advantage that non-characters (groups, macros, and spaces) are echoed to the output stream, without the addition of \myfill. Therefore, as in the 3rd example, internal italics can be preserved over part of the input stream.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tokcycle}
\newcommand\initials[1]{\tokencycle
  {\addcytoks{##1}\tcpeek{\z}%
   \ifx\empty\z
     \ifnum\tcdepth=0 \else\addcytoks[1]{\myfill}\fi
   \else\addcytoks[1]{\myfill}\fi}% CHARACTERS
  {\processtoks{##1}}% GROUPS
  {\addcytoks{##1}}%MACROS
  {\addcytoks{##1}}%SPACES
  #1\endtokencycle}
\begin{document}
\newcommand\myfill{~}
\initials{GRRM}

\renewcommand\myfill{*}
\initials{GRRM}

\initials{G\textit{RR}M}

Detokenized: ``\detokenize\expandafter{\the\cytoks}''
\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .