Finalization of fenced code block improvements by Mario Konrad:

- Moving `code_block_content_func` configuration variable to regular Markdown parser, now using it to convert the content of indented code blocks to HTML too.
- Fix for code block class name and special attribute blocks together.
- Updated the fenced code block syntax in the HTML block parser (so it correctly skips those code blocks).
- Updated Readme.md to explain the changes.
This commit is contained in:
Michel Fortin 2015-08-04 17:05:44 -04:00
parent 3ace64bc13
commit c9220d1bb3
3 changed files with 32 additions and 17 deletions

View file

@ -64,6 +64,9 @@ class Markdown implements MarkdownInterface {
# Optional header id="" generation callback function.
public $header_id_func = null;
# Optional function for converting code block content to HTML
public $code_block_content_func = null;
# Class attribute to toggle "enhanced ordered list" behaviour
# setting this to true will allow ordered lists to start from the index
@ -1024,7 +1027,11 @@ class Markdown implements MarkdownInterface {
$codeblock = $matches[1];
$codeblock = $this->outdent($codeblock);
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
if ($this->code_block_content_func) {
$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
} else {
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
}
# trim leading newlines and trailing newlines
$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);

View file

@ -42,9 +42,6 @@ class MarkdownExtra extends \Michelf\Markdown {
# Class attribute for code blocks goes on the `code` tag;
# setting this to true will put attributes on the `pre` tag instead.
public $code_attr_on_pre = false;
# Optional content function for code blocks
public $code_block_content_func = null;
# Predefined abbreviations.
public $predef_abbr = array();
@ -138,7 +135,7 @@ class MarkdownExtra extends \Michelf\Markdown {
# Expression to use when parsing in a context when no capture is desired
protected $id_class_attr_nocatch_re = '\{(?:[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}';
protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null) {
protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) {
#
# Parse attributes caught by the $this->id_class_attr_catch_re expression
# and return the HTML-formatted list of attributes.
@ -148,14 +145,13 @@ class MarkdownExtra extends \Michelf\Markdown {
# In addition, this method also supports supplying a default Id value,
# which will be used to populate the id attribute in case it was not
# overridden.
if (empty($attr) && !$defaultIdValue) return "";
if (empty($attr) && !$defaultIdValue && empty($classes)) return "";
# Split on components
preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches);
$elements = $matches[0];
# handle classes and ids (only first id taken into account)
$classes = array();
$attributes = array();
$id = false;
foreach ($elements as $element) {
@ -352,12 +348,10 @@ class MarkdownExtra extends \Michelf\Markdown {
# Fenced code block marker
(?<= ^ | \n )
[ ]{0,'.($indent+3).'}(?:~{3,}|`{3,})
[ ]*
(?:
\.?[-_:a-zA-Z0-9]+ # standalone class name
|
'.$this->id_class_attr_nocatch_re.' # extra attributes
)?
[ ]*
(?: \.?[-_:a-zA-Z0-9]+ )? # standalone class name
[ ]*
(?: '.$this->id_class_attr_nocatch_re.' )? # extra attributes
[ ]*
(?= \n )
' : '' ). ' # End (if not is span).
@ -413,7 +407,7 @@ class MarkdownExtra extends \Michelf\Markdown {
# Note: need to recheck the whole tag to disambiguate backtick
# fences from code spans
#
if (preg_match('{^\n?([ ]{0,'.($indent+3).'})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+|'.$this->id_class_attr_nocatch_re.')?[ ]*\n?$}', $tag, $capture)) {
if (preg_match('{^\n?([ ]{0,'.($indent+3).'})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:'.$this->id_class_attr_nocatch_re.')?[ ]*\n?$}', $tag, $capture)) {
# Fenced code block marker: find matching end marker.
$fence_indent = strlen($capture[1]); # use captured indent in re
$fence_re = $capture[2]; # use captured fence in re
@ -1333,13 +1327,13 @@ class MarkdownExtra extends \Michelf\Markdown {
$codeblock = preg_replace_callback('/^\n+/',
array($this, '_doFencedCodeBlocks_newlines'), $codeblock);
$classes = array();
if ($classname != "") {
if ($classname{0} == '.')
$classname = substr($classname, 1);
$attr_str = ' class="'.$this->code_class_prefix.$classname.'"';
} else {
$attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs);
$classes[] = $this->code_class_prefix.$classname;
}
$attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes);
$pre_attr_str = $this->code_attr_on_pre ? $attr_str : '';
$code_attr_str = $this->code_attr_on_pre ? '' : $attr_str;
$codeblock = "<pre$pre_attr_str><code$code_attr_str>$codeblock</code></pre>";

View file

@ -174,6 +174,20 @@ PHP Markdown, please visit [michelf.ca/donate] or send Bitcoin to
Version History
---------------
Current Version
* For fenced code blocks in Markdown Extra, can now set a class name for the
code block's language before the special attribute block. Previously, this
class name was only allowed in the absence of the special attribute block.
* Added a `code_block_content_func` configuration variable which takes a
function that will convert the content of the code block to HTML. This is
most useful for syntax highlighting. For fenced code blocks in Markdown
Extra, the function has access to the language class name (the one outside
of the special attribute block). Credits to Mario Konrad for providing the
implementation.
PHP Markdown Lib 1.5.0 (1 Mar 2015)
* Added the ability start ordered lists with a number different from 1 and