下面的 MWE
!
使用以下解决方案在数学模式下激活在数学模式下通过宏激活字符和- 使用
tikz
\hcancel
通过斜线开始太低,结束太高。
!
然而,当之内编译\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@nonactiveexlmark
do 重新定义为与 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}
文本现在说了一个谎言。;-)