Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Let's say I have a class file with \title command, and I want to check that the title starts with a letter, and not with math or a number or a symbol. How can I do that?

This is my MnWE, the syntax of \@iffirstnotletter can be of course reasonably modified. If it recognized accented characters as well, it would be a bonus, but it's not necessary.

\documentclass{article}

\makeatletter
\newcommand\@iffirstnotletter[3]{#2} % <-- should be modified

\renewcommand\title[1]{\@iffirstnotletter{#1}{%
    \GenericWarning{}{Please start the title with a letter!}%
  }{}%
  \def\@title{#1}%
}%
\makeatother

\title{Ahoj}

\begin{document}

\maketitle

\end{document}

EDIT:

My first idea was along the lines of this:

\def\ONETWO#1#2\ENDONETWO{#1} % strips the 1st token of
                             % whatever is between `\ONETWO...\ENDONETWO`
\def\@iffirstnotletter#1#2#3{%
  % checks the \catcode of the 1st token of #1 
  \expandafter\ifnum\expandafter\the\expandafter\catcode
    \expandafter`\csname\ONETWO#1\ENDONETWO\endcsname=11\relax
  #3\else#2
\fi}

But it has a crazy behaviour for example when the very first thing is \( as a beginning of a math-mode: then it gives ! Missing \endcsname inserted.

share|improve this question
    
At least for non accented letters \ifcat should help –  cgnieder Jan 24 at 19:42
    
ah \ifcat, ok, seems better than my crazy construct :) –  tohecz Jan 24 at 19:48

2 Answers 2

This is my try which seems to cover the basics:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox}% I don't want to define \ifdefmacro

\makeatletter
\newcommand\ifletter[1]{%
  \ifcat#1a\@empty
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\newcommand\iffirstletter[1]{\@iffirstletter#1\@empty\q@stop}
\def\@iffirstletter#1#2\q@stop{%
  \ifdefmacro{#1}  % to prevent error messages from accented letters, they're false
    {\@secondoftwo}% starts with macro...
    {\ifletter{#1}}%
}
\makeatother

\begin{document}

!\iffirstletter{foo}{true}{false}! = true

!\iffirstletter{ foo}{true}{false}! = true

!\iffirstletter{f12}{true}{false}! = true

!\iffirstletter{1oo}{true}{false}! = false

!\iffirstletter{$math$}{true}{false}! = false

!\iffirstletter{\(math\)}{true}{false}! = false

!\iffirstletter{äoo}{true}{false}! = false % this may be misleading

!\iffirstletter{\relax}{true}{false}! = false

!\iffirstletter{}{true}{false}! = false

\end{document}
share|improve this answer
    
\UTFviii@two@octets{...} is what all UTF characters expand to, but that's not so important now. I can always state in the manual that the warning should be ignored in such cases. I'll, however, wait to see if someone finds a different approach that would solve the other issues, too. –  tohecz Jan 24 at 19:58
    
Ah, yes. I knew that once... One could add a test for that of course. (But wouldn't that then tie a user to utf8 as input encoding (what they should be using anyway)?) Or recommend XeLaTeX/LuaLaTeX where accented letters are letters :) –  cgnieder Jan 24 at 20:08
1  
@tohecz not all characters, just ones that take two octets (some take 3 or 4) –  David Carlisle Jan 24 at 23:40

A long check with \futurelet; this covers UTF-8 multibyte characters, but in the case the first item in the argument is a multibyte character, it will give "good” anyway, as the concept of “UTF-8 letter” is not well defined. On the other hand, this will fail in cases such as “\'{U}jezd”. One could add a list of admissible control sequences for coping with this case.

\documentclass{article}
\usepackage[utf8]{inputenc}

\makeatletter
\newcommand\ifletter[1]{%
  \futurelet\letter@token\checknextletter#1\relax\@nil
}
\def\checknextletter{%
  \ifcat\noexpand\letter@token a%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\@gobbleto@nil{good}}%
  {\checknextutfii}%
}

\def\checknextutfii{%
  \expandafter\ifx\expandafter\UTFviii@two@octets\letter@token
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\@gobbleto@nil{good}}%
  {\checknextutfiii}%
}

\def\checknextutfiii{%
  \expandafter\ifx\expandafter\UTFviii@three@octets\letter@token
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\@gobbleto@nil{good}}%
  {\checknextutfiv}%
}

\def\checknextutfiv{%
  \expandafter\ifx\expandafter\UTFviii@four@octets\letter@token
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\@gobbleto@nil{good}}%
  {\GenericWarning{}{Please start the title with a letter}%
   \@gobbleto@nil{bad}}%
}

\long\def\@gobbleto@nil#1#2\@nil{#1}

\makeatother

\begin{document}

\verb*'foo': \ifletter{foo} = good

\verb*' foo': \ifletter{ foo} = bad

\verb*'f12': \ifletter{f12} = good

\verb*'1oo': \ifletter{1oo} = bad

\verb*'$math$': \ifletter{$math$} = bad

\verb*'\(math\)': \ifletter{\(math\)} = bad

\verb*'äoo': \ifletter{äoo} = good

\verb*'\relax': \ifletter{\relax} = bad

\verb*'': \ifletter{} = bad

\end{document}

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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