Skip to content

Commit

Permalink
feat: add a plugin option of searchResultContextMaxLength
Browse files Browse the repository at this point in the history
  • Loading branch information
weareoutman committed Oct 23, 2020
1 parent 2b9a7e5 commit 3313552
Show file tree
Hide file tree
Showing 16 changed files with 51 additions and 29 deletions.
27 changes: 14 additions & 13 deletions README.md
Expand Up @@ -64,19 +64,20 @@ yarn add nodejieba

## Plugin Options

| Name | Type | Default | Description |
| --------------------------- | ------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------ |
| indexDocs | boolean | `true` | Whether to index docs. |
| indexBlog | boolean | `true` | Whether to index blog. |
| indexPages | boolean | `false` | Whether to index pages. |
| docsRouteBasePath | string | `"/docs"` | Base route path of docs. Slash at beginning is not required. |
| blogRouteBasePath | string | `"/blog"` | Base route path of blog. Slash at beginning is not required. |
| language | string \| string[] | `"en"` | All [lunr-languages](https://github.com/MihaiValentin/lunr-languages) supported languages, + `zh` 🔥. |
| hashed | boolean | `false` | Whether to add a hashed query when fetching index (based on the content hash of all `*.md`) |
| docsDir | string | `"docs"` | The dir of docs to get the content hash, it's relative to the dir of your project. |
| blogDir | string | `"blog"` | Just like the `docsDir` but applied to blog. |
| removeDefaultStopWordFilter | boolean | `false` | Sometimes people (E.g., us) want to keep the English stop words as indexed, since they maybe are relevant in programming docs. |
| searchResultLimits | number | `8` | Limit the search results. |
| Name | Type | Default | Description |
| ---------------------------- | ------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------ |
| indexDocs | boolean | `true` | Whether to index docs. |
| indexBlog | boolean | `true` | Whether to index blog. |
| indexPages | boolean | `false` | Whether to index pages. |
| docsRouteBasePath | string | `"/docs"` | Base route path of docs. Slash at beginning is not required. |
| blogRouteBasePath | string | `"/blog"` | Base route path of blog. Slash at beginning is not required. |
| language | string \| string[] | `"en"` | All [lunr-languages](https://github.com/MihaiValentin/lunr-languages) supported languages, + `zh` 🔥. |
| hashed | boolean | `false` | Whether to add a hashed query when fetching index (based on the content hash of all `*.md`) |
| docsDir | string | `"docs"` | The dir of docs to get the content hash, it's relative to the dir of your project. |
| blogDir | string | `"blog"` | Just like the `docsDir` but applied to blog. |
| removeDefaultStopWordFilter | boolean | `false` | Sometimes people (E.g., us) want to keep the English stop words as indexed, since they maybe are relevant in programming docs. |
| searchResultLimits | number | `8` | Limit the search results. |
| searchResultContextMaxLength | number | `50` | Set the max length of characters of each search result to show. results. |

## Custom Styles

Expand Down
3 changes: 1 addition & 2 deletions src/client/theme/SearchBar/SearchBar.tsx
Expand Up @@ -8,8 +8,7 @@ import { EmptyTemplate } from "../../utils/EmptyTemplate.js";
import { SearchResult } from "../../../shared/interfaces";

// This file is auto generated while building.
import { searchResultLimits } from "../../../../generated.js";

import { searchResultLimits } from "../../utils/proxiedGenerated";
import "./SearchBar.css";

async function fetchAutoCompleteJS(): Promise<any> {
Expand Down
9 changes: 2 additions & 7 deletions src/client/theme/SearchBar/fetchIndexes.spec.ts
Expand Up @@ -2,13 +2,8 @@ import lunr from "lunr";
import { fetchIndexes } from "./fetchIndexes";

jest.mock("lunr");
jest.mock(
"../../../../generated.js",
() => ({
indexHash: "abc",
}),
{ virtual: true }
);
jest.mock("../../utils/proxiedGenerated");

const mockLunrIndexLoad = (jest.spyOn(
lunr.Index,
"load"
Expand Down
2 changes: 1 addition & 1 deletion src/client/theme/SearchBar/fetchIndexes.ts
Expand Up @@ -6,7 +6,7 @@ import {
} from "../../../shared/interfaces";

// This file is auto generated while building.
import { indexHash } from "../../../../generated.js";
import { indexHash } from "../../utils/proxiedGenerated";

interface SerializedIndex {
documents: SearchDocument[];
Expand Down
2 changes: 1 addition & 1 deletion src/client/theme/SearchBar/index.ts
@@ -1,4 +1,4 @@
import "../../../../generated.js";
import "../../utils/proxiedGenerated";
import SearchBar from "./SearchBar";

export default SearchBar;
1 change: 1 addition & 0 deletions src/client/utils/SuggestionTemplate.spec.ts
@@ -1,6 +1,7 @@
import { SuggestionTemplate } from "./SuggestionTemplate";

jest.mock("./icons");
jest.mock("./proxiedGenerated");

describe("SuggestionTemplate", () => {
test("page title", () => {
Expand Down
3 changes: 3 additions & 0 deletions src/client/utils/__mocks__/proxiedGenerated.ts
@@ -0,0 +1,3 @@
export const indexHash = "abc";
export const searchResultLimits = 8;
export const searchResultContextMaxLength = 50;
4 changes: 3 additions & 1 deletion src/client/utils/highlightStemmed.spec.ts
Expand Up @@ -5,6 +5,8 @@ import {
} from "../../shared/interfaces";
import { highlightStemmed, splitIntoChunks } from "./highlightStemmed";

jest.mock("./proxiedGenerated");

describe("highlightStemmed", () => {
test.each<[string, MetadataPosition[], string[], number | undefined, string]>(
[
Expand Down Expand Up @@ -158,7 +160,7 @@ describe("splitIntoChunks", () => {
])(
"splitIntoChunks('%s', %j, %j, 0, 0) should return %j",
(text, positions, tokens, chunks, chunkIndex) => {
const chunkIndexRef: ChunkIndexRef = {};
const chunkIndexRef = {} as ChunkIndexRef;
expect(
splitIntoChunks(text, positions, tokens, 0, 0, chunkIndexRef)
).toEqual(chunks);
Expand Down
3 changes: 2 additions & 1 deletion src/client/utils/highlightStemmed.ts
Expand Up @@ -6,12 +6,13 @@ import {
import { escapeHtml } from "./escapeHtml";
import { highlight } from "./highlight";
import { looseTokenize } from "./looseTokenize";
import { searchResultContextMaxLength } from "./proxiedGenerated";

export function highlightStemmed(
content: string,
positions: MetadataPosition[],
tokens: string[],
maxLength = 50
maxLength = searchResultContextMaxLength
): string {
const chunkIndexRef: ChunkIndexRef = {
chunkIndex: -1,
Expand Down
1 change: 1 addition & 0 deletions src/client/utils/proxiedGenerated.ts
@@ -0,0 +1 @@
export * from "../../../generated.js";
1 change: 1 addition & 0 deletions src/declarations.ts
Expand Up @@ -20,4 +20,5 @@ declare module "autocomplete.js" {
declare module "*/generated.js" {
export const indexHash: string | undefined;
export const searchResultLimits: number;
export const searchResultContextMaxLength: number;
}
11 changes: 10 additions & 1 deletion src/server/utils/generate.spec.ts
Expand Up @@ -21,6 +21,7 @@ describe("generate", () => {
'import lunr from "lunr";',
'export const indexHash = "abc";',
"export const searchResultLimits = 8;",
"export const searchResultContextMaxLength = 50;",
],
],
[
Expand All @@ -31,6 +32,7 @@ describe("generate", () => {
'require("./client/shared/lunrLanguageZh").lunrLanguageZh(lunr);',
'export const indexHash = "abc";',
"export const searchResultLimits = 8;",
"export const searchResultContextMaxLength = 50;",
],
],
[
Expand All @@ -41,6 +43,7 @@ describe("generate", () => {
'require("lunr-languages/lunr.es")(lunr);',
'export const indexHash = "abc";',
"export const searchResultLimits = 8;",
"export const searchResultContextMaxLength = 50;",
],
],
[
Expand All @@ -52,6 +55,7 @@ describe("generate", () => {
'require("lunr-languages/lunr.multi")(lunr);',
'export const indexHash = "abc";',
"export const searchResultLimits = 8;",
"export const searchResultContextMaxLength = 50;",
],
],
[
Expand All @@ -64,10 +68,15 @@ describe("generate", () => {
'require("lunr-languages/lunr.multi")(lunr);',
'export const indexHash = "abc";',
"export const searchResultLimits = 8;",
"export const searchResultContextMaxLength = 50;",
],
],
])("generate({ language: %j }) should work", (language, contents) => {
generate({ language, searchResultLimits: 8 } as ProcessedPluginOptions);
generate({
language,
searchResultLimits: 8,
searchResultContextMaxLength: 50,
} as ProcessedPluginOptions);
expect(mockWriteFileSync).toBeCalledWith(
expect.stringContaining("generated.js"),
contents.join("\n")
Expand Down
7 changes: 5 additions & 2 deletions src/server/utils/generate.ts
Expand Up @@ -4,7 +4,7 @@ import { ProcessedPluginOptions } from "../../shared/interfaces";
import { getIndexHash } from "./getIndexHash";

export function generate(config: ProcessedPluginOptions): void {
const { language, searchResultLimits } = config;
const { language, searchResultLimits, searchResultContextMaxLength } = config;
const indexHash = getIndexHash(config);
const contents: string[] = ['import lunr from "lunr";'];
if (language.length > 1 || language.some((item) => item !== "en")) {
Expand All @@ -25,7 +25,10 @@ export function generate(config: ProcessedPluginOptions): void {
}
contents.push(`export const indexHash = ${JSON.stringify(indexHash)};`);
contents.push(
`export const searchResultLimits = ${JSON.stringify(searchResultLimits)};`
`export const searchResultLimits = ${JSON.stringify(searchResultLimits)};`,
`export const searchResultContextMaxLength = ${JSON.stringify(
searchResultContextMaxLength
)};`
);

fs.writeFileSync(
Expand Down
4 changes: 4 additions & 0 deletions src/server/utils/processPluginOptions.spec.ts
Expand Up @@ -19,6 +19,7 @@ describe("processPluginOptions", () => {
language: ["en"],
removeDefaultStopWordFilter: false,
searchResultLimits: 8,
searchResultContextMaxLength: 50,
},
],
[
Expand All @@ -35,13 +36,15 @@ describe("processPluginOptions", () => {
language: ["en", "zh"],
removeDefaultStopWordFilter: false,
searchResultLimits: 8,
searchResultContextMaxLength: 50,
},
],
[
{
docsDir: "src/docs",
blogDir: "src/blog",
searchResultLimits: 5,
searchResultContextMaxLength: 30,
},
{
blogRouteBasePath: "blog",
Expand All @@ -55,6 +58,7 @@ describe("processPluginOptions", () => {
language: ["en"],
removeDefaultStopWordFilter: false,
searchResultLimits: 5,
searchResultContextMaxLength: 30,
},
],
])("processPluginOptions(...) should work", (options, config) => {
Expand Down
1 change: 1 addition & 0 deletions src/server/utils/processPluginOptions.ts
Expand Up @@ -18,6 +18,7 @@ export function processPluginOptions(
blogDir: "blog",
removeDefaultStopWordFilter: false,
searchResultLimits: 8,
searchResultContextMaxLength: 50,
},
options
) as ProcessedPluginOptions;
Expand Down
1 change: 1 addition & 0 deletions src/shared/interfaces.ts
Expand Up @@ -112,6 +112,7 @@ export interface PluginOptions {
blogDir?: string;
removeDefaultStopWordFilter?: boolean;
searchResultLimits?: number;
searchResultContextMaxLength?: number;
}

export type ProcessedPluginOptions = Required<PluginOptions> & {
Expand Down

0 comments on commit 3313552

Please sign in to comment.