rdiscount 1.2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +52 -0
 - data/README +54 -0
 - data/Rakefile +169 -0
 - data/ext/amalloc.h +29 -0
 - data/ext/config.h +8 -0
 - data/ext/cstring.h +68 -0
 - data/ext/docheader.c +43 -0
 - data/ext/dumptree.c +147 -0
 - data/ext/extconf.rb +14 -0
 - data/ext/generate.c +1319 -0
 - data/ext/markdown.c +866 -0
 - data/ext/markdown.h +125 -0
 - data/ext/mkdio.c +223 -0
 - data/ext/mkdio.h +58 -0
 - data/ext/rbstrio.c +48 -0
 - data/ext/rbstrio.h +4 -0
 - data/ext/rdiscount.c +48 -0
 - data/ext/resource.c +167 -0
 - data/lib/rdiscount.rb +73 -0
 - data/test/benchmark.rb +49 -0
 - data/test/benchmark.txt +306 -0
 - data/test/rdiscount_test.rb +78 -0
 - metadata +77 -0
 
    
        data/ext/markdown.h
    ADDED
    
    | 
         @@ -0,0 +1,125 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #ifndef _MARKDOWN_D
         
     | 
| 
      
 2 
     | 
    
         
            +
            #define _MARKDOWN_D
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            #include "cstring.h"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            /* reference-style links (and images) are stored in an array
         
     | 
| 
      
 7 
     | 
    
         
            +
             * of footnotes.
         
     | 
| 
      
 8 
     | 
    
         
            +
             */
         
     | 
| 
      
 9 
     | 
    
         
            +
            typedef struct footnote {
         
     | 
| 
      
 10 
     | 
    
         
            +
                Cstring tag;		/* the tag for the reference link */
         
     | 
| 
      
 11 
     | 
    
         
            +
                Cstring link;		/* what this footnote points to */
         
     | 
| 
      
 12 
     | 
    
         
            +
                Cstring title;		/* what it's called (TITLE= attribute) */
         
     | 
| 
      
 13 
     | 
    
         
            +
                int height, width;		/* dimensions (for image link) */
         
     | 
| 
      
 14 
     | 
    
         
            +
            } Footnote;
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            /* each input line is read into a Line, which contains the line,
         
     | 
| 
      
 17 
     | 
    
         
            +
             * the offset of the first non-space character [this assumes 
         
     | 
| 
      
 18 
     | 
    
         
            +
             * that all tabs will be expanded to spaces!], and a pointer to
         
     | 
| 
      
 19 
     | 
    
         
            +
             * the next line.
         
     | 
| 
      
 20 
     | 
    
         
            +
             */
         
     | 
| 
      
 21 
     | 
    
         
            +
            typedef struct line {
         
     | 
| 
      
 22 
     | 
    
         
            +
                Cstring text;
         
     | 
| 
      
 23 
     | 
    
         
            +
                struct line *next;
         
     | 
| 
      
 24 
     | 
    
         
            +
                int dle;
         
     | 
| 
      
 25 
     | 
    
         
            +
            } Line;
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            /* a paragraph is a collection of Lines, with links to the next paragraph
         
     | 
| 
      
 29 
     | 
    
         
            +
             * and (if it's a QUOTE, UL, or OL) to the reparsed contents of this
         
     | 
| 
      
 30 
     | 
    
         
            +
             * paragraph.
         
     | 
| 
      
 31 
     | 
    
         
            +
             */
         
     | 
| 
      
 32 
     | 
    
         
            +
            typedef struct paragraph {
         
     | 
| 
      
 33 
     | 
    
         
            +
                struct paragraph *next;	/* next paragraph */
         
     | 
| 
      
 34 
     | 
    
         
            +
                struct paragraph *down;	/* recompiled contents of this paragraph */
         
     | 
| 
      
 35 
     | 
    
         
            +
                struct line *text;		/* all the text in this paragraph */
         
     | 
| 
      
 36 
     | 
    
         
            +
                enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
         
     | 
| 
      
 37 
     | 
    
         
            +
            	   HTML, STYLE, DL, UL, OL, LISTITEM,
         
     | 
| 
      
 38 
     | 
    
         
            +
            	   HDR, HR } typ;
         
     | 
