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
"$":url -> url
"$(title)":url -> url
!imageurl! -> Scientists say1 the moon is small.
The 'a b c' backlink characters can be altered too. For example if you wanted the notes to have numeric backlinks starting from 1: notelist:1. Table syntax: Simple tables: |a|simple|table|row| |And|Another|table|row| |With an||empty|cell| |=. My table caption goes here |_. A|_. table|_. header|_.row| |A|simple|table|row| Tables with attributes: table{border:1px solid black}. My table summary here {background:#ddd;color:red}. |{}| | | | To specify thead / tfoot / tbody groups, add one of these on its own line above the row(s) you wish to wrap (you may specify attributes before the dot): |^. # thead |-. # tbody |~. # tfoot Column groups: |:\3. 100 Becomes: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 ->\n"; $o2 = "\t\t"; } elseif ($tag == 'bc') { $o1 = "pba($att, '', 0).">"; $c2 = "
"; $c1 = "\n\t
";
$o2 = "pba($att, '', 0).">";
$c2 = "
";
$c1 = "
";
$content = $this->shelve($this->r_encode_html(rtrim($content, "\n")."\n"));
}
elseif ($tag == 'notextile') {
$content = $this->shelve($content);
$o1 = $o2 = '';
$c1 = $c2 = '';
}
elseif ($tag == 'pre') {
$content = $this->shelve($this->r_encode_html(rtrim($content, "\n")."\n"));
$o1 = ""; $o2 = $c2 = ''; $c1 = ""; } elseif ($tag == '###') { $eat = true; } else { $o2 = "\t<$tag$atts>"; $c2 = "$tag>"; } $content = (!$eat) ? $this->graf($content) : ''; return array($o1, $o2, $content, $c2, $c1, $eat); } // ------------------------------------------------------------- function graf($text) { // handle normal paragraph text if (!$this->lite) { $text = $this->noTextile($text); $text = $this->code($text); } $text = $this->getRefs($text); $text = $this->links($text); if (!$this->noimage) $text = $this->image($text); if (!$this->lite) { $text = $this->table($text); $text = $this->lists($text); } $text = $this->span($text); $text = $this->footnoteRef($text); $text = $this->noteRef($text); $text = $this->glyphs($text); return rtrim($text, "\n"); } // ------------------------------------------------------------- function span($text) { $qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~','\^'); $pnct = ".,\"'?!;:"; $this->span_depth++; if( $this->span_depth <= $this->max_span_depth ) { foreach($qtags as $f) { $text = preg_replace_callback("/ (^|(?<=[\s>$pnct\(])|[{[]) # pre ($f)(?!$f) # tag ({$this->c}) # atts (?::(\S+))? # cite ([^\s$f]+|\S.*?[^\s$f\n]) # content ([$pnct]*) # end $f ($|[\]}]|(?=[[:punct:]]{1,2}|\s|\))) # tail /x", array(&$this, "fSpan"), $text); } } $this->span_depth--; return $text; } // ------------------------------------------------------------- function fSpan($m) { $qtags = array( '*' => 'strong', '**' => 'b', '??' => 'cite', '_' => 'em', '__' => 'i', '-' => 'del', '%' => 'span', '+' => 'ins', '~' => 'sub', '^' => 'sup', ); list(, $pre, $tag, $atts, $cite, $content, $end, $tail) = $m; $tag = $qtags[$tag]; $atts = $this->pba($atts); $atts .= ($cite != '') ? 'cite="' . $cite . '"' : ''; $content = $this->span($content); $opentag = '<'.$tag.$atts.'>'; $closetag = ''.$tag.'>'; $tags = $this->storeTags($opentag, $closetag); $out = "{$tags['open']}{$content}{$end}{$tags['close']}"; if (($pre and !$tail) or ($tail and !$pre)) $out = $pre.$out.$tail; return $out; } // ------------------------------------------------------------- function storeTags($opentag,$closetag='') { $key = ($this->tag_index++); $key = str_pad( (string)$key, 10, '0', STR_PAD_LEFT ); # $key must be of fixed length to allow proper matching in retrieveTags $this->tagCache[$key] = array('open'=>$opentag, 'close'=>$closetag); $tags = array( 'open' => "textileopentag{$key} ", 'close' => " textileclosetag{$key}", ); return $tags; } // ------------------------------------------------------------- function retrieveTags($text) { $text = preg_replace_callback('/textileopentag([\d]{10}) /' , array(&$this, 'fRetrieveOpenTags'), $text); $text = preg_replace_callback('/ textileclosetag([\d]{10})/', array(&$this, 'fRetrieveCloseTags'), $text); return $text; } // ------------------------------------------------------------- function fRetrieveOpenTags($m) { list(, $key ) = $m; return $this->tagCache[$key]['open']; } // ------------------------------------------------------------- function fRetrieveCloseTags($m) { list(, $key ) = $m; return $this->tagCache[$key]['close']; } // ------------------------------------------------------------- function placeNoteLists($text) { extract($this->regex_snippets); # Sequence all referenced definitions... if( !empty($this->notes) ) { $o = array(); foreach( $this->notes as $label=>$info ) { $i = @$info['seq']; if( !empty($i) ) { $info['seq'] = $label; $o[$i] = $info; } else { $this->unreferencedNotes[] = $info; # unreferenced definitions go here for possible future use. } } if( !empty($o) ) ksort($o); $this->notes = $o; } # Replace list markers... $text = preg_replace_callback("@
notelist({$this->c})(?:\:($wrd))?([\^!]?)(\+?)\.[\s]*
@U$mod", array(&$this, "fNoteLists"), $text ); return $text; } // ------------------------------------------------------------- function fParseNoteDefs($m) { list(, $label, $link, $att, $content) = $m; # Assign an id if the note reference parse hasn't found the label yet. $id = @$this->notes[$label]['id']; if( !$id ) $this->notes[$label]['id'] = uniqid(rand()); if( empty($this->notes[$label]['def']) ) # Ignores subsequent defs using the same label { $this->notes[$label]['def'] = array( 'atts' => $this->pba($att), 'content' => $this->graf($content), 'link' => $link, ); } return ''; } // ------------------------------------------------------------- function noteRef($text) { $text = preg_replace_callback("/ \[ # start ({$this->c}) # !atts \# ([^\]!]+?) # !label ([!]?) # !nolink \] /Ux", array(&$this, "fParseNoteRefs"), $text); return $text; } // ------------------------------------------------------------- function fParseNoteRefs($m) { # By the time this function is called, all the defs will have been processed # into the notes array. So now we can resolve the link numbers in the order # we process the refs... list(, $atts, $label, $nolink) = $m; $atts = $this->pba($atts); $nolink = ($nolink === '!'); # Assign a sequence number to this reference if there isn't one already... $num = @$this->notes[$label]['seq']; if( !$num ) $num = $this->notes[$label]['seq'] = ($this->note_index++); # Make our anchor point & stash it for possible use in backlinks when the # note list is generated later... $this->notes[$label]['refids'][] = $refid = uniqid(rand()); # If we are referencing a note that hasn't had the definition parsed yet, then assign it an ID... $id = @$this->notes[$label]['id']; if( !$id ) $id = $this->notes[$label]['id'] = uniqid(rand()); # Build the link (if any)... $_ = ''.$num.''; if( !$nolink ) $_ = ''.$_.''; # Build the reference... $_ = ''.$_.''; return $_; } // ------------------------------------------------------------- function fNoteLists($m) { list(, $att, $start_char, $g_links, $extras) = $m; if( !$start_char ) $start_char = 'a'; $index = $g_links.$extras.$start_char; if( empty($this->notelist_cache[$index]) ) { # If not in cache, build the entry... $o = array(); if( !empty($this->notes)) { foreach($this->notes as $seq=>$info) { $links = $this->makeBackrefLink($info, $g_links, $start_char ); if( !empty($info['def'])) { $id = $info['id']; extract($info['def']); $o[] = "\t".'', '
', 'fCode');
$text = $this->doSpecial($text, '@', '@', 'fCode');
$text = $this->doSpecial($text, '', '', 'fPre'); return $text; } // ------------------------------------------------------------- function fCode($m) { @list(, $before, $text, $after) = $m; return $before.$this->shelve('
'.$this->r_encode_html($text).'
').$after;
}
// -------------------------------------------------------------
function fPre($m)
{
@list(, $before, $text, $after) = $m;
return $before.''.$this->shelve($this->r_encode_html($text)).''.$after; } // ------------------------------------------------------------- function shelve($val) { $i = uniqid(rand()); $this->shelf[$i] = $val; return $i; } // ------------------------------------------------------------- function retrieve($text) { if (is_array($this->shelf)) do { $old = $text; $text = strtr($text, $this->shelf); } while ($text != $old); return $text; } // ------------------------------------------------------------- // NOTE: deprecated function incomingEntities($text) { return preg_replace("/&(?![#a-z0-9]+;)/i", "x%x%", $text); } // ------------------------------------------------------------- // NOTE: deprecated function encodeEntities($text) { return (function_exists('mb_encode_numericentity')) ? $this->encode_high($text) : htmlentities($text, ENT_NOQUOTES, "utf-8"); } // ------------------------------------------------------------- // NOTE: deprecated function fixEntities($text) { /* de-entify any remaining angle brackets or ampersands */ return str_replace(array(">", "<", "&"), array(">", "<", "&"), $text); } // ------------------------------------------------------------- function cleanWhiteSpace($text) { $out = preg_replace("/^\xEF\xBB\xBF|\x1A/", '', $text); # Byte order mark (if present) $out = preg_replace("/\r\n?/", "\n", $out); # DOS and MAC line endings to *NIX style endings $out = preg_replace("/^[ \t]*\n/m", "\n", $out); # lines containing only whitespace $out = preg_replace("/\n{3,}/", "\n\n", $out); # 3 or more line ends $out = preg_replace("/^\n*/", "", $out); # leading blank lines return $out; } // ------------------------------------------------------------- function doSpecial($text, $start, $end, $method='fSpecial') { return preg_replace_callback('/(^|\s|[[({>])'.preg_quote($start, '/').'(.*?)'.preg_quote($end, '/').'(\s|$|[\])}])?/ms', array(&$this, $method), $text); } // ------------------------------------------------------------- function fSpecial($m) { // A special block like notextile or code @list(, $before, $text, $after) = $m; return $before.$this->shelve($this->encode_html($text)).$after; } // ------------------------------------------------------------- function noTextile($text) { $text = $this->doSpecial($text, '
",(is_array($a)) ? print_r($a) : ((is_bool($a)) ? $bool[(int)$a] : $a), "\n"; return $this; } // ------------------------------------------------------------- function blockLite($text) { $this->btag = array('bq', 'p'); return $this->block($text."\n\n"); } } // end class