Completed
Pull Request — 2.x (#3830)
by Scott Kingsley
05:08 queued 01:06
created

Markdown_Parser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 0
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 31 and the first side effect is on line 39.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * ID: markdown-syntax
4
 *
5
 * Name: Markdown Syntax
6
 *
7
 * Description: Integration with Markdown (http://michelf.com/projects/php-markdown/); Adds an option to enable Markdown syntax for Paragraph text fields.
8
 *
9
 * Version: 1.0
10
 *
11
 * Category: Field Types
12
 *
13
 * @package Pods\Components
14
 * @subpackage Markdown
15
 */
16
17
if ( !function_exists( 'Markdown' ) ) :
18
#
19
# Markdown  -  A text-to-HTML conversion tool for web writers
20
#
21
# PHP Markdown
22
# Copyright (c) 2004-2013 Michel Fortin
23
# <http://michelf.ca/projects/php-markdown/>
24
#
25
# Original Markdown
26
# Copyright (c) 2004-2006 John Gruber
27
# <http://daringfireball.net/projects/markdown/>
28
#
29
30
31
define( 'MARKDOWN_VERSION',  "1.0.2" ); # 29 Nov 2013
32
33
34
#
35
# Global default settings:
36
#
37
38
# Change to ">" for HTML output
39
@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX',  " />");
40
41
# Define the width of a tab for code blocks.
42
@define( 'MARKDOWN_TAB_WIDTH',     4 );
43
44
45
#
46
# WordPress settings:
47
#
48
49
# Change to false to remove Markdown from posts and/or comments.
50
@define( 'MARKDOWN_WP_POSTS',      true );
51
@define( 'MARKDOWN_WP_COMMENTS',   true );
52
53
54
55
### Standard Function Interface ###
56
57
@define( 'MARKDOWN_PARSER_CLASS',  'Markdown_Parser' );
58
59
function Markdown($text) {
60
#
61
# Initialize the parser and return the result of its transform method.
62
#
63
	# Setup static parser variable.
64
	static $parser;
65
	if (!isset($parser)) {
66
		$parser_class = MARKDOWN_PARSER_CLASS;
67
		$parser = new $parser_class;
68
	}
69
70
	# Transform text using parser.
71
	return $parser->transform($text);
72
}
73
74
75
### WordPress Plugin Interface ###
76
77
if (isset($wp_version)) {
78
	# More details about how it works here:
79
	# <http://michelf.ca/weblog/2005/wordpress-text-flow-vs-markdown/>
80
81
	# Post content and excerpts
82
	# - Remove WordPress paragraph generator.
83
	# - Run Markdown on excerpt, then remove all tags.
84
	# - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
85
	if (MARKDOWN_WP_POSTS) {
86
		remove_filter('the_content',     'wpautop');
87
        remove_filter('the_content_rss', 'wpautop');
88
		remove_filter('the_excerpt',     'wpautop');
89
		add_filter('the_content',     'Markdown', 6);
90
        add_filter('the_content_rss', 'Markdown', 6);
91
		add_filter('get_the_excerpt', 'Markdown', 6);
92
		add_filter('get_the_excerpt', 'trim', 7);
93
		add_filter('the_excerpt',     'mdwp_add_p');
94
		add_filter('the_excerpt_rss', 'mdwp_strip_p');
95
96
		remove_filter('content_save_pre',  'balanceTags', 50);
97
		remove_filter('excerpt_save_pre',  'balanceTags', 50);
98
		add_filter('the_content',  	  'balanceTags', 50);
99
		add_filter('get_the_excerpt', 'balanceTags', 9);
100
	}
101
102
	# Comments
103
	# - Remove WordPress paragraph generator.
104
	# - Remove WordPress auto-link generator.
105
	# - Scramble important tags before passing them to the kses filter.
106
	# - Run Markdown on excerpt then remove paragraph tags.
107
	if (MARKDOWN_WP_COMMENTS) {
108
		remove_filter('comment_text', 'wpautop', 30);
109
		remove_filter('comment_text', 'make_clickable');
110
		add_filter('pre_comment_content', 'Markdown', 6);
111
		add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
112
		add_filter('pre_comment_content', 'mdwp_show_tags', 12);
113
		add_filter('get_comment_text',    'Markdown', 6);
114
		add_filter('get_comment_excerpt', 'Markdown', 6);
115
		add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
116
117
		global $mdwp_hidden_tags, $mdwp_placeholders;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
118
		$mdwp_hidden_tags = explode(' ',
119
			'<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
120
		$mdwp_placeholders = explode(' ', str_rot13(
121
			'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
122
			'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
123
	}
124
125
	function mdwp_add_p($text) {
126
		if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
127
			$text = '<p>'.$text.'</p>';
128
			$text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
129
		}
130
		return $text;
131
	}
132
133
	function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
134
135
	function mdwp_hide_tags($text) {
136
		global $mdwp_hidden_tags, $mdwp_placeholders;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
137
		return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
138
	}
139
	function mdwp_show_tags($text) {
140
		global $mdwp_hidden_tags, $mdwp_placeholders;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
141
		return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
142
	}
143
}
144
145
146
### bBlog Plugin Info ###
147
148
function identify_modifier_markdown() {
149
	return array(
150
		'name'			=> 'markdown',
151
		'type'			=> 'modifier',
152
		'nicename'		=> 'Markdown',
153
		'description'	=> 'A text-to-HTML conversion tool for web writers',
154
		'authors'		=> 'Michel Fortin and John Gruber',
155
		'licence'		=> 'BSD-like',
156
		'version'		=> MARKDOWN_VERSION,
157
		'help'			=> '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.ca/projects/php-markdown/">More...</a>'
158
	);
159
}
160
161
162
### Smarty Modifier Interface ###
163
164
function smarty_modifier_markdown($text) {
165
	return Markdown($text);
166
}
167
168
169
### Textile Compatibility Mode ###
170
171
# Rename this file to "classTextile.php" and it can replace Textile everywhere.
172
173
if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
174
	# Try to include PHP SmartyPants. Should be in the same directory.
175
	@include_once 'smartypants.php';
176
	# Fake Textile class. It calls Markdown instead.
177
	class Textile {
178
		function TextileThis($text, $lite='', $encode='') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
179
			if ($lite == '' && $encode == '')    $text = Markdown($text);
180
			if (function_exists('SmartyPants'))  $text = SmartyPants($text);
181
			return $text;
182
		}
183
		# Fake restricted version: restrictions are not supported for now.
184
		function TextileRestricted($text, $lite='', $noimage='') {
0 ignored issues
show
Unused Code introduced by
The parameter $noimage is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
185
			return $this->TextileThis($text, $lite);
186
		}
187
		# Workaround to ensure compatibility with TextPattern 4.0.3.
188
		function blockLite($text) { return $text; }
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
189
	}
190
}
191
192
193
194
#
195
# Markdown Parser Class
196
#
197
198
class Markdown_Parser {
199
200
	### Configuration Variables ###
201
202
	# Change to ">" for HTML output.
203
	var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $empty_element_suffix.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
204
	var $tab_width = MARKDOWN_TAB_WIDTH;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tab_width.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
205
206
	# Change to `true` to disallow markup or entities.
207
	var $no_markup = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $no_markup.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
208
	var $no_entities = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $no_entities.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
209
210
	# Predefined urls and titles for reference links and images.
211
	var $predef_urls = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $predef_urls.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
212
	var $predef_titles = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $predef_titles.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
213
214
215
	### Parser Implementation ###
216
217
	# Regex to match balanced [brackets].
218
	# Needed to insert a maximum bracked depth while converting to PHP.
219
	var $nested_brackets_depth = 6;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $nested_brackets_depth.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
220
	var $nested_brackets_re;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $nested_brackets_re.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
221
222
	var $nested_url_parenthesis_depth = 4;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $nested_url_parenthesis_depth.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
223
	var $nested_url_parenthesis_re;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $nested_url_parenthesis_re.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
224
225
	# Table of hash values for escaped characters:
226
	var $escape_chars = '\`*_{}[]()>#+-.!';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $escape_chars.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
227
	var $escape_chars_re;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $escape_chars_re.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
228
229
230
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
231
	#
232
	# Constructor function. Initialize appropriate member variables.
233
	#
234
		$this->_initDetab();
235
		$this->prepareItalicsAndBold();
236
237
		$this->nested_brackets_re =
238
			str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
239
			str_repeat('\])*', $this->nested_brackets_depth);
240
241
		$this->nested_url_parenthesis_re =
242
			str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
243
			str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
244
245
		$this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
246
247
		# Sort document, block, and span gamut in ascendent priority order.
248
		asort($this->document_gamut);
249
		asort($this->block_gamut);
250
		asort($this->span_gamut);
251
	}
252
253
254
	# Internal hashes used during transformation.
255
	var $urls = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $urls.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
256
	var $titles = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $titles.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
257
	var $html_hashes = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $html_hashes.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
258
259
	# Status flag to avoid invalid nesting.
260
	var $in_anchor = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $in_anchor.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
261
262
263
	function setup() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
264
	#
265
	# Called before the transformation process starts to setup parser
266
	# states.
267
	#
268
		# Clear global hashes.
269
		$this->urls = $this->predef_urls;
270
		$this->titles = $this->predef_titles;
271
		$this->html_hashes = array();
272
273
		$this->in_anchor = false;
274
	}
275
276
	function teardown() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
277
	#
278
	# Called after the transformation process to clear any variable
279
	# which may be taking up memory unnecessarly.
280
	#
281
		$this->urls = array();
282
		$this->titles = array();
283
		$this->html_hashes = array();
284
	}
