|
Lines 6-12
Link Here
|
| 6 |
Version: 1.0b4 |
6 |
Version: 1.0b4 |
| 7 |
Author: John Gruber |
7 |
Author: John Gruber |
| 8 |
Author URI: http://daringfireball.net/ |
8 |
Author URI: http://daringfireball.net/ |
| 9 |
*/ |
9 |
*/ |
| 10 |
|
10 |
|
| 11 |
|
11 |
|
| 12 |
/* |
12 |
/* |
|
Lines 18-24
Link Here
|
| 18 |
$g_empty_element_suffix = " />"; # Change to ">" for HTML output |
18 |
$g_empty_element_suffix = " />"; # Change to ">" for HTML output |
| 19 |
$g_tab_width = 4; |
19 |
$g_tab_width = 4; |
| 20 |
$g_nested_brackets_depth = 6; |
20 |
$g_nested_brackets_depth = 6; |
| 21 |
$g_nested_brackets = |
21 |
$g_nested_brackets = |
| 22 |
str_repeat('(?>[^\[\]]+|\[', $g_nested_brackets_depth). |
22 |
str_repeat('(?>[^\[\]]+|\[', $g_nested_brackets_depth). |
| 23 |
str_repeat('\])*', $g_nested_brackets_depth); |
23 |
str_repeat('\])*', $g_nested_brackets_depth); |
| 24 |
$g_escape_table = array( |
24 |
$g_escape_table = array( |
|
Lines 133-139
Link Here
|
| 133 |
[ \t]* |
133 |
[ \t]* |
| 134 |
<(hr) # start tag = $2 |
134 |
<(hr) # start tag = $2 |
| 135 |
\b # word break |
135 |
\b # word break |
| 136 |
([^<>])*? # |
136 |
([^<>])*? # |
| 137 |
/?> # the matching end tag |
137 |
/?> # the matching end tag |
| 138 |
(?=\n{2,}|\Z) # followed by a blank line or end of document |
138 |
(?=\n{2,}|\Z) # followed by a blank line or end of document |
| 139 |
) |
139 |
) |
|
Lines 153-166
Link Here
|
| 153 |
|
153 |
|
| 154 |
function _RunBlockGamut($text) { |
154 |
function _RunBlockGamut($text) { |
| 155 |
global $g_empty_element_suffix; |
155 |
global $g_empty_element_suffix; |
| 156 |
|
156 |
|
| 157 |
$text = _DoHeaders($text); |
157 |
$text = _DoHeaders($text); |
| 158 |
|
158 |
|
| 159 |
$text = preg_replace( |
159 |
$text = preg_replace( |
| 160 |
array('/^( ?\* ?){3,}$/m', |
160 |
array('/^( ?\* ?){3,}$/m', |
| 161 |
'/^( ?- ?){3,}$/m'), |
161 |
'/^( ?- ?){3,}$/m'), |
| 162 |
array("\n<hr$g_empty_element_suffix\n", |
162 |
array("\n<hr$g_empty_element_suffix\n", |
| 163 |
"\n<hr$g_empty_element_suffix\n"), |
163 |
"\n<hr$g_empty_element_suffix\n"), |
| 164 |
$text); |
164 |
$text); |
| 165 |
|
165 |
|
| 166 |
$text = _DoLists($text); |
166 |
$text = _DoLists($text); |
|
Lines 191-197
Link Here
|
| 191 |
|
191 |
|
| 192 |
|
192 |
|
| 193 |
$text = _DoItalicsAndBold($text); |
193 |
$text = _DoItalicsAndBold($text); |
| 194 |
|
194 |
|
| 195 |
# Do hard breaks: |
195 |
# Do hard breaks: |
| 196 |
$text = preg_replace('/ {2,}\n/', "<br$g_empty_element_suffix\n", $text); |
196 |
$text = preg_replace('/ {2,}\n/', "<br$g_empty_element_suffix\n", $text); |
| 197 |
|
197 |
|
|
Lines 244-250
Link Here
|
| 244 |
) |
244 |
) |
| 245 |
}xs", |
245 |
}xs", |
| 246 |
'_DoAnchors_reference_callback', $text); |
246 |
'_DoAnchors_reference_callback', $text); |
| 247 |
|
247 |
|
| 248 |
$text = preg_replace_callback("{ |
248 |
$text = preg_replace_callback("{ |
| 249 |
( # wrap whole match in $1 |
249 |
( # wrap whole match in $1 |
| 250 |
\\[ |
250 |
\\[ |
|
Lines 263-269
Link Here
|
| 263 |
) |
263 |
) |
| 264 |
}xs", |
264 |
}xs", |
| 265 |
'_DoAnchors_inline_callback', $text); |
265 |
'_DoAnchors_inline_callback', $text); |
| 266 |
|
266 |
|
| 267 |
return $text; |
267 |
return $text; |
| 268 |
} |
268 |
} |
| 269 |
function _DoAnchors_reference_callback($matches) { |
269 |
function _DoAnchors_reference_callback($matches) { |
|
Lines 282-288
Link Here
|
| 282 |
$url = str_replace(array('*', '_'), |
282 |
$url = str_replace(array('*', '_'), |
| 283 |
array('*', '_'), $url); |
283 |
array('*', '_'), $url); |
| 284 |
$result = "<a href='$url'"; |
284 |
$result = "<a href='$url'"; |
| 285 |
if ( isset( $g_title[$link_id] ) ) { |
285 |
if ( isset( $g_titles[$link_id] ) ) { |
| 286 |
$title = $g_titles[$link_id]; |
286 |
$title = $g_titles[$link_id]; |
| 287 |
$title = str_replace(array('*', '_'), |
287 |
$title = str_replace(array('*', '_'), |
| 288 |
array('*', '_'), $title); |
288 |
array('*', '_'), $title); |
|
Lines 332-338
Link Here
|
| 332 |
\] |
332 |
\] |
| 333 |
|
333 |
|
| 334 |
) |
334 |
) |
| 335 |
}xs', |
335 |
}xs', |
| 336 |
'_DoImages_reference_callback', $text); |
336 |
'_DoImages_reference_callback', $text); |
| 337 |
|
337 |
|
| 338 |
# |
338 |
# |
|
Lines 371-377
Link Here
|
| 371 |
if ($link_id == "") { |
371 |
if ($link_id == "") { |
| 372 |
$link_id = strtolower($alt_text); # for shortcut links like ![this][]. |
372 |
$link_id = strtolower($alt_text); # for shortcut links like ![this][]. |
| 373 |
} |
373 |
} |
| 374 |
|
374 |
|
| 375 |
if (isset($g_urls[$link_id])) { |
375 |
if (isset($g_urls[$link_id])) { |
| 376 |
$url = $g_urls[$link_id]; |
376 |
$url = $g_urls[$link_id]; |
| 377 |
$url = str_replace(array('*', '_'), |
377 |
$url = str_replace(array('*', '_'), |
|
Lines 531-537
Link Here
|
| 531 |
$codeblock = $matches[4]; |
531 |
$codeblock = $matches[4]; |
| 532 |
|
532 |
|
| 533 |
$result; # return value |
533 |
$result; # return value |
| 534 |
|
534 |
|
| 535 |
|
535 |
|
| 536 |
$prefix = ""; |
536 |
$prefix = ""; |
| 537 |
if (!(preg_match('/\s/', $prevchar) || ($prevchar == ""))) { |
537 |
if (!(preg_match('/\s/', $prevchar) || ($prevchar == ""))) { |
|
Lines 541-547
Link Here
|
| 541 |
$codeblock = _Detab($codeblock); |
541 |
$codeblock = _Detab($codeblock); |
| 542 |
# trim leading newlines and trailing whitespace |
542 |
# trim leading newlines and trailing whitespace |
| 543 |
$codeblock = preg_replace(array('/\A\n+/', '/\s+\z/'), '', $codeblock); |
543 |
$codeblock = preg_replace(array('/\A\n+/', '/\s+\z/'), '', $codeblock); |
| 544 |
|
544 |
|
| 545 |
$result = $prefix . "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n"; |
545 |
$result = $prefix . "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n"; |
| 546 |
|
546 |
|
| 547 |
return $result; |
547 |
return $result; |
|
Lines 578-588
Link Here
|
| 578 |
$_ = str_replace('&', '&', $_); |
578 |
$_ = str_replace('&', '&', $_); |
| 579 |
|
579 |
|
| 580 |
# Do the angle bracket song and dance: |
580 |
# Do the angle bracket song and dance: |
| 581 |
$_ = str_replace(array('<', '>'), |
581 |
$_ = str_replace(array('<', '>'), |
| 582 |
array('<', '>'), $_); |
582 |
array('<', '>'), $_); |
| 583 |
|
583 |
|
| 584 |
# Now, escape characters that are magic in Markdown: |
584 |
# Now, escape characters that are magic in Markdown: |
| 585 |
$_ = str_replace(array_keys($g_escape_table), |
585 |
$_ = str_replace(array_keys($g_escape_table), |
| 586 |
array_values($g_escape_table), $_); |
586 |
array_values($g_escape_table), $_); |
| 587 |
|
587 |
|
| 588 |
return $_; |
588 |
return $_; |
|
Lines 618-627
Link Here
|
| 618 |
} |
618 |
} |
| 619 |
function _DoBlockQuotes_callback($matches) { |
619 |
function _DoBlockQuotes_callback($matches) { |
| 620 |
$bq = $matches[1]; |
620 |
$bq = $matches[1]; |
| 621 |
$bq = preg_replace('/^[ \t]*>[ \t]?/m', '', $bq); |
621 |
$bq = preg_replace('/^[ \t]*>[ \t]?/m', '', $bq); |
| 622 |
$bq = _RunBlockGamut($bq); # recurse |
622 |
$bq = _RunBlockGamut($bq); # recurse |
| 623 |
$bq = preg_replace('/^/m', "\t", $bq); |
623 |
$bq = preg_replace('/^/m', "\t", $bq); |
| 624 |
|
624 |
|
| 625 |
return "<blockquote>\n$bq\n</blockquote>\n\n"; |
625 |
return "<blockquote>\n$bq\n</blockquote>\n\n"; |
| 626 |
} |
626 |
} |
| 627 |
|
627 |
|
|
Lines 657-663
Link Here
|
| 657 |
|
657 |
|
| 658 |
|
658 |
|
| 659 |
function _EncodeAmpsAndAngles($text) { |
659 |
function _EncodeAmpsAndAngles($text) { |
| 660 |
$text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w{1,8});)/', |
660 |
$text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w{1,8});)/', |
| 661 |
'&', $text);; |
661 |
'&', $text);; |
| 662 |
|
662 |
|
| 663 |
# Encode naked <'s |
663 |
# Encode naked <'s |
|
Lines 676-684
Link Here
|
| 676 |
|
676 |
|
| 677 |
|
677 |
|
| 678 |
function _DoAutoLinks($text) { |
678 |
function _DoAutoLinks($text) { |
| 679 |
$text = preg_replace("!<((https?|ftp):[^'\">\\s]+)>!", |
679 |
$text = preg_replace("!<((https?|ftp):[^'\">\\s]+)>!", |
| 680 |
'<a href="\1">\1</a>', $text); |
680 |
'<a href="\1">\1</a>', $text); |
| 681 |
|
681 |
|
| 682 |
# Email addresses: <address@domain.foo> |
682 |
# Email addresses: <address@domain.foo> |
| 683 |
$text = preg_replace('{ |
683 |
$text = preg_replace('{ |
| 684 |
< |
684 |
< |
|
Lines 691-697
Link Here
|
| 691 |
}exi', |
691 |
}exi', |
| 692 |
"_EncodeEmailAddress(_UnescapeSpecialChars(_UnslashQuotes('\\1')))", |
692 |
"_EncodeEmailAddress(_UnescapeSpecialChars(_UnslashQuotes('\\1')))", |
| 693 |
$text); |
693 |
$text); |
| 694 |
|
694 |
|
| 695 |
return $text; |
695 |
return $text; |
| 696 |
} |
696 |
} |
| 697 |
|
697 |
|
|
Lines 700-706
Link Here
|
| 700 |
$addr = "mailto:" . $addr; |
700 |
$addr = "mailto:" . $addr; |
| 701 |
$length = strlen($addr); |
701 |
$length = strlen($addr); |
| 702 |
|
702 |
|
| 703 |
$addr = preg_replace_callback('/([^\:])/', |
703 |
$addr = preg_replace_callback('/([^\:])/', |
| 704 |
'_EncodeEmailAddress_callback', $addr); |
704 |
'_EncodeEmailAddress_callback', $addr); |
| 705 |
|
705 |
|
| 706 |
$addr = "<a href=\"$addr\">$addr</a>"; |
706 |
$addr = "<a href=\"$addr\">$addr</a>"; |
|
Lines 719-725
Link Here
|
| 719 |
|
719 |
|
| 720 |
function _UnescapeSpecialChars($text) { |
720 |
function _UnescapeSpecialChars($text) { |
| 721 |
global $g_escape_table; |
721 |
global $g_escape_table; |
| 722 |
return str_replace(array_values($g_escape_table), |
722 |
return str_replace(array_values($g_escape_table), |
| 723 |
array_keys($g_escape_table), $text); |
723 |
array_keys($g_escape_table), $text); |
| 724 |
} |
724 |
} |
| 725 |
|
725 |
|
|
Lines 735-742
Link Here
|
| 735 |
$match = "(?s:<!(--.*?--\s*)+>)|". # comment |
735 |
$match = "(?s:<!(--.*?--\s*)+>)|". # comment |
| 736 |
"(?s:<\?.*?\?>)|". # processing instruction |
736 |
"(?s:<\?.*?\?>)|". # processing instruction |
| 737 |
"$nested_tags"; # nested tags |
737 |
"$nested_tags"; # nested tags |
| 738 |
|
738 |
|
| 739 |
preg_match_all("/($match)/", $str, $matches, |
739 |
preg_match_all("/($match)/", $str, $matches, |
| 740 |
PREG_SET_ORDER | PREG_OFFSET_CAPTURE); |
740 |
PREG_SET_ORDER | PREG_OFFSET_CAPTURE); |
| 741 |
|
741 |
|
| 742 |
foreach ($matches as $element) { |
742 |
foreach ($matches as $element) { |
|
Lines 744-758
Link Here
|
| 744 |
$tag_start = $element[0][1]; |
744 |
$tag_start = $element[0][1]; |
| 745 |
$sec_start = $tag_start + strlen($whole_tag); |
745 |
$sec_start = $tag_start + strlen($whole_tag); |
| 746 |
if ($pos < $tag_start) { |
746 |
if ($pos < $tag_start) { |
| 747 |
array_push($tokens, array('text', |
747 |
array_push($tokens, array('text', |
| 748 |
substr($str, $pos, $tag_start - $pos))); |
748 |
substr($str, $pos, $tag_start - $pos))); |
| 749 |
} |
749 |
} |
| 750 |
array_push($tokens, array('tag', $whole_tag)); |
750 |
array_push($tokens, array('tag', $whole_tag)); |
| 751 |
$pos = $sec_start; |
751 |
$pos = $sec_start; |
| 752 |
} |
752 |
} |
| 753 |
|
753 |
|
| 754 |
if ($pos < $len) |
754 |
if ($pos < $len) |
| 755 |
array_push($tokens, array('text', |
755 |
array_push($tokens, array('text', |
| 756 |
substr($str, $pos, $len - $pos))); |
756 |
substr($str, $pos, $len - $pos))); |
| 757 |
return $tokens; |
757 |
return $tokens; |
| 758 |
} |
758 |
} |