% \section{Patching code}
%
%    \begin{macrocode}
%<*fontspec>
%    \end{macrocode}
%
%
% \subsection{Italic small caps and so on} \label{sec:sishape}
%
% \begin{macro}{\sishape}
% \begin{macro}{\textsi}
% These commands for actually selecting italic small caps have been defined for many years; I'm inclined to drop them.
% They're probably used very infrequently; I personally prefer just writing
% |\textit{\textsc{...}}| instead.
%
%    \begin{macrocode}
\providecommand*\itscdefault{\itdefault\scdefault}
\providecommand*\slscdefault{\sldefault\scdefault}
\DeclareRobustCommand{\sishape}
 {
  \not@math@alphabet\sishape\relax
  \fontshape{\itscdefault}\selectfont
 }
\DeclareTextFontCommand{\textsi}{\sishape}
%    \end{macrocode}
% \end{macro} \end{macro}
%
% \LaTeX's `shape' font axis needs to be overloaded to support italic small caps and slanted small caps.
% These are the combinations to support:
%    \begin{macrocode}
\cs_new:Nn \@@_shape_merge:nn { c_@@_shape_#1_#2_tl }
\tl_const:cn { \@@_shape_merge:nn \itdefault   \scdefault } {\itscdefault}
\tl_const:cn { \@@_shape_merge:nn \sldefault   \scdefault } {\slscdefault}
\tl_const:cn { \@@_shape_merge:nn \scdefault   \itdefault } {\itscdefault}
\tl_const:cn { \@@_shape_merge:nn \scdefault   \sldefault } {\slscdefault}
\tl_const:cn { \@@_shape_merge:nn \slscdefault \itdefault } {\itscdefault}
\tl_const:cn { \@@_shape_merge:nn \itscdefault \sldefault } {\slscdefault}
\tl_const:cn { \@@_shape_merge:nn \itscdefault \updefault } {\scdefault}
\tl_const:cn { \@@_shape_merge:nn \slscdefault \updefault } {\scdefault}
%    \end{macrocode}
%
% \begin{macro}{\fontspec_merge_shape:n}
% These macros enable the overload on the |\..shape| commands.
% First, a shape `new+current' (prefix) or `current+new' (suffix) is tried.
% If not found, fall back on the `new' shape.
%    \begin{macrocode}
\cs_new:Nn \fontspec_merge_shape:n
  {
    \@@_if_merge_shape:nTF {#1}
      { \fontshape { \tl_use:c { \@@_shape_merge:nn {\f@shape} {#1} } } \selectfont }
      { \fontshape {#1} \selectfont }
  }
%    \end{macrocode}
% The following is rather specific; it only returns true if the merged shape exists,
% but more importantly also if the merged shape is defined for the current font.
%    \begin{macrocode}
\prg_new_conditional:Nnn \@@_if_merge_shape:n {TF}
  {
    \bool_if:nTF
      {
        \tl_if_exist_p:c { \@@_shape_merge:nn {\f@shape} {#1} }   &&
        \cs_if_exist_p:c
          {
            \f@encoding/\f@family/\f@series/
            \tl_use:c { \@@_shape_merge:nn {\f@shape} {#1} }
          }
      }
    \prg_return_true: \prg_return_false:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\itshape} \begin{macro}{\scshape} \begin{macro}{\upshape} \begin{macro}{\slshape}
% The original |\..shape| commands are redefined to use the merge shape macro.
%    \begin{macrocode}
\DeclareRobustCommand \itshape
 {
  \not@math@alphabet\itshape\mathit
  \fontspec_merge_shape:n\itdefault
 }
\DeclareRobustCommand \slshape
 {
  \not@math@alphabet\slshape\relax
  \fontspec_merge_shape:n\sldefault
 }
\DeclareRobustCommand \scshape
 {
  \not@math@alphabet\scshape\relax
  \fontspec_merge_shape:n\scdefault
 }
\DeclareRobustCommand \upshape
 {
  \not@math@alphabet\upshape\relax
  \fontspec_merge_shape:n\updefault
 }
%    \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro}
%
%
%
% \subsection{Emphasis}
%
% \begin{macro}{\em}
% \begin{macro}{\emph}
% \begin{macro}{\emshape}
% \begin{macro}{\eminnershape}
% \begin{macro}{\emfontdeclare}
% Redefinition of |{\em ...}| and |\emph{...}| to allow nesting of emphases.
%
%    \begin{macrocode}
\cs_new_protected:Npn \emfontdeclare #1
  {
    \prop_clear:N \g_@@_em_prop
    \int_zero:N   \l_@@_emdef_int
    \group_begin:
      \normalfont
      \clist_map_inline:nn {\emreset,#1}
        {
          ##1
          \prop_gput_if_new:NxV \g_@@_em_prop { \f@series/\f@shape } { \l_@@_emdef_int }
          \prop_gput:Nxn \g_@@_em_prop { switch-\int_use:N \l_@@_emdef_int } { ##1 }
          \int_incr:N \l_@@_emdef_int
        }
    \group_end:
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareRobustCommand \em
  {
    \@nomath\em

    \prop_get:NxNT \g_@@_em_prop { \f@series/\f@shape } \l_@@_em_tmp_tl
      { \int_set:Nn \l_@@_em_int { \l_@@_em_tmp_tl } }

    \int_incr:N \l_@@_em_int

    \prop_get:NxNTF \g_@@_em_prop { switch-\int_use:N \l_@@_em_int } \l_@@_em_switch_tl
      { \l_@@_em_switch_tl }
      {
        \int_zero:N \l_@@_em_int
        \emreset
      }

  }
%    \end{macrocode}
% Document commands:
%    \begin{macrocode}
\DeclareTextFontCommand{\emph}{\em}
\cs_set:Npn \emreset { \upshape }
\cs_set:Npn \emshape { \itshape }
\cs_set:Npn \eminnershape { \upshape }
\emfontdeclare{ \emshape, \eminnershape }
%    \end{macrocode}
% Ensure nesting resets when necessary:
%    \begin{macrocode}
\cs_set:Npn \reset@font { \normalfont \int_zero:N \l__fontspec_em_int }
%    \end{macrocode}
% Programmer's interface for setting nesting level:
%    \begin{macrocode}
\cs_new:Nn \fontspec_set_em_level:n { \int_set:Nn \l_@@_em_int {#1} }
%    \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
% \subsection{\cmd\-}
%
% \begin{macro}{\-}
% This macro is courtesy of Frank Mittelbach and the \LaTeXe\ source code.
%    \begin{macrocode}
\DeclareRobustCommand{\-}
 {
  \discretionary
   {
    \char\ifnum\hyphenchar\font<\z@
           \xlx@defaulthyphenchar
         \else
           \hyphenchar\font
         \fi
   }{}{}
 }
\def\xlx@defaulthyphenchar{`\-}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Verbatims}
%
% Many thanks to Apostolos Syropoulos for discovering this problem and writing the  redefinion of \LaTeX's |verbatim| environment and \cs{verb*} command.
%
% \begin{macro}{\fontspec_visible_space:}
% Print \unichar{2423}{Open box}, which is used to visibly display a space character.
%    \begin{macrocode}
\cs_new:Nn \fontspec_visible_space:
 {
  \@@_primitive_font_glyph_if_exist:NnTF \font {"2423}
   { \char"2423\scan_stop: }
   { \fontspec_visible_space_fallback: }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fontspec_visible_space_fallback:}
% If the current font doesn't have \unichar{2423}{Open box}, use Latin Modern Mono instead.
%    \begin{macrocode}
\cs_new:Nn \fontspec_visible_space_fallback:
 {
  {
   \usefont{\g_fontspec_encoding_tl}{lmtt}{\f@series}{\f@shape}
   \textvisiblespace
  }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fontspec_print_visible_spaces:}
% Helper macro to turn spaces (\verb|^^20|) active and print visible space instead.
%    \begin{macrocode}
\group_begin:
\char_set_catcode_active:n{"20}%
\cs_gset:Npn\fontspec_print_visible_spaces:{%
\char_set_catcode_active:n{"20}%
\cs_set_eq:NN^^20\fontspec_visible_space:%
}%
\group_end:
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\verb}
% \begin{macro}{\verb*}
% Redefine \cmd\verb\ to use \cmd\fontspec_print_visible_spaces:.
%    \begin{macrocode}
\def\verb
 {
  \relax\ifmmode\hbox\else\leavevmode\null\fi
  \bgroup
    \verb@eol@error \let\do\@makeother \dospecials
    \verbatim@font\@noligs
    \@ifstar\@@sverb\@verb
 }
\def\@@sverb{\fontspec_print_visible_spaces:\@sverb}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% It's better to put small things into \cmd\AtBeginDocument, so here we go:
%    \begin{macrocode}
\AtBeginDocument
 {
  \fontspec_patch_verbatim:
  \fontspec_patch_moreverb:
  \fontspec_patch_fancyvrb:
  \fontspec_patch_listings:
 }
%    \end{macrocode}
%
% \begin{environment}{verbatim*}
% With the \pkg{verbatim} package.
%    \begin{macrocode}
\cs_set:Npn \fontspec_patch_verbatim:
 {
  \@ifpackageloaded{verbatim}
   {
    \cs_set:cpn {verbatim*}
     {
      \group_begin: \@verbatim \fontspec_print_visible_spaces: \verbatim@start
     }
   }
%    \end{macrocode}
% This is for vanilla \LaTeX.
%    \begin{macrocode}
   {
    \cs_set:cpn {verbatim*}
     {
      \@verbatim \fontspec_print_visible_spaces: \@sxverbatim
     }
   }
 }
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{listingcont*}
% This is for \pkg{moreverb}.
% The main |listing*| environment inherits this definition.
%    \begin{macrocode}
\cs_set:Npn \fontspec_patch_moreverb:
 {
  \@ifpackageloaded{moreverb}{
    \cs_set:cpn {listingcont*}
     {
      \cs_set:Npn \verbatim@processline
       {
        \thelisting@line \global\advance\listing@line\c_one
        \the\verbatim@line\par
       }
      \@verbatim \fontspec_print_visible_spaces: \verbatim@start
     }
  }{}
 }
%    \end{macrocode}
% \end{environment}
%
% \pkg{listings} and \pkg{fancvrb} make things nice and easy:
%    \begin{macrocode}
\cs_set:Npn \fontspec_patch_fancyvrb:
 {
  \@ifpackageloaded{fancyvrb}
   {
    \cs_set_eq:NN \FancyVerbSpace \fontspec_visible_space:
   }{}
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_set:Npn \fontspec_patch_listings:
 {
  \@ifpackageloaded{listings}
   {
    \cs_set_eq:NN \lst@visiblespace \fontspec_visible_space:
   }{}
 }
%    \end{macrocode}
%
% \subsection{\cs{oldstylenums}}
%
%
% \begin{macro}{\oldstylenums}
% \begin{macro}{\liningnums}
% This command obviously needs a redefinition.
% And we may as well provide the reverse command.
%    \begin{macrocode}
\RenewDocumentCommand \oldstylenums {m}
 {
  { \addfontfeature{Numbers=OldStyle} #1 }
 }
\NewDocumentCommand \liningnums {m}
 {
  { \addfontfeature{Numbers=Lining} #1 }
 }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%    \begin{macrocode}
%</fontspec>
%    \end{macrocode}
