Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit 5a6e4055bdffb977c079dee628f3e7372c785ad4 0 parents
@eduardonunesp authored
Showing with 4,493 additions and 0 deletions.
  1. +3 −0  Anomade.pro
  2. +159 −0 Makefile
  3. 0  README
  4. +231 −0 libs/Makefile.MarkdownLib
  5. +20 −0 libs/MarkdownLib.pro
  6. +29 −0 libs/amalloc.h
  7. +29 −0 libs/config.h
  8. +68 −0 libs/cstring.h
  9. +43 −0 libs/docheader.c
  10. +147 −0 libs/dumptree.c
  11. +1,283 −0 libs/generate.c
  12. +866 −0 libs/markdown.c
  13. +136 −0 libs/markdown.h
  14. +34 −0 libs/markdowncxx.cpp
  15. +7 −0 libs/markdowncxx.h
  16. +256 −0 libs/mkdio.c
  17. +167 −0 libs/resource.c
  18. +16 −0 libs/version.c
  19. BIN  src/.obj/docheader.o
  20. BIN  src/.obj/dumptree.o
  21. BIN  src/.obj/generate.o
  22. BIN  src/.obj/markdown.o
  23. BIN  src/.obj/markdowncxx.o
  24. BIN  src/.obj/mkdio.o
  25. BIN  src/.obj/qrc_Anomade.o
  26. BIN  src/.obj/resource.o
  27. BIN  src/.obj/version.o
  28. +22 −0 src/AnomadeApp.pro
  29. +5 −0 src/AnomadeApp.qrc
  30. +70 −0 src/Highlighter.cpp
  31. +39 −0 src/Highlighter.hpp
  32. +412 −0 src/MainWindow.cpp
  33. +71 −0 src/MainWindow.hpp
  34. +248 −0 src/Makefile.AnomadeApp
  35. +13 −0 src/main.cpp
  36. +119 −0 src/resources/my.css
