mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Core: deprecate highlight on content highlighter
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
deprecate `highlight` on content highlighter
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { Root } from 'mdast';
|
||||
import type { ReactNode } from 'react';
|
||||
import { remark } from 'remark';
|
||||
import type { Transformer } from 'unified';
|
||||
import { visit } from 'unist-util-visit';
|
||||
|
||||
export interface SortedResult<Content = string> {
|
||||
@@ -43,14 +42,15 @@ function buildRegexFromQuery(q: string): RegExp | null {
|
||||
return new RegExp(`(${escaped})`, 'gi');
|
||||
}
|
||||
|
||||
const processor = remark();
|
||||
|
||||
export function createContentHighlighter(query: string | RegExp) {
|
||||
let processor = remark();
|
||||
const regex = typeof query === 'string' ? buildRegexFromQuery(query) : query;
|
||||
if (regex) {
|
||||
processor = processor.use(remarkHighlight, regex) as never;
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* @deprecated use `highlightMarkdown()` instead.
|
||||
*/
|
||||
highlight(content: string): HighlightedText[] {
|
||||
if (!regex) return [{ type: 'text', content }];
|
||||
const out: HighlightedText[] = [];
|
||||
@@ -89,34 +89,33 @@ export function createContentHighlighter(query: string | RegExp) {
|
||||
*/
|
||||
highlightMarkdown(content: string): string {
|
||||
if (!regex) return content;
|
||||
|
||||
return String(processor.processSync(content).value);
|
||||
const tree = processor.parse(content);
|
||||
highlightInTree(tree, regex);
|
||||
return processor.stringify(tree);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function remarkHighlight(regex: RegExp): Transformer<Root, Root> {
|
||||
return (tree) => {
|
||||
visit(tree, 'text', (node) => {
|
||||
let out = '';
|
||||
const content = node.value;
|
||||
function highlightInTree(tree: Root, regex: RegExp) {
|
||||
visit(tree, 'text', (node) => {
|
||||
let out = '';
|
||||
const content = node.value;
|
||||
|
||||
let i = 0;
|
||||
for (const match of content.matchAll(regex)) {
|
||||
if (i < match.index) {
|
||||
out += content.substring(i, match.index);
|
||||
}
|
||||
|
||||
out += `<mark>${match[0]}</mark>`;
|
||||
i = match.index + match[0].length;
|
||||
let i = 0;
|
||||
for (const match of content.matchAll(regex)) {
|
||||
if (i < match.index) {
|
||||
out += content.substring(i, match.index);
|
||||
}
|
||||
|
||||
if (i < content.length) {
|
||||
out += content.substring(i);
|
||||
}
|
||||
out += `<mark>${match[0]}</mark>`;
|
||||
i = match.index + match[0].length;
|
||||
}
|
||||
|
||||
node.type = 'html' as never;
|
||||
node.value = out;
|
||||
});
|
||||
};
|
||||
if (i < content.length) {
|
||||
out += content.substring(i);
|
||||
}
|
||||
|
||||
node.type = 'html' as never;
|
||||
node.value = out;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,96 +4,17 @@ import { createContentHighlighter } from '@/search';
|
||||
test('highlight search results', () => {
|
||||
const highlighter = createContentHighlighter('hello world helloworld');
|
||||
|
||||
expect(highlighter.highlight('oops hello, world hello! worldhello')).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"content": "oops ",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "hello",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": ", ",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "world",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": " ",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "hello",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "! ",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "world",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "hello",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
]
|
||||
expect(highlighter.highlightMarkdown('oops hello, world hello! worldhello'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"oops <mark>hello</mark>, <mark>world</mark> <mark>hello</mark>! <mark>world</mark><mark>hello</mark>
|
||||
"
|
||||
`);
|
||||
expect(highlighter.highlight('helloworld!!!')).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"content": "hello",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "world",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "!!!",
|
||||
"type": "text",
|
||||
},
|
||||
]
|
||||
expect(highlighter.highlightMarkdown('helloworld!!!')).toMatchInlineSnapshot(`
|
||||
"<mark>hello</mark><mark>world</mark>!!!
|
||||
"
|
||||
`);
|
||||
expect(highlighter.highlight('wor ld hello')).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"content": "wor ld ",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"content": "hello",
|
||||
"styles": {
|
||||
"highlight": true,
|
||||
},
|
||||
"type": "text",
|
||||
},
|
||||
]
|
||||
expect(highlighter.highlightMarkdown('wor ld hello')).toMatchInlineSnapshot(`
|
||||
"wor ld <mark>hello</mark>
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createI18nSearchAPI, createSearchAPI } from '@/search/server';
|
||||
import { createI18nSearchAPI, createSearchAPI, type ExportedData } from '@/search/server';
|
||||
import { expect, test } from 'vitest';
|
||||
import { structure } from '@/mdx-plugins';
|
||||
|
||||
@@ -101,7 +101,7 @@ test('Search API I18n', async () => {
|
||||
expect(await api.search('English', { locale: 'en' })).toHaveLength(1);
|
||||
expect(await api.search('amico', { locale: 'italian' })).toHaveLength(1);
|
||||
expect(await api.search('italian', { locale: 'en' })).toHaveLength(0);
|
||||
const exported = await api.export();
|
||||
const exported = (await api.export()) as ExportedData;
|
||||
expect(exported.type).toBe('i18n');
|
||||
|
||||
if (exported.type === 'i18n')
|
||||
|
||||
Reference in New Issue
Block a user