Jinwen-XU / create-theorem

Initializing and configuring theorem-like environments, with multilingual support
https://ctan.org/pkg/create-theorem
LaTeX Project Public License v1.3c
5 stars 0 forks source link

QED symbol compatibility with amsthm #3

Closed atxy-blip closed 2 years ago

atxy-blip commented 2 years ago

In recent tests I have found some issues with the qed setup of create-theorem. To configure an environment with QED symbol, I have to load amsthm to provide the commands \pushQED, \popQED and \qed. However, this would cause multiple QED symbols generated.

\documentclass{ctexart}
\usepackage{amsthm}
\usepackage{create-theorem}

\CreateTheorem{proof}{name={heading={证明}},qed=\rule{1ex}{1ex}}

\begin{document}

\begin{proof}[foo]
    some proof
\end{proof}

\begin{proof}
    some proof
\end{proof}

\end{document}

The MWE above would generate the result as follows. Note that this is actually the proof environment defined by amsthm with an additional QED symbol.

image

The problem could be resolved by defining those commands mentioned by the package itself. The next MWE generates the desired result, where the qed command is simply borrowed from amsthm. There is still one problem with this approach, which is that the default value of qed key is not valid.

\documentclass{ctexart}
\usepackage{create-theorem}

\makeatletter
\DeclareRobustCommand{\qed}{%
  \ifmmode \mathqed
  \else
    \leavevmode\unskip\penalty9999 \hbox{}\nobreak\hfill
    \quad\hbox{\qedsymbol}%
  \fi
}
\ExplSyntaxOn
\seq_new:N \l_qed_stack_seq
\cs_set_protected:Npn \pushQED #1
    { \seq_push:Nn \l_qed_stack_seq {#1} }
\cs_set_protected:Npn \popQED
    { \seq_pop:NN \l_qed_stack_seq \l_tmp_tl \l_tmp_tl }
\ExplSyntaxOff
\makeatother

\CreateTheorem{proof}{name={heading={证明}},qed=\rule{1ex}{1ex}}

\begin{document}

\begin{proof}[foo]
    some proof
\end{proof}

\begin{proof}
    some proof
\end{proof}

\end{document}

image

It is also worth mentioning that not loading amsthm will also cause problems with numberless option, which I have not found a proper solution so far.

Jinwen-XU commented 2 years ago

This is because that amsthm already defined the environment proof, and the key qed of create-theorem simply adds another Q.E.D. symbol to it without checking.

When you use create-theorem to define the proof environment, the main reason I can think of is to have a numbered version of proof. For this, you need to write something like the following:

\documentclass{article}
\usepackage{amsthm}
\usepackage{create-theorem}

\ExplSyntaxOn

\newcounter { proof }

\tl_new:N \l_mymodule_name_of_proof_tl
\CreateTheorem { proof_inner }
  {
    name = { heading = { \l_mymodule_name_of_proof_tl } },
    create-starred-version,
    style = remark,
    qed,
    shared-counter = proof,
  }

\cs_undefine:c { proof }
\cs_undefine:c { endproof }

\NewDocumentEnvironment { proof } { O{\proofname} }
  {
    \tl_set:Nn \l_mymodule_name_of_proof_tl { #1 }
    \begin { proof_inner }
  }
  {
    \end { proof_inner }
  }
\NewDocumentEnvironment { proof* } { O{\proofname} }
  {
    \tl_set:Nn \l_mymodule_name_of_proof_tl { #1 }
    \begin { proof_inner* }
  }
  {
    \end { proof_inner* }
  }

\CreateTheorem { proof_mymodule_temp } { copy-existed = proof* }
\CreateTheorem { proof* } { copy-existed = proof }
\CreateTheorem { proof } { copy-existed = proof_mymodule_temp }

\SetTheoremBinding { proof* } { proof_inner }
\SetTheoremBinding { proof } { proof_inner* }

\ExplSyntaxOff

\begin{document}

\begin{proof}[foo]
    some proof
\end{proof}

\begin{proof}
    some proof
\end{proof}

\begin{proof*}[foo]
  some proof
\end{proof*}

\SetTheorem{proof*}{number within = section}

\begin{proof*}
  some proof
\end{proof*}

\end{document}

The code is copied from my package projlib-theorem with only minor modifications. It defines an environment proof_inner (with its starred variant) with theorem style remark to mimic the default one (you are welcome to use your own style here), and with the name to be a variable which is latter used to define the real environments proof and proof*. The three lines of \CreateTheorem following it is to switch the environments proof and proof* so that proof is the usual unnumbered version and proof* is the numbered version (you can of course directly define them to work like this, I'm only writing this more complex version to demonstrate the feature). The \SetTheoremBinding lines are to ensure that user can directly write \SetTheorem{proof} rather than \SetTheorem{proof_inner}.

This may seem a little troublesome, but since you are also a class/package author this shouldn't be a problem ;)

Jinwen-XU commented 2 years ago

After Update 2022-08-04 (6b5b63df92763c55a2a711db6fe745afa37968fc) the key qed shall have no effect when the environment is not definable.

Regarding the issue without amsthm, when I was designing this package I didn't load amsthm by default, since some people may prefer ntheorem or some other lower-level theorem packages. However, since I was always testing the package with amsthm, some feature (like qed) might implicitly require it. If you have explicit reason(s) not to use amsthm, please let me know and I might be able to come up with some solution in the future versions.

atxy-blip commented 2 years ago

When you use create-theorem to define the proof environment, the main reason I can think of is ...

In fact, I chose create-theorem mainly because it provides a universal key-value interface for theorem environments, a feature not yet available from its counterparts, which is consistent with the LaTeX3 format of my ongoing work.

If you have explicit reason(s) not to use amsthm

Perhaps the most direct reason is that in the beginning create-theorem works fine without other packages, to make me assume that adding several options will preserve its functionality. Now I am aware that the LaTeX2e kernel provides only the \newtheorem command, while \newtheorem* and \theoremstyle are implemented by amsthm or other similar packages. The absence of the very commands would generate weired error messages in the terminal. Maybe create-theorem should check the presence of those and prompt messages?

Jinwen-XU commented 2 years ago

When I wrote this package, in my mind I was assuming that amsthm was loaded. However, as with the package thmtools, for the generality, I decided to leave it to the users, hence the first sentence in the documentation:

First, you need a backend to provide the command \newtheorem with the usual behaviour, for example, amsthm.


Regarding my

When you use create-theorem to define the proof environment, the main reason I can think of is ...

I was mainly referring to the reason why you redefine the environment proof. Since the default style is nice enough (in that it is both clear and simple), I assumed that the main reason you need to redefine it is the need for a numbered version (hence my suggestion in the previous comment)? Although it occurs to me now that it could also be that \proofname is not changed to Chinese by default (or is it in ctexart?) so you need a Chinese version. By the way, if you don't mind, try out the package projlib-theorem, I once used it when designing my university's (unofficial) undergraduate thesis template -- since the theorem-like environments are pre-defined, the rest setup should be quite easy (but sorry that I haven't take the time to write a new documentation). You may refer to the package minimalist (minimalist-plain.sty) to see an example of use. Hopefully this won't cause conflicts with the other part of your settings (since create-theorem is the relatively stable and lower-level part separated from projlib-theorem, I would expect the users to use ProjLib eventually).


As of your request

The absence of the very commands would generate weired error messages in the terminal. Maybe create-theorem should check the presence of those and prompt messages?

Would you mind opening a new issue for this? I should be able to achieve this within a day or two.

atxy-blip commented 2 years ago

I was mainly referring to the reason why you redefine the environment proof.

Forgive me for not making it clear. I created a numbered proof environment above simply because numberless option fails when using create-theorem alone. The default style of proof, on the other hand, is not consistent with other environments created by the package.

or is it in ctexart?

\proofname is automatically switched to Chinese in ctex classes :)

Would you mind opening a new issue for this?

Sure, and please do not hurry. I am very appreciated for the extensive discussion and suggestion above. Thanks again for your time!!