活动!角色在 TikZ 中挂起

活动!角色在 TikZ 中挂起

下面的 MWE

!然而,当之内编译\hcancel好像挂起了?


期望的输出是:

在此处输入图片描述

但是如果我取消注释代码并打算生成最后取消的术语,编译似乎会挂起。

代码:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xcolor,etoolbox}
\usepackage{tikz}
\usetikzlibrary{calc}


\makeatletter
%% https://tex.stackexchange.com/questions/299798/make-characters-active-via-macro-in-math-mode
\newcommand{\DeclareMathActive}[2]{%
  % #1 is the character, #2 is the definition
  \expandafter\edef\csname keep@#1@code\endcsname{\mathchar\the\mathcode`#1 }
  \begingroup\lccode`~=`#1\relax
  \lowercase{\endgroup\def~}{#2}%
  \AtBeginDocument{\mathcode`#1="8000 }%
}

\newcommand{\std}[1]{\csname keep@#1@code\endcsname}
\patchcmd{\newmcodes@}{\mathcode`\-\relax}{\std@minuscode\relax}{}{\ddt}
\AtBeginDocument{\edef\std@minuscode{\the\mathcode`-}}
\makeatother

\DeclareMathActive{!}{\mathclose{\textcolor{blue}{\std{!}}}}



%% https://tex.stackexchange.com/questions/20643/diagonal-strikeout-starting-too-low-and-ending-too-high
\newcommand{\hcancel}[5]{%
    \tikz[baseline=(tocancel.base)]{
        \node[inner sep=0pt,outer sep=0pt] (tocancel) {#1};
        \draw[red] ($(tocancel.south west)+(#2,#3)$) -- ($(tocancel.north east)+(#4,#5)$);
    }%
}%

\begin{document}

Active ! works: $3!$

Cancel with non-active ! works: 
\hcancel{$3\std{!}$}{-3pt}{0pt}{3pt}{0pt}

\medskip
Combine cancel with active ! hangs: 
%\hcancel{$3!$}{-3pt}{0pt}{3pt}{0pt}% <-- This hangs!!

\end{document}

答案1

你真倒霉。

法语模块将babel变成!主动字符,以实施法语标点符号惯例。因此,从一开始,TikZ 就对此采取了预防措施,因为它!在语法中使用了 。因此,!如果使用法语,它会为主动字符赋予新的含义。

它本质上

\begingroup\lccode`~=`! \lowercase{\endgroup\def~}{\tikz@nonactiveexlmark}
\edef\tikz@nonactiveexlmark{\string!}

对于;:和 也是如此|。因此在tikzpicture环境中,指定的含义\mathclose{\textcolor{blue}{\std{!}}}会丢失。更糟糕的是,当!数学处于活动状态时,TeX 会进入无限循环:

  • !在数学模式下处理仿佛它是活跃的,所以它被它的含义所取代\tikz@nonactiveexlmark

  • \tikz@nonactiveexlmark被其含义所取代,类别!代码为 12

  • !在数学模式下处理仿佛它是活跃的,所以它被它的含义所取代\tikz@nonactiveexlmark

由于您不使用法语,因此您可以将\tikz@nonactiveexlmarkdo 重新定义为与 math active 相同!

\documentclass{article}
\usepackage{amsmath}
\usepackage{xcolor,etoolbox}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
%% http://tex.stackexchange.com/questions/299798/make-characters-active-via-macro-in-math-mode
\newcommand{\DeclareMathActive}[2]{%
  % #1 is the character, #2 is the definition
  \expandafter\edef\csname keep@#1@code\endcsname{\mathchar\the\mathcode`#1 }
  \begingroup\lccode`~=`#1\relax
  \lowercase{\endgroup\def~}{#2}%
  \AtBeginDocument{\mathcode`#1="8000 }%
}

\def\tikz@nonactiveexlmark{\mathclose{\textcolor{blue}{\std{!}}}}

\newcommand{\std}[1]{\csname keep@#1@code\endcsname}
\patchcmd{\newmcodes@}{\mathcode`\-\relax}{\std@minuscode\relax}{}{\ddt}
\AtBeginDocument{\edef\std@minuscode{\the\mathcode`-}}
\makeatother

\DeclareMathActive{!}{\mathclose{\textcolor{blue}{\std{!}}}}



%% http://tex.stackexchange.com/questions/20643/diagonal-strikeout-starting-too-low-and-ending-too-high
\newcommand{\hcancel}[5]{%
    \tikz[baseline=(tocancel.base)]{
        \node[inner sep=0pt,outer sep=0pt] (tocancel) {#1};
        \draw[red] ($(tocancel.south west)+(#2,#3)$) -- ($(tocancel.north east)+(#4,#5)$);
    }%
}%

\begin{document}

Active ! works: $3!$

Cancel with non-active ! works: 
\hcancel{$3\std{!}$}{-3pt}{0pt}{3pt}{0pt}

\medskip
Combine cancel with active ! hangs: 
\hcancel{$3!$}{-3pt}{0pt}{3pt}{0pt}% <-- This hangs!!

\end{document}

文本现在说了一个谎言。;-)

在此处输入图片描述

相关内容