import {
Paragraph,
ParagraphChild,
IPropertiesOptions,
Table,
TextRun
} from "docx"
import docxTitle from "./docxTitle"
import docxText from "./docxText"
import docxList from "./docxList"
import docxTable from "./docxTable"
import docxImage from "./docxImage"
// 全局标签
const TagsList = [
'h1', // 标题
'h2', // 章节
'h3', 'h4', 'h5', 'h6', // 子章节
// 文本标签
'p', // 段落(自动在前后添加间距)
'br', // 换行(单标签,插入换行)
'hr', // 水平线(分隔内容,常用于段落之间)
// 'pre', // 预格式化文本(保留空格和换行,常用于代码块)
'strong', // 强调重要性(加粗)
'em', // 强调语气(斜体)
'b', // 粗体
'i', // 斜体
'mark', // 高亮(黄色背景)
'small', // 小字(字体变小)
'sub', // 下标
'sup', // 上标
'del', // 删除内容(删除线)
'ins', // 插入内容(下划线)
'blockquote', // 块引用(长段引用内容,默认缩进)
'q', // 行内短引用(自动加引号)
'cite', // 引用来源(常用于引用文章标题或出处)
'code', // 代码片段(等宽字体)
'kbd', // 用户输入(表示键盘输入)
'samp', // 输出结果(表示计算机输出)
'var', // 变量名(通常斜体)
'mjx-container', // 数学公式
'div', // 块 -> 可转换成特殊表格块
'details', // 描述 -> 可转换成特殊表格块
'ul', // 无序列表,子项标签
'ol', // 有序列表,子项标签
'table', // 表格主体标签
'img', 'canvas', // 图片
]
// 可嵌套标签
const NestTagsList = [
// 文本标签
'p', // 段落(自动在前后添加间距)
'br', // 换行(单标签,插入换行)
'hr', // 水平线(分隔内容,常用于段落之间)
// 'pre', // 预格式化文本(保留空格和换行,常用于代码块)
'strong', // 强调重要性(加粗)
'em', // 强调语气(斜体)
'b', // 粗体
'i', // 斜体
'mark', // 高亮(黄色背景)
'small', // 小字(字体变小)
'sub', // 下标
'sup', // 上标
'del', // 删除内容(删除线)
'ins', // 插入内容(下划线)
'blockquote', // 块引用(长段引用内容,默认缩进)
'q', // 行内短引用(自动加引号)
'cite', // 引用来源(常用于引用文章标题或出处)
'code', // 代码片段(等宽字体)
'kbd', // 用户输入(表示键盘输入)
'samp', // 输出结果(表示计算机输出)
'var', // 变量名(通常斜体)
'mjx-container', // 数学公式
'ul', // 无序列表,子项标签
'ol', // 有序列表,子项标签
'table', // 表格主体标签
'img', 'canvas', // 图片
]
// 可内嵌标签(段落内部嵌套标签)
const EmbeddedTagsList = [
// 文本标签
'br', // 换行(单标签,插入换行)
// 'pre', // 预格式化文本(保留空格和换行,常用于代码块)
'strong', // 强调重要性(加粗)
'em', // 强调语气(斜体)
'b', // 粗体
'i', // 斜体
'mark', // 高亮(黄色背景)
'small', // 小字(字体变小)
'sub', // 下标
'sup', // 上标
'del', // 删除内容(删除线)
'ins', // 插入内容(下划线)
'blockquote', // 块引用(长段引用内容,默认缩进)
'q', // 行内短引用(自动加引号)
'cite', // 引用来源(常用于引用文章标题或出处)
'code', // 代码片段(等宽字体)
'kbd', // 用户输入(表示键盘输入)
'samp', // 输出结果(表示计算机输出)
'var', // 变量名(通常斜体)
'mjx-container', // 数学公式
]
let title: string | undefined = undefined
export function getTitle(): string | undefined {
return title
}
export function getConfig(): Omit {
return {
...docxTitle.config,
...docxText.config,
...docxList.config,
...docxTable.config,
...docxImage.config
}
}
export const handleElement = async (dom: Element): Promise<(Paragraph | Table)[]> => {
const paragraphs: (Paragraph | Table)[] = []
for (const el of dom.querySelectorAll(TagsList.toString())) {
const text = el.textContent?.trim()
if (!text) continue
// 处理标题
if (title === undefined) {
title = docxTitle.handleTitle(el)
}
// 处理章节标题和普通文本内容
const textParagraph = docxText.handleText(el)
if (textParagraph) {
paragraphs.push(textParagraph)
continue
}
// 处理无序和有序列表
const listParagraph = await docxList.handleList(el)
if (listParagraph) {
paragraphs.push(...listParagraph)
continue
}
// 处理表格
const tableParagraph = docxTable.handleTable(el)
if (tableParagraph) {
paragraphs.push(tableParagraph)
continue
}
// 处理图片
const imageParagraph = await docxImage.handleImage(el)
if (imageParagraph) {
paragraphs.push(imageParagraph)
continue
}
console.warn(`${el.tagName} 标签未处理。`)
}
return paragraphs
}
export const handleNestElement = async (dom: Element): Promise<(Paragraph | Table)[]> => {
const paragraphs: (Paragraph | Table)[] = []
for (const el of dom.querySelectorAll(NestTagsList.toString())) {
const text = el.textContent?.trim()
if (!text) continue
// 处理章节标题和普通文本内容
const textParagraph = docxText.handleText(el)
if (textParagraph) {
paragraphs.push(textParagraph)
continue
}
// 处理无序和有序列表
const listParagraph = await docxList.handleList(el)
if (listParagraph) {
paragraphs.push(...listParagraph)
continue
}
// 处理表格
const tableParagraph = docxTable.handleTable(el)
if (tableParagraph) {
paragraphs.push(tableParagraph)
continue
}
// 处理图片
const imageParagraph = await docxImage.handleImage(el)
if (imageParagraph) {
paragraphs.push(imageParagraph)
continue
}
console.warn(`${el.tagName} 标签未处理。`)
}
return paragraphs
}
export const handleEmbeddedElement = (dom: Element): ParagraphChild => {
for (const el of dom.querySelectorAll(EmbeddedTagsList.toString())) {
const text = el.textContent?.trim()
if (!text) continue
// 处理章节标题和普通文本内容
const textParagraphChiled = docxText.handleEmbeddedText(el)
if (textParagraphChiled) {
return textParagraphChiled
}
console.warn(`${el.tagName} 标签未处理。`)
return new TextRun("")
}
}