考虑以下 MWE:
\documentclass[letterpaper,11pt]{article}
\usepackage{l3draw}
\ExplSyntaxOn
\dim_new:N \l__pencil_dim
\fp_new:N \l__pencil_linethickness_fp
\cs_new_protected:Nn \pencil_diagram:n
{
\dim_set:Nn \l__pencil_dim { #1 }
\draw_begin:
\draw_transform_rotate:n { 110 } %rotation
\draw_linewidth:n { \l__pencil_linethickness_fp }
\draw_cap_round:
\draw_join_round:
\draw_path_moveto:n { 0.0\l__pencil_dim , 0.125\l__pencil_dim }
\draw_path_lineto:n { 0.125\l__pencil_dim , 0.0\l__pencil_dim }
\draw_path_lineto:n { 1.0\l__pencil_dim , 0.0\l__pencil_dim }
\draw_path_lineto:n { 1.0\l__pencil_dim , 0.25\l__pencil_dim }
\draw_path_lineto:n { 0.125\l__pencil_dim , 0.25\l__pencil_dim }
\draw_path_close:
\color_fill:n { black } %color
\draw_path_use_clear:n { fill, stroke }
\draw_path_moveto:n { 1.125\l__pencil_dim , 0.0\l__pencil_dim }
\draw_path_lineto:n { 1.25\l__pencil_dim , 0.0\l__pencil_dim }
\draw_path_curveto:nn
{ 1.35\l__pencil_dim , 0.125\l__pencil_dim }
{ 1.25\l__pencil_dim , 0.25\l__pencil_dim }
\draw_path_lineto:n { 1.125\l__pencil_dim , 0.25\l__pencil_dim }
\draw_path_close:
\color_fill:n { black } %color
\draw_path_use_clear:n { fill, stroke }
\draw_end:
}
\NewDocumentCommand{\explpencil}{ O{1ex} }
{
\fp_set:Nn \l__pencil_linethickness_fp { 0.08ex }
\pencil_diagram:n { #1 }
}
\ExplSyntaxOff
\begin{document}
\explpencil[2ex] sample text
\end{document}
在@egreg解决方案他使用l3keys
值来定义用户可以拥有的输入,尤其是的用法tl_if_empty:NTF
。我喜欢这样的事实:输入不是强制性的,也不依赖于用户。
我如何创建类似的键值,重点关注颜色 ( \l__pencil_color
)、尺寸 ( \l__pencil_dim
) 和旋转 ( \l__pencil_rotation
)。括号中的名称只是建议的名称。
我正在寻找类似的可能性
\explpencil
,\explpencil[2ex]
,\explpencil[2ex,30]
,\explpencil[red][2ex][30]
最好是输入的顺序无关紧要但可以产生预期的结果;比如说\explpencil[red][2ex][30]=\explpencil[2ex][red][30]
。
答案1
一个可选参数就足够了,两个参数记住就行;如果参数超过两个,则需要查阅手册以了解它们的相对顺序。
当有许多选项需要设置时,使用键值语法会更好。
\documentclass[letterpaper,11pt]{article}
\usepackage{l3draw}
\ExplSyntaxOn
% user interface
\NewDocumentCommand{\explpencil}{ O{} }
{
\group_begin:
\aze_pencil_diagram:n { #1 }
\group_end:
}
% variables and variants
\cs_generate_variant:Nn \color_fill:n { V }
\dim_new:N \l__aze_pencil_size_dim
\fp_new:N \l__aze_pencil_linethickness_fp
\keys_define:nn { aze/pencil }
{
size .dim_set:N = \l__aze_pencil_size_dim,
color .tl_set:N = \l__aze_pencil_color_tl,
color .initial:n = black,
angle .fp_set:N = \l__aze_pencil_angle_fp,
angle .initial:n = 110,
thick .dim_set:N = \l__aze_pencil_thick_dim,
}
% internal implementation
\cs_new_protected:Nn \aze_pencil_diagram:n
{
\keys_set:nn { aze/pencil } { size=1ex, thick=0.08ex, #1 }
\draw_begin:
\draw_transform_rotate:n { \l__aze_pencil_angle_fp } % angle
\draw_linewidth:n { \l__aze_pencil_thick_dim }
\draw_cap_round:
\draw_join_round:
\draw_path_moveto:n { 0.000\l__aze_pencil_size_dim , 0.125\l__aze_pencil_size_dim }
\draw_path_lineto:n { 0.125\l__aze_pencil_size_dim , 0.000\l__aze_pencil_size_dim }
\draw_path_lineto:n { 1.000\l__aze_pencil_size_dim , 0.000\l__aze_pencil_size_dim }
\draw_path_lineto:n { 1.000\l__aze_pencil_size_dim , 0.250\l__aze_pencil_size_dim }
\draw_path_lineto:n { 0.125\l__aze_pencil_size_dim , 0.250\l__aze_pencil_size_dim }
\draw_path_close:
\color_fill:V \l__aze_pencil_color_tl %color
\draw_path_use_clear:n { fill, stroke }
\draw_path_moveto:n { 1.125\l__aze_pencil_size_dim , 0.0\l__aze_pencil_size_dim }
\draw_path_lineto:n { 1.250\l__aze_pencil_size_dim , 0.0\l__aze_pencil_size_dim }
\draw_path_curveto:nn
{ 1.35\l__aze_pencil_size_dim , 0.125\l__aze_pencil_size_dim }
{ 1.25\l__aze_pencil_size_dim , 0.250\l__aze_pencil_size_dim }
\draw_path_lineto:n { 1.125\l__aze_pencil_size_dim , 0.25\l__aze_pencil_size_dim }
\draw_path_close:
\color_fill:V \l__aze_pencil_color_tl %color
\draw_path_use_clear:n { fill, stroke }
\draw_end:
}
\ExplSyntaxOff
\begin{document}
\explpencil{} sample text
\explpencil[size=2ex] sample text
\explpencil[size=1ex,color=red,angle=50,thick=0.01ex] sample text
\end{document}
可能的选项是size
、color
和。最后一个对于黑色铅笔来说基本无关紧要,但对于彩色铅笔来说却很重要angle
。thick
为什么color
和angle
有初始值,而size
和thick
没有?因为我们希望size
是ex
,这样绘图才能适应上下文。如果我们size
最初将 设置为1ex
,这将是维度当时设置已完成,因此在文档序言中。对于 也类似thick
,因此值在调用时设置,可能被显式选项覆盖。