diff --git a/code/DocumentationParser.php b/code/DocumentationParser.php index 46d807d..1a76dc4 100755 --- a/code/DocumentationParser.php +++ b/code/DocumentationParser.php @@ -1,24 +1,32 @@ $line) { if(!$started && preg_match('/^\t*:::\s*(.*)/', $line, $matches)) { // first line with custom formatting $started = true; - $lines[$i] = sprintf('
', $matches[1]);
-			} elseif(preg_match('/^\t(.*)/', $line, $matches)) {
-				// inner line of ::: block, or first line of standard markdown code block
+				$mode = self::CODE_BLOCK_COLON;
+				$output[$i] = sprintf('
', (isset($matches[1])) ? $matches[1] : "");
+			} 
+			elseif(!$started && preg_match('/^\t*```\s*(.*)/', $line, $matches)) {
+				$started = true;
+				$mode = self::CODE_BLOCK_BACKTICK;
+				$output[$i] = sprintf('
', (isset($matches[1])) ? $matches[1] : "");
+			} 
+			elseif($started && $mode == self::CODE_BLOCK_BACKTICK) {
+				// inside a backtick fenced box
+				if(preg_match('/^\t*```\s*/', $line, $matches)) {
+					// end of the backtick fenced box. Unset the line that contains the backticks
+					$end = true;
+				}
+				else {
+					// still inside the line.
+					$output[$i] = ($started) ? '' : '
' . "\n";
+					$output[$i] .= htmlentities($line, ENT_COMPAT, 'UTF-8');
+					$inner = true;
+				}
+			} 
+			elseif(preg_match('/^\t(.*)/', $line, $matches)) {
+				// inner line of block, or first line of standard markdown code block
 				// regex removes first tab (any following tabs are part of the code).
-				$lines[$i] = ($started) ? '' : '
' . "\n";
-				$lines[$i] .= htmlentities($matches[1], ENT_COMPAT, 'UTF-8');
+				$output[$i] = ($started) ? '' : '
' . "\n";
+				$output[$i] .= htmlentities($matches[1], ENT_COMPAT, 'UTF-8');
 				$inner = true;
 				$started = true;
-			} elseif($started && $inner) {
-				// remove any previous blank lines
-				$j = $i-1;
-				while(isset($lines[$j]) && preg_match('/^[\t\s]*$/', $lines[$j])) {
-					unset($lines[$j]);
-					$j--;
-				}
-				
-				// last line, close pre
-				$lines[$i] = '
' . "\n\n" . $line; - + } + elseif($started && $inner && $mode == self::CODE_BLOCK_COLON && trim($line) === "") { + // still inside a colon based block, if the line is only whitespace + // then continue with with it. We can continue with it for now as + // it'll be tidied up later in the $end section. + $inner = true; + $output[$i] = $line; + } + elseif($started && $inner) { + // line contains something other than whitespace, or tabbed. E.g + // > code + // > \n + // > some message + // + // So actually want to reset $i to the line before this new line + // and include this line. The edge case where this will fail is + // new the following segment contains a code block as well as it + // will not open. + $end = true; + $output[$i] = $line; + $i = $i -1; + } + else { + $output[$i] = $line; + } + + if($end) { + $output = self::finalize_code_output($i, $output); + // reset state - $started = $inner = false; + $started = $inner = $mode = $end = false; } } - - return join("\n", $lines); + if($started) { + $output = self::finalize_code_output($i, $output); + } + + return join("\n", $output); + + } + + /** + * @param int + * @param array + * + * @return array + */ + private static function finalize_code_output($i, $output) { + $j = $i; + + while(isset($output[$j]) && trim($output[$j]) === "") { + unset($output[$j]); + + $j--; + } + + if(isset($output[$j])) { + $output[$j] .= "
\n"; + } + + else { + $output[$j] = "
\n\n"; + } + + return $output; } static function rewrite_image_links($md, $page) { diff --git a/docs/en/Syntax-Highlighting.md b/docs/en/Syntax-Highlighting.md index 5d361f3..58c097a 100644 --- a/docs/en/Syntax-Highlighting.md +++ b/docs/en/Syntax-Highlighting.md @@ -3,41 +3,36 @@ The custom Markdown parser can render custom prefixes for code blocks, and render it via a [javascript syntax highlighter](http://alexgorbatchev.com/SyntaxHighlighter). -In: +To see examples of the syntax, check out the source of this file in docs/en/ - :::php - my sourcecode - -Out: - -
-	my sourcecode
-	
- To include the syntax highlighter source, add the following to your `DocumentationViewer->init()`: - Requirements::javascript(THIRDPARTY_DIR .'/jquery/jquery.js'); - Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shCore.js'); - Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushJScript.js'); - Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushPHP.js'); - Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushXML.js'); - // ... any additional syntaxes you want to support - Requirements::combine_files( - 'syntaxhighlighter.js', - array( - 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shCore.js', - 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushJScript.js', - 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushPHP.js', - 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushXML.js' - ) - ); - - Requirements::javascript('sapphiredocs/javascript/DocumentationViewer.js'); - // css - Requirements::css('sapphiredocs/thirdparty/syntaxhighlighter/styles/shCore.css'); - Requirements::css('sapphiredocs/thirdparty/syntaxhighlighter/styles/shCoreDefault.css'); - Requirements::css('sapphiredocs/thirdparty/syntaxhighlighter/styles/shThemeRDark.css'); - +```php + +Requirements::javascript(THIRDPARTY_DIR .'/jquery/jquery.js'); +Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shCore.js'); +Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushJScript.js'); +Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushPHP.js'); +Requirements::javascript('sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushXML.js'); +// ... any additional syntaxes you want to support +Requirements::combine_files( + 'syntaxhighlighter.js', + array( + 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shCore.js', + 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushJScript.js', + 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushPHP.js', + 'sapphiredocs/thirdparty/syntaxhighlighter/scripts/shBrushXML.js' + ) +); + +Requirements::javascript('sapphiredocs/javascript/DocumentationViewer.js'); + +// css +Requirements::css('sapphiredocs/thirdparty/syntaxhighlighter/styles/shCore.css'); +Requirements::css('sapphiredocs/thirdparty/syntaxhighlighter/styles/shCoreDefault.css'); +Requirements::css('sapphiredocs/thirdparty/syntaxhighlighter/styles/shThemeRDark.css'); +``` + You can overload the `DocumentationViewer` class and add a custom route through `Director::addRule()` if you prefer not to modify the module file. diff --git a/lang/en.yml b/lang/en.yml new file mode 100644 index 0000000..da293ab --- /dev/null +++ b/lang/en.yml @@ -0,0 +1,19 @@ +en: + DocumentationSearch: + SEARCH: Search + SEARCHRESULTS: 'Search Results' + DocumentationViewer: + CHANGE: Change + KEYWORDS: Keywords + LANGUAGE: Language + MODULES: Modules + OPENSEARCHDESC: 'Search the documentation' + OPENSEARCHNAME: 'Documentation Search' + OPENSEARCHTAGS: documentation + SEARCH: Search + VERSIONS: Versions + DocumentationViewer_home.ss: + DOCUMENTEDMODULES: 'Documented Modules' + NOMODULEDOCUMENTATION: 'No modules with documentation installed could be found.' + DocumentationViewer_results.ss: + ADVANCEDSEARCH: 'Advanced Search' diff --git a/tests/DocumentationParserTest.php b/tests/DocumentationParserTest.php index 7897032..b68920e 100755 --- a/tests/DocumentationParserTest.php +++ b/tests/DocumentationParserTest.php @@ -26,21 +26,40 @@ code block with multiple lines and tab indent - and escaped < brackets -
+ and escaped < brackets
Normal text after code block HTML; + $this->assertContains($expected, $result, 'Custom code blocks with ::: prefix'); $expected = << code block -without formatting prefix -
+without formatting prefix HTML; $this->assertContains($expected, $result, 'Traditional markdown code blocks'); + + $expected = << +Fenced code block + +HTML; + $this->assertContains($expected, $result, 'Backtick code blocks'); + + $expected = << +Fenced box with + +new lines in + +between + +content + +HTML; + $this->assertContains($expected, $result, 'Backtick with newlines'); } function testImageRewrites() { diff --git a/tests/docs/en/test.md b/tests/docs/en/test.md index df723d0..69c6439 100755 --- a/tests/docs/en/test.md +++ b/tests/docs/en/test.md @@ -24,7 +24,23 @@ Normal text after code block code block without formatting prefix - + +``` +Fenced code block +``` + +Did the fence work? + +```php +Fenced box with + +new lines in + +between + +content +``` + # Heading one # Heading with custom anchor {#custom-anchor}