Added code highlighting

This commit is contained in:
Jori Lallo
2016-05-22 22:08:09 -07:00
parent 84b3b8ee39
commit d53bd8cebb
9 changed files with 144 additions and 24 deletions

View File

@ -75,6 +75,7 @@
"exports-loader": "^0.6.3", "exports-loader": "^0.6.3",
"file-loader": "^0.8.5", "file-loader": "^0.8.5",
"fsevents": "^1.0.11", "fsevents": "^1.0.11",
"highlight.js": "^9.4.0",
"history": "^1.17.0", "history": "^1.17.0",
"imports-loader": "^0.6.5", "imports-loader": "^0.6.5",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",

View File

@ -2,6 +2,10 @@ import {
DataTypes, DataTypes,
sequelize, sequelize,
} from '../sequelize'; } from '../sequelize';
import {
convertToMarkdown,
truncateMarkdown,
} from '../utils/markdown';
import Atlas from './Atlas'; import Atlas from './Atlas';
import Team from './Team'; import Team from './Team';
import User from './User'; import User from './User';
@ -10,6 +14,15 @@ const Document = sequelize.define('document', {
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true }, id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true },
title: DataTypes.STRING, title: DataTypes.STRING,
text: DataTypes.TEXT, text: DataTypes.TEXT,
html: DataTypes.TEXT,
preview: DataTypes.TEXT,
}, {
hooks: {
beforeCreate: (doc) => {
doc.html = convertToMarkdown(doc.text);
doc.preview = truncateMarkdown(doc.text, 160);
},
}
}); });
Document.belongsTo(Atlas, { as: 'atlas' }); Document.belongsTo(Atlas, { as: 'atlas' });

View File

@ -1,6 +1,3 @@
import marked from 'marked';
import { truncateMarkdown } from './utils/truncate';
import Document from './models/Document'; import Document from './models/Document';
export function presentUser(user) { export function presentUser(user) {
@ -60,8 +57,8 @@ export async function presentDocument(document, includeAtlas=false) {
id: document.id, id: document.id,
title: document.title, title: document.title,
text: document.text, text: document.text,
html: marked(document.text), html: document.html,
preview: truncateMarkdown(document.text, 160), preview: document.preview,
createdAt: document.createdAt, createdAt: document.createdAt,
updatedAt: document.updatedAt, updatedAt: document.updatedAt,
atlas: document.atlaId, atlas: document.atlaId,

45
server/utils/markdown.js Normal file
View File

@ -0,0 +1,45 @@
import truncate from 'truncate-html';
import marked, { Renderer } from 'marked';
import highlight from 'highlight.js';
const renderer = new Renderer();
renderer.code = (code, language) => {
const validLang = !!(language && highlight.getLanguage(language));
const highlighted = validLang ? highlight.highlight(language, code).value : code;
return `<pre><code class="hljs ${language}">${highlighted}</code></pre>`;
};
marked.setOptions({
renderer: renderer,
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: true,
});
// TODO: This is syncronous and can be costly,
// should be performed outside http request
const convertToMarkdown = (text) => {
return marked(text);
};
truncate.defaultOptions = {
stripTags: false,
ellipsis: '...',
decodeEntities: false,
excludes: ['h1', 'pre', ],
};
const truncateMarkdown = (text, length) => {
const html = convertToMarkdown(text);
return truncate(html, length);
};
export {
convertToMarkdown,
truncateMarkdown,
};

View File

@ -1,18 +0,0 @@
import truncate from 'truncate-html';
import marked from 'marked';
truncate.defaultOptions = {
stripTags: false,
ellipsis: '...',
decodeEntities: false,
excludes: ['h1', 'pre',],
};
const truncateMarkdown = (text, length) => {
const html = marked(text);
return truncate(html, length);
};
export {
truncateMarkdown
};

View File

@ -0,0 +1,73 @@
:global {
/**
* GitHub Gist Theme
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
*/
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
}

View File

@ -16,7 +16,7 @@ const CenteredContent = (props) => {
}; };
CenteredContent.defaultProps = { CenteredContent.defaultProps = {
maxWidth: '600px', maxWidth: '740px',
}; };
CenteredContent.propTypes = { CenteredContent.propTypes = {

View File

@ -18,6 +18,7 @@ import reducers from 'reducers';
import 'normalize.css/normalize.css'; import 'normalize.css/normalize.css';
import 'utils/base-styles.scss'; import 'utils/base-styles.scss';
import 'fonts/atlas/atlas.css'; import 'fonts/atlas/atlas.css';
import 'assets/styles/github-gist.scss';
import Home from 'scenes/Home'; import Home from 'scenes/Home';
import Editor from 'scenes/Editor'; import Editor from 'scenes/Editor';

View File

@ -85,3 +85,11 @@ hr {
border-bottom-style: solid; border-bottom-style: solid;
border-bottom-color: #ccc; border-bottom-color: #ccc;
} }
:global {
.hljs {
border: 1px solid rgba(0,0,0,.0625);
padding: 1rem;
border-radius: 0.25rem;
}
}