|
@@ -962,8 +962,9 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
self->global |= GL_HEADING; |
|
|
self->global |= GL_HEADING; |
|
|
Py_ssize_t reset = self->head; |
|
|
Py_ssize_t reset = self->head; |
|
|
self->head += 1; |
|
|
self->head += 1; |
|
|
Py_ssize_t best = 1, i; |
|
|
|
|
|
|
|
|
Py_ssize_t best = 1; |
|
|
PyObject* text; |
|
|
PyObject* text; |
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
while (Tokenizer_READ(self, 0) == PU "=") { |
|
|
while (Tokenizer_READ(self, 0) == PU "=") { |
|
|
best++; |
|
|
best++; |
|
@@ -988,11 +989,11 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
HeadingData* heading = (HeadingData*) Tokenizer_parse(self, context); |
|
|
HeadingData* heading = (HeadingData*) Tokenizer_parse(self, context); |
|
|
if (!heading) return -1; |
|
|
|
|
|
|
|
|
|
|
|
PyObject* level = PyInt_FromSsize_t(heading->level); |
|
|
PyObject* level = PyInt_FromSsize_t(heading->level); |
|
|
if (!level) { |
|
|
if (!level) { |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -1000,6 +1001,7 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
if (!class) { |
|
|
if (!class) { |
|
|
Py_DECREF(level); |
|
|
Py_DECREF(level); |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
PyObject* kwargs = PyDict_New(); |
|
|
PyObject* kwargs = PyDict_New(); |
|
@@ -1007,6 +1009,7 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
Py_DECREF(class); |
|
|
Py_DECREF(class); |
|
|
Py_DECREF(level); |
|
|
Py_DECREF(level); |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
PyDict_SetItemString(kwargs, "level", level); |
|
|
PyDict_SetItemString(kwargs, "level", level); |
|
@@ -1015,11 +1018,16 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
PyObject* token = PyInstance_New(class, NOARGS, kwargs); |
|
|
PyObject* token = PyInstance_New(class, NOARGS, kwargs); |
|
|
Py_DECREF(class); |
|
|
Py_DECREF(class); |
|
|
Py_DECREF(kwargs); |
|
|
Py_DECREF(kwargs); |
|
|
if (!token) return -1; |
|
|
|
|
|
|
|
|
if (!token) { |
|
|
|
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (Tokenizer_write(self, token)) { |
|
|
if (Tokenizer_write(self, token)) { |
|
|
Py_DECREF(token); |
|
|
Py_DECREF(token); |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
Py_DECREF(token); |
|
|
Py_DECREF(token); |
|
@@ -1027,16 +1035,18 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
if (heading->level < best) { |
|
|
if (heading->level < best) { |
|
|
Py_ssize_t diff = best - heading->level; |
|
|
Py_ssize_t diff = best - heading->level; |
|
|
char diffblocks[diff]; |
|
|
char diffblocks[diff]; |
|
|
for (i = 0; i < diff; i++) diffblocks[i] = *"{"; |
|
|
|
|
|
|
|
|
for (i = 0; i < diff; i++) diffblocks[i] = *"="; |
|
|
PyObject* text = PyUnicode_FromString(diffblocks); |
|
|
PyObject* text = PyUnicode_FromString(diffblocks); |
|
|
if (!text) { |
|
|
if (!text) { |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (Tokenizer_write_text_then_stack(self, text)) { |
|
|
if (Tokenizer_write_text_then_stack(self, text)) { |
|
|
Py_DECREF(text); |
|
|
Py_DECREF(text); |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
Py_DECREF(text); |
|
|
Py_DECREF(text); |
|
@@ -1044,9 +1054,11 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
|
|
|
|
|
|
if (Tokenizer_write_all(self, heading->title)) { |
|
|
if (Tokenizer_write_all(self, heading->title)) { |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
Py_DECREF(heading->title); |
|
|
Py_DECREF(heading->title); |
|
|
|
|
|
free(heading); |
|
|
|
|
|
|
|
|
class = PyObject_GetAttrString(tokens, "HeadingEnd"); |
|
|
class = PyObject_GetAttrString(tokens, "HeadingEnd"); |
|
|
if (!class) return -1; |
|
|
if (!class) return -1; |
|
@@ -1071,7 +1083,79 @@ Tokenizer_parse_heading(Tokenizer* self) |
|
|
static HeadingData* |
|
|
static HeadingData* |
|
|
Tokenizer_handle_heading_end(Tokenizer* self) |
|
|
Tokenizer_handle_heading_end(Tokenizer* self) |
|
|
{ |
|
|
{ |
|
|
|
|
|
Py_ssize_t reset = self->head; |
|
|
|
|
|
self->head += 1; |
|
|
|
|
|
Py_ssize_t best = 1; |
|
|
|
|
|
PyObject* text; |
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
while (Tokenizer_READ(self, 0) == PU "=") { |
|
|
|
|
|
best++; |
|
|
|
|
|
self->head++; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Py_ssize_t current = LC_HEADING_LEVEL_1 << (best > 5 ? 5 : best - 1); // FIXME |
|
|
|
|
|
Py_ssize_t level = current > best ? (best > 6 ? 6 : best) : (current > 6 ? 6 : current); |
|
|
|
|
|
|
|
|
|
|
|
if (setjmp(exception_env) == BAD_ROUTE) { |
|
|
|
|
|
if (level < best) { |
|
|
|
|
|
Py_ssize_t diff = best - level; |
|
|
|
|
|
char diffblocks[diff]; |
|
|
|
|
|
for (i = 0; i < diff; i++) diffblocks[i] = *"="; |
|
|
|
|
|
text = PyUnicode_FromString(diffblocks); |
|
|
|
|
|
if (!text) return NULL; |
|
|
|
|
|
|
|
|
|
|
|
if (Tokenizer_write_text_then_stack(self, text)) { |
|
|
|
|
|
Py_DECREF(text); |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
Py_DECREF(text); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self->head = reset + best - 1; |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
Py_ssize_t context = Tokenizer_CONTEXT_VAL(self); |
|
|
|
|
|
HeadingData* after = (HeadingData*) Tokenizer_parse(self, context); |
|
|
|
|
|
|
|
|
|
|
|
char blocks[best]; |
|
|
|
|
|
for (i = 0; i < best; i++) blocks[i] = *"="; |
|
|
|
|
|
text = PyUnicode_FromString(blocks); |
|
|
|
|
|
if (!text) { |
|
|
|
|
|
Py_DECREF(after->title); |
|
|
|
|
|
free(after); |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (Tokenizer_write_text_then_stack(self, text)) { |
|
|
|
|
|
Py_DECREF(text); |
|
|
|
|
|
Py_DECREF(after->title); |
|
|
|
|
|
free(after); |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
Py_DECREF(text); |
|
|
|
|
|
|
|
|
|
|
|
if (Tokenizer_write_all(self, after->title)) { |
|
|
|
|
|
Py_DECREF(after->title); |
|
|
|
|
|
free(after); |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
Py_DECREF(after->title); |
|
|
|
|
|
level = after->level; |
|
|
|
|
|
free(after); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PyObject* stack = Tokenizer_pop(self); |
|
|
|
|
|
if (!stack) return NULL; |
|
|
|
|
|
|
|
|
|
|
|
HeadingData* heading = malloc(sizeof(HeadingData)); |
|
|
|
|
|
if (!heading) { |
|
|
|
|
|
PyErr_NoMemory(); |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
heading->title = stack; |
|
|
|
|
|
heading->level = level; |
|
|
|
|
|
return heading; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
@@ -1184,11 +1268,10 @@ Tokenizer_parse_comment(Tokenizer* self) |
|
|
static PyObject* |
|
|
static PyObject* |
|
|
Tokenizer_parse(Tokenizer* self, Py_ssize_t context) |
|
|
Tokenizer_parse(Tokenizer* self, Py_ssize_t context) |
|
|
{ |
|
|
{ |
|
|
Py_ssize_t fail_contexts = LC_TEMPLATE | LC_ARGUMENT | LC_HEADING | LC_COMMENT; |
|
|
|
|
|
|
|
|
|
|
|
PyObject *this; |
|
|
PyObject *this; |
|
|
Py_UNICODE *this_data, *next, *next_next, *last; |
|
|
Py_UNICODE *this_data, *next, *next_next, *last; |
|
|
Py_ssize_t this_context; |
|
|
Py_ssize_t this_context; |
|
|
|
|
|
Py_ssize_t fail_contexts = LC_TEMPLATE | LC_ARGUMENT | LC_HEADING | LC_COMMENT; |
|
|
int is_marker, i; |
|
|
int is_marker, i; |
|
|
|
|
|
|
|
|
Tokenizer_push(self, context); |
|
|
Tokenizer_push(self, context); |
|
|