diff --git a/docs/en/guide/command-get.md b/docs/en/guide/command-get.md index 96f633b..eab021d 100644 --- a/docs/en/guide/command-get.md +++ b/docs/en/guide/command-get.md @@ -114,3 +114,17 @@ const { footer: string } = await instance.command.getHTML() ``` + +## getText + +Feature: Get text + +Usage: + +```javascript +const { + header: string + main: string + footer: string +} = await instance.command.getText() +``` diff --git a/docs/guide/command-get.md b/docs/guide/command-get.md index bdeaf55..967bd65 100644 --- a/docs/guide/command-get.md +++ b/docs/guide/command-get.md @@ -114,3 +114,17 @@ const { footer: string } = await instance.command.getHTML() ``` + +## getText + +功能:获取文本 + +用法: + +```javascript +const { + header: string + main: string + footer: string +} = await instance.command.getText() +``` diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index 7cd6c21..c386fe4 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -80,6 +80,7 @@ export class Command { public getImage: CommandAdapt['getImage'] public getValue: CommandAdapt['getValue'] public getHTML: CommandAdapt['getHTML'] + public getText: CommandAdapt['getText'] public getWordCount: CommandAdapt['getWordCount'] public getRangeText: CommandAdapt['getRangeText'] public getRangeContext: CommandAdapt['getRangeContext'] @@ -174,6 +175,7 @@ export class Command { this.getImage = adapt.getImage.bind(adapt) this.getValue = adapt.getValue.bind(adapt) this.getHTML = adapt.getHTML.bind(adapt) + this.getText = adapt.getText.bind(adapt) this.getWordCount = adapt.getWordCount.bind(adapt) this.getRangeText = adapt.getRangeText.bind(adapt) this.getRangeContext = adapt.getRangeContext.bind(adapt) diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index 7e00da7..ad76899 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -29,7 +29,8 @@ import { IEditorData, IEditorHTML, IEditorOption, - IEditorResult + IEditorResult, + IEditorText } from '../../interface/Editor' import { IElement, IElementStyle } from '../../interface/Element' import { IMargin } from '../../interface/Margin' @@ -45,7 +46,8 @@ import { formatElementList, isTextLikeElement, pickElementAttr, - getElementListByHTML + getElementListByHTML, + getTextFromElementList } from '../../utils/element' import { printImageBase64 } from '../../utils/print' import { Control } from '../draw/control/Control' @@ -1703,6 +1705,17 @@ export class CommandAdapt { } } + public getText(): IEditorText { + const headerElementList = this.draw.getHeaderElementList() + const mainElementList = this.draw.getOriginalMainElementList() + const footerElementList = this.draw.getFooterElementList() + return { + header: getTextFromElementList(headerElementList), + main: getTextFromElementList(mainElementList), + footer: getTextFromElementList(footerElementList) + } + } + public getWordCount(): Promise { return this.workerManager.getWordCount() } diff --git a/src/editor/core/range/RangeManager.ts b/src/editor/core/range/RangeManager.ts index 894020f..3442634 100644 --- a/src/editor/core/range/RangeManager.ts +++ b/src/editor/core/range/RangeManager.ts @@ -509,7 +509,7 @@ export class RangeManager { } public toString(): string { - const selection = this.getSelection() + const selection = this.getTextLikeSelection() if (!selection) return '' return selection .map(s => s.value) diff --git a/src/editor/interface/Editor.ts b/src/editor/interface/Editor.ts index 713ad10..57038da 100644 --- a/src/editor/interface/Editor.ts +++ b/src/editor/interface/Editor.ts @@ -86,3 +86,5 @@ export interface IEditorHTML { main: string footer: string } + +export type IEditorText = IEditorHTML diff --git a/src/editor/utils/element.ts b/src/editor/utils/element.ts index dbefe5b..135eaf7 100644 --- a/src/editor/utils/element.ts +++ b/src/editor/utils/element.ts @@ -701,6 +701,36 @@ export function convertElementToDom( return dom } +export function splitListElement( + elementList: IElement[] +): Map { + let curListIndex = 0 + const listElementListMap: Map = new Map() + for (let e = 0; e < elementList.length; e++) { + const element = elementList[e] + if (element.listWrap) { + const listElementList = listElementListMap.get(curListIndex) || [] + listElementList.push(element) + listElementListMap.set(curListIndex, listElementList) + } else { + const valueList = element.value.split('\n') + for (let c = 0; c < valueList.length; c++) { + if (c > 0) { + curListIndex += 1 + } + const value = valueList[c] + const listElementList = listElementListMap.get(curListIndex) || [] + listElementList.push({ + ...element, + value + }) + listElementListMap.set(curListIndex, listElementList) + } + } + } + return listElementListMap +} + export function createDomFromElementList( elementList: IElement[], options: DeepRequired @@ -754,31 +784,8 @@ export function createDomFromElementList( list.style.listStyleType = listStyleCSSMapping[element.listStyle] } // 按照换行符拆分 - let curListIndex = 0 - const listElementListMap: Map = new Map() const zipList = zipElementList(element.valueList!) - for (let z = 0; z < zipList.length; z++) { - const zipElement = zipList[z] - if (zipElement.listWrap) { - const listElementList = listElementListMap.get(curListIndex) || [] - listElementList.push(zipElement) - listElementListMap.set(curListIndex, listElementList) - } else { - const zipValueList = zipElement.value.split('\n') - for (let c = 0; c < zipValueList.length; c++) { - if (c > 0) { - curListIndex += 1 - } - const value = zipValueList[c] - const listElementList = listElementListMap.get(curListIndex) || [] - listElementList.push({ - ...zipElement, - value - }) - listElementListMap.set(curListIndex, listElementList) - } - } - } + const listElementListMap = splitListElement(zipList) listElementListMap.forEach(listElementList => { const li = document.createElement('li') const childDom = buildDom(listElementList) @@ -1061,3 +1068,59 @@ export function getElementListByHTML( clipboardDom.remove() return elementList } + +export function getTextFromElementList(elementList: IElement[]) { + function buildText(payload: IElement[]): string { + let text = '' + for (let e = 0; e < payload.length; e++) { + const element = payload[e] + // 构造表格 + if (element.type === ElementType.TABLE) { + text += `\n` + const trList = element.trList! + for (let t = 0; t < trList.length; t++) { + const tr = trList[t] + for (let d = 0; d < tr.tdList.length; d++) { + const td = tr.tdList[d] + const tdText = buildText(zipElementList(td.value!)) + const isFirst = d === 0 + const isLast = tr.tdList.length - 1 === d + text += `${!isFirst ? ` ` : ``}${tdText}${isLast ? `\n` : ``}` + } + } + } else if (element.type === ElementType.HYPERLINK) { + text += element.valueList!.map(v => v.value).join('') + } else if (element.type === ElementType.TITLE) { + text += `${buildText(zipElementList(element.valueList!))}` + } else if (element.type === ElementType.LIST) { + // 按照换行符拆分 + const zipList = zipElementList(element.valueList!) + const listElementListMap = splitListElement(zipList) + listElementListMap.forEach((listElementList, listIndex) => { + const isLast = listElementListMap.size - 1 === listIndex + text += `\n${listIndex + 1}.${buildText(listElementList)}${ + isLast ? `\n` : `` + }` + }) + } else if (element.type === ElementType.CHECKBOX) { + text += element.checkbox?.value ? `☑` : `□` + } else if ( + !element.type || + element.type === ElementType.LATEX || + TEXTLIKE_ELEMENT_TYPE.includes(element.type) + ) { + let textLike = '' + if (element.type === ElementType.CONTROL) { + textLike = element.control!.value?.[0]?.value || '' + } else if (element.type === ElementType.DATE) { + textLike = element.valueList?.map(v => v.value).join('') || '' + } else { + textLike = element.value + } + text += textLike.replace(new RegExp(`${ZERO}`, 'g'), '\n') + } + } + return text + } + return buildText(zipElementList(elementList)) +}