73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
|
import { NgModule } from 'ng-metadata/core';
|
||
|
import { Converter, ConverterOptions } from 'showdown';
|
||
|
import * as showdown from 'showdown';
|
||
|
import { registerLanguage, highlightAuto } from 'highlight.js/lib/highlight';
|
||
|
import 'highlight.js/styles/vs.css';
|
||
|
const highlightedLanguages: string[] = require('../../../constants/highlighted-languages.constant.json');
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Dynamically fetch and register a new language with Highlight.js
|
||
|
*/
|
||
|
export const addHighlightedLanguage = (language: string): Promise<{}> => {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
try {
|
||
|
// TODO(alecmerdler): Use `import()` here instead of `require()`
|
||
|
const langModule = require(`highlight.js/lib/languages/${language}`);
|
||
|
registerLanguage(language, langModule);
|
||
|
resolve();
|
||
|
} catch (error) {
|
||
|
console.log(`Language ${language} not supported for syntax highlighting`);
|
||
|
reject(error);
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Showdown JS extension for syntax highlighting using Highlight.js
|
||
|
*/
|
||
|
export const showdownHighlight = (): showdown.FilterExtension => {
|
||
|
const htmlunencode = (text: string) => {
|
||
|
return (text
|
||
|
.replace(/&/g, '&')
|
||
|
.replace(/</g, '<')
|
||
|
.replace(/>/g, '>'));
|
||
|
};
|
||
|
|
||
|
const left = '<pre><code\\b[^>]*>';
|
||
|
const right = '</code></pre>';
|
||
|
const flags = 'g';
|
||
|
const replacement = (wholeMatch: string, match: string, leftSide: string, rightSide: string) => {
|
||
|
// TODO(alecmerdler): Call `addHighlightedLanguage` to load new languages that are detected using code-splitting
|
||
|
match = htmlunencode(match);
|
||
|
return leftSide + highlightAuto(match).value + rightSide;
|
||
|
};
|
||
|
|
||
|
return {
|
||
|
type: 'output',
|
||
|
filter: (text, converter, options) => {
|
||
|
return (<any>showdown).helper.replaceRecursiveRegExp(text, replacement, left, right, flags);
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
// Dynamically import syntax-highlighting supported languages
|
||
|
highlightedLanguages.forEach((langName) => addHighlightedLanguage(langName));
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Markdown editor and view module.
|
||
|
*/
|
||
|
@NgModule({
|
||
|
imports: [],
|
||
|
declarations: [],
|
||
|
providers: [
|
||
|
{provide: 'markdownConverter', useValue: new Converter({extensions: [<any>showdownHighlight]})},
|
||
|
],
|
||
|
})
|
||
|
export class MarkdownModule {
|
||
|
|
||
|
}
|