@@ -142,6 +142,22 @@ class Builder(object): | |||
else: | |||
self._write(self._handle_token(token)) | |||
def _handle_external_link(self, token): | |||
"""Handle when an external link is at the head of the tokens.""" | |||
brackets, url = token.brackets, None | |||
self._push() | |||
while self._tokens: | |||
token = self._tokens.pop() | |||
if isinstance(token, tokens.ExternalLinkSeparator): | |||
url = self._pop() | |||
self._push() | |||
elif isinstance(token, tokens.ExternalLinkClose): | |||
if url is not None: | |||
return ExternalLink(url, self._pop(), brackets) | |||
return ExternalLink(self._pop(), brackets=brackets) | |||
else: | |||
self._write(self._handle_token(token)) | |||
def _handle_entity(self): | |||
"""Handle a case where an HTML entity is at the head of the tokens.""" | |||
token = self._tokens.pop() | |||
@@ -234,22 +250,6 @@ class Builder(object): | |||
else: | |||
self._write(self._handle_token(token)) | |||
def _handle_external_link(self, token): | |||
"""Handle when an external link is at the head of the tokens.""" | |||
brackets, url = token.brackets, None | |||
self._push() | |||
while self._tokens: | |||
token = self._tokens.pop() | |||
if isinstance(token, tokens.ExternalLinkSeparator): | |||
url = self._pop() | |||
self._push() | |||
elif isinstance(token, tokens.ExternalLinkClose): | |||
if url is not None: | |||
return ExternalLink(url, self._pop(), brackets) | |||
return ExternalLink(self._pop(), brackets=brackets) | |||
else: | |||
self._write(self._handle_token(token)) | |||
def _handle_token(self, token): | |||
"""Handle a single token.""" | |||
if isinstance(token, tokens.Text): | |||
@@ -260,6 +260,8 @@ class Builder(object): | |||
return self._handle_argument() | |||
elif isinstance(token, tokens.WikilinkOpen): | |||
return self._handle_wikilink() | |||
elif isinstance(token, tokens.ExternalLinkOpen): | |||
return self._handle_external_link(token) | |||
elif isinstance(token, tokens.HTMLEntityStart): | |||
return self._handle_entity() | |||
elif isinstance(token, tokens.HeadingStart): | |||
@@ -268,8 +270,6 @@ class Builder(object): | |||
return self._handle_comment() | |||
elif isinstance(token, tokens.TagOpenOpen): | |||
return self._handle_tag(token) | |||
elif isinstance(token, tokens.ExternalLinkOpen): | |||
return self._handle_external_link(token) | |||
def build(self, tokenlist): | |||
"""Build a Wikicode object from a list tokens and return it.""" | |||
@@ -51,6 +51,12 @@ Local (stack-specific) contexts: | |||
* :py:const:`WIKILINK_TITLE` | |||
* :py:const:`WIKILINK_TEXT` | |||
* :py:const:`EXTERNAL_LINK` | |||
* :py:const:`EXTERNAL_LINK_URL` | |||
* :py:const:`EXTERNAL_LINK_TITLE` | |||
* :py:const:`EXTERNAL_LINK_BRACKETS` | |||
* :py:const:`HEADING` | |||
* :py:const:`HEADING_LEVEL_1` | |||
@@ -112,35 +118,40 @@ WIKILINK_TITLE = 1 << 5 | |||
WIKILINK_TEXT = 1 << 6 | |||
WIKILINK = WIKILINK_TITLE + WIKILINK_TEXT | |||
HEADING_LEVEL_1 = 1 << 7 | |||
HEADING_LEVEL_2 = 1 << 8 | |||
HEADING_LEVEL_3 = 1 << 9 | |||
HEADING_LEVEL_4 = 1 << 10 | |||
HEADING_LEVEL_5 = 1 << 11 | |||
HEADING_LEVEL_6 = 1 << 12 | |||
EXTERNAL_LINK_URL = 1 << 7 | |||
EXTERNAL_LINK_TITLE = 1 << 8 | |||
EXTERNAL_LINK_BRACKETS = 1 << 9 | |||
EXTERNAL_LINK = EXTERNAL_LINK_URL + EXTERNAL_LINK_TITLE | |||
HEADING_LEVEL_1 = 1 << 10 | |||
HEADING_LEVEL_2 = 1 << 11 | |||
HEADING_LEVEL_3 = 1 << 12 | |||
HEADING_LEVEL_4 = 1 << 13 | |||
HEADING_LEVEL_5 = 1 << 14 | |||
HEADING_LEVEL_6 = 1 << 15 | |||
HEADING = (HEADING_LEVEL_1 + HEADING_LEVEL_2 + HEADING_LEVEL_3 + | |||
HEADING_LEVEL_4 + HEADING_LEVEL_5 + HEADING_LEVEL_6) | |||
TAG_OPEN = 1 << 13 | |||
TAG_ATTR = 1 << 14 | |||
TAG_BODY = 1 << 15 | |||
TAG_CLOSE = 1 << 16 | |||
TAG_OPEN = 1 << 16 | |||
TAG_ATTR = 1 << 17 | |||
TAG_BODY = 1 << 18 | |||
TAG_CLOSE = 1 << 19 | |||
TAG = TAG_OPEN + TAG_ATTR + TAG_BODY + TAG_CLOSE | |||
STYLE_ITALICS = 1 << 17 | |||
STYLE_BOLD = 1 << 18 | |||
STYLE_PASS_AGAIN = 1 << 19 | |||
STYLE_SECOND_PASS = 1 << 20 | |||
STYLE_ITALICS = 1 << 20 | |||
STYLE_BOLD = 1 << 21 | |||
STYLE_PASS_AGAIN = 1 << 22 | |||
STYLE_SECOND_PASS = 1 << 23 | |||
STYLE = STYLE_ITALICS + STYLE_BOLD + STYLE_PASS_AGAIN + STYLE_SECOND_PASS | |||
DL_TERM = 1 << 21 | |||
DL_TERM = 1 << 24 | |||
HAS_TEXT = 1 << 22 | |||
FAIL_ON_TEXT = 1 << 23 | |||
FAIL_NEXT = 1 << 24 | |||
FAIL_ON_LBRACE = 1 << 25 | |||
FAIL_ON_RBRACE = 1 << 26 | |||
FAIL_ON_EQUALS = 1 << 27 | |||
HAS_TEXT = 1 << 25 | |||
FAIL_ON_TEXT = 1 << 26 | |||
FAIL_NEXT = 1 << 27 | |||
FAIL_ON_LBRACE = 1 << 28 | |||
FAIL_ON_RBRACE = 1 << 29 | |||
FAIL_ON_EQUALS = 1 << 30 | |||
SAFETY_CHECK = (HAS_TEXT + FAIL_ON_TEXT + FAIL_NEXT + FAIL_ON_LBRACE + | |||
FAIL_ON_RBRACE + FAIL_ON_EQUALS) | |||
@@ -150,7 +161,7 @@ GL_HEADING = 1 << 0 | |||
# Aggregate contexts: | |||
FAIL = TEMPLATE + ARGUMENT + WIKILINK + HEADING + TAG + STYLE | |||
FAIL = TEMPLATE + ARGUMENT + WIKILINK + EXTERNAL_LINK + HEADING + TAG + STYLE | |||
UNSAFE = (TEMPLATE_NAME + WIKILINK_TITLE + TEMPLATE_PARAM_KEY + ARGUMENT_NAME + | |||
TAG_CLOSE) | |||
DOUBLE = TEMPLATE_PARAM_KEY + TAG_CLOSE |
@@ -84,6 +84,10 @@ WikilinkOpen = make("WikilinkOpen") # [[ | |||
WikilinkSeparator = make("WikilinkSeparator") # | | |||
WikilinkClose = make("WikilinkClose") # ]] | |||
ExternalLinkOpen = make("ExternalLinkOpen") # [ | |||
ExternalLinkSeparator = make("ExternalLinkSeparator") # | |||
ExternalLinkClose = make("ExternalLinkClose") # ] | |||
HTMLEntityStart = make("HTMLEntityStart") # & | |||
HTMLEntityNumeric = make("HTMLEntityNumeric") # # | |||
HTMLEntityHex = make("HTMLEntityHex") # x | |||
@@ -104,8 +108,4 @@ TagCloseSelfclose = make("TagCloseSelfclose") # /> | |||
TagOpenClose = make("TagOpenClose") # </ | |||
TagCloseClose = make("TagCloseClose") # > | |||
ExternalLinkOpen = make("ExternalLinkOpen") # [ | |||
ExternalLinkSeparator = make("ExternalLinkSeparator") # | |||
ExternalLinkClose = make("ExternalLinkClose") # ] | |||
del make |