csslib
csslib copied to clipboard
how to use this lib to read properties and values from a CSS Declaration and store it in a Map
how to use this lib to read properties and values from a CSS Declaration and store it in a Map. I'm trying to use this lib to convert an SVG styled in a
import 'dart:io';
import 'package:csslib/visitor.dart';
import 'package:xml/xml.dart';
import 'package:csslib/parser.dart';
import 'package:csslib/parser.dart' as css;
extension ListToMap on List {
Map toMap() {
return Map.fromIterable(this, key: (v) => v[0], value: (v) => v[1]);
}
}
void main() {
// Load the SVG file
final svgData = File('.\\bin\\svg_with_style.svg').readAsStringSync();
// Parse the SVG file using the XML package
final document = XmlDocument.parse(svgData);
// Find the <style> element and extract the CSS rules
final XmlNode? styleTag = document.descendants
.firstWhere((node) => node is XmlElement && node.name.local == 'style');
if (styleTag != null) {
final cssRules = styleTag.text.trim();
//print('cssRules: $cssRules');
var stylesheet = parse(cssRules);
var allRules = stylesheet.topLevels
.where((s) => s is RuleSet)
.map((e) => e as RuleSet)
.toList();
// Remove the <style> element
//styleTag.remove();
// Apply the CSS rules to the appropriate elements
final elements = document.descendants.toList();
//print('elements: $elements');
for (final element in elements) {
final cssClass = element.getAttribute('class');
if (cssClass != null) {
// stylesheet.topLevels.where((e) => e.)
//print(stylesheet.toDebugString());
var elementRules = allRules.where((r) {
return r.selectorGroup != null
? r.selectorGroup!.selectors.where((s) {
return s.simpleSelectorSequences.where((ss) {
return ss.simpleSelector.name == cssClass;
}).isNotEmpty;
}).isNotEmpty
: false;
}).toList();
var properties =
elementRules.map((r) => r.declarationGroup.declarations.map((e) {
var dec = e as Declaration;
return dec.property;
}));
var values =
elementRules.map((r) => r.declarationGroup.declarations.map((e) {
var dec = e as Declaration;
return dec.value;
}));
print('role ${values}');
// Set the inline styles on the element
// cssRulesMap.forEach((property, value) {
// element.setAttribute(property, value);
// });
// Remove the class attribute
//element.removeAttribute('class');
}
}
}
// Save the modified SVG file
final output = document.toXmlString(pretty: true, indent: '\t');
File('.\\bin\\output.svg').writeAsStringSync(output);
}
The value of (declaration.term
) often returns null.
Map<String, dynamic> _getStylesOfSelectors(List<String> selectors, Iterable<visitor.StyleSheet?>? styleSheets) {
final Map<String, dynamic> styles = {}; // Results (styles).
if (styleSheets == null || styleSheets.length == 0) return styles;
// Collect the rules of the specified selectors from [styleSheets].
for (visitor.StyleSheet styleSheet in styleSheets.whereNotNull()) {
final List<visitor.RuleSet> rules = styleSheet.topLevels.whereType<visitor.RuleSet>().where((visitor.RuleSet ruleSet) {
if (ruleSet.selectorGroup == null) return false;
return (ruleSet.selectorGroup!.selectors.where(
(visitor.Selector selector) {
return (selector.simpleSelectorSequences.where(
(visitor.SimpleSelectorSequence simpleSelectorSequence) {
print('CLASS ${simpleSelectorSequence.simpleSelector.name}');
return selectors.contains(simpleSelectorSequence.simpleSelector.name);
},
).length >
0);
},
).length >
0);
}).toList();
// Collect all the styles of the specified selectors.
for (final visitor.RuleSet rule in rules) {
for (final visitor.TreeNode node in rule.declarationGroup.declarations) {
final visitor.Declaration declaration = (node as visitor.Declaration);
styles.addAll({
declaration.property: declaration.term,
});
}
}
}
return styles;
}
UPDATE
Replace declaration.term
with value
.
final String value = (declaration.expression as visitor.Expressions).expressions.fold(
'',
(String value, visitor.Expression expression) {
final visitor.LiteralTerm literalTerm = (expression as visitor.LiteralTerm);
return (value + literalTerm.text);
},
);
@PresKhaled thank you for the snippet, I was struggling to get the attributes as well.
Any chance of this snippet being part of the readme or some example?