| 
      
 39 
     | 
    
         
            +
                enum { IMPLICIT=0, PARA, CENTER} align;
         
     | 
| 
      
 40 
     | 
    
         
            +
                int hnumber;		/* <Hn> for typ == HDR */
         
     | 
| 
      
 41 
     | 
    
         
            +
            } Paragraph;
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            enum { ETX, SETEXT };	/* header types */
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            typedef struct block {
         
     | 
| 
      
 47 
     | 
    
         
            +
                enum { bTEXT, bSTAR, bUNDER } b_type;
         
     | 
| 
      
 48 
     | 
    
         
            +
                int  b_count;
         
     | 
| 
      
 49 
     | 
    
         
            +
                char b_char;
         
     | 
| 
      
 50 
     | 
    
         
            +
                Cstring b_text;
         
     | 
| 
      
 51 
     | 
    
         
            +
                Cstring b_post;
         
     | 
| 
      
 52 
     | 
    
         
            +
            } block;
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            typedef STRING(block) Qblock;
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            /* a magic markdown io thing holds all the data structures needed to
         
     | 
| 
      
 58 
     | 
    
         
            +
             * do the backend processing of a markdown document
         
     | 
| 
      
 59 
     | 
    
         
            +
             */
         
     | 
| 
      
 60 
     | 
    
         
            +
            typedef struct mmiot {
         
     | 
| 
      
 61 
     | 
    
         
            +
                Cstring out;
         
     | 
| 
      
 62 
     | 
    
         
            +
                Cstring in;
         
     | 
| 
      
 63 
     | 
    
         
            +
                Qblock Q;
         
     | 
| 
      
 64 
     | 
    
         
            +
                int isp;
         
     | 
| 
      
 65 
     | 
    
         
            +
                STRING(Footnote) *footnotes;
         
     | 
| 
      
 66 
     | 
    
         
            +
                int flags;
         
     | 
| 
      
 67 
     | 
    
         
            +
            #define DENY_A		0x0001
         
     | 
| 
      
 68 
     | 
    
         
            +
            #define DENY_IMG	0x0002
         
     | 
| 
      
 69 
     | 
    
         
            +
            #define DENY_SMARTY	0x0004
         
     | 
| 
      
 70 
     | 
    
         
            +
            #define INSIDE_TAG	0x0020
         
     | 
| 
      
 71 
     | 
    
         
            +
            #define NO_PSEUDO_PROTO	0x0040
         
     | 
| 
      
 72 
     | 
    
         
            +
            #define CDATA_OUTPUT	0x0080
         
     | 
| 
      
 73 
     | 
    
         
            +
            #define USER_FLAGS	0x00FF
         
     | 
| 
      
 74 
     | 
    
         
            +
            #define EMBEDDED	DENY_A|DENY_IMG|NO_PSEUDO_PROTO|CDATA_OUTPUT
         
     | 
| 
      
 75 
     | 
    
         
            +
                char *base;
         
     | 
| 
      
 76 
     | 
    
         
            +
            } MMIOT;
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            /*
         
     | 
| 
      
 80 
     | 
    
         
            +
             * the mkdio text input functions return a document structure,
         
     | 
| 
      
 81 
     | 
    
         
            +
             * which contains a header (retrieved from the document if
         
     | 
| 
      
 82 
     | 
    
         
            +
             * markdown was configured * with the * --enable-pandoc-header
         
     | 
| 
      
 83 
     | 
    
         
            +
             * and the document begins with a pandoc-style header) and the
         
     | 
| 
      
 84 
     | 
    
         
            +
             * root of the linked list of Lines.
         
     | 
| 
      
 85 
     | 
    
         
            +
             */
         
     | 
