Added code highlighting
This commit is contained in:
@ -75,6 +75,7 @@
|
||||
"exports-loader": "^0.6.3",
|
||||
"file-loader": "^0.8.5",
|
||||
"fsevents": "^1.0.11",
|
||||
"highlight.js": "^9.4.0",
|
||||
"history": "^1.17.0",
|
||||
"imports-loader": "^0.6.5",
|
||||
"json-loader": "^0.5.4",
|
||||
|
@ -2,6 +2,10 @@ import {
|
||||
DataTypes,
|
||||
sequelize,
|
||||
} from '../sequelize';
|
||||
import {
|
||||
convertToMarkdown,
|
||||
truncateMarkdown,
|
||||
} from '../utils/markdown';
|
||||
import Atlas from './Atlas';
|
||||
import Team from './Team';
|
||||
import User from './User';
|
||||
@ -10,6 +14,15 @@ const Document = sequelize.define('document', {
|
||||
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true },
|
||||
title: DataTypes.STRING,
|
||||
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' });
|
||||
|
@ -1,6 +1,3 @@
|
||||
import marked from 'marked';
|
||||
import { truncateMarkdown } from './utils/truncate';
|
||||
|
||||
import Document from './models/Document';
|
||||
|
||||
export function presentUser(user) {
|
||||
@ -60,8 +57,8 @@ export async function presentDocument(document, includeAtlas=false) {
|
||||
id: document.id,
|
||||
title: document.title,
|
||||
text: document.text,
|
||||
html: marked(document.text),
|
||||
preview: truncateMarkdown(document.text, 160),
|
||||
html: document.html,
|
||||
preview: document.preview,
|
||||
createdAt: document.createdAt,
|
||||
updatedAt: document.updatedAt,
|
||||
atlas: document.atlaId,
|
||||
|
45
server/utils/markdown.js
Normal file
45
server/utils/markdown.js
Normal 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,
|
||||
};
|
@ -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
|
||||
};
|
73
src/assets/styles/github-gist.scss
Normal file
73
src/assets/styles/github-gist.scss
Normal 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;
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ const CenteredContent = (props) => {
|
||||
};
|
||||
|
||||
CenteredContent.defaultProps = {
|
||||
maxWidth: '600px',
|
||||
maxWidth: '740px',
|
||||
};
|
||||
|
||||
CenteredContent.propTypes = {
|
||||
|
@ -18,6 +18,7 @@ import reducers from 'reducers';
|
||||
import 'normalize.css/normalize.css';
|
||||
import 'utils/base-styles.scss';
|
||||
import 'fonts/atlas/atlas.css';
|
||||
import 'assets/styles/github-gist.scss';
|
||||
|
||||
import Home from 'scenes/Home';
|
||||
import Editor from 'scenes/Editor';
|
||||
|
@ -85,3 +85,11 @@ hr {
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #ccc;
|
||||
}
|
||||
|
||||
:global {
|
||||
.hljs {
|
||||
border: 1px solid rgba(0,0,0,.0625);
|
||||
padding: 1rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user