285
286
287
	function transform($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
288
	#
289
	# Main function. Performs some preprocessing on the input text
290
	# and pass it through the document gamut.
291
	#
292
		$this->setup();
293
294
		# Remove UTF-8 BOM and marker character in input, if present.
295
		$text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
296
297
		# Standardize line endings:
298
		#   DOS to Unix and Mac to Unix
299
		$text = preg_replace('{\r\n?}', "\n", $text);
300
301
		# Make sure $text ends with a couple of newlines:
302
		$text .= "\n\n";
303
304
		# Convert all tabs to spaces.
305
		$text = $this->detab($text);
306
307
		# Turn block-level HTML blocks into hash entries
308
		$text = $this->hashHTMLBlocks($text);
309
310
		# Strip any lines consisting only of spaces and tabs.
311
		# This makes subsequent regexen easier to write, because we can
312
		# match consecutive blank lines with /\n+/ instead of something
313
		# contorted like /[ ]*\n+/ .
314
		$text = preg_replace('/^[ ]+$/m', '', $text);
315
316
		# Run document gamut methods.
317
		foreach ($this->document_gamut as $method => $priority) {
318
			$text = $this->$method($text);
319
		}
320
321
		$this->teardown();
322
323
		return $text . "\n";
324
	}
325
326
	var $document_gamut = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $document_gamut.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
327
		# Strip link definitions, store in hashes.
328
		"stripLinkDefinitions" => 20,
329
330
		"runBasicBlockGamut"   => 30,
331
		);
332
333
334
	function stripLinkDefinitions($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
335
	#
336
	# Strips link definitions from text, stores the URLs and titles in
337
	# hash references.
338
	#
339
		$less_than_tab = $this->tab_width - 1;
340
341
		# Link defs are in the form: ^[id]: url "optional title"
342
		$text = preg_replace_callback('{
343
							^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?:	# id = $1
344
							  [ ]*
345
							  \n?				# maybe *one* newline
346
							  [ ]*
347
							(?:
348
							  <(.+?)>			# url = $2
349
							|
350
							  (\S+?)			# url = $3
351
							)
352
							  [ ]*
353
							  \n?				# maybe one newline
354
							  [ ]*
355
							(?:
356
								(?<=\s)			# lookbehind for whitespace
357
								["(]
358
								(.*?)			# title = $4
359
								[")]
360
								[ ]*
361
							)?	# title is optional
362
							(?:\n+|\Z)
363
			}xm',
364
			array(&$this, '_stripLinkDefinitions_callback'),
365
			$text);
366
		return $text;
367
	}
368
	function _stripLinkDefinitions_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
369
		$link_id = strtolower($matches[1]);
370
		$url = $matches[2] == '' ? $matches[3] : $matches[2];
371
		$this->urls[$link_id] = $url;
372
		$this->titles[$link_id] =& $matches[4];
373
		return ''; # String that will replace the block
374
	}
375
376
377
	function hashHTMLBlocks($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
378
		if ($this->no_markup)  return $text;
379
380
		$less_than_tab = $this->tab_width - 1;
381
382
		# Hashify HTML blocks:
383
		# We only want to do this for block-level HTML tags, such as headers,
384
		# lists, and tables. That's because we still want to wrap <p>s around
385
		# "paragraphs" that are wrapped in non-block-level tags, such as anchors,
386
		# phrase emphasis, and spans. The list of tags we're looking for is
387
		# hard-coded:
388
		#
389
		# *  List "a" is made of tags which can be both inline or block-level.
390
		#    These will be treated block-level when the start tag is alone on
391
		#    its line, otherwise they're not matched here and will be taken as
392
		#    inline later.
393
		# *  List "b" is made of tags which are always block-level;
394
		#
395
		$block_tags_a_re = 'ins|del';
396
		$block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
397
						   'script|noscript|form|fieldset|iframe|math|svg|'.
398
						   'article|section|nav|aside|hgroup|header|footer|'.
399
						   'figure';
400
401
		# Regular expression for the content of a block tag.
402
		$nested_tags_level = 4;
403
		$attr = '
404
			(?>				# optional tag attributes
405
			  \s			# starts with whitespace
406
			  (?>
407
				[^>"/]+		# text outside quotes
408
			  |
409
				/+(?!>)		# slash not followed by ">"
410
			  |
411
				"[^"]*"		# text inside double quotes (tolerate ">")
412
			  |
413
				\'[^\']*\'	# text inside single quotes (tolerate ">")
414
			  )*
415
			)?
416
			';
417
		$content =
418
			str_repeat('
419
				(?>
420
				  [^<]+			# content without tag
421
				|
422
				  <\2			# nested opening tag
423
					'.$attr.'	# attributes
424
					(?>
425
					  />
426
					|
427
					  >', $nested_tags_level).	# end of opening tag
428
					  '.*?'.					# last level nested tag content
429
			str_repeat('
430
					  </\2\s*>	# closing nested tag
431
					)
432
				  |
433
					<(?!/\2\s*>	# other tags with a different name
434
				  )
435
				)*',
436
				$nested_tags_level);
437
		$content2 = str_replace('\2', '\3', $content);
438
439
		# First, look for nested blocks, e.g.:
440
		# 	<div>
441
		# 		<div>
442
		# 		tags for inner block must be indented.
443
		# 		</div>
444
		# 	</div>
445
		#
446
		# The outermost tags must start at the left margin for this to match, and
447
		# the inner nested divs must be indented.
448
		# We need to do this before the next, more liberal match, because the next
449
		# match will start at the first `<div>` and stop at the first `</div>`.
450
		$text = preg_replace_callback('{(?>
451
			(?>
452
				(?<=\n\n)		# Starting after a blank line
453
				|				# or
454
				\A\n?			# the beginning of the doc
455
			)
456
			(						# save in $1
457
458
			  # Match from `\n<tag>` to `</tag>\n`, handling nested tags
459
			  # in between.
460
461
						[ ]{0,'.$less_than_tab.'}
462
						<('.$block_tags_b_re.')# start tag = $2
463
						'.$attr.'>			# attributes followed by > and \n
464
						'.$content.'		# content, support nesting
465
						</\2>				# the matching end tag
466
						[ ]*				# trailing spaces/tabs
467
						(?=\n+|\Z)	# followed by a newline or end of document
468
469
			| # Special version for tags of group a.
470
471
						[ ]{0,'.$less_than_tab.'}
472
						<('.$block_tags_a_re.')# start tag = $3
473
						'.$attr.'>[ ]*\n	# attributes followed by >
474
						'.$content2.'		# content, support nesting
475
						</\3>				# the matching end tag
476
						[ ]*				# trailing spaces/tabs
477
						(?=\n+|\Z)	# followed by a newline or end of document
478
479
			| # Special case just for <hr />. It was easier to make a special
480
			  # case than to make the other regex more complicated.
481
482
						[ ]{0,'.$less_than_tab.'}
483
						<(hr)				# start tag = $2
484
						'.$attr.'			# attributes
485
						/?>					# the matching end tag
486
						[ ]*
487
						(?=\n{2,}|\Z)		# followed by a blank line or end of document
488
489
			| # Special case for standalone HTML comments:
490
491
					[ ]{0,'.$less_than_tab.'}
492
					(?s:
493
						<!-- .*? -->
494
					)
495
					[ ]*
496
					(?=\n{2,}|\Z)		# followed by a blank line or end of document
497
498
			| # PHP and ASP-style processor instructions (<? and <%)
499
500
					[ ]{0,'.$less_than_tab.'}
501
					(?s:
502
						<([?%])			# $2
503
						.*?
504
						\2>
505
					)
506
					[ ]*
507
					(?=\n{2,}|\Z)		# followed by a blank line or end of document
508
509
			)
510
			)}Sxmi',
511
			array(&$this, '_hashHTMLBlocks_callback'),
512
			$text);
