Text Header with CSS class: hn(class). Paragraphs beginning with 'hn(class). ' receive a CSS class attribute. Example:
Text
Paragraph with CSS class: p(class). Paragraphs beginning with 'p(class). ' receive a CSS class attribute. Example:Text
Blockquote: bq. Paragraphs beginning with 'bq. ' are wrapped in block quote tags. Example:TextBlockquote with citation: bq(citeurl). Paragraphs beginning with 'bq(citeurl). ' receive a citation attribute. Example:
TextNumeric list: # Consecutive paragraphs beginning with # are wrapped in ordered list tags. Example:
computer code
==notextile== leave text alone (do not format)
"linktext":url linktext
"linktext(title)":url linktext
!imageurl!
!imageurl(alt text)!
!imageurl!:linkurl
ABC(Always Be Closing) ABC
*/
function textile($text) {
### Basic global changes
$text = stripslashes($text);
# turn any incoming ampersands into a dummy character for now.
# This uses a negative lookahead for alphanumerics followed by a semicolon,
# implying an incoming html entity, to be skipped
$text = preg_replace("/&(?![#a-zA-Z0-9]+;)/","x%x%",$text);
# entify everything
if (function_exists('mb_encode_numericentity')) {
$text = encode_high($text);
} else {
$text = htmlentities($text,ENT_NOQUOTES,"utf-8");
}
# unentify angle brackets and ampersands
$text = str_replace(array(">", "<", "&"), array(">", "<", "&"), $text);
# zap carriage returns
$text = str_replace("\r\n", "\n", $text);
# zap tabs
$text = str_replace("\t", "", $text);
$text = preg_split("/\n/",$text);
foreach($text as $line){
$line = trim($line);
$lineout[] = $line;
}
$text = implode("\n",$lineout);
### Find and replace quick tags
# double equal signs means or
$codepre = false;
# if there is no html, do a simple search and replace
if(!preg_match("/<.*>/",$text)){
$text = preg_replace($glyph_search,$glyph_replace,$text);
} else {
# else split the text into an array at <.*>
$text = preg_split("/(<.*>)/U",$text,-1,PREG_SPLIT_DELIM_CAPTURE);
foreach($text as $line){
# matches are off if we're between , etc.
if(preg_match('/<(code|pre|kbd|notextile)>/i',$line)){$codepre = true; }
if(preg_match('/<\/(code|pre|kbd|notextile)>/i',$line)){$codepre = false; }
if(!preg_match("/<.*>/",$line) && $codepre == false){
$line = preg_replace($glyph_search,$glyph_replace,$line);
}
# convert htmlspecial if between
if ($codepre == true){
$line = htmlspecialchars($line,ENT_NOQUOTES,"UTF-8");
$line = str_replace("<pre>","",$line);
$line = str_replace("<code>","",$line);
$line = str_replace("<notextile>","",$line);
$line = str_replace("<kbd>","",$line);
}
# each line gets pushed to a new array
$glyph_out[] = $line;
}
# $text is now the new array, cast to a string
$text = implode('',$glyph_out);
}
### Block level formatting
# deal with forced breaks; this is going to be a problem between
# tags, but we'll clean them later
$text = preg_replace("/(\S)(_*)([[:punct:]]*) *\n([^#*\s])/", "$1$2$3
$4", $text);
# might be a problem with lists
$text = str_replace("l>
", "l>\n", $text);
# clear out multiple newlines for now
# $text = preg_replace("/\n+/","\n",$text);
# split the text into an array by newlines
$text = preg_split("/\n/",$text);
array_push($text," ");
$list = '';
$pre = false;
$block_find = array(
'/^\s?\*\s(.*)/', # bulleted list *
'/^\s?#\s(.*)/', # numeric list #
'/^bq\. (.*)/', # blockquote bq.
'/^h(\d)\(([[:alnum:]]+)\)\.\s(.*)/', # header hn(class). w/ css class
'/^h(\d)\. (.*)/', # plain header hn.
'/^p\(([[:alnum:]]+)\)\.\s(.*)/', # para p(class). w/ css class
'/^p\. (.*)/i', # plain paragraph
'/^([^\t ]+.*)/i' # remaining plain paragraph
);
$block_replace = array(
"\t\t
$1 ",
"\t\t\t$1 ",
"\t$1
",
"\t$3 $4",
"\t$2 $3",
"\t$2
$3",
"\t$1
",
"\t$1
$2"
);
# loop through lines
foreach($text as $line){
# matches are off if we're between or tags
if(preg_match('//i',$line)){$pre = true; }
# deal with block replacements first, then see if we're in a list
if ($pre == false){
$line = preg_replace($block_find,$block_replace,$line);
}
# kill any br tags that slipped in earlier
if ($pre == true){
$line = str_replace("
","\n",$line);
}
# matches back on after
if(preg_match('/<\/pre>/i',$line)){$pre = false; }
# on entry to a list, $list switches to a value
# two tabs means unordered list
if ($list == '' && preg_match('/^\t\t/',$line)){
$list = "ul";
$line = preg_replace('/^(\t\t .*)/',"\t\n$1",$line);
} else if ($list == '' && preg_match('/^\t\t\t- /',$line)){
$list = "ol";
$line = preg_replace('/^\t(\t\t
- .*)/',"\t
\n$1",$line);
# at the end of a ul
} else if ($list == 'ul' && !preg_match('/^\t\t- /',$line)){
$list = '';
$line = preg_replace('/^(.*)$/',"\t
\n$1",$line);
# at the end of a ol
} else if ($list == 'ol' && !preg_match('/^\t\t\t /',$line)){
$list = '';
$line = preg_replace('/^(.*)$/',"\t\n$1",$line);
}
# push each line to a new array once processed
$block_out[] = $line;
}
$text = implode("\n",$block_out);
#clean up
$text = preg_replace('/<\/?notextile>/', "",$text);
# turn the temp char back to an ampersand entity
$text = str_replace("x%x%","&",$text);
# Newline linebreaks, just for markup tidiness
$text = str_replace("
","
\n",$text);
return $text;
}
function callback_url($text,$title='',$url) {
$out = 'a href="'.$url.'"';
$out.=($title!='')?' title="'.$title.'"':'';
$out.='>$text';
return $out;
}
function textile_popup_help($name,$helpvar,$windowW,$windowH) {
$out = $name;
$out .= ' ?
';
print $out;
}
function encode_high($text) {
$cmap = cmap();
return mb_encode_numericentity($text, $cmap, "UTF-8");
}
function decode_high($text) {
$cmap = cmap();
return mb_decode_numericentity($text, $cmap, "UTF-8");
}
function cmap() {
$f = 0xffff;
$cmap = array(
160, 255, 0, $f,
402, 402, 0, $f,
913, 929, 0, $f,
931, 937, 0, $f,
945, 969, 0, $f,
977, 978, 0, $f,
982, 982, 0, $f,
8226, 8226, 0, $f,
8230, 8230, 0, $f,
8242, 8243, 0, $f,
8254, 8254, 0, $f,
8260, 8260, 0, $f,
8465, 8465, 0, $f,
8472, 8472, 0, $f,
8476, 8476, 0, $f,
8482, 8482, 0, $f,
8501, 8501, 0, $f,
8592, 8596, 0, $f,
8629, 8629, 0, $f,
8656, 8660, 0, $f,
8704, 8704, 0, $f,
8706, 8707, 0, $f,
8709, 8709, 0, $f,
8711, 8713, 0, $f,
8715, 8715, 0, $f,
8719, 8719, 0, $f,
8721, 8722, 0, $f,
8727, 8727, 0, $f,
8730, 8730, 0, $f,
8733, 8734, 0, $f,
8736, 8736, 0, $f,
8743, 8747, 0, $f,
8756, 8756, 0, $f,
8764, 8764, 0, $f,
8773, 8773, 0, $f,
8776, 8776, 0, $f,
8800, 8801, 0, $f,
8804, 8805, 0, $f,
8834, 8836, 0, $f,
8838, 8839, 0, $f,
8853, 8853, 0, $f,
8855, 8855, 0, $f,
8869, 8869, 0, $f,
8901, 8901, 0, $f,
8968, 8971, 0, $f,
9001, 9002, 0, $f,
9674, 9674, 0, $f,
9824, 9824, 0, $f,
9827, 9827, 0, $f,
9829, 9830, 0, $f,
338, 339, 0, $f,
352, 353, 0, $f,
376, 376, 0, $f,
710, 710, 0, $f,
732, 732, 0, $f,
8194, 8195, 0, $f,
8201, 8201, 0, $f,
8204, 8207, 0, $f,
8211, 8212, 0, $f,
8216, 8218, 0, $f,
8218, 8218, 0, $f,
8220, 8222, 0, $f,
8224, 8225, 0, $f,
8240, 8240, 0, $f,
8249, 8250, 0, $f,
8364, 8364, 0, $f
);
return $cmap;
}
function linkit($text,$title,$url){
$url = preg_replace("/&(?!amp;)/","&",$url);
$out = '';
return $out;
}
?>