summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalo <57839069+MDLC01@users.noreply.github.com>2024-08-11 22:18:57 +0200
committerGitHub <noreply@github.com>2024-08-11 20:18:57 +0000
commit79fb2c36893140ce61765e2b437ef37c51235615 (patch)
treed2b3cbf8a5926fccf2bdb05446f65b805c104c53
parent70931ac1f6f68f013e25fe5437e23ad148ce23e1 (diff)
Fix `calc.inf`, `-calc.inf`, and `calc.nan` reprs and displays (#4724)
-rw-r--r--crates/typst/src/foundations/repr.rs20
-rw-r--r--tests/ref/float-display.pngbin1621 -> 1848 bytes
-rw-r--r--tests/ref/float-repr.pngbin1923 -> 2443 bytes
-rw-r--r--tests/ref/grid-rowspan-split-15.pngbin1727 -> 2948 bytes
-rw-r--r--tests/ref/ops-multiply-inf-with-length.pngbin1066 -> 2414 bytes
-rw-r--r--tests/suite/foundations/float.typ15
-rw-r--r--tests/suite/scripting/ops.typ4
7 files changed, 30 insertions, 9 deletions
diff --git a/crates/typst/src/foundations/repr.rs b/crates/typst/src/foundations/repr.rs
index 00d9931a..68c94c56 100644
--- a/crates/typst/src/foundations/repr.rs
+++ b/crates/typst/src/foundations/repr.rs
@@ -73,12 +73,15 @@ pub fn format_int_with_base(mut n: i64, base: i64) -> EcoString {
}
/// Converts a float to a string representation with a specific precision and a
-/// suffix, all with a single allocation.
+/// unit, all with a single allocation.
+///
+/// The returned string is always valid Typst code. As such, it might not be a
+/// float literal. For example, it may return `"calc.inf"`.
pub fn format_float(
mut value: f64,
precision: Option<u8>,
force_separator: bool,
- suffix: &str,
+ unit: &str,
) -> EcoString {
if let Some(p) = precision {
let offset = 10_f64.powi(p as i32);
@@ -86,12 +89,16 @@ pub fn format_float(
}
// Debug for f64 always prints a decimal separator, while Display only does
// when necessary.
+ let unit_multiplication = if unit.is_empty() { "" } else { " * 1" };
if value.is_nan() {
- "NaN".into()
+ eco_format!("calc.nan{unit_multiplication}{unit}")
+ } else if value.is_infinite() {
+ let sign = if value < 0.0 { "-" } else { "" };
+ eco_format!("{sign}calc.inf{unit_multiplication}{unit}")
} else if force_separator {
- eco_format!("{:?}{}", value, suffix)
+ eco_format!("{value:?}{unit}")
} else {
- eco_format!("{}{}", value, suffix)
+ eco_format!("{value}{unit}")
}
}
@@ -112,6 +119,9 @@ pub fn format_float_with_unit(value: f64, unit: &str) -> EcoString {
pub fn display_float(value: f64) -> EcoString {
if value.is_nan() {
"NaN".into()
+ } else if value.is_infinite() {
+ let sign = if value < 0.0 { MINUS_SIGN } else { "" };
+ eco_format!("{sign}∞")
} else if value < 0.0 {
eco_format!("{}{}", MINUS_SIGN, value.abs())
} else {
diff --git a/tests/ref/float-display.png b/tests/ref/float-display.png
index 6c33b372..bfece012 100644
--- a/tests/ref/float-display.png
+++ b/tests/ref/float-display.png
Binary files differ
diff --git a/tests/ref/float-repr.png b/tests/ref/float-repr.png
index 8b510969..7b49e9d1 100644
--- a/tests/ref/float-repr.png
+++ b/tests/ref/float-repr.png
Binary files differ
diff --git a/tests/ref/grid-rowspan-split-15.png b/tests/ref/grid-rowspan-split-15.png
index 445f0a95..bbefe0da 100644
--- a/tests/ref/grid-rowspan-split-15.png
+++ b/tests/ref/grid-rowspan-split-15.png
Binary files differ
diff --git a/tests/ref/ops-multiply-inf-with-length.png b/tests/ref/ops-multiply-inf-with-length.png
index 749be056..0662d568 100644
--- a/tests/ref/ops-multiply-inf-with-length.png
+++ b/tests/ref/ops-multiply-inf-with-length.png
Binary files differ
diff --git a/tests/suite/foundations/float.typ b/tests/suite/foundations/float.typ
index 770533b9..206013ac 100644
--- a/tests/suite/foundations/float.typ
+++ b/tests/suite/foundations/float.typ
@@ -20,6 +20,8 @@
// Test float `is-nan()`.
#test(float(calc.nan).is-nan(), true)
#test(float(10).is-nan(), false)
+#test(float(calc.inf).is-nan(), false)
+#test(float(-calc.inf).is-nan(), false)
--- float-is-infinite ---
// Test float `is-infinite()`.
@@ -27,6 +29,7 @@
#test(float(-calc.inf).is-infinite(), true)
#test(float(10).is-infinite(), false)
#test(float(-10).is-infinite(), false)
+#test(float(calc.nan).is-infinite(), false)
--- float-signum ---
// Test float `signum()`
@@ -35,6 +38,8 @@
#test(float(-1.0).signum(), -1.0)
#test(float(10.0).signum(), 1.0)
#test(float(-10.0).signum(), -1.0)
+#test(float(calc.inf).signum(), 1.0)
+#test(float(-calc.inf).signum(), -1.0)
#test(float(calc.nan).signum().is-nan(), true)
--- float-repr ---
@@ -49,7 +54,10 @@
#repr(-9876543210.0) \
#repr(-0987654321.0) \
#repr(-3.14) \
-#repr(4.0 - 8.0)
+#repr(4.0 - 8.0) \
+#repr(calc.inf) \
+#repr(-calc.inf) \
+#repr(calc.nan)
--- float-display ---
// Test floats.
@@ -63,4 +71,7 @@
#(-9876543210.0) \
#(-0987654321.0) \
#(-3.14) \
-#(4.0 - 8.0)
+#(4.0 - 8.0) \
+#calc.inf \
+#(-calc.inf) \
+#calc.nan
diff --git a/tests/suite/scripting/ops.typ b/tests/suite/scripting/ops.typ
index 0f13d212..0df4b82d 100644
--- a/tests/suite/scripting/ops.typ
+++ b/tests/suite/scripting/ops.typ
@@ -335,7 +335,7 @@
#(1em <= 10pt)
--- ops-compare-normal-float-with-nan ---
-// Error: 3-22 cannot compare 2.2 with NaN
+// Error: 3-22 cannot compare 2.2 with calc.nan
#(2.2 <= float("nan"))
--- ops-compare-int-and-str ---
@@ -343,7 +343,7 @@
#((0, 1, 3) > (0, 1, "a"))
--- ops-compare-array-nested-failure ---
-// Error: 3-42 cannot compare 3.5 with NaN
+// Error: 3-42 cannot compare 3.5 with calc.nan
#((0, "a", 3.5) <= (0, "a", float("nan")))
--- ops-divide-by-zero-float ---