# Markdown - A text-to-HTML conversion tool for web writers
#
# PHP Markdown
-# Copyright (c) 2004-2013 Michel Fortin
+# Copyright (c) 2004-2014 Michel Fortin
# <http://michelf.com/projects/php-markdown/>
#
# Original Markdown
### Version ###
- const MARKDOWNLIB_VERSION = "1.4.0";
+ const MARKDOWNLIB_VERSION = "1.4.1";
### Simple Function Interface ###
public $predef_urls = array();
public $predef_titles = array();
+ # Optional filter function for URLs
+ public $url_filter_func = null;
+
### Parser Implementation ###
)? # title is optional
(?:\n+|\Z)
}xm',
- array(&$this, '_stripLinkDefinitions_callback'),
+ array($this, '_stripLinkDefinitions_callback'),
$text);
return $text;
}
#
$block_tags_a_re = 'ins|del';
$block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
- 'script|noscript|form|fieldset|iframe|math|svg|'.
+ 'script|noscript|style|form|fieldset|iframe|math|svg|'.
'article|section|nav|aside|hgroup|header|footer|'.
'figure';
# match will start at the first `<div>` and stop at the first `</div>`.
$text = preg_replace_callback('{(?>
(?>
- (?<=\n\n) # Starting after a blank line
+ (?<=\n) # Starting on its own line
| # or
- \A\n? # the beginning of the doc
+ \A\n? # the at beginning of the doc
)
( # save in $1
)
)}Sxmi',
- array(&$this, '_hashHTMLBlocks_callback'),
+ array($this, '_hashHTMLBlocks_callback'),
$text);
return $text;
protected function doHardBreaks($text) {
# Do hard breaks:
return preg_replace_callback('/ {2,}\n/',
- array(&$this, '_doHardBreaks_callback'), $text);
+ array($this, '_doHardBreaks_callback'), $text);
}
protected function _doHardBreaks_callback($matches) {
return $this->hashPart("<br$this->empty_element_suffix\n");
\]
)
}xs',
- array(&$this, '_doAnchors_reference_callback'), $text);
+ array($this, '_doAnchors_reference_callback'), $text);
#
# Next, inline-style links: [link text](url "optional title")
\)
)
}xs',
- array(&$this, '_doAnchors_inline_callback'), $text);
+ array($this, '_doAnchors_inline_callback'), $text);
#
# Last, handle reference-style shortcuts: [link text]
\]
)
}xs',
- array(&$this, '_doAnchors_reference_callback'), $text);
+ array($this, '_doAnchors_reference_callback'), $text);
$this->in_anchor = false;
return $text;
if (isset($this->urls[$link_id])) {
$url = $this->urls[$link_id];
- $url = $this->encodeAttribute($url);
+ $url = $this->encodeURLAttribute($url);
$result = "<a href=\"$url\"";
if ( isset( $this->titles[$link_id] ) ) {
$url = $matches[3] == '' ? $matches[4] : $matches[3];
$title =& $matches[7];
- $url = $this->encodeAttribute($url);
+ // if the URL was of the form <s p a c e s> it got caught by the HTML
+ // tag parser and hashed. Need to reverse the process before using the URL.
+ $unhashed = $this->unhash($url);
+ if ($unhashed != $url)
+ $url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
+
+ $url = $this->encodeURLAttribute($url);
$result = "<a href=\"$url\"";
if (isset($title)) {
)
}xs',
- array(&$this, '_doImages_reference_callback'), $text);
+ array($this, '_doImages_reference_callback'), $text);
#
# Next, handle inline images: ![alt text](url "optional title")
\)
)
}xs',
- array(&$this, '_doImages_inline_callback'), $text);
+ array($this, '_doImages_inline_callback'), $text);
return $text;
}
$alt_text = $this->encodeAttribute($alt_text);
if (isset($this->urls[$link_id])) {
- $url = $this->encodeAttribute($this->urls[$link_id]);
+ $url = $this->encodeURLAttribute($this->urls[$link_id]);
$result = "<img src=\"$url\" alt=\"$alt_text\"";
if (isset($this->titles[$link_id])) {
$title = $this->titles[$link_id];
$title =& $matches[7];
$alt_text = $this->encodeAttribute($alt_text);
- $url = $this->encodeAttribute($url);
+ $url = $this->encodeURLAttribute($url);
$result = "<img src=\"$url\" alt=\"$alt_text\"";
if (isset($title)) {
$title = $this->encodeAttribute($title);
# --------
#
$text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
- array(&$this, '_doHeaders_callback_setext'), $text);
+ array($this, '_doHeaders_callback_setext'), $text);
# atx-style headers:
# # Header 1
\#* # optional closing #\'s (not counted)
\n+
}xm',
- array(&$this, '_doHeaders_callback_atx'), $text);
+ array($this, '_doHeaders_callback_atx'), $text);
return $text;
}
# Re-usable patterns to match list item bullets and number markers:
$marker_ul_re = '[*+-]';
$marker_ol_re = '\d+[\.]';
- $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
$markers_relist = array(
$marker_ul_re => $marker_ol_re,
^
'.$whole_list_re.'
}mx',
- array(&$this, '_doLists_callback'), $text);
+ array($this, '_doLists_callback'), $text);
}
else {
$text = preg_replace_callback('{
(?:(?<=\n)\n|\A\n?) # Must eat the newline
'.$whole_list_re.'
}mx',
- array(&$this, '_doLists_callback'), $text);
+ array($this, '_doLists_callback'), $text);
}
}
(?:(\n+(?=\n))|\n) # tailing blank line = $5
(?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
}xm',
- array(&$this, '_processListItems_callback'), $list_str);
+ array($this, '_processListItems_callback'), $list_str);
$this->list_level--;
return $list_str;
)
((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
}xm',
- array(&$this, '_doCodeBlocks_callback'), $text);
+ array($this, '_doCodeBlocks_callback'), $text);
return $text;
}
protected $em_relist = array(
- '' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![\.,:;]\s)',
- '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
- '_' => '(?<=\S|^)(?<!_)_(?!_)',
+ '' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?![\.,:;]?\s)',
+ '*' => '(?<![\s*])\*(?!\*)',
+ '_' => '(?<![\s_])_(?!_)',
);
protected $strong_relist = array(
- '' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![\.,:;]\s)',
- '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
- '__' => '(?<=\S|^)(?<!_)__(?!_)',
+ '' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?![\.,:;]?\s)',
+ '**' => '(?<![\s*])\*\*(?!\*)',
+ '__' => '(?<![\s_])__(?!_)',
);
protected $em_strong_relist = array(
- '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![\.,:;]\s)',
- '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
- '___' => '(?<=\S|^)(?<!_)___(?!_)',
+ '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?![\.,:;]?\s)',
+ '***' => '(?<![\s*])\*\*\*(?!\*)',
+ '___' => '(?<![\s_])___(?!_)',
);
protected $em_strong_prepared_relist;
)+
)
/xm',
- array(&$this, '_doBlockQuotes_callback'), $text);
+ array($this, '_doBlockQuotes_callback'), $text);
return $text;
}
# These leading spaces cause problem with <pre> content,
# so we need to fix that:
$bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
- array(&$this, '_doBlockQuotes_callback2'), $bq);
+ array($this, '_doBlockQuotes_callback2'), $bq);
return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
}
$text = str_replace('"', '"', $text);
return $text;
}
+
+
+ protected function encodeURLAttribute($url, &$text = null) {
+ #
+ # Encode text for a double-quoted HTML attribute containing a URL,
+ # applying the URL filter if set. Also generates the textual
+ # representation for the URL (removing mailto: or tel:) storing it in $text.
+ # This function is *not* suitable for attributes enclosed in single quotes.
+ #
+ if ($this->url_filter_func)
+ $url = call_user_func($this->url_filter_func, $url);
+
+ if (preg_match('{^mailto:}i', $url))
+ $url = $this->encodeEntityObfuscatedAttribute($url, $text, 7);
+ else if (preg_match('{^tel:}i', $url))
+ {
+ $url = $this->encodeAttribute($url);
+ $text = substr($url, 4);
+ }
+ else
+ {
+ $url = $this->encodeAttribute($url);
+ $text = $url;
+ }
+
+ return $url;
+ }
protected function encodeAmpsAndAngles($text) {
protected function doAutoLinks($text) {
- $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
- array(&$this, '_doAutoLinks_url_callback'), $text);
+ $text = preg_replace_callback('{<((https?|ftp|dict|tel):[^\'">\s]+)>}i',
+ array($this, '_doAutoLinks_url_callback'), $text);
# Email addresses: <address@domain.foo>
$text = preg_replace_callback('{
)
>
}xi',
- array(&$this, '_doAutoLinks_email_callback'), $text);
- $text = preg_replace_callback('{<(tel:([^\'">\s]+))>}i',array(&$this, '_doAutoLinks_tel_callback'), $text);
+ array($this, '_doAutoLinks_email_callback'), $text);
return $text;
}
- protected function _doAutoLinks_tel_callback($matches) {
- $url = $this->encodeAttribute($matches[1]);
- $tel = $this->encodeAttribute($matches[2]);
- $link = "<a href=\"$url\">$tel</a>";
- return $this->hashPart($link);
- }
protected function _doAutoLinks_url_callback($matches) {
- $url = $this->encodeAttribute($matches[1]);
- $link = "<a href=\"$url\">$url</a>";
+ $url = $this->encodeURLAttribute($matches[1], $text);
+ $link = "<a href=\"$url\">$text</a>";
return $this->hashPart($link);
}
protected function _doAutoLinks_email_callback($matches) {
- $address = $matches[1];
- $link = $this->encodeEmailAddress($address);
+ $addr = $matches[1];
+ $url = $this->encodeURLAttribute("mailto:$addr", $text);
+ $link = "<a href=\"$url\">$text</a>";
return $this->hashPart($link);
}
- protected function encodeEmailAddress($addr) {
+ protected function encodeEntityObfuscatedAttribute($text, &$tail = null, $head_length = 0) {
#
- # Input: an email address, e.g. "foo@example.com"
+ # Input: some text to obfuscate, e.g. "mailto:foo@example.com"
#
- # Output: the email address as a mailto link, with each character
- # of the address encoded as either a decimal or hex entity, in
- # the hopes of foiling most address harvesting spam bots. E.g.:
+ # Output: the same text but with most characters encoded as either a
+ # decimal or hex entity, in the hopes of foiling most address
+ # harvesting spam bots. E.g.:
#
- # <p><a href="mailto:foo
+ # mailto:foo
# @example.co
- # m">foo@exampl
- # e.com</a></p>
+ # m
+ #
+ # Note: the additional output $tail is assigned the same value as the
+ # ouput, minus the number of characters specified by $head_length.
#
# Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
- # With some optimizations by Milian Wolff.
+ # With some optimizations by Milian Wolff. Forced encoding of HTML
+ # attribute special characters by Allan Odgaard.
#
- $addr = "mailto:" . $addr;
- $chars = preg_split('/(?<!^)(?!$)/', $addr);
- $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
-
+ if ($text == "") return $tail = "";
+
+ $chars = preg_split('/(?<!^)(?!$)/', $text);
+ $seed = (int)abs(crc32($text) / strlen($text)); # Deterministic seed.
+
foreach ($chars as $key => $char) {
$ord = ord($char);
# Ignore non-ascii chars.
$r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
# roughly 10% raw, 45% hex, 45% dec
# '@' *must* be encoded. I insist.
- if ($r > 90 && $char != '@') /* do nothing */;
+ # '"' and '>' have to be encoded inside the attribute
+ if ($r > 90 && strpos('@"&>', $char) === false) /* do nothing */;
else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
else $chars[$key] = '&#'.$ord.';';
}
}
-
- $addr = implode('', $chars);
- $text = implode('', array_slice($chars, 7)); # text without `mailto:`
- $addr = "<a href=\"$addr\">$text</a>";
- return $addr;
+ $text = implode('', $chars);
+ $tail = $head_length ? implode('', array_slice($chars, $head_length)) : $text;
+
+ return $text;
}
# appropriate number of space between each blocks.
$text = preg_replace_callback('/^.*\t.*$/m',
- array(&$this, '_detab_callback'), $text);
+ array($this, '_detab_callback'), $text);
return $text;
}
# Swap back in all the tags hashed by _HashHTMLBlocks.
#
return preg_replace_callback('/(.)\x1A[0-9]+\1/',
- array(&$this, '_unhash_callback'), $text);
+ array($this, '_unhash_callback'), $text);
}
protected function _unhash_callback($matches) {
return $this->html_hashes[$matches[0]];
### Extra Attribute Parser ###
# Expression to use to catch attributes (includes the braces)
- protected $id_class_attr_catch_re = '\{((?:[ ]*[#.][-_:a-zA-Z0-9]+){1,})[ ]*\}';
+ protected $id_class_attr_catch_re = '\{((?:[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}';
# Expression to use when parsing in a context when no capture is desired
- protected $id_class_attr_nocatch_re = '\{(?:[ ]*[#.][-_:a-zA-Z0-9]+){1,}[ ]*\}';
+ protected $id_class_attr_nocatch_re = '\{(?:[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}';
protected function doExtraAttributes($tag_name, $attr) {
#
if (empty($attr)) return "";
# Split on components
- preg_match_all('/[#.][-_:a-zA-Z0-9]+/', $attr, $matches);
+ 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) {
if ($element{0} == '.') {
$classes[] = substr($element, 1);
} else if ($element{0} == '#') {
if ($id === false) $id = substr($element, 1);
+ } else if (strpos($element, '=') > 0) {
+ $parts = explode('=', $element, 2);
+ $attributes[] = $parts[0] . '="' . $parts[1] . '"';
}
}
if (!empty($classes)) {
$attr_str .= ' class="'.implode(" ", $classes).'"';
}
+ if (!$this->no_markup && !empty($attributes)) {
+ $attr_str .= ' '.implode(" ", $attributes);
+ }
return $attr_str;
}
(?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr
(?:\n+|\Z)
}xm',
- array(&$this, '_stripLinkDefinitions_callback'),
+ array($this, '_stripLinkDefinitions_callback'),
$text);
return $text;
}
### HTML Block Parser ###
# Tags that are always treated as block tags:
- protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption';
+ protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure';
# Tags treated as block tags only if the opening tag is alone on its line:
- protected $context_block_tags_re = 'script|noscript|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video';
+ protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video';
# Tags where markdown="1" default to span mode:
protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
# Tags which must not have their contents modified, no matter where
# they appear:
- protected $clean_tags_re = 'script|math|svg';
+ protected $clean_tags_re = 'script|style|math|svg';
# Tags that do not need to be closed.
protected $auto_close_tags_re = 'hr|img|param|source|track';
\]
)
}xs',
- array(&$this, '_doAnchors_reference_callback'), $text);
+ array($this, '_doAnchors_reference_callback'), $text);
#
# Next, inline-style links: [link text](url "optional title")
(?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes
)
}xs',
- array(&$this, '_doAnchors_inline_callback'), $text);
+ array($this, '_doAnchors_inline_callback'), $text);
#
# Last, handle reference-style shortcuts: [link text]
\]
)
}xs',
- array(&$this, '_doAnchors_reference_callback'), $text);
+ array($this, '_doAnchors_reference_callback'), $text);
$this->in_anchor = false;
return $text;
if (isset($this->urls[$link_id])) {
$url = $this->urls[$link_id];
- $url = $this->encodeAttribute($url);
+ $url = $this->encodeURLAttribute($url);
$result = "<a href=\"$url\"";
if ( isset( $this->titles[$link_id] ) ) {
$title =& $matches[7];
$attr = $this->doExtraAttributes("a", $dummy =& $matches[8]);
+ // if the URL was of the form <s p a c e s> it got caught by the HTML
+ // tag parser and hashed. Need to reverse the process before using the URL.
+ $unhashed = $this->unhash($url);
+ if ($unhashed != $url)
+ $url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
- $url = $this->encodeAttribute($url);
+ $url = $this->encodeURLAttribute($url);
$result = "<a href=\"$url\"";
if (isset($title)) {
)
}xs',
- array(&$this, '_doImages_reference_callback'), $text);
+ array($this, '_doImages_reference_callback'), $text);
#
# Next, handle inline images: ![alt text](url "optional title")
(?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes
)
}xs',
- array(&$this, '_doImages_inline_callback'), $text);
+ array($this, '_doImages_inline_callback'), $text);
return $text;
}
$alt_text = $this->encodeAttribute($alt_text);
if (isset($this->urls[$link_id])) {
- $url = $this->encodeAttribute($this->urls[$link_id]);
+ $url = $this->encodeURLAttribute($this->urls[$link_id]);
$result = "<img src=\"$url\" alt=\"$alt_text\"";
if (isset($this->titles[$link_id])) {
$title = $this->titles[$link_id];
$attr = $this->doExtraAttributes("img", $dummy =& $matches[8]);
$alt_text = $this->encodeAttribute($alt_text);
- $url = $this->encodeAttribute($url);
+ $url = $this->encodeURLAttribute($url);
$result = "<img src=\"$url\" alt=\"$alt_text\"";
if (isset($title)) {
$title = $this->encodeAttribute($title);
(?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes
[ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer
}mx',
- array(&$this, '_doHeaders_callback_setext'), $text);
+ array($this, '_doHeaders_callback_setext'), $text);
# atx-style headers:
# # Header 1 {#header1}
[ ]*
\n+
}xm',
- array(&$this, '_doHeaders_callback_atx'), $text);
+ array($this, '_doHeaders_callback_atx'), $text);
return $text;
}
)
(?=\n|\Z) # Stop at final double newline.
}xm',
- array(&$this, '_doTable_leadingPipe_callback'), $text);
+ array($this, '_doTable_leadingPipe_callback'), $text);
#
# Find tables without leading pipe.
)
(?=\n|\Z) # Stop at final double newline.
}xm',
- array(&$this, '_DoTable_callback'), $text);
+ array($this, '_DoTable_callback'), $text);
return $text;
}
(?>\A\n?|(?<=\n\n))
'.$whole_list_re.'
}mx',
- array(&$this, '_doDefLists_callback'), $text);
+ array($this, '_doDefLists_callback'), $text);
return $text;
}
(?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed
# with a definition mark.
}xm',
- array(&$this, '_processDefListItems_callback_dt'), $list_str);
+ array($this, '_processDefListItems_callback_dt'), $list_str);
# Process actual definitions.
$list_str = preg_replace_callback('{
)
)
}xm',
- array(&$this, '_processDefListItems_callback_dd'), $list_str);
+ array($this, '_processDefListItems_callback_dd'), $list_str);
return $list_str;
}
# Closing marker.
\1 [ ]* (?= \n )
}xm',
- array(&$this, '_doFencedCodeBlocks_callback'), $text);
+ array($this, '_doFencedCodeBlocks_callback'), $text);
return $text;
}
$codeblock = $matches[4];
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
$codeblock = preg_replace_callback('/^\n+/',
- array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock);
+ array($this, '_doFencedCodeBlocks_newlines'), $codeblock);
if ($classname != "") {
if ($classname{0} == '.')
# work in the middle of a word.
#
protected $em_relist = array(
- '' => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?=\S|$)(?![\.,:;]\s)',
- '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
- '_' => '(?<=\S|^)(?<!_)_(?![a-zA-Z0-9_])',
+ '' => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?![\.,:;]?\s)',
+ '*' => '(?<![\s*])\*(?!\*)',
+ '_' => '(?<![\s_])_(?![a-zA-Z0-9_])',
);
protected $strong_relist = array(
- '' => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?=\S|$)(?![\.,:;]\s)',
- '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
- '__' => '(?<=\S|^)(?<!_)__(?![a-zA-Z0-9_])',
+ '' => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?![\.,:;]?\s)',
+ '**' => '(?<![\s*])\*\*(?!\*)',
+ '__' => '(?<![\s_])__(?![a-zA-Z0-9_])',
);
protected $em_strong_relist = array(
- '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?=\S|$)(?![\.,:;]\s)',
- '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
- '___' => '(?<=\S|^)(?<!_)___(?![a-zA-Z0-9_])',
+ '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?![\.,:;]?\s)',
+ '***' => '(?<![\s*])\*\*\*(?!\*)',
+ '___' => '(?<![\s_])___(?![a-zA-Z0-9_])',
);
.+ # actual text
|
\n # newlines but
- (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
+ (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker.
(?!\n+[ ]{0,3}\S)# ensure line is not blank and followed
# by non-indented content
)*
)
}xm',
- array(&$this, '_stripFootnotes_callback'),
+ array($this, '_stripFootnotes_callback'),
$text);
return $text;
}
# Append footnote list to text.
#
$text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
- array(&$this, '_appendFootnotes_callback'), $text);
+ array($this, '_appendFootnotes_callback'), $text);
if (!empty($this->footnotes_ordered)) {
$text .= "\n\n";
$footnote .= "\n"; # Need to append newline before parsing.
$footnote = $this->runBlockGamut("$footnote\n");
$footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
- array(&$this, '_appendFootnotes_callback'), $footnote);
+ array($this, '_appendFootnotes_callback'), $footnote);
$attr = str_replace("%%", ++$num, $attr);
$note_id = $this->encodeAttribute($note_id);
^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1
(.*) # text = $2 (no blank lines allowed)
}xm',
- array(&$this, '_stripAbbreviations_callback'),
+ array($this, '_stripAbbreviations_callback'),
$text);
return $text;
}
'(?:'.$this->abbr_word_re.')'.
'(?![\w\x1A])'.
'}',
- array(&$this, '_doAbbreviations_callback'), $text);
+ array($this, '_doAbbreviations_callback'), $text);
}
return $text;
}