Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit d5d33d8

Browse files
author
ijoshua
committed
Documenting iteration protocol. Rearranging parse.py methods. Some typographic changes.
git-svn-id: http://css-py.googlecode.com/svn/trunk@7 255e942d-184c-0410-a885-59fc1719c42d
1 parent 14bd5fd commit d5d33d8

File tree

4 files changed

+112
-77
lines changed

4 files changed

+112
-77
lines changed

css/__init__.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# -*- coding: utf-8 -*-
2-
# CSS package
3-
# Author: Joshua E Cook <jcook at particleweb dot com>
2+
'''
3+
CSS package
4+
Author: Joshua E Cook <jcook at particleweb dot com>
5+
6+
Examples:
7+
8+
from css.parse import parse
9+
10+
data = """p { color: red; font-size: 12pt }
11+
p:first-letter { color: green; font-size: 200% }
12+
p:first-line { color: blue }"""
13+
14+
for rule in parse(data):
15+
print rule
16+
# or do something with each rule
17+
18+
'''
19+
20+
__all__ = ('csslex', 'cssyacc', 'css', 'serialize', 'parse')
21+
422

5-
__all__ = ('csslex', 'cssyacc','css', 'serialize')

css/css.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
'Media', 'Import', 'Stylesheet')
1313

1414
class SyntaxObject(object):
15+
'''
16+
An abstract type of syntactic construct.
17+
'''
1518
def __str__(self):
1619
return self.datum(str)
1720

@@ -145,6 +148,9 @@ def datum(self, serializer):
145148
class Ruleset(SyntaxObject):
146149
'''
147150
A list of declarations for a given list of selectors.
151+
152+
When iterating, yields each of its declarations in order of
153+
their appearance.
148154
'''
149155
def __init__(self, selectors, declarations=None):
150156
self.selectors = selectors
@@ -188,6 +194,9 @@ class Page(SyntaxObject):
188194
A @page rule statement containing a list of declarations.
189195
190196
The rule may have a pseudo-page specifer like :left or :right.
197+
198+
When iterating, yields each of its declarations in order of
199+
their appearance.
191200
'''
192201
def __init__(self, declarations=None, pseudo_page=None):
193202
self.declarations = declarations or list()
@@ -216,6 +225,9 @@ def datum(self, serializer):
216225
class Media(SyntaxObject):
217226
'''
218227
An @media rule statement containing a list of rulesets.
228+
229+
When iterating, yields each of its rulesets in order of
230+
their appearance.
219231
'''
220232
def __init__(self, media_types, rulesets=None):
221233
self.media_types = media_types
@@ -268,6 +280,9 @@ class Stylesheet(SyntaxObject):
268280
269281
May have an optional list of import rules and an optional
270282
character set specification.
283+
284+
When iterating, yields each of its rules, including @import
285+
and @charset rules, in order of their appearance.
271286
'''
272287
def __init__(self, statements, imports=None, charset=None):
273288
self.statements = statements

css/parse.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from urllib2 import urlopen
55
from codecs import EncodedFile
66
import css, csslex, cssyacc
7-
from serialize import serialize
87
from uri import uri
98

109
__all__ = ('parse','export')
@@ -14,26 +13,26 @@ def parse(data):
1413
parser.lexer = csslex.lex()
1514
return parser.parse(data, debug=True)
1615

17-
def export(stylesheet):
18-
if stylesheet.charset:
19-
print serialize(stylesheet.charset, unicode)
20-
21-
for i in stylesheet.imports:
22-
url = i.source
16+
def export(base, stylesheet, recursive=False):
17+
def recur(rule):
18+
url = rule.source
2319
if isinstance(url, css.Uri):
2420
url = url.url
25-
importuri = uri.resolve(fileuri, url)
26-
importfile = urlopen(importuri)
27-
export(parse(importfile.read()))
21+
url = uri.resolve(base, url)
22+
export(base, parse(urlopen(url).read()))
23+
24+
for rule in stylesheet:
25+
if recursive and isinstance(rule, css.Import):
26+
recur(rule)
27+
else:
28+
print rule.datum(unicode)
2829

29-
for s in stylesheet.statements:
30-
print serialize(s, unicode)
3130

3231
def main(fileuri, options):
3332
inputfile = urlopen(fileuri)
3433

