diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-26 12:49:30 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-26 12:51:15 +0100 |
| commit | 3cdd8bfa40fe5fdf0c676af905c3c2c1f614ef24 (patch) | |
| tree | fe837d4a30bcad673f581fab18fd946364a60ef3 /library/src/base | |
| parent | bf5edbbbbb75120d065d1c9587ccfa4eed4fdca1 (diff) | |
Extract numbering pattern from list node
Diffstat (limited to 'library/src/base')
| -rw-r--r-- | library/src/base/string.rs | 99 |
1 files changed, 5 insertions, 94 deletions
diff --git a/library/src/base/string.rs b/library/src/base/string.rs index 058ee248..262dd5c6 100644 --- a/library/src/base/string.rs +++ b/library/src/base/string.rs @@ -1,6 +1,7 @@ use typst::model::Regex; use crate::prelude::*; +use crate::shared::NumberingKind; /// The string representation of a value. pub fn repr(_: &Vm, args: &mut Args) -> SourceResult<Value> { @@ -32,110 +33,20 @@ pub fn regex(_: &Vm, args: &mut Args) -> SourceResult<Value> { /// Converts an integer into one or multiple letters. pub fn letter(_: &Vm, args: &mut Args) -> SourceResult<Value> { - numbered(Numbering::Letter, args) + numbered(NumberingKind::Letter, args) } /// Converts an integer into a roman numeral. pub fn roman(_: &Vm, args: &mut Args) -> SourceResult<Value> { - numbered(Numbering::Roman, args) + numbered(NumberingKind::Roman, args) } /// Convert a number into a symbol. pub fn symbol(_: &Vm, args: &mut Args) -> SourceResult<Value> { - numbered(Numbering::Symbol, args) + numbered(NumberingKind::Symbol, args) } -fn numbered(numbering: Numbering, args: &mut Args) -> SourceResult<Value> { +fn numbered(numbering: NumberingKind, args: &mut Args) -> SourceResult<Value> { let n = args.expect::<usize>("non-negative integer")?; Ok(Value::Str(numbering.apply(n).into())) } - -/// Allows to convert a number into letters, roman numerals and symbols. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum Numbering { - Arabic, - Letter, - Roman, - Symbol, -} - -impl Numbering { - /// Apply the numbering to the given number. - pub fn apply(self, mut n: usize) -> EcoString { - match self { - Self::Arabic => { - format_eco!("{}", n) - } - Self::Letter => { - if n == 0 { - return '-'.into(); - } - - n -= 1; - - let mut letters = vec![]; - loop { - letters.push(b'a' + (n % 26) as u8); - n /= 26; - if n == 0 { - break; - } - } - - letters.reverse(); - String::from_utf8(letters).unwrap().into() - } - Self::Roman => { - if n == 0 { - return 'N'.into(); - } - - // Adapted from Yann Villessuzanne's roman.rs under the Unlicense, at - // https://github.com/linfir/roman.rs/ - let mut fmt = EcoString::new(); - for &(name, value) in ROMANS { - while n >= value { - n -= value; - fmt.push_str(name); - } - } - - fmt - } - Self::Symbol => { - if n == 0 { - return '-'.into(); - } - - let symbol = SYMBOLS[(n - 1) % SYMBOLS.len()]; - let amount = ((n - 1) / SYMBOLS.len()) + 1; - std::iter::repeat(symbol).take(amount).collect() - } - } - } -} - -const ROMANS: &[(&str, usize)] = &[ - ("M̅", 1000000), - ("D̅", 500000), - ("C̅", 100000), - ("L̅", 50000), - ("X̅", 10000), - ("V̅", 5000), - ("I̅V̅", 4000), - ("M", 1000), - ("CM", 900), - ("D", 500), - ("CD", 400), - ("C", 100), - ("XC", 90), - ("L", 50), - ("XL", 40), - ("X", 10), - ("IX", 9), - ("V", 5), - ("IV", 4), - ("I", 1), -]; - -const SYMBOLS: &[char] = &['*', '†', '‡', '§', '‖', '¶']; |
