Further tidy up of api link parsing and testing

typo

another typo

ANOTHER typo

update tests

fixed regexs

resolving test failures

resolving test failures

tidy up

test tidy up

refined regexs, output formatting, and tests

further refined regexs

typo in comments

whitespace

comment
This commit is contained in:
David Alexander 2016-01-23 14:42:42 +13:00
parent bad24d82b5
commit 26c66f494b
3 changed files with 74 additions and 48 deletions

View File

@ -12,11 +12,6 @@ class DocumentationParser
const CODE_BLOCK_BACKTICK = 1;
const CODE_BLOCK_COLON = 2;
/**
* @var string Format string for api urls. See rewrite_api_links().
*/
public static $api_link_base = 'http://api.silverstripe.org/search/lookup/?q=%s&version=%s&module=%s';
/**
* @var array
*/
@ -299,49 +294,73 @@ class DocumentationParser
* (6) [Title](api:DataObject->populateDefaults()) gets re-written to
* <a href="https://api.silverstripe.org/search/lookup/?q=DataObject::populateDefaults()&version=2.4&module=framework">Title</a>
*
* The markdown parser gets confused by the extra pair of parentheses in links of the form [DataObject](api:DataObject->populateDefaults()) so
* The above api links can be enclosed in backticks.
*
* The markdown parser gets confused by the extra pair of parentheses in links of the form [DataObject](api:DataObject->populateDefaults()) so
* all links are re-written as html markup instead of markdown [Title](url). This also prevents other markdown parsing problems.
*
* @param String $md
* @param DocumentationPage $page
* @return String
*/
public static function rewrite_api_links($md, $page)
public static function rewrite_api_links($markdown, $doc_page)
{
$version = $doc_page->getVersion();
$module = $doc_page->getEntity()->getKey();
// define regexs of the api links to be parsed (note: do not include backticks)
$regexs = array(
'title_and_method' => '\[(.*?)\]\(api:(.*?\(\))\)', // title_and_method handles case (6) and must precede title_remaining
'title_remaining' => '\[(.*?)\]\(api:(.*?)\)', // title_and_remaining handles cases (4) and (5)
'no_title' => '\[api:(.*?)\]' // no_title handles cases (1),(2) and (3)
'title_and_method' => '# \[ ([^\]]*) \] \( api: ([^\)]*\(\)) \) #x', // title_and_method = (6) (must be first)
'title_remaining' => '# \[ ([^\]]*) \] \( api: ([^\)]*) \) #x', // title_and_remaining = (4) and (5)
'no_title' => '# \[ api: ([^\]]*) \] #x' // no_title = (1),(2) and (3)
);
foreach($regexs as $regex_type => $regex) {
$link_regex = '/ `? '. $regex . ' `? /x';
preg_match_all($link_regex, $md, $links);
// define output format for parsing api links without backticks into html
$html_format = '<a href="http://api.silverstripe.org/search/lookup/?q=%s&version=%s&module=%s">%s</a>';
// parse api links without backticks into html
foreach($regexs as $type => $regex) {
preg_match_all($regex, $markdown, $links);
if($links) {
foreach($links[0] as $i => $match) {
if( $regex_type === 'no_title' ){
if($type === 'no_title'){
$title = $links[1][$i];
$link = $links[1][$i];
// change backticked links to avoid being parsed in the same way as non-backticked links
$markdown = str_replace('`'.$match.'`','SS'.$link.'SS',$markdown);
} else {
$title = $links[1][$i];
$link = $links[2][$i];
// change backticked links to avoid being parsed in the same way as non-backticked links
$markdown = str_replace('`'.$match.'`','XX'.$title.'YY'.$link.'ZZ',$markdown);
}
$url = sprintf(
self::$api_link_base,
$link,
$page->getVersion(),
$page->getEntity()->getKey()
);
$md = str_replace(
$match,
sprintf('<a href="%s">%s</a>', $url, $title),
$md
);
$html = sprintf($html_format, $link, $version, $module, $title);
$markdown = str_replace($match,$html,$markdown);
}
}
}
}
return $md;
// recover backticked links with no titles
preg_match_all('#SS(.*)?SS#', $markdown, $links);
if($links) {
foreach($links[0] as $i => $match) {
$link = $links[1][$i];
$markdown = str_replace($match,'`[api:'.$link.']`',$markdown);
}
}
// recover backticked links with titles
preg_match_all('#XX(.*)?YY(.*)?ZZ#', $markdown, $links);
if($links) {
foreach($links[0] as $i => $match) {
$title = $links[1][$i];
$link = $links[2][$i];
$markdown = str_replace($match,'`['.$title.'](api:'.$link.')`',$markdown);
}
}
return $markdown;
}

View File

@ -196,12 +196,7 @@ HTML;
'[link: http](http://silverstripe.org)',
$result
);
$this->assertContains(
'[link: api](api:DataObject)',
$result
);
$result = DocumentationParser::rewrite_relative_links(
$this->subPage->getMarkdown(),
$this->subPage
@ -325,21 +320,28 @@ HTML;
$page_version = $this->page->getVersion();
// expected url format resulting from rewriting api shortcode links
$url_format = '<a href="http://api.silverstripe.org/search/lookup/?q=%s&version='.$page_version.'&module=documentationparsertest">%s</a>';
$html_format = '<a href="http://api.silverstripe.org/search/lookup/?q=%s&version='.$page_version.'&module=documentationparsertest">%s</a>';
// test cases: api shortcode references and the expected urls resulting from rewriting them
// test cases: non-backtick enclosed api links and the expected html resulting from rewriting them
// note that api links enclosed in backticks are left unchanged
$test_cases = array(
array('[api:DataObject]', sprintf($url_format,'DataObject','DataObject')),
array('[api:DataObject::$defaults]',sprintf($url_format,'DataObject::$defaults','DataObject::$defaults')),
array('[api:DataObject::populateDefaults()]',sprintf($url_format,'DataObject::populateDefaults()','DataObject::populateDefaults()')),
array('[Title](api:DataObject)',sprintf($url_format,'DataObject','Title')),
array('[Title](api:DataObject::$defaults)',sprintf($url_format,'DataObject::$defaults','Title')),
array('[Title](api:DataObject::populateDefaults())',sprintf($url_format,'DataObject::populateDefaults()','Title'))
array('`[api:DataObject]`','`[api:DataObject]`'),
array('`[api:DataObject::$defaults]`','`[api:DataObject::$defaults]`'),
array('`[api:DataObject::populateDefaults()]`','`[api:DataObject::populateDefaults()]`'),
array('`[Title](api:DataObject)`','`[Title](api:DataObject)`'),
array('`[Title](api:DataObject::$defaults)`','`[Title](api:DataObject::$defaults)`'),
array('`[Title](api:DataObject::populateDefaults())`','`[Title](api:DataObject::populateDefaults())`'),
array('[api:DataObject]', sprintf($html_format,'DataObject','DataObject')),
array('[api:DataObject::$defaults]',sprintf($html_format,'DataObject::$defaults','DataObject::$defaults')),
array('[api:DataObject::populateDefaults()]',sprintf($html_format,'DataObject::populateDefaults()','DataObject::populateDefaults()')),
array('[Title](api:DataObject)',sprintf($html_format,'DataObject','Title')),
array('[Title](api:DataObject::$defaults)',sprintf($html_format,'DataObject::$defaults','Title')),
array('[Title](api:DataObject::populateDefaults())',sprintf($html_format,'DataObject::populateDefaults()','Title'))
);
foreach($test_cases as $test_case) {
$expected_api_url = $test_case[1];
$this->assertContains($expected_api_url,$parsed_page);
$expected_html = $test_case[1];
$this->assertContains($expected_html,$parsed_page);
}
}

View File

@ -8,14 +8,19 @@ test
[link: subfolder page](subfolder/subpage)
[link: with anchor](/test#anchor)
[link: http](http://silverstripe.org)
[link: api](api:DataObject)
[api:DataObject]
[api:DataObject::$defaults]
[api:DataObject::populateDefaults()]
`[Title](api:DataObject)`
`[Title](api:DataObject::$defaults)`
`[Title](api:DataObject::populateDefaults())`
`[api:DataObject]`
`[api:DataObject::$defaults]`
`[api:DataObject::populateDefaults()]`
[Title](api:DataObject)
[Title](api:DataObject::$defaults)
[Title](api:DataObject::populateDefaults())
[api:DataObject]
[api:DataObject::$defaults]
[api:DataObject::populateDefaults()]
:::php
code block