Skip to content

Commit

Permalink
feat: add basic toc generate
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Mar 13, 2020
1 parent ffae659 commit 30e4426
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ChartOptions from './chart-options';
import ECharts = echarts.ECharts;

import MarkdownHelper from '../model/markdown.helper';
import Tocify, {TocItem} from './tocify';


@Component({
Expand Down Expand Up @@ -35,8 +36,9 @@ export class MarkdownRenderComponent implements OnInit, OnChanges {
private chartInfos = [];
private radarChartIndex = 0;
private chartInstances: ECharts[] = [];
private toc = [];

constructor(private markdownService: MarkdownService) {
constructor(private markdownService: MarkdownService, private tocify: Tocify) {
}

ngOnInit(): void {
Expand All @@ -52,6 +54,9 @@ export class MarkdownRenderComponent implements OnInit, OnChanges {
chartInstance.clear();
}
setTimeout(() => this.renderChat(), 50);
const items = this.tocify.tocItems;
let tocStr = this.renderToc(items);
console.log(tocStr);
}

ngOnChanges(changes: SimpleChanges): void {
Expand All @@ -61,6 +66,14 @@ export class MarkdownRenderComponent implements OnInit, OnChanges {
}
}

private renderToc(items: TocItem[]) {
return items.map(item => {
return `<a href="#${item.anchor}" title={item.text}>
${item}
</a>`;
});
}

private renderImage(markedOptions: any) {
return (href: string, title: string, text: string): string => {
if (href === null) {
Expand All @@ -77,13 +90,12 @@ export class MarkdownRenderComponent implements OnInit, OnChanges {
};
}


private renderHeading(options: any) {
return (text: string, level: number, raw: string, slugger: Slugger) => {
this.tocify.add(text, level);
if (options.headerIds) {
return '<h' + level + ' id="' + options.headerPrefix + slugger.slug(raw) + '">' + text + '</h' + level + '>\n';
}

return '<h' + level + '>' + text + '</h' + level + '>\n';
};
}
Expand Down
61 changes: 61 additions & 0 deletions src/app/shared/components/markdown-render/tocify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { last } from 'lodash-es';

export interface TocItem {
anchor: string;
level: number;
text: string;
children?: TocItem[];
}

export type TocItems = TocItem[]; // TOC目录树结构

export default class Tocify {
anchors: string[];
tocItems: TocItems = [];

constructor() {
this.anchors = [];
this.tocItems = [];
}

add(text: string, level: number, id: string = '') {
// tslint:disable-next-line:no-shadowed-variable
const count = this.anchors.filter(anchor => anchor === text).length;
const anchor = id || (count ? `${text}${count}` : text);
this.anchors.push(anchor);
const item = {anchor, level, text};
const items = this.tocItems;

if (items.length === 0) { // 第一个 item 直接 push
items.push(item);
} else {
let lastItem = last(items) as TocItem; // 最后一个 item

if (item.level > lastItem.level) { // item 是 lastItem 的 children
for (let i = lastItem.level + 1; i <= 6; i++) {
const {children} = lastItem;
if (!children) { // 如果 children 不存在
lastItem.children = [item];
break;
}

lastItem = last(children) as TocItem; // 重置 lastItem 为 children 的最后一个 item

if (item.level <= lastItem.level) { // item level 小于或等于 lastItem level 都视为与 children 同级
children.push(item);
break;
}
}
} else { // 置于最顶级
items.push(item);
}
}

return anchor;
}

reset = () => {
this.tocItems = [];
this.anchors = [];
}
}
29 changes: 23 additions & 6 deletions src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { NgModule } from '@angular/core';
import {NgModule, SecurityContext} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { MarkdownRenderComponent } from './components/markdown-render/markdown-render.component';
import { MarkdownModule } from 'ngx-markdown';
import { MarkdownModule, MarkedOptions } from 'ngx-markdown';
import { CustomMaterialModule } from './custom-material.module';
import { MarkdownRadarChartComponent } from './components/markdown-radar-chart/markdown-radar-chart.component';
import { MarkdownRatingComponent } from './components/markdown-radar-chart/markdown-rating/markdown-rating.component';
import { MarkdownRatingItemComponent } from './components/markdown-radar-chart/markdown-rating-item/markdown-rating-item.component';
import { ProcessTableComponent } from './components/process-table/process-table.component';
import {MarkdownReporterComponent} from './components/markdown-reporter/markdown-reporter.component';
import {MarkdownChartComponent} from './components/markdown-chart/markdown-chart.component';
import {MarkdownTreeComponent} from './components/markdown-tree/markdown-tree.component';
import { MarkdownReporterComponent } from './components/markdown-reporter/markdown-reporter.component';
import { MarkdownChartComponent } from './components/markdown-chart/markdown-chart.component';
import { MarkdownTreeComponent } from './components/markdown-tree/markdown-tree.component';
import Tocify from './components/markdown-render/tocify';

@NgModule({
imports: [
Expand All @@ -22,7 +23,22 @@ import {MarkdownTreeComponent} from './components/markdown-tree/markdown-tree.co
HttpClientModule,
ReactiveFormsModule,
CustomMaterialModule,
MarkdownModule.forRoot({ loader: HttpClient })
MarkdownModule.forRoot({
sanitize: SecurityContext.NONE,
loader: HttpClient,
markedOptions: {
provide: MarkedOptions,
useValue: {
gfm: true,
breaks: false,
pedantic: false,
smartLists: true,
smartypants: false,
headerPrefix: '',
headerIds: true,
},
}
})
],
declarations: [
MarkdownRenderComponent,
Expand All @@ -35,6 +51,7 @@ import {MarkdownTreeComponent} from './components/markdown-tree/markdown-tree.co
MarkdownTreeComponent,
],
providers: [
Tocify,
],
exports: [
MarkdownRenderComponent,
Expand Down

0 comments on commit 30e4426

Please sign in to comment.