Make test pass with preformatted block

This commit is contained in:
Nathan Fisher 2023-10-25 23:05:10 -04:00
parent c20957b1be
commit b4c0b24a4a
3 changed files with 38 additions and 5 deletions

View file

@ -302,7 +302,7 @@ void switchMode(gemtextParser *parser, gemtextParserMode mode, char c) {
void enterPreformattedMode(gemtextParser *parser) { void enterPreformattedMode(gemtextParser *parser) {
parser->mode = preformattedMode; parser->mode = preformattedMode;
parser->state = preformattedAlt; parser->state = trimStart;
lineBufferReset(&parser->buffer); lineBufferReset(&parser->buffer);
} }
@ -360,13 +360,24 @@ int parsePreformatted(gemtextParser *parser, gemtextLineQueue *lq, char c) {
assert(parser->mode == preformattedMode); assert(parser->mode == preformattedMode);
switch (parser->state) { switch (parser->state) {
case trimStart:
if (c == '\n') {
parser->state = lineStart;
parser->altText = NULL;
} else if (c == ' ' || c == '\t') {
lineBufferRewind(&parser->buffer);
} else {
parser->state = preformattedAlt;
}
break;
case preformattedAlt: case preformattedAlt:
if (c == '\n') { if (c == '\n') {
parser->state = normalState; parser->state = lineStart;
if (parser->buffer.len > 0) { if (parser->buffer.len > 0) {
buf = strncpy(buf, parser->buffer.buf, parser->buffer.len); buf = strndup(parser->buffer.buf, parser->buffer.len - 1);
if (buf == NULL) return errno; if (buf == NULL) return errno;
parser->altText = buf; parser->altText = buf;
lineBufferReset(&parser->buffer);
} }
} }
break; break;
@ -377,7 +388,11 @@ int parsePreformatted(gemtextParser *parser, gemtextLineQueue *lq, char c) {
break; break;
case lineStart: case lineStart:
if (c == '\n') { if (c == '\n') {
parser->state = lineStart;
} else if (c == '`') {
parser->state = firstBacktickChar; parser->state = firstBacktickChar;
} else {
parser->state = normalState;
} }
break; break;
case firstBacktickChar: case firstBacktickChar:
@ -564,6 +579,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
parser->state = normalState; parser->state = normalState;
parser->mode = normalMode; parser->mode = normalMode;
} }
break;
case secondBacktickChar: case secondBacktickChar:
if (c == '`') { if (c == '`') {
enterPreformattedMode(parser); enterPreformattedMode(parser);
@ -574,6 +590,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
parser->state = normalState; parser->state = normalState;
parser->mode = normalMode; parser->mode = normalMode;
} }
break;
default: default:
break; break;
} }

View file

@ -81,7 +81,17 @@ int main() {
assert(memcmp(line->link->display, "This is a link", 14) == 0); assert(memcmp(line->link->display, "This is a link", 14) == 0);
gemtextLineDeinit(line); gemtextLineDeinit(line);
gemtextLineDeinit(lq.head); line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(*line->str == '\n');
gemtextLineDeinit(line);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == preformattedLine);
assert(memcmp(line->node->altText, "Test preformatted block", 23) == 0);
assert(memcmp(line->node->body, "This is a preformatted block", 28) == 0);
gemtextLineDeinit(line);
gemtextParserDeinit(&parser); gemtextParserDeinit(&parser);
return ret; return ret;
} }

View file

@ -11,3 +11,9 @@ This is a simple gemtext file used for testing the gemtext parser. There's nothi
* second item * second item
=> gemini://example.org/test.gmi This is a link => gemini://example.org/test.gmi This is a link
``` Test preformatted block
This is a preformatted block.
Everything in this block should appear exactly as entered in a Monospace font,
with no styling applied.
```