Mercurial > hg
comparison mercurial/templater.py @ 1896:f8f818a04f5b
move hgweb template code out to templater
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Sun, 26 Feb 2006 12:59:28 -0800 |
parents | |
children | 58b6784cf9f1 |
comparison
equal
deleted
inserted
replaced
1800:414e81ae971f | 1896:f8f818a04f5b |
---|---|
1 from demandload import demandload | |
2 demandload(globals(), "cgi os re time urllib util") | |
3 | |
4 class templater(object): | |
5 def __init__(self, mapfile, filters={}, defaults={}): | |
6 self.cache = {} | |
7 self.map = {} | |
8 self.base = os.path.dirname(mapfile) | |
9 self.filters = filters | |
10 self.defaults = defaults | |
11 | |
12 for l in file(mapfile): | |
13 m = re.match(r'(\S+)\s*=\s*"(.*)"$', l) | |
14 if m: | |
15 self.cache[m.group(1)] = m.group(2) | |
16 else: | |
17 m = re.match(r'(\S+)\s*=\s*(\S+)', l) | |
18 if m: | |
19 self.map[m.group(1)] = os.path.join(self.base, m.group(2)) | |
20 else: | |
21 raise LookupError(_("unknown map entry '%s'") % l) | |
22 | |
23 def __call__(self, t, **map): | |
24 m = self.defaults.copy() | |
25 m.update(map) | |
26 try: | |
27 tmpl = self.cache[t] | |
28 except KeyError: | |
29 tmpl = self.cache[t] = file(self.map[t]).read() | |
30 return self.template(tmpl, self.filters, **m) | |
31 | |
32 def template(self, tmpl, filters={}, **map): | |
33 while tmpl: | |
34 m = re.search(r"#([a-zA-Z0-9]+)((%[a-zA-Z0-9]+)*)((\|[a-zA-Z0-9]+)*)#", tmpl) | |
35 if m: | |
36 yield tmpl[:m.start(0)] | |
37 v = map.get(m.group(1), "") | |
38 v = callable(v) and v(**map) or v | |
39 | |
40 format = m.group(2) | |
41 fl = m.group(4) | |
42 | |
43 if format: | |
44 q = v.__iter__ | |
45 for i in q(): | |
46 lm = map.copy() | |
47 lm.update(i) | |
48 yield self(format[1:], **lm) | |
49 | |
50 v = "" | |
51 | |
52 elif fl: | |
53 for f in fl.split("|")[1:]: | |
54 v = filters[f](v) | |
55 | |
56 yield v | |
57 tmpl = tmpl[m.end(0):] | |
58 else: | |
59 yield tmpl | |
60 return | |
61 | |
62 def age(x): | |
63 def plural(t, c): | |
64 if c == 1: | |
65 return t | |
66 return t + "s" | |
67 def fmt(t, c): | |
68 return "%d %s" % (c, plural(t, c)) | |
69 | |
70 now = time.time() | |
71 then = x[0] | |
72 delta = max(1, int(now - then)) | |
73 | |
74 scales = [["second", 1], | |
75 ["minute", 60], | |
76 ["hour", 3600], | |
77 ["day", 3600 * 24], | |
78 ["week", 3600 * 24 * 7], | |
79 ["month", 3600 * 24 * 30], | |
80 ["year", 3600 * 24 * 365]] | |
81 | |
82 scales.reverse() | |
83 | |
84 for t, s in scales: | |
85 n = delta / s | |
86 if n >= 2 or s == 1: | |
87 return fmt(t, n) | |
88 | |
89 def nl2br(text): | |
90 return text.replace('\n', '<br/>\n') | |
91 | |
92 def obfuscate(text): | |
93 return ''.join(['&#%d;' % ord(c) for c in text]) | |
94 | |
95 common_filters = { | |
96 "escape": lambda x: cgi.escape(x, True), | |
97 "urlescape": urllib.quote, | |
98 "strip": lambda x: x.strip(), | |
99 "age": age, | |
100 "date": lambda x: util.datestr(x), | |
101 "addbreaks": nl2br, | |
102 "obfuscate": obfuscate, | |
103 "short": (lambda x: x[:12]), | |
104 "firstline": (lambda x: x.splitlines(1)[0]), | |
105 "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"), | |
106 "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"), | |
107 } |