| @@ -1886,6 +1886,7 @@ static int Tokenizer_emit_style_tag(Tokenizer* self, char tag, int ticks, | |||
| return -1; | |||
| } | |||
| Py_DECREF(token); | |||
| Py_DECREF(body); | |||
| return 0; | |||
| } | |||
| @@ -1953,42 +1954,82 @@ static int Tokenizer_parse_bold(Tokenizer* self) | |||
| */ | |||
| static int Tokenizer_parse_italics_and_bold(Tokenizer* self) | |||
| { | |||
| // 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_style_tag("i", "''", stack) | |||
| // else: | |||
| // self._push() | |||
| // self._emit_style_tag("i", "''", stack) | |||
| // self._emit_all(stack2) | |||
| // self._emit_style_tag("b", "'''", self._pop()) | |||
| // else: | |||
| // reset = self._head | |||
| // try: | |||
| // stack2 = self._parse(contexts.STYLE_ITALICS) | |||
| // except BadRoute: | |||
| // self._head = reset | |||
| // self._emit_text("''") | |||
| // self._emit_style_tag("b", "'''", stack) | |||
| // else: | |||
| // self._push() | |||
| // self._emit_style_tag("b", "'''", stack) | |||
| // self._emit_all(stack2) | |||
| // self._emit_style_tag("i", "''", self._pop()) | |||
| Py_ssize_t reset = self->head; | |||
| PyObject *stack, *stack2; | |||
| stack = Tokenizer_parse(self, LC_STYLE_BOLD, 1); | |||
| if (BAD_ROUTE) { | |||
| RESET_ROUTE(); | |||
| self->head = reset; | |||
| stack = Tokenizer_parse(self, LC_STYLE_ITALICS, 1); | |||
| if (BAD_ROUTE) { | |||
| RESET_ROUTE(); | |||
| self->head = reset; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| return Tokenizer_emit_text(self, *"'"); | |||
| } | |||
| if (!stack) | |||
| return -1; | |||
| reset = self->head; | |||
| stack2 = Tokenizer_parse(self, LC_STYLE_BOLD, 1); | |||
| if (BAD_ROUTE) { | |||
| RESET_ROUTE(); | |||
| self->head = reset; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| return Tokenizer_emit_style_tag(self, *"i", 2, stack); | |||
| } | |||
| if (!stack2) | |||
| return -1; | |||
| if (Tokenizer_push(self, 0)) | |||
| return -1; | |||
| if (Tokenizer_emit_style_tag(self, *"i", 2, stack)) | |||
| return -1; | |||
| if (Tokenizer_emit_all(self, stack2)) | |||
| return -1; | |||
| Py_DECREF(stack2); | |||
| stack2 = Tokenizer_pop(self); | |||
| if (!stack2) | |||
| return -1; | |||
| return Tokenizer_emit_style_tag(self, *"b", 3, stack2); | |||
| } | |||
| if (!stack) | |||
| return -1; | |||
| reset = self->head; | |||
| stack2 = Tokenizer_parse(self, LC_STYLE_ITALICS, 1); | |||
| if (BAD_ROUTE) { | |||
| RESET_ROUTE(); | |||
| self->head = reset; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return -1; | |||
| return Tokenizer_emit_style_tag(self, *"b", 3, stack); | |||
| } | |||
| if (!stack2) | |||
| return -1; | |||
| if (Tokenizer_push(self, 0)) | |||
| return -1; | |||
| if (Tokenizer_emit_style_tag(self, *"b", 3, stack)) | |||
| return -1; | |||
| if (Tokenizer_emit_all(self, stack2)) | |||
| return -1; | |||
| Py_DECREF(stack2); | |||
| stack2 = Tokenizer_pop(self); | |||
| if (!stack2) | |||
| return -1; | |||
| return Tokenizer_emit_style_tag(self, *"i", 2, stack2); | |||
| } | |||
| /* | |||
| @@ -1996,39 +2037,63 @@ static int Tokenizer_parse_italics_and_bold(Tokenizer* self) | |||
| */ | |||
| static PyObject* Tokenizer_parse_style(Tokenizer* self) | |||
| { | |||
| // self._head += 2 | |||
| // ticks = 2 | |||
| // while self._read() == "'": | |||
| // self._head += 1 | |||
| // ticks += 1 | |||
| // italics = self._context & contexts.STYLE_ITALICS | |||
| // bold = self._context & contexts.STYLE_BOLD | |||
| // if ticks > 5: | |||
| // self._emit_text("'" * (ticks - 5)) | |||
| // ticks = 5 | |||
| // elif ticks == 4: | |||
| // self._emit_text("'") | |||
| // ticks = 3 | |||
| // 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_SECOND_PASS: | |||
| // self._emit_text("'") | |||
| // return self._pop() | |||
| // self._context |= contexts.STYLE_PASS_AGAIN | |||
| // self._emit_text("'" * ticks) | |||
| // elif ticks == 2: | |||
| // self._parse_italics() | |||
| // elif ticks == 3: | |||
| // if self._parse_bold(): | |||
| // return self._pop() | |||
| // elif ticks == 5: | |||
| // self._parse_italics_and_bold() | |||
| // self._head -= 1 | |||
| // ## we can return Py_None for non-error empty returns | |||
| int context = self->topstack->context, ticks = 2, i; | |||
| self->head += 2; | |||
| while (Tokenizer_READ(self, 0) == *"'") { | |||
| self->head++; | |||
| ticks++; | |||
| } | |||
| if (ticks > 5) { | |||
| for (i = 0; i < ticks - 5; i++) { | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return NULL; | |||
| } | |||
| ticks = 5; | |||
| } | |||
| else if (ticks == 4) { | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return NULL; | |||
| ticks = 3; | |||
| } | |||
| if ((context & LC_STYLE_ITALICS && (ticks == 2 || ticks == 5)) || | |||
| (context & LC_STYLE_BOLD && (ticks == 3 || ticks == 5))) { | |||
| if (ticks == 5) | |||
| self->head -= context & LC_STYLE_ITALICS ? 3 : 2; | |||
| return Tokenizer_pop(self); | |||
| } | |||
| if (!Tokenizer_CAN_RECURSE(self)) { | |||
| if (ticks == 3) { | |||
| if (context & LC_STYLE_SECOND_PASS) { | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return NULL; | |||
| return Tokenizer_pop(self); | |||
| } | |||
| self->topstack->context |= LC_STYLE_PASS_AGAIN; | |||
| } | |||
| for (i = 0; i < ticks; i++) { | |||
| if (Tokenizer_emit_text(self, *"'")) | |||
| return NULL; | |||
| } | |||
| } | |||
| else if (ticks == 2) { | |||
| if (Tokenizer_parse_italics(self)) | |||
| return NULL; | |||
| } | |||
| else if (ticks == 3) { | |||
| switch (Tokenizer_parse_bold(self)) { | |||
| case 1: | |||
| return Tokenizer_pop(self); | |||
| case -1: | |||
| return NULL; | |||
| } | |||
| } | |||
| else { | |||
| if (Tokenizer_parse_italics_and_bold(self)) | |||
| return NULL; | |||
| } | |||
| self->head--; | |||
| return Py_None; | |||
| } | |||
| /* | |||
| @@ -2339,7 +2404,7 @@ static PyObject* Tokenizer_parse(Tokenizer* self, int context, int push) | |||
| return Tokenizer_handle_tag_close_close(self); | |||
| else if (this == next && next == *"'") { | |||
| temp = Tokenizer_parse_style(self); | |||
| if (temp) | |||
| if (temp != Py_None) | |||
| return temp; | |||
| } | |||
| else if (last == *"\n" || last == *"") { | |||