diff --git a/src/main.c b/src/main.c index 37c64ac..504ff4b 100644 --- a/src/main.c +++ b/src/main.c @@ -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; }