From 3a5abb2538905a0f7243811aa453073bdf4f7ac2 Mon Sep 17 00:00:00 2001 From: Nate Choe Date: Sun, 1 May 2022 02:45:05 -0500 Subject: [PATCH] Inline code spans --- src/include/inlines.h | 26 +++++++++++++ src/inlines.c | 87 +++++++++++++++++++++++++++++++++++++++++++ src/template.c | 22 +++++------ 3 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 src/include/inlines.h create mode 100644 src/inlines.c diff --git a/src/include/inlines.h b/src/include/inlines.h new file mode 100644 index 0000000..966272c --- /dev/null +++ b/src/include/inlines.h @@ -0,0 +1,26 @@ +/* + 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 . + */ +#ifndef HAVE_INLINES +#define HAVE_INLINES + +#include + +void writeline(char *data, FILE *out); +void writedata(char *data, size_t len, FILE *out); + +#endif diff --git a/src/inlines.c b/src/inlines.c new file mode 100644 index 0000000..2d967d2 --- /dev/null +++ b/src/inlines.c @@ -0,0 +1,87 @@ +#include + +#include + +static const char *punctuation = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; +struct escape { + char c; + char *code; +}; +struct escape escapes[] = { + {'<', "<"}, + {'>', ">"}, + {'&', "&"}, +}; + +static int writecodespan(char *data, int i, size_t len, FILE *out); +static void writeescaped(char *data, size_t len, FILE *out); +static void writechescape(char c, FILE *out); + +void writeline(char *data, FILE *out) { + writedata(data, strlen(data), out); +} + +void writedata(char *data, size_t len, FILE *out) { + int i; + for (i = 0; i < len; ++i) { + int newi; + if ((newi = writecodespan(data, i, len, out)) >= 0) + goto special; + if (data[i] == '\\') { + if (strchr(punctuation, data[i + 1]) == NULL) + writechescape('\\', out); + ++i; + } + writechescape(data[i], out); + continue; +special: + i = newi - 1; + } +} + +static int writecodespan(char *data, int i, size_t len, FILE *out) { + int ticklen; + int start, end; + + if (data[i] != '`') + return -1; + for (ticklen = 0; data[i + ticklen] == '`'; ++ticklen) ; + + start = i + ticklen; + for (end = start; end < len; ++end) { + int thislen; + if (data[end] != '`') + continue; + for (thislen = 0; data[end + thislen] == '`'; ++thislen); + if (ticklen == thislen) + break; + end += thislen - 1; + } + if (end >= len) { + for (i = 0; i < ticklen; ++i) + fputc('`', out); + return start + ticklen; + } + + fputs("", out); + writeescaped(data + start, end - start, out); + fputs("", out); + return end + ticklen; +} + +static void writeescaped(char *data, size_t len, FILE *out) { + int i; + for (i = 0; i < len; ++i) + writechescape(data[i], out); +} + +static void writechescape(char c, FILE *out) { + int i; + for (i = 0; i < sizeof escapes / sizeof *escapes; ++i) { + if (escapes[i].c == c) { + fputs(escapes[i].code, out); + return; + } + } + fputc(c, out); +} diff --git a/src/template.c b/src/template.c index 25f20a7..39e9b94 100644 --- a/src/template.c +++ b/src/template.c @@ -23,6 +23,7 @@ #include #include #include +#include #include struct parsestate { @@ -80,12 +81,10 @@ static int parseline(char *line, struct parsestate *currstate, FILE *out) { type.data.intensity >= currstate->intensity) { currstate->prev.type = EMPTY; - fputs("", out); + fputs("", out); return 0; } - if (!currstate->isfirst) - fputs("
", out); - fputs(line, out); + fprintf(out, "%s\n", line); currstate->isfirst = 0; return 0; case HTMLCONCRETE: @@ -124,7 +123,7 @@ static int parseline(char *line, struct parsestate *currstate, FILE *out) { return 1; currstate->prev.type = EMPTY; fputs("

", out); - fwrite(currstate->para->data, 1, currstate->para->len, out); + writedata(currstate->para->data, currstate->para->len, out); fputs("

", out); resetstring(currstate->para); break; @@ -133,7 +132,7 @@ static int parseline(char *line, struct parsestate *currstate, FILE *out) { goto hr; currstate->prev.type = EMPTY; fputs("

", out); - fwrite(currstate->para->data, 1, currstate->para->len, out); + writedata(currstate->para->data, currstate->para->len, out); fputs("

", out); resetstring(currstate->para); break; @@ -169,7 +168,7 @@ static int parseline(char *line, struct parsestate *currstate, FILE *out) { * as to not include the wrong tags. * */ case FENCECODE: - fputs("", out); + fputs("
", out);
 		currstate->prev.type = FENCECODE;
 		currstate->isfirst = 1;
 		currstate->intensity = type.data.intensity;
@@ -186,10 +185,9 @@ static int parseline(char *line, struct parsestate *currstate, FILE *out) {
 		break;
 	case HEADER:
 		endpara(currstate, out);
-		fprintf(out, "%s",
-				type.data.intensity,
-				realcontent(line, &type),
-				type.data.intensity);
+		fprintf(out, "", type.data.intensity);
+		writeline(realcontent(line, &type), out);
+		fprintf(out, "", type.data.intensity);
 		currstate->prev.type = EMPTY;
 		break;
 	case HTMLCONCRETE:
@@ -225,7 +223,7 @@ static int endpara(struct parsestate *state, FILE *out) {
 		return 0;
 	case PLAIN:
 		fputs("

", out); - fwrite(state->para->data, 1, state->para->len, out); + writedata(state->para->data, state->para->len, out); fputs("

", out); resetstring(state->para); return 0;