我刚刚发现tikzmark
感谢博客,听起来很有希望。我从 CTAN 下载了文件,并将它们放在tikzlibrarytikzmark.code.tex
与tikzmarklibrarylistings.code.tex
我的主文件夹相同的文件夹中.tex
。我试图从手册本身重现第一个示例,法语。
\documentclass[french]{beamer}
\usepackage{babel}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\begin{document}
\begin{frame}{Test}
\[
\tikzmark{a} \frac{x^2}{n!}
\]
Test \tikz[remember picture,overlay,baseline=0pt] \draw[->] (0,1em) to (pic cs:a);
\end{frame}
\end{document}
:
我猜这与特定语法中的冒号有关tikzmark
,对吧?有什么想法吗?如果我french
用替换,编译就很好english
。
答案1
它不是结肠,而是埋藏的非活动性分结肠。
TikZ 在处理活动分号方面非常聪明。当它启动一个\tikz
命令(或一个\draw
或其他命令)时,它会调用某个宏来收集命令的其余部分。命令的其余部分是直到下一个分号的所有内容(“直到”通常为 TeX 分组)。但是,由于存在诸如使babel
分号活动之类的流行软件包,因此分隔 TikZ 命令的分号可以是活动的也可以是非活动的(好吧,它可能有很多种,但这些是最有可能的),并且两者并不等同。因此,TikZ 在调用宏之前会检查分号的状态,并根据分号的状态调用不同的宏。
一切都非常好。
输入tikzmark
。这将扩展为\tikz <something>;
。但是,它是在文档正式开始之前定义的。这意味着分号具有前导分号的状态。 babel
只会在实际文档开始时更改分号的状态,这意味着这分号不起作用。但当\tikzmark
实际使用时,TikZ 检查当前的分号状态。因此,它开始寻找活动的分号,但找不到,导致它在混乱中退出。
可能有几种解决方案,但我认为最好的方法是\tikzmark
进行自己的分结肠检查并使用右分结肠^TM(TM = tikzmark)。
下面是一些可以实现该功能的代码:
\documentclass[french]{beamer}
%\url{https://tex.stackexchange.com/q/110014/86}
\usepackage{babel}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\makeatletter
\begingroup
\catcode`\;=\active
\gdef\tikzmark@active#1#2{%
\tikz[remember picture with id=#2] #1;}
\endgroup
\def\tikzmark@nonactive#1#2{%
\tikz[remember picture with id=#2] #1;}
\renewcommand\tikzmark[2][]{%
\ifnum\catcode`\;=\active
\let\@next=\tikzmark@active
\else
\let\@next=\tikzmark@nonactive
\fi
\@next{#1}{#2}}
\makeatother
\begin{document}
\begin{frame}{Test}
\[
\tikzmark{a}
\frac{x^2}{n!}
\]
Test \tikz[remember picture,overlay,baseline=0pt] \draw[->] (0,1em) to (pic cs:a);
\end{frame}
\end{document}
假设没有人告诉我这是 Catcode Protection^TM 的错误实现,那么我会将其粘贴在 tikzmark 代码中并将其上传到 CTAN。
为了清晰起见添加这是在本质上与遇到的问题相同tikz 声明函数和 babel 法语选项和巴别塔和 pgf 间谍之间发生意外冲突。对于上述每一种情况,我都倾向于修改原始代码以处理活动分号的解决方案 - 这是我上面所做的。在这种情况下,弄清楚到底需要修改什么在每种情况下都有点不同。其他问题包含不需要这种修改的其他可能性,因此在类似情况下更容易有人自己实现。 然而但是,我要警告的是,使用beamer
可能会导致与 catcodes 有关的某些问题,因为除非您使用该fragile
选项,否则 catcodes 会在框架内“冻结”。