summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-06-30 22:32:24 +0200
committerGitHub <noreply@github.com>2021-06-30 22:32:24 +0200
commit17e89468847735df10381c47c46c7d82d33cc463 (patch)
treeb0ce55f7d62aac399717aac3ab5a76c981c66f65
parent911b5818344e85a58da9db895a333d22484b7ae7 (diff)
Remove color literals (#39)
-rw-r--r--src/color.rs4
-rw-r--r--src/eval/mod.rs2
-rw-r--r--src/library/utility.rs43
-rw-r--r--src/parse/mod.rs8
-rw-r--r--src/parse/tokens.rs56
-rw-r--r--src/pretty.rs2
-rw-r--r--src/syntax/expr.rs4
-rw-r--r--src/syntax/token.rs4
-rw-r--r--src/syntax/visit.rs1
-rw-r--r--tests/typ/code/array.typ2
-rw-r--r--tests/typ/code/repr.typ2
-rw-r--r--tests/typ/insert/circle.typ6
-rw-r--r--tests/typ/insert/ellipse.typ2
-rw-r--r--tests/typ/insert/rect.typ14
-rw-r--r--tests/typ/insert/square.typ4
-rw-r--r--tests/typ/layout/grid-1.typ24
-rw-r--r--tests/typ/layout/grid-3.typ4
-rw-r--r--tests/typ/layout/pad.typ2
-rw-r--r--tests/typ/layout/stack.typ2
-rw-r--r--tests/typ/text/decorations.typ13
-rw-r--r--tests/typ/text/font.typ2
-rw-r--r--tests/typ/utility/color.typ13
22 files changed, 89 insertions, 125 deletions
diff --git a/src/color.rs b/src/color.rs
index c3ab5aa9..124c2042 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
/// A color in a dynamic format.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum Color {
- /// An 8-bit RGBA color: `#423abaff`.
+ /// An 8-bit RGBA color.
Rgba(RgbaColor),
}
@@ -28,7 +28,7 @@ impl Debug for Color {
}
}
-/// An 8-bit RGBA color: `#423abaff`.
+/// An 8-bit RGBA color.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct RgbaColor {
/// Red channel.
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index 8579025f..96ac87a9 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -16,7 +16,6 @@ use std::path::{Path, PathBuf};
use std::rc::Rc;
use crate::cache::Cache;
-use crate::color::Color;
use crate::diag::{Diag, DiagSet, Pass};
use crate::geom::{Angle, Fractional, Length, Relative};
use crate::loading::{FileHash, Loader};
@@ -248,7 +247,6 @@ impl Eval for Expr {
Self::Angle(_, v, unit) => Value::Angle(Angle::with_unit(v, unit)),
Self::Percent(_, v) => Value::Relative(Relative::new(v / 100.0)),
Self::Fractional(_, v) => Value::Fractional(Fractional::new(v)),
- Self::Color(_, v) => Value::Color(Color::Rgba(v)),
Self::Str(_, ref v) => Value::Str(v.clone()),
Self::Ident(ref v) => match ctx.scopes.get(&v) {
Some(slot) => slot.borrow().clone(),
diff --git a/src/library/utility.rs b/src/library/utility.rs
index 146fce9c..272183aa 100644
--- a/src/library/utility.rs
+++ b/src/library/utility.rs
@@ -1,4 +1,5 @@
use std::cmp::Ordering;
+use std::str::FromStr;
use crate::color::{Color, RgbaColor};
use crate::pretty::pretty;
@@ -37,26 +38,32 @@ pub fn len(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
/// `rgb`: Create an RGB(A) color.
pub fn rgb(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let r = args.expect(ctx, "red component");
- let g = args.expect(ctx, "green component");
- let b = args.expect(ctx, "blue component");
- let a = args.eat(ctx);
-
- let mut clamp = |component: Option<Spanned<f64>>, default| {
- component.map_or(default, |c| {
- if c.v < 0.0 || c.v > 1.0 {
- ctx.diag(warning!(c.span, "should be between 0.0 and 1.0"));
+ Value::Color(Color::Rgba(
+ if let Some(string) = args.eat::<Spanned<String>>(ctx) {
+ match RgbaColor::from_str(&string.v) {
+ Ok(color) => color,
+ Err(_) => {
+ ctx.diag(error!(string.span, "invalid color"));
+ return Value::Error;
+ }
}
- (c.v.max(0.0).min(1.0) * 255.0).round() as u8
- })
- };
+ } else {
+ let r = args.expect(ctx, "red component");
+ let g = args.expect(ctx, "green component");
+ let b = args.expect(ctx, "blue component");
+ let a = args.eat(ctx);
+ let mut clamp = |component: Option<Spanned<f64>>, default| {
+ component.map_or(default, |c| {
+ if c.v < 0.0 || c.v > 1.0 {
+ ctx.diag(warning!(c.span, "should be between 0.0 and 1.0"));
+ }
+ (c.v.max(0.0).min(1.0) * 255.0).round() as u8
+ })
+ };
- Value::Color(Color::Rgba(RgbaColor::new(
- clamp(r, 0),
- clamp(g, 0),
- clamp(b, 0),
- clamp(a, 255),
- )))
+ RgbaColor::new(clamp(r, 0), clamp(g, 0), clamp(b, 0), clamp(a, 255))
+ },
+ ))
}
/// `min`: The minimum of a sequence of values.
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 0afcd88b..a56e451d 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -385,7 +385,6 @@ fn literal(p: &mut Parser) -> Option<Expr> {
Token::Angle(val, unit) => Expr::Angle(span, val, unit),
Token::Percent(p) => Expr::Percent(span, p),
Token::Fraction(p) => Expr::Fractional(span, p),
- Token::Color(color) => Expr::Color(span, color),
Token::Str(token) => Expr::Str(span, {
if !token.terminated {
p.expected_at("quote", p.peek_span().end);
@@ -672,10 +671,9 @@ fn if_expr(p: &mut Parser) -> Option<Expr> {
// We are in code mode but still want to react to `#else` if the
// outer mode is markup.
- if match p.outer_mode() {
- TokenMode::Markup => p.eat_if(Token::Invalid("#else")),
- TokenMode::Code => p.eat_if(Token::Else),
- } {
+ if (p.outer_mode() == TokenMode::Code || p.eat_if(Token::Invalid("#")))
+ && p.eat_if(Token::Else)
+ {
else_body = body(p);
}
diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs
index 4d90dded..522b3136 100644
--- a/src/parse/tokens.rs
+++ b/src/parse/tokens.rs
@@ -1,8 +1,6 @@
use std::fmt::{self, Debug, Formatter};
-use std::str::FromStr;
use super::{is_newline, Scanner};
-use crate::color::RgbaColor;
use crate::geom::{AngularUnit, LengthUnit};
use crate::syntax::*;
@@ -71,9 +69,6 @@ impl<'s> Iterator for Tokens<'s> {
'{' => Token::LeftBrace,
'}' => Token::RightBrace,
- // Headings, keywords, identifiers, colors.
- '#' => self.hash(start),
-
// Whitespace.
c if c.is_whitespace() => self.whitespace(c),
@@ -104,6 +99,9 @@ impl<'s> Tokens<'s> {
'-' => self.hyph(start),
c if c == '.' || c.is_ascii_digit() => self.numbering(start, c),
+ // Headings, keywords and identifiers.
+ '#' => self.hash(start),
+
// Plain text.
_ => self.text(start),
}
@@ -236,29 +234,17 @@ impl<'s> Tokens<'s> {
}
fn hash(&mut self, start: usize) -> Token<'s> {
- match self.mode {
- TokenMode::Markup => {
- if self.s.check(is_id_start) {
- let read = self.s.eat_while(is_id_continue);
- if let Some(keyword) = keyword(read) {
- keyword
- } else {
- Token::Ident(read)
- }
- } else if self.s.check(|c| c != '#' && !c.is_whitespace()) {
- Token::Text(self.s.eaten_from(start))
- } else {
- Token::Hashtag
- }
- }
- TokenMode::Code => {
- let read = self.s.eat_while(is_id_continue);
- if let Ok(color) = RgbaColor::from_str(read) {
- Token::Color(color)
- } else {
- Token::Invalid(self.s.eaten_from(start))
- }
+ if self.s.check(is_id_start) {
+ let read = self.s.eat_while(is_id_continue);
+ if let Some(keyword) = keyword(read) {
+ keyword
+ } else {
+ Token::Ident(read)
}
+ } else if self.s.check(|c| c != '#' && !c.is_whitespace()) {
+ Token::Text(self.s.eaten_from(start))
+ } else {
+ Token::Hashtag
}
}
@@ -528,10 +514,6 @@ mod tests {
Token::Math(MathToken { formula, display, terminated })
}
- const fn Color(r: u8, g: u8, b: u8, a: u8) -> Token<'static> {
- Token::Color(RgbaColor { r, g, b, a })
- }
-
const fn Str(string: &str, terminated: bool) -> Token {
Token::Str(StrToken { string, terminated })
}
@@ -583,7 +565,6 @@ mod tests {
('/', Some(Code), "(", LeftParen),
('/', Some(Code), ":", Colon),
('/', Some(Code), "+=", PlusEq),
- ('/', Some(Code), "#123", Color(0x11, 0x22, 0x33, 0xff)),
];
macro_rules! t {
@@ -927,13 +908,6 @@ mod tests {
}
#[test]
- fn test_tokenize_color() {
- t!(Code[" /"]: "#ABC" => Color(0xAA, 0xBB, 0xCC, 0xff));
- t!(Code[" /"]: "#6ae6dd" => Color(0x6a, 0xe6, 0xdd, 0xff));
- t!(Code[" /"]: "#8A083caf" => Color(0x8A, 0x08, 0x3c, 0xaf));
- }
-
- #[test]
fn test_tokenize_strings() {
// Test basic strings.
t!(Code: "\"hi\"" => Str("hi", true));
@@ -999,13 +973,11 @@ mod tests {
t!(Code: r"\:" => Invalid(r"\"), Colon);
t!(Code: "meal⌚" => Ident("meal"), Invalid("⌚"));
t!(Code[" /"]: r"\a" => Invalid(r"\"), Ident("a"));
+ t!(Code[" /"]: "#" => Invalid("#"));
// Test invalid number suffixes.
t!(Code[" /"]: "1foo" => Invalid("1foo"));
t!(Code: "1p%" => Invalid("1p"), Invalid("%"));
t!(Code: "1%%" => Percent(1.0), Invalid("%"));
-
- // Test invalid color.
- t!(Code[" /"]: r"#letter" => Invalid(r"#letter"));
}
}
diff --git a/src/pretty.rs b/src/pretty.rs
index ccf4d88d..17609cea 100644
--- a/src/pretty.rs
+++ b/src/pretty.rs
@@ -205,7 +205,6 @@ impl Pretty for Expr {
Self::Angle(_, v, u) => write!(p, "{}{}", v, u).unwrap(),
Self::Percent(_, v) => write!(p, "{}%", v).unwrap(),
Self::Fractional(_, v) => write!(p, "{}fr", v).unwrap(),
- Self::Color(_, v) => v.pretty(p),
Self::Str(_, v) => v.pretty(p),
Self::Ident(v) => v.pretty(p),
Self::Array(v) => v.pretty(p),
@@ -687,7 +686,6 @@ mod tests {
roundtrip("{14.1deg}");
roundtrip("{20%}");
roundtrip("{0.5fr}");
- roundtrip("{#abcdef}");
roundtrip(r#"{"hi"}"#);
test_parse(r#"{"let's \" go"}"#, r#"{"let's \" go"}"#);
roundtrip("{hi}");
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs
index 26ec7f48..a8a5854a 100644
--- a/src/syntax/expr.rs
+++ b/src/syntax/expr.rs
@@ -1,7 +1,6 @@
use std::rc::Rc;
use super::*;
-use crate::color::RgbaColor;
use crate::geom::{AngularUnit, LengthUnit};
/// An expression.
@@ -28,8 +27,6 @@ pub enum Expr {
Percent(Span, f64),
/// A fraction unit literal: `1fr`.
Fractional(Span, f64),
- /// A color literal: `#ffccee`.
- Color(Span, RgbaColor),
/// A string literal: `"hello!"`.
Str(Span, String),
/// An identifier: `left`.
@@ -81,7 +78,6 @@ impl Expr {
Self::Angle(span, _, _) => span,
Self::Percent(span, _) => span,
Self::Fractional(span, _) => span,
- Self::Color(span, _) => span,
Self::Str(span, _) => span,
Self::Ident(ref v) => v.span,
Self::Array(ref v) => v.span,
diff --git a/src/syntax/token.rs b/src/syntax/token.rs
index 25062264..32a14d58 100644
--- a/src/syntax/token.rs
+++ b/src/syntax/token.rs
@@ -1,4 +1,3 @@
-use crate::color::RgbaColor;
use crate::geom::{AngularUnit, LengthUnit};
/// A minimal semantic entity of source code.
@@ -145,8 +144,6 @@ pub enum Token<'s> {
Percent(f64),
/// A fraction unit: `3fr`.
Fraction(f64),
- /// A color value: `#20d82a`.
- Color(RgbaColor),
/// A quoted string: `"..."`.
Str(StrToken<'s>),
/// Two slashes followed by inner contents, terminated with a newline:
@@ -275,7 +272,6 @@ impl<'s> Token<'s> {
Self::Angle(_, _) => "angle",
Self::Percent(_) => "percentage",
Self::Fraction(_) => "`fr` value",
- Self::Color(_) => "color",
Self::Str(_) => "string",
Self::LineComment(_) => "line comment",
Self::BlockComment(_) => "block comment",
diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs
index 66c5f979..1184010b 100644
--- a/src/syntax/visit.rs
+++ b/src/syntax/visit.rs
@@ -124,7 +124,6 @@ impl_visitors! {
Expr::Angle(_, _, _) => {}
Expr::Percent(_, _) => {}
Expr::Fractional(_, _) => {}
- Expr::Color(_, _) => {}
Expr::Str(_, _) => {}
Expr::Ident(_) => {}
Expr::Array(e) => v.visit_array(e),
diff --git a/tests/typ/code/array.typ b/tests/typ/code/array.typ
index c9383501..002a792a 100644
--- a/tests/typ/code/array.typ
+++ b/tests/typ/code/array.typ
@@ -15,7 +15,7 @@
// Multiple lines and items and trailing comma.
{("1"
- , #002
+ , rgb("002")
,)}
// Error: 3 expected closing paren
diff --git a/tests/typ/code/repr.typ b/tests/typ/code/repr.typ
index eacbf8e8..3da86bf8 100644
--- a/tests/typ/code/repr.typ
+++ b/tests/typ/code/repr.typ
@@ -34,7 +34,7 @@
---
// Colors.
-{#f7a20500}
+#rgb("f7a20500")
---
// Strings and escaping.
diff --git a/tests/typ/insert/circle.typ b/tests/typ/insert/circle.typ
index 1c8808a4..fbb45435 100644
--- a/tests/typ/insert/circle.typ
+++ b/tests/typ/insert/circle.typ
@@ -4,7 +4,7 @@
// Test auto sizing.
Auto-sized circle. \
-#circle(fill: #eb5278)[
+#circle(fill: rgb("eb5278"))[
#align!(center, center)
But, soft!
]
@@ -28,9 +28,9 @@ Expanded by height.
---
// Test relative sizing.
-#rect(width: 100%, height: 50pt, fill: #aaa)[
+#rect(width: 100%, height: 50pt, fill: rgb("aaa"))[
#align!(center, center)
- #font!(color: #fff)
+ #font!(color: white)
#circle(radius: 10pt, fill: eastern)[A]
#circle(height: 60%, fill: eastern)[B]
#circle(width: 20% + 20pt, fill: eastern)[C]
diff --git a/tests/typ/insert/ellipse.typ b/tests/typ/insert/ellipse.typ
index a086ab74..29f9b556 100644
--- a/tests/typ/insert/ellipse.typ
+++ b/tests/typ/insert/ellipse.typ
@@ -2,7 +2,7 @@
---
100% rect in 100% ellipse in fixed rect. \
-#rect(width: 3cm, height: 2cm, fill: #2a631a)[
+#rect(width: 3cm, height: 2cm, fill: rgb("2a631a"))[
#ellipse!(width: 100%, height: 100%, fill: forest)
#rect!(width: 100%, height: 100%, fill: conifer)
#align!(center, center)
diff --git a/tests/typ/insert/rect.typ b/tests/typ/insert/rect.typ
index 93df071b..7f6bb899 100644
--- a/tests/typ/insert/rect.typ
+++ b/tests/typ/insert/rect.typ
@@ -9,19 +9,19 @@
#rect(fill: conifer)[Textbox]
// Empty with fixed width and height.
-#rect(width: 3cm, height: 12pt, fill: #CB4CED)
+#rect(width: 3cm, height: 12pt, fill: rgb("CB4CED"))
// Fixed width, text height.
-#rect(width: 2cm, fill: #9650D6, pad(5pt)[Fixed and padded])
+#rect(width: 2cm, fill: rgb("9650D6"), pad(5pt)[Fixed and padded])
// Page width, fixed height.
-#rect(height: 1cm, width: 100%, fill: #734CED)[Topleft]
+#rect(height: 1cm, width: 100%, fill: rgb("734CED"))[Topleft]
// Not visible, but creates a gap between the boxes above and below
// due to line spacing.
-#rect(width: 1in, fill: #ff0000)
+#rect(width: 1in, fill: rgb("ff0000"))
// These are in a row!
-#rect(width: 0.5in, height: 10pt, fill: #D6CD67)
-#rect(width: 0.5in, height: 10pt, fill: #EDD466)
-#rect(width: 0.5in, height: 10pt, fill: #E3BE62)
+#rect(width: 0.5in, height: 10pt, fill: rgb("D6CD67"))
+#rect(width: 0.5in, height: 10pt, fill: rgb("EDD466"))
+#rect(width: 0.5in, height: 10pt, fill: rgb("E3BE62"))
diff --git a/tests/typ/insert/square.typ b/tests/typ/insert/square.typ
index 4dd8964f..f9efb98e 100644
--- a/tests/typ/insert/square.typ
+++ b/tests/typ/insert/square.typ
@@ -5,7 +5,7 @@ Auto-sized square. \
#square(fill: eastern)[
#align!(center)
#pad!(5pt)
- #font!(color: #fff, weight: bold)
+ #font!(color: white, weight: bold)
Typst
]
@@ -13,7 +13,7 @@ Auto-sized square. \
// Length wins over width and height.
// Error: 2:9-2:20 unexpected argument
// Error: 1:22-1:34 unexpected argument
-#square(width: 10cm, height: 20cm, length: 1cm, fill: #eb5278)
+#square(width: 10cm, height: 20cm, length: 1cm, fill: rgb("eb5278"))
---
// Test height overflow.
diff --git a/tests/typ/layout/grid-1.typ b/tests/typ/layout/grid-1.typ
index 2938a7f2..ad55b53f 100644
--- a/tests/typ/layout/grid-1.typ
+++ b/tests/typ/layout/grid-1.typ
@@ -6,18 +6,18 @@
#page!(width: 100pt, height: 140pt)
#grid(
columns: (auto, 1fr, 3fr, 0.25cm, 3%, 2mm + 10%),
- rect(0.5cm, #2a631a),
+ rect(0.5cm, rgb("2a631a")),
rect(100%, forest),
rect(100%, conifer),
- rect(100%, #ff0000),
- rect(100%, #00ff00),
- rect(80%, #00faf0),
- rect(1cm, #00ff00),
- rect(0.5cm, #2a631a),
+ rect(100%, rgb("ff0000")),
+ rect(100%, rgb("00ff00")),
+ rect(80%, rgb("00faf0")),
+ rect(1cm, rgb("00ff00")),
+ rect(0.5cm, rgb("2a631a")),
rect(100%, forest),
rect(100%, conifer),
- rect(100%, #ff0000),
- rect(100%, #00ff00),
+ rect(100%, rgb("ff0000")),
+ rect(100%, rgb("00ff00")),
)
#grid()
@@ -29,7 +29,7 @@
gutter-rows: (1fr,),
rect(fill: eastern)[dddaa aaa aaa],
rect(fill: conifer)[ccc],
- rect(width: 100%, fill: #dddddd)[aaa],
+ rect(width: 100%, fill: rgb("dddddd"))[aaa],
)
---
@@ -38,11 +38,11 @@
columns: (1fr, 1cm, 1fr, 1fr),
column-dir: ttb,
rows: (auto, 1fr),
- rect(height: 100%, fill: #222222)[foo],
- rect(height: 100%, fill: #547d0a)[bar],
+ rect(height: 100%, fill: rgb("222222"))[foo],
+ rect(height: 100%, fill: rgb("547d0a"))[bar],
rect(height: 100%, fill: eastern)[hab],
rect(height: 100%, fill: conifer)[baz],
- rect(height: 100%, width: 100%, fill: #547d0a)[bar],
+ rect(height: 100%, width: 100%, fill: rgb("547d0a"))[bar],
)
---
diff --git a/tests/typ/layout/grid-3.typ b/tests/typ/layout/grid-3.typ
index 62af4072..38572520 100644
--- a/tests/typ/layout/grid-3.typ
+++ b/tests/typ/layout/grid-3.typ
@@ -67,9 +67,9 @@
columns: 2 * (1fr,),
rows: (1fr, 2fr, auto, 1fr, 1cm),
gutter-rows: 4 * (10pt,),
- rect(height: 100%, width: 100%, fill: #ff0000)[No height],
+ rect(height: 100%, width: 100%, fill: rgb("ff0000"))[No height],
[foo],
- rect(height: 100%, width: 100%, fill: #fc0030)[Still no height],
+ rect(height: 100%, width: 100%, fill: rgb("fc0030"))[Still no height],
[bar],
[The nature of being itself is in question. Am I One? Am I Many? What is being alive?],
[baz],
diff --git a/tests/typ/layout/pad.typ b/tests/typ/layout/pad.typ
index 05f9b359..d43cafc5 100644
--- a/tests/typ/layout/pad.typ
+++ b/tests/typ/layout/pad.typ
@@ -7,7 +7,7 @@
// All sides together.
#rect(fill: conifer)[
#pad!(10pt, right: 20pt)
- #rect(width: 20pt, height: 20pt, fill: #eb5278)
+ #rect(width: 20pt, height: 20pt, fill: rgb("eb5278"))
]
// Error: 13-23 missing argument: body
diff --git a/tests/typ/layout/stack.typ b/tests/typ/layout/stack.typ
index 89e587c7..fd5201df 100644
--- a/tests/typ/layout/stack.typ
+++ b/tests/typ/layout/stack.typ
@@ -3,7 +3,7 @@
---
#let rect(width, color) = rect(width: width, height: 1cm, fill: color)
#stack(
- rect(2cm, #2a631a),
+ rect(2cm, rgb("2a631a")),
rect(3cm, forest),
rect(1cm, conifer),
)
diff --git a/tests/typ/text/decorations.typ b/tests/typ/text/decorations.typ
index 3e298ece..247178b2 100644
--- a/tests/typ/text/decorations.typ
+++ b/tests/typ/text/decorations.typ
@@ -3,17 +3,14 @@
---
#strike[Statements dreamt up by the utterly deranged.]
-Sometimes, we work #strike(extent: 5%, strength: 10pt)[in secret].
-There might be #strike(extent: 5%, strength: 10pt, color: #abcdef88)[redacted]
-things.
+Sometimes, we work #strike(extent: 5%, strength: 10pt)[in secret]. There might
+be #strike(extent: 5%, strength: 10pt, color: rgb("abcdef88"))[redacted] things.
---
-#underline(color: #fc0030)[Critical information is conveyed here.]
-#underline[
- Still important, but not #underline(strength: 0pt)[mission ]critical.
-]
+#underline(color: rgb("fc0030"))[Critical information is conveyed here.]
+#underline[Still important, but not #underline(strength: 0pt)[mission ]critical.]
-#font(color: #fc0030, underline[Change with the wind.])
+#font(color: rgb("fc0030"), underline[Change with the wind.])
---
#overline(underline[Running amongst the wolves.])
diff --git a/tests/typ/text/font.typ b/tests/typ/text/font.typ
index d6161c81..9bfeb684 100644
--- a/tests/typ/text/font.typ
+++ b/tests/typ/text/font.typ
@@ -30,7 +30,7 @@ Emoji: πŸͺ, πŸŒ‹, 🏞
]
// Colors.
-#font(color: eastern)[This is #font(color: #FA644B)[way more] colorful.]
+#font(color: eastern)[This is #font(color: rgb("FA644B"))[way more] colorful.]
---
// Test top and bottom edge.
diff --git a/tests/typ/utility/color.typ b/tests/typ/utility/color.typ
index 2e40828b..6523a08d 100644
--- a/tests/typ/utility/color.typ
+++ b/tests/typ/utility/color.typ
@@ -2,18 +2,21 @@
// Ref: false
---
-// Check the output.
-#test(rgb(0.0, 0.3, 0.7), #004db3)
+// Compare both ways.
+#test(rgb(0.0, 0.3, 0.7), rgb("004db3"))
// Alpha channel.
-#test(rgb(1.0, 0.0, 0.0, 0.5), #ff000080)
+#test(rgb(1.0, 0.0, 0.0, 0.5), rgb("ff000080"))
// Warning: 2:11-2:14 should be between 0.0 and 1.0
// Warning: 1:16-1:20 should be between 0.0 and 1.0
-#test(rgb(-30, 15.5, 0.5), #00ff80)
+#test(rgb(-30, 15.5, 0.5), rgb("00ff80"))
// Error: 11-15 missing argument: blue component
-#test(rgb(0, 1), #00ff00)
+#test(rgb(0, 1), rgb("00ff00"))
+
+// Error: 11-16 invalid color
+#test(rgb("lol"), error)
// Error: 3:11-3:11 missing argument: red component
// Error: 2:11-2:11 missing argument: green component