7

I try to fine-tune a macro depending on whether it is following a specific character/text. E.g.,

This is it! \great! Wait, what is \great?

should become

This is it! Grrreeeaaat! Wait, what is great?

because the first occurence of \great was after an exclamation mark, the second just in the middle of the sentence.

So I think I need something like a look behind but couldn't find anything except for \lastbox. Isn't there something like \pastlet complementing \futurelet, which allows checking for the next character, i.e. a look ahead?

nox
  • 4,160
  • 12
  • 26
  • Yo are probably much more likely to get help if you provide a full example of what you are doing. In what context this is used, etc. – daleif Jul 12 '18 at 12:19
  • I am still just playing around and want to see what I can do. A possible use could be \MakeUppercase after a period. – nox Jul 12 '18 at 12:26

2 Answers2

9
\documentclass[10pt]{report}
 \sfcode`\!=1001
 \newcommand\great{\ifnum\spacefactor=1001 Grrreeeaaat\else great\fi}
 \begin{document}
 This is it! \great! Wait, what is \great?
 \end{document}

enter image description here

See also Detect beginning of a sentence in a macro for capitalization

Ulrike Fischer
  • 327,261
5

Use the current space factor code. I also load amsthm because

\documentclass{article}

% not needed if amsthm is loaded
\def\frenchspacing{\sfcode`\.1006\sfcode`\?1005\sfcode`\!1004%
  \sfcode`\:1003\sfcode`\;1002\sfcode`\,1001 }
%%%

\makeatletter
\newcommand{\afterbigpunctornot}{%
  \ifnum\spacefactor>\sfcode`:
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

\newcommand{\great}{\afterbigpunctornot{G}{g}reat}

\begin{document}

This is it. \great! Wait, what is \great?

This is it! \great! Wait, what is \great?

This is it? \great! Wait, what is \great?

This is it, \great! Wait, what is \great?

This is it; \great! Wait, what is \great?

This is it: \great! Wait, what is \great?

\frenchspacing

This is it. \great! Wait, what is \great?

This is it! \great! Wait, what is \great?

This is it? \great! Wait, what is \great?

This is it, \great! Wait, what is \great?

This is it; \great! Wait, what is \great?

This is it: \great! Wait, what is \great?

\end{document}

enter image description here

The idea is that the colon has the highest space factor code among all non “big” punctuation marks. We have to redefine \frenchspacing because the default definition just sets all space factor codes to 1000.

If you need the change only after the exclamation mark, we have to set its space factor code to a unique one.

\documentclass{article}

% not needed if amsthm is loaded
\sfcode`!=\numexpr\sfcode`!+1\relax

\def\frenchspacing{\sfcode`\.1006\sfcode`\?1005\sfcode`\!1004%
  \sfcode`\:1003\sfcode`\;1002\sfcode`\,1001 }
%%%

\makeatletter
\newcommand{\afterexclamation}{%
  \ifnum\spacefactor=\sfcode`!
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

\newcommand{\great}{\afterexclamation{Grrrr}{g}reat}

\begin{document}

This is it! \great! Wait, what is \great?

This is it. \great! Wait, what is \great?

This is it? \great! Wait, what is \great?

This is it, \great! Wait, what is \great?

This is it; \great! Wait, what is \great?

This is it: \great! Wait, what is \great?

\frenchspacing

This is it! \great! Wait, what is \great?

This is it. \great! Wait, what is \great?

This is it? \great! Wait, what is \great?

This is it, \great! Wait, what is \great?

This is it; \great! Wait, what is \great?

This is it: \great! Wait, what is \great?

\end{document}

enter image description here

egreg
  • 1,121,712