513
514
		return $text;
515
	}
516
	function _hashHTMLBlocks_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
517
		$text = $matches[1];
518
		$key  = $this->hashBlock($text);
519
		return "\n\n$key\n\n";
520
	}
521
522
523
	function hashPart($text, $boundary = 'X') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
524
	#
525
	# Called whenever a tag must be hashed when a function insert an atomic
526
	# element in the text stream. Passing $text to through this function gives
527
	# a unique text-token which will be reverted back when calling unhash.
528
	#
529
	# The $boundary argument specify what character should be used to surround
530
	# the token. By convension, "B" is used for block elements that needs not
531
	# to be wrapped into paragraph tags at the end, ":" is used for elements
532
	# that are word separators and "X" is used in the general case.
533
	#
534
		# Swap back any tag hash found in $text so we do not have to `unhash`
535
		# multiple times at the end.
536
		$text = $this->unhash($text);
537
538
		# Then hash the block.
539
		static $i = 0;
540
		$key = "$boundary\x1A" . ++$i . $boundary;
541
		$this->html_hashes[$key] = $text;
542
		return $key; # String that will replace the tag.
543
	}
544
545
546
	function hashBlock($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
547
	#
548
	# Shortcut function for hashPart with block-level boundaries.
549
	#
550
		return $this->hashPart($text, 'B');
551
	}
552
553
554
	var $block_gamut = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $block_gamut.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
555
	#
556
	# These are all the transformations that form block-level
557
	# tags like paragraphs, headers, and list items.
558
	#
559
		"doHeaders"         => 10,
560
		"doHorizontalRules" => 20,
561
562
		"doLists"           => 40,
563
		"doCodeBlocks"      => 50,
564
		"doBlockQuotes"     => 60,
565
		);
566
567
	function runBlockGamut($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
568
	#
569
	# Run block gamut tranformations.
570
	#
571
		# We need to escape raw HTML in Markdown source before doing anything
572
		# else. This need to be done for each block, and not only at the
573
		# begining in the Markdown function since hashed blocks can be part of
574
		# list items and could have been indented. Indented blocks would have
575
		# been seen as a code block in a previous pass of hashHTMLBlocks.
576
		$text = $this->hashHTMLBlocks($text);
577
578
		return $this->runBasicBlockGamut($text);
579
	}
580
581
	function runBasicBlockGamut($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
582
	#
583
	# Run block gamut tranformations, without hashing HTML blocks. This is
584
	# useful when HTML blocks are known to be already hashed, like in the first
585
	# whole-document pass.
586
	#
587
		foreach ($this->block_gamut as $method => $priority) {
588
			$text = $this->$method($text);
589
		}
590
591
		# Finally form paragraph and restore hashed blocks.
592
		$text = $this->formParagraphs($text);
593
594
		return $text;
595
	}
596
597
598
	function doHorizontalRules($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
599
		# Do Horizontal Rules:
600
		return preg_replace(
601
			'{
602
				^[ ]{0,3}	# Leading space
603
				([-*_])		# $1: First marker
604
				(?>			# Repeated marker group
605
					[ ]{0,2}	# Zero, one, or two spaces.
606
					\1			# Marker character
607
				){2,}		# Group repeated at least twice
608
				[ ]*		# Tailing spaces
609
				$			# End of line.
610
			}mx',
611
			"\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n",
612
			$text);
613
	}
614
615
616
	var $span_gamut = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $span_gamut.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
617
	#
618
	# These are all the transformations that occur *within* block-level
619
	# tags like paragraphs, headers, and list items.
620
	#
621
		# Process character escapes, code spans, and inline HTML
622
		# in one shot.
623
		"parseSpan"           => -30,
624
625
		# Process anchor and image tags. Images must come first,
626
		# because ![foo][f] looks like an anchor.
627
		"doImages"            =>  10,
628
		"doAnchors"           =>  20,
629
630
		# Make links out of things like `<http://example.com/>`
631
		# Must come after doAnchors, because you can use < and >
632
		# delimiters in inline links like [this](<url>).
633
		"doAutoLinks"         =>  30,
634
		"encodeAmpsAndAngles" =>  40,
635
636
		"doItalicsAndBold"    =>  50,
637
		"doHardBreaks"        =>  60,
638
		);
639
640
	function runSpanGamut($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
641
	#
642
	# Run span gamut tranformations.
643
	#
644
		foreach ($this->span_gamut as $method => $priority) {
645
			$text = $this->$method($text);
646
		}
647
648
		return $text;
649
	}
650
651
652
	function doHardBreaks($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
653
		# Do hard breaks:
654
		return preg_replace_callback('/ {2,}\n/',
655
			array(&$this, '_doHardBreaks_callback'), $text);
656
	}
657
	function _doHardBreaks_callback($matches) {
0 ignored issues
show
Unused Code introduced by
The parameter $matches is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
658
		return $this->hashPart("<br$this->empty_element_suffix\n");
659
	}
