Implement literal sections

master
Drew DeVault 7 years ago
parent 688923fabc
commit 5f44aae0f7
  1. 79
      src/main.c

@ -150,19 +150,21 @@ static void parse_heading(struct parser *p) {
}
}
static int parse_indent(struct parser *p, int *indent) {
static int parse_indent(struct parser *p, int *indent, bool write) {
int i = 0;
uint32_t ch;
while ((ch = parser_getch(p)) == '\t') {
++i;
}
parser_pushch(p, ch);
if (i == *indent - 1) {
roff_macro(p, "RE", NULL);
} else if (i == *indent + 1) {
roff_macro(p, "RS", "4", NULL);
} else if (i != *indent && ch == '\t') {
parser_fatal(p, "(De)indented by an amount greater than 1");
if (write) {
if (i == *indent - 1) {
roff_macro(p, "RE", NULL);
} else if (i == *indent + 1) {
roff_macro(p, "RS", "4", NULL);
} else if (i != *indent && ch == '\t') {
parser_fatal(p, "(De)indented by an amount greater than 1");
}
}
*indent = i;
return i;
@ -176,7 +178,7 @@ static void parse_list(struct parser *p, int *indent) {
roff_macro(p, "IP", "\\(bu", "4", NULL);
parse_text(p);
do {
parse_indent(p, indent);
parse_indent(p, indent, true);
if ((ch = parser_getch(p)) == UTF8_INVALID) {
break;
}
@ -199,11 +201,67 @@ static void parse_list(struct parser *p, int *indent) {
} while (ch != UTF8_INVALID);
}
static void parse_literal(struct parser *p, int *indent) {
uint32_t ch;
if ((ch = parser_getch(p)) != '`' ||
(ch = parser_getch(p)) != '`' ||
(ch = parser_getch(p)) != '\n') {
parser_fatal(p, "Expected ``` and a newline to begin literal block");
}
int stops = 0;
roff_macro(p, "nf", NULL);
roff_macro(p, "RS", "4", NULL);
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 ((ch = parser_getch(p)) == UTF8_INVALID) {
break;
}
if (ch == '`') {
if (++stops == 3) {
if ((ch = parser_getch(p)) != '\n') {
parser_fatal(p, "Expected literal block to end with newline");
}
roff_macro(p, "fi", NULL);
roff_macro(p, "RE", NULL);
return;
}
} else {
stops = 0;
switch (ch) {
case '.':
fprintf(p->output, "\\&.");
break;
case '\\':
ch = parser_getch(p);
if (ch == UTF8_INVALID) {
parser_fatal(p, "Unexpected EOF");
} else if (ch == '\\') {
fprintf(p->output, "\\\\");
} else {
utf8_fputch(p->output, ch);
}
break;
default:
utf8_fputch(p->output, ch);
break;
}
}
} while (ch != UTF8_INVALID);
}
static void parse_document(struct parser *p) {
uint32_t ch;
int indent = 0;
do {
parse_indent(p, &indent);
parse_indent(p, &indent, true);
if ((ch = parser_getch(p)) == UTF8_INVALID) {
break;
}
@ -219,6 +277,9 @@ static void parse_document(struct parser *p) {
case '-':
parse_list(p, &indent);
break;
case '`':
parse_literal(p, &indent);
break;
case ' ':
parser_fatal(p, "Tabs are required for indentation");
break;

Loading…
Cancel
Save