|
|
@@ -632,8 +632,8 @@ class Tokenizer(object): |
|
|
|
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" |
|
|
|
markup = "''" if context & contexts.STYLE_ITALICS else "'''" |
|
|
|
tag = "i" if context & contexts.STYLE_ITALICS else "b" |
|
|
|
|
|
|
|
self._emit(tokens.TagOpenOpen(wiki_markup=markup)) |
|
|
|
self._emit_text(tag) |
|
|
@@ -659,27 +659,128 @@ class Tokenizer(object): |
|
|
|
self._emit_text("'") |
|
|
|
ticks = 3 |
|
|
|
|
|
|
|
if ticks == 5: |
|
|
|
raise NotImplementedError() |
|
|
|
if ticks == 3: |
|
|
|
try: |
|
|
|
return self._really_parse_style(contexts.STYLE_BOLD) |
|
|
|
except BadRoute: |
|
|
|
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("''") |
|
|
|
elif ticks == 3: |
|
|
|
if self._context & contexts.STYLE_BOLD: |
|
|
|
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("'") |
|
|
|
self._head = reset |
|
|
|
try: |
|
|
|
self._really_parse_style(contexts.STYLE_ITALICS) |
|
|
|
except BadRoute: |
|
|
|
self._emit_text("''") |
|
|
|
self._head = reset - 1 |
|
|
|
|
|
|
|
def _handle_style_end(self): |
|
|
|
"""Handle the end of wiki-style italics or bold (``''`` or ``'''``).""" |
|
|
|
self._head += 1 if self._context & contexts.STYLE_ITALICS else 2 |
|
|
|
while self._read(1) == "'": |
|
|
|
self._emit_text("'") |
|
|
|
self._head += 1 |
|
|
|
return self._pop() |
|
|
|
return self._pop() |
|
|
|
else: ## here is our hook for STYLE_PASS_AGAIN |
|
|
|
self._emit_text("'''") |
|
|
|
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._head -= 1 |
|
|
|
|
|
|
|
def _handle_list_marker(self): |
|
|
|
"""Handle a list marker at the head (``#``, ``*``, ``;``, ``:``).""" |
|
|
@@ -871,13 +972,9 @@ class Tokenizer(object): |
|
|
|
elif this == ">" and self._context & contexts.TAG_CLOSE: |
|
|
|
return self._handle_tag_close_close() |
|
|
|
elif this == next == "'": |
|
|
|
if not self._context & contexts.STYLE and self._can_recurse(): |
|
|
|
self._parse_style() |
|
|
|
elif (self._context & contexts.STYLE_ITALICS or |
|
|
|
self._read(2) == "'" and self._context & contexts.STYLE_BOLD): |
|
|
|
return self._handle_style_end() |
|
|
|
else: |
|
|
|
self._emit_text("'") |
|
|
|
result = self._parse_style() |
|
|
|
if result is not None: |
|
|
|
return result |
|
|
|
elif self._read(-1) in ("\n", self.START): |
|
|
|
if this in ("#", "*", ";", ":"): |
|
|
|
self._handle_list() |
|
|
|