Selector-Scope

Hier muss ich wahrscheinlich erst einmal klären, was ich genau damit meine:

Meine CSS-Dateien sehen oft folgendermaßen aus:

Code:#hauptID { ... } #hauptID .subClass { ... } #hauptID h1 { ... }
Man sieht, dass sich "#hauptID" oft wiederholt und nun habe ich mir gedacht:
Hey, du bist doch faul... warum kann man diese Regeln nicht einfach zusammenfassen und nur einmal "#hauptID" schreiben?
Gedacht - getan:

Syntax

Hier habe ich nicht lange überlegen müssen - geschweifte Klammern zum Zusammenfassen sind schon im CSS vorhanden... übernehmen wir das. So würde das obige Beispiel folgendermaßen aussehen:

Code:@parser scope #hauptID { { ... } .subClass { ... } h1 { ... } }
Jetzt haben wir aber in CSS natürlich noch die Unterscheidung zwischen "#ID .class" und "#ID.class" - also der Tatsache ob zwischen den einzelnen Selectoren ein Leerzeichen ist oder nicht. Wie kommt das hier zum Tragen?
Realtiv einfach - ABER leider nicht ganz intuitiv:

Wenn am Ende des Selektors das ansonsten verbotene Zeichen "|" (Pipe) steht wird der Inhalt des Scopes direkt an den Selektor angehängt. D.h. die beiden Beispiele von oben würde so aussehen:

Code: @parser scope #ID { .class { ... } } /* und */ @parser scope #ID|{ .class { ... } }

Natürlich kann man das Ganze auch schachteln und auch komplette Dateien in einen Scope packen:

Code:@parser scope #hauptID { @parser include(dateiname); }
- dafür müssen wir nur in unserer $this->parse-Funktion das Einfügen der Dateien vor dem Auflösen des Scopes machen.

Realisierung

Dieses Problem hat mich völlig überrascht: es ging so einfach:

Code: private function resolveScope($content){ return preg_replace_callback('/(?:\r?\n)?[ \t]*@parser\s+scope\s+([^{}]+)({(?:[^{}"\']+|' . self::$strRegExp . '|(?2))*})[ \t]*(?:\r?\n)?/', array($this, "parseScopeRegExpWrapper"), $content); } private function parseScopeRegExpWrapper($match){ $name = preg_replace('/\s+$/', "", $match[1]); if ($name{strlen($name) - 1} == "|") $name = substr($name, 0, -1); else $name .= " "; // hier war in der letzten Version ein Fehler: mit "," separierte Werte wurden nicht beachtet $content = preg_replace('/[ \t]*([^{}\n\r,]*)({(?:[^{}"\']+|' . self::$strRegExp . ')*}|,\s*)/', $name . "$1$2", $this->resolveScope( preg_replace('/^{|[ \t]*}$/', "", $match[2]) ) ); return $content; }