tomduck/pandoc-eqnos

New filter request: Theorem like environment

ouboub opened this issue · 18 comments

Hi

pandoc-eqnos is a great leap forward in order to produce decent epub3 math documents, what I am missing right now, are theorem likes environments, its automatic enumeration and references.

any intention to include it?

thanks

Uwe Brauer

Hi Uwe. Thanks for this feedback. I'm not really sure what to do about it because pandoc doesn't currently support theorems. Pandoc-eqnos and friends add referencing to existing pandoc elements.

Woukd it be possible to simply "duplicate" Eqnos, name it Theonos, and change "Equation" to "Theorem" in the YAML? (Same with the abbreviation). That way it would be possible to have, both, equation and theorem numbering and cross-referencing separate.

How do you write theorems into markdown documents?

In bookdown it's implemented this way (there are I think a wide range of ways to use theorems in terms of how long they are, how much text versus formulas etc)
https://bookdown.org/yihui/bookdown/markdown-extensions-by-bookdown.html#theorems

Very roughly it would be a numbered version (analogous to figures or equations) of using

Theorem

: here's my theorem

that can be referred to as a theorem.

That's an interesting idea, @jrennstich. The syntax you give above is how pandoc supports definition lists, and pandoc has a DefinitionList block element in its json format. I can imagine writing pandoc-defnos or some such thing.

Below are some thoughts on a possible implementation.

The first requirement would be to attach attributes to a definitions list. @jgm recommends using bracketed spans for this purpose (see also bracketed spans in the pandoc README). As such, the syntax would look something like

