我正在尝试编写一些代码,使我可以分阶段显示预先存在的文件的内容(pspicture
显示几何构造)。我尝试使用 LaTeX3 编写此代码。我有一些工作代码,但我不喜欢我实现它的方式。目前,工作版本是一组混乱的命令。我想使用来简化这一点l3keys
。但是,我陷入了困境。
正在起作用的是:
以下是我所得到的工作。有三个文件:
我定义接口的文件expl3
:它被放在一个名为阶段.tex
%% defining stages
\usepackage{xparse}
\usepackage{verbatim}
\ExplSyntaxOn
\tl_new:N \ace_reveal_tl
\tl_gset:Nn \ace_reveal_tl {REVEAL}
\tl_new:N \ace_conceal_tl
\tl_gset:Nn \ace_conceal_tl {CONCEAL}
\NewDocumentCommand{\revealstage}{ m }{
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_reveal_tl
}
\NewDocumentCommand{\burystage}{ m }{
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_conceal_tl
}
\NewDocumentCommand{\testforstage}{ m m m }{
\tl_if_eq:cNTF { ace__reveal__ #1 __stage__new } \ace_reveal_tl
{#2}
{#3}
}
\NewDocumentEnvironment{stage}{ m }
{
\tl_if_eq:cNF { ace__reveal__ #1 __stage__new } \ace_reveal_tl
{\expandafter\comment}
}
{
\tl_if_eq:cNF { ace__reveal__ #1 __stage__new } \ace_reveal_tl
{\expandafter\endcomment}
}
\ExplSyntaxOff
我在其中定义要使用的图片的文件,我在其中实现阶段:这个文件被称为图表.tex
\begin{pspicture}[showgrid=false](-20,-13)(20,13)
%..% compass directions %..%
{
\psset{PointName=none,PointSymbol=none}
\pstGeonode(0,0){o}(1,0){r}(0,1){u}
\pstRotation[RotAngle=20]{o}{r}[r1]
\pstGeonode(0,0){Q}
}
%% temporarily define midpont of segment(PQ) --> M to control positioning
\pstGeonode[PointName=none,PointSymbol=none,PosAngle=0](0,0){tM}
%% point outside the circle and the center of circle
\pstTranslation[DistCoef=14,PosAngle=80]{o}{r1}{tM}[Q]
\pstTranslation[DistCoef=10,PosAngle=-100]{r1}{o}{tM}[P]
%% construct circle centered at P
\pstCircleOA[Radius=\pstDistVal{9}]{P}{}
%% construct mid-point between P and Q
\pstTranslation[DistCoef=9,PointName=none,PointSymbol=none]{o}{r}{P}[B]
\pstTranslation[DistCoef=0.5,PointName=none,PointSymbol=none]{P}{Q}{P}[M]
%% show constructions
\begin{stage}{midpoint}
\pstLineAB[linecolor=blue,linewidth=0.1pt,linestyle=dashed]{P}{Q}
\pstGeonode[PointName=M,PosAngle=-90](M){showM}
\end{stage}
%% construct circle centered at M passing through P and Q
\begin{stage}{large circle}
\pstCircleOA[linecolor=blue,linewidth=0.2pt,linestyle=dashed]{M}{P}
\end{stage}
%% construct tangents
\pstInterCC[PointName=none,PointSymbol=none,RadiusB=\pstDistVal{9}]{M}{P}{P}{}{U}{V}
\begin{stage}{tangents}
\testforstage{large circle}{
\pstGeonode[PointName={U},PosAngle=-90](U){showU}
\pstGeonode[PointName={V},PosAngle=110](V){showV}
}{
\pstGeonode[PointName={U},PosAngle=-50](U){showU}
\pstGeonode[PointName={V},PosAngle=90](V){showV}
}
\pstLineAB[linecolor=red,nodesep=-8]{Q}{V}
\pstLineAB[linecolor=red,nodesep=-8]{Q}{U}
\end{stage}
\end{pspicture}
主要文件:
\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.15cm}
\usepackage[margin=1in]{geometry}
\input{stages}
\pagestyle{empty}
\begin{document}
\input{diagram}
\revealstage{midpoint}
\input{diagram}
\revealstage{large circle}
\input{diagram}
\revealstage{tangents}
\input{diagram}
\burystage{midpoint}
\burystage{large circle}
\input{diagram}
\end{document}
这将创建:
不起作用的地方:
我真的很想在主文件:
\activatestage[reveal=midpoint,
conceal={large circle,
midpoint}]
{diagram}
但是上面的例子比我目前尝试实现的要复杂一些。目前,我还没有编写代码来处理传递多个值以通过键进行解析。我只写了一些我相信应该能够处理以下事项:
\activatestage[reveal=midpoint,
conceal=large circle]
{diagram}
这是我用来尝试实现这一点的代码:
%% defining keys
\ExplSyntaxOn
\keys_define:nn { stages }{
reveal .code:n = \fnc_reveal_stages:n #1,
conceal .code:n = \fnc_conceal_stages:n #1
}
\cs_new:Npn \fnc_reveal_stages:n #1 {
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_reveal_tl
}
\cs_new:Npn \fnc_conceal_stages:n #1 {
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_conceal_tl
}
\NewDocumentCommand{\activatestage}{ o m }{
\tl_set:Nn \l__no_value_tl { \NoValue }
\tl_set:Nn \l__keys_present_tl { #1 }
\tl_show:N \l__keys_present_tl
\bool_if:nF { \tl_if_eq_p:NN \l__keys_present_tl \l__no_value_tl) }
{
\keys_set:nn{ stages }{#1}
}
\input{#2}
}
\ExplSyntaxOff
我把上面的内容放在了一个名为附加内容.tex
这是我尝试实施新方法的主要文档:
\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.15cm}
\usepackage[margin=1in]{geometry}
\input{stages}
\input{additions}
\pagestyle{empty}
\begin{document}
\input{diagram}
\revealstage{midpoint}
\input{diagram}
\revealstage{large circle}
\input{diagram}
\revealstage{tangents}
\input{diagram}
\activatestage[reveal=midpoint,
conceal=large circle]
{diagram}
\end{document}
但这会导致:
但这并没有达到我的预期(与我的工作示例相比,您可以看到)。密钥似乎只能看到传递给它的值的首字母。我如何让密钥看到整个值?
答案1
将n
类型参数括在括号中:应该是
\keys_define:nn { stages }
{
reveal .code:n = \fnc_reveal_stages:n { #1 },
conceal .code:n = \fnc_conceal_stages:n { #1 },
}
这是使用布尔值和大量简化的提议。但是,您还应该添加一个命令来定义所有允许的“阶段”。
\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.15cm}
\usepackage[margin=1in]{geometry}
%% defining stages
\usepackage{xparse}
\usepackage{verbatim}
\ExplSyntaxOn
\NewDocumentCommand{\revealstage}{ m }
{
\ace_reveal_stage:n { #1 }
}
\cs_new_protected:Npn \ace_reveal_stage:n #1
{
\bool_if_exist:cF { g__ace_reveal_ #1 _stage_bool }
{ \bool_new:c { g__ace_reveal_ #1 _stage_bool } }
\bool_gset_true:c { g__ace_reveal_ #1 _stage_bool }
}
\NewDocumentCommand{\burystage}{ m }
{
\ace_conceal_stage:n { #1 }
}
\cs_new_protected:Npn \ace_conceal_stage:n #1
{
\bool_if_exist:cF { g__ace_reveal_ #1 _stage_bool }
{ \bool_new:c { g__ace_reveal_ #1 _stage_bool } }
\bool_gset_false:c { g__ace_reveal_ #1 _stage_bool }
}
\NewDocumentCommand{\testforstage}{ m m m }
{
\bool_if:cTF { g__ace_reveal_ #1 _stage_bool } { #2 } { #3 }
}
\NewDocumentEnvironment{stage}{ m }
{
\bool_if:cF { g__ace_reveal_ #1 _stage_bool } {\comment}
}
{
\bool_if:cF { g__ace_reveal_ #1 _stage_bool } {\endcomment}
}
%%% Keyval syntax
\keys_define:nn { stages }{
reveal .code:n = \ace_reveal_stage:n { #1 },
conceal .code:n = \ace_conceal_stage:n { #1 },
}
\NewDocumentCommand{\activatestage}{ O{} m }
{
\keys_set:nn { stages } { #1 }
\input{#2}
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\activatestage[reveal=midpoint,
conceal=large circle]
{diagram}
\end{document}
笔记
比较标记列表不是一种有效的方法;布尔值肯定更好。
请遵守命名约定;变量应该以
l_
或开头g_
(如果是“内部”的,则以l__
和开头)。g__
\keys_set:nn
非常乐意处理一个空洞的论点,所以\NewDocumentCommand{\activatestage}{ O{} m }
比测试 更有效
\NoValue
。无论如何,您都应该使用\IfNoValueTF
来测试是否存在可选参数。