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

Resumable enum numbering #325

Open
ararunaufc opened this issue Mar 26, 2023 · 10 comments
Open

Resumable enum numbering #325

ararunaufc opened this issue Mar 26, 2023 · 10 comments
Labels
feature request New feature or request model Related to structure and semantics.

Comments

@ararunaufc
Copy link

Having a way to provide a counter for an enum to use would be great for one use case I have right now, which involves defining a custom numbered list, but it would also enable resuming the counting of one enum from another, like when you "suspend" the list with some text in between items.

Replicating this idea on other numbered entities would also easen customization, like defining separate numbering on front matter / main matter / back matter, or continuous numbering for Theorems, Lemmas, etc.

@lingo
Copy link

lingo commented Apr 11, 2023

I have a different use case, but I believe this is relevant here.

I feel that we should be able to provide a counter for an enum, or be able to retrieve the value of a counter from an enum.

*My use case: *

I'm trying to create a link to a particular step of an enum.

I found a solution, but it feels very hacky...
#[
  // create a counter
  #let s = counter("number")
  #{ s.update(c => 1) } // start at 1

  // ensure all enums (in this block?) update the counter before rendering
  #set enum(numbering: it  => {
    s.update(number => it)
    numbering("1.", it) // can't seem to find out what numbering the enum is using
  })

    This
    Is
    a numbered <step-link>
    list
    below
    is a link to a numbered step

  See #link(<step-link>)[#locate(loc => {
      let item = query(<step-link>, before: loc).first();
      [Step #{numbering("1.",..s.at(item.location()))}] // can't work out numbering of enum, but render number
  })] for further information
]

I can use a link successfully with a label, but I wondered if I can auto-generate the text from the enum's counter, e.g. See #link()[...]. I tried using a ref but this of course currently requires a figure.

I tried to use locate() and query() to display a counter value, but when trying to use counter(enum), I get error: enum is not locatable
I tried using a custom figure kind, and my own counter, but had problems there too.

From looking at the typst source, it appears enums indeed do not use counters. Perhaps they should, like headings? The logic seems to be sufficiently similar (e.g. use of numbering vs level, etc)

See also:

I'd be happy to attempt a PR, making the enums use counters, but I'm new to the codebase - I don't know what architectural decisions have led to the current code.

@laurmaedje
Copy link
Member

Better integration between enums and counters seems very reasonable. One big difference though is that counters are always global to the document whereas enums are generally counted locally.

@AlbertoFabbri93
Copy link

I ended up here by searching how to skip a number when using a numbered list. The idea is that something like this:

#set enum(start: 2)

  Bla

  Bla bla

#counter(enum).step()

  Bla bla bla

Should be printed as:
2. Bla
3. Bla bla
5. Bla bla bla

@laurmaedje laurmaedje changed the title Feature Request: numbered entities with custom counters Numbered entities with custom counters Sep 18, 2023
@laurmaedje laurmaedje changed the title Numbered entities with custom counters Resumable enum numbering Nov 5, 2023
@laurmaedje laurmaedje added model Related to structure and semantics. and removed meta labels Nov 24, 2023
@Andrew15-5
Copy link
Contributor

I had a very similar problem to the one of @lingo, but my workaround didn't work perfectly:

source

#locate(loc => counter("source").final(loc).first())
#show enum.item: it => {
  counter("source").step()
  it
}
  item
  item
  item

output

image

Using set enum(numbering) instead of show enum.item works flawlessly:

source

#locate(loc => counter("source").final(loc).first())
#set enum(full: false, numbering: (n) => {
  counter("source").update(n)
  numbering("1.", n)
})
  item
  item
  item

output

image

@sbaumard
Copy link

I can't seem to be able to adapt @Andrew15-5 's workaround to both manage multi-leveled numbered lists (such as "1)a)") and reuse the saved counter in a new list. Does anyone have an idea ?

@Andrew15-5
Copy link
Contributor

Yeah, multi-level numbering is not as simple. I haven't tried it with that, but it might work with some improved version. For that, the argument must be ..n instead of n, that is for sure.

@Esn024
Copy link

Esn024 commented Feb 28, 2024

query(<step-link>, before: loc).first()

This part of @lingo's example currently gives the error "missing argument: location". How should one write this with the current syntax?

I'm trying to figure out if the above examples from lingo and @Andrew15-5 will work with the solution given here to allow enums to be referenced later in the document (that solution works, but only if you number your numbered list manually as in the example

1. amongus <label>
2. amongus
3. trimongus <labelled>

because the number property in typst only seems to be set if you number your list manually, not automatically.

...which makes that solution a lot less useful, and also seems to make it impossible to reference those items in a way not using numbers (roman numerals, letters, etc.)

@laurmaedje
Copy link
Member

The 0.10 (currently released) syntax is query(selector(<step-link>).before(loc), loc). With the upcoming 0.11, it will become query(selector(<step-link>).before(here())) and should be wrapped in a context block instead of a locate callback.

@Andrew15-5
Copy link
Contributor

Will the current usage/syntax be deprecated or removed completely?

@Esn024
Copy link

Esn024 commented Feb 28, 2024

@laurmaedje, thank you, that works. I've put @lingo's solution into a function, so that it's not so wordy for every reference to a label:

#[
  // create a counter
  #let s = counter("number")
  #{ s.update(c => 1) } // start at 1
  
  // function to allow references to numbered list items
  #let l(label, numberingSystem: "1.") = {
    link(label)[#locate(loc => {
      let item = query(selector(label).before(loc), loc).first();
      [#{numbering(numberingSystem,..s.at(item.location()))}]})]
  }

  // ensure all enums update the counter before rendering
  #set enum(numbering: it  => {
    s.update(number => it)
    numbering("A)", it) // can't seem to find out what numbering the enum is using
  })

    This
    Is
    a numbered <step-link>
    list
    below
    is a link to a numbered step

  Text

  // start a new numbered list
    point 1
    point 2 <step-link2>

  See #l(<step-link>) for further info \ // See 3. for further info
  See #l(<step-link2>, numberingSystem: "A") for further info // See B for further info
]

Ultimately it would be nice to use @step-link2 to reference a labelled numbered list item, but at least this works and is relatively concise for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request model Related to structure and semantics.
Projects
None yet
Development

No branches or pull requests

8 participants