[Tex/LaTex] Faking small caps in XeLaTeX

fontspecmacrossmall-capstex-core

In the post Fake small caps with XeTeX/fontspec? I have found the following definitions to fake small caps

   \def\mycommand{\bgroup\obeyspaces\mycommandaux}
   \def\mycommandaux#1{\mycommandauxii #1\relax\relax\egroup}
   \def\mycommandauxii#1{%
   \ifx\relax#1\else 
   \ifcat#1\@sptoken{}  
   \expandafter\expandafter\expandafter\mycommandauxii\else
   \ifnum`#1=\uccode`#1 {\normalsize #1}\else {\footnotesize \uppercase{#1}}\fi   
   \expandafter\expandafter\expandafter\mycommandauxii\expandafter\fi\fi}

   % ...

   \mycommand{This text is set in fake small caps.}

\mycommand works properly in the main text. However, when \mycommand is used inside other commands like \title of \footnote it removes the spaces between the words.

So I wonder if there is any way to make the above command to work inside other commands or if there are other ways to achieve the same result.

In the code above \normalsize and \footnotesize can be replaced some \fontspec instructions. An advantage of the approach (or similar) is that it could work for generic fonts without small caps (I am aware of fontinst and the support for creating small caps in fontforge)

Best Answer

A different approach: with \fakesc you can store the "faked" text in a control sequence for later use.

\documentclass[]{article}
\usepackage{fontspec,xparse}

\ExplSyntaxOn
\NewDocumentCommand{\fakesc}{ o m }
 {
  \guido_fakesc:n { #2 }
  \IfNoValueTF{#1}
   {
    \tl_use:N \l__guido_temp_tl
   }
   {
    \cs_set_eq:NN #1 \l__guido_temp_tl
   }
 }
\cs_new_protected:Npn \guido_fakesc:n #1
 {
  \tl_set:Nn \l__guido_text_tl { #1 }
  \tl_replace_all:Nnn \l__guido_text_tl { ~ } { \q_space }
  \tl_set:Nn \l__guido_temp_tl { \group_begin: \footnotesize }
  \tl_map_inline:Nn \l__guido_text_tl
   {
    \token_if_eq_meaning:NNTF ##1 \q_space
     {
      \tl_put_right:Nn \l__guido_temp_tl { ~ }
     }
     {
      \int_compare:nTF { \char_value_uccode:n { `##1 } = `##1 }
       {
        \tl_put_right:Nn \l__guido_temp_tl { {\normalsize ##1} }
       }
       {
        \tl_put_right:Nn \l__guido_temp_tl { \tl_upper_case:n { ##1 } }
       }
     }
   }
  \tl_put_right:Nn \l__guido_temp_tl { \group_end: }
 }
\quark_new:N \q_space
\tl_new:N \l__guido_text_tl
\tl_new:N \l__guido_temp_tl
\ExplSyntaxOff

\begin{document}
\fakesc[\mytitle]{This is the title}

\title{\mytitle}
\author{An Author}
\maketitle


\fakesc{All inside this are fake caps} and this is normal

\end{document}

But this is just a hack and real small caps should be preferred. The argument to \fakesc must consist only of letters and spaces. No fancy characters or commands.

enter image description here