2

Macrons in LaTeX are typset with '\=' preceeding the character, for example '\=o' creates an 'o' with a macron. I would like to use stringstrings to define a newcommand to replace all '/' characters with the macron '\=' sequence. The catch- the letter 'i' is special. In LaTeX you have to use a non-dotted 'i', e.g. '\={\i}' in order to create the 'i' with a macron. This special case is breaking my new command. Here is my attempt at this:

\documentclass{article}
\usepackage{stringstrings}
\newcommand\macronify[1]{%
  \convertword[q]{#1}{/i}{\={\i}}%
  \convertchar{\thestring}{/}{\=}%
}
\begin{document}
This is a test: \macronify{laud/o, laud/are, laud/av/i, laudatum}.
\end{document}

Running pdflatex on this creates a PDF, and the first two words do have the macrons as expected, but the 3rd word with the troublesome 'i' is messed up. It is displayed as ' . . 22 .. , laudatum'.

Thanks for any help.

1

Here is a easier solution involving xstring

\documentclass{article}
\usepackage{xstring}
\newcommand\macronify[1]{%
    \saveexpandmode\expandarg
    \StrSubstitute{\noexpand#1}{/i}{\noexpand\=\i}[\temp]%
    \StrSubstitute\temp/{\noexpand\=}\restoreexpandmode
}
\begin{document}
This is a test: \macronify{laud/o, laud/are, laud/av/i, laudatum}.
\end{document}
1

I recommend against the use of stringstrings package for this task, because it is slow, inefficient, and not intended for manipulating non-regex tokens.

But, as a matter of pride, having written the package long ago, I feel compelled to solve the problem using it. I did have to edit a package routine that had forgotten a % or two and thus introduced stray spaces without the edit.

The key is, for manipulating non-regex tokens (like \= and \i), the capability is quite limited and involves encoding such tokens in ascii escape sequences, manipulating those sequences with regex routines, and then repopulating the resulting string with the original macro tokens.

\documentclass{article}
\usepackage{stringstrings}
\newcommand\macronify[1]{%
  \encodetoken{\i}%
  \encodetoken[2]{\=}%
  \convertword[e]{#1}{/i}{\=\i}%
  \convertchar[e]{\thestring}{/}{\=}%
  \retokenize{\thestring}\thestring%
  \decodetoken{\i}%
  \decodetoken[2]{\=}%
}

%%%%% ADDED SOME MISSING % SIGNS IN THIS stringstings CODE
\makeatletter
\renewcommand\testmatchingchar[3]{%
  \setbox0=\hbox{%
  \substring[e]{#1}{#2}{#2}\+%
  \isnextbyte[q]{\EscapeChar}{#3}%
  \if T\theresult%
    \isnextbyte[q]{\EscapeChar}{\thestring}%
    \if T\theresult%
      \edef\@testcode{\expandafter\@DiscardNextChar\expandafter{#3}}%
      \edef\@teststring{\@DiscardNextChar{\thestring}}%
      \if \@teststring\@testcode\matchingchartrue\else\matchingcharfalse\fi
    \else
      \global\matchingcharfalse%
    \fi
  \else
    \if \thestring#3\global\matchingchartrue\else\global\matchingcharfalse\fi
  \fi}%
\?}
%%%%%
\makeatother

\begin{document}
This is a test: \macronify{laud/o, laud/are, laud/av/i, laudatum}.
\end{document}

enter image description here

I consider my honor defended.

0

I'm not sure how to do it with stringstrings, but there's an easier method:

\documentclass{article}
\usepackage{xparse}

\DeclareTextCompositeCommand{\=}{\encodingdefault}{i}{\={\i}}

\ExplSyntaxOn
\NewDocumentCommand\macronify{m}
 {
  \tl_set:Nn \l_tmpa_tl { #1 }
  \tl_replace_all:Nnn \l_tmpa_tl { / } { \= }
  \tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff

\begin{document}
This is a test: \macronify{laud/o, laud/are, laud/av/i, laudatum}.
\end{document}

The first instruction defines \=i as a known combination that is transformed into \={\i}. Thus we just have to substitute / with \= and this is the job of \tl_replace_all:Nnn.

enter image description here

Note that your macro with stringstrings applied to laud/o produces

laud\unhbox \voidb@x \bgroup \let \unhbox \voidb@x \setbox \@tempboxa \hbox {o\global \mathchardef \accent@spacefactor \spacefactor }\accent 22 o\egroup \spacefactor \accent@spacefactor

which is not something I'd like to transform my tokens into.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.