diff options
-rw-r--r-- | Makefile | 17 | ||||
-rw-r--r-- | README.md | 28 | ||||
-rw-r--r-- | cat.c | 34 | ||||
-rw-r--r-- | md2html.c | 322 |
4 files changed, 346 insertions, 55 deletions
diff --git a/Makefile b/Makefile index f0d9e30..cccffaf 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,18 @@ CC=gcc CC_OPTS=-g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone -fno-omit-frame-pointer -pg -mnop-mcount INCLUDE=-fuse-ld=bfd -Wl,-T,ape/ape.lds -include ape/cosmopolitan.h ape/crt.o ape/ape.o ape/cosmopolitan.a -all: cat.com +NAME=md2html -cat.com.dbg: cat.c - $(CC) $(CC_OPTS) cat.c -o cat.com.dbg $(INCLUDE) +all: $(NAME).com -cat.com: cat.com.dbg - objcopy -S -O binary cat.com.dbg cat.com +$(NAME).com.dbg: $(NAME).c + $(CC) $(CC_OPTS) $(NAME).c -o $(NAME).com.dbg $(INCLUDE) + +$(NAME).com: $(NAME).com.dbg + objcopy -S -O binary $(NAME).com.dbg $(NAME).com clean: - rm cat.com cat.com.dbg + rm $(NAME).com $(NAME).com.dbg + +deploy: $(NAME).com + scp $(NAME).com srv1:/var/www/niedzwiedzinski.cyou/$(NAME).com diff --git a/README.md b/README.md index 7a93879..90c0adb 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,32 @@ -# cat +# md2html -This is a simple C program that outputs file content. The magic is that it works -on Linux, *BSD, macOs, Windows thanks to [cosmopolitan](https://github.com/jart/cosmopolitan). +> Markdown to html renderer that works on Windows -I created this repo as a project template for simple ape programs. `/ape` folder -contains https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-0.3.zip and -`/stdio` is copied from cosmopolitan@7ed524ca31bca83fe6700045d346cad3f97b9567 +Fork of [md2html](https://github.com/kukrimate/md2html). The magic is that it works +on Linux, *BSD, macOs, Windows thanks to [cosmopolitan](https://github.com/jart/cosmopolitan). ## Running ```sh -wget https://niedzwiedzinski.cyou/cat.com -chmod +x cat.com -sha256sum cat.com -# 495b3bb169813b07d4c4c43568c6c395e72a952fdf7fe3e5b46bf130cc415af0 +wget https://niedzwiedzinski.cyou/md2htmmd2html.com +chmod +x md2html.com +sha256sum md2html.com +# 0f1477ae8abfbc9c973d5149a63e5fe33d5121d515de2c9379e29bca42736d1c # For zsh or fish -bash -c "./cat.com" +bash -c "./md2html.com" # For everything else -./cat.com +./md2html.com ``` ## Compiling Requirements: -- make -- gcc -- objcopy (from pkg `binutils`) +* make +* gcc +* objcopy (from pkg `binutils`) ``` make diff --git a/cat.c b/cat.c deleted file mode 100644 index 92a19b7..0000000 --- a/cat.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "stdio/stdio.h" - -int cat(char* filename) { - FILE *f; - f = fopen(filename, "r"); - if (f == NULL) { - printf("Cannot open file '%s'\n", filename); - return 1; - } - - char *line = NULL; - size_t linecap = 0; - ssize_t linelen; - while ((linelen = getline(&line, &linecap, f)) != -1) { - printf("%s", line); - } - free(line); - fclose(f); - return 0; -} - -int main(int argc, char *argv[]) { - int err = 0; - - if (argc > 1) { - for (int i = 1; i < argc; i++) { - cat(argv[i]); - } - } else { - printf("Usage: cat FILE [FILE] ...\n"); - } - - return 0; -} diff --git a/md2html.c b/md2html.c new file mode 100644 index 0000000..ab78ad1 --- /dev/null +++ b/md2html.c @@ -0,0 +1,322 @@ +/* + * Source: https://github.com/kukrimate/md2html + * + * Copyright (c) 2020, Máté Kukri + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "stdio/stdio.h" + +int +peak(FILE *fp) +{ + int ch; + + ungetc((ch = fgetc(fp)), fp); + return ch; +} + +int +next(FILE *fp, int want) +{ + int ch; + + ch = fgetc(fp); + if (ch != want) + ungetc(ch, fp); + return ch; +} + +char * +nextstr(FILE *fp, char *want) +{ + char *cur; + int ch; + + for (cur = want; *cur; ++cur) + if ((ch = fgetc(fp)) != *cur) + goto fail; + return want; +fail: + ungetc(ch, fp); + while (--cur >= want) + ungetc(*cur, fp); + return NULL; +} + +void +skip_white(FILE *fp) +{ + int ch; + + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + case ' ': + case '\t': + case '\r': + case '\n': + case '\v': + case '\f': + break; + default: + ungetc(ch, fp); + return; + } +} + +void +code(FILE *fp) +{ + int ch; + + printf("<code>"); + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + case '`': + goto end; + default: + putchar(ch); + } +end: + printf("</code>"); +} + +void +esccode(FILE *fp) +{ + int ch; + + printf("<code>"); + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + case '`': + if (next(fp, '`') == '`') + goto end; + default: + putchar(ch); + } +end: + printf("</code>"); +} + +void +codeblock(FILE *fp) +{ + int ch; + + skip_white(fp); + printf("<pre><code>"); + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + case '`': + if (nextstr(fp, "``")) + goto end; + default: + putchar(ch); + } +end: + printf("</code></pre>\n"); +} + +void +heading(FILE *fp, int lvl) +{ + int ch; + + skip_white(fp); + printf("<h%d>", lvl); + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + /* End of heading */ + case '\n': + goto end; + default: + putchar(ch); + } +end: + printf("</h%d>\n", lvl); +} + +void +blockquote(FILE *fp) +{ + int ch; + + printf("<blockquote>"); + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + case '\n': + /* End of blockquote */ + if (next(fp, '\n') == '\n') + goto end; + + /* Next top level element */ + switch (peak(fp)) { + case '#': /* Heading */ + case '*': /* List */ + goto end; + case '`': /* Code block */ + if (nextstr(fp, "```")) { + ungetc('`', fp); + ungetc('`', fp); + ungetc('`', fp); + goto end; + } + } + + /* Ignore > on subsequent lines */ + if (next(fp, '>') == '>') + break; + default: + putchar(ch); + } +end: + printf("</blockquote>\n"); +} + +void +list(FILE *fp) +{ + int ch; + + printf("<ul><li>"); + + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + case '\n': + /* End of list */ + if (next(fp, '\n') == '\n') + goto end; + + /* Next top level element */ + switch (peak(fp)) { + case '#': /* Heading */ + case '>': /* Blockquote */ + goto end; + case '`': /* Code block */ + if (nextstr(fp, "```")) { + ungetc('`', fp); + ungetc('`', fp); + ungetc('`', fp); + goto end; + } + } + + /* Line starting with * means next element */ + if (next(fp, '*') == '*') { + printf("</li><li>"); + break; + } + default: + putchar(ch); + } + +end: + printf("</li></ul>\n"); +} + +void +paragraph(FILE *fp) +{ + int ch; + + printf("<p>"); + while ((ch = fgetc(fp)) != EOF) + switch (ch) { + case '`': + if (next(fp, '`') == '`') /* Escaped code */ + esccode(fp); + else /* Normal code */ + code(fp); + break; + case '\n': + /* End of paragraph */ + if (next(fp, '\n') == '\n') + goto end; + + /* Next top level element */ + switch (peak(fp)) { + case '#': /* Heading */ + case '>': /* Blockquote */ + case '*': /* List */ + goto end; + case '`': /* Code block */ + if (nextstr(fp, "```")) { + ungetc('`', fp); + ungetc('`', fp); + ungetc('`', fp); + goto end; + } + } + default: + putchar(ch); + } + +end: + printf("</p>\n"); +} + +void +md2html(FILE *fp) +{ + int ch, cnt; + + for (;;) + switch ((ch = fgetc(fp))) { + case EOF: + return; + /* Consume newlines at the start of top level blocks */ + case '\n': + break; + case '#': + cnt = 1; + while (next(fp, '#') == '#') + ++cnt; + heading(fp, cnt); + break; + case '>': + blockquote(fp); + break; + case '*': + list(fp); + break; + case '`': + if (nextstr(fp, "``")) { + codeblock(fp); + break; + } + default: + ungetc(ch, fp); + paragraph(fp); + } +} + +int +main(int argc, char *argv[]) +{ + FILE *fp; + + if (argc < 2) { + fp = stdin; + } else { + if (!(fp = fopen(argv[1], "r"))) { + perror(argv[1]); + return 1; + } + } + + md2html(fp); + fclose(fp); + return 0; +} |