| 
      
 86 
     | 
    
         
            +
            typedef struct document {
         
     | 
| 
      
 87 
     | 
    
         
            +
                Line *headers;		/* title -> author(s) -> date */
         
     | 
| 
      
 88 
     | 
    
         
            +
                ANCHOR(Line) content;	/* uncompiled text, not valid after compile() */
         
     | 
| 
      
 89 
     | 
    
         
            +
                Paragraph *code;		/* intermediate code generated by compile() */
         
     | 
| 
      
 90 
     | 
    
         
            +
                int compiled;		/* set after mkd_compile() */
         
     | 
| 
      
 91 
     | 
    
         
            +
                int html;			/* set after (internal) htmlify() */
         
     | 
| 
      
 92 
     | 
    
         
            +
                int tabstop;		/* for properly expanding tabs (ick) */
         
     | 
| 
      
 93 
     | 
    
         
            +
                MMIOT *ctx;			/* backend buffers, flags, and structures */
         
     | 
| 
      
 94 
     | 
    
         
            +
                char *base;			/* url basename for url fragments */
         
     | 
| 
      
 95 
     | 
    
         
            +
            } Document;
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            extern int  mkd_firstnonblank(Line *);
         
     | 
| 
      
 99 
     | 
    
         
            +
            extern int  mkd_compile(Document *, int);
         
     | 
| 
      
 100 
     | 
    
         
            +
            extern int  mkd_document(Document *, char **);
         
     | 
| 
      
 101 
     | 
    
         
            +
            extern int  mkd_generatehtml(Document *, FILE *);
         
     | 
| 
      
 102 
     | 
    
         
            +
            extern void mkd_cleanup(Document *);
         
     | 
| 
      
 103 
     | 
    
         
            +
            extern int  mkd_text(char *, int, FILE*, int);
         
     | 
| 
      
 104 
     | 
    
         
            +
            extern void mkd_basename(Document*, char *);
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            extern Document *mkd_in(FILE *, int);
         
     | 
| 
      
 107 
     | 
    
         
            +
            extern Document *mkd_string(char*,int, int);
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            #define NO_HEADER	0x0100
         
     | 
| 
      
 110 
     | 
    
         
            +
            #define STD_TABSTOP	0x0200
         
     | 
| 
      
 111 
     | 
    
         
            +
            #define INPUT_MASK	(NO_HEADER|STD_TABSTOP)
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            /* internal resource handling functions.
         
     | 
| 
      
 115 
     | 
    
         
            +
             */
         
     | 
| 
      
 116 
     | 
    
         
            +
            extern void ___mkd_freeLine(Line *);
         
     | 
| 
      
 117 
     | 
    
         
            +
            extern void ___mkd_freeLines(Line *);
         
     | 
| 
      
 118 
     | 
    
         
            +
            extern void ___mkd_freeParagraph(Paragraph *);
         
     | 
| 
      
 119 
     | 
    
         
            +
            extern void ___mkd_freefootnotes(MMIOT *);
         
     | 
| 
      
 120 
     | 
    
         
            +
            extern void ___mkd_initmmiot(MMIOT *, void *);
         
     | 
| 
      
 121 
     | 
    
         
            +
            extern void ___mkd_freemmiot(MMIOT *, void *);
         
     | 
| 
      
 122 
     | 
    
         
            +
            extern void ___mkd_freeLineRange(Line *, Line *);
         
     | 
| 
      
 123 
     | 
    
         
            +
            extern void ___mkd_xml(char *, int, FILE *);
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            #endif/*_MARKDOWN_D*/
         
     | 
    
        data/ext/mkdio.c
    ADDED
    
    | 
         @@ -0,0 +1,223 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             * mkdio -- markdown front end input functions
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
             * Copyright (C) 2007 David L Parsons.
         
     | 
| 
      
 5 
     | 
    
         
            +
             * The redistribution terms are provided in the COPYRIGHT file that must
         
     | 
| 
      
 6 
     | 
    
         
            +
             * be distributed with this source code.
         
     | 
| 
      
 7 
     | 
    
         
            +
             */
         
     | 
| 
      
 8 
     | 
    
         
            +
            #include "config.h"
         
     | 
| 
      
 9 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 11 
     | 
    
         
            +
            #include <ctype.h>
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            #include "cstring.h"
         
     | 
| 
      
 14 
     | 
    
         
            +
            #include "markdown.h"
         
     | 
| 
      
 15 
     | 
    
         
            +
            #include "amalloc.h"
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            typedef ANCHOR(Line) LineAnchor;
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            /* create a new blank Document
         
     | 
| 
      
 20 
     | 
    
         
            +
             */
         
     | 
| 
      
 21 
     | 
    
         
            +
            static Document*
         
     | 
| 
      
 22 
     | 
    
         
            +
            new_Document()
         
     | 
