Tikz 短命令和关闭新命令问题

Tikz 短命令和关闭新命令问题

通常情况下,我使用 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!以显示切换的工作方式。它们可以安全地被删除。

相关内容