Skip to content

Commit

Permalink
feat: @font-feature-values (#840)
Browse files Browse the repository at this point in the history
  • Loading branch information
CGQAQ authored Jan 1, 2025
1 parent f035bfc commit 4cffb66
Show file tree
Hide file tree
Showing 12 changed files with 675 additions and 75 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ visitor = []
into_owned = [
"static-self",
"static-self/smallvec",
"static-self/indexmap",
"parcel_selectors/into_owned",
]
substitute_variables = ["visitor", "into_owned"]
Expand All @@ -72,7 +73,7 @@ const-str = "0.3.1"
pathdiff = "0.2.1"
ahash = "0.8.7"
paste = "1.0.12"
indexmap = "2.2.6"
indexmap = { version = "2.2.6", features = ["serde"] }
# CLI deps
atty = { version = "0.2", optional = true }
clap = { version = "3.0.6", features = ["derive"], optional = true }
Expand All @@ -81,7 +82,7 @@ rayon = { version = "1.5.1", optional = true }
dashmap = { version = "5.0.0", optional = true }
serde_json = { version = "1.0.78", optional = true }
lightningcss-derive = { version = "=1.0.0-alpha.43", path = "./derive" }
schemars = { version = "0.8.19", features = ["smallvec"], optional = true }
schemars = { version = "0.8.19", features = ["smallvec", "indexmap2"], optional = true }
static-self = { version = "0.1.0", path = "static-self", optional = true }

[target.'cfg(target_os = "macos")'.dependencies]
Expand Down
1 change: 1 addition & 0 deletions napi/src/transformer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ impl<'i> Visitor<'i, AtRule<'i>> for JsVisitor {
CssRule::Keyframes(..) => "keyframes",
CssRule::FontFace(..) => "font-face",
CssRule::FontPaletteValues(..) => "font-palette-values",
CssRule::FontFeatureValues(..) => "font-feature-values",
CssRule::Page(..) => "page",
CssRule::Supports(..) => "supports",
CssRule::CounterStyle(..) => "counter-style",
Expand Down
53 changes: 53 additions & 0 deletions node/ast.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export type Rule<D = Declaration, M = MediaQuery> = | {
type: "font-palette-values";
value: FontPaletteValuesRule;
}
| {
type: "font-feature-values";
value: FontFeatureValuesRule;
}
| {
type: "page";
value: PageRule<D>;
Expand Down Expand Up @@ -7159,6 +7163,17 @@ export type BasePalette =
type: "integer";
value: number;
};
/**
* The name of the `@font-feature-values` sub-rule. font-feature-value-type = <@stylistic> | <@historical-forms> | <@styleset> | <@character-variant> | <@swash> | <@ornaments> | <@annotation>
*/
export type FontFeatureSubruleType =
| "stylistic"
| "historical-forms"
| "styleset"
| "character-variant"
| "swash"
| "ornaments"
| "annotation";
/**
* A [page margin box](https://www.w3.org/TR/css-page-3/#margin-boxes).
*/
Expand Down Expand Up @@ -9328,6 +9343,44 @@ export interface OverrideColors {
*/
index: number;
}
/**
* A [@font-feature-values](https://drafts.csswg.org/css-fonts/#font-feature-values) rule.
*/
export interface FontFeatureValuesRule {
/**
* The location of the rule in the source file.
*/
loc: Location2;
/**
* The name of the font feature values.
*/
name: String[];
/**
* The rules within the `@font-feature-values` rule.
*/
rules: {
[k: string]: FontFeatureSubrule;
};
}
/**
* A sub-rule of `@font-feature-values` https://drafts.csswg.org/css-fonts/#font-feature-values-syntax
*/
export interface FontFeatureSubrule {
/**
* The declarations within the `@font-feature-values` sub-rules.
*/
declarations: {
[k: string]: number[];
};
/**
* The location of the rule in the source file.
*/
loc: Location2;
/**
* The name of the `@font-feature-values` sub-rule.
*/
name: FontFeatureSubruleType;
}
/**
* A [@page](https://www.w3.org/TR/css-page-3/#at-page-rule) rule.
*/
Expand Down
119 changes: 119 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13648,6 +13648,125 @@ mod tests {
minify_test(".foo { font-palette: --Custom; }", ".foo{font-palette:--Custom}");
}

#[test]
fn test_font_feature_values() {
// https://github.com/clagnut/TODS/blob/e693d52ad411507b960cf01a9734265e3efab102/tods.css#L116-L142
minify_test(
r#"
@font-feature-values "Fancy Font Name" {
@styleset { cursive: 1; swoopy: 7 16; }
@character-variant { ampersand: 1; capital-q: 2; }
@stylistic { two-story-g: 1; straight-y: 2; }
@swash { swishy: 1; flowing: 2; }
@ornaments { clover: 1; fleuron: 2; }
@annotation { circled: 1; boxed: 2; }
}
"#,
r#"@font-feature-values Fancy Font Name{@styleset{cursive:1;swoopy:7 16}@character-variant{ampersand:1;capital-q:2}@stylistic{two-story-g:1;straight-y:2}@swash{swishy:1;flowing:2}@ornaments{clover:1;fleuron:2}@annotation{circled:1;boxed:2}}"#,
);

// https://github.com/Sorixelle/srxl.me/blob/4eb4f4a15cb2d21356df24c096d6a819cfdc1a99/public/fonts/inter/inter.css#L201-L222
minify_test(
r#"
@font-feature-values "Inter", "Inter var", "Inter var experimental" {
@styleset {
open-digits: 1;
disambiguation: 2;
curved-r: 3;
disambiguation-without-zero: 4;
}

@character-variant {
alt-one: 1;
open-four: 2;
open-six: 3;
open-nine: 4;
lower-l-with-tail: 5;
curved-lower-r: 6;
german-double-s: 7;
upper-i-with-serif: 8;
flat-top-three: 9;
upper-g-with-spur: 10;
single-storey-a: 11;
}
}
"#,
r#"@font-feature-values Inter,Inter var,Inter var experimental{@styleset{open-digits:1;disambiguation:2;curved-r:3;disambiguation-without-zero:4}@character-variant{alt-one:1;open-four:2;open-six:3;open-nine:4;lower-l-with-tail:5;curved-lower-r:6;german-double-s:7;upper-i-with-serif:8;flat-top-three:9;upper-g-with-spur:10;single-storey-a:11}}"#,
);

// https://github.com/MihailJP/Inconsolata-LGC/blob/7c53cf455787096c93d82d9a51018f12ec39a6e9/Inconsolata-LGC.css#L65-L91
minify_test(
r#"
@font-feature-values "Inconsolata LGC" {
@styleset {
alternative-umlaut: 1;
}
@character-variant {
zero-plain: 1 1;
zero-dotted: 1 2;
zero-longslash: 1 3;
r-with-serif: 2 1;
eng-descender: 3 1;
eng-uppercase: 3 2;
dollar-open: 4 1;
dollar-oldstyle: 4 2;
dollar-cifrao: 4 2;
ezh-no-descender: 5 1;
ezh-reversed-sigma: 5 2;
triangle-text-form: 6 1;
el-with-hook-old: 7 1;
qa-enlarged-lowercase: 8 1;
qa-reversed-p: 8 2;
che-with-hook: 9 1;
che-with-hook-alt: 9 2;
ge-with-hook: 10 1;
ge-with-hook-alt: 10 2;
ge-with-stroke-and-descender: 11 1;
}
}
"#,
r#"@font-feature-values Inconsolata LGC{@styleset{alternative-umlaut:1}@character-variant{zero-plain:1 1;zero-dotted:1 2;zero-longslash:1 3;r-with-serif:2 1;eng-descender:3 1;eng-uppercase:3 2;dollar-open:4 1;dollar-oldstyle:4 2;dollar-cifrao:4 2;ezh-no-descender:5 1;ezh-reversed-sigma:5 2;triangle-text-form:6 1;el-with-hook-old:7 1;qa-enlarged-lowercase:8 1;qa-reversed-p:8 2;che-with-hook:9 1;che-with-hook-alt:9 2;ge-with-hook:10 1;ge-with-hook-alt:10 2;ge-with-stroke-and-descender:11 1}}"#,
);

minify_test(
r#"
@font-feature-values "Fancy Font Name" {
@styleset { cursive: 1; swoopy: 7 16; }
@character-variant { ampersand: 1; capital-q: 2; }
}
"#,
r#"@font-feature-values Fancy Font Name{@styleset{cursive:1;swoopy:7 16}@character-variant{ampersand:1;capital-q:2}}"#,
);
minify_test(
r#"
@font-feature-values foo {
@swash { pretty: 0; pretty: 1; cool: 2; }
}
"#,
"@font-feature-values foo{@swash{pretty:1;cool:2}}",
);
minify_test(
r#"
@font-feature-values foo {
@swash { pretty: 1; }
@swash { cool: 2; }
}
"#,
"@font-feature-values foo{@swash{pretty:1;cool:2}}",
);
minify_test(
r#"
@font-feature-values foo {
@swash { pretty: 1; }
}
@font-feature-values foo {
@swash { cool: 2; }
}
"#,
"@font-feature-values foo{@swash{pretty:1;cool:2}}",
);
}

#[test]
fn test_page_rule() {
minify_test("@page {margin: 0.5cm}", "@page{margin:.5cm}");
Expand Down
Loading

0 comments on commit 4cffb66

Please sign in to comment.