(self, i)
| 248 | |
| 249 | # Internal -- handle starttag, return length or -1 if not terminated |
| 250 | def parse_starttag(self, i): |
| 251 | self.__starttag_text = None |
| 252 | start_pos = i |
| 253 | rawdata = self.rawdata |
| 254 | if shorttagopen.match(rawdata, i): |
| 255 | # SGML shorthand: <tag/data/ == <tag>data</tag> |
| 256 | # XXX Can data contain &... (entity or char refs)? |
| 257 | # XXX Can data contain < or > (tag characters)? |
| 258 | # XXX Can there be whitespace before the first /? |
| 259 | match = shorttag.match(rawdata, i) |
| 260 | if not match: |
| 261 | return -1 |
| 262 | tag, data = match.group(1, 2) |
| 263 | self.__starttag_text = '<%s/' % tag |
| 264 | tag = tag.lower() |
| 265 | k = match.end(0) |
| 266 | self.finish_shorttag(tag, data) |
| 267 | self.__starttag_text = rawdata[start_pos:match.end(1) + 1] |
| 268 | return k |
| 269 | # XXX The following should skip matching quotes (' or ") |
| 270 | # As a shortcut way to exit, this isn't so bad, but shouldn't |
| 271 | # be used to locate the actual end of the start tag since the |
| 272 | # < or > characters may be embedded in an attribute value. |
| 273 | match = endbracket.search(rawdata, i + 1) |
| 274 | if not match: |
| 275 | return -1 |
| 276 | j = match.start(0) |
| 277 | # Now parse the data between i + 1 and j into a tag and attrs |
| 278 | attrs = [] |
| 279 | if rawdata[i:i + 2] == '<>': |
| 280 | # SGML shorthand: <> == <last open tag seen> |
| 281 | k = j |
| 282 | tag = self.lasttag |
| 283 | else: |
| 284 | match = tagfind.match(rawdata, i + 1) |
| 285 | if not match: |
| 286 | self.error('unexpected call to parse_starttag') |
| 287 | k = match.end(0) |
| 288 | tag = rawdata[i + 1:k].lower() |
| 289 | self.lasttag = tag |
| 290 | while k < j: |
| 291 | match = attrfind.match(rawdata, k) |
| 292 | if not match: |
| 293 | break |
| 294 | attrname, rest, attrvalue = match.group(1, 2, 3) |
| 295 | if not rest: |
| 296 | attrvalue = attrname |
| 297 | else: |
| 298 | if (attrvalue[:1] == "'" == attrvalue[-1:] or |
| 299 | attrvalue[:1] == '"' == attrvalue[-1:]): |
| 300 | # strip quotes |
| 301 | attrvalue = attrvalue[1:-1] |
| 302 | attrvalue = self.entity_or_charref.sub( |
| 303 | self._convert_ref, attrvalue) |
| 304 | attrs.append((attrname.lower(), attrvalue)) |
| 305 | k = match.end(0) |
| 306 | if rawdata[j] == '>': |
| 307 | j = j + 1 |
no test coverage detected