function testGetPath()
 {
     $absPath = BASE_PATH . '/sapphiredocs/tests/docs/';
     $page = new DocumentationPage('test.md', new DocumentationEntity('mymodule', null, $absPath));
     $this->assertEquals($absPath . 'en/test.md', $page->getPath());
     $page = new DocumentationPage('subfolder/subpage.md', new DocumentationEntity('mymodule', null, $absPath));
     $this->assertEquals($absPath . 'en/subfolder/subpage.md', $page->getPath());
 }
 public function testGetBreadcrumbTitle()
 {
     $page = new DocumentationPage($this->entity, 'test.md', DOCSVIEWER_PATH . '/tests/docs/en/test.md');
     $this->assertEquals("Test - Doctest", $page->getBreadcrumbTitle());
     $page = new DocumentationFolder($this->entity, '1-basic.md', DOCSVIEWER_PATH . '/tests/docs/en/sort/1-basic.md');
     $this->assertEquals('Basic - Sort - Doctest', $page->getBreadcrumbTitle());
     $page = new DocumentationFolder($this->entity, '', DOCSVIEWER_PATH . '/tests/docs/en/sort/');
     $this->assertEquals('Sort - Doctest', $page->getBreadcrumbTitle());
 }
 function testGetBreadcrumbTitle()
 {
     $entity = new DocumentationEntity('testmodule', null, BASE_PATH . '/sapphiredocs/tests/docs/');
     $page = new DocumentationPage();
     $page->setRelativePath('test.md');
     $page->setEntity($entity);
     $this->assertEquals("Testmodule - Test", $page->getBreadcrumbTitle());
     $page = new DocumentationPage();
     $page->setRelativePath('subfolder/subpage.md');
     $page->setEntity(new DocumentationEntity('mymodule', null, BASE_PATH . '/sapphiredocs/tests/docs/'));
     $this->assertEquals('Mymodule - Subfolder - Subpage', $page->getBreadcrumbTitle());
 }
    /**
     * Strips out the metadata for a page
     *
     * @param DocumentationPage
     */
    public static function retrieve_meta_data(DocumentationPage &$page)
    {
        if ($md = $page->getMarkdown()) {
            $matches = preg_match_all('/
				(?<key>[A-Za-z0-9_-]+): 
				\\s*
				(?<value>.*)
			/x', $md, $meta);
            if ($matches) {
                foreach ($meta['key'] as $index => $key) {
                    if (isset($meta['value'][$index])) {
                        $page->setMetaData($key, $meta['value'][$index]);
                    }
                }
            }
        }
    }
 /**
  * Return the summary / index text for this entity. Either pulled
  * from an index file or some other summary field
  *
  * @return DocumentationPage
  */
 function getIndexPage($version, $lang = 'en')
 {
     $path = $this->getPath($version, $lang);
     $absFilepath = Controller::join_links($path, 'index.md');
     if (file_exists($absFilepath)) {
         $relativeFilePath = str_replace($path, '', $absFilepath);
         $page = new DocumentationPage();
         $page->setRelativePath($relativeFilePath);
         $page->setEntity($this);
         $page->setLang($lang);
         $page->setVersion($version);
         return $page;
     }
     return false;
 }
 /**
  * Return the children from a given entity sorted by Title using natural ordering. 
  * It is used for building the tree of the page.
  *
  * @param DocumentationEntity path
  * @param string - an optional path within a entity
  * @param bool enable several recursive calls (more than 1 level)
  * @param string - version to use
  * @param string - lang to use
  *
  * @throws Exception
  * @return DataObjectSet
  */
 public static function get_pages_from_folder($entity, $relativePath = false, $recursive = true, $version = 'trunk', $lang = 'en')
 {
     $output = new DataObjectSet();
     $pages = array();
     if (!$entity instanceof DocumentationEntity) {
         user_error("get_pages_from_folder must be passed a entity", E_USER_ERROR);
     }
     $path = $entity->getPath($version, $lang);
     if (self::is_registered_entity($entity)) {
         self::get_pages_from_folder_recursive($path, $relativePath, $recursive, $pages);
     } else {
         return user_error("{$entity} is not registered", E_USER_WARNING);
     }
     if (count($pages) > 0) {
         natsort($pages);
         foreach ($pages as $key => $pagePath) {
             // get file name from the path
             $file = ($pos = strrpos($pagePath, '/')) ? substr($pagePath, $pos + 1) : $pagePath;
             $page = new DocumentationPage();
             $page->setTitle(self::clean_page_name($file));
             $relative = str_replace($path, '', $pagePath);
             // if no extension, put a slash on it
             if (strpos($relative, '.') === false) {
                 $relative .= '/';
             }
             $page->setEntity($entity);
             $page->setRelativePath($relative);
             $page->setVersion($version);
             $page->setLang($lang);
             $output->push($page);
         }
     }
     return $output;
 }
 function testRewritingRelativeLinksToFiles()
 {
     $folder = '/sapphiredocs/tests/docs-parser/';
     $page = new DocumentationPage();
     $page->setRelativePath('file-download.md');
     $page->setEntity(new DocumentationEntity('parser', '2.4', BASE_PATH . $folder));
     $parsed = DocumentationParser::parse($page, $folder);
     $this->assertContains(Controller::join_links($folder, '/en/_images/external_link.png'), $parsed);
     $this->assertContains(Controller::join_links($folder, '/en/_images/test.tar.gz'), $parsed);
 }
 /**
  * @param DocumentationPage $page
  *
  * @return boolean
  */
 public function hasRecord($page)
 {
     if (!$page) {
         return false;
     }
     return strstr($page->getPath(), $this->getPath()) !== false;
 }
 /**
  *
  * @param DocumentationPage $page
  * @param string $basename
  * @param string $path
  */
 protected function addPage($page, $basename, $path)
 {
     $link = $this->stripLinkBase($page->Link());
     $this->pages[$link] = array('title' => $page->getTitle(), 'basename' => $basename, 'filepath' => $path, 'type' => get_class($page), 'entitypath' => $this->entity->getPath(), 'summary' => $page->getSummary());
 }
    public function testRewriteCodeBlocks()
    {
        $codePage = new DocumentationPage($this->entityAlt, 'CodeSnippets.md', DOCSVIEWER_PATH . '/tests/docs-parser/en/CodeSnippets.md');
        $result = DocumentationParser::rewrite_code_blocks($codePage->getMarkdown());
        $expected = <<<HTML
#### <% control Foo %>
```
code block
<% without formatting prefix %>
```
Paragraph with a segment of <% foo %>
```
code block

that has a line in it
```
This is a yaml block

```yaml
foo: bar

baz: qux
```
This is a yaml block with tab in that new line

```yaml
foo: bar

baz: qux
```
HTML;
        $this->assertEquals($expected, $result, 'Code blocks support line breaks');
        $result = DocumentationParser::rewrite_code_blocks($this->page->getMarkdown());
        $expected = <<<HTML
```php
code block
with multiple
lines
\tand tab indent
\tand escaped < brackets
\t
```
Normal text after code block
HTML;
        $this->assertContains($expected, $result, 'Custom code blocks with ::: prefix');
        $expected = <<<HTML
```
code block
without formatting prefix
```
HTML;
        $this->assertContains($expected, $result, 'Traditional markdown code blocks');
        $expected = <<<HTML
```
Fenced code block
```
HTML;
        $this->assertContains($expected, $result, 'Backtick code blocks');
        $expected = <<<HTML
```php
Fenced box with

new lines in

between

content
```
HTML;
        $this->assertContains($expected, $result, 'Backtick with newlines');
    }
    /**
     * Resolves all relative links within markdown.
     * 
     * @param String $md Markdown content
     * @param DocumentationPage $page
     * @param String $baselink
     * @return String Markdown
     */
    static function rewrite_relative_links($md, $page, $baselink)
    {
        $re = '/
			([^\\!]?) # exclude image format
			\\[
				(.*?) # link title (non greedy)
			\\] 
			\\(
				(.*?) # link url (non greedy)
			\\)
		/x';
        preg_match_all($re, $md, $matches);
        // relative path (to module base folder), without the filename
        $relativePath = dirname($page->getRelativePath());
        if ($relativePath == '.') {
            $relativePath = '';
        }
        if ($matches) {
            foreach ($matches[0] as $i => $match) {
                $title = $matches[2][$i];
                $url = $matches[3][$i];
                // Don't process API links
                if (preg_match('/^api:/', $url)) {
                    continue;
                }
                // Don't process absolute links (based on protocol detection)
                $urlParts = parse_url($url);
                if ($urlParts && isset($urlParts['scheme'])) {
                    continue;
                }
                // Rewrite URL (relative or absolute)
                if (preg_match('/^\\//', $url)) {
                    $relativeUrl = $baselink . $url;
                } else {
                    $relativeUrl = $baselink . '/' . $relativePath . '/' . $url;
                }
                // Resolve relative paths
                while (strpos($relativeUrl, '..') !== FALSE) {
                    $relativeUrl = preg_replace('/\\w+\\/\\.\\.\\//', '', $relativeUrl);
                }
                // Replace any double slashes (apart from protocol)
                $relativeUrl = preg_replace('/([^:])\\/{2,}/', '$1/', $relativeUrl);
                // Replace in original content
                $md = str_replace($match, sprintf('%s[%s](%s)', $matches[1][$i], $title, $relativeUrl), $md);
            }
        }
        return $md;
    }
 /**
  * Returns the previous page. Either returns the previous sibling or the
  * parent of this page
  *
  * @return DocumentationPage
  */
 public function getPreviousPage()
 {
     return $this->record ? $this->getManifest()->getPreviousPage($this->record->getPath(), $this->getEntity()->getPath()) : null;
 }
 /**
  * @return DocumentationPage
  */
 function getPage()
 {
     $entity = $this->getEntity();
     if (!$entity) {
         return false;
     }
     $version = $this->getVersion();
     $lang = $this->getLang();
     $absFilepath = DocumentationService::find_page($entity, $this->Remaining, $version, $lang);
     if ($absFilepath) {
         $relativeFilePath = str_replace($entity->getPath($version, $lang), '', $absFilepath);
         $page = new DocumentationPage();
         $page->setRelativePath($relativeFilePath);
         $page->setEntity($entity);
         $page->setLang($lang);
         $page->setVersion($version);
         return $page;
     }
     return false;
 }