Improve CSS link styling priorities - Now all protocols except `http*` are prioritized over domains and extensions for choosing a link styling icon.
Zoom zoomrmc+git@gmail.com
Wed, 20 Sep 2023 14:55:00 +0400
2 files changed,
34 insertions(+),
36 deletions(-)
M
src/hastyscribe.nim
→
src/hastyscribe.nim
@@ -366,19 +366,21 @@ block linkStyles: # Check links
# Init with `document-top`: it's added to the document later with `utils.add_jump_to_top_links` var linkHrefs: CritBitTree[void] = ["#document-top"].toCritBitTree() for link in html.querySelectorAll("a[href]"): linkHrefs.incl(link.attr("href")) - var linkRulesSet: tuple[exts, doms, protos: CritBitTree[void]] + var linkRulesSets: array[CssSelPriority, CritBitTree[void]] for href in linkHrefs.keys: block search: - for (val, rule) in css_rules_links.extensions: - if href.endsWith(val): linkRulesSet.exts.incl(rule); break search - for (val, rule) in css_rules_links.domains: - if href.contains(val): linkRulesSet.doms.incl(rule); break search - for (val, rule) in css_rules_links.protocols: - if href.startsWith(val): linkRulesSet.protos.incl(rule); break search - # Adding to rules in reversed order of precedence - for rule in linkRulesSet.protos.keys: rules.add(rule) - for rule in linkRulesSet.doms.keys: rules.add(rule) - for rule in linkRulesSet.exts.keys: rules.add(rule) + for prio in countDown(csspProto, csspLowProto): # Traverse rules in order of decreasing priority + for (val, rule) in css_rules_links[prio]: + let match = + case prio: + of csspLowProto, csspProto: href.startsWith(val) + of csspDom: href.contains(val) + of csspExt: href.endsWith(val) + else: false + if match: linkRulesSets[prio].incl(rule); break search + # Adding rules in order of increasing priority + for prio in CssSelPriority: + for rule in linkRulesSets[prio]: rules.add(rule) rules.join("\n").style_tag()
M
src/hastyscribepkg/consts.nim
→
src/hastyscribepkg/consts.nim
@@ -2,12 +2,15 @@ import std/[pegs]
from std/strutils import strip type - Rule = tuple[selValue: string, definition: string] + CssSelPriority* = enum csspIgnore, csspLowProto, csspDom, csspExt, csspProto + Rule = tuple[selValue: string, definition: string] ## CSS selector rule Rules = seq[Rule] -proc parseLinkRules(css: string): tuple[extensions, domains, protocols: Rules] = +const CssSelLowPriorityProtos = ["http", "https"] + +proc parseLinkRules(css: string): array[CssSelPriority, Rules] = ## Parses a CSS in format adgering to `hastystyles.links.css`: - ## Each line is a link styling with a single selector of + ## Each line is a link styling with a single selector of ## `^=` / `*=` / `$=` and a `:before` # TODO: - Support multiple selectors for a styling: # either in form of "a[href$='.zip']:before, a[href$='.gz']:before"@@ -19,14 +22,8 @@ definition <- 'a[href' op '\'' val '\']:before' \s* @ (\n / $)
op <- ['^*$'] '=' val <- [a-z0-9-.#]+ """ - type - CssSelectorKind = enum - selUnknown = "", selEnds = "$=", selContains = "*=", selStarts = "^=" - RuleAttrs = object - kind: CssSelectorKind = selUnknown - selValue: string = "" - var extensions, domains, protocols: Rules - var attrs = default(RuleAttrs) + var attr: tuple[kind: CssSelPriority; selValue: string] + var linkRules: array[CssSelPriority, Rules] let parse = peg_linkstyle_def.eventParser: pkNonTerminal: leave:@@ -35,25 +32,24 @@ if length > 0:
case p.nt.name of "op": # debugEcho " op:", s.substr(start, start+1) - attrs.kind = case s[start]: - of '$': selEnds - of '*': selContains - of '^': selStarts - else: selUnknown - of "val": attrs.selValue = s.substr(start, start+length-1) + attr.kind = case s[start]: + of '$': csspExt # endsWiths + of '*': csspDom # contains + of '^': csspProto # startsWith + else: csspIgnore + of "val": + attr.selValue = s.substr(start, start+length-1) + if attr.kind == csspProto and attr.selValue in CssSelLowPriorityProtos: + attr.kind = csspLowProto of "definition": let definition = s.substr(start, start+length-1).strip() - if attrs.kind == selUnknown or attrs.selValue == "" or definition == "": + if attr.kind == csspIgnore or attr.selValue == "" or definition == "": echo "Error parsing `stylesheet_links`!"; quit(1) - case attrs.kind: - of selEnds: extensions.add((attrs.selValue, definition)) - of selContains: domains.add((attrs.selValue, definition)) - of selStarts: protocols.add((attrs.selValue, definition)) - else: doAssert(false) # already checked - attrs = default(RuleAttrs) + linkRules[attr.kind].add((attr.selValue, definition)) + attr = (csspLowProto, "") else: discard # parsed the file discard parse(css) - (extensions: extensions, domains: domains, protocols: protocols) + linkRules const