Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ By default, the hyperlink on the current page is recognized and the content is s
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
```

This plugin ignores diacritical marks when performing a full text search (e.g., "cafe" will also match "café"). Legacy browsers like IE11 require the following [String.normalize()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) polyfill to ignore diacritical marks:

```html
<script src="//polyfill.io/v3/polyfill.min.js?features=String.prototype.normalize"></script>
```

## Google Analytics

Install the plugin and configure the track id.
Expand Down
28 changes: 23 additions & 5 deletions src/plugins/search/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ export function genIndex(path, content = '', router, depth) {
return index;
}

export function ignoreDiacriticalMarks(keyword) {
if (keyword && keyword.normalize) {
return keyword.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
return keyword;
}

/**
* @param {String} query Search query
* @returns {Array} Array of results
Expand All @@ -152,6 +159,8 @@ export function search(query) {
const post = data[i];
let matchesScore = 0;
let resultStr = '';
let handlePostTitle = '';
let handlePostContent = '';
const postTitle = post.title && post.title.trim();
const postContent = post.body && post.body.trim();
const postUrl = post.slug || '';
Expand All @@ -160,14 +169,23 @@ export function search(query) {
keywords.forEach(keyword => {
// From https://github.com/sindresorhus/escape-string-regexp
const regEx = new RegExp(
keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'),
ignoreDiacriticalMarks(keyword).replace(
/[|\\{}()[\]^$+*?.]/g,
'\\$&'
),
'gi'
);
let indexTitle = -1;
let indexContent = -1;
handlePostTitle = postTitle
? ignoreDiacriticalMarks(postTitle)
: postTitle;
handlePostContent = postContent
? ignoreDiacriticalMarks(postContent)
: postContent;

indexTitle = postTitle ? postTitle.search(regEx) : -1;
indexContent = postContent ? postContent.search(regEx) : -1;
indexTitle = postTitle ? handlePostTitle.search(regEx) : -1;
indexContent = postContent ? handlePostContent.search(regEx) : -1;

if (indexTitle >= 0 || indexContent >= 0) {
matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0;
Expand All @@ -187,7 +205,7 @@ export function search(query) {

const matchContent =
'...' +
escapeHtml(postContent)
handlePostContent
.substring(start, end)
.replace(
regEx,
Expand All @@ -201,7 +219,7 @@ export function search(query) {

if (matchesScore > 0) {
const matchingPost = {
title: escapeHtml(postTitle),
title: handlePostTitle,
content: postContent ? resultStr : '',
url: postUrl,
score: matchesScore,
Expand Down
19 changes: 19 additions & 0 deletions test/e2e/search.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,23 @@ describe('Search Plugin Tests', function() {
await page.fill('input[type=search]', 'test');
await expect(page).toEqualText('.results-panel h2', 'Test Page');
});

test('search ignore diacritical marks', async () => {
const docsifyInitConfig = {
markdown: {
homepage: `
# Qué es

docsify genera su sitio web de documentación sobre la marcha. A diferencia de GitBook, no genera archivos estáticos html. En cambio, carga y analiza de forma inteligente sus archivos de Markdown y los muestra como sitio web. Todo lo que necesita hacer es crear un index.html para comenzar y desplegarlo en GitHub Pages.
`,
},
scriptURLs: ['/lib/plugins/search.min.js'],
};
await docsifyInit(docsifyInitConfig);
await page.fill('input[type=search]', 'documentacion');
await expect(page).toEqualText('.results-panel h2', 'Que es');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to show the accent in the result ?

sorry if I missed any previous discussion regarding this. LMK

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a good idea how to do it...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like @sy-records got 2 of the 3 I listed. Perhaps we should open a new issue regarding missing diacritical marks in the search results so we can merge and release this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. #1491

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a new issue for missing diacritical remarks in search results (#1492).

await page.click('.clear-button');
await page.fill('input[type=search]', 'estáticos');
await expect(page).toEqualText('.results-panel h2', 'Que es');
});
});