8000 Jinja by aelaguiz · Pull Request #1 · cratejoy/html5lib-python · GitHub
[go: up one dir, main page]

Skip to content

Jinja #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additio 8000 ns & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ stats.prof

# We have no interest in built Sphinx files
/doc/_build

venv
11 changes: 9 additions & 2 deletions html5lib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -3088,12 +3088,19 @@
"ParseError": 7,
"JinjaStatementStartTag": 8,
"JinjaStatementEndTag": 9,
"JinjaStatementTag": 10,
"JinjaStatement": 10,
"JinjaVariableStartTag": 11,
"JinjaVariableEndTag": 12,
"JinjaVariable": 13,
"JinjaFilter": 14,
"JinjaPipe": 15
"JinjaPipe": 15,
"JinjaArgumentStartTag": 16,
"JinjaArgumentEndTag": 17,
"JinjaArgument": 18,
"JinjaExtendTag": 19,
"JinjaIncludeTag": 20,
"JinjaImportTag": 21,
"JinjaComment": 22
}

tagTokenTypes = frozenset((tokenTypes["StartTag"], tokenTypes["EndTag"],
Expand Down
141 changes: 121 additions & 20 deletions html5lib/html5parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,19 @@ def mainLoop(self):
ParseErrorToken = tokenTypes["ParseError"]
JinjaStatementStartTag = tokenTypes["JinjaStatementStartTag"]
JinjaStatementEndTag = tokenTypes["JinjaStatementEndTag"]
JinjaStatementTag = tokenTypes["JinjaStatementTag"]
JinjaStatement = tokenTypes["JinjaStatement"]
JinjaVariableStartTag = tokenTypes["JinjaVariableStartTag"]
JinjaVariableEndTag = tokenTypes["JinjaVariableEndTag"]
JinjaVariable = tokenTypes["JinjaVariable"]
JinjaPipe = tokenTypes["JinjaPipe"]
JinjaFilter = tokenTypes["JinjaFilter"]
JinjaArgumentStartTag = tokenTypes["JinjaArgumentStartTag"]
JinjaArgumentEndTag = tokenTypes["JinjaArgumentEndTag"]
JinjaArgument = tokenTypes["JinjaArgument"]
JinjaExtendTag = tokenTypes["JinjaExtendTag"]
JinjaIncludeTag = tokenTypes["JinjaIncludeTag"]
JinjaImportTag = tokenTypes["JinjaImportTag"]
JinjaComment = tokenTypes["JinjaComment"]

for token in self.normalizedTokens():
new_token = token
Expand All @@ -190,8 +197,11 @@ def mainLoop(self):
new_token = None
else:
if type in (JinjaVariableStartTag, JinjaVariableEndTag, JinjaVariable, JinjaFilter, JinjaPipe):
log.debug(u"Type is a jinja tag")
phase = self.phases["inJinjaVariable"]
elif type in (JinjaStatementStartTag, JinjaStatementEndTag, JinjaStatement):
phase = self.phases["inJinjaStatement"]
elif type in (JinjaArgumentStartTag, JinjaArgumentEndTag, JinjaArgument):
phase = self.phases["inJinjaArgument"]
elif (
len(self.tree.openElements) == 0 or
currentNodeNamespace == self.tree.defaultNamespace or
Expand Down Expand Up @@ -224,8 +234,8 @@ def mainLoop(self):
new_token = phase.processJinjaStatementStartTag(new_token)
elif type == JinjaStatementEndTag:
new_token = phase.processJinjaStatementEndTag(new_token)
elif type == JinjaStatementTag:
new_token = phase.processJinjaStatementTag(new_token)
elif type == JinjaStatement:
new_token = phase.processJinjaStatement(new_token)
elif type == JinjaVariableStartTag:
new_token = phase.processJinjaVariableStartTag(new_token)
elif type == JinjaVariableEndTag:
Expand All @@ -234,8 +244,22 @@ def mainLoop(self):
new_token = phase.processJinjaVariable(new_token)
elif type == JinjaPipe:
new_token = phase.processJinjaPipe(new_token)
elif type == JinjaComment:
new_token = phase.processJinjaComment(new_token)
elif type == JinjaFilter:
new_token = phase.processJinjaFilter(new_token)
elif type == JinjaArgumentStartTag:
new_token = phase.processJinjaArgumentStartTag(new_token)
elif type == JinjaArgumentEndTag:
new_token = phase.processJinjaArgumentEndTag(new_token)
elif type == JinjaArgument:
new_token = phase.processJinjaArgument(new_token)
elif type == JinjaExtendTag:
new_token = phase.processJinjaExtendTag(new_token)
elif type == JinjaIncludeTag:
new_token = phase.processJinjaIncludeTag(new_token)
elif type == JinjaImportTag:
new_token = phase.processJinjaImportTag(new_token)

if (type == StartTagToken and token["selfClosing"]
and not token["selfClosingAcknowledged"]):
Expand Down Expand Up @@ -432,7 +456,6 @@ def resetInsertionMode(self):
new_phase = self.phases["inBody"]
break

#log.debug(u"Changing phase to {}".format(new_phase))
self.phase = new_phase

def parseRCDataRawtext(self, token, contentType):
Expand All @@ -450,7 +473,6 @@ def parseRCDataRawtext(self, token, contentType):

self.originalPhase = self.phase

log.debug(u"Changing phase to text")
self.phase = self.phases["text"]


Expand Down Expand Up @@ -517,7 +539,7 @@ def processJinjaStatementStartTag(self, token):
def processJinjaStatementEndTag(self, token):
pass

def processJinjaStatementTag(self, token):
def processJinjaStatement(self, token):
pass

def processJinjaVariableStartTag(self, token):
Expand All @@ -529,6 +551,31 @@ def processJinjaVariableEndTag(self, token):
def processJinjaVariable(self, token):
pass

def processJinjaExtendTag(self, token):
element = self.tree.createElementWithoutNamespace(token)
self.tree.openElements[-1].appendChild(element)

def processJinjaIncludeTag(self, token):
element = self.tree.createElementWithoutNamespace(token)
self.tree.openElements[-1].appendChild(element)

def processJinjaComment(self, token):
element = self.tree.createElementWithoutNamespace(token)
self.tree.openElements[-1].appendChild(element)

def processJinjaImportTag(self, token):
element = self.tree.createElementWithoutNamespace(token)
self.tree.openElements[-1].appendChild(element)

def processJinjaArgumentStartTag(self, token):
pass

def processJinjaArgumentEndTag(self, token):
pass

def processJinjaArgument(self, token):
pass

def processJinjaPipe(self, token):
pass

Expand All @@ -553,27 +600,20 @@ def processEndTag(self, token):

class InJinjaVariablePhase(Phase):
def processJinjaVariableStartTag(self, token):
log = logging.getLogger('html5lib')
log.debug(u"InJinja: Start Tag")
self.tree.reconstructActiveFormattingElements()
self.tree.insertElement(token)

def processJinjaVariableEndTag(self, token):
log = logging.getLogger('html5lib')
log.debug(u"InJinja: End Tag {}".format(token["name"]))
for node in self.tree.openElements[::-1]:
log.debug(u"InJinja: Open tag {} token {}".format(node, token))
if node.name == token["name"]:
self.tree.generateImpliedEndTags(exclude=token["name"])
log.debug(u"InJinja: Implied end tag {} {}".format(self.tree.openElements[-1].name, token["name"]))
if self.tree.openElements[-1].name != token["name"]:
self.parser.parseError("unexpected-end-tag", {"name": token["name"]})
while self.tree.openElements.pop() != node:
pass
break
else:
if node.nameTuple in specialElements:
log.debug(u"Nametuple {} in {}".format(node.nameTuple, specialElements))
self.parser.parseError("unexpected-end-tag", {"name": token["name"]})
break

Expand All @@ -589,6 +629,68 @@ def processJinjaFilter(self, token):
element = self.tree.createElementWithoutNamespace(token)
self.tree.openElements[-1].appendChild(element)

class InJinjaStatementPhase(Phase):
def processJinjaStatementStartTag(self, token):
if token['name'] == 'jinjaelse':
self.closeOpenIf(token)
elif token['name'] == 'jinjaelif':
self.closeOpenIf(token)

self.tree.reconstructActiveFormattingElements()
self.tree.insertElement(token)

def closeOpenIf(self, token):
#import logging
#log = logging.getLogger(u"html5lib")

for node in self.tree.openElements[::-1]:
#log.debug(u"Prev {} Cur {}".format(node.name, token['name']))

if node.name == token["name"] or (node.name in ["jinjaif", "jinjaelif"] and token["name"] in ["jinjaelse", "jinjaelif"]):
self.tree.generateImpliedEndTags(exclude=token["name"])

if self.tree.openElements[-1].name in ["jinjaif", "jinjaelif"] and token["name"] in ["jinjaelse", "jinjaelif"]:
pass
elif self.tree.openElements[-1].name != token["name"]:
self.parser.parseError("unexpected-end-tag", {"name": token["name"]})
while self.tree.openElements.pop() != node:
pass

break
else:
if node.nameTuple in specialElements:
self.parser.parseError("unexpected-end-tag", {"name": token["name"]})
break

def processJinjaStatementEndTag(self, token):
import logging
log = logging.getLogger(u"html5lib")

for node in self.tree.openElements[::-1]:
if node.name == token["name"] or (node.name in ["jinjaelse", "jinjaelif"] and token["name"] == "jinjaif"):
self.tree.generateImpliedEndTags(exclude=token["name"])

if self.tree.openElements[-1].name in ["jinjaelse", "jinjaelif"] and token["name"] == "jinjaif":
pass
elif self.tree.openElements[-1].name != token["name"]:
self.parser.parseError("unexpected-end-tag", {"name": token["name"]})

while self.tree.openElements.pop() != node:
pass
break
else:
log.debug(u"Node {}".format(node.name))
self.tree.openElements.pop()

def processJinjaStatement(self, token):
element = self.tree.createElementWithoutNamespace(token)
self.tree.openElements[-1].appendChild(element)

class InJinjaArgumentPhase(Phase):
def processJinjaArgument(self, token):
element = self.tree.createElementWithoutNamespace(token)
self.tree.openElements[-1].childNodes[-1].appendChild(element)

class InitialPhase(Phase):
def processSpaceCharacters(self, token):
pass
Expand Down Expand Up @@ -882,8 +984,6 @@ def startTagOther(self, token):
def endTagHead(self, token):
node = self.parser.tree.openElements.pop()
assert node.name == "head", "Expected head got %s" % node.name
log = logging.getLogger(u"html5lib")
log.debug(u"Switching phase to afterHead")
self.parser.phase = self.parser.phases["afterHead"]

def endTagHtmlBodyBr(self, token):
Expand All @@ -894,8 +994,6 @@ def endTagOther(self, token):
self.parser.parseError("unexpected-end-tag", {"name": token["name"]})

def anythingElse(self):
log = logging.getLogger(u"html5lib")
log.debug(u"Implied end head tag")
self.endTagHead(impliedTagToken("head"))

# XXX If we implement a parser for which scripting is disabled we need to
Expand Down Expand Up @@ -966,8 +1064,6 @@ def endTagOther(self, token):

def anythingElse(self):
self.tree.insertElement(impliedTagToken("body", "StartTag"))
log = logging.getLogger(u"html5lib")
log.debug(u"Changing phase to body")
self.parser.phase = self.parser.phases["inBody"]
self.parser.framesetOK = True

Expand Down Expand Up @@ -1080,6 +1176,9 @@ def processEOF(self):
"tfoot", "th", "thead", "tr", "body",
"html"))
for node in self.tree.openElements[::-1]:
if node.name.startswith("jinja"):
continue

if node.name not in allowed_elements:
self.parser.parseError("expected-closing-tag-but-got-eof")
break
Expand Down Expand Up @@ -2794,6 +2893,8 @@ def processEndTag(self, token):
# XXX "inHeadNoscript": InHeadNoScriptPhase,
"afterHead": AfterHeadPhase,
"inJinjaVariable": InJinjaVariablePhase,
"inJinjaStatement": InJinjaStatementPhase,
"inJinjaArgument": InJinjaArgumentPhase,
"inBody": InBodyPhase,
"text": TextPhase,
"inTable": InTablePhase,
Expand Down
3 changes: 3 additions & 0 deletions html5lib/inputstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import codecs
import re
import logging

from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase
from .constants import encodings, ReparseException
Expand Down Expand Up @@ -43,6 +44,8 @@ class BufferedIOBase(object):
# Cache for charsUntil()
charsUntilRegEx = {}

log = logging.getLogger(u"html5lib")


class BufferedStream(object):
"""Buffering for streams that do not have buffering of their own
Expand Down
Loading
0