transform($text); } public function __construct() { // doImage is 10, add image url just before $this->span_gamut['doImageURL'] = 9; // doLink is 20, add base url just before $this->span_gamut['doBaseURL'] = 19; // Add API links $this->span_gamut['doAPI'] = 90; // Add note spans last $this->span_gamut['doNotes'] = 100; // Parse Kohana view inclusions at the very end $this->document_gamut['doIncludeViews'] = 99; // Show table of contents for userguide pages $this->document_gamut['doTOC'] = 100; // Call parent constructor. parent::__construct(); } /** * Callback for the heading setext style * * Heading 1 * ========= * * @param array Matches from regex call * @return string Generated html */ function _doHeaders_callback_setext($matches) { if ($matches[3] == '-' AND preg_match('{^- }', $matches[1])) return $matches[0]; $level = ($matches[3]{0} == '=') ? 1 : 2; $attr = $this->_doHeaders_attr($id =& $matches[2]); // Only auto-generate id if one doesn't exist if (empty($attr)) { $attr = ' id="'.$this->make_heading_id($matches[1]).'"'; } // Add this header to the page toc $this->_add_to_toc($level,$matches[1],$this->make_heading_id($matches[1])); $block = "".$this->runSpanGamut($matches[1]).""; return "\n".$this->hashBlock($block)."\n\n"; } /** * Callback for the heading atx style * * # Heading 1 * * @param array Matches from regex call * @return string Generated html */ function _doHeaders_callback_atx($matches) { $level = strlen($matches[1]); $attr = $this->_doHeaders_attr($id =& $matches[3]); // Only auto-generate id if one doesn't exist if (empty($attr)) { $attr = ' id="'.$this->make_heading_id($matches[2]).'"'; } // Add this header to the page toc $this->_add_to_toc($level, $matches[2], $this->make_heading_id(empty($matches[3]) ? $matches[2] : $matches[3])); $block = "".$this->runSpanGamut($matches[2]).""; return "\n".$this->hashBlock($block)."\n\n"; } /** * Makes a heading id from the heading text * If any heading share the same name then subsequent headings will have an integer appended * * @param string The heading text * @return string ID for the heading */ function make_heading_id($heading) { $id = url::title($heading, '-', TRUE); if (isset($this->_heading_ids[$id])) { $id .= '-'; $count = 0; while (isset($this->_heading_ids[$id]) AND ++$count) { $id .= $count; } } return $id; } public function doIncludeViews($text) { if (preg_match_all('/{{([^\s{}]++)}}/', $text, $matches, PREG_SET_ORDER)) { $replace = array(); foreach ($matches as $set) { list($search, $view) = $set; if (Kohana::find_file('views', $view)) { try { $replace[$search] = View::factory($view)->render(); } catch (Exception $e) { /** * Capture the exception handler output and insert it instead. * * NOTE: Is this really the correct way to handle an exception? */ $response = Kohana_exception::_handler($e); $replace[$search] = $response->body(); } } } $text = strtr($text, $replace); } return $text; } /** * Add the current base url to all local links. * * [filesystem](about.filesystem "Optional title") * * @param string Span text * @return string */ public function doBaseURL($text) { // URLs containing "://" are left untouched return preg_replace('~(?hashBlock('

'.$match[1].'

'); } protected function _add_to_toc($level, $name, $id) { self::$_toc[] = array( 'level' => $level, 'name' => $name, 'id' => $id); } public function doTOC($text) { // Only add the toc do userguide pages, not api since they already have one if (self::$show_toc AND Route::name(Request::current()->route()) == "docs/guide") { $toc = View::factory('userguide/page-toc') ->set('array', self::$_toc) ->render() ; if (($offset = strpos($text, '

')) !== FALSE) { // Insert the page TOC just before the first

, which every // Markdown page should (will?) have. $text = substr_replace($text, $toc, $offset, 0); } } return $text; } } // End Kodoc_Markdown