Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

js-solr-highlighter

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-solr-highlighter - npm Package Compare versions

Comparing version 0.7.3 to 0.7.4

42

build/index.js

@@ -24,2 +24,3 @@ "use strict";

function highlightByQuery(query, content, options = {}) {
// can allow more options of text-annotator***
const {

@@ -30,3 +31,4 @@ validFields,

highlightedFields,
highlightIdPattern
highlightIdPattern,
caseSensitive
} = options;

@@ -36,3 +38,3 @@ const searchFunc = highlightAll === undefined || highlightAll ? 'searchAll' : 'search';

const lucene = require('lucene'); // possible: [\+\-\!\(\)\{\}\[\]\^\"\?\:\\\&\|\'\/\s\*\~]
const lucene = require('lucene'); // [\+\-\!\(\)\{\}\[\]\^\"\?\:\\\&\|\'\/\s\*\~]

@@ -52,3 +54,3 @@

});
}; // escape invalid fields and char
}; // escape invalid fields

@@ -58,4 +60,4 @@

const fieldVals = [];
const fieldVals2 = []; // possible: /([^:\s]+):([^:\s]+)/g
// xxx:xxx, xxx: xxx
const fieldVals2 = []; // /([^:\s]+):([^:\s]+)/g
// deal with cases like xxx:xxx, xxx: xxx

@@ -69,14 +71,7 @@ let regex = /([^(\s]+):\s?([^\s)"]+)/g;

if (validFields === undefined || validFields.includes(field)) {
// remove invalid "
if (res[2].startsWith('"') && !res[2].endsWith('"')) {
fieldVals.push([fieldVal, res[1] + ':' + res[2].substring(1)]);
} else if (!res[2].startsWith('"') && res[2].endsWith('"')) {
fieldVals.push(fieldVal, res[1] + ':' + res[2].substring(0, res[2].length - 1));
}
} else {
if (validFields !== undefined && !validFields.includes(field)) {
fieldVals2.push(fieldVal);
}
} // possible: , /([a-zA-Z]+)(\s+):(\s+)([a-zA-Z]+)/g
// xxx:"xxx" xxx:"xxx
} // /([a-zA-Z]+)(\s+):(\s+)([a-zA-Z]+)/g
// deal with cases like xxx:"xxx", xxx:"xxx

@@ -110,3 +105,4 @@

const ast = lucene.parse(q);
const ast = lucene.parse(q); // add terms to be highlighted
const {

@@ -117,3 +113,3 @@ start,

operator
} = ast; // add terms to be highlighted
} = ast;

@@ -135,3 +131,3 @@ const addTerm = (words, term, quoted) => {

const allOperators = astString.match(/"operator":"([^(,)]+)"/g);
const allFields = astString.match(/"field":"([^(,)]+)"/g); // the !left.quoted condition is not elegant
const allFields = astString.match(/"field":"([^(,)]+)"/g); // the !left.quoted condition is not elegant***

@@ -147,3 +143,3 @@ if (allOperators && allOperators.every(operator => operator === '"operator":"<implicit>"') && allFields && allFields.every(field => field === '"field":"<implicit>"') && !left.quoted) {

const canHighlight = field => highlightedFields === undefined ? field : highlightedFields.includes(field); // not an elegant solution
const canHighlight = field => highlightedFields === undefined ? field : highlightedFields.includes(field); // not an elegant solution***

@@ -177,3 +173,3 @@

} // highlight one word by another
// some filters may be moved above
// some filters may be moved up***

@@ -191,3 +187,3 @@

directSearchOptions: {
caseSensitive: false
caseSensitive: caseSensitive !== undefined && caseSensitive
}

@@ -203,3 +199,4 @@ });

return !c.match(letters);
}; // make sure we do not highlight part of a word; can be moved up
}; // make sure we do not highlight part of a word
// this logic may be moved up***

@@ -211,3 +208,2 @@

