mirror of
https://github.com/silverstripe/silverstripe-docsviewer
synced 2024-10-22 09:05:56 +00:00
FEATURE Rewrite image links
ENHANCEMENT Return string from parser (instead of HTMLText dependency)
This commit is contained in:
parent
845e2e61b2
commit
e1da17e9d9
@ -29,7 +29,7 @@ class DocumentationParser {
|
|||||||
* @param String $baselink Link relative to webroot, up until the "root" of the module.
|
* @param String $baselink Link relative to webroot, up until the "root" of the module.
|
||||||
* Necessary to rewrite relative links
|
* Necessary to rewrite relative links
|
||||||
*
|
*
|
||||||
* @return HTMLText
|
* @return String
|
||||||
*/
|
*/
|
||||||
public static function parse(DocumentationPage $page, $baselink = null) {
|
public static function parse(DocumentationPage $page, $baselink = null) {
|
||||||
require_once('../sapphiredocs/thirdparty/markdown.php');
|
require_once('../sapphiredocs/thirdparty/markdown.php');
|
||||||
@ -37,12 +37,60 @@ class DocumentationParser {
|
|||||||
$md = $page->getMarkdown();
|
$md = $page->getMarkdown();
|
||||||
|
|
||||||
// Pre-processing
|
// Pre-processing
|
||||||
|
$md = self::rewrite_image_links($md, $page);
|
||||||
$md = self::rewrite_relative_links($md, $page, $baselink);
|
$md = self::rewrite_relative_links($md, $page, $baselink);
|
||||||
$md = self::rewrite_api_links($md, $page);
|
$md = self::rewrite_api_links($md, $page);
|
||||||
|
|
||||||
|
|
||||||
$html = Markdown($md);
|
$html = Markdown($md);
|
||||||
|
|
||||||
return DBField::create('HTMLText', $html);
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function rewrite_image_links($md, $page) {
|
||||||
|
// Links with titles
|
||||||
|
$re = '/
|
||||||
|
!
|
||||||
|
\[
|
||||||
|
(.*?) # image title (non greedy)
|
||||||
|
\]
|
||||||
|
\(
|
||||||
|
(.*?) # image url (non greedy)
|
||||||
|
\)
|
||||||
|
/x';
|
||||||
|
preg_match_all($re, $md, $images);
|
||||||
|
if($images) foreach($images[0] as $i => $match) {
|
||||||
|
$title = $images[1][$i];
|
||||||
|
$url = $images[2][$i];
|
||||||
|
|
||||||
|
// Don't process absolute links (based on protocol detection)
|
||||||
|
$urlParts = parse_url($url);
|
||||||
|
if($urlParts && isset($urlParts['scheme'])) continue;
|
||||||
|
|
||||||
|
// Rewrite URL (relative or absolute)
|
||||||
|
$baselink = Director::makeRelative(dirname($page->getPath()));
|
||||||
|
$relativeUrl = rtrim($baselink, '/') . '/' . ltrim($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);
|
||||||
|
|
||||||
|
// Make it absolute again
|
||||||
|
$absoluteUrl = Director::absoluteBaseURL() . $relativeUrl;
|
||||||
|
|
||||||
|
// Replace in original content
|
||||||
|
$md = str_replace(
|
||||||
|
$match,
|
||||||
|
sprintf('', $title, $absoluteUrl),
|
||||||
|
$md
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $md;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,6 +162,7 @@ class DocumentationParser {
|
|||||||
*/
|
*/
|
||||||
static function rewrite_relative_links($md, $page, $baselink) {
|
static function rewrite_relative_links($md, $page, $baselink) {
|
||||||
$re = '/
|
$re = '/
|
||||||
|
([^\!]?) # exclude image format
|
||||||
\[
|
\[
|
||||||
(.*?) # link title (non greedy)
|
(.*?) # link title (non greedy)
|
||||||
\]
|
\]
|
||||||
@ -128,8 +177,8 @@ class DocumentationParser {
|
|||||||
if($relativePath == '.') $relativePath = '';
|
if($relativePath == '.') $relativePath = '';
|
||||||
|
|
||||||
if($matches) foreach($matches[0] as $i => $match) {
|
if($matches) foreach($matches[0] as $i => $match) {
|
||||||
$title = $matches[1][$i];
|
$title = $matches[2][$i];
|
||||||
$url = $matches[2][$i];
|
$url = $matches[3][$i];
|
||||||
|
|
||||||
// Don't process API links
|
// Don't process API links
|
||||||
if(preg_match('/^api:/', $url)) continue;
|
if(preg_match('/^api:/', $url)) continue;
|
||||||
@ -156,7 +205,7 @@ class DocumentationParser {
|
|||||||
// Replace in original content
|
// Replace in original content
|
||||||
$md = str_replace(
|
$md = str_replace(
|
||||||
$match,
|
$match,
|
||||||
sprintf('[%s](%s)', $title, $relativeUrl),
|
sprintf('%s[%s](%s)', $matches[1][$i], $title, $relativeUrl),
|
||||||
$md
|
$md
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ class DocumentationViewer extends Controller {
|
|||||||
$output->push(new ArrayData(array(
|
$output->push(new ArrayData(array(
|
||||||
'Title' => $module->getTitle(),
|
'Title' => $module->getTitle(),
|
||||||
'Code' => $module,
|
'Code' => $module,
|
||||||
'Content' => $content
|
'Content' => DBField::create("HTMLText", $content)
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -384,7 +384,8 @@ class DocumentationViewer extends Controller {
|
|||||||
function getContent() {
|
function getContent() {
|
||||||
if($page = $this->getPage()) {
|
if($page = $this->getPage()) {
|
||||||
// Remove last portion of path (filename), we want a link to the folder base
|
// Remove last portion of path (filename), we want a link to the folder base
|
||||||
return DocumentationParser::parse($page, $this->Link(array_slice($this->Remaining, -1, -1)));
|
$html = DocumentationParser::parse($page, $this->Link(array_slice($this->Remaining, -1, -1)));
|
||||||
|
return DBField::create("HTMLText", $html);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -4,6 +4,30 @@
|
|||||||
*/
|
*/
|
||||||
class DocumentationParserTest extends SapphireTest {
|
class DocumentationParserTest extends SapphireTest {
|
||||||
|
|
||||||
|
function testImageRewrites() {
|
||||||
|
// Page on toplevel
|
||||||
|
$page = new DocumentationPage(
|
||||||
|
'subfolder/subpage.md',
|
||||||
|
new DocumentationEntity('mymodule', '2.4', BASE_PATH . '/sapphiredocs/tests/docs/'),
|
||||||
|
'en',
|
||||||
|
'2.4'
|
||||||
|
);
|
||||||
|
$result = DocumentationParser::rewrite_image_links($page->getMarkdown(), $page, 'mycontroller/cms/2.4/en/');
|
||||||
|
$this->assertContains(
|
||||||
|
'[relative image link](' . Director::absoluteBaseURL() . '/sapphiredocs/tests/docs/en/subfolder/_images/image.png)',
|
||||||
|
$result
|
||||||
|
);
|
||||||
|
$this->assertContains(
|
||||||
|
'[parent image link](' . Director::absoluteBaseURL() . '/sapphiredocs/tests/docs/en/_images/image.png)',
|
||||||
|
$result
|
||||||
|
);
|
||||||
|
// TODO Fix absolute image references
|
||||||
|
// $this->assertContains(
|
||||||
|
// '[absolute image link](' . Director::absoluteBaseURL() . '/sapphiredocs/tests/docs/en/_images/image.png)',
|
||||||
|
// $result
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
function testApiLinks() {
|
function testApiLinks() {
|
||||||
// Page on toplevel
|
// Page on toplevel
|
||||||
$page = new DocumentationPage(
|
$page = new DocumentationPage(
|
||||||
|
@ -3,3 +3,7 @@
|
|||||||
[link: relative index](../)
|
[link: relative index](../)
|
||||||
[link: relative parent page](../test)
|
[link: relative parent page](../test)
|
||||||
[link: absolute parent page](/test)
|
[link: absolute parent page](/test)
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
Loading…
x
Reference in New Issue
Block a user