annotate genshi/template/text.py @ 336:7763f7aec949 trunk

Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
author cmlenz
date Wed, 08 Nov 2006 15:50:15 +0000
parents
children fe40d34fb71d a81675590258
rev   line source
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
2 #
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
3 # Copyright (C) 2006 Edgewall Software
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
4 # All rights reserved.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
5 #
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
9 #
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
13
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
14 """Plain text templating engine."""
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
15
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
16 import re
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
17
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
18 from genshi.template.core import BadDirectiveError, Template, SUB
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
19 from genshi.template.directives import *
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
20
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
21
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
22 class TextTemplate(Template):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
23 """Implementation of a simple text-based template engine.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
24
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
25 >>> tmpl = TextTemplate('''Dear $name,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
26 ...
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
27 ... We have the following items for you:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
28 ... #for item in items
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
29 ... * $item
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
30 ... #end
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
31 ...
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
32 ... All the best,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
33 ... Foobar''')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
34 >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render('text')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
35 Dear Joe,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
36 <BLANKLINE>
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
37 We have the following items for you:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
38 * 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
39 * 2
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
40 * 3
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
41 <BLANKLINE>
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
42 All the best,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
43 Foobar
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
44 """
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
45 directives = [('def', DefDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
46 ('when', WhenDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
47 ('otherwise', OtherwiseDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
48 ('for', ForDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
49 ('if', IfDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
50 ('choose', ChooseDirective),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
51 ('with', WithDirective)]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
52
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
53 _DIRECTIVE_RE = re.compile(r'^\s*(?<!\\)#((?:\w+|#).*)\n?', re.MULTILINE)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
54
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
55 def _parse(self, encoding):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
56 """Parse the template from text input."""
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
57 stream = [] # list of events of the "compiled" template
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
58 dirmap = {} # temporary mapping of directives to elements
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
59 depth = 0
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
60 if not encoding:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
61 encoding = 'utf-8'
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
62
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
63 source = self.source.read().decode(encoding, 'replace')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
64 offset = 0
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
65 lineno = 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
66
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
67 for idx, mo in enumerate(self._DIRECTIVE_RE.finditer(source)):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
68 start, end = mo.span()
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
69 if start > offset:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
70 text = source[offset:start]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
71 for kind, data, pos in self._interpolate(text, self.basedir,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
72 self.filename, lineno):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
73 stream.append((kind, data, pos))
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
74 lineno += len(text.splitlines())
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
75
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
76 text = source[start:end].lstrip()[1:]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
77 lineno += len(text.splitlines())
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
78 directive = text.split(None, 1)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
79 if len(directive) > 1:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
80 command, value = directive
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
81 else:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
82 command, value = directive[0], None
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
83
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
84 if command == 'end':
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
85 depth -= 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
86 if depth in dirmap:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
87 directive, start_offset = dirmap.pop(depth)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
88 substream = stream[start_offset:]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
89 stream[start_offset:] = [(SUB, ([directive], substream),
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
90 (self.filepath, lineno, 0))]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
91 elif command != '#':
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
92 cls = self._dir_by_name.get(command)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
93 if cls is None:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
94 raise BadDirectiveError(command)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
95 directive = cls(value, None, self.filepath, lineno, 0)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
96 dirmap[depth] = (directive, len(stream))
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
97 depth += 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
98
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
99 offset = end
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
100
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
101 if offset < len(source):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
102 text = source[offset:].replace('\\#', '#')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
103 for kind, data, pos in self._interpolate(text, self.basedir,
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
104 self.filename, lineno):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
105 stream.append((kind, data, pos))
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
106
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
107 return stream
Copyright (C) 2012-2017 Edgewall Software