mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
refactoring to ParserContext
This commit is contained in:
parent
a8d12f723f
commit
75d8627f1c
@ -1,3 +1,4 @@
|
|||||||
|
const ParsingContext = require("../src/services/search/parsing_context");
|
||||||
const parser = require('../src/services/search/parser');
|
const parser = require('../src/services/search/parser');
|
||||||
|
|
||||||
describe("Parser", () => {
|
describe("Parser", () => {
|
||||||
@ -5,7 +6,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: ["hello", "hi"],
|
fulltextTokens: ["hello", "hi"],
|
||||||
expressionTokens: [],
|
expressionTokens: [],
|
||||||
includingNoteContent: false
|
parsingContext: new ParsingContext(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("NoteCacheFulltextExp");
|
expect(rootExp.constructor.name).toEqual("NoteCacheFulltextExp");
|
||||||
@ -16,7 +17,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: ["hello", "hi"],
|
fulltextTokens: ["hello", "hi"],
|
||||||
expressionTokens: [],
|
expressionTokens: [],
|
||||||
includingNoteContent: true
|
parsingContext: new ParsingContext(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("OrExp");
|
expect(rootExp.constructor.name).toEqual("OrExp");
|
||||||
@ -33,7 +34,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: [],
|
fulltextTokens: [],
|
||||||
expressionTokens: ["#mylabel", "=", "text"],
|
expressionTokens: ["#mylabel", "=", "text"],
|
||||||
includingNoteContent: true
|
parsingContext: new ParsingContext(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("FieldComparisonExp");
|
expect(rootExp.constructor.name).toEqual("FieldComparisonExp");
|
||||||
@ -46,7 +47,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: [],
|
fulltextTokens: [],
|
||||||
expressionTokens: ["#first", "=", "text", "AND", "#second", "=", "text"],
|
expressionTokens: ["#first", "=", "text", "AND", "#second", "=", "text"],
|
||||||
includingNoteContent: true
|
parsingContext: new ParsingContext(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("AndExp");
|
expect(rootExp.constructor.name).toEqual("AndExp");
|
||||||
@ -63,7 +64,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: [],
|
fulltextTokens: [],
|
||||||
expressionTokens: ["#first", "=", "text", "#second", "=", "text"],
|
expressionTokens: ["#first", "=", "text", "#second", "=", "text"],
|
||||||
includingNoteContent: true
|
parsingContext: new ParsingContext(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("AndExp");
|
expect(rootExp.constructor.name).toEqual("AndExp");
|
||||||
@ -80,7 +81,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: [],
|
fulltextTokens: [],
|
||||||
expressionTokens: ["#first", "=", "text", "OR", "#second", "=", "text"],
|
expressionTokens: ["#first", "=", "text", "OR", "#second", "=", "text"],
|
||||||
includingNoteContent: true
|
parsingContext: new ParsingContext(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("OrExp");
|
expect(rootExp.constructor.name).toEqual("OrExp");
|
||||||
@ -97,7 +98,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: ["hello"],
|
fulltextTokens: ["hello"],
|
||||||
expressionTokens: ["#mylabel", "=", "text"],
|
expressionTokens: ["#mylabel", "=", "text"],
|
||||||
includingNoteContent: false
|
parsingContext: new ParsingContext(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("AndExp");
|
expect(rootExp.constructor.name).toEqual("AndExp");
|
||||||
@ -114,7 +115,7 @@ describe("Parser", () => {
|
|||||||
const rootExp = parser({
|
const rootExp = parser({
|
||||||
fulltextTokens: [],
|
fulltextTokens: [],
|
||||||
expressionTokens: ["#first", "=", "text", "OR", ["#second", "=", "text", "AND", "#third", "=", "text"]],
|
expressionTokens: ["#first", "=", "text", "OR", ["#second", "=", "text", "AND", "#third", "=", "text"]],
|
||||||
includingNoteContent: false
|
parsingContext: new ParsingContext(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(rootExp.constructor.name).toEqual("OrExp");
|
expect(rootExp.constructor.name).toEqual("OrExp");
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const ParsingContext = require('./parsing_context');
|
||||||
const AndExp = require('./expressions/and');
|
const AndExp = require('./expressions/and');
|
||||||
const OrExp = require('./expressions/or');
|
const OrExp = require('./expressions/or');
|
||||||
const NotExp = require('./expressions/not');
|
const NotExp = require('./expressions/not');
|
||||||
@ -7,13 +10,13 @@ const NoteCacheFulltextExp = require('./expressions/note_cache_fulltext');
|
|||||||
const NoteContentFulltextExp = require('./expressions/note_content_fulltext');
|
const NoteContentFulltextExp = require('./expressions/note_content_fulltext');
|
||||||
const comparatorBuilder = require('./comparator_builder');
|
const comparatorBuilder = require('./comparator_builder');
|
||||||
|
|
||||||
function getFulltext(tokens, includingNoteContent, highlightedTokens) {
|
function getFulltext(tokens, parsingContext) {
|
||||||
highlightedTokens.push(...tokens);
|
parsingContext.highlightedTokens.push(...tokens);
|
||||||
|
|
||||||
if (tokens.length === 0) {
|
if (tokens.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else if (includingNoteContent) {
|
else if (parsingContext.includeNoteContent) {
|
||||||
return new OrExp([
|
return new OrExp([
|
||||||
new NoteCacheFulltextExp(tokens),
|
new NoteCacheFulltextExp(tokens),
|
||||||
new NoteContentFulltextExp(tokens)
|
new NoteContentFulltextExp(tokens)
|
||||||
@ -28,7 +31,7 @@ function isOperator(str) {
|
|||||||
return str.match(/^[=<>*]+$/);
|
return str.match(/^[=<>*]+$/);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExpression(tokens, highlightedTokens) {
|
function getExpression(tokens, parsingContext) {
|
||||||
if (tokens.length === 0) {
|
if (tokens.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -44,18 +47,18 @@ function getExpression(tokens, highlightedTokens) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(token)) {
|
if (Array.isArray(token)) {
|
||||||
expressions.push(getExpression(token, highlightedTokens));
|
expressions.push(getExpression(token, parsingContext));
|
||||||
}
|
}
|
||||||
else if (token.startsWith('#') || token.startsWith('@')) {
|
else if (token.startsWith('#') || token.startsWith('@')) {
|
||||||
const type = token.startsWith('#') ? 'label' : 'relation';
|
const type = token.startsWith('#') ? 'label' : 'relation';
|
||||||
|
|
||||||
highlightedTokens.push(token.substr(1));
|
parsingContext.highlightedTokens.push(token.substr(1));
|
||||||
|
|
||||||
if (i < tokens.length - 2 && isOperator(tokens[i + 1])) {
|
if (i < tokens.length - 2 && isOperator(tokens[i + 1])) {
|
||||||
const operator = tokens[i + 1];
|
const operator = tokens[i + 1];
|
||||||
const comparedValue = tokens[i + 2];
|
const comparedValue = tokens[i + 2];
|
||||||
|
|
||||||
highlightedTokens.push(comparedValue);
|
parsingContext.highlightedTokens.push(comparedValue);
|
||||||
|
|
||||||
const comparator = comparatorBuilder(operator, comparedValue);
|
const comparator = comparatorBuilder(operator, comparedValue);
|
||||||
|
|
||||||
@ -99,12 +102,10 @@ function getExpression(tokens, highlightedTokens) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse({fulltextTokens, expressionTokens, includingNoteContent, highlightedTokens}) {
|
function parse({fulltextTokens, expressionTokens, parsingContext}) {
|
||||||
highlightedTokens = highlightedTokens || [];
|
|
||||||
|
|
||||||
return AndExp.of([
|
return AndExp.of([
|
||||||
getFulltext(fulltextTokens, includingNoteContent, highlightedTokens),
|
getFulltext(fulltextTokens, parsingContext),
|
||||||
getExpression(expressionTokens, highlightedTokens)
|
getExpression(expressionTokens, parsingContext)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
src/services/search/parsing_context.js
Normal file
18
src/services/search/parsing_context.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
class ParsingContext {
|
||||||
|
constructor(includeNoteContent) {
|
||||||
|
this.includeNoteContent = includeNoteContent;
|
||||||
|
this.highlightedTokens = [];
|
||||||
|
this.error = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
addError(error) {
|
||||||
|
// we record only the first error, subsequent ones are usually consequence of the first
|
||||||
|
if (!this.error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ParsingContext;
|
@ -42,15 +42,14 @@ async function findNotesWithExpression(expression) {
|
|||||||
return searchResults;
|
return searchResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseQueryToExpression(query, highlightedTokens) {
|
function parseQueryToExpression(query, parsingContext) {
|
||||||
const {fulltextTokens, expressionTokens} = lexer(query);
|
const {fulltextTokens, expressionTokens} = lexer(query);
|
||||||
const structuredExpressionTokens = parens(expressionTokens);
|
const structuredExpressionTokens = parens(expressionTokens);
|
||||||
|
|
||||||
const expression = parser({
|
const expression = parser({
|
||||||
fulltextTokens,
|
fulltextTokens,
|
||||||
expressionTokens: structuredExpressionTokens,
|
expressionTokens: structuredExpressionTokens,
|
||||||
includingNoteContent: false,
|
parsingContext
|
||||||
highlightedTokens
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return expression;
|
return expression;
|
||||||
@ -61,9 +60,12 @@ async function searchNotesForAutocomplete(query) {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlightedTokens = [];
|
const parsingContext = {
|
||||||
|
includeNoteContent: false,
|
||||||
|
highlightedTokens: []
|
||||||
|
};
|
||||||
|
|
||||||
const expression = parseQueryToExpression(query, highlightedTokens);
|
const expression = parseQueryToExpression(query, parsingContext);
|
||||||
|
|
||||||
if (!expression) {
|
if (!expression) {
|
||||||
return [];
|
return [];
|
||||||
@ -73,7 +75,7 @@ async function searchNotesForAutocomplete(query) {
|
|||||||
|
|
||||||
searchResults = searchResults.slice(0, 200);
|
searchResults = searchResults.slice(0, 200);
|
||||||
|
|
||||||
highlightSearchResults(searchResults, highlightedTokens);
|
highlightSearchResults(searchResults, parsingContext.highlightedTokens);
|
||||||
|
|
||||||
return searchResults.map(result => {
|
return searchResults.map(result => {
|
||||||
return {
|
return {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user