/
MarkdownHelper.php
129 lines (112 loc) · 3.05 KB
/
MarkdownHelper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
App::uses('AppHelper', 'View/Helper');
App::import('Vendor', 'Markdown/Markdown');
class MarkdownHelper extends AppHelper {
/**
* settings
*/
public $settings = array();
/**
* parser
*/
protected $parser;
/**
* defaultSettings
*/
protected $defaultSettings = array(
'run' => 'afterRender'
);
/**
* __construct
*
* @param View $View
* @param array $settings
*/
public function __construct(View $View, $settings = array()) {
$this->settings = $this->defaultSettings + $settings;
$this->parser = new PhaseMarkdownParser();
if (!empty($View->request->params['ext'])) {
$ext = $View->request->params['ext'];
if ($ext !== 'html') {
$this->settings['run'] = 'never';
}
}
return parent::__construct($View, $settings);
}
/**
* afterRender
*
* @param mixed $filename
*/
public function afterRender($filename) {
if ($this->settings['run'] !== 'afterRender') {
return;
}
$this->_View->output = $this->process($this->_View->output);
}
/**
* process
*
* @param string $input
*/
public function process($input = '') {
return $this->parser->transform($input);
}
}
/**
* PhaseMarkdownParser
*
* Overridden to inject automatic header anchor links
*/
class PhaseMarkdownParser extends MarkdownExtra_Parser {
/**
* headerIds
*
* Stack of ids already used in header links
*/
protected $headerIds = array();
function _doHeaders_callback_atx($matches) {
if (empty($matches[3])) {
$matches[3] = Inflector::slug($matches[2], '-');
}
$link = $this->getAnchorLink($matches[3]);
$level = strlen($matches[1]);
$attr = $this->_doHeaders_attr($id =& $matches[3]);
$block = "<h$level$attr>".$this->runSpanGamut($matches[2])."$link</h$level>";
return "\n" . $this->hashBlock($block) . "\n\n";
}
/**
* _doHeaders_callback_setext
*
* @param mixed $matches
*/
function _doHeaders_callback_setext($matches) {
if (!$matches[2]) {
$matches[2] = Inflector::slug($matches[1], '-');
}
$link = $this->getAnchorLink($matches[2]);
if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
return $matches[0];
$level = $matches[3]{0} == '=' ? 1 : 2;
$attr = $this->_doHeaders_attr($id =& $matches[2]);
$block = "<h$level$attr>".$this->runSpanGamut($matches[1])."$link</h$level>";
return "\n" . $this->hashBlock($block) . "\n\n";
}
/**
* getAnchorLink
*
* Generate a unique id, and return a link pointing at it
*
* @param mixed $id
*/
protected function getAnchorLink(&$id) {
$i = 0;
$suffix = '';
while (in_array($id . $suffix, $this->headerIds)) {
$suffix = '-' . ++$i;
}
$id .= $suffix;
$this->headerIds[] = $id;
return '<a class="headerAnchor" href="#' . $id . '">§</a>';
}
}