Forráskód Böngészése

Update libdiscount to 2.2.0

mingodad 9 éve
szülő
commit
d2039379f6

+ 25 - 42
discount/COPYRIGHT

@@ -1,47 +1,30 @@
 ->Copyright (C) 2007 David Loren Parsons.  
 All rights reserved.<-
 
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation files
-(the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicence, and/or sell copies of the Software,
-and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1.  Redistributions of works must retain the original copyright notice,
+    this list of conditions and the following disclaimer.
+2.  Redistributions in binary form must reproduce the original copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+3.  Neither my name (David L Parsons) nor the names of contributors to
+    this code may be used to endorse or promote products derived
+    from this work without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
 
- 1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions, and the following disclaimer.
 
- 2. Redistributions in binary form must reproduce the above
-    copyright notice, this list of conditions and the following
-    disclaimer in the documentation and/or other materials provided
-    with the distribution, and in the same place and form as other
-    copyright, license and disclaimer information.
-
- 3. The end-user documentation included with the redistribution, if
-    any, must include the following acknowledgment:
-
-        This product includes software developed by
-        David Loren Parsons <http://www.pell.portland.or.us/~orc>
-
-    in the same place and form as other third-party acknowledgments.
-    Alternately, this acknowledgment may appear in the software
-    itself, in the same form and location as other such third-party
-    acknowledgments.
-
- 4. Except as contained in this notice, the name of David Loren
-    Parsons shall not be used in advertising or otherwise to promote
-    the sale, use or other dealings in this Software without prior
-    written authorization from David Loren Parsons.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL DAVID LOREN PARSONS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.

+ 1 - 1
discount/CREDITS

@@ -2,7 +2,7 @@ Discount is primarily my work, but it has only reached the point
 where it is via contributions, critiques, and bug reports from a
 host of other people, some of which are listed before.   If your
 name isn't on this list, please remind me
-				    -david parsons (orc@pell.chi.il.us)
+				    -david parsons (orc@pell.portland.or.us)
 
 
 Josh Wood	--  Plan9 support.

+ 1 - 1
discount/Csio.c

@@ -54,7 +54,7 @@ Csreparse(Cstring *iot, char *buf, int size, int flags)
 {
     MMIOT f;
     ___mkd_initmmiot(&f, 0);
-    ___mkd_reparse(buf, size, 0, &f);
+    ___mkd_reparse(buf, size, 0, &f, 0);
     ___mkd_emblock(&f);
     SUFFIX(*iot, T(f.out), S(f.out));
     ___mkd_freemmiot(&f, 0);

+ 42 - 36
discount/Makefile

@@ -1,10 +1,11 @@
-CC=gcc -I. -L.
+CC=cc -Wno-return-type -Wno-implicit-int -I.
+LFLAGS=-L.
 CFLAGS=-g
-AR=/mingw/bin/ar
-RANLIB=/mingw/bin/ranlib
+AR=/usr/bin/ar
+RANLIB=/usr/bin/ranlib
 
 BINDIR=/usr/local/bin
-MANDIR=/usr/local/share/man
+MANDIR=/usr/local/man
 LIBDIR=/usr/local/lib
 INCDIR=/usr/local/include
 
@@ -15,55 +16,60 @@ MKDLIB=libmarkdown
 OBJS=mkdio.o markdown.o dumptree.o generate.o \
      resource.o docheader.o version.o toc.o css.o \
      xml.o Csio.o xmlpage.o basename.o emmatch.o \
-     setup.o tags.o html5.o flags.o 
+     github_flavoured.o setup.o tags.o html5.o flags.o 
 TESTFRAMEWORK=echo cols
 
 MAN3PAGES=mkd-callbacks.3 mkd-functions.3 markdown.3 mkd-line.3
 
 all: $(PGMS) $(SAMPLE_PGMS) $(TESTFRAMEWORK)
 
-install: $(PGMS) $(DESTDIR)/$(BINDIR) $(DESTDIR)/$(LIBDIR) $(DESTDIR)/$(INCDIR)
-	/bin/install -s -m 755 $(PGMS) $(DESTDIR)/$(BINDIR)
-	./librarian.sh install libmarkdown VERSION $(DESTDIR)/$(LIBDIR)
-	/bin/install -m 444 mkdio.h $(DESTDIR)/$(INCDIR)
+install: $(PGMS) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCDIR)
+	/usr/bin/install -s -m 755 $(PGMS) $(DESTDIR)$(BINDIR)
+	./librarian.sh install libmarkdown VERSION $(DESTDIR)$(LIBDIR)
+	/usr/bin/install -m 444 mkdio.h $(DESTDIR)$(INCDIR)
 
 install.everything: install install.samples install.man
 
-install.samples: $(SAMPLE_PGMS) install $(DESTDIR)/$(BINDIR)
-	/bin/install -s -m 755 $(SAMPLE_PGMS) $(DESTDIR)/$(BINDIR)
-	/g/c/discount-2.1.2/config.md $(DESTDIR)/$(MANDIR)/man1
-	/bin/install -m 444 theme.1 makepage.1 mkd2html.1 $(DESTDIR)/$(MANDIR)/man1
+install.samples: $(SAMPLE_PGMS) install $(DESTDIR)$(BINDIR)
+	./config.md $(DESTDIR)$(MANDIR)/man1
+	for x in $(SAMPLE_PGMS); do \
+	    /usr/bin/install -s -m 755 $$x $(DESTDIR)$(BINDIR)/$(SAMPLE_PFX)$$x; \
+	    /usr/bin/install -m 444 $$x.1 $(DESTDIR)$(MANDIR)/man1/$(SAMPLE_PFX)$$x.1; \
+	done
 
 install.man:
-	/g/c/discount-2.1.2/config.md $(DESTDIR)/$(MANDIR)/man3
-	/bin/install -m 444 $(MAN3PAGES) $(DESTDIR)/$(MANDIR)/man3
+	./config.md $(DESTDIR)$(MANDIR)/man3
+	/usr/bin/install -m 444 $(MAN3PAGES) $(DESTDIR)$(MANDIR)/man3
 	for x in mkd_line mkd_generateline; do \
-	    ( echo '.\"' ; echo ".so man3/mkd-line.3" ) > $(DESTDIR)/$(MANDIR)/man3/$$x.3;\
+	    ( echo '.\"' ; echo ".so man3/mkd-line.3" ) > $(DESTDIR)$(MANDIR)/man3/$$x.3;\
 	done
 	for x in mkd_in mkd_string; do \
-	    ( echo '.\"' ; echo ".so man3/markdown.3" ) > $(DESTDIR)/$(MANDIR)/man3/$$x.3;\
+	    ( echo '.\"' ; echo ".so man3/markdown.3" ) > $(DESTDIR)$(MANDIR)/man3/$$x.3;\
 	done
 	for x in mkd_compile mkd_css mkd_generatecss mkd_generatehtml mkd_cleanup mkd_doc_title mkd_doc_author mkd_doc_date; do \
-	    ( echo '.\"' ; echo ".so man3/mkd-functions.3" ) > $(DESTDIR)/$(MANDIR)/man3/$$x.3; \
+	    ( echo '.\"' ; echo ".so man3/mkd-functions.3" ) > $(DESTDIR)$(MANDIR)/man3/$$x.3; \
 	done
-	/g/c/discount-2.1.2/config.md $(DESTDIR)/$(MANDIR)/man7
-	/bin/install -m 444 markdown.7 mkd-extensions.7 $(DESTDIR)/$(MANDIR)/man7
-	/g/c/discount-2.1.2/config.md $(DESTDIR)/$(MANDIR)/man1
-	/bin/install -m 444 markdown.1 $(DESTDIR)/$(MANDIR)/man1
+	./config.md $(DESTDIR)$(MANDIR)/man7
+	/usr/bin/install -m 444 markdown.7 mkd-extensions.7 $(DESTDIR)$(MANDIR)/man7
+	./config.md $(DESTDIR)$(MANDIR)/man1
+	/usr/bin/install -m 444 markdown.1 $(DESTDIR)$(MANDIR)/man1
 
 install.everything: install install.man
 
-$(DESTDIR)/$(BINDIR):
-	/g/c/discount-2.1.2/config.md $(DESTDIR)/$(BINDIR)
+$(DESTDIR)$(BINDIR):
+	./config.md $(DESTDIR)$(BINDIR)
 
-$(DESTDIR)/$(INCDIR):
-	/g/c/discount-2.1.2/config.md $(DESTDIR)/$(INCDIR)
+$(DESTDIR)$(INCDIR):
+	./config.md $(DESTDIR)$(INCDIR)
 
-$(DESTDIR)/$(LIBDIR):
-	/g/c/discount-2.1.2/config.md $(DESTDIR)/$(LIBDIR)
+$(DESTDIR)$(LIBDIR):
+	./config.md $(DESTDIR)$(LIBDIR)
 
 version.o: version.c VERSION
-	$(CC) -DVERSION=\"`cat VERSION`\" -c version.c
+	$(CC) $(CFLAGS) -DVERSION=\"`cat VERSION`\" -c version.c
+
+VERSION:
+	@true
 
 tags.o: tags.c blocktags
 
@@ -72,23 +78,23 @@ blocktags: mktags
 
 # example programs
 theme:  theme.o $(MKDLIB) mkdio.h
-	$(CC) -o theme theme.o -lmarkdown 
+	$(CC) $(CFLAGS) $(LFLAGS) -o theme theme.o pgm_options.o -lmarkdown 
 
 
 mkd2html:  mkd2html.o $(MKDLIB) mkdio.h
-	$(CC) -o mkd2html mkd2html.o -lmarkdown 
+	$(CC) $(CFLAGS) $(LFLAGS) -o mkd2html mkd2html.o -lmarkdown 
 
 markdown: main.o pgm_options.o $(MKDLIB)
-	$(CC) $(CFLAGS) -o markdown main.o pgm_options.o -lmarkdown 
+	$(CC) $(CFLAGS) $(LFLAGS) -o markdown main.o pgm_options.o -lmarkdown 
 	
 makepage:  makepage.c pgm_options.o $(MKDLIB) mkdio.h
-	$(CC) $(CFLAGS) -o makepage makepage.c pgm_options.o -lmarkdown 
+	$(CC) $(CFLAGS) $(LFLAGS) -o makepage makepage.c pgm_options.o -lmarkdown 
 
 pgm_options.o: pgm_options.c mkdio.h config.h
-	$(CC) -I. -c pgm_options.c
+	$(CC) $(CFLAGS) -I. -c pgm_options.c
 
 main.o: main.c mkdio.h config.h
-	$(CC) -I. -c main.c
+	$(CC) $(CFLAGS) -I. -c main.c
 
 $(MKDLIB): $(OBJS)
 	./librarian.sh make $(MKDLIB) VERSION $(OBJS)
@@ -111,7 +117,7 @@ clean:
 	rm -f $(MKDLIB) `./librarian.sh files $(MKDLIB) VERSION`
 
 distclean spotless: clean
-	rm -f Makefile version.c mkdio.h config.cmd config.sub config.h config.mak config.log config.md
+	rm -f Makefile version.c mkdio.h config.cmd config.sub config.h config.mak config.log config.md ./mktags ./blocktags ./librarian.sh
 
 Csio.o: Csio.c cstring.h amalloc.h config.h markdown.h
 amalloc.o: amalloc.c

+ 18 - 12
discount/Makefile.in

@@ -1,4 +1,5 @@
-CC=@CC@ -I. -L.
+CC=@CC@ -I.
+LFLAGS=-L.
 CFLAGS=@CFLAGS@
 AR=@AR@
 RANLIB=@RANLIB@
@@ -15,7 +16,7 @@ MKDLIB=libmarkdown
 OBJS=mkdio.o markdown.o dumptree.o generate.o \
      resource.o docheader.o version.o toc.o css.o \
      xml.o Csio.o xmlpage.o basename.o emmatch.o \
-     setup.o tags.o html5.o flags.o @AMALLOC@
+     github_flavoured.o setup.o tags.o html5.o flags.o @AMALLOC@
 TESTFRAMEWORK=echo cols
 
 MAN3PAGES=mkd-callbacks.3 mkd-functions.3 markdown.3 mkd-line.3
@@ -30,9 +31,11 @@ install: $(PGMS) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCDIR)
 install.everything: install install.samples install.man
 
 install.samples: $(SAMPLE_PGMS) install $(DESTDIR)$(BINDIR)
-	@INSTALL_PROGRAM@ $(SAMPLE_PGMS) $(DESTDIR)$(BINDIR)
 	@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man1
-	@INSTALL_DATA@ theme.1 makepage.1 mkd2html.1 $(DESTDIR)$(MANDIR)/man1
+	for x in $(SAMPLE_PGMS); do \
+	    @INSTALL_PROGRAM@ $$x $(DESTDIR)$(BINDIR)/$(SAMPLE_PFX)$$x; \
+	    @INSTALL_DATA@ $$x.1 $(DESTDIR)$(MANDIR)/man1/$(SAMPLE_PFX)$$x.1; \
+	done
 
 install.man:
 	@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man3
@@ -63,7 +66,10 @@ $(DESTDIR)$(LIBDIR):
 	@INSTALL_DIR@ $(DESTDIR)$(LIBDIR)
 
 version.o: version.c VERSION
-	$(CC) -DVERSION=\"`cat VERSION`\" -c version.c
+	$(CC) $(CFLAGS) -DVERSION=\"`cat VERSION`\" -c version.c
+
+VERSION:
+	@true
 
 tags.o: tags.c blocktags
 
@@ -72,23 +78,23 @@ blocktags: mktags
 
 # example programs
 @THEME@theme:  theme.o $(MKDLIB) mkdio.h
-@THEME@	$(CC) -o theme theme.o -lmarkdown @LIBS@
+@THEME@	$(CC) $(CFLAGS) $(LFLAGS) -o theme theme.o pgm_options.o -lmarkdown @LIBS@
 
 
 mkd2html:  mkd2html.o $(MKDLIB) mkdio.h
-	$(CC) -o mkd2html mkd2html.o -lmarkdown @LIBS@
+	$(CC) $(CFLAGS) $(LFLAGS) -o mkd2html mkd2html.o -lmarkdown @LIBS@
 
 markdown: main.o pgm_options.o $(MKDLIB)
-	$(CC) $(CFLAGS) -o markdown main.o pgm_options.o -lmarkdown @LIBS@
+	$(CC) $(CFLAGS) $(LFLAGS) -o markdown main.o pgm_options.o -lmarkdown @LIBS@
 	
 makepage:  makepage.c pgm_options.o $(MKDLIB) mkdio.h
-	$(CC) $(CFLAGS) -o makepage makepage.c pgm_options.o -lmarkdown @LIBS@
+	$(CC) $(CFLAGS) $(LFLAGS) -o makepage makepage.c pgm_options.o -lmarkdown @LIBS@
 
 pgm_options.o: pgm_options.c mkdio.h config.h
-	$(CC) -I. -c pgm_options.c
+	$(CC) $(CFLAGS) -I. -c pgm_options.c
 
 main.o: main.c mkdio.h config.h
-	$(CC) -I. -c main.c
+	$(CC) $(CFLAGS) -I. -c main.c
 
 $(MKDLIB): $(OBJS)
 	./librarian.sh make $(MKDLIB) VERSION $(OBJS)
@@ -111,7 +117,7 @@ clean:
 	rm -f $(MKDLIB) `./librarian.sh files $(MKDLIB) VERSION`
 
 distclean spotless: clean
-	rm -f @GENERATED_FILES@ @CONFIGURE_FILES@
+	rm -f @GENERATED_FILES@ @CONFIGURE_FILES@ ./mktags ./blocktags ./librarian.sh
 
 Csio.o: Csio.c cstring.h amalloc.h config.h markdown.h
 amalloc.o: amalloc.c

+ 1 - 1
discount/README

@@ -5,7 +5,7 @@ language as described in
 and passes the Markdown test suite at
 <http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip>
 
-DISCOUNT is free software written by David Parsons <orc@pell.chi.il.us>;
+DISCOUNT is free software written by David Parsons <orc@pell.portland.or.us>;
 it is released under a BSD-style license that allows you to do
 as you wish with it as long as you don't attempt to claim it as
 your own work.

+ 1 - 1
discount/VERSION

@@ -1 +1 @@
-2.1.3
+2.2.0

+ 29 - 5
discount/amalloc.c

@@ -8,7 +8,7 @@
 
 #define MAGIC 0x1f2e3d4c
 
-struct alist { int magic, size; struct alist *next, *last; };
+struct alist { int magic, size, index; int *end; struct alist *next, *last; };
 
 static struct alist list =  { 0, 0, 0, 0 };
 
@@ -16,14 +16,32 @@ static int mallocs=0;
 static int reallocs=0;
 static int frees=0;
 
+static int index = 0;
+
+static void
+die(char *msg, int index)
+{
+    fprintf(stderr, msg, index);
+    abort();
+}
+
+
 void *
