Refactor markdown headings parsing

This commit is contained in:
Roman Hotsiy 2017-01-30 17:21:12 +02:00
parent 1ff87ce665
commit 7fa850b41d
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
3 changed files with 43 additions and 32 deletions

View File

@ -8,7 +8,7 @@ import { SpecManager } from '../utils/spec-manager';
import { SchemaHelper } from './schema-helper.service';
import { AppStateService } from './app-state.service';
import { LazyTasksService } from '../shared/components/LazyFor/lazy-for';
import { JsonPointer } from '../utils/JsonPointer';
import { JsonPointer, MarkdownHeading, StringMap } from '../utils/';
import * as slugify from 'slugify';
@ -250,40 +250,35 @@ export class MenuService {
addMarkdownItems() {
let schema = this.specMgr.schema;
for (let header of (<Array<string>>(schema.info && schema.info['x-redoc-markdown-headers'] || []))) {
let id = 'section/' + slugify(header);
let headings = schema.info['x-redoc-markdown-headers'] as StringMap<MarkdownHeading>;
Object.keys(headings).forEach(h => {
let heading = headings[h];
let id = 'section/' + heading.id;
let item = {
name: header,
name: heading.title,
id: id,
items: null
};
item.items = this.getMarkdownSubheaders(item);
item.items = this.getMarkdownSubheaders(item, heading);
this.items.push(item);
}
});
}
getMarkdownSubheaders(parent: MenuItem):MenuItem[] {
getMarkdownSubheaders(parent: MenuItem, parentHeading: MarkdownHeading):MenuItem[] {
let res = [];
let schema = this.specMgr.schema;
for (let subheader of (<Array<string>>(schema.info && schema.info['x-redoc-markdown-subheaders'] || []))) {
let parts = subheader.split('/');
let header = parts[0];
if (parent.name !== header) {
continue;
}
let name = parts[1];
let id = parent.id + '/' + slugify(name);
Object.keys(parentHeading.children || {}).forEach(h => {
let heading = parentHeading.children[h];
let id = 'section/' + heading.id;
let subItem = {
name: name,
name: heading.title,
id: id,
parent: parent
};
res.push(subItem);
}
});
return res;
}

View File

@ -3,6 +3,7 @@
import { Injectable } from '@angular/core';
import * as slugify from 'slugify';
import * as Remarkable from 'remarkable';
import { StringMap } from './';
declare var Prism: any;
const md = new Remarkable({
@ -19,11 +20,17 @@ const md = new Remarkable({
}
});
export interface MarkdownHeading {
title?: string;
id: string;
content?: string;
children?: StringMap<MarkdownHeading>;
}
@Injectable()
export class MdRenderer {
public firstLevelHeadings: string[] = [];
public secondLevelHeadings: string[] = [];
public currentHeading: string = null;
public headings: StringMap<MarkdownHeading> = {};
currentTopHeading: MarkdownHeading;
private _origRules:any = {};
private _preProcessors:Function[] = [];
@ -45,21 +52,31 @@ export class MdRenderer {
md.renderer.rules.heading_close = this._origRules.close;
}
saveHeading(title: string, parent:MarkdownHeading = {id:null, children: this.headings}) :MarkdownHeading {
let id = slugify(title);
if (parent && parent.id) id = `${parent.id}/${id}`;
parent.children = parent.children || {};
parent.children[id] = {
title,
id
};
return parent.children[id];
}
headingOpenRule(tokens, idx) {
if (tokens[idx].hLevel > 2 ) {
return this._origRules.open(tokens, idx);
} else {
let content = tokens[idx + 1].content;
if (tokens[idx].hLevel === 1 ) {
this.firstLevelHeadings.push(content);
this.currentHeading = content;
let contentSlug = slugify(content);
return `<h${tokens[idx].hLevel} section="section/${contentSlug}">` +
`<a class="share-link" href="#section/${contentSlug}"></a>`;
this.currentTopHeading = this.saveHeading(content);;
let id = this.currentTopHeading.id;
return `<h${tokens[idx].hLevel} section="section/${id}">` +
`<a class="share-link" href="#section/${id}"></a>`;
} else if (tokens[idx].hLevel === 2 ) {
this.secondLevelHeadings.push(this.currentHeading + `/` + content);
let contentSlug = slugify(this.currentHeading) + `/` + slugify(content);
return `<h${tokens[idx].hLevel} section="section/${contentSlug}">` +
let heading = this.saveHeading(content, this.currentTopHeading);
let contentSlug = `${heading.id}`;
return `<h${tokens[idx].hLevel} section="section/${heading.id}">` +
`<a class="share-link" href="#section/${contentSlug}"></a>`;
}
}

View File

@ -84,8 +84,7 @@ export class SpecManager {
mdRender.addPreprocessor(SecurityDefinitions.insertTagIntoDescription);
}
this._schema.info['x-redoc-html-description'] = mdRender.renderMd(this._schema.info.description);
this._schema.info['x-redoc-markdown-headers'] = mdRender.firstLevelHeadings;
this._schema.info['x-redoc-markdown-subheaders'] = mdRender.secondLevelHeadings;
this._schema.info['x-redoc-markdown-headers'] = mdRender.headings;
}
get schema() {