Charles.Forsyth20060303a828770d19 years agoHistory
143 lines · 2.7 KB · Brainfuck
RawDownload
implement CSSparser; include "sys.m";	sys: Sys;include "string.m";	str: String;include "css.m";	css: CSS;	Stylesheet, Statement, Select, Value: import css;include "cssparser.m"; init(){	sys = load Sys Sys->PATH;	str = load String String->PATH;	css = load CSS CSS->PATH;	if (css == nil) {		sys->fprint(sys->fildes(2), "cssparser: cannot load %s: %r\n", CSS->PATH);		raise "fail:bad module";	}	css->init(1);} parse(s: string): list of (string, list of Decl){	(stylesheet, e) := css->parse(s);	if (stylesheet == nil) {		warning("error parsing stylesheet: " + e);		return nil;	}	rules, r: list of (string, list of Decl);	for (stl := stylesheet.statements; stl != nil; stl = tl stl) {		pick st := hd stl {		Ruleset =>			rules = ruleset2rule(st, rules);		}	}	for (; rules != nil; rules = tl rules)		r = hd rules :: r;	return r;} ruleset2rule(statement: ref Statement.Ruleset, onto: list of (string, list of Decl)): list of (string, list of Decl){	d := makedecls(statement.decls);		names: list of string;	for (sels := statement.selectors; sels != nil; sels = tl sels) {		csel := hd sels;		if (len csel != 1) {			warning("context-specific selectors not allowed");			continue;		}		(nil, l) := hd csel;		if ((name := selector2name(l)) != nil)			names = name :: names;	}	for (; names != nil; names = tl names)		onto = (hd names, d) :: onto;		return onto;} makedecls(decls: list of ref CSS->Decl): list of Decl{	d: list of Decl;	for (; decls != nil; decls = tl decls) {		nd: Decl;		nd.name = (hd decls).property;		nd.important = (hd decls).important;		s := "";		for (vals := (hd decls).values; vals != nil; vals = tl vals) {			vs: string;			pick v := hd vals {			Percentage =>				vs = v.value + "%";			String or			Number or			Url or			Unicoderange =>				vs = v.value;			Hexcolour =>				vs = rgb2s(v.rgb);			RGB =>				vs = rgb2s(v.rgb);			Ident =>				vs = v.name;			Unit =>				vs = v.value + v.units;			}			if (s != nil)				s[len s] = (hd vals).sep;			s += vs;		}		nd.val = s;		d = nd :: d;	}	return d;} rgb2s(rgb: (int, int, int)): string{	(r, g, b) := rgb;	return sys->sprint("#%.2x%.2x%.2x", r, g, b);} warning(s: string){	sys->fprint(sys->fildes(2), "cssparser: %s\n", s);} selector2name(sel: list of ref Select): string{	tag: string;	class: string;	pseudo: string; 	for (; sel != nil; sel = tl sel) {		pick v := hd sel {		Element =>			tag = v.name;		Class =>			class = "." + v.name;		Pseudo =>			class = ":" + v.name;		* =>			warning("unknown selector type " + string tagof(hd sel));		}	}	return tag + class + pseudo;} parsedecl(s: string): list of Decl{	if (s == nil)		return nil;	(d, e) := css->parsedecl(s);	if (d == nil) {		warning(e);		return nil;	}	return makedecls(d);}