|
@@ -629,20 +629,106 @@ class Tokenizer(object): |
|
|
else: |
|
|
else: |
|
|
self._emit_all(tag) |
|
|
self._emit_all(tag) |
|
|
|
|
|
|
|
|
def _really_parse_style(self, context): |
|
|
|
|
|
"""Parse wiki-style bold or italics. Raises :py:exc:`BadRoute`.""" |
|
|
|
|
|
stack = self._parse(context) |
|
|
|
|
|
markup = "''" if context & contexts.STYLE_ITALICS else "'''" |
|
|
|
|
|
tag = "i" if context & contexts.STYLE_ITALICS else "b" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _emit_tag_open(self, tag, markup): |
|
|
|
|
|
"""Write the three tokens in a tag opening sequence.""" |
|
|
self._emit(tokens.TagOpenOpen(wiki_markup=markup)) |
|
|
self._emit(tokens.TagOpenOpen(wiki_markup=markup)) |
|
|
self._emit_text(tag) |
|
|
self._emit_text(tag) |
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
self._emit_all(stack) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _emit_tag_close(self, tag): |
|
|
|
|
|
"""Write the three tokens in a tag closing sequence.""" |
|
|
self._emit(tokens.TagOpenClose()) |
|
|
self._emit(tokens.TagOpenClose()) |
|
|
self._emit_text(tag) |
|
|
self._emit_text(tag) |
|
|
self._emit(tokens.TagCloseClose()) |
|
|
self._emit(tokens.TagCloseClose()) |
|
|
|
|
|
|
|
|
|
|
|
def _really_parse_style(self, context, reset, markup, tag): |
|
|
|
|
|
"""Parse wiki-style bold or italics. Raises :py:exc:`BadRoute`.""" |
|
|
|
|
|
if context & contexts.STYLE_ITALICS: |
|
|
|
|
|
try: |
|
|
|
|
|
stack = self._parse(context) |
|
|
|
|
|
except BadRoute: ## only if STYLE_PASS_AGAIN in destroyed context |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
stack = self._parse(context | contexts.STYLE_PASS_2) |
|
|
|
|
|
else: |
|
|
|
|
|
stack = self._parse(context) |
|
|
|
|
|
|
|
|
|
|
|
self._emit_tag_open(tag, markup) |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit_tag_close(tag) |
|
|
|
|
|
|
|
|
|
|
|
def _parse_italics(self): |
|
|
|
|
|
"""Parse wiki-style italics.""" |
|
|
|
|
|
reset = self._head |
|
|
|
|
|
try: |
|
|
|
|
|
self._really_parse_style(contexts.STYLE_ITALICS, reset, "''", "i") |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("''") |
|
|
|
|
|
|
|
|
|
|
|
def _parse_bold(self): |
|
|
|
|
|
"""Parse wiki-style bold.""" |
|
|
|
|
|
reset = self._head |
|
|
|
|
|
try: |
|
|
|
|
|
self._really_parse_style(contexts.STYLE_BOLD, reset, "'''", "b") |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
if self._context & contexts.STYLE_PASS_2: |
|
|
|
|
|
self._emit_text("'") |
|
|
|
|
|
return True |
|
|
|
|
|
elif self._context & contexts.STYLE_ITALICS: |
|
|
|
|
|
# Set STYLE_PASS_AGAIN |
|
|
|
|
|
self._emit_text("'''") |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit_text("'") |
|
|
|
|
|
self._parse_italics() |
|
|
|
|
|
|
|
|
|
|
|
def _parse_italics_and_bold(self): |
|
|
|
|
|
"""Parse wiki-style italics and bold together (i.e., five ticks).""" |
|
|
|
|
|
reset = self._head |
|
|
|
|
|
try: |
|
|
|
|
|
stack = self._parse(contexts.STYLE_BOLD) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
try: |
|
|
|
|
|
stack = self._parse(contexts.STYLE_ITALICS) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("'''''") |
|
|
|
|
|
else: |
|
|
|
|
|
reset = self._head |
|
|
|
|
|
try: |
|
|
|
|
|
stack2 = self._parse(contexts.STYLE_BOLD) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("'''") |
|
|
|
|
|
self._emit_tag_open("i", "''") |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit_tag_close("i") |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit_tag_open("b", "'''") |
|
|
|
|
|
self._emit_tag_open("i", "''") |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit_tag_close("i") |
|
|
|
|
|
self._emit_all(stack2) |
|
|
|
|
|
self._emit_tag_close("b") |
|
|
|
|
|
else: |
|
|
|
|
|
reset = self._head |
|
|
|
|
|
try: |
|
|
|
|
|
stack2 = self._parse(contexts.STYLE_ITALICS) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("''") |
|
|
|
|
|
self._emit_tag_open("b", "'''") |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit_tag_close("b") |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit_tag_open("i", "''") |
|
|
|
|
|
self._emit_tag_open("b", "'''") |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit_tag_close("b") |
|
|
|
|
|
self._emit_all(stack2) |
|
|
|
|
|
self._emit_tag_close("i") |
|
|
|
|
|
|
|
|
def _parse_style(self): |
|
|
def _parse_style(self): |
|
|
"""Parse wiki-style formatting (``''``/``'''`` for italics/bold).""" |
|
|
"""Parse wiki-style formatting (``''``/``'''`` for italics/bold).""" |
|
|
self._head += 2 |
|
|
self._head += 2 |
|
@@ -650,7 +736,8 @@ class Tokenizer(object): |
|
|
while self._read() == "'": |
|
|
while self._read() == "'": |
|
|
self._head += 1 |
|
|
self._head += 1 |
|
|
ticks += 1 |
|
|
ticks += 1 |
|
|
reset = self._head |
|
|
|
|
|
|
|
|
italics = self._context & contexts.STYLE_ITALICS |
|
|
|
|
|
bold = self._context & contexts.STYLE_BOLD |
|
|
|
|
|
|
|
|
if ticks > 5: |
|
|
if ticks > 5: |
|
|
self._emit_text("'" * (ticks - 5)) |
|
|
self._emit_text("'" * (ticks - 5)) |
|
@@ -659,127 +746,24 @@ class Tokenizer(object): |
|
|
self._emit_text("'") |
|
|
self._emit_text("'") |
|
|
ticks = 3 |
|
|
ticks = 3 |
|
|
|
|
|
|
|
|
if ticks == 2: |
|
|
|
|
|
if self._context & contexts.STYLE_ITALICS: |
|
|
|
|
|
return self._pop() |
|
|
|
|
|
if self._can_recurse(): |
|
|
|
|
|
try: |
|
|
|
|
|
self._really_parse_style(contexts.STYLE_ITALICS) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
try: ## only if STYLE_PASS_AGAIN in destroyed context |
|
|
|
|
|
self._really_parse_style(contexts.STYLE_ITALICS|contexts.STYLE_PASS_2) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("''") |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit_text("''") |
|
|
|
|
|
|
|
|
if (italics and ticks in (2, 5)) or (bold and ticks in (3, 5)): |
|
|
|
|
|
if ticks == 5: |
|
|
|
|
|
self._head -= 3 if italics else 2 |
|
|
|
|
|
return self._pop() |
|
|
|
|
|
elif not self._can_recurse(): |
|
|
|
|
|
if ticks == 3: |
|
|
|
|
|
if self._context & contexts.STYLE_PASS_2: |
|
|
|
|
|
self._emit_text("'") |
|
|
|
|
|
return self._pop() |
|
|
|
|
|
# Set STYLE_PASS_AGAIN |
|
|
|
|
|
self._emit_text("'" * ticks) |
|
|
|
|
|
elif ticks == 2: |
|
|
|
|
|
self._parse_italics() |
|
|
elif ticks == 3: |
|
|
elif ticks == 3: |
|
|
if self._context & contexts.STYLE_BOLD: |
|
|
|
|
|
|
|
|
if self._parse_bold(): |
|
|
return self._pop() |
|
|
return self._pop() |
|
|
elif self._can_recurse(): |
|
|
|
|
|
try: |
|
|
|
|
|
self._really_parse_style(contexts.STYLE_BOLD) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
if self._context & contexts.STYLE_ITALICS: |
|
|
|
|
|
if self._context & contexts.STYLE_PASS_2: |
|
|
|
|
|
self._emit_text("'") |
|
|
|
|
|
return self._pop() |
|
|
|
|
|
self._emit_text("'''") ## here is our hook for STYLE_PASS_AGAIN |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit_text("'") |
|
|
|
|
|
try: |
|
|
|
|
|
self._really_parse_style(contexts.STYLE_ITALICS) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
try: ## only if STYLE_PASS_AGAIN in destroyed context |
|
|
|
|
|
self._really_parse_style(contexts.STYLE_ITALICS|contexts.STYLE_PASS_2) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("''") |
|
|
|
|
|
elif self._context & contexts.STYLE_ITALICS and self._context & contexts.STYLE_PASS_2: |
|
|
|
|
|
self._emit_text("'") |
|
|
|
|
|
return self._pop() |
|
|
|
|
|
else: ## here is our hook for STYLE_PASS_AGAIN |
|
|
|
|
|
self._emit_text("'''") |
|
|
|
|
|
elif ticks == 5: |
|
|
elif ticks == 5: |
|
|
if self._context & contexts.STYLE_ITALICS: |
|
|
|
|
|
self._head -= 3 |
|
|
|
|
|
return self._pop() |
|
|
|
|
|
elif self._context & contexts.STYLE_BOLD: |
|
|
|
|
|
self._head -= 2 |
|
|
|
|
|
return self._pop() |
|
|
|
|
|
elif self._can_recurse(): |
|
|
|
|
|
try: |
|
|
|
|
|
stack = self._parse(contexts.STYLE_BOLD) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
try: |
|
|
|
|
|
stack = self._parse(contexts.STYLE_ITALICS) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("'''''") |
|
|
|
|
|
else: |
|
|
|
|
|
reset = self._head |
|
|
|
|
|
try: |
|
|
|
|
|
stack2 = self._parse(contexts.STYLE_BOLD) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("'''") |
|
|
|
|
|
self._emit(tokens.TagOpenOpen(wiki_markup="''")) |
|
|
|
|
|
self._emit_text("i") |
|
|
|
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit(tokens.TagOpenClose()) |
|
|
|
|
|
self._emit_text("i") |
|
|
|
|
|
self._emit(tokens.TagCloseClose()) |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit(tokens.TagOpenOpen(wiki_markup="'''")) |
|
|
|
|
|
self._emit_text("b") |
|
|
|
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
|
|
|
self._emit(tokens.TagOpenOpen(wiki_markup="''")) |
|
|
|
|
|
self._emit_text("i") |
|
|
|
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit(tokens.TagOpenClose()) |
|
|
|
|
|
self._emit_text("i") |
|
|
|
|
|
self._emit(tokens.TagCloseClose()) |
|
|
|
|
|
self._emit_all(stack2) |
|
|
|
|
|
self._emit(tokens.TagOpenClose()) |
|
|
|
|
|
self._emit_text("b") |
|
|
|
|
|
self._emit(tokens.TagCloseClose()) |
|
|
|
|
|
else: |
|
|
|
|
|
reset = self._head |
|
|
|
|
|
try: |
|
|
|
|
|
stack2 = self._parse(contexts.STYLE_ITALICS) |
|
|
|
|
|
except BadRoute: |
|
|
|
|
|
self._head = reset |
|
|
|
|
|
self._emit_text("''") |
|
|
|
|
|
self._emit(tokens.TagOpenOpen(wiki_markup="'''")) |
|
|
|
|
|
self._emit_text("b") |
|
|
|
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit(tokens.TagOpenClose()) |
|
|
|
|
|
self._emit_text("b") |
|
|
|
|
|
self._emit(tokens.TagCloseClose()) |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit(tokens.TagOpenOpen(wiki_markup="''")) |
|
|
|
|
|
self._emit_text("i") |
|
|
|
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
|
|
|
self._emit(tokens.TagOpenOpen(wiki_markup="'''")) |
|
|
|
|
|
self._emit_text("b") |
|
|
|
|
|
self._emit(tokens.TagCloseOpen()) |
|
|
|
|
|
self._emit_all(stack) |
|
|
|
|
|
self._emit(tokens.TagOpenClose()) |
|
|
|
|
|
self._emit_text("b") |
|
|
|
|
|
self._emit(tokens.TagCloseClose()) |
|
|
|
|
|
self._emit_all(stack2) |
|
|
|
|
|
self._emit(tokens.TagOpenClose()) |
|
|
|
|
|
self._emit_text("i") |
|
|
|
|
|
self._emit(tokens.TagCloseClose()) |
|
|
|
|
|
else: |
|
|
|
|
|
self._emit_text("'''''") |
|
|
|
|
|
|
|
|
self._parse_italics_and_bold() |
|
|
self._head -= 1 |
|
|
self._head -= 1 |
|
|
|
|
|
|
|
|
def _handle_list_marker(self): |
|
|
def _handle_list_marker(self): |
|
|