bluecloth 2.0.3 → 2.0.4
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/ChangeLog +23 -0
 - data/ext/Csio.c +2 -2
 - data/ext/VERSION +1 -1
 - data/ext/bluecloth.c +7 -1
 - data/ext/cstring.h +3 -3
 - data/ext/generate.c +362 -217
 - data/ext/markdown.c +7 -6
 - data/ext/markdown.h +5 -1
 - data/ext/mkdio.c +1 -1
 - data/ext/mkdio.h +2 -0
 - data/ext/resource.c +13 -5
 - data/lib/bluecloth.rb +10 -4
 - data/rake/helpers.rb +16 -16
 - data/rake/svn.rb +5 -4
 - data/spec/bluecloth/links_spec.rb +3 -3
 - data/spec/bluecloth_spec.rb +34 -0
 - data/spec/discount_spec.rb +67 -0
 - data/spec/lib/matchers.rb +29 -29
 - metadata +6 -8
 
    
        data/ChangeLog
    CHANGED
    
    | 
         @@ -1,3 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            -- Tue, 30 Jun 2009 01:33:36 -0000 by deveiant (r124) -----
         
     | 
| 
      
 2 
     | 
    
         
            +
               Changed: ext/markdown.c
         
     | 
| 
      
 3 
     | 
    
         
            +
                        ext/VERSION
         
     | 
| 
      
 4 
     | 
    
         
            +
                        ext/markdown.h
         
     | 
| 
      
 5 
     | 
    
         
            +
                        ext/generate.c
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                * Updated with Discount 1.4.4.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            -- Mon, 15 Jun 2009 13:15:54 -0000 by deveiant (r123) -----
         
     | 
| 
      
 11 
     | 
    
         
            +
               Added:   spec/discount_spec.rb (new)
         
     | 
| 
      
 12 
     | 
    
         
            +
               Changed: ext/cstring.h
         
     | 
| 
      
 13 
     | 
    
         
            +
                        ext/bluecloth.c
         
     | 
| 
      
 14 
     | 
    
         
            +
                        ext/markdown.c
         
     | 
| 
      
 15 
     | 
    
         
            +
                        spec/bluecloth/links_spec.rb
         
     | 
| 
      
 16 
     | 
    
         
            +
                        spec/lib/matchers.rb
         
     | 
| 
      
 17 
     | 
    
         
            +
                        ext/resource.c (and 10 other/s)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                * Updated to Discount 1.4.2.
         
     | 
| 
      
 20 
     | 
    
         
            +
                * Added some more tests for various Discount extensions.
         
     | 
| 
      
 21 
     | 
    
         
            +
                * Added support for the MKD_AUTOLINK and MKD_SAFELINK.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
       1 
24 
     | 
    
         
             
            -- Tue, 26 May 2009 05:08:15 -0000 by deveiant (r121) -----
         
     | 
| 
       2 
25 
     | 
    
         
             
               Added:   ext/Csio.c (new)
         
     | 
| 
       3 
26 
     | 
    
         
             
                        ext/xmlpage.c (new)
         
     | 
    
        data/ext/Csio.c
    CHANGED
    
    | 
         @@ -26,9 +26,9 @@ Csprintf(Cstring *iot, char *fmt, ...) 
     | 
|
| 
       26 
26 
     | 
    
         
             
                do {
         
     | 
| 
       27 
27 
     | 
    
         
             
            	RESERVE(*iot, siz);
         
     | 
| 
       28 
28 
     | 
    
         
             
            	va_start(ptr, fmt);
         
     | 
| 
       29 
     | 
    
         
            -
            	siz = vsnprintf(T(*iot)+S(*iot),  
     | 
| 
      
 29 
     | 
    
         
            +
            	siz = vsnprintf(T(*iot)+S(*iot), ALLOCATED(*iot)-S(*iot), fmt, ptr);
         
     | 
| 
       30 
30 
     | 
    
         
             
            	va_end(ptr);
         
     | 
| 
       31 
     | 
    
         
            -
                } while ( siz > ( 
     | 
| 
      
 31 
     | 
    
         
            +
                } while ( siz > (ALLOCATED(*iot)-S(*iot)) );
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                S(*iot) += siz;
         
     | 
| 
       34 
34 
     | 
    
         
             
                return siz;
         
     | 
    
        data/ext/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            1.4. 
     | 
| 
      
 1 
     | 
    
         
            +
            1.4.4
         
     | 
    
        data/ext/bluecloth.c
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            /* 
         
     | 
| 
       2 
2 
     | 
    
         
             
             * BlueCloth -- a Ruby implementation of Markdown
         
     | 
| 
       3 
     | 
    
         
            -
             * $Id: bluecloth.c  
     | 
| 
      
 3 
     | 
    
         
            +
             * $Id: bluecloth.c 123 2009-06-15 13:15:54Z deveiant $
         
     | 
| 
       4 
4 
     | 
    
         
             
             * 
         
     | 
| 
       5 
5 
     | 
    
         
             
             * = Authors
         
     | 
| 
       6 
6 
     | 
    
         
             
             * 
         
     | 
| 
         @@ -358,6 +358,12 @@ void Init_bluecloth_ext( void ) { 
     | 
|
| 
       358 
358 
     | 
    
         
             
            	/* MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT */
         
     | 
| 
       359 
359 
     | 
    
         
             
            	rb_define_const( bluecloth_cBlueCloth, "MKD_EMBED",    INT2FIX(MKD_EMBED) );
         
     | 
| 
       360 
360 
     | 
    
         | 
| 
      
 361 
     | 
    
         
            +
            	/* Create links for inline URIs */
         
     | 
| 
      
 362 
     | 
    
         
            +
            	rb_define_const( bluecloth_cBlueCloth, "MKD_AUTOLINK", INT2FIX(MKD_AUTOLINK) );
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
            	/* Be paranoid about link protocols */
         
     | 
| 
      
 365 
     | 
    
         
            +
            	rb_define_const( bluecloth_cBlueCloth, "MKD_SAFELINK", INT2FIX(MKD_SAFELINK) );
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
       361 
367 
     | 
    
         | 
| 
       362 
368 
     | 
    
         
             
            	/* don't process header blocks */
         
     | 
| 
       363 
369 
     | 
    
         
             
            	rb_define_const( bluecloth_cBlueCloth, "MKD_NOHEADER", INT2FIX(MKD_NOHEADER) );
         
     | 
    
        data/ext/cstring.h
    CHANGED
    
    | 
         @@ -22,8 +22,8 @@ 
     | 
|
| 
       22 
22 
     | 
    
         
             
            			    : (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
         
     | 
| 
       23 
23 
     | 
    
         
             
            					   : malloc(sizeof T(x)[0] * ((x).alloc += 100)) )]
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
            #define DELETE(x)	(x) 
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
      
 25 
     | 
    
         
            +
            #define DELETE(x)	ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
         
     | 
| 
      
 26 
     | 
    
         
            +
            				     : ( S(x) = 0 )
         
     | 
| 
       27 
27 
     | 
    
         
             
            #define CLIP(t,i,sz)	\
         
     | 
| 
       28 
28 
     | 
    
         
             
            	    ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
         
     | 
| 
       29 
29 
     | 
    
         
             
            	    (memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
         
     | 
| 
         @@ -50,7 +50,7 @@ 
     | 
|
| 
       50 
50 
     | 
    
         
             
             */
         
     | 
| 
       51 
51 
     | 
    
         
             
            #define T(x)		(x).text
         
     | 
| 
       52 
52 
     | 
    
         
             
            #define S(x)		(x).size
         
     | 
| 
       53 
     | 
    
         
            -
            #define  
     | 
| 
      
 53 
     | 
    
         
            +
            #define ALLOCATED(x)	(x).alloc
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
            /* abstract anchor type that defines a list base
         
     | 
| 
       56 
56 
     | 
    
         
             
             * with a function that attaches an element to
         
     | 
    
        data/ext/generate.c
    CHANGED
    
    | 
         @@ -17,11 +17,6 @@ 
     | 
|
| 
       17 
17 
     | 
    
         
             
            #include "markdown.h"
         
     | 
| 
       18 
18 
     | 
    
         
             
            #include "amalloc.h"
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
            /* prefixes for <automatic links>
         
     | 
| 
       21 
     | 
    
         
            -
             */
         
     | 
| 
       22 
     | 
    
         
            -
            static char *autoprefix[] = { "http://", "https://", "ftp://", "news://" };
         
     | 
| 
       23 
     | 
    
         
            -
            #define SZAUTOPREFIX	(sizeof autoprefix / sizeof autoprefix[0])
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
20 
     | 
    
         
             
            typedef int (*stfu)(const void*,const void*);
         
     | 
| 
       26 
21 
     | 
    
         | 
| 
       27 
22 
     | 
    
         | 
| 
         @@ -119,7 +114,7 @@ shift(MMIOT *f, int i) 
     | 
|
| 
       119 
114 
     | 
    
         
             
            /* Qchar()
         
     | 
| 
       120 
115 
     | 
    
         
             
             */
         
     | 
| 
       121 
116 
     | 
    
         
             
            static void
         
     | 
| 
       122 
     | 
    
         
            -
            Qchar( 
     | 
| 
      
 117 
     | 
    
         
            +
            Qchar(int c, MMIOT *f)
         
     | 
| 
       123 
118 
     | 
    
         
             
            {
         
     | 
| 
       124 
119 
     | 
    
         
             
                block *cur;
         
     | 
| 
       125 
120 
     | 
    
         | 
| 
         @@ -328,18 +323,27 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f) 
     | 
|
| 
       328 
323 
     | 
    
         
             
             * write out a url, escaping problematic characters
         
     | 
| 
       329 
324 
     | 
    
         
             
             */
         
     | 
| 
       330 
325 
     | 
    
         
             
            static void
         
     | 
| 
       331 
     | 
    
         
            -
            puturl(char *s, int size, MMIOT *f)
         
     | 
| 
      
 326 
     | 
    
         
            +
            puturl(char *s, int size, MMIOT *f, int display)
         
     | 
| 
       332 
327 
     | 
    
         
             
            {
         
     | 
| 
       333 
328 
     | 
    
         
             
                unsigned char c;
         
     | 
| 
       334 
329 
     | 
    
         | 
| 
       335 
330 
     | 
    
         
             
                while ( size-- > 0 ) {
         
     | 
| 
       336 
331 
     | 
    
         
             
            	c = *s++;
         
     | 
| 
       337 
332 
     | 
    
         | 
| 
      
 333 
     | 
    
         
            +
            	if ( c == '\\' && size-- > 0 ) {
         
     | 
| 
      
 334 
     | 
    
         
            +
            	    c = *s++;
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
            	    if ( !( ispunct(c) || isspace(c) ) )
         
     | 
| 
      
 337 
     | 
    
         
            +
            		Qchar('\\', f);
         
     | 
| 
      
 338 
     | 
    
         
            +
            	}
         
     | 
| 
      
 339 
     | 
    
         
            +
            	
         
     | 
| 
       338 
340 
     | 
    
         
             
            	if ( c == '&' )
         
     | 
| 
       339 
341 
     | 
    
         
             
            	    Qstring("&", f);
         
     | 
| 
       340 
342 
     | 
    
         
             
            	else if ( c == '<' )
         
     | 
| 
       341 
343 
     | 
    
         
             
            	    Qstring("<", f);
         
     | 
| 
       342 
     | 
    
         
            -
            	else if (  
     | 
| 
      
 344 
     | 
    
         
            +
            	else if ( c == '"' )
         
     | 
| 
      
 345 
     | 
    
         
            +
            	    Qstring("%22", f);
         
     | 
| 
      
 346 
     | 
    
         
            +
            	else if ( isalnum(c) || ispunct(c) || (display && isspace(c)) )
         
     | 
| 
       343 
347 
     | 
    
         
             
            	    Qchar(c, f);
         
     | 
| 
       344 
348 
     | 
    
         
             
            	else
         
     | 
| 
       345 
349 
     | 
    
         
             
            	    Qprintf(f, "%%%02X", c);
         
     | 
| 
         @@ -372,186 +376,164 @@ parenthetical(int in, int out, MMIOT *f) 
     | 
|
| 
       372 
376 
     | 
    
         
             
            	    return EOF;
         
     | 
| 
       373 
377 
     | 
    
         
             
            	else if ( c == in )
         
     | 
| 
       374 
378 
     | 
    
         
             
            	    ++indent;
         
     | 
| 
      
 379 
     | 
    
         
            +
            	else if ( (c == '\\') && (peek(f,1) == out) ) {
         
     | 
| 
      
 380 
     | 
    
         
            +
            	    ++size;
         
     | 
| 
      
 381 
     | 
    
         
            +
            	    pull(f);
         
     | 
| 
      
 382 
     | 
    
         
            +
            	}
         
     | 
| 
       375 
383 
     | 
    
         
             
            	else if ( c == out )
         
     | 
| 
       376 
384 
     | 
    
         
             
            	    --indent;
         
     | 
| 
       377 
385 
     | 
    
         
             
                }
         
     | 
| 
       378 
     | 
    
         
            -
                return size-1;
         
     | 
| 
      
 386 
     | 
    
         
            +
                return size ? (size-1) : 0;
         
     | 
| 
       379 
387 
     | 
    
         
             
            }
         
     | 
| 
       380 
388 
     | 
    
         | 
| 
       381 
389 
     | 
    
         | 
| 
       382 
390 
     | 
    
         
             
            /* extract a []-delimited label from the input stream.
         
     | 
| 
       383 
391 
     | 
    
         
             
             */
         
     | 
| 
       384 
     | 
    
         
            -
            static  
     | 
| 
       385 
     | 
    
         
            -
            linkylabel(MMIOT *f,  
     | 
| 
      
 392 
     | 
    
         
            +
            static int
         
     | 
| 
      
 393 
     | 
    
         
            +
            linkylabel(MMIOT *f, Cstring *res)
         
     | 
| 
       386 
394 
     | 
    
         
             
            {
         
     | 
| 
       387 
395 
     | 
    
         
             
                char *ptr = cursor(f);
         
     | 
| 
      
 396 
     | 
    
         
            +
                int size;
         
     | 
| 
       388 
397 
     | 
    
         | 
| 
       389 
     | 
    
         
            -
                if ( ( 
     | 
| 
       390 
     | 
    
         
            -
            	 
     | 
| 
      
 398 
     | 
    
         
            +
                if ( (size = parenthetical('[',']',f)) != EOF ) {
         
     | 
| 
      
 399 
     | 
    
         
            +
            	T(*res) = ptr;
         
     | 
| 
      
 400 
     | 
    
         
            +
            	S(*res) = size;
         
     | 
| 
      
 401 
     | 
    
         
            +
            	return 1;
         
     | 
| 
      
 402 
     | 
    
         
            +
                }
         
     | 
| 
       391 
403 
     | 
    
         
             
                return 0;
         
     | 
| 
       392 
404 
     | 
    
         
             
            }
         
     | 
| 
       393 
405 
     | 
    
         | 
| 
       394 
406 
     | 
    
         | 
| 
       395 
     | 
    
         
            -
            /*  
     | 
| 
       396 
     | 
    
         
            -
             * the label is either of the format `<link>`, where I
         
     | 
| 
       397 
     | 
    
         
            -
             * extract until I find a >, or it is of the format
         
     | 
| 
       398 
     | 
    
         
            -
             * `text`, where I extract until I reach a ')' or
         
     | 
| 
       399 
     | 
    
         
            -
             * whitespace.
         
     | 
| 
      
 407 
     | 
    
         
            +
            /* see if the quote-prefixed linky segment is actually a title.
         
     | 
| 
       400 
408 
     | 
    
         
             
             */
         
     | 
| 
       401 
     | 
    
         
            -
            static  
     | 
| 
       402 
     | 
    
         
            -
             
     | 
| 
      
 409 
     | 
    
         
            +
            static int
         
     | 
| 
      
 410 
     | 
    
         
            +
            linkytitle(MMIOT *f, char quote, Footnote *ref)
         
     | 
| 
       403 
411 
     | 
    
         
             
            {
         
     | 
| 
       404 
     | 
    
         
            -
                int  
     | 
| 
       405 
     | 
    
         
            -
                char * 
     | 
| 
       406 
     | 
    
         
            -
                 
     | 
| 
       407 
     | 
    
         
            -
             
     | 
| 
       408 
     | 
    
         
            -
                if ( (c = eatspace(f)) == EOF )
         
     | 
| 
       409 
     | 
    
         
            -
            	return 0;
         
     | 
| 
      
 412 
     | 
    
         
            +
                int whence = mmiottell(f);
         
     | 
| 
      
 413 
     | 
    
         
            +
                char *title = cursor(f);
         
     | 
| 
      
 414 
     | 
    
         
            +
                char *e;
         
     | 
| 
      
 415 
     | 
    
         
            +
                register int c;
         
     | 
| 
       410 
416 
     | 
    
         | 
| 
       411 
     | 
    
         
            -
                 
     | 
| 
       412 
     | 
    
         
            -
             
     | 
| 
       413 
     | 
    
         
            -
             
     | 
| 
       414 
     | 
    
         
            -
             
     | 
| 
       415 
     | 
    
         
            -
             
     | 
| 
       416 
     | 
    
         
            -
             
     | 
| 
       417 
     | 
    
         
            -
             
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
            	 
     | 
| 
       420 
     | 
    
         
            -
            	ptr++;
         
     | 
| 
       421 
     | 
    
         
            -
            	if ( (size = parenthetical('<', '>', f)) == EOF )
         
     | 
| 
       422 
     | 
    
         
            -
            	    return 0;
         
     | 
| 
       423 
     | 
    
         
            -
                }
         
     | 
| 
       424 
     | 
    
         
            -
                else {
         
     | 
| 
       425 
     | 
    
         
            -
            	for ( ; ((c=pull(f)) != ')') && !isspace(c); size++)
         
     | 
| 
       426 
     | 
    
         
            -
            	    if ( c == EOF ) return 0;
         
     | 
| 
       427 
     | 
    
         
            -
            	if ( c == ')' )
         
     | 
| 
       428 
     | 
    
         
            -
            	    shift(f, -1);
         
     | 
| 
      
 417 
     | 
    
         
            +
                while ( (c = pull(f)) != EOF ) {
         
     | 
| 
      
 418 
     | 
    
         
            +
            	e = cursor(f);
         
     | 
| 
      
 419 
     | 
    
         
            +
            	if ( c == quote ) {
         
     | 
| 
      
 420 
     | 
    
         
            +
            	    if ( (c = eatspace(f)) == ')' ) {
         
     | 
| 
      
 421 
     | 
    
         
            +
            		T(ref->title) = 1+title;
         
     | 
| 
      
 422 
     | 
    
         
            +
            		S(ref->title) = (e-title)-2;
         
     | 
| 
      
 423 
     | 
    
         
            +
            		return 1;
         
     | 
| 
      
 424 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 425 
     | 
    
         
            +
            	}
         
     | 
| 
       429 
426 
     | 
    
         
             
                }
         
     | 
| 
       430 
     | 
    
         
            -
                 
     | 
| 
       431 
     | 
    
         
            -
                return  
     | 
| 
      
 427 
     | 
    
         
            +
                mmiotseek(f, whence);
         
     | 
| 
      
 428 
     | 
    
         
            +
                return 0;
         
     | 
| 
       432 
429 
     | 
    
         
             
            }
         
     | 
| 
       433 
430 
     | 
    
         | 
| 
       434 
431 
     | 
    
         | 
| 
       435 
432 
     | 
    
         
             
            /* extract a =HHHxWWW size from the input stream
         
     | 
| 
       436 
433 
     | 
    
         
             
             */
         
     | 
| 
       437 
434 
     | 
    
         
             
            static int
         
     | 
| 
       438 
     | 
    
         
            -
            linkysize(MMIOT *f,  
     | 
| 
      
 435 
     | 
    
         
            +
            linkysize(MMIOT *f, Footnote *ref)
         
     | 
| 
       439 
436 
     | 
    
         
             
            {
         
     | 
| 
       440 
437 
     | 
    
         
             
                int height=0, width=0;
         
     | 
| 
      
 438 
     | 
    
         
            +
                int whence = mmiottell(f);
         
     | 
| 
       441 
439 
     | 
    
         
             
                int c;
         
     | 
| 
       442 
440 
     | 
    
         | 
| 
       443 
     | 
    
         
            -
                 
     | 
| 
       444 
     | 
    
         
            -
             
     | 
| 
       445 
     | 
    
         
            -
             
     | 
| 
       446 
     | 
    
         
            -
                if ( (c = eatspace(f)) != '=' ) 
         
     | 
| 
       447 
     | 
    
         
            -
            	return (c != EOF);
         
     | 
| 
       448 
     | 
    
         
            -
                pull(f);	/* eat '=' */
         
     | 
| 
      
 441 
     | 
    
         
            +
                if ( isspace(peek(f,0)) ) {
         
     | 
| 
      
 442 
     | 
    
         
            +
            	pull(f);	/* eat '=' */
         
     | 
| 
       449 
443 
     | 
    
         | 
| 
       450 
     | 
    
         
            -
                for ( c = pull(f); isdigit(c); c = pull(f))
         
     | 
| 
       451 
     | 
    
         
            -
            	width = (width * 10) + (c - '0');
         
     | 
| 
       452 
     | 
    
         
            -
             
     | 
| 
       453 
     | 
    
         
            -
                if ( c == 'x' ) {
         
     | 
| 
       454 
444 
     | 
    
         
             
            	for ( c = pull(f); isdigit(c); c = pull(f))
         
     | 
| 
       455 
     | 
    
         
            -
            	     
     | 
| 
       456 
     | 
    
         
            -
             
     | 
| 
       457 
     | 
    
         
            -
            	if ( c != EOF ) {
         
     | 
| 
       458 
     | 
    
         
            -
            	    if ( !isspace(c) ) shift(f, -1);
         
     | 
| 
       459 
     | 
    
         
            -
            	    *heightp = height;
         
     | 
| 
       460 
     | 
    
         
            -
            	    *widthp = width;
         
     | 
| 
       461 
     | 
    
         
            -
            	    return 1;
         
     | 
| 
       462 
     | 
    
         
            -
            	}
         
     | 
| 
       463 
     | 
    
         
            -
                }
         
     | 
| 
       464 
     | 
    
         
            -
                return 0;
         
     | 
| 
       465 
     | 
    
         
            -
            }
         
     | 
| 
       466 
     | 
    
         
            -
             
     | 
| 
      
 445 
     | 
    
         
            +
            	    width = (width * 10) + (c - '0');
         
     | 
| 
       467 
446 
     | 
    
         | 
| 
       468 
     | 
    
         
            -
             
     | 
| 
       469 
     | 
    
         
            -
              
     | 
| 
       470 
     | 
    
         
            -
             
     | 
| 
       471 
     | 
    
         
            -
            linkytitle(MMIOT *f, int *sizep)
         
     | 
| 
       472 
     | 
    
         
            -
            {
         
     | 
| 
       473 
     | 
    
         
            -
                int countq=0, qc, c, size;
         
     | 
| 
       474 
     | 
    
         
            -
                char *ret, *lastqc = 0;
         
     | 
| 
       475 
     | 
    
         
            -
             
     | 
| 
       476 
     | 
    
         
            -
                eatspace(f);
         
     | 
| 
       477 
     | 
    
         
            -
                if ( (qc=pull(f)) != '"' && qc != '\'' && qc != '(' )
         
     | 
| 
       478 
     | 
    
         
            -
            	return 0;
         
     | 
| 
      
 447 
     | 
    
         
            +
            	if ( c == 'x' ) {
         
     | 
| 
      
 448 
     | 
    
         
            +
            	    for ( c = pull(f); isdigit(c); c = pull(f))
         
     | 
| 
      
 449 
     | 
    
         
            +
            		height = (height*10) + (c - '0');
         
     | 
| 
       479 
450 
     | 
    
         | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
      
 451 
     | 
    
         
            +
            	    if ( isspace(c) )
         
     | 
| 
      
 452 
     | 
    
         
            +
            		c = eatspace(f);
         
     | 
| 
       481 
453 
     | 
    
         | 
| 
       482 
     | 
    
         
            -
             
     | 
| 
       483 
     | 
    
         
            -
             
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
       485 
     | 
    
         
            -
             
     | 
| 
       486 
     | 
    
         
            -
            	     
     | 
| 
       487 
     | 
    
         
            -
            	}
         
     | 
| 
       488 
     | 
    
         
            -
            	else if ( c == qc ) {
         
     | 
| 
       489 
     | 
    
         
            -
            	    lastqc = cursor(f);
         
     | 
| 
       490 
     | 
    
         
            -
            	    countq++;
         
     | 
| 
      
 454 
     | 
    
         
            +
            	    if ( (c == ')') || ((c == '\'' || c == '"') && linkytitle(f, c, ref)) ) {
         
     | 
| 
      
 455 
     | 
    
         
            +
            		ref->height = height;
         
     | 
| 
      
 456 
     | 
    
         
            +
            		ref->width  = width;
         
     | 
| 
      
 457 
     | 
    
         
            +
            		return 1;
         
     | 
| 
      
 458 
     | 
    
         
            +
            	    }
         
     | 
| 
       491 
459 
     | 
    
         
             
            	}
         
     | 
| 
       492 
460 
     | 
    
         
             
                }
         
     | 
| 
      
 461 
     | 
    
         
            +
                mmiotseek(f, whence);
         
     | 
| 
       493 
462 
     | 
    
         
             
                return 0;
         
     | 
| 
       494 
463 
     | 
    
         
             
            }
         
     | 
| 
       495 
464 
     | 
    
         | 
| 
       496 
465 
     | 
    
         | 
| 
       497 
     | 
    
         
            -
            /*  
     | 
| 
       498 
     | 
    
         
            -
             *  
     | 
| 
      
 466 
     | 
    
         
            +
            /* extract a (-prefixed url from the input stream.
         
     | 
| 
      
 467 
     | 
    
         
            +
             * the label is either of the format `<link>`, where I
         
     | 
| 
      
 468 
     | 
    
         
            +
             * extract until I find a >, or it is of the format
         
     | 
| 
      
 469 
     | 
    
         
            +
             * `text`, where I extract until I reach a ')', a quote,
         
     | 
| 
      
 470 
     | 
    
         
            +
             * or (if image) a '='
         
     | 
| 
       499 
471 
     | 
    
         
             
             */
         
     | 
| 
       500 
472 
     | 
    
         
             
            static int
         
     | 
| 
       501 
     | 
    
         
            -
             
     | 
| 
      
 473 
     | 
    
         
            +
            linkyurl(MMIOT *f, int image, Footnote *p)
         
     | 
| 
       502 
474 
     | 
    
         
             
            {
         
     | 
| 
       503 
     | 
    
         
            -
                 
     | 
| 
       504 
     | 
    
         
            -
                 
     | 
| 
       505 
     | 
    
         
            -
                int here;
         
     | 
| 
       506 
     | 
    
         
            -
             
     | 
| 
       507 
     | 
    
         
            -
                memset(val, 0, sizeof *val);
         
     | 
| 
      
 475 
     | 
    
         
            +
                int c;
         
     | 
| 
      
 476 
     | 
    
         
            +
                int mayneedtotrim=0;
         
     | 
| 
       508 
477 
     | 
    
         | 
| 
       509 
     | 
    
         
            -
                if ( ( 
     | 
| 
      
 478 
     | 
    
         
            +
                if ( (c = eatspace(f)) == EOF )
         
     | 
| 
       510 
479 
     | 
    
         
             
            	return 0;
         
     | 
| 
       511 
480 
     | 
    
         | 
| 
       512 
     | 
    
         
            -
                 
     | 
| 
       513 
     | 
    
         
            -
             
     | 
| 
       514 
     | 
    
         
            -
             
     | 
| 
       515 
     | 
    
         
            -
                 
     | 
| 
       516 
     | 
    
         
            -
            	/* embedded link */
         
     | 
| 
       517 
     | 
    
         
            -
            	if ( (T(val->link) = linkyurl(f,&S(val->link))) == 0 )
         
     | 
| 
       518 
     | 
    
         
            -
            	    return 0;
         
     | 
| 
      
 481 
     | 
    
         
            +
                if ( c == '<' ) {
         
     | 
| 
      
 482 
     | 
    
         
            +
            	pull(f);
         
     | 
| 
      
 483 
     | 
    
         
            +
            	mayneedtotrim=1;
         
     | 
| 
      
 484 
     | 
    
         
            +
                }
         
     | 
| 
       519 
485 
     | 
    
         | 
| 
       520 
     | 
    
         
            -
             
     | 
| 
      
 486 
     | 
    
         
            +
                T(p->link) = cursor(f);
         
     | 
| 
      
 487 
     | 
    
         
            +
                for ( S(p->link)=0; (c = peek(f,1)) != ')'; ++S(p->link) ) {
         
     | 
| 
      
 488 
     | 
    
         
            +
            	if ( c == EOF )
         
     | 
| 
       521 
489 
     | 
    
         
             
            	    return 0;
         
     | 
| 
      
 490 
     | 
    
         
            +
            	else if ( (c == '"' || c == '\'') && linkytitle(f, c, p) )
         
     | 
| 
      
 491 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 492 
     | 
    
         
            +
            	else if ( image && (c == '=') && linkysize(f, p) )
         
     | 
| 
      
 493 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 494 
     | 
    
         
            +
            	else if ( (c == '\\') && ispunct(peek(f,2)) ) {
         
     | 
| 
      
 495 
     | 
    
         
            +
            	    ++S(p->link);
         
     | 
| 
      
 496 
     | 
    
         
            +
            	    pull(f);
         
     | 
| 
      
 497 
     | 
    
         
            +
            	}
         
     | 
| 
      
 498 
     | 
    
         
            +
            	pull(f);
         
     | 
| 
      
 499 
     | 
    
         
            +
                }
         
     | 
| 
      
 500 
     | 
    
         
            +
                if ( peek(f, 1) == ')' )
         
     | 
| 
      
 501 
     | 
    
         
            +
            	pull(f);
         
     | 
| 
      
 502 
     | 
    
         
            +
            	
         
     | 
| 
      
 503 
     | 
    
         
            +
                ___mkd_tidy(&p->link);
         
     | 
| 
      
 504 
     | 
    
         
            +
                
         
     | 
| 
      
 505 
     | 
    
         
            +
                if ( mayneedtotrim && (T(p->link)[S(p->link)-1] == '>') )
         
     | 
| 
      
 506 
     | 
    
         
            +
            	--S(p->link);
         
     | 
| 
      
 507 
     | 
    
         
            +
                
         
     | 
| 
      
 508 
     | 
    
         
            +
                return 1;
         
     | 
| 
      
 509 
     | 
    
         
            +
            }
         
     | 
| 
       522 
510 
     | 
    
         | 
| 
       523 
     | 
    
         
            -
            	T(val->title) = linkytitle(f, &S(val->title));
         
     | 
| 
       524 
511 
     | 
    
         | 
| 
       525 
     | 
    
         
            -
            	return peek(f,0) == ')';
         
     | 
| 
       526 
512 
     | 
    
         | 
| 
       527 
     | 
    
         
            -
             
     | 
| 
       528 
     | 
    
         
            -
             
     | 
| 
       529 
     | 
    
         
            -
             
     | 
| 
       530 
     | 
    
         
            -
             
     | 
| 
       531 
     | 
    
         
            -
             
     | 
| 
       532 
     | 
    
         
            -
             
     | 
| 
       533 
     | 
    
         
            -
             
     | 
| 
      
 513 
     | 
    
         
            +
            /* prefixes for <automatic links>
         
     | 
| 
      
 514 
     | 
    
         
            +
             */
         
     | 
| 
      
 515 
     | 
    
         
            +
            static struct {
         
     | 
| 
      
 516 
     | 
    
         
            +
                char *name;
         
     | 
| 
      
 517 
     | 
    
         
            +
                int   nlen;
         
     | 
| 
      
 518 
     | 
    
         
            +
            } protocol[] = { 
         
     | 
| 
      
 519 
     | 
    
         
            +
            #define _aprotocol(x)	{ x, (sizeof x)-1 }
         
     | 
| 
      
 520 
     | 
    
         
            +
                _aprotocol( "http://" ), 
         
     | 
| 
      
 521 
     | 
    
         
            +
                _aprotocol( "https://" ), 
         
     | 
| 
      
 522 
     | 
    
         
            +
                _aprotocol( "ftp://" ), 
         
     | 
| 
      
 523 
     | 
    
         
            +
                _aprotocol( "news://" ),
         
     | 
| 
      
 524 
     | 
    
         
            +
            #undef _aprotocol
         
     | 
| 
      
 525 
     | 
    
         
            +
            };
         
     | 
| 
      
 526 
     | 
    
         
            +
            #define NRPROTOCOLS	(sizeof protocol / sizeof protocol[0])
         
     | 
| 
       534 
527 
     | 
    
         | 
| 
       535 
     | 
    
         
            -
            	    if ( !S(val->tag) )
         
     | 
| 
       536 
     | 
    
         
            -
            		val->tag = mylabel;
         
     | 
| 
       537 
     | 
    
         
            -
            	}
         
     | 
| 
       538 
     | 
    
         
            -
            	else if ( f->flags & MKD_1_COMPAT )
         
     | 
| 
       539 
     | 
    
         
            -
            	    break;
         
     | 
| 
       540 
     | 
    
         
            -
            	else
         
     | 
| 
       541 
     | 
    
         
            -
            	    mmiotseek(f,here);
         
     | 
| 
       542 
528 
     | 
    
         | 
| 
       543 
     | 
    
         
            -
             
     | 
| 
       544 
     | 
    
         
            -
             
     | 
| 
      
 529 
     | 
    
         
            +
            static int
         
     | 
| 
      
 530 
     | 
    
         
            +
            isautoprefix(char *text)
         
     | 
| 
      
 531 
     | 
    
         
            +
            {
         
     | 
| 
      
 532 
     | 
    
         
            +
                int i;
         
     | 
| 
       545 
533 
     | 
    
         | 
| 
       546 
     | 
    
         
            -
             
     | 
| 
       547 
     | 
    
         
            -
             
     | 
| 
       548 
     | 
    
         
            -
            	    val->link = ret->link;
         
     | 
| 
       549 
     | 
    
         
            -
            	    val->title = ret->title;
         
     | 
| 
       550 
     | 
    
         
            -
            	    val->height = ret->height;
         
     | 
| 
       551 
     | 
    
         
            -
            	    val->width = ret->width;
         
     | 
| 
      
 534 
     | 
    
         
            +
                for (i=0; i < NRPROTOCOLS; i++)
         
     | 
| 
      
 535 
     | 
    
         
            +
            	if ( strncasecmp(text, protocol[i].name, protocol[i].nlen) == 0 )
         
     | 
| 
       552 
536 
     | 
    
         
             
            	    return 1;
         
     | 
| 
       553 
     | 
    
         
            -
            	}
         
     | 
| 
       554 
     | 
    
         
            -
                }
         
     | 
| 
       555 
537 
     | 
    
         
             
                return 0;
         
     | 
| 
       556 
538 
     | 
    
         
             
            }
         
     | 
| 
       557 
539 
     | 
    
         | 
| 
         @@ -569,12 +551,14 @@ typedef struct linkytype { 
     | 
|
| 
       569 
551 
     | 
    
         
             
                char *text_pfx;	/* text prefix                  (eg: ">"           */
         
     | 
| 
       570 
552 
     | 
    
         
             
                char *text_sfx;	/* text suffix			(eg: "</a>"        */
         
     | 
| 
       571 
553 
     | 
    
         
             
                int      flags;	/* reparse flags */
         
     | 
| 
      
 554 
     | 
    
         
            +
                int      kind;	/* tag is url or something else? */
         
     | 
| 
      
 555 
     | 
    
         
            +
            #define IS_URL	0x01
         
     | 
| 
       572 
556 
     | 
    
         
             
            } linkytype;
         
     | 
| 
       573 
557 
     | 
    
         | 
| 
       574 
558 
     | 
    
         
             
            static linkytype imaget = { 0, 0, "<img src=\"", "\"",
         
     | 
| 
       575 
     | 
    
         
            -
            			     1, " alt=\"", "\" />", DENY_IMG|INSIDE_TAG };
         
     | 
| 
      
 559 
     | 
    
         
            +
            			     1, " alt=\"", "\" />", DENY_IMG|INSIDE_TAG, IS_URL };
         
     | 
| 
       576 
560 
     | 
    
         
             
            static linkytype linkt  = { 0, 0, "<a href=\"", "\"",
         
     | 
| 
       577 
     | 
    
         
            -
                                         0, ">", "</a>", DENY_A };
         
     | 
| 
      
 561 
     | 
    
         
            +
                                         0, ">", "</a>", DENY_A, IS_URL };
         
     | 
| 
       578 
562 
     | 
    
         | 
| 
       579 
563 
     | 
    
         
             
            /*
         
     | 
| 
       580 
564 
     | 
    
         
             
             * pseudo-protocols for [][];
         
     | 
| 
         @@ -584,9 +568,10 @@ static linkytype linkt  = { 0, 0, "<a href=\"", "\"", 
     | 
|
| 
       584 
568 
     | 
    
         
             
             * raw: just dump the link without any processing
         
     | 
| 
       585 
569 
     | 
    
         
             
             */
         
     | 
| 
       586 
570 
     | 
    
         
             
            static linkytype specials[] = {
         
     | 
| 
       587 
     | 
    
         
            -
                { "id:", 3, "<a id=\"", "\"", 0, ">", "</a>", 0 },
         
     | 
| 
       588 
     | 
    
         
            -
                { "class:", 6, "<span class=\"", "\"", 0, ">", "</span>", 0 },
         
     | 
| 
       589 
     | 
    
         
            -
                { "raw:", 4, 0, 0, 0, 0, 0, 0 },
         
     | 
| 
      
 571 
     | 
    
         
            +
                { "id:", 3, "<a id=\"", "\"", 0, ">", "</a>", 0, IS_URL },
         
     | 
| 
      
 572 
     | 
    
         
            +
                { "class:", 6, "<span class=\"", "\"", 0, ">", "</span>", 0, 0 },
         
     | 
| 
      
 573 
     | 
    
         
            +
                { "raw:", 4, 0, 0, 0, 0, 0, DENY_HTML, 0 },
         
     | 
| 
      
 574 
     | 
    
         
            +
                { "abbr:", 5, "<abbr title=\"", "\"", 0, ">", "</abbr>", 0, 0 },
         
     | 
| 
       590 
575 
     | 
    
         
             
            } ;
         
     | 
| 
       591 
576 
     | 
    
         | 
| 
       592 
577 
     | 
    
         
             
            #define NR(x)	(sizeof x / sizeof x[0])
         
     | 
| 
         @@ -594,7 +579,7 @@ static linkytype specials[] = { 
     | 
|
| 
       594 
579 
     | 
    
         
             
            /* see if t contains one of our pseudo-protocols.
         
     | 
| 
       595 
580 
     | 
    
         
             
             */
         
     | 
| 
       596 
581 
     | 
    
         
             
            static linkytype *
         
     | 
| 
       597 
     | 
    
         
            -
             
     | 
| 
      
 582 
     | 
    
         
            +
            pseudo(Cstring t)
         
     | 
| 
       598 
583 
     | 
    
         
             
            {
         
     | 
| 
       599 
584 
     | 
    
         
             
                int i;
         
     | 
| 
       600 
585 
     | 
    
         
             
                linkytype *r;
         
     | 
| 
         @@ -608,57 +593,122 @@ extratag(Cstring t) 
     | 
|
| 
       608 
593 
     | 
    
         
             
            }
         
     | 
| 
       609 
594 
     | 
    
         | 
| 
       610 
595 
     | 
    
         | 
| 
       611 
     | 
    
         
            -
            /*
         
     | 
| 
       612 
     | 
    
         
            -
             * process embedded links and images
         
     | 
| 
      
 596 
     | 
    
         
            +
            /* print out a linky (or fail if it's Not Allowed)
         
     | 
| 
       613 
597 
     | 
    
         
             
             */
         
     | 
| 
       614 
598 
     | 
    
         
             
            static int
         
     | 
| 
       615 
     | 
    
         
            -
             
     | 
| 
      
 599 
     | 
    
         
            +
            linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
         
     | 
| 
       616 
600 
     | 
    
         
             
            {
         
     | 
| 
       617 
     | 
    
         
            -
                int start = mmiottell(f);
         
     | 
| 
       618 
     | 
    
         
            -
                Footnote link;
         
     | 
| 
       619 
601 
     | 
    
         
             
                linkytype *tag;
         
     | 
| 
       620 
602 
     | 
    
         | 
| 
       621 
     | 
    
         
            -
                if ( !linkykey(image, &link, f) ) {
         
     | 
| 
       622 
     | 
    
         
            -
            	mmiotseek(f, start);
         
     | 
| 
       623 
     | 
    
         
            -
            	return 0;
         
     | 
| 
       624 
     | 
    
         
            -
                }
         
     | 
| 
       625 
     | 
    
         
            -
             
     | 
| 
       626 
603 
     | 
    
         
             
                if ( image )
         
     | 
| 
       627 
604 
     | 
    
         
             
            	tag = &imaget;
         
     | 
| 
       628 
     | 
    
         
            -
                else if (  
     | 
| 
      
 605 
     | 
    
         
            +
                else if ( tag = pseudo(ref->link) ) {
         
     | 
| 
      
 606 
     | 
    
         
            +
            	if ( f->flags & (NO_PSEUDO_PROTO|SAFELINK) )
         
     | 
| 
      
 607 
     | 
    
         
            +
            	    return 0;
         
     | 
| 
      
 608 
     | 
    
         
            +
                }
         
     | 
| 
      
 609 
     | 
    
         
            +
                else if ( (f->flags & SAFELINK) && T(ref->link)
         
     | 
| 
      
 610 
     | 
    
         
            +
            				    && (T(ref->link)[0] != '/')
         
     | 
| 
      
 611 
     | 
    
         
            +
            				    && !isautoprefix(T(ref->link)) )
         
     | 
| 
      
 612 
     | 
    
         
            +
            	/* if SAFELINK, only accept links that are local or
         
     | 
| 
      
 613 
     | 
    
         
            +
            	 * a well-known protocol
         
     | 
| 
      
 614 
     | 
    
         
            +
            	 */
         
     | 
| 
      
 615 
     | 
    
         
            +
            	    return 0;
         
     | 
| 
      
 616 
     | 
    
         
            +
                else
         
     | 
| 
       629 
617 
     | 
    
         
             
            	tag = &linkt;
         
     | 
| 
       630 
618 
     | 
    
         | 
| 
       631 
     | 
    
         
            -
                if ( f->flags & tag-> 
     | 
| 
       632 
     | 
    
         
            -
            	mmiotseek(f, start);
         
     | 
| 
      
 619 
     | 
    
         
            +
                if ( f->flags & tag->flags )
         
     | 
| 
       633 
620 
     | 
    
         
             
            	return 0;
         
     | 
| 
       634 
     | 
    
         
            -
                }
         
     | 
| 
       635 
621 
     | 
    
         | 
| 
       636 
622 
     | 
    
         
             
                if ( tag->link_pfx ) {
         
     | 
| 
       637 
623 
     | 
    
         
             
            	Qstring(tag->link_pfx, f);
         
     | 
| 
       638 
     | 
    
         
            -
            	 
     | 
| 
       639 
     | 
    
         
            -
             
     | 
| 
       640 
     | 
    
         
            -
             
     | 
| 
      
 624 
     | 
    
         
            +
            	
         
     | 
| 
      
 625 
     | 
    
         
            +
            	if ( tag->kind & IS_URL ) {
         
     | 
| 
      
 626 
     | 
    
         
            +
            	    if ( f->base && T(ref->link) && (T(ref->link)[tag->szpat] == '/') )
         
     | 
| 
      
 627 
     | 
    
         
            +
            		puturl(f->base, strlen(f->base), f, 0);
         
     | 
| 
      
 628 
     | 
    
         
            +
            	    puturl(T(ref->link) + tag->szpat, S(ref->link) - tag->szpat, f, 0);
         
     | 
| 
      
 629 
     | 
    
         
            +
            	}
         
     | 
| 
      
 630 
     | 
    
         
            +
            	else
         
     | 
| 
      
 631 
     | 
    
         
            +
            	    ___mkd_reparse(T(ref->link) + tag->szpat, S(ref->link) - tag->szpat, INSIDE_TAG, f);
         
     | 
| 
      
 632 
     | 
    
         
            +
            	
         
     | 
| 
       641 
633 
     | 
    
         
             
            	Qstring(tag->link_sfx, f);
         
     | 
| 
       642 
634 
     | 
    
         | 
| 
       643 
     | 
    
         
            -
            	if ( tag->WxH &&  
     | 
| 
       644 
     | 
    
         
            -
            	    Qprintf(f," height=\"%d\"",  
     | 
| 
       645 
     | 
    
         
            -
            	    Qprintf(f, " width=\"%d\"",  
     | 
| 
      
 635 
     | 
    
         
            +
            	if ( tag->WxH && ref->height && ref->width ) {
         
     | 
| 
      
 636 
     | 
    
         
            +
            	    Qprintf(f," height=\"%d\"", ref->height);
         
     | 
| 
      
 637 
     | 
    
         
            +
            	    Qprintf(f, " width=\"%d\"", ref->width);
         
     | 
| 
       646 
638 
     | 
    
         
             
            	}
         
     | 
| 
       647 
639 
     | 
    
         | 
| 
       648 
     | 
    
         
            -
            	if ( S( 
     | 
| 
      
 640 
     | 
    
         
            +
            	if ( S(ref->title) ) {
         
     | 
| 
       649 
641 
     | 
    
         
             
            	    Qstring(" title=\"", f);
         
     | 
| 
       650 
     | 
    
         
            -
            	    ___mkd_reparse(T( 
     | 
| 
      
 642 
     | 
    
         
            +
            	    ___mkd_reparse(T(ref->title), S(ref->title), INSIDE_TAG, f);
         
     | 
| 
       651 
643 
     | 
    
         
             
            	    Qchar('"', f);
         
     | 
| 
       652 
644 
     | 
    
         
             
            	}
         
     | 
| 
       653 
645 
     | 
    
         | 
| 
       654 
646 
     | 
    
         
             
            	Qstring(tag->text_pfx, f);
         
     | 
| 
       655 
     | 
    
         
            -
            	___mkd_reparse(T( 
     | 
| 
      
 647 
     | 
    
         
            +
            	___mkd_reparse(T(text), S(text), tag->flags, f);
         
     | 
| 
       656 
648 
     | 
    
         
             
            	Qstring(tag->text_sfx, f);
         
     | 
| 
       657 
649 
     | 
    
         
             
                }
         
     | 
| 
       658 
650 
     | 
    
         
             
                else
         
     | 
| 
       659 
     | 
    
         
            -
            	Qwrite(T(link 
     | 
| 
      
 651 
     | 
    
         
            +
            	Qwrite(T(ref->link) + tag->szpat, S(ref->link) - tag->szpat, f);
         
     | 
| 
       660 
652 
     | 
    
         | 
| 
       661 
653 
     | 
    
         
             
                return 1;
         
     | 
| 
      
 654 
     | 
    
         
            +
            } /* linkyformat */
         
     | 
| 
      
 655 
     | 
    
         
            +
             
     | 
| 
      
 656 
     | 
    
         
            +
             
     | 
| 
      
 657 
     | 
    
         
            +
            /*
         
     | 
| 
      
 658 
     | 
    
         
            +
             * process embedded links and images
         
     | 
| 
      
 659 
     | 
    
         
            +
             */
         
     | 
| 
      
 660 
     | 
    
         
            +
            static int
         
     | 
| 
      
 661 
     | 
    
         
            +
            linkylinky(int image, MMIOT *f)
         
     | 
| 
      
 662 
     | 
    
         
            +
            {
         
     | 
| 
      
 663 
     | 
    
         
            +
                int start = mmiottell(f);
         
     | 
| 
      
 664 
     | 
    
         
            +
                int implicit_mark;
         
     | 
| 
      
 665 
     | 
    
         
            +
                Cstring name;
         
     | 
| 
      
 666 
     | 
    
         
            +
                Footnote key, *ref;
         
     | 
| 
      
 667 
     | 
    
         
            +
            		
         
     | 
| 
      
 668 
     | 
    
         
            +
                int status = 0;
         
     | 
| 
      
 669 
     | 
    
         
            +
             
     | 
| 
      
 670 
     | 
    
         
            +
                CREATE(name);
         
     | 
| 
      
 671 
     | 
    
         
            +
                bzero(&key, sizeof key);
         
     | 
| 
      
 672 
     | 
    
         
            +
             
     | 
| 
      
 673 
     | 
    
         
            +
                if ( linkylabel(f, &name) ) {
         
     | 
| 
      
 674 
     | 
    
         
            +
            	implicit_mark = mmiottell(f);
         
     | 
| 
      
 675 
     | 
    
         
            +
            	eatspace(f);
         
     | 
| 
      
 676 
     | 
    
         
            +
             
     | 
| 
      
 677 
     | 
    
         
            +
            	switch ( pull(f) ) {
         
     | 
| 
      
 678 
     | 
    
         
            +
            	case '(':  /* embedded link */
         
     | 
| 
      
 679 
     | 
    
         
            +
            	    if ( linkyurl(f, image, &key) )
         
     | 
| 
      
 680 
     | 
    
         
            +
            		status = linkyformat(f, name, image, &key);
         
     | 
| 
      
 681 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 682 
     | 
    
         
            +
            	
         
     | 
| 
      
 683 
     | 
    
         
            +
            	case '[':/* footnote link */
         
     | 
| 
      
 684 
     | 
    
         
            +
            	default: /* (undocumented) implicit link */
         
     | 
| 
      
 685 
     | 
    
         
            +
            	    if ( peek(f, 0) != '[' ) {
         
     | 
| 
      
 686 
     | 
    
         
            +
            		mmiotseek(f, implicit_mark);
         
     | 
| 
      
 687 
     | 
    
         
            +
            		if ( f->flags & MKD_1_COMPAT )
         
     | 
| 
      
 688 
     | 
    
         
            +
            		    break;
         
     | 
| 
      
 689 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 690 
     | 
    
         
            +
            	    else if ( !linkylabel(f, &key.tag) )
         
     | 
| 
      
 691 
     | 
    
         
            +
            		break;
         
     | 
| 
      
 692 
     | 
    
         
            +
            	    
         
     | 
| 
      
 693 
     | 
    
         
            +
            	    if ( !S(key.tag) ) {
         
     | 
| 
      
 694 
     | 
    
         
            +
            		DELETE(key.tag);
         
     | 
| 
      
 695 
     | 
    
         
            +
            		T(key.tag) = T(name);
         
     | 
| 
      
 696 
     | 
    
         
            +
            		S(key.tag) = S(name);
         
     | 
| 
      
 697 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 698 
     | 
    
         
            +
             
     | 
| 
      
 699 
     | 
    
         
            +
            	    if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
         
     | 
| 
      
 700 
     | 
    
         
            +
            				      sizeof key, (stfu)__mkd_footsort) )
         
     | 
| 
      
 701 
     | 
    
         
            +
            		status = linkyformat(f, name, image, ref);
         
     | 
| 
      
 702 
     | 
    
         
            +
            	}
         
     | 
| 
      
 703 
     | 
    
         
            +
                }
         
     | 
| 
      
 704 
     | 
    
         
            +
             
     | 
| 
      
 705 
     | 
    
         
            +
                DELETE(name);
         
     | 
| 
      
 706 
     | 
    
         
            +
                ___mkd_freefootnote(&key);
         
     | 
| 
      
 707 
     | 
    
         
            +
             
     | 
| 
      
 708 
     | 
    
         
            +
                if ( status == 0 )
         
     | 
| 
      
 709 
     | 
    
         
            +
            	mmiotseek(f, start);
         
     | 
| 
      
 710 
     | 
    
         
            +
             
     | 
| 
      
 711 
     | 
    
         
            +
                return status;
         
     | 
| 
       662 
712 
     | 
    
         
             
            }
         
     | 
| 
       663 
713 
     | 
    
         | 
| 
       664 
714 
     | 
    
         | 
| 
         @@ -711,6 +761,80 @@ forbidden_tag(MMIOT *f) 
     | 
|
| 
       711 
761 
     | 
    
         
             
            }
         
     | 
| 
       712 
762 
     | 
    
         | 
| 
       713 
763 
     | 
    
         | 
| 
      
 764 
     | 
    
         
            +
            /* Check a string to see if it looks like a mail address
         
     | 
| 
      
 765 
     | 
    
         
            +
             * "looks like a mail address" means alphanumeric + some
         
     | 
| 
      
 766 
     | 
    
         
            +
             * specials, then a `@`, then alphanumeric + some specials,
         
     | 
| 
      
 767 
     | 
    
         
            +
             * but with a `.`
         
     | 
| 
      
 768 
     | 
    
         
            +
             */
         
     | 
| 
      
 769 
     | 
    
         
            +
            static int
         
     | 
| 
      
 770 
     | 
    
         
            +
            maybe_address(char *p, int size)
         
     | 
| 
      
 771 
     | 
    
         
            +
            {
         
     | 
| 
      
 772 
     | 
    
         
            +
                int ok = 0;
         
     | 
| 
      
 773 
     | 
    
         
            +
                
         
     | 
| 
      
 774 
     | 
    
         
            +
                for ( ;size && (isalnum(*p) || strchr("._-+*", *p)); ++p, --size)
         
     | 
| 
      
 775 
     | 
    
         
            +
            	;
         
     | 
| 
      
 776 
     | 
    
         
            +
             
     | 
| 
      
 777 
     | 
    
         
            +
                if ( ! (size && *p == '@') )
         
     | 
| 
      
 778 
     | 
    
         
            +
            	return 0;
         
     | 
| 
      
 779 
     | 
    
         
            +
                
         
     | 
| 
      
 780 
     | 
    
         
            +
                --size, ++p;
         
     | 
| 
      
 781 
     | 
    
         
            +
             
     | 
| 
      
 782 
     | 
    
         
            +
                if ( size && *p == '.' ) return 0;
         
     | 
| 
      
 783 
     | 
    
         
            +
                
         
     | 
| 
      
 784 
     | 
    
         
            +
                for ( ;size && (isalnum(*p) || strchr("._-+", *p)); ++p, --size )
         
     | 
| 
      
 785 
     | 
    
         
            +
            	if ( *p == '.' && size > 1 ) ok = 1;
         
     | 
| 
      
 786 
     | 
    
         
            +
             
     | 
| 
      
 787 
     | 
    
         
            +
                return size ? 0 : ok;
         
     | 
| 
      
 788 
     | 
    
         
            +
            }
         
     | 
| 
      
 789 
     | 
    
         
            +
             
     | 
| 
      
 790 
     | 
    
         
            +
             
     | 
| 
      
 791 
     | 
    
         
            +
            /* The size-length token at cursor(f) is either a mailto:, an
         
     | 
| 
      
 792 
     | 
    
         
            +
             * implicit mailto:, one of the approved url protocols, or just
         
     | 
| 
      
 793 
     | 
    
         
            +
             * plain old text.   If it's a mailto: or an approved protocol,
         
     | 
| 
      
 794 
     | 
    
         
            +
             * linkify it, otherwise say "no"
         
     | 
| 
      
 795 
     | 
    
         
            +
             */
         
     | 
| 
      
 796 
     | 
    
         
            +
            static int
         
     | 
| 
      
 797 
     | 
    
         
            +
            process_possible_link(MMIOT *f, int size)
         
     | 
| 
      
 798 
     | 
    
         
            +
            {
         
     | 
| 
      
 799 
     | 
    
         
            +
                int address= 0;
         
     | 
| 
      
 800 
     | 
    
         
            +
                int mailto = 0;
         
     | 
| 
      
 801 
     | 
    
         
            +
                char *text = cursor(f);
         
     | 
| 
      
 802 
     | 
    
         
            +
                
         
     | 
| 
      
 803 
     | 
    
         
            +
                if ( f->flags & DENY_A ) return 0;
         
     | 
| 
      
 804 
     | 
    
         
            +
             
     | 
| 
      
 805 
     | 
    
         
            +
                if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 ) {
         
     | 
| 
      
 806 
     | 
    
         
            +
            	/* if it says it's a mailto, it's a mailto -- who am
         
     | 
| 
      
 807 
     | 
    
         
            +
            	 * I to second-guess the user?
         
     | 
| 
      
 808 
     | 
    
         
            +
            	 */
         
     | 
| 
      
 809 
     | 
    
         
            +
            	address = 1;
         
     | 
| 
      
 810 
     | 
    
         
            +
            	mailto = 7; 	/* 7 is the length of "mailto:"; we need this */
         
     | 
| 
      
 811 
     | 
    
         
            +
                }
         
     | 
| 
      
 812 
     | 
    
         
            +
                else 
         
     | 
| 
      
 813 
     | 
    
         
            +
            	address = maybe_address(text, size);
         
     | 
| 
      
 814 
     | 
    
         
            +
             
     | 
| 
      
 815 
     | 
    
         
            +
                if ( address ) { 
         
     | 
| 
      
 816 
     | 
    
         
            +
            	Qstring("<a href=\"", f);
         
     | 
| 
      
 817 
     | 
    
         
            +
            	if ( !mailto ) {
         
     | 
| 
      
 818 
     | 
    
         
            +
            	    /* supply a mailto: protocol if one wasn't attached */
         
     | 
| 
      
 819 
     | 
    
         
            +
            	    mangle("mailto:", 7, f);
         
     | 
| 
      
 820 
     | 
    
         
            +
            	}
         
     | 
| 
      
 821 
     | 
    
         
            +
            	mangle(text, size, f);
         
     | 
| 
      
 822 
     | 
    
         
            +
            	Qstring("\">", f);
         
     | 
| 
      
 823 
     | 
    
         
            +
            	mangle(text+mailto, size-mailto, f);
         
     | 
| 
      
 824 
     | 
    
         
            +
            	Qstring("</a>", f);
         
     | 
| 
      
 825 
     | 
    
         
            +
            	return 1;
         
     | 
| 
      
 826 
     | 
    
         
            +
                }
         
     | 
| 
      
 827 
     | 
    
         
            +
                else if ( isautoprefix(text) ) {
         
     | 
| 
      
 828 
     | 
    
         
            +
            	Qstring("<a href=\"", f);
         
     | 
| 
      
 829 
     | 
    
         
            +
            	puturl(text,size,f, 0);
         
     | 
| 
      
 830 
     | 
    
         
            +
            	Qstring("\">", f);
         
     | 
| 
      
 831 
     | 
    
         
            +
            	puturl(text,size,f, 1);
         
     | 
| 
      
 832 
     | 
    
         
            +
            	Qstring("</a>", f);
         
     | 
| 
      
 833 
     | 
    
         
            +
            	return 1;
         
     | 
| 
      
 834 
     | 
    
         
            +
                }
         
     | 
| 
      
 835 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 836 
     | 
    
         
            +
            } /* process_possible_link */
         
     | 
| 
      
 837 
     | 
    
         
            +
             
     | 
| 
       714 
838 
     | 
    
         | 
| 
       715 
839 
     | 
    
         
             
            /* a < may be just a regular character, the start of an embedded html
         
     | 
| 
       716 
840 
     | 
    
         
             
             * tag, or the start of an <automatic link>.    If it's an automatic
         
     | 
| 
         @@ -721,68 +845,69 @@ forbidden_tag(MMIOT *f) 
     | 
|
| 
       721 
845 
     | 
    
         
             
            static int
         
     | 
| 
       722 
846 
     | 
    
         
             
            maybe_tag_or_link(MMIOT *f)
         
     | 
| 
       723 
847 
     | 
    
         
             
            {
         
     | 
| 
       724 
     | 
    
         
            -
                 
     | 
| 
       725 
     | 
    
         
            -
                int  
     | 
| 
       726 
     | 
    
         
            -
                int maybetag=1, maybeaddress=0;
         
     | 
| 
       727 
     | 
    
         
            -
                int mailto;
         
     | 
| 
      
 848 
     | 
    
         
            +
                int c, size;
         
     | 
| 
      
 849 
     | 
    
         
            +
                int maybetag = 1;
         
     | 
| 
       728 
850 
     | 
    
         | 
| 
       729 
851 
     | 
    
         
             
                if ( f->flags & INSIDE_TAG )
         
     | 
| 
       730 
852 
     | 
    
         
             
            	return 0;
         
     | 
| 
       731 
853 
     | 
    
         | 
| 
       732 
     | 
    
         
            -
                for ( size=0; ( 
     | 
| 
       733 
     | 
    
         
            -
            	if (  
     | 
| 
       734 
     | 
    
         
            -
            	    maybetag=0;
         
     | 
| 
       735 
     | 
    
         
            -
            	if ( c == '@' )
         
     | 
| 
       736 
     | 
    
         
            -
            	    maybeaddress=1;
         
     | 
| 
       737 
     | 
    
         
            -
            	else if ( c == EOF )
         
     | 
| 
      
 854 
     | 
    
         
            +
                for ( size=0; (c = peek(f, size+1)) != '>'; size++) {
         
     | 
| 
      
 855 
     | 
    
         
            +
            	if ( c == EOF )
         
     | 
| 
       738 
856 
     | 
    
         
             
            	    return 0;
         
     | 
| 
      
 857 
     | 
    
         
            +
            	else if ( c == '\\' ) {
         
     | 
| 
      
 858 
     | 
    
         
            +
            	    maybetag=0;
         
     | 
| 
      
 859 
     | 
    
         
            +
            	    if ( peek(f, size+2) != EOF )
         
     | 
| 
      
 860 
     | 
    
         
            +
            		size++;
         
     | 
| 
      
 861 
     | 
    
         
            +
            	}
         
     | 
| 
      
 862 
     | 
    
         
            +
            	else if ( isspace(c) )
         
     | 
| 
      
 863 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 864 
     | 
    
         
            +
            	else if ( ! (c == '/' || isalnum(c) ) )
         
     | 
| 
      
 865 
     | 
    
         
            +
            	    maybetag=0;
         
     | 
| 
       739 
866 
     | 
    
         
             
                }
         
     | 
| 
       740 
867 
     | 
    
         | 
| 
       741 
     | 
    
         
            -
                if ( size  
     | 
| 
       742 
     | 
    
         
            -
            	 
     | 
| 
       743 
     | 
    
         
            -
             
     | 
| 
       744 
     | 
    
         
            -
             
     | 
| 
       745 
     | 
    
         
            -
             
     | 
| 
       746 
     | 
    
         
            -
             
     | 
| 
       747 
     | 
    
         
            -
             
     | 
| 
       748 
     | 
    
         
            -
            	 
     | 
| 
      
 868 
     | 
    
         
            +
                if ( size ) {
         
     | 
| 
      
 869 
     | 
    
         
            +
            	if ( maybetag || (size >= 3 && strncmp(cursor(f), "!--", 3) == 0) ) {
         
     | 
| 
      
 870 
     | 
    
         
            +
            	    Qstring(forbidden_tag(f) ? "<" : "<", f);
         
     | 
| 
      
 871 
     | 
    
         
            +
            	    while ( ((c = peek(f, 1)) != EOF) && (c != '>') )
         
     | 
| 
      
 872 
     | 
    
         
            +
            		cputc(pull(f), f);
         
     | 
| 
      
 873 
     | 
    
         
            +
            	    return 1;
         
     | 
| 
      
 874 
     | 
    
         
            +
            	}
         
     | 
| 
      
 875 
     | 
    
         
            +
            	else if ( !isspace(c) && process_possible_link(f, size) ) {
         
     | 
| 
      
 876 
     | 
    
         
            +
            	    shift(f, size+1);
         
     | 
| 
      
 877 
     | 
    
         
            +
            	    return 1;
         
     | 
| 
      
 878 
     | 
    
         
            +
            	}
         
     | 
| 
       749 
879 
     | 
    
         
             
                }
         
     | 
| 
      
 880 
     | 
    
         
            +
                
         
     | 
| 
      
 881 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 882 
     | 
    
         
            +
            }
         
     | 
| 
       750 
883 
     | 
    
         | 
| 
       751 
     | 
    
         
            -
                if ( f->flags & DENY_A ) return 0;
         
     | 
| 
       752 
     | 
    
         
            -
             
     | 
| 
       753 
     | 
    
         
            -
                text = cursor(f);
         
     | 
| 
       754 
     | 
    
         
            -
                shift(f, size+1);
         
     | 
| 
       755 
884 
     | 
    
         | 
| 
       756 
     | 
    
         
            -
             
     | 
| 
       757 
     | 
    
         
            -
             
     | 
| 
       758 
     | 
    
         
            -
             
     | 
| 
       759 
     | 
    
         
            -
             
     | 
| 
       760 
     | 
    
         
            -
             
     | 
| 
       761 
     | 
    
         
            -
             
     | 
| 
       762 
     | 
    
         
            -
             
     | 
| 
       763 
     | 
    
         
            -
             
     | 
| 
       764 
     | 
    
         
            -
             
     | 
| 
       765 
     | 
    
         
            -
                if ( maybeaddress ) {
         
     | 
| 
      
 885 
     | 
    
         
            +
            /* autolinking means that all inline html is <a href'ified>.   A
         
     | 
| 
      
 886 
     | 
    
         
            +
             * autolink url is alphanumerics, slashes, periods, underscores,
         
     | 
| 
      
 887 
     | 
    
         
            +
             * the at sign, colon, and the % character.
         
     | 
| 
      
 888 
     | 
    
         
            +
             */
         
     | 
| 
      
 889 
     | 
    
         
            +
            static int
         
     | 
| 
      
 890 
     | 
    
         
            +
            maybe_autolink(MMIOT *f)
         
     | 
| 
      
 891 
     | 
    
         
            +
            {
         
     | 
| 
      
 892 
     | 
    
         
            +
                register int c;
         
     | 
| 
      
 893 
     | 
    
         
            +
                int size;
         
     | 
| 
       766 
894 
     | 
    
         | 
| 
       767 
     | 
    
         
            -
             
     | 
| 
       768 
     | 
    
         
            -
             
     | 
| 
       769 
     | 
    
         
            -
             
     | 
| 
       770 
     | 
    
         
            -
            	 
     | 
| 
       771 
     | 
    
         
            -
             
     | 
| 
       772 
     | 
    
         
            -
             
     | 
| 
       773 
     | 
    
         
            -
            	    mangle("mailto:", 7, f);
         
     | 
| 
      
 895 
     | 
    
         
            +
                /* greedily scan forward for the end of a legitimate link.
         
     | 
| 
      
 896 
     | 
    
         
            +
                 */
         
     | 
| 
      
 897 
     | 
    
         
            +
                for ( size=0; (c=peek(f, size+1)) != EOF; size++ )
         
     | 
| 
      
 898 
     | 
    
         
            +
            	if ( c == '\\' ) {
         
     | 
| 
      
 899 
     | 
    
         
            +
            	     if ( peek(f, size+2) != EOF )
         
     | 
| 
      
 900 
     | 
    
         
            +
            		++size;
         
     | 
| 
       774 
901 
     | 
    
         
             
            	}
         
     | 
| 
      
 902 
     | 
    
         
            +
            	else if ( isspace(c) || strchr("'\"()[]{}<>`", c) )
         
     | 
| 
      
 903 
     | 
    
         
            +
            	    break;
         
     | 
| 
       775 
904 
     | 
    
         | 
| 
       776 
     | 
    
         
            -
             
     | 
| 
       777 
     | 
    
         
            -
            	 
     | 
| 
       778 
     | 
    
         
            -
            	mangle(text+mailto, size-mailto, f);
         
     | 
| 
       779 
     | 
    
         
            -
            	Qstring("</a>", f);
         
     | 
| 
      
 905 
     | 
    
         
            +
                if ( (size > 1) && process_possible_link(f, size) ) {
         
     | 
| 
      
 906 
     | 
    
         
            +
            	shift(f, size);
         
     | 
| 
       780 
907 
     | 
    
         
             
            	return 1;
         
     | 
| 
       781 
908 
     | 
    
         
             
                }
         
     | 
| 
       782 
     | 
    
         
            -
             
     | 
| 
       783 
     | 
    
         
            -
                shift(f, -(size+1));
         
     | 
| 
       784 
909 
     | 
    
         
             
                return 0;
         
     | 
| 
       785 
     | 
    
         
            -
            } 
     | 
| 
      
 910 
     | 
    
         
            +
            }
         
     | 
| 
       786 
911 
     | 
    
         | 
| 
       787 
912 
     | 
    
         | 
| 
       788 
913 
     | 
    
         
             
            /* smartyquote code that's common for single and double quotes
         
     | 
| 
         @@ -868,7 +993,7 @@ smartypants(int c, int *flags, MMIOT *f) 
     | 
|
| 
       868 
993 
     | 
    
         
             
            {
         
     | 
| 
       869 
994 
     | 
    
         
             
                int i;
         
     | 
| 
       870 
995 
     | 
    
         | 
| 
       871 
     | 
    
         
            -
                if ( f->flags & DENY_SMARTY )
         
     | 
| 
      
 996 
     | 
    
         
            +
                if ( f->flags & (DENY_SMARTY|INSIDE_TAG) )
         
     | 
| 
       872 
997 
     | 
    
         
             
            	return 0;
         
     | 
| 
       873 
998 
     | 
    
         | 
| 
       874 
999 
     | 
    
         
             
                for ( i=0; i < NRSMART; i++)
         
     | 
| 
         @@ -922,12 +1047,23 @@ text(MMIOT *f) 
     | 
|
| 
       922 
1047 
     | 
    
         
             
                int rep;
         
     | 
| 
       923 
1048 
     | 
    
         
             
                int smartyflags = 0;
         
     | 
| 
       924 
1049 
     | 
    
         | 
| 
       925 
     | 
    
         
            -
                while ( 
     | 
| 
      
 1050 
     | 
    
         
            +
                while (1) {
         
     | 
| 
      
 1051 
     | 
    
         
            +
                    if ( (f->flags & AUTOLINK) && isalpha(peek(f,1)) )
         
     | 
| 
      
 1052 
     | 
    
         
            +
            	    maybe_autolink(f);
         
     | 
| 
      
 1053 
     | 
    
         
            +
             
     | 
| 
      
 1054 
     | 
    
         
            +
                    c = pull(f);
         
     | 
| 
      
 1055 
     | 
    
         
            +
             
     | 
| 
      
 1056 
     | 
    
         
            +
                    if (c == EOF)
         
     | 
| 
      
 1057 
     | 
    
         
            +
                      break;
         
     | 
| 
      
 1058 
     | 
    
         
            +
             
     | 
| 
       926 
1059 
     | 
    
         
             
            	if ( smartypants(c, &smartyflags, f) )
         
     | 
| 
       927 
1060 
     | 
    
         
             
            	    continue;
         
     | 
| 
       928 
1061 
     | 
    
         
             
            	switch (c) {
         
     | 
| 
       929 
1062 
     | 
    
         
             
            	case 0:     break;
         
     | 
| 
       930 
1063 
     | 
    
         | 
| 
      
 1064 
     | 
    
         
            +
            	case 3:     Qstring("<br/>", f);
         
     | 
| 
      
 1065 
     | 
    
         
            +
            		    break;
         
     | 
| 
      
 1066 
     | 
    
         
            +
             
     | 
| 
       931 
1067 
     | 
    
         
             
            	case '>':   if ( tag_text(f) )
         
     | 
| 
       932 
1068 
     | 
    
         
             
            			Qstring(">", f);
         
     | 
| 
       933 
1069 
     | 
    
         
             
            		    else
         
     | 
| 
         @@ -971,15 +1107,24 @@ text(MMIOT *f) 
     | 
|
| 
       971 
1107 
     | 
    
         
             
            	case '_':
         
     | 
| 
       972 
1108 
     | 
    
         
             
            #if RELAXED_EMPHASIS
         
     | 
| 
       973 
1109 
     | 
    
         
             
            	/* Underscores don't count if they're in the middle of a word */
         
     | 
| 
       974 
     | 
    
         
            -
            		    if (  
     | 
| 
       975 
     | 
    
         
            -
             
     | 
| 
       976 
     | 
    
         
            -
             
     | 
| 
      
 1110 
     | 
    
         
            +
            		    if ( !(f->flags & STRICT) && isthisalnum(f,-1)
         
     | 
| 
      
 1111 
     | 
    
         
            +
            					      && isthisalnum(f,1) ) {
         
     | 
| 
      
 1112 
     | 
    
         
            +
            			Qchar(c, f);
         
     | 
| 
      
 1113 
     | 
    
         
            +
            			break;
         
     | 
| 
      
 1114 
     | 
    
         
            +
            		    }
         
     | 
| 
      
 1115 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1116 
     | 
    
         
            +
            	case '*':
         
     | 
| 
      
 1117 
     | 
    
         
            +
            #if RELAXED_EMPHASIS
         
     | 
| 
      
 1118 
     | 
    
         
            +
            	/* Underscores & stars don't count if they're out in the middle
         
     | 
| 
      
 1119 
     | 
    
         
            +
            	 * of whitespace */
         
     | 
| 
      
 1120 
     | 
    
         
            +
            		    if ( !(f->flags & STRICT) && isthisspace(f,-1)
         
     | 
| 
      
 1121 
     | 
    
         
            +
            					      && isthisspace(f,1) ) {
         
     | 
| 
       977 
1122 
     | 
    
         
             
            			Qchar(c, f);
         
     | 
| 
       978 
1123 
     | 
    
         
             
            			break;
         
     | 
| 
       979 
1124 
     | 
    
         
             
            		    }
         
     | 
| 
       980 
1125 
     | 
    
         
             
            		    /* else fall into the regular old emphasis case */
         
     | 
| 
       981 
1126 
     | 
    
         
             
            #endif
         
     | 
| 
       982 
     | 
    
         
            -
             
     | 
| 
      
 1127 
     | 
    
         
            +
            		    if ( tag_text(f) )
         
     | 
| 
       983 
1128 
     | 
    
         
             
            			Qchar(c, f);
         
     | 
| 
       984 
1129 
     | 
    
         
             
            		    else {
         
     | 
| 
       985 
1130 
     | 
    
         
             
            			for (rep = 1; peek(f,1) == c; pull(f) )
         
     | 
| 
         @@ -1143,10 +1288,10 @@ printblock(Paragraph *pp, MMIOT *f) 
     | 
|
| 
       1143 
1288 
     | 
    
         
             
            	    if ( S(t->text) > 2 && T(t->text)[S(t->text)-2] == ' '
         
     | 
| 
       1144 
1289 
     | 
    
         
             
            				&& T(t->text)[S(t->text)-1] == ' ') {
         
     | 
| 
       1145 
1290 
     | 
    
         
             
            		push(T(t->text), S(t->text)-2, f);
         
     | 
| 
       1146 
     | 
    
         
            -
            		push(" 
     | 
| 
      
 1291 
     | 
    
         
            +
            		push("\003\n", 2, f);
         
     | 
| 
       1147 
1292 
     | 
    
         
             
            	    }
         
     | 
| 
       1148 
1293 
     | 
    
         
             
            	    else {
         
     | 
| 
       1149 
     | 
    
         
            -
            		___mkd_tidy(t);
         
     | 
| 
      
 1294 
     | 
    
         
            +
            		___mkd_tidy(&t->text);
         
     | 
| 
       1150 
1295 
     | 
    
         
             
            		push(T(t->text), S(t->text), f);
         
     | 
| 
       1151 
1296 
     | 
    
         
             
            		if ( t->next )
         
     | 
| 
       1152 
1297 
     | 
    
         
             
            		    push("\n", 1, f);
         
     |