3  Anomade.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS = libs/MarkdownLib.pro src/AnomadeApp.pro
+src.depends = libs
159 Makefile
@@ -0,0 +1,159 @@
+#############################################################################
+# Makefile for building: Anomade
+# Generated by qmake (2.01a) (Qt 4.7.4) on: Thu Dec 22 17:16:29 2011
+# Project: Anomade.pro
+# Template: subdirs
+# Command: /Volumes/TheBox/QtSDK/Desktop/Qt/474/gcc/bin/qmake -spec ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o Makefile Anomade.pro
+#############################################################################
+
+first: make_default
+MAKEFILE = Makefile
+QMAKE = /Volumes/TheBox/QtSDK/Desktop/Qt/474/gcc/bin/qmake
+DEL_FILE = rm -f
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir -p
+COPY = cp -f
+COPY_FILE = cp -f
+COPY_DIR = cp -f -R
+INSTALL_FILE = $(COPY_FILE)
+INSTALL_PROGRAM = $(COPY_FILE)
+INSTALL_DIR = $(COPY_DIR)
+DEL_FILE = rm -f
+SYMLINK = ln -f -s
+DEL_DIR = rmdir
+MOVE = mv -f
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir -p
+SUBTARGETS = \
+ sub-libs-MarkdownLib-pro \
+ sub-src-AnomadeApp-pro
+
+libs/$(MAKEFILE).MarkdownLib:
+ @$(CHK_DIR_EXISTS) libs/ || $(MKDIR) libs/
+ cd libs/ && $(QMAKE) /Volumes/TheBox/Repos/anomade/libs/MarkdownLib.pro -spec ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o $(MAKEFILE).MarkdownLib
+sub-libs-MarkdownLib-pro-qmake_all: FORCE
+ @$(CHK_DIR_EXISTS) libs/ || $(MKDIR) libs/
+ cd libs/ && $(QMAKE) /Volumes/TheBox/Repos/anomade/libs/MarkdownLib.pro -spec ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o $(MAKEFILE).MarkdownLib
+sub-libs-MarkdownLib-pro: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib
+sub-libs-MarkdownLib-pro-make_default: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib
+sub-libs-MarkdownLib-pro-make_first: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib first
+sub-libs-MarkdownLib-pro-all: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib all
+sub-libs-MarkdownLib-pro-clean: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib clean
+sub-libs-MarkdownLib-pro-distclean: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib distclean
+sub-libs-MarkdownLib-pro-install_subtargets: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib install
+sub-libs-MarkdownLib-pro-uninstall_subtargets: libs/$(MAKEFILE).MarkdownLib FORCE
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib uninstall
+src/$(MAKEFILE).AnomadeApp:
+ @$(CHK_DIR_EXISTS) src/ || $(MKDIR) src/
+ cd src/ && $(QMAKE) /Volumes/TheBox/Repos/anomade/src/AnomadeApp.pro -spec ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o $(MAKEFILE).AnomadeApp
+sub-src-AnomadeApp-pro-qmake_all: FORCE
+ @$(CHK_DIR_EXISTS) src/ || $(MKDIR) src/
+ cd src/ && $(QMAKE) /Volumes/TheBox/Repos/anomade/src/AnomadeApp.pro -spec ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o $(MAKEFILE).AnomadeApp
+sub-src-AnomadeApp-pro: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp
+sub-src-AnomadeApp-pro-make_default: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp
+sub-src-AnomadeApp-pro-make_first: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp first
+sub-src-AnomadeApp-pro-all: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp all
+sub-src-AnomadeApp-pro-clean: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp clean
+sub-src-AnomadeApp-pro-distclean: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp distclean
+sub-src-AnomadeApp-pro-install_subtargets: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp install
+sub-src-AnomadeApp-pro-uninstall_subtargets: src/$(MAKEFILE).AnomadeApp FORCE
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp uninstall
+
+Makefile: Anomade.pro ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++/qmake.conf ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/unix.conf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac.conf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac-g++.conf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/qconfig.pri \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/modules/qt_webkit_version.pri \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_functions.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_config.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/exclusive_builds.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_pre.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_pre.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/dwarf2.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/debug.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_post.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_post.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/x86_64.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/objective_c.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/warn_on.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/unix/thread.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/moc.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/rez.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/sdk.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/resources.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/uic.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/yacc.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/lex.prf \
+ ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/include_source_dir.prf
+ $(QMAKE) -spec ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o Makefile Anomade.pro
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/unix.conf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac.conf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac-g++.conf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/qconfig.pri:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/modules/qt_webkit_version.pri:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_functions.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_config.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/exclusive_builds.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_pre.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_pre.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/dwarf2.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/debug.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_post.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_post.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/x86_64.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/objective_c.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/warn_on.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/unix/thread.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/moc.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/rez.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/sdk.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/resources.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/uic.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/yacc.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/lex.prf:
+../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/include_source_dir.prf:
+qmake: qmake_all FORCE
+ @$(QMAKE) -spec ../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o Makefile Anomade.pro
+
+qmake_all: sub-libs-MarkdownLib-pro-qmake_all sub-src-AnomadeApp-pro-qmake_all FORCE
+
+make_default: sub-libs-MarkdownLib-pro-make_default sub-src-AnomadeApp-pro-make_default FORCE
+make_first: sub-libs-MarkdownLib-pro-make_first sub-src-AnomadeApp-pro-make_first FORCE
+all: sub-libs-MarkdownLib-pro-all sub-src-AnomadeApp-pro-all FORCE
+clean: sub-libs-MarkdownLib-pro-clean sub-src-AnomadeApp-pro-clean FORCE
+distclean: sub-libs-MarkdownLib-pro-distclean sub-src-AnomadeApp-pro-distclean FORCE
+ -$(DEL_FILE) Makefile
+install_subtargets: sub-libs-MarkdownLib-pro-install_subtargets sub-src-AnomadeApp-pro-install_subtargets FORCE
+uninstall_subtargets: sub-libs-MarkdownLib-pro-uninstall_subtargets sub-src-AnomadeApp-pro-uninstall_subtargets FORCE
+
+sub-libs-MarkdownLib-pro-check: libs/$(MAKEFILE).MarkdownLib
+ cd libs/ && $(MAKE) -f $(MAKEFILE).MarkdownLib check
+sub-src-AnomadeApp-pro-check: src/$(MAKEFILE).AnomadeApp
+ cd src/ && $(MAKE) -f $(MAKEFILE).AnomadeApp check
+check: sub-libs-MarkdownLib-pro-check sub-src-AnomadeApp-pro-check
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+install: install_subtargets FORCE
+
+uninstall: uninstall_subtargets FORCE
+
+FORCE:
+
0  README
No changes.
231 libs/Makefile.MarkdownLib
@@ -0,0 +1,231 @@
+#############################################################################
+# Makefile for building: libmarkdown.a
+# Generated by qmake (2.01a) (Qt 4.7.4) on: Thu Dec 22 17:16:29 2011
+# Project: MarkdownLib.pro
+# Template: lib
+# Command: /Volumes/TheBox/QtSDK/Desktop/Qt/474/gcc/bin/qmake -spec ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o Makefile.MarkdownLib MarkdownLib.pro
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+DEFINES =
+CFLAGS = -pipe -O2 -fPIC $(DEFINES)
+CXXFLAGS = -pipe -O2 -fPIC $(DEFINES)
+INCPATH = -I../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -I.
+AR = ar cq
+RANLIB = ranlib -s
+QMAKE = /Volumes/TheBox/QtSDK/Desktop/Qt/474/gcc/bin/qmake
+TAR = tar -cf
+COMPRESS = gzip -9f
+COPY = cp -f
+SED = sed
+COPY_FILE = cp -f
+COPY_DIR = cp -f -R
+STRIP =
+INSTALL_FILE = $(COPY_FILE)
+INSTALL_DIR = $(COPY_DIR)
+INSTALL_PROGRAM = $(COPY_FILE)
+DEL_FILE = rm -f
+SYMLINK = ln -f -s
+DEL_DIR = rmdir
+MOVE = mv -f
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir -p
+export MACOSX_DEPLOYMENT_TARGET = 10.4
+
+####### Output directory
+
+OBJECTS_DIR = .obj/
+
+####### Files
+
+SOURCES = docheader.c \
+ dumptree.c \
+ generate.c \
+ markdown.c \
+ mkdio.c \
+ resource.c \
+ version.c \
+ markdowncxx.cpp
+OBJECTS = .obj/docheader.o \
+ .obj/dumptree.o \
+ .obj/generate.o \
+ .obj/markdown.o \
+ .obj/mkdio.o \
+ .obj/resource.o \
+ .obj/version.o \
+ .obj/markdowncxx.o
+DIST = ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/unix.conf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac.conf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac-g++.conf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/qconfig.pri \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/modules/qt_webkit_version.pri \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_functions.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_config.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/exclusive_builds.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_pre.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_pre.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/release.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_post.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_post.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/objective_c.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/staticlib.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/static.prf \
+ MarkdownLib.pro
+QMAKE_TARGET = markdown
+DESTDIR =
+TARGET = libmarkdown.a
+
+####### Custom Compiler Variables
+QMAKE_COMP_QMAKE_OBJECTIVE_CFLAGS = -pipe \
+ -O2
+
+
+first: all
+####### Implicit rules
+
+.SUFFIXES: .o .c .cpp .cc .cxx .C
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
+
+####### Build rules
+
+all: Makefile.MarkdownLib $(TARGET)
+
+staticlib: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJCOMP)
+ -$(DEL_FILE) $(TARGET)
+ $(AR) $(TARGET) $(OBJECTS)
+ $(RANLIB) $(TARGET)
+
+
+Makefile.MarkdownLib: MarkdownLib.pro ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++/qmake.conf ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/unix.conf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac.conf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac-g++.conf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/qconfig.pri \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/modules/qt_webkit_version.pri \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_functions.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_config.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/exclusive_builds.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_pre.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_pre.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/release.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_post.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_post.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/objective_c.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/staticlib.prf \
+ ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/static.prf
+ $(QMAKE) -spec ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o Makefile.MarkdownLib MarkdownLib.pro
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/unix.conf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac.conf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/common/mac-g++.conf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/qconfig.pri:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/modules/qt_webkit_version.pri:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_functions.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/qt_config.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/exclusive_builds.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_pre.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_pre.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/release.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/default_post.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/default_post.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/mac/objective_c.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/staticlib.prf:
+../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/features/static.prf:
+qmake: FORCE
+ @$(QMAKE) -spec ../../../QtSDK/Desktop/Qt/474/gcc/mkspecs/macx-g++ -o Makefile.MarkdownLib MarkdownLib.pro
+
+dist:
+ @$(CHK_DIR_EXISTS) .obj/markdown1.0.0 || $(MKDIR) .obj/markdown1.0.0
+ $(COPY_FILE) --parents $(SOURCES) $(DIST) .obj/markdown1.0.0/ && (cd `dirname .obj/markdown1.0.0` && $(TAR) markdown1.0.0.tar markdown1.0.0 && $(COMPRESS) markdown1.0.0.tar) && $(MOVE) `dirname .obj/markdown1.0.0`/markdown1.0.0.tar.gz . && $(DEL_FILE) -r .obj/markdown1.0.0
+
+
+clean:compiler_clean
+ -$(DEL_FILE) $(OBJECTS)
+ -$(DEL_FILE) *~ core *.core
+
+
+####### Sub-libraries
+
+distclean: clean
+ -$(DEL_FILE) $(TARGET)
+ -$(DEL_FILE) Makefile.MarkdownLib
+
+
+check: first
+
+compiler_objective_c_make_all:
+compiler_objective_c_clean:
+compiler_clean:
+
+####### Compile
+
+.obj/docheader.o: docheader.c config.h \
+ cstring.h \
+ amalloc.h \
+ markdown.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o .obj/docheader.o docheader.c
+
+.obj/dumptree.o: dumptree.c markdown.h \
+ cstring.h \
+ amalloc.h \
+ config.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o .obj/dumptree.o dumptree.c
+
+.obj/generate.o: generate.c config.h \
+ cstring.h \
+ amalloc.h \
+ markdown.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o .obj/generate.o generate.c
+
+.obj/markdown.o: markdown.c config.h \
+ cstring.h \
+ amalloc.h \
+ markdown.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o .obj/markdown.o markdown.c
+
+.obj/mkdio.o: mkdio.c config.h \
+ cstring.h \
+ amalloc.h \
+ markdown.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o .obj/mkdio.o mkdio.c
+
+.obj/resource.o: resource.c config.h \
+ cstring.h \
+ amalloc.h \
+ markdown.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o .obj/resource.o resource.c
+
+.obj/version.o: version.c config.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o .obj/version.o version.c
+
+.obj/markdowncxx.o: markdowncxx.cpp markdown.h \
+ cstring.h \
+ amalloc.h \
+ config.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/markdowncxx.o markdowncxx.cpp
+
+####### Install
+
+install: FORCE
+
+uninstall: FORCE
+
+FORCE:
+
20 libs/MarkdownLib.pro
@@ -0,0 +1,20 @@
+TARGET = markdown
+TEMPLATE = lib
+CONFIG = staticlib
+HEADERS = amalloc.h \
+ config.h \
+ cstring.h \
+ markdowncxx.h \
+ markdown.h
+
+SOURCES = docheader.c \
+ dumptree.c \
+ generate.c \
+ markdown.c \
+ mkdio.c \
+ resource.c \
+ version.c \
+ markdowncxx.cpp
+
+MOC_DIR = .obj
+OBJECTS_DIR = .obj
29 libs/amalloc.h
@@ -0,0 +1,29 @@
+/*
+ * debugging malloc()/realloc()/calloc()/free() that attempts
+ * to keep track of just what's been allocated today.
+ */
+#ifndef AMALLOC_D
+#define AMALLOC_D
+
+#include "config.h"
+
+#ifdef USE_AMALLOC
+
+extern void *amalloc(int);
+extern void *acalloc(int,int);
+extern void *arealloc(void*,int);
+extern void afree(void*);
+extern void adump();
+
+#define malloc amalloc
+#define calloc acalloc
+#define realloc arealloc
+#define free afree
+
+#else
+
+#define adump() (void)1
+
+#endif
+
+#endif/*AMALLOC_D*/
29 libs/config.h
@@ -0,0 +1,29 @@
+/*
+ * configuration for markdown, generated Fri Apr 11 20:52:10 IDT 2008
+ * by artik@artyom-linux
+ */
+#ifndef __AC_MARKDOWN_D
+#define __AC_MARKDOWN_D 1
+
+
+#define OS_LINUX 1
+#define DWORD unsigned int
+#define WORD unsigned short
+#define BYTE unsigned char
+#define HAVE_BASENAME 1
+#define HAVE_LIBGEN_H 1
+#define HAVE_PWD_H 1
+#define HAVE_GETPWUID 1
+#define HAVE_SRANDOM 1
+#define INITRNG(x) srandom((unsigned int)x)
+#define HAVE_RANDOM 1
+#define COINTOSS() (random()&1)
+#define HAVE_STRCASECMP 1
+#define HAVE_STRNCASECMP 1
+#define HAVE_FCHDIR 1
+#define TABSTOP 4
+#define HAVE_MALLOC_H 1
+#define DL_TAG_EXTENSION 1
+#define PATH_SED "/bin/sed"
+
+#endif/* __AC_MARKDOWN_D */
68 libs/cstring.h
@@ -0,0 +1,68 @@
+/* two template types: STRING(t) which defines a pascal-style string
+ * of element (t) [STRING(char) is the closest to the pascal string],
+ * and ANCHOR(t) which defines a baseplate that a linked list can be
+ * built up from. [The linked list /must/ contain a ->next pointer
+ * for linking the list together with.]
+ */
+#ifndef _CSTRING_D
+#define _CSTRING_D
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "amalloc.h"
+
+/* expandable Pascal-style string.
+ */
+#define STRING(type) struct { type *text; int size, alloc; }
+
+#define CREATE(x) T(x) = (void*)(S(x) = (x).alloc = 0,NULL)
+#define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
+ ? (T(x)) \
+ : (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
+ : malloc(sizeof T(x)[0] * ((x).alloc += 100)) )]
+
+#define DELETE(x) (x).alloc ? (free(T(x)), S(x) = (x).alloc = 0) \
+ : ( S(x) = 0 )
+#define CLIP(t,i,sz) \
+ ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
+ (memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
+ S(t) -= (sz)) : -1
+
+#define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \
+ ? T(x) \
+ : T(x) \
+ ? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \
+ : malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))))
+#define SUFFIX(t,p,sz) \
+ memcpy(((S(t) += (sz)) - (sz)) + \
+ (T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \
+ : malloc(sizeof T(t)[0] * ((t).alloc += sz))), \
+ (p), sizeof(T(t)[0])*(sz))
+
+#define PREFIX(t,p,sz) \
+ RESERVE( (t), (sz) ); \
+ if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \
+ memcpy( T(t), (p), (sz) ); \
+ S(t) += (sz)
+
+/* reference-style links (and images) are stored in an array
+ */
+#define T(x) (x).text
+#define S(x) (x).size
+
+/* abstract anchor type that defines a list base
+ * with a function that attaches an element to
+ * the end of the list.
+ *
+ * the list base field is named .text so that the T()
+ * macro will work with it.
+ */
+#define ANCHOR(t) struct { t *text, *end; }
+
+#define ATTACH(t, p) ( (t).text ?( ((t).end->next = (p)), ((t).end = (p)) ) \
+ :( ((t).text = (t).end = (p)) ) )
+
+typedef STRING(char) Cstring;
+
+#endif/*_CSTRING_D*/
43 libs/docheader.c
@@ -0,0 +1,43 @@
+/*
+ * docheader -- get values from the document header
+ *
+ * Copyright (C) 2007 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"
+
+#define afterdle(t) (T((t)->text) + (t)->dle)
+
+char *
+mkd_doc_title(Document *doc)
+{
+ if ( doc && doc->headers )
+ return afterdle(doc->headers);
+ return 0;
+}
+
+
+char *
+mkd_doc_author(Document *doc)
+{
+ if ( doc && doc->headers && doc->headers->next )
+ return afterdle(doc->headers->next);
+ return 0;
+}
+
+
+char *
+mkd_doc_date(Document *doc)
+{
+ if ( doc && doc->headers && doc->headers->next && doc->headers->next->next )
+ return afterdle(doc->headers->next->next);
+ return 0;
+}
147 libs/dumptree.c
@@ -0,0 +1,147 @@
+/* markdown: a C implementation of John Gruber's Markdown markup language.
+ *
+ * Copyright (C) 2007 David L Parsons.
+ * The redistribution terms are provided in the COPYRIGHT file that must
+ * be distributed with this source code.
+ */
+#include <stdio.h>
+#include "markdown.h"
+#include "cstring.h"
+#include "amalloc.h"
+
+struct frame {
+ int indent;
+ char c;
+};
+
+typedef STRING(struct frame) Stack;
+
+static char *
+Pptype(int typ)
+{
+ switch (typ) {
+ case WHITESPACE: return "whitespace";
+ case CODE : return "code";
+ case QUOTE : return "quote";
+ case MARKUP : return "markup";
+ case HTML : return "html";
+ case DL : return "dl";
+ case UL : return "ul";
+ case OL : return "ol";
+ case LISTITEM : return "item";
+ case HDR : return "header";
+ case HR : return "HR";
+ default : return "mystery node!";
+ }
+}
+
+static void
+pushpfx(int indent, char c, Stack *sp)
+{
+ struct frame *q = &EXPAND(*sp);
+
+ q->indent = indent;
+ q->c = c;
+}
+
+
+static void
+poppfx(Stack *sp)
+{
+ S(*sp)--;
+}
+
+
+static void
+changepfx(Stack *sp, char c)
+{
+ char ch;
+
+ if ( !S(*sp) ) return;
+
+ ch = T(*sp)[S(*sp)-1].c;
+
+ if ( ch == '+' || ch == '|' )
+ T(*sp)[S(*sp)-1].c = c;
+}
+
+
+static void
+printpfx(Stack *sp, FILE *f)
+{
+ int i;
+ char c;
+
+ if ( !S(*sp) ) return;
+
+ c = T(*sp)[S(*sp)-1].c;
+
+ if ( c == '+' || c == '-' ) {
+ fprintf(f, "--%c", c);
+ T(*sp)[S(*sp)-1].c = (c == '-') ? ' ' : '|';
+ }
+ else
+ for ( i=0; i < S(*sp); i++ ) {
+ if ( i )
+ fprintf(f, " ");
+ fprintf(f, "%*s%c", T(*sp)[i].indent + 2, " ", T(*sp)[i].c);
+ if ( T(*sp)[i].c == '`' )
+ T(*sp)[i].c = ' ';
+ }
+ fprintf(f, "--");
+}
+
+
+static void
+dumptree(Paragraph *pp, Stack *sp, FILE *f)
+{
+ int count;
+ Line *p;
+ int d;
+ static char *Begin[] = { 0, "P", "center" };
+
+ while ( pp ) {
+ if ( !pp->next )
+ changepfx(sp, '`');
+ printpfx(sp, f);
+
+ d = fprintf(f, "[%s", Pptype(pp->typ));
+ if ( pp->align )
+ d += fprintf(f, ", <%s>", Begin[pp->align]);
+
+ for (count=0, p=pp->text; p; ++count, (p = p->next) )
+ ;
+
+ if ( count )
+ d += fprintf(f, ", %d line%s", count, (count==1)?"":"s");
+
+ d += fprintf(f, "]");
+
+ if ( pp->down ) {
+ pushpfx(d, pp->down->next ? '+' : '-', sp);
+ dumptree(pp->down, sp, f);
+ poppfx(sp);
+ }
+ else fputc('\n', f);
+ pp = pp->next;
+ }
+}
+
+
+int
+mkd_dump(Document *doc, FILE *out, int flags, char *title)
+{
+ Stack stack;
+
+ if (mkd_compile(doc, flags) ) {
+
+ CREATE(stack);
+ pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack);
+ dumptree(doc->code, &stack, out);
+ DELETE(stack);
+
+ mkd_cleanup(doc);
+ return 0;
+ }
+ return -1;
+}
1,283 libs/generate.c
@@ -0,0 +1,1283 @@
+/* markdown: a C implementation of John Gruber's Markdown markup language.
+ *
+ * Copyright (C) 2007 David L Parsons.
+ * The redistribution terms are provided in the COPYRIGHT file that must
+ * be distributed with this source code.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "config.h"
+
+#include "cstring.h"
+#include "markdown.h"
+#include "amalloc.h"
+
+/* prefixes for <automatic links>
+ */
+static char *autoprefix[] = { "http://", "https://", "ftp://", "news://" };
+#define SZAUTOPREFIX (sizeof autoprefix / sizeof autoprefix[0])
+
+typedef int (*stfu)(const void*,const void*);
+
+
+/* forward declarations */
+static void code(int, MMIOT*);
+static void text(MMIOT *f);
+static Paragraph *display(Paragraph*, MMIOT*);
+
+/* externals from markdown.c */
+int __mkd_footsort(Footnote *, Footnote *);
+
+/*
+ * push text into the generator input buffer
+ */
+static void
+push(char *bfr, int size, MMIOT *f)
+{
+ while ( size-- > 0 )
+ EXPAND(f->in) = *bfr++;
+}
+
+
+/* look <i> characters ahead of the cursor.
+ */
+static int
+peek(MMIOT *f, int i)
+{
+
+ i += (f->isp-1);
+
+ return (i >= 0) && (i < S(f->in)) ? T(f->in)[i] : EOF;
+}
+
+
+/* pull a byte from the input buffer
+ */
+static int
+pull(MMIOT *f)
+{
+ return ( f->isp < S(f->in) ) ? T(f->in)[f->isp++] : EOF;
+}
+
+
+/* return a pointer to the current position in the input buffer.
+ */
+static char*
+cursor(MMIOT *f)
+{
+ return T(f->in) + f->isp;
+}
+
+
+/* return/set the current cursor position
+ */
+#define mmiotseek(f,x) (f->isp = x)
+#define mmiottell(f) (f->isp)
+
+
+/* move n characters forward ( or -n characters backward) in the input buffer.
+ */
+static void
+shift(MMIOT *f, int i)
+{
+ if (f->isp + i >= 0 )
+ f->isp += i;
+}
+
+
+/* Qchar()
+ */
+static void
+Qchar(char c, MMIOT *f)
+{
+ block *cur;
+
+ if ( S(f->Q) == 0 ) {
+ cur = &EXPAND(f->Q);
+ memset(cur, 0, sizeof *cur);
+ cur->b_type = bTEXT;
+ }
+ else
+ cur = &T(f->Q)[S(f->Q)-1];
+
+ EXPAND(cur->b_text) = c;
+
+}
+
+
+/* Qstring()
+ */
+static void
+Qstring(char *s, MMIOT *f)
+{
+ while (*s)
+ Qchar(*s++, f);
+}
+
+
+/* Qwrite()
+ */
+static void
+Qwrite(char *s, int size, MMIOT *f)
+{
+ while (size-- > 0)
+ Qchar(*s++, f);
+}
+
+
+/* Qprintf()
+ */
+static void
+Qprintf(MMIOT *f, char *fmt, ...)
+{
+ char bfr[80];
+ va_list ptr;
+
+ va_start(ptr,fmt);
+ vsnprintf(bfr, sizeof bfr, fmt, ptr);
+ va_end(ptr);
+ Qstring(bfr, f);
+}
+
+
+/* Qem()
+ */
+static void
+Qem(MMIOT *f, char c, int count)
+{
+ block *p = &EXPAND(f->Q);
+
+ memset(p, 0, sizeof *p);
+ p->b_type = (c == '*') ? bSTAR : bUNDER;
+ p->b_char = c;
+ p->b_count = count;
+
+ memset(&EXPAND(f->Q), 0, sizeof(block));
+}
+
+
+/* empair()
+ */
+static int
+empair(MMIOT *f, int go, int level)
+{
+
+ int i;
+ block *begin, *p;
+
+ begin = &T(f->Q)[go];
+ for (i=go+1; i < S(f->Q); i++) {
+ p = &T(f->Q)[i];
+
+ if ( (p->b_type != bTEXT) && (p->b_count <= 0) )
+ break;
+
+ if ( p->b_type == begin->b_type ) {
+ if ( p->b_count == level ) /* exact match */
+ return i-go;
+
+ if ( p->b_count > 2 ) /* fuzzy match */
+ return i-go;
+ }
+ }
+ return EOF;
+}
+
+
+
+static struct emtags {
+ char open[10];
+ char close[10];
+ int size;
+} emtags[] = { { "<em>" , "</em>", 5 }, { "<strong>", "</strong>", 9 } };
+
+
+static void
+emclose(Cstring *s, int level)
+{
+ PREFIX(*s, emtags[level-1].close, emtags[level-1].size);
+}
+
+
+static void
+emopen(Cstring *s, int level)
+{
+ SUFFIX(*s, emtags[level-1].open, emtags[level-1].size-1);
+}
+
+
+/* emmatch()
+ */
+static void
+emmatch(MMIOT *f, int go)
+{
+ block *start = &T(f->Q)[go], *end;
+ int e, e2, i, match;
+
+ while ( start->b_count ) {
+ switch (start->b_count) {
+ case 2: e = empair(f,go,match=2);
+ if ( e != EOF ) break;
+ case 1: e = empair(f,go,match=1); break;
+ default:
+ e = empair(f,go,1);
+ e2= empair(f,go,2);
+
+ if ( e == EOF || ((e2 != EOF) && (e2 >= e)) ) {
+ e = e2;
+ match = 2;
+ }
+ else
+ match = 1;
+ }
+ if ( e != EOF ) {
+ end = &T(f->Q)[go+e];
+ emclose(&end->b_post, match);
+ emopen(&start->b_text, match);
+ end->b_count -= match;
+ }
+ else {
+ for (i=0; i < match; i++)
+ EXPAND(start->b_text) = start->b_char;
+ }
+
+ start->b_count -= match;
+ }
+}
+
+
+/* emblock()
+ */
+static void
+emblock(MMIOT *f)
+{
+ int i;
+ block *p;
+
+ for (i=0; i < S(f->Q); i++) {
+ p = &T(f->Q)[i];
+
+ if ( p->b_type != bTEXT ) emmatch(f, i);
+
+ if ( S(p->b_post) ) { SUFFIX(f->out, T(p->b_post), S(p->b_post));
+ DELETE(p->b_post); }
+ if ( S(p->b_text) ) { SUFFIX(f->out, T(p->b_text), S(p->b_text));
+ DELETE(p->b_text); }
+ }
+ S(f->Q) = 0;
+}
+
+
+/* generate html from a markup fragment
+ */
+static void
+reparse(char *bfr, int size, int flags, MMIOT *f)
+{
+ MMIOT sub;
+
+ ___mkd_initmmiot(&sub, f->footnotes);
+
+ sub.flags = f->flags | flags;
+ sub.base = f->base;
+
+ push(bfr, size, &sub);
+ EXPAND(sub.in) = 0;
+ S(sub.in)--;
+
+ text(&sub);
+ emblock(&sub);
+
+ Qwrite(T(sub.out), S(sub.out), f);
+
+ ___mkd_freemmiot(&sub, f->footnotes);
+}
+
+
+/*
+ * write out a url, escaping problematic characters
+ */
+static void
+puturl(char *s, int size, MMIOT *f)
+{
+ unsigned char c;
+
+ while ( size-- > 0 ) {
+ c = *s++;
+
+ if ( c == '&' )
+ Qstring("&amp;", f);
+ else if ( c == '<' )
+ Qstring("&lt;", f);
+ else if ( isalnum(c) || c == '.' || c == '-' || c == '_' || c == '/'
+ || c == '=' || c == '?' || c == ':' || c == '#' )
+ Qchar(c, f);
+ else
+ Qprintf(f, "%%%02X", c);
+ }
+}
+
+
+/* advance forward until the next character is not whitespace
+ */
+static int
+eatspace(MMIOT *f)
+{
+ int c;
+
+ for ( ; ((c=peek(f, 1)) != EOF) && isspace(c); pull(f) )
+ ;
+ return c;
+}
+
+
+/* (match (a (nested (parenthetical (string.)))))
+ */
+static int
+parenthetical(int in, int out, MMIOT *f)
+{
+ int size, indent, c;
+
+ for ( indent=1,size=0; indent; size++ ) {
+ if ( (c = pull(f)) == EOF )
+ return EOF;
+ else if ( c == in )
+ ++indent;
+ else if ( c == out )
+ --indent;
+ }
+ return size-1;
+}
+
+
+/* extract a []-delimited label from the input stream.
+ */
+static char *
+linkylabel(MMIOT *f, int *sizep)
+{
+ char *ptr = cursor(f);
+
+ if ( (*sizep = parenthetical('[',']',f)) != EOF )
+ return ptr;
+ return 0;
+}
+
+
+/* extract a (-prefixed url from the input stream.
+ * the label is either of the format `<link>`, where I
+ * extract until I find a >, or it is of the format
+ * `text`, where I extract until I reach a ')' or
+ * whitespace.
+ */
+static char*
+linkyurl(MMIOT *f, int *sizep)
+{
+ int size = 0;
+ char *ptr;
+ int c;
+
+ if ( (c = eatspace(f)) == EOF )
+ return 0;
+
+ ptr = cursor(f);
+
+ if ( c == '<' ) {
+ pull(f);
+ ptr++;
+ if ( (size = parenthetical('<', '>', f)) == EOF )
+ return 0;
+ }
+ else {
+ for ( ; ((c=pull(f)) != ')') && !isspace(c); size++)
+ if ( c == EOF ) return 0;
+ if ( c == ')' )
+ shift(f, -1);
+ }
+ *sizep = size;
+ return ptr;
+}
+
+
+/* extract a =HHHxWWW size from the input stream
+ */
+static int
+linkysize(MMIOT *f, int *heightp, int *widthp)
+{
+ int height=0, width=0;
+ int c;
+
+ *heightp = 0;
+ *widthp = 0;
+
+ if ( (c = eatspace(f)) != '=' )
+ return (c != EOF);
+ pull(f); /* eat '=' */
+
+ for ( c = pull(f); isdigit(c); c = pull(f))
+ width = (width * 10) + (c - '0');
+
+ if ( c == 'x' ) {
+ for ( c = pull(f); isdigit(c); c = pull(f))
+ height = (height*10) + (c - '0');
+
+ if ( c != EOF ) {
+ if ( !isspace(c) ) shift(f, -1);
+ *heightp = height;
+ *widthp = width;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* extract a )-terminated title from the input stream.
+ */
+static char*
+linkytitle(MMIOT *f, int *sizep)
+{
+ int countq=0, qc, c, size;
+ char *ret, *lastqc = 0;
+
+ eatspace(f);
+ if ( (qc=pull(f)) != '"' && qc != '\'' && qc != '(' )
+ return 0;
+
+ if ( qc == '(' ) qc = ')';
+
+ for ( ret = cursor(f); (c = pull(f)) != EOF; ) {
+ if ( (c == ')') && countq ) {
+ size = (lastqc ? lastqc : cursor(f)) - ret;
+ *sizep = size-1;
+ return ret;
+ }
+ else if ( c == qc ) {
+ lastqc = cursor(f);
+ countq++;
+ }
+ }
+ return 0;
+}
+
+
+/* look up (or construct) a footnote from the [xxx] link
+ * at the head of the stream.
+ */
+static int
+linkykey(int image, Footnote *val, MMIOT *f)
+{
+ Footnote *ret;
+ Cstring mylabel;
+
+ memset(val, 0, sizeof *val);
+
+ if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
+ return 0;
+
+ eatspace(f);
+ switch ( pull(f) ) {
+ case '(':
+ /* embedded link */
+ if ( (T(val->link) = linkyurl(f,&S(val->link))) == 0 )
+ return 0;
+
+ if ( image && !linkysize(f, &val->height, &val->width) )
+ return 0;
+
+ T(val->title) = linkytitle(f, &S(val->title));
+
+ return peek(f,0) == ')';
+
+ case '[':
+ /* footnote link */
+ mylabel = val->tag;
+ if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
+ return 0;
+
+ if ( !S(val->tag) )
+ val->tag = mylabel;
+
+ ret = bsearch(val, T(*f->footnotes), S(*f->footnotes),
+ sizeof *val, (stfu)__mkd_footsort);
+
+ if ( ret ) {
+ val->tag = mylabel;
+ val->link = ret->link;
+ val->title = ret->title;
+ val->height = ret->height;
+ val->width = ret->width;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * all the tag types that linkylinky can produce are
+ * defined by this structure.
+ */
+typedef struct linkytype {
+ char *pat;
+ int szpat;
+ char *link_pfx; /* tag prefix and link pointer (eg: "<a href="\"" */
+ char *link_sfx; /* link suffix (eg: "\"" */
+ int WxH; /* this tag allows width x height arguments */
+ char *text_pfx; /* text prefix (eg: ">" */
+ char *text_sfx; /* text suffix (eg: "</a>" */
+ int flags; /* reparse flags */
+} linkytype;
+
+static linkytype imaget = { 0, 0, "<img src=\"", "\"",
+ 1, " alt=\"", "\" />", DENY_IMG|INSIDE_TAG };
+static linkytype linkt = { 0, 0, "<a href=\"", "\"",
+ 0, ">", "</a>", DENY_A };
+
+/*
+ * pseudo-protocols for [][];
+ *
+ * id: generates <a id="link">tag</a>
+ * class: generates <span class="link">tag</span>
+ * raw: just dump the link without any processing
+ */
+static linkytype specials[] = {
+ { "id:", 3, "<a id=\"", "\"", 0, ">", "</a>", 0 },
+ { "class:", 6, "<span class=\"", "\"", 0, ">", "</span>", 0 },
+ { "raw:", 4, 0, 0, 0, 0, 0, 0 },
+} ;
+
+#define NR(x) (sizeof x / sizeof x[0])
+
+/* see if t contains one of our pseudo-protocols.
+ */
+static linkytype *
+extratag(Cstring t)
+{
+ int i;
+ linkytype *r;
+
+ for ( i=0; i < NR(specials); i++ ) {
+ r = &specials[i];
+ if ( (S(t) > r->szpat) && (strncasecmp(T(t), r->pat, r->szpat) == 0) )
+ return r;
+ }
+ return 0;
+}
+
+
+/*
+ * process embedded links and images
+ */
+static int
+linkylinky(int image, MMIOT *f)
+{
+ int start = mmiottell(f);
+ Footnote link;
+ linkytype *tag;
+
+ if ( !(linkykey(image, &link, f) && S(link.tag)) ) {
+ mmiotseek(f, start);
+ return 0;
+ }
+
+ if ( image )
+ tag = &imaget;
+ else if ( (f->flags & NO_PSEUDO_PROTO) || (tag = extratag(link.link)) == 0 )
+ tag = &linkt;
+
+ if ( f->flags & tag-> flags ) {
+ mmiotseek(f, start);
+ return 0;
+ }
+
+ if ( tag->link_pfx ) {
+ Qstring(tag->link_pfx, f);
+ if ( f->base && (T(link.link)[tag->szpat] == '/') )
+ puturl(f->base, strlen(f->base), f);
+ puturl(T(link.link) + tag->szpat, S(link.link) - tag->szpat, f);
+ Qstring(tag->link_sfx, f);
+
+ if ( tag->WxH && link.height && link.width ) {
+ Qprintf(f," height=\"%d\"", link.height);
+ Qprintf(f, " width=\"%d\"", link.width);
+ }
+
+ if ( S(link.title) ) {
+ Qstring(" title=\"", f);
+ reparse(T(link.title), S(link.title), INSIDE_TAG, f);
+ Qchar('"', f);
+ }
+
+ Qstring(tag->text_pfx, f);
+ reparse(T(link.tag), S(link.tag), tag->flags, f);
+ Qstring(tag->text_sfx, f);
+ }
+ else
+ Qwrite(T(link.link) + tag->szpat, S(link.link) - tag->szpat, f);
+
+ return 1;
+}
+
+
+/* write a character to output, doing text escapes ( & -> &amp;,
+ * > -> &gt; < -> &lt; )
+ */
+static void
+cputc(int c, MMIOT *f)
+{
+ switch (c) {
+ case '&': Qstring("&amp;", f); break;
+ case '>': Qstring("&gt;", f); break;
+ case '<': Qstring("&lt;", f); break;
+ default : Qchar(c, f); break;
+ }
+}
+
+
+/*
+ * convert an email address to a string of nonsense
+ */
+static void
+mangle(unsigned char *s, int len, MMIOT *f)
+{
+ while ( len-- > 0 ) {
+ Qstring("&#", f);
+ Qprintf(f, COINTOSS() ? "x%02x;" : "%02d;", *s++);
+ }
+}
+
+
+/* before letting a tag through, validate against
+ * DENY_A and DENY_IMG
+ */
+static int
+forbidden_tag(MMIOT *f)
+{
+ int c = toupper(peek(f, 1));
+
+ if ( c == 'A' && (f->flags & DENY_A) && !isalnum(peek(f,2)) )
+ return 1;
+ if ( c == 'I' && (f->flags & DENY_IMG)
+ && strncasecmp(cursor(f)+1, "MG", 2) == 0
+ && !isalnum(peek(f,4)) )
+ return 1;
+ return 0;
+}
+
+
+
+/* a < may be just a regular character, the start of an embedded html
+ * tag, or the start of an <automatic link>. If it's an automatic
+ * link, we also need to know if it's an email address because if it
+ * is we need to mangle it in our futile attempt to cut down on the
+ * spaminess of the rendered page.
+ */
+static int
+maybe_tag_or_link(MMIOT *f)
+{
+ char *text;
+ int c, size, i;
+ int maybetag=1, maybeaddress=0;
+ int mailto;
+
+ if ( f->flags & INSIDE_TAG )
+ return 0;
+
+ for ( size=0; ((c = peek(f,size+1)) != '>') && !isspace(c); size++ ) {
+ if ( ! (c == '/' || isalnum(c) || c == '~') )
+ maybetag=0;
+ if ( c == '@' )
+ maybeaddress=1;
+ else if ( c == EOF )
+ return 0;
+ }
+
+ if ( size == 0 )
+ return 0;
+
+ if ( maybetag || (size >= 3 && strncmp(cursor(f), "!--", 3) == 0) ) {
+ Qstring(forbidden_tag(f) ? "&lt;" : "<", f);
+ while ( ((c = peek(f, 1)) != EOF) && (c != '>') )
+ cputc(pull(f), f);
+ return 1;
+ }
+
+ if ( f->flags & DENY_A ) return 0;
+
+ text = cursor(f);
+ shift(f, size+1);
+
+ for ( i=0; i < SZAUTOPREFIX; i++ )
+ if ( strncasecmp(text, autoprefix[i], strlen(autoprefix[i])) == 0 ) {
+ Qstring("<a href=\"", f);
+ puturl(text,size,f);
+ Qstring("\">", f);
+ puturl(text,size,f);
+ Qstring("</a>", f);
+ return 1;
+ }
+ if ( maybeaddress ) {
+
+ Qstring("<a href=\"", f);
+ if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 )
+ mailto = 7;
+ else {
+ mailto = 0;
+ /* supply a mailto: protocol if one wasn't attached */
+ mangle((unsigned char *)"mailto:", 7, f);
+ }
+
+ mangle((unsigned char*)text, size, f);
+ Qstring("\">", f);
+ mangle((unsigned char*)text+mailto, size-mailto, f);
+ Qstring("</a>", f);
+ return 1;
+ }
+
+ shift(f, -(size+1));
+ return 0;
+} /* maybe_tag_or_link */
+
+
+static int
+isthisspace(MMIOT *f, int i)
+{
+ int c = peek(f, i);
+
+ return isspace(c) || (c == EOF);
+}
+
+
+static int
+isthisnonword(MMIOT *f, int i)
+{
+ return isthisspace(f, i) || ispunct(peek(f,i));
+}
+
+
+
+static int
+islike(MMIOT *f, char *s)
+{
+ int len;
+ int i;
+
+ if ( s[0] == '<' ) {
+ if ( !isthisnonword(f, -1) )
+ return 0;
+ ++s;
+ }
+
+ if ( !(len = strlen(s)) )
+ return 0;
+
+ if ( s[len-1] == '>' ) {
+ if ( !isthisnonword(f,len-1) )
+ return 0;
+ len--;
+ }
+
+ for (i=1; i < len; i++)
+ if (tolower(peek(f,i)) != s[i])
+ return 0;
+ return 1;
+}
+
+
+static struct smarties {
+ char c0;
+ char *pat;
+ char *entity;
+ int shift;
+} smarties[] = {
+ { '\'', "'s>", "rsquo", 0 },
+ { '\'', "'t>", "rsquo", 0 },
+ { '-', "---", "mdash", 2 },
+ { '-', "--", "ndash", 1 },
+ { '.', "...", "hellip", 2 },
+ { '.', ". . .", "hellip", 4 },
+ { '(', "(c)", "copy", 2 },
+ { '(', "(r)", "reg", 2 },
+ { '(', "(tm)", "trade", 3 },
+ { '3', "<3/4>", "frac34", 2 },
+ { '3', "<3/4ths>", "frac34", 2 },
+ { '1', "<1/2>", "frac12", 2 },
+ { '1', "<1/4>", "frac14", 2 },
+ { '1', "<1/4th>", "frac14", 2 },
+ { '&', "&#0;", 0, 3 },
+} ;
+#define NRSMART ( sizeof smarties / sizeof smarties[0] )
+
+
+/* Smarty-pants-style chrome for quotes, -, ellipses, and (r)(c)(tm)
+ */
+static int
+smartypants(int c, int *flags, MMIOT *f)
+{
+ int i;
+
+ if ( f->flags & DENY_SMARTY )
+ return 0;
+
+ for ( i=0; i < NRSMART; i++)
+ if ( (c == smarties[i].c0) && islike(f, smarties[i].pat) ) {
+ if ( smarties[i].entity )
+ Qprintf(f, "&%s;", smarties[i].entity);
+ shift(f, smarties[i].shift);
+ return 1;
+ }
+ return 0;
+} /* smartypants */
+
+
+#define tag_text(f) (f->flags & INSIDE_TAG)
+
+
+static void
+text(MMIOT *f)
+{
+ int c, j;
+ int rep;
+ int smartyflags = 0;
+
+ while ( (c = pull(f)) != EOF ) {
+ if ( smartypants(c, &smartyflags, f) )
+ continue;
+ switch (c) {
+ case 0: break;
+
+ case '>': if ( tag_text(f) )
+ Qstring("&gt;", f);
+ else
+ Qchar(c, f);
+ break;
+
+ case '"': if ( tag_text(f) )
+ Qstring("&quot;", f);
+ else
+ Qchar(c, f);
+ break;
+
+ case '!': if ( peek(f,1) == '[' ) {
+ pull(f);
+ if ( tag_text(f) || !linkylinky(1, f) )
+ Qstring("![", f);
+ }
+ else
+ Qchar(c, f);
+ break;
+ case '[': if ( tag_text(f) || !linkylinky(0, f) )
+ Qchar(c, f);
+ break;
+#if SUPERSCRIPT
+ case '^': if ( isthisspace(f,-1) || isthisspace(f,1) )
+ Qchar(c,f);
+ else {
+ char *sup = cursor(f);
+ int len = 0;
+ Qstring("<sup>",f);
+ while ( !isthisspace(f,1+len) ) {
+ ++len;
+ }
+ shift(f,len);
+ reparse(sup, len, 0, f);
+ Qstring("</sup>", f);
+ }
+ break;
+#endif
+ case '*':
+ case '_': if ( tag_text(f) )
+ Qchar(c, f);
+#if RELAXED_EMPHASIS
+ else if ( peek(f,1) == c ) {
+ for ( rep = 1; peek(f,1) == c; pull(f) )
+ ++rep;
+
+ Qem(f, c, rep);
+ }
+ else if ( (isthisspace(f,-1) && isthisspace(f,1))
+ || (isalnum(peek(f,-1)) && isalnum(peek(f,1))) )
+ Qchar(c, f);
+ else {
+ Qem(f, c, 1);
+ }
+#else
+ else {
+ for (rep = 1; peek(f,1) == c; pull(f) )
+ ++rep;
+ Qem(f,c,rep);
+ }
+#endif
+ break;
+
+ case '`': if ( tag_text(f) )
+ Qchar(c, f);
+ else {
+ Qstring("<code>", f);
+ if ( peek(f, 1) == '`' ) {
+ pull(f);
+ code(2, f);
+ }
+ else
+ code(1, f);
+ Qstring("</code>", f);
+ }
+ break;
+
+ case '\\': switch ( c = pull(f) ) {
+ case '&': Qstring("&amp;", f);
+ break;
+ case '<': Qstring("&lt;", f);
+ break;
+ case '\\':
+ case '>': case '#': case '.': case '-':
+ case '+': case '{': case '}': case ']':
+ case '(': case ')': case '"': case '\'':
+ case '!': case '[': case '*': case '_':
+ case '`': Qchar(c, f);
+ break;
+ default:
+ Qchar('\\', f);
+ if ( c != EOF )
+ shift(f,-1);
+ break;
+ }
+ break;
+
+ case '<': if ( !maybe_tag_or_link(f) )
+ Qstring("&lt;", f);
+ break;
+
+ case '&': j = (peek(f,1) == '#' ) ? 2 : 1;
+ while ( isalnum(peek(f,j)) )
+ ++j;
+
+ if ( peek(f,j) != ';' )
+ Qstring("&amp;", f);
+ else
+ Qchar(c, f);
+ break;
+
+ default: Qchar(c, f);
+ break;
+ }
+ }
+} /* text */
+
+
+static int
+endofcode(int escape, int offset, MMIOT *f)
+{
+ switch (escape) {
+ case 2: if ( peek(f, offset+1) == '`' ) {
+ shift(f,1);
+ case 1: shift(f,offset);
+ return 1;
+ }
+ default:return 0;
+ }
+}
+
+
+/* the only characters that have special meaning in a code block are
+ * `<' and `&' , which are /always/ expanded to &lt; and &amp;
+ */
+static void
+code(int escape, MMIOT *f)
+{
+ int c;
+
+ if ( escape && (peek(f,1) == ' ') )
+ shift(f,1);
+
+ while ( (c = pull(f)) != EOF ) {
+ switch (c) {
+ case ' ': if ( peek(f,1) == '`' && endofcode(escape, 1, f) )
+ return;
+ Qchar(c, f);
+ break;
+
+ case '`': if ( endofcode(escape, 0, f) )
+ return;
+ Qchar(c, f);
+ break;
+
+ case '\\': cputc(c, f);
+ if ( peek(f,1) == '>' || (c = pull(f)) == EOF )
+ break;
+
+ default: cputc(c, f);
+ break;
+ }
+ }
+} /* code */
+
+
+/* print a header block
+ */
+static void
+printheader(Paragraph *pp, MMIOT *f)
+{
+ Qprintf(f, "<h%d>", pp->hnumber);
+ push(T(pp->text->text), S(pp->text->text), f);
+ text(f);
+ Qprintf(f, "</h%d>", pp->hnumber);
+}
+
+
+static int
+printblock(Paragraph *pp, MMIOT *f)
+{
+ Line *t = pp->text;
+ static char *Begin[] = { "", "<p>", "<center>" };
+ static char *End[] = { "", "</p>","</center>" };
+
+ while (t) {
+ if ( S(t->text) ) {
+ if ( S(t->text) > 2 && T(t->text)[S(t->text)-2] == ' '
+ && T(t->text)[S(t->text)-1] == ' ') {
+ push(T(t->text), S(t->text)-2, f);
+ push("<br/>\n", 6, f);
+ }
+ else {
+ push(T(t->text), S(t->text), f);
+ if ( t->next )
+ push("\n", 1, f);
+ }
+ }
+ t = t->next;
+ }
+ Qstring(Begin[pp->align], f);
+ text(f);
+ Qstring(End[pp->align], f);
+ return 1;
+}
+
+
+static void
+printcode(Line *t, MMIOT *f)
+{
+ int blanks;
+
+ for ( blanks = 0; t ; t = t->next )
+ if ( S(t->text) > t->dle ) {
+ while ( blanks ) {
+ push("\n", 1, f);
+ --blanks;
+ }
+ push(T(t->text), S(t->text), f);
+ push("\n", 1, f);
+ }
+ else blanks++;
+
+ Qstring("<pre name=\"code\" class=\"cpp\" >", f);
+ code(0, f);
+ Qstring("</pre>", f);
+}
+
+
+static void
+printhtml(Line *t, MMIOT *f)
+{
+ int blanks;
+
+ for ( blanks=0; t ; t = t->next )
+ if ( S(t->text) ) {
+ for ( ; blanks; --blanks )
+ Qchar('\n', f);
+
+ Qwrite(T(t->text), S(t->text), f);
+ Qchar('\n', f);
+ }
+ else
+ blanks++;
+}
+
+
+static void
+htmlify(Paragraph *p, char *block, MMIOT *f)
+{
+ emblock(f);
+ if ( block ) Qprintf(f, "<%s>", block);
+ emblock(f);
+
+ while (( p = display(p, f) )) {
+ emblock(f);
+ Qstring("\n\n", f);
+ }
+
+ if ( block ) Qprintf(f, "</%s>", block);
+ emblock(f);
+}
+
+
+#if DL_TAG_EXTENSION
+static void
+definitionlist(Paragraph *p, MMIOT *f)
+{
+ Line *tag;
+
+ if ( p ) {
+ Qstring("<dl>\n", f);
+
+ for ( ; p ; p = p->next) {
+ for ( tag = p->text; tag; tag = tag->next ) {
+ Qstring("<dt>", f);
+ reparse(T(tag->text), S(tag->text), 0, f);
+ Qstring("</dt>\n", f);
+ }
+
+ htmlify(p->down, "dd", f);
+ }
+
+ Qstring("</dl>", f);
+ }
+}
+#endif
+
+
+static void
+listdisplay(int typ, Paragraph *p, MMIOT* f)
+{
+ if ( p ) {
+ Qprintf(f, "<%cl>\n", (typ==UL)?'u':'o');
+
+ for ( ; p ; p = p->next ) {
+ htmlify(p->down, "li", f);
+ Qchar('\n', f);
+ }
+
+ Qprintf(f, "</%cl>\n", (typ==UL)?'u':'o');
+ }
+}
+
+
+/* dump out a Paragraph in the desired manner
+ */
+static Paragraph*
+display(Paragraph *p, MMIOT *f)
+{
+ if ( !p ) return 0;
+
+ switch ( p->typ ) {
+ case STYLE:
+ case WHITESPACE:
+ break;
+
+ case HTML:
+ printhtml(p->text, f);
+ break;
+
+ case CODE:
+ printcode(p->text, f);
+ break;
+
+ case QUOTE:
+ htmlify(p->down, "blockquote", f);
+ break;
+
+ case UL:
+ case OL:
+ listdisplay(p->typ, p->down, f);
+ break;
+
+#if DL_TAG_EXTENSION
+ case DL:
+ definitionlist(p->down, f);
+ break;
+#endif
+
+ case HR:
+ Qstring("<hr />", f);
+ break;
+
+ case HDR:
+ printheader(p, f);
+ break;
+
+ default:
+ printblock(p, f);
+ break;
+ }
+ return p->next;
+}
+
+
+/*
+ * dump out stylesheet sections.
+ */
+static int
+stylesheets(Paragraph *p, FILE *f)
+{
+ Line* q;
+
+ for ( ; p ; p = p->next ) {
+ if ( p->typ == STYLE ) {
+ for ( q = p->text; q ; q = q->next )
+ if ( fwrite(T(q->text), S(q->text), 1, f) == 1 )
+ putc('\n', f);
+ else
+ return EOF;
+ }
+ if ( p->down && (stylesheets(p->down, f) == EOF) )
+ return EOF;
+ }
+ return 0;
+}
+
+
+/* return a pointer to the compiled markdown
+ * document.
+ */
+int
+mkd_document(Document *p, char **res)
+{
+ if ( p && p->compiled ) {
+ if ( ! p->html ) {
+ htmlify(p->code, 0, p->ctx);
+ p->html = 1;
+ }
+
+ *res = T(p->ctx->out);
+ return S(p->ctx->out);
+ }
+ return EOF;
+}
+
+
+/* public interface for reparse()
+ */
+int
+mkd_text(char *bfr, int size, FILE *output, int flags)
+{
+ MMIOT f;
+
+ ___mkd_initmmiot(&f, 0);
+ f.flags = flags & USER_FLAGS;
+
+ reparse(bfr, size, 0, &f);
+ emblock(&f);
+ if ( flags & CDATA_OUTPUT )
+ ___mkd_xml(T(f.out), S(f.out), output);
+ else
+ fwrite(T(f.out), S(f.out), 1, output);
+
+ ___mkd_freemmiot(&f, 0);
+ return 0;
+}
+
+
+/* dump any embedded styles
+ */
+int
+mkd_style(Document *d, FILE *f)
+{
+ if ( d && d->compiled )
+ return stylesheets(d->code, f);
+ return EOF;
+}
+
866 libs/markdown.c
@@ -0,0 +1,866 @@
+/* markdown: a C implementation of John Gruber's Markdown markup language.
+ *
+ * Copyright (C) 2007 David L Parsons.
+ * The redistribution terms are provided in the COPYRIGHT file that must
+ * be distributed with this source code.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "config.h"
+
+#include "cstring.h"
+#include "markdown.h"
+#include "amalloc.h"
+
+/* block-level tags for passing html blocks through the blender
+ */
+struct kw {
+ char *id;
+ int siz;
+} ;
+
+#define KW(x) { x, sizeof(x)-1 }
+
+static struct kw blocktags[] = { KW("!--"), KW("STYLE"), KW("SCRIPT"),
+ KW("ADDRESS"), KW("BDO"), KW("BLOCKQUOTE"),
+ KW("CENTER"), KW("DFN"), KW("DIV"), KW("H1"),
+ KW("H2"), KW("H3"), KW("H4"), KW("H5"),
+ KW("H6"), KW("LISTING"), KW("NOBR"),
+ KW("UL"), KW("P"), KW("OL"), KW("DL"),
+ KW("PLAINTEXT"), KW("PRE"), KW("TABLE"),
+ KW("WBR"), KW("XMP"), KW("HR"), KW("BR") };
+#define SZTAGS (sizeof blocktags / sizeof blocktags[0])
+#define MAXTAG 11 /* sizeof "BLOCKQUOTE" */
+
+typedef int (*stfu)(const void*,const void*);
+
+typedef ANCHOR(Paragraph) ParagraphRoot;
+
+
+/* case insensitive string sort (for qsort() and bsearch() of block tags)
+ */
+static int
+casort(struct kw *a, struct kw *b)
+{
+ if ( a->siz != b->siz )
+ return a->siz - b->siz;
+ return strncasecmp(a->id, b->id, b->siz);
+}
+
+
+/* case insensitive string sort for Footnote tags.
+ */
+int
+__mkd_footsort(Footnote *a, Footnote *b)
+{
+ int i;
+ char ac, bc;
+
+ if ( S(a->tag) != S(b->tag) )
+ return S(a->tag) - S(b->tag);
+
+ for ( i=0; i < S(a->tag); i++) {
+ ac = tolower(T(a->tag)[i]);
+ bc = tolower(T(b->tag)[i]);
+
+ if ( isspace(ac) && isspace(bc) )
+ continue;
+ if ( ac != bc )
+ return ac - bc;
+ }
+ return 0;
+}
+
+
+/* find the first blank character after position <i>
+ */
+static int
+nextblank(Line *t, int i)
+{
+ while ( (i < S(t->text)) && !isspace(T(t->text)[i]) )
+ ++i;
+ return i;
+}
+
+
+/* find the next nonblank character after position <i>
+ */
+static int
+nextnonblank(Line *t, int i)
+{
+ while ( (i < S(t->text)) && isspace(T(t->text)[i]) )
+ ++i;
+ return i;
+}
+
+
+/* find the first nonblank character on the Line.
+ */
+int
+mkd_firstnonblank(Line *p)
+{
+ return nextnonblank(p,0);
+}
+
+
+static int
+blankline(Line *p)
+{
+ return ! (p && (S(p->text) > p->dle) );
+}
+
+
+static Line *
+skipempty(Line *p)
+{
+ while ( p && (p->dle == S(p->text)) )
+ p = p->next;
+ return p;
+}
+
+
+static char *
+isopentag(Line *p)
+{
+ int i=0, len;
+ struct kw key, *ret;
+
+ if ( !p ) return 0;
+
+ len = S(p->text);
+
+ if ( len < 3 || T(p->text)[0] != '<' )
+ return 0;
+
+ /* find how long the tag is so we can check to see if
+ * it's a block-level tag
+ */
+ for ( i=1; i < len && T(p->text)[i] != '>'
+ && T(p->text)[i] != '/'
+ && !isspace(T(p->text)[i]); ++i )
+ ;
+
+ key.id = T(p->text)+1;
+ key.siz = i-1;
+
+ if ( (ret = bsearch(&key,blocktags,SZTAGS,sizeof key, (stfu)casort)) )
+ return ret->id;
+
+ return 0;
+}
+
+
+static int
+selfclose(Line *t, char *tag)
+{
+ char *q = T(t->text);
+ int siz = strlen(tag);
+ int i;
+
+ if ( strcasecmp(tag, "HR") == 0 || strcasecmp(tag, "BR") == 0 )
+ /* <HR> and <BR> are self-closing block-level tags,
+ */
+ return 1;
+
+ i = S(t->text) - (siz + 3);
+
+ /* we specialcase start and end tags on the same line.
+ */
+ return ( i > 0 ) && (q[i] == '<') && (q[i+1] == '/')
+ && (q[i+2+siz] == '>')
+ && (strncasecmp(&q[i+2], tag, siz) == 0);
+}
+
+
+static Line *
+htmlblock(Paragraph *p, char *tag)
+{
+ Line *t = p->text, *ret;
+ int closesize;
+ char close[MAXTAG+4];
+
+ if ( selfclose(t, tag) || (strlen(tag) >= MAXTAG) ) {
+ ret = t->next;
+ t->next = 0;
+ return ret;
+ }
+
+ closesize = sprintf(close, "</%s>", tag);
+
+ for ( ; t ; t = t->next) {
+ if ( strncasecmp(T(t->text), close, closesize) == 0 ) {
+ ret = t->next;
+ t->next = 0;
+ return ret;
+ }
+ }
+ return 0;
+}
+
+
+static Line *
+comment(Paragraph *p, char *key)
+{
+ Line *t, *ret;
+
+ for ( t = p->text; t ; t = t->next) {
+ if ( strstr(T(t->text), "-->") ) {
+ ret = t->next;
+ t->next = 0;
+ return ret;
+ }
+ }
+ return t;
+
+}
+
+
+/* footnotes look like ^<whitespace>{0,3}[stuff]: <content>$
+ */
+static int
+isfootnote(Line *t)
+{
+ int i;
+
+ if ( ( (i = t->dle) > 3) || (T(t->text)[i] != '[') )
+ return 0;
+
+ for ( ++i; i < S(t->text) ; ++i ) {
+ if ( T(t->text)[i] == '[' )
+ return 0;
+ else if ( T(t->text)[i] == ']' && T(t->text)[i+1] == ':' )
+ return 1;
+ }
+ return 0;
+}
+
+
+static int
+isquote(Line *t)
+{
+ return ( T(t->text)[0] == '>' );
+}
+
+
+static int
+dashchar(char c)
+{
+ return (c == '*') || (c == '-') || (c == '_');
+}
+
+
+static int
+iscode(Line *t)
+{
+ return (t->dle >= 4);
+}
+
+
+static int
+ishr(Line *t)
+{
+ int i, count=0;
+ char dash = 0;
+ char c;
+
+ if ( iscode(t) ) return 0;
+
+ for ( i = 0; i < S(t->text); i++) {
+ c = T(t->text)[i];
+ if ( (dash == 0) && dashchar(c) )
+ dash = c;
+
+ if ( c == dash ) ++count;
+ else if ( !isspace(c) )
+ return 0;
+ }
+ return (count >= 3);
+}
+
+
+static int
+ishdr(Line *t, int *htyp)
+{
+ int i, j;
+
+
+ /* first check for etx-style ###HEADER###
+ */
+
+ /* leading run of `#`'s ?
+ */
+ for ( i=0; T(t->text)[i] == '#'; ++i)
+ ;
+
+ if ( i ) {
+ i = nextnonblank(t, i);
+
+ j = S(t->text)-1;
+
+ while ( (j > i) && (T(t->text)[j] == '#') )
+ --j;
+
+ while ( (j > 1) && isspace(T(t->text)[j]) )
+ --j;
+
+ if ( i < j ) {
+ *htyp = ETX;
+ return 1;
+ }
+ }
+
+ /* then check for setext-style HEADER
+ * ======
+ */
+
+ if ( t->next ) {
+ char *q = T(t->next->text);
+
+ if ( (*q == '=') || (*q == '-') ) {
+ for (i=1; i < S(t->next->text); i++)
+ if ( q[0] != q[i] )
+ return 0;
+ *htyp = SETEXT;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+static int
+isdefinition(Line *t)
+{
+#if DL_TAG_EXTENSION
+ return t && t->next
+ && (S(t->text) > 2)
+ && (t->dle == 0)
+ && (T(t->text)[0] == '=')
+ && (T(t->text)[S(t->text)-1] == '=')
+ && ( (t->next->dle >= 4) || isdefinition(t->next) );
+#else
+ return 0;
+#endif
+}
+
+
+static int
+islist(Line *t, int *trim)
+{
+ int i, j;
+ char *q;
+
+ if ( iscode(t) || blankline(t) || ishdr(t,&i) || ishr(t) )
+ return 0;
+
+ if ( isdefinition(t) ) {
+ *trim = 4;
+ return DL;
+ }
+
+ if ( strchr("*-+", T(t->text)[t->dle]) && isspace(T(t->text)[t->dle+1]) ) {
+ i = nextnonblank(t, t->dle+1);
+ *trim = (i > 4) ? 4 : i;
+ return UL;
+ }
+
+ if ( (j = nextblank(t,t->dle)) > t->dle ) {
+ if ( T(t->text)[j-1] == '.' ) {
+ strtoul(T(t->text)+t->dle, &q, 10);
+ if ( (q > T(t->text)+t->dle) && (q == T(t->text) + (j-1)) ) {
+ j = nextnonblank(t,j);
+ *trim = j;
+ return OL;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static Line *
+headerblock(Paragraph *pp, int htyp)
+{
+ Line *ret = 0;
+ Line *p = pp->text;
+ int i, j;
+
+ switch (htyp) {
+ case SETEXT:
+ /* p->text is header, p->next->text is -'s or ='s
+ */
+ pp->hnumber = (T(p->next->text)[0] == '=') ? 1 : 2;
+
+ ret = p->next->next;
+ ___mkd_freeLine(p->next);
+ p->next = 0;
+ break;
+
+ case ETX:
+ /* p->text is ###header###, so we need to trim off
+ * the leading and trailing `#`'s
+ */
+
+ for (i=0; T(p->text)[i] == T(p->text)[0]; i++)
+ ;
+
+ pp->hnumber = i;
+
+ CLIP(p->text, 0, i);
+
+ for (j=S(p->text); j && (T(p->text)[j-1] == '#'); --j)
+ ;
+
+ S(p->text) = j;
+
+ ret = p->next;
+ p->next = 0;
+ break;
+ }
+ return ret;
+}
+
+
+static Line *
+codeblock(Paragraph *p)
+{
+ Line *t = p->text, *r;
+
+ /* HORRIBLE STANDARDS KLUDGE: the first line of every block
+ * has trailing whitespace trimmed off.
+ */
+ while ( S(t->text) && isspace(T(t->text)[S(t->text)-1]) )
+ --S(t->text);
+
+ for ( ; t; t = r ) {
+ CLIP(t->text,0,4);
+ t->dle = mkd_firstnonblank(t);
+
+ if ( !( (r = skipempty(t->next)) && iscode(r)) ) {
+ ___mkd_freeLineRange(t,r);
+ t->next = 0;
+ return r;
+ }
+ }
+ return t;
+}
+
+
+static int
+centered(Line *first, Line *last)
+{
+
+ if ( first&&last ) {
+ int len = S(last->text);
+
+ if ( (len > 2) && (strncmp(T(first->text), "->", 2) == 0)
+ && (strncmp(T(last->text)+len-2, "<-", 2) == 0) ) {
+ CLIP(first->text, 0, 2);
+ S(last->text) -= 2;
+ return CENTER;
+ }
+ }
+ return 0;
+}
+
+
+static int
+endoftextblock(Line *t, int toplevelblock)
+{
+ int z;