Skip to content

Commit ba5d10a

Browse files
Merge pull request #8349 from Sesquipedalian/3.0/markdown
2 parents fa83011 + 95d6b70 commit ba5d10a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+6345
-1498
lines changed

Languages/en_US/Admin.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,9 +586,10 @@
586586
$txt['manageposts_settings'] = 'Post Settings';
587587
$txt['manageposts_settings_description'] = 'Here you can set everything related to posts and posting.';
588588

589-
$txt['manageposts_bbc_settings'] = 'Bulletin Board Code';
590-
$txt['manageposts_bbc_settings_description'] = 'Bulletin board code can be used to add markup to forum messages. For example, to highlight the word "house" you can type [b]house[/b]. All Bulletin board code tags are surrounded by square brackets ("[" and "]").';
589+
$txt['manageposts_bbc_settings'] = 'Bulletin Board Code & Markdown';
590+
$txt['manageposts_bbc_settings_description'] = 'Bulletin board code and Markdown can be used to add markup to forum messages. For example, to highlight the word "house" you can type [b]house[/b] (using BBC) or **house** (using Markdown). All bulletin board code tags are surrounded by square brackets ("[" and "]"). <a href="https://commonmark.org/help/" target="_blank">Markdown syntax</a> is a little more complicated, but not too hard.';
591591
$txt['manageposts_bbc_settings_title'] = 'Bulletin Board Code settings';
592+
$txt['manageposts_markdown_settings_title'] = 'Markdown settings';
592593

593594
$txt['manageposts_topic_settings'] = 'Topic Settings';
594595
$txt['manageposts_topic_settings_description'] = 'Here you can set all settings involving topics.';
@@ -630,6 +631,10 @@
630631
$txt['enabled_bbc_select_all'] = 'Select all tags';
631632
$txt['groups_can_use'] = 'Membergroups allowed to use {0}';
632633

634+
$txt['enableMarkdown'] = 'Enable Markdown';
635+
$txt['collapse_blank_lines'] = 'Collapse extra blank lines';
636+
$txt['collapse_single_breaks'] = 'Clean up line breaks inside paragraphs';
637+
633638
$txt['enableParticipation'] = 'Enable participation icons';
634639
$txt['oldTopicDays'] = 'Time before topic is warned as old on reply';
635640
$txt['defaultMaxTopics'] = 'Number of topics per page in the message index';

Languages/en_US/Editor.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
$editortxt['insert_table'] = 'Insert a table';
3434
$editortxt['insert_horizontal_rule'] = 'Insert a horizontal rule';
3535
$editortxt['code'] = 'Code';
36+
$editortxt['tt'] = 'Inline code';
3637
$editortxt['insert_quote'] = 'Insert a Quote';
3738
$editortxt['width'] = 'Width (optional):';
3839
$editortxt['height'] = 'Height (optional):';
@@ -60,5 +61,6 @@
6061
$editortxt['float_right'] = 'Float right';
6162
$editortxt['maximize'] = 'Maximize';
6263
$editortxt['dateformat'] = 'month/day/year';
64+
$editortxt['heading'] = 'Heading';
6365

6466
?>

Languages/en_US/Help.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@
337337
<li>&lt;pre&gt;, &lt;blockquote&gt;</li>
338338
</ul>';
339339

340+
$helptxt['enableMarkdown'] = 'Enabling this setting will allow your members to use Markdown throughout the forum, providing them with an alternative syntax to format their posts.<br><br>Note that, unlike pure Markdown, SMF’s implementation does not allow authors to embed raw HTML into their posts except as permitted by the "Enable basic HTML in posts" setting.';
341+
$helptxt['collapse_blank_lines'] = 'Enabling this setting will remove unnecessary blank lines in post content, resulting in more consistent formatting in the output. Leave it disabled to preserve the blank lines.<br><br>This feature is only available when Markdown support is enabled.';
342+
$helptxt['collapse_single_breaks'] = 'Enabling this setting will remove single line breaks inside paragraphs, resulting in more consistent formatting in the output. Leave it disabled to preserve the line breaks.<br><br>Even when this feature is enabled, authors can still force line breaks to happen by using the [br] BBCode or by ending the line with a backslash character or with two or more spaces.<br><br>This feature is only available when Markdown support is enabled.';
343+
340344
$helptxt['themes_manage'] = 'Here you can install new themes and select which themes your users can choose from, the default theme that new users and guests will use, as well as other theme selection settings.';
341345
$helptxt['theme_install'] = 'This allows you to install new themes. You can do this from an existing directory, by uploading an archive for the theme, or by copying the default theme.<br><br>Note that the archive or directory must have a <pre>theme_info.xml</pre> definition file.';
342346
$helptxt['xmlnews_enable'] = 'Allows people to link to <a href="{scripturl}?action=.xml;sa=news" target="_blank" rel="noopener">Recent news</a>

Sources/Actions/Admin/ACP.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use SMF\Actions\MessageIndex;
2020
use SMF\Actions\Notify;
2121
use SMF\ActionTrait;
22-
use SMF\BBCodeParser;
2322
use SMF\Cache\CacheApi;
2423
use SMF\Config;
2524
use SMF\Db\DatabaseApi as Db;
@@ -28,6 +27,7 @@
2827
use SMF\Lang;
2928
use SMF\Mail;
3029
use SMF\Menu;
30+
use SMF\Parser;
3131
use SMF\SecurityToken;
3232
use SMF\Theme;
3333
use SMF\Url;
@@ -976,7 +976,7 @@ public static function prepareDBSettingContext(array &$config_vars): void
976976
// What about any BBC selection boxes?
977977
if (!empty($bbcChoice)) {
978978
// What are the options, eh?
979-
$temp = BBCodeParser::getCodes();
979+
$temp = Parser::getBBCodes();
980980
$bbcTags = [];
981981

982982
foreach ($temp as $tag) {
@@ -1351,7 +1351,7 @@ public static function saveDBSettings(array &$config_vars): void
13511351
elseif ($var[0] == 'bbc') {
13521352
$bbcTags = [];
13531353

1354-
foreach (BBCodeParser::getCodes() as $tag) {
1354+
foreach (Parser::getBBCodes() as $tag) {
13551355
$bbcTags[] = $tag['tag'];
13561356
}
13571357

Sources/Actions/Admin/Boards.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use SMF\ActionInterface;
1919
use SMF\Actions\BackwardCompatibility;
2020
use SMF\ActionTrait;
21-
use SMF\BBCodeParser;
2221
use SMF\Board;
2322
use SMF\Category;
2423
use SMF\Config;
@@ -28,6 +27,7 @@
2827
use SMF\IntegrationHook;
2928
use SMF\Lang;
3029
use SMF\Menu;
30+
use SMF\Parser;
3131
use SMF\SecurityToken;
3232
use SMF\Theme;
3333
use SMF\Url;
@@ -366,7 +366,7 @@ public function editCategory2(): void
366366

367367
// Try to get any valid HTML to BBC first, add a naive attempt to strip it off, htmlspecialchars for the rest
368368
$catOptions['cat_name'] = Utils::htmlspecialchars(strip_tags($_POST['cat_name']));
369-
$catOptions['cat_desc'] = Utils::htmlspecialchars(strip_tags(BBCodeParser::load()->unparse($_POST['cat_desc'])));
369+
$catOptions['cat_desc'] = Utils::htmlspecialchars(strip_tags(Parser::transform($_POST['cat_desc'], Parser::OUTPUT_BBC)));
370370
$catOptions['is_collapsible'] = isset($_POST['collapse']);
371371

372372
if (isset($_POST['add'])) {
@@ -677,7 +677,7 @@ public function editBoard2(): void
677677

678678
// Try to get any valid HTML to BBC first, add a naive attempt to strip it off, htmlspecialchars for the rest
679679
$boardOptions['board_name'] = Utils::htmlspecialchars(strip_tags($_POST['board_name']));
680-
$boardOptions['board_description'] = Utils::htmlspecialchars(strip_tags(BBCodeParser::load()->unparse($_POST['desc'])));
680+
$boardOptions['board_description'] = Utils::htmlspecialchars(strip_tags(Parser::transform($_POST['desc'], Parser::OUTPUT_BBC)));
681681

682682
$boardOptions['moderator_string'] = $_POST['moderators'];
683683

Sources/Actions/Admin/ErrorLog.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717

1818
use SMF\ActionInterface;
1919
use SMF\ActionTrait;
20-
use SMF\BBCodeParser;
2120
use SMF\Config;
2221
use SMF\Db\DatabaseApi as Db;
2322
use SMF\ErrorHandler;
2423
use SMF\IP;
2524
use SMF\Lang;
2625
use SMF\PageIndex;
26+
use SMF\Parser;
2727
use SMF\SecurityToken;
2828
use SMF\Theme;
2929
use SMF\Time;
@@ -318,11 +318,11 @@ public function view(): void
318318
} elseif ($this->filter['variable'] == 'url') {
319319
Utils::$context['filter']['value']['html'] = '\'' . strtr(Utils::htmlspecialchars((str_starts_with($this->filter['value']['sql'], '?') ? Config::$scripturl : '') . $this->filter['value']['sql']), ['\\_' => '_']) . '\'';
320320
} elseif ($this->filter['variable'] == 'message') {
321-
Utils::$context['filter']['value']['html'] = '\'' . strtr(Utils::htmlspecialchars($this->filter['value']['sql']), ["\n" => '<br>', '&lt;br /&gt;' => '<br>', "\t" => '&nbsp;&nbsp;&nbsp;', '\\_' => '_', '\\%' => '%', '\\\\' => '\\']) . '\'';
321+
Utils::$context['filter']['value']['html'] = '\'' . strtr(Utils::htmlspecialchars($this->filter['value']['sql']), ["\n" => '<br>', '&lt;br /&gt;' => '<br>', "\t" => Utils::TAB_SUBSTITUTE, '\\_' => '_', '\\%' => '%', '\\\\' => '\\']) . '\'';
322322

323323
Utils::$context['filter']['value']['html'] = preg_replace('~&amp;lt;span class=&amp;quot;remove&amp;quot;&amp;gt;(.+?)&amp;lt;/span&amp;gt;~', '$1', Utils::$context['filter']['value']['html']);
324324
} elseif ($this->filter['variable'] == 'error_type') {
325-
Utils::$context['filter']['value']['html'] = '\'' . strtr(Utils::htmlspecialchars($this->filter['value']['sql']), ["\n" => '<br>', '&lt;br /&gt;' => '<br>', "\t" => '&nbsp;&nbsp;&nbsp;', '\\_' => '_', '\\%' => '%', '\\\\' => '\\']) . '\'';
325+
Utils::$context['filter']['value']['html'] = '\'' . strtr(Utils::htmlspecialchars($this->filter['value']['sql']), ["\n" => '<br>', '&lt;br /&gt;' => '<br>', "\t" => Utils::TAB_SUBSTITUTE, '\\_' => '_', '\\%' => '%', '\\\\' => '\\']) . '\'';
326326
} else {
327327
Utils::$context['filter']['value']['html'] = &$this->filter['value']['sql'];
328328
}
@@ -430,7 +430,7 @@ public function viewFile(): void
430430
ErrorHandler::fatalLang('error_bad_line');
431431
}
432432

433-
$file_data = explode('<br />', BBCodeParser::highlightPhpCode(Utils::htmlspecialchars(file_get_contents($file))));
433+
$file_data = explode('<br />', Parser::highlightPhpCode(Utils::htmlspecialchars(file_get_contents($file))));
434434

435435
// We don't want to slice off too many so lets make sure we stop at the last one
436436
$max = min($max, max(array_keys($file_data)));

Sources/Actions/Admin/Features.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use SMF\Actions\BackwardCompatibility;
2020
use SMF\Actions\Profile\Notification;
2121
use SMF\ActionTrait;
22-
use SMF\BBCodeParser;
2322
use SMF\Config;
2423
use SMF\Db\DatabaseApi as Db;
2524
use SMF\ErrorHandler;
@@ -28,6 +27,8 @@
2827
use SMF\ItemList;
2928
use SMF\Lang;
3029
use SMF\Menu;
30+
use SMF\Parser;
31+
use SMF\Parsers\MarkdownParser;
3132
use SMF\Profile;
3233
use SMF\Sapi;
3334
use SMF\SecurityToken;
@@ -165,6 +166,10 @@ public function bbc(): void
165166
// Legacy BBC are listed separately, but we use the same info in both cases
166167
Config::$modSettings['bbc_disabled_legacyBBC'] = Config::$modSettings['bbc_disabled_disabledBBC'];
167168

169+
// The Markdown settings for handling line breaks are actually a single bitmask.
170+
Config::$modSettings['collapse_blank_lines'] = (int) !((Config::$modSettings['markdown_brs'] ?? 0) & MarkdownParser::BR_LINES);
171+
Config::$modSettings['collapse_single_breaks'] = (int) !((Config::$modSettings['markdown_brs'] ?? 0) & MarkdownParser::BR_IN_PARAGRAPHS);
172+
168173
$extra = '';
169174

170175
if (isset($_REQUEST['cowsay'])) {
@@ -180,7 +185,7 @@ public function bbc(): void
180185
$bbcTags = [];
181186
$bbcTagsChildren = [];
182187

183-
foreach (BBCodeParser::getCodes() as $tag) {
188+
foreach (Parser::getBBCodes() as $tag) {
184189
$bbcTags[] = $tag['tag'];
185190

186191
if (isset($tag['require_children'])) {
@@ -189,8 +194,8 @@ public function bbc(): void
189194
}
190195

191196
// Clean up tags with children
192-
foreach($bbcTagsChildren as $parent_tag => $children) {
193-
foreach($children as $index => $child_tag) {
197+
foreach ($bbcTagsChildren as $parent_tag => $children) {
198+
foreach ($children as $index => $child_tag) {
194199
// Remove entries where parent and child tag is the same
195200
if ($child_tag == $parent_tag) {
196201
unset($bbcTagsChildren[$parent_tag][$index]);
@@ -239,6 +244,12 @@ function ($config_var) {
239244
},
240245
);
241246

247+
// Save the Markdown collapse_* settings as a bitmask.
248+
$config_vars[] = ['int', 'markdown_brs'];
249+
$_POST['markdown_brs'] = (!empty($_POST['collapse_blank_lines']) ? 0 : MarkdownParser::BR_LINES);
250+
$_POST['markdown_brs'] |= (!empty($_POST['collapse_single_breaks']) ? 0 : MarkdownParser::BR_IN_PARAGRAPHS);
251+
unset($_POST['collapse_blank_lines'], $_POST['collapse_single_breaks']);
252+
242253
IntegrationHook::call('integrate_save_bbc_settings', [$bbcTags]);
243254

244255
ACP::saveDBSettings($config_vars);
@@ -581,7 +592,7 @@ public function signature(): void
581592
// Clean up the tag stuff!
582593
$bbcTags = [];
583594

584-
foreach (BBCodeParser::getCodes() as $tag) {
595+
foreach (Parser::getBBCodes() as $tag) {
585596
$bbcTags[] = $tag['tag'];
586597
}
587598

@@ -1024,7 +1035,7 @@ public function profileEdit(): void
10241035
[],
10251036
);
10261037

1027-
while($row = Db::$db->fetch_assoc($request)) {
1038+
while ($row = Db::$db->fetch_assoc($request)) {
10281039
$fields[] = $row['id_field'];
10291040
}
10301041
Db::$db->free_result($request);
@@ -1613,6 +1624,12 @@ public static function bbcConfigVars(): array
16131624

16141625
// This one is actually pretend...
16151626
['bbc', 'legacyBBC', 'help' => 'legacy_bbc'],
1627+
1628+
// Markdown settings
1629+
['title', 'markdown_settings', 'text_label' => Lang::$txt['manageposts_markdown_settings_title']],
1630+
['check', 'enableMarkdown', 'onchange' => 'document.getElementById(\'collapse_blank_lines\').disabled = !this.checked; document.getElementById(\'collapse_single_breaks\').disabled = !this.checked;'],
1631+
['check', 'collapse_blank_lines', 'disabled' => empty(Config::$modSettings['enableMarkdown'])],
1632+
['check', 'collapse_single_breaks', 'disabled' => empty(Config::$modSettings['enableMarkdown'])],
16161633
];
16171634

16181635
// Permissions for restricted BBC

Sources/Actions/Admin/News.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use SMF\Actions\BackwardCompatibility;
2020
use SMF\Actions\Notify;
2121
use SMF\ActionTrait;
22-
use SMF\BBCodeParser;
2322
use SMF\Config;
2423
use SMF\Db\DatabaseApi as Db;
2524
use SMF\Editor;
@@ -31,6 +30,7 @@
3130
use SMF\Mail;
3231
use SMF\Menu;
3332
use SMF\Msg;
33+
use SMF\Parser;
3434
use SMF\PersonalMessage\PM;
3535
use SMF\SecurityToken;
3636
use SMF\Theme;
@@ -197,7 +197,7 @@ function addNewsItem ()
197197

198198
' + last_preview + ' .
199199

200-
'{js_escape:" style="overflow: auto; width: 100%; height: 10ex;"></div>
200+
'{js_escape:" style="overflow: auto; width: 100%; min-height: 10ex;"></div>
201201
</td>
202202
<td></td>
203203
</tr>}' .
@@ -1106,7 +1106,7 @@ public static function list_getNews(): array
11061106
$admin_current_news[$id] = [
11071107
'id' => $id,
11081108
'unparsed' => Msg::un_preparsecode($line),
1109-
'parsed' => preg_replace('~<([/]?)form[^>]*?[>]*>~i', '<em class="smalltext">&lt;$1form&gt;</em>', BBCodeParser::load()->parse($line)),
1109+
'parsed' => preg_replace('~<([/]?)form[^>]*?[>]*>~i', '<em class="smalltext">&lt;$1form&gt;</em>', Parser::transform($line)),
11101110
];
11111111
}
11121112

@@ -1141,7 +1141,7 @@ public static function list_getNewsTextarea(array $news): string
11411141
*/
11421142
public static function list_getNewsPreview(array $news): string
11431143
{
1144-
return '<div id="box_preview_' . $news['id'] . '" style="overflow: auto; width: 100%; height: 10ex;">' . $news['parsed'] . '</div>';
1144+
return '<div id="box_preview_' . $news['id'] . '" style="overflow: auto; width: 100%; min-height: 10ex;">' . Utils::adjustHeadingLevels($news['parsed'], null) . '</div>';
11451145
}
11461146

11471147
/**
@@ -1193,7 +1193,7 @@ public static function prepareMailingForPreview(): void
11931193
if (!empty(Utils::$context['send_html'])) {
11941194
$enablePostHTML = Config::$modSettings['enablePostHTML'];
11951195
Config::$modSettings['enablePostHTML'] = Utils::$context['send_html'];
1196-
Utils::$context[$key] = BBCodeParser::load()->parse(Utils::$context[$key]);
1196+
Utils::$context[$key] = Parser::transform(Utils::$context[$key]);
11971197
Config::$modSettings['enablePostHTML'] = $enablePostHTML;
11981198
}
11991199

Sources/Actions/Admin/Smileys.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use SMF\Actions\BackwardCompatibility;
2222
use SMF\Actions\MessageIndex;
2323
use SMF\ActionTrait;
24-
use SMF\BBCodeParser;
2524
use SMF\Cache\CacheApi;
2625
use SMF\Config;
2726
use SMF\Db\DatabaseApi as Db;
@@ -33,6 +32,7 @@
3332
use SMF\Menu;
3433
use SMF\Msg;
3534
use SMF\PackageManager\SubsPackage;
35+
use SMF\Parser;
3636
use SMF\SecurityToken;
3737
use SMF\Theme;
3838
use SMF\User;
@@ -1622,7 +1622,7 @@ public function install(): void
16221622

16231623
if (!empty($action['parse_bbc'])) {
16241624
Msg::preparsecode(Utils::$context[$type]);
1625-
Utils::$context[$type] = BBCodeParser::load()->parse(Utils::$context[$type]);
1625+
Utils::$context[$type] = Parser::transform(Utils::$context[$type]);
16261626
} else {
16271627
Utils::$context[$type] = nl2br(Utils::$context[$type]);
16281628
}
@@ -1671,7 +1671,7 @@ public function install(): void
16711671
Utils::$context['is_installed'] = false;
16721672
Utils::$context['package_name'] = $smileyInfo['name'];
16731673

1674-
loadTemplate('Packages');
1674+
Theme::loadTemplate('Packages');
16751675
}
16761676
// Do the actual install
16771677
else {
@@ -2248,7 +2248,7 @@ protected function __construct()
22482248
User::$me->isAllowedTo('manage_smileys');
22492249

22502250
Lang::load('ManageSmileys');
2251-
loadTemplate('ManageSmileys');
2251+
Theme::loadTemplate('ManageSmileys');
22522252

22532253
// If customized smileys is disabled don't show the setting page
22542254
if (empty(Config::$modSettings['smiley_enable'])) {

Sources/Actions/Agreement.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717

1818
use SMF\ActionInterface;
1919
use SMF\ActionTrait;
20-
use SMF\BBCodeParser;
2120
use SMF\Config;
2221
use SMF\ErrorHandler;
2322
use SMF\Lang;
23+
use SMF\Parser;
2424
use SMF\Theme;
2525
use SMF\User;
2626
use SMF\Utils;
@@ -148,7 +148,10 @@ protected function prepareAgreementContext(): void
148148

149149
if (!empty(Utils::$context['agreement_file'])) {
150150
$cache_id = strtr(Utils::$context['agreement_file'], [Config::$languagesdir => '', '.txt' => '', '.' => '_']);
151-
Utils::$context['agreement'] = BBCodeParser::load()->parse(file_get_contents(Utils::$context['agreement_file']), true, $cache_id);
151+
Utils::$context['agreement'] = Parser::transform(
152+
string: file_get_contents(Utils::$context['agreement_file']),
153+
options: ['cache_id' => $cache_id, 'hard_breaks' => 0],
154+
);
152155
} elseif (Utils::$context['can_accept_agreement']) {
153156
ErrorHandler::fatalLang('error_no_agreement', false);
154157
}
@@ -157,9 +160,15 @@ protected function prepareAgreementContext(): void
157160
if (!Utils::$context['accept_doc'] || Utils::$context['can_accept_privacy_policy']) {
158161
// Have we got a localized policy?
159162
if (!empty(Config::$modSettings['policy_' . User::$me->language])) {
160-
Utils::$context['privacy_policy'] = BBCodeParser::load()->parse(Config::$modSettings['policy_' . User::$me->language]);
163+
Utils::$context['privacy_policy'] = Parser::transform(
164+
string: Config::$modSettings['policy_' . User::$me->language],
165+
options: ['hard_breaks' => 0],
166+
);
161167
} elseif (!empty(Config::$modSettings['policy_' . Lang::$default])) {
162-
Utils::$context['privacy_policy'] = BBCodeParser::load()->parse(Config::$modSettings['policy_' . Lang::$default]);
168+
Utils::$context['privacy_policy'] = Parser::transform(
169+
string: Config::$modSettings['policy_' . Lang::$default],
170+
options: ['hard_breaks' => 0],
171+
);
163172
}
164173
// Then I guess we've got nothing
165174
elseif (Utils::$context['can_accept_privacy_policy']) {

0 commit comments

Comments
 (0)