Let's build a Markdown component
By leveraging Ember Auto Import, we can make our own Markdown component with syntax highlighting using MarkdownIt and Highlight.js.
Summary
From a brand new app, we start by installing the ember-auto-import
addon
ember install ember-auto-import
Next, install the MarkdownIt library directly from npm:
yarn add -D markdown-it
Now we can create a new <Markdown />
component, and use MarkdownIt to render some HTML:
// markdown/component.js
import Component from '@ember/component';
import MarkdownIt from 'markdown-it';
import { computed } from '@ember/object';
import { htmlSafe } from '@ember/string';
const md = new MarkdownIt();
export default Component.extend({
source: 'Hello, *markdown*!',
html: computed('source', function() {
return htmlSafe(md.render(this.source));
})
});
{{! markdown/template.hbs }}
{{html}}
Using angle bracket syntax and the @
sign, we can easily pass in new source content from our Application template. (We'll also install dedent
to make our lives a little easier).
// application/controller.js
import Controller from '@ember/controller';
import dedent from 'dedent';
export default Controller.extend({
blogPost: dedent`
# Quick start
This guide will teach you how to build a simple app using Ember from scratch.
We'll cover these steps:
1. Installing Ember.
2. Creating a new application.
3. Defining a route.
4. Writing a UI component.
5. Building your app to be deployed to production.
`
});
{{! application/template.hbs}}
<Markdown @source={{blogPost}} />
Looking good!
To add syntax highlighting, we're going to use Highlight.js. Let's install it with Yarn:
yarn add -D highlight.js
Now we can add a highlight
function to our MarkdownIt instance:
import Component from '@ember/component';
import MarkdownIt form 'markdown-it';
import hljs from 'highlight.js';
import { computed } from '@ember/object';
import { htmlSafe } from '@ember/string';
const md = new MarkdownIt({
highlight(code, lang) {
let highlihgtedCode = code;
if (hljs.getLanguage(lang)) {
highlightedCode = hljs.highlight(lang, code).value;
}
return `<pre class='hljs'><code>${higlightedCode}</code></pre>`;
}
});
export default Component.extend({
classNames: 'Markdown',
source: 'Hello, *markdown*!',
html: computed('source', function() {
return htmlSafe(md.render(this.source));
})
});
Finally, we need to import a Highlight.js theme. We can do that by importing the CSS file directly from node_modules
in our ember-cli-build.js
file:
app.import('node_modules/highlight.js/styles/atom-one-dark.css');
And with that, we have a <Markdown />
component, complete with syntax highlighting using a theme of our choosing!
If we don't want to include all of Highlight.js's languages into our bundle, we can whitelist the ones we want:
- import hljs from 'highlight.js';
+ import hljs from 'highlight.js/lib/highlight';
+ import javascript from 'highlight.js/lib/languages/javascript';
+ import css from 'highlight.js/lib/languages/css';
+ import handlebars from 'highlight.js/lib/languages/handlebars';
+ import htmlbars from 'highlight.js/lib/languages/htmlbars';
+ import json from 'highlight.js/lib/languages/json';
+ import xml from 'highlight.js/lib/languages/xml';
+ import diff from 'highlight.js/lib/languages/diff';
+ hljs.registerLanguage('javascript', javascript);
+ hljs.registerLanguage('css', css);
+ hljs.registerLanguage('handlebars', handlebars);
+ hljs.registerLanguage('htmlbars', htmlbars);
+ hljs.registerLanguage('json', json);
+ hljs.registerLanguage('xml', xml);
+ hljs.registerLanguage('diff', diff);