diff --git a/lib/utils/helpers.ts b/lib/utils/helpers.ts
index 991526bf..46f1ed66 100644
--- a/lib/utils/helpers.ts
+++ b/lib/utils/helpers.ts
@@ -1,25 +1,4 @@
'use strict';
-import * as Remarkable from 'remarkable';
-declare var Prism: any;
-
-const md = new Remarkable({
- html: true,
- linkify: true,
- breaks: false,
- typographer: false,
- highlight: (str, lang) => {
- if (lang === 'json') lang = 'js';
- let grammar = Prism.languages[lang];
- //fallback to clike
- if (!grammar) return str;
- return Prism.highlight(str, grammar);
- }
-});
-
-interface HeadersHandler {
- open: Function;
- close: Function;
-}
export function stringify(obj:any) {
return JSON.stringify(obj);
@@ -34,41 +13,7 @@ export function isFunction(func: any) {
}
export function isBlank(obj: any): boolean {
- return obj == null;
-}
-
-export function renderMd(rawText:string, headersHandler?:HeadersHandler) {
- let _origRule;
- if (headersHandler) {
- _origRule = {
- open: md.renderer.rules.heading_open,
- close: md.renderer.rules.heading_close
- };
- md.renderer.rules.heading_open = (tokens, idx) => {
- if (tokens[idx].hLevel !== 1 ) {
- return _origRule.open(tokens, idx);
- } else {
- return headersHandler.open(tokens, idx);
- }
- };
-
- md.renderer.rules.heading_close = (tokens, idx) => {
- if (tokens[idx].hLevel !== 1 ) {
- return _origRule.close(tokens, idx);
- } else {
- return headersHandler.close(tokens, idx);
- }
- };
- }
-
- let res = md.render(rawText);
-
- if (headersHandler) {
- md.renderer.rules.heading_open = _origRule.open;
- md.renderer.rules.heading_close = _origRule.close;
- }
-
- return res;
+ return obj == undefined;
}
export function statusCodeType(statusCode) {
diff --git a/lib/utils/index.ts b/lib/utils/index.ts
index e1b0cf0c..cd933708 100644
--- a/lib/utils/index.ts
+++ b/lib/utils/index.ts
@@ -1 +1,3 @@
export * from './custom-error-handler';
+export * from './helpers';
+export * from './md-renderer';
diff --git a/lib/utils/md-renderer.ts b/lib/utils/md-renderer.ts
new file mode 100644
index 00000000..3c89bd67
--- /dev/null
+++ b/lib/utils/md-renderer.ts
@@ -0,0 +1,95 @@
+'use strict';
+
+import { Injectable } from '@angular/core';
+import * as slugify from 'slugify';
+import * as Remarkable from 'remarkable';
+
+import { SecurityDefinitions } from '../components/';
+
+declare var Prism: any;
+const md = new Remarkable({
+ html: true,
+ linkify: true,
+ breaks: false,
+ typographer: false,
+ highlight: (str, lang) => {
+ if (lang === 'json') lang = 'js';
+ let grammar = Prism.languages[lang];
+ //fallback to clike
+ if (!grammar) return str;
+ return Prism.highlight(str, grammar);
+ }
+});
+
+interface HeadersHandler {
+ open: Function;
+ close: Function;
+}
+
+@Injectable()
+export class MdRenderer {
+ private _origRules:any = {};
+ private _preProcessors:Function[] = [];
+
+ public firstLevelHeadings: string[] = [];
+ constructor(private raw: boolean = false) {
+ // TODO
+ if (!raw) {
+ this.addPreprocessor(SecurityDefinitions.insertTagIntoDescription);
+ }
+ }
+
+ addPreprocessor(p: Function) {
+ this._preProcessors.push(p);
+ }
+
+ saveOrigRules() {
+ this._origRules.open = md.renderer.rules.heading_open;
+ this._origRules.close = md.renderer.rules.heading_close;
+ }
+
+ restoreOrigRules() {
+ md.renderer.rules.heading_open = this._origRules.open;
+ md.renderer.rules.heading_close = this._origRules.close;
+ }
+
+ headingOpenRule(tokens, idx) {
+ if (tokens[idx].hLevel !== 1 ) {
+ return this._origRules.open(tokens, idx);
+ } else {
+ let content = tokens[idx + 1].content;
+ this.firstLevelHeadings.push(content);
+ let contentSlug = slugify(content);
+ return `` +
+ ``;
+ }
+ }
+
+ headingCloseRule(tokens, idx) {
+ if (tokens[idx].hLevel !== 1 ) {
+ return this._origRules.close(tokens, idx);
+ } else {
+ return `\n`;
+ }
+ }
+
+ renderMd(rawText:string) {
+ if (!this.raw) {
+ this.saveOrigRules();
+ md.renderer.rules.heading_open = this.headingOpenRule.bind(this);
+ md.renderer.rules.heading_close = this.headingCloseRule.bind(this);
+ }
+ let text = rawText;
+
+ for (let i=0; i${renderMd(value)}`
+ `${this.renderer.renderMd(value)}`
);
}
}
@@ -125,5 +128,5 @@ export class EncodeURIComponentPipe implements PipeTransform {
}
export const REDOC_PIPES = [
- JsonPointerEscapePipe, MarkedPipe, SafePipe, PrismPipe, EncodeURIComponentPipe, JsonFormatter
+ JsonPointerEscapePipe, MarkedPipe, SafePipe, PrismPipe, EncodeURIComponentPipe, JsonFormatter, KeysPipe
];
diff --git a/lib/utils/spec-manager.ts b/lib/utils/spec-manager.ts
index f9e9d4c4..283d82e3 100644
--- a/lib/utils/spec-manager.ts
+++ b/lib/utils/spec-manager.ts
@@ -2,11 +2,11 @@
import * as JsonSchemaRefParser from 'json-schema-ref-parser';
import { JsonPointer } from './JsonPointer';
-import { renderMd, safePush } from './helpers';
-import * as slugify from 'slugify';
import { parse as urlParse, resolve as urlResolve } from 'url';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { MdRenderer } from './';
+
export class SpecManager {
public _schema: any = {};
public apiUrl: string;
@@ -75,18 +75,10 @@ export class SpecManager {
}
preprocess() {
- this._schema.info['x-redoc-html-description'] = renderMd( this._schema.info.description, {
- open: (tokens, idx) => {
- let content = tokens[idx + 1].content;
- safePush(this._schema.info, 'x-redoc-markdown-headers', content);
- content = slugify(content);
- return `` +
- ``;
- },
- close: (tokens, idx) => {
- return ``;
- }
- });
+ let mdRender = new MdRenderer();
+ if (!this._schema.info.description) this._schema.info.description = '';
+ this._schema.info['x-redoc-html-description'] = mdRender.renderMd(this._schema.info.description);
+ this._schema.info['x-redoc-markdown-headers'] = mdRender.firstLevelHeadings;
}
get schema() {