|
|
|
@ -40,8 +40,7 @@ static void parse_preamble(struct parser *p) { |
|
|
|
|
str_t *name = str_create(); |
|
|
|
|
int section = -1; |
|
|
|
|
uint32_t ch; |
|
|
|
|
do { |
|
|
|
|
ch = parser_getch(p); |
|
|
|
|
while ((ch = parser_getch(p)) != UTF8_INVALID) { |
|
|
|
|
if (isalnum(ch)) { |
|
|
|
|
assert(str_append_ch(name, ch) != -1); |
|
|
|
|
} else if (ch == '(') { |
|
|
|
@ -57,11 +56,81 @@ static void parse_preamble(struct parser *p) { |
|
|
|
|
roff_macro(p, "TH", name->str, sec, date, NULL); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} while (ch != UTF8_INVALID); |
|
|
|
|
} |
|
|
|
|
str_free(name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void output_preamble(struct parser *p) { |
|
|
|
|
static void parse_text(struct parser *p) { |
|
|
|
|
uint32_t ch; |
|
|
|
|
while ((ch = parser_getch(p)) != UTF8_INVALID) { |
|
|
|
|
switch (ch) { |
|
|
|
|
case '\\': |
|
|
|
|
fprintf(p->output, "\\\\"); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
utf8_fputch(p->output, ch); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (ch == '\n') { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void parse_heading(struct parser *p) { |
|
|
|
|
uint32_t ch; |
|
|
|
|
int level = 1; |
|
|
|
|
while ((ch = parser_getch(p)) != UTF8_INVALID) { |
|
|
|
|
if (ch == '#') { |
|
|
|
|
++level; |
|
|
|
|
} else if (ch == ' ') { |
|
|
|
|
break; |
|
|
|
|
} else { |
|
|
|
|
parser_fatal(p, "Invalid start of heading (probably needs a space)"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
switch (level) { |
|
|
|
|
case 1: |
|
|
|
|
fprintf(p->output, ".SH "); |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
fprintf(p->output, ".SS "); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
parser_fatal(p, "Only headings up to two levels deep are permitted"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
while ((ch = parser_getch(p)) != UTF8_INVALID) { |
|
|
|
|
utf8_fputch(p->output, ch); |
|
|
|
|
if (ch == '\n') { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void parse_document(struct parser *p) { |
|
|
|
|
uint32_t ch; |
|
|
|
|
while ((ch = parser_getch(p)) != UTF8_INVALID) { |
|
|
|
|
switch (ch) { |
|
|
|
|
case '#': |
|
|
|
|
parse_heading(p); |
|
|
|
|
break; |
|
|
|
|
case '\n': |
|
|
|
|
roff_macro(p, "P", NULL); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
if (ch == '.') { |
|
|
|
|
fprintf(p->output, "\\&."); |
|
|
|
|
} else { |
|
|
|
|
utf8_fputch(p->output, ch); |
|
|
|
|
} |
|
|
|
|
parse_text(p); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void output_scdoc_preamble(struct parser *p) { |
|
|
|
|
// TODO: Add version here
|
|
|
|
|
fprintf(p->output, ".\\\" Generated by scdoc\n"); |
|
|
|
|
fprintf(p->output, ".\\\" Fix weird qutation marks:\n"); |
|
|
|
@ -89,7 +158,8 @@ int main(int argc, char **argv) { |
|
|
|
|
.line = 1, |
|
|
|
|
.col = 1 |
|
|
|
|
}; |
|
|
|
|
output_preamble(&p); |
|
|
|
|
output_scdoc_preamble(&p); |
|
|
|
|
parse_preamble(&p); |
|
|
|
|
parse_document(&p); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|