Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SVCS-418] Render MD Files at the Frontend #305

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions mfr/extensions/md/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## Using Markdown-it with plugins

If we had `npm`, here were the would-be configuration.

```bash
npm [email protected]
npm install @centerforopenscience/[email protected]
npm install [email protected]
npm install [email protected]
npm install [email protected]
npm install [email protected]
```

For MFR, a customized local copy of each script is stored in the extension's static folder. There are a few issues:

* MFR scripts run directly in the browser without Babel. For ES5 compatibility, developers must use [Babel](https://babeljs.io/repl/) to convert ES6 `markdown-it-highlightjs` to an ES5 version.

* MFR does not use a package manager. Thus, `require` is **NOT** available. For the `viewer.mako` to be able to load these libraries, customization is necessary to export via `root.<PLUGIN_NAME>`. The main script in the `viewer.mako` uses `window.<PLUGIN_NAME>` to access them. `markdown-it` and `markdown-it-sanitizer` are already set up to be exported code. MFR loads the `min` version directly. `markdown-it-toc`, `markdown-it-highlightjs`, `markdown-it-ins-del` and `markdown-it-mathjax` are not. The following wrapper must be used.

```javascript
(function (root, factory) {
if (typeof exports === "object") {
module.exports = factory();
} else {
root.<PLUGIN_NAME> = factory();
}
}) (this, function () {
return function(md/*, optional arguments*/) {
/* library code */
}
});
```

Here is a list of the original copies of the scripts:

* [[email protected]](https://github.com/markdown-it/markdown-it/blob/8.4.0/bin/markdown-it.js)
* [[email protected]](https://github.com/svbergerem/markdown-it-sanitizer/blob/v0.4.3/dist/markdown-it-sanitizer.min.js)
* [[email protected]](https://github.com/classeur/markdown-it-mathjax/blob/v2.0.0/markdown-it-mathjax.js)
* [[email protected]](https://github.com/cos-forks/markdown-it-toc/blob/1.1.1/index.js)
* [[email protected]](https://github.com/brianjgeiger/markdown-it-ins-del/blob/1.0.0/index.js)
* [[email protected]](https://github.com/cslzchen/markdown-it-highlightjs/blob/release/3.0.0/index.es5.js)
18 changes: 3 additions & 15 deletions mfr/extensions/md/render.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import os

import markdown
from markdown.extensions import Extension

from mako.lookup import TemplateLookup

from mfr.core import extension


class EscapeHtml(Extension):
def extendMarkdown(self, md, md_globals):
del md.preprocessors['html_block']
del md.inlinePatterns['html']
from mfr.core.extension import BaseRenderer


class MdRenderer(extension.BaseRenderer):
class MdRenderer(BaseRenderer):

TEMPLATE = TemplateLookup(
directories=[
Expand All @@ -23,13 +14,10 @@ class MdRenderer(extension.BaseRenderer):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.metrics.add('markdown_version', markdown.version)

def render(self):
"""Render a markdown file to html."""
with open(self.file_path, 'r') as fp:
body = markdown.markdown(fp.read(), extensions=[EscapeHtml()])
return self.TEMPLATE.render(base=self.assets_url, body=body)
return self.TEMPLATE.render(base=self.assets_url, url=self.metadata.download_url)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MD renderer is now of type direct-to-wb instead of through-renderer. Only pass the WB download URL to the template.


@property
def file_required(self):
Expand Down
9 changes: 9 additions & 0 deletions mfr/extensions/md/static/css/default.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@charset "utf-8";

.mfrViewer {
font-family: 'Open Sans';
padding: 1em;
background: #fefefe;
height: auto;
word-wrap: break-word;
}
99 changes: 99 additions & 0 deletions mfr/extensions/md/static/css/highlightjs-default.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* Original highlight.js style (c) Ivan Sagalaev <[email protected]>
*
* https://github.com/isagalaev/highlight.js/blob/9.12.0/src/styles/default.css
*/

.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #F0F0F0;
}


/* Base color: saturation 0; */

.hljs,
.hljs-subst {
color: #444;
}

.hljs-comment {
color: #888888;
}

.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-meta-keyword,
.hljs-doctag,
.hljs-name {
font-weight: bold;
}


/* User color: hue: 0 */

.hljs-type,
.hljs-string,
.hljs-number,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
color: #880000;
}

.hljs-title,
.hljs-section {
color: #880000;
font-weight: bold;
}

.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #BC6060;
}


/* Language color: hue: 90; */

.hljs-literal {
color: #78A960;
}

.hljs-built_in,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #397300;
}


/* Meta color: hue: 200 */

.hljs-meta {
color: #1f7199;
}

.hljs-meta-string {
color: #4d99bf;
}


/* Misc effects */

.hljs-emphasis {
font-style: italic;
}

.hljs-strong {
font-weight: bold;
}
72 changes: 72 additions & 0 deletions mfr/extensions/md/static/js/markdown-it-highlightjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Preset to use highlight.js with markdown-it.
*
* Origin: https://github.com/valeriangalliat/markdown-it-highlightjs/tree/v3.0.0/index.js
* The above link gives a 404. Here is a forked copy and Babel-converted ES5 version:
* (ES6) https://github.com/cslzchen/markdown-it-highlightjs/blob/release/3.0.0/index.js
* (ES5) https://github.com/cslzchen/markdown-it-highlightjs/blob/release/3.0.0/index.es5.js
*
* Version: https://github.com/valeriangalliat/markdown-it-highlightjs/releases/tag/v3.0.0
*/

(function (root, factory) {
if (typeof exports === "object") {
module.exports = factory();
} else {
root.markdownitHightlightjs = factory();
}
})(this, function () {

"use strict";

var maybe = function maybe(f) {
try {
return f();
} catch (e) {
return false;
}
};

// Highlight with given language.
var highlight = function highlight(code, lang) {
return maybe(function () {
return hljs.highlight(lang, code, true).value;
}) || "";
};

// Highlight with given language or automatically.
var highlightAuto = function highlightAuto(code, lang) {
return lang ? highlight(code, lang) : maybe(function () {
return hljs.highlightAuto(code).value;
}) || "";
};

// Wrap a render function to add `hljs` class to code blocks.
var wrap = function wrap(render) {
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}

return render.apply(this, args).replace("<code class=\"", "<code class=\"hljs ").replace("<code>", "<code class=\"hljs\">");
};
};

var defaults = {
auto: true,
code: true
};

return function(md, opts) {

opts = Object.assign({}, defaults, opts);

md.options.highlight = opts.auto ? highlightAuto : highlight;
md.renderer.rules.fence = wrap(md.renderer.rules.fence);

if (opts.code) {
md.renderer.rules.code_block = wrap(md.renderer.rules.code_block);
}
};

});
Loading