3

I'm using quarto to write an online book and need to mimic the environments and counters of a published book. The latter employs five custom framed environments (examples, exercises, remarks, theorems, definitions) with a joined counter (within the chapter).

In quarto there is very nice infrastructure for creating such cross references for theorems and proofs but they have separate counters. Is it possible to configure/force them to use a joint consecutive counter?

As an example, the following code

The first example is @exm-1.

::: {#exm-1}
This should be Example 1.1.
:::

It is followed by the first exercise, @exr-1

::: {#exr-1}
This should be Exercise 1.2.
:::

is rendered as


The first example is Example 1.1.

Example 1.1

This should be Example 1.1.

It is followed by the first exercise, Exercise 1.1

Exercise 1.1

This should be Exercise 1.2.


Note that the first exercise should receive the number 1.2 (instead of 1.1) because it is the second environment in that chapter.

(Remark: I've also tried to do this via callout blocks as provided through quarto, see Is it possible in quarto to create custom cross-references to callout blocks?.)

Achim Zeileis
  • 15,710
  • 1
  • 39
  • 49

2 Answers2

3

Assuming that, you are trying to do this for an HTML book (since you have said online book), we can hack a way to do this using javascript.

At first, we use the example environment #exm in the case of exercises too and also add an additional class name, say .custom like this,

intro.qmd


# Introduction


The first example is @exm-1.

::: {#exm-1}
This should be Example 1.1.
:::

It is followed by the first exercise, [Exercise @exm-2]

::: {#exm-2 .custom}
This should be Exercise 1.2.
:::

It is followed by the first exercise, [Exercise @exm-3]

::: {#exm-3 .custom}
This should be Exercise 1.3.
:::

Note Two things here,

  • I have used custom reference syntax [Exercise @exm-2] to refer to those exercises, so that they will render as Exercise 1.2 instead of Example 1.2.

  • Added a class .custom to those example environments which I want to render as Exercise but with the consecutive (shared) counter.

Now since we have used example environments for those with .custom class too, quarto will render those as Example 1.2, Example 1.3, but we need them as Exercise 1.2, Exercise 1.3. So to get them Exercise, we will use javascript on the elements of .custom to simply replace the word Example with Exercise and the counter will remain consecutive since under the hood they are actually example environments.

Therefore, we create an HTML file, say custom.html, and put the necessary javascript code wrapped with script tag into that file,

custom.html


<script>
var custom_title = document.querySelectorAll('.custom .theorem-title');

for (let i = 0; i < custom_title.length; i++ ) {
   var mod_name = custom_title[i].innerHTML;
   custom_title[i].innerHTML = mod_name.replace("Example", "Exercise");
};
</script>

Then simply add this html file with include-after-body option in _quarto.yaml

_quarto.yaml


project:
  type: book
  
book:
  title: "test_book"
  author: "Jane Doe"
  date: "8/7/2022"
  chapters:
    - index.qmd
    - intro.qmd

format:
  html:
    include-after-body: custom.html
    theme: cosmo


Then if we render the book, this rendered output will look like this,

image_book_output

shafee
  • 15,566
  • 3
  • 19
  • 47
  • Nice trick, thanks! It's a bit hacky but might be good enough for the HTML version, we will consider it. It will not work for the PDF version, though, because we end up with only the `{example}` environments without the `.custom` information. The PDF is not the primary concern at the moment but we plan on making that available as well. – Achim Zeileis Aug 11 '22 at 00:18
  • 1
    @AchimZeileis, Yes, its not going to work with `pdf`. For `pdf`, you may have to search for Latex trick..though I am not sure how to do that. – shafee Aug 11 '22 at 00:51
  • I solved the LaTeX side by a suitable `\renewenvironment{}` with a custom counter. If anyone is interested, I can post a code snippet. – Achim Zeileis Aug 24 '22 at 20:34
  • @AchimZeileis, yes, that would be nice to have the latex solution as another answer to this interesting problem. – shafee Aug 28 '22 at 03:00
  • 1
    I think it is a workaround (which I upvoted) but not a solution which would close the question. – Achim Zeileis Aug 28 '22 at 09:14
0

I have written an extension for that, custom-numbered-blocks, that supports pdf and html. It does not work with quarto cross references, but with latex cross references, also for html.

The idea of that extension is to enable user defined classes for fenced blocks (environments). For the present question, you would want a class Exercise and a class Example. Then you can define groups of classes that share both counter and also a customizable design.

Here is an example yaml for joint counting of examples and exercises

---
format: 
   html: default
number-sections: true

filters: 
  - custom-numbered-blocks
custom-numbered-blocks:
  groups: 
    exgrp: 
      collapse: false
      boxstyle: foldbox.simple  
  classes:
    Example:
      group: exgrp
    Exercise:
      group: exgrp
---       

These definitions can be used in the document as follows:

# This is a heading

The first example is \ref{exm-1}.

::: {.Example #exm-1}
This should be Example 1.1.
:::

It is followed by the first exercise, \ref{exr-1}

::: {.Exercise #exr-1}
This should be Exercise 1.2.
:::

The example renders as: rendered example

See also related question about numbered callouts.

Ute
  • 238
  • 1
  • 9
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/34620554) – DreadedFrost Jun 30 '23 at 19:29
  • Hi @DreadedFrost, you-re right, I've fleshed out the answer :-) – Ute Jul 10 '23 at 20:03