redcarpet 1.2.2 → 1.3.0
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.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- data/ext/array.c +1 -1
- data/ext/buffer.c +3 -2
- data/ext/markdown.c +75 -66
- data/ext/markdown.h +12 -37
- data/ext/redcarpet.c +8 -2
- data/ext/{render.c → xhtml.c} +103 -4
- data/ext/xhtml.h +43 -0
- data/lib/redcarpet.rb +1 -1
- data/redcarpet.gemspec +4 -4
- data/test/redcarpet_test.rb +2 -2
- metadata +6 -6
- data/ext/toc.c +0 -101
    
        data/ext/array.c
    CHANGED
    
    
    
        data/ext/buffer.c
    CHANGED
    
    | @@ -302,10 +302,11 @@ vbufprintf(struct buf *buf, const char *fmt, va_list ap) { | |
| 302 302 | 
             
            	n = vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap);
         | 
| 303 303 |  | 
| 304 304 | 
             
            	if (n < 0 || (size_t)n >= buf->asize - buf->size) {
         | 
| 305 | 
            -
            		 | 
| 305 | 
            +
            		size_t new_size = (n > 0) ? n : buf->size;
         | 
| 306 | 
            +
            		if (!bufgrow (buf, buf->size + new_size + 1))
         | 
| 306 307 | 
             
            			return;
         | 
| 307 308 |  | 
| 308 | 
            -
            		n = vsnprintf | 
| 309 | 
            +
            		n = vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap_save);
         | 
| 309 310 | 
             
            	}
         | 
| 310 311 | 
             
            	va_end(ap_save);
         | 
