出于显而易见的原因,放置脚注标记是一种很好的做法(实际上也是正确的做法)后标点符号,这是:
- 错误:
- 这是声明1。
- 这是语句2,这是另一个语句。
- 这是问题3吗?
- 正确的:
- 这是一个声明。1
- 这是一个声明,2这是另一个声明。
- 这是一个问题吗?3
现在,我很健忘,所以我通常做错事。也就是说,我经常写成This is a statement\footnotemark.
而不是This is a statement.\footnotemark
。此外,我很懒,所以我宁愿让计算机帮我纠正我(和其他人)的错误,或者至少提醒我。因此,我制作了以下宏:
\let\oldfootnotemark\footnotemark
\renewcommand{\footnotemark}{%
\@ifnextchar.{%
% I neet to change this line so the dot and the mark switch places
\oldfootnotemark\textcolor{red}{\bfseries Fix me!}
}{\oldfootnotemark\xspace}%
}
这是一个 MWE,在实际实现中,有多个\@ifnextchar
嵌套,涵盖逗号、分号、句号、问号和感叹号。我的具体问题是:
- 我怎样才能抑制下一个字符(宏后面的字符)以便脚注标记和标点符号交换位置?请考虑这也必须与
\footnote
已经接受参数的参数一起工作。 - 有没有更优雅的方式来处理这个其他棕褐色嵌套
\@ifnextchar
?
我几乎确信这无法在 LaTeX 中完成,但在放弃之前,我宁愿咨询专家。
提前致谢。
注意:请不要提出建议sed
或任何其他基于 bash 的方法。我知道我可以在 Makefile 中添加一些行来修复 latex 代码,但这不是重点(已经实现)。
答案1
我正在使用完全不同的方法添加第二个答案。而我的另一个答案用于listofitems
搜索标点符号列表,它只能处理后面跟着\footnotemark
单个标点符号的情况。
\footnotemark
例如,如果 后面跟着 、...
、."
甚至".
,那么它将不起作用''
。为了在这里处理这个问题,在不使用包的情况\futurelet
下,我使用了一种模仿cite
包中使用的方法,检查连续的字符以查看它们是否与 中找到的字符匹配\marklist
。
这里,我仅介绍了 的方法\footnotemark
,但没有理由不能为 提供类似的方法\footnote
。请注意,这里不提供对可选参数的支持。
\documentclass{article}
\let\oldfootnotemark\footnotemark
\def\marklist{.,:;!?'"}% LIST OF SEARCHED-FOR PUNCTUATION
\def\foundmarks{}%
\def\foundmark#1{\footnotemark}% EATS THE RESIDUAL MARK AND LOOKS AGAIN
\def\nomarksfound{%
\foundmarks
\gdef\foundmarks{}%
\oldfootnotemark{}}% PRINTS OUT FOUND MARKS FOLLOWED BY ORIG. \footnotemark
% \foundmarks ARE SAVED AND PRINTED TOGETHER FOR KERNING REASONS, e.g. ''
\def\footnotemark{%
\let\fnmcloseout\nomarksfound% ASSUME NO PUNCTUATION FOLLOWS \footnotemark
\futurelet\tmpA\testformarks}
\def\testformarks{%
\expandafter\marktest\expandafter\tmpA\marklist\delimiter\fnmcloseout}
\makeatletter
\def\marktest#1#2#3\delimiter{%
\ifx#1#2%
\g@addto@macro\foundmarks{#2}% SAVED, NOT PRINTED, FOR KERNING REASONS
\let\fnmcloseout\foundmark% SET UP CLOSEOUT TO DO IT AGAIN
\fi
\ifx\relax#3\relax\else
\marktest#1#3\delimiter% AGAIN, UNTIL MARK LIST EXHAUSTED
\fi}
\makeatother
\begin{document}
Word\footnotemark next
Word\footnotemark{} next
Word\footnotemark: Next
Word\footnotemark. Next
Word\footnotemark... Next
``Word\footnotemark.'' Next
\end{document}
如果真的想采用这种方法(没有可选参数)\footnote
,那么可以简单地定义
\renewcommand\footnote[1]{%
\stepcounter{footnote}%
\footnotetext{#1}%
\addtocounter{footnote}{-1}%
\footnotemark%
}
调用上述版本的\footnotemark
。
答案2
这可能就足够了,但是正如 MWE 中所描述的,在某些情况下可能会中断。
\documentclass{article}
\usepackage{listofitems}
\let\oldfootnotemark\footnotemark
\renewcommand\footnotemark[1]{%
\setsepchar{.||,||;||:||"||?||!}%
\readlist\nextchar{ #1}%
\ifnum\listlen\nextchar[]>1\relax #1\oldfootnotemark\else
\oldfootnotemark\expandafter#1\fi%
}
\let\oldfootnote\footnote
\renewcommand\footnote[2]{%
\setsepchar{.||,||;||:||"||?||!}%
\readlist\nextchar{ #2}%
\ifnum\listlen\nextchar[]>1\relax #2\oldfootnote{#1}\else
\oldfootnote{#1} \expandafter#2\fi%
}
\begin{document}
xyz\footnotemark
xyz\footnotemark{} text
xyz\footnotemark.
xyz\footnotemark,
xyz\footnotemark!
``xyz\footnotemark"
\footnotemark\begin{tabular}{|c|}\hline x\\\hline\end{tabular} can occur right
before an environment.\bigskip
Footnote\footnote{My fn}, changed separately.
Footnote\footnote{My fn} was changed separately.
Footnote\footnote{My fn}\begin{tabular}{|c|}\hline x\\\hline\end{tabular} can occur
before environment, but a space is injected.\bigskip
BAD CASE:
Footnote\footnote{My fn}-mid-word has wrong spacing.
\end{document}
答案3
到目前为止,我已经让这个解决方案奏效了。它并不强大,因此欢迎提出意见和改进。
\let\oldfootnote\footnote
\let\oldfootnotemark\footnotemark
\renewcommand{\footnote}[2]{%
\IfSubStr{.,;?!}{#2}{%
#2\oldfootnote{#1}\xspace%
}{%
\oldfootnote{#1}\xspace#2%
}%
}
\renewcommand{\footnotemark}[1]{%
\IfSubStr{.,;?!}{#1}{%
#1\oldfootnotemark\xspace%
}{%
\oldfootnotemark\xspace#1%
}%
}