From 26c66f494b0dc683af385e866ee3c04f0e968d7c Mon Sep 17 00:00:00 2001 From: David Alexander Date: Sat, 23 Jan 2016 14:42:42 +1300 Subject: [PATCH] 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 --- code/DocumentationParser.php | 77 +++++++++++++++++++------------ tests/DocumentationParserTest.php | 32 +++++++------ tests/docs/en/test.md | 13 ++++-- 3 files changed, 74 insertions(+), 48 deletions(-) diff --git a/code/DocumentationParser.php b/code/DocumentationParser.php index 7cb77e2..c4f2d04 100755 --- a/code/DocumentationParser.php +++ b/code/DocumentationParser.php @@ -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 * Title * - * 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 = '%s'; + + // 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('%s', $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; } diff --git a/tests/DocumentationParserTest.php b/tests/DocumentationParserTest.php index 651cd53..83e6e1e 100755 --- a/tests/DocumentationParserTest.php +++ b/tests/DocumentationParserTest.php @@ -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 = '%s'; + $html_format = '%s'; - // 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); } } diff --git a/tests/docs/en/test.md b/tests/docs/en/test.md index e5f56fb..082763e 100755 --- a/tests/docs/en/test.md +++ b/tests/docs/en/test.md @@ -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