![如何解决 \usetikzlibrary{babel} 的问题?](https://linux22.com/image/329798/%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%20%5Cusetikzlibrary%7Bbabel%7D%20%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%9F.png)
我目前正在更新 tkz-euclide 和新文档,但我刚刚遇到了以下问题。如果我使用 pdflatex 或 lualatex 和 pgf 2.1(pgf 2.1 中不存在 babel 库)编译此代码,则代码可以正常编译,但使用 3.0 pgf 时,我必须对调用进行注释\usetikzlibrary{babel}
(pgf 文档给出所以我建议总是通过 \usetikzlibrary{babel} 来加载这个库)。我想知道错误发生在哪里。特别是我想解决这个问题。
我\usetikzlibrary{babel}
收到错误 Latex 错误:./untitled 2.tex:46 未定义的控制序列。l.1 \tkz@line@start
babel 中的 Bug,tikzlibrary{babel}
我的代码中的 Bug。我想保留它
\usetikzlibrary{babel}
,但要避免错误。
%!TEX TS-program = pdflatex
\documentclass[a4paper]{article}
\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}
%\usetikzlibrary{babel}
\makeatletter
\pgfkeys{%
tkzdrawline/.cd,
start/.code = {\gdef\tkz@line@start{#1}},%
end/.code = {\gdef\tkz@line@end{#1}},%
start style/.code = {\tikzset{tkzstartstyle/.style={#1}}},%
end style/.code = {\tikzset{tkzendstyle/.style={#1}}},%
/tkzdrawline/.unknown/.code ={\let\searchname=\pgfkeyscurrentname\pgfkeysalso{%
\searchname/.try=#1,/tikz/\searchname/.retry=#1}}}
%<--------------------------------------------------------------–>
% Draw line
%<--------------------------------------------------------------–>
\pgfkeys{tkzdrawline/.cd,
start/.code = {\def\tkz@line@start{#1}},%
end/.code = {\def\tkz@line@end{#1}},
start style/.code = {\tikzset{tkzstartstyle/.style={#1}}},
end style/.code = {\tikzset{tkzendstyle/.style={#1}}},
/tkzdrawline/.unknown/.code = {\let\searchname=\pgfkeyscurrentname
\pgfkeysalso{\searchname/.try=#1,
/tikz/\searchname/.retry=#1}}}%
%<--------------------------------------------------------------–>
\def\tkzDrawLine{\pgfutil@ifnextchar[{\tkz@DrawLine}{%
\tkz@DrawLine[]}}%
\def\tkz@DrawLine[#1](#2,#3){%
\begingroup
\pgfkeys{tkzdrawline/.cd,start = {}, end = {}, start style={}, end style={},}
\pgfqkeys{/tkzdrawline}{#1}
\draw[ /tkzdrawline/.cd,#1] (#2) to%
node [at start,left,/tkzdrawline/.cd,tkzstartstyle] {\tkz@line@start}%
node [at end,right,/tkzdrawline/.cd,tkzendstyle] {\tkz@line@end} (#3);
\endgroup
}%
\makeatother
\begin{document}
\begin{tikzpicture}
\node (A) at (0,1) {};
\node (B) at (5,2) {};
\tkzDrawLine[end = {$\alpha$}](A,B)
\end{tikzpicture}
\end{document}
答案1
TikZbabel
库调用两个键handle active characters in code
和handle active characters in nodes
。后者控制如何解析节点内容。关键代码是:
\def\tikz@collect@arg#1{%
\iftikz@handle@active@nodes%
\iftikz@collect@pic%
\expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}%
\else%
\expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{\scantokens{#1}}}%
\fi%
\else%
\expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}%
\fi%
\tikz@collect@cont%
}
你发现了吗?它位于\scantokens
内部\else
分支中。这意味着节点的内容将被重新扫描,因此\makeatletter
不再适用。因此,当\tkz@line@start
调用时,将重新扫描标记,这意味着它是\tkz @ l i n e @ s t a r t
(使用空格分隔标记)。
如何克服这个问题取决于代码中这个问题的严重程度。如果这是一个典型的例子,你可以使用\csname tkz@line@start\endcsname
。另一个解决方案,在我看来更优雅一点,是使用 key node contents
。这没有似乎受到了影响\scantokens
(我猜是因为node contents
在样式中比在纯文本中更可能使用)。(有点奇怪的是,node
当我这样做时,我似乎仍然需要在第二个括号后使用空括号。)
%!TEX TS-program = pdflatex
\documentclass[a4paper]{article}
%\url{http://tex.stackexchange.com/q/298177/86}
\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{babel}
\makeatletter
\pgfkeys{%
tkzdrawline/.cd,
start/.code = {\gdef\tkz@line@start{#1}},%
end/.code = {\gdef\tkz@line@end{#1}},%
start style/.code = {\tikzset{tkzstartstyle/.style={#1}}},%
end style/.code = {\tikzset{tkzendstyle/.style={#1}}},%
/tkzdrawline/.unknown/.code ={\let\searchname=\pgfkeyscurrentname\pgfkeysalso{%
\searchname/.try=#1,/tikz/\searchname/.retry=#1}}}
%<--------------------------------------------------------------–>
% Draw line
%<--------------------------------------------------------------–>
\pgfkeys{tkzdrawline/.cd,
start/.code = {\def\tkz@line@start{#1}},%
end/.code = {\def\tkz@line@end{#1}},
start style/.code = {\tikzset{tkzstartstyle/.style={#1}}},
end style/.code = {\tikzset{tkzendstyle/.style={#1}}},
/tkzdrawline/.unknown/.code = {\let\searchname=\pgfkeyscurrentname
\pgfkeysalso{\searchname/.try=#1,
/tikz/\searchname/.retry=#1}}}%
%<--------------------------------------------------------------–>
\def\tkzDrawLine{\pgfutil@ifnextchar[{\tkz@DrawLine}{%
\tkz@DrawLine[]}}%
\def\tkz@DrawLine[#1](#2,#3){%
\begingroup
\pgfkeys{tkzdrawline/.cd,start = {}, end = {}, start style={}, end style={},}
\pgfqkeys{/tkzdrawline}{#1}
\draw[ /tkzdrawline/.cd,#1] (#2) to%
node [at start,left,/tkzdrawline/.cd,tkzstartstyle,node contents={\tkz@line@start}]%
node [at end,right,/tkzdrawline/.cd,tkzendstyle,node contents={\tkz@line@end}] {} (#3);
\endgroup
}%
\makeatother
\begin{document}
\begin{tikzpicture}
\node (A) at (0,1) {};
\node (B) at (5,2) {};
\tkzDrawLine[end = {$\alpha$}, start={$\beta$}](A,B)
\end{tikzpicture}
\end{document}