Skip to content

Numbering#5622

Closed
samuelireson wants to merge 17 commits intotypst:mainfrom
samuelireson:numbering
Closed

Numbering#5622
samuelireson wants to merge 17 commits intotypst:mainfrom
samuelireson:numbering

Conversation

@samuelireson
Copy link
Contributor

@samuelireson samuelireson commented Dec 23, 2024

An implementation of the changes discussed in #1177 (comment).

I also decided to try to centralise the numbering styles for Roman, Hebrew, Greek etc. by introducing a function called additive which assigns symbols numeric values and returns the symbolic representation. This is function is described here. This can also replace the current Chinese numeral implementation - TODO. - the algorithm for representing Chinese numerals cannot use the numeric function

Alongside this, I have introduced functions for each of the CSS counter algorithms described on the page above. I think this is better than the current approach since it means we only need to test the output of these functions for a subset of the NumberingKinds, rather than test every NumberingKind which is the current approach.

TODO

  • Implement more numbering kinds - this is a discussion point. How many should be supported? The list of styles here is huge, but I suppose exhaustive.
  • Test cases.
  • Naming convention - I have followed the CSS naming convention as seen in the previously referenced web pages, but there was some discussion in Cyrillic numbering #5597 about using an {Upper}/{lower} convention instead.
  • Re-implement the numbering patterns which I removed (Bengali numbers etc.).
  • Choose 'shorter' names for the NumberingKinds - so each of the kinds which support "1" as a pattern will also support "{1}" etc. - just add all the current ones; others can be added if wanted later.

I thought it was a good idea to open this PR to discuss these things, but if this is wrong (sorry) - just let me know!

@Myriad-Dreamin
Copy link
Contributor

The popular numbly package implemented similar syntax. They can also use levels to generate numbering string. Not sure whether we can get any inspiration from it.

@samuelireson
Copy link
Contributor Author

From what I can tell the numbly package tries to solve a slightly different problem - heading numbering per level.

The initial discussion which led to this PR was related to the potential to support Cyrillic numbering and the subsequent need to support verbose naming for numbering, since there are multiple Cyrillic numbering styles (Belorussian, Bulgarian, Macedonian, etc.) but these all use the same first letter (/u{430}). At some point, the numberingx was also mentioned as a means of solving this problem.

@samuelireson samuelireson marked this pull request as draft December 24, 2024 09:24
@samuelireson
Copy link
Contributor Author

Maybe this is slightly overkill, but I have now implemented all the numbering styles shown here. This is still failing tests since we now return the name of the NumberingKind rather than its representative character and the visual outputs will change on this account. I didn't know whether just running testit --update was a viable solution here or there was more of a procedure for changing the expected output.

@samuelireson samuelireson marked this pull request as ready for review January 1, 2025 19:08
Since the name of the NumberingKind is now returned in it's verbose
format, this should be wrapped in {} in order for it to be used
correctly in future #numbering() calls.
@samuelireson
Copy link
Contributor Author

So I guess this needs a little more thought, or maybe the test cases need to be slightly changed. Since we now return the NumberingKind's name rather than it's representative character, using something like,

#set heading(numbering: "I")
#show heading: it => it.numbering

will not give the previously expected output. By setting the numbering to "I", UpperRoman NumberingKind is chosen, and when calling it.numbering, the name (in kebab-case) of this NumberingKind is returned; upper-roman. Is this desired?

To me it doesn't seem like this test is giving the output which would be desired anyway, since any future calls to #heading() will still give the representative character of the numbering, rather than the value of counter(heading) at that point. But maybe this test is just to see that the numbering of an element can be returned if wanted.

The other test which has altered output is the self-proclaimed 'cursed' test, show-set-same-element-matched-field. In this case, to get the behaviour which was wanted, a user would have to use,

#set heading(numbering: "(I)")
#show heading.where(numbering: "({upper-roman})"): set heading(numbering: "1.")

rather than the previous,

#set heading(numbering: "(I)")
#show heading.where(numbering: "(I)"): set heading(numbering: "1.")

I'm not sure how intuitive this is, but can't think of a good way around it. For those NumberingKind without representative characters, the behaviour makes sense. For example,

#set heading(numbering: "{adlam}")
#show heading.where(numbering: "{adlam}"): set heading(numbering: "1.")

will work as expected.

I am also aware that this PR has grown maybe too large (sorry), although I'm not sure how this could have been avoided given the necessary verbosity of the pattern implementations for each NumberingKind.

@laurmaedje
Copy link
Member

Both the syntax changes and new numberings are indeed a bit much for one PR. We should start with the syntactical changes. If we then decide to support all the CSS counter styles, I think that should be put into a separate repository and crate, since it's a bit much for inclusion here.


There is another concurrent PR, see my comment there regarding the conflict.

@samuelireson
Copy link
Contributor Author

I will start to revert back to the basic changes. Which numbering patterns should I leave behind? Just the ones which were originally supported?

@samuelireson
Copy link
Contributor Author

I have removed the numbering patterns which were not present previously, and converted the unicode character codes to their actual characters since this is quite a bit easier on the eye. I suppose the implementation could be put back further, to the point before the CSS counter algorithm named functions were introduced, but I don't think this is really necessary - the diff is very reduced given these removals already.

@laurmaedje laurmaedje added interface PRs that add to or change Typst's user-facing interface as opposed to internals or docs changes. model Related to model category, which is all about structure and semantics. labels Mar 24, 2025
@laurmaedje
Copy link
Member

I'm sorry for the radio silence here. I was quite busy over the past months, and the large nature of this PR made it hard to fit in between. To get this landed, I think it'd still be good to break this up further. This makes it much easier to review, which also helps speed things up on my end. As I see it, there are a few different changes bundled up here:

  1. Refactors/Streamlining of the implementations of the numbering patterns.
  2. Changes to the names of existing numbering patterns to align them with CSS. This is not breaking as the names are not currently exposed.
  3. Support for { in numbering patterns.

I think 1 would make for a good standalone PRs and is independent of the others.

2 is relevant to 3 as 3 will expose the names. Following CSS probably makes sense, but maybe this warrants some further discussion. For example, I find it a bit odd that CSS spells it "greek-lower-modern", but "lower-roman" (lower once before and once after the writing system).

3 would then follow after 2.

Split up this way, we can land things incrementally.

@samuelireson
Copy link
Contributor Author

Makes sense - followed my nose too far on this one! Should we close this pr and I will reopen for each stage as I complete?

@laurmaedje
Copy link
Member

Yeah that sounds good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

interface PRs that add to or change Typst's user-facing interface as opposed to internals or docs changes. model Related to model category, which is all about structure and semantics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants