mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-23 00:56:33 +03:00
Refactor markdown headings parsing
This commit is contained in:
parent
1ff87ce665
commit
7fa850b41d
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user