通常情况下,我使用 babel 和 !: 不会有问题,而且我也不常用 shortandoff-on 开关。但是自从我使用 !#1 参数创建命令后,问题又出现了。
在命令外部使用相同的语法可以正常工作,但在命令中我收到错误消息:
!包 tikz 错误:预期为 + 或 -。
不使用短路和断路开关如何解决问题?
\documentclass[french,a4paper]{article}
\RequirePackage{etex}
\RequirePackage[utf8]{inputenc}
\RequirePackage[T1]{fontenc}
\RequirePackage{fourier}
\RequirePackage{tikz}
\usetikzlibrary{calc,intersections}
%%%%%%%%%%%%%%%%%%%%%%
%%%% Francisation %%%%
%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{babel}
%%%%%%%%%%%%%%%%%%% ----------------------------------------
%%%% Géométrie %%%%
%%%%%%%%%%%%%%%%%%%-----------------------------------------
% #1 option du path
% #2 premier point
% #3 second point
% #4 longueur dans un sens
% #5 longueur dans l'autre
% défini Mil#1#2
\newcommand{\Med}[5][]{%
\path[#1,name path=Med#2#3] ($(#2)!.5!(#3)$) node (Mil#2#3) {}
($(Mil#2#3)!#4!90:(#3)$) -- ($(Mil#2#3)!#5!270:(#3)$) ; }
\tikzset{small dot/.style={fill=black,circle,scale=0.3}}
\begin{document}
%\shorthandoff{:!}
\begin{tikzpicture}
\coordinate[label=below left:$A$] (A) at (0,0) ;
\coordinate[label=below right:$B$] (B) at (4,0) ;
\draw (A)--(B) ;
%\Med[draw]{A}{B}{1}{1} ;
\draw($(A)!.5!(B)$) node (MilAB) {}
($(MilAB)!1!90:(B)$) -- ($(MilAB)!1!270:(B)$) ;
\end{tikzpicture}
%\shorthandon{:!}
\end{document}
答案1
TikZ v3.0.0 引入了一个babel
用于此目的的库。它记录在 pgfmanual 的第 526 页(42 巴别图书馆)。
在它的帮助下
\Med[draw]{A}{B}{1}{1} ;
现在可以工作:
\documentclass[french,a4paper]{article}
\RequirePackage{etex}
\RequirePackage[utf8]{inputenc}
\RequirePackage[T1]{fontenc}
\RequirePackage{fourier}
\RequirePackage{tikz}
\usetikzlibrary{calc,intersections}
\usetikzlibrary{babel} % <= the new library
%%%%%%%%%%%%%%%%%%%%%%
%%%% Francisation %%%%
%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{babel}
%%%%%%%%%%%%%%%%%%% ----------------------------------------
%%%% Géométrie %%%%
%%%%%%%%%%%%%%%%%%%-----------------------------------------
% #1 option du path
% #2 premier point
% #3 second point
% #4 longueur dans un sens
% #5 longueur dans l'autre
% défini Mil#1#2
\newcommand{\Med}[5][]{%
\path[#1,name path=Med#2#3] ($(#2)!.5!(#3)$) node (Mil#2#3) {}
($(Mil#2#3)!#4!90:(#3)$) -- ($(Mil#2#3)!#5!270:(#3)$) ; }
\tikzset{small dot/.style={fill=black,circle,scale=0.3}}
\begin{document}
\begin{tikzpicture}
\coordinate[label=below left:$A$] (A) at (0,0) ;
\coordinate[label=below right:$B$] (B) at (4,0) ;
\draw (A)--(B) ;
\Med[draw]{A}{B}{1}{1} ;
\draw($(A)!.5!(B)$) node (MilAB) {}
($(MilAB)!1!90:(B)$) -- ($(MilAB)!1!270:(B)$) ;
\end{tikzpicture}
\end{document}
结果:
答案2
TikZ 尝试与 babel 等软件包配合使用,这些软件包可以更改某些字符的 catcode。问题是 TikZ 需要解析各种表达式,例如($(a)!.5!(b)$)
包含特殊字符(如!
和)的表达式$
。对于我们人类的眼睛来说,这些看起来很容易识别。但 TikZ 必须在 TeX 的世界中工作,因此也必须考虑 catcode。因此它必须查找$
-as-math-shift 或$
-as-active 或$
-as-something-else。TikZ 确定要查找哪一个的方法是检查当前的特殊字符的 catcode 并查找它。因此它说“当前的 catcode 是什么$
?好的,使用该 catcode 查找$
。”(嗯,这比这更复杂一些......但这个解释就够了。)
问题出现在使用在不同的catcode 方案。如果你定义了一个命令,比如说,!
是“其他”,但在!
“活动”时使用它,那么你就会让解析器感到困惑。它期望!
是活动的(因为它在使用时间)但找不到它(因为嵌入!
被冻结为“其他”)。
最简单的解决方案是确保您在与命令将要使用的相同的 catcode 方案下定义命令。不幸的是,babel
直到之后才将其 catcode 方案落实到位,\begin{document}
因此要么在之后定义这些命令\begin{document}
(这很好,但风格不好)要么在定义它们时切换 catcode。后者使用\shorthandon
/\shorthandoff
开关很容易做到。
如果您要在不同的 catcode 方案下使用这些命令,那么生活就会变得更加复杂。实际上,您必须模拟 TikZ 的切换方法并定义不同版本的命令,每个方案一个,然后根据当前的 catcode 方案在它们之间切换。不过,这是一个更复杂的答案,所以如果您愿意,可以提出一个新的问题。
对于一个可以解决所有问题的方案,这里有一个可能的版本:
\documentclass[french,a4paper]{article}
%\url{http://tex.stackexchange.com/q/163929/86}
\RequirePackage{etex}
\RequirePackage[utf8]{inputenc}
\RequirePackage[T1]{fontenc}
\RequirePackage{fourier}
\RequirePackage{tikz}
\usetikzlibrary{calc,intersections}
%%%%%%%%%%%%%%%%%%%%%%
%%%% Francisation %%%%
%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{babel}
%%%%%%%%%%%%%%%%%%% ----------------------------------------
%%%% Géométrie %%%%
%%%%%%%%%%%%%%%%%%%-----------------------------------------
% #1 option du path
% #2 premier point
% #3 second point
% #4 longueur dans un sens
% #5 longueur dans l'autre
% défini Mil#1#2
\showthe\catcode`! % 12, other
\shorthandon{:!}
\showthe\catcode`! % 13, active
\newcommand{\Med}[5][]{%
\path[#1,name path=Med#2#3] ($(#2)!.5!(#3)$) node (Mil#2#3) {}
($(Mil#2#3)!#4!90:(#3)$) -- ($(Mil#2#3)!#5!270:(#3)$) ; }
\shorthandoff{:!}
\showthe\catcode`! % 12,other
\tikzset{small dot/.style={fill=black,circle,scale=0.3}}
\begin{document}
\showthe\catcode`! % 13, active
\begin{tikzpicture}
\showthe\catcode`! % 13, active
\coordinate[label=below left:$A$] (A) at (0,0) ;
\coordinate[label=below right:$B$] (B) at (4,0) ;
\draw (A)--(B) ;
\Med[draw]{A}{B}{1}{1}
\end{tikzpicture}
\end{document}
所有\showthe\catcode
内容都是在适当的节点打印 catcode!
以显示切换的工作方式。它们可以安全地被删除。