8

For example, SoMeThInGlIkEtHiS

How might one achieve this? I am writing a meme paper this is important. . .

Evan Pu
  • 203

3 Answers3

6

A LaTeX3 version, adapted from egreg's answer here:

\documentclass{article}
\usepackage{xparse}
\usepackage{expl3}

\ExplSyntaxOn
\NewDocumentCommand{\markletters}{m}
 {
  \int_zero:N \l_tmpa_int
  \tl_set:Nn \l_tmpa_tl { #1 }
  % replace spaces with something different
  \tl_replace_all:Nnn \l_tmpa_tl { ~ } { \c_space_tl }
  \tl_map_inline:Nn \l_tmpa_tl
   {
    \tl_if_blank:eTF { ##1 }
     { ~ } % don't advance the counter and issue a space
     {
      \int_if_odd:nTF { \l_tmpa_int } { \tex_lowercase:D } { \tex_uppercase:D } { ##1 }
      \int_incr:N \l_tmpa_int
     }
   }
 }
\prg_generate_conditional_variant:Nnn \tl_if_blank:n { e } { T,F,TF,p }
\ExplSyntaxOff

\begin{document}

\markletters{something like this}

\end{document}

enter image description here

siracusa
  • 13,411
6

A bit shorter with the xstring package:

\documentclass{article}
\usepackage{xstring}
\newif\ifupper\uppertrue
\newcommand{\mixedcase}[1]{%
\StrSplit{#1}{1}{\currentchr}{\tailchr}%
\ifupper\MakeUppercase{\currentchr}\upperfalse\else\MakeLowercase{\currentchr}\uppertrue\fi%
\IfStrEq{\tailchr}{}{\uppertrue}{\mixedcase{\tailchr}}%
}
\begin{document}
\mixedcase{something like this}
\end{document}

Same output as Andrews answer.

Explanation: split the string at the first character, make this character upper or lower case depending on a toggle (\ifupper), switch the toggle, check if there are characters left in the string (the second part of the split is not empty), if yes call the command recursively, if no then reset the toggle for the next time and stop.

Marijn
  • 37,699
4

Here's a slightly different LaTeX3 implementation using regular expressions. A space character is treated as a letter so that the two lines

\CaPiTaLiSe{Something like this}
\CaPiTaLiSe{Somethinglikethis}

produce slightly different capitalisations:

enter image description here

Here is the code:

\documentclass{article}

\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_evan_letters_seq
\cs_new_protected_nopar:Nn \evan_make_upper:n {
  \str_uppercase:n {#1}
  \cs_set_eq:NN \evan_capitalise:n \evan_make_lower:n
}
\cs_new_protected_nopar:Nn \evan_make_lower:n {
  \str_lowercase:n {#1}
  \cs_set_eq:NN \evan_capitalise:n \evan_make_upper:n
}
\NewDocumentCommand\CaPiTaLiSe{m}{
  \regex_split:nnN {} {#1} \l_evan_letters_seq
  \cs_set_eq:NN \evan_capitalise:n \evan_make_upper:n
  \seq_map_inline:Nn \l_evan_letters_seq {\evan_capitalise:n {##1} }
}
\ExplSyntaxOff
\begin{document}

  \CaPiTaLiSe{Something like this}

  \CaPiTaLiSe{Somethinglikethis}

\end{document}

Rather than incrementing a counter I have a dummy macro \evan_capitalise:n that swaps between choosing upper and lower case.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • 2
    Rather than \let, LaTeX3 offers \cs_set_eq:NN. Instead of applying _nopar at the \cs_new... level (programming layer, affects all arguments), you can use arg specifiers like +o, +m, etc. in \NewDocumentCommand (+ makes the corresponding arguments accept \par tokens: the opposite of no_par). Also, you may want to take a look at the LaTeX3 style guide for spacing and brace placement. By the way, this document talks about the no_par variants in section 4. My (IMHO) two cents. :-) – frougon May 21 '19 at 07:25
  • @frougon Thanks! I thought that there should be a latex3 variant of \let but could not find it. Coming from a python background I'm not so fond of the latex spacing recommendations:) In this instance I don't want \par tokens! –  May 21 '19 at 08:01
  • 2
    You're welcome. I can understand you for the par tokens, but consider that arguments of macros defined with \NewDocumentCommand don't accept \par unless you use the + prefix. So, your \CaPiTaLiSe is already safe, even without using any no_par. Concerning \evan_make_upper:n and \evan_make_lower:n, I thought they would let \par tokens unmodified if the no_par were to be removed, but it appears not to be the case, so okay. :-) If you allow me, I can post a small test I did on pastebin.com, based on your code... (can't put it here with formatting, unfortunately). – frougon May 21 '19 at 08:13
  • @frougon On the basis of other posts on TeX.Sx I thought that using \cs_new_protected_nopar:Nn for these "hidden" macros is "better" stylistically, but I have no idea really:) Happy for you to add your code from pastebin. In fact, I'd be interested to see it. –  May 21 '19 at 09:22
  • @frougon Updated to use \cs_set_eq:NN. Thanks! –  May 21 '19 at 09:37
  • 1
    Here you are. It's mostly yours with the stylistic fixes I mentioned and slight changes to see what \evan_make_upper:n and \evan_make_lower:n would do without the no_par when provided with an argument containing possibly several paragraphs. I'm a bit disappointed by the handling of \par. :-/ If you uncomment the \usepackage[T1]{fontenc}, this handling changes but is not what I expected either... – frougon May 21 '19 at 09:39
  • @/joseph-wright You know far more about this than I but I do not understand you edit because according to the manual, \str_uppercase:n doesn't exist and \str_upper_case:n was correct? Similarly, with \str_lower_case:n. –  Jan 14 '20 at 14:20
  • I fear @JosephWright won't see your notification? Anyway, look at LaTeX3 commit d5296c790e. The changes to l3kernel/l3deprecation.dtx indicate that \str_upper_case:n and \str_lower_case:n are deprecated and will trigger an error when the expl3 date is more recent than 2021-01-01. – frougon Jan 14 '20 at 15:06
  • @Andrew We have just updated expl3 with some renames: the new code was available in TeX Live from today, so I'm looking to update answers to reflect this. One of the team will post a 'what happened to the old names' question/answer shortly. – Joseph Wright Jan 14 '20 at 15:36