| | 1052 | class TextTemplate(Template): |
| | 1053 | """ |
| | 1054 | >>> tmpl = TextTemplate('''Dear $name, |
| | 1055 | ... |
| | 1056 | ... We have the following items for you: |
| | 1057 | ... #for item in items |
| | 1058 | ... * $item |
| | 1059 | ... #endfor |
| | 1060 | ... |
| | 1061 | ... All the best, |
| | 1062 | ... Foobar |
| | 1063 | ... #endif''') |
| | 1064 | >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render('text') |
| | 1065 | Dear Joe, |
| | 1066 | <BLANKLINE> |
| | 1067 | We have the following items for you: |
| | 1068 | * 1 |
| | 1069 | * 2 |
| | 1070 | * 3 |
| | 1071 | <BLANKLINE> |
| | 1072 | All the best, |
| | 1073 | Foobar |
| | 1074 | <BLANKLINE> |
| | 1075 | """ |
| | 1076 | |
| | 1077 | _DIRECTIVE_RE = re.compile('^#(\w+.*)\n?', re.MULTILINE) |
| | 1078 | |
| | 1079 | def parse(self): |
| | 1080 | stream = [] # list of events of the "compiled" template |
| | 1081 | dirmap = {} # temporary mapping of directives to elements |
| | 1082 | depth = 0 |
| | 1083 | |
| | 1084 | source = self.source.read() |
| | 1085 | for idx, part in enumerate(self._DIRECTIVE_RE.split(source)): |
| | 1086 | |
| | 1087 | if idx % 2: |
| | 1088 | directive = part.split(None, 1) |
| | 1089 | if len(directive) > 1: |
| | 1090 | command, value = directive |
| | 1091 | else: |
| | 1092 | command, value = directive[0], None |
| | 1093 | |
| | 1094 | if not command.startswith('end'): |
| | 1095 | cls = self._dir_by_name.get(command) |
| | 1096 | if cls is None: |
| | 1097 | raise BadDirectiveError(command) |
| | 1098 | directive = cls(value, None, -1, -1) |
| | 1099 | dirmap[depth] = (directive, len(stream)) |
| | 1100 | depth += 1 |
| | 1101 | else: |
| | 1102 | depth -= 1 |
| | 1103 | command = command[3:] |
| | 1104 | if depth in dirmap: |
| | 1105 | directive, start_offset = dirmap.pop(depth) |
| | 1106 | substream = stream[start_offset:] |
| | 1107 | stream[start_offset:] = [(SUB, ([directive], substream), |
| | 1108 | (None, -1, -1))] |
| | 1109 | |
| | 1110 | else: |
| | 1111 | for kind, data, pos in self._interpolate(part): |
| | 1112 | stream.append((kind, data, (None, -1, -1))) |
| | 1113 | |
| | 1114 | return stream |
| | 1115 | |
| | 1116 | |