| 
      
 23 
     | 
    
         
            +
            {
         
     | 
| 
      
 24 
     | 
    
         
            +
                Document *ret = calloc(sizeof(Document), 1);
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                if ( ret ) {
         
     | 
| 
      
 27 
     | 
    
         
            +
            	if (( ret->ctx = calloc(sizeof(MMIOT), 1) ))
         
     | 
| 
      
 28 
     | 
    
         
            +
            	    return ret;
         
     | 
| 
      
 29 
     | 
    
         
            +
            	free(ret);
         
     | 
| 
      
 30 
     | 
    
         
            +
                }
         
     | 
| 
      
 31 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 32 
     | 
    
         
            +
            }
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            /* add a line to the markdown input chain
         
     | 
| 
      
 36 
     | 
    
         
            +
             */
         
     | 
| 
      
 37 
     | 
    
         
            +
            static void
         
     | 
| 
      
 38 
     | 
    
         
            +
            queue(Document* a, Cstring *line)
         
     | 
| 
      
 39 
     | 
    
         
            +
            {
         
     | 
| 
      
 40 
     | 
    
         
            +
                Line *p = calloc(sizeof *p, 1);
         
     | 
| 
      
 41 
     | 
    
         
            +
                unsigned char c;
         
     | 
| 
      
 42 
     | 
    
         
            +
                int xp = 0;
         
     | 
| 
      
 43 
     | 
    
         
            +
                int           size = S(*line);
         
     | 
| 
      
 44 
     | 
    
         
            +
                unsigned char *str = T(*line);
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                CREATE(p->text);
         
     | 
| 
      
 47 
     | 
    
         
            +
                ATTACH(a->content, p);
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                while ( size-- ) {
         
     | 
| 
      
 50 
     | 
    
         
            +
            	if ( (c = *str++) == '\t' ) {
         
     | 
| 
      
 51 
     | 
    
         
            +
            	    /* expand tabs into ->tabstop spaces.  We use ->tabstop
         
     | 
| 
      
 52 
     | 
    
         
            +
            	     * because the ENTIRE FREAKING COMPUTER WORLD uses editors
         
     | 
| 
      
 53 
     | 
    
         
            +
            	     * that don't do ^T/^D, but instead use tabs for indentation,
         
     | 
| 
      
 54 
     | 
    
         
            +
            	     * and, of course, set their tabs down to 4 spaces 
         
     | 
| 
      
 55 
     | 
    
         
            +
            	     */
         
     | 
| 
      
 56 
     | 
    
         
            +
            	    do {
         
     | 
| 
      
 57 
     | 
    
         
            +
            		EXPAND(p->text) = ' ';
         
     | 
| 
      
 58 
     | 
    
         
            +
            	    } while ( ++xp % a->tabstop );
         
     | 
| 
      
 59 
     | 
    
         
            +
            	}
         
     | 
| 
      
 60 
     | 
    
         
            +
            	else if ( c >= ' ' ) {
         
     | 
| 
      
 61 
     | 
    
         
            +
            	    EXPAND(p->text) = c;
         
     | 
| 
      
 62 
     | 
    
         
            +
            	    ++xp;
         
     | 
| 
      
 63 
     | 
    
         
            +
            	}
         
     | 
| 
      
 64 
     | 
    
         
            +
                }
         
     | 
| 
      
 65 
     | 
    
         
            +
                EXPAND(p->text) = 0;
         
     | 
| 
      
 66 
     | 
    
         
            +
                S(p->text)--;
         
     | 
| 
      
 67 
     | 
    
         
            +
                p->dle = mkd_firstnonblank(p);
         
     | 
| 
      
 68 
     | 
    
         
            +
            }
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            /* trim leading blanks from a header line
         
     | 
| 
      
 72 
     | 
    
         
            +
             */
         
     | 
| 
      
 73 
     | 
    
         
            +
            static void
         
     | 
| 
      
 74 
     | 
    
         
            +
            snip(Line *p)
         
     | 
| 
      
 75 
     | 
    
         
            +
            {
         
     | 
| 
      
 76 
     | 
    
         
            +
                CLIP(p->text, 0, 1);
         
     | 
| 
      
 77 
     | 
    
         
            +
                p->dle = mkd_firstnonblank(p);
         
     | 
| 
      
 78 
     | 
    
         
            +
            }
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            /* build a Document from any old input.
         
     | 
| 
      
 82 
     | 
    
         
            +
             */
         
     | 
