csslib icon indicating copy to clipboard operation
csslib copied to clipboard

how to use this lib to read properties and values from a CSS Declaration and store it in a Map

Open insinfo opened this issue 1 year ago • 2 comments

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);
}

insinfo avatar Mar 08 '23 18:03 insinfo

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 avatar Sep 01 '23 11:09 PresKhaled

@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?

fabricio-godoi avatar Jun 22 '24 22:06 fabricio-godoi