使用以下代码:
\documentclass[a4paper]{report}
\usepackage{lipsum,amsthm,thmtools,hyperref}
\declaretheoremstyle[
spaceabove=\topsep, spacebelow=\topsep,
headfont=\normalfont\bfseries,
notefont=\bfseries, notebraces={}{},
bodyfont=\normalfont\itshape,
postheadspace=\mw@mystyleposthead,
name={\ignorespaces},
numbered=no,
headpunct=.]
{mystyle}
\declaretheorem[style=mystyle]{thm}
\begin{document}
\hypertarget{thm1}{}
\begin{thm}
Some theorem. Some theorem. Some theorem. Some theorem.
\end{thm}
\lipsum[1]
\begin{thm}[name=Exension of \hyperlink{thm1}{the one above}]
The extension. The extension. The extension. The extension.
\end{thm}
\end{document}
我非常简化了我的实际上下文。目的是将 放在\hyperlink
定理名称中。然而,在代码中我得到了错误:
Undefined control sequence.
\th@mystyle ...@indent \noindent \thm@headsep \mw
@mystyleposthead\relax \th...
l.23 S
ome theorem. Some theorem. Some theorem. Some theorem.
在我的上下文中我得到:
Use of \\thmt@setnewoptarg doesn't match its definit
ion.
\@ifnextchar ... \reserved@d =#1\def \reserved@a {
#2}\def \reserved@b {#3}\f...
l.276 ...ttr}[name=Extension of \hyperlink{gu}{1}]
添加fontspec
上面的代码会使错误变成:
Runaway argument?
\x@protect \[\protect \[ \@nil \@ifpackageloaded {amstex}{\def \@tempa \ETC.
/usr/local/texlive/2013/texmf-dist/tex/latex/amscls/amsthm.sty:435: Paragraph e
nded before \@tempa was complete.
<to be read again>
\par
l.435 \newenvironment{proof}[1][\proofname]{\par
所以问题是:错误为什么会改变?我知道解释“我的上下文”中发生了什么变化并不容易(甚至可能不可能),但恐怕我无法发布该上下文,因为它使用了我自己的包。所以你可以避免回答有关我的上下文的问题。另一个问题是,正如标题所示,主要问题:如何获取定理名称中的超链接?
编辑:
正如 David Carlisle 指出的那样,我缺少了\makeatletter
,但不仅仅是。添加:
\makeatletter
\newlength\mw@mystyleposthead
\mw@mystyleposthead=0.5em
就在\declaretheoremstyle
和调用之前noindentafter
,最后更改thm
为@thmattr
将错误变成:
Runaway argument?
\x@protect \[\protect \[ \@nil \@ifpackageloaded {amstex}{\def \@tempa \ETC.
/usr/local/texlive/2013/texmf-dist/tex/latex/amscls/amsthm.sty:435: Paragraph e
nded before \@tempa was complete.
<to be read again>
\par
l.435 \newenvironment{proof}[1][\proofname]{\par
删除后fontspec
错误变成:
./thmname@[email protected]:27: Undefined control sequence.
\hyper@@link ->\let \Hy@reserved@a
\relax \@ifnextchar [{\hyper@link@ }{\hyp...
l.27 ...ension of \hyperlink{thm1}{the one above}]
因此,带有 的错误fontspec
与以前相同,而不带有 的错误已经改变,并且仍然不是我上下文中的错误,在不改变错误(或几乎不改变错误)的情况下,我尽可能地减少错误,如下所示:
\documentclass[a4paper]{report}
\usepackage{amsthm}
\usepackage{xparse,thmtools,mathtools}
\usepackage{hyperref}
\makeatletter
%Declares theorem style mystyle. Requires amsthm.
\declaretheoremstyle[
spaceabove=\topsep, spacebelow=\topsep,
headfont=\normalfont\bfseries,
notefont=\bfseries, notebraces={}{},
bodyfont=\normalfont\itshape,
postheadspace=0.5em,
name={\ignorespaces},
numbered=no,
headpunct=.]
{mystyle}
%Declares theorem @thmattr with style mystyle. Now this is a class of theorems which is instanced by the xtheor environment, which is a big mess of coding and which I will comment inside the code, also to make it more readable to myself.
\declaretheorem[style=mystyle]{@thmattr}
\newcommand{\refstyle}[1]{{\bfseries\color{blue}#1}}
\newcommand{\setrefstyle}{\renewcommand\refstyle[1]}
\newcommand{\resetrefstyle}{\renewcommand{\refstyle}[1]{{\bfseries\color{purple!60!black}##1}}}
\newcommand{\setmwref}[2]{\expandafter\xdef\csname mw@thmref@#1\endcsname{#2}}
\newcommand{\setmwrefb}[2]{\expandafter\xdef\csname mw@thmrefb@#1\endcsname{#2}}
\newcommand{\setmwrefc}[2]{\expandafter\xdef\csname mw@thmrefc@#1\endcsname{#2}}
\newcommand{\getmwref}[1]{\hyperlink{#1}{\refstyle{\csname mw@thmref@#1\endcsname}}}
\newcommand{\getmwrefb}[1]{\hyperlink{#1}{\refstyle{\csname mw@thmrefb@#1\endcsname}}}
\newcommand{\getmwrefc}[1]{\hyperlink{#1}{\refstyle{\csname mw@thmrefc@#1\endcsname}}}
\newcommand{\refprep}{di}
\newcommand{\setprep}{\renewcommand\refprep}
\newcommand{\@rel}[1]{\ (#1)}
\newcommand{\setrel}{\renewcommand\@rel[1]}
\newcommand{\resetrel}{\renewcommand{\@rel}[1]{\ (##1)}}
\newcommand{\@lrel}[1]{:\ #1}
\newcommand{\setlrel}{\renewcommand\@lrel[1]}
\newcommand{\resetlrel}{\renewcommand{\@lrel}[1]{:\ ##1}}
\newcommand{\contrel}[1]{\ (continua da #1)}
\newcommand{\setcontrel}{\renewcommand\contrel[1]}
\newcommand{\resetcontrel}{\renewcommand{\contrel}[1]{\ (continua da ##1)}}
\newcommand{\setpage}[2]{\expandafter\xdef\csname #1@savedpage\endcsname{#2}}
\newcommand{\getpage}[1]{\csname #1@savedpage\endcsname}
\newcommand{\setcnt}[2]{\expandafter\xdef\csname #1@savedcnt\endcsname{#2}}
\newcommand{\getcnt}[1]{\csname #1@savedcnt\endcsname}
\ExplSyntaxOn
%Here we are: xtheor.
\NewDocumentEnvironment{xtheor}{moO{x}oood()}%Many arguments, one mandatory and 5 optional, with default only for the second optional, set to x.
{\IfValueTF{#5}{\IfNoValueTF{#7}{\hypertarget{#5}{}\setpage{#5}{\thepage}\setcnt{#5}{\@ifundefined{c@#2}{1}{\arabic{#2}}}}{}}{}%\@ifundefined{\csname mw@thmref@#5\endcsname}{}{\PackageWarning{mworkx}{Label #5 already used}}{}
\IfNoValueTF{#2}%Is there a 2?
{\def\theorem@attr{#1\IfValueTF{#7}{\contrel{\hyperlink{#5}{#7}}}{}}\IfValueTF{#5}{\IfNoValueTF{#7}{\setmwref{#5}{#1}}{}}{}}%No? Then \theorem@attr, which will probably become the theorem's name, is #1. And so is the reference.
{\@ifundefined{c@#2}%There IS a 2? OK then it's a mess. Because it means we have a counter sequence to create. So is there a counter named like 2?
{\newcounter{#2} \setcounter{#2}{1}}%No? Make it. And set it to 1. Obvously it's the first theorem of that kind.
{\addtocounter{#2}{+1}}%Yes? Then just increase it by +1.
\ifnum\c@chapter>0
\ifnum\c@section>0
\ifnum\c@subsection>0
\xdef\acounters{\arabic{chapter}.\arabic{section}.\arabic{subsection}.\IfNoValueTF{#7}{\arabic{#2}}{\csname #5@savedcnt \endcsname}}
\else
\xdef\acounters{\arabic{chapter}.\arabic{section}.\IfNoValueTF{#7}{\arabic{#2}}{\csname #5@savedcnt \endcsname}}
\fi
\else
\xdef\acounters{\arabic{chapter}.\IfNoValueTF{#7}{\arabic{#2}}{\csname #5@savedcnt \endcsname}}
\fi
\else
\xdef\acounters{\IfNoValueTF{#7}{\arabic{#2}}{\csname #5@savedcnt \endcsname}}
\fi
\def\counters{%Now we create the counter sequence.
\str_case:nnF{#3}%We test argument 3.
{
{c}{\IfNoValueTF{#7}
{\arabic{chapter}.\arabic{#2}}
{\arabic{chapter}.\csname #5@savedcnt \endcsname}
}%c stands for chapter numbering, so if #3 is c the counters are chapter, separating dot, #2, all in arabic representation.
{s}{\IfNoValueTF{#7}
{\arabic{chapter}.\arabic{section}.\arabic{#2}}
{\arabic{chapter}.\arabic{section}.\csname #5@savedcnt \endcsname}
}%s stands for section, so if #3 is s we have chapter, dot, section, dot #2.
{x}{\IfNoValueTF{#7}
{\arabic{chapter}.\arabic{section}.\arabic{subsection}.\arabic{#2}}
{\arabic{chapter}.\arabic{section}.\arabic{subsection}.\csname #5@savedcnt \endcsname}
}%x is subsection, so to those above we add the subsection counter.
{n}{\IfNoValueTF{#7}
{\arabic{#2}}
{\csname #5@savedcnt \endcsname}
}%n stands for none, so just #2.
{a}{\acounters}%Finally, a stands for automatic, which means if any of chapter, section or subsection is positive (i.e. not 0 and not negative), they are put in this order with separating dots, then we have, of course, #2. This is actually dealt with by the nested \ifs in the definition of \acounters, for if those \ifs were placed in here, it wouldn't work. I tried that. Trust me :).
{@@}{}%If it is @@, no counters at all, not even #2. That is to be able to use #5 (the label) when we have a special theorem which needs no number.
}
{\errmessage{Illegal argument in counter definition}%What? None of those before? Error: illegal argument.
\errhelp{The third argument must be either c, s or x, for chapter, section and subsection respectively, or n for none of those, or a to let me choose the counters automatically, or @@ for no counters at all.}}
}%So now we have the counter sequence.
\IfValueTF{#5}{\IfNoValueTF{#7}{
\setmwref{#5}{#1\ \counters}
\setmwrefb{#5}{#1\ \refprep\ #4}
\setmwrefc{#5}{#1:\ #4}}
{}}{}
\edef\theorem@attr{
#1
\str_if_eq:nnTF{#3}{@@}
{}
{\,\,}
\counters
\IfValueTF{#7}
{\contrel{#7}}
{}
}}%At this point, we define \theorem@attr, which is the theorem's name, to be #1, which is the theorem kind or full theorem name when it's counterless, and #1 plus two \,s plus #4 when #3 is neither nothing nor @@. The spacing between the counters and #4 and company if present is handled by \@rel.
\def\name@thmlist{
#1\IfValueTF{#2}
{\ \counters}
{}
\IfValueTF{#4}
{\IfValueTF{#6}
{\@lrel{#6}}
{\@lrel{#4}}
}
{}
}%And we define \name@thmlist, which, as the name says, is the theorem's name in the \listoftheorems. This is #1, plus \ \counters, when #2 is present, plus #4 if present without #6, and plus #6 if #4 and #6 are present, in any case separated from \counters as specified by \@lrel if \counters doesn't end \name@thmlist. Requesting both presences is not restrictive, as no #4 implies no #6.
\IfNoValueTF{#7}
{\IfNoValueTF{#4}%Now we wonder: is #4 present?
{\begin{@thmattr}[{name=[\name@thmlist]\theorem@attr}]}%No? Then we finally start a @thmattr with name \theorem@attr and name in the list \name@thmlist.
{\str_if_eq:nnTF{#4}{\ }
{\begin{@thmattr}[{name=[\name@thmlist]\theorem@attr}]}
{\begin{@thmattr}[{name=[\name@thmlist]\theorem@attr\@rel{#4}}]}
}}%Since the label in #5 is dealt with before, we don't need to do anything about it now, so we only ask if #4 is \ , in which case we ignore it, otherwise we put it next to \theorem@attr as specified by \@rel.
{\begin{@thmattr}[name=\theorem@attr]}
}
%Note that in all cases, though \theorem@attr is followed by a space before (, it is ignored. That's why \theorem@attr contains that \,\, we saw before. Same thing as before concerning the #4=space case.
{\end{@thmattr}}%And in the \end part, just end the @thmattr.
%From this analysis, we see that:
%1: #1 is the theorem kind (Theorem, Remark, Proposition, Lemma, etc) or the full theorem name in case of a theorem with a special name like the Hairy Ball Theorem, which has no counter. That's why it's the only mandatory argument;
%2: #2 is the name of the counter associated with that theorem kind;
%3: #3 is a parameter to decide the counter style: c corresponding to [chapter] in plain theorem declarations (\newtheorem{foo}[chapter]), s corresponding to [section], x corresponding to [subsection], and n for a lone counter, probably for exercises;
%4: #4 is the theorem's name in the page where it is started; if #6 is given, this corresponds to foo in {name=[bar]foo}, otherwise it is the foo in name=foo;
%5: #5 is the label, so label=foo corresponds to foo in #5;
%6: #6, finally, is the name in the \listoftheorems, thus corresponds to the bar in {name=[bar]foo}.
\ExplSyntaxOff
\newcommand{\xtheorsetlist}{\renewcommand\thmt@listnumwidth{-1.5em}}%This is sort of forced by the use of xtheor, so to speed it up I've made it into a command.
\ExplSyntaxOff
\makeatother
\xtheorsetlist
\begin{document}
\begin{xtheor}{Teorema}[teor][s][Bogus][thm:teor:Bogus]
\end{xtheor}
\getmwref{thm:teor:Bogus}
\hypertarget{gu}{}
\begin{@thmattr}[name=1]
\end{@thmattr}
\begin{@thmattr}[name=Extension of \hyperlink{gu}{1}]
\end{@thmattr}
\end{document}
%10 adding d() and doing nested delimiter thing and 2 comment. 13 fixing last thing about labels and 1 comment. 2 fixing problems IN THIS DOCUMENT (\setrefstyle{}, no inputenc) and 2 comment.
似乎\getmwref{thm:teor:Bogus}
是在扰乱最后@thmattr
,改变错误。
答案1
正如错误消息所示,问题是
\mw
@mystyleposthead
这表明它\mw@mystyleposthead
没有被解析为一个标记,这表明它@
不是一个字母。修复这个问题(我在这里用 10pt 替换了它),一旦你\protect
\hyperlink
\documentclass[a4paper]{report}
\usepackage{lipsum,amsthm,thmtools,hyperref}
\declaretheoremstyle[
spaceabove=\topsep,
spacebelow=\topsep,
headfont=\normalfont\bfseries,
notefont=\bfseries, notebraces={}{},
bodyfont=\normalfont\itshape,
postheadspace=10pt,
name={\ignorespaces},
numbered=no,
headpunct=.]
{mystyle}
\declaretheorem[style=mystyle]{thm}
\begin{document}
\hypertarget{thm1}{}
\begin{thm}
Some theorem. Some theorem. Some theorem. Some theorem.
\end{thm}
\lipsum[1]
\begin{thm}[name=Exension of \protect\hyperlink{thm1}{the one above}]
The extension. The extension. The extension. The extension.
\end{thm}
\end{document}