3534
stylesheet = parse(inputfile.read())
36-
export(stylesheet)
35+
export(fileuri, stylesheet)
3736

3837

3938
if '__main__' == __name__:

css/serialize.py

Lines changed: 65 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,108 +15,112 @@
1515
# serialize(), and possibly a new serialize_<type>()
1616
# method. (The data types of CSS are finite and the number
1717
# relatively small, so this should be a rare occassion.)
18+
#
19+
# Each serializer method takes a `printer` argument,
20+
# which should be a function that returns a serialized
21+
# value for objects of builtin types.
1822

19-
def serialize(obj, serializer):
23+
def serialize(obj, printer=str):
2024
if isinstance(obj, css.Hexcolor):
21-
return serialize_Hexcolor(obj, serializer)
25+
return serialize_Hexcolor(obj, printer)
2226
elif isinstance(obj, css.Function):
23-
return serialize_Function(obj, serializer)
27+
return serialize_Function(obj, printer)
2428
elif isinstance(obj, css.Uri):
25-
return serialize_Uri(obj, serializer)
29+
return serialize_Uri(obj, printer)
2630
elif isinstance(obj, css.String):
27-
return serialize_String(obj, serializer)
31+
return serialize_String(obj, printer)
2832
elif isinstance(obj, css.Ident):
29-
return serialize_Ident(obj, serializer)
33+
return serialize_Ident(obj, printer)
3034
elif isinstance(obj, css.Term):
31-
return serialize_Term(obj, serializer)
35+
return serialize_Term(obj, printer)
3236
elif isinstance(obj, css.Declaration):
33-
return serialize_Declaration(obj, serializer)
37+
return serialize_Declaration(obj, printer)
3438
elif isinstance(obj, css.Ruleset):
35-
return serialize_Ruleset(obj, serializer)
39+
return serialize_Ruleset(obj, printer)
3640
elif isinstance(obj, css.Charset):
37-
return serialize_Charset(obj, serializer)
41+
return serialize_Charset(obj, printer)
3842
elif isinstance(obj, css.Page):
39-
return serialize_Page(obj, serializer)
43+
return serialize_Page(obj, printer)
4044
elif isinstance(obj, css.Media):
41-
return serialize_Media(obj, serializer)
45+
return serialize_Media(obj, printer)
4246
elif isinstance(obj, css.Import):
43-
return serialize_Import(obj, serializer)
47+
return serialize_Import(obj, printer)
4448
elif isinstance(obj, css.Stylesheet):
45-
return serialize_Stylesheet(obj, serializer)
49+
return serialize_Stylesheet(obj, printer)
4650
else:
47-
return serializer(obj)
51+
return printer(obj)
4852

49-
def serialize_Hexcolor(obj, serializer):
50-
return serializer('#') + serializer(obj.value)
53+
def serialize_Hexcolor(obj, printer):
54+
return printer('#') + printer(obj.value)
5155

52-
def serialize_Function(obj, serializer):
53-
return serializer(obj.name) + serializer('(') + serializer(obj.parameters) + serializer(')')
56+
def serialize_Function(obj, printer):
57+
return printer(obj.name) + printer('(') + printer(obj.parameters) + printer(')')
5458

55-
def serialize_Uri(obj, serializer):
56-
return serializer('url(') + serializer(obj.url) + serializer(')')
59+
def serialize_Uri(obj, printer):
60+
return printer('url(') + printer(obj.url) + printer(')')
5761

58-
def serialize_String(obj, serializer):
59-
s = serializer(obj.value.replace(u'"', u'\\"'))
60-
return serializer('"') + s + serializer('"')
62+
def serialize_String(obj, printer):
63+
s = printer(obj.value.replace(u'"', u'\\"'))
64+
return printer('"') + s + printer('"')
6165

62-
def serialize_Ident(obj, serializer):
63-
return serializer(obj.name)
66+
def serialize_Ident(obj, printer):
67+
return printer(obj.name)
6468

65-
def serialize_Term(obj, serializer):
66-
s = serializer(obj.value)
69+
def serialize_Term(obj, printer):
70+
s = printer(obj.value)
6771
if obj.unary_operator:
68-
s = serializer(obj.unary_operator) + s
72+
s = printer(obj.unary_operator) + s
6973
return s
7074

