fuc-new/doc/node_modules/@vuepress/helper/lib/node/page/text.js
hellcat 6adbc04d4b 1
2025-10-03 17:17:08 +08:00

105 lines
3.0 KiB
JavaScript

/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
import { isHTMLTag } from '@vue/shared';
import { load } from 'cheerio';
import {} from 'vuepress/shared';
import { isArray } from '../../shared/index.js';
const MEDIA_WITH_ALT = ['img'];
const REMOVED_TAGS = [
// non content
'title',
'base',
'meta',
'template',
'script',
'style',
'canvas',
'slot',
// not main content
'nav',
'aside',
'footer',
// deleted
'del',
's',
// rich media
'audio',
'video',
'canvas',
'iframe',
'map',
'area',
'track',
'object',
// input
'input',
'textarea',
'select',
'option',
'optgroup',
'datalist',
];
const handleNode = (node, { base, removedTags }) => {
if (node.type === 'tag') {
// toc should be dropped
if ([node.attribs.class, node.attribs.id].some((item) => ['table-of-contents', 'toc'].includes(item)))
return '';
// return alt text
if (MEDIA_WITH_ALT.includes(node.tagName)) {
return node.attribs.alt || '';
}
// html tags can be returned
if (!REMOVED_TAGS.includes(node.tagName) &&
!removedTags.includes(node.tagName) &&
isHTMLTag(node.tagName)) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return handleNodes(node.children, { base, removedTags });
}
return '';
}
if (node.type === 'text')
return node.data;
return '';
};
const handleNodes = (nodes, { base, removedTags }) => isArray(nodes)
? nodes.map((node) => handleNode(node, { base, removedTags })).join('')
: '';
const $ = load('');
/**
* Get plain text from html content
*
* 从 HTML 内容中获取纯文本
*
* @param html - HTML content / HTML 内容
* @param base - Base url of site / 站点的基础 URL
* @param options - Options for getting text / 获取文本的选项
*
* @returns Plain text content / 纯文本内容
*/
export const getText = (html, base, { length = 300, singleLine, removedTags = ['table', 'pre'], } = {}) => {
let result = '';
const rootNodes = html ? $.parseHTML(html) : [];
for (const node of rootNodes) {
const text = handleNode(node, { base, removedTags });
if (text) {
result += text;
if (text.length >= length)
break;
}
}
return (singleLine ? result.replace(/\n/g, ' ').replace(/\s+/g, ' ') : result).trim();
};
/**
* Get plain text of page content
*
* 获取页面内容的纯文本
*
* @param app - VuePress App / VuePress 应用
* @param page - VuePress Page / VuePress 页面
* @param options - Options for getting text / 获取文本的选项
*
* @returns Plain text of page content / 页面内容的纯文本
*/
export const getPageText = ({ options: { base } }, { contentRendered,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}, options = {}) => getText(contentRendered, base, options);