[Term]{#def:id}

:   definition text

where Term and definition text could be whatever you want; as per the other pandoc-xnos filters, id is a unique identifier.

References would look like @def:id.

I have already checked to see how pandoc processes the above markdown, and it is manageable.

However, there would need to be some differences from the other pandoc-xnos filters. Where should the reference name come from? In pandoc-eqnos it comes from a yaml variable (with the sensible default of 'eq.'). I'm thinking for this it should come from what is in the square brackets, above.

But what if people use different text in the brackets? i.e., maybe a document has a bunch of Term definitions and a bunch of Theorem definitions. It seems to me that there should be separate counters for these.

Finally, there would need to be a specialization for when Theorem is used. For LaTeX output, it should clearly use the theorem environment.

Comments?

Thanks for looking into this! Your proposed syntax would be exactly what I was looking for/would fit my needs and I believe would be flexible enough for the needs of others.

But what if people use different text in the brackets? i.e., maybe a document has a bunch of Term definitions and a bunch of Theorem definitions. It seems to me that there should be separate counters for these.

I fully agree. Would it be possible to work alone the lines of eqnos-plus-name and eqnos-star-name wich, essentially, add the possibility of a Theorem list? I don't know the requirements of the filter referencing; can there be more than one symbol prior to the @ symbol? Then one could define theorem-plusplus-name for ++@def (or using #theorem:id instead of #def:id, then it would say ++@theorem:id).

Perhaps it's possible to stick to the definitions of the LaTeX environment (also used in the Bookdown and theorem environment examples: theorem, lemma, definition, corollary, proposition, example, exercise.

So, in [Term] then you would put the equivalent of \begin{definition}[Term]... in LaTeX and instead of using #def:id you would offer the options: theorem:id, #lemma:id, #definition:id, #corollary:id, #proposition:id, #example:id, and #exercise:id as fixed options, that the filter then can use. That would also make it much easier for the LaTeX output, I would imagine.

For example:

[Pythagorean theorem]{#theorem:pythagorean_theorem}

: For a right triangle, if $c$ denotes the length of the hypotenuse
and $a$ and $b$ denote the lengths of the other two sides, we have

$$a^2 + b^2 = c^2$$

Would produce

Theorem 1 (Pythagorean theorem) For a right triangle, if
c denotes the length of the hypotenuse and ...

whereas

[Definition]{#definition:sum}

: The sum of all the somethings add to the something else.

Would produce

Definition 1 The sum of all the somethings add to the something else.

This would require, that if the text in the brackets would be scanned for the "type" of theorem (e.g., "theorem", "definition", etc.) and then would put the respective "type" into the numbering (as in the example above).

Seems a bit complicated but workable, at least in min mind :-)

Would it be possible to list in the YAML---again, analogous to the theorem environment--- also the theoremstyles (plain/definition/remark)?

Addendum: Here's what I see as the key challenges to meet:

  • need to be able to differentiate between different types (theorem, lemma, definition, corollary, proposition, example, exercise) for
    • naming
    • numbering
  • need to have flexibility in naming the types similar to the way it is handled in pandoc-eqnos and the others

So after having returned from the walk in the woods with my dog I figured it would be perhaps best, not to differentiate in the [Term/Name] bracket part, but rather the #def:id? Not sure how the parsing works and what can be included where for the parsing to work and what's predefined, but perhaps this scheme would work:

pandoc-theoremnos

[name]{#type:id} 

:    text of theorem

Types (used in {#type:id} available:

  • theorem
  • lemma
  • definition
  • corollary
  • proposition
  • example
  • exercise

YAML options for customization:

  • theoremnos-cleveref or just cleveref - Set to On to assume "+" clever references by default;
  • theoremnos-style-name with sub-options for each style, that is

For style "theorem" it would be

  • theoremnos_theorem-name: Theorem - Sets the default name at the beginning of a Theorem

  • theoremnos_definition-name: Definition - Sets the default name at the beginning of a Definition
    ...

  • theoremnos_style-plus-name - Sets the name of a "+" reference (e.g., change it from "eq." to "equation"); and

  • theoremnos_style-star-name - Sets the name of a "*" reference (e.g., change it from "Equation" to "Eq.")
    with sub-options for each style, that is:

For style "theorem" it would be

  • theoremnos_theorem-plus-name: Theorem - (e.g., change it from "thm." to "Theorem")
  • theoremnos_theorem-star-name: Thm - (e.g., change it from "Theorem" to "Thm.").

for style "definition" it would be

  • theoremnos_definition-plus-name: Definition - (e.g., change it from "Def." to "Definition")
  • theoremnos_defintion-star-name: Def. - (e.g., change it from "Definition" to "Def.")
    ...

Numbering and naming

  • Numbering style and wording set for each style separately, based on {type:id}; e.g., {proposition:PropositionOfSomething} - this tells Pandoc-Theoremnos that this definition is of the type "Proposition" and defines it as such, using the naming-scheme for this type (i.e., "Proposition" or "Prop." if used with e.g., *@proposition:PropositionIdentity and thus defined in the YAML)
  • Naming - whatever is in the bracket [NAME] will be used as name for type of theorem; e.g., [Pythagorean theorem]{@theorem:Pythagorean} will return "Theorem 1 (Pythagorean theorem)"
  • Naming with no individual name - this will result in Pandoc-Theoremnos to use the style-default as name before auto-numbering; e.g.,
[Definition]{#definition:DefinitionNature}

:    This is my definition of nature.

will result in "Definition 1 This is my definition of nature"

whereas

[Theorem]{#theorem:Nature}

:    This is my theorem of nature.

will result in "Theorem 1 This is my theorem of nature"

pandoc-theoremnos would be absolutely fantastic!
Even if its is just one counter for the beginning, that does not distinguish Remarks from Theorems (aside the name in the [] ).

What about proofs? Proofs does not require numbering, but such blocks are clearly useful.
I'm all for theoremnos. But this looks like one should just create a numbering and referencing system for any block.
Pandoc supports custom blocks since Oct 2017. So maybe a generic block level system works well.

::: Theorem {#thm:fundalge title="Fundamental Theorem of Algebra"}
Any polynomial of degree $n$ has $n$ roots.
:::
The filter should transform the above into the following latex.

\begin{theorem}[Fundamental Theorem of Algebra]\label{thm:fundalge}
Any polynomial of degree $n$ has $n$ roots.
\end{theorem}
The above is fairly reasonable because most theorem in a math paper does not have a name.

::: Theorem {#thm:noname}
This theorem has no name, and probably show up as Theorem 2. 
:::

::: Proof :::::::
Let's do some nesting of block level elements.

::: Claim
Claim blah blah
:::
:::::::::::::::::::::

One thing I do not like is that each block has to be closed, but this might change when side-marked syntax being reconsidered.
One can use YAML to store the mapping in the beginning of the document. For example, some YAML shows Theorem maps to theorem (the environment), and Theorem also maps to a particular counter. Also title maps to the first argument.
This allows user to create their own numbered div changing the YAML. For example, I might use a Problem environment, or Claim environment.

@tomduck First of all, thanks a lot for the great work with your pandoc-*nos filters. I wrote a first version of a pandoc-theoremnos filter based on the ideas of @jrennstich. I'd be very happy to share this, would you like to set up a repository for that?

FANTASTIC. I would be thrilled to see such a contribution made to the filter suite. ☺︎

How would you like to proceed? I can set up a repository as you suggest, but I also would be perfectly comfortable with it if you wanted to do so under your own account.

I'd also be comfortable with both options. My first thought was that it would probably receive more attention and be less confusing for new users if it's under your account. I honestly don't have any preference, so, if you don't mind I'd suggest that you just create an empty repository and I open a pull request for my first version.

Thanks, @ValiValpas. I just created an empty pandoc-theoremnos. Please go ahead and make a PR.

I'm not married to this name. We can discuss it more once I have a sense of the range of things your new filter supports. In particular, I take from @chaoxu's comment that the new filter should be described as generally as possible.

Again, thank you. It is exciting to receive such a contribution to the project.

@tomduck, thank you very much. I'm quite busy at the moment and have not found the time yet to prepare the PR. I'll come back to this for sure, I just wanted to give a sign of life from my side.

No worries, @ValiValpas. I completely understand. Thanks for your note. :o) Cheers, Tom

@tomduck Could you please add an initial commit to the pandoc-theoremnos repository? Unfortunately, I cannot fork from an empty repository.

@ValiValpas Done.

Pandoc-theoremnos is now being developed on GitHub. Thanks to @ValiValpas for this wonderful contribution.