scdoc2mdoc

A fork of scdoc to output mdoc(7)
git clone git://git.sgregoratto.me/scdoc2mdoc
Log | Files | Refs | README | LICENSE

commit 9f74b6a0bf9794081b755274bbddd15deb6a10aa
parent a4193949ec755b3848a803a9b02364eeddbb1455
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat,  9 Dec 2017 23:34:45 -0500

Parse section headings

Diffstat:
Msrc/main.c | 80++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 75 insertions(+), 5 deletions(-)

diff --git 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; }