71-
def serialize_Declaration(obj, serializer):
72-
s = serialize_Ident(obj.property, serializer)
73-
s += serializer(':') + serializer(obj.value)
75+
def serialize_Declaration(obj, printer):
76+
s = serialize_Ident(obj.property, printer)
77+
s += printer(':') + printer(obj.value)
7478
if obj.important:
75-
s += serializer(' !important')
79+
s += printer(' !important')
7680
return s
7781

78-
def serialize_Ruleset(obj, serializer):
79-
s = serialize_Selector_group(obj.selectors, serializer)
80-
s += serialize_Declaration_block(obj.declarations, serializer)
82+
def serialize_Ruleset(obj, printer):
83+
s = serialize_Selector_group(obj.selectors, printer)
84+
s += serialize_Declaration_block(obj.declarations, printer)
8185
return s
8286

83-
def serialize_Charset(obj, serializer):
84-
return serializer('@charset ') + serializer(obj.encoding) + serializer(';')
87+
def serialize_Charset(obj, printer):
88+
return printer('@charset ') + printer(obj.encoding) + printer(';')
8589

86-
def serialize_Page(obj, serializer):
87-
s = serializer('@page')
90+
def serialize_Page(obj, printer):
91+
s = printer('@page')
8892
if obj.pseudo_page:
89-
s += serialize_Pseudo(obj.pseudo_page, serializer)
90-
s += serialize_Declaration_block(obj.declarations, serializer)
93+
s += serialize_Pseudo(obj.pseudo_page, printer)
94+
s += serialize_Declaration_block(obj.declarations, printer)
9195
return s
9296

93-
def serialize_Media(obj, serializer):
94-
s = serializer('@media ')
95-
s += serializer(',').join((serializer(x) for x in obj.media_types))
96-
s += serializer('{') + serializer('\n').join([serialize_Ruleset(x, serializer) for x in obj.rulesets]) + serializer('}')
97+
def serialize_Media(obj, printer):
98+
s = printer('@media ')
99+
s += printer(',').join((printer(x) for x in obj.media_types))
100+
s += printer('{') + printer('\n').join([serialize_Ruleset(x, printer) for x in obj.rulesets]) + printer('}')
97101
return s
98102

99-
def serialize_Import(obj, serializer):
100-
s = serializer('@import ') + serialize(obj.source, serializer)
103+
def serialize_Import(obj, printer):
104+
s = printer('@import ') + serialize(obj.source, printer)
101105
if obj.media_types:
102-
s += serializer(' ') + serializer(',').join((serializer(x) for x in obj.media_types))
103-
s += serializer(';')
106+
s += printer(' ') + printer(',').join((printer(x) for x in obj.media_types))
107+
s += printer(';')
104108
return s
105109

106-
def serialize_Stylesheet(obj, serializer):
107-
s = serializer('')
110+
def serialize_Stylesheet(obj, printer):
111+
s = printer('')
108112
if obj.charset:
109-
s += serialize_Charset(obj.charset, serializer) + serializer('\n')
113+
s += serialize_Charset(obj.charset, printer) + printer('\n')
110114
if obj.imports:
111-
s += serializer('\n').join((serialize_Import(x, serializer) for x in obj.imports)) + serializer('\n')
112-
s += serializer('\n').join((serialize(x, serializer) for x in obj.statements))
115+
s += printer('\n').join((serialize_Import(x, printer) for x in obj.imports)) + printer('\n')
116+
s += printer('\n').join((serialize(x, printer) for x in obj.statements))
113117
return s
114118

115-
def serialize_Pseudo(obj, serializer):
116-
return serializer(':') + serialize_Ident(obj, serializer)
119+
def serialize_Pseudo(obj, printer):
120+
return printer(':') + serialize_Ident(obj, printer)
117121

118-
def serialize_Selector_group(selectors, serializer):
119-
return serializer(',').join((serializer(x) for x in selectors))
122+
def serialize_Selector_group(selectors, printer):
123+
return printer(',').join((printer(x) for x in selectors))
120124

121-
def serialize_Declaration_block(declarations, serializer):
122-
return serializer('{') + serializer(';').join((serialize_Declaration(x, serializer) for x in declarations)) + serializer('}')
125+
def serialize_Declaration_block(declarations, printer):
126+
return printer('{') + printer(';').join((serialize_Declaration(x, printer) for x in declarations)) + printer('}')

0 commit comments

Comments
 (0)