-acalloc(int size, int count)
+acalloc(int count, int size)
 {
-    struct alist *ret = calloc(size + sizeof(struct alist), count);
+    struct alist *ret;
+
+    if ( size > 1 ) {
+	count *= size;
+	size = 1;
+    }
 
-    if ( ret ) {
+    if ( ret = calloc(count + sizeof(struct alist) + sizeof(int), size) ) {
 	ret->magic = MAGIC;
 	ret->size = size * count;
+	ret->index = index ++;
+	ret->end = (int*)(count + (char*) (ret + 1));
+	*(ret->end) = ~MAGIC;
 	if ( list.next ) {
 	    ret->next = list.next;
 	    ret->last = &list;
@@ -54,6 +72,8 @@ afree(void *ptr)
     struct alist *p2 = ((struct alist*)ptr)-1;
 
     if ( p2->magic == MAGIC ) {
+	if ( ! (p2->end && *(p2->end) == ~MAGIC) )
+	    die("goddam: corrupted memory block %d in free()!\n", p2->index);
 	p2->last->next = p2->next;
 	p2->next->last = p2->last;
 	++frees;
@@ -71,12 +91,16 @@ arealloc(void *ptr, int size)
     struct alist save;
 
     if ( p2->magic == MAGIC ) {
+	if ( ! (p2->end && *(p2->end) == ~MAGIC) )
+	    die("goddam: corrupted memory block %d in realloc()!\n", p2->index);
 	save.next = p2->next;
 	save.last = p2->last;
-	p2 = realloc(p2, sizeof(*p2) + size);
+	p2 = realloc(p2, sizeof(int) + sizeof(*p2) + size);
 
 	if ( p2 ) {
 	    p2->size = size;
+	    p2->end = (int*)(size + (char*) (p2 + 1));
+	    *(p2->end) = ~MAGIC;
 	    p2->next->last = p2;
 	    p2->last->next = p2;
 	    ++reallocs;

+ 1 - 1
discount/config.cmd

@@ -1,2 +1,2 @@
 #! /bin/sh
-CC='gcc'  ./configure.sh 
+  ./configure.sh 

+ 21 - 13
discount/config.h

@@ -1,27 +1,35 @@
 /*
- * configuration for markdown, generated Mon Dec  5 22:48:15 GMT 2011
- * by mingo2@mingov
+ * configuration for markdown, generated Fri Mar 11 09:57:13 GMT 2016
+ * by mingo@mingo-Lenovo-G580
  */
 #ifndef __AC_MARKDOWN_D
 #define __AC_MARKDOWN_D 1
 
 
-#define OS_MINGW32_NT 1
-#define USE_DISCOUNT_DL 1
-#define DWORD unsigned long
-#define WORD unsigned short
-#define BYTE unsigned char
-#define HAVE_SRAND 1
-#define INITRNG(x) srand((unsigned int)x)
+#define OS_LINUX 1
+#define THEME_CF 1
+#define while(x) while( (x) != 0 )
+#define if(x) if( (x) != 0 )
+#define DWORD unsigned int
+#define WORD unsigned short
+#define BYTE unsigned char
+#define HAVE_BASENAME 1
+#define HAVE_LIBGEN_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_ALLOCA_H 1
+#define HAVE_PWD_H 1
+#define HAVE_GETPWUID 1
+#define HAVE_SRANDOM 1
+#define INITRNG(x) srandom((unsigned int)x)
 #define HAVE_BZERO 1
-#define HAVE_RAND 1
-#define COINTOSS() (rand()&1)
+#define HAVE_RANDOM 1
+#define COINTOSS() (random()&1)
 #define HAVE_STRCASECMP 1
 #define HAVE_STRNCASECMP 1
-#define HAVE_GETCWD 1
+#define HAVE_FCHDIR 1
 #define TABSTOP 4
 #define HAVE_MALLOC_H 1
-#define PATH_FIND "/bin/find"
+#define PATH_FIND "/usr/bin/find"
 #define PATH_SED "/bin/sed"
 
 #endif/* __AC_MARKDOWN_D */

+ 1 - 1
discount/config.md

@@ -1,5 +1,5 @@
 #! /bin/sh
-# script generated Mon Dec 5 22:48:16 GMT 2011 by configure.sh
+# script generated Fri Mar 11 09:57:13 GMT 2016 by configure.sh
 
 test -d "$1" || mkdir -p "$1"
 exit 0

+ 17 - 18
discount/config.sub

@@ -1,35 +1,34 @@
-s;@CPP@;/mingw/bin/cpp;g
+s;@CPP@;/lib/cpp;g
 s;@CPPFLAGS@;;g
-s;@INSTALL@;/bin/install;g
-s;@INSTALL_PROGRAM@;/bin/install -s -m 755;g
-s;@INSTALL_DATA@;/bin/install -m 444;g
-s;@INSTALL_DIR@;/g/c/discount-2.1.2/config.md;g
-s;@CC@;gcc;g
-s;@AR@;/mingw/bin/ar;g
-s;@RANLIB@;/mingw/bin/ranlib;g
-s:@DWORD@:unsigned long:g
-s:@WORD@:unsigned short:g
-s:@BYTE@:unsigned char:g
+s;@INSTALL@;/usr/bin/install;g
+s;@INSTALL_PROGRAM@;/usr/bin/install -s -m 755;g
+s;@INSTALL_DATA@;/usr/bin/install -m 444;g
+s;@INSTALL_DIR@;./config.md;g
+s;@AR@;/usr/bin/ar;g
+s;@RANLIB@;/usr/bin/ranlib;g
+s:@DWORD@:unsigned int:g
+s:@WORD@:unsigned short:g
+s:@BYTE@:unsigned char:g
 s;@THEME@;;g
 s;@TABSTOP@;4;g
 s;@AMALLOC@;;g
 s;@LIBS@;;g
 s;@CONFIGURE_FILES@;config.cmd config.sub config.h config.mak config.log config.md;g
 s;@GENERATED_FILES@;Makefile version.c mkdio.h;g
+s;@CC@;cc -Wno-return-type -Wno-implicit-int;g
 s;@CFLAGS@;-g;g
 s;@LDFLAGS@;-g;g
-s;@srcdir@;/g/c/discount-2.1.2;g
+s;@srcdir@;/home/mingo/dev/SquiLu/discount;g
 s;@prefix@;/usr/local;g
 s;@exedir@;/usr/local/bin;g
 s;@sbindir@;/usr/local/sbin;g
 s;@libdir@;/usr/local/lib;g
 s;@libexec@;/usr/local/lib;g
 s;@confdir@;/etc;g
-s;@mandir@;/usr/local/share/man;g
-s;@FIND@;/bin/find;g
-s;@LN_S@;;g
-s;@LN@;/bin/ln;g
-s;@AR@;/mingw/bin/ar;g
-s;@RANLIB@;/mingw/bin/ranlib;g
+s;@mandir@;/usr/local/man;g
+s;@FIND@;/usr/bin/find;g
+s;@LN_S@;/bin/ln -s;g
+s;@AR@;/usr/bin/ar;g
+s;@RANLIB@;/usr/bin/ranlib;g
 s;@LD_LIBRARY_PATH@;HERE;g
 s;@SED@;/bin/sed;g

+ 155 - 96
discount/configure.inc

@@ -169,7 +169,7 @@ AC_CHECK_HEADERS () {
     for hdr in $*; do
 	echo "#include <$hdr>" >> ngc$$.c
     done
-    echo "main() { }" >> ngc$$.c
+    echo "int main() { }" >> ngc$$.c
 
     LOGN "looking for header $hdr"
 
@@ -193,8 +193,8 @@ AC_CHECK_FUNCS () {
     B=`echo "$1" | sed -e 's/(.*)//'`
 
     case "$B" in
-    "$1") F="$1()" ;;
-    *)    F="$1" ;;
+    "$1") F="$1()"; need_proto=1 ;;
+    *)    F="$1"  ; unset need_proto ;;
     esac
 
     shift
@@ -205,8 +205,12 @@ AC_CHECK_FUNCS () {
 	shift
     done
 
+    if [ "$need_proto" ]; then
+	echo "void $F;" >> ngc$$.c
+    fi
+
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
 
     $F;
@@ -247,7 +251,7 @@ AC_CHECK_STRUCT () {
     done
 
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
     struct $struct foo;
 }
@@ -282,7 +286,7 @@ AC_CHECK_TYPE () {
     done
 
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
     $type foo;
 }
@@ -319,7 +323,7 @@ AC_CHECK_FIELD () {
     done
 
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
     struct $struct foo;
 
@@ -348,7 +352,7 @@ AC_PROG_CC () {
 
     cat > ngc$$.c << \EOF
 #include <stdio.h>
-main()
+int main()
 {
     puts("hello, sailor");
 }
@@ -356,7 +360,7 @@ EOF
 
     TLOGN "checking the C compiler"
 
-    unset AC_CFLAGS AC_LDFLAGS
+    unset AC_CFLAGS AC_LDFLAGS __MACOS_DSYM
 
     if [ "$CC" ] ; then
 	AC_CC="$CC"
@@ -377,19 +381,19 @@ EOF
     fi
     echo "checking out the C compiler"
 
-    unset __MACOS_DSYM
     $AC_CC -o ngc$$ ngc$$.c
     status=$?
-    test -d ngc$$.dSYM && __MACOS_DSYM=1
 
     TLOGN " ($AC_CC)"
 
     if [ $status -eq 0 ]; then
 	if $AC_CC -x c /dev/null -dM -E 2>&1 | grep '__clang__' >/dev/null; then
 	    TLOG " yuck, you're using clang"
+	    IS_CLANG=T
 	    IS_BROKEN_CC=T
 	elif $AC_CC -v 2>&1 | grep 'gcc version' >/dev/null; then
 	    TLOG " oh ick, it looks like gcc"
+	    IS_GCC=T
 	    IS_BROKEN_CC=T
 	else
 	    TLOG " ok"
@@ -421,12 +425,16 @@ EOF
 	else
 	    AC_LDFLAGS=${CFLAGS:-"-g"}
 	fi
+	
+	# macos-specific(?) test for .dSYM resource directories
+	$AC_CC $AC_CFLAGS $AC_LDFLAGS -o ngc$$ ngc$$.c
+	ls -dl ngc$$*
+	test -d ngc$$.dSYM && __MACOS_DSYM=1
+	
     else
 	AC_FAIL " does not compile code properly"
     fi
 
-    AC_SUB 'CC' "$AC_CC"
-
     __remove ngc$$ ngc$$.c ngc$$.o
 
     return $status
@@ -505,7 +513,7 @@ AC_INIT () {
     __config_files="config.cmd config.sub config.h config.mak config.log"
     rm -f $__config_files
     __cwd=`pwd`
-    exec 5>&1 1>$__cwd/config.log 2>&1
+    exec 5>&1 1>"$__cwd"/config.log 2>&1
     AC_CONFIGURE_FOR=__AC_`echo $1 | sed -e 's/\..$//' | $AC_UPPERCASE  | tr ' ' '_'`_D
 
     # check to see whether to use echo -n or echo ...\c
@@ -528,7 +536,7 @@ AC_INIT () {
 
     LOG "Configuring for [$1]"
 
-    cat > $__cwd/config.h << EOF
+    cat > "$__cwd"/config.h << EOF
 /*
  * configuration for $1${2:+" ($2)"}, generated `date`
  * by ${LOGNAME:-`whoami`}@`hostname`
@@ -864,6 +872,18 @@ AC_C_INLINE() {
 # AC_SCALAR_TYPES checks to see if the compiler can generate 2 and 4 byte ints.
 #
 AC_SCALAR_TYPES () {
+
+    rc=1
+    LOGN "defining WORD & DWORD scalar types"
+    
+    if AC_QUIET AC_CHECK_HEADERS WinDef.h; then
+	# windows machine; BYTE, WORD, DWORD already
+	# defined
+	echo "#include <WinDef.h>" >> "$__cwd"/config.h
+	TLOG " (defined in WinDef.h)"
+	return 0
+    fi
+	
     cat > ngc$$.c << EOF
 #include <stdio.h>
 #include <string.h>
@@ -904,22 +924,20 @@ char **argv;
     exit(0);
 }
 EOF
-    rc=1
-    LOGN "defining WORD & DWORD scalar types"
     if $AC_CC ngc$$.c -o ngc$$; then
 	while [ "$1" ]; do
 	    case "$1" in
-	    sub)if ./ngc$$ sub >> $__cwd/config.sub; then
+	    sub)if ./ngc$$ sub >> "$__cwd"/config.sub; then
 		    rc=0
 		fi;;
-	    *)  if ./ngc$$ >> $__cwd/config.h; then
+	    *)  if ./ngc$$ >> "$__cwd"/config.h; then
 		    rc=0
 		fi ;;
 	    esac
 	    shift
 	done
 	if [ "$rc" != 0 ]; then
-	    if ./ngc$$ >> $__cwd/config.h; then
+	    if ./ngc$$ >> "$__cwd"/config.h; then
 		rc=1
 	    fi
 	fi
@@ -929,6 +947,7 @@ EOF
     0) TLOG "" ;;
     *) AC_FAIL " ** FAILED **" ;;
     esac
+    return $rc
 }
 
 
@@ -936,10 +955,19 @@ EOF
 # AC_OUTPUT generates makefiles from makefile.in's
 #
 AC_OUTPUT () {
-    cd $__cwd
+    
+    cd "$__cwd"
     AC_SUB 'LIBS'    "$AC_LIBS"
     AC_SUB 'CONFIGURE_FILES' "$__config_files"
-    AC_SUB 'GENERATED_FILES' "$*"
+    
+    if test "$__MACOS_DSYM"; then
+	# deal with extra OSX droppings, if they exist
+	AC_SUB 'GENERATED_FILES' "-r *.dSYM $*"
+    else
+	AC_SUB 'GENERATED_FILES' "$*"
+    fi
+    
+    AC_SUB 'CC'      "$AC_CC"
     AC_SUB 'CFLAGS'  "$AC_CFLAGS"
     AC_SUB 'LDFLAGS' "$AC_LDFLAGS"
     AC_SUB 'srcdir'  "$AC_SRCDIR"
@@ -965,7 +993,7 @@ AC_OUTPUT () {
 	AC_PROG ar
 	AC_PROG ranlib
 	AC_SUB LD_LIBRARY_PATH HERE
-	AC
+
 	__config_files="$__config_files librarian.sh"
 	cat > librarian.sh << EOF
 #! /bin/sh
@@ -1008,10 +1036,10 @@ EOF
 
 	__d=$AC_SRCDIR
 	for makefile in $*;do
-	    if test -r $__d/${makefile}.in; then
+	    if test -r "$__d/${makefile}.in"; then
 		LOG "generating $makefile"
 		./config.md `__ac_dirname ./$makefile` 2>/dev/null
-		$AC_SED_PROG -f config.sub < $__d/${makefile}.in > $makefile
+		$AC_SED_PROG -f config.sub < "$__d/${makefile}.in" > $makefile
 		__config_files="$__config_files $makefile"
 	    else
 		LOG "WARNING: ${makefile}.in does not exist!"
@@ -1038,7 +1066,7 @@ AC_CHECK_FLOCK() {
 #include <sys/types.h>
 #include <fcntl.h>
 
-main()
+int main()
 {
     int x = open("$$.c", O_RDWR, 0666);
     int y = open("$$.c", O_RDWR, 0666);
@@ -1091,7 +1119,7 @@ AC_CHECK_RESOLVER () {
 #include <arpa/nameser.h>
 #include <resolv.h>
 
-main()
+int main()
 {
     char bfr[256];
 
@@ -1103,14 +1131,15 @@ EOF
     if $AC_CC -o ngc$$ ngc$$.c; then
 	TLOG " (found)"
     elif $AC_CC -o ngc$$ ngc$$.c -lresolv; then
-	TLOG " (found, needs -lresolv)"
+	TLOG " (yes, needs -lresolv)"
 	AC_LIBS="$AC_LIBS -lresolv"
     elif $AC_CC -DBIND_8_COMPAT -o ngc$$ ngc$$.c; then
-	TLOG " (found, needs BIND_8_COMPAT)"
+	TLOG " (fyes, needs BIND_8_COMPAT)"
 	AC_DEFINE BIND_8_COMPAT 1
     elif $AC_CC -DBIND_8_COMPAT -o ngc$$ ngc$$.c -lresolv; then
-	TLOG " (found, needs BIND_8_COMPAT & -lresolv)"
+	TLOG " (yes, needs BIND_8_COMPAT & -lresolv)"
 	AC_DEFINE BIND_8_COMPAT 1
+	AC_LIBS="$AC_LIBS -lresolv"
     else
 	TLOG " (not found)"
 	__ACR_rc=1
@@ -1134,7 +1163,7 @@ AC_CHECK_ALLOCA () {
 #else
 # include <stdlib.h>
 #endif
-main()
+int main()
 {
 	alloca(10);
 }
@@ -1168,11 +1197,16 @@ AC_CHECK_BASENAME() {
     cat > ngc$$.c << EOF
 #include <string.h>
 
-main()
+extern char *basename(char*);
+
+int main()
 {
     char *a = basename("/a/test");
     char *b = basename("/a/nother");
 
+    if ( a == 0 || b == 0 || a == b )
+	return 0;
+
     return (strcmp(a,b) != 0) ? 0 : 1;
 
 }
@@ -1214,31 +1248,16 @@ AC_COMPILER_PIC () {
     return $__rc
 }
 
-#
-# AC_CC_SHLIBS checks if the C compiler can produce shared libraries
-# and if it can writes a librarian that handles those libraries for us.
-#
-AC_CC_SHLIBS () {
-    AC_PROG_CC || AC_FAIL "Need a C compiler to build shared libraries"
-    AC_PROG_LN_S || AC_FAIL "Need to be able to make symbolic links for shared libraries"
-    AC_PROG_INSTALL || AC_FAIL "Need an install program to install shared libraries"
-    LOGN "checking whether the C compiler can build shared libraries "
-
-    echo "int some_variable = 0;" > ngc$$.c 
 
-    if $AC_CC $AC_PICFLAG -shared -o ngc$$.so ngc$$.c; then
-	AC_SUB LD_LIBRARY_PATH LD_LIBRARY_PATH
-	# -Wl option probably works, but be paranoid anyway
-	_VFLAGS="$AC_PICFLAG -shared -Wl,-soname,ngc$$.so.1"
-	if $AC_CC $_VFLAGS -o ngc$$.so ngc$$.c; then
-	    USE_SONAME=T
-	fi
-	LDCONFIG=`AC_PATH=/sbin:/usr/sbin:/usr/local/sbin acLookFor ldconfig`
-	__config_files="$__config_files librarian.sh"
-	cat > librarian.sh << EOF
+# generate a macosX librarian
+#
+__AC_MACOS_LIBRARIAN() {
+    AC_SUB LD_LIBRARY_PATH DYLD_LIBRARY_PATH
+    __config_files="$__config_files librarian.sh"
+    cat > librarian.sh << EOF
 #! /bin/sh
 #
-#  Build ELF shared libraries, hiding (some) ickiness from the makefile
+#  Build MacOS shared libraries, hiding (some) ickiness from the makefile
 
 ACTION=\$1; shift
 LIBRARY=\$1; shift
@@ -1247,41 +1266,43 @@ eval \`awk -F. '{ printf "MAJOR=%d\n", \$1;
 		  printf "VERSION=%d.%d.%d\n", \$1, \$2, \$3; }' \$1\`
 shift
 
-LIBNAME=\$LIBRARY.so
-FULLNAME=\$LIBNAME.\$VERSION
+LIBNAME=\$LIBRARY.dylib
+FULLNAME=\$LIBNAME
 
 case "\$ACTION" in
-make)   FLAGS="$AC_CFLAGS -shared"
-	unset VFLAGS
-	test "$USE_SONAME" && VFLAGS="-Wl,-soname,\$LIBNAME.\$MAJOR"
+make)   FLAGS="$AC_CFLAGS -dynamiclib"
+	VFLAGS="-current_version \$VERSION -compatibility_version \$MAJOR"
 
-	rm -f \$LIBRARY \$LIBNAME \$LIBNAME.\$MAJOR
+	rm -f \$LIBRARY
 	if $AC_CC \$FLAGS \$VFLAGS -o \$FULLNAME "\$@"; then
 	    $PROG_LN_S \$FULLNAME \$LIBRARY
-	    $PROG_LN_S \$FULLNAME \$LIBNAME
-	    $PROG_LN_S \$FULLNAME \$LIBNAME.\$MAJOR
 	fi
 	;;
-files)  echo "\$FULLNAME" "\$LIBNAME" "\$LIBNAME.\$MAJOR"
+files)  echo "\$FULLNAME"
 	;;
 install)$PROG_INSTALL -c \$FULLNAME "\$1"
-	$PROG_LN_S -f \$FULLNAME \$1/\$LIBNAME.\$MAJOR
-	$PROG_LN_S -f \$FULLNAME \$1/\$LIBNAME
-	test "$LDCONFIG" && $LDCONFIG "\$1"
 	;;
 esac
 EOF
-	chmod +x librarian.sh
-        LOG "(yes; -shared)"
-	__rc=0
-    elif $AC_CC $AC_PICFLAG  -dynamiclib -o ngc$$.so ngc$$.c; then
-	# macosx
-	AC_SUB LD_LIBRARY_PATH DYLD_LIBRARY_PATH
-	__config_files="$__config_files librarian.sh"
-	cat > librarian.sh << EOF
+    chmod +x librarian.sh
+}
+
+
+# Generate an ELF librarian (for Linux, freebsd)
+#
+__AC_ELF_LIBRARIAN() {
+    AC_SUB LD_LIBRARY_PATH LD_LIBRARY_PATH
+    # -Wl option probably works, but be paranoid anyway
+    _VFLAGS="$AC_PICFLAG -shared -Wl,-soname,ngc$$.so.1"
+    if $AC_CC $_VFLAGS -o ngc$$.so ngc$$.c; then
+	USE_SONAME=T
+    fi
+    LDCONFIG=`AC_PATH=/sbin:/usr/sbin:/usr/local/sbin acLookFor ldconfig`
+    __config_files="$__config_files librarian.sh"
+    cat > librarian.sh << EOF
 #! /bin/sh
 #
-#  Build MacOS shared libraries, hiding (some) ickiness from the makefile
+#  Build ELF shared libraries, hiding (some) ickiness from the makefile
 
 ACTION=\$1; shift
 LIBRARY=\$1; shift
@@ -1290,26 +1311,62 @@ eval \`awk -F. '{ printf "MAJOR=%d\n", \$1;
 		  printf "VERSION=%d.%d.%d\n", \$1, \$2, \$3; }' \$1\`
 shift
 
-LIBNAME=\$LIBRARY.dylib
-FULLNAME=\$LIBNAME
+LIBNAME=\$LIBRARY.so
+FULLNAME=\$LIBNAME.\$VERSION
 
 case "\$ACTION" in
-make)   FLAGS="$AC_CFLAGS -dynamiclib"
-	VFLAGS="-current_version \$VERSION -compatibility_version \$MAJOR"
+make)   FLAGS="$AC_CFLAGS -shared"
+	unset VFLAGS
+	test "$USE_SONAME" && VFLAGS="-Wl,-soname,\$LIBNAME.\$MAJOR"
 
-	rm -f \$LIBRARY
+	rm -f \$LIBRARY \$LIBNAME \$LIBNAME.\$MAJOR
 	if $AC_CC \$FLAGS \$VFLAGS -o \$FULLNAME "\$@"; then
 	    $PROG_LN_S \$FULLNAME \$LIBRARY
+	    $PROG_LN_S \$FULLNAME \$LIBNAME
+	    $PROG_LN_S \$FULLNAME \$LIBNAME.\$MAJOR
 	fi
 	;;
-files)  echo "\$FULLNAME"
+files)  echo "\$FULLNAME" "\$LIBNAME" "\$LIBNAME.\$MAJOR"
 	;;
 install)$PROG_INSTALL -c \$FULLNAME "\$1"
+	$PROG_LN_S -f \$FULLNAME \$1/\$LIBNAME.\$MAJOR
+	$PROG_LN_S -f \$FULLNAME \$1/\$LIBNAME
+EOF
+    test "$LDCONFIG" && echo '	'$LDCONFIG '"$1"' >> librarian.sh
+    cat >> librarian.sh << EOF
 	;;
 esac
 EOF
-	chmod +x librarian.sh
-        LOG "(yes; macos dylib)"
+    chmod +x librarian.sh
+}
+
+
+#
+# AC_CC_SHLIBS checks if the C compiler can produce shared libraries
+# and if it can writes a librarian that handles those libraries for us.
+#
+AC_CC_SHLIBS () {
+    AC_PROG_CC || AC_FAIL "Need a C compiler to build shared libraries"
+    AC_PROG_LN_S || AC_FAIL "Need to be able to make symbolic links for shared libraries"
+    AC_PROG_INSTALL || AC_FAIL "Need an install program to install shared libraries"
+    LOGN "checking whether the C compiler can build shared libraries "
+
+    echo "int some_variable = 0;" > ngc$$.c 
+
+    if uname -a | grep Darwin >/dev/null; then
+	# Claims to be macos?
+	if $AC_CC $AC_PICFLAG  -dynamiclib -o ngc$$.so ngc$$.c; then
+	    __AC_MACOS_LIBRARIAN
+
+	    LOG "(yes; macos dylib)"
+	    __rc=0
+	else
+	    LOG "(no)"
+	    __rc=1
+	fi
+    elif $AC_CC $AC_PICFLAG -shared -o ngc$$.so ngc$$.c; then
+	__AC_ELF_LIBRARIAN
+        LOG "(yes; -shared)"
 	__rc=0
     else
         LOG "(no)"
@@ -1383,15 +1440,15 @@ AC_PROG_INSTALL () {
     fi
 
     __config_files="$__config_files config.md"
-    AC_SUB 'INSTALL_DIR' "$__cwd/config.md"
-    echo "#! /bin/sh"                                   > $__cwd/config.md
-    echo "# script generated" `date` "by configure.sh" >> $__cwd/config.md
-    echo                                               >> $__cwd/config.md
+    AC_SUB 'INSTALL_DIR' "./config.md"
+    echo "#! /bin/sh"                                   > ""$__cwd"/config.md"
+    echo "# script generated" `date` "by configure.sh" >> ""$__cwd"/config.md"
+    echo                                               >> ""$__cwd"/config.md"
     if [ "$__mkdir" ]; then
-	echo "test -d \"\$1\" || $__mkdir \"\$1\""     >> $__cwd/config.md
-	echo "exit $?"                                 >> $__cwd/config.md
+	echo "test -d \"\$1\" || $__mkdir \"\$1\""     >> ""$__cwd"/config.md"
+	echo "exit $?"                                 >> ""$__cwd"/config.md"
     else
-	cat - >> $__cwd/config.md << \EOD
+	cat - >> ""$__cwd"/config.md" << \EOD
 pieces=`IFS=/; for x in $1; do echo $x; done`
 dir=
 for x in $pieces; do
@@ -1402,7 +1459,7 @@ done
 exit 0
 EOD
     fi
-    chmod +x $__cwd/config.md
+    chmod +x "$__cwd"/config.md
 }
 
 #
@@ -1474,26 +1531,28 @@ AC_FAIL() {
 #
 # AC_SUB writes a substitution into config.sub
 AC_SUB() {
-    (   _subst=`echo $2 | sed -e 's/;/\\;/g'`
-	echo "s;@$1@;$_subst;g" ) >> $__cwd/config.sub
+    (   _target="$1"
+	shift
+	_subst=`echo "$*" | sed -e 's/;/\\;/g'`
+	echo "s;@$_target@;$_subst;g" ) >> "$__cwd"/config.sub
 }
 
 #
 # AC_MAK writes a define into config.mak
 AC_MAK() {
-    echo "HAVE_$1 = 1" >> $__cwd/config.mak
+    echo "HAVE_$1 = 1" >> "$__cwd"/config.mak
 }
 
 #
 # AC_DEFINE adds a #define to config.h
 AC_DEFINE() {
-    echo "#define $1 ${2:-1}" >> $__cwd/config.h
+    echo "#define $1 ${2:-1}" >> "$__cwd"/config.h
 }
 
 #
 # AC_INCLUDE adds a #include to config.h
 AC_INCLUDE() {
-    echo "#include \"$1\"" >> $__cwd/config.h
+    echo "#include \"$1\"" >> "$__cwd"/config.h
 }
 
 #

+ 37 - 18
discount/configure.sh

@@ -9,10 +9,7 @@
 #
 ac_help='--enable-amalloc	Enable memory allocation debugging
 --with-tabstops=N	Set tabstops to N characters (default is 4)
---with-dl=X		Use Discount, Extra, or Both types of definition list
---with-id-anchor	Use id= anchors for table-of-contents links
---with-github-tags	Allow `_` and `-` in <> tags
---with-fenced-code	Allow fenced code blocks
+--with-latex		Enable latex passthrough
 --enable-all-features	Turn on all stable optional features
 --shared		Build shared libraries (default is static)'
 
@@ -36,6 +33,9 @@ locals() {
 		;;
     --ENABLE-*)	enable=`echo $K | sed -e 's/--ENABLE-//' | tr '-' '_'`
 		echo WITH_${enable}=T ;;
+    --DEBIAN-GLITCH)
+		echo DEBIAN_GLITCH=T
+		;;
     esac
 }
 
@@ -44,28 +44,45 @@ TARGET=markdown
 
 AC_INIT $TARGET
 
-__DL=`echo "$WITH_DL" | $AC_UPPERCASE`
+for banned_with in dl fenced-code id-anchor github-tags urlencoded-anchor; do
+    banned_with_variable_ref=\$WITH_`echo "$banned_with" | $AC_UPPERCASE | tr - _`
+    if [ "`eval echo "$banned_with_variable_ref"`" ]; then
+	LOG "Setting theme default --with-$banned_with."
+    fi
+done
 
-case "$__DL" in
-EXTRA)         AC_DEFINE 'USE_EXTRA_DL' 1 ;;
-DISCOUNT|1|"") AC_DEFINE 'USE_DISCOUNT_DL' 1 ;;
-BOTH)          AC_DEFINE 'USE_EXTRA_DL' 1
-	       AC_DEFINE 'USE_DISCOUNT_DL' 1 ;;
-*)             AC_FAIL "Unknown value <$WITH_DL> for --with-dl (want 'discount', 'extra', or 'both')" ;;
+# theme wants the old behavior of --with-(foo)
+#
+case "`echo "$WITH_DL" | $AC_UPPERCASE`" in
+    EXTRA)         THEME_CF="MKD_DLEXTRA|MKD_NODLDISCOUNT";;
+    BOTH)          THEME_CF="MKD_DLEXTRA";;
 esac
+test "$WITH_FENCED_CODE" && THEME_CF="${THEME_CF:+$THEME_CF|}MKD_FENCEDCODE"
+
+AC_DEFINE THEME_CF "$THEME_CF"
+
 
-test "$WITH_FENCED_CODE" && AC_DEFINE "WITH_FENCED_CODE" 1
-test "$WITH_ID_ANCHOR" && AC_DEFINE 'WITH_ID_ANCHOR' 1
-test "$WITH_GITHUB_TAGS" && AC_DEFINE 'WITH_GITHUB_TAGS' 1
+test "$DEBIAN_GLITCH" && AC_DEFINE 'DEBIAN_GLITCH' 1
 
 AC_PROG_CC
 
 test "$TRY_SHARED" && AC_COMPILER_PIC && AC_CC_SHLIBS
 
-case "$AC_CC $AC_CFLAGS" in
-*-Wall*)    AC_DEFINE 'while(x)' 'while( (x) != 0 )'
-	    AC_DEFINE 'if(x)' 'if( (x) != 0 )' ;;
-esac
+if [ "IS_BROKEN_CC" ]; then
+    case "$AC_CC $AC_CFLAGS" in
+    *-pedantic*) ;;
+    *)  # hack around deficiencies in gcc and clang
+	#
+	AC_DEFINE 'while(x)' 'while( (x) != 0 )'
+	AC_DEFINE 'if(x)' 'if( (x) != 0 )'
+
+	if [ "$IS_CLANG" ]; then
+	    AC_CC="$AC_CC -Wno-implicit-int"
+	elif [ "$IS_GCC" ]; then
+	    AC_CC="$AC_CC -Wno-return-type -Wno-implicit-int"
+	fi ;;
+    esac
+fi
 
 AC_PROG ar || AC_FAIL "$TARGET requires ar"
 AC_PROG ranlib
@@ -75,6 +92,7 @@ AC_C_CONST
 AC_C_INLINE
 AC_SCALAR_TYPES sub hdr
 AC_CHECK_BASENAME
+AC_CHECK_ALLOCA
 
 AC_CHECK_HEADERS sys/types.h pwd.h && AC_CHECK_FUNCS getpwuid
 
@@ -145,5 +163,6 @@ fi
 [ "$OS_FREEBSD" -o "$OS_DRAGONFLY" ] || AC_CHECK_HEADERS malloc.h
 
 [ "$WITH_PANDOC_HEADER" ] && AC_DEFINE 'PANDOC_HEADER' '1'
+[ "$WITH_LATEX" ] && AC_DEFINE 'WITH_LATEX' '1'
 
 AC_OUTPUT Makefile version.c mkdio.h

+ 5 - 3
discount/css.c

@@ -75,11 +75,13 @@ int
 mkd_generatecss(Document *d, FILE *f)
 {
     char *res;
-    int written = EOF, size = mkd_css(d, &res);
+    int written;
+    int size = mkd_css(d, &res);
 
-    if ( size > 0 )
-	written = fwrite(res, 1, size, f);
+    written = (size > 0) ? fwrite(res,1,size,f) : 0;
+    
     if ( res )
 	free(res);
+    
     return (written == size) ? size : EOF;
 }

+ 2 - 2
discount/cstring.h

@@ -27,9 +27,9 @@
 #define DELETE(x)	ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
 				     : ( S(x) = 0 )
 #define CLIP(t,i,sz)	\
-	    ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
+	    S(t) -= ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
 	    (memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
-		S(t) -= (sz)) : -1
+		(sz)) : 0
 
 #define RESERVE(x, sz)	T(x) = ((x).alloc > S(x) + (sz) \
 			    ? T(x) \

+ 1 - 1
discount/discount.cbp

@@ -35,7 +35,7 @@
 		<Compiler>
 			<Add option="-Wall" />
 			<Add option="-g" />
-			<Add directory="../discount-2.1.2" />
+			<Add directory="../discount" />
 		</Compiler>
 		<Linker>
 			<Add library="discount" />

+ 0 - 1
discount/dumptree.c

@@ -145,7 +145,6 @@ mkd_dump(Document *doc, FILE *out, int flags, char *title)
 	dumptree(doc->code, &stack, out);
 	DELETE(stack);
 
-	mkd_cleanup(doc);
 	return 0;
     }
     return -1;

+ 1 - 1
discount/emmatch.c

@@ -22,7 +22,7 @@
  *          of html has been generated.
  *
  *          It should create MarkdownTest_1.0 (and _1.0.3)
- *          compatable emphasis for non-pathological cases
+ *          compatible emphasis for non-pathological cases
  *          and it should fail in a standards-compliant way
  *          when someone attempts to feed it junk.
  *

+ 7 - 0
discount/flags.c

@@ -29,6 +29,13 @@ static struct flagnames flagnames[] = {
     { MKD_NOALPHALIST,    "!ALPHALIST" },
     { MKD_NODLIST,        "!DLIST" },
     { MKD_EXTRA_FOOTNOTE, "FOOTNOTE" },
+    { MKD_NOSTYLE,        "!STYLE" },
+    { MKD_NODLDISCOUNT,   "!DLDISCOUNT" },
+    { MKD_DLEXTRA,        "DLEXTRA" },
+    { MKD_FENCEDCODE,     "FENCEDCODE" },
+    { MKD_IDANCHOR,       "IDANCHOR" },
+    { MKD_GITHUBTAGS,     "GITHUBTAGS" },
+    { MKD_URLENCODEDANCHOR, "URLENCODEDANCHOR" },
 };
 #define NR(x)	(sizeof x/sizeof x[0])
 

+ 203 - 91
discount/generate.c

@@ -38,6 +38,16 @@ push(char *bfr, int size, MMIOT *f)
 }
 
 
+/*
+ * push a character into the generator input buffer
+ */
+static void 
+pushc(char c, MMIOT *f)
+{
+    EXPAND(f->in) = c;
+}
+
+
 /* look <i> characters ahead of the cursor.
  */
 static inline int
@@ -73,7 +83,11 @@ isthisspace(MMIOT *f, int i)
 {
     int c = peek(f, i);
 
-    return isspace(c) || (c == EOF);
+    if ( c == EOF )
+	return 1;
+    if ( c & 0x80 )
+	return 0;
+    return isspace(c) || (c < ' ');
 }
 
 
@@ -194,9 +208,10 @@ Qem(MMIOT *f, char c, int count)
 /* generate html from a markup fragment
  */
 void
-___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
+___mkd_reparse(char *bfr, int size, int flags, MMIOT *f, char *esc)
 {
     MMIOT sub;
+    struct escaped e;
 
     ___mkd_initmmiot(&sub, f->footnotes);
 
@@ -204,6 +219,14 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
     sub.cb = f->cb;
     sub.ref_prefix = f->ref_prefix;
 
+    if ( esc ) {
+	sub.esc = &e;
+	e.up = f->esc;
+	e.text = esc;
+    }
+    else
+	sub.esc = f->esc;
+
     push(bfr, size, &sub);
     EXPAND(sub.in) = 0;
     S(sub.in)--;
@@ -217,6 +240,23 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
 }
 
 
+/*
+ * check the escape list for special cases
+ */
+static int
+escaped(MMIOT *f, char c)
+{
+    struct escaped *thing = f->esc;
+
+    while ( thing ) {
+	if ( strchr(thing->text, c) )
+	    return 1;
+	thing = thing->up;
+    }
+    return 0;
+}
+
+
 /*
  * write out a url, escaping problematic characters
  */
@@ -243,7 +283,7 @@ puturl(char *s, int size, MMIOT *f, int display)
 	    Qstring("%22", f);
 	else if ( isalnum(c) || ispunct(c) || (display && isspace(c)) )
 	    Qchar(c, f);
-	else if ( c == 003 )	/* untokenize ^C */
+	else if ( c == MKD_EOLN )	/* untokenize hard return */
 	    Qstring("  ", f);
 	else
 	    Qprintf(f, "%%%02X", c);
@@ -366,7 +406,7 @@ linkysize(MMIOT *f, Footnote *ref)
 /* extract a <...>-encased url from the input stream.
  * (markdown 1.0.2b8 compatibility; older versions
  * of markdown treated the < and > as syntactic
- * sugar that didn't have to be there.  1.0.2b8
+ * sugar that didn't have to be there.  1.0.2b8 
  * requires a closing >, and then falls into the
  * title or closing )
  */
@@ -564,7 +604,7 @@ printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
 	    puturl(link + tag->szpat, size - tag->szpat, f, 0);
     }
     else
-	___mkd_reparse(link + tag->szpat, size - tag->szpat, MKD_TAGTEXT, f);
+	___mkd_reparse(link + tag->szpat, size - tag->szpat, MKD_TAGTEXT, f, 0);
 
     Qstring(tag->link_sfx, f);
 
@@ -596,10 +636,10 @@ extra_linky(MMIOT *f, Cstring text, Footnote *ref)
 	return 0;
 
     if ( f->flags & IS_LABEL )
-    	___mkd_reparse(T(text), S(text), linkt.flags, f);
+    	___mkd_reparse(T(text), S(text), linkt.flags, f, 0);
     else {
 	ref->flags |= REFERENCED;
-	ref->refnumber = ++ f->reference;
+	ref->refnumber = ++ f->footnotes->reference;
 	Qprintf(f, "<sup id=\"%sref:%d\"><a href=\"#%s:%d\" rel=\"footnote\">%d</a></sup>",
 		p_or_nothing(f), ref->refnumber,
 		p_or_nothing(f), ref->refnumber, ref->refnumber);
@@ -615,7 +655,8 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
 {
     linkytype *tag;
 
-    if ( image || (ref == 0) )
+
+    if ( image )
 	tag = &imaget;
     else if ( tag = pseudo(ref->link) ) {
 	if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) )
@@ -635,7 +676,7 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
 	return 0;
 
     if ( f->flags & IS_LABEL )
-	___mkd_reparse(T(text), S(text), tag->flags, f);
+	___mkd_reparse(T(text), S(text), tag->flags, f, 0);
     else if ( tag->link_pfx ) {
 	printlinkyref(f, tag, T(ref->link), S(ref->link));
 
@@ -646,12 +687,12 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
 
 	if ( S(ref->title) ) {
 	    Qstring(" title=\"", f);
-	    ___mkd_reparse(T(ref->title), S(ref->title), MKD_TAGTEXT, f);
+	    ___mkd_reparse(T(ref->title), S(ref->title), MKD_TAGTEXT, f, 0);
 	    Qchar('"', f);
 	}
 
 	Qstring(tag->text_pfx, f);
-	___mkd_reparse(T(text), S(text), tag->flags, f);
+	___mkd_reparse(T(text), S(text), tag->flags, f, 0);
 	Qstring(tag->text_sfx, f);
     }
     else
@@ -711,8 +752,9 @@ linkylinky(int image, MMIOT *f)
 		    S(key.tag) = S(name);
 		}
 
-		if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
-					  sizeof key, (stfu)__mkd_footsort) ) {
+		if ( ref = bsearch(&key, T(f->footnotes->note),
+					 S(f->footnotes->note),
+					 sizeof key, (stfu)__mkd_footsort) ) {
 		    if ( extra_footnote )
 			status = extra_linky(f,name,ref);
 		    else
@@ -756,8 +798,12 @@ static void
 mangle(char *s, int len, MMIOT *f)
 {
     while ( len-- > 0 ) {
+#if DEBIAN_GLITCH
+	Qprintf(f, "&#%02d;", *((unsigned char*)(s++)) );
+#else
 	Qstring("&#", f);
 	Qprintf(f, COINTOSS() ? "x%02x;" : "%02d;", *((unsigned char*)(s++)) );
+#endif
     }
 }
 
@@ -819,20 +865,21 @@ code(MMIOT *f, char *s, int length)
     int i,c;
 
     for ( i=0; i < length; i++ )
-	if ( (c = s[i]) == 003)  /* ^C: expand back to 2 spaces */
+	if ( (c = s[i]) == MKD_EOLN)  /* ^C: expand back to 2 spaces */
 	    Qstring("  ", f);
+	else if ( c == '\\' && (i < length-1) && escaped(f, s[i+1]) )
+	    cputc(s[++i], f);
 	else
 	    cputc(c, f);
 } /* code */
 
-
 /*  delspan() -- write out a chunk of text, blocking with <del>...</del>
  */
 static void
 delspan(MMIOT *f, int size)
 {
     Qstring("<del>", f);
-    ___mkd_reparse(cursor(f)-1, size, 0, f);
+    ___mkd_reparse(cursor(f)-1, size, 0, f, 0);
     Qstring("</del>", f);
 }
 
@@ -974,11 +1021,9 @@ maybe_tag_or_link(MMIOT *f)
 	}
 	else if ( isspace(c) )
 	    break;
-#if WITH_GITHUB_TAGS
-	else if ( ! (c == '/' || c == '-' || c == '_' || isalnum(c) ) )
-#else
-	else if ( ! (c == '/' || isalnum(c) ) )
-#endif
+	else if ( ! (c == '/'
+		     || (f->flags & MKD_GITHUBTAGS && (c == '-' || c == '_'))
+		     || isalnum(c) ) )
 	    maybetag=0;
     }
 
@@ -1024,13 +1069,16 @@ maybe_autolink(MMIOT *f)
 
     /* greedily scan forward for the end of a legitimate link.
      */
-    for ( size=0; (c=peek(f, size+1)) != EOF; size++ )
+    for ( size=0; (c=peek(f, size+1)) != EOF; size++ ) {
 	if ( c == '\\' ) {
 	     if ( peek(f, size+2) != EOF )
 		++size;
 	}
-	else if ( isspace(c) || strchr("'\"()[]{}<>`", c) )
+	else if ( c & 0x80 )	/* HACK: ignore utf-8 extended characters */
+	    continue;
+	else if ( isspace(c) || strchr("'\"()[]{}<>`", c) || c == MKD_EOLN )
 	    break;
+    }
 
     if ( (size > 1) && process_possible_link(f, size) ) {
 	shift(f, size);
@@ -1069,7 +1117,7 @@ islike(MMIOT *f, char *s)
     int len;
     int i;
 
-    if ( s[0] == '<' ) {
+    if ( s[0] == '|' ) {
 	if ( !isthisnonword(f, -1) )
 	    return 0;
        ++s;
@@ -1078,7 +1126,7 @@ islike(MMIOT *f, char *s)
     if ( !(len = strlen(s)) )
 	return 0;
 
-    if ( s[len-1] == '>' ) {
+    if ( s[len-1] == '|' ) {
 	if ( !isthisnonword(f,len-1) )
 	    return 0;
 	len--;
@@ -1097,13 +1145,13 @@ static struct smarties {
     char *entity;
     int shift;
 } smarties[] = {
-    { '\'', "'s>",      "rsquo",  0 },
-    { '\'', "'t>",      "rsquo",  0 },
-    { '\'', "'re>",     "rsquo",  0 },
-    { '\'', "'ll>",     "rsquo",  0 },
-    { '\'', "'ve>",     "rsquo",  0 },
-    { '\'', "'m>",      "rsquo",  0 },
-    { '\'', "'d>",      "rsquo",  0 },
+    { '\'', "'s|",      "rsquo",  0 },
+    { '\'', "'t|",      "rsquo",  0 },
+    { '\'', "'re|",     "rsquo",  0 },
+    { '\'', "'ll|",     "rsquo",  0 },
+    { '\'', "'ve|",     "rsquo",  0 },
+    { '\'', "'m|",      "rsquo",  0 },
+    { '\'', "'d|",      "rsquo",  0 },
     { '-',  "---",      "mdash",  2 },
     { '-',  "--",       "ndash",  1 },
     { '.',  "...",      "hellip", 2 },
@@ -1111,11 +1159,11 @@ static struct smarties {
     { '(',  "(c)",      "copy",   2 },
     { '(',  "(r)",      "reg",    2 },
     { '(',  "(tm)",     "trade",  3 },
-    { '3',  "<3/4>",    "frac34", 2 },
-    { '3',  "<3/4ths>", "frac34", 2 },
-    { '1',  "<1/2>",    "frac12", 2 },
-    { '1',  "<1/4>",    "frac14", 2 },
-    { '1',  "<1/4th>",  "frac14", 2 },
+    { '3',  "|3/4|",    "frac34", 2 },
+    { '3',  "|3/4ths|", "frac34", 2 },
+    { '1',  "|1/2|",    "frac12", 2 },
+    { '1',  "|1/4|",    "frac14", 2 },
+    { '1',  "|1/4th|",  "frac14", 2 },
     { '&',  "&#0;",      0,       3 },
 } ;
 #define NRSMART ( sizeof smarties / sizeof smarties[0] )
@@ -1157,7 +1205,7 @@ smartypants(int c, int *flags, MMIOT *f)
 			    break;
 			else if ( c == '\'' && peek(f, j+1) == '\'' ) {
 			    Qstring("&ldquo;", f);
-			    ___mkd_reparse(cursor(f)+1, j-2, 0, f);
+			    ___mkd_reparse(cursor(f)+1, j-2, 0, f, 0);
 			    Qstring("&rdquo;", f);
 			    shift(f,j+1);
 			    return 1;
@@ -1172,6 +1220,29 @@ smartypants(int c, int *flags, MMIOT *f)
 } /* smartypants */
 
 
+#if WITH_LATEX
+/* process latex with arbitrary 2-character ( $$ .. $$, \[ .. \], \( .. \)
+ * delimiters
+ */
+static int
+mathhandler(MMIOT *f, int e1, int e2)
+{
+    int i = 0;
+
+    while(peek(f, ++i) != EOF) {
+        if (peek(f, i) == e1 && peek(f, i+1) == e2) {
+	    cputc(peek(f,-1), f);
+	    cputc(peek(f, 0), f);
+	    while ( i-- > -1 )
+		cputc(pull(f), f);
+            return 1;
+        }
+    }
+    return 0;
+}
+#endif
+
+
 /* process a body of text encased in some sort of tick marks.   If it
  * works, generate the output and return 1, otherwise just return 0 and
  * let the caller figure it out.
@@ -1223,7 +1294,8 @@ text(MMIOT *f)
 	switch (c) {
 	case 0:     break;
 
-	case 3:     Qstring(tag_text(f) ? "  " : "<br/>", f);
+	case MKD_EOLN:
+		    Qstring(tag_text(f) ? "  " : "<br/>", f);
 		    break;
 
 	case '>':   if ( tag_text(f) )
@@ -1246,6 +1318,7 @@ text(MMIOT *f)
 		    else
 			Qchar(c, f);
 		    break;
+
 	case '[':   if ( tag_text(f) || !linkylinky(0, f) )
 			Qchar(c, f);
 		    break;
@@ -1279,7 +1352,7 @@ text(MMIOT *f)
 			    shift(f,len);
 			}
 			Qstring("<sup>",f);
-			___mkd_reparse(sup, len, 0, f);
+			___mkd_reparse(sup, len, 0, f, "()");
 			Qstring("</sup>", f);
 		    }
 		    break;
@@ -1319,7 +1392,16 @@ text(MMIOT *f)
 	case '\\':  switch ( c = pull(f) ) {
 		    case '&':   Qstring("&amp;", f);
 				break;
-		    case '<':   Qstring("&lt;", f);
+		    case '<':   c = peek(f,1);
+				if ( (c == EOF) || isspace(c) )
+				    Qstring("&lt;", f);
+				else {
+				    /* Markdown.pl does not escape <[nonwhite]
+				     * sequences */
+				    Qchar('\\', f);
+				    shift(f, -1);
+				}
+				
 				break;
 		    case '^':   if ( f->flags & (MKD_STRICT|MKD_NOSUPERSCRIPT) ) {
 				    Qchar('\\', f);
@@ -1337,17 +1419,24 @@ text(MMIOT *f)
 				}
 				Qchar(c, f);
 				break;
-
-		    case '>': case '#': case '.': case '-':
-		    case '+': case '{': case '}': case ']':
-		    case '!': case '[': case '*': case '_':
-		    case '\\':case '(': case ')':
-		    case '`':	Qchar(c, f);
+				
+		    case EOF:	Qchar('\\', f);
 				break;
-		    default:
-				Qchar('\\', f);
-				if ( c != EOF )
-				    shift(f,-1);
+
+#if WITH_LATEX
+		    case '[':
+		    case '(':   if ( mathhandler(f, '\\', (c =='(')?')':']') )
+				    break;
+				/* else fall through to default */
+#endif
+			
+		    default:    if ( escaped(f,c) ||
+				     strchr(">#.-+{}]![*_\\()`", c) )
+				    Qchar(c, f);
+				else {
+				    Qchar('\\', f);
+				    shift(f, -1);
+				}
 				break;
 		    }
 		    break;
@@ -1366,6 +1455,16 @@ text(MMIOT *f)
 			Qchar(c, f);
 		    break;
 
+#if WITH_LATEX
+	case '$':   if ( peek(f, 1) == '$' ) {
+			pull(f);
+			if ( mathhandler(f, '$', '$') )
+			    break;
+			Qchar('$', f);
+		    }
+		    /* fall through to default */
+#endif
+	
 	default:    Qchar(c, f);
 		    break;
 	}
@@ -1380,26 +1479,26 @@ text(MMIOT *f)
 static void
 printheader(Paragraph *pp, MMIOT *f)
 {
-#if WITH_ID_ANCHOR
-    Qprintf(f, "<h%d", pp->hnumber);
-    if ( f->flags & MKD_TOC ) {
-	Qstring(" id=\"", f);
-	mkd_string_to_anchor(T(pp->text->text),
-			     S(pp->text->text),
-			     (mkd_sta_function_t)Qchar, f, 1);
-	Qchar('"', f);
-    }
-    Qchar('>', f);
-#else
-    if ( f->flags & MKD_TOC ) {
-	Qstring("<a name=\"", f);
-	mkd_string_to_anchor(T(pp->text->text),
-			     S(pp->text->text),
-			     (mkd_sta_function_t)Qchar, f, 1);
-	Qstring("\"></a>\n", f);
+    if ( f->flags & MKD_IDANCHOR ) {
+	Qprintf(f, "<h%d", pp->hnumber);
+	if ( f->flags & MKD_TOC ) {
+	    Qstring(" id=\"", f);
+	    mkd_string_to_anchor(T(pp->text->text),
+				 S(pp->text->text),
+				 (mkd_sta_function_t)Qchar, f, 1, f->flags);
+	    Qchar('"', f);
+	}
+	Qchar('>', f);
+    } else {
+	if ( f->flags & MKD_TOC ) {
+	    Qstring("<a name=\"", f);
+	    mkd_string_to_anchor(T(pp->text->text),
+				 S(pp->text->text),
+				 (mkd_sta_function_t)Qchar, f, 1, f->flags);
+	    Qstring("\"></a>\n", f);
+	}
+	Qprintf(f, "<h%d>", pp->hnumber);
     }
-    Qprintf(f, "<h%d>", pp->hnumber);
-#endif
     push(T(pp->text->text), S(pp->text->text), f);
     text(f);
     Qprintf(f, "</h%d>", pp->hnumber);
@@ -1408,8 +1507,9 @@ printheader(Paragraph *pp, MMIOT *f)
 
 enum e_alignments { a_NONE, a_CENTER, a_LEFT, a_RIGHT };
 
-static char* alignments[] = { "", " align=\"center\"", " align=\"left\"",
-				  " align=\"right\"" };
+static char* alignments[] = { "", " style=\"text-align:center;\"",
+				  " style=\"text-align:left;\"",
+				  " style=\"text-align:right;\"" };
 
 typedef STRING(int) Istring;
 
@@ -1440,7 +1540,7 @@ splat(Line *p, char *block, Istring align, int force, MMIOT *f)
 	Qprintf(f, "<%s%s>",
 		   block,
 		   alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]);
-	___mkd_reparse(T(p->text)+first, idx-first, 0, f);
+	___mkd_reparse(T(p->text)+first, idx-first, 0, f, "|");
 	Qprintf(f, "</%s>\n", block);
 	idx++;
 	colno++;
@@ -1546,13 +1646,14 @@ printblock(Paragraph *pp, MMIOT *f)
 			 && T(t->text)[S(t->text)-2] == ' '
 			 && T(t->text)[S(t->text)-1] == ' ' ) {
 		push(T(t->text), S(t->text)-2, f);
-		push("\003\n", 2, f);
+		pushc(MKD_EOLN, f);
+		pushc('\n', f);
 	    }
 	    else {
 		___mkd_tidy(&t->text);
 		push(T(t->text), S(t->text), f);
 		if ( t->next )
-		    push("\n", 1, f);
+		    pushc('\n', f);
 	    }
 	}
 	t = t->next;
@@ -1565,11 +1666,17 @@ printblock(Paragraph *pp, MMIOT *f)
 
 
 static void
-printcode(Line *t, MMIOT *f)
+printcode(Line *t, char *lang, MMIOT *f)
 {
     int blanks;
 
-    Qstring("<pre><code>", f);
+    Qstring("<pre><code", f);
+    if (lang) {
+      Qstring(" class=\"", f);
+      Qstring(lang, f);
+      Qstring("\"", f);
+    }
+    Qstring(">", f);
     for ( blanks = 0; t ; t = t->next ) {
 	if ( S(t->text) > t->dle ) {
 	    while ( blanks ) {
@@ -1633,7 +1740,7 @@ definitionlist(Paragraph *p, MMIOT *f)
 	for ( ; p ; p = p->next) {
 	    for ( tag = p->text; tag; tag = tag->next ) {
 		Qstring("<dt>", f);
-		___mkd_reparse(T(tag->text), S(tag->text), 0, f);
+		___mkd_reparse(T(tag->text), S(tag->text), 0, f, 0);
 		Qstring("</dt>\n", f);
 	    }
 
@@ -1682,7 +1789,7 @@ display(Paragraph *p, MMIOT *f)
 	break;
 
     case CODE:
-	printcode(p->text, f);
+	printcode(p->text, p->lang, f);
 	break;
 
     case QUOTE:
@@ -1731,14 +1838,14 @@ mkd_extra_footnotes(MMIOT *m)
     int j, i;
     Footnote *t;
 
-    if ( m->reference == 0 )
+    if ( m->footnotes->reference == 0 )
 	return;
 
     Csprintf(&m->out, "\n<div class=\"footnotes\">\n<hr/>\n<ol>\n");
-
-    for ( i=1; i <= m->reference; i++ ) {
-	for ( j=0; j < S(*m->footnotes); j++ ) {
-	    t = &T(*m->footnotes)[j];
+    
+    for ( i=1; i <= m->footnotes->reference; i++ ) {
+	for ( j=0; j < S(m->footnotes->note); j++ ) {
+	    t = &T(m->footnotes->note)[j];
 	    if ( (t->refnumber == i) && (t->flags & REFERENCED) ) {
 		Csprintf(&m->out, "<li id=\"%s:%d\">\n<p>",
 			    p_or_nothing(m), t->refnumber);
@@ -1767,15 +1874,20 @@ mkd_document(Document *p, char **res)
 	    if ( p->ctx->flags & MKD_EXTRA_FOOTNOTE )
 		mkd_extra_footnotes(p->ctx);
 	    p->html = 1;
+	    size = S(p->ctx->out);
+	
+	    if ( (size == 0) || T(p->ctx->out)[size-1] ) {
+		/* Add a null byte at the end of the generated html,
+		 * but pretend it doesn't exist.
+		 */
+		EXPAND(p->ctx->out) = 0;
+		--S(p->ctx->out);
+	    }
 	}
-
-	size = S(p->ctx->out);
-
-	if ( (size == 0) || T(p->ctx->out)[size-1] )
-	    EXPAND(p->ctx->out) = 0;
-
+	
 	*res = T(p->ctx->out);
-	return size;
+	return S(p->ctx->out);
     }
     return EOF;
 }
+

+ 100 - 0
discount/github_flavoured.c

@@ -0,0 +1,100 @@
+
+/*
+ * github_flavoured -- implement the obnoxious "returns are hard newlines"
+ *                     feature in github flavoured markdown.
+ *
+ * Copyright (C) 2012 David L Parsons.
+ * The redistribution terms are provided in the COPYRIGHT file that must
+ * be distributed with this source code.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "cstring.h"
+#include "markdown.h"
+#include "amalloc.h"
+
+/* build a Document from any old input.
+ */
+typedef int (*getc_func)(void*);
+
+Document *
+gfm_populate(getc_func getc, void* ctx, int flags)
+{
+    Cstring line;
+    Document *a = __mkd_new_Document();
+    int c;
+    int pandoc = 0;
+
+    if ( !a ) return 0;
+
+    a->tabstop = (flags & MKD_TABSTOP) ? 4 : TABSTOP;
+
+    CREATE(line);
+
+    while ( (c = (*getc)(ctx)) != EOF ) {
+	if ( c == '\n' ) {
+	    if ( pandoc != EOF && pandoc < 3 ) {
+		if ( S(line) && (T(line)[0] == '%') )
+		    pandoc++;
+		else
+		    pandoc = EOF;
+	    }
+            
+            if (pandoc == EOF) {
+		EXPAND(line) = ' ';
+		EXPAND(line) = ' ';
+	    }
+	    __mkd_enqueue(a, &line);
+	    S(line) = 0;
+	}
+	else if ( isprint(c) || isspace(c) || (c & 0x80) )
+	    EXPAND(line) = c;
+    }
+
+    if ( S(line) )
+	__mkd_enqueue(a, &line);
+
+    DELETE(line);
+
+    if ( (pandoc == 3) && !(flags & (MKD_NOHEADER|MKD_STRICT)) ) {
+	/* the first three lines started with %, so we have a header.
+	 * clip the first three lines out of content and hang them
+	 * off header.
+	 */
+	Line *headers = T(a->content);
+
+	a->title = headers;             __mkd_header_dle(a->title);
+	a->author= headers->next;       __mkd_header_dle(a->author);
+	a->date  = headers->next->next; __mkd_header_dle(a->date);
+
+	T(a->content) = headers->next->next->next;
+    }
+
+    return a;
+}
+
+
+/* convert a block of text into a linked list
+ */
+Document *
+gfm_string(const char *buf, int len, DWORD flags)
+{
+    struct string_stream about;
+
+    about.data = buf;
+    about.size = len;
+
+    return gfm_populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK);
+}
+
+
+/* convert a file into a linked list
+ */
+Document *
+gfm_in(FILE *f, DWORD flags)
+{
+    return gfm_populate((getc_func)fgetc, f, flags & INPUT_MASK);
+}

+ 3 - 0
discount/libdiscount.cbp

@@ -89,6 +89,9 @@
 		<Unit filename="generate.c">
 			<Option compilerVar="CC" />
 		</Unit>
+		<Unit filename="github_flavoured.c">
+			<Option compilerVar="CC" />
+		</Unit>
 		<Unit filename="html5.c">
 			<Option compilerVar="CC" />
 		</Unit>

+ 4 - 4
discount/librarian.sh

@@ -7,13 +7,13 @@ LIBRARY=$1; shift
 VERSION=$1; shift
 
 case "$ACTION" in
-make)   /mingw/bin/ar crv $LIBRARY.a "$@"
-	/mingw/bin/ranlib $LIBRARY.a
+make)   /usr/bin/ar crv $LIBRARY.a "$@"
+	/usr/bin/ranlib $LIBRARY.a
 	rm -f $LIBRARY
-	/bin/ln $LIBRARY.a $LIBRARY
+	/bin/ln -s $LIBRARY.a $LIBRARY
 	;;
 files)  echo "${LIBRARY}.a"
 	;;
-install)/bin/install -m 644 ${LIBRARY}.a $1
+install)/usr/bin/install -m 644 ${LIBRARY}.a $1
 	;;
 esac

+ 25 - 7
discount/main.c

@@ -18,6 +18,7 @@
 #include "config.h"
 #include "amalloc.h"
 #include "pgm_options.h"
+#include "tags.h"
 
 #if HAVE_LIBGEN_H
 #include <libgen.h>
@@ -75,9 +76,12 @@ main(int argc, char **argv)
     mkd_flag_t flags = 0;
     int debug = 0;
     int toc = 0;
+    int content = 1;
     int version = 0;
     int with_html5 = 0;
+    int styles = 0;
     int use_mkd_line = 0;
+    int github_flavoured = 0;
     char *extra_footnote_prefix = 0;
     char *urlflags = 0;
     char *text = 0;
@@ -92,7 +96,7 @@ main(int argc, char **argv)
     pgm = basename(argv[0]);
     opterr = 1;
 
-    while ( (opt=getopt(argc, argv, "5b:C:df:E:F:o:s:t:TV")) != EOF ) {
+    while ( (opt=getopt(argc, argv, "5b:C:df:E:F:Gno:s:St:TV")) != EOF ) {
 	switch (opt) {
 	case '5':   with_html5 = 1;
 		    break;
@@ -118,13 +122,19 @@ main(int argc, char **argv)
 		    else if ( !set_flag(&flags, optarg) )
 			complain("unknown option <%s>", optarg);
 		    break;
+	case 'G':   github_flavoured = 1;
+		    break;
+	case 'n':   content = 0;
+		    break;
+	case 's':   text = optarg;
+		    break;
+	case 'S':   styles = 1;
+		    break;
 	case 't':   text = optarg;
 		    use_mkd_line = 1;
 		    break;
 	case 'T':   toc = 1;
 		    break;
-	case 's':   text = optarg;
-		    break;
 	case 'C':   extra_footnote_prefix = optarg;
 		    break;
 	case 'o':   if ( ofile ) {
@@ -165,7 +175,10 @@ main(int argc, char **argv)
 	rc = mkd_generateline( text, strlen(text), stdout, flags);
     else {
 	if ( text ) {
-	    if ( (doc = mkd_string(text, strlen(text), flags)) == 0 ) {
+	    doc = github_flavoured ? gfm_string(text, strlen(text), flags)
+				   : mkd_string(text, strlen(text), flags) ;
+
+	    if ( !doc ) {
 		perror(text);
 		exit(1);
 	    }
@@ -175,7 +188,9 @@ main(int argc, char **argv)
 		perror(argv[0]);
 		exit(1);
 	    }
-	    if ( (doc = mkd_in(stdin,flags)) == 0 ) {
+
+	    doc = github_flavoured ? gfm_in(stdin,flags) : mkd_in(stdin,flags);
+	    if ( !doc ) {
 		perror(argc ? argv[0] : "stdin");
 		exit(1);
 	    }
@@ -195,12 +210,15 @@ main(int argc, char **argv)
 	    rc = 1;
 	    if ( mkd_compile(doc, flags) ) {
 		rc = 0;
+		if ( styles )
+		    mkd_generatecss(doc, stdout);
 		if ( toc )
 		    mkd_generatetoc(doc, stdout);
-		mkd_generatehtml(doc, stdout);
-		mkd_cleanup(doc);
+		if ( content )
+		    mkd_generatehtml(doc, stdout);
 	    }
 	}
+	mkd_cleanup(doc);
     }
     mkd_deallocate_tags();
     adump();

+ 1 - 1
discount/makepage.1

@@ -42,4 +42,4 @@ utility exits 0 on success, and >0 if an error occurs.
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .An David Parsons
-.Pq Li orc@pell.chi.il.us
+.Pq Li orc@pell.portland.or.us

+ 6 - 1
discount/makepage.c

@@ -30,6 +30,7 @@ char **argv;
     char *q;
     int version = 0;
     int opt;
+    int ret;
     mkd_flag_t flags = 0;
 
     if ( (q = getenv("MARKDOWN_FLAGS")) )
@@ -82,5 +83,9 @@ char **argv;
 	exit(1);
     }
 
-    exit(mkd_xhtmlpage(doc, flags, stdout));
+    ret = mkd_xhtmlpage(doc, flags, stdout);
+
+    mkd_cleanup(doc);
+
+    return (ret == EOF);
 }

+ 29 - 5
discount/markdown.1

@@ -15,7 +15,9 @@
 .Op Fl C Ar prefix
 .Op Fl F Pa bitmap
 .Op Fl f Ar flags
+.Op Fl n
 .Op Fl o Pa file
+.Op Fl S
 .Op Fl s Pa text
 .Op Fl t Pa text
 .Op Pa textfile
@@ -104,9 +106,27 @@ blocks.
 .It Ar alphalist
 Allow alphabetic lists.
 .It Ar definitionlist
-Allow definition lists.
+Allow definition lists at all (default). Use
+.Em dldiscount
+and
+.Em dlextra
+to control which syntaxes are respected.
+.It Ar dldiscount
+Enable discount-style definition lists (default).
+.It Ar dlextra
+Enable extra-style definition lists (not default). Both styles may be enabled simultaneously.
 .It Ar footnote
 Allow markdown extra-style footnotes.
+.It Ar style
+Extract <style> blocks from the output.
+.It Ar fencedcode
+Allow fenced code blocks (not default).
+.It Ar idanchor
+Use id= anchors for table-of-contents links instead of <a name=/> (not default).
+.It Ar githubtags
+Allow underscore and dash in passed through element names (not default).
+.It Ar urlencodedanchor
+Use url-encoded chars for multibyte and nonalphanumeric chars rather than dots in toc links.
 .El
 .Pp
 As an example, the option
@@ -123,6 +143,13 @@ described in
 .Xr markdown 3 
 (the flag values are defined in
 .Pa mkdio.h )
+.It Fl n
+Don't write generated html.
+.It Fl o Pa file
+Write the generated html to 
+.Pa file .
+.It Fl S
+output <style> blocks.
 .It Fl V
 Show the version# and compile-time configuration data.
 .Pp
@@ -138,9 +165,6 @@ was configured to use the specified tabstop.
 .It Fl VV
 Show the version#, the compile-time configuration, and the
 run-time configuration.
-.It Fl o Pa file
-Write the generated html to 
-.Pa file .
 .It Fl t Ar text
 Use
 .Xr mkd_text 3
@@ -168,4 +192,4 @@ utility exits 0 on success, and >0 if an error occurs.
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .An David Parsons
-.Pq Li orc@pell.chi.il.us
+.Pq Li orc@pell.portland.or.us

+ 14 - 0
discount/markdown.3

@@ -104,8 +104,22 @@ blocks.
 Forbid alphabetic lists.
 .It Ar MKD_NODLIST
 Forbid definition lists.
+.It Ar MKD_NODLDISCOUNT
+Disable the discount definition list syntax style.
+.It Ar MKD_DLEXTRA
+Enable the extra definition list syntax style.
 .It Ar MKD_EXTRA_FOOTNOTE
 Enable markdown extra-style footnotes.
+.It Ar MKD_NOSTYLE
+Do not extract (omit) <style/> blocks from the output.
+.It Ar MKD_FENCEDCODE
+Allow fenced code blocks.
+.It Ar MKD_IDANCHOR
+Use id= anchors instead of <a name=/> for table-of-contents links.
+.It Ar MKD_GITHUBTAGS
+Allow underscore and dash in passed through element names.
+.It Ar MKD_URLENCODEDANCHOR
+Use url-encoded chars for multibyte and nonalphanumeric chars rather than dots in toc links.
 .El
 .Sh RETURN VALUES
 .Fn markdown

+ 137 - 78
discount/markdown.c

@@ -178,17 +178,22 @@ splitline(Line *t, int cutpoint)
 
 #define UNCHECK(l) ((l)->flags &= ~CHECKED)
 
+#define UNLESS_FENCED(t) if (fenced) { \
+    other = 1; l->count += (c == ' ' ? 0 : -1); \
+  } else { t; }
+
 /*
  * walk a line, seeing if it's any of half a dozen interesting regular
  * types.
  */
 static void
-checkline(Line *l)
+checkline(Line *l, DWORD flags)
 {
     int eol, i;
     int dashes = 0, spaces = 0,
 	equals = 0, underscores = 0,
-	stars = 0, tildes = 0;
+	stars = 0, tildes = 0, other = 0,
+	backticks = 0, fenced = 0;
 
     l->flags |= CHECKED;
     l->kind = chk_text;
@@ -201,21 +206,34 @@ checkline(Line *l)
 
     for (i=l->dle; i<eol; i++) {
 	register int c = T(l->text)[i];
+	int is_fence_char = 0;
 
 	if ( c != ' ' ) l->count++;
 
 	switch (c) {
-	case '-':  dashes = 1; break;
-	case ' ':  spaces = 1; break;
+	case '-':  UNLESS_FENCED(dashes = 1); break;
+	case ' ':  UNLESS_FENCED(spaces = 1); break;
 	case '=':  equals = 1; break;
-	case '_':  underscores = 1; break;
+	case '_':  UNLESS_FENCED(underscores = 1); break;
 	case '*':  stars = 1; break;
-	case '~':  tildes = 1; break;
-	default:   return;
+	default:
+	    if (flags & MKD_FENCEDCODE) {
+		switch (c) {
+		case '~':  if (other) return; is_fence_char = 1; tildes = 1; break;
+		case '`':  if (other) return; is_fence_char = 1; backticks = 1; break;
+		}
+		if (is_fence_char) {
+		    fenced = 1;
+		    break;
+		}
+	    }
+	    other = 1;
+	    l->count--;
+	    if (!fenced) return;
 	}
     }
 
-    if ( dashes + equals + underscores + stars + tildes > 1 )
+    if ( dashes + equals + underscores + stars + tildes + backticks > 1 )
 	return;
 
     if ( spaces ) {
@@ -226,26 +244,33 @@ checkline(Line *l)
 
     if ( stars || underscores ) { l->kind = chk_hr; }
     else if ( dashes ) { l->kind = chk_dash; }
-    else if ( tildes ) { l->kind = chk_tilde; }
     else if ( equals ) { l->kind = chk_equal; }
+    else if ( tildes ) { l->kind = chk_tilde; }
+    else if ( backticks ) { l->kind = chk_backtick; }
 }
 
 
 
+/* markdown only does special handling of comments if the comment end
+ * is at the end of a line
+ */
 static Line *
 commentblock(Paragraph *p, int *unclosed)
 {
     Line *t, *ret;
     char *end;
 
-    for ( t = p->text; t ; t = t->next) {
-	if ( end = strstr(T(t->text), "-->") ) {
-	    splitline(t, 3 + (end - T(t->text)) );
-	    ret = t->next;
-	    t->next = 0;
-	    return ret;
-	}
+       for ( t = p->text; t ; t = t->next) {
+	   if ( end = strstr(T(t->text), "-->") ) {
+	       if ( nextnonblank(t, 3 + (end - T(t->text))) < S(t->text) )
+		   continue;
+	       /*splitline(t, 3 + (end - T(t->text)) );*/
+	       ret = t->next;
+	       t->next = 0;
+	       return ret;
+	   }
     }
+
     *unclosed = 1;
     return t;
 
@@ -289,8 +314,8 @@ htmlblock(Paragraph *p, struct kw *tag, int *unclosed)
 	    else {
 		if ( closing = (c == '/') ) c = flogetc(&f);
 
-		for ( i=0; i < tag->size; c=flogetc(&f) ) {
-		    if ( tag->id[i++] != toupper(c) )
+		for ( i=0; i < tag->size; i++, c=flogetc(&f) ) {
+		    if ( tag->id[i] != toupper(c) )
 			break;
 		}
 
@@ -354,10 +379,10 @@ iscode(Line *t)
 
 
 static inline int
-ishr(Line *t)
+ishr(Line *t, DWORD flags)
 {
     if ( ! (t->flags & CHECKED) )
-	checkline(t);
+	checkline(t, flags);
 
     if ( t->count > 2 )
 	return t->kind == chk_hr || t->kind == chk_dash || t->kind == chk_equal;
@@ -366,7 +391,7 @@ ishr(Line *t)
 
 
 static int
-issetext(Line *t, int *htyp)
+issetext(Line *t, int *htyp, DWORD flags)
 {
     Line *n;
 
@@ -376,7 +401,7 @@ issetext(Line *t, int *htyp)
 
     if ( (n = t->next) ) {
 	if ( !(n->flags & CHECKED) )
-	    checkline(n);
+	    checkline(n, flags);
 
 	if ( n->kind == chk_dash || n->kind == chk_equal ) {
 	    *htyp = SETEXT;
@@ -388,7 +413,7 @@ issetext(Line *t, int *htyp)
 
 
 static int
-ishdr(Line *t, int *htyp)
+ishdr(Line *t, int *htyp, DWORD flags)
 {
     /* ANY leading `#`'s make this into an ETX header
      */
@@ -399,27 +424,28 @@ ishdr(Line *t, int *htyp)
 
     /* And if not, maybe it's a SETEXT header instead
      */
-    return issetext(t, htyp);
+    return issetext(t, htyp, flags);
 }
 
 
 static inline int
-end_of_block(Line *t)
+end_of_block(Line *t, DWORD flags)
 {
     int dummy;
 
     if ( !t )
 	return 0;
-
-    return ( (S(t->text) <= t->dle) || ishr(t) || ishdr(t, &dummy) );
+	
+    return ( (S(t->text) <= t->dle) || ishr(t, flags) || ishdr(t, &dummy, flags) );
 }
 
 
 static Line*
-is_discount_dt(Line *t, int *clip)
+is_discount_dt(Line *t, int *clip, DWORD flags)
 {
-#if USE_DISCOUNT_DL
-    if ( t && t->next
+    if ( !(flags & MKD_NODLDISCOUNT)
+	   && t
+	   && t->next
 	   && (S(t->text) > 2)
 	   && (t->dle == 0)
 	   && (T(t->text)[0] == '=')
@@ -429,9 +455,8 @@ is_discount_dt(Line *t, int *clip)
 	    return t;
 	}
 	else
-	    return is_discount_dt(t->next, clip);
+	    return is_discount_dt(t->next, clip, flags);
     }
-#endif
     return 0;
 }
 
@@ -445,41 +470,40 @@ is_extra_dd(Line *t)
 
 
 static Line*
-is_extra_dt(Line *t, int *clip)
+is_extra_dt(Line *t, int *clip, DWORD flags)
 {
-#if USE_EXTRA_DL
-
-    if ( t && t->next && T(t->text)[0] != '='
+    if ( flags & MKD_DLEXTRA
+	   && t
+	   && t->next && S(t->text) && T(t->text)[0] != '='
 		      && T(t->text)[S(t->text)-1] != '=') {
 	Line *x;
-
-	if ( iscode(t) || end_of_block(t) )
+    
+	if ( iscode(t) || end_of_block(t, flags) )
 	    return 0;
 
 	if ( (x = skipempty(t->next)) && is_extra_dd(x) ) {
 	    *clip = x->dle+2;
 	    return t;
 	}
-
-	if ( x=is_extra_dt(t->next, clip) )
+	
+	if ( x=is_extra_dt(t->next, clip, flags) )
 	    return x;
     }
-#endif
     return 0;
 }
 
 
 static Line*
-isdefinition(Line *t, int *clip, int *kind)
+isdefinition(Line *t, int *clip, int *kind, DWORD flags)
 {
     Line *ret;
 
     *kind = 1;
-    if ( ret = is_discount_dt(t,clip) )
+    if ( ret = is_discount_dt(t,clip,flags) )
 	return ret;
 
     *kind=2;
-    return is_extra_dt(t,clip);
+    return is_extra_dt(t,clip,flags);
 }
 
 
@@ -488,11 +512,11 @@ islist(Line *t, int *clip, DWORD flags, int *list_type)
 {
     int i, j;
     char *q;
-
-    if ( end_of_block(t) )
+    
+    if ( end_of_block(t, flags) )
 	return 0;
 
-    if ( !(flags & (MKD_NODLIST|MKD_STRICT)) && isdefinition(t,clip,list_type) )
+    if ( !(flags & (MKD_NODLIST|MKD_STRICT)) && isdefinition(t,clip,list_type,flags) )
 	return DL;
 
     if ( strchr("*-+", T(t->text)[t->dle]) && isspace(T(t->text)[t->dle+1]) ) {
@@ -517,7 +541,7 @@ islist(Line *t, int *clip, DWORD flags, int *list_type)
 	    strtoul(T(t->text)+t->dle, &q, 10);
 	    if ( (q > T(t->text)+t->dle) && (q == T(t->text) + (j-1)) ) {
 		j = nextnonblank(t,j);
-		*clip = (j > 4) ? 4 : j;
+		*clip = j;
 		*list_type = OL;
 		return AL;
 	    }
@@ -597,18 +621,23 @@ codeblock(Paragraph *p)
 }
 
 
-#ifdef WITH_FENCED_CODE
 static int
-iscodefence(Line *r, int size)
+iscodefence(Line *r, int size, line_type kind, DWORD flags)
 {
+    if ( !(flags & MKD_FENCEDCODE) )
+	return 0;
+
     if ( !(r->flags & CHECKED) )
-	checkline(r);
+	checkline(r, flags);
 
-    return (r->kind == chk_tilde) && (r->count >= size);
+    if ( kind )
+	return (r->kind == kind) && (r->count >= size);
+    else
+	return (r->kind == chk_tilde || r->kind == chk_backtick) && (r->count >= size);
 }
 
 static Paragraph *
-fencedcodeblock(ParagraphRoot *d, Line **ptr)
+fencedcodeblock(ParagraphRoot *d, Line **ptr, DWORD flags)
 {
     Line *first, *r;
     Paragraph *ret;
@@ -617,16 +646,24 @@ fencedcodeblock(ParagraphRoot *d, Line **ptr)
 
     /* don't allow zero-length code fences
      */
-    if ( (first->next == 0) || iscodefence(first->next, first->count) )
+    if ( (first->next == 0) || iscodefence(first->next, first->count, 0, flags) )
 	return 0;
 
     /* find the closing fence, discard the fences,
      * return a Paragraph with the contents
      */
     for ( r = first; r && r->next; r = r->next )
-	if ( iscodefence(r->next, first->count) ) {
+	if ( iscodefence(r->next, first->count, first->kind, flags) ) {
 	    (*ptr) = r->next->next;
 	    ret = Pp(d, first->next, CODE);
+      if (S(first->text) - first->count > 0) {
+        char *lang_attr = T(first->text) + first->count;
+        while ( *lang_attr != 0 && *lang_attr == ' ' ) lang_attr++;
+        ret->lang = strdup(lang_attr);
+      }
+      else {
+        ret->lang = 0;
+      }
 	    ___mkd_freeLine(first);
 	    ___mkd_freeLine(r->next);
 	    r->next = 0;
@@ -634,7 +671,6 @@ fencedcodeblock(ParagraphRoot *d, Line **ptr)
 	}
     return 0;
 }
-#endif
 
 
 static int
@@ -660,7 +696,7 @@ endoftextblock(Line *t, int toplevelblock, DWORD flags)
 {
     int z;
 
-    if ( end_of_block(t) || isquote(t) )
+    if ( end_of_block(t, flags) || isquote(t) )
 	return 1;
 
     /* HORRIBLE STANDARDS KLUDGES:
@@ -719,6 +755,7 @@ isdivmarker(Line *p, int start, DWORD flags)
     if ( flags & (MKD_NODIVQUOTE|MKD_STRICT) )
 	return 0;
 
+    start = nextnonblank(p, start);
     last= S(p->text) - (1 + start);
     s   = T(p->text) + start;
 
@@ -821,6 +858,12 @@ listitem(Paragraph *p, int indent, DWORD flags, linefn check)
 	UNCHECK(t);
 	t->dle = mkd_firstnonblank(t);
 
+        /* even though we had to trim a long leader off this item,
+         * the indent for trailing paragraphs is still 4...
+	 */
+	if (indent > 4) {
+	    indent = 4;
+	}
 	if ( (q = skipempty(t->next)) == 0 ) {
 	    ___mkd_freeLineRange(t,q);
 	    return 0;
@@ -842,9 +885,9 @@ listitem(Paragraph *p, int indent, DWORD flags, linefn check)
 	    indent = clip ? clip : 2;
 	}
 
-	if ( (q->dle < indent) && (ishr(q) || islist(q,&z,flags,&z)
+	if ( (q->dle < indent) && (ishr(q,flags) || islist(q,&z,flags,&z)
 					   || (check && (*check)(q)))
-			       && !issetext(q,&z) ) {
+			       && !issetext(q,&z,flags) ) {
 	    q = t->next;
 	    t->next = 0;
 	    return q;
@@ -866,13 +909,13 @@ definition_block(Paragraph *top, int clip, MMIOT *f, int kind)
 
     while (( labels = q )) {
 
-	if ( (q = isdefinition(labels, &z, &kind)) == 0 )
+	if ( (q = isdefinition(labels, &z, &kind, f->flags)) == 0 )
 	    break;
 
 	if ( (text = skipempty(q->next)) == 0 )
 	    break;
 
-	if (( para = (text != q->next) ))
+	if ( para = (text != q->next) )
 	    ___mkd_freeLineRange(q, text);
 
 	q->next = 0;
@@ -895,7 +938,7 @@ definition_block(Paragraph *top, int clip, MMIOT *f, int kind)
 	if ( (q = skipempty(text)) == 0 )
 	    break;
 
-	if (( para = (q != text) )) {
+	if ( para = (q != text) ) {
 	    Line anchor;
 
 	    anchor.next = text;
@@ -972,8 +1015,8 @@ addfootnote(Line *p, MMIOT* f)
     int c;
     Line *np = p->next;
 
-    Footnote *foot = &EXPAND(*f->footnotes);
-
+    Footnote *foot = &EXPAND(f->footnotes->note);
+    
     CREATE(foot->tag);
     CREATE(foot->link);
     CREATE(foot->title);
@@ -987,6 +1030,7 @@ addfootnote(Line *p, MMIOT* f)
     j = nextnonblank(p, j+2);
 
     if ( (f->flags & MKD_EXTRA_FOOTNOTE) && (T(foot->tag)[0] == '^') ) {
+	/* need to consume all lines until non-indented block? */
 	while ( j < S(p->text) )
 	    EXPAND(foot->title) = T(p->text)[j++];
 	goto skip_to_end;
@@ -1085,6 +1129,7 @@ compile_document(Line *ptr, MMIOT *f)
 
     while ( ptr ) {
 	if ( !(f->flags & MKD_NOHTML) && (tag = isopentag(ptr)) ) {
+	    int blocktype;
 	    /* If we encounter a html/style block, compile and save all
 	     * of the cached source BEFORE processing the html/style.
 	     */
@@ -1094,7 +1139,12 @@ compile_document(Line *ptr, MMIOT *f)
 		p->down = compile(T(source), 1, f);
 		T(source) = E(source) = 0;
 	    }
-	    p = Pp(&d, ptr, strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML);
+	    
+	    if ( f->flags & MKD_NOSTYLE )
+		blocktype = HTML;
+	    else
+		blocktype = strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML;
+	    p = Pp(&d, ptr, blocktype);
 	    ptr = htmlblock(p, tag, &unclosed);
 	    if ( unclosed ) {
 		p->typ = SOURCE;
@@ -1172,7 +1222,7 @@ actually_a_table(MMIOT *f, Line *pp)
     for ( j=r->dle; j < S(r->text); ++j ) {
 	c = T(r->text)[j];
 
-	if ( !(isspace(c)||(c=='-')||(c=='=')||(c==':')||(c=='|')) ) {
+	if ( !(isspace(c)||(c=='-')||(c==':')||(c=='|')) ) {
 	    return 0;
 	}
     }
@@ -1211,17 +1261,15 @@ compile(Line *ptr, int toplevel, MMIOT *f)
 
 	    ptr = codeblock(p);
 	}
-#if WITH_FENCED_CODE
-	else if ( iscodefence(ptr,3) && (p=fencedcodeblock(&d, &ptr)) )
+	else if ( iscodefence(ptr,3,0,f->flags) && (p=fencedcodeblock(&d, &ptr, f->flags)) )
 	    /* yay, it's already done */ ;
-#endif
-	else if ( ishr(ptr) ) {
+	else if ( ishr(ptr, f->flags) ) {
 	    p = Pp(&d, 0, HR);
 	    r = ptr;
 	    ptr = ptr->next;
 	    ___mkd_freeLine(r);
 	}
-	else if (( list_class = islist(ptr, &indent, f->flags, &list_type) )) {
+	else if ( list_class = islist(ptr, &indent, f->flags, &list_type) ) {
 	    if ( list_class == DL ) {
 		p = Pp(&d, ptr, DL);
 		ptr = definition_block(p, indent, f, list_type);
@@ -1237,7 +1285,7 @@ compile(Line *ptr, int toplevel, MMIOT *f)
 	    p->down = compile(p->text, 1, f);
 	    p->text = 0;
 	}
-	else if ( ishdr(ptr, &hdr_type) ) {
+	else if ( ishdr(ptr, &hdr_type, f->flags) ) {
 	    p = Pp(&d, ptr, HDR);
 	    ptr = headerblock(p, hdr_type);
 	}
@@ -1278,23 +1326,34 @@ mkd_compile(Document *doc, DWORD flags)
     if ( !doc )
 	return 0;
 
-    if ( doc->compiled )
-	return 1;
+    flags &= USER_FLAGS;
+    
+    if ( doc->compiled ) {
+	if ( doc->ctx->flags == flags )
+	    return 1;
+	else {
+	    if ( doc->code)
+		___mkd_freeParagraph(doc->code);
+	    if ( doc->ctx->footnotes )
+		___mkd_freefootnotes(doc->ctx);
+	}
+    }
 
     doc->compiled = 1;
     memset(doc->ctx, 0, sizeof(MMIOT) );
     doc->ctx->ref_prefix= doc->ref_prefix;
     doc->ctx->cb        = &(doc->cb);
-    doc->ctx->flags     = flags & USER_FLAGS;
+    doc->ctx->flags     = flags;
     CREATE(doc->ctx->in);
     doc->ctx->footnotes = malloc(sizeof doc->ctx->footnotes[0]);
-    CREATE(*doc->ctx->footnotes);
+    doc->ctx->footnotes->reference = 0;
+    CREATE(doc->ctx->footnotes->note);
 
     mkd_initialize();
 
     doc->code = compile_document(T(doc->content), doc->ctx);
-    qsort(T(*doc->ctx->footnotes), S(*doc->ctx->footnotes),
-		        sizeof T(*doc->ctx->footnotes)[0],
+    qsort(T(doc->ctx->footnotes->note), S(doc->ctx->footnotes->note),
+		        sizeof T(doc->ctx->footnotes->note)[0],
 			           (stfu)__mkd_footsort);
     memset(&doc->content, 0, sizeof doc->content);
     return 1;

+ 59 - 11
discount/markdown.h

@@ -19,10 +19,14 @@ typedef struct footnote {
 } Footnote;
 
 /* each input line is read into a Line, which contains the line,
- * the offset of the first non-space character [this assumes 
+ * the offset of the first non-space character [this assumes
  * that all tabs will be expanded to spaces!], and a pointer to
  * the next line.
  */
+typedef enum { chk_text, chk_code,
+	       chk_hr, chk_dash,
+	       chk_tilde, chk_backtick,
+	       chk_equal } line_type;
 typedef struct line {
     Cstring text;
     struct line *next;
@@ -31,9 +35,7 @@ typedef struct line {
 #define PIPECHAR	0x01		/* line contains a | */
 #define CHECKED		0x02
 
-    enum { chk_text, chk_code,
-	   chk_hr, chk_dash,
-	   chk_tilde, chk_equal } kind;
+    line_type kind;
     int count;
 } Line;
 
@@ -47,6 +49,7 @@ typedef struct paragraph {
     struct paragraph *down;	/* recompiled contents of this paragraph */
     struct line *text;		/* all the text in this paragraph */
     char *ident;		/* %id% tag for QUOTE */
+    char *lang;         /* lang attribute for CODE */
     enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
 	   HTML, STYLE, DL, UL, OL, AL, LISTITEM,
 	   HDR, HR, TABLE, SOURCE } typ;
@@ -79,6 +82,18 @@ typedef struct callback_data {
 } Callback_data;
 
 
+struct escaped {
+    char *text;
+    struct escaped *up;
+} ;
+
+
+struct footnote_list {
+    int reference;
+    STRING(Footnote) note;
+} ;
+
+
 /* a magic markdown io thing holds all the data structures needed to
  * do the backend processing of a markdown document
  */
@@ -87,9 +102,9 @@ typedef struct mmiot {
     Cstring in;
     Qblock Q;
     int isp;
-    int reference;
+    struct escaped *esc;
     char *ref_prefix;
-    STRING(Footnote) *footnotes;
+    struct footnote_list *footnotes;
     DWORD flags;
 #define MKD_NOLINKS	0x00000001
 #define MKD_NOIMAGE	0x00000002
@@ -113,14 +128,24 @@ typedef struct mmiot {
 #define MKD_NOALPHALIST	0x00080000
 #define MKD_NODLIST	0x00100000
 #define MKD_EXTRA_FOOTNOTE 0x00200000
-#define IS_LABEL	0x08000000
-#define USER_FLAGS	0x0FFFFFFF
+#define MKD_NOSTYLE	0x00400000
+#define MKD_NODLDISCOUNT 0x00800000
+#define	MKD_DLEXTRA	0x01000000
+#define MKD_FENCEDCODE	0x02000000
+#define MKD_IDANCHOR	0x04000000
+#define MKD_GITHUBTAGS	0x08000000
+#define MKD_URLENCODEDANCHOR 0x10000000
+#define IS_LABEL	0x20000000
+#define USER_FLAGS	0x3FFFFFFF
 #define INPUT_MASK	(MKD_NOHEADER|MKD_TABSTOP)
 
     Callback_data *cb;
 } MMIOT;
 
 
+#define MKD_EOLN	3
+
+
 /*
  * the mkdio text input functions return a document structure,
  * which contains a header (retrieved from the document if
@@ -145,6 +170,16 @@ typedef struct document {
 } Document;
 
 
+/*
+ * economy FILE-type structure for pulling characters out of a
+ * fixed-length string.
+ */
+struct string_stream {
+    const char *data;	/* the unread data */
+    int   size;		/* and how much is there? */
+} ;
+
+
 extern int  mkd_firstnonblank(Line *);
 extern int  mkd_compile(Document *, DWORD);
 extern int  mkd_document(Document *, char **);
@@ -161,11 +196,14 @@ extern int  mkd_generateline(char *, int, FILE*, DWORD);
 extern void mkd_basename(Document*, char *);
 
 typedef int (*mkd_sta_function_t)(const int,const void*);
-extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int);
+extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int, DWORD);
 
 extern Document *mkd_in(FILE *, DWORD);
 extern Document *mkd_string(const char*,int, DWORD);
 
+extern Document *gfm_in(FILE *, DWORD);
+extern Document *gfm_string(const char*,int, DWORD);
+
 extern void mkd_initialize();
 extern void mkd_shlib_destructor();
 
@@ -182,12 +220,22 @@ extern void ___mkd_initmmiot(MMIOT *, void *);
 extern void ___mkd_freemmiot(MMIOT *, void *);
 extern void ___mkd_freeLineRange(Line *, Line *);
 extern void ___mkd_xml(char *, int, FILE *);
-extern void ___mkd_reparse(char *, int, int, MMIOT*);
+extern void ___mkd_reparse(char *, int, int, MMIOT*, char*);
 extern void ___mkd_emblock(MMIOT*);
 extern void ___mkd_tidy(Cstring *);
 
+extern Document *__mkd_new_Document();
+extern void __mkd_enqueue(Document*, Cstring *);
+extern void __mkd_header_dle(Line *);
+
+extern int  __mkd_io_strget(struct string_stream *);
+
+/* utility function to do some operation and exit the current function
+ * if it fails
+ */
+#define DO_OR_DIE(op) if ( (op) == EOF ) return EOF; else 1
+
 extern int mkd_generatehtml_str(Document *p,void *out,void (*mywrite)(char const *,int size,void*));
 extern int markdown_str(Document *document, void *out,void (*)(char const *,int size,void*), int flags);
 
-
 #endif/*_MARKDOWN_D*/

+ 2 - 3
discount/markdowncpp.cbp

@@ -23,11 +23,9 @@
 				<Compiler>
 					<Add option="-O2" />
 					<Add option="-DTEST_MARKDOWN_LIBRARY=1" />
-					<Add directory="../discount-2.1.2" />
 				</Compiler>
 				<Linker>
 					<Add option="-s" />
-					<Add directory="../discount-2.1.2" />
 				</Linker>
 			</Target>
 		</Build>
@@ -36,7 +34,8 @@
 			<Add option="-fexceptions" />
 		</Compiler>
 		<Linker>
-			<Add library="discount" />
+			<Add library="libdiscount.a" />
+			<Add directory="../discount" />
 		</Linker>
 		<Unit filename="markdowncxx.cpp" />
 		<Unit filename="markdowncxx.h" />

+ 0 - 8
discount/mkd-extensions.7

@@ -111,14 +111,6 @@ at the beginning of a subsequent line.
 .Pp
 Be warned that style blocks work like footnote links -- no matter
 where you define them they are valid for the entire document.
-.Ss relaxed emphasis
-The rules for emphasis are changed so that a single
-.Ar _
-will
-.Em not
-count as a emphasis character if it's in the middle of a word.
-This is primarily for documenting code, if you don't wish to
-have to backquote all code references.
 .Ss alpha lists
 Alphabetic lists (like regular numeric lists, but with alphabetic
 items) are supported.    So:

+ 1 - 1
discount/mkd2html.1

@@ -49,4 +49,4 @@ utility exits 0 on success, and >0 if an error occurs.
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .An David Parsons
-.Pq Li orc@pell.chi.il.us
+.Pq Li orc@pell.portland.or.us

+ 18 - 11
discount/mkd2html.c

@@ -45,7 +45,7 @@ basename(char *path)
 {
     char *p;
 
-    if (( p = strrchr(path, '/') ))
+    if ( p = strrchr(path, '/') )
 	return 1+p;
     return path;
 }
@@ -82,7 +82,7 @@ char **argv;
     CREATE(footers);
     pgm = basename(argv[0]);
 
-    while ( argc > 2 ) {
+    while ( argc > 1 ) {
 	if ( strcmp(argv[1], "-css") == 0 ) {
 	    EXPAND(css) = argv[2];
 	    argc -= 2;
@@ -98,14 +98,20 @@ char **argv;
 	    argc -= 2;
 	    argv += 2;
 	}
+	else
+	    break;
     }
 
-
-    if ( argc > 1 ) {
+    switch ( argc ) {
 	char *p, *dot;
-	
+    case 1:
+	input = stdin;
+	output = stdout;
+	break;
+    case 2:
+    case 3:
+	dest   = malloc(strlen(argv[argc-1]) + 6);
 	source = malloc(strlen(argv[1]) + 6);
-	dest   = malloc(strlen(argv[1]) + 6);
 
 	if ( !(source && dest) )
 	    fail("out of memory allocating name buffers");
@@ -129,10 +135,11 @@ char **argv;
 
 	if ( (output = fopen(dest, "w")) == 0 )
 	    fail("can't write to %s", dest);
-    }
-    else {
-	input = stdin;
-	output = stdout;
+	break;
+
+    default:
+	fprintf(stderr, "usage: %s [opts] source [dest]\n", pgm);
+	exit(1);
     }
 
     if ( (mmiot = mkd_in(input, 0)) == 0 )
@@ -153,7 +160,7 @@ char **argv;
 	"  <meta name=\"GENERATOR\" content=\"mkd2html %s\">\n", markdown_version);
 
     fprintf(output,"  <meta http-equiv=\"Content-Type\"\n"
-		   "        content=\"text/html; charset-us-ascii\">");
+		   "        content=\"text/html; charset=utf-8\">");
 
     for ( i=0; i < S(css); i++ )
 	fprintf(output, "  <link rel=\"stylesheet\"\n"

+ 41 - 38
discount/mkdio.c

@@ -16,15 +16,16 @@
 
 typedef ANCHOR(Line) LineAnchor;
 
+
 /* create a new blank Document
  */
-static Document*
-new_Document()
+Document*
+__mkd_new_Document()
 {
     Document *ret = calloc(sizeof(Document), 1);
 
     if ( ret ) {
-	if (( ret->ctx = calloc(sizeof(MMIOT), 1) )) {
+	if ( ret->ctx = calloc(sizeof(MMIOT), 1) ) {
 	    ret->magic = VALID_DOCUMENT;
 	    return ret;
 	}
@@ -37,8 +38,8 @@ new_Document()
 /* add a line to the markdown input chain, expanding tabs and
  * noting the presence of special characters as we go.
  */
-static void
-queue(Document* a, Cstring *line)
+void
+__mkd_enqueue(Document* a, Cstring *line)
 {
     Line *p = calloc(sizeof *p, 1);
     unsigned char c;
@@ -75,8 +76,8 @@ queue(Document* a, Cstring *line)
 
 /* trim leading blanks from a header line
  */
-static void
-header_dle(Line *p)
+void
+__mkd_header_dle(Line *p)
 {
     CLIP(p->text, 0, 1);
     p->dle = mkd_firstnonblank(p);
@@ -91,7 +92,7 @@ Document *
 populate(getc_func getc, void* ctx, int flags)
 {
     Cstring line;
-    Document *a = new_Document();
+    Document *a = __mkd_new_Document();
     int c;
     int pandoc = 0;
 
@@ -109,7 +110,7 @@ populate(getc_func getc, void* ctx, int flags)
 		else
 		    pandoc = EOF;
 	    }
-	    queue(a, &line);
+	    __mkd_enqueue(a, &line);
 	    S(line) = 0;
 	}
 	else if ( isprint(c) || isspace(c) || (c & 0x80) )
@@ -117,7 +118,7 @@ populate(getc_func getc, void* ctx, int flags)
     }
 
     if ( S(line) )
-	queue(a, &line);
+	__mkd_enqueue(a, &line);
 
     DELETE(line);
 
@@ -128,9 +129,9 @@ populate(getc_func getc, void* ctx, int flags)
 	 */
 	Line *headers = T(a->content);
 
-	a->title = headers;             header_dle(a->title);
-	a->author= headers->next;       header_dle(a->author);
-	a->date  = headers->next->next; header_dle(a->date);
+	a->title = headers;             __mkd_header_dle(a->title);
+	a->author= headers->next;       __mkd_header_dle(a->author);
+	a->date  = headers->next->next; __mkd_header_dle(a->date);
 
 	T(a->content) = headers->next->next->next;
     }
@@ -150,14 +151,8 @@ mkd_in(FILE *f, DWORD flags)
 
 /* return a single character out of a buffer
  */
-struct string_ctx {
-    const char *data;	/* the unread data */
-    int   size;		/* and how much is there? */
-} ;
-
-
-static int
-strget(struct string_ctx *in)
+int
+__mkd_io_strget(struct string_stream *in)
 {
     if ( !in->size ) return EOF;
 
@@ -172,12 +167,12 @@ strget(struct string_ctx *in)
 Document *
 mkd_string(const char *buf, int len, DWORD flags)
 {
-    struct string_ctx about;
+    struct string_stream about;
 
     about.data = buf;
     about.size = len;
 
-    return populate((getc_func)strget, &about, flags & INPUT_MASK);
+    return populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK);
 }
 
 
@@ -189,15 +184,13 @@ mkd_generatehtml(Document *p, FILE *output)
     char *doc;
     int szdoc;
 
-    if ( (szdoc = mkd_document(p, &doc)) != EOF ) {
-	if ( p->ctx->flags & MKD_CDATA )
-	    mkd_generatexml(doc, szdoc, output);
-	else
-	    fwrite(doc, szdoc, 1, output);
-	putc('\n', output);
-	return 0;
-    }
-    return -1;
+    DO_OR_DIE( szdoc = mkd_document(p,&doc) );
+    if ( p->ctx->flags & MKD_CDATA )
+	DO_OR_DIE( mkd_generatexml(doc, szdoc, output) );
+    else if ( fwrite(doc, szdoc, 1, output) != 1 )
+	return EOF;
+    DO_OR_DIE( putc('\n', output) );
+    return 0;
 }
 
 
@@ -219,8 +212,10 @@ markdown(Document *document, FILE *out, int flags)
  */
 void
 mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
-				       void *out, int labelformat)
+				       void *out, int labelformat,
+				       DWORD flags)
 {
+    static const unsigned char hexchars[] = "0123456789abcdef";
     unsigned char c;
 
     int i, size;
@@ -228,13 +223,20 @@ mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
 
     size = mkd_line(s, len, &line, IS_LABEL);
 
-    if ( labelformat && (size>0) && !isalpha(line[0]) )
+    if ( !(flags & MKD_URLENCODEDANCHOR)
+	 && labelformat
+	 && (size>0) && !isalpha(line[0]) )
 	(*outchar)('L',out);
     for ( i=0; i < size ; i++ ) {
 	c = line[i];
 	if ( labelformat ) {
 	    if ( isalnum(c) || (c == '_') || (c == ':') || (c == '-') || (c == '.' ) )
 		(*outchar)(c, out);
+	    else if ( flags & MKD_URLENCODEDANCHOR ) {
+		(*outchar)('%', out);
+		(*outchar)(hexchars[c >> 4 & 0xf], out);
+		(*outchar)(hexchars[c      & 0xf], out);
+	    }
 	    else
 		(*outchar)('.', out);
 	}
@@ -254,7 +256,7 @@ mkd_parse_line(char *bfr, int size, MMIOT *f, int flags)
 {
     ___mkd_initmmiot(f, 0);
     f->flags = flags & USER_FLAGS;
-    ___mkd_reparse(bfr, size, 0, f);
+    ___mkd_reparse(bfr, size, 0, f, 0);
     ___mkd_emblock(f);
 }
 
@@ -295,15 +297,16 @@ int
 mkd_generateline(char *bfr, int size, FILE *output, DWORD flags)
 {
     MMIOT f;
+    int status;
 
     mkd_parse_line(bfr, size, &f, flags);
     if ( flags & MKD_CDATA )
-	mkd_generatexml(T(f.out), S(f.out), output);
+	status = mkd_generatexml(T(f.out), S(f.out), output) != EOF;
     else
-	fwrite(T(f.out), S(f.out), 1, output);
+	status = fwrite(T(f.out), S(f.out), 1, output) == S(f.out);
 
     ___mkd_freemmiot(&f, 0);
-    return 0;
+    return status ? 0 : EOF;
 }
 
 

+ 14 - 1
discount/mkdio.h

@@ -12,6 +12,11 @@ typedef unsigned int mkd_flag_t;
 MMIOT *mkd_in(FILE*,mkd_flag_t);		/* assemble input from a file */
 MMIOT *mkd_string(const char*,int,mkd_flag_t);	/* assemble input from a buffer */
 
+/* line builder for github flavoured markdown
+ */
+MMIOT *gfm_in(FILE*,mkd_flag_t);		/* assemble input from a file */
+MMIOT *gfm_string(const char*,int,mkd_flag_t);	/* assemble input from a buffer */
+
 void mkd_basename(MMIOT*,char*);
 
 void mkd_initialize();
@@ -21,7 +26,7 @@ void mkd_shlib_destructor();
 /* compilation, debugging, cleanup
  */
 int mkd_compile(MMIOT*, mkd_flag_t);
-int mkd_cleanup(MMIOT*);
+void mkd_cleanup(MMIOT*);
 
 /* markup functions
  */
@@ -102,6 +107,14 @@ void mkd_ref_prefix(MMIOT*, char*);
 #define MKD_NOALPHALIST	0x00080000	/* forbid alphabetic lists */
 #define MKD_NODLIST	0x00100000	/* forbid definition lists */
 #define MKD_EXTRA_FOOTNOTE 0x00200000	/* enable markdown extra-style footnotes */
+#define MKD_NOSTYLE	0x00400000	/* don't extract <style> blocks */
+#define MKD_NODLDISCOUNT 0x00800000	/* disable discount-style definition lists */
+#define	MKD_DLEXTRA	0x01000000	/* enable extra-style definition lists */
+#define MKD_FENCEDCODE	0x02000000	/* enabled fenced code blocks */
+#define MKD_IDANCHOR	0x04000000	/* use id= anchors for TOC links */
+#define MKD_GITHUBTAGS	0x08000000	/* allow dash and underscore in element names */
+#define MKD_URLENCODEDANCHOR 0x10000000 /* urlencode non-identifier chars instead of replacing with dots */
+
 #define MKD_EMBED	MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
 
 /* special flags for mkd_in() and mkd_string()

+ 14 - 1
discount/mkdio.h.in

@@ -12,6 +12,11 @@ typedef @DWORD@ mkd_flag_t;
 MMIOT *mkd_in(FILE*,mkd_flag_t);		/* assemble input from a file */
 MMIOT *mkd_string(const char*,int,mkd_flag_t);	/* assemble input from a buffer */
 
+/* line builder for github flavoured markdown
+ */
+MMIOT *gfm_in(FILE*,mkd_flag_t);		/* assemble input from a file */
+MMIOT *gfm_string(const char*,int,mkd_flag_t);	/* assemble input from a buffer */
+
 void mkd_basename(MMIOT*,char*);
 
 void mkd_initialize();
@@ -21,7 +26,7 @@ void mkd_shlib_destructor();
 /* compilation, debugging, cleanup
  */
 int mkd_compile(MMIOT*, mkd_flag_t);
-int mkd_cleanup(MMIOT*);
+void mkd_cleanup(MMIOT*);
 
 /* markup functions
  */
@@ -102,6 +107,14 @@ void mkd_ref_prefix(MMIOT*, char*);
 #define MKD_NOALPHALIST	0x00080000	/* forbid alphabetic lists */
 #define MKD_NODLIST	0x00100000	/* forbid definition lists */
 #define MKD_EXTRA_FOOTNOTE 0x00200000	/* enable markdown extra-style footnotes */
+#define MKD_NOSTYLE	0x00400000	/* don't extract <style> blocks */
+#define MKD_NODLDISCOUNT 0x00800000	/* disable discount-style definition lists */
+#define	MKD_DLEXTRA	0x01000000	/* enable extra-style definition lists */
+#define MKD_FENCEDCODE	0x02000000	/* enabled fenced code blocks */
+#define MKD_IDANCHOR	0x04000000	/* use id= anchors for TOC links */
+#define MKD_GITHUBTAGS	0x08000000	/* allow dash and underscore in element names */
+#define MKD_URLENCODEDANCHOR 0x10000000 /* urlencode non-identifier chars instead of replacing with dots */
+
 #define MKD_EMBED	MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
 
 /* special flags for mkd_in() and mkd_string()

+ 12 - 3
discount/pgm_options.c

@@ -25,7 +25,7 @@ static struct _opt {
     char *name;
     char *desc;
     int off;
-    int skip;
+    int skip; /* this opt is a synonym */
     int sayenable;
     mkd_flag_t flag;
 } opts[] = {
@@ -54,11 +54,20 @@ static struct _opt {
     { "1.0",           "markdown 1.0 compatibility", 0, 0, 1, MKD_1_COMPAT },
     { "footnotes",     "markdown extra footnotes",   0, 0, 1, MKD_EXTRA_FOOTNOTE },
     { "footnote",      "markdown extra footnotes",   0, 1, 1, MKD_EXTRA_FOOTNOTE },
+    { "style",         "extract style blocks",       1, 0, 1, MKD_NOSTYLE },
+    { "dldiscount",    "discount-style definition lists", 1, 0, 1, MKD_NODLDISCOUNT },
+    { "dlextra",       "extra-style definition lists", 0, 0, 1, MKD_DLEXTRA },
+    { "fencedcode",    "fenced code blocks",         0, 0, 1, MKD_FENCEDCODE },
+    { "idanchor",      "id= anchors in TOC",         0, 0, 1, MKD_IDANCHOR },
+    { "githubtags",    "permit - and _ in element names", 0, 0, 0, MKD_GITHUBTAGS },
+    { "urlencodedanchor", "urlencode special chars in TOC links", 0, 0, 0, MKD_URLENCODEDANCHOR },
 } ;
 
 #define NR(x)	(sizeof x / sizeof x[0])
 
 
+typedef int (*stfu)(const void *, const void *);
+
 int
 sort_by_name(struct _opt *a, struct _opt *b)
 {
@@ -78,14 +87,14 @@ show_flags(int byname)
     int i;
 
     if ( byname ) {
-	qsort(opts, NR(opts), sizeof(opts[0]), sort_by_name);
+	qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name);
     
 	for (i=0; i < NR(opts); i++)
 	    if ( ! opts[i].skip )
 		fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc);
     }
     else {
-	qsort(opts, NR(opts), sizeof(opts[0]), sort_by_flag);
+	qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag);
 	
 	for (i=0; i < NR(opts); i++)
 	    if ( ! opts[i].skip ) {

+ 6 - 4
discount/resource.c

@@ -51,6 +51,8 @@ ___mkd_freeParagraph(Paragraph *p)
 	___mkd_freeLines(p->text);
     if (p->ident)
 	free(p->ident);
+    if (p->lang)
+	free(p->lang);
     free(p);
 }
 
@@ -74,9 +76,9 @@ ___mkd_freefootnotes(MMIOT *f)
     int i;
 
     if ( f->footnotes ) {
-	for (i=0; i < S(*f->footnotes); i++)
-	    ___mkd_freefootnote( &T(*f->footnotes)[i] );
-	DELETE(*f->footnotes);
+	for (i=0; i < S(f->footnotes->note); i++)
+	    ___mkd_freefootnote( &T(f->footnotes->note)[i] );
+	DELETE(f->footnotes->note);
 	free(f->footnotes);
     }
 }
@@ -96,7 +98,7 @@ ___mkd_initmmiot(MMIOT *f, void *footnotes)
 	    f->footnotes = footnotes;
 	else {
 	    f->footnotes = malloc(sizeof f->footnotes[0]);
-	    CREATE(*f->footnotes);
+	    CREATE(f->footnotes->note);
 	}
     }
 }

+ 3 - 0
discount/tags.c

@@ -26,6 +26,9 @@ mkd_define_tag(char *id, int selfclose)
      * either the standard or extra tag tables.
      */
     if ( !(p = mkd_search_tags(id, strlen(id))) ) {
+	/* extratags could be deallocated */
+	if ( S(extratags) == 0 )
+	    CREATE(extratags);
 	p = &EXPAND(extratags);
 	p->id = id;
 	p->size = strlen(id);

+ 3 - 1
discount/theme.1

@@ -8,6 +8,8 @@
 .Nd create a web page from a template file
 .Sh SYNOPSIS
 .Nm
+.Op Fl C Pa option-flags
+.Op Fl c Pa options
 .Op Fl d Pa root
 .Op Fl E
 .Op Fl f
@@ -155,4 +157,4 @@ utility exits 0 on success, and >0 if an error occurs.
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .An David Parsons
-.Pq Li orc@pell.chi.il.us
+.Pq Li orc@pell.portland.or.us

+ 23 - 4
discount/theme.c

@@ -10,6 +10,7 @@
  * be distributed with this source code.
  */
 #include "config.h"
+#include "pgm_options.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -17,6 +18,9 @@
 #if defined(HAVE_BASENAME) && defined(HAVE_LIBGEN_H)
 #  include <libgen.h>
 #endif
+#if defined(HAVE_ALLOCA_H)
+#  include <alloca.h>
+#endif
 #include <unistd.h>
 #include <stdarg.h>
 #include <sys/types.h>
@@ -56,7 +60,7 @@ basename(char *path)
 {
     char *p;
 
-    if (( p = strrchr(path, '/') ))
+    if ( p = strrchr(path, '/') )
 	return 1+p;
     return path;
 }
@@ -507,6 +511,7 @@ char **argv;
     char *source = "stdin";
     FILE *tmplfile;
     int opt;
+    mkd_flag_t flags = THEME_CF|MKD_TOC;
     int force = 0;
     MMIOT *doc;
     struct stat sourceinfo;
@@ -514,7 +519,7 @@ char **argv;
     opterr=1;
     pgm = basename(argv[0]);
 
-    while ( (opt=getopt(argc, argv, "Efd:t:p:o:V")) != EOF ) {
+    while ( (opt=getopt(argc, argv, "EfC:c:d:t:p:o:V")) != EOF ) {
 	switch (opt) {
 	case 'd':   root = optarg;
 		    break;
@@ -526,6 +531,20 @@ char **argv;
 		    break;
 	case 't':   template = optarg;
 		    break;
+	case 'C':   if ( strcmp(optarg, "?") == 0 ) {
+			show_flags(0);
+			exit(0);
+		    }
+		    else
+			flags = strtol(optarg, 0, 0);
+		    break;
+	case 'c':   if ( strcmp(optarg, "?") == 0 ) {
+			show_flags(1);
+			exit(0);
+		    }
+		    else if ( !set_flag(&flags, optarg) )
+			fprintf(stderr,"%s: unknown option <%s>", pgm, optarg);
+		    break;		    
 	case 'o':   output = optarg;
 		    break;
 	case 'V':   printf("theme+discount %s\n", markdown_version);
@@ -577,7 +596,7 @@ char **argv;
 	    strcat(q, ".html");
 	}
     }
-    if ( output ) {
+    if ( output && strcmp(output, "-") ) {
 	if ( force )
 	    unlink(output);
 	if ( !freopen(output, "w", stdout) )
@@ -600,7 +619,7 @@ char **argv;
 	fail("out of memory");
 #endif
 
-    if ( !mkd_compile(doc, MKD_TOC) )
+    if ( !mkd_compile(doc, flags) )
 	fail("couldn't compile input");
 
     if ( tmplfile )

+ 2 - 2
discount/toc.c

@@ -62,11 +62,11 @@ mkd_toc(Document *p, char **doc)
 		    Csprintf(&res, "%*s<li><a href=\"#", srcp->hnumber, "");
 		    mkd_string_to_anchor(T(srcp->text->text),
 					 S(srcp->text->text),
-					 (mkd_sta_function_t)Csputc, &res,1);
+					 (mkd_sta_function_t)Csputc, &res,1,p->ctx->flags);
 		    Csprintf(&res, "\">");
 		    mkd_string_to_anchor(T(srcp->text->text),
 					 S(srcp->text->text),
-					 (mkd_sta_function_t)Csputc, &res,0);
+					 (mkd_sta_function_t)Csputc, &res,0,p->ctx->flags);
 		    Csprintf(&res, "</a>");
 
 		    first = 0;

+ 4 - 19
discount/version.c

@@ -1,7 +1,9 @@
 #include "config.h"
+
 #ifndef VERSION
 #define VERSION "0.0"
 #endif
+
 char markdown_version[] = VERSION
 #if 4 != 4
 		" TAB=4"
@@ -9,24 +11,7 @@ char markdown_version[] = VERSION
 #if USE_AMALLOC
 		" DEBUG"
 #endif
-#if USE_DISCOUNT_DL
-# if USE_EXTRA_DL
-		" DL=BOTH"
-# else
-		" DL=DISCOUNT"
-# endif
-#elif USE_EXTRA_DL
-		" DL=EXTRA"
-#else
-		" DL=NONE"
-#endif
-#if WITH_ID_ANCHOR
-		" ID-ANCHOR"
-#endif
-#if WITH_GITHUB_TAGS
-		" GITHUB-TAGS"
-#endif
-#if WITH_FENCED_CODE
-		" FENCED-CODE"
+#if WITH_LATEX
+		" LATEX"
 #endif
 		;

+ 2 - 19
discount/version.c.in

@@ -11,24 +11,7 @@ char markdown_version[] = VERSION
 #if USE_AMALLOC
 		" DEBUG"
 #endif
-#if USE_DISCOUNT_DL
-# if USE_EXTRA_DL
-		" DL=BOTH"
-# else
-		" DL=DISCOUNT"
-# endif
-#elif USE_EXTRA_DL
-		" DL=EXTRA"
-#else
-		" DL=NONE"
-#endif
-#if WITH_ID_ANCHOR
-		" ID-ANCHOR"
-#endif
-#if WITH_GITHUB_TAGS
-		" GITHUB-TAGS"
-#endif
-#if WITH_FENCED_CODE
-		" FENCED-CODE"
+#if WITH_LATEX
+		" LATEX"
 #endif
 		;

+ 2 - 2
discount/xml.c

@@ -47,9 +47,9 @@ mkd_generatexml(char *p, int size, FILE *out)
 	c = *p++;
 
 	if ( entity = mkd_xmlchar(c) )
-	    fputs(entity, out);
+	    DO_OR_DIE( fputs(entity, out) );
 	else
-	    fputc(c, out);
+	    DO_OR_DIE( fputc(c, out) );
     }
     return 0;
 }

+ 16 - 18
discount/xmlpage.c

@@ -22,27 +22,25 @@ mkd_xhtmlpage(Document *p, int flags, FILE *out)
     extern char *mkd_doc_title(Document *);
     
     if ( mkd_compile(p, flags) ) {
-	fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-	fprintf(out, "<!DOCTYPE html "
-		     " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
-		     " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
+	DO_OR_DIE( fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+				"<!DOCTYPE html "
+				" PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
+				" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
+				"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n") );
 
-	fprintf(out, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n");
-
-	fprintf(out, "<head>\n");
-	if ( title = mkd_doc_title(p) )
-	    fprintf(out, "<title>%s</title>\n", title);
-	mkd_generatecss(p, out);
-	fprintf(out, "</head>\n");
-	
-	fprintf(out, "<body>\n");
-	mkd_generatehtml(p, out);
-	fprintf(out, "</body>\n");
-	fprintf(out, "</html>\n");
+	DO_OR_DIE( fprintf(out, "<head>\n") );
+	if ( title = mkd_doc_title(p) ) {
+	    DO_OR_DIE( fprintf(out, "<title>%s</title>\n", title) );
+	}
+	DO_OR_DIE( mkd_generatecss(p, out) );
+	DO_OR_DIE( fprintf(out, "</head>\n"
+				"<body>\n") );
 	
-	mkd_cleanup(p);
+	DO_OR_DIE( mkd_generatehtml(p, out) );
+	DO_OR_DIE( fprintf(out, "</body>\n"
+				"</html>\n") );
 
 	return 0;
     }
-    return -1;
+    return EOF;
 }