summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZandr Martin <git@zandr.me>2019-08-13 07:49:18 -0400
committerDrew DeVault <sir@cmpwn.com>2019-08-16 09:23:43 +0900
commit5c782cda95427e7170bab7a9d7eef19c7c2d12d0 (patch)
tree25e4da760c1b2644ac346da2d15fcb5a1cacc4f4
parent053c7705f337927c242290eeae6262ab597c999b (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.c23
-rwxr-xr-xtest/indent21
2 files changed, 36 insertions, 8 deletions
diff --git a/src/main.c b/src/main.c
index 72b7eaf..cf14288 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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