diff options
author | Zandr Martin <git@zandr.me> | 2019-08-13 07:49:18 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-08-16 09:23:43 +0900 |
commit | 5c782cda95427e7170bab7a9d7eef19c7c2d12d0 (patch) | |
tree | 25e4da760c1b2644ac346da2d15fcb5a1cacc4f4 | |
parent | 053c7705f337927c242290eeae6262ab597c999b (diff) |
fix bug preventing indented literal blocks1.9.7
This commit fixes a bug in parsing indented literal blocks. For example:
test(8)
```
This is a block
```
Prior to this commit, this would fail, but with an unexpected error
message: "Error at 4:3: Cannot deindent in literal block". The
indentation was being parsed at every character, so the parser saw the
`T`, then parsed indentation again. The indentation was 0 (since there
were no tab characters between the `T` and the `h`), but the block
started with an indentation level of 1. 0 < 1, so this would be
considered a dedent, which is not allowed.
This commit introduces a new local variable, `check_indent`, which
controls whether the parser tries to parse indentation or not; now
indentation is only parsed when the last character was a newline. From
my testing this seems to fix the issue - indented literal blocks are now
allowed.
-rw-r--r-- | src/main.c | 23 | ||||
-rwxr-xr-x | test/indent | 21 |
2 files changed, 36 insertions, 8 deletions
@@ -374,15 +374,19 @@ static void parse_literal(struct parser *p, int *indent) { int stops = 0; roff_macro(p, "nf", NULL); fprintf(p->output, ".RS 4\n"); + bool check_indent = true; do { - int _indent = *indent; - parse_indent(p, &_indent, false); - if (_indent < *indent) { - parser_fatal(p, "Cannot deindent in literal block"); - } - while (_indent > *indent) { - --_indent; - fprintf(p->output, "\t"); + if (check_indent) { + int _indent = *indent; + parse_indent(p, &_indent, false); + if (_indent < *indent) { + parser_fatal(p, "Cannot deindent in literal block"); + } + while (_indent > *indent) { + --_indent; + fprintf(p->output, "\t"); + } + check_indent = false; } if ((ch = parser_getch(p)) == UTF8_INVALID) { break; @@ -415,6 +419,9 @@ static void parse_literal(struct parser *p, int *indent) { utf8_fputch(p->output, ch); } break; + case '\n': + check_indent = true; + /* fallthrough */ default: utf8_fputch(p->output, ch); break; diff --git a/test/indent b/test/indent index 9ea38e1..6ce4892 100755 --- a/test/indent +++ b/test/indent @@ -54,3 +54,24 @@ Not indented Not indented EOF end 0 + +begin "Allows indented literal blocks" +scdoc <<EOF >/dev/null +test(8) + + \`\`\` + This block is indented. + \`\`\` +EOF +end 0 + +begin "Disallows dedenting in literal blocks" +scdoc <<EOF >/dev/null +test(8) + + \`\`\` + This block is indented. + This line is dedented past the start of the block. + \`\`\` +EOF +end 1 |