Skip to content

Commit

Permalink
utilities: simplify and fix conversion of relative lengths to pt
Browse files Browse the repository at this point in the history
The `convert-length-to-pt` previously used regex to retrieve the ratio
portion of the relative length. However, this is not necessary as
relative lengths expose their components through their `ratio` and
`length` fields. We can simply pass each component to the respective
conversion function for their type and add the results.

The old implementation also had an issue when the `length` component is
compound and positive (e.g., 1em + 1pt). It would throw an error because
Typst does not allow comparing positive compound lengths with 0pt. For
some reason, no error would be thrown for negative compound lengths (not
sure why), but the result of the conversion appears to become 0pt.
  • Loading branch information
dixslyf committed Dec 1, 2023
1 parent 28ce889 commit 176402a
Showing 1 changed file with 3 additions and 30 deletions.
33 changes: 3 additions & 30 deletions src/utilities.typ
Original file line number Diff line number Diff line change
Expand Up @@ -197,37 +197,10 @@
} else if type(len) == _fraction_type {
convert-fraction-type-topt(len, frac_amount, frac_total)
} else if type(len) == _rel_len_type {
if styles == none {
panic("Cannot convert relative length to pt ('styles' not specified).")
}

let ratio_regex = regex("^\\d+%")
let ratio = repr(len).find(ratio_regex)

if ratio == none { // 2em + 5pt (doesn't contain 100% or something)
measure(line(length: len), styles).width
} else { // 100% + 2em + 5pt --> extract the "100%" part
if page_size == none {
panic("Cannot convert relative length to pt ('page_size' not specified).")
}

// SAFETY: guaranteed to be a ratio by regex
let ratio_part = eval(ratio)
assert(type(ratio_part) == _ratio_type, message: "Eval didn't return a ratio")

let other_part = len - ratio_part // get the (2em + 5pt) part
let ratio_part_pt = convert-ratio-type-to-pt(len.ratio, page_size)
let length_part_pt = convert-length-type-to-pt(len.length, styles)

let ratio_part_pt = if is-infinite-len(page_size) { 0pt } else { ((ratio_part / 1%) / 100) * page_size }
let other_part_pt = 0pt

if other_part < 0pt {
other_part_pt = -measure(line(length: -other_part), styles).width
} else {
other_part_pt = measure(line(length: other_part), styles).width
}

ratio_part_pt + other_part_pt + 0pt
}
ratio_part_pt + length_part_pt
} else {
panic("Cannot convert '" + type(len) + "' to length.")
}
Expand Down

0 comments on commit 176402a

Please sign in to comment.