UNPKG

5.61 kBJavaScriptView Raw
1"use strict";
2var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6 return c > 3 && r && Object.defineProperty(target, key, r), r;
7};
8Object.defineProperty(exports, "__esModule", { value: true });
9const FS = require("fs-extra");
10const Path = require("path");
11const Marked = require("marked");
12const HighlightJS = require("highlight.js");
13const Handlebars = require("handlebars");
14const components_1 = require("../components");
15const events_1 = require("../events");
16const component_1 = require("../../utils/component");
17const declaration_1 = require("../../utils/options/declaration");
18const customMarkedRenderer = new Marked.Renderer();
19customMarkedRenderer.heading = (text, level, _, slugger) => {
20 const slug = slugger.slug(text);
21 return `
22<a href="#${slug}" id="${slug}" style="color: inherit; text-decoration: none;">
23 <h${level}>${text}</h${level}>
24</a>
25`;
26};
27let MarkedPlugin = class MarkedPlugin extends components_1.ContextAwareRendererComponent {
28 constructor() {
29 super(...arguments);
30 this.includePattern = /\[\[include:([^\]]+?)\]\]/g;
31 this.mediaPattern = /media:\/\/([^ "\)\]\}]+)/g;
32 }
33 initialize() {
34 super.initialize();
35 this.listenTo(this.owner, events_1.MarkdownEvent.PARSE, this.onParseMarkdown);
36 const that = this;
37 Handlebars.registerHelper('markdown', function (arg) { return that.parseMarkdown(arg.fn(this), this); });
38 Handlebars.registerHelper('relativeURL', (url) => url ? this.getRelativeUrl(url) : url);
39 Marked.setOptions({
40 highlight: (text, lang) => this.getHighlighted(text, lang),
41 renderer: customMarkedRenderer
42 });
43 }
44 getHighlighted(text, lang) {
45 try {
46 if (lang) {
47 return HighlightJS.highlight(lang, text).value;
48 }
49 else {
50 return HighlightJS.highlightAuto(text).value;
51 }
52 }
53 catch (error) {
54 this.application.logger.warn(error.message);
55 return text;
56 }
57 }
58 parseMarkdown(text, context) {
59 if (this.includes) {
60 text = text.replace(this.includePattern, (match, path) => {
61 path = Path.join(this.includes, path.trim());
62 if (FS.existsSync(path) && FS.statSync(path).isFile()) {
63 const contents = FS.readFileSync(path, 'utf-8');
64 if (path.substr(-4).toLocaleLowerCase() === '.hbs') {
65 const template = Handlebars.compile(contents);
66 return template(context);
67 }
68 else {
69 return contents;
70 }
71 }
72 else {
73 return '';
74 }
75 });
76 }
77 if (this.mediaDirectory) {
78 text = text.replace(this.mediaPattern, (match, path) => {
79 if (FS.existsSync(Path.join(this.mediaDirectory, path))) {
80 return this.getRelativeUrl('media') + '/' + path;
81 }
82 else {
83 return match;
84 }
85 });
86 }
87 const event = new events_1.MarkdownEvent(events_1.MarkdownEvent.PARSE, text, text);
88 this.owner.trigger(event);
89 return event.parsedText;
90 }
91 onBeginRenderer(event) {
92 super.onBeginRenderer(event);
93 delete this.includes;
94 if (this.includeSource) {
95 const includes = Path.resolve(this.includeSource);
96 if (FS.existsSync(includes) && FS.statSync(includes).isDirectory()) {
97 this.includes = includes;
98 }
99 else {
100 this.application.logger.warn('Could not find provided includes directory: ' + includes);
101 }
102 }
103 if (this.mediaSource) {
104 const media = Path.resolve(this.mediaSource);
105 if (FS.existsSync(media) && FS.statSync(media).isDirectory()) {
106 this.mediaDirectory = Path.join(event.outputDirectory, 'media');
107 FS.copySync(media, this.mediaDirectory);
108 }
109 else {
110 this.mediaDirectory = undefined;
111 this.application.logger.warn('Could not find provided media directory: ' + media);
112 }
113 }
114 }
115 onParseMarkdown(event) {
116 event.parsedText = Marked(event.parsedText);
117 }
118};
119__decorate([
120 component_1.Option({
121 name: 'includes',
122 help: 'Specifies the location to look for included documents (use [[include:FILENAME]] in comments).',
123 hint: declaration_1.ParameterHint.Directory
124 })
125], MarkedPlugin.prototype, "includeSource", void 0);
126__decorate([
127 component_1.Option({
128 name: 'media',
129 help: 'Specifies the location with media files that should be copied to the output directory.',
130 hint: declaration_1.ParameterHint.Directory
131 })
132], MarkedPlugin.prototype, "mediaSource", void 0);
133MarkedPlugin = __decorate([
134 components_1.Component({ name: 'marked' })
135], MarkedPlugin);
136exports.MarkedPlugin = MarkedPlugin;
137//# sourceMappingURL=MarkedPlugin.js.map
\No newline at end of file