2

The following MWE shows that how I get the first letter of a word and compare it with other character both defined in macros. In my case I need to perform it case-insensitively so I used \uppercase to make both characters uppercase; the latter one is uppercase too.

\documentclass{article}

\def\firstletter#1{\expandafter\justfirst#1\relax}
\def\justfirst#1#2\relax{#1}

\begin{document}
    \def\data{abcde}
    \uppercase{\edef\letter{\firstletter{\data}}}%
    \def\A{A}
    \ifx\A\letter Equal\else Not Equal\fi
\end{document}

I don't know why it doesn't work as I was expected! (getting Equal not Not Equal).

3

\uppercase doesn't expand the contents of its argument, so there's nothing there to be uppercased as far as it is concerned.

A couple of various possibilities to fix it:

\edef\letter{\firstletter{\data}}% 
\uppercase\expandafter{\expandafter\edef\expandafter\letter\expandafter{\letter}}%

Or:

\edef\tmpa{\uppercase{\edef\noexpand\letter{\firstletter{\data}}}}%
\tmpa

There are probably other alternatives as well.

2
  • Thanks, but why can't we use something like \edef\letter{\uppercase{\edef\noexpand\letter{\firstletter{\data}}}}? I mean without using any temporary macro, just expanding the original one.
    – javadr
    Dec 9 '17 at 7:25
  • @javadr — write \show\letter to see why. \uppercase doesn't expand, so the temporary macro needs to be executed for \uppercase to finally perform its duty. Dec 10 '17 at 11:22
1

Assuming only string data (all macros to be tested expand to characters), you can do by switching arguments around. This assumes the first argument to \firstletterequalTF does not expand to an empty list.

\documentclass{article}

\makeatletter
\newcommand{\firstletterequalTF}[2]{% both can be macros
  \expandafter\fle@i#1\@nil{#2}%
}
\def\fle@i#1#2\@nil#3{%
  \expandafter\fle@ii\expandafter{#3}{#1}%
}
\def\fle@ii#1#2{%
  \uppercase{\if#1#2}%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

\newcommand\dataa{abcde}
\newcommand\dataA{Abcde}
\newcommand\datab{bcde}
\newcommand\fixedA{A}

\begin{document}

\firstletterequalTF{abcde}{A}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{A}{Equal}{Not Equal} /
\firstletterequalTF{abcde}{\fixedA}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{\fixedA}{Equal}{Not Equal}

\firstletterequalTF{\dataA}{\fixedA}{Equal}{Not Equal}

\firstletterequalTF{\datab}{\fixedA}{Equal}{Not Equal}

\end{document}

enter image description here

An implementation in expl3, where the ability to expandably compare strings is exploited, note the last command that shows that, contrary to macros using \uppercase, the function is expandable. Empty strings are not of a concern.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\prg_new_conditional:Nnn \javadr_firstletterequal:nn { T,F,TF,p }
 {
  % compare the two strings after full expansion:
  % extract the first item from the the first string and uppercase it;
  % uppercase the second string; f expansion is used so using explicit
  % strings or macros is the same
  \str_if_eq_x:nnTF
   { \str_upper_case:f { \str_head:f { #1 } } }
   { \str_upper_case:f { #2 } }
   { \prg_return_true: }
   { \prg_return_false: }
 }
\cs_generate_variant:Nn \str_head:n { f }

\NewExpandableDocumentCommand{\firstletterequalTF}{mmmm}
 {
  \javadr_firstletterequal:nnTF { #1 } { #2 } { #3 } { #4 }
 }

\ExplSyntaxOff

\newcommand\dataa{abcde}
\newcommand\dataA{Abcde}
\newcommand\datab{bcde}
\newcommand\fixedA{A}

\begin{document}

\firstletterequalTF{abcde}{A}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{A}{Equal}{Not Equal} /
\firstletterequalTF{abcde}{\fixedA}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{\fixedA}{Equal}{Not Equal}

\firstletterequalTF{\dataA}{\fixedA}{Equal}{Not Equal}

\firstletterequalTF{\datab}{\fixedA}{Equal}{Not Equal}

\firstletterequalTF{}{}{Equal}{Not Equal}

\firstletterequalTF{}{\fixedA}{Equal}{Not Equal}

\edef\test{%
  \firstletterequalTF{\dataa}{\fixedA}{Equal}{Not Equal}%
}
\texttt{\meaning\test}

\end{document}

enter image description here

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.