diff --git a/crates/doc/src/expr.rs b/crates/doc/src/expr.rs index 8ea891a9..5e86b2bb 100644 --- a/crates/doc/src/expr.rs +++ b/crates/doc/src/expr.rs @@ -281,6 +281,13 @@ fn lex_spans(s: &str) -> Result, DocError> { } else if c == '°' { out.push((Tok::Id("deg".into()), at(i), at(i + 1))); i += 1; + } else if c == '"' || c == '″' { + // Inch and foot marks (`1"`, `2'`, #1502), straight or as primes. + out.push((Tok::Id("in".into()), at(i), at(i + 1))); + i += 1; + } else if c == '\'' || c == '′' { + out.push((Tok::Id("ft".into()), at(i), at(i + 1))); + i += 1; } else if c == '×' || c == '·' { out.push((Tok::Op('*'), at(i), at(i + 1))); i += 1; @@ -856,6 +863,20 @@ mod tests { } } + #[test] + fn inch_and_foot_marks() { + // #1502: `1"` in a millimetre design is an inch, `2'` two feet, straight or as primes. + assert_eq!(ev("1\"", Kind::Length).unwrap(), 25.4); + assert_eq!(ev("1″", Kind::Length).unwrap(), 25.4); + assert_eq!(ev("2'", Kind::Length).unwrap(), 609.6); + assert_eq!(ev("2′", Kind::Length).unwrap(), 609.6); + assert_eq!(ev("1/2\"", Kind::Length).unwrap(), 12.7); + assert_eq!(ev("width + 1\"", Kind::Length).unwrap(), 65.4); + assert_eq!(ev("2' + 3\"", Kind::Length).unwrap(), 685.8); + // A mark alone is its unit alone, as `in` is. + assert_eq!(ev("\"", Kind::Length).ok(), ev("in", Kind::Length).ok()); + } + #[test] fn arithmetic_and_units() { assert_eq!(ev("10", Kind::Length).unwrap(), 10.0);