Show More
@@ -32,28 +32,33 b' def parsestring(s, quoted=True):' | |||||
32 |
|
32 | |||
33 | class templater(object): |
|
33 | class templater(object): | |
34 | def __init__(self, mapfile, filters={}, defaults={}): |
|
34 | def __init__(self, mapfile, filters={}, defaults={}): | |
|
35 | self.mapfile = mapfile or 'template' | |||
35 | self.cache = {} |
|
36 | self.cache = {} | |
36 | self.map = {} |
|
37 | self.map = {} | |
37 | self.base = os.path.dirname(mapfile) |
|
38 | self.base = (mapfile and os.path.dirname(mapfile)) or '' | |
38 | self.filters = filters |
|
39 | self.filters = filters | |
39 | self.defaults = defaults |
|
40 | self.defaults = defaults | |
40 |
|
41 | |||
|
42 | if not mapfile: | |||
|
43 | return | |||
41 | i = 0 |
|
44 | i = 0 | |
42 | for l in file(mapfile): |
|
45 | for l in file(mapfile): | |
|
46 | l = l.rstrip('\r\n') | |||
43 | i += 1 |
|
47 | i += 1 | |
44 | m = re.match(r'(\S+)\s*=\s*(["\'].*["\'])$', l) |
|
48 | if l.startswith('#') or not l.strip(): continue | |
|
49 | m = re.match(r'([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$', l) | |||
45 | if m: |
|
50 | if m: | |
46 | try: |
|
51 | key, val = m.groups() | |
47 | s = m.group(2) |
|
52 | if val[0] in "'\"": | |
48 | self.cache[m.group(1)] = parsestring(s) |
|
53 | try: | |
49 | except SyntaxError, inst: |
|
54 | self.cache[key] = parsestring(val) | |
50 |
|
|
55 | except SyntaxError, inst: | |
|
56 | raise SyntaxError('%s:%s: %s' % | |||
|
57 | (mapfile, i, inst.args[0])) | |||
|
58 | else: | |||
|
59 | self.map[key] = os.path.join(self.base, val) | |||
51 | else: |
|
60 | else: | |
52 | m = re.match(r'(\S+)\s*=\s*(\S+)', l) |
|
61 | raise SyntaxError(_("%s:%s: parse error") % (mapfile, i)) | |
53 | if m: |
|
|||
54 | self.map[m.group(1)] = os.path.join(self.base, m.group(2)) |
|
|||
55 | else: |
|
|||
56 | raise LookupError(_("unknown map entry '%s'") % l) |
|
|||
57 |
|
62 | |||
58 | def __contains__(self, key): |
|
63 | def __contains__(self, key): | |
59 | return key in self.cache |
|
64 | return key in self.cache | |
@@ -64,7 +69,11 b' class templater(object):' | |||||
64 | try: |
|
69 | try: | |
65 | tmpl = self.cache[t] |
|
70 | tmpl = self.cache[t] | |
66 | except KeyError: |
|
71 | except KeyError: | |
67 | tmpl = self.cache[t] = file(self.map[t]).read() |
|
72 | try: | |
|
73 | tmpl = self.cache[t] = file(self.map[t]).read() | |||
|
74 | except IOError, inst: | |||
|
75 | raise IOError(inst.args[0], _('template file %s: %s') % | |||
|
76 | (self.map[t], inst.args[1])) | |||
68 | return self.template(tmpl, self.filters, **m) |
|
77 | return self.template(tmpl, self.filters, **m) | |
69 |
|
78 | |||
70 | template_re = re.compile(r"[#{]([a-zA-Z_][a-zA-Z0-9_]*)" |
|
79 | template_re = re.compile(r"[#{]([a-zA-Z_][a-zA-Z0-9_]*)" | |
@@ -76,10 +85,15 b' class templater(object):' | |||||
76 | while tmpl: |
|
85 | while tmpl: | |
77 | m = self.template_re.search(tmpl) |
|
86 | m = self.template_re.search(tmpl) | |
78 | if m: |
|
87 | if m: | |
79 |
start = m.s |
|
88 | start, end = m.span(0) | |
|
89 | s, e = tmpl[start], tmpl[end - 1] | |||
|
90 | key = m.group(1) | |||
|
91 | if ((s == '#' and e != '#') or (s == '{' and e != '}')): | |||
|
92 | raise SyntaxError(_("'%s'/'%s' mismatch expanding '%s'") % | |||
|
93 | (s, e, key)) | |||
80 | if start: |
|
94 | if start: | |
81 | yield tmpl[:start] |
|
95 | yield tmpl[:start] | |
82 |
v = map.get( |
|
96 | v = map.get(key, "") | |
83 | v = callable(v) and v(**map) or v |
|
97 | v = callable(v) and v(**map) or v | |
84 |
|
98 | |||
85 | format = m.group(2) |
|
99 | format = m.group(2) | |
@@ -98,7 +112,7 b' class templater(object):' | |||||
98 | v = filters[f](v) |
|
112 | v = filters[f](v) | |
99 |
|
113 | |||
100 | yield v |
|
114 | yield v | |
101 |
tmpl = tmpl[ |
|
115 | tmpl = tmpl[end:] | |
102 | else: |
|
116 | else: | |
103 | yield tmpl |
|
117 | yield tmpl | |
104 | break |
|
118 | break | |
@@ -153,9 +167,9 b' common_filters = {' | |||||
153 | "addbreaks": nl2br, |
|
167 | "addbreaks": nl2br, | |
154 | "age": age, |
|
168 | "age": age, | |
155 | "date": lambda x: util.datestr(x), |
|
169 | "date": lambda x: util.datestr(x), | |
|
170 | "domain": domain, | |||
156 | "escape": lambda x: cgi.escape(x, True), |
|
171 | "escape": lambda x: cgi.escape(x, True), | |
157 | "firstline": (lambda x: x.splitlines(1)[0]), |
|
172 | "firstline": (lambda x: x.splitlines(1)[0]), | |
158 | "domain": domain, |
|
|||
159 | "obfuscate": obfuscate, |
|
173 | "obfuscate": obfuscate, | |
160 | "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"), |
|
174 | "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"), | |
161 | "person": person, |
|
175 | "person": person, |
General Comments 0
You need to be logged in to leave comments.
Login now