/** * Transform some text using [Kodoc_Markdown] * * @see Markdown() * * @param string Text to parse * @return string Transformed text */ public static function markdown($text) { static $instance; if ($instance === NULL) { $instance = new Kodoc_Markdown(); } return $instance->transform($text); }
public function before() { if ($this->request->action === 'media') { // Do not template media files $this->auto_render = FALSE; } else { // Grab the necessary routes $this->media = Route::get('docs/media'); $this->api = Route::get('docs/api'); $this->guide = Route::get('docs/guide'); if (isset($_GET['lang'])) { $lang = $_GET['lang']; // Load the accepted language list $translations = array_keys(Kohana::message('userguide', 'translations')); if (in_array($lang, $translations)) { // Set the language cookie Cookie::set('userguide_language', $lang, Date::YEAR); } // Reload the page $this->request->redirect($this->request->uri); } // Set the translation language I18n::$lang = Cookie::get('userguide_language', Kohana::config('userguide')->lang); // Use customized Markdown parser define('MARKDOWN_PARSER_CLASS', 'Kodoc_Markdown'); // Load Markdown support require Kohana::find_file('vendor', 'markdown/markdown'); // Set the base URL for links and images Kodoc_Markdown::$base_url = URL::site($this->guide->uri()) . '/'; Kodoc_Markdown::$image_url = URL::site($this->media->uri()) . '/'; } parent::before(); }
public function __construct($class, $property) { $property = new ReflectionProperty($class, $property); list($description, $tags) = Kodoc::parse($property->getDocComment()); $this->description = $description; if ($modifiers = $property->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if (isset($tags['var'])) { if (preg_match('/^(\\S*)(?:\\s*(.+?))?$/', $tags['var'][0], $matches)) { $this->type = $matches[1]; if (isset($matches[2])) { $this->description = Kodoc_Markdown::markdown($matches[2]); } } } $this->property = $property; // Show the value of static properties, but only if they are public or we are php 5.3 or higher and can force them to be accessible if ($property->isStatic() and ($property->isPublic() or version_compare(PHP_VERSION, '5.3', '>='))) { // Force the property to be accessible if (version_compare(PHP_VERSION, '5.3', '>=')) { $property->setAccessible(TRUE); } // Don't debug the entire object, just say what kind of object it is if (is_object($property->getValue($class))) { $this->value = '<pre>object ' . get_class($property->getValue($class)) . '()</pre>'; } else { $this->value = Debug::vars($property->getValue($class)); } } }
public function __construct() { parent::__construct(); // Create a custom 404 handler for this controller Event::clear('system.404', array('Kohana_404_Exception', 'trigger')); Event::add('system.404', array($this, 'error')); // Do we have anything cached? if (Kohana::config('userguide.cache')) { $this->cache = Cache::instance(); } if (Router::$method === 'media') { // Do not template media files $this->auto_render = FALSE; } // Use customized Markdown parser define('MARKDOWN_PARSER_CLASS', 'Kodoc_Markdown'); // Load Markdown support require Kohana::find_file('vendor', 'markdown', TRUE); // Set the base URL for links and images Kodoc_Markdown::$base_url = url::site('userguide') . '/'; Kodoc_Markdown::$image_url = url::site('userguide/media') . '/'; // Disable eAccelerator, it messes with the ReflectionClass->getDocComments() calls ini_set('eaccelerator.enable', 0); // Bind the breadcrumb $this->template->bind('breadcrumb', $this->breadcrumb); // Add the breadcrumb $this->breadcrumb = array(); $this->breadcrumb['userguide'] = 'User Guide'; if ($this->package = URI::instance()->segment(3)) { $this->breadcrumb['userguide/guide/' . $this->package] = ucfirst($this->package); } }
/** * Loads a class and uses [reflection](http://php.net/reflection) to parse * the class. Reads the class modifiers, constants and comment. Parses the * comment to find the description and tags. * * @param string class name * @return void */ public function __construct($class) { $this->class = new ReflectionClass($class); if ($modifiers = $this->class->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } if ($constants = $this->class->getConstants()) { foreach ($constants as $name => $value) { $this->constants[$name] = Debug::vars($value); } } // If ReflectionClass::getParentClass() won't work if the class in // question is an interface if ($this->class->isInterface()) { $this->parents = $this->class->getInterfaces(); } else { $parent = $this->class; while ($parent = $parent->getParentClass()) { $this->parents[] = $parent; } } $parents = $this->parents; array_unshift($parents, $this->class); foreach ($parents as $parent) { if ($comment = $parent->getDocComment()) { // Found a description for this class break; } } list($this->description, $this->tags) = Kodoc::parse($comment); // If this class extends Kodoc_Missing, add a warning about possible // incomplete documentation foreach ($parents as $parent) { if ($parent->name == 'Kodoc_Missing') { $warning = "[!!] **This class, or a class parent, could not be\n\t\t\t\t found or loaded. This could be caused by a missing\n\t\t\t\t\t\t module or other dependancy. The documentation for\n\t\t\t\t\t\t class may not be complete!**"; $this->description = Kodoc_Markdown::markdown($warning) . $this->description; } } }
public function action_api() { // Reset the base URL for links with new routes Kodoc_Markdown::$base_url = URL::site($this->api->uri()) . '/'; // Get the class from the request $class = $this->request->param('class'); if (!$class) { // Redirect to Jelly class to ensure menu is open $this->request->redirect($this->api->uri(array('class' => 'Jelly'))); } // Set the template title $this->template->title = $class; $this->template->content = View::factory('userguide/api/class')->set('doc', Kodoc::factory($class))->set('route', $this->request->route); // Attach the menu to the template $this->template->menu = self::api_menu(); // Bind the breadcrumb $this->template->bind('breadcrumb', $breadcrumb); // Add the breadcrumb $breadcrumb = array(); $breadcrumb['/'] = __('Jelly Home'); $breadcrumb[$this->guide->uri(array('page' => NULL))] = __('User Guide'); $breadcrumb[$this->request->route->uri()] = __('API Reference'); $breadcrumb[] = $this->template->title; }
public function action_docs() { $module = $this->request->param('module'); $page = $this->request->param('page'); // Trim trailing slash $page = rtrim($page, '/'); // If no module provided in the url, show the user guide index page, which lists the modules. if (!$module) { return $this->index(); } // If this module's userguide pages are disabled, show the error page if (!Kohana::$config->load('userguide.modules.' . $module . '.enabled')) { return $this->error('That module doesn\'t exist, or has userguide pages disabled.'); } // Prevent "guide/module" and "guide/module/index" from having duplicate content if ($page == 'index') { return $this->error('Userguide page not found'); } // If a module is set, but no page was provided in the url, show the index page if (!$page) { $page = 'index'; } // Find the markdown file for this page $file = $this->file($module . '/' . $page); // If it's not found, show the error page if (!$file) { return $this->error('Userguide page not found'); } // Namespace the markdown parser Kodoc_Markdown::$base_url = URL::site($this->guide->uri()) . '/' . $module . '/'; Kodoc_Markdown::$image_url = URL::site($this->media->uri()) . '/' . $module . '/'; // Set the page title $this->template->title = $page == 'index' ? Kohana::$config->load('userguide.modules.' . $module . '.name') : $this->title($page); // Parse the page contents into the template Kodoc_Markdown::$show_toc = TRUE; $this->template->content = Kodoc_Markdown::markdown(file_get_contents($file)); Kodoc_Markdown::$show_toc = FALSE; // Attach this module's menu to the template $this->template->menu = Kodoc_Markdown::markdown($this->_get_all_menu_markdown()); // Bind the breadcrumb $this->template->bind('breadcrumb', $breadcrumb); // Bind the copyright $this->template->copyright = Kohana::$config->load('userguide.modules.' . $module . '.copyright'); // Add the breadcrumb trail $breadcrumb = array(); $breadcrumb[$this->guide->uri()] = 'User Guide'; $breadcrumb[$this->guide->uri(array('module' => $module))] = Kohana::$config->load('userguide.modules.' . $module . '.name'); // TODO try and get parent category names (from menu). Regex magic or javascript dom stuff perhaps? // Only add the current page title to breadcrumbs if it isn't the index, otherwise we get repeats. if ($page != 'index') { $breadcrumb[] = $this->template->title; } }
/** * Parse a comment to extract the description and the tags * * [!!] Converting the output to HTML in this method is deprecated in 3.3 * * @param string $comment The DocBlock to parse * @param boolean $html Whether or not to convert the return values * to HTML (deprecated) * @return array array(string $description, array $tags) */ public static function parse($comment, $html = TRUE) { // Normalize all new lines to \n $comment = str_replace(array("\r\n", "\n"), "\n", $comment); // Split into lines while capturing without leading whitespace preg_match_all('/^\\s*\\* ?(.*)\\n/m', $comment, $lines); // Tag content $tags = array(); /** * Process a tag and add it to $tags * * @param string $tag Name of the tag without @ * @param string $text Content of the tag * @return void */ $add_tag = function ($tag, $text) use($html, &$tags) { // Don't show @access lines, they are shown elsewhere if ($tag !== 'access') { if ($html) { $text = Kodoc::format_tag($tag, $text); } // Add the tag $tags[$tag][] = $text; } }; $comment = $tag = NULL; $end = count($lines[1]) - 1; foreach ($lines[1] as $i => $line) { // Search this line for a tag if (preg_match('/^@(\\S+)\\s*(.+)?$/', $line, $matches)) { if ($tag) { // Previous tag is finished $add_tag($tag, $text); } $tag = $matches[1]; $text = isset($matches[2]) ? $matches[2] : ''; if ($i === $end) { // No more lines $add_tag($tag, $text); } } elseif ($tag) { // This is the continuation of the previous tag $text .= "\n" . $line; if ($i === $end) { // No more lines $add_tag($tag, $text); } } else { $comment .= "\n" . $line; } } $comment = trim($comment, "\n"); if ($comment and $html) { // Parse the comment with Markdown $comment = Kodoc_Markdown::markdown($comment); } return array($comment, $tags); }
/** * Parse a comment to extract the description and the tags * * @param string the comment retreived using ReflectionClass->getDocComment() * @return array array(string $description, array $tags) */ public static function parse($comment) { // Normalize all new lines to \n $comment = str_replace(array("\r\n", "\n"), "\n", $comment); // Remove the phpdoc open/close tags and split $comment = array_slice(explode("\n", $comment), 1, -1); // Tag content $tags = array(); foreach ($comment as $i => $line) { // Remove all leading whitespace $line = preg_replace('/^\\s*\\* ?/m', '', $line); // Search this line for a tag if (preg_match('/^@(\\S+)(?:\\s*(.+))?$/', $line, $matches)) { // This is a tag line unset($comment[$i]); $name = $matches[1]; $text = isset($matches[2]) ? $matches[2] : ''; switch ($name) { case 'license': if (strpos($text, '://') !== FALSE) { // Convert the lincense into a link $text = HTML::anchor($text); } break; case 'link': $text = preg_split('/\\s+/', $text, 2); $text = HTML::anchor($text[0], isset($text[1]) ? $text[1] : $text[0]); break; case 'copyright': if (strpos($text, '(c)') !== FALSE) { // Convert the copyright sign $text = str_replace('(c)', '©', $text); } break; case 'throws': if (preg_match('/^(\\w+)\\W(.*)$/', $text, $matches)) { $text = HTML::anchor(Route::get('docs/api')->uri(array('class' => $matches[1])), $matches[1]) . ' ' . $matches[2]; } else { $text = HTML::anchor(Route::get('docs/api')->uri(array('class' => $text)), $text); } break; case 'uses': if (preg_match('/^' . Kodoc::$regex_class_member . '$/i', $text, $matches)) { $text = Kodoc::link_class_member($matches); } break; // Don't show @access lines, they are shown elsewhere // Don't show @access lines, they are shown elsewhere case 'access': continue 2; } // Add the tag $tags[$name][] = $text; } else { // Overwrite the comment line $comment[$i] = (string) $line; } } // Concat the comment lines back to a block of text if ($comment = trim(implode("\n", $comment))) { // Parse the comment with Markdown $comment = Kodoc_Markdown::markdown($comment); } return array($comment, $tags); }
/** * Get the description of this class as HTML. Includes a warning when the * class or one of its parents could not be found. * * @return string HTML */ public function description() { $result = $this->description; // If this class extends Kodoc_Missing, add a warning about possible // incomplete documentation foreach ($this->parents as $parent) { if ($parent->name == 'Kodoc_Missing') { $result .= "[!!] **This class, or a class parent, could not be\r\n\t\t\t\t found or loaded. This could be caused by a missing\r\n\t\t\t\t module or other dependancy. The documentation for\r\n\t\t\t\t class may not be complete!**"; } } return Kodoc_Markdown::markdown($result); }
public function action_docs() { $module = $this->request->param('module'); $page = $this->request->param('page'); // Trim trailing slash $page = rtrim($page, '/'); // If no module provided in the url, show the user guide index page, which lists the modules. if (!$module) { return $this->index(); } // If this module's userguide pages are disabled, show the error page if (!Kohana::$config->load('userguide.modules.' . $module . '.enabled')) { return $this->error(__('That module doesn\'t exist, or has userguide pages disabled.')); } // Prevent "guide/module" and "guide/module/index" from having duplicate content if ($page == 'index') { return $this->error(__('Userguide page not found')); } // If a module is set, but no page was provided in the url, show the index page if (!$page) { $page = 'index'; } // Find the markdown file for this page $file = $this->file($module . '/' . $page); // If it's not found, show the error page if (!$file) { return $this->error(__('Userguide page not found')); } // Namespace the markdown parser Kodoc_Markdown::$base_url = URL::site($this->guide->uri()) . '/' . $module . '/'; Kodoc_Markdown::$image_url = URL::site($this->media->uri()) . '/' . $module . '/'; // Set the page title $this->template->title = $page == 'index' ? Kohana::$config->load('userguide.modules.' . $module . '.name') : $this->title($page); // Parse the page contents into the template Kodoc_Markdown::$show_toc = true; $this->template->content = Markdown(file_get_contents($file)); Kodoc_Markdown::$show_toc = false; // Attach this module's menu to the template $this->template->menu = View::factory('userguide/doc/menu')->set('menu', Markdown($this->_get_all_menu_markdown())); // Bind the copyright $this->template->copyright = Kohana::$config->load('userguide.modules.' . $module . '.copyright'); // Add the breadcrumb trail $this->breadcrumbs->add(__('User Guide'), $this->guide->uri())->add(Kohana::$config->load('userguide.modules.' . $module . '.name'), $this->guide->uri(array('module' => $module))); }