Skip to content

Number formatting #3269

@tertsdiepraam

Description

@tertsdiepraam

Description

I'd like to have more powerful number formatting built-into Typst. This could be done by providing a display method to both integers and floats, which could take options on how to format the number. For example:

  • The group separator (string)
  • The thousands separator (string)
  • Precision (int)
  • And possibly also hexadecimal, octal & binary representations.
100.24.display(thousands: ".", decimal: ",", precision: 2)

These could all be optional as well. However, the question in that case becomes what the default values should be: should they be based on the US locale or should they be locale-dependent?

There are a lot of questions about how flexible this system should be. For example, should it be flexible enough to do the Indian style of number formatting:

The Indian numbering system is somewhat more complex: It groups the rightmost three digits together (until the hundreds place) and thereafter groups by sets of two digits. For example, one American trillion (European billion) would thus be written as 10,00,00,00,00,000 or 10 kharab.

Source: https://en.wikipedia.org/wiki/Decimal_separator#Digit_grouping

My suggestion would be to keep this method fairly simple and leave complex locale-dependent formatting to dedicated systems for localization.

Use Case

I came across this while writing an invoice using Typst. For any financial documents, it could be pretty important to have precise control over how the numbers are formatted, because they should match the conventions of the country and, for example, always use a precision of 2. My country (The Netherlands) uses , as a decimal separator and . as a thousands separator.

This can all be solved with custom functions, as can be seen in the details element below, which I wrote the invoice (it's probably a pretty bad function, I'm fairly new to Typst). However, I think that reimplementing this for every document is error-prone and annoying and I wouldn't trust it for large documents with many numbers.

Custom function for formatting prices
#let price(number) = {
  let chunks = ()
  let integer = int(number)
  while integer > 1000 {
    let n = str(int(calc.rem(integer, 1000)))
    let chunk = ""
    for i in range(3 - n.len()) {
      chunk += "0"
    }
    chunk += n
    chunks.push(chunk)
    integer = int(integer / 1000);
  }

  chunks.push(str(integer))

  let s = ""
  for chunk in chunks.rev() {
    s += str(chunk)
    s += "."
  }
  s = s.slice(0, s.len() -1)
  
  let decimal = str(int(calc.rem(number * 100, 100)))
  s += ","
  
  for i in range(2 - decimal.len()){
    s = s + "0"
  }
  s += decimal
  s
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestNew feature or requestscriptingAbout Typst's coding capabilities

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions