1
2
3
4
5
6
7
8
9
10
11
12
13 """HTML formated DocumentTemplates
14
15 $Id: DT_HTML.py 1007 2007-02-10 01:07:28Z stefan $"""
16
17 from DT_String import String, FileMixin
18 import DT_String, re
19 from DT_Util import ParseError, str
20
22 """ This needs to be replaced before 2.4. It's a hackaround. """
23 - def search(self, text, start=0,
24 name_match=re.compile('[\000- ]*[a-zA-Z]+[\000- ]*').match,
25 end_match=re.compile('[\000- ]*(/|end)', re.I).match,
26 start_search=re.compile('[<&]').search,
27 ent_name=re.compile('[-a-zA-Z0-9_.]+').match,
28 ):
29
30 while 1:
31 mo = start_search(text,start)
32 if mo is None: return None
33 s = mo.start(0)
34 if text[s:s+5] == '<!--#':
35 n=s+5
36 e=text.find('-->',n)
37 if e < 0: return None
38 en=3
39
40 mo =end_match(text,n)
41 if mo is not None:
42 l = mo.end(0) - mo.start(0)
43 end=text[n:n+l].strip()
44 n=n+l
45 else: end=''
46
47 elif text[s:s+6] == '<dtml-':
48 e=n=s+6
49 while 1:
50 e=text.find('>',e+1)
51 if e < 0: return None
52 if len(text[n:e].split('"'))%2:
53
54 break
55
56 en=1
57 end=''
58
59 elif text[s:s+7] == '</dtml-':
60 e=n=s+7
61 while 1:
62 e=text.find('>',e+1)
63 if e < 0: return None
64 if len(text[n:e].split('"'))%2:
65
66 break
67
68 en=1
69 end='/'
70
71 else:
72 if text[s:s+5] == '&dtml' and text[s+5] in '.-':
73 n=s+6
74 e=text.find(';',n)
75 if e >= 0:
76 args=text[n:e]
77 l=len(args)
78 mo = ent_name(args)
79 if mo is not None:
80 if mo.end(0)-mo.start(0) == l:
81 d=self.__dict__
82 if text[s+5]=='-':
83 d[1]=d['end']=''
84 d[2]=d['name']='var'
85 d[0]=text[s:e+1]
86 d[3]=d['args']=args+' html_quote'
87 self._start = s
88 return self
89 else:
90 nn=args.find('-')
91 if nn >= 0 and nn < l-1:
92 d[1]=d['end']=''
93 d[2]=d['name']='var'
94 d[0]=text[s:e+1]
95 args=args[nn+1:]+' '+ \
96 args[:nn].replace('.',' ')
97 d[3]=d['args']=args
98 self._start = s
99 return self
100
101 start=s+1
102 continue
103
104 break
105
106 mo = name_match(text,n)
107 if mo is None: return None
108 l = mo.end(0) - mo.start(0)
109
110 a=n+l
111 name=text[n:a].strip()
112
113 args=text[a:e].strip()
114
115 d=self.__dict__
116 d[0]=text[s:e+en]
117 d[1]=d['end']=end
118 d[2]=d['name']=name
119 d[3]=d['args']=args
120 self._start = s
121 return self
122
128
131
132 -class HTML(DT_String.String):
133 """HTML Document Templates
134
135 HTML Document templates use HTML server-side-include syntax,
136 rather than Python format-string syntax. Here's a simple example:
137
138 <!--#in results-->
139 <!--#var name-->
140 <!--#/in-->
141
142 HTML document templates quote HTML tags in source when the
143 template is converted to a string. This is handy when templates
144 are inserted into HTML editing forms.
145 """
146
147 tagre__roles__=()
150
151 parseTag__roles__=()
153 """Parse a tag using an already matched re
154
155 Return: tag, args, command, coname
156
157 where: tag is the tag,
158 args is the tag\'s argument string,
159 command is a corresponding command info structure if the
160 tag is a start tag, or None otherwise, and
161 coname is the name of a continue tag (e.g. else)
162 or None otherwise
163 """
164 tag, end, name, args = match_ob.group(0, 'end', 'name', 'args')
165 args=args.strip()
166 if end:
167 if not command or name != command.name:
168 raise ParseError, ('unexpected end tag', tag)
169 return tag, args, None, None
170
171 if command and name in command.blockContinuations:
172
173 if name=='else' and args:
174
175
176 l=len(args)
177 if not (args==sargs or
178 args==sargs[:l] and sargs[l:l+1] in ' \t\n'):
179 return tag, args, self.commands[name], None
180
181 return tag, args, None, name
182
183 try: return tag, args, self.commands[name], None
184 except KeyError:
185 raise ParseError, ('Unexpected tag', tag)
186
187 SubTemplate__roles__=()
189
190 varExtra__roles__=()
192
193 manage_edit__roles__=()
198
199 quotedHTML__roles__=()
200 - def quotedHTML(self,
201 text=None,
202 character_entities=(
203 (('&'), '&'),
204 (("<"), '<' ),
205 ((">"), '>' ),
206 (('"'), '"'))):
207 if text is None: text=self.read_raw()
208 for re,name in character_entities:
209 if text.find(re) >= 0: text=name.join(text.split(re))
210 return text
211
212 errQuote__roles__=()
213 errQuote=quotedHTML
214
217
218
219 management_interface__roles__=()
221 '''Hook to allow public execution of management interface with
222 everything else private.'''
223 return self
224
225 manage_editForm__roles__=()
235
236 manage_editDocument__roles__=()
237 manage__roles__=()
238 manage_editDocument=manage=manage_editForm
239
241 '''\
242 HTML document templates that edit themselves through copy.
243
244 This is to make a distinction from HTML objects that should edit
245 themselves in place.
246 '''
247 copy_class__roles__=()
248 copy_class=HTML
249
250 manage_edit__roles__=()
252 'edit a template'
253 newHTML=self.copy_class(data,self.globals,self.__name__)
254 setattr(PARENTS[1],URL1[URL1.rfind('/')+1:],newHTML)
255 return self.editConfirmation(self,REQUEST)
256
257
316