在 Tikz 坐标计算中使用宏

在 Tikz 坐标计算中使用宏

我正在尝试创建一个打印特定自定义字符的通用宏,根据我之前的一个问题的回答。这是一个最小(非)工作示例:

%!TEX encoding = UTF-8 Unicode
%!TEX TS-program = xelatex

\documentclass{standalone}
\usepackage[xetex]{accsupp}
\usepackage{xkeyval}
\usepackage[xetex]{xcolor}
\usepackage{xxcolor,tikz,pagecolor}
\usetikzlibrary{calc}
\makeatletter
\newcommand{\SS@xX@draw@val}{.}% default: the current text color
\define@key[SS]{xX}{draw}{\renewcommand{\SS@xX@draw@val}{#1}}
\newcommand{\SS@xX@fill@val}{\thepagecolor}% default: the current page color
\define@key[SS]{xX}{fill}{\renewcommand{\SS@xX@fill@val}{#1}}
\newcommand{\SS@xX@thickness@val}{0.125ex}
\define@key[SS]{xX}{thickness}{\renewcommand{\SS@xX@thickness@val}{#1}}
\newcommand{\SS@xX@shift@val}{(0ex,0ex)}
\define@key[SS]{xX}{shift}{\renewcommand{\SS@xX@shift@val}{#1}}
\newcommand{\SS@x@size@val}{0.25ex}
\define@key[SS]{x}{size}{\renewcommand{\SS@x@size@val}{#1}}
\newcommand*\x[1][]{\BeginAccSupp{method=escape,unicode,ActualText={x⃘}}%
\begin{tikzpicture}\setkeys[SS]{xX,x}{#1}
\node[inner sep=0pt,outer sep=0pt] (letter) {x};
\draw[line width=\SS@xX@thickness@val,\SS@xX@draw@val,fill=\SS@xX@fill@val] let \p{shift} = {\SS@xX@shift@val} in ($ (letter.center) + \p{shift} $) circle (\SS@x@size@val);
\end{tikzpicture}%
\EndAccSupp{}\ignorespaces}
\newcommand{\SS@X@size@val}{0.35ex}
\define@key[SS]{X}{size}{\renewcommand{\SS@X@size@val}{#1}}
\newcommand*\X[1][]{\BeginAccSupp{method=escape,unicode,ActualText={X⃘}}%
\begin{tikzpicture}\setkeys[SS]{xX,X}{#1}
\node[inner sep=0pt,outer sep=0pt] (letter) {X};
\draw[line width=\SS@xX@thickness@val,\SS@xX@draw@val,fill=\SS@xX@fill@val] let \p{shift} = {\SS@xX@shift@val} in ($ (letter.center) + \p{shift} $) circle (\SS@X@size@val);
\end{tikzpicture}%
\EndAccSupp{}\ignorespaces}
\makeatother

\begin{document}
\x\X
\end{document}

目前此操作失败,错误为“ Package tikz Error: Cannot Parse this coordinate.

通过摆弄 s tikzpicture,我确定问题出在 的使用上\SS@xX@shift@val,但我不知道如何修复它。有没有办法让它做我想做的事情?(如果\SS@xX@shift@val删除了它的使用,其他一切都可以完美运行。)

编辑:添加 MWE。

答案1

这是两个因素的结合,首先,宏周围的括号\SS@xX@shift@val导致 TikZ 在解析坐标之前不扩展,并且\p{...}不会扩展为文字(x,y)类型的语法,而是重新定义\pgf@x,\pgf@y宏。因此,您可以按如下方式修复代码(截断不相关的部分:

let \p{shift} = \SS@xX@shift@val in ($ (letter.center) + (\x{shift},\y{shift}) $) circle (\SS@x@size@val);

但这仍然有点复杂,因为 TikZ 已经有了直接的移位语法,形式如下

([shift={(xshift,yshift)}]x,y)

括号的作用是隐藏解析器的括号,但由于它位于宏中,因此您不再需要它们。因此,您可以跳过该calc部分并使用以下代码

\documentclass{standalone}
\usepackage{accsupp}
\usepackage{xkeyval}
\usepackage{xcolor}
\usepackage{xxcolor,tikz,pagecolor}
%\usetikzlibrary{calc}
\makeatletter
\newcommand{\SS@xX@draw@val}{.}% default: the current text color
\define@key[SS]{xX}{draw}{\renewcommand{\SS@xX@draw@val}{#1}}
\newcommand{\SS@xX@fill@val}{\thepagecolor}% default: the current page color
\define@key[SS]{xX}{fill}{\renewcommand{\SS@xX@fill@val}{#1}}
\newcommand{\SS@xX@thickness@val}{0.125ex}
\define@key[SS]{xX}{thickness}{\renewcommand{\SS@xX@thickness@val}{#1}}
\newcommand{\SS@xX@shift@val}{(0ex,0ex)}
\define@key[SS]{xX}{shift}{\renewcommand{\SS@xX@shift@val}{#1}}
\newcommand{\SS@x@size@val}{0.25ex}
\define@key[SS]{x}{size}{\renewcommand{\SS@x@size@val}{#1}}
\newcommand*\x[1][]{\BeginAccSupp{method=escape,unicode,ActualText={x⃘}}%
\begin{tikzpicture}\setkeys[SS]{xX,x}{#1}
\node[inner sep=0pt,outer sep=0pt] (letter) {x};
\draw[line width=\SS@xX@thickness@val,\SS@xX@draw@val,fill=\SS@xX@fill@val] ([shift=\SS@xX@shift@val]letter.center) circle (\SS@x@size@val);
\end{tikzpicture}%
\EndAccSupp{}\ignorespaces}
\newcommand{\SS@X@size@val}{0.35ex}
\define@key[SS]{X}{size}{\renewcommand{\SS@X@size@val}{#1}}
\newcommand*\X[1][]{\BeginAccSupp{method=escape,unicode,ActualText={X⃘}}%
\begin{tikzpicture}\setkeys[SS]{xX,X}{#1}
\node[inner sep=0pt,outer sep=0pt] (letter) {X};
\draw[line width=\SS@xX@thickness@val,\SS@xX@draw@val,fill=\SS@xX@fill@val] ([shift=\SS@xX@shift@val]letter.center) circle (\SS@x@size@val);
\end{tikzpicture}%
\EndAccSupp{}\ignorespaces}
\makeatother

\begin{document}
\x\X
\end{document}

在此处输入图片描述

还要注意,几乎所有软件包都可以发现正在使用的引擎,因此您不需要[xetex]选项。

最后,这个更加简单且结构化pgfkeys,您可以考虑切换。

相关内容