660
661
662
	function doAnchors($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
663
	#
664
	# Turn Markdown link shortcuts into XHTML <a> tags.
665
	#
666
		if ($this->in_anchor) return $text;
667
		$this->in_anchor = true;
668
669
		#
670
		# First, handle reference-style links: [link text] [id]
671
		#
672
		$text = preg_replace_callback('{
673
			(					# wrap whole match in $1
674
			  \[
675
				('.$this->nested_brackets_re.')	# link text = $2
676
			  \]
677
678
			  [ ]?				# one optional space
679
			  (?:\n[ ]*)?		# one optional newline followed by spaces
680
681
			  \[
682
				(.*?)		# id = $3
683
			  \]
684
			)
685
			}xs',
686
			array(&$this, '_doAnchors_reference_callback'), $text);
687
688
		#
689
		# Next, inline-style links: [link text](url "optional title")
690
		#
691
		$text = preg_replace_callback('{
692
			(				# wrap whole match in $1
693
			  \[
694
				('.$this->nested_brackets_re.')	# link text = $2
695
			  \]
696
			  \(			# literal paren
697
				[ \n]*
698
				(?:
699
					<(.+?)>	# href = $3
700
				|
701
					('.$this->nested_url_parenthesis_re.')	# href = $4
702
				)
703
				[ \n]*
704
				(			# $5
705
				  ([\'"])	# quote char = $6
706
				  (.*?)		# Title = $7
707
				  \6		# matching quote
708
				  [ \n]*	# ignore any spaces/tabs between closing quote and )
709
				)?			# title is optional
710
			  \)
711
			)
712
			}xs',
713
			array(&$this, '_doAnchors_inline_callback'), $text);
714
715
		#
716
		# Last, handle reference-style shortcuts: [link text]
717
		# These must come last in case you've also got [link text][1]
718
		# or [link text](/foo)
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
719
		#
720
		$text = preg_replace_callback('{
721
			(					# wrap whole match in $1
722
			  \[
723
				([^\[\]]+)		# link text = $2; can\'t contain [ or ]
724
			  \]
725
			)
726
			}xs',
727
			array(&$this, '_doAnchors_reference_callback'), $text);
728
729
		$this->in_anchor = false;
730
		return $text;
731
	}
732
	function _doAnchors_reference_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
733
		$whole_match =  $matches[1];
734
		$link_text   =  $matches[2];
735
		$link_id     =& $matches[3];
736
737
		if ($link_id == "") {
738
			# for shortcut links like [this][] or [this].
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
739
			$link_id = $link_text;
740
		}
741
742
		# lower-case and turn embedded newlines into spaces
743
		$link_id = strtolower($link_id);
744
		$link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
745
746
		if (isset($this->urls[$link_id])) {
747
			$url = $this->urls[$link_id];
748
			$url = $this->encodeAttribute($url);
749
750
			$result = "<a href=\"$url\"";
751 View Code Duplication
			if ( isset( $this->titles[$link_id] ) ) {
752
				$title = $this->titles[$link_id];
753
				$title = $this->encodeAttribute($title);
754
				$result .=  " title=\"$title\"";
755
			}
756
757
			$link_text = $this->runSpanGamut($link_text);
758
			$result .= ">$link_text</a>";
759
			$result = $this->hashPart($result);
760
		}
761
		else {
762
			$result = $whole_match;
763
		}
764
		return $result;
765
	}
766 View Code Duplication
	function _doAnchors_inline_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
767
		$whole_match	=  $matches[1];
768
		$link_text		=  $this->runSpanGamut($matches[2]);
769
		$url			=  $matches[3] == '' ? $matches[4] : $matches[3];
770
		$title			=& $matches[7];
771
772
		$url = $this->encodeAttribute($url);
773
774
		$result = "<a href=\"$url\"";
775
		if (isset($title)) {
776
			$title = $this->encodeAttribute($title);
777
			$result .=  " title=\"$title\"";
778
		}
779
780
		$link_text = $this->runSpanGamut($link_text);
781
		$result .= ">$link_text</a>";
782
783
		return $this->hashPart($result);
784
	}
785
786
787
	function doImages($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
788
	#
789
	# Turn Markdown image shortcuts into <img> tags.
790
	#
791
		#
792
		# First, handle reference-style labeled images: ![alt text][id]
793
		#
794
		$text = preg_replace_callback('{
795
			(				# wrap whole match in $1
796
			  !\[
797
				('.$this->nested_brackets_re.')		# alt text = $2
798
			  \]
799
800
			  [ ]?				# one optional space
801
			  (?:\n[ ]*)?		# one optional newline followed by spaces
802
803
			  \[
804
				(.*?)		# id = $3
805
			  \]
806
807
			)
808
			}xs',
809
			array(&$this, '_doImages_reference_callback'), $text);
810
811
		#
812
		# Next, handle inline images:  ![alt text](url "optional title")
813
		# Don't forget: encode * and _
814
		#
815
		$text = preg_replace_callback('{
816
			(				# wrap whole match in $1
817
			  !\[
818
				('.$this->nested_brackets_re.')		# alt text = $2
819
			  \]
820
			  \s?			# One optional whitespace character
821
			  \(			# literal paren
822
				[ \n]*
823
				(?:
824
					<(\S*)>	# src url = $3
825
				|
826
					('.$this->nested_url_parenthesis_re.')	# src url = $4
827
				)
828
				[ \n]*
829
				(			# $5
830
				  ([\'"])	# quote char = $6
831
				  (.*?)		# title = $7
832
				  \6		# matching quote
833
				  [ \n]*
834
				)?			# title is optional
835
			  \)
836
			)
837
			}xs',
838
			array(&$this, '_doImages_inline_callback'), $text);
839
840
		return $text;
841
	}
842
	function _doImages_reference_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
843
		$whole_match = $matches[1];
844
		$alt_text    = $matches[2];
845
		$link_id     = strtolower($matches[3]);
846
847
		if ($link_id == "") {
848
			$link_id = strtolower($alt_text); # for shortcut links like ![this][].
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
849
		}
850
851
		$alt_text = $this->encodeAttribute($alt_text);
852
		if (isset($this->urls[$link_id])) {
853
			$url = $this->encodeAttribute($this->urls[$link_id]);
854
			$result = "<img src=\"$url\" alt=\"$alt_text\"";
855 View Code Duplication
			if (isset($this->titles[$link_id])) {
856
				$title = $this->titles[$link_id];
857
				$title = $this->encodeAttribute($title);
858
				$result .=  " title=\"$title\"";
859
			}
860
			$result .= $this->empty_element_suffix;
861
			$result = $this->hashPart($result);
862
		}
863
		else {
864
			# If there's no such link ID, leave intact:
865
			$result = $whole_match;
866
		}
867
868
		return $result;
869
	}
870 View Code Duplication
	function _doImages_inline_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
871
		$whole_match	= $matches[1];
872
		$alt_text		= $matches[2];
873
		$url			= $matches[3] == '' ? $matches[4] : $matches[3];
874
		$title			=& $matches[7];
875
876
		$alt_text = $this->encodeAttribute($alt_text);
877
		$url = $this->encodeAttribute($url);
878
		$result = "<img src=\"$url\" alt=\"$alt_text\"";
879
		if (isset($title)) {
880
			$title = $this->encodeAttribute($title);
881
			$result .=  " title=\"$title\""; # $title already quoted
882
		}
883
		$result .= $this->empty_element_suffix;
884
885
		return $this->hashPart($result);
886
	}
887
888
889
	function doHeaders($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
890
		# Setext-style headers:
891
		#	  Header 1
892
		#	  ========
893
		#
894
		#	  Header 2
895
		#	  --------
896
		#
897
		$text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
898
			array(&$this, '_doHeaders_callback_setext'), $text);
