Introduction
Introduction Statistics Contact Development Disclaimer Help
renamed project to smu - simple markup - smu - smu - simple markup (Markdown) p…
git clone git://git.codemadness.org/smu
Log
Files
Refs
README
LICENSE
---
commit 4f419311ff164306ae138bb363dbffa5797fbd12
parent d5058298da1fef8596066d1822a67d6a0eaff614
Author: [email protected] <[email protected]>
Date: Tue, 1 Jan 2008 14:52:08 +0100
renamed project to smu - simple markup
--HG--
rename : cmarkdown.1 => smu.1
rename : cmarkdown.c => smu.c
Diffstat:
M Makefile | 34 ++++++++++++++++-------------…
D cmarkdown.1 | 23 -----------------------
D cmarkdown.c | 537 -----------------------------…
M config.mk | 2 +-
A smu.1 | 23 +++++++++++++++++++++++
A smu.c | 537 +++++++++++++++++++++++++++++…
6 files changed, 578 insertions(+), 578 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -1,15 +1,15 @@
-# cmarkdown
+# smu - simple markup
# (c) 2007 Enno Boland
include config.mk
-SRC = cmarkdown.c
+SRC = smu.c
OBJ = ${SRC:.c=.o}
-all: options cmarkdown
+all: options smu
options:
- @echo cmarkdown build options:
+ @echo smu build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
@@ -20,37 +20,37 @@ options:
${OBJ}: config.mk
-cmarkdown: ${OBJ}
+smu: ${OBJ}
@echo LD $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
@echo cleaning
- @rm -f cmarkdown ${OBJ} cmarkdown-${VERSION}.tar.gz
+ @rm -f smu ${OBJ} smu-${VERSION}.tar.gz
dist: clean
@echo creating dist tarball
- @mkdir -p cmarkdown-${VERSION}
+ @mkdir -p smu-${VERSION}
@cp -R LICENSE Makefile config.mk \
- cmarkdown.1 ${SRC} cmarkdown-${VERSION}
- @tar -cf cmarkdown-${VERSION}.tar cmarkdown-${VERSION}
- @gzip cmarkdown-${VERSION}.tar
- @rm -rf cmarkdown-${VERSION}
+ smu.1 ${SRC} smu-${VERSION}
+ @tar -cf smu-${VERSION}.tar smu-${VERSION}
+ @gzip smu-${VERSION}.tar
+ @rm -rf smu-${VERSION}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
- @cp -f cmarkdown ${DESTDIR}${PREFIX}/bin
- @chmod 755 ${DESTDIR}${PREFIX}/bin/cmarkdown
+ @cp -f smu ${DESTDIR}${PREFIX}/bin
+ @chmod 755 ${DESTDIR}${PREFIX}/bin/smu
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
- @sed "s/VERSION/${VERSION}/g" < cmarkdown.1 > ${DESTDIR}${MANPREFIX}/m…
- @chmod 644 ${DESTDIR}${MANPREFIX}/man1/cmarkdown.1
+ @sed "s/VERSION/${VERSION}/g" < smu.1 > ${DESTDIR}${MANPREFIX}/man1/sm…
+ @chmod 644 ${DESTDIR}${MANPREFIX}/man1/smu.1
uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
- @rm -f ${DESTDIR}${PREFIX}/bin/cmarkdown
+ @rm -f ${DESTDIR}${PREFIX}/bin/smu
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
- @rm -f ${DESTDIR}${MANPREFIX}/man1/cmarkdown.1
+ @rm -f ${DESTDIR}${MANPREFIX}/man1/smu.1
.PHONY: all options clean dist install uninstall
diff --git a/cmarkdown.1 b/cmarkdown.1
@@ -1,23 +0,0 @@
-.TH cmarkdown 1 cmarkdown\-VERSION
-.SH NAME
-cmarkdown \- Markdown interpreter in C
-.SH SYNOPSIS
-.B cmarkdown
-.RB [ \-h ]
-.RB [ \-v ]
-.RB [ \-n ]
-.RB [ file ]
-.SH DESCRIPTION
-cmarkdown is a simple interpreter for the markdown syntax.
-.SH OPTIONS
-.TP
-.B \-v
-prints version information to standard error, then exits.
-.TP
-.B \-h
-prints usage information to standard error, then exits.
-.TP
-.B \-n
-escapes all HTML Tags.
-.SH BUGS
-Markdown may never be fully supported.
diff --git a/cmarkdown.c b/cmarkdown.c
@@ -1,537 +0,0 @@
-/* cmarkdown
- * Copyright (C) <2007> Enno boland <g s01 de>
- *
- * See LICENSE for further informations
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#define BUFFERSIZE 512
-#define LENGTH(x) sizeof(x)/sizeof(x[0])
-#define ADDC(b,i) if(i % BUFFERSIZE == 0) \
- { b = realloc(b,(i + BUFFERSIZE) * sizeof(b)); if(!b) eprint("Malloc f…
-
-
-typedef unsigned int (*Parser)(const char *, const char *, int);
-struct Tag {
- char *search;
- int process;
- char *before, *after;
-};
-
-
-void eprint(const char *format, ...); /* Prints error a…
-unsigned int doamp(const char *begin, const char *end, int newblock);
- /* Parser for & */
-unsigned int dohtml(const char *begin, const char *end, int newblock);
- /* Parser for html */
-unsigned int dolineprefix(const char *begin, const char *end, int newblock);
- /* Parser for line pre…
-unsigned int dolink(const char *begin, const char *end, int newblock);
- /* Parser for links an…
-unsigned int dolist(const char *begin, const char *end, int newblock);
- /* Parser for lists */
-unsigned int doparagraph(const char *begin, const char *end, int newblock);
- /* Parser for paragrap…
-unsigned int doreplace(const char *begin, const char *end, int newblock);
- /* Parser for simple r…
-unsigned int doshortlink(const char *begin, const char *end, int newblock);
- /* Parser for links an…
-unsigned int dosurround(const char *begin, const char *end, int newblock);
- /* Parser for surround…
-unsigned int dounderline(const char *begin, const char *end, int newblock);
- /* Parser for underlin…
-void hprint(const char *begin, const char *end); /* escapes HTML and pr…
-void process(const char *begin, const char *end, int isblock);
- /* Processes range bet…
-
-Parser parsers[] = { dounderline, dohtml, dolineprefix, dolist, doparagraph,
- dosurround, dolink, doshortlink, doamp, doreplace }; /* list of…
-FILE *source;
-unsigned int bsize = 0, nohtml = 0;
-struct Tag lineprefix[] = {
- { " ", 0, "<pre><code>", "</code></pre>" },
- { "\t", 0, "<pre><code>", "</code></pre>" },
- { "> ", 2, "<blockquote>", "</blockquote>…
- { "###### ", 1, "<h6>", "</h6>" },
- { "##### ", 1, "<h5>", "</h5>" },
- { "#### ", 1, "<h4>", "</h4>" },
- { "### ", 1, "<h3>", "</h3>" },
- { "## ", 1, "<h2>", "</h2>" },
- { "# ", 1, "<h1>", "</h1>" },
-};
-struct Tag underline[] = {
- { "=", 1, "<h1>", "</h1>\n" },
- { "-", 1, "<h2>", "</h2>\n" },
-};
-struct Tag surround[] = {
- { "``", 0, "<code>", "</code>" },
- { "`", 0, "<code>", "</code>" },
- { "__", 1, "<strong>", "</strong>" },
- { "**", 1, "<strong>", "</strong>" },
- { "*", 1, "<em>", "</em>" },
- { "_", 1, "<em>", "</em>" },
-};
-char * replace[][2] = {
- { "\n- - -\n", "\n<hr />\n" },
- { "\n- - - \n", "\n<hr />\n" },
- { " ######\n", "\n" },
- { " #####\n", "\n" },
- { " ####\n", "\n" },
- { " ###\n", "\n" },
- { " ##\n", "\n" },
- { " #\n", "\n" },
- { " >", "&gt;" },
- { "< ", "&lt;" },
- { "\\\\", "\\" },
- { "\\`", "`" },
- { "\\*", "*" },
- { "\\_", "_" },
- { "\\{", "{" },
- { "\\}", "}" },
- { "\\[", "[" },
- { "\\]", "]" },
- { "\\(", "(" },
- { "\\)", ")" },
- { "\\#", "#" },
- { "\\+", "+" },
- { "\\-", "-" },
- { "\\.", "." },
- { "\\!", "!" },
-};
-char * insert[][2] = {
- { " \n", "<br />" },
-};
-
-void
-eprint(const char *format, ...) {
- va_list ap;
-
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
- exit(EXIT_FAILURE);
-}
-
-unsigned int
-doamp(const char *begin, const char *end, int newblock) {
- const char *p;
-
- if(*begin != '&')
- return 0;
- if(!nohtml) {
- for(p = begin + 1; !strchr("; \\\n\t",*p); p++);
- if(*p == ';')
- return 0;
- }
- fputs("&amp;",stdout);
- return 1;
-}
-
-unsigned int
-dohtml(const char *begin, const char *end, int newblock) {
- const char *p, *tag, *tagend;
-
- if(nohtml || !newblock || *begin == '\n')
- return 0;
- p = begin;
- if(p[1] == '\n')
- p++;
- if(p[1] != '<' || strchr(" /\n\t\\",p[2]))
- return 0;
- tag = p + 2;
- p += 2;
- for(; !strchr(" >",*p);p++);
- tagend = p;
- while((p = strstr(p,"\n</")) && p < end) {
- p+=3;
- if(strncmp(p, tag, tagend-tag) == 0 && p[tagend-tag] == '>') {
- p++;
- fwrite(begin, sizeof(char), p - begin + tagend - tag,s…
- puts("\n");
- return -(p - begin + tagend - tag);
- }
- }
- return 0;
-}
-
-unsigned int
-dolineprefix(const char *begin, const char *end, int newblock) {
- unsigned int i, j, l;
- char *buffer;
- const char *p;
-
- if(!newblock)
- return 0;
- p = begin;
- for(i = 0; i < LENGTH(lineprefix); i++) {
- l = strlen(lineprefix[i].search);
- if(end - p < l)
- continue;
- if(strncmp(lineprefix[i].search,p,l))
- continue;
- if(!(buffer = malloc(BUFFERSIZE)))
- eprint("Malloc failed.");
- buffer[0] = '\0';
- fputs(lineprefix[i].before,stdout);
- for(j = 0, p += l; p != end; p++, j++) {
- ADDC(buffer,j) = *p;
- if(*p == '\n') {
- if(strncmp(lineprefix[i].search,p+1,l) != 0)
- break;
- p += l;
- }
- }
- ADDC(buffer,j) = '\0';
- if(lineprefix[i].process)
- process(buffer,buffer+strlen(buffer), lineprefix[i].pr…
- else
- hprint(buffer,buffer+strlen(buffer));
- puts(lineprefix[i].after);
- free(buffer);
- return -(p - begin);
- }
- return 0;
-}
-
-unsigned int
-dolink(const char *begin, const char *end, int newblock) {
- int img;
- const char *desc, *link, *p, *q, *descend, *linkend;
-
- if(*begin == '[')
- img = 0;
- else if(strncmp(begin,"![",2) == 0)
- img = 1;
- else
- return 0;
- p = desc = begin + 1 + img;
- if(!(p = strstr(desc, "](")) || p > end)
- return 0;
- for(q = strstr(desc, "!["); q && q < end && q < p; q = strstr(q+1,"!["…
- if(!(p = strstr(p+1, "](")) || p > end)
- return 0;
- descend = p;
- link = p + 2;
- if(!(p = strstr(link, ")")) || p > end)
- return 0;
- linkend = p;
- if(img) {
- fputs("<img src=\"",stdout);
- hprint(link,linkend);
- fputs("\" alt=\"",stdout);
- hprint(desc,descend);
- fputs("\" />",stdout);
- }
- else {
- fputs("<a href=\"",stdout);
- hprint(link,linkend);
- fputs("\">",stdout);
- process(desc,descend,0);
- fputs("</a>",stdout);
- }
- return p + 1 - begin;
-}
-
-unsigned int
-dolist(const char *begin, const char *end, int newblock) {
- unsigned int i, j, indent, run, ul, isblock;
- const char *p, *q;
- char *buffer;
-
- isblock = 0;
- if(newblock)
- p = begin;
- else if(*begin == '\n')
- p = begin + 1;
- else
- return 0;
- q = p;
- if(*p == '-' || *p == '*' || *p == '+')
- ul = 1;
- else {
- ul = 0;
- for(; *p && p != end && *p >= '0' && *p <= '9';p++);
- if(!*p || p[0] != '.')
- return 0;
- }
- if(p[1] != ' ' && p[1] != '\t')
- return 0;
- for(p++; *p && p != end && (*p == ' ' || *p == '\t'); p++);
- indent = p - q;
- if(!(buffer = malloc(BUFFERSIZE)))
- eprint("Malloc failed.");
- if(!newblock)
- putchar('\n');
- fputs(ul ? "<ul>\n" : "<ol>\n",stdout);
- run = 1;
- for(i = 0; *p && p < end && run; p++) {
- buffer[0] = '\0';
- for(i = 0; *p && p < end && run; p++,i++) {
- if(*p == '\n') {
- if(p[1] == '\n') {
- p++;
- ADDC(buffer,i) = '\n';
- i++;
- run = 0;
- isblock++;
- }
- q = p + 1;
- j = 0;
- if(ul && (*q == '-' || *q == '*' || *q == '+'))
- j = 1;
- else if(!ul) {
- for(; q[j] >= '0' && q[j] <= '9' && j …
- if(j > 0 && q[j] == '.')
- j++;
- else
- j = 0;
- }
- for(;(q[j] == ' ' || *q == '\t') && j < indent…
- if(j == indent) {
- ADDC(buffer,i) = '\n';
- i++;
- p += indent;
- run = 1;
- if(*q == ' ' || *q == '\t')
- p++;
- else
- break;
- }
- }
- ADDC(buffer,i) = *p;
- }
- ADDC(buffer,i) = '\0';
- fputs("<li>",stdout);
- process(buffer,buffer+i,isblock > 1 || (isblock == 1 && run));
- fputs("</li>\n",stdout);
- }
- fputs(ul ? "</ul>\n" : "</ol>\n",stdout);
- free(buffer);
- p--;
- while(*(--p) == '\n');
- return -(p - begin + 1);
-}
-
-unsigned int
-doparagraph(const char *begin, const char *end, int newblock) {
- const char *p, *q;
-
- if(!newblock)
- return 0;
- p = begin;
- q = strstr(p, "\n\n");
- if(!q || q > end)
- q = end;
- if(q - begin <= 1)
- return 0;
- fputs("<p>\n",stdout);
- process(p,q,0);
- fputs("\n</p>\n",stdout);
- return -(q - begin);
-}
-
-unsigned int
-doreplace(const char *begin, const char *end, int newblock) {
- unsigned int i, l;
-
- for(i = 0; i < LENGTH(insert); i++)
- if(strncmp(insert[i][0],begin,strlen(insert[i][0])) == 0)
- fputs(insert[i][1], stdout);
- for(i = 0; i < LENGTH(replace); i++) {
- l = strlen(replace[i][0]);
- if(end - begin < l)
- continue;
- if(strncmp(replace[i][0],begin,l) == 0) {
- fputs(replace[i][1], stdout);
- return l;
- }
- }
- return 0;
-}
-
-unsigned int
-doshortlink(const char *begin, const char *end, int newblock) {
- const char *p, *c;
- int ismail = 0;
-
- if(*begin != '<')
- return 0;
- for(p = begin+1; p && p != end && !strchr(" \t\n",*p); p++) {
- switch(*p) {
- case '#':
- case ':':
- ismail = -1;
- break;
- case '@':
- if(ismail == 0)
- ismail = 1;
- break;
- case '>':
- if(ismail == 0)
- return 0;
- fputs("<a href=\"",stdout);
- if(ismail == 1) {
- /* mailto: */
- fputs("&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:",stdou…
- for(c = begin+1; *c != '>'; c++) {
- printf("&#%u;",*c);
- }
- fputs("\">",stdout);
- for(c = begin+1; *c != '>'; c++) {
- printf("&#%u;",*c);
- }
- }
- else {
- hprint(begin+1,p);
- fputs("\">",stdout);
- hprint(begin+1,p);
- }
- fputs("</a>",stdout);
- return p - begin + 1;
- }
- }
- return 0;
-}
-
-unsigned int
-dosurround(const char *begin, const char *end, int newblock) {
- unsigned int i,l;
- const char *p, *ps, *q, *qend;
-
- for(i = 0; i < LENGTH(surround); i++) {
- l = strlen(surround[i].search);
- if(end - begin < l || strncmp(begin,surround[i].search,l) != 0)
- continue;
- for(ps = surround[i].search; *ps == '\n'; ps++);
- l = strlen(ps);
- p = begin + strlen(surround[i].search) - 1;
- do {
- p = strstr(p+1, ps);
- } while(p && p[-1] == '\\');
- if(!p || p > end)
- continue;
- fputs(surround[i].before,stdout);
- for(q = begin + strlen(surround[i].search); *q == ' '; q++);
- for(qend = p-1; *qend == ' '; qend--);
- if(surround[i].process)
- process(q, qend+1,0);
- else
- hprint(q, qend+1);
- fputs(surround[i].after,stdout);
- return p - begin + l;
- }
- return 0;
-}
-
-unsigned int
-dounderline(const char *begin, const char *end, int newblock) {
- unsigned int i, j, l;
- const char *p;
-
- if(!newblock)
- return 0;
- p = begin;
- for(l = 0; p[l] != '\n' && p[l] && p+l != end; l++);
- p += l + 1;
- if(l == 0)
- return 0;
- for(i = 0; i < LENGTH(underline); i++) {
- for(j = 0; p[j] != '\n' && p[j] == underline[i].search[0] && p…
- if(j >= l) {
- fputs(underline[i].before,stdout);
- if(underline[i].process)
- process(begin, begin + l, 0);
- else
- hprint(begin, begin + l);
- fputs(underline[i].after,stdout);
- return -(j + p - begin);
- }
- }
- return 0;
-}
-
-void
-hprint(const char *begin, const char *end) {
- const char *p;
-
- for(p = begin; p && p != end; p++) {
- if(*p == '&')
- fputs("&amp;",stdout);
- else if(*p == '"')
- fputs("&quot;",stdout);
- else if(*p == '>')
- fputs("&gt;",stdout);
- else if(*p == '<')
- fputs("&lt;",stdout);
- else
- putchar(*p);
- }
-}
-
-void
-process(const char *begin, const char *end, int newblock) {
- const char *p, *q;
- int affected;
- unsigned int i;
-
- for(p = begin; *p && p < end;) {
- if(newblock)
- while(*p == '\n') p++;
- affected = 0;
- for(i = 0; i < LENGTH(parsers) && affected == 0; i++)
- affected = parsers[i](p, end, newblock);
- p += abs(affected);
- if(!affected) {
- if(nohtml)
- hprint(p,p+1);
- else
- putchar(*p);
- p++;
- }
- for(q = p; *q == '\n' && q < end; q++);
- if(q == end)
- return;
- else if(p[0] == '\n' && p[1] == '\n')
- newblock = 1;
- else
- newblock = affected < 0;
- }
-}
-
-int
-main(int argc, char *argv[]) {
- char *p, *buffer;
- int s;
-
- source = stdin;
- if(argc > 1 && strcmp("-v", argv[1]) == 0)
- eprint("markdown in C %s (C) Enno Boland\n",VERSION);
- else if(argc > 1 && strcmp("-h", argv[1]) == 0)
- eprint("Usage %s [-n] [file]\n -n escape html strictly\n",argv…
- if(argc > 1 && strcmp("-n", argv[1]) == 0)
- nohtml = 1;
- if(argc > 1 + nohtml && strcmp("-", argv[1 + nohtml]) != 0
- && !(source = fopen(argv[1 + nohtml],"r")))
- eprint("Cannot open file `%s`\n",argv[1 + nohtml]);
- if(!(buffer = malloc(BUFFERSIZE)))
- eprint("Malloc failed.");
- bsize = BUFFERSIZE;
- buffer[0] = '\0';
- p = buffer+strlen(buffer);
- while((s = fread(p, sizeof(char),BUFFERSIZE, source))) {
- p += s;
- *p = '\0';
- if(BUFFERSIZE + strlen(buffer) > bsize) {
- bsize += BUFFERSIZE;
- if(!(buffer = realloc(buffer, bsize)))
- eprint("Malloc failed.");
- }
- }
- process(buffer,buffer+strlen(buffer),1);
- free(buffer);
- return EXIT_SUCCESS;
-}
diff --git a/config.mk b/config.mk
@@ -1,4 +1,4 @@
-# cmarkdown version
+# smu version
VERSION = 0.9
# paths
diff --git a/smu.1 b/smu.1
@@ -0,0 +1,23 @@
+.TH smu 1 smu\-VERSION
+.SH NAME
+smu \- simple markup
+.SH SYNOPSIS
+.B smu
+.RB [ \-h ]
+.RB [ \-v ]
+.RB [ \-n ]
+.RB [ file ]
+.SH DESCRIPTION
+smu is a simple interpreter for a simplified markdown dialect.
+.SH OPTIONS
+.TP
+.B \-v
+prints version information to standard error, then exits.
+.TP
+.B \-h
+prints usage information to standard error, then exits.
+.TP
+.B \-n
+escapes all HTML Tags.
+.SH BUGS
+Please report any Bugs!
diff --git a/smu.c b/smu.c
@@ -0,0 +1,537 @@
+/* smu - simple markup
+ * Copyright (C) <2007> Enno boland <g s01 de>
+ *
+ * See LICENSE for further informations
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define BUFFERSIZE 512
+#define LENGTH(x) sizeof(x)/sizeof(x[0])
+#define ADDC(b,i) if(i % BUFFERSIZE == 0) \
+ { b = realloc(b,(i + BUFFERSIZE) * sizeof(b)); if(!b) eprint("Malloc f…
+
+
+typedef unsigned int (*Parser)(const char *, const char *, int);
+struct Tag {
+ char *search;
+ int process;
+ char *before, *after;
+};
+
+
+void eprint(const char *format, ...); /* Prints error a…
+unsigned int doamp(const char *begin, const char *end, int newblock);
+ /* Parser for & */
+unsigned int dohtml(const char *begin, const char *end, int newblock);
+ /* Parser for html */
+unsigned int dolineprefix(const char *begin, const char *end, int newblock);
+ /* Parser for line pre…
+unsigned int dolink(const char *begin, const char *end, int newblock);
+ /* Parser for links an…
+unsigned int dolist(const char *begin, const char *end, int newblock);
+ /* Parser for lists */
+unsigned int doparagraph(const char *begin, const char *end, int newblock);
+ /* Parser for paragrap…
+unsigned int doreplace(const char *begin, const char *end, int newblock);
+ /* Parser for simple r…
+unsigned int doshortlink(const char *begin, const char *end, int newblock);
+ /* Parser for links an…
+unsigned int dosurround(const char *begin, const char *end, int newblock);
+ /* Parser for surround…
+unsigned int dounderline(const char *begin, const char *end, int newblock);
+ /* Parser for underlin…
+void hprint(const char *begin, const char *end); /* escapes HTML and pr…
+void process(const char *begin, const char *end, int isblock);
+ /* Processes range bet…
+
+Parser parsers[] = { dounderline, dohtml, dolineprefix, dolist, doparagraph,
+ dosurround, dolink, doshortlink, doamp, doreplace }; /* list of…
+FILE *source;
+unsigned int bsize = 0, nohtml = 0;
+struct Tag lineprefix[] = {
+ { " ", 0, "<pre><code>", "</code></pre>" },
+ { "\t", 0, "<pre><code>", "</code></pre>" },
+ { "> ", 2, "<blockquote>", "</blockquote>…
+ { "###### ", 1, "<h6>", "</h6>" },
+ { "##### ", 1, "<h5>", "</h5>" },
+ { "#### ", 1, "<h4>", "</h4>" },
+ { "### ", 1, "<h3>", "</h3>" },
+ { "## ", 1, "<h2>", "</h2>" },
+ { "# ", 1, "<h1>", "</h1>" },
+};
+struct Tag underline[] = {
+ { "=", 1, "<h1>", "</h1>\n" },
+ { "-", 1, "<h2>", "</h2>\n" },
+};
+struct Tag surround[] = {
+ { "``", 0, "<code>", "</code>" },
+ { "`", 0, "<code>", "</code>" },
+ { "__", 1, "<strong>", "</strong>" },
+ { "**", 1, "<strong>", "</strong>" },
+ { "*", 1, "<em>", "</em>" },
+ { "_", 1, "<em>", "</em>" },
+};
+char * replace[][2] = {
+ { "\n- - -\n", "\n<hr />\n" },
+ { "\n- - - \n", "\n<hr />\n" },
+ { " ######\n", "\n" },
+ { " #####\n", "\n" },
+ { " ####\n", "\n" },
+ { " ###\n", "\n" },
+ { " ##\n", "\n" },
+ { " #\n", "\n" },
+ { " >", "&gt;" },
+ { "< ", "&lt;" },
+ { "\\\\", "\\" },
+ { "\\`", "`" },
+ { "\\*", "*" },
+ { "\\_", "_" },
+ { "\\{", "{" },
+ { "\\}", "}" },
+ { "\\[", "[" },
+ { "\\]", "]" },
+ { "\\(", "(" },
+ { "\\)", ")" },
+ { "\\#", "#" },
+ { "\\+", "+" },
+ { "\\-", "-" },
+ { "\\.", "." },
+ { "\\!", "!" },
+};
+char * insert[][2] = {
+ { " \n", "<br />" },
+};
+
+void
+eprint(const char *format, ...) {
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+unsigned int
+doamp(const char *begin, const char *end, int newblock) {
+ const char *p;
+
+ if(*begin != '&')
+ return 0;
+ if(!nohtml) {
+ for(p = begin + 1; !strchr("; \\\n\t",*p); p++);
+ if(*p == ';')
+ return 0;
+ }
+ fputs("&amp;",stdout);
+ return 1;
+}
+
+unsigned int
+dohtml(const char *begin, const char *end, int newblock) {
+ const char *p, *tag, *tagend;
+
+ if(nohtml || !newblock || *begin == '\n')
+ return 0;
+ p = begin;
+ if(p[1] == '\n')
+ p++;
+ if(p[1] != '<' || strchr(" /\n\t\\",p[2]))
+ return 0;
+ tag = p + 2;
+ p += 2;
+ for(; !strchr(" >",*p);p++);
+ tagend = p;
+ while((p = strstr(p,"\n</")) && p < end) {
+ p+=3;
+ if(strncmp(p, tag, tagend-tag) == 0 && p[tagend-tag] == '>') {
+ p++;
+ fwrite(begin, sizeof(char), p - begin + tagend - tag,s…
+ puts("\n");
+ return -(p - begin + tagend - tag);
+ }
+ }
+ return 0;
+}
+
+unsigned int
+dolineprefix(const char *begin, const char *end, int newblock) {
+ unsigned int i, j, l;
+ char *buffer;
+ const char *p;
+
+ if(!newblock)
+ return 0;
+ p = begin;
+ for(i = 0; i < LENGTH(lineprefix); i++) {
+ l = strlen(lineprefix[i].search);
+ if(end - p < l)
+ continue;
+ if(strncmp(lineprefix[i].search,p,l))
+ continue;
+ if(!(buffer = malloc(BUFFERSIZE)))
+ eprint("Malloc failed.");
+ buffer[0] = '\0';
+ fputs(lineprefix[i].before,stdout);
+ for(j = 0, p += l; p != end; p++, j++) {
+ ADDC(buffer,j) = *p;
+ if(*p == '\n') {
+ if(strncmp(lineprefix[i].search,p+1,l) != 0)
+ break;
+ p += l;
+ }
+ }
+ ADDC(buffer,j) = '\0';
+ if(lineprefix[i].process)
+ process(buffer,buffer+strlen(buffer), lineprefix[i].pr…
+ else
+ hprint(buffer,buffer+strlen(buffer));
+ puts(lineprefix[i].after);
+ free(buffer);
+ return -(p - begin);
+ }
+ return 0;
+}
+
+unsigned int
+dolink(const char *begin, const char *end, int newblock) {
+ int img;
+ const char *desc, *link, *p, *q, *descend, *linkend;
+
+ if(*begin == '[')
+ img = 0;
+ else if(strncmp(begin,"![",2) == 0)
+ img = 1;
+ else
+ return 0;
+ p = desc = begin + 1 + img;
+ if(!(p = strstr(desc, "](")) || p > end)
+ return 0;
+ for(q = strstr(desc, "!["); q && q < end && q < p; q = strstr(q+1,"!["…
+ if(!(p = strstr(p+1, "](")) || p > end)
+ return 0;
+ descend = p;
+ link = p + 2;
+ if(!(p = strstr(link, ")")) || p > end)
+ return 0;
+ linkend = p;
+ if(img) {
+ fputs("<img src=\"",stdout);
+ hprint(link,linkend);
+ fputs("\" alt=\"",stdout);
+ hprint(desc,descend);
+ fputs("\" />",stdout);
+ }
+ else {
+ fputs("<a href=\"",stdout);
+ hprint(link,linkend);
+ fputs("\">",stdout);
+ process(desc,descend,0);
+ fputs("</a>",stdout);
+ }
+ return p + 1 - begin;
+}
+
+unsigned int
+dolist(const char *begin, const char *end, int newblock) {
+ unsigned int i, j, indent, run, ul, isblock;
+ const char *p, *q;
+ char *buffer;
+
+ isblock = 0;
+ if(newblock)
+ p = begin;
+ else if(*begin == '\n')
+ p = begin + 1;
+ else
+ return 0;
+ q = p;
+ if(*p == '-' || *p == '*' || *p == '+')
+ ul = 1;
+ else {
+ ul = 0;
+ for(; *p && p != end && *p >= '0' && *p <= '9';p++);
+ if(!*p || p[0] != '.')
+ return 0;
+ }
+ if(p[1] != ' ' && p[1] != '\t')
+ return 0;
+ for(p++; *p && p != end && (*p == ' ' || *p == '\t'); p++);
+ indent = p - q;
+ if(!(buffer = malloc(BUFFERSIZE)))
+ eprint("Malloc failed.");
+ if(!newblock)
+ putchar('\n');
+ fputs(ul ? "<ul>\n" : "<ol>\n",stdout);
+ run = 1;
+ for(i = 0; *p && p < end && run; p++) {
+ buffer[0] = '\0';
+ for(i = 0; *p && p < end && run; p++,i++) {
+ if(*p == '\n') {
+ if(p[1] == '\n') {
+ p++;
+ ADDC(buffer,i) = '\n';
+ i++;
+ run = 0;
+ isblock++;
+ }
+ q = p + 1;
+ j = 0;
+ if(ul && (*q == '-' || *q == '*' || *q == '+'))
+ j = 1;
+ else if(!ul) {
+ for(; q[j] >= '0' && q[j] <= '9' && j …
+ if(j > 0 && q[j] == '.')
+ j++;
+ else
+ j = 0;
+ }
+ for(;(q[j] == ' ' || *q == '\t') && j < indent…
+ if(j == indent) {
+ ADDC(buffer,i) = '\n';
+ i++;
+ p += indent;
+ run = 1;
+ if(*q == ' ' || *q == '\t')
+ p++;
+ else
+ break;
+ }
+ }
+ ADDC(buffer,i) = *p;
+ }
+ ADDC(buffer,i) = '\0';
+ fputs("<li>",stdout);
+ process(buffer,buffer+i,isblock > 1 || (isblock == 1 && run));
+ fputs("</li>\n",stdout);
+ }
+ fputs(ul ? "</ul>\n" : "</ol>\n",stdout);
+ free(buffer);
+ p--;
+ while(*(--p) == '\n');
+ return -(p - begin + 1);
+}
+
+unsigned int
+doparagraph(const char *begin, const char *end, int newblock) {
+ const char *p, *q;
+
+ if(!newblock)
+ return 0;
+ p = begin;
+ q = strstr(p, "\n\n");
+ if(!q || q > end)
+ q = end;
+ if(q - begin <= 1)
+ return 0;
+ fputs("<p>\n",stdout);
+ process(p,q,0);
+ fputs("\n</p>\n",stdout);
+ return -(q - begin);
+}
+
+unsigned int
+doreplace(const char *begin, const char *end, int newblock) {
+ unsigned int i, l;
+
+ for(i = 0; i < LENGTH(insert); i++)
+ if(strncmp(insert[i][0],begin,strlen(insert[i][0])) == 0)
+ fputs(insert[i][1], stdout);
+ for(i = 0; i < LENGTH(replace); i++) {
+ l = strlen(replace[i][0]);
+ if(end - begin < l)
+ continue;
+ if(strncmp(replace[i][0],begin,l) == 0) {
+ fputs(replace[i][1], stdout);
+ return l;
+ }
+ }
+ return 0;
+}
+
+unsigned int
+doshortlink(const char *begin, const char *end, int newblock) {
+ const char *p, *c;
+ int ismail = 0;
+
+ if(*begin != '<')
+ return 0;
+ for(p = begin+1; p && p != end && !strchr(" \t\n",*p); p++) {
+ switch(*p) {
+ case '#':
+ case ':':
+ ismail = -1;
+ break;
+ case '@':
+ if(ismail == 0)
+ ismail = 1;
+ break;
+ case '>':
+ if(ismail == 0)
+ return 0;
+ fputs("<a href=\"",stdout);
+ if(ismail == 1) {
+ /* mailto: */
+ fputs("&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:",stdou…
+ for(c = begin+1; *c != '>'; c++) {
+ printf("&#%u;",*c);
+ }
+ fputs("\">",stdout);
+ for(c = begin+1; *c != '>'; c++) {
+ printf("&#%u;",*c);
+ }
+ }
+ else {
+ hprint(begin+1,p);
+ fputs("\">",stdout);
+ hprint(begin+1,p);
+ }
+ fputs("</a>",stdout);
+ return p - begin + 1;
+ }
+ }
+ return 0;
+}
+
+unsigned int
+dosurround(const char *begin, const char *end, int newblock) {
+ unsigned int i,l;
+ const char *p, *ps, *q, *qend;
+
+ for(i = 0; i < LENGTH(surround); i++) {
+ l = strlen(surround[i].search);
+ if(end - begin < l || strncmp(begin,surround[i].search,l) != 0)
+ continue;
+ for(ps = surround[i].search; *ps == '\n'; ps++);
+ l = strlen(ps);
+ p = begin + strlen(surround[i].search) - 1;
+ do {
+ p = strstr(p+1, ps);
+ } while(p && p[-1] == '\\');
+ if(!p || p > end)
+ continue;
+ fputs(surround[i].before,stdout);
+ for(q = begin + strlen(surround[i].search); *q == ' '; q++);
+ for(qend = p-1; *qend == ' '; qend--);
+ if(surround[i].process)
+ process(q, qend+1,0);
+ else
+ hprint(q, qend+1);
+ fputs(surround[i].after,stdout);
+ return p - begin + l;
+ }
+ return 0;
+}
+
+unsigned int
+dounderline(const char *begin, const char *end, int newblock) {
+ unsigned int i, j, l;
+ const char *p;
+
+ if(!newblock)
+ return 0;
+ p = begin;
+ for(l = 0; p[l] != '\n' && p[l] && p+l != end; l++);
+ p += l + 1;
+ if(l == 0)
+ return 0;
+ for(i = 0; i < LENGTH(underline); i++) {
+ for(j = 0; p[j] != '\n' && p[j] == underline[i].search[0] && p…
+ if(j >= l) {
+ fputs(underline[i].before,stdout);
+ if(underline[i].process)
+ process(begin, begin + l, 0);
+ else
+ hprint(begin, begin + l);
+ fputs(underline[i].after,stdout);
+ return -(j + p - begin);
+ }
+ }
+ return 0;
+}
+
+void
+hprint(const char *begin, const char *end) {
+ const char *p;
+
+ for(p = begin; p && p != end; p++) {
+ if(*p == '&')
+ fputs("&amp;",stdout);
+ else if(*p == '"')
+ fputs("&quot;",stdout);
+ else if(*p == '>')
+ fputs("&gt;",stdout);
+ else if(*p == '<')
+ fputs("&lt;",stdout);
+ else
+ putchar(*p);
+ }
+}
+
+void
+process(const char *begin, const char *end, int newblock) {
+ const char *p, *q;
+ int affected;
+ unsigned int i;
+
+ for(p = begin; *p && p < end;) {
+ if(newblock)
+ while(*p == '\n') p++;
+ affected = 0;
+ for(i = 0; i < LENGTH(parsers) && affected == 0; i++)
+ affected = parsers[i](p, end, newblock);
+ p += abs(affected);
+ if(!affected) {
+ if(nohtml)
+ hprint(p,p+1);
+ else
+ putchar(*p);
+ p++;
+ }
+ for(q = p; *q == '\n' && q < end; q++);
+ if(q == end)
+ return;
+ else if(p[0] == '\n' && p[1] == '\n')
+ newblock = 1;
+ else
+ newblock = affected < 0;
+ }
+}
+
+int
+main(int argc, char *argv[]) {
+ char *p, *buffer;
+ int s;
+
+ source = stdin;
+ if(argc > 1 && strcmp("-v", argv[1]) == 0)
+ eprint("markdown in C %s (C) Enno Boland\n",VERSION);
+ else if(argc > 1 && strcmp("-h", argv[1]) == 0)
+ eprint("Usage %s [-n] [file]\n -n escape html strictly\n",argv…
+ if(argc > 1 && strcmp("-n", argv[1]) == 0)
+ nohtml = 1;
+ if(argc > 1 + nohtml && strcmp("-", argv[1 + nohtml]) != 0
+ && !(source = fopen(argv[1 + nohtml],"r")))
+ eprint("Cannot open file `%s`\n",argv[1 + nohtml]);
+ if(!(buffer = malloc(BUFFERSIZE)))
+ eprint("Malloc failed.");
+ bsize = BUFFERSIZE;
+ buffer[0] = '\0';
+ p = buffer+strlen(buffer);
+ while((s = fread(p, sizeof(char),BUFFERSIZE, source))) {
+ p += s;
+ *p = '\0';
+ if(BUFFERSIZE + strlen(buffer) > bsize) {
+ bsize += BUFFERSIZE;
+ if(!(buffer = realloc(buffer, bsize)))
+ eprint("Malloc failed.");
+ }
+ }
+ process(buffer,buffer+strlen(buffer),1);
+ free(buffer);
+ return EXIT_SUCCESS;
+}
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.