| 
      
 83 
     | 
    
         
            +
            typedef unsigned int (*getc_func)(void*);
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            Document *
         
     | 
| 
      
 86 
     | 
    
         
            +
            populate(getc_func getc, void* ctx, int flags)
         
     | 
| 
      
 87 
     | 
    
         
            +
            {
         
     | 
| 
      
 88 
     | 
    
         
            +
                Cstring line;
         
     | 
| 
      
 89 
     | 
    
         
            +
                Document *a = new_Document();
         
     | 
| 
      
 90 
     | 
    
         
            +
                int c;
         
     | 
| 
      
 91 
     | 
    
         
            +
            #ifdef PANDOC_HEADER
         
     | 
| 
      
 92 
     | 
    
         
            +
                int pandoc = 0;
         
     | 
| 
      
 93 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                if ( !a ) return 0;
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                a->tabstop = (flags & STD_TABSTOP) ? 4 : TABSTOP;
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                CREATE(line);
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                while ( (c = (*getc)(ctx)) != EOF ) {
         
     | 
| 
      
 102 
     | 
    
         
            +
            	if ( c == '\n' ) {
         
     | 
| 
      
 103 
     | 
    
         
            +
            #ifdef PANDOC_HEADER
         
     | 
| 
      
 104 
     | 
    
         
            +
            	    if ( pandoc != EOF && pandoc < 3 ) {
         
     | 
| 
      
 105 
     | 
    
         
            +
            		if ( S(line) && (T(line)[0] == '%') )
         
     | 
| 
      
 106 
     | 
    
         
            +
            		    pandoc++;
         
     | 
| 
      
 107 
     | 
    
         
            +
            		else
         
     | 
| 
      
 108 
     | 
    
         
            +
            		    pandoc = EOF;
         
     | 
| 
      
 109 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 110 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 111 
     | 
    
         
            +
            	    queue(a, &line);
         
     | 
| 
      
 112 
     | 
    
         
            +
            	    S(line) = 0;
         
     | 
| 
      
 113 
     | 
    
         
            +
            	}
         
     | 
| 
      
 114 
     | 
    
         
            +
            	else
         
     | 
| 
      
 115 
     | 
    
         
            +
            	    EXPAND(line) = c;
         
     | 
| 
      
 116 
     | 
    
         
            +
                }
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                if ( S(line) )
         
     | 
| 
      
 119 
     | 
    
         
            +
            	queue(a, &line);
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                DELETE(line);
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            #ifdef PANDOC_HEADER
         
     | 
| 
      
 124 
     | 
    
         
            +
                if ( (pandoc == 3) && !(flags & NO_HEADER) ) {
         
     | 
| 
      
 125 
     | 
    
         
            +
            	/* the first three lines started with %, so we have a header.
         
     | 
| 
      
 126 
     | 
    
         
            +
            	 * clip the first three lines out of content and hang them
         
     | 
| 
      
 127 
     | 
    
         
            +
            	 * off header.
         
     | 
| 
      
 128 
     | 
    
         
            +
            	 */
         
     | 
| 
      
 129 
     | 
    
         
            +
            	a->headers = T(a->content);
         
     | 
| 
      
 130 
     | 
    
         
            +
            	T(a->content) = a->headers->next->next->next;
         
     | 
| 
      
 131 
     | 
    
         
            +
            	a->headers->next->next->next = 0;
         
     | 
| 
      
 132 
     | 
    
         
            +
            	snip(a->headers);
         
     | 
| 
      
 133 
     | 
    
         
            +
            	snip(a->headers->next);
         
     | 
| 
      
 134 
     | 
    
         
            +
            	snip(a->headers->next->next);
         
     | 
| 
      
 135 
     | 
    
         
            +
                }
         
     | 
| 
      
 136 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                return a;
         
     | 
| 
      
 139 
     | 
    
         
            +
            }
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            /* convert a file into a linked list
         
     | 
| 
      
 143 
     | 
    
         
            +
             */
         
     | 
| 
      
 144 
     | 
    
         
            +
            Document *
         
     | 
| 
      
 145 
     | 
    
         
            +
            mkd_in(FILE *f, int flags)
         
     | 
| 
      
 146 
     | 
    
         
            +
            {
         
     | 
| 
      
 147 
     | 
    
         
            +
                return populate((getc_func)fgetc, f, flags & INPUT_MASK);
         
     | 
| 
      
 148 
     | 
    
         
            +
            }
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
            /* return a single character out of a buffer
         
     | 
| 
      
 152 
     | 
    
         
            +
             */
         
     | 
| 
      
 153 
     | 
    
         
            +
            struct string_ctx {
         
     | 
| 
      
 154 
     | 
    
         
            +
                char *data;		/* the unread data */
         
     | 
| 
      
 155 
     | 
    
         
            +
                int   size;		/* and how much is there? */
         
     | 
| 
      
 156 
     | 
    
         
            +
            } ;
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
            static char
         
     | 
| 
      
 160 
     | 
    
         
            +
            strget(struct string_ctx *in)
         
     | 
| 
      
 161 
     | 
    
         
            +
            {
         
     | 
| 
      
 162 
     | 
    
         
            +
                if ( !in->size ) return EOF;
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                --(in->size);
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                return *(in->data)++;
         
     | 
| 
      
 167 
     | 
    
         
            +
            }
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
            /* convert a block of text into a linked list
         
     | 
| 
      
 171 
     | 
    
         
            +
             */
         
     | 
| 
      
 172 
     | 
    
         
            +
            Document *
         
     | 
| 
      
 173 
     | 
    
         
            +
            mkd_string(char *buf, int len, int flags)
         
     | 
| 
      
 174 
     | 
    
         
            +
            {
         
     | 
| 
      
 175 
     | 
    
         
            +
                struct string_ctx about;
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                about.data = buf;
         
     | 
| 
      
 178 
     | 
    
         
            +
                about.size = len;
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                return populate((getc_func)strget, &about, flags & INPUT_MASK);
         
     | 
| 
      
 181 
     | 
    
         
            +
            }
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            /* write the html to a file (xmlified if necessary)
         
     | 
| 
      
 185 
     | 
    
         
            +
             */
         
     | 
| 
      
 186 
     | 
    
         
            +
            int
         
     | 
| 
      
 187 
     | 
    
         
            +
            mkd_generatehtml(Document *p, FILE *output)
         
     | 
| 
      
 188 
     | 
    
         
            +
            {
         
     | 
| 
      
 189 
     | 
    
         
            +
                char *doc;
         
     | 
| 
      
 190 
     | 
    
         
            +
                int szdoc;
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                if ( (szdoc = mkd_document(p, &doc)) != EOF ) {
         
     | 
| 
      
 193 
     | 
    
         
            +
            	if ( p->ctx->flags & CDATA_OUTPUT )
         
     | 
| 
      
 194 
     | 
    
         
            +
            	    ___mkd_xml(doc, szdoc, output);
         
     | 
| 
      
 195 
     | 
    
         
            +
            	else
         
     | 
| 
      
 196 
     | 
    
         
            +
            	    fwrite(doc, szdoc, 1, output);
         
     | 
| 
      
 197 
     | 
    
         
            +
            	putc('\n', output);
         
     | 
| 
      
 198 
     | 
    
         
            +
            	return 0;
         
     | 
| 
      
 199 
     | 
    
         
            +
                }
         
     | 
| 
      
 200 
     | 
    
         
            +
                return -1;
         
     | 
| 
      
 201 
     | 
    
         
            +
            }
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            /* convert some markdown text to html
         
     | 
| 
      
 205 
     | 
    
         
            +
             */
         
     | 
| 
      
 206 
     | 
    
         
            +
            int
         
     | 
| 
      
 207 
     | 
    
         
            +
            markdown(Document *document, FILE *out, int flags)
         
     | 
| 
      
 208 
     | 
    
         
            +
            {
         
     | 
| 
      
 209 
     | 
    
         
            +
                if ( mkd_compile(document, flags) ) {
         
     | 
| 
      
 210 
     | 
    
         
            +
            	mkd_generatehtml(document, out);
         
     | 
| 
      
 211 
     | 
    
         
            +
            	mkd_cleanup(document);
         
     | 
| 
      
 212 
     | 
    
         
            +
            	return 0;
         
     | 
| 
      
 213 
     | 
    
         
            +
                }
         
     | 
| 
      
 214 
     | 
    
         
            +
                return -1;
         
     | 
| 
      
 215 
     | 
    
         
            +
            }
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
            void
         
     | 
| 
      
 219 
     | 
    
         
            +
            mkd_basename(Document *document, char *base)
         
     | 
| 
      
 220 
     | 
    
         
            +
            {
         
     | 
| 
      
 221 
     | 
    
         
            +
                if ( document )
         
     | 
| 
      
 222 
     | 
    
         
            +
            	document->base = base;
         
     | 
| 
      
 223 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/mkdio.h
    ADDED
    
    | 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #ifndef _MKDIO_D
         
     | 
| 
      
 2 
     | 
    
         
            +
            #define _MKDIO_D
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            typedef void MMIOT;
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            /* line builder for markdown()
         
     | 
| 
      
 9 
     | 
    
         
            +
             */
         
     | 
| 
      
 10 
     | 
    
         
            +
            MMIOT *mkd_in(FILE*,int);		/* assemble input from a file */
         
     | 
| 
      
 11 
     | 
    
         
            +
            MMIOT *mkd_string(char*,int,int);	/* assemble input from a buffer */
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            void mkd_basename(MMIOT*,char*);
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            /* compilation, debugging, cleanup
         
     | 
| 
      
 16 
     | 
    
         
            +
             */
         
     | 
| 
      
 17 
     | 
    
         
            +
            int mkd_compile(MMIOT*, int);
         
     | 
| 
      
 18 
     | 
    
         
            +
            int mkd_generatehtml(MMIOT*,FILE*);
         
     | 
| 
      
 19 
     | 
    
         
            +
            int mkd_cleanup(MMIOT*);
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            /* markup functions
         
     | 
| 
      
 22 
     | 
    
         
            +
             */
         
     | 
| 
      
 23 
     | 
    
         
            +
            int mkd_text(char *, int, FILE*, int);
         
     | 
| 
      
 24 
     | 
    
         
            +
            int mkd_style(MMIOT*, FILE*);
         
     | 
| 
      
 25 
     | 
    
         
            +
            int mkd_dump(MMIOT*, FILE*, int, char*);
         
     | 
| 
      
 26 
     | 
    
         
            +
            int markdown(MMIOT*, FILE*, int);
         
     | 
| 
      
 27 
     | 
    
         
            +
            void mkd_basename(MMIOT*,char*);
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            /* header block access
         
     | 
| 
      
 30 
     | 
    
         
            +
             */
         
     | 
| 
      
 31 
     | 
    
         
            +
            char* mkd_doc_title(MMIOT*);
         
     | 
| 
      
 32 
     | 
    
         
            +
            char* mkd_doc_author(MMIOT*);
         
     | 
| 
      
 33 
     | 
    
         
            +
            char* mkd_doc_date(MMIOT*);
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            /* compiled data access
         
     | 
| 
      
 36 
     | 
    
         
            +
             */
         
     | 
| 
      
 37 
     | 
    
         
            +
            int mkd_document(MMIOT*, char**);
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            /* version#.
         
     | 
| 
      
 40 
     | 
    
         
            +
             */
         
     | 
| 
      
 41 
     | 
    
         
            +
            extern char markdown_version[];
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            /* special flags for markdown() and mkd_text()
         
     | 
| 
      
 44 
     | 
    
         
            +
             */
         
     | 
| 
      
 45 
     | 
    
         
            +
            #define MKD_NOLINKS	0x0001	/* don't do link processing, block <a> tags  */
         
     | 
| 
      
 46 
     | 
    
         
            +
            #define MKD_NOIMAGE	0x0002	/* don't do image processing, block <img> */
         
     | 
| 
      
 47 
     | 
    
         
            +
            #define MKD_NOPANTS	0x0004	/* don't run smartypants() */
         
     | 
| 
      
 48 
     | 
    
         
            +
            #define MKD_TAGTEXT	0x0020	/* don't expand `_` and `*` */
         
     | 
| 
      
 49 
     | 
    
         
            +
            #define MKD_NO_EXT	0x0040	/* don't allow pseudo-protocols */
         
     | 
| 
      
 50 
     | 
    
         
            +
            #define MKD_CDATA	0x0080	/* generate code for xml ![CDATA[...]] */
         
     | 
| 
      
 51 
     | 
    
         
            +
            #define MKD_EMBED	MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            /* special flags for mkd_in() and mkd_string()
         
     | 
| 
      
 54 
     | 
    
         
            +
             */
         
     | 
| 
      
 55 
     | 
    
         
            +
            #define MKD_NOHEADER	0x0100	/* don't process header blocks */
         
     | 
| 
      
 56 
     | 
    
         
            +
            #define MKD_TABSTOP	0x0200	/* expand tabs to 4 spaces */
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            #endif/*_MKDIO_D*/
         
     | 
    
        data/ext/rbstrio.c
    ADDED
    
    | 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #if defined(HAVE_FOPENCOOKIE)
         
     | 
| 
      
 2 
     | 
    
         
            +
            #    define _GNU_SOURCE
         
     | 
| 
      
 3 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include "rbstrio.h"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            #define INCREMENT 1024
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            /* called when data is written to the stream. */
         
     | 
| 
      
 11 
     | 
    
         
            +
            static int rb_str_io_write(void *cookie, const char *data, int len) {
         
     | 
| 
      
 12 
     | 
    
         
            +
                VALUE buf = (VALUE)cookie;
         
     | 
| 
      
 13 
     | 
    
         
            +
                rb_str_cat(buf, data, len);
         
     | 
| 
      
 14 
     | 
    
         
            +
                return len;
         
     | 
| 
      
 15 
     | 
    
         
            +
            }
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            /* called when the stream is closed */
         
     | 
| 
      
 18 
     | 
    
         
            +
            static int rb_str_io_close(void *cookie) {
         
     | 
| 
      
 19 
     | 
    
         
            +
                VALUE buf = (VALUE)cookie;
         
     | 
| 
      
 20 
     | 
    
         
            +
                rb_gc_unregister_address(&buf);
         
     | 
| 
      
 21 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 22 
     | 
    
         
            +
            }
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            #if defined(HAVE_FOPENCOOKIE)
         
     | 
| 
      
 25 
     | 
    
         
            +
            cookie_io_functions_t rb_str_io_functions =
         
     | 
| 
      
 26 
     | 
    
         
            +
            {
         
     | 
| 
      
 27 
     | 
    
         
            +
                (cookie_read_function_t*)NULL,
         
     | 
| 
      
 28 
     | 
    
         
            +
                (cookie_write_function_t*)rb_str_io_write,
         
     | 
| 
      
 29 
     | 
    
         
            +
                (cookie_seek_function_t*)NULL,
         
     | 
| 
      
 30 
     | 
    
         
            +
                (cookie_close_function_t*)rb_str_io_close
         
     | 
| 
      
 31 
     | 
    
         
            +
            };
         
     | 
| 
      
 32 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            /* create a stream backed by a Ruby string. */
         
     | 
| 
      
 35 
     | 
    
         
            +
            FILE *rb_str_io_new(VALUE buf) {
         
     | 
| 
      
 36 
     | 
    
         
            +
                FILE *rv;
         
     | 
| 
      
 37 
     | 
    
         
            +
                Check_Type(buf, T_STRING);
         
     | 
| 
      
 38 
     | 
    
         
            +
            #if defined(HAVE_FOPENCOOKIE)
         
     | 
| 
      
 39 
     | 
    
         
            +
                rv = fopencookie((void*)buf, "w", rb_str_io_functions);
         
     | 
| 
      
 40 
     | 
    
         
            +
            #else
         
     | 
| 
      
 41 
     | 
    
         
            +
                rv = funopen((void*)buf, NULL, rb_str_io_write, NULL, rb_str_io_close);
         
     | 
| 
      
 42 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 43 
     | 
    
         
            +
                /* TODO if (rv == NULL) */
         
     | 
| 
      
 44 
     | 
    
         
            +
                rb_gc_register_address(&buf);
         
     | 
| 
      
 45 
     | 
    
         
            +
                return rv;
         
     | 
| 
      
 46 
     | 
    
         
            +
            }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            /* vim: set ts=4 sw=4: */
         
     |