cmap是pdftex特有的功能,其它编译器不可用。
你之前那个问题是pdftex下,使用cjk支持中文出现的错误,不是标准行为。
cmap是pdftex特有的功能,其它编译器不可用。
你之前那个问题是pdftex下,使用cjk支持中文出现的错误,不是标准行为。
\the\dimexpr 1em\relax
= 10.0pt
\the\dimexpr 1em\relax = 10.0pt
\ExplSyntaxOn
\dim_to_decimal:n { 1em } = 10
\dim_to_decimal_in_bp:n { 1em } = 9.96265
\dim_to_decimal_in_sp:n { 1em } = 655360
\dim_to_decimal_in_unit:nn { 1em } { 1mm } = 3.51462
\ExplSyntaxOff
使用 enumitem
宏包。
这种情况推荐使用 description
环境。
\documentclass{ctexart}
\usepackage{enumitem}
\usepackage{zhlipsum}
\begin{document}
\zhlipsum[9][name=zhufu]
%% 全局设置使用 \setlist[description]{...}
\begin{description}[nosep,labelindent=2em,leftmargin=6.5em,font=\normalfont]
\item[参数a:] 啦啦啦
\item[参数b:] 啦啦啦
\item[参数c:] 欸\zhlipsum[14][name=zhufu]
\end{description}
\noindent\hrulefill
\zhlipsum[9][name=zhufu]
\begin{itemize}[nosep,left=5em]
\item[参数a:] 啦啦啦
\item[参数b:] 啦啦啦
\item[参数c:] 欸\zhlipsum[14][name=zhufu]
\end{itemize}
\begin{itemize}[left=5em]
\item[参数a:] 啦啦啦
\item[参数b:] 啦啦啦
\item[参数c:] 欸\zhlipsum[14][name=zhufu]
\end{itemize}
\end{document}
实际上,页眉处的“第一章 研究进展”等文字是由 \<section>mark
来进行记录的,这里的 <section>
就是 chapter
、section
、subsection
等。
使用 ctex 文档类或使用 ctexheading
宏包,或在 ctex
宏包中启用 heading=true
选项时,ctex
将自动地修改这些 \<section>mark
命令,类似于
\renewcommand{\sectionmark}[1]{\markright{\CTEXthesection #1}}
\renewcommand{\chaptermark}[1]{\markboth{\CTEXthechapter #1}{}}
这里的 \CTEXthesection
、\CTEXthechapter
就是在页眉处输出 “第一节”、“第一章” 的。
这里的变量 #1
就是 \<section>
中给出的标题,如“研究进展”。
因此只要重定义这些 mark,去掉诸如 \CTEXthesection
之类的命令,就可以实现你的需求了。ctex
宏包文档 6.3 节给出了两个例子。
这里再给一个例子:
\documentclass{ctexbook}
\usepackage{fancyhdr}
\usepackage{zhlipsum}
% \pagestyle{...} 放前面
\def\chaptermark#1{\markboth{#1}{}}
\def\sectionmark#1{\markright{#1}}
\begin{document}
\chapter{章一第}
\zhlipsum[1]
\section{节二第}
\zhlipsum[2-5]
\section{节三第}
\zhlipsum[6-10]
\end{document}
简单来说,当 label 不存在时,强行展开 \pageref
就会出现该错误。
第一次运行时,label 还没有写入 aux,这时,由于 \write
会自动展开它的参数,于是就出错了。
知道这之后,就容易解决了。
% \usepackage{expl3}% 在较新的 LaTeX2e 中是不必要的
\makeatletter
\ExplSyntaxOn
\cs_if_free:NT \use_ii:nnnnn
{ \cs_new:Npn \use_ii:nnnnn #1#2#3#4#5 { #2 } }
% 使用 hyperref,`\newlabel` 会写入 5 个参数,不使用 hyperref,则会写入 2 个参数,需要分别处理
% 第二个参数就是 page
\@ifpackageloaded{hyperref}
{
\cs_set_nopar:Npn \getrefpage #1
{ % 判断 label 是否存在,LaTeX 使用 "r@<label>" 保存 label
\cs_if_exist:cTF { r@#1 }
{ \exp_last_unbraced:Nv \use_ii:nnnnn { r@#1 } } % 获得5个中的第2个
{ 0 } % 若不存在则使用 0
}
}
{
\cs_set_nopar:Npn \getrefpage #1
{ % 同上
\cs_if_exist:cTF { r@#1 }
{ \exp_last_unbraced:Nv \use_ii:nn { r@#1 } }
{ 0 }
}
}
\ExplSyntaxOff
\makeatother
这样我们就可以使用 \getrefpage{<label>}
来获取 \label
定义的 label 的页码
\immediate\write\myoutfile{\getrefpage{nohere:a}}
\label{nohere:a} % label 需要在 \write 外部,才能创造一个label
由于 \label
是不可扩展的,若要在 \write
中写入,则需要使用 \noexpand
或 \string
:
\immediate\write\myoutfile{\getrefpage{nohere:a}\noexpand\label{nohere:a}}
\label{nohere:a}
另外,\label
中的 page 实际上是 \thepage
而不是绝对页码,也不一定是数字,例如修改了 page
计数器,或者使用了 \pagenumbering
。
此时,要想获得绝对页面,可以使用 zref-abspage
宏包,相应的,可以定义一个 \getzrefabspage
和 \getzrefpage
来获得绝对页码和相对页码。
% \usepackage{zref-abspage}
\makeatletter
\def\getzrefabspage#1{\zref@extract{#1}{abspage}}
\def\getzrefpage#1{\zref@ifrefundefined{#1}{0}{\zref@extract{#1}{page}}} % 同样需要检查是否存在
\makeatother
% \usepackage{zref-user,zref-abspage}
\zlabel{here:a}% 使用 \zlabel 而不是 \label
\immediate\write\myoutfile{\getzrefpage{here:a}\noexpand\zlabel{here:a}}
\immediate\write\myoutfile{\getzrefabspage{here:a}\noexpand\zlabel{here:a}}
当修改了 page
计数器,或者使用了 \pagenumbering
时,这二者是不同的。
一个完整的例子:
\documentclass{article}
% \usepackage{expl3}
\usepackage{zref-user,zref-abspage,lipsum}
\newwrite\myoutfile
\immediate\openout\myoutfile=\jobname-myoutfile.txt
\makeatletter
\def\getzrefabspage#1{\zref@extract{#1}{abspage}}
\def\getzrefpage#1{\zref@ifrefundefined{#1}{0}{\zref@extract{#1}{page}}}
\ExplSyntaxOn
\cs_if_free:NT \use_ii:nnnnn
{ \cs_new:Npn \use_ii:nnnnn #1#2#3#4#5 { #2 } }
\@ifpackageloaded{hyperref}
{
\cs_set_nopar:Npn \getrefpage #1
{
\cs_if_exist:cTF { r@#1 }
{ \exp_last_unbraced:Nv \use_ii:nnnnn { r@#1 } }
{ 0 }
}
}
{
\cs_set_nopar:Npn \getrefpage #1
{
\cs_if_exist:cTF { r@#1 }
{ \exp_last_unbraced:Nv \use_ii:nn { r@#1 } }
{ 0 }
}
}
\ExplSyntaxOff
\makeatother
\begin{document}
\immediate\write\myoutfile{\getzrefpage{here:a}\noexpand\zlabel{here:a}}
\immediate\write\myoutfile{\getzrefabspage{here:a}\noexpand\zlabel{here:a}}
\zlabel{here:a}
\immediate\write\myoutfile{\getrefpage{nohere:a}\noexpand\label{nohere:a}}
\label{nohere:a}
\lipsum[1-10]
\pagenumbering{alph}
\zlabel{here:b}.
\immediate\write\myoutfile{\getzrefpage{here:b}\noexpand\zlabel{here:b}}
\immediate\write\myoutfile{\getzrefabspage{here:b}\noexpand\zlabel{here:b}}
\label{nohere:b}.
\immediate\write\myoutfile{\getrefpage{nohere:b}\noexpand\label{nohere:b}}
\lipsum[10-12]
\end{document}
在较新的 LaTeX2e 发行版中,原生提供了 \ReadonlyShipoutCounter
和 totalpages
计数器来记录绝对页码。
使用 fancyhdr
宏包,重定义 \headrule
命令。
% \usepackage{fancyhdr}
% 定义三个长度
\newdimen\doublelineskip % 两横线间的距离
\setlength\doublelineskip{2pt}
\newdimen\headrulewidthA % 第一条线的宽度
\setlength\headrulewidthA{.8pt}
\newdimen\headrulewidthB % 第二条线的宽度
\setlength\headrulewidthB{.4pt}
% 定义(修改) headings 样式,如果你使用了自定义样式则不必进行该步骤
\fancypagestyle{headings}{
\renewcommand\headrulewidth{0.4pt}
}
% 基于 headings 样式定义一个 doubleline 样式,用于插入页眉“文武线”线,原来的 headings 仍然可用
% 如果使用了自己的样式,把 headings 修改为自己的样式名字
\fancypagestyle{doubleline}[headings]{
\renewcommand\headrule{%
\hrule height\headrulewidthA width\headwidth% 第一根线
\vskip \doublelineskip%
\hrule height\headrulewidthB width\headwidth}% 第二根线
}
完整的例子:
\documentclass{article}
\usepackage{fancyhdr}
\usepackage{lipsum}
\usepackage[paperheight=10cm,textheight=6cm]{geometry}
\newdimen\doublelineskip % 两横线间的距离
\setlength\doublelineskip{2pt}
\newdimen\headrulewidthA % 第一条线的宽度
\setlength\headrulewidthA{.8pt}
\newdimen\headrulewidthB % 第二条线的宽度
\setlength\headrulewidthB{.4pt}
\setlength\headheight{21pt}
\fancypagestyle{headings}{
\renewcommand\headrulewidth{0.4pt}
}
\fancypagestyle{doubleline}[headings]{
\renewcommand\headrule{%
\hrule height\headrulewidthA width\headwidth%
\vskip \doublelineskip%
\hrule height\headrulewidthB width\headwidth}
}
%\pagestyle{headings}
\pagestyle{doubleline}
\begin{document}
\section{SE1}
\lipsum[1-6]
\section{SE2}
\lipsum[7-15]
\end{document}
若使用 titleps
宏包,则重定义 \makeheadrule
。
% \usepackage{titleps}
% \newdimen 3 个,同 fancyhdr
\newpagestyle{doubleline}{
\renewcommand\makeheadrule{%
\makebox[0pt][l]{\rule[\doublelineskip]{\linewidth}{\headrulewidthA}}%
\rule{\linewidth}{\headrulewidthB}}%
}
可以使用 cleveref
宏包。
主要的配置命令如下:
% \usepackage{hyperref}
% \usepackage{cleveref} % 注意顺序
% 修改 autorefname,也方便在后面使用
\def\figureautorefname{Fig.}
\def\figureautorefnames{Figs.}
\crefformat{figure}{#2\figureautorefname~#1#3}
\crefmultiformat{figure}
{#2\figureautorefnames~#1#3}
{ and~#2#1#3}
{, #2#1#3}
{ and~#2#1#3}
\crefrangeformat{figure}{#3\figureautorefnames~#1#4 to~#5#2#6}
详细用法见说明文档。
完整的例子:
\documentclass{article}
\usepackage[colorlinks]{hyperref}
\usepackage{cleveref}
\def\figureautorefname{Fig.}
\def\figureautorefnames{Figs.}
\crefformat{figure}{#2\figureautorefname~#1#3}
\crefmultiformat{figure}
{#2\figureautorefnames~#1#3}
{ and~#2#1#3}
{, #2#1#3}
{ and~#2#1#3}
\crefrangeformat{figure}{#3\figureautorefnames~#1#4 to~#5#2#6}
\begin{document}
Hello, \LaTeXe.
\begin{figure}[h]
\caption{FIGURE ONE}\label{fig:1}
\centering\fbox{FIGURE ONE}
\end{figure}
\begin{figure}[h]
\caption{FIGURE TWO}\label{fig:2}
\centering\fbox{FIGURE TWO}
\end{figure}
\begin{figure}[h]
\caption{FIGURE THREE}\label{fig:3}
\centering\fbox{FIGURE THREE}
\end{figure}
reference: \ref{fig:1} \& \ref{fig:2} \& \ref{fig:3}
autoref: \autoref{fig:1} \& \autoref{fig:2} \& \autoref{fig:3}
cleveref: \cref{fig:1} \& \cref{fig:2} \& \cref{fig:3}
multi cref: \cref{fig:1,fig:2} \& \cref{fig:1,fig:2,fig:3} \& \cref{fig:1,,fig:2,,fig:3}
---------------------------
\crefmultiformat{figure}
{\figureautorefnames~#2#1#3}
{ and~#2#1#3}
{, #2#1#3}
{ and~#2#1#3}
\crefrangeformat{figure}{\figureautorefnames~#3#1#4 to~#5#2#6}
multi cref: \cref{fig:1,fig:2} \& \cref{fig:1,fig:2,fig:3} \& \cref{fig:1,,fig:2,,fig:3}
\end{document}
编译不成功的原因是
\newtcbtheorem
不会展开其参数;\setkeys
以及几乎所有的键设置命令(\keys_set:nn
、\pgfkeys
)都是不可扩展的。(也有一部分命令是可扩展的,如 \keyval_parse:nnn
、expkv
宏包的部分命令。)首先要说明的是,LaTeX3 不依赖任何其它宏包,甚至都不需要是 LaTeX。以及 l3keys
也不依赖 l3prop
,这二者是独立的。键值设置一般使用 l3keys
,l3prop
使用得较少。
要想成功编译,首先必须解析传入的键值,然后将其传给 \newtcbtheorem
。
可用的方法有很多,但是既然使用了 tcolorbox
,就使用 pgfkeys
来实现吧。
首先定义几个辅助命令与句柄(handler):
\makeatletter
\ExplSyntaxOn
\cs_new_nopar:Npn \zt@appto@clist #1#2 { \clist_put_right:Nn #2 {#1} }
\cs_new_nopar:Npn \zt@preto@clist #1#2 { \clist_put_left:Nn #2 {#1} }
\ExplSyntaxOff
\pgfkeys{
% {<prefix list>} {<clist>},把 <prefix list> 放到 <clist> 之前,<clist> 是一个 list 宏
/handlers/.prefix to clist/.code 2 args=%
\pgfkeysdef{\pgfkeyscurrentpath}{\zt@preto@clist{#1}{#2}},
% {<append list>} {<clist>}
/handlers/.append to clist/.code 2 args=%
\pgfkeysdef{\pgfkeyscurrentpath}{\zt@appto@clist{#1}{#2}},
}
\tcbset{
zljTheoStyle/.style={}, % 你自己的代码
}
% 这个命令类似于 \tikzset、\tcbset,它的形式是 \ztpgfset{<module>}{<key-val>}
\def\ztpgfset#1{\pgfqkeys{zt/#1}}
\NewDocumentCommand\ztset{O{}}
{
\def\zt@tmplist{}% 这个命令用于保存解析的键值
\ztpgfset{tcb}{#1} % 这个命令用于解析传入的键值参数,使用 tcb 模块
\def\zt@tmp{\newtcbtheorem{zljtest}{name}}
\expandafter\zt@tmp\expandafter{\zt@tmplist,zljTheoStyle,}{zljtest} % 必须展开解析得到的键值
}
现在就可以定义自己的键了,把它们放到 tcb 模块:
\ztpgfset{tcb}{
color/.append to clist={colbacktitle={#1}}{\zt@tmplist},% 把 "colbacktitle={#1}" 放到 \zt@tmplist 之后,效果和 "color/.code=\zt@appto@clist{#1}{\zt@tmplist}" 一样
color/.default=red,% 默认值为 red
cf/.append to clist={colframe=#1}{\zt@tmplist},% 把 "colframe=#1" 放到 \zt@tmplist 之后
cf/.default=yellow!80!black,
}
\makeatother
一个完整的例子:
\documentclass{ctexart}
\usepackage[most]{tcolorbox}
\makeatletter
\ExplSyntaxOn
\cs_new_nopar:Npn \zt@appto@clist #1#2 { \clist_put_right:Nn #2 {#1} }
\cs_new_nopar:Npn \zt@preto@clist #1#2 { \clist_put_left:Nn #2 {#1} }
\ExplSyntaxOff
\pgfkeys{
/handlers/.prefix to clist/.code 2 args=%
\pgfkeysdef{\pgfkeyscurrentpath}{\zt@preto@clist{#1}{#2}},
/handlers/.append to clist/.code 2 args=%
\pgfkeysdef{\pgfkeyscurrentpath}{\zt@appto@clist{#1}{#2}},
}
\tcbset{
zljTheoStyle/.style={}, % 你自己的代码
}
\def\ztpgfset#1{\pgfqkeys{zt/#1}}
\NewDocumentCommand\ztset{O{}}
{
\def\zt@tmplist{}% 这个命令用于保存解析的键值
\ztpgfset{tcb}{#1} % 这个命令用于解析传入的键值参数,使用 tcb 模块
\def\zt@tmp{\newtcbtheorem{zljtest}{name}}
\expandafter\zt@tmp\expandafter{\zt@tmplist,zljTheoStyle,}{zljtest}
}
\ztpgfset{tcb}{
color/.append to clist={colbacktitle={#1}}{\zt@tmplist},% 把 "colbacktitle={#1}" 放到 \zt@tmplist 之后
color/.default=red,% 默认值为 red
cf/.append to clist={colframe=#1}{\zt@tmplist},% 把 "colframe=#1" 放到 \zt@tmplist 之后
cf/.default=yellow!80!black,
}
\makeatother
\begin{document}
\ztset[color=blue,cf]
\begin{zljtest}{}{}
测试基
\end{zljtest}
\end{document}
在正常的 LaTeX3
环境(类代码,字符码等)下是一样的。
\cs_new:cn
实际上是 \exp_args:Nc \cs_new:Nn
,\exp_args:Nc <#1> <#2>
是 \expandafter<#1>\csname <#2>\endcsname
。
所以实际上 \cs_new:cn
就是先把第一个参数变成一个控制序列,然后再把 \cs_new:Nn
放在这个控制序列的前面。
难点在于既要使用 alignat
环境(包含编号),又要有大括号,又要跨括号对齐。任意两点其实都不算难,但是三点都要实现就比较麻烦了。这里提供两种并不优雅的解决方案。
一个是使用 array
环境。
% \usepackage{array,multirow}
{\renewcommand\arraystretch{1.3}\[
\begin{array}{r@{} *{2}{r@{}>{{}}c<{{}}@{}} l@{\qquad}r} %% @{} 为了去除间距
\multirow{2}*{$\biggl\{\biggr.$}& x & + & 3y & = & 11 & (1) \\
& 2x & - & y & = & -9 & (2) \\
\multirow{2}*{result$\biggl\{\biggr.$} & x & = & x_1 &&& (1') \\
& y & = & y_1 &&& (2')
\end{array}
\]}
效果如下:
这里的大括号是对齐的
不过编号的位置需要设置,这里使用一个 \quad
。
另一个就是使用 empheq
宏包的 empheq
环境,该宏包属于 mathtools
的一部分,(详细用法查看其参考文档)。
实际上,不要求括号处对齐是比较容易实现的:
% \usepackage{amsmath,empheq}
\begin{empheq}[left={ }\empheqlbrace]{alignat*=2}
x &+{}& 3y &= 11, \tag{1} \\
2x &-{}& y &= -9 \tag{2}
\end{empheq}
\begin{empheq}[left=\llap{result}\empheqlbrace]{align*}
x&=x_1, \tag{1'} \\
y&=y_1 \tag{2'}
\end{empheq}
如果在括号处对齐则需要半手动调整间距了:
% \usepackage{amsmath,empheq}
\newdimen\tmpadim
\newdimen\tmpbdim
%% 这两个是为了计算宽度
\settowidth\tmpadim{$
\begin{alignedat}{2}
x &+{}& 3y &= 11, \\
2x &-{}& y &= -9
\end{alignedat}
$}
\settowidth\tmpbdim{$
\begin{aligned}
x &= x_1, \\
y &= y_1
\end{aligned}
$}
\begin{empheq}[left={ }\empheqlbrace]{alignat*=2}
x &+{}& 3y &= 11, \tag{1}\label{eq:1} \\
2x &-{}& y &= -9 \tag{2}
\end{empheq}
\begin{empheq}[left=\llap{result}\empheqlbrace]{align*}
x&=x_1, \hspace{\dimexpr\tmpadim-\tmpbdim} \tag{1'}\label{eq:1'} \\ % 插入一个间距
y&=y_1 \tag{2'}
\end{empheq}
\eqref{eq:1} and \eqref{eq:1'}
括号处是对齐的:
我们知道,如果一个宏是使用如下方式定义的:
\def\foo#1\T{something #1 else...}
那么在使用该宏时必须使用 \T
作为(第一个)参数的分隔符,也就是必须使用
\foo balabala\T
如若没有 \T
,TeX 将会报错。
你的代码就是这种错误。
因为使用了 \cs_new:Npn \__tk_before_slashsearch:w #1 / #2 \s_stop
,所以参数分隔符 /
和 \s_stop
是必须给出的。
但是 \clist_map_function:NN <clist> <func>
所做的仅仅是把 <clist>
的 <item>
置于 <func>
之后,也就是
\__tk_before_slashsearch:w <item>
这样 \s_stop
是没有的,所以必须通过一个辅助函数给出,也就是原来 \__tk_slashed_items:n
的作用之一。
因为这里的 \tk_iteratesearch:N
必须可扩展,所以不能使用 \clist_map_inline:Nn
。
没懂你想干什么。但是呢 LaTeX3 提供了一个 \cs_to_str:N
命令,用于输出控制序列的名字。
\documentclass{article}
\ExplSyntaxOn
\cs_new_protected_nopar:Npn \csusewithname #1
{
\cs_to_str:N #1
#1
}
\ExplSyntaxOff
\begin{document}
\csusewithname\section{sec 1}
\csusewithname\label{lab:1}
\ref{lab:1}
\end{document}
出现这种情况是因为 extarrows
宏包内部使用了 amsmath
宏包的 \ext@arrow
命令,该命令的第 #6
、#7
参数对应于 \xlongrightarrow[<#6>]{<#7>}
。只是这 #6
、#7
会被使用两次,一次用于测量盒子的宽度,另一次则用于输出。(见 \ext@arrow
的定义,位于 amsmath.sty
)
知道这个就容易修改了:
\makeatletter
\newif\ifext@arrow@measuring@
\let\saved@ext@arrow\ext@arrow % 保存原始定义
\def\ext@arrow#1#2#3#4#5#6#7{%
\mathrel{\mathop{%
\setbox\z@\hbox{#5\displaystyle}%
\ext@arrow@measuring@true% 增加一个
\setbox\tw@\vbox{\m@th
\hbox{$\scriptstyle\mkern#3mu{#6}\mkern#4mu$}%
\hbox{$\scriptstyle\mkern#3mu{#7}\mkern#4mu$}%
\copy\z@
}%
\hbox to\wd\tw@{\unhbox\z@}}%
\ext@arrow@measuring@false% 增加一个,实际上是不需要的,由于 \mathop 构建一个组
\limits
\@ifnotempty{#7}{^{\if0#1\else\mkern#1mu\fi
#7\if0#2\else\mkern#2mu\fi}}%
\@ifnotempty{#6}{_{\if0#1\else\mkern#1mu\fi
#6\if0#2\else\mkern#2mu\fi}}}%
}
% 直接写 \def\arrowmeasuring#1#2{\ifext@arrow@measuring#1\else#2\fi} 也可以
\def\arrowmeasuring{\ifext@arrow@measuring@\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
\def\fake@footnotemark{\textsuperscript{\the\numexpr\value{footnote}+1\relax}}
\def\longrightmark{\arrowmeasuring{\fake@footnotemark}{\footnotemark}} % 增加一个判断
\makeatother
然后呢就可以使用
\begin{tabular}{cc}
a & b \\
$\xlongrightarrow{x + y \longrightmark}$ & d
\end{tabular}
\footnotetext{note1}
或者
\begin{table}[htbp]
\begin{tabular}{cc}
a & b \\
$\xlongrightarrow{x + y \arrowmeasuring{\csname fake@footnotemark\endcsname}{\tablefootnote{note2}}}$ & d
\end{tabular}
\end{table}
都能正确生成了。
一个更好的办法是使用 etoolbox
宏包的 \patchcmd
命令,而不直接重定义 \ext@arrow
。
%\usepackage{etoolbox}
\patchcmd\ext@arrow{\mathop}{\ext@arrow@measuring@true\mathop}{}{}
% 不在 \mathop 之内,必须加上
\patchcmd\ext@arrow{\limits}{\ext@arrow@measuring@false\limits}{}{}
完整的例子:
\documentclass[UTF8,11pt]{ctexart}
\usepackage{hyperref}
\usepackage{extarrows}
\usepackage{tablefootnote}
\usepackage{etoolbox}
\makeatletter
\newif\ifext@arrow@measuring@
\let\saved@ext@arrow\ext@arrow % 保存原始定义
\def\fake@footnotemark{\textsuperscript{\the\numexpr\value{footnote}+1\relax}}
\patchcmd\ext@arrow{\mathop}{\ext@arrow@measuring@true\mathop}{}{}
\patchcmd\ext@arrow{\limits}{\ext@arrow@measuring@false\limits}{}{}
\def\arrowmeasuring#1#2{\ifext@arrow@measuring@#1\else#2\fi}
\def\longrightmark{\arrowmeasuring{\fake@footnotemark}{\footnotemark}}
\def\amsmeasuring#1#2{\ifmeasuring@#1\else#2\fi}
\makeatother
\begin{document}
\begin{tabular}{cc}
a & b \\
$\xlongrightarrow{x + y \longrightmark}$ & d
\end{tabular}
\footnotetext{note1}
\begin{table}[htbp]
\begin{tabular}{cc}
a & b \\
$\xlongrightarrow{x + y \arrowmeasuring{\csname fake@footnotemark\endcsname}{\tablefootnote{note2}}}$ & d
\end{tabular}
\end{table}
\end{document}
对 \ext@arrow
的修改应该是不会影响正常使用的。这对于所有使用 \ext@arrow
定义的命令都是有效的,如 \xrightarrow
等。
另一个方案见:https://tex.stackexchange.com/questions/335968/skipped-footnote-numbers-in-math-mode。
不建议在数学模式下使用 footnote
问 关于XeLaTeX的字体cmap的问题