Skip to content

Commit 05be3b3

Browse files
AddisonSchillercslzchen
authored andcommitted
Updating the markdown renderer to use markdown-it
instead of original markdown.
1 parent 174828f commit 05be3b3

15 files changed

+959
-48
lines changed

mfr/extensions/md/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
## Markdown plus Mathjax readme
3+
4+
Most of the packages are in there to try to match what the OSF wiki is doing. The two exceptions being markdown-it-highlightjs.js and markdown-it-mathjax.js. The highlighter matches the functionality of what is on the osf however, and the markdown-it-mathjax.js increases functionality with mathjax.
5+
6+
to get all the libraries needed:
7+
Note: You do not need to use npm, you can easily get them off of github.
8+
9+
```bash
10+
11+
npm install @centerforopenscience/[email protected]
12+
npm install [email protected]
13+
npm install [email protected]
14+
npm install [email protected]
15+
npm install [email protected]
16+
```
17+
18+
github:
19+
20+
https://github.com/cos-forks/markdown-it-toc
21+
https://github.com/valeriangalliat/markdown-it-highlightjs
22+
https://github.com/brianjgeiger/markdown-it-ins-del
23+
https://github.com/svbergerem/markdown-it-sanitizer
24+
https://github.com/classeur/markdown-it-mathjax
25+
26+
To add a new library, you need to make sure its loadable in md.js somehow, either through exporting via `root.<name>` or some other means. Some of the markdown plugins added have custom code in them to load them into `root`.
27+
28+
Libraries should try to use the same version as the ones used on the OSF. The plugins do not matter as much, but `markdown-it` and `Mathjax` you should try to match exactly because styling can change between versions.
29+
30+
To add a new library that is not already set up to export to `root` can be a bit tricky but the gist of it is, wrap the plugin in this code:
31+
32+
```javascript
33+
;(function (root, factory) {
34+
if (typeof exports === 'object') {
35+
module.exports = factory()
36+
} else {
37+
root.<PLUGIN_NAME> = factory()
38+
}
39+
})(this, function () {
40+
41+
42+
return function(md){
43+
44+
.....
45+
}
46+
47+
})
48+
```
49+
50+
And then modify it to work in this context. See other plugins for examples.
51+
52+
Then in md.js, you can add a plugin to the markdown renderer by adding a `.use(window.<PLUGIN_NAME>)` after loading the file into `viewer.mako`.

mfr/extensions/md/render.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
import os
22

3-
import markdown
4-
from markdown.extensions import Extension
5-
3+
import bleach
64
from mako.lookup import TemplateLookup
75

86
from mfr.core import extension
9-
10-
11-
class EscapeHtml(Extension):
12-
def extendMarkdown(self, md, md_globals):
13-
del md.preprocessors['html_block']
14-
del md.inlinePatterns['html']
15-
7+
from mfr.extensions.md.settings import BLEACH_WHITELIST
168

179
class MdRenderer(extension.BaseRenderer):
1810

@@ -23,12 +15,13 @@ class MdRenderer(extension.BaseRenderer):
2315

2416
def __init__(self, *args, **kwargs):
2517
super().__init__(*args, **kwargs)
26-
self.metrics.add('markdown_version', markdown.version)
2718

2819
def render(self):
2920
"""Render a markdown file to html."""
3021
with open(self.file_path, 'r') as fp:
31-
body = markdown.markdown(fp.read(), extensions=[EscapeHtml()])
22+
# Bleach will bug out on unclosed tags. OSF wiki does not have this issue.
23+
# This is due to versioning problems: https://github.com/mozilla/bleach/issues/271
24+
body = bleach.clean(fp.read(), **BLEACH_WHITELIST)
3225
return self.TEMPLATE.render(base=self.assets_url, body=body)
3326

3427
@property

