Jelajahi Sumber

Update libdiscount to 2.2.0

mingodad 9 tahun lalu
induk
melakukan
d2039379f6

+ 25 - 42
discount/COPYRIGHT

@@ -1,47 +1,30 @@
 ->Copyright (C) 2007 David Loren Parsons.  
 ->Copyright (C) 2007 David Loren Parsons.  
 All rights reserved.<-
 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
 where it is via contributions, critiques, and bug reports from a
 host of other people, some of which are listed before.   If your
 host of other people, some of which are listed before.   If your
 name isn't on this list, please remind me
 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.
 Josh Wood	--  Plan9 support.

+ 1 - 1
discount/Csio.c

@@ -54,7 +54,7 @@ Csreparse(Cstring *iot, char *buf, int size, int flags)
 {
 {
     MMIOT f;
     MMIOT f;
     ___mkd_initmmiot(&f, 0);
     ___mkd_initmmiot(&f, 0);
-    ___mkd_reparse(buf, size, 0, &f);
+    ___mkd_reparse(buf, size, 0, &f, 0);
     ___mkd_emblock(&f);
     ___mkd_emblock(&f);
     SUFFIX(*iot, T(f.out), S(f.out));
     SUFFIX(*iot, T(f.out), S(f.out));
     ___mkd_freemmiot(&f, 0);
     ___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
 CFLAGS=-g
-AR=/mingw/bin/ar
-RANLIB=/mingw/bin/ranlib
+AR=/usr/bin/ar
+RANLIB=/usr/bin/ranlib
 
 
 BINDIR=/usr/local/bin
 BINDIR=/usr/local/bin
-MANDIR=/usr/local/share/man
+MANDIR=/usr/local/man
 LIBDIR=/usr/local/lib
 LIBDIR=/usr/local/lib
 INCDIR=/usr/local/include
 INCDIR=/usr/local/include
 
 
@@ -15,55 +16,60 @@ MKDLIB=libmarkdown
 OBJS=mkdio.o markdown.o dumptree.o generate.o \
 OBJS=mkdio.o markdown.o dumptree.o generate.o \
      resource.o docheader.o version.o toc.o css.o \
      resource.o docheader.o version.o toc.o css.o \
      xml.o Csio.o xmlpage.o basename.o emmatch.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
 TESTFRAMEWORK=echo cols
 
 
 MAN3PAGES=mkd-callbacks.3 mkd-functions.3 markdown.3 mkd-line.3
 MAN3PAGES=mkd-callbacks.3 mkd-functions.3 markdown.3 mkd-line.3
 
 
 all: $(PGMS) $(SAMPLE_PGMS) $(TESTFRAMEWORK)
 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.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:
 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 \
 	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
 	done
 	for x in mkd_in mkd_string; do \
 	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
 	done
 	for x in mkd_compile mkd_css mkd_generatecss mkd_generatehtml mkd_cleanup mkd_doc_title mkd_doc_author mkd_doc_date; do \
 	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
 	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
 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
 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
 tags.o: tags.c blocktags
 
 
@@ -72,23 +78,23 @@ blocktags: mktags
 
 
 # example programs
 # example programs
 theme:  theme.o $(MKDLIB) mkdio.h
 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
 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)
 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
 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
 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
 main.o: main.c mkdio.h config.h
-	$(CC) -I. -c main.c
+	$(CC) $(CFLAGS) -I. -c main.c
 
 
 $(MKDLIB): $(OBJS)
 $(MKDLIB): $(OBJS)
 	./librarian.sh make $(MKDLIB) VERSION $(OBJS)
 	./librarian.sh make $(MKDLIB) VERSION $(OBJS)
@@ -111,7 +117,7 @@ clean:
 	rm -f $(MKDLIB) `./librarian.sh files $(MKDLIB) VERSION`
 	rm -f $(MKDLIB) `./librarian.sh files $(MKDLIB) VERSION`
 
 
 distclean spotless: clean
 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
 Csio.o: Csio.c cstring.h amalloc.h config.h markdown.h
 amalloc.o: amalloc.c
 amalloc.o: amalloc.c

+ 18 - 12
discount/Makefile.in

@@ -1,4 +1,5 @@
-CC=@CC@ -I. -L.
+CC=@CC@ -I.
+LFLAGS=-L.
 CFLAGS=@CFLAGS@
 CFLAGS=@CFLAGS@
 AR=@AR@
 AR=@AR@
 RANLIB=@RANLIB@
 RANLIB=@RANLIB@
@@ -15,7 +16,7 @@ MKDLIB=libmarkdown
 OBJS=mkdio.o markdown.o dumptree.o generate.o \
 OBJS=mkdio.o markdown.o dumptree.o generate.o \
      resource.o docheader.o version.o toc.o css.o \
      resource.o docheader.o version.o toc.o css.o \
      xml.o Csio.o xmlpage.o basename.o emmatch.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
 TESTFRAMEWORK=echo cols
 
 
 MAN3PAGES=mkd-callbacks.3 mkd-functions.3 markdown.3 mkd-line.3
 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.everything: install install.samples install.man
 
 
 install.samples: $(SAMPLE_PGMS) install $(DESTDIR)$(BINDIR)
 install.samples: $(SAMPLE_PGMS) install $(DESTDIR)$(BINDIR)
-	@INSTALL_PROGRAM@ $(SAMPLE_PGMS) $(DESTDIR)$(BINDIR)
 	@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man1
 	@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.man:
 	@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man3
 	@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man3
@@ -63,7 +66,10 @@ $(DESTDIR)$(LIBDIR):
 	@INSTALL_DIR@ $(DESTDIR)$(LIBDIR)
 	@INSTALL_DIR@ $(DESTDIR)$(LIBDIR)
 
 
 version.o: version.c VERSION
 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
 tags.o: tags.c blocktags
 
 
@@ -72,23 +78,23 @@ blocktags: mktags
 
 
 # example programs
 # example programs
 @THEME@theme:  theme.o $(MKDLIB) mkdio.h
 @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
 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)
 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
 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
 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
 main.o: main.c mkdio.h config.h
-	$(CC) -I. -c main.c
+	$(CC) $(CFLAGS) -I. -c main.c
 
 
 $(MKDLIB): $(OBJS)
 $(MKDLIB): $(OBJS)
 	./librarian.sh make $(MKDLIB) VERSION $(OBJS)
 	./librarian.sh make $(MKDLIB) VERSION $(OBJS)
@@ -111,7 +117,7 @@ clean:
 	rm -f $(MKDLIB) `./librarian.sh files $(MKDLIB) VERSION`
 	rm -f $(MKDLIB) `./librarian.sh files $(MKDLIB) VERSION`
 
 
 distclean spotless: clean
 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
 Csio.o: Csio.c cstring.h amalloc.h config.h markdown.h
 amalloc.o: amalloc.c
 amalloc.o: amalloc.c

+ 1 - 1
discount/README

@@ -5,7 +5,7 @@ language as described in
 and passes the Markdown test suite at
 and passes the Markdown test suite at
 <http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip>
 <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
 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
 as you wish with it as long as you don't attempt to claim it as
 your own work.
 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
 #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 };
 static struct alist list =  { 0, 0, 0, 0 };
 
 
@@ -16,14 +16,32 @@ static int mallocs=0;
 static int reallocs=0;
 static int reallocs=0;
 static int frees=0;
 static int frees=0;
 
 
+static int index = 0;
+
+static void
+die(char *msg, int index)
+{
+    fprintf(stderr, msg, index);
+    abort();
+}
+
+
 void *
 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->magic = MAGIC;
 	ret->size = size * count;
 	ret->size = size * count;
