Chapter 1
", out);
+ }
+ else
+ fputs("
", out);
+ fputs(realcontent(line, type), out);
+ break;
}
- return count >= 3;
return 0;
}
-static enum paratype identifypara(char *line, char **contentret) {
- int i;
- for (i = 0; i < 4; ++i) {
- if (line[i] == ' ')
- continue;
- if (line[i] == '\0')
- return EMPTY;
- goto whitegone;
- }
-
- *contentret = line + i;
- return CODESPACE;
-
-whitegone:
- line += i;
- /* At this point, line has no extraneous trailing whitespace */
- switch (line[0]) {
- case '\0':
- return EMPTY;
- case '#':
- for (i = 0; i < 6 && line[i] == '#'; ++i) ;
- *contentret = line + i;
- if (line[i] != '\0' && line[i] != ' ')
- goto normal;
- return H1 + i - 1;
- case '>':
- *contentret = line + 1;
- return BLOCKQUOTE;
- case '*':
- if (isbreak(line))
- return HL;
- *contentret = line + 1;
- return UL;
- case '-': case '_':
- if (isbreak(line))
- return HL;
- goto normal;
- case '`':
- for (i = 0; i < 3; ++i)
- if (line[i] != '`')
- goto normal;
- return CODEBACK;
- default:
- if (isdigit(line[0])) {
- for (i = 0; isdigit(line[i]); ++i) ;
- if (line[i] == '.' || line[i] == ')') {
- *contentret = line + i + 1;
- return OL;
- }
- }
- goto normal;
- normal:
- *contentret = line;
- return NORMAL;
- }
-}
-
-static char *untrail(char *line) {
- while (isspace(line[0]))
- ++line;
- return line;
-}
-
-static size_t reallen(char *line) {
- size_t fakelen;
- fakelen = strlen(line);
- if (line[fakelen - 1] == '\\')
- --fakelen;
- while (isspace(line[fakelen]))
- --fakelen;
- return fakelen;
-}
-
-static int islinebreak(char *line) {
- size_t len;
- int i;
- len = strlen(line);
- if (line[len - 1] == '\\')
- return 1;
- if (len < 2)
+static int endpara(struct parsestate *state, FILE *out) {
+ switch (state->type) {
+ case PARAGRAPH:
+ fputs("", out);
+ fwrite(state->para->data, 1, state->para->len, out);
+ fputs("
", out);
+ resetstring(state->para);
return 0;
- for (i = 0; i < 2; ++i)
- if (!isspace(line[len - i - 1]))
- return 0;
+ case CODE:
+ fputs("", out);
+ return 0;
+ case NONE:
+ return 0;
+ }
return 1;
}
-
-static int paraeasycase(struct linefile *infile, FILE *outfile,
- char *line, char *buff,
- char *tag, enum paratype type) {
- size_t writelen;
-
- writelen = reallen(buff);
-
- fprintf(outfile, "<%s>", tag);
- for (;;) {
- writedata(buff, writelen, outfile);
- free(line);
- line = getline(infile);
- if (line == NULL)
- break;
- if (identifypara(line, &buff) != type) {
- ungetline(infile, line);
- line = NULL;
- break;
- }
- else
- buff = untrail(buff);
- }
- fprintf(outfile, "%s>", tag);
-
- free(line);
- return 0;
-}
-
-static int parahardcase(struct linefile *infile, FILE *outfile,
- char *line, char *buff,
- char *vars, char *linetag, char *tag, enum paratype type) {
- size_t writelen;
-
- if (vars == NULL)
- fprintf(outfile, "<%s>", tag);
- else
- fprintf(outfile, "<%s %s>", tag, vars);
- for (;;) {
- writelen = reallen(buff);
-
- if (linetag != NULL)
- fprintf(outfile, "<%s>", linetag);
- writedata(buff, writelen, outfile);
- if (islinebreak(line))
- fputs("", outfile);
- else
- fprintf(outfile, "", vars);
- seenfirst = 0;
- newtype = type;
- for (;;) {
- if ((type == CODEBACK && type != newtype) ||
- newtype == CODESPACE) {
- if (seenfirst)
- fputs("
", outfile);
- seenfirst = 1;
- }
-
- if (newtype != CODEBACK)
- writesimple(buff, -1, outfile);
-
- free(line);
- line = getline(infile);
- if (line == NULL)
- return 1;
-
- newtype = identifypara(line, &buff);
- if (type == CODEBACK && newtype == CODEBACK)
- break;
- if (type == CODESPACE && newtype != type) {
- ungetline(infile, line);
- break;
- }
- }
- fputs("", outfile);
-
- if (type == CODEBACK)
- free(line);
- return 0;
-}
-
-static long strsearch(char *data, long start, size_t datalen,
- char c, int reps) {
- long i;
-
- for (i = start; data[i] == c; ++i) ;
-
- while (i + reps - 1 < datalen) {
- int j;
- for (j = 0; j < reps; ++j)
- if (data[i + j] != c)
- goto failure;
- goto success;
- continue;
-failure:
- ++i;
- }
- return -1;
-
-success:
- while (data[i + reps] == c && i + reps < datalen)
- ++i;
- return i;
-}
-
-static long writelinked(char *data, long i, size_t len, char *tag,
- FILE *outfile) {
- long linkend, textend;
- textend = strsearch(data, i, len, ']', 1);
- if (textend < 0)
- return -1;
- linkend = strsearch(data, textend, len, ')', 1);
- if (linkend < 0)
- return -1;
- if (strcmp(tag, "a") == 0) {
- fputs("", outfile);
- writesimple(data + i + 1,
- textend - i - 1, outfile);
- fputs("", outfile);
- return linkend;
- }
- else if (strcmp(tag, "img") == 0) {
- fputs("
", outfile);
- return linkend;
- }
- return -1;
-}
-
-static int writeescape(char c, FILE *outfile) {
- int i;
- for (i = 0; i < sizeof escapes / sizeof *escapes; ++i) {
- if (escapes[i].c == c) {
- fputs(escapes[i].escape, outfile);
- return 0;
- }
- }
- fputc(c, outfile);
- return 0;
-}
-
-static int writedata(char *data, size_t len, FILE *outfile) {
- long i;
- long start;
- long end;
- for (i = 0; i < len; ++i) {
- switch (data[i]) {
-#define STANDOUT_CHAR(c) \
- case c: \
- if (data[i + 1] == c) { \
- start = i + 2; \
- end = strsearch(data, start, len, \
- c, 2); \
- goto bold; \
- } \
- start = i + 1; \
- end = strsearch(data, start, len, c, 1); \
- goto italic;
- STANDOUT_CHAR('*');
- STANDOUT_CHAR('_');
- italic:
- if (end < 0)
- goto normal;
- fputs("", outfile);
- writedata(data + start, end - start, outfile);
- fputs("", outfile);
- i = end;
- break;
- bold:
- if (end < 0)
- goto normal;
- fputs("", outfile);
- writedata(data + start, end - start, outfile);
- fputs("", outfile);
- i = end + 1;
- break;
-
- case '`':
- end = strsearch(data, i, len, '`', 1);
- if (end < 0)
- goto normal;
- fputs("", outfile);
- writedata(data + i, end - i, outfile);
- fputs("", outfile);
- i = end;
- break;
- case '[':
- end = writelinked(data, i, len, "a", outfile);
- if (end < 0)
- goto normal;
- i = end;
- break;
- case '!':
- end = writelinked(data, i + 1, len, "img", outfile);
- if (end < 0)
- goto normal;
- i = end;
- break;
- case '\\':
- if (i == len ||
- strchr(escapedchars, data[i+1]) == NULL) {
- fputc('\\', outfile);
- break;
- }
- ++i;
- goto normal;
- default: normal:
- writeescape(data[i], outfile);
- break;
- }
- }
- return 0;
-}
-
-static int writesimple(char *data, size_t len, FILE *outfile) {
- long i;
- for (i = 0; (len < 0 && data[i] != '\0') || i < len; ++i) {
- if (data[i] == '\\')
- if (strchr(escapedchars, data[i]) == NULL)
- fputc('\\', outfile);
- writeescape(data[i], outfile);
- }
- return 0;
-}
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..51261b6
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,79 @@
+/*
+ ncdg - A program to help generate natechoe.dev
+ Copyright (C) 2022 Nate Choe (natechoe9@gmail.com)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+#include
+#include
+
+#include
+
+struct string *newstring() {
+ struct string *ret;
+ ret = malloc(sizeof *ret);
+ if (ret == NULL)
+ return NULL;
+ ret->len = 0;
+ ret->alloc = 20;
+ ret->data = malloc(ret->alloc);
+ if (ret->data == NULL)
+ return NULL;
+ return ret;
+}
+
+void freestring(struct string *str) {
+ free(str->data);
+ free(str);
+}
+
+int appendcharstring(struct string *str, char c) {
+ if (str->len >= str->alloc) {
+ char *newdata;
+ size_t newalloc;
+ newalloc = str->alloc * 2;
+ newdata = realloc(str->data, newalloc);
+ if (newdata == NULL) {
+ return 1;
+ }
+ str->data = newdata;
+ str->alloc = newalloc;
+ }
+ str->data[str->len++] = c;
+ return 0;
+}
+
+int appendstrstring(struct string *str, char *s) {
+ size_t len;
+ len = strlen(s);
+ if (str->len + len >= str->alloc) {
+ char *newdata;
+ size_t newalloc;
+ newalloc = str->alloc;
+ while (str->len + len >= newalloc)
+ newalloc *= 2;
+ newdata = realloc(str->data, newalloc);
+ if (newdata == NULL)
+ return 1;
+ str->data = newdata;
+ str->alloc = newalloc;
+ }
+ memcpy(str->data + str->len, s, len);
+ str->len += len;
+ return 0;
+}
+
+void resetstring(struct string *str) {
+ str->len = 0;
+}