parse method
Implementation
void parse(String source) {
if (source.trim().isEmpty) return;
final String cleaned = source.replaceAll(RegExp(r"/\*.*?\*/", dotAll: true), "");
int index = 0;
int guard = 0;
while (index < cleaned.length && guard < 20000) {
guard++;
final int brace = cleaned.indexOf("{", index);
if (brace < 0) break;
final int end = cleaned.indexOf("}", brace);
if (end < 0) break;
final String selectorText = cleaned.substring(index, brace).trim();
final String body = cleaned.substring(brace + 1, end);
index = end + 1;
if (selectorText.startsWith("@")) {
if (selectorText.toLowerCase().startsWith("@font-face")) {
final Map<String, String> declarations = _declarations(body);
final String family = (declarations["font-family"] ?? "").replaceAll("\"", "").replaceAll("'", "").trim();
if (family.isNotEmpty) fontFaces[family.toLowerCase()] = declarations;
}
continue;
}
final Map<String, String> declarations = _declarations(body);
if (declarations.isEmpty) continue;
for (final String selector in selectorText.split(",")) {
final List<UEpubSelectorPart> parts = <UEpubSelectorPart>[];
int specificity = 0;
for (final String piece in selector.trim().split(RegExp(r"\s+"))) {
if (piece.isEmpty || piece == ">" || piece == "+" || piece == "~") continue;
final String withoutPseudo = piece.split(":").first;
final RegExpMatch? match = RegExp(r"^([A-Za-z][A-Za-z0-9]*|\*)?(?:#([-\w]+))?(?:\.([-\w]+))?").firstMatch(withoutPseudo);
if (match == null) continue;
final String tag = (match.group(1) ?? "").toLowerCase();
final String id = match.group(2) ?? "";
final String className = match.group(3) ?? "";
if (tag.isEmpty && id.isEmpty && className.isEmpty) continue;
if (id.isNotEmpty) specificity += 100;
if (className.isNotEmpty) specificity += 10;
if (tag.isNotEmpty && tag != "*") specificity += 1;
parts.add(UEpubSelectorPart(tag: tag, className: className, id: id));
}
if (parts.isEmpty) continue;
rules.add(UEpubRule(parts, declarations, specificity));
}
}
}