From 002371920d6f9acedaf987f273bb138a95353ffd Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Fri, 15 Mar 2024 10:38:05 +0100 Subject: Fixed search for tags with spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should not split the body mindlessly, but we have to be more careful about it. Moreover, this commit also polishes the order for tags inside of comments. Signed-off-by: Miquel Sabaté Solà --- app/models/search.rb | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'app/models/search.rb') diff --git a/app/models/search.rb b/app/models/search.rb index 7823a74..053e641 100644 --- a/app/models/search.rb +++ b/app/models/search.rb @@ -31,7 +31,7 @@ class Search < ApplicationRecord def parse_body res = { tag: [], plain: [] } - body.split.each do |part| + split_body.each do |part| if part.include?(':') parts = part.split(':', 2) parts[1] = clean_clause(part: parts[1]) @@ -47,6 +47,31 @@ class Search < ApplicationRecord res end + # Returns the body split into its constituents. Note that we cannot mindlessly + # do something like `body.split` because that would ignore quotes that are not + # to be split among other things. + def split_body + cur = '' + res = [] + co = '' + + body.each_char do |c| + if c.match?(/\s/) && co == '' + res << cur if cur.present? + cur = '' + else + # If it is a quote character, check whether it's being opened or + # closed. + co = c == co ? '' : c if c == '"' || c == "'" + + cur += c + end + end + + res << cur if cur.present? && co.blank? + res + end + # Returns the argument without any leading/trailing quotes. def clean_clause(part:) part.gsub(/^("|')+/, '').gsub(/("|')+$/, '') -- cgit v1.2.3