. */ // $Id: markdown.php 68 2010-01-16 11:11:50Z extremo $ @define('MARKDOWN_PARSER_CLASS', 'MarkdownDocs_Parser'); require_once TF_VENDOR.'markdown/markdown.php'; require_once TF_VENDOR.'geshi/geshi.php'; /* Original Markdown parser is written in PHP4, so I don't think it is necessary to use 'private' and 'public' in functions here - eXtreme */ class MarkdownDocs_Parser extends MarkdownExtra_Parser { var $page_id = ''; function _doCodeBlocks_callback($matches) { $codeblock = $matches[1]; $codeblock = $this->outdent($codeblock); # trim leading newlines and trailing newlines $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock); $clear = true; $codeblock = $this->_codeBlockHighlighter($codeblock, $clear); if($clear) { $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); $codeblock = "
$codeblock\n
"; } return "\n\n".$this->hashBlock($codeblock)."\n\n"; } // end _doCodeBlocks_callback(); function _doFencedCodeBlocks_callback($matches) { $codeblock = $matches[2]; $clear = true; $codeblock = $this->_codeBlockHighlighter($codeblock, $clear); if($clear) { $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); $codeblock = preg_replace_callback('/^\n+/', array($this, '_doFencedCodeBlocks_newlines'), $codeblock); $codeblock = "
$codeblock
"; } return "\n\n".$this->hashBlock($codeblock)."\n\n"; } // end _doFencedCodeBlocks_callback(); function _codeBlockHighlighter($codeblock, &$clear) { $split = preg_split('/[\r\n]/', $codeblock, 2, PREG_SPLIT_NO_EMPTY); if(count($split) == 2 && preg_match('/^\s*((\\\){0,2}\[([a-zA-Z0-9\-_]+)\]\s*)/', $split[0], $matches)) { if($matches[2] == '\\') { $codeblock = substr($codeblock, 1); return $codeblock; } $strlen = strlen($matches[0]); $parser = strtolower($matches[3]); $codeblock = $split[1]; if($strlen > 0) { if($parser == 'console') { $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); $codeblock = preg_replace_callback('/^\n+/', array($this, '_doFencedCodeBlocks_newlines'), $codeblock); $codeblock = "
$codeblock
"; } else { $codeblock = preg_replace('/\n+$/', '', $codeblock); $geshi = new GeSHi($codeblock, $parser); $geshi->set_overall_style(''); $codeblock = $geshi->parse_code(); } $clear = false; } } return $codeblock; } // end _codeBlockHighlighter(); function _doBlockQuotes_callback($matches) { $bq = $matches[1]; # trim one level of quoting - trim whitespace-only lines $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); $addClass = ''; if(preg_match('/^((\\\){0,2}\[([a-zA-Z0-9\-_]+)\]\s*\n)/', $bq, $matches)) { if($matches[2] == '\\') { $bq = substr($bq, 1); } else { $strlen = strlen($matches[1]); $parser = strtolower($matches[3]); if($strlen > 0) { $bq = substr($bq, $strlen); $addClass = ' class="'.$parser.'"'; } } } $bq = $this->runBlockGamut($bq); # recurse $bq = preg_replace('/^/m', " ", $bq); # These leading spaces cause problem with
 content, 
			# so we need to fix that:
			$bq = preg_replace_callback('{(\s*]*>.+?
)}sx', array(&$this, '_DoBlockQuotes_callback2'), $bq); return "\n".$this->hashBlock("\n$bq\n")."\n\n"; } // end _doBlockQuotes_callback(); function _doHeaders_attr($attr) { if(empty($attr)) return ""; return ' id="h:'.str_replace('.', '_', $this->page_id).':'.$attr.'"'; } // end _doHeaders_attr(); function _doHeaders_callback_setext($matches) { if($matches[3] == '-' && preg_match('{^- }', $matches[1])) return $matches[0]; $level = $matches[3]{0} == '=' ? 1 : 2; $level += 1; $attr = $this->_doHeaders_attr($id =& $matches[2]); $block = "".$this->runSpanGamut($matches[1]).""; return "\n".$this->hashBlock($block)."\n\n"; } // end _doHeaders_callback_setext(); function _doHeaders_callback_atx($matches) { $level = strlen($matches[1]); $level += 1; if($level > 6) $level = 6; $attr = $this->_doHeaders_attr($id =& $matches[3]); $block = "".$this->runSpanGamut($matches[2]).""; return "\n".$this->hashBlock($block)."\n\n"; } // end _doHeaders_callback_atx(); function _doAnchors_reference_callback($matches) { $whole_match = $matches[1]; $res = parent::_doAnchors_reference_callback($matches); if($res != $whole_match || strpos($matches[3], '#') === false) { return $res; } list($matches[3], $anchor) = explode('#', $matches[3], 2); $link_id = strtolower($matches[3]); $temp = false; if(isset($this->urls[$link_id])) { $temp = $this->urls[$link_id]; $explode = explode('#', $this->urls[$link_id], 2); if(count($explode) == 2) { $this->urls[$link_id] = $explode[0]; } $this->urls[$link_id] .= '#h:'.str_replace('.', '_', $link_id).':'.$anchor; } $res = parent::_doAnchors_reference_callback($matches); if($temp !== false) { $this->urls[$link_id] = $temp; } return $res; } // end _doAnchors_reference_callback(); } // end MarkdownDocs_Parser;