+	ret->index = index ++;
+	ret->end = (int*)(count + (char*) (ret + 1));
+	*(ret->end) = ~MAGIC;
 	if ( list.next ) {
 	if ( list.next ) {
 	    ret->next = list.next;
 	    ret->next = list.next;
 	    ret->last = &list;
 	    ret->last = &list;
@@ -54,6 +72,8 @@ afree(void *ptr)
     struct alist *p2 = ((struct alist*)ptr)-1;
     struct alist *p2 = ((struct alist*)ptr)-1;
 
 
     if ( p2->magic == MAGIC ) {
     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->last->next = p2->next;
 	p2->next->last = p2->last;
 	p2->next->last = p2->last;
 	++frees;
 	++frees;
@@ -71,12 +91,16 @@ arealloc(void *ptr, int size)
     struct alist save;
     struct alist save;
 
 
     if ( p2->magic == MAGIC ) {
     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.next = p2->next;
 	save.last = p2->last;
 	save.last = p2->last;
-	p2 = realloc(p2, sizeof(*p2) + size);
+	p2 = realloc(p2, sizeof(int) + sizeof(*p2) + size);
 
 
 	if ( p2 ) {
 	if ( p2 ) {
 	    p2->size = size;
 	    p2->size = size;
+	    p2->end = (int*)(size + (char*) (p2 + 1));
+	    *(p2->end) = ~MAGIC;
 	    p2->next->last = p2;
 	    p2->next->last = p2;
 	    p2->last->next = p2;
 	    p2->last->next = p2;
 	    ++reallocs;
 	    ++reallocs;

+ 1 - 1
discount/config.cmd

@@ -1,2 +1,2 @@
 #! /bin/sh
 #! /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
 #ifndef __AC_MARKDOWN_D
 #define __AC_MARKDOWN_D 1
 #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_BZERO 1
-#define HAVE_RAND 1
-#define COINTOSS() (rand()&1)
+#define HAVE_RANDOM 1
+#define COINTOSS() (random()&1)
 #define HAVE_STRCASECMP 1
 #define HAVE_STRCASECMP 1
 #define HAVE_STRNCASECMP 1
 #define HAVE_STRNCASECMP 1
-#define HAVE_GETCWD 1
+#define HAVE_FCHDIR 1
 #define TABSTOP 4
 #define TABSTOP 4
 #define HAVE_MALLOC_H 1
 #define HAVE_MALLOC_H 1
-#define PATH_FIND "/bin/find"
+#define PATH_FIND "/usr/bin/find"
 #define PATH_SED "/bin/sed"
 #define PATH_SED "/bin/sed"
 
 
 #endif/* __AC_MARKDOWN_D */
 #endif/* __AC_MARKDOWN_D */

+ 1 - 1
discount/config.md

@@ -1,5 +1,5 @@
 #! /bin/sh
 #! /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"
 test -d "$1" || mkdir -p "$1"
 exit 0
 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;@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;@THEME@;;g
 s;@TABSTOP@;4;g
 s;@TABSTOP@;4;g
 s;@AMALLOC@;;g
 s;@AMALLOC@;;g
 s;@LIBS@;;g
 s;@LIBS@;;g
 s;@CONFIGURE_FILES@;config.cmd config.sub config.h config.mak config.log config.md;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;@GENERATED_FILES@;Makefile version.c mkdio.h;g
+s;@CC@;cc -Wno-return-type -Wno-implicit-int;g
 s;@CFLAGS@;-g;g
 s;@CFLAGS@;-g;g
 s;@LDFLAGS@;-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;@prefix@;/usr/local;g
 s;@exedir@;/usr/local/bin;g
 s;@exedir@;/usr/local/bin;g
 s;@sbindir@;/usr/local/sbin;g
 s;@sbindir@;/usr/local/sbin;g
 s;@libdir@;/usr/local/lib;g
 s;@libdir@;/usr/local/lib;g
 s;@libexec@;/usr/local/lib;g
 s;@libexec@;/usr/local/lib;g
 s;@confdir@;/etc;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;@LD_LIBRARY_PATH@;HERE;g
 s;@SED@;/bin/sed;g
 s;@SED@;/bin/sed;g

+ 155 - 96
discount/configure.inc

@@ -169,7 +169,7 @@ AC_CHECK_HEADERS () {
     for hdr in $*; do
     for hdr in $*; do
 	echo "#include <$hdr>" >> ngc$$.c
 	echo "#include <$hdr>" >> ngc$$.c
     done
     done
-    echo "main() { }" >> ngc$$.c
+    echo "int main() { }" >> ngc$$.c
 
 
     LOGN "looking for header $hdr"
     LOGN "looking for header $hdr"
 
 
@@ -193,8 +193,8 @@ AC_CHECK_FUNCS () {
     B=`echo "$1" | sed -e 's/(.*)//'`
     B=`echo "$1" | sed -e 's/(.*)//'`
 
 
     case "$B" in
     case "$B" in
-    "$1") F="$1()" ;;
-    *)    F="$1" ;;
+    "$1") F="$1()"; need_proto=1 ;;
+    *)    F="$1"  ; unset need_proto ;;
     esac
     esac
 
 
     shift
     shift
@@ -205,8 +205,12 @@ AC_CHECK_FUNCS () {
 	shift
 	shift
     done
     done
 
 
+    if [ "$need_proto" ]; then
+	echo "void $F;" >> ngc$$.c
+    fi
+
     cat >> ngc$$.c << EOF
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
 {
 
 
     $F;
     $F;
@@ -247,7 +251,7 @@ AC_CHECK_STRUCT () {
     done
     done
 
 
     cat >> ngc$$.c << EOF
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
 {
     struct $struct foo;
     struct $struct foo;
 }
 }
@@ -282,7 +286,7 @@ AC_CHECK_TYPE () {
     done
     done
 
 
     cat >> ngc$$.c << EOF
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
 {
     $type foo;
     $type foo;
 }
 }
@@ -319,7 +323,7 @@ AC_CHECK_FIELD () {
     done
     done
 
 
     cat >> ngc$$.c << EOF
     cat >> ngc$$.c << EOF
-main()
+int main()
 {
 {
     struct $struct foo;
     struct $struct foo;
 
 
@@ -348,7 +352,7 @@ AC_PROG_CC () {
 
 
     cat > ngc$$.c << \EOF
     cat > ngc$$.c << \EOF
 #include <stdio.h>
 #include <stdio.h>
-main()
+int main()
 {
 {
     puts("hello, sailor");
     puts("hello, sailor");
 }
 }
@@ -356,7 +360,7 @@ EOF
 
 
     TLOGN "checking the C compiler"
     TLOGN "checking the C compiler"
 
 
-    unset AC_CFLAGS AC_LDFLAGS
+    unset AC_CFLAGS AC_LDFLAGS __MACOS_DSYM
 
 
     if [ "$CC" ] ; then
     if [ "$CC" ] ; then
 	AC_CC="$CC"
 	AC_CC="$CC"
@@ -377,19 +381,19 @@ EOF
     fi
     fi
     echo "checking out the C compiler"
     echo "checking out the C compiler"
 
 
-    unset __MACOS_DSYM
     $AC_CC -o ngc$$ ngc$$.c
     $AC_CC -o ngc$$ ngc$$.c
     status=$?
     status=$?
-    test -d ngc$$.dSYM && __MACOS_DSYM=1
 
 
     TLOGN " ($AC_CC)"
     TLOGN " ($AC_CC)"
 
 
     if [ $status -eq 0 ]; then
     if [ $status -eq 0 ]; then
 	if $AC_CC -x c /dev/null -dM -E 2>&1 | grep '__clang__' >/dev/null; then
 	if $AC_CC -x c /dev/null -dM -E 2>&1 | grep '__clang__' >/dev/null; then
 	    TLOG " yuck, you're using clang"
 	    TLOG " yuck, you're using clang"
+	    IS_CLANG=T
 	    IS_BROKEN_CC=T
 	    IS_BROKEN_CC=T
 	elif $AC_CC -v 2>&1 | grep 'gcc version' >/dev/null; then
 	elif $AC_CC -v 2>&1 | grep 'gcc version' >/dev/null; then
 	    TLOG " oh ick, it looks like gcc"
 	    TLOG " oh ick, it looks like gcc"
+	    IS_GCC=T
 	    IS_BROKEN_CC=T
 	    IS_BROKEN_CC=T
 	else
 	else
 	    TLOG " ok"
 	    TLOG " ok"
@@ -421,12 +425,16 @@ EOF
 	else
 	else
 	    AC_LDFLAGS=${CFLAGS:-"-g"}
 	    AC_LDFLAGS=${CFLAGS:-"-g"}
 	fi
 	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
     else
 	AC_FAIL " does not compile code properly"
 	AC_FAIL " does not compile code properly"
     fi
     fi
 
 
-    AC_SUB 'CC' "$AC_CC"
-
     __remove ngc$$ ngc$$.c ngc$$.o
     __remove ngc$$ ngc$$.c ngc$$.o
 
 
     return $status
     return $status
@@ -505,7 +513,7 @@ AC_INIT () {
     __config_files="config.cmd config.sub config.h config.mak config.log"
     __config_files="config.cmd config.sub config.h config.mak config.log"
     rm -f $__config_files
     rm -f $__config_files
     __cwd=`pwd`
     __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
     AC_CONFIGURE_FOR=__AC_`echo $1 | sed -e 's/\..$//' | $AC_UPPERCASE  | tr ' ' '_'`_D
 
 
     # check to see whether to use echo -n or echo ...\c
     # check to see whether to use echo -n or echo ...\c
@@ -528,7 +536,7 @@ AC_INIT () {
 
 
     LOG "Configuring for [$1]"
     LOG "Configuring for [$1]"
 
 
-    cat > $__cwd/config.h << EOF
+    cat > "$__cwd"/config.h << EOF
 /*
 /*
  * configuration for $1${2:+" ($2)"}, generated `date`
  * configuration for $1${2:+" ($2)"}, generated `date`
  * by ${LOGNAME:-`whoami`}@`hostname`
  * 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 checks to see if the compiler can generate 2 and 4 byte ints.
 #
 #
 AC_SCALAR_TYPES () {
 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
     cat > ngc$$.c << EOF
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
@@ -904,22 +924,20 @@ char **argv;
     exit(0);
     exit(0);
 }
 }
 EOF
 EOF
-    rc=1
-    LOGN "defining WORD & DWORD scalar types"
     if $AC_CC ngc$$.c -o ngc$$; then
     if $AC_CC ngc$$.c -o ngc$$; then
 	while [ "$1" ]; do
 	while [ "$1" ]; do
 	    case "$1" in
 	    case "$1" in
-	    sub)if ./ngc$$ sub >> $__cwd/config.sub; then
+	    sub)if ./ngc$$ sub >> "$__cwd"/config.sub; then
 		    rc=0
 		    rc=0
 		fi;;
 		fi;;
-	    *)  if ./ngc$$ >> $__cwd/config.h; then
+	    *)  if ./ngc$$ >> "$__cwd"/config.h; then
 		    rc=0
 		    rc=0
 		fi ;;
 		fi ;;
 	    esac
 	    esac
 	    shift
 	    shift
 	done
 	done
 	if [ "$rc" != 0 ]; then
 	if [ "$rc" != 0 ]; then
-	    if ./ngc$$ >> $__cwd/config.h; then
+	    if ./ngc$$ >> "$__cwd"/config.h; then
 		rc=1
 		rc=1
 	    fi
 	    fi
 	fi
 	fi
@@ -929,6 +947,7 @@ EOF
     0) TLOG "" ;;
     0) TLOG "" ;;
     *) AC_FAIL " ** FAILED **" ;;
     *) AC_FAIL " ** FAILED **" ;;
     esac
     esac
+    return $rc
 }
 }
 
 
 
 
@@ -936,10 +955,19 @@ EOF
 # AC_OUTPUT generates makefiles from makefile.in's
 # AC_OUTPUT generates makefiles from makefile.in's
 #
 #
 AC_OUTPUT () {
 AC_OUTPUT () {
-    cd $__cwd
+    
+    cd "$__cwd"
     AC_SUB 'LIBS'    "$AC_LIBS"
     AC_SUB 'LIBS'    "$AC_LIBS"
     AC_SUB 'CONFIGURE_FILES' "$__config_files"
     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 'CFLAGS'  "$AC_CFLAGS"
     AC_SUB 'LDFLAGS' "$AC_LDFLAGS"
     AC_SUB 'LDFLAGS' "$AC_LDFLAGS"
     AC_SUB 'srcdir'  "$AC_SRCDIR"
     AC_SUB 'srcdir'  "$AC_SRCDIR"
@@ -965,7 +993,7 @@ AC_OUTPUT () {
 	AC_PROG ar
 	AC_PROG ar
 	AC_PROG ranlib
 	AC_PROG ranlib
 	AC_SUB LD_LIBRARY_PATH HERE
 	AC_SUB LD_LIBRARY_PATH HERE
-	AC
+
 	__config_files="$__config_files librarian.sh"
 	__config_files="$__config_files librarian.sh"
 	cat > librarian.sh << EOF
 	cat > librarian.sh << EOF
 #! /bin/sh
 #! /bin/sh
@@ -1008,10 +1036,10 @@ EOF
 
 
 	__d=$AC_SRCDIR
 	__d=$AC_SRCDIR
 	for makefile in $*;do
 	for makefile in $*;do
-	    if test -r $__d/${makefile}.in; then
+	    if test -r "$__d/${makefile}.in"; then
 		LOG "generating $makefile"
 		LOG "generating $makefile"
 		./config.md `__ac_dirname ./$makefile` 2>/dev/null
 		./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"
 		__config_files="$__config_files $makefile"
 	    else
 	    else
 		LOG "WARNING: ${makefile}.in does not exist!"
 		LOG "WARNING: ${makefile}.in does not exist!"
@@ -1038,7 +1066,7 @@ AC_CHECK_FLOCK() {
 #include <sys/types.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <fcntl.h>
 
 
-main()
+int main()
 {
 {
     int x = open("$$.c", O_RDWR, 0666);
     int x = open("$$.c", O_RDWR, 0666);
     int y = open("$$.c", O_RDWR, 0666);
     int y = open("$$.c", O_RDWR, 0666);
@@ -1091,7 +1119,7 @@ AC_CHECK_RESOLVER () {
 #include <arpa/nameser.h>
 #include <arpa/nameser.h>
 #include <resolv.h>
 #include <resolv.h>
 
 
-main()
+int main()
 {
 {
     char bfr[256];
     char bfr[256];
 
 
@@ -1103,14 +1131,15 @@ EOF
     if $AC_CC -o ngc$$ ngc$$.c; then
     if $AC_CC -o ngc$$ ngc$$.c; then
 	TLOG " (found)"
 	TLOG " (found)"
     elif $AC_CC -o ngc$$ ngc$$.c -lresolv; then
     elif $AC_CC -o ngc$$ ngc$$.c -lresolv; then
-	TLOG " (found, needs -lresolv)"
+	TLOG " (yes, needs -lresolv)"
 	AC_LIBS="$AC_LIBS -lresolv"
 	AC_LIBS="$AC_LIBS -lresolv"
     elif $AC_CC -DBIND_8_COMPAT -o ngc$$ ngc$$.c; then
     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
 	AC_DEFINE BIND_8_COMPAT 1
     elif $AC_CC -DBIND_8_COMPAT -o ngc$$ ngc$$.c -lresolv; then
     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_DEFINE BIND_8_COMPAT 1
+	AC_LIBS="$AC_LIBS -lresolv"
     else
     else
 	TLOG " (not found)"
 	TLOG " (not found)"
 	__ACR_rc=1
 	__ACR_rc=1
@@ -1134,7 +1163,7 @@ AC_CHECK_ALLOCA () {
 #else
 #else
 # include <stdlib.h>
 # include <stdlib.h>
 #endif
 #endif
-main()
+int main()
 {
 {
 	alloca(10);
 	alloca(10);
 }
 }
@@ -1168,11 +1197,16 @@ AC_CHECK_BASENAME() {
     cat > ngc$$.c << EOF
     cat > ngc$$.c << EOF
 #include <string.h>
 #include <string.h>
 
 
-main()
+extern char *basename(char*);
+
+int main()
 {
 {
     char *a = basename("/a/test");
     char *a = basename("/a/test");
     char *b = basename("/a/nother");
     char *b = basename("/a/nother");
 
 
+    if ( a == 0 || b == 0 || a == b )
+	return 0;
+
     return (strcmp(a,b) != 0) ? 0 : 1;
     return (strcmp(a,b) != 0) ? 0 : 1;
 
 
 }
 }
@@ -1214,31 +1248,16 @@ AC_COMPILER_PIC () {
     return $__rc
     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
 #! /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
 ACTION=\$1; shift
 LIBRARY=\$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\`
 		  printf "VERSION=%d.%d.%d\n", \$1, \$2, \$3; }' \$1\`
 shift
 shift
 
 
-LIBNAME=\$LIBRARY.so
-FULLNAME=\$LIBNAME.\$VERSION
+LIBNAME=\$LIBRARY.dylib
+FULLNAME=\$LIBNAME
 
 
 case "\$ACTION" in
 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
 	if $AC_CC \$FLAGS \$VFLAGS -o \$FULLNAME "\$@"; then
 	    $PROG_LN_S \$FULLNAME \$LIBRARY
 	    $PROG_LN_S \$FULLNAME \$LIBRARY
-	    $PROG_LN_S \$FULLNAME \$LIBNAME
-	    $PROG_LN_S \$FULLNAME \$LIBNAME.\$MAJOR
 	fi
 	fi
 	;;
 	;;
-files)  echo "\$FULLNAME" "\$LIBNAME" "\$LIBNAME.\$MAJOR"
+files)  echo "\$FULLNAME"
 	;;
 	;;
 install)$PROG_INSTALL -c \$FULLNAME "\$1"
 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
 esac
 EOF
 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
 #! /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
 ACTION=\$1; shift
 LIBRARY=\$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\`
 		  printf "VERSION=%d.%d.%d\n", \$1, \$2, \$3; }' \$1\`
 shift
 shift
 
 
-LIBNAME=\$LIBRARY.dylib
-FULLNAME=\$LIBNAME
+LIBNAME=\$LIBRARY.so
+FULLNAME=\$LIBNAME.\$VERSION
 
 
 case "\$ACTION" in
 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
 	if $AC_CC \$FLAGS \$VFLAGS -o \$FULLNAME "\$@"; then
 	    $PROG_LN_S \$FULLNAME \$LIBRARY
 	    $PROG_LN_S \$FULLNAME \$LIBRARY
+	    $PROG_LN_S \$FULLNAME \$LIBNAME
+	    $PROG_LN_S \$FULLNAME \$LIBNAME.\$MAJOR
 	fi
 	fi
 	;;
 	;;
-files)  echo "\$FULLNAME"
+files)  echo "\$FULLNAME" "\$LIBNAME" "\$LIBNAME.\$MAJOR"
 	;;
 	;;
 install)$PROG_INSTALL -c \$FULLNAME "\$1"
 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
 esac
 EOF
 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
 	__rc=0
     else
     else
         LOG "(no)"
         LOG "(no)"
@@ -1383,15 +1440,15 @@ AC_PROG_INSTALL () {
     fi
     fi
 
 
     __config_files="$__config_files config.md"
     __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
     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
     else
-	cat - >> $__cwd/config.md << \EOD
+	cat - >> ""$__cwd"/config.md" << \EOD
 pieces=`IFS=/; for x in $1; do echo $x; done`
 pieces=`IFS=/; for x in $1; do echo $x; done`
 dir=
 dir=
 for x in $pieces; do
 for x in $pieces; do
@@ -1402,7 +1459,7 @@ done
 exit 0
 exit 0
 EOD
 EOD
     fi
     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 writes a substitution into config.sub
 AC_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 writes a define into config.mak
 AC_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 adds a #define to config.h
 AC_DEFINE() {
 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 adds a #include to config.h
 AC_INCLUDE() {
 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
 ac_help='--enable-amalloc	Enable memory allocation debugging
 --with-tabstops=N	Set tabstops to N characters (default is 4)
 --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
 --enable-all-features	Turn on all stable optional features
 --shared		Build shared libraries (default is static)'
 --shared		Build shared libraries (default is static)'
 
 
@@ -36,6 +33,9 @@ locals() {
 		;;
 		;;
     --ENABLE-*)	enable=`echo $K | sed -e 's/--ENABLE-//' | tr '-' '_'`
     --ENABLE-*)	enable=`echo $K | sed -e 's/--ENABLE-//' | tr '-' '_'`
 		echo WITH_${enable}=T ;;
 		echo WITH_${enable}=T ;;
+    --DEBIAN-GLITCH)
+		echo DEBIAN_GLITCH=T
+		;;
     esac
     esac
 }
 }
 
 
@@ -44,28 +44,45 @@ TARGET=markdown
 
 
 AC_INIT $TARGET
 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
 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
 AC_PROG_CC
 
 
 test "$TRY_SHARED" && AC_COMPILER_PIC && AC_CC_SHLIBS
 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 ar || AC_FAIL "$TARGET requires ar"
 AC_PROG ranlib
 AC_PROG ranlib
@@ -75,6 +92,7 @@ AC_C_CONST
 AC_C_INLINE
 AC_C_INLINE
 AC_SCALAR_TYPES sub hdr
 AC_SCALAR_TYPES sub hdr
 AC_CHECK_BASENAME
 AC_CHECK_BASENAME
+AC_CHECK_ALLOCA
 
 
 AC_CHECK_HEADERS sys/types.h pwd.h && AC_CHECK_FUNCS getpwuid
 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
 [ "$OS_FREEBSD" -o "$OS_DRAGONFLY" ] || AC_CHECK_HEADERS malloc.h
 
 
 [ "$WITH_PANDOC_HEADER" ] && AC_DEFINE 'PANDOC_HEADER' '1'
 [ "$WITH_PANDOC_HEADER" ] && AC_DEFINE 'PANDOC_HEADER' '1'
+[ "$WITH_LATEX" ] && AC_DEFINE 'WITH_LATEX' '1'
 
 
 AC_OUTPUT Makefile version.c mkdio.h
 AC_OUTPUT Makefile version.c mkdio.h

+ 5 - 3
discount/css.c

@@ -75,11 +75,13 @@ int
 mkd_generatecss(Document *d, FILE *f)
 mkd_generatecss(Document *d, FILE *f)
 {
 {
     char *res;
     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 )
     if ( res )
 	free(res);
 	free(res);
+    
     return (written == size) ? size : EOF;
     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) \
 #define DELETE(x)	ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
 				     : ( S(x) = 0 )
 				     : ( S(x) = 0 )
 #define CLIP(t,i,sz)	\
 #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])), \
 	    (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) \
 #define RESERVE(x, sz)	T(x) = ((x).alloc > S(x) + (sz) \
 			    ? T(x) \
 			    ? T(x) \

+ 1 - 1
discount/discount.cbp

@@ -35,7 +35,7 @@
 		<Compiler>
 		<Compiler>
 			<Add option="-Wall" />
 			<Add option="-Wall" />
 			<Add option="-g" />
 			<Add option="-g" />
-			<Add directory="../discount-2.1.2" />
+			<Add directory="../discount" />
 		</Compiler>
 		</Compiler>
 		<Linker>
 		<Linker>
 			<Add library="discount" />
 			<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);
 	dumptree(doc->code, &stack, out);
 	DELETE(stack);
 	DELETE(stack);
 
 
-	mkd_cleanup(doc);
 	return 0;
 	return 0;
     }
     }
     return -1;
     return -1;

+ 1 - 1
discount/emmatch.c

@@ -22,7 +22,7 @@
  *          of html has been generated.
  *          of html has been generated.
  *
  *
  *          It should create MarkdownTest_1.0 (and _1.0.3)
  *          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
  *          and it should fail in a standards-compliant way
  *          when someone attempts to feed it junk.
  *          when someone attempts to feed it junk.
  *
  *

+ 7 - 0
discount/flags.c

@@ -29,6 +29,13 @@ static struct flagnames flagnames[] = {
     { MKD_NOALPHALIST,    "!ALPHALIST" },
     { MKD_NOALPHALIST,    "!ALPHALIST" },
     { MKD_NODLIST,        "!DLIST" },
     { MKD_NODLIST,        "!DLIST" },
     { MKD_EXTRA_FOOTNOTE, "FOOTNOTE" },
     { 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])
 #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.
 /* look <i> characters ahead of the cursor.
  */
  */
 static inline int
 static inline int
@@ -73,7 +83,11 @@ isthisspace(MMIOT *f, int i)
 {
 {
     int c = peek(f, 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
 /* generate html from a markup fragment
  */
  */
 void
 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;
     MMIOT sub;
+    struct escaped e;
 
 
     ___mkd_initmmiot(&sub, f->footnotes);
     ___mkd_initmmiot(&sub, f->footnotes);
 
 
@@ -204,6 +219,14 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
     sub.cb = f->cb;
     sub.cb = f->cb;
     sub.ref_prefix = f->ref_prefix;
     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);
     push(bfr, size, &sub);
     EXPAND(sub.in) = 0;
     EXPAND(sub.in) = 0;
     S(sub.in)--;
     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
  * write out a url, escaping problematic characters
  */
  */
@@ -243,7 +283,7 @@ puturl(char *s, int size, MMIOT *f, int display)
 	    Qstring("%22", f);
 	    Qstring("%22", f);
 	else if ( isalnum(c) || ispunct(c) || (display && isspace(c)) )
 	else if ( isalnum(c) || ispunct(c) || (display && isspace(c)) )
 	    Qchar(c, f);
 	    Qchar(c, f);
-	else if ( c == 003 )	/* untokenize ^C */
+	else if ( c == MKD_EOLN )	/* untokenize hard return */
 	    Qstring("  ", f);
 	    Qstring("  ", f);
 	else
 	else
 	    Qprintf(f, "%%%02X", c);
 	    Qprintf(f, "%%%02X", c);
@@ -366,7 +406,7 @@ linkysize(MMIOT *f, Footnote *ref)
 /* extract a <...>-encased url from the input stream.
 /* extract a <...>-encased url from the input stream.
  * (markdown 1.0.2b8 compatibility; older versions
  * (markdown 1.0.2b8 compatibility; older versions
  * of markdown treated the < and > as syntactic
  * 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
  * requires a closing >, and then falls into the
  * title or closing )
  * 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);
 	    puturl(link + tag->szpat, size - tag->szpat, f, 0);
     }
     }
     else
     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);
     Qstring(tag->link_sfx, f);
 
 
@@ -596,10 +636,10 @@ extra_linky(MMIOT *f, Cstring text, Footnote *ref)
 	return 0;
 	return 0;
 
 
     if ( f->flags & IS_LABEL )
     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 {
     else {
 	ref->flags |= REFERENCED;
 	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>",
 	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,
 		p_or_nothing(f), ref->refnumber, 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;
     linkytype *tag;
 
 
-    if ( image || (ref == 0) )
+
+    if ( image )
 	tag = &imaget;
 	tag = &imaget;
     else if ( tag = pseudo(ref->link) ) {
     else if ( tag = pseudo(ref->link) ) {
 	if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) )
 	if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) )
@@ -635,7 +676,7 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
 	return 0;
 	return 0;
 
 
     if ( f->flags & IS_LABEL )
     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 ) {
     else if ( tag->link_pfx ) {
 	printlinkyref(f, tag, T(ref->link), S(ref->link));
 	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) ) {
 	if ( S(ref->title) ) {
 	    Qstring(" title=\"", f);
 	    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);
 	    Qchar('"', f);
 	}
 	}
 
 
 	Qstring(tag->text_pfx, 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);
 	Qstring(tag->text_sfx, f);
     }
     }
     else
     else
@@ -711,8 +752,9 @@ linkylinky(int image, MMIOT *f)
 		    S(key.tag) = S(name);
 		    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 )
 		    if ( extra_footnote )
 			status = extra_linky(f,name,ref);
 			status = extra_linky(f,name,ref);
 		    else
 		    else
@@ -756,8 +798,12 @@ static void
 mangle(char *s, int len, MMIOT *f)
 mangle(char *s, int len, MMIOT *f)
 {
 {
     while ( len-- > 0 ) {
     while ( len-- > 0 ) {
+#if DEBIAN_GLITCH
+	Qprintf(f, "&#%02d;", *((unsigned char*)(s++)) );
+#else
 	Qstring("&#", f);
 	Qstring("&#", f);
 	Qprintf(f, COINTOSS() ? "x%02x;" : "%02d;", *((unsigned char*)(s++)) );
 	Qprintf(f, COINTOSS() ? "x%02x;" : "%02d;", *((unsigned char*)(s++)) );
+#endif
     }
     }
 }
 }
 
 
@@ -819,20 +865,21 @@ code(MMIOT *f, char *s, int length)
     int i,c;
     int i,c;
 
 
     for ( i=0; i < length; i++ )
     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);
 	    Qstring("  ", f);
+	else if ( c == '\\' && (i < length-1) && escaped(f, s[i+1]) )
+	    cputc(s[++i], f);
 	else
 	else
 	    cputc(c, f);
 	    cputc(c, f);
 } /* code */
 } /* code */
 
 
-
 /*  delspan() -- write out a chunk of text, blocking with <del>...</del>
 /*  delspan() -- write out a chunk of text, blocking with <del>...</del>
  */
  */
 static void
 static void
 delspan(MMIOT *f, int size)
 delspan(MMIOT *f, int size)
 {
 {
     Qstring("<del>", f);
     Qstring("<del>", f);
-    ___mkd_reparse(cursor(f)-1, size, 0, f);
+    ___mkd_reparse(cursor(f)-1, size, 0, f, 0);
     Qstring("</del>", f);
     Qstring("</del>", f);
 }
 }
 
 
@@ -974,11 +1021,9 @@ maybe_tag_or_link(MMIOT *f)
 	}
 	}
 	else if ( isspace(c) )
 	else if ( isspace(c) )
 	    break;
 	    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;
 	    maybetag=0;
     }
     }
 
 
@@ -1024,13 +1069,16 @@ maybe_autolink(MMIOT *f)
 
 
     /* greedily scan forward for the end of a legitimate link.
     /* 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 ( c == '\\' ) {
 	     if ( peek(f, size+2) != EOF )
 	     if ( peek(f, size+2) != EOF )
 		++size;
 		++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;
 	    break;
+    }
 
 
     if ( (size > 1) && process_possible_link(f, size) ) {
     if ( (size > 1) && process_possible_link(f, size) ) {
 	shift(f, size);
 	shift(f, size);
@@ -1069,7 +1117,7 @@ islike(MMIOT *f, char *s)
     int len;
     int len;
     int i;
     int i;
 
 
-    if ( s[0] == '<' ) {
+    if ( s[0] == '|' ) {
 	if ( !isthisnonword(f, -1) )
 	if ( !isthisnonword(f, -1) )
 	    return 0;
 	    return 0;
        ++s;
        ++s;
@@ -1078,7 +1126,7 @@ islike(MMIOT *f, char *s)
     if ( !(len = strlen(s)) )
     if ( !(len = strlen(s)) )
 	return 0;
 	return 0;
 
 
-    if ( s[len-1] == '>' ) {
+    if ( s[len-1] == '|' ) {
 	if ( !isthisnonword(f,len-1) )
 	if ( !isthisnonword(f,len-1) )
 	    return 0;
 	    return 0;
 	len--;
 	len--;
@@ -1097,13 +1145,13 @@ static struct smarties {
     char *entity;
     char *entity;
     int shift;
     int shift;
 } smarties[] = {
 } 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 },
     { '-',  "---",      "mdash",  2 },
     { '-',  "--",       "ndash",  1 },
     { '-',  "--",       "ndash",  1 },
     { '.',  "...",      "hellip", 2 },
     { '.',  "...",      "hellip", 2 },
@@ -1111,11 +1159,11 @@ static struct smarties {
     { '(',  "(c)",      "copy",   2 },
     { '(',  "(c)",      "copy",   2 },
     { '(',  "(r)",      "reg",    2 },
     { '(',  "(r)",      "reg",    2 },
     { '(',  "(tm)",     "trade",  3 },
     { '(',  "(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 },
     { '&',  "&#0;",      0,       3 },
 } ;
 } ;
 #define NRSMART ( sizeof smarties / sizeof smarties[0] )
 #define NRSMART ( sizeof smarties / sizeof smarties[0] )
@@ -1157,7 +1205,7 @@ smartypants(int c, int *flags, MMIOT *f)
 			    break;
 			    break;
 			else if ( c == '\'' && peek(f, j+1) == '\'' ) {
 			else if ( c == '\'' && peek(f, j+1) == '\'' ) {
 			    Qstring("&ldquo;", f);
 			    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);
 			    Qstring("&rdquo;", f);
 			    shift(f,j+1);
 			    shift(f,j+1);
 			    return 1;
 			    return 1;
@@ -1172,6 +1220,29 @@ smartypants(int c, int *flags, MMIOT *f)
 } /* smartypants */
 } /* 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
 /* 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
  * works, generate the output and return 1, otherwise just return 0 and
  * let the caller figure it out.
  * let the caller figure it out.
@@ -1223,7 +1294,8 @@ text(MMIOT *f)
 	switch (c) {
 	switch (c) {
 	case 0:     break;
 	case 0:     break;
 
 
-	case 3:     Qstring(tag_text(f) ? "  " : "<br/>", f);
+	case MKD_EOLN:
+		    Qstring(tag_text(f) ? "  " : "<br/>", f);
 		    break;
 		    break;
 
 
 	case '>':   if ( tag_text(f) )
 	case '>':   if ( tag_text(f) )
@@ -1246,6 +1318,7 @@ text(MMIOT *f)
 		    else
 		    else
 			Qchar(c, f);
 			Qchar(c, f);
 		    break;
 		    break;
+
 	case '[':   if ( tag_text(f) || !linkylinky(0, f) )
 	case '[':   if ( tag_text(f) || !linkylinky(0, f) )
 			Qchar(c, f);
 			Qchar(c, f);
 		    break;
 		    break;
@@ -1279,7 +1352,7 @@ text(MMIOT *f)
 			    shift(f,len);
 			    shift(f,len);
 			}
 			}
 			Qstring("<sup>",f);
 			Qstring("<sup>",f);
-			___mkd_reparse(sup, len, 0, f);
+			___mkd_reparse(sup, len, 0, f, "()");
 			Qstring("</sup>", f);
 			Qstring("</sup>", f);
 		    }
 		    }
 		    break;
 		    break;
@@ -1319,7 +1392,16 @@ text(MMIOT *f)
 	case '\\':  switch ( c = pull(f) ) {
 	case '\\':  switch ( c = pull(f) ) {
 		    case '&':   Qstring("&amp;", f);
 		    case '&':   Qstring("&amp;", f);
 				break;
 				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;
 				break;
 		    case '^':   if ( f->flags & (MKD_STRICT|MKD_NOSUPERSCRIPT) ) {
 		    case '^':   if ( f->flags & (MKD_STRICT|MKD_NOSUPERSCRIPT) ) {
 				    Qchar('\\', f);
 				    Qchar('\\', f);
@@ -1337,17 +1419,24 @@ text(MMIOT *f)
 				}
 				}
 				Qchar(c, f);
 				Qchar(c, f);
 				break;
 				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;
 				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;
 		    }
 		    }
 		    break;
 		    break;
@@ -1366,6 +1455,16 @@ text(MMIOT *f)
 			Qchar(c, f);
 			Qchar(c, f);
 		    break;
 		    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);
 	default:    Qchar(c, f);
 		    break;
 		    break;
 	}
 	}
@@ -1380,26 +1479,26 @@ text(MMIOT *f)
 static void
 static void
 printheader(Paragraph *pp, MMIOT *f)
 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);
     push(T(pp->text->text), S(pp->text->text), f);
     text(f);
     text(f);
     Qprintf(f, "</h%d>", pp->hnumber);
     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 };
 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;
 typedef STRING(int) Istring;
 
 
@@ -1440,7 +1540,7 @@ splat(Line *p, char *block, Istring align, int force, MMIOT *f)
 	Qprintf(f, "<%s%s>",
 	Qprintf(f, "<%s%s>",
 		   block,
 		   block,
 		   alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]);
 		   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);
 	Qprintf(f, "</%s>\n", block);
 	idx++;
 	idx++;
 	colno++;
 	colno++;
@@ -1546,13 +1646,14 @@ printblock(Paragraph *pp, MMIOT *f)
 			 && T(t->text)[S(t->text)-2] == ' '
 			 && T(t->text)[S(t->text)-2] == ' '
 			 && T(t->text)[S(t->text)-1] == ' ' ) {
 			 && T(t->text)[S(t->text)-1] == ' ' ) {
 		push(T(t->text), S(t->text)-2, f);
 		push(T(t->text), S(t->text)-2, f);
-		push("\003\n", 2, f);
+		pushc(MKD_EOLN, f);
+		pushc('\n', f);
 	    }
 	    }
 	    else {
 	    else {
 		___mkd_tidy(&t->text);
 		___mkd_tidy(&t->text);
 		push(T(t->text), S(t->text), f);
 		push(T(t->text), S(t->text), f);
 		if ( t->next )
 		if ( t->next )
-		    push("\n", 1, f);
+		    pushc('\n', f);
 	    }
 	    }
 	}
 	}
 	t = t->next;
 	t = t->next;
@@ -1565,11 +1666,17 @@ printblock(Paragraph *pp, MMIOT *f)
 
 
 
 
 static void
 static void
-printcode(Line *t, MMIOT *f)
+printcode(Line *t, char *lang, MMIOT *f)
 {
 {
     int blanks;
     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 ) {
     for ( blanks = 0; t ; t = t->next ) {
 	if ( S(t->text) > t->dle ) {
 	if ( S(t->text) > t->dle ) {
 	    while ( blanks ) {
 	    while ( blanks ) {
@@ -1633,7 +1740,7 @@ definitionlist(Paragraph *p, MMIOT *f)
 	for ( ; p ; p = p->next) {
 	for ( ; p ; p = p->next) {
 	    for ( tag = p->text; tag; tag = tag->next ) {
 	    for ( tag = p->text; tag; tag = tag->next ) {
 		Qstring("<dt>", f);
 		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);
 		Qstring("</dt>\n", f);
 	    }
 	    }
 
 
@@ -1682,7 +1789,7 @@ display(Paragraph *p, MMIOT *f)
 	break;
 	break;
 
 
     case CODE:
     case CODE:
-	printcode(p->text, f);
+	printcode(p->text, p->lang, f);
 	break;
 	break;
 
 
     case QUOTE:
     case QUOTE:
@@ -1731,14 +1838,14 @@ mkd_extra_footnotes(MMIOT *m)
     int j, i;
     int j, i;
     Footnote *t;
     Footnote *t;
 
 
-    if ( m->reference == 0 )
+    if ( m->footnotes->reference == 0 )
 	return;
 	return;
 
 
     Csprintf(&m->out, "\n<div class=\"footnotes\">\n<hr/>\n<ol>\n");
     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) ) {
 	    if ( (t->refnumber == i) && (t->flags & REFERENCED) ) {
 		Csprintf(&m->out, "<li id=\"%s:%d\">\n<p>",
 		Csprintf(&m->out, "<li id=\"%s:%d\">\n<p>",
 			    p_or_nothing(m), t->refnumber);
 			    p_or_nothing(m), t->refnumber);
@@ -1767,15 +1874,20 @@ mkd_document(Document *p, char **res)
 	    if ( p->ctx->flags & MKD_EXTRA_FOOTNOTE )
 	    if ( p->ctx->flags & MKD_EXTRA_FOOTNOTE )
 		mkd_extra_footnotes(p->ctx);
 		mkd_extra_footnotes(p->ctx);
 	    p->html = 1;
 	    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);
 	*res = T(p->ctx->out);
-	return size;
+	return S(p->ctx->out);
     }
     }
     return EOF;
     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">
 		<Unit filename="generate.c">
 			<Option compilerVar="CC" />
 			<Option compilerVar="CC" />
 		</Unit>
 		</Unit>
+		<Unit filename="github_flavoured.c">
+			<Option compilerVar="CC" />
+		</Unit>
 		<Unit filename="html5.c">
 		<Unit filename="html5.c">
 			<Option compilerVar="CC" />
 			<Option compilerVar="CC" />
 		</Unit>
 		</Unit>

+ 4 - 4
discount/librarian.sh

@@ -7,13 +7,13 @@ LIBRARY=$1; shift
 VERSION=$1; shift
 VERSION=$1; shift
 
 
 case "$ACTION" in
 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
 	rm -f $LIBRARY
-	/bin/ln $LIBRARY.a $LIBRARY
+	/bin/ln -s $LIBRARY.a $LIBRARY
 	;;
 	;;
 files)  echo "${LIBRARY}.a"
 files)  echo "${LIBRARY}.a"
 	;;
 	;;
-install)/bin/install -m 644 ${LIBRARY}.a $1
+install)/usr/bin/install -m 644 ${LIBRARY}.a $1
 	;;
 	;;
 esac
 esac

+ 25 - 7
discount/main.c

@@ -18,6 +18,7 @@
 #include "config.h"
 #include "config.h"
 #include "amalloc.h"
 #include "amalloc.h"
 #include "pgm_options.h"
 #include "pgm_options.h"
+#include "tags.h"
 
 
 #if HAVE_LIBGEN_H
 #if HAVE_LIBGEN_H
 #include <libgen.h>
 #include <libgen.h>
@@ -75,9 +76,12 @@ main(int argc, char **argv)
     mkd_flag_t flags = 0;
     mkd_flag_t flags = 0;
     int debug = 0;
     int debug = 0;
     int toc = 0;
     int toc = 0;
+    int content = 1;
     int version = 0;
     int version = 0;
     int with_html5 = 0;
     int with_html5 = 0;
+    int styles = 0;
     int use_mkd_line = 0;
     int use_mkd_line = 0;
+    int github_flavoured = 0;
     char *extra_footnote_prefix = 0;
     char *extra_footnote_prefix = 0;
     char *urlflags = 0;
     char *urlflags = 0;
     char *text = 0;
     char *text = 0;
@@ -92,7 +96,7 @@ main(int argc, char **argv)
     pgm = basename(argv[0]);
     pgm = basename(argv[0]);
     opterr = 1;
     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) {
 	switch (opt) {
 	case '5':   with_html5 = 1;
 	case '5':   with_html5 = 1;
 		    break;
 		    break;
@@ -118,13 +122,19 @@ main(int argc, char **argv)
 		    else if ( !set_flag(&flags, optarg) )
 		    else if ( !set_flag(&flags, optarg) )
 			complain("unknown option <%s>", optarg);
 			complain("unknown option <%s>", optarg);
 		    break;
 		    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;
 	case 't':   text = optarg;
 		    use_mkd_line = 1;
 		    use_mkd_line = 1;
 		    break;
 		    break;
 	case 'T':   toc = 1;
 	case 'T':   toc = 1;
 		    break;
 		    break;
-	case 's':   text = optarg;
-		    break;
 	case 'C':   extra_footnote_prefix = optarg;
 	case 'C':   extra_footnote_prefix = optarg;
 		    break;
 		    break;
 	case 'o':   if ( ofile ) {
 	case 'o':   if ( ofile ) {
@@ -165,7 +175,10 @@ main(int argc, char **argv)
 	rc = mkd_generateline( text, strlen(text), stdout, flags);
 	rc = mkd_generateline( text, strlen(text), stdout, flags);
     else {
     else {
 	if ( text ) {
 	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);
 		perror(text);
 		exit(1);
 		exit(1);
 	    }
 	    }
@@ -175,7 +188,9 @@ main(int argc, char **argv)
 		perror(argv[0]);
 		perror(argv[0]);
 		exit(1);
 		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");
 		perror(argc ? argv[0] : "stdin");
 		exit(1);
 		exit(1);
 	    }
 	    }
@@ -195,12 +210,15 @@ main(int argc, char **argv)
 	    rc = 1;
 	    rc = 1;
 	    if ( mkd_compile(doc, flags) ) {
 	    if ( mkd_compile(doc, flags) ) {
 		rc = 0;
 		rc = 0;
+		if ( styles )
+		    mkd_generatecss(doc, stdout);
 		if ( toc )
 		if ( toc )
 		    mkd_generatetoc(doc, stdout);
 		    mkd_generatetoc(doc, stdout);
-		mkd_generatehtml(doc, stdout);
-		mkd_cleanup(doc);
+		if ( content )
+		    mkd_generatehtml(doc, stdout);
 	    }
 	    }
 	}
 	}
+	mkd_cleanup(doc);
     }
     }
     mkd_deallocate_tags();
     mkd_deallocate_tags();
     adump();
     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 .
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .Sh AUTHOR
 .An David Parsons
 .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;
     char *q;
     int version = 0;
     int version = 0;
     int opt;
     int opt;
+    int ret;
     mkd_flag_t flags = 0;
     mkd_flag_t flags = 0;
 
 
     if ( (q = getenv("MARKDOWN_FLAGS")) )
     if ( (q = getenv("MARKDOWN_FLAGS")) )
@@ -82,5 +83,9 @@ char **argv;
 	exit(1);
 	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 C Ar prefix
 .Op Fl F Pa bitmap
 .Op Fl F Pa bitmap
 .Op Fl f Ar flags
 .Op Fl f Ar flags
+.Op Fl n
 .Op Fl o Pa file
 .Op Fl o Pa file
+.Op Fl S
 .Op Fl s Pa text
 .Op Fl s Pa text
 .Op Fl t Pa text
 .Op Fl t Pa text
 .Op Pa textfile
 .Op Pa textfile
@@ -104,9 +106,27 @@ blocks.
 .It Ar alphalist
 .It Ar alphalist
 Allow alphabetic lists.
 Allow alphabetic lists.
 .It Ar definitionlist
 .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
 .It Ar footnote
 Allow markdown extra-style footnotes.
 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
 .El
 .Pp
 .Pp
 As an example, the option
 As an example, the option
@@ -123,6 +143,13 @@ described in
 .Xr markdown 3 
 .Xr markdown 3 
 (the flag values are defined in
 (the flag values are defined in
 .Pa mkdio.h )
 .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
 .It Fl V
 Show the version# and compile-time configuration data.
 Show the version# and compile-time configuration data.
 .Pp
 .Pp
@@ -138,9 +165,6 @@ was configured to use the specified tabstop.
 .It Fl VV
 .It Fl VV
 Show the version#, the compile-time configuration, and the
 Show the version#, the compile-time configuration, and the
 run-time configuration.
 run-time configuration.
-.It Fl o Pa file
-Write the generated html to 
-.Pa file .
 .It Fl t Ar text
 .It Fl t Ar text
 Use
 Use
 .Xr mkd_text 3
 .Xr mkd_text 3
@@ -168,4 +192,4 @@ utility exits 0 on success, and >0 if an error occurs.
 .Xr mkd-extensions 7 .
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .Sh AUTHOR
 .An David Parsons
 .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.
 Forbid alphabetic lists.
 .It Ar MKD_NODLIST
 .It Ar MKD_NODLIST
 Forbid definition lists.
 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
 .It Ar MKD_EXTRA_FOOTNOTE
 Enable markdown extra-style footnotes.
 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
 .El
 .Sh RETURN VALUES
 .Sh RETURN VALUES
 .Fn markdown
 .Fn markdown

+ 137 - 78
discount/markdown.c

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

+ 59 - 11
discount/markdown.h

@@ -19,10 +19,14 @@ typedef struct footnote {
 } Footnote;
 } Footnote;
 
 
 /* each input line is read into a Line, which contains the line,
 /* 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
  * that all tabs will be expanded to spaces!], and a pointer to
  * the next line.
  * the next line.
  */
  */
+typedef enum { chk_text, chk_code,
+	       chk_hr, chk_dash,
+	       chk_tilde, chk_backtick,
+	       chk_equal } line_type;
 typedef struct line {
 typedef struct line {
     Cstring text;
     Cstring text;
     struct line *next;
     struct line *next;
@@ -31,9 +35,7 @@ typedef struct line {
 #define PIPECHAR	0x01		/* line contains a | */
 #define PIPECHAR	0x01		/* line contains a | */
 #define CHECKED		0x02
 #define CHECKED		0x02
 
 
-    enum { chk_text, chk_code,
-	   chk_hr, chk_dash,
-	   chk_tilde, chk_equal } kind;
+    line_type kind;
     int count;
     int count;
 } Line;
 } Line;
 
 
@@ -47,6 +49,7 @@ typedef struct paragraph {
     struct paragraph *down;	/* recompiled contents of this paragraph */
     struct paragraph *down;	/* recompiled contents of this paragraph */
     struct line *text;		/* all the text in this paragraph */
     struct line *text;		/* all the text in this paragraph */
     char *ident;		/* %id% tag for QUOTE */
     char *ident;		/* %id% tag for QUOTE */
+    char *lang;         /* lang attribute for CODE */
     enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
     enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
 	   HTML, STYLE, DL, UL, OL, AL, LISTITEM,
 	   HTML, STYLE, DL, UL, OL, AL, LISTITEM,
 	   HDR, HR, TABLE, SOURCE } typ;
 	   HDR, HR, TABLE, SOURCE } typ;
@@ -79,6 +82,18 @@ typedef struct callback_data {
 } 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
 /* a magic markdown io thing holds all the data structures needed to
  * do the backend processing of a markdown document
  * do the backend processing of a markdown document
  */
  */
@@ -87,9 +102,9 @@ typedef struct mmiot {
     Cstring in;
     Cstring in;
     Qblock Q;
     Qblock Q;
     int isp;
     int isp;
-    int reference;
+    struct escaped *esc;
     char *ref_prefix;
     char *ref_prefix;
-    STRING(Footnote) *footnotes;
+    struct footnote_list *footnotes;
     DWORD flags;
     DWORD flags;
 #define MKD_NOLINKS	0x00000001
 #define MKD_NOLINKS	0x00000001
 #define MKD_NOIMAGE	0x00000002
 #define MKD_NOIMAGE	0x00000002
@@ -113,14 +128,24 @@ typedef struct mmiot {
 #define MKD_NOALPHALIST	0x00080000
 #define MKD_NOALPHALIST	0x00080000
 #define MKD_NODLIST	0x00100000
 #define MKD_NODLIST	0x00100000
 #define MKD_EXTRA_FOOTNOTE 0x00200000
 #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)
 #define INPUT_MASK	(MKD_NOHEADER|MKD_TABSTOP)
 
 
     Callback_data *cb;
     Callback_data *cb;
 } MMIOT;
 } MMIOT;
 
 
 
 
+#define MKD_EOLN	3
+
+
 /*
 /*
  * the mkdio text input functions return a document structure,
  * the mkdio text input functions return a document structure,
  * which contains a header (retrieved from the document if
  * which contains a header (retrieved from the document if
@@ -145,6 +170,16 @@ typedef struct document {
 } 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_firstnonblank(Line *);
 extern int  mkd_compile(Document *, DWORD);
 extern int  mkd_compile(Document *, DWORD);
 extern int  mkd_document(Document *, char **);
 extern int  mkd_document(Document *, char **);
@@ -161,11 +196,14 @@ extern int  mkd_generateline(char *, int, FILE*, DWORD);
 extern void mkd_basename(Document*, char *);
 extern void mkd_basename(Document*, char *);
 
 
 typedef int (*mkd_sta_function_t)(const int,const void*);
 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_in(FILE *, DWORD);
 extern Document *mkd_string(const char*,int, 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_initialize();
 extern void mkd_shlib_destructor();
 extern void mkd_shlib_destructor();
 
 
@@ -182,12 +220,22 @@ extern void ___mkd_initmmiot(MMIOT *, void *);
 extern void ___mkd_freemmiot(MMIOT *, void *);
 extern void ___mkd_freemmiot(MMIOT *, void *);
 extern void ___mkd_freeLineRange(Line *, Line *);
 extern void ___mkd_freeLineRange(Line *, Line *);
 extern void ___mkd_xml(char *, int, FILE *);
 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_emblock(MMIOT*);
 extern void ___mkd_tidy(Cstring *);
 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 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);
 extern int markdown_str(Document *document, void *out,void (*)(char const *,int size,void*), int flags);
 
 
-
 #endif/*_MARKDOWN_D*/
 #endif/*_MARKDOWN_D*/

+ 2 - 3
discount/markdowncpp.cbp

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

+ 0 - 8
discount/mkd-extensions.7

@@ -111,14 +111,6 @@ at the beginning of a subsequent line.
 .Pp
 .Pp
 Be warned that style blocks work like footnote links -- no matter
 Be warned that style blocks work like footnote links -- no matter
 where you define them they are valid for the entire document.
 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
 .Ss alpha lists
 Alphabetic lists (like regular numeric lists, but with alphabetic
 Alphabetic lists (like regular numeric lists, but with alphabetic
 items) are supported.    So:
 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 .
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .Sh AUTHOR
 .An David Parsons
 .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;
     char *p;
 
 
-    if (( p = strrchr(path, '/') ))
+    if ( p = strrchr(path, '/') )
 	return 1+p;
 	return 1+p;
     return path;
     return path;
 }
 }
@@ -82,7 +82,7 @@ char **argv;
     CREATE(footers);
     CREATE(footers);
     pgm = basename(argv[0]);
     pgm = basename(argv[0]);
 
 
-    while ( argc > 2 ) {
+    while ( argc > 1 ) {
 	if ( strcmp(argv[1], "-css") == 0 ) {
 	if ( strcmp(argv[1], "-css") == 0 ) {
 	    EXPAND(css) = argv[2];
 	    EXPAND(css) = argv[2];
 	    argc -= 2;
 	    argc -= 2;
@@ -98,14 +98,20 @@ char **argv;
 	    argc -= 2;
 	    argc -= 2;
 	    argv += 2;
 	    argv += 2;
 	}
 	}
+	else
+	    break;
     }
     }
 
 
-
-    if ( argc > 1 ) {
+    switch ( argc ) {
 	char *p, *dot;
 	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);
 	source = malloc(strlen(argv[1]) + 6);
-	dest   = malloc(strlen(argv[1]) + 6);
 
 
 	if ( !(source && dest) )
 	if ( !(source && dest) )
 	    fail("out of memory allocating name buffers");
 	    fail("out of memory allocating name buffers");
@@ -129,10 +135,11 @@ char **argv;
 
 
 	if ( (output = fopen(dest, "w")) == 0 )
 	if ( (output = fopen(dest, "w")) == 0 )
 	    fail("can't write to %s", dest);
 	    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 )
     if ( (mmiot = mkd_in(input, 0)) == 0 )
@@ -153,7 +160,7 @@ char **argv;
 	"  <meta name=\"GENERATOR\" content=\"mkd2html %s\">\n", markdown_version);
 	"  <meta name=\"GENERATOR\" content=\"mkd2html %s\">\n", markdown_version);
 
 
     fprintf(output,"  <meta http-equiv=\"Content-Type\"\n"
     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++ )
     for ( i=0; i < S(css); i++ )
 	fprintf(output, "  <link rel=\"stylesheet\"\n"
 	fprintf(output, "  <link rel=\"stylesheet\"\n"

+ 41 - 38
discount/mkdio.c

@@ -16,15 +16,16 @@
 
 
 typedef ANCHOR(Line) LineAnchor;
 typedef ANCHOR(Line) LineAnchor;
 
 
+
 /* create a new blank Document
 /* create a new blank Document
  */
  */
-static Document*
-new_Document()
+Document*
+__mkd_new_Document()
 {
 {
     Document *ret = calloc(sizeof(Document), 1);
     Document *ret = calloc(sizeof(Document), 1);
 
 
     if ( ret ) {
     if ( ret ) {
-	if (( ret->ctx = calloc(sizeof(MMIOT), 1) )) {
+	if ( ret->ctx = calloc(sizeof(MMIOT), 1) ) {
 	    ret->magic = VALID_DOCUMENT;
 	    ret->magic = VALID_DOCUMENT;
 	    return ret;
 	    return ret;
 	}
 	}
@@ -37,8 +38,8 @@ new_Document()
 /* add a line to the markdown input chain, expanding tabs and
 /* add a line to the markdown input chain, expanding tabs and
  * noting the presence of special characters as we go.
  * 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);
     Line *p = calloc(sizeof *p, 1);
     unsigned char c;
     unsigned char c;
@@ -75,8 +76,8 @@ queue(Document* a, Cstring *line)
 
 
 /* trim leading blanks from a header 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);
     CLIP(p->text, 0, 1);
     p->dle = mkd_firstnonblank(p);
     p->dle = mkd_firstnonblank(p);
@@ -91,7 +92,7 @@ Document *
 populate(getc_func getc, void* ctx, int flags)
 populate(getc_func getc, void* ctx, int flags)
 {
 {
     Cstring line;
     Cstring line;
-    Document *a = new_Document();
+    Document *a = __mkd_new_Document();
     int c;
     int c;
     int pandoc = 0;
     int pandoc = 0;
 
 
@@ -109,7 +110,7 @@ populate(getc_func getc, void* ctx, int flags)
 		else
 		else
 		    pandoc = EOF;
 		    pandoc = EOF;
 	    }
 	    }
-	    queue(a, &line);
+	    __mkd_enqueue(a, &line);
 	    S(line) = 0;
 	    S(line) = 0;
 	}
 	}
 	else if ( isprint(c) || isspace(c) || (c & 0x80) )
 	else if ( isprint(c) || isspace(c) || (c & 0x80) )
@@ -117,7 +118,7 @@ populate(getc_func getc, void* ctx, int flags)
     }
     }
 
 
     if ( S(line) )
     if ( S(line) )
-	queue(a, &line);
+	__mkd_enqueue(a, &line);
 
 
     DELETE(line);
     DELETE(line);
 
 
@@ -128,9 +129,9 @@ populate(getc_func getc, void* ctx, int flags)
 	 */
 	 */
 	Line *headers = T(a->content);
 	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;
 	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
 /* 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;
     if ( !in->size ) return EOF;
 
 
@@ -172,12 +167,12 @@ strget(struct string_ctx *in)
 Document *
 Document *
 mkd_string(const char *buf, int len, DWORD flags)
 mkd_string(const char *buf, int len, DWORD flags)
 {
 {
-    struct string_ctx about;
+    struct string_stream about;
 
 
     about.data = buf;
     about.data = buf;
     about.size = len;
     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;
     char *doc;
     int szdoc;
     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
 void
 mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
 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;
     unsigned char c;
 
 
     int i, size;
     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);
     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);
 	(*outchar)('L',out);
     for ( i=0; i < size ; i++ ) {
     for ( i=0; i < size ; i++ ) {
 	c = line[i];
 	c = line[i];
 	if ( labelformat ) {
 	if ( labelformat ) {
 	    if ( isalnum(c) || (c == '_') || (c == ':') || (c == '-') || (c == '.' ) )
 	    if ( isalnum(c) || (c == '_') || (c == ':') || (c == '-') || (c == '.' ) )
 		(*outchar)(c, out);
 		(*outchar)(c, out);
+	    else if ( flags & MKD_URLENCODEDANCHOR ) {
+		(*outchar)('%', out);
+		(*outchar)(hexchars[c >> 4 & 0xf], out);
+		(*outchar)(hexchars[c      & 0xf], out);
+	    }
 	    else
 	    else
 		(*outchar)('.', out);
 		(*outchar)('.', out);
 	}
 	}
@@ -254,7 +256,7 @@ mkd_parse_line(char *bfr, int size, MMIOT *f, int flags)
 {
 {
     ___mkd_initmmiot(f, 0);
     ___mkd_initmmiot(f, 0);
     f->flags = flags & USER_FLAGS;
     f->flags = flags & USER_FLAGS;
-    ___mkd_reparse(bfr, size, 0, f);
+    ___mkd_reparse(bfr, size, 0, f, 0);
     ___mkd_emblock(f);
     ___mkd_emblock(f);
 }
 }
 
 
@@ -295,15 +297,16 @@ int
 mkd_generateline(char *bfr, int size, FILE *output, DWORD flags)
 mkd_generateline(char *bfr, int size, FILE *output, DWORD flags)
 {
 {
     MMIOT f;
     MMIOT f;
+    int status;
 
 
     mkd_parse_line(bfr, size, &f, flags);
     mkd_parse_line(bfr, size, &f, flags);
     if ( flags & MKD_CDATA )
     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
     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);
     ___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_in(FILE*,mkd_flag_t);		/* assemble input from a file */
 MMIOT *mkd_string(const char*,int,mkd_flag_t);	/* assemble input from a buffer */
 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_basename(MMIOT*,char*);
 
 
 void mkd_initialize();
 void mkd_initialize();
@@ -21,7 +26,7 @@ void mkd_shlib_destructor();
 /* compilation, debugging, cleanup
 /* compilation, debugging, cleanup
  */
  */
 int mkd_compile(MMIOT*, mkd_flag_t);
 int mkd_compile(MMIOT*, mkd_flag_t);
-int mkd_cleanup(MMIOT*);
+void mkd_cleanup(MMIOT*);
 
 
 /* markup functions
 /* markup functions
  */
  */
@@ -102,6 +107,14 @@ void mkd_ref_prefix(MMIOT*, char*);
 #define MKD_NOALPHALIST	0x00080000	/* forbid alphabetic lists */
 #define MKD_NOALPHALIST	0x00080000	/* forbid alphabetic lists */
 #define MKD_NODLIST	0x00100000	/* forbid definition lists */
 #define MKD_NODLIST	0x00100000	/* forbid definition lists */
 #define MKD_EXTRA_FOOTNOTE 0x00200000	/* enable markdown extra-style footnotes */
 #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
 #define MKD_EMBED	MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
 
 
 /* special flags for mkd_in() and mkd_string()
 /* 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_in(FILE*,mkd_flag_t);		/* assemble input from a file */
 MMIOT *mkd_string(const char*,int,mkd_flag_t);	/* assemble input from a buffer */
 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_basename(MMIOT*,char*);
 
 
 void mkd_initialize();
 void mkd_initialize();
@@ -21,7 +26,7 @@ void mkd_shlib_destructor();
 /* compilation, debugging, cleanup
 /* compilation, debugging, cleanup
  */
  */
 int mkd_compile(MMIOT*, mkd_flag_t);
 int mkd_compile(MMIOT*, mkd_flag_t);
-int mkd_cleanup(MMIOT*);
+void mkd_cleanup(MMIOT*);
 
 
 /* markup functions
 /* markup functions
  */
  */
@@ -102,6 +107,14 @@ void mkd_ref_prefix(MMIOT*, char*);
 #define MKD_NOALPHALIST	0x00080000	/* forbid alphabetic lists */
 #define MKD_NOALPHALIST	0x00080000	/* forbid alphabetic lists */
 #define MKD_NODLIST	0x00100000	/* forbid definition lists */
 #define MKD_NODLIST	0x00100000	/* forbid definition lists */
 #define MKD_EXTRA_FOOTNOTE 0x00200000	/* enable markdown extra-style footnotes */
 #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
 #define MKD_EMBED	MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
 
 
 /* special flags for mkd_in() and mkd_string()
 /* special flags for mkd_in() and mkd_string()

+ 12 - 3
discount/pgm_options.c

@@ -25,7 +25,7 @@ static struct _opt {
     char *name;
     char *name;
     char *desc;
     char *desc;
     int off;
     int off;
-    int skip;
+    int skip; /* this opt is a synonym */
     int sayenable;
     int sayenable;
     mkd_flag_t flag;
     mkd_flag_t flag;
 } opts[] = {
 } opts[] = {
@@ -54,11 +54,20 @@ static struct _opt {
     { "1.0",           "markdown 1.0 compatibility", 0, 0, 1, MKD_1_COMPAT },
     { "1.0",           "markdown 1.0 compatibility", 0, 0, 1, MKD_1_COMPAT },
     { "footnotes",     "markdown extra footnotes",   0, 0, 1, MKD_EXTRA_FOOTNOTE },
     { "footnotes",     "markdown extra footnotes",   0, 0, 1, MKD_EXTRA_FOOTNOTE },
     { "footnote",      "markdown extra footnotes",   0, 1, 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])
 #define NR(x)	(sizeof x / sizeof x[0])
 
 
 
 
+typedef int (*stfu)(const void *, const void *);
+
 int
 int
 sort_by_name(struct _opt *a, struct _opt *b)
 sort_by_name(struct _opt *a, struct _opt *b)
 {
 {
@@ -78,14 +87,14 @@ show_flags(int byname)
     int i;
     int i;
 
 
     if ( byname ) {
     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++)
 	for (i=0; i < NR(opts); i++)
 	    if ( ! opts[i].skip )
 	    if ( ! opts[i].skip )
 		fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc);
 		fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc);
     }
     }
     else {
     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++)
 	for (i=0; i < NR(opts); i++)
 	    if ( ! opts[i].skip ) {
 	    if ( ! opts[i].skip ) {

+ 6 - 4
discount/resource.c

@@ -51,6 +51,8 @@ ___mkd_freeParagraph(Paragraph *p)
 	___mkd_freeLines(p->text);
 	___mkd_freeLines(p->text);
     if (p->ident)
     if (p->ident)
 	free(p->ident);
 	free(p->ident);
+    if (p->lang)
+	free(p->lang);
     free(p);
     free(p);
 }
 }
 
 
@@ -74,9 +76,9 @@ ___mkd_freefootnotes(MMIOT *f)
     int i;
     int i;
 
 
     if ( f->footnotes ) {
     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);
 	free(f->footnotes);
     }
     }
 }
 }
@@ -96,7 +98,7 @@ ___mkd_initmmiot(MMIOT *f, void *footnotes)
 	    f->footnotes = footnotes;
 	    f->footnotes = footnotes;
 	else {
 	else {
 	    f->footnotes = malloc(sizeof f->footnotes[0]);
 	    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.
      * either the standard or extra tag tables.
      */
      */
     if ( !(p = mkd_search_tags(id, strlen(id))) ) {
     if ( !(p = mkd_search_tags(id, strlen(id))) ) {
+	/* extratags could be deallocated */
+	if ( S(extratags) == 0 )
+	    CREATE(extratags);
 	p = &EXPAND(extratags);
 	p = &EXPAND(extratags);
 	p->id = id;
 	p->id = id;
 	p->size = strlen(id);
 	p->size = strlen(id);

+ 3 - 1
discount/theme.1

@@ -8,6 +8,8 @@
 .Nd create a web page from a template file
 .Nd create a web page from a template file
 .Sh SYNOPSIS
 .Sh SYNOPSIS
 .Nm
 .Nm
+.Op Fl C Pa option-flags
+.Op Fl c Pa options
 .Op Fl d Pa root
 .Op Fl d Pa root
 .Op Fl E
 .Op Fl E
 .Op Fl f
 .Op Fl f
@@ -155,4 +157,4 @@ utility exits 0 on success, and >0 if an error occurs.
 .Xr mkd-extensions 7 .
 .Xr mkd-extensions 7 .
 .Sh AUTHOR
 .Sh AUTHOR
 .An David Parsons
 .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.
  * be distributed with this source code.
  */
  */
 #include "config.h"
 #include "config.h"
+#include "pgm_options.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -17,6 +18,9 @@
 #if defined(HAVE_BASENAME) && defined(HAVE_LIBGEN_H)
 #if defined(HAVE_BASENAME) && defined(HAVE_LIBGEN_H)
 #  include <libgen.h>
 #  include <libgen.h>
 #endif
 #endif
+#if defined(HAVE_ALLOCA_H)
+#  include <alloca.h>
+#endif
 #include <unistd.h>
 #include <unistd.h>
 #include <stdarg.h>
 #include <stdarg.h>
 #include <sys/types.h>
 #include <sys/types.h>
@@ -56,7 +60,7 @@ basename(char *path)
 {
 {
     char *p;
     char *p;
 
 
-    if (( p = strrchr(path, '/') ))
+    if ( p = strrchr(path, '/') )
 	return 1+p;
 	return 1+p;
     return path;
     return path;
 }
 }
@@ -507,6 +511,7 @@ char **argv;
     char *source = "stdin";
     char *source = "stdin";
     FILE *tmplfile;
     FILE *tmplfile;
     int opt;
     int opt;
+    mkd_flag_t flags = THEME_CF|MKD_TOC;
     int force = 0;
     int force = 0;
     MMIOT *doc;
     MMIOT *doc;
     struct stat sourceinfo;
     struct stat sourceinfo;
@@ -514,7 +519,7 @@ char **argv;
     opterr=1;
     opterr=1;
     pgm = basename(argv[0]);
     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) {
 	switch (opt) {
 	case 'd':   root = optarg;
 	case 'd':   root = optarg;
 		    break;
 		    break;
@@ -526,6 +531,20 @@ char **argv;
 		    break;
 		    break;
 	case 't':   template = optarg;
 	case 't':   template = optarg;
 		    break;
 		    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;
 	case 'o':   output = optarg;
 		    break;
 		    break;
 	case 'V':   printf("theme+discount %s\n", markdown_version);
 	case 'V':   printf("theme+discount %s\n", markdown_version);
@@ -577,7 +596,7 @@ char **argv;
 	    strcat(q, ".html");
 	    strcat(q, ".html");
 	}
 	}
     }
     }
-    if ( output ) {
+    if ( output && strcmp(output, "-") ) {
 	if ( force )
 	if ( force )
 	    unlink(output);
 	    unlink(output);
 	if ( !freopen(output, "w", stdout) )
 	if ( !freopen(output, "w", stdout) )
@@ -600,7 +619,7 @@ char **argv;
 	fail("out of memory");
 	fail("out of memory");
 #endif
 #endif
 
 
-    if ( !mkd_compile(doc, MKD_TOC) )
+    if ( !mkd_compile(doc, flags) )
 	fail("couldn't compile input");
 	fail("couldn't compile input");
 
 
     if ( tmplfile )
     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, "");
 		    Csprintf(&res, "%*s<li><a href=\"#", srcp->hnumber, "");
 		    mkd_string_to_anchor(T(srcp->text->text),
 		    mkd_string_to_anchor(T(srcp->text->text),
 					 S(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, "\">");
 		    Csprintf(&res, "\">");
 		    mkd_string_to_anchor(T(srcp->text->text),
 		    mkd_string_to_anchor(T(srcp->text->text),
 					 S(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>");
 		    Csprintf(&res, "</a>");
 
 
 		    first = 0;
 		    first = 0;

+ 4 - 19
discount/version.c

@@ -1,7 +1,9 @@
 #include "config.h"
 #include "config.h"
+
 #ifndef VERSION
 #ifndef VERSION
 #define VERSION "0.0"
 #define VERSION "0.0"
 #endif
 #endif
+
 char markdown_version[] = VERSION
 char markdown_version[] = VERSION
 #if 4 != 4
 #if 4 != 4
 		" TAB=4"
 		" TAB=4"
@@ -9,24 +11,7 @@ char markdown_version[] = VERSION
 #if USE_AMALLOC
 #if USE_AMALLOC
 		" DEBUG"
 		" DEBUG"
 #endif
 #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
 #endif
 		;
 		;

+ 2 - 19
discount/version.c.in

@@ -11,24 +11,7 @@ char markdown_version[] = VERSION
 #if USE_AMALLOC
 #if USE_AMALLOC
 		" DEBUG"
 		" DEBUG"
 #endif
 #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
 #endif
 		;
 		;

+ 2 - 2
discount/xml.c

@@ -47,9 +47,9 @@ mkd_generatexml(char *p, int size, FILE *out)
 	c = *p++;
 	c = *p++;
 
 
 	if ( entity = mkd_xmlchar(c) )
 	if ( entity = mkd_xmlchar(c) )
-	    fputs(entity, out);
+	    DO_OR_DIE( fputs(entity, out) );
 	else
 	else
-	    fputc(c, out);
+	    DO_OR_DIE( fputc(c, out) );
     }
     }
     return 0;
     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 *);
     extern char *mkd_doc_title(Document *);
     
     
     if ( mkd_compile(p, flags) ) {
     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 0;
     }
     }
-    return -1;
+    return EOF;
 }
 }