typst / typst

A new markup-based typesetting system that is powerful and easy to learn.
https://typst.app
Apache License 2.0
30.05k stars 826 forks source link

Heading numbering function does not apply correctly with template. #806

Closed arj0019 closed 1 year ago

arj0019 commented 1 year ago

Discussed in https://github.com/typst/typst/discussions/778

Originally posted by **Holt59** April 13, 2023 I am writing a template with utility for other users and I'd like a function `appendices()` to start writing appendices with custom style, in particular, I'd like to 1) make a page break, 2) reset the heading counter and 3) change numbering to use `A` instead of `1`. I currently have this: ```typ #let appendices() = { pagebreak() counter(heading).update(0) counter("appendices").update(1) set heading( numbering: (..nums) => { let vals = nums.pos() let value = "ABCDEFGHIJ".at(vals.at(0) - 1) if vals.len() == 1 { return "APPENDIX " + value + ": " } else { return value + "." + nums.pos().slice(1).map(str).join(".") } } ); } ``` Part 1) and 2) work but the `set heading(...)` is not doing anything within the function. If I extract it and do a `#let` it works. Any way to have it working within the function? Or something else? I tried doing a global numbering and use a counter to check if I was in appendices but it did not work.
johannes-wolf commented 1 year ago

You could pass the content it should act on as body:

#let appendices(body) = {
  counter(heading).update(0)
  counter("appendices").update(1)

  set heading(
    numbering: (..nums) => {
      let vals = nums.pos()
      let value = "ABCDEFGHIJ".at(vals.at(0) - 1)
      if vals.len() == 1 {
        return "APPENDIX " + value + ": "
      }
      else {
        return value + "." + nums.pos().slice(1).map(str).join(".")
      }
    }  
  );
  [#body]
}

#appendices[
= Maybe
= This
= Works
]

image

Holt59 commented 1 year ago

You could pass the content it should act on as body:

#let appendices(body) = {
}

#appendices[
= Maybe
= This
= Works
]

As mentioned in the discussion, that's far from ideal if you have large appendices... It would be nice to have an option to alter headings like that, I think it's pretty common to have appendices with different headings.

Right now my workaround is to set the counter to 1, and then check the value of the counter in set heading via a locate() call. But this also implies a custom code in outline() because the counter value is not right in outline()... I already have a custom outline(), so that's not a big issue for me, but for those that don't, that's a lot of work.

laurmaedje commented 1 year ago

The linked discussion seems to be resolved in favor of a show rule, so I'm closing this.

Holt59 commented 1 year ago

The linked discussion seems to be resolved in favor of a show rule, so I'm closing this.

I'm okay with closing that issue although I would say that show-rules probably need more attention/examples in the documentation, in particular regarding "recursive" show rules (which works as I expect them to, but there is no clear example in the doc.).