MCPcopy Create free account
hub / github.com/csskit/csskit / parse_spec_properties

Function parse_spec_properties

crates/csskit_spec_generator/src/spec_parser.rs:20–77  ·  view source on GitHub ↗

Parse property definitions from a CSS spec HTML

(html: &str)

Source from the content-addressed store, hash-verified

18
19/// Parse property definitions from a CSS spec HTML
20pub fn parse_spec_properties(html: &str) -> Result<Vec<PropertyDefinition>> {
21 let document = Html::parse_document(html);
22 let table_selector = Selector::parse("table.propdef, table.descdef").unwrap();
23 let tr_selector = Selector::parse("tr").unwrap();
24 let th_selector = Selector::parse("th").unwrap();
25 let td_selector = Selector::parse("td").unwrap();
26
27 let mut properties = Vec::new();
28
29 for table in document.select(&table_selector) {
30 let mut prop_data: HashMap<String, String> = HashMap::new();
31 for row in table.select(&tr_selector) {
32 let headers: Vec<_> = row.select(&th_selector).collect();
33 let data: Vec<_> = row.select(&td_selector).collect();
34
35 if headers.len() == 1 && data.len() == 1 {
36 let key = headers[0].text().collect::<String>().trim().to_lowercase();
37 let key = key.trim_end_matches(':').to_string();
38 let value = data[0].text().collect::<String>().trim().to_string();
39 prop_data.insert(key, value);
40 }
41 }
42
43 if let Some(names) = prop_data.get("name") {
44 for name in names.split(',') {
45 let name = name.trim().to_string();
46
47 // Skip if:
48 // - this has "new values" - it means it's extending an existing property
49 // - this has "for" - it means it's for an @-rule and not a general style value
50 // TODO: We should be smarter about these, but for now we can simply skip
51 if prop_data.contains_key("new values") || prop_data.contains_key("for") {
52 continue;
53 }
54
55 if let Some(value) = prop_data.get("value") {
56 properties.push(PropertyDefinition {
57 name: name.clone(),
58 value: value.clone(),
59 initial: prop_data.get("initial").cloned().unwrap_or_default(),
60 applies_to: prop_data.get("applies to").cloned().unwrap_or_default(),
61 inherited: prop_data.get("inherited").cloned().unwrap_or_default(),
62 percentages: prop_data.get("percentages").cloned().unwrap_or_default(),
63 animation_type: prop_data
64 .get("animation type")
65 .or_else(|| prop_data.get("animatable"))
66 .cloned(),
67 computed_value: prop_data.get("computed value").or_else(|| prop_data.get("computed")).cloned(),
68 canonical_order: prop_data.get("canonical order").cloned(),
69 logical_property_group: prop_data.get("logical property group").cloned(),
70 });
71 }
72 }
73 }
74 }
75
76 Ok(properties)
77}

Callers 3

process_single_versionFunction · 0.85

Calls 6

collectMethod · 0.80
cloneMethod · 0.80
parseFunction · 0.50
lenMethod · 0.45
insertMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected