No change to the default code and no category code change either.
The argument (or arguments in case of \section[x]{y}
) are massaged looking for <(any tokens)>
(lazy search) and substituting it with \texttt{<(any tokens)>}
, then passed to the original \section
or \subsection
commands.
If you plan to use the double optional argument provided by memoir
, some changes are needed in the scanning of the optional arguments.
\documentclass{article}
\usepackage{xparse,l3regex}
\usepackage{color}
\ExplSyntaxOn
\cs_set_eq:NN \latexsection \section
\cs_set_eq:NN \latexsubsection \subsection
\RenewDocumentCommand{\section}{}
{
\genericsection{\latexsection}
}
\RenewDocumentCommand{\subsection}{}
{
\genericsection{\latexsubsection}
}
\NewDocumentCommand{\genericsection}{msom}
{
\IfValueT{#3}
{
\kexx_section_keyword:Nn \l_kexx_section_texto_tl { #3 }
}
\kexx_section_keyword:Nn \l_kexx_section_textm_tl { #4 }
\IfBooleanTF{#2}
{
#1*{\l_kexx_section_textm_tl}
}
{
\IfValueTF{#3}
{
#1[ \l_kexx_section_texto_tl ]{ \l_kexx_section_textm_tl }
}
{
#1{ \l_kexx_section_textm_tl }
}
}
}
\tl_new:N \l_kexx_section_textm_tl
\tl_new:N \l_kexx_section_texto_tl
\cs_new_protected:Nn \kexx_section_keyword:Nn
{
\tl_set:Nn #1 { #2 }
\regex_replace_all:nnN { (\<.*?\>) } { \c{texttt}\cB\{\1\cE\} } #1
}
\ExplSyntaxOff
\begin{document}
\section{Headline <keyword> \textcolor{red}{\itshape{this}}}
\subsection{Headline <keyword>}
\subsection{Headline \textcolor{red}{<keyword>}}
\end{document}

In order to accommodate the double optional argument of memoir
, some more work is needed:
\documentclass{memoir}
\usepackage{xparse,l3regex}
\usepackage{color}
\ExplSyntaxOn
\cs_set_eq:NN \memoirsection \section
\cs_set_eq:NN \memoirsubsection \subsection
\RenewDocumentCommand{\section}{}
{
\genericsection{\memoirsection}
}
\RenewDocumentCommand{\subsection}{}
{
\genericsection{\memoirsubsection}
}
\NewDocumentCommand{\genericsection}{msoom}
{
\IfValueTF{#4}
{
\kexx_section_keyword:Nn \l_kexx_section_textob_tl { #4 }
\kexx_section_keyword:Nn \l_kexx_section_textoa_tl { #3 }
}
{
\IfValueT{#3}
{
\kexx_section_keyword:Nn \l_kexx_section_textoa_tl { #3 }
}
}
\kexx_section_keyword:Nn \l_kexx_section_textm_tl { #5 }
\IfBooleanTF{#2}
{
#1*{\l_kexx_section_textm_tl}
}
{
\IfValueTF{#4}
{
#1[ \l_kexx_section_textoa_tl ][ \l_kexx_section_textob_tl ]{ \l_kexx_section_textm_tl }
}
{
\IfValueTF{#3}
{
#1[ \l_kexx_section_textoa_tl ]{ \l_kexx_section_textm_tl }
}
{
#1{ \l_kexx_section_textm_tl }
}
}
}
}
\tl_new:N \l_kexx_section_textm_tl
\tl_new:N \l_kexx_section_textoa_tl
\tl_new:N \l_kexx_section_textob_tl
\cs_new_protected:Nn \kexx_section_keyword:Nn
{
\tl_set:Nn #1 { #2 }
\regex_replace_all:nnN { (\<.*?\>) } { \c{texttt}\cB\{\1\cE\} } #1
}
\ExplSyntaxOff
\begin{document}
\section{Headline <keyword> \textcolor{red}{\itshape{this}}}
\subsection{Headline <keyword>}
\subsection[<key>][aaa<key>]{Headline \textcolor{red}{<keyword>}}
\end{document}
More complicated is getting uppercase titles, but it's possible.
\documentclass{memoir}
\usepackage{xparse,l3regex}
\usepackage{color}
\ExplSyntaxOn
\cs_set_eq:NN \memoirchapter \chapter
\cs_set_eq:NN \memoirsection \section
\cs_set_eq:NN \memoirsubsection \subsection
\tl_put_right:Nn \l_tl_case_change_exclude_tl { \textttnocase }
\RenewDocumentCommand{\chapter}{}
{
\genericsection{\use:n}{\memoirchapter}
}
\RenewDocumentCommand{\section}{}
{
\genericsection{\use:n}{\memoirsection}
}
\RenewDocumentCommand{\subsection}{}
{
\genericsection{\tl_upper_case:n}{\memoirsubsection}
}
\NewDocumentCommand{\genericsection}{mmsoom}
{
\IfValueTF{#5}
{
\kexx_section_keyword:Nn \l_kexx_section_textob_tl { #5 }
\kexx_section_keyword:Nn \l_kexx_section_textoa_tl { #4 }
}
{
\IfValueT{#4}
{
\kexx_section_keyword:Nn \l_kexx_section_textoa_tl { #4 }
}
}
\kexx_section_keyword:Nn \l_kexx_section_textm_tl { #6 }
\IfBooleanTF{#3}
{
\use:x
{
\exp_not:N #2 * { \exp_not:N #1 {\exp_not:V \l_kexx_section_textm_tl} }
}
}
{
\IfValueTF{#5}
{
\use:x
{
\exp_not:N #2
[ \exp_not:N #1 {\exp_not:V \l_kexx_section_textoa_tl} ]
[ \exp_not:N #1 {\exp_not:V \l_kexx_section_textob_tl} ]
{ \exp_not:N #1 {\exp_not:V \l_kexx_section_textm_tl} }
}
}
{
\IfValueTF{#4}
{
\use:x
{
\exp_not:N #2
[ \exp_not:N #1 {\exp_not:V \l_kexx_section_textoa_tl} ]
{ \exp_not:N #1 {\exp_not:V \l_kexx_section_textm_tl} }
}
}
{
\use:x
{
\exp_not:N #2 { \exp_not:N #1 {\exp_not:V \l_kexx_section_textm_tl} }
}
}
}
}
}
\tl_new:N \l_kexx_section_textm_tl
\tl_new:N \l_kexx_section_texto_tl
\cs_new_protected:Nn \kexx_section_keyword:Nn
{
\tl_set:Nn #1 { #2 }
\regex_replace_all:nnN { (\<.*?\>) } { \c{textttnocase}\cB\{\1\cE\} } #1
}
\ExplSyntaxOff
\NewDocumentCommand{\redtext}{m}{\textcolor{red}{#1}}
\NewDocumentCommand{\textttnocase}{m}{\NoCaseChange{\texttt{#1}}}
\begin{document}
\chapter{Headline <keyword>}
\section{Headline <keyword> \redtext{\itshape{this}}}
\subsection{Headline <keyword>}
\subsection[<key>][aaa<key>]{Headline\"a \redtext{<keyword>}}
\end{document}

Note that page headers need special treatment, too.
\keyword
or a search-and-replace instead of modifying the\section
and\subsection
commands. – bombcar Mar 27 '17 at 18:24