commit 9f74b6a0bf9794081b755274bbddd15deb6a10aa
parent a4193949ec755b3848a803a9b02364eeddbb1455
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 9 Dec 2017 23:34:45 -0500
Parse section headings
Diffstat:
M | src/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;
}