![使用 xparse 或 latex3 语法将命令重写为](https://linux22.com/image/310305/%E4%BD%BF%E7%94%A8%20xparse%20%E6%88%96%20latex3%20%E8%AF%AD%E6%B3%95%E5%B0%86%E5%91%BD%E4%BB%A4%E9%87%8D%E5%86%99%E4%B8%BA%20.png)
我编写了一个宏来使用一些命令,例如ltxdoc
(\oarg,\meta,\marg),而不使用textcomp
andltxdoc
来着色并决定命令中的角度、括号和文本的字体样式。我想编写以下形式的命令:
\mycomand[key=value]{...}
但由于源字体选择为 typewrite 和 roman,这对我来说很困难。这是文件 (MWE)
% 2015-29-04
\documentclass{article}
\usepackage[T1]{fontenc}%
\usepackage{libertine}%
\usepackage[dvipsnames]{xcolor}
\usepackage{listings}
% Font used for \textangle in \ttfamily
\DeclareFontEncoding{TS1}{}{}
\DeclareFontSubstitution{TS1}{cmr}{m}{n}
\DeclareTextSymbol{\ttlangle}{TS1}{60}
\DeclareTextSymbol{\ttrangle}{TS1}{62}
\DeclareTextSymbolDefault{\ttlangle}{TS1}
\DeclareTextSymbolDefault{\ttrangle}{TS1}
% adapted from doc.dtx
\providecommand\meta[1]{{\fontfamily{cmr}\fontencoding{TS1}\selectfont\ttlangle\/}\ignorespaces{\normalfont\itshape #1\/}{\fontfamily{cmr}\fontencoding{TS1}\selectfont\/\ttrangle}} % close
% adapted from ltxdoc.dtx
\providecommand\marg[1]{{\fontfamily{cmr}\fontencoding{T1}\selectfont\{\ignorespaces}\normalfont\meta{#1}\ignorespaces{\fontfamily{cmr}\fontencoding{T1}\selectfont\}\ignorespaces}} % close
\providecommand\oarg[1]{{\fontfamily{cmr}\fontencoding{T1}\selectfont [}\normalfont\meta{#1}{\fontfamily{cmr}\fontencoding{T1}\selectfont ]\ignorespaces}} % close
\begin{document}
\noindent
ROMAN
\textlangle\emph{meta}\textrangle \par
[\textlangle\emph{oarg}\textrangle] \par
\{\textlangle\emph{marg}\textrangle\} \par
\noindent
TYPEWRITE
\meta{meta} \par
\oarg{oarg} \par
\marg{marg} \par
\let\us\textunderscore
\newcommand\placeholder[1]%
{%
\bgroup
\normalfont\upshape\color{RubineRed}%
\textlangle{\itshape #1\/}\textrangle%
\egroup
}
\lstset
{%
basicstyle = \ttfamily,
escapeinside={<}{>},%
}
\noindent
TEST USING ROMAN
\begin{lstlisting}
for i= <\placeholder{first\us{}value}>:<\placeholder{last\us{}value}>
% do stuff
end
\end{lstlisting}
\noindent
TEST USING TYPEWRITER
\begin{lstlisting}
for i= <\meta{first\us{}value}>:<\meta{last\us{}value}>
% do stuff
end
\end{lstlisting}
TRY
\begin{lstlisting}
\mymeta[type=<\meta{tt,rm}>,cf=<\meta{color font}>,ac=<\meta{angle color}>]{ ... }
\myoarg[type=<\meta{tt,rm}>,cf=<\meta{color font}>,ac=<\meta{angle color}>,sbc=<\meta{square brackets color}>]{ ... }
\mymarg[type=<\meta{tt,rm}>,cf=<\meta{color font}>,ac=<\meta{angle color}>,cbc=<\meta{curly braces color}>]{ ... }
\end{lstlisting}
\end{document}
我的想法是让默认的打字字体和所有内容都变成黑色。
编辑: 尝试定义键:
type= text font (tt or rm) (default tt)
cf = color font (default black)
ac = angle color (default black)
sbc = square brackets color (default black)
cbc = curly braces color (default black)
和命令
% use \meta
\mymeta[type=tt,cf=red,ac=green}]{ ... }
% use \oarg
\myoarg[type=tt,cf=red,ac=green,sbc=blue]{ ... }
% use \marg
\mymarg[type=tt,cf=red,ac=green,cbc=blue]{ ... }
提前致谢。
答案1
这是一个可能的实现:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
%\usepackage{libertine}
\usepackage[dvipsnames]{xcolor}
\usepackage{xparse}
\ExplSyntaxOn
% user level commands
\NewDocumentCommand{\meta}{O{}m}
{
\pablo_meta_generic:Nnn \pablo_meta:n { #1 } { #2 }
}
\NewDocumentCommand{\marg}{O{}m}
{
\pablo_meta_generic:Nnn \pablo_marg:n { #1 } { #2 }
}
\NewDocumentCommand{\oarg}{O{}m}
{
\pablo_meta_generic:Nnn \pablo_oarg:n { #1 } { #2 }
}
% variables and keys
\tl_new:N \l_pablo_meta_font_tl
\keys_define:nn { pablo/meta }
{
type .choice:,
type / tt .code:n = \tl_set:Nn \l_pablo_meta_font_tl { \ttfamily },
type / rm .code:n = \tl_set:Nn \l_pablo_meta_font_tl { \rmfamily },
type .initial:n = tt,
cf .tl_set:N = \l_pablo_meta_color_tl,
cf .initial:n = black,
ac .tl_set:N = \l_pablo_meta_anglecolor_tl,
ac .initial:n = black,
sbc .tl_set:N = \l_pablo_meta_brackcolor_tl,
sbc .initial:n = black,
cbc .tl_set:N = \l_pablo_meta_bracecolor_tl,
cbc .initial:n = black,
}
% internal commands
\cs_new_protected:Npn \pablo_meta_generic:Nnn #1 #2 #3
{
\group_begin:
\keys_set:nn { pablo/meta } { #2 }
\color{ \l_pablo_meta_color_tl }
\l_pablo_meta_font_tl
#1 { #3 } % #1 is \pablo_meta:n, \pablo_marg:n or \pablo_oarg:n
\group_end:
}
\cs_new_protected:Npn \pablo_meta:n #1
{
\pablo_meta_angle:n { \textlangle }
\pablo_meta_meta:n { #1 }
\pablo_meta_angle:n { \textrangle }
}
\cs_new_protected:Npn \pablo_marg:n #1
{
\pablo_meta_brace:n { \textbraceleft }
\pablo_meta:n { #1 }
\pablo_meta_brace:n { \textbraceright }
}
\cs_new_protected:Npn \pablo_oarg:n #1
{
\pablo_meta_brack:n { [ }
\pablo_meta:n { #1 }
\pablo_meta_brack:n { ] }
}
\cs_new_protected:Npn \pablo_meta_meta:n #1
{
\textnormal{\textit{#1}}
}
\cs_new_protected:Npn \pablo_meta_angle:n #1
{
\group_begin:
\fontfamily{cmr}\selectfont
\textcolor{\l_pablo_meta_anglecolor_tl}{#1}
\group_end:
}
\cs_new_protected:Npn \pablo_meta_brace:n #1
{
\group_begin:
\color{\l_pablo_meta_bracecolor_tl}
#1
\group_end:
}
\cs_new_protected:Npn \pablo_meta_brack:n #1
{
\textcolor{\l_pablo_meta_brackcolor_tl}{#1}
}
\ExplSyntaxOff
\begin{document}
\noindent
\meta{something}\\
\marg{mandatory argument}\\
\oarg{optional argument}
\noindent
\meta[cf=red,ac=green]{something}\\
\marg[type=rm,cbc=red]{mandatory argument}\\
\oarg[type=rm,sbc=blue]{optional argument}
\end{document}
\noindent
\meta{something}\\
\marg{mandatory argument}\\
\oarg{optional argument}
\noindent
\meta{something}\\
\marg{mandatory argument}\\
\oarg{optional argument}
\noindent
\meta{something}\\
\marg{mandatory argument}\\
\oarg{optional argument}
\end{document}
我将其注释掉,libertine
因为使用 Computer Modern 可以更好地看到罗马字体和等宽字体之间的区别。
请注意\meta
,\marg
和\oarg
是根据通用命令定义的,该命令执行键的设置并调用相应的内部命令。所有项目都使用特定的宏定义,以实现统一性。