Skip to content

Commit f744910

Browse files
authored
Merge pull request #331 from topcoder-platform/issues-309
Issues-309: added callback for anchors
2 parents 7503f61 + 81413ea commit f744910

File tree

2 files changed

+303
-1
lines changed

2 files changed

+303
-1
lines changed

config/vanilla/config.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,4 +196,6 @@
196196
$Configuration['Garden']['Upload']['MaxFileSize'] = '5M';
197197
$Configuration['Garden']['Upload']['AllowedFileExtensions'] = [
198198
'txt', 'jpg', 'jpeg', 'gif', 'png', 'bmp', 'tiff', 'ico', 'zip', 'gz', 'tar.gz', 'tgz', 'psd', 'ai', 'pdf', 'doc', 'xls', 'ppt', 'docx', 'xlsx', 'pptx', 'log', 'rar', '7z', 'xml', 'json'
199-
];
199+
];
200+
// Allow "target='_blank'" for Markdown format;
201+
$Configuration['Garden']['Html']['BlockedAttributes']='on*, download';
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
<?php
2+
3+
/**
4+
* @copyright 2009-2019 Vanilla Forums Inc.
5+
* @license GPL-2.0-only
6+
*/
7+
8+
/**
9+
* Vanilla Markdown Override
10+
*
11+
* This class extends the Markdown vendor library to add some optional
12+
* customizations to the rendering process.
13+
*
14+
* @author Tim Gunter <tim@vanillaforums.com>
15+
* @package core
16+
* @since 2.2
17+
*/
18+
class MarkdownVanilla extends \Michelf\MarkdownExtra {
19+
20+
/**
21+
* Add all Vanilla customizations to markdown parsing
22+
*
23+
* @return void
24+
*/
25+
public function addAllFlavor() {
26+
$this->addStrikeout();
27+
$this->addBreaks();
28+
$this->addSpoilers();
29+
$this->addListFix();
30+
31+
// Sort gamuts by their priority.
32+
asort($this->block_gamut);
33+
asort($this->span_gamut);
34+
}
35+
36+
/**
37+
* Add soft breaks to markdown parsing
38+
*
39+
* @return void
40+
*/
41+
public function addBreaks() {
42+
$this->span_gamut = array_replace($this->span_gamut, [
43+
'doStrikeout' => 15,
44+
'doSoftBreaks' => 80,
45+
]);
46+
}
47+
48+
/**
49+
* Add strikeouts to markdown parsing
50+
*
51+
* @return void
52+
*/
53+
public function addStrikeout() {
54+
$this->span_gamut = array_replace($this->span_gamut, [
55+
'doStrikeout' => 15,
56+
]);
57+
}
58+
59+
/**
60+
* Add spoilers to markdown parsing
61+
*
62+
* @return void
63+
*/
64+
public function addSpoilers() {
65+
$this->block_gamut = array_replace($this->block_gamut, [
66+
'doSpoilers' => 55,
67+
]);
68+
}
69+
70+
71+
/**
72+
* Don't require a newline for unordered lists to be recognized.
73+
*
74+
* @return void
75+
*/
76+
public function addListFix() {
77+
$this->block_gamut = array_replace($this->block_gamut, [
78+
'doListFix' => 39
79+
]);
80+
}
81+
82+
83+
/**
84+
* Add Spoilers implementation (3 methods).
85+
*
86+
* @param string $text
87+
* @return string
88+
*/
89+
protected function doSpoilers($text) {
90+
$text = preg_replace_callback(
91+
'/( # Wrap whole match in $1
92+
(?>
93+
^[ ]*>![ ]? # ">" at the start of a line
94+
.+\n # rest of the first line
95+
\n* # blanks
96+
)+
97+
)/xm',
98+
[$this, '_doSpoilers_callback'],
99+
$text
100+
);
101+
102+
return $text;
103+
}
104+
protected function _doSpoilers_callback($matches) {
105+
$bq = $matches[1];
106+
# trim one level of quoting - trim whitespace-only lines
107+
$bq = preg_replace('/^[ ]*>![ ]?|^[ ]+$/m', '', $bq);
108+
$bq = $this->runBlockGamut($bq); # recurse
109+
110+
$bq = preg_replace('/^/m', " ", $bq);
111+
# These leading spaces cause problem with <pre> content,
112+
# so we need to fix that:
113+
$bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
114+
[&$this, '_doSpoilers_callback2'], $bq);
115+
116+
return "\n". $this->hashBlock(Gdn_Format::spoilerHtml($bq))."\n\n";
117+
}
118+
protected function _doSpoilers_callback2($matches) {
119+
$pre = $matches[1];
120+
$pre = preg_replace('/^ /m', '', $pre);
121+
return $pre;
122+
}
123+
124+
/**
125+
* Add Strikeout implementation (2 methods).
126+
*
127+
* @param string $text
128+
* @return string
129+
*/
130+
protected function doStrikeout($text) {
131+
$text = preg_replace_callback('/
132+
~~ # open
133+
(.+?) # $1 = strike text
134+
~~ # close
135+
/xm',
136+
[$this, '_doStrikeout_callback'], $text);
137+
return $text;
138+
}
139+
protected function _doStrikeout_callback($matches) {
140+
return $this->hashPart("<s>".$this->runSpanGamut($matches[1])."</s>");
141+
}
142+
143+
/**
144+
* Add soft line breaks implementation (2 methods).
145+
*
146+
* @param string $text
147+
* @return string
148+
*/
149+
protected function doSoftBreaks($text) {
150+
# Do soft line breaks for 1 return:
151+
return preg_replace_callback('/\n{1}/',
152+
[$this, '_doSoftBreaks_callback'], $text);
153+
}
154+
protected function _doSoftBreaks_callback($matches) {
155+
return $this->hashPart("<br$this->empty_element_suffix\n");
156+
}
157+
158+
/**
159+
* Work around php-markdown's non-standard implementation of lists.
160+
* Allows starting unordered lists without a newline.
161+
*
162+
* @param string $text
163+
* @return string
164+
*/
165+
protected function doListFix($text) {
166+
return preg_replace('/(^[^\n*+-].*\n)([*+-] )/m', "$1\n$2", $text);
167+
}
168+
169+
/**
170+
* Parse Markdown blockquotes to HTML.
171+
*
172+
* Vanilla override.
173+
*
174+
* @override
175+
* @param string $text
176+
* @return string
177+
*/
178+
protected function doBlockQuotes($text) {
179+
return preg_replace_callback(
180+
'/( # Wrap whole match in $1
181+
(?>
182+
^[ ]*>[ ]? # ">" at the start of a line
183+
.+\n # rest of the first line
184+
\n* # blanks
185+
)+
186+
)/xm',
187+
[$this, '_doBlockQuotes_callback'],
188+
$text
189+
);
190+
}
191+
/**
192+
* Blockquote parsing callback.
193+
*
194+
* Vanilla override.
195+
*
196+
* @param array $matches
197+
* @return string
198+
*/
199+
protected function _doBlockQuotes_callback($matches) {
200+
$bq = $matches[1];
201+
// trim one level of quoting - trim whitespace-only lines
202+
$bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
203+
$bq = $this->runBlockGamut($bq); // recurse
204+
205+
$bq = preg_replace('/^/m', " ", $bq);
206+
// These leading spaces cause problem with <pre> content,
207+
// so we need to fix that:
208+
$bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
209+
[$this, '_doBlockQuotes_callback2'], $bq);
210+
211+
// return "\n" . $this->hashBlock("<blockquote>\n$bq\n</blockquote>") . "\n\n";
212+
return "\n" . $this->hashBlock("<blockquote class=\"UserQuote\"><div class=\"QuoteText\">\n$bq\n</div></blockquote>") . "\n\n";
213+
}
214+
215+
/**
216+
* Create a code span markup for $code. Called from handleSpanToken.
217+
*
218+
* Vanilla override.
219+
*
220+
* @param string $code
221+
* @return string
222+
*/
223+
protected function makeCodeSpan($code) {
224+
$code = str_replace(["\r", "\n"], ' ', $code);
225+
return parent::makeCodeSpan($code);
226+
}
227+
228+
/**
229+
* Callback for inline images
230+
* @param array $matches
231+
* @return string
232+
*/
233+
protected function _doImages_inline_callback($matches) {
234+
$whole_match = $matches[1];
235+
$alt_text = $matches[2];
236+
$url = $matches[3] == '' ? $matches[4] : $matches[3];
237+
$title =& $matches[7];
238+
$attr = $this->doExtraAttributes("img", $dummy =& $matches[8]);
239+
240+
$alt_text = $this->encodeAttribute($alt_text);
241+
$url = $this->encodeURLAttribute($url);
242+
$result = "<a href=\"$url\" target=\"_blank\"><img src=\"$url\" alt=\"$alt_text\"";
243+
if (isset($title)) {
244+
$title = $this->encodeAttribute($title);
245+
$result .= " title=\"$title\""; // $title already quoted
246+
}
247+
$result .= $attr;
248+
$result .= $this->empty_element_suffix;
249+
$result .= "</a>";
250+
return $this->hashPart($result);
251+
}
252+
253+
/**
254+
* Callback for inline anchors
255+
* @param array $matches
256+
* @return string
257+
*/
258+
protected function _doAnchors_inline_callback($matches) {
259+
$whole_match = $matches[1];
260+
$link_text = $this->runSpanGamut($matches[2]);
261+
$url = $matches[3] == '' ? $matches[4] : $matches[3];
262+
$title =& $matches[7];
263+
$attr = $this->doExtraAttributes("a", $dummy =& $matches[8]);
264+
265+
// if the URL was of the form <s p a c e s> it got caught by the HTML
266+
// tag parser and hashed. Need to reverse the process before using the URL.
267+
$unhashed = $this->unhash($url);
268+
if ($unhashed != $url)
269+
$url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
270+
271+
$url = $this->encodeURLAttribute($url);
272+
273+
//FIX: process url
274+
$url = $this->processUrl($url);
275+
276+
$result = "<a href=\"$url\" target=\"_blank\"";
277+
if (isset($title)) {
278+
$title = $this->encodeAttribute($title);
279+
$result .= " title=\"$title\"";
280+
}
281+
$result .= $attr;
282+
283+
$link_text = $this->runSpanGamut($link_text);
284+
$result .= ">$link_text</a>";
285+
return $this->hashPart($result);
286+
}
287+
288+
/**
289+
* Call a custom function
290+
* @param $url
291+
* @return string
292+
*/
293+
function processUrl($url) {
294+
if(function_exists('file_embed_process_url')) {
295+
$url = file_embed_process_url($url);
296+
}
297+
return $url;
298+
}
299+
300+
}

0 commit comments

Comments
 (0)