Text
Blockquote: bq. Example: bq. Block quotation... ->Block quotation...Blockquote with citation: bq.:http://citation.url Example: bq.:http://textism.com/ Text... ->
Text...Footnote: fn(1-100). Example: fn1. Footnote... ->
Footnote...
Numeric list: #, ## Consecutive paragraphs beginning with # are wrapped in ordered list tags. Example:computer code
%(bob)span% -> span
==notextile== -> leave text alone (do not format)
"linktext":url -> linktext
"linktext(title)":url -> linktext
!imageurl! -> paragraph
p(#fluid). paragraph ->paragraph
(classes and ids can be combined) p(hector#fluid). paragraph ->paragraph
Curly {brackets} insert arbitrary css style p{line-height:18px}. paragraph ->paragraph
h3{color:red}. header 3 ->paragraph
%[fr]phrase% -> phrase Usually Textile block element syntax requires a dot and space before the block begins, but since lists don't, they can be styled just using braces #{color:blue} one ->/i',$line)) { $pre = true; } foreach($find as $tag){ $line = ($pre==false) ? preg_replace_callback("/^($tag)($textile_a$textile_c)\.(?::(\S+))? (.*)$/", "textile_fBlock",$line) : $line; } $line = preg_replace('/^(?!\t|<\/?pre|<\/?code|$| )(.*)/',"\t$1
",$line); $line=($pre==true) ? str_replace("
","\n",$line):$line; if (preg_match('/<\/pre>/i',$line)) { $pre = false; } $out[] = $line; } return join("\n",$out); } // ------------------------------------------------------------- function textile_fBlock($m) { # dump($m); list(,$tag,$textile_atts,$textile_cite,$textile_content) = $m; $textile_atts = textile_pba($textile_atts); if(preg_match("/fn(\d+)/",$tag,$fns)){ $tag = 'p'; $textile_atts.= ' id="fn'.$fns[1].'"'; $textile_content = ''.$fns[1].' '.$textile_content; } $textile_start = "\t<$tag"; $end = "$tag>"; if ($tag=="bq") { $textile_cite = textile_checkRefs($textile_cite); $textile_cite = ($textile_cite!='') ? ' cite="'.$textile_cite.'"' : ''; $textile_start = "\t\n\t\t"; } return "$textile_start$textile_atts>$textile_content$end"; } // ------------------------------------------------------------- function textile_span($text) { global $textile_c,$textile_pnct; $qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~'); foreach($qtags as $f) { $text = preg_replace_callback( "/(?<=^|\s|\>|[[:punct:]]|[{(\[]) ($f) ($textile_c) (?::(\S+))? (\w.+\w) ([[:punct:]]*) $f (?=[])}]|[[:punct:]]+|\s|$) /xmU","textile_fSpan",$text); } return $text; } // ------------------------------------------------------------- function textile_fSpan($m) { # dump($m); global $textile_c; $qtags = array( '*' => 'b', '**' => 'strong', '??' => 'cite', '_' => 'em', '__' => 'i', '-' => 'del', '%' => 'span', '+' => 'ins', '~' => 'sub'); list(,$tag,$textile_atts,$textile_cite,$textile_content,$end) = $m; $tag = $qtags[$tag]; $textile_atts = textile_pba($textile_atts); $textile_atts.= ($textile_cite!='') ? 'cite="'.$textile_cite.'"' : ''; return "<$tag$textile_atts>$textile_content$end$tag>"; } // ------------------------------------------------------------- function textile_links($text) { global $textile_c; return preg_replace_callback('/ ([\s[{(]|[[:punct:]])? # $pre ("|") # start ('.$textile_c.') # $textile_atts ([^"]+) # $text \s? (?:\(([^)]+)\)(?="))? # $title ("|"): (\S+\b) # $url (\/)? # $textile_slash ([^\w\/;]*) # $post (?=\s|$) /Ux',"textile_fLink",$text); } // ------------------------------------------------------------- function textile_fLink($m) { list(,$pre,$textile_atts,$text,$title,$url,$textile_slash,$post) = $m; $url = textile_checkRefs($url); $textile_atts = textile_pba($textile_atts); $textile_atts.= ($title!='') ? ' title="'.$title.'"' : ''; $textile_atts = ($textile_atts!='') ? textile_shelve($textile_atts) : ''; if ($text=='_') { $text = $url; } if (preg_match('/^http(s?):\/\//i', $url)) { $textile_atts.=' class="external"'; } return $pre.''.$text.''.$post; } // ------------------------------------------------------------- function textile_getRefs($text) { return preg_replace_callback("/(?<=^|\s)\[(.+)\]((?:http:\/\/|\/)\S+)(?=\s|$)/U", "textile_refs",$text); } // ------------------------------------------------------------- function textile_refs($m) { list(,$flag,$url) = $m; $GLOBALS['urlrefs'][$flag] = $url; return ''; } // ------------------------------------------------------------- function textile_checkRefs($text) { global $urlrefs; return (isset($urlrefs[$text])) ? $urlrefs[$text] : $text; } // ------------------------------------------------------------- function textile_image($text) { global $textile_c; return preg_replace_callback("/ \! # opening (\<|\=|\>)? # optional alignment atts ($textile_c) # optional style,class atts (?:\. )? # optional dot-space ([^\s(!]+) # presume this is the src \s? # optional space (?:\(([^\)]+)\))? # optional title \! # closing (?::(\S+))? # optional href (?=\s|$) # lookahead: space or end of string /Ux","textile_fImage",$text); } // ------------------------------------------------------------- function textile_fImage($m) { list(,$textile_algn,$textile_atts,$url) = $m; $textile_atts = textile_pba($textile_atts); $textile_atts.= ($textile_algn!='') ? ' align="'.textile_iAlign($textile_algn).'"' : ''; $textile_atts.= (isset($m[4])) ? ' title="'.$m[4].'"' : ''; $textile_size = @getimagesize($url); if($textile_size) $textile_atts.= " $textile_size[3]"; $href = (isset($m[5])) ? textile_checkRefs($m[5]) : ''; $url = textile_checkRefs($url); $out = ''; $out.= ($href!='') ? '' : ''; $out.= '\n\t
'; $out.= ($href!='') ? '' : ''; return $out; } // ------------------------------------------------------------- function textile_code($text) { global $textile_pnct; return preg_replace_callback("/ (?:^|(?<=[\s\(])|([[{])) # 1 open bracket? @ # opening (?:\|(\w+)\|)? # 2 language (.+) # 3 code @ # closing (?:$|([\]}])| (?=[[:punct:]]{1,2}| \s)) # 4 closing bracket? /Ux","textile_fCode",$text); } // ------------------------------------------------------------- function textile_fCode($m) { list(,$before,$lang,$textile_code,$textile_after) = $m; $lang = ($lang!='') ? ' language="'.$lang.'"' : ''; return $before.'
'.$textile_code.'
'.$textile_after; } // ------------------------------------------------------------- function textile_shelve($val) { $GLOBALS['shelf'][] = $val; return ' <'.count($GLOBALS['shelf']).'>'; } // ------------------------------------------------------------- function textile_retrieve($text) { global $textile_shelf; $i = 0; if(is_array($textile_shelf)) { foreach($textile_shelf as $r){ $i++; $text = str_replace("<$i>",$r,$text); } } return $text; } // ------------------------------------------------------------- function textile_incomingEntities($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 */ return preg_replace("/&(?![#a-z0-9]+;)/i","x%x%",$text); } // ------------------------------------------------------------- function textile_encodeEntities($text) { /* Convert high and low ascii to entities. If multibyte string functions are available (on by default in php 4.3+), we convert using unicode mapping as defined in the function encode_high(). If not, we use php's nasty built-in htmlentities() */ return (function_exists('mb_encode_numericentity')) ? textile_encode_high($text) : htmlentities($text,ENT_NOQUOTES,"utf-8"); } // ------------------------------------------------------------- function textile_fixEntities($text) { /* de-entify any remaining angle brackets or ampersands */ return str_replace(array(">", "<", "&"), array(">", "<", "&"), $text); } // ------------------------------------------------------------- function textile_cleanWhiteSpace($text) { $out = str_replace(array("\r\n","\t"), array("\n",''), $text); $out = preg_replace("/\n{3,}/","\n\n",$out); $out = preg_replace("/\n *\n/","\n\n",$out); $out = preg_replace('/"$/',"\" ", $out); return $out; } // ------------------------------------------------------------- function textile_noTextile($text) { return preg_replace('/(^|\s)==(.*)==(\s|$)?/msU', '$1$2 $3',$text); } // ------------------------------------------------------------- function textile_superscript($text) { return preg_replace('/\^(.*)\^/mU','$1',$text); } // ------------------------------------------------------------- function textile_footnoteRef($text) { return preg_replace('/\b\[([0-9]+)\](\s)?/U', '$1$2',$text); } // ------------------------------------------------------------- function textile_glyphs($text) { // fix: hackish $text = preg_replace('/"\z/',"\" ", $text); $glyph_search = array( '/([^\s[{(>])?\'(?(1)|(?=\s|s\b|[[:punct:]]))/', // single closing '/\'/', // single opening '/([^\s[{(>])?"(?(1)|(?=\s|[[:punct:]]))/', // double closing '/"/', // double opening '/\b( )?\.{3}/', // ellipsis '/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/', // 3+ uppercase acronym '/(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^$1', // 3+ uppercase acronym '$1$2$3', // 3+ uppercase caps '—', // em dash ' – ', // en dash '$1×$2', // dimension sign '™', // trademark '®', // registered '©'); // copyright $textile_codepre = false; /* if no html, do a simple search and replace... */ if (!preg_match("/<.*>/",$text)) { $text = preg_replace($glyph_search,$glyph_replace,$text); return $text; } else { $text = preg_split("/(<.*>)/U",$text,-1,PREG_SPLIT_DELIM_CAPTURE); foreach($text as $line) { $offtags = ('code|pre|kbd|notextile'); /* matches are off if we're between ,
etc. */ if (preg_match('/<('.$offtags.')>/i',$line)) $textile_codepre = true; if (preg_match('/<\/('.$offtags.')>/i',$line)) $textile_codepre = false; if (!preg_match("/<.*>/",$line) && $textile_codepre == false) { $line = preg_replace($glyph_search,$glyph_replace,$line); } /* do htmlspecial if between*/ if ($textile_codepre == true) { $line = htmlspecialchars($line,ENT_NOQUOTES,"UTF-8"); $line = preg_replace('/<(\/?'.$offtags.')>/',"<$1>",$line); } $glyph_out[] = $line; } return join('',$glyph_out); } } // ------------------------------------------------------------- function textile_iAlign($in) { $vals = array( '<'=>'left', '='=>'center', '>'=>'right'); return (isset($vals[$in])) ? $vals[$in] : ''; } // ------------------------------------------------------------- function textile_hAlign($in) { $vals = array( '<'=>'left', '='=>'center', '>'=>'right', '<>'=>'justify'); return (isset($vals[$in])) ? $vals[$in] : ''; } // ------------------------------------------------------------- function textile_vAlign($in) { $vals = array( '^'=>'top', '-'=>'middle', '~'=>'bottom'); return (isset($vals[$in])) ? $vals[$in] : ''; } // ------------------------------------------------------------- function textile_encode_high($text,$textile_charset="UTF-8") { $textile_cmap = textile_cmap(); return mb_encode_numericentity($text, $textile_cmap, $textile_charset); } // ------------------------------------------------------------- function textile_decode_high($text,$textile_charset="UTF-8") { $textile_cmap = textile_cmap(); return mb_decode_numericentity($text, $textile_cmap, $textile_charset); } // ------------------------------------------------------------- function textile_cmap() { $f = 0xffff; $textile_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 $textile_cmap; } // ------------------------------------------------------------- function textile_popup_help($name,$helpvar,$windowW,$windowH) { return ' '.$name.'
'; } // ------------------------------------------------------------- function textile_txtgps($thing) { if (isset($_POST[$thing])){ if (get_magic_quotes_gpc()==1){ return stripslashes($_POST[$thing]); } else { return $_POST[$thing]; } } else { return ''; } } // ------------------------------------------------------------- // The following functions are used to detextile html, a process // still in development. // ------------------------------------------------------------- function textile_detextile($text) { $text = preg_replace("/
\s*/","\n",$text); $oktags = array('p','ol','ul','li','i','b','em','strong','span','a','h[1-6]', 'table','tr','td','u','del','sup','sub','blockquote'); foreach($oktags as $tag){ $text = preg_replace_callback("/\t*<(".$tag.")\s*([^>]*)>(.*)<\/\\1>/Usi", "textile_processTag",$text); } $glyphs = array( '’'=>'\'', # single closing '‘'=>'\'', # single opening '”'=>'"', # double closing '“'=>'"', # double opening '—'=>'--', # em dash '–'=>' - ', # en dash '×' =>'x', # dimension sign '™'=>'(TM)', # trademark '®' =>'(R)', # registered '©' =>'(C)', # copyright '…'=>'...' # ellipsis ); foreach($glyphs as $f=>$r){ $text = str_replace($f,$r,$text); } $list = false; $text = preg_split("/(<.*>)/U",$text,-1,PREG_SPLIT_DELIM_CAPTURE); foreach($text as $line){ if ($list == false && preg_match('//U','# ', $line); } else if ($list == 'u'){ $line = preg_replace('/
/U','* ', $line); } $glyph_out[] = $line; } $text = implode('',$glyph_out); $text = preg_replace('/^\t* *p\. /m','',$text); return textile_decode_high($text); } // ------------------------------------------------------------- function textile_processTag($matches) { list($textile_all,$tag,$textile_atts,$textile_content) = $matches; $textile_a = textile_splat($textile_atts); # dump($tag); dump($textile_content); dump($textile_a); $phr = array( 'em'=>'_', 'i'=>'__', 'b'=>'**', 'strong'=>'*', 'cite'=>'??', 'del'=>'-', 'ins'=>'+', 'sup'=>'^', 'sub'=>'~', 'span'=>'%'); $blk = array('p','h1','h2','h3','h4','h5','h6'); if(isset($phr[$tag])) { return $phr[$tag].textile_sci($textile_a).$textile_content.$phr[$tag]; } elseif($tag=='blockquote') { return 'bq.'.textile_sci($textile_a).' '.$textile_content; } elseif(in_array($tag,$blk)) { return $tag.textile_sci($textile_a).'. '.$textile_content; } elseif ($tag=='a') { $t = textile_filterAtts($textile_a,array('href','title')); $out = '"'.$textile_content; $out.= (isset($t['title'])) ? ' ('.$t['title'].')' : ''; $out.= '":'.$t['href']; return $out; } else { return $textile_all; } } // ------------------------------------------------------------- function textile_filterAtts($textile_atts,$ok) { foreach($textile_atts as $textile_a) { if(in_array($textile_a['name'],$ok)) { if($textile_a['att']!='') { $out[$textile_a['name']] = $textile_a['att']; } } } # dump($out); return $out; } // ------------------------------------------------------------- function textile_sci($textile_a) { $out = ''; foreach($textile_a as $t){ $out.= ($t['name']=='class') ? '(='.$t['att'].')' : ''; $out.= ($t['name']=='id') ? '[='.$t['att'].']' : ''; $out.= ($t['name']=='style') ? '{='.$t['att'].'}' : ''; $out.= ($t['name']=='cite') ? ':'.$t['att'] : ''; } return $out; } // ------------------------------------------------------------- function textile_splat($textile_attr) // returns attributes as an array { $textile_arr = array(); $textile_atnm = ''; $mode = 0; while (strlen($textile_attr) != 0){ $ok = 0; switch ($mode) { case 0: // name if (preg_match('/^([a-z]+)/i', $textile_attr, $match)) { $textile_atnm = $match[1]; $ok = $mode = 1; $textile_attr = preg_replace('/^[a-z]+/i', '', $textile_attr); } break; case 1: // = if (preg_match('/^\s*=\s*/', $textile_attr)) { $ok = 1; $mode = 2; $textile_attr = preg_replace('/^\s*=\s*/', '', $textile_attr); break; } if (preg_match('/^\s+/', $textile_attr)) { $ok = 1; $mode = 0; $textile_arr[] = array('name'=>$textile_atnm,'whole'=>$textile_atnm,'att'=>$textile_atnm); $textile_attr = preg_replace('/^\s+/', '', $textile_attr); } break; case 2: // value if (preg_match('/^("[^"]*")(\s+|$)/', $textile_attr, $match)) { $textile_arr[]=array('name' =>$textile_atnm,'whole'=>$textile_atnm.'='.$match[1], 'att'=>str_replace('"','',$match[1])); $ok = 1; $mode = 0; $textile_attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $textile_attr); break; } if (preg_match("/^('[^']*')(\s+|$)/", $textile_attr, $match)) { $textile_arr[]=array('name' =>$textile_atnm,'whole'=>$textile_atnm.'='.$match[1], 'att'=>str_replace("'",'',$match[1])); $ok = 1; $mode = 0; $textile_attr = preg_replace("/^'[^']*'(\s+|$)/", '', $textile_attr); break; } if (preg_match("/^(\w+)(\s+|$)/", $textile_attr, $match)) { $textile_arr[]= array('name'=>$textile_atnm,'whole'=>$textile_atnm.'="'.$match[1].'"', 'att'=>$match[1]); $ok = 1; $mode = 0; $textile_attr = preg_replace("/^\w+(\s+|$)/", '', $textile_attr); } break; } if ($ok == 0){ $textile_attr = preg_replace('/^\S*\s*/', '', $textile_attr); $mode = 0; } } if ($mode == 1) $textile_arr[] = array ('name'=>$textile_atnm,'whole'=>$textile_atnm.'="'.$textile_atnm.'"','att'=>$textile_atnm); return $textile_arr; } ?>