| 311 312 |  | 
    
        data/ext/markdown.c
    CHANGED
    
    | @@ -47,7 +47,7 @@ struct link_ref { | |
| 47 47 | 
             
            /*   offset is the number of valid chars before data */
         | 
| 48 48 | 
             
            struct render;
         | 
| 49 49 | 
             
            typedef size_t
         | 
| 50 | 
            -
            (*char_trigger)(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 50 | 
            +
            (*char_trigger)(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
         | 
| 51 51 |  | 
| 52 52 |  | 
| 53 53 | 
             
            /* render • structure containing one particular render */
         | 
| @@ -56,7 +56,6 @@ struct render { | |
| 56 56 | 
             
            	struct array refs;
         | 
| 57 57 | 
             
            	char_trigger active_char[256];
         | 
| 58 58 | 
             
            	struct parray work;
         | 
| 59 | 
            -
            	int header_count;
         | 
| 60 59 | 
             
            };
         | 
| 61 60 |  | 
| 62 61 | 
             
            /* html_tag • structure for quick HTML tag search (inspired from discount) */
         | 
| @@ -233,13 +232,13 @@ tag_length(char *data, size_t size, enum mkd_autolink *autolink) | |
| 233 232 |  | 
| 234 233 | 
             
            /* parse_inline • parses inline markdown elements */
         | 
| 235 234 | 
             
            static void
         | 
| 236 | 
            -
            parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size | 
| 235 | 
            +
            parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
         | 
| 237 236 | 
             
            {
         | 
| 238 237 | 
             
            	size_t i = 0, end = 0;
         | 
| 239 238 | 
             
            	char_trigger action = 0;
         | 
| 240 239 | 
             
            	struct buf work = { 0, 0, 0, 0, 0 };
         | 
| 241 240 |  | 
| 242 | 
            -
            	if ( | 
| 241 | 
            +
            	if (rndr->work.size > rndr->make.parser_options.recursion_depth)
         | 
| 243 242 | 
             
            		return;
         | 
| 244 243 |  | 
| 245 244 | 
             
            	while (i < size) {
         | 
| @@ -259,7 +258,7 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size, int d | |
| 259 258 | 
             
            		i = end;
         | 
| 260 259 |  | 
| 261 260 | 
             
            		/* calling the trigger */
         | 
| 262 | 
            -
            		end = action(ob, rndr, data + i, i, size - i | 
| 261 | 
            +
            		end = action(ob, rndr, data + i, i, size - i);
         | 
| 263 262 | 
             
            		if (!end) /* no action from the callback */
         | 
| 264 263 | 
             
            			end = i + 1;
         | 
| 265 264 | 
             
            		else { 
         | 
| @@ -323,7 +322,7 @@ find_emph_char(char *data, size_t size, char c) | |
| 323 322 | 
             
            /* parse_emph1 • parsing single emphase */
         | 
| 324 323 | 
             
            /* closed by a symbol not preceded by whitespace and not followed by symbol */
         | 
| 325 324 | 
             
            static size_t
         | 
| 326 | 
            -
            parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c | 
| 325 | 
            +
            parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
         | 
| 327 326 | 
             
            {
         | 
| 328 327 | 
             
            	size_t i = 0, len;
         | 
| 329 328 | 
             
            	struct buf *work = 0;
         | 
| @@ -347,7 +346,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c | |
| 347 346 |  | 
| 348 347 | 
             
            		if (data[i] == c && !isspace(data[i - 1])) {
         | 
| 349 348 |  | 
| 350 | 
            -
            			if ((rndr->make.parser_options.flags &  | 
| 349 | 
            +
            			if ((rndr->make.parser_options.flags & MKD_LAX_EMPHASIS) == 0) {
         | 
| 351 350 | 
             
            				if (!(i + 1 == size || isspace(data[i + 1]) || ispunct(data[i + 1])))
         | 
| 352 351 | 
             
            					continue;
         | 
| 353 352 | 
             
            			}
         | 
| @@ -360,7 +359,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c | |
| 360 359 | 
             
            				parr_push(&rndr->work, work);
         | 
| 361 360 | 
             
            			}
         | 
| 362 361 |  | 
| 363 | 
            -
            			parse_inline(work, rndr, data, i | 
| 362 | 
            +
            			parse_inline(work, rndr, data, i);
         | 
| 364 363 | 
             
            			r = rndr->make.emphasis(ob, work, c, &rndr->make.render_options);
         | 
| 365 364 | 
             
            			rndr->work.size -= 1;
         | 
| 366 365 | 
             
            			return r ? i + 1 : 0;
         | 
| @@ -372,13 +371,14 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c | |
| 372 371 |  | 
| 373 372 | 
             
            /* parse_emph2 • parsing single emphase */
         | 
| 374 373 | 
             
            static size_t
         | 
| 375 | 
            -
            parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c | 
| 374 | 
            +
            parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
         | 
| 376 375 | 
             
            {
         | 
| 377 376 | 
             
            	size_t i = 0, len;
         | 
| 378 377 | 
             
            	struct buf *work = 0;
         | 
| 379 378 | 
             
            	int r;
         | 
| 380 379 |  | 
| 381 | 
            -
            	if (!rndr->make.double_emphasis) | 
| 380 | 
            +
            	if (!rndr->make.double_emphasis)
         | 
| 381 | 
            +
            		return 0;
         | 
| 382 382 |  | 
| 383 383 | 
             
            	while (i < size) {
         | 
| 384 384 | 
             
            		len = find_emph_char(data + i, size - i, c);
         | 
| @@ -394,7 +394,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c | |
| 394 394 | 
             
            				parr_push(&rndr->work, work);
         | 
| 395 395 | 
             
            			}
         | 
| 396 396 |  | 
| 397 | 
            -
            			parse_inline(work, rndr, data, i | 
| 397 | 
            +
            			parse_inline(work, rndr, data, i);
         | 
| 398 398 | 
             
            			r = rndr->make.double_emphasis(ob, work, c, &rndr->make.render_options);
         | 
| 399 399 | 
             
            			rndr->work.size -= 1;
         | 
| 400 400 | 
             
            			return r ? i + 2 : 0;
         | 
| @@ -407,7 +407,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c | |
| 407 407 | 
             
            /* parse_emph3 • parsing single emphase */
         | 
| 408 408 | 
             
            /* finds the first closing tag, and delegates to the other emph */
         | 
| 409 409 | 
             
            static size_t
         | 
| 410 | 
            -
            parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c | 
| 410 | 
            +
            parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
         | 
| 411 411 | 
             
            {
         | 
| 412 412 | 
             
            	size_t i = 0, len;
         | 
| 413 413 | 
             
            	int r;
         | 
| @@ -432,20 +432,20 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c | |
| 432 432 | 
             
            				parr_push(&rndr->work, work);
         | 
| 433 433 | 
             
            			}
         | 
| 434 434 |  | 
| 435 | 
            -
            			parse_inline(work, rndr, data, i | 
| 435 | 
            +
            			parse_inline(work, rndr, data, i);
         | 
| 436 436 | 
             
            			r = rndr->make.triple_emphasis(ob, work, c, &rndr->make.render_options);
         | 
| 437 437 | 
             
            			rndr->work.size -= 1;
         | 
| 438 438 | 
             
            			return r ? i + 3 : 0;
         | 
| 439 439 |  | 
| 440 440 | 
             
            		} else if (i + 1 < size && data[i + 1] == c) {
         | 
| 441 441 | 
             
            			/* double symbol found, handing over to emph1 */
         | 
| 442 | 
            -
            			len = parse_emph1(ob, rndr, data - 2, size + 2, c | 
| 442 | 
            +
            			len = parse_emph1(ob, rndr, data - 2, size + 2, c);
         | 
| 443 443 | 
             
            			if (!len) return 0;
         | 
| 444 444 | 
             
            			else return len - 2;
         | 
| 445 445 |  | 
| 446 446 | 
             
            		} else {
         | 
| 447 447 | 
             
            			/* single symbol found, handing over to emph2 */
         | 
| 448 | 
            -
            			len = parse_emph2(ob, rndr, data - 1, size + 1, c | 
| 448 | 
            +
            			len = parse_emph2(ob, rndr, data - 1, size + 1, c);
         | 
| 449 449 | 
             
            			if (!len) return 0;
         | 
| 450 450 | 
             
            			else return len - 1;
         | 
| 451 451 | 
             
            		}
         | 
| @@ -455,28 +455,28 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c | |
| 455 455 |  | 
| 456 456 | 
             
            /* char_emphasis • single and double emphasis parsing */
         | 
| 457 457 | 
             
            static size_t
         | 
| 458 | 
            -
            char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 458 | 
            +
            char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
         | 
| 459 459 | 
             
            {
         | 
| 460 460 | 
             
            	char c = data[0];
         | 
| 461 461 | 
             
            	size_t ret;
         | 
| 462 462 |  | 
| 463 463 | 
             
            	if (size > 2 && data[1] != c) {
         | 
| 464 464 | 
             
            		/* whitespace cannot follow an opening emphasis */
         | 
| 465 | 
            -
            		if (isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c | 
| 465 | 
            +
            		if (isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)
         | 
| 466 466 | 
             
            			return 0;
         | 
| 467 467 |  | 
| 468 468 | 
             
            		return ret + 1;
         | 
| 469 469 | 
             
            	}
         | 
| 470 470 |  | 
| 471 471 | 
             
            	if (size > 3 && data[1] == c && data[2] != c) {
         | 
| 472 | 
            -
            		if (isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c | 
| 472 | 
            +
            		if (isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c)) == 0)
         | 
| 473 473 | 
             
            			return 0;
         | 
| 474 474 |  | 
| 475 475 | 
             
            		return ret + 2;
         | 
| 476 476 | 
             
            	}
         | 
| 477 477 |  | 
| 478 478 | 
             
            	if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {
         | 
| 479 | 
            -
            		if (isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c | 
| 479 | 
            +
            		if (isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)
         | 
| 480 480 | 
             
            			return 0;
         | 
| 481 481 |  | 
| 482 482 | 
             
            		return ret + 3;
         | 
| @@ -488,7 +488,7 @@ char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, si | |
| 488 488 |  | 
| 489 489 | 
             
            /* char_linebreak • '\n' preceded by two spaces (assuming linebreak != 0) */
         | 
| 490 490 | 
             
            static size_t
         | 
| 491 | 
            -
            char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 491 | 
            +
            char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
         | 
| 492 492 | 
             
            {
         | 
| 493 493 | 
             
            	if (offset < 2 || data[-1] != ' ' || data[-2] != ' ')
         | 
| 494 494 | 
             
            		return 0;
         | 
| @@ -503,7 +503,7 @@ char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, s | |
| 503 503 |  | 
| 504 504 | 
             
            /* char_codespan • '`' parsing a code span (assuming codespan != 0) */
         | 
| 505 505 | 
             
            static size_t
         | 
| 506 | 
            -
            char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 506 | 
            +
            char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
         | 
| 507 507 | 
             
            {
         | 
| 508 508 | 
             
            	size_t end, nb = 0, i, f_begin, f_end;
         | 
| 509 509 |  | 
| @@ -546,7 +546,7 @@ char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, si | |
| 546 546 |  | 
| 547 547 | 
             
            /* char_escape • '\\' backslash escape */
         | 
| 548 548 | 
             
            static size_t
         | 
| 549 | 
            -
            char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 549 | 
            +
            char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
         | 
| 550 550 | 
             
            {
         | 
| 551 551 | 
             
            	struct buf work = { 0, 0, 0, 0, 0 };
         | 
| 552 552 |  | 
| @@ -565,7 +565,7 @@ char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size | |
| 565 565 | 
             
            /* char_entity • '&' escaped when it doesn't belong to an entity */
         | 
| 566 566 | 
             
            /* valid entities are assumed to be anything mathing &#?[A-Za-z0-9]+; */
         | 
| 567 567 | 
             
            static size_t
         | 
| 568 | 
            -
            char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 568 | 
            +
            char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
         | 
| 569 569 | 
             
            {
         | 
| 570 570 | 
             
            	size_t end = 1;
         | 
| 571 571 | 
             
            	struct buf work;
         | 
| @@ -593,7 +593,7 @@ char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size | |
| 593 593 |  | 
| 594 594 | 
             
            /* char_langle_tag • '<' when tags or autolinks are allowed */
         | 
| 595 595 | 
             
            static size_t
         | 
| 596 | 
            -
            char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 596 | 
            +
            char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
         | 
| 597 597 | 
             
            {
         | 
| 598 598 | 
             
            	enum mkd_autolink altype = MKDA_NOT_AUTOLINK;
         | 
| 599 599 | 
             
            	size_t end = tag_length(data, size, &altype);
         | 
| @@ -617,7 +617,7 @@ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, | |
| 617 617 |  | 
| 618 618 | 
             
            /* char_link • '[': parsing a link or an image */
         | 
| 619 619 | 
             
            static size_t
         | 
| 620 | 
            -
            char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size | 
| 620 | 
            +
            char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
         | 
| 621 621 | 
             
            {
         | 
| 622 622 | 
             
            	int is_img = (offset && data[-1] == '!'), level;
         | 
| 623 623 | 
             
            	size_t i = 1, txt_e, link_b = 0, link_e = 0, title_b = 0, title_e = 0;
         | 
| @@ -802,7 +802,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t | |
| 802 802 | 
             
            		}
         | 
| 803 803 |  | 
| 804 804 | 
             
            		if (is_img) bufput(content, data + 1, txt_e - 1);
         | 
| 805 | 
            -
            		else parse_inline(content, rndr, data + 1, txt_e - 1 | 
| 805 | 
            +
            		else parse_inline(content, rndr, data + 1, txt_e - 1);
         | 
| 806 806 | 
             
            	}
         | 
| 807 807 |  | 
| 808 808 | 
             
            	/* calling the relevant rendering function */
         | 
| @@ -944,12 +944,12 @@ prefix_uli(char *data, size_t size) | |
| 944 944 |  | 
| 945 945 | 
             
            /* parse_block • parsing of one block, returning next char to parse */
         | 
| 946 946 | 
             
            static void parse_block(struct buf *ob, struct render *rndr,
         | 
| 947 | 
            -
            			char *data, size_t size | 
| 947 | 
            +
            			char *data, size_t size);
         | 
| 948 948 |  | 
| 949 949 |  | 
| 950 950 | 
             
            /* parse_blockquote • hanldes parsing of a blockquote fragment */
         | 
| 951 951 | 
             
            static size_t
         | 
| 952 | 
            -
            parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size | 
| 952 | 
            +
            parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size)
         | 
| 953 953 | 
             
            {
         | 
| 954 954 | 
             
            	size_t beg, end = 0, pre, work_size = 0;
         | 
| 955 955 | 
             
            	char *work_data = 0;
         | 
| @@ -964,8 +964,7 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size, i | |
| 964 964 |  | 
| 965 965 | 
             
            	beg = 0;
         | 
| 966 966 | 
             
            	while (beg < size) {
         | 
| 967 | 
            -
            		for (end = beg + 1; end < size && data[end - 1] != '\n';
         | 
| 968 | 
            -
            							end += 1);
         | 
| 967 | 
            +
            		for (end = beg + 1; end < size && data[end - 1] != '\n'; end += 1);
         | 
| 969 968 | 
             
            		pre = prefix_quote(data + beg, end - beg);
         | 
| 970 969 | 
             
            		if (pre) beg += pre; /* skipping prefix */
         | 
| 971 970 | 
             
            		else if (is_empty(data + beg, end - beg)
         | 
| @@ -983,7 +982,7 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size, i | |
| 983 982 | 
             
            			work_size += end - beg; }
         | 
| 984 983 | 
             
            		beg = end; }
         | 
| 985 984 |  | 
| 986 | 
            -
            	parse_block(out, rndr, work_data, work_size | 
| 985 | 
            +
            	parse_block(out, rndr, work_data, work_size);
         | 
| 987 986 | 
             
            	if (rndr->make.blockquote)
         | 
| 988 987 | 
             
            		rndr->make.blockquote(ob, out, &rndr->make.render_options);
         | 
| 989 988 | 
             
            	rndr->work.size -= 1;
         | 
| @@ -995,7 +994,7 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in | |
| 995 994 |  | 
| 996 995 | 
             
            /* parse_blockquote • hanldes parsing of a regular paragraph */
         | 
| 997 996 | 
             
            static size_t
         | 
| 998 | 
            -
            parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size | 
| 997 | 
            +
            parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
         | 
| 999 998 | 
             
            {
         | 
| 1000 999 | 
             
            	size_t i = 0, end = 0;
         | 
| 1001 1000 | 
             
            	int level = 0;
         | 
| @@ -1037,7 +1036,7 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size, in | |
| 1037 1036 | 
             
            		else {
         | 
| 1038 1037 | 
             
            			tmp = bufnew(WORK_UNIT);
         | 
| 1039 1038 | 
             
            			parr_push(&rndr->work, tmp); }
         | 
| 1040 | 
            -
            		parse_inline(tmp, rndr, work.data, work.size | 
| 1039 | 
            +
            		parse_inline(tmp, rndr, work.data, work.size);
         | 
| 1041 1040 | 
             
            		if (rndr->make.paragraph)
         | 
| 1042 1041 | 
             
            			rndr->make.paragraph(ob, tmp, &rndr->make.render_options);
         | 
| 1043 1042 | 
             
            		rndr->work.size -= 1; }
         | 
| @@ -1059,16 +1058,15 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size, in | |
| 1059 1058 | 
             
            				else {
         | 
| 1060 1059 | 
             
            					tmp = bufnew(WORK_UNIT);
         | 
| 1061 1060 | 
             
            					parr_push(&rndr->work, tmp); }
         | 
| 1062 | 
            -
            				parse_inline(tmp, rndr, work.data, work.size | 
| 1061 | 
            +
            				parse_inline(tmp, rndr, work.data, work.size);
         | 
| 1063 1062 | 
             
            				if (rndr->make.paragraph)
         | 
| 1064 | 
            -
            					rndr->make.paragraph(ob, tmp,
         | 
| 1065 | 
            -
            							&rndr->make.render_options);
         | 
| 1063 | 
            +
            					rndr->make.paragraph(ob, tmp, &rndr->make.render_options);
         | 
| 1066 1064 | 
             
            				rndr->work.size -= 1;
         | 
| 1067 1065 | 
             
            				work.data += beg;
         | 
| 1068 1066 | 
             
            				work.size = i - beg; }
         | 
| 1069 1067 | 
             
            			else work.size = i; }
         | 
| 1070 1068 | 
             
            		if (rndr->make.header)
         | 
| 1071 | 
            -
            			rndr->make.header(ob, &work, level,  | 
| 1069 | 
            +
            			rndr->make.header(ob, &work, level, &rndr->make.render_options);}
         | 
| 1072 1070 | 
             
            	return end;
         | 
| 1073 1071 | 
             
            }
         | 
| 1074 1072 |  | 
| @@ -1115,7 +1113,7 @@ parse_blockcode(struct buf *ob, struct render *rndr, char *data, size_t size) | |
| 1115 1113 | 
             
            /* parse_listitem • parsing of a single list item */
         | 
| 1116 1114 | 
             
            /*	assuming initial prefix is already removed */
         | 
| 1117 1115 | 
             
            static size_t
         | 
| 1118 | 
            -
            parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int *flags | 
| 1116 | 
            +
            parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int *flags)
         | 
| 1119 1117 | 
             
            {
         | 
| 1120 1118 | 
             
            	struct buf *work = 0, *inter = 0;
         | 
| 1121 1119 | 
             
            	size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
         | 
| @@ -1215,19 +1213,19 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int | |
| 1215 1213 | 
             
            	if (*flags & MKD_LI_BLOCK) {
         | 
| 1216 1214 | 
             
            		/* intermediate render of block li */
         | 
| 1217 1215 | 
             
            		if (sublist && sublist < work->size) {
         | 
| 1218 | 
            -
            			parse_block(inter, rndr, work->data, sublist | 
| 1219 | 
            -
            			parse_block(inter, rndr, work->data + sublist, work->size - sublist | 
| 1216 | 
            +
            			parse_block(inter, rndr, work->data, sublist);
         | 
| 1217 | 
            +
            			parse_block(inter, rndr, work->data + sublist, work->size - sublist); 
         | 
| 1220 1218 | 
             
            		}
         | 
| 1221 1219 | 
             
            		else
         | 
| 1222 | 
            -
            			parse_block(inter, rndr, work->data, work->size | 
| 1220 | 
            +
            			parse_block(inter, rndr, work->data, work->size);
         | 
| 1223 1221 | 
             
            	} else {
         | 
| 1224 1222 | 
             
            		/* intermediate render of inline li */
         | 
| 1225 1223 | 
             
            		if (sublist && sublist < work->size) {
         | 
| 1226 | 
            -
            			parse_inline(inter, rndr, work->data, sublist | 
| 1227 | 
            -
            			parse_block(inter, rndr, work->data + sublist, work->size - sublist | 
| 1224 | 
            +
            			parse_inline(inter, rndr, work->data, sublist);
         | 
| 1225 | 
            +
            			parse_block(inter, rndr, work->data + sublist, work->size - sublist);
         | 
| 1228 1226 | 
             
            		}
         | 
| 1229 1227 | 
             
            		else
         | 
| 1230 | 
            -
            			parse_inline(inter, rndr, work->data, work->size | 
| 1228 | 
            +
            			parse_inline(inter, rndr, work->data, work->size);
         | 
| 1231 1229 | 
             
            	}
         | 
| 1232 1230 |  | 
| 1233 1231 | 
             
            	/* render of li itself */
         | 
| @@ -1241,7 +1239,7 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int | |
| 1241 1239 |  | 
| 1242 1240 | 
             
            /* parse_list • parsing ordered or unordered list block */
         | 
| 1243 1241 | 
             
            static size_t
         | 
| 1244 | 
            -
            parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int flags | 
| 1242 | 
            +
            parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int flags)
         | 
| 1245 1243 | 
             
            {
         | 
| 1246 1244 | 
             
            	struct buf *work = 0;
         | 
| 1247 1245 | 
             
            	size_t i = 0, j;
         | 
| @@ -1254,7 +1252,7 @@ parse_list(struct buf *ob, struct render *rndr, char *data, size_t size, int fla | |
| 1254 1252 | 
             
            		parr_push(&rndr->work, work); }
         | 
| 1255 1253 |  | 
| 1256 1254 | 
             
            	while (i < size) {
         | 
| 1257 | 
            -
            		j = parse_listitem(work, rndr, data + i, size - i, &flags | 
| 1255 | 
            +
            		j = parse_listitem(work, rndr, data + i, size - i, &flags);
         | 
| 1258 1256 | 
             
            		i += j;
         | 
| 1259 1257 |  | 
| 1260 1258 | 
             
            		if (!j || (flags & MKD_LI_END))
         | 
| @@ -1287,7 +1285,7 @@ parse_atxheader(struct buf *ob, struct render *rndr, char *data, size_t size) | |
| 1287 1285 | 
             
            	while (end && (data[end - 1] == ' ' || data[end - 1] == '\t')) end -= 1;
         | 
| 1288 1286 | 
             
            	work.size = end - i;
         | 
| 1289 1287 | 
             
            	if (rndr->make.header)
         | 
| 1290 | 
            -
            		rndr->make.header(ob, &work, (int)level,  | 
| 1288 | 
            +
            		rndr->make.header(ob, &work, (int)level, &rndr->make.render_options);
         | 
| 1291 1289 | 
             
            	return skip;
         | 
| 1292 1290 | 
             
            }
         | 
| 1293 1291 |  | 
| @@ -1439,40 +1437,52 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in | |
| 1439 1437 |  | 
| 1440 1438 | 
             
            /* parse_block • parsing of one block, returning next char to parse */
         | 
| 1441 1439 | 
             
            static void
         | 
| 1442 | 
            -
            parse_block(struct buf *ob, struct render *rndr, char *data, size_t size | 
| 1440 | 
            +
            parse_block(struct buf *ob, struct render *rndr, char *data, size_t size)
         | 
| 1443 1441 | 
             
            {
         | 
| 1444 1442 | 
             
            	size_t beg, end, i;
         | 
| 1445 1443 | 
             
            	char *txt_data;
         | 
| 1446 1444 | 
             
            	beg = 0;
         | 
| 1447 1445 |  | 
| 1448 | 
            -
            	if ( | 
| 1446 | 
            +
            	if (rndr->work.size > rndr->make.parser_options.recursion_depth)
         | 
| 1449 1447 | 
             
            		return;
         | 
| 1450 1448 |  | 
| 1451 1449 | 
             
            	while (beg < size) {
         | 
| 1452 1450 | 
             
            		txt_data = data + beg;
         | 
| 1453 1451 | 
             
            		end = size - beg;
         | 
| 1452 | 
            +
             | 
| 1454 1453 | 
             
            		if (data[beg] == '#')
         | 
| 1455 1454 | 
             
            			beg += parse_atxheader(ob, rndr, txt_data, end);
         | 
| 1456 | 
            -
             | 
| 1457 | 
            -
             | 
| 1455 | 
            +
             | 
| 1456 | 
            +
            		else if (data[beg] == '<' && rndr->make.blockhtml && (i = parse_htmlblock(ob, rndr, txt_data, end, 1)) != 0)
         | 
| 1458 1457 | 
             
            			beg += i;
         | 
| 1458 | 
            +
             | 
| 1459 1459 | 
             
            		else if ((i = is_empty(txt_data, end)) != 0)
         | 
| 1460 1460 | 
             
            			beg += i;
         | 
| 1461 | 
            +
             | 
| 1461 1462 | 
             
            		else if (is_hrule(txt_data, end)) {
         | 
| 1462 1463 | 
             
            			if (rndr->make.hrule)
         | 
| 1463 1464 | 
             
            				rndr->make.hrule(ob, &rndr->make.render_options);
         | 
| 1464 | 
            -
             | 
| 1465 | 
            -
            			beg  | 
| 1465 | 
            +
             | 
| 1466 | 
            +
            			while (beg < size && data[beg] != '\n')
         | 
| 1467 | 
            +
            				beg++;
         | 
| 1468 | 
            +
             | 
| 1469 | 
            +
            			beg++;
         | 
| 1470 | 
            +
            		}
         | 
| 1471 | 
            +
             | 
| 1466 1472 | 
             
            		else if (prefix_quote(txt_data, end))
         | 
| 1467 | 
            -
            			beg += parse_blockquote(ob, rndr, txt_data, end | 
| 1473 | 
            +
            			beg += parse_blockquote(ob, rndr, txt_data, end);
         | 
| 1474 | 
            +
             | 
| 1468 1475 | 
             
            		else if (prefix_code(txt_data, end))
         | 
| 1469 1476 | 
             
            			beg += parse_blockcode(ob, rndr, txt_data, end);
         | 
| 1477 | 
            +
             | 
| 1470 1478 | 
             
            		else if (prefix_uli(txt_data, end))
         | 
| 1471 | 
            -
            			beg += parse_list(ob, rndr, txt_data, end, 0 | 
| 1479 | 
            +
            			beg += parse_list(ob, rndr, txt_data, end, 0);
         | 
| 1480 | 
            +
             | 
| 1472 1481 | 
             
            		else if (prefix_oli(txt_data, end))
         | 
| 1473 | 
            -
            			beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED | 
| 1482 | 
            +
            			beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED);
         | 
| 1483 | 
            +
             | 
| 1474 1484 | 
             
            		else
         | 
| 1475 | 
            -
            			beg += parse_paragraph(ob, rndr, txt_data, end | 
| 1485 | 
            +
            			beg += parse_paragraph(ob, rndr, txt_data, end);
         | 
| 1476 1486 | 
             
            	}
         | 
| 1477 1487 | 
             
            }
         | 
| 1478 1488 |  | 
| @@ -1652,8 +1662,6 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer) { | |
| 1652 1662 | 
             
            	rndr.active_char['\\'] = char_escape;
         | 
| 1653 1663 | 
             
            	rndr.active_char['&'] = char_entity;
         | 
| 1654 1664 |  | 
| 1655 | 
            -
            	rndr.header_count = 1;
         | 
| 1656 | 
            -
             | 
| 1657 1665 | 
             
            	/* first pass: looking for references, copying everything else */
         | 
| 1658 1666 | 
             
            	beg = 0;
         | 
| 1659 1667 | 
             
            	while (beg < ib->size) /* iterating over lines */
         | 
| @@ -1690,9 +1698,13 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer) { | |
| 1690 1698 | 
             
            		bufputc(text, '\n');
         | 
| 1691 1699 |  | 
| 1692 1700 | 
             
            	/* second pass: actual rendering */
         | 
| 1693 | 
            -
            	 | 
| 1694 | 
            -
             | 
| 1695 | 
            -
             | 
| 1701 | 
            +
            	if (rndr.make.doc_header)
         | 
| 1702 | 
            +
            		rndr.make.doc_header(ob, &rndr.make.render_options);
         | 
| 1703 | 
            +
             | 
| 1704 | 
            +
            	parse_block(ob, &rndr, text->data, text->size);
         | 
| 1705 | 
            +
             | 
| 1706 | 
            +
            	if (rndr.make.doc_footer)
         | 
| 1707 | 
            +
            		rndr.make.doc_footer(ob, &rndr.make.render_options);
         | 
| 1696 1708 |  | 
| 1697 1709 | 
             
            	/* clean-up */
         | 
| 1698 1710 | 
             
            	bufrelease(text);
         | 
| @@ -1705,10 +1717,7 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer) { | |
| 1705 1717 |  | 
| 1706 1718 | 
             
            	arr_free(&rndr.refs);
         | 
| 1707 1719 |  | 
| 1708 | 
            -
            	 | 
| 1709 | 
            -
            	 * file will result in parts of the work queue not being
         | 
| 1710 | 
            -
            	 * printed. We cannot crash the library in that case. Duh. */
         | 
| 1711 | 
            -
            	//assert(rndr.work.size == 0);
         | 
| 1720 | 
            +
            	assert(rndr.work.size == 0);
         | 
| 1712 1721 |  | 
| 1713 1722 | 
             
            	for (i = 0; i < (size_t)rndr.work.asize; i += 1)
         | 
| 1714 1723 | 
             
            		bufrelease(rndr.work.item[i]);
         | 
    
        data/ext/markdown.h
    CHANGED
    
    | @@ -16,8 +16,8 @@ | |
| 16 16 | 
             
             * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
         | 
| 17 17 | 
             
             */
         | 
| 18 18 |  | 
| 19 | 
            -
            #ifndef  | 
| 20 | 
            -
            #define  | 
| 19 | 
            +
            #ifndef UPSKIRT_MARKDOWN_H
         | 
| 20 | 
            +
            #define UPSKIRT_MARKDOWN_H
         | 
| 21 21 |  | 
| 22 22 | 
             
            #include "buffer.h"
         | 
| 23 23 |  | 
| @@ -36,12 +36,12 @@ enum mkd_autolink { | |
| 36 36 | 
             
            	MKDA_IMPLICIT_EMAIL	/* e-mail link without mailto: */
         | 
| 37 37 | 
             
            };
         | 
| 38 38 |  | 
| 39 | 
            -
             | 
| 40 | 
            -
            	 | 
| 41 | 
            -
             | 
| 42 | 
            -
            		void *ptr;
         | 
| 43 | 
            -
            	} opaque;
         | 
| 39 | 
            +
            typedef enum {
         | 
| 40 | 
            +
            	MKD_LAX_EMPHASIS = (1 << 0),
         | 
| 41 | 
            +
            } mkd_parser_mode;
         | 
| 44 42 |  | 
| 43 | 
            +
            struct mkd_renderopt {
         | 
| 44 | 
            +
            	void *opaque;
         | 
| 45 45 | 
             
            	unsigned int flags;
         | 
| 46 46 | 
             
            };
         | 
| 47 47 |  | 
| @@ -56,7 +56,7 @@ struct mkd_renderer { | |
| 56 56 | 
             
            	void (*blockcode)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
         | 
| 57 57 | 
             
            	void (*blockquote)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
         | 
| 58 58 | 
             
            	void (*blockhtml)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
         | 
| 59 | 
            -
            	void (*header)(struct buf *ob, struct buf *text, int level,  | 
| 59 | 
            +
            	void (*header)(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *opaque);
         | 
| 60 60 | 
             
            	void (*hrule)(struct buf *ob, struct mkd_renderopt *opaque);
         | 
| 61 61 | 
             
            	void (*list)(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opaque);
         | 
| 62 62 | 
             
            	void (*listitem)(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opaque);
         | 
| @@ -77,8 +77,9 @@ struct mkd_renderer { | |
| 77 77 | 
             
            	void (*entity)(struct buf *ob, struct buf *entity, struct mkd_renderopt *opaque);
         | 
| 78 78 | 
             
            	void (*normal_text)(struct buf *ob, struct buf *text, struct mkd_renderopt *opaque);
         | 
| 79 79 |  | 
| 80 | 
            -
            	/*  | 
| 81 | 
            -
            	void (* | 
| 80 | 
            +
            	/* header and footer */
         | 
| 81 | 
            +
            	void (*doc_header)(struct buf *ob, struct mkd_renderopt *opaque);
         | 
| 82 | 
            +
            	void (*doc_footer)(struct buf *ob, struct mkd_renderopt *opaque);
         | 
| 82 83 |  | 
| 83 84 | 
             
            	/* renderer data */
         | 
| 84 85 | 
             
            	const char *emph_chars; /* chars that trigger emphasis rendering */
         | 
| @@ -87,8 +88,6 @@ struct mkd_renderer { | |
| 87 88 | 
             
            	struct mkd_parseropt parser_options;
         | 
| 88 89 | 
             
            };
         | 
| 89 90 |  | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 91 | 
             
            /*********
         | 
| 93 92 | 
             
             * FLAGS *
         | 
| 94 93 | 
             
             *********/
         | 
| @@ -97,22 +96,6 @@ struct mkd_renderer { | |
| 97 96 | 
             
            #define MKD_LIST_ORDERED	1
         | 
| 98 97 | 
             
            #define MKD_LI_BLOCK		2  /* <li> containing block data */
         | 
| 99 98 |  | 
| 100 | 
            -
            typedef enum {
         | 
| 101 | 
            -
            	RENDER_SKIP_HTML = (1 << 0),
         | 
| 102 | 
            -
            	RENDER_SKIP_STYLE = (1 << 1),
         | 
| 103 | 
            -
            	RENDER_SKIP_IMAGES = (1 << 2),
         | 
| 104 | 
            -
            	RENDER_SKIP_LINKS = (1 << 3),
         | 
| 105 | 
            -
            	RENDER_SMARTYPANTS = (1 << 4),
         | 
| 106 | 
            -
            	RENDER_EXPAND_TABS = (1 << 5),
         | 
| 107 | 
            -
            	RENDER_AUTOLINK = (1 << 6),
         | 
| 108 | 
            -
            	RENDER_SAFELINK = (1 << 7),
         | 
| 109 | 
            -
            	RENDER_TOC = (1 << 8),
         | 
| 110 | 
            -
            } render_mode;
         | 
| 111 | 
            -
             | 
| 112 | 
            -
            typedef enum {
         | 
| 113 | 
            -
            	PARSER_STRICT = (1 << 0),
         | 
| 114 | 
            -
            } parser_mode;
         | 
| 115 | 
            -
             | 
| 116 99 | 
             
            /**********************
         | 
| 117 100 | 
             
             * EXPORTED FUNCTIONS *
         | 
| 118 101 | 
             
             **********************/
         | 
| @@ -121,14 +104,6 @@ typedef enum { | |
| 121 104 | 
             
            void
         | 
| 122 105 | 
             
            markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndr);
         | 
| 123 106 |  | 
| 124 | 
            -
             | 
| 125 | 
            -
            init_xhtml_renderer(struct mkd_renderer *renderer,
         | 
| 126 | 
            -
            		unsigned int render_flags,
         | 
| 127 | 
            -
            		unsigned int parser_flags, int recursion_depth);
         | 
| 128 | 
            -
             | 
| 129 | 
            -
            void
         | 
| 130 | 
            -
            init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth);
         | 
| 131 | 
            -
             | 
| 132 | 
            -
            #endif /* ndef LITHIUM_MARKDOWN_H */
         | 
| 107 | 
            +
            #endif
         | 
| 133 108 |  | 
| 134 109 | 
             
            /* vim: set filetype=c: */
         | 
    
        data/ext/redcarpet.c
    CHANGED
    
    | @@ -2,6 +2,7 @@ | |
| 2 2 | 
             
            #include "ruby.h"
         | 
| 3 3 |  | 
| 4 4 | 
             
            #include "markdown.h"
         | 
| 5 | 
            +
            #include "xhtml.h"
         | 
| 5 6 |  | 
| 6 7 | 
             
            #define REDCARPET_RECURSION_LIMIT 16
         | 
| 7 8 |  | 
| @@ -49,9 +50,13 @@ static void rb_redcarpet__setup_xhtml(struct mkd_renderer *rnd, VALUE ruby_obj) | |
| 49 50 | 
             
            	if (rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
         | 
| 50 51 | 
             
            		render_flags |= RENDER_TOC;
         | 
| 51 52 |  | 
| 52 | 
            -
            	/* parser - strict | 
| 53 | 
            +
            	/* parser - strict
         | 
| 54 | 
            +
            	 * This is fucking stupid; what the 'strict' flag actually
         | 
| 55 | 
            +
            	 * enforces is laxer emphasis parsing. So we use a properly
         | 
| 56 | 
            +
            	 * named flag internally, even if outside we have retarded
         | 
| 57 | 
            +
            	 * naming because of compat. issues .*/
         | 
| 53 58 | 
             
            	if (rb_funcall(ruby_obj, rb_intern("strict"), 0) == Qtrue)
         | 
| 54 | 
            -
            		parser_flags |=  | 
| 59 | 
            +
            		parser_flags |= MKD_LAX_EMPHASIS;
         | 
| 55 60 |  | 
| 56 61 | 
             
            	init_xhtml_renderer(rnd, render_flags, parser_flags, REDCARPET_RECURSION_LIMIT);
         | 
| 57 62 | 
             
            }
         | 
| @@ -90,6 +95,7 @@ static VALUE rb_redcarpet__render(VALUE self, RendererType render_type) | |
| 90 95 |  | 
| 91 96 | 
             
            	result = rb_str_new(output_buf->data, output_buf->size);
         | 
| 92 97 | 
             
            	bufrelease(output_buf);
         | 
| 98 | 
            +
            	free_renderer(&renderer);
         | 
| 93 99 |  | 
| 94 100 | 
             
            	/* force the input encoding */
         | 
| 95 101 | 
             
            	if (rb_respond_to(text, rb_intern("encoding"))) {
         | 
    
        data/ext/{render.c → xhtml.c}
    RENAMED
    
    | @@ -16,11 +16,16 @@ | |
| 16 16 | 
             
             */
         | 
| 17 17 |  | 
| 18 18 | 
             
            #include "markdown.h"
         | 
| 19 | 
            +
            #include "xhtml.h"
         | 
| 19 20 |  | 
| 20 21 | 
             
            #include <strings.h>
         | 
| 21 22 | 
             
            #include <stdlib.h>
         | 
| 22 23 | 
             
            #include <stdio.h>
         | 
| 23 24 |  | 
| 25 | 
            +
            struct toc_data {
         | 
| 26 | 
            +
            	int header_count;
         | 
| 27 | 
            +
            	int current_level;
         | 
| 28 | 
            +
            };
         | 
| 24 29 |  | 
| 25 30 | 
             
            static int
         | 
| 26 31 | 
             
            is_safe_link(const char *link, size_t link_len)
         | 
| @@ -48,7 +53,7 @@ is_uri_char(char c) | |
| 48 53 | 
             
            	return isalnum(c) || strchr("/:$-_.+!*'(),", c) != NULL;
         | 
| 49 54 | 
             
            }
         | 
| 50 55 |  | 
| 51 | 
            -
            static int
         | 
| 56 | 
            +
            static inline int
         | 
| 52 57 | 
             
            put_scaped_char(struct buf *ob, char c)
         | 
| 53 58 | 
             
            {
         | 
| 54 59 | 
             
            	switch (c) {
         | 
| @@ -174,13 +179,15 @@ rndr_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *op | |
| 174 179 | 
             
            }
         | 
| 175 180 |  | 
| 176 181 | 
             
            static void
         | 
| 177 | 
            -
            rndr_header(struct buf *ob, struct buf *text, int level,  | 
| 182 | 
            +
            rndr_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
         | 
| 178 183 | 
             
            {
         | 
| 179 184 | 
             
            	if (ob->size)
         | 
| 180 185 | 
             
            		bufputc(ob, '\n');
         | 
| 181 186 |  | 
| 182 | 
            -
            	if (options->flags & RENDER_TOC)
         | 
| 183 | 
            -
            		 | 
| 187 | 
            +
            	if (options->flags & RENDER_TOC) {
         | 
| 188 | 
            +
            		struct toc_data *data = options->opaque;
         | 
| 189 | 
            +
            		bufprintf(ob, "<a name=\"toc_%d\"></a>", data->header_count++);
         | 
| 190 | 
            +
            	}
         | 
| 184 191 |  | 
| 185 192 | 
             
            	bufprintf(ob, "<h%d>", level);
         | 
| 186 193 | 
             
            	if (text) bufput(ob, text->data, text->size);
         | 
| @@ -561,6 +568,87 @@ rndr_normal_text(struct buf *ob, struct buf *text, struct mkd_renderopt *options | |
| 561 568 | 
             
            	}
         | 
| 562 569 | 
             
            }
         | 
| 563 570 |  | 
| 571 | 
            +
            static void
         | 
| 572 | 
            +
            toc_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
         | 
| 573 | 
            +
            {
         | 
| 574 | 
            +
            	struct toc_data *data = (struct toc_data *)options->opaque;
         | 
| 575 | 
            +
             | 
| 576 | 
            +
            	if (level > data->current_level) {
         | 
| 577 | 
            +
            		if (level > 1)
         | 
| 578 | 
            +
            			BUFPUTSL(ob, "<li>");
         | 
| 579 | 
            +
            		BUFPUTSL(ob, "<ul>\n");
         | 
| 580 | 
            +
            	}
         | 
| 581 | 
            +
            	
         | 
| 582 | 
            +
            	if (level < data->current_level) {
         | 
| 583 | 
            +
            		BUFPUTSL(ob, "</ul>");
         | 
| 584 | 
            +
            		if (data->current_level > 1)
         | 
| 585 | 
            +
            			BUFPUTSL(ob, "</li>\n");
         | 
| 586 | 
            +
            	}
         | 
| 587 | 
            +
             | 
| 588 | 
            +
            	data->current_level = level;
         | 
| 589 | 
            +
             | 
| 590 | 
            +
            	bufprintf(ob, "<li><a href=\"#toc_%d\">", data->header_count++);
         | 
| 591 | 
            +
            	if (text)
         | 
| 592 | 
            +
            		bufput(ob, text->data, text->size);
         | 
| 593 | 
            +
            	BUFPUTSL(ob, "</a></li>\n");
         | 
| 594 | 
            +
            }
         | 
| 595 | 
            +
             | 
| 596 | 
            +
            static void
         | 
| 597 | 
            +
            toc_finalize(struct buf *ob, struct mkd_renderopt *options)
         | 
| 598 | 
            +
            {
         | 
| 599 | 
            +
            	struct toc_data *data = (struct toc_data *)options->opaque;
         | 
| 600 | 
            +
             | 
| 601 | 
            +
            	while (data->current_level > 1) {
         | 
| 602 | 
            +
            		BUFPUTSL(ob, "</ul></li>\n");
         | 
| 603 | 
            +
            		data->current_level--;
         | 
| 604 | 
            +
            	}
         | 
| 605 | 
            +
             | 
| 606 | 
            +
            	if (data->current_level)
         | 
| 607 | 
            +
            		BUFPUTSL(ob, "</ul>\n");
         | 
| 608 | 
            +
            }
         | 
| 609 | 
            +
             | 
| 610 | 
            +
            void
         | 
| 611 | 
            +
            init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth)
         | 
| 612 | 
            +
            {
         | 
| 613 | 
            +
            	static const struct mkd_renderer toc_render = {
         | 
| 614 | 
            +
            		NULL,
         | 
| 615 | 
            +
            		NULL,
         | 
| 616 | 
            +
            		NULL,
         | 
| 617 | 
            +
            		toc_header,
         | 
| 618 | 
            +
            		NULL,
         | 
| 619 | 
            +
            		NULL,
         | 
| 620 | 
            +
            		NULL,
         | 
| 621 | 
            +
            		NULL,
         | 
| 622 | 
            +
             | 
| 623 | 
            +
            		rndr_autolink,
         | 
| 624 | 
            +
            		rndr_codespan,
         | 
| 625 | 
            +
            		rndr_double_emphasis,
         | 
| 626 | 
            +
            		rndr_emphasis,
         | 
| 627 | 
            +
            		rndr_image,
         | 
| 628 | 
            +
            		rndr_linebreak,
         | 
| 629 | 
            +
            		rndr_link,
         | 
| 630 | 
            +
            		rndr_raw_html,
         | 
| 631 | 
            +
            		rndr_triple_emphasis,
         | 
| 632 | 
            +
             | 
| 633 | 
            +
            		NULL,
         | 
| 634 | 
            +
            		NULL,
         | 
| 635 | 
            +
             | 
| 636 | 
            +
            		NULL,
         | 
| 637 | 
            +
            		toc_finalize,
         | 
| 638 | 
            +
             | 
| 639 | 
            +
            		NULL,
         | 
| 640 | 
            +
             | 
| 641 | 
            +
            		{ 0, 0 },
         | 
| 642 | 
            +
            		{ 0, 0 },
         | 
| 643 | 
            +
            	};
         | 
| 644 | 
            +
             | 
| 645 | 
            +
            	memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
         | 
| 646 | 
            +
             | 
| 647 | 
            +
            	renderer->parser_options.recursion_depth = recursion_depth;
         | 
| 648 | 
            +
            	renderer->render_options.flags = RENDER_TOC;
         | 
| 649 | 
            +
            	renderer->render_options.opaque = calloc(1, sizeof(struct toc_data));
         | 
| 650 | 
            +
            }
         | 
| 651 | 
            +
             | 
| 564 652 | 
             
            void
         | 
| 565 653 | 
             
            init_xhtml_renderer(struct mkd_renderer *renderer,
         | 
| 566 654 | 
             
            		unsigned int render_flags,
         | 
| @@ -588,6 +676,8 @@ init_xhtml_renderer(struct mkd_renderer *renderer, | |
| 588 676 |  | 
| 589 677 | 
             
            		NULL,
         | 
| 590 678 | 
             
            		rndr_normal_text,
         | 
| 679 | 
            +
             | 
| 680 | 
            +
            		NULL,
         | 
| 591 681 | 
             
            		NULL,
         | 
| 592 682 |  | 
| 593 683 | 
             
            		"*_",
         | 
| @@ -608,6 +698,15 @@ init_xhtml_renderer(struct mkd_renderer *renderer, | |
| 608 698 |  | 
| 609 699 | 
             
            	renderer->parser_options.recursion_depth = recursion_depth;
         | 
| 610 700 | 
             
            	renderer->parser_options.flags = parser_flags;
         | 
| 701 | 
            +
             | 
| 611 702 | 
             
            	renderer->render_options.flags = render_flags;
         | 
| 703 | 
            +
            	if (render_flags & RENDER_TOC)
         | 
| 704 | 
            +
            		renderer->render_options.opaque = calloc(1, sizeof(struct toc_data));
         | 
| 705 | 
            +
            }
         | 
| 706 | 
            +
             | 
| 707 | 
            +
            void
         | 
| 708 | 
            +
            free_renderer(struct mkd_renderer *renderer)
         | 
| 709 | 
            +
            {
         | 
| 710 | 
            +
            	free(renderer->render_options.opaque);
         | 
| 612 711 | 
             
            }
         | 
| 613 712 |  | 
    
        data/ext/xhtml.h
    ADDED
    
    | @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            /*
         | 
| 2 | 
            +
             * Copyright (c) 2011, Vicent Marti
         | 
| 3 | 
            +
             *
         | 
| 4 | 
            +
             * Permission to use, copy, modify, and distribute this software for any
         | 
| 5 | 
            +
             * purpose with or without fee is hereby granted, provided that the above
         | 
| 6 | 
            +
             * copyright notice and this permission notice appear in all copies.
         | 
| 7 | 
            +
             *
         | 
| 8 | 
            +
             * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
         | 
| 9 | 
            +
             * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
         | 
| 10 | 
            +
             * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
         | 
| 11 | 
            +
             * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
         | 
| 12 | 
            +
             * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
         | 
| 13 | 
            +
             * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
         | 
| 14 | 
            +
             * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
         | 
| 15 | 
            +
             */
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            #ifndef UPSKIRT_XHTML_H
         | 
| 18 | 
            +
            #define UPSKIRT_XHTML_H
         | 
| 19 | 
            +
            typedef enum {
         | 
| 20 | 
            +
            	RENDER_SKIP_HTML = (1 << 0),
         | 
| 21 | 
            +
            	RENDER_SKIP_STYLE = (1 << 1),
         | 
| 22 | 
            +
            	RENDER_SKIP_IMAGES = (1 << 2),
         | 
| 23 | 
            +
            	RENDER_SKIP_LINKS = (1 << 3),
         | 
| 24 | 
            +
            	RENDER_SMARTYPANTS = (1 << 4),
         | 
| 25 | 
            +
            	RENDER_EXPAND_TABS = (1 << 5),
         | 
| 26 | 
            +
            	RENDER_AUTOLINK = (1 << 6),
         | 
| 27 | 
            +
            	RENDER_SAFELINK = (1 << 7),
         | 
| 28 | 
            +
            	RENDER_TOC = (1 << 8),
         | 
| 29 | 
            +
            } render_mode;
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            void
         | 
| 32 | 
            +
            init_xhtml_renderer(struct mkd_renderer *renderer,
         | 
| 33 | 
            +
            		unsigned int render_flags,
         | 
| 34 | 
            +
            		unsigned int parser_flags, int recursion_depth);
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            void
         | 
| 37 | 
            +
            init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth);
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            void
         | 
| 40 | 
            +
            free_renderer(struct mkd_renderer *renderer);
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            #endif
         | 
| 43 | 
            +
             | 
    
        data/lib/redcarpet.rb
    CHANGED
    
    
    
        data/redcarpet.gemspec
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            Gem::Specification.new do |s|
         | 
| 2 2 | 
             
              s.name = 'redcarpet'
         | 
| 3 | 
            -
              s.version = '1. | 
| 3 | 
            +
              s.version = '1.3.0'
         | 
| 4 4 | 
             
              s.summary = "Ruby bindings for libupskirt"
         | 
| 5 | 
            -
              s.date = '2011-04- | 
| 5 | 
            +
              s.date = '2011-04-05'
         | 
| 6 6 | 
             
              s.email = 'vicent@github.com'
         | 
| 7 7 | 
             
              s.homepage = 'http://github.com/tanoku/redcarpet'
         | 
| 8 8 | 
             
              s.has_rdoc = true
         | 
| @@ -21,8 +21,8 @@ Gem::Specification.new do |s| | |
| 21 21 | 
             
                ext/markdown.c
         | 
| 22 22 | 
             
                ext/markdown.h
         | 
| 23 23 | 
             
                ext/redcarpet.c
         | 
| 24 | 
            -
                ext/ | 
| 25 | 
            -
                ext/ | 
| 24 | 
            +
                ext/xhtml.c
         | 
| 25 | 
            +
                ext/xhtml.h
         | 
| 26 26 | 
             
                lib/markdown.rb
         | 
| 27 27 | 
             
                lib/redcarpet.rb
         | 
| 28 28 | 
             
                redcarpet.gemspec
         | 
    
        data/test/redcarpet_test.rb
    CHANGED
    
    | @@ -113,12 +113,12 @@ class RedcarpetTest < Test::Unit::TestCase | |
| 113 113 | 
             
              def test_that_generate_toc_sets_toc_ids
         | 
| 114 114 | 
             
                rd = Redcarpet.new("# Level 1\n\n## Level 2", :generate_toc)
         | 
| 115 115 | 
             
                assert rd.generate_toc
         | 
| 116 | 
            -
                assert_equal %(<a name=" | 
| 116 | 
            +
                assert_equal %(<a name="toc_0"></a><h1>Level 1</h1>\n\n<a name="toc_1"></a><h2>Level 2</h2>\n), rd.to_html
         | 
| 117 117 | 
             
              end
         | 
| 118 118 |  | 
| 119 119 | 
             
              def test_should_get_the_generated_toc
         | 
| 120 120 | 
             
                rd = Redcarpet.new("# Level 1\n\n## Level 2", :generate_toc)
         | 
| 121 | 
            -
                exp = %(<ul>\n<li><a href="# | 
| 121 | 
            +
                exp = %(<ul>\n<li><a href="#toc_0">Level 1</a></li>\n<li><ul>\n<li><a href="#toc_1">Level 2</a></li>\n</ul></li>\n</ul>)
         | 
| 122 122 | 
             
                assert_equal exp, rd.toc_content.strip
         | 
| 123 123 | 
             
              end
         | 
| 124 124 |  | 
    
        metadata
    CHANGED
    
    | @@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version | |
| 5 5 | 
             
              prerelease: false
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 1
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 1. | 
| 8 | 
            +
              - 3
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 1.3.0
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - "Natacha Port\xC3\xA9"
         | 
| @@ -16,7 +16,7 @@ autorequire: | |
| 16 16 | 
             
            bindir: bin
         | 
| 17 17 | 
             
            cert_chain: []
         | 
| 18 18 |  | 
| 19 | 
            -
            date: 2011-04- | 
| 19 | 
            +
            date: 2011-04-05 00:00:00 +03:00
         | 
| 20 20 | 
             
            default_executable: 
         | 
| 21 21 | 
             
            dependencies: []
         | 
| 22 22 |  | 
| @@ -41,8 +41,8 @@ files: | |
| 41 41 | 
             
            - ext/markdown.c
         | 
| 42 42 | 
             
            - ext/markdown.h
         | 
| 43 43 | 
             
            - ext/redcarpet.c
         | 
| 44 | 
            -
            - ext/ | 
| 45 | 
            -
            - ext/ | 
| 44 | 
            +
            - ext/xhtml.c
         | 
| 45 | 
            +
            - ext/xhtml.h
         | 
| 46 46 | 
             
            - lib/markdown.rb
         | 
| 47 47 | 
             
            - lib/redcarpet.rb
         | 
| 48 48 | 
             
            - redcarpet.gemspec
         | 
    
        data/ext/toc.c
    DELETED
    
    | @@ -1,101 +0,0 @@ | |
| 1 | 
            -
            /*
         | 
| 2 | 
            -
             * Copyright (c) 2011, Vicent Marti
         | 
| 3 | 
            -
             *
         | 
| 4 | 
            -
             * Permission to use, copy, modify, and distribute this software for any
         | 
| 5 | 
            -
             * purpose with or without fee is hereby granted, provided that the above
         | 
| 6 | 
            -
             * copyright notice and this permission notice appear in all copies.
         | 
| 7 | 
            -
             *
         | 
| 8 | 
            -
             * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
         | 
| 9 | 
            -
             * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
         | 
| 10 | 
            -
             * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
         | 
| 11 | 
            -
             * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
         | 
| 12 | 
            -
             * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
         | 
| 13 | 
            -
             * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
         | 
| 14 | 
            -
             * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
         | 
| 15 | 
            -
             */
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            #include "markdown.h"
         | 
| 18 | 
            -
             | 
| 19 | 
            -
            #include <strings.h>
         | 
| 20 | 
            -
            #include <stdlib.h>
         | 
| 21 | 
            -
            #include <stdio.h>
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            static void
         | 
| 24 | 
            -
            toc_header(struct buf *ob, struct buf *text, int level, int header_id, struct mkd_renderopt *options)
         | 
| 25 | 
            -
            {
         | 
| 26 | 
            -
            	int current_level = (int)options->opaque.data;
         | 
| 27 | 
            -
             | 
| 28 | 
            -
            	if (level > current_level) {
         | 
| 29 | 
            -
            		if (level > 1)
         | 
| 30 | 
            -
            			BUFPUTSL(ob, "<li>");
         | 
| 31 | 
            -
            		BUFPUTSL(ob, "<ul>\n");
         | 
| 32 | 
            -
            	}
         | 
| 33 | 
            -
            	
         | 
| 34 | 
            -
            	if (level < current_level) {
         | 
| 35 | 
            -
            		BUFPUTSL(ob, "</ul>");
         | 
| 36 | 
            -
            		if (current_level > 1)
         | 
| 37 | 
            -
            			BUFPUTSL(ob, "</li>\n");
         | 
| 38 | 
            -
            	}
         | 
| 39 | 
            -
             | 
| 40 | 
            -
            	options->opaque.data = level;
         | 
| 41 | 
            -
             | 
| 42 | 
            -
            	bufprintf(ob, "<li><a href=\"#toc_%d\">", header_id);
         | 
| 43 | 
            -
            	if (text)
         | 
| 44 | 
            -
            		bufput(ob, text->data, text->size);
         | 
| 45 | 
            -
            	BUFPUTSL(ob, "</a></li>\n");
         | 
| 46 | 
            -
            }
         | 
| 47 | 
            -
             | 
| 48 | 
            -
            static void
         | 
| 49 | 
            -
            toc_finalize(struct buf *ob, struct mkd_renderopt *options)
         | 
| 50 | 
            -
            {
         | 
| 51 | 
            -
            	int current_level = (int)options->opaque.data;
         | 
| 52 | 
            -
             | 
| 53 | 
            -
            	while (current_level > 1) {
         | 
| 54 | 
            -
            		BUFPUTSL(ob, "</ul></li>\n");
         | 
| 55 | 
            -
            		current_level--;
         | 
| 56 | 
            -
            	}
         | 
| 57 | 
            -
             | 
| 58 | 
            -
            	if (current_level)
         | 
| 59 | 
            -
            		BUFPUTSL(ob, "</ul>\n");
         | 
| 60 | 
            -
            }
         | 
| 61 | 
            -
             | 
| 62 | 
            -
            void
         | 
| 63 | 
            -
            init_toc_renderer(struct mkd_renderer *renderer, int recursion_depth)
         | 
| 64 | 
            -
            {
         | 
| 65 | 
            -
            	static const struct mkd_renderer toc_render = {
         | 
| 66 | 
            -
            		NULL,
         | 
| 67 | 
            -
            		NULL,
         | 
| 68 | 
            -
            		NULL,
         | 
| 69 | 
            -
            		toc_header,
         | 
| 70 | 
            -
            		NULL,
         | 
| 71 | 
            -
            		NULL,
         | 
| 72 | 
            -
            		NULL,
         | 
| 73 | 
            -
            		NULL,
         | 
| 74 | 
            -
             | 
| 75 | 
            -
            		NULL,
         | 
| 76 | 
            -
            		NULL,
         | 
| 77 | 
            -
            		NULL,
         | 
| 78 | 
            -
            		NULL,
         | 
| 79 | 
            -
            		NULL,
         | 
| 80 | 
            -
            		NULL,
         | 
| 81 | 
            -
            		NULL,
         | 
| 82 | 
            -
            		NULL,
         | 
| 83 | 
            -
            		NULL,
         | 
| 84 | 
            -
             | 
| 85 | 
            -
            		NULL,
         | 
| 86 | 
            -
            		NULL,
         | 
| 87 | 
            -
            		toc_finalize,
         | 
| 88 | 
            -
             | 
| 89 | 
            -
            		NULL,
         | 
| 90 | 
            -
             | 
| 91 | 
            -
            		{ 0, 0 },
         | 
| 92 | 
            -
            		{ 0, 0 },
         | 
| 93 | 
            -
            	};
         | 
| 94 | 
            -
             | 
| 95 | 
            -
            	memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
         | 
| 96 | 
            -
             | 
| 97 | 
            -
            	renderer->parser_options.recursion_depth = recursion_depth;
         | 
| 98 | 
            -
            	renderer->render_options.flags = RENDER_TOC;
         | 
| 99 | 
            -
            	renderer->render_options.opaque.data = 0;
         | 
| 100 | 
            -
            }
         | 
| 101 | 
            -
             |