| @@ -632,8 +632,8 @@ class Tokenizer(object): | |||||
| def _really_parse_style(self, context): | def _really_parse_style(self, context): | ||||
| """Parse wiki-style bold or italics. Raises :py:exc:`BadRoute`.""" | """Parse wiki-style bold or italics. Raises :py:exc:`BadRoute`.""" | ||||
| stack = self._parse(context) | 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(tokens.TagOpenOpen(wiki_markup=markup)) | ||||
| self._emit_text(tag) | self._emit_text(tag) | ||||
| @@ -659,27 +659,128 @@ class Tokenizer(object): | |||||
| self._emit_text("'") | self._emit_text("'") | ||||
| ticks = 3 | 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._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): | def _handle_list_marker(self): | ||||
| """Handle a list marker at the head (``#``, ``*``, ``;``, ``:``).""" | """Handle a list marker at the head (``#``, ``*``, ``;``, ``:``).""" | ||||
| @@ -871,13 +972,9 @@ class Tokenizer(object): | |||||
| elif this == ">" and self._context & contexts.TAG_CLOSE: | elif this == ">" and self._context & contexts.TAG_CLOSE: | ||||
| return self._handle_tag_close_close() | return self._handle_tag_close_close() | ||||
| elif this == next == "'": | 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): | elif self._read(-1) in ("\n", self.START): | ||||
| if this in ("#", "*", ";", ":"): | if this in ("#", "*", ";", ":"): | ||||
| self._handle_list() | self._handle_list() | ||||