Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two counter aliasing utilities #2

Open
muzimuzhi opened this issue Jun 4, 2022 · 6 comments
Open

Two counter aliasing utilities #2

muzimuzhi opened this issue Jun 4, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@muzimuzhi
Copy link

Currently two different counter aliasing macros are used

  • \newaliascnt from package aliascnt which globally lets \c@<cnt>, \the<cnt>, \theH<cnt> and \p@<cnt>, and globally defines \cl@<cnt> (to hold the \cl@<mirrored cnt>)
  • \crthm_counter_alias:nn, which locally lets \c@<cnt>, \cl@<cnt> and \the<cnt>.

Are these differences on purpose?

@Jinwen-XU
Copy link
Owner

No.

The \newaliascnt approach was proposed by Ulrich Diez a long time ago, when \CreateTheorem was still an internal command in my document class. Its purpose is to help \cref to address the type of theorems correctly when they share the same numbering. This approach, to my understanding, is reliable.

\crthm_counter_alias:nn is my own stupid approach. It is for \SetTheorem so that users can change the shared counter in the middle of the document. I'm not familiar with the counter mechanism, and it is not until the day before yesterday that I was reminded the existence of \cl@<cnt>. \crthm_counter_alias:nn works good so far in my documents but I cannot guarantee that there won't be further issues. (I only learnt from Ulrich Diez about \p@<cnt> yesterday, and I've never heard about \theH<cnt> before.)

Since you clearly understand these better, do you think there's hope in refining the current \crthm_counter_alias:nn? For example like this below?

\cs_new:Nn \crthm_counter_alias:nn
  {
    \cs_set_eq:cc { c@ #1 } { c@ #2 }
    \cs_set_eq:cc { the #1 } { the #2 }
    \cs_set_eq:cc { theH #1 } { theH #2 }
    \cs_set_eq:cc { p@ #1 } { p@ #2 }
    \cs_set_eq:cc { cl@ #1 } { cl@ #2 }
  }

@muzimuzhi
Copy link
Author

\theH<cnt> is used by hyperref.

Similar to \newaliascnt from aliascnt and \@counteralias from thmtools, you may need to

Also I'm not sure which one is right, \cs_set_eq:cc { cl@ #1 } { cl@ #2 } or \exp_args:Nnc \cs_gset:cpn { cl@ #1 } { cl@ #2 }. Both aliascnt and thmtools use the latter one. Sorry this is not a thorough analysis with testing. Perhaps I would do one in next days.

@Jinwen-XU
Copy link
Owner

Thank you. Your code is very helpful, after reading it, I changed \crthm_counter_alias:nn into the following (since I may use \cs_generate_variant:Nn \crthm_counter_alias:nn { en } in expl3, the \aliasctr@temp approach seems useless here).

\cs_new:Nn \crthm_counter_alias:nn
  {
    \cs_if_exist:cTF { c@ #2 }
      {
        \cs_gset_eq:cc { c@ #1 } { c@ #2 }
        \cs_gset_eq:cc { the #1 } { the #2 }
        \cs_gset_eq:cc { theH #1 } { theH #2 }
        \cs_gset_eq:cc { p@ #1 } { p@ #2 }
        \cs_gset_eq:cc { cl@ #1 } { cl@ #2 }
        \cref@resetby { #2 } { \cref@result }
        \cs_if_exist:NT \cref@result
          {
            \cref@addtoreset { #1 } { \cref@result }
          }
      }
      {
        \@nocounterr { #2 }
      }
  }

Notably, this works for the MWE you provided in your Issue, below is the create-theorem version:

\documentclass{article}

\usepackage{create-theorem}
\CreateTheorem{theorem}{shared counter = subsection}

\begin{document}

\section{title}
\begin{theorem}
Blah.
\end{theorem}

\begin{theorem}\label{theorem}
Blah.
\end{theorem}

\section{title}
\begin{theorem}\label{othertheorem}
Blah.
\end{theorem}

\Cref{theorem,othertheorem}.

\end{document}

The result is now "Theorems 1.2 and 2.1" as expected.

However I didn't make the commit yet. I'm playing with things unfamiliar to me here, and your suggestion would be most welcome :)


By the way, I don't quite understand the \exp_args:Nnc \cs_gset:cpn { cl@ #1 } { cl@ #2 } you proposed (I was once told that if one uses \cs_set_eq it would be much difficult for debugging, is this the reason why we should only assign the variable name here instead of copy the content?). Actually I don't even understand why we should make all the \cs_set_eq global here -- local version looks fine to me (but since global version is always guaranteed to work, I shall not think too much about it).

@muzimuzhi
Copy link
Author

For gset instead of gset_eq for cl@<cnt>, suppose one uses either \counterwithin{lemma}{section} or \counterwithin{theorem}{section} after

\newcounter{lemma}
\newcounter{theorem}
\newaliascnt{lemma}{theorem}

then he/she will expect both lemma and theorem are now numbered within section. Using \gset_eq, the two cl@<cnt> are not in sync, but using gset or just new (because new functions like \cs_new:Npn are always global, see texdoc interface3, sec. 4.3.1 Defining functions or run latexdef -s \cs_new:Npn for a quick check).

For global instead of local definition, that's for being consistent with \newcounter. \newcounter allocates a new counter and provides all its internal macros (\the<cnt>, \p@<cnt>, etc.) globally. Other latex counter commands like \addtocounter operates on counter globally as well. You can run latexdef -s \@definecounter and latexdef -s \addtocounter to have a quick check.

Also the initial purpose of this issue is more or less to suggest to use only one (set of) counter aliasing utility, for example stick to aliascnt package.

@Jinwen-XU
Copy link
Owner

Jinwen-XU commented Jun 5, 2022

Regarding you first paragraph, this was actually designed on purpose. When using \SetTheorem, one should expect that the setting is only applied to the current environment, otherwise the behavior would be much too unpredictable. If one really needs for example both lemma and theorem to be numbered within section, one should write \SetTheorem{lemma,theorem}{number within = section}. It is never my intention for users to use commands like \newaliascnt themselves.

Regarding your initial purpose, I would be glad to use only \crthm_counter_alias:nn. There is actually only one place in my code that uses \newaliascnt, with the sole purpose of serving cleveref. You might have noticed that for \cref, there are two modes for the theorem labels: one is called "regionalref", that always use the name corresponding to the surrounding context, for example printing "le théorème 1.1" in French context; another is called "originalref", which shall use the name as when the environment is applied, for example a theorem written in English context shall always be referred to as theorem 1.1, even if (for example) one is currently in French context (the distinction between "regionalref" and "originalref" was actually one of the most important initial motivations in creating this package, at the time I didn't see any other packages with this switch). The \newaliascnt is used in the "originalref" mode, for aliasing the counters of language-specific auxiliary environments to the corresponding main counter like theorem. However I haven't read the code of \newaliascnt yet, so I'm not sure if the current \crthm_counter_alias:nn would be suffice for this purpose.

P.S. Thanks for mentioning latexdef, a very convenient command indeed :)

@Jinwen-XU
Copy link
Owner

My current \crthm_counter_alias:nn (#2 (comment)) does not work.

Consider the following example, which tries to change the shared counter locally in the middle of a document.

\documentclass{article}

\usepackage{create-theorem}
\CreateTheorem{theorem}{shared counter = subsection}

\begin{document}

\section{title}
\SetTheorem{theorem}{shared counter = subsubsection}
\begin{theorem}
Blah.
\end{theorem}
\SetTheorem{theorem}{shared counter = subsection}

\begin{theorem}
Blah.
\end{theorem}

\end{document}

One shall get the following error:

TeX capacity exceeded, sorry [input stack size=10000].
<to be read again> 
\c@subparagraph 

The error is probably caused by \cref@addtoreset (one might not be able to apply this twice), but for now I have no idea how to fix it. May I ask your opinion on this?

@Jinwen-XU Jinwen-XU added the bug Something isn't working label Aug 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants