0

In the following, I have three kinds of theorems:

  1. an "ordinary" theorem, which just has the head "Theorem", as in the 3rd;
  2. a theorem having both a head and a note, "Theorem (...)", as in the 2nd; and
  3. a namedtheorem, where the note becomes the name, as in the 1st.

Desired format: Wanted form for list of theorems

Question: What modification is needed so that the output from \listoftheorems removes the parentheses from the namedtheorem entry but preseres the parentheses of the note in a theorem having both head and note?

Failed attempt 1: removes parentheses for namedtheorem but unfortunately also removes them from the entry with the note.

\documentclass{article}
\usepackage{amsmath,amsthm,thmtools}

% For \listoftheorems \renewcommand\thmtformatoptarg[1]{#1} % remove parens \usepackage{xpatch} \makeatletter \patchcmd{\thmt@mklistcmd}{\thmt@thmname}{}{}{} \makeatother

\swapnumbers

\declaretheoremstyle[ headformat=\NAME\NUMBER\let\thmt@space@empty\NOTE, bodyfont=\slshape, ]{thmstyle} \declaretheorem[name=Theorem,style=thmstyle]{theorem}

\declaretheoremstyle[ postheadspace=0.5em, notebraces={}{}, headformat=\NUMBER\let\thmt@space@empty\NOTE, notefont=\bfseries, bodyfont=\slshape, ]{namedthmstyle} \declaretheorem[ style=namedthmstyle, name=Theorem, title = {}, numberlike=theorem ]{namedtheorem}

\begin{document}

\listoftheorems[ignoreall,onlynamed={theorem,namedtheorem}]

\bigskip

\begin{namedtheorem}[Heine-Borel Theorem] A closed and bounded subset of Euclidean $n$-space is compact. \end{namedtheorem}

\begin{theorem}[compact subset of Hausdorff space] A compact subset of a Hausdorff space is closed in that space. \end{theorem}

\begin{theorem} The square on the hypotenuse of a right triangle equals the sum of the squares on the other two sides. \end{theorem}

\end{document}

No parens whatsoever in listoftheorems Failed attempt 2: Comment out the line \renewcommand\thmtformatoptarg[1]{#1}. Then parentheses still remain around the entry for the namedtheorem.

Unwanted parens around name of named theorem

Question, restated: Thus, how can I somehow combine different treatments of a theorem having a parenthesized note, on the one hand, and a namedtheorem, on the other hand?

Related: https://tex.stackexchange.com/a/193020/13492, https://tex.stackexchange.com/a/180749/13492,https://tex.stackexchange.com/q/509672/13492, How make first letter upper-case in list of theorems?

murray
  • 7,944
  • What is the purpose of the \patchcmd? It does not do anything in the MWE you posted. Perhaps you included it for other reasons? – Willie Wong Jun 15 '23 at 14:24

1 Answers1

1

There are several problems in the code you posted, aside from what you are asking about.

  1. The bit that does the \patchcmd does nothing in your minimal example (what it does, is to remove the theorem title from being shown in the listoftheorems only for unnumbered theorems. This doesn't make any sense to me so I removed it in my code below.
  2. The \makeatletter...\makeatother pair should encompass everything that uses the @ symbol, currently your \declaretheoremstyle macros do not include it, and so the code you showed does something different from its coded intent. I've moved the \makeatother to the correct place, and removed the declaration to remove \thmt@space from the basic thmstyle, since that space should be there and should not be removed.
  3. In defining namedtheorem, you specified both name and title; they are synonyms and you should specify only one.

Now, on to the real problem: the use of the \thmtformatoptarg macro is baked firmly into how thmtools handle the list of theorems. Specifically, we note that:

  1. The <project>.loe file which has all the theorem entries for the list of theorems uses \thmtformatoptarg. This means that any changes to \thmtformatoptarg will automatically apply to ALL entries, and you cannot do it selectively.
  2. And someone annoyingly, the onlynamed key in \listoftheorems detects the presence of \thmtformatoptarg in the contents line to decide whether to show that entry.

To work around the two problems, the following is a bit of a hack:

  1. We redefine how namedtheorems are written to the loe file, to ignore \thmtformatoptarg completely. This is most easily done by just completely redefining how things goes, rather than patching, so I also removed xpatch.
  2. We assume that every instance of namedtheorem comes with an optional argument (if not, the theorem name would be empty....), so instead of testing for onlynamed={namedtheorem}, we just do show={namedtheorem} which should functionally be the same.

With that, the following MWE is attained:

\documentclass{article}
\usepackage{amsmath,amsthm,thmtools}

\swapnumbers

\makeatletter \declaretheoremstyle[ headformat=\NAME\NUMBER\NOTE, bodyfont=\slshape, ]{thmstyle} \declaretheorem[name=Theorem,style=thmstyle]{theorem}

\declaretheoremstyle[ postheadspace=0.5em, notebraces={}{}, headformat=\NUMBER\let\thmt@space@empty\NOTE, notefont=\bfseries, bodyfont=\slshape, ]{namedthmstyle} \declaretheorem[ style=namedthmstyle, title = @empty, numberlike=theorem ]{namedtheorem}

%% Note, the following line must come AFTER the \declaretheorem...{namedtheorem} %% as we are trying to overwrite the definition provided by thmtools %% that occurs during the \declaretheorem process %% The definition below will still work if you don't \swapnumbers, but %% it does assume that the namedtheorems are numbered. @xa\def\csname ll@namedtheorem\endcsname{% \protect\ifthmt@listswap \thmt@shortoptarg~\csname thenamedtheorem\endcsname \protect\else \protect\numberline{\csname thenamedtheorem\endcsname}% \thmt@shortoptarg \protect\fi }% \makeatother

\declaretheorem[name=Remark,style=thmstyle,numbered=no]{remark}

\begin{document}

\listoftheorems[ignoreall,onlynamed={theorem,remark},show={namedtheorem}]

\bigskip

\begin{namedtheorem}[Heine-Borel Theorem] A closed and bounded subset of Euclidean $n$-space is compact. \end{namedtheorem}

\begin{theorem}[compact subset of Hausdorff space] A compact subset of a Hausdorff space is closed in that space. \end{theorem}

\begin{theorem} The square on the hypotenuse of a right triangle equals the sum of the squares on the other two sides. \end{theorem}

\begin{remark}[Test] Test \end{remark}

\end{document}

Output:

enter image description here


To automate the process somewhat, if you have multiple environments, we can redefine the \thmt@mklistcmd to do the right thing automatically. There may be better way to do this logic, but the following should work. (Basically, instead of printing \thmt@thmname, we test to see if it is empty, and if true, print the optional argument instead. But this means that when it comes time to print the optional argument, we should suppress it from printing at all if it has already been used in place of the empty \thmt@thmname. Note: I didn't bother to make the analogous change for unnumbered theorems; hopefully you can figure out what to change yourself by comparing this with the definition in thmtools/thm-listof.sty.)

\documentclass{article}
\usepackage{amsmath,amsthm,thmtools}

\swapnumbers \makeatletter

\renewcommand\thmt@mklistcmd{% \thmtlo@newentry \ifthmt@isstarred @xa\def\csname ll@\thmt@envname\endcsname{% \protect\ifthmt@listswap \protect\else \protect\numberline{\protect\let\protect\autodot\protect@empty}% \protect\fi \thmt@thmname \ifx@empty\thmt@shortoptarg\else\protect\thmtformatoptarg{\thmt@shortoptarg}\fi }% \else @xa\def\csname ll@\thmt@envname\endcsname{% \protect\ifthmt@listswap \ifx@empty\thmt@thmname\thmt@shortoptarg\else\thmt@thmname\fi~\csname the\thmt@envname\endcsname \protect\else \protect\numberline{\csname the\thmt@envname\endcsname}% \ifx@empty\thmt@thmname\thmt@shortoptarg\else\thmt@thmname\fi \protect\fi \ifx@empty\thmt@thmname\else\ifx@empty\thmt@shortoptarg\else\protect\thmtformatoptarg{\thmt@shortoptarg}\fi\fi }% \fi @xa\gdef\csname thmt@contentsline@\thmt@envname\endcsname{% \thmt@contentslineShow% default:show }% }

\declaretheoremstyle[ headformat=\NAME\NUMBER\NOTE, bodyfont=\slshape, ]{thmstyle} \declaretheorem[name=Theorem,style=thmstyle]{theorem}

\declaretheoremstyle[ postheadspace=0.5em, notebraces={}{}, headformat=\NUMBER\let\thmt@space@empty\NOTE, notefont=\bfseries, bodyfont=\slshape, ]{namedthmstyle} \declaretheorem[ style=namedthmstyle, title = @empty, numberlike=theorem ]{namedtheorem} \declaretheorem[ style=namedthmstyle, title = {}, numberlike=theorem ]{namedlemma} \makeatother

\begin{document}

\listoftheorems[ignoreall,onlynamed={theorem},show={namedtheorem,namedlemma}]

\bigskip

\begin{namedtheorem}[Heine-Borel Theorem] A closed and bounded subset of Euclidean $n$-space is compact. \end{namedtheorem}

\begin{theorem}[compact subset of Hausdorff space] A compact subset of a Hausdorff space is closed in that space. \end{theorem}

\begin{theorem} The square on the hypotenuse of a right triangle equals the sum of the squares on the other two sides. \end{theorem}

\begin{namedlemma}[Borel-Cantelli Lemma] Very useful in analysis \end{namedlemma}

\end{document}

This provides

enter image description here

Willie Wong
  • 24,733
  • 8
  • 74
  • 106
  • As an aside: the creation of the remark environment is because I was trying to debug your code related to the first two errors that I mentioned. It is not very relevant to the solution. – Willie Wong Jun 15 '23 at 15:41
  • sorry about the misplaced \makeatother -- a result of moving code from a package (where of course \makeatletter...\makeatother is not needed) to the .tex source. – murray Jun 15 '23 at 15:51
  • What is the difference between title = \@empty and my title = {} ? – murray Jun 15 '23 at 15:53
  • No difference. I was debugging something else and swapped to \@empty for convenience. – Willie Wong Jun 15 '23 at 15:58
  • I also have several other "named" environments (namedproposition, namedaxiom, namedlemma) that need to be treated similarly to namedtheorem. Is there an abstraction to cover such that would avoid essentially duplicating your ll@namedtheorem definition for each of those (ll@namedproposition, etc.)? – murray Jun 15 '23 at 16:26
  • Should your code work if it is inserted into the \declaretheorem[...]{namedtheorem} as a postheadhook option? – murray Jun 15 '23 at 16:28
  • I was afraid you are going to ask that. I'll put in a new edit soon. – Willie Wong Jun 15 '23 at 16:35
  • Putting it in postheadhook would not work. The code to write stuff to the loe file is implemented itself as a postheadhook action, and head hook action is executed FIFO. This means that any new postheadhook you define will be executed after the loe file is written. To take this approach you will have to basically make your own copy of thm-listof.sty and insert appropriate changes in there. – Willie Wong Jun 15 '23 at 17:00
  • The generalized code works perfectly. Thank you! – murray Jun 16 '23 at 17:21