if (prevCharValid && nextCharValid) {
// highlight options can be made customised
newContent = highlighter.highlight(highlightIndex, {

@@ -214,0 +210,0 @@ content: newContent,

@@ -48,2 +48,3 @@ import TextAnnotator from 'text-annotator'

function highlightByQuery(query, content, options = {}) {
// can allow more options of text-annotator***
const {

@@ -54,3 +55,4 @@ validFields,

highlightedFields,
highlightIdPattern
highlightIdPattern,
caseSensitive
} = options

@@ -63,3 +65,3 @@ const searchFunc =

const lucene = require('lucene')
// possible: [\+\-\!\(\)\{\}\[\]\^\"\?\:\\\&\|\'\/\s\*\~]
// [\+\-\!\(\)\{\}\[\]\^\"\?\:\\\&\|\'\/\s\*\~]
const esc = (s, c) => {

@@ -78,9 +80,8 @@ const regex = new RegExp(c, 'g')

// escape invalid fields and char
// escape invalid fields
let q = query
const fieldVals = []
const fieldVals2 = []
// possible: /([^:\s]+):([^:\s]+)/g
// xxx:xxx, xxx: xxx
// /([^:\s]+):([^:\s]+)/g
// deal with cases like xxx:xxx, xxx: xxx
let regex = /([^(\s]+):\s?([^\s)"]+)/g

@@ -91,19 +92,8 @@ let res

const fieldVal = res[0]
if (validFields === undefined || validFields.includes(field)) {
// remove invalid "
if (res[2].startsWith('"') && !res[2].endsWith('"')) {
fieldVals.push([fieldVal, res[1] + ':' + res[2].substring(1)])
} else if (!res[2].startsWith('"') && res[2].endsWith('"')) {
fieldVals.push(
fieldVal,
res[1] + ':' + res[2].substring(0, res[2].length - 1)
)
}
} else {
if (validFields !== undefined && !validFields.includes(field)) {
fieldVals2.push(fieldVal)
}
}
// possible: , /([a-zA-Z]+)(\s+):(\s+)([a-zA-Z]+)/g
// xxx:"xxx" xxx:"xxx
// /([a-zA-Z]+)(\s+):(\s+)([a-zA-Z]+)/g
// deal with cases like xxx:"xxx", xxx:"xxx
const regex2 = /([^\s(]+):\s?("[^"]+"?[^)])/g

@@ -127,3 +117,2 @@ while ((res = regex2.exec(q)) !== null) {

}
fieldVals.forEach(fv => {

@@ -139,5 +128,5 @@ q = q.replace(fv[0], fv[1])

const ast = lucene.parse(q)
const { start, left, right, operator } = ast
// add terms to be highlighted
const { start, left, right, operator } = ast
const addTerm = (words, term, quoted) => {

@@ -157,7 +146,6 @@ term = unesc(term, ':')

}
const astString = JSON.stringify(ast)
const allOperators = astString.match(/"operator":"([^(,)]+)"/g)
const allFields = astString.match(/"field":"([^(,)]+)"/g)
// the !left.quoted condition is not elegant
// the !left.quoted condition is not elegant***
if (

@@ -184,3 +172,3 @@ allOperators &&

// not an elegant solution
// not an elegant solution***
if (

@@ -226,3 +214,3 @@ !canHighlight(left.field) &&

// highlight one word by another
// some filters may be moved above
// some filters may be moved up***
words = words.filter(

@@ -240,3 +228,3 @@ word =>

directSearchOptions: {
caseSensitive: false
caseSensitive: caseSensitive !== undefined && caseSensitive
}

@@ -253,3 +241,4 @@ })

}
// make sure we do not highlight part of a word; can be moved up
// make sure we do not highlight part of a word
// this logic may be moved up***
const prevCharValid = loc[0] === 0 || fixVaild(text.charAt(loc[0] - 1))

@@ -259,3 +248,2 @@ const nextCharValid =

if (prevCharValid && nextCharValid) {
// highlight options can be made customised
newContent = highlighter.highlight(highlightIndex, {

@@ -262,0 +250,0 @@ content: newContent,

import { isStopWord, highlightByQuery } from './index.js'
describe('tests for function highlightByQuery derived by faults found in Europe PMC', () => {
describe("tests with Europe PMC's standard query set", () => {
const options = {

@@ -337,3 +337,3 @@ validFields: [

// throw errors but work; improve later
// throw errors but work; improve later***
// test('PUBLISHER:"[Institute for Quality and Efficiency in Health Care (IQWiG)][Cologne (Germany)]"', () => {

@@ -497,4 +497,4 @@ // const query = 'PUBLISHER:"[Institute for Quality and Efficiency in Health Care (IQWiG)][Cologne (Germany)]"'

describe('other tests for function highlightByQuery', () => {
test('TITLE:blood AND CONTENT:cell', () => {
describe('tests for the options argument', () => {
test('test the validFields option', () => {
const query = 'TITLE:blood AND CONTENT:cell'

@@ -511,3 +511,15 @@ const content =

test('TITLE:blood OR CONTENT:cell', () => {
// test('test the validFields option', () => {
// const query = 'TITLE:blood OR cell'
// const content =
// 'A molecular map of lymph node blood vascular endothelium at single cell resolution'
// const received = highlightByQuery(query, content, {
// validFields: ['TITLE']
// })
// const expected =
// 'A molecular map of lymph node <span id="highlight-0" class="highlight">blood</span> vascular endothelium at single <span id="highlight-1" class="highlight">cell</span> resolution'
// expect(received).toBe(expected)
// })
test('test the highlightedFields option', () => {
const query = 'TITLE:blood OR CONTENT:cell'

@@ -525,18 +537,6 @@ const content =

test('TITLE:blood OR cell', () => {
const query = 'TITLE:blood OR cell'
const content =
'A molecular map of lymph node blood vascular endothelium at single cell resolution'
const received = highlightByQuery(query, content, {
validFields: ['TITLE']
})
const expected =
'A molecular map of lymph node <span id="highlight-0" class="highlight">blood</span> vascular endothelium at single <span id="highlight-1" class="highlight">cell</span> resolution'
expect(received).toBe(expected)
})
test('blood', () => {
test('test the highlightAll option', () => {
const query = 'blood'
const content =
'Pediatric non-red cell blood product transfusion practices: what\'s the evidence to guide transfusion of the \'yellow\' blood products?'
"Pediatric non-red cell blood product transfusion practices: what's the evidence to guide transfusion of the 'yellow' blood products?"
const received = highlightByQuery(query, content, {

@@ -550,3 +550,3 @@ highlightAll: false

test('breast cancer', () => {
test('test the highlightIdPattern option', () => {
const query = 'breast cancer'

@@ -559,7 +559,7 @@ const content =

const expected =
'Editorial: The Role of <span id=\"new-highlight-0\" class=\"highlight\">Breast</span> <span id=\"new-highlight-1\" class=\"highlight\">Cancer</span> Stem Cells in Clinical Outcomes.'
'Editorial: The Role of <span id="new-highlight-0" class="highlight">Breast</span> <span id="new-highlight-1" class="highlight">Cancer</span> Stem Cells in Clinical Outcomes.'
expect(received).toBe(expected)
})
test('breast cancer', () => {
test('test the highlightClass option', () => {
const query = 'breast cancer'

@@ -572,13 +572,23 @@ const content =

const expected =
'Editorial: The Role of <span id=\"highlight-0\" class=\"new-highlight\">Breast</span> <span id=\"highlight-1\" class=\"new-highlight\">Cancer</span> Stem Cells in Clinical Outcomes.'
'Editorial: The Role of <span id="highlight-0" class="new-highlight">Breast</span> <span id="highlight-1" class="new-highlight">Cancer</span> Stem Cells in Clinical Outcomes.'
expect(received).toBe(expected)
})
test('test the caseSensitive option', () => {
const query = 'covid-19'
const content = 'Clinical observation and management of COVID-19 patients.'
const received = highlightByQuery(query, content, {
caseSensitive: true
})
const expected = 'Clinical observation and management of COVID-19 patients.'
expect(received).toBe(expected)
})
})
describe('tests for function isStopWord', () => {
test('return true', () => {
describe('tests for the isStopWord function', () => {
test('is a stop word', () => {
const received = isStopWord('of')
expect(received).toBeTruthy()
})
test('return false', () => {
test('is not a stop word', () => {
const received = isStopWord('I')

@@ -585,0 +595,0 @@ expect(received).toBeFalsy()

{
"name": "js-solr-highlighter",
"version": "0.7.3",
"version": "0.7.4",
"description": "A JavaScript library for highlighting HTML text based on the query in the lucene/solr query syntax",

@@ -5,0 +5,0 @@ "main": "build/index.js",

@@ -9,4 +9,4 @@ # js-solr-highlighter

## An example from [Europe PMC](https://europepmc.org "Europe PMC")
js-solr-highlighter has been used to highlight the article titles in the search results of Europe PMC. An example is https://europepmc.org/search?query=blood%20AND%20TITLE%3Acancer
## An example from Europe PMC
js-solr-highlighter has been used to highlight the article titles in the search results of [Europe PMC](https://europepmc.org "Europe PMC"). An example is https://europepmc.org/search?query=blood%20AND%20TITLE%3Acancer
!["an example from Europe PMC" "an example from Europe PMC"](example.JPG)

@@ -49,2 +49,3 @@

| highlightClass | string | highlightClass is the classname of every highlight in the HTML.<br />If undefined, it is "highlight". |
| caseSensitive | boolean | caseSensitive indicates whether to ignore case when highlighting.<br />If undefined, it is false (ignore).

@@ -51,0 +52,0 @@ ## Highlighting rules

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc