feat: get catalog api

pr675
Hufe921 3 years ago committed by Hufe
parent 3d7d7e2107
commit 237c0f22cb

@ -1,6 +1,7 @@
import { IElement, ImageDisplay, INavigateInfo, ListStyle, ListType, TableBorder, TitleLevel, VerticalAlign } from '../..'
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
import { RowFlex } from '../../dataset/enum/Row'
import { ICatalog } from '../../interface/Catalog'
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
import { IEditorResult } from '../../interface/Editor'
import { IMargin } from '../../interface/Margin'
@ -85,6 +86,7 @@ export class Command {
private static insertElementList: CommandAdapt['insertElementList']
private static removeControl: CommandAdapt['removeControl']
private static setLocale: CommandAdapt['setLocale']
private static getCatalog: CommandAdapt['getCatalog']
constructor(adapt: CommandAdapt) {
Command.mode = adapt.mode.bind(adapt)
@ -163,6 +165,7 @@ export class Command {
Command.insertElementList = adapt.insertElementList.bind(adapt)
Command.removeControl = adapt.removeControl.bind(adapt)
Command.setLocale = adapt.setLocale.bind(adapt)
Command.getCatalog = adapt.getCatalog.bind(adapt)
}
// 全局命令
@ -476,4 +479,8 @@ export class Command {
return Command.setLocale(payload)
}
public getCatalog(): Promise<ICatalog | null> {
return Command.getCatalog()
}
}

@ -11,6 +11,7 @@ import { RowFlex } from '../../dataset/enum/Row'
import { TableBorder } from '../../dataset/enum/table/Table'
import { TitleLevel } from '../../dataset/enum/Title'
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
import { ICatalog } from '../../interface/Catalog'
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
import { IEditorOption, IEditorResult } from '../../interface/Editor'
import { IElement, IElementStyle } from '../../interface/Element'
@ -1655,4 +1656,8 @@ export class CommandAdapt {
this.i18n.setLocale(payload)
}
public getCatalog(): Promise<ICatalog | null> {
return this.workerManager.getCatalog()
}
}

@ -1,14 +1,19 @@
import { Draw } from '../draw/Draw'
import WordCountWorker from './works/wordCount?worker&inline'
import CatalogWorker from './works/catalog?worker&inline'
import { ICatalog } from '../../interface/Catalog'
export class WorkerManager {
private draw: Draw
private wordCountWorker: Worker
private catalogWorker: Worker
constructor(draw: Draw) {
this.draw = draw
this.wordCountWorker = new WordCountWorker()
this.catalogWorker = new CatalogWorker()
}
public getWordCount(): Promise<number> {
@ -26,4 +31,19 @@ export class WorkerManager {
})
}
public getCatalog(): Promise<ICatalog | null> {
return new Promise((resolve, reject) => {
this.catalogWorker.onmessage = (evt) => {
resolve(evt.data)
}
this.catalogWorker.onerror = (evt) => {
reject(evt)
}
const elementList = this.draw.getOriginalMainElementList()
this.catalogWorker.postMessage(elementList)
})
}
}

@ -0,0 +1,104 @@
import { ICatalog, ICatalogItem } from '../../../interface/Catalog'
import { IElement } from '../../../interface/Element'
enum ElementType {
TITLE = 'title'
}
enum TitleLevel {
FIRST = 'first',
SECOND = 'second',
THIRD = 'third',
FOURTH = 'fourth',
FIFTH = 'fifth',
SIXTH = 'sixth'
}
const titleOrderNumberMapping: Record<TitleLevel, number> = {
[TitleLevel.FIRST]: 1,
[TitleLevel.SECOND]: 2,
[TitleLevel.THIRD]: 3,
[TitleLevel.FOURTH]: 4,
[TitleLevel.FIFTH]: 5,
[TitleLevel.SIXTH]: 6
}
const ZERO = '\u200B'
function getCatalog(elementList: IElement[]): ICatalog | null {
// 筛选标题
const titleElementList: IElement[] = []
let t = 0
while (t < elementList.length) {
const element = elementList[t]
if (element.titleId) {
const titleId = element.titleId
const level = element.level
const titleElement: IElement = {
type: ElementType.TITLE,
value: '',
level,
titleId
}
const valueList: IElement[] = []
while (t < elementList.length) {
const titleE = elementList[t]
if (titleId !== titleE.titleId) {
t--
break
}
valueList.push(titleE)
t++
}
titleElement.value = valueList.map(s => s.value)
.join('')
.replace(new RegExp(ZERO, 'g'), '')
titleElementList.push(titleElement)
}
t++
}
if (!titleElementList.length) return null
// 查找到比最新元素大的标题时终止
const recursiveInsert = (title: IElement, catalogItem: ICatalogItem) => {
const subCatalogItem = catalogItem.subCatalog[catalogItem.subCatalog.length - 1]
const catalogItemLevel = titleOrderNumberMapping[subCatalogItem?.level]
const titleLevel = titleOrderNumberMapping[title.level!]
if (subCatalogItem && titleLevel > catalogItemLevel) {
recursiveInsert(title, subCatalogItem)
} else {
catalogItem.subCatalog.push({
id: title.titleId!,
name: title.value,
level: title.level!,
subCatalog: []
})
}
}
// 循环标题组
// 如果当前列表级别小于标题组最新标题级别:则递归查找最小级别并追加
// 如果大于:则直接追加至当前标题组
const catalog: ICatalog = []
for (let e = 0; e < titleElementList.length; e++) {
const title = titleElementList[e]
const catalogItem = catalog[catalog.length - 1]
const catalogItemLevel = titleOrderNumberMapping[catalogItem?.level]
const titleLevel = titleOrderNumberMapping[title.level!]
if (catalogItem && titleLevel > catalogItemLevel) {
recursiveInsert(title, catalogItem)
} else {
catalog.push({
id: title.titleId!,
name: title.value,
level: title.level!,
subCatalog: []
})
}
}
return catalog
}
onmessage = (evt) => {
const elementList = <IElement[]>evt.data
const catalog = getCatalog(elementList)
postMessage(catalog)
}

@ -0,0 +1,10 @@
import { TitleLevel } from '../dataset/enum/Title'
export interface ICatalogItem {
id: string;
name: string;
level: TitleLevel;
subCatalog: ICatalogItem[];
}
export type ICatalog = ICatalogItem[]
Loading…
Cancel
Save