From 3afaa9de9aaae7654c1d03ddc22ee97724cbb159 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 31 Jul 2019 21:36:12 +0100 Subject: [PATCH] Add support for anchored searches --- core/modules/filters/search.js | 1 + core/modules/wiki.js | 10 ++++++---- editions/test/tiddlers/tests/test-filters.js | 1 + editions/tw5.com/tiddlers/filters/search.tid | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/core/modules/filters/search.js b/core/modules/filters/search.js index 1e59deb63..adcb076a0 100644 --- a/core/modules/filters/search.js +++ b/core/modules/filters/search.js @@ -43,6 +43,7 @@ exports.search = function(source,operator,options) { caseSensitive: hasFlag("casesensitive"), literal: hasFlag("literal"), whitespace: hasFlag("whitespace"), + anchored: hasFlag("anchored"), regexp: hasFlag("regexp"), words: hasFlag("words") }); diff --git a/core/modules/wiki.js b/core/modules/wiki.js index 4d1f938e7..3e5687638 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -1065,6 +1065,7 @@ Options available: invert: If true returns tiddlers that do not contain the specified string caseSensitive: If true forces a case sensitive search field: If specified, restricts the search to the specified field, or an array of field names + anchored: If true, forces all but regexp searches to be anchored to the start of text excludeField: If true, the field options are inverted to specify the fields that are not to be searched The search mode is determined by the first of these boolean flags to be true literal: searches for literal string @@ -1079,12 +1080,13 @@ exports.search = function(text,options) { invert = !!options.invert; // Convert the search string into a regexp for each term var terms, searchTermsRegExps, - flags = options.caseSensitive ? "" : "i"; + flags = options.caseSensitive ? "" : "i", + anchor = options.anchored ? "^" : ""; if(options.literal) { if(text.length === 0) { searchTermsRegExps = null; } else { - searchTermsRegExps = [new RegExp("(" + $tw.utils.escapeRegExp(text) + ")",flags)]; + searchTermsRegExps = [new RegExp("(" + anchor + $tw.utils.escapeRegExp(text) + ")",flags)]; } } else if(options.whitespace) { terms = []; @@ -1093,7 +1095,7 @@ exports.search = function(text,options) { terms.push($tw.utils.escapeRegExp(term)); } }); - searchTermsRegExps = [new RegExp("(" + terms.join("\\s+") + ")",flags)]; + searchTermsRegExps = [new RegExp("(" + anchor + terms.join("\\s+") + ")",flags)]; } else if(options.regexp) { try { searchTermsRegExps = [new RegExp("(" + text + ")",flags)]; @@ -1108,7 +1110,7 @@ exports.search = function(text,options) { } else { searchTermsRegExps = []; for(t=0; t> operator. ** ''words'': (the default) treats the search string as a list of tokens separated by whitespace, and matches if all of the tokens appear in the string (regardless of ordering and whether there is other text in between) * ''casesensitive'': if present, this flag forces a case-sensitive match, where upper and lower case letters are considered different. By default, upper and lower case letters are considered identical for matching purposes. +* ''anchored'': <<.from-version "5.1.20">> anchors the search to the start of the string (applies to ''whitespace'', ''literal'' and ''words'' modes) <<.operator-examples "search">>