diff --git a/mwparserfromhell/parser/builder.py b/mwparserfromhell/parser/builder.py index ee914c3..d31f450 100644 --- a/mwparserfromhell/parser/builder.py +++ b/mwparserfromhell/parser/builder.py @@ -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.""" diff --git a/mwparserfromhell/parser/contexts.py b/mwparserfromhell/parser/contexts.py index a1b67be..38154bb 100644 --- a/mwparserfromhell/parser/contexts.py +++ b/mwparserfromhell/parser/contexts.py @@ -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 diff --git a/mwparserfromhell/parser/tokens.py b/mwparserfromhell/parser/tokens.py index ae58ec8..57308ea 100644 --- a/mwparserfromhell/parser/tokens.py +++ b/mwparserfromhell/parser/tokens.py @@ -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") # -ExternalLinkOpen = make("ExternalLinkOpen") # [ -ExternalLinkSeparator = make("ExternalLinkSeparator") # -ExternalLinkClose = make("ExternalLinkClose") # ] - del make