jbirnick / typst-rich-counters

Typst counters that can inherit from other counters.
MIT License
3 stars 0 forks source link

Layout non-convergence when using 2 counters #1

Closed jamesrswift closed 1 month ago

jamesrswift commented 1 month ago

MRE:

#import "@preview/rich-counters:0.1.0": *

#set heading(numbering: "1.1")
#let counter1 = richcounter(
  identifier: "counter1",
  inherited_levels: 1,
  inherited_from: heading
)

#let counter2 = richcounter(
  identifier: "counter2",
  inherited_from: counter1
)

= Heading 1
#(counter1.step)() #context{(counter1.display)("1.1")}

#(counter2.step)() #context{(counter2.display)("1.1")}
jbirnick commented 1 month ago

Thanks for catching this.

I tried to debug it but I don't know what goes wrong. I'm rather getting more and more confused what the layout engine is doing... without understanding how it works, I can't really understand in detail what's happening and hence what goes wrong.

If anybody has a basic understanding of the layout engine please let me know.

PS: On the way, I discovered a little bug in my logic, but it has nothing to do with the primary issue here.

jbirnick commented 1 month ago

Okay breakthrough. It DOES converge within 10 iterations. :D

Now, based on what I've seen what the layout engine produces after 1,2,3, etc. iterations, my current arrogant standpoint is that the layout engine just works relatively inefficient, and hence needs more than 5 iterations for this comparatively simple code construct.

I guess I will have to speak to Typst "experts" to find out why the layout engine needs so many iterations for this, and if there is a way to make the layout engine more efficient (-> a lot of work I guess).

jbirnick commented 1 month ago

Here is a Discord discussion about this: https://discord.com/channels/1054443721975922748/1291866041022021756

jbirnick commented 1 month ago

Issue fixed! I re-implemented the package with a completely new algorithm and even more functionality!

Now your example compiles perfectly. You just need to change the version to 0.2.1 and richcounter to rich-counter.

#import "@preview/rich-counters:0.2.1": *

#set heading(numbering: "1.1")
#let counter1 = rich-counter(
  identifier: "counter1",
  inherited_levels: 1,
  inherited_from: heading
)

#let counter2 = rich-counter(
  identifier: "counter2",
  inherited_from: counter1
)

= Heading 1
#(counter1.step)() #context{(counter1.display)("1.1")}

#(counter2.step)() #context{(counter2.display)("1.1")}

I hope the package will be useful to you!

PS: If you only only want to inherit from the heading counter, I have also published a headcount, which is more tailored to exactly that purpose.