showdown
showdown copied to clipboard
Support for "reddit" flavor markdown
Reddit has some markdown differences and it would be nice to automatically be able to convert Reddit markdown to HTML for displaying on web pages.
Most important differences are the superscript and table syntax.
Other features would be nice but not necessary.
Reddit-specific extensions
-
Superscript — Reddit has its own syntax (
^text,^(multiple words)) Nesting is supported (one^two^three) -
Strikethrough — Reddit's syntax is different from the GFM extension (
~~strikethrough~~) (Works already whenstrikethrough: trueis set) -
Spoilertext — Spoilertext (
>!spoiler!<) is Reddit-specific. (Can be ignored as I don't think there is standard HTML for this?) Possibly a class (eg.<span class='md-spoiler-text'>) can be used for allowing custom styling and scripts? -
Redditlinks and userlinks — Names of subreddits and Reddit users, prefixed with
/r/,r/,/u/, andu/, are automatically linked. (Not critical, but would be a cool addition) Would be similar to GitHub mention support. -
Rich text media — Reddit supports submissions containing images, videos, and gifs, and these are encoded into the Markdown with a customized inline image syntax. This feature is only supported by the Fancy Pants editor — the syntax would be prohibitively difficult to write manually at present. (Probably not worth implementing?)
Other differences
- Tables — Tables on reddit can have only a single dash for alignment, for example:
| **Normal** | **Center** | **Left** | **Right** |
|-|:-:|:-|-:|
| A | B | C | D |
Currently with showdown, this only becomes a table when center is written as :--:, right as --: and left as :-- or --.
| **Normal** | **Center** | **Left** | **Right** |
|--|:--:|:--|--:|
| A | B | C | D |
>with no space currently does not create blockquotes or support other markdown
>#Header 1
>##Header 2
>###Header 3
>####Header 4
>#####Header 5
>######Header 6
Expected:
Actual:

- Lists should order starting from 1
7. Item 1
2. Item 2
5. Item 3
Expected:
Actual:

- Bullets on same line as ordered list number
1. Ordered list item 1
2. * Bullet 1 in list item 2
* Bullet 2 in list item 2
3. List item 3
Expected:
Actual:

See reference: https://www.reddit.com/wiki/markdown
Current workaround
(This only solves part of the issues)
const mdConverter = new showdown.Converter({
tables: true,
simplifiedAutoLink: true,
literalMidWordUnderscores: true,
strikethrough: true,
ghCodeBlocks: true,
disableForced4SpacesIndentedSublists: true,
});
function redditPostToHTML(original) {
// fix Reddit tables to have at least two dashes per cell in the alignment row
let body = original.replace(/(?<=^\s*|\|\s*)(:?)-(:?)(?=\s*\|[-|\s:]*$)/gm, "$1--$2");
// convert superscripts in the form "^(some text)" or "^text" to <sup>text</sup>
const multiwordSuperscriptRegex = /\^\((.+?)\)/gm;
while (multiwordSuperscriptRegex.test(body)) {
body = body.replace(multiwordSuperscriptRegex, "<sup>$1</sup>");
}
const superscriptRegex = /\^(\S+)/gm;
while (superscriptRegex.test(body)) {
body = body.replace(superscriptRegex, "<sup>$1</sup>");
}
// convert user and subreddit mentions to links (can be /u/, /r/, u/, or r/)
body = body.replace(/(?<=^|[^\w\/])(\/?)([ur]\/\w+)/gm, "[$1$2](/$2)");
// add spaces after '>' to keep blockquotes (if it has '>!' ignore since that is spoilertext)
body = body.replace(/^((?:>|>)+)(?=[^!\s])/gm, function (match, p1) {
return p1.replace(/>/g, ">") + " ";
});
// convert markdown to HTML
let html = mdConverter.makeHtml(body);
// convert Reddit spoilertext
return html.replace(
/(?<=^|\s|>)>!(.+?)!<(?=$|\s|<)/gm,
"<span class='md-spoiler-text' title='Reveal spoiler'>$1</span>"
);
}