899
900
		# atx-style headers:
901
		#	# Header 1
902
		#	## Header 2
903
		#	## Header 2 with closing hashes ##
904
		#	...
905
		#	###### Header 6
906
		#
907
		$text = preg_replace_callback('{
908
				^(\#{1,6})	# $1 = string of #\'s
909
				[ ]*
910
				(.+?)		# $2 = Header text
911
				[ ]*
912
				\#*			# optional closing #\'s (not counted)
913
				\n+
914
			}xm',
915
			array(&$this, '_doHeaders_callback_atx'), $text);
916
917
		return $text;
918
	}
919
	function _doHeaders_callback_setext($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
920
		# Terrible hack to check we haven't found an empty list item.
921
		if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
922
			return $matches[0];
923
924
		$level = $matches[2]{0} == '=' ? 1 : 2;
925
		$block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
926
		return "\n" . $this->hashBlock($block) . "\n\n";
927
	}
928
	function _doHeaders_callback_atx($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
929
		$level = strlen($matches[1]);
930
		$block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
931
		return "\n" . $this->hashBlock($block) . "\n\n";
932
	}
933
934
935
	function doLists($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
936
	#
937
	# Form HTML ordered (numbered) and unordered (bulleted) lists.
938
	#
939
		$less_than_tab = $this->tab_width - 1;
940
941
		# Re-usable patterns to match list item bullets and number markers:
942
		$marker_ul_re  = '[*+-]';
943
		$marker_ol_re  = '\d+[\.]';
944
		$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
945
946
		$markers_relist = array(
947
			$marker_ul_re => $marker_ol_re,
948
			$marker_ol_re => $marker_ul_re,
949
			);
950
951
		foreach ($markers_relist as $marker_re => $other_marker_re) {
952
			# Re-usable pattern to match any entirel ul or ol list:
953
			$whole_list_re = '
954
				(								# $1 = whole list
955
				  (								# $2
956
					([ ]{0,'.$less_than_tab.'})	# $3 = number of spaces
957
					('.$marker_re.')			# $4 = first list item marker
958
					[ ]+
959
				  )
960
				  (?s:.+?)
961
				  (								# $5
962
					  \z
963
					|
964
					  \n{2,}
965
					  (?=\S)
966
					  (?!						# Negative lookahead for another list item marker
967
						[ ]*
968
						'.$marker_re.'[ ]+
969
					  )
970
					|
971
					  (?=						# Lookahead for another kind of list
972
					    \n
973
						\3						# Must have the same indentation
974
						'.$other_marker_re.'[ ]+
975
					  )
976
				  )
977
				)
978
			'; // mx
979
980
			# We use a different prefix before nested lists than top-level lists.
981
			# See extended comment in _ProcessListItems().
982
983
			if ($this->list_level) {
984
				$text = preg_replace_callback('{
985
						^
986
						'.$whole_list_re.'
987
					}mx',
988
					array(&$this, '_doLists_callback'), $text);
989
			}
990
			else {
991
				$text = preg_replace_callback('{
992
						(?:(?<=\n)\n|\A\n?) # Must eat the newline
993
						'.$whole_list_re.'
994
					}mx',
995
					array(&$this, '_doLists_callback'), $text);
996
			}
997
		}
998
999
		return $text;
1000
	}
1001
	function _doLists_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1002
		# Re-usable patterns to match list item bullets and number markers:
1003
		$marker_ul_re  = '[*+-]';
1004
		$marker_ol_re  = '\d+[\.]';
1005
		$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
1006
1007
		$list = $matches[1];
1008
		$list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
1009
1010
		$marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
1011
1012
		$list .= "\n";
1013
		$result = $this->processListItems($list, $marker_any_re);
1014
1015
		$result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
1016
		return "\n". $result ."\n\n";
1017
	}
1018
1019
	var $list_level = 0;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $list_level.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
1020
1021
	function processListItems($list_str, $marker_any_re) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1022
	#
1023
	#	Process the contents of a single ordered or unordered list, splitting it
1024
	#	into individual list items.
1025
	#
1026
		# The $this->list_level global keeps track of when we're inside a list.
1027
		# Each time we enter a list, we increment it; when we leave a list,
1028
		# we decrement. If it's zero, we're not in a list anymore.
1029
		#
1030
		# We do this because when we're not inside a list, we want to treat
1031
		# something like this:
1032
		#
1033
		#		I recommend upgrading to version
1034
		#		8. Oops, now this line is treated
1035
		#		as a sub-list.
1036
		#
1037
		# As a single paragraph, despite the fact that the second line starts
1038
		# with a digit-period-space sequence.
1039
		#
1040
		# Whereas when we're inside a list (or sub-list), that line will be
1041
		# treated as the start of a sub-list. What a kludge, huh? This is
1042
		# an aspect of Markdown's syntax that's hard to parse perfectly
1043
		# without resorting to mind-reading. Perhaps the solution is to
1044
		# change the syntax rules such that sub-lists must start with a
1045
		# starting cardinal number; e.g. "1." or "a.".
1046
1047
		$this->list_level++;
1048
1049
		# trim trailing blank lines:
1050
		$list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
1051
1052
		$list_str = preg_replace_callback('{
1053
			(\n)?							# leading line = $1
1054
			(^[ ]*)							# leading whitespace = $2
1055
			('.$marker_any_re.'				# list marker and space = $3
1056
				(?:[ ]+|(?=\n))	# space only required if item is not empty
1057
			)
1058
			((?s:.*?))						# list item text   = $4
1059
			(?:(\n+(?=\n))|\n)				# tailing blank line = $5
1060
			(?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
1061
			}xm',
1062
			array(&$this, '_processListItems_callback'), $list_str);
1063
1064
		$this->list_level--;
1065
		return $list_str;
1066
	}
1067
	function _processListItems_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1068
		$item = $matches[4];
1069
		$leading_line =& $matches[1];
1070
		$leading_space =& $matches[2];
1071
		$marker_space = $matches[3];
1072
		$tailing_blank_line =& $matches[5];
1073
1074
		if ($leading_line || $tailing_blank_line ||
1075
			preg_match('/\n{2,}/', $item))
1076
		{
1077
			# Replace marker with the appropriate whitespace indentation
1078
			$item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
1079
			$item = $this->runBlockGamut($this->outdent($item)."\n");
1080
		}
1081
		else {
1082
			# Recursion for sub-lists:
1083
			$item = $this->doLists($this->outdent($item));
1084
			$item = preg_replace('/\n+$/', '', $item);
1085
			$item = $this->runSpanGamut($item);
1086
		}
1087
1088
		return "<li>" . $item . "</li>\n";
1089
	}
1090
1091
1092
	function doCodeBlocks($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1093
	#
1094
	#	Process Markdown `<pre><code>` blocks.
1095
	#
1096
		$text = preg_replace_callback('{
1097
				(?:\n\n|\A\n?)
1098
				(	            # $1 = the code block -- one or more lines, starting with a space/tab
1099
				  (?>
1100
					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
1101
					.*\n+
1102
				  )+
1103
				)
1104
				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
1105
			}xm',
1106
			array(&$this, '_doCodeBlocks_callback'), $text);
1107
1108
		return $text;
1109
	}
1110
	function _doCodeBlocks_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1111
		$codeblock = $matches[1];
1112
1113
		$codeblock = $this->outdent($codeblock);
1114
		$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
1115
1116
		# trim leading newlines and trailing newlines
1117
		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
1118
1119
		$codeblock = "<pre><code>$codeblock\n</code></pre>";
1120
		return "\n\n".$this->hashBlock($codeblock)."\n\n";
1121
	}
1122
1123
1124
	function makeCodeSpan($code) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1125
	#
1126
	# Create a code span markup for $code. Called from handleSpanToken.
1127
	#
1128
		$code = htmlspecialchars(trim($code), ENT_NOQUOTES);
1129
		return $this->hashPart("<code>$code</code>");
1130
	}
1131
1132
1133
	var $em_relist = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $em_relist.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
1134
		''  => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![\.,:;]\s)',
1135
		'*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
1136
		'_' => '(?<=\S|^)(?<!_)_(?!_)',
1137
		);
1138
	var $strong_relist = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $strong_relist.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
1139
		''   => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![\.,:;]\s)',
1140
		'**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
1141
		'__' => '(?<=\S|^)(?<!_)__(?!_)',
1142
		);
1143
	var $em_strong_relist = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $em_strong_relist.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
1144
		''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![\.,:;]\s)',
1145
		'***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
1146
		'___' => '(?<=\S|^)(?<!_)___(?!_)',
1147
		);
1148
	var $em_strong_prepared_relist;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $em_strong_prepared_relist.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
1149
1150
	function prepareItalicsAndBold() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1151
	#
1152
	# Prepare regular expressions for searching emphasis tokens in any
1153
	# context.
1154
	#
1155
		foreach ($this->em_relist as $em => $em_re) {
1156
			foreach ($this->strong_relist as $strong => $strong_re) {
1157
				# Construct list of allowed token expressions.
1158
				$token_relist = array();
1159
				if (isset($this->em_strong_relist["$em$strong"])) {
1160
					$token_relist[] = $this->em_strong_relist["$em$strong"];
1161
				}
1162
				$token_relist[] = $em_re;
1163
				$token_relist[] = $strong_re;
1164
1165
				# Construct master expression from list.
1166
				$token_re = '{('. implode('|', $token_relist) .')}';
1167
				$this->em_strong_prepared_relist["$em$strong"] = $token_re;
1168
			}
1169
		}
1170
	}
1171
1172
	function doItalicsAndBold($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1173
		$token_stack = array('');
1174
		$text_stack = array('');
1175
		$em = '';
1176
		$strong = '';
1177
		$tree_char_em = false;
1178
1179
		while (1) {
1180
			#
1181
			# Get prepared regular expression for seraching emphasis tokens
1182
			# in current context.
1183
			#
1184
			$token_re = $this->em_strong_prepared_relist["$em$strong"];
1185
1186
			#
1187
			# Each loop iteration search for the next emphasis token.
1188
			# Each token is then passed to handleSpanToken.
1189
			#
1190
			$parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
1191
			$text_stack[0] .= $parts[0];
1192
			$token =& $parts[1];
1193
			$text =& $parts[2];
1194
1195 View Code Duplication
			if (empty($token)) {
1196
				# Reached end of text span: empty stack without emitting.
1197
				# any more emphasis.
1198
				while ($token_stack[0]) {
1199
					$text_stack[1] .= array_shift($token_stack);
1200
					$text_stack[0] .= array_shift($text_stack);
1201
				}
1202
				break;
1203
			}
1204
1205
			$token_len = strlen($token);
1206
			if ($tree_char_em) {
1207
				# Reached closing marker while inside a three-char emphasis.
1208
				if ($token_len == 3) {
1209
					# Three-char closing marker, close em and strong.
1210
					array_shift($token_stack);
1211
					$span = array_shift($text_stack);
1212
					$span = $this->runSpanGamut($span);
1213
					$span = "<strong><em>$span</em></strong>";
1214
					$text_stack[0] .= $this->hashPart($span);
1215
					$em = '';
1216
					$strong = '';
1217
				} else {
1218
					# Other closing marker: close one em or strong and
1219
					# change current token state to match the other
1220
					$token_stack[0] = str_repeat($token{0}, 3-$token_len);
1221
					$tag = $token_len == 2 ? "strong" : "em";
1222
					$span = $text_stack[0];
1223
					$span = $this->runSpanGamut($span);
1224
					$span = "<$tag>$span</$tag>";
1225
					$text_stack[0] = $this->hashPart($span);
1226
					$$tag = ''; # $$tag stands for $em or $strong
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1227
				}
1228
				$tree_char_em = false;
1229
			} else if ($token_len == 3) {
1230
				if ($em) {
1231
					# Reached closing marker for both em and strong.
1232
					# Closing strong marker:
1233
					for ($i = 0; $i < 2; ++$i) {
1234
						$shifted_token = array_shift($token_stack);
1235
						$tag = strlen($shifted_token) == 2 ? "strong" : "em";
1236
						$span = array_shift($text_stack);
1237
						$span = $this->runSpanGamut($span);
1238
						$span = "<$tag>$span</$tag>";
1239
						$text_stack[0] .= $this->hashPart($span);
1240
						$$tag = ''; # $$tag stands for $em or $strong
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1241
					}
1242
				} else {
1243
					# Reached opening three-char emphasis marker. Push on token
1244
					# stack; will be handled by the special condition above.
1245
					$em = $token{0};
1246
					$strong = "$em$em";
1247
					array_unshift($token_stack, $token);
1248
					array_unshift($text_stack, '');
1249
					$tree_char_em = true;
1250
				}
1251
			} else if ($token_len == 2) {
1252
				if ($strong) {
1253
					# Unwind any dangling emphasis marker:
1254 View Code Duplication
					if (strlen($token_stack[0]) == 1) {
1255
						$text_stack[1] .= array_shift($token_stack);
1256
						$text_stack[0] .= array_shift($text_stack);
1257
					}
1258
					# Closing strong marker:
1259
					array_shift($token_stack);
1260
					$span = array_shift($text_stack);
1261
					$span = $this->runSpanGamut($span);
1262
					$span = "<strong>$span</strong>";
1263
					$text_stack[0] .= $this->hashPart($span);
1264
					$strong = '';
1265
				} else {
1266
					array_unshift($token_stack, $token);
1267
					array_unshift($text_stack, '');
1268
					$strong = $token;
1269
				}
1270
			} else {
1271
				# Here $token_len == 1
1272
				if ($em) {
1273
					if (strlen($token_stack[0]) == 1) {
1274
						# Closing emphasis marker:
1275
						array_shift($token_stack);
1276
						$span = array_shift($text_stack);
1277
						$span = $this->runSpanGamut($span);
1278
						$span = "<em>$span</em>";
1279
						$text_stack[0] .= $this->hashPart($span);
1280
						$em = '';
1281
					} else {
1282
						$text_stack[0] .= $token;
1283
					}
1284
				} else {
1285
					array_unshift($token_stack, $token);
1286
					array_unshift($text_stack, '');
1287
					$em = $token;
1288
				}
1289
			}
1290
		}
1291
		return $text_stack[0];
1292
	}
1293
1294
1295
	function doBlockQuotes($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1296
		$text = preg_replace_callback('/
1297
			  (								# Wrap whole match in $1
1298
				(?>
1299
				  ^[ ]*>[ ]?			# ">" at the start of a line
1300
					.+\n					# rest of the first line
1301
				  (.+\n)*					# subsequent consecutive lines
1302
				  \n*						# blanks
1303
				)+
1304
			  )
1305
			/xm',
1306
			array(&$this, '_doBlockQuotes_callback'), $text);
1307
1308
		return $text;
1309
	}
1310
	function _doBlockQuotes_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1311
		$bq = $matches[1];
1312
		# trim one level of quoting - trim whitespace-only lines
1313
		$bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
1314
		$bq = $this->runBlockGamut($bq);		# recurse
1315
1316
		$bq = preg_replace('/^/m', "  ", $bq);
1317
		# These leading spaces cause problem with <pre> content,
1318
		# so we need to fix that:
1319
		$bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
1320
			array(&$this, '_doBlockQuotes_callback2'), $bq);
1321
1322
		return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
1323
	}
1324
	function _doBlockQuotes_callback2($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1325
		$pre = $matches[1];
1326
		$pre = preg_replace('/^  /m', '', $pre);
1327
		return $pre;
1328
	}
1329
1330
1331
	function formParagraphs($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1332
	#
1333
	#	Params:
1334
	#		$text - string to process with html <p> tags
1335
	#
1336
		# Strip leading and trailing lines:
1337
		$text = preg_replace('/\A\n+|\n+\z/', '', $text);
1338
1339
		$grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
1340
1341
		#
1342
		# Wrap <p> tags and unhashify HTML blocks
1343
		#
1344
		foreach ($grafs as $key => $value) {
1345
			if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
1346
				# Is a paragraph.
1347
				$value = $this->runSpanGamut($value);
1348
				$value = preg_replace('/^([ ]*)/', "<p>", $value);
1349
				$value .= "</p>";
1350
				$grafs[$key] = $this->unhash($value);
1351
			}
1352
			else {
1353
				# Is a block.
1354
				# Modify elements of @grafs in-place...
1355
				$graf = $value;
1356
				$block = $this->html_hashes[$graf];
1357
				$graf = $block;
1358
//				if (preg_match('{
1359
//					\A
1360
//					(							# $1 = <div> tag
1361
//					  <div  \s+
1362
//					  [^>]*
1363
//					  \b
1364
//					  markdown\s*=\s*  ([\'"])	#	$2 = attr quote char
1365
//					  1
1366
//					  \2
1367
//					  [^>]*
1368
//					  >
1369
//					)
1370
//					(							# $3 = contents
1371
//					.*
1372
//					)
1373
//					(</div>)					# $4 = closing tag
1374
//					\z
1375
//					}xs', $block, $matches))
1376
//				{
1377
//					list(, $div_open, , $div_content, $div_close) = $matches;
1378
//
1379
//					# We can't call Markdown(), because that resets the hash;
1380
//					# that initialization code should be pulled into its own sub, though.
1381
//					$div_content = $this->hashHTMLBlocks($div_content);
1382
//
1383
//					# Run document gamut methods on the content.
1384
//					foreach ($this->document_gamut as $method => $priority) {
1385
//						$div_content = $this->$method($div_content);
1386
//					}
1387
//
1388
//					$div_open = preg_replace(
1389
//						'{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
1390
//
1391
//					$graf = $div_open . "\n" . $div_content . "\n" . $div_close;
1392
//				}
1393
				$grafs[$key] = $graf;
1394
			}
1395
		}
1396
1397
		return implode("\n\n", $grafs);
1398
	}
1399
1400
1401
	function encodeAttribute($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1402
	#
1403
	# Encode text for a double-quoted HTML attribute. This function
1404
	# is *not* suitable for attributes enclosed in single quotes.
1405
	#
1406
		$text = $this->encodeAmpsAndAngles($text);
1407
		$text = str_replace('"', '&quot;', $text);
1408
		return $text;
1409
	}
1410
1411
1412
	function encodeAmpsAndAngles($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1413
	#
1414
	# Smart processing for ampersands and angle brackets that need to
1415
	# be encoded. Valid character entities are left alone unless the
1416
	# no-entities mode is set.
1417
	#
1418
		if ($this->no_entities) {
1419
			$text = str_replace('&', '&amp;', $text);
1420
		} else {
1421
			# Ampersand-encoding based entirely on Nat Irons's Amputator
1422
			# MT plugin: <http://bumppo.net/projects/amputator/>
1423
			$text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
1424
								'&amp;', $text);;
1425
		}
1426
		# Encode remaining <'s
1427
		$text = str_replace('<', '&lt;', $text);
1428
1429
		return $text;
1430
	}
1431
1432
1433
	function doAutoLinks($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1434
		$text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
1435
			array(&$this, '_doAutoLinks_url_callback'), $text);
1436
1437
		# Email addresses: <[email protected]>
1438
		$text = preg_replace_callback('{
1439
			<
1440
			(?:mailto:)?
1441
			(
1442
				(?:
1443
					[-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
1444
				|
1445
					".*?"
1446
				)
1447
				\@
1448
				(?:
1449
					[-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
1450
				|
1451
					\[[\d.a-fA-F:]+\]	# IPv4 & IPv6
1452
				)
1453
			)
1454
			>
1455
			}xi',
1456
			array(&$this, '_doAutoLinks_email_callback'), $text);
1457
		$text = preg_replace_callback('{<(tel:([^\'">\s]+))>}i',array(&$this, '_doAutoLinks_tel_callback'), $text);
1458
1459
		return $text;
1460
	}
1461
	function _doAutoLinks_tel_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1462
		$url = $this->encodeAttribute($matches[1]);
1463
		$tel = $this->encodeAttribute($matches[2]);
1464
		$link = "<a href=\"$url\">$tel</a>";
1465
		return $this->hashPart($link);
1466
	}
1467
	function _doAutoLinks_url_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1468
		$url = $this->encodeAttribute($matches[1]);
1469
		$link = "<a href=\"$url\">$url</a>";
1470
		return $this->hashPart($link);
1471
	}
1472
	function _doAutoLinks_email_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1473
		$address = $matches[1];
1474
		$link = $this->encodeEmailAddress($address);
1475
		return $this->hashPart($link);
1476
	}
1477
1478
1479
	function encodeEmailAddress($addr) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1480
	#
1481
	#	Input: an email address, e.g. "[email protected]"
1482
	#
1483
	#	Output: the email address as a mailto link, with each character
1484
	#		of the address encoded as either a decimal or hex entity, in
1485
	#		the hopes of foiling most address harvesting spam bots. E.g.:
1486
	#
1487
	#	  <p><a href="&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
1488
	#        &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
1489
	#        &#x6d;">&#x66;o&#111;&#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;
1490
	#        &#101;&#46;&#x63;&#111;&#x6d;</a></p>
1491
	#
1492
	#	Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
1493
	#   With some optimizations by Milian Wolff.
1494
	#
1495
		$addr = "mailto:" . $addr;
1496
		$chars = preg_split('/(?<!^)(?!$)/', $addr);
1497
		$seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
1498
1499
		foreach ($chars as $key => $char) {
1500
			$ord = ord($char);
1501
			# Ignore non-ascii chars.
1502
			if ($ord < 128) {
1503
				$r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
1504
				# roughly 10% raw, 45% hex, 45% dec
1505
				# '@' *must* be encoded. I insist.
1506
				if ($r > 90 && $char != '@') /* do nothing */;
1507
				else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
1508
				else              $chars[$key] = '&#'.$ord.';';
1509
			}
1510
		}
1511
1512
		$addr = implode('', $chars);
1513
		$text = implode('', array_slice($chars, 7)); # text without `mailto:`
1514
		$addr = "<a href=\"$addr\">$text</a>";
1515
1516
		return $addr;
1517
	}
1518
1519
1520
	function parseSpan($str) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1521
	#
1522
	# Take the string $str and parse it into tokens, hashing embeded HTML,
1523
	# escaped characters and handling code spans.
1524
	#
1525
		$output = '';
1526
1527
		$span_re = '{
1528
				(
1529
					\\\\'.$this->escape_chars_re.'
1530
				|
1531
					(?<![`\\\\])
1532
					`+						# code span marker
1533
			'.( $this->no_markup ? '' : '
1534
				|
1535
					<!--    .*?     -->		# comment
1536
				|
1537
					<\?.*?\?> | <%.*?%>		# processing instruction
1538
				|
1539
					<[!$]?[-a-zA-Z0-9:_]+	# regular tags
1540
					(?>
1541
						\s
1542
						(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
1543
					)?
1544
					>
1545
				|
1546
					<[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag
1547
				|
1548
					</[-a-zA-Z0-9:_]+\s*> # closing tag
1549
			').'
1550
				)
1551
				}xs';
1552
1553
		while (1) {
1554
			#
1555
			# Each loop iteration seach for either the next tag, the next
1556
			# openning code span marker, or the next escaped character.
1557
			# Each token is then passed to handleSpanToken.
1558
			#
1559
			$parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
1560
1561
			# Create token from text preceding tag.
1562
			if ($parts[0] != "") {
1563
				$output .= $parts[0];
1564
			}
1565
1566
			# Check if we reach the end.
1567
			if (isset($parts[1])) {
1568
				$output .= $this->handleSpanToken($parts[1], $parts[2]);
1569
				$str = $parts[2];
1570
			}
1571
			else {
1572
				break;
1573
			}
1574
		}
1575
1576
		return $output;
1577
	}
1578
1579
1580
	function handleSpanToken($token, &$str) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1581
	#
1582
	# Handle $token provided by parseSpan by determining its nature and
1583
	# returning the corresponding value that should replace it.
1584
	#
1585
		switch ($token{0}) {
1586
			case "\\":
1587
				return $this->hashPart("&#". ord($token{1}). ";");
1588
			case "`":
1589
				# Search for end marker in remaining text.
1590
				if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
1591
					$str, $matches))
1592
				{
1593
					$str = $matches[2];
1594
					$codespan = $this->makeCodeSpan($matches[1]);
1595
					return $this->hashPart($codespan);
1596
				}
1597
				return $token; // return as text since no ending marker found.
1598
			default:
1599
				return $this->hashPart($token);
1600
		}
1601
	}
1602
1603
1604
	function outdent($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1605
	#
1606
	# Remove one level of line-leading tabs or spaces
1607
	#
1608
		return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
1609
	}
1610
1611
1612
	# String length function for detab. `_initDetab` will create a function to
1613
	# hanlde UTF-8 if the default function does not exist.
1614
	var $utf8_strlen = 'mb_strlen';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $utf8_strlen.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
1615
1616
	function detab($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1617
	#
1618
	# Replace tabs with the appropriate amount of space.
1619
	#
1620
		# For each line we separate the line in blocks delemited by
1621
		# tab characters. Then we reconstruct every line by adding the
1622
		# appropriate number of space between each blocks.
1623
1624
		$text = preg_replace_callback('/^.*\t.*$/m',
1625
			array(&$this, '_detab_callback'), $text);
1626
1627
		return $text;
1628
	}
1629
	function _detab_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1630
		$line = $matches[0];
1631
		$strlen = $this->utf8_strlen; # strlen function for UTF-8.
1632
1633
		# Split in blocks.
1634
		$blocks = explode("\t", $line);
1635
		# Add each blocks to the line.
1636
		$line = $blocks[0];
1637
		unset($blocks[0]); # Do not add first block twice.
1638
		foreach ($blocks as $block) {
1639
			# Calculate amount of space, insert spaces, insert block.
1640
			$amount = $this->tab_width -
1641
				$strlen($line, 'UTF-8') % $this->tab_width;
1642
			$line .= str_repeat(" ", $amount) . $block;
1643
		}
1644
		return $line;
1645
	}
1646
	function _initDetab() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1647
	#
1648
	# Check for the availability of the function in the `utf8_strlen` property
1649
	# (initially `mb_strlen`). If the function is not available, create a
1650
	# function that will loosely count the number of UTF-8 characters with a
1651
	# regular expression.
1652
	#
1653
		if (function_exists($this->utf8_strlen)) return;
1654
		$this->utf8_strlen = create_function('$text', 'return preg_match_all(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1655
			"/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
1656
			$text, $m);');
1657
	}
1658
1659
1660
	function unhash($text) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1661
	#
1662
	# Swap back in all the tags hashed by _HashHTMLBlocks.
1663
	#
1664
		return preg_replace_callback('/(.)\x1A[0-9]+\1/',
1665
			array(&$this, '_unhash_callback'), $text);
1666
	}
1667
	function _unhash_callback($matches) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1668
		return $this->html_hashes[$matches[0]];
1669
	}
1670
1671
}
1672
1673
/*
1674
1675
PHP Markdown
1676
============
1677
1678
Description
1679
-----------
1680
1681
This is a PHP translation of the original Markdown formatter written in
1682
Perl by John Gruber.
1683
1684
Markdown is a text-to-HTML filter; it translates an easy-to-read /
1685
easy-to-write structured text format into HTML. Markdown's text format
1686
is mostly similar to that of plain text email, and supports features such
1687
as headers, *emphasis*, code blocks, blockquotes, and links.
1688
1689
Markdown's syntax is designed not as a generic markup language, but
1690
specifically to serve as a front-end to (X)HTML. You can use span-level
1691
HTML tags anywhere in a Markdown document, and you can use block level
1692
HTML tags (like <div> and <table> as well).
1693
1694
For more information about Markdown's syntax, see:
1695
1696
<http://daringfireball.net/projects/markdown/>
1697
1698
1699
Bugs
1700
----
1701
1702
To file bug reports please send email to:
1703
1704
<[email protected]>
1705
1706
Please include with your report: (1) the example input; (2) the output you
1707
expected; (3) the output Markdown actually produced.
1708
1709
1710
Version History
1711
---------------
1712
1713
See the readme file for detailed release notes for this version.
1714
1715
1716
Copyright and License
1717
---------------------
1718
1719
PHP Markdown
1720
Copyright (c) 2004-2013 Michel Fortin
1721
<http://michelf.ca/>
1722
All rights reserved.
1723
1724
Based on Markdown
1725
Copyright (c) 2003-2006 John Gruber
1726
<http://daringfireball.net/>
1727
All rights reserved.
1728
1729
Redistribution and use in source and binary forms, with or without
1730
modification, are permitted provided that the following conditions are
1731
met:
1732
1733
*	Redistributions of source code must retain the above copyright notice,
1734
	this list of conditions and the following disclaimer.
1735
1736
*	Redistributions in binary form must reproduce the above copyright
1737
	notice, this list of conditions and the following disclaimer in the
1738
	documentation and/or other materials provided with the distribution.
1739
1740
*	Neither the name "Markdown" nor the names of its contributors may
1741
	be used to endorse or promote products derived from this software
1742
	without specific prior written permission.
1743
1744
This software is provided by the copyright holders and contributors "as
1745
is" and any express or implied warranties, including, but not limited
1746
to, the implied warranties of merchantability and fitness for a
1747
particular purpose are disclaimed. In no event shall the copyright owner
1748
or contributors be liable for any direct, indirect, incidental, special,
1749
exemplary, or consequential damages (including, but not limited to,
1750
procurement of substitute goods or services; loss of use, data, or
1751
profits; or business interruption) however caused and on any theory of
1752
liability, whether in contract, strict liability, or tort (including
1753
negligence or otherwise) arising in any way out of the use of this
1754
software, even if advised of the possibility of such damage.
1755
1756
*/
1757
endif;