我想使用\ref{#1}c
而不是\cref{#1}
来解决一些自动完成问题。
我一直在尝试使用以下代码来实现这一点:
\let\oldref\ref
\def\ref{\futurelet\@nexttoken\myref}
\def\myref#1{\if c\@nexttoken\creftemp{#1}\else\oldref{#1}\fi}
\def\creftemp#1c{\cref{#1}}
但结果没有改变。哪里出了问题?
梅威瑟:
\documentclass[10pt]{article}
\usepackage{hyperref}
\usepackage{amsthm}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}
\makeatletter
\let\oldref\ref
\def\ref{\futurelet\@nexttoken\myref}
\def\myref#1{\if c\@nexttoken\creftemp{#1}\else\oldref{#1}\fi}
\def\creftemp#1c{\cref{#1}}
\makeatother
\begin{document}
\begin{theorem}[sdfs] \label{sdf} asfa \end{theorem}
\cref{sdf} = theorem 1
\ref{sdf}c = theorem 1
\ref{sdf} c = 1 c
\end{document}
答案1
你的定义有几个缺陷。你需要先吸收论证,\ref
然后再检查是否c
符合。
条件也应该结束前调用“gobbling”宏。
最后,\ref
在文档开始时被重新定义hyperref
,因此您自己的重新定义应该被延迟。
另一个小问题是使用\let
命令\ref
来hyperref
使其更强大;在这里我使用\NewCommandCopy
已经可用一年多了;如果你的 TeX 发行版较旧,请使用包\LetLtxMacro
中的命令letltxmacro
。
\documentclass[10pt]{article}
\usepackage{amsthm}
\usepackage{hyperref}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}
\makeatletter
\AtBeginDocument{%
\NewCommandCopy{\old@ref}{\ref}%
\def\ref#1{\def\temp@ref{#1}\futurelet\@nexttoken\new@ref}%
}
\def\new@ref{%
\if c\noexpand\@nexttoken
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\cref@eatc{\temp@ref}}%
{\old@ref{\temp@ref}}%
}
\def\cref@eatc#1c{\cref{#1}}
\makeatother
\begin{document}
\begin{theorem}[sdfs] \label{sdf} asfa \end{theorem}
\cref{sdf} = theorem 1
\ref{sdf}c = theorem 1
\ref{sdf} c = 1 c
\end{document}
为什么\noexpand
?因为你不想扩展下面的标记,它可能是宏或~
。
您可能会欣赏expl3
相同的版本,它更易于实现,但在概念上并没有什么不同。
\documentclass[10pt]{article}
\usepackage{amsthm}
\usepackage{hyperref}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}
\ExplSyntaxOn
\AtBeginDocument
{
\NewCommandCopy{\__refc_saved_ref:n}{\ref}
\cs_set_eq:NN \ref \__refc_new_ref:n
}
\tl_new:N \l__refc_arg_tl
\cs_new_protected:Nn \__refc_new_ref:n
{
\tl_set:Nn \l__refc_arg_tl { #1 }
\peek_charcode_remove:NTF c
{
\exp_args:NV \cref \l__refc_arg_tl
}
{
\exp_args:NV \__refc_saved_ref:n \l__refc_arg_tl
}
}
\ExplSyntaxOff
\begin{document}
\begin{theorem}[sdfs] \label{sdf} asfa \end{theorem}
\cref{sdf} = theorem 1
\ref{sdf}c = theorem 1
\ref{sdf} c = 1 c
\end{document}
答案2
这里我使用一个标记循环来获取结果。为了使 的行为正确hyperref
,必须将 的重新定义\ref
放在\AtBeginDocument
。
\documentclass{article}
\usepackage{hyperref}
\usepackage{amsthm}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}
\let\oldref\ref
\usepackage{tokcycle}
\newcommand\tcpushliteral[1]{\tcpush{\noexpand#1}}
\stripgroupingtrue
\AtBeginDocument{\renewcommand\ref[1]{%
\tokencycle
{\ifx c##1\tcpush{\cref{#1}}\else\tcpush{\oldref{#1}##1}\fi
\tcpushliteral{\endtokcycraw}}
{\tcpushliteral{\truncatenow{##1}}}
{\ifx\truncatenow##1\else
\tcpush{##1}\fi\tcpush{\oldref{#1}}%
\tcpushliteral{\endtokcycraw}}
{\tcpush{\oldref{#1}##1}\tcpushliteral{\endtokcycraw}}%
}}
\begin{document}
\begin{theorem}[sdfs] \label{sdf} asfa \end{theorem}
\cref{sdf} = theorem 1
\ref{sdf}c = theorem 1
\ref{sdf} c = 1 c
\ref{sdf}x = 1x
\ref{sdf}\today = 1\today
\ref{sdf}{\itshape d}x = 1{\itshape d}x
\end{document}