mfr/extensions/md/settings.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# This list comes from the OSF
2+
BLEACH_WHITELIST = {
3+
'tags': [
4+
'a', 'abbr', 'acronym', 'b', 'bdo', 'big', 'blockquote', 'br',
5+
'center', 'cite', 'code',
6+
'dd', 'del', 'dfn', 'div', 'dl', 'dt', 'em', 'embed', 'font',
7+
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins',
8+
'kbd', 'li', 'object', 'ol', 'param', 'pre', 'p', 'q',
9+
's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup',
10+
'table', 'tbody', 'td', 'th', 'thead', 'tr', 'tt', 'ul', 'u',
11+
'var', 'wbr',
12+
],
13+
'attributes': [
14+
'align', 'alt', 'border', 'cite', 'class', 'dir',
15+
'height', 'href', 'id', 'src', 'style', 'title', 'type', 'width',
16+
'face', 'size', # font tags
17+
'salign', 'align', 'wmode', 'target',
18+
],
19+
'styles': [
20+
'top', 'left', 'width', 'height', 'position',
21+
'background', 'font-size', 'text-align', 'z-index',
22+
'list-style',
23+
]
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@charset "utf-8";
2+
3+
4+
/*Had quite a few css woes on this one
5+
Chrome has some scroll bar issues. This is mostly due to
6+
Iframe problems. There may be a better combination of CSS to get rid of this,
7+
for now just going the best combination found.
8+
9+
*/
10+
.mfrViewer {
11+
font-family: 'Open Sans';
12+
padding:1em;
13+
background:#fefefe;
14+
height: auto;
15+
word-wrap: break-word;
16+
}
17+
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
3+
Original highlight.js style (c) Ivan Sagalaev <[email protected]>
4+
5+
*/
6+
7+
.hljs {
8+
display: block;
9+
overflow-x: auto;
10+
padding: 0.5em;
11+
background: #F0F0F0;
12+
}
13+
14+
15+
/* Base color: saturation 0; */
16+
17+
.hljs,
18+
.hljs-subst {
19+
color: #444;
20+
}
21+
22+
.hljs-comment {
23+
color: #888888;
24+
}
25+
26+
.hljs-keyword,
27+
.hljs-attribute,
28+
.hljs-selector-tag,
29+
.hljs-meta-keyword,
30+
.hljs-doctag,
31+
.hljs-name {
32+
font-weight: bold;
33+
}
34+
35+
36+
/* User color: hue: 0 */
37+
38+
.hljs-type,
39+
.hljs-string,
40+
.hljs-number,
41+
.hljs-selector-id,
42+
.hljs-selector-class,
43+
.hljs-quote,
44+
.hljs-template-tag,
45+
.hljs-deletion {
46+
color: #880000;
47+
}
48+
49+
.hljs-title,
50+
.hljs-section {
51+
color: #880000;
52+
font-weight: bold;
53+
}
54+
55+
.hljs-regexp,
56+
.hljs-symbol,
57+
.hljs-variable,
58+
.hljs-template-variable,
59+
.hljs-link,
60+
.hljs-selector-attr,
61+
.hljs-selector-pseudo {
62+
color: #BC6060;
63+
}
64+
65+
66+
/* Language color: hue: 90; */
67+
68+
.hljs-literal {
69+
color: #78A960;
70+
}
71+
72+
.hljs-built_in,
73+
.hljs-bullet,
74+
.hljs-code,
75+
.hljs-addition {
76+
color: #397300;
77+
}
78+
79+
80+
/* Meta color: hue: 200 */
81+
82+
.hljs-meta {
83+
color: #1f7199;
84+
}
85+
86+
.hljs-meta-string {
87+
color: #4d99bf;
88+
}
89+
90+
91+
/* Misc effects */
92+
93+
.hljs-emphasis {
94+
font-style: italic;
95+
}
96+
97+
.hljs-strong {
98+
font-weight: bold;
99+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
;(function (root, factory) {
2+
if (typeof exports === 'object') {
3+
module.exports = factory()
4+
} else {
5+
root.markdownitHightlightjs = factory()
6+
}
7+
})(this, function () {
8+
9+
const maybe = f => {
10+
try {
11+
return f()
12+
} catch (e) {
13+
return false
14+
}
15+
}
16+
17+
// Highlight with given language.
18+
const highlight = (code, lang) =>
19+
maybe(() => hljs.highlight(lang, code, true).value) || ''
20+
21+
// Highlight with given language or automatically.
22+
const highlightAuto = (code, lang) =>
23+
lang
24+
? highlight(code, lang)
25+
: maybe(() => hljs.highlightAuto(code).value) || ''
26+
27+
// Wrap a render function to add `hljs` class to code blocks.
28+
const wrap = render =>
29+
function (...args) {
30+
return render.apply(this, args)
31+
.replace('<code class="', '<code class="hljs ')
32+
.replace('<code>', '<code class="hljs">')
33+
}
34+
var defaults = {
35+
auto: true,
36+
code: true
37+
}
38+
39+
return function(md, opts){
40+
opts = Object.assign({}, defaults, opts)
41+
42+
md.options.highlight = opts.auto ? highlightAuto : highlight
43+
md.renderer.rules.fence = wrap(md.renderer.rules.fence)
44+
45+
if (opts.code) {
46+
md.renderer.rules.code_block = wrap(md.renderer.rules.code_block)
47+
}
48+
}
49+
50+
})

0 commit comments

Comments
 (0)