post queries: track whether metatag values are quoted.
This is necessary for the `commentary:` metatag, which has different behavior depending on whether the metatag value is quoted. For example, `commentary:translated` finds translated commentaries, while `commentary:"translated"` finds commentaries containing the literal word "translated".
This commit is contained in:
@@ -60,8 +60,8 @@ class PostQuery
|
|||||||
AST.new(:tag, [name])
|
AST.new(:tag, [name])
|
||||||
end
|
end
|
||||||
|
|
||||||
def metatag(name, value)
|
def metatag(name, value, quoted = false)
|
||||||
AST.new(:metatag, [name, value])
|
AST.new(:metatag, [name, value, quoted])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ class PostQuery
|
|||||||
"none"
|
"none"
|
||||||
in [:tag, name]
|
in [:tag, name]
|
||||||
name
|
name
|
||||||
in [:metatag, name, value]
|
in [:metatag, name, value, quoted]
|
||||||
"#{name}:#{quoted_value}"
|
"#{name}:#{quoted_value}"
|
||||||
in [:wildcard, name]
|
in [:wildcard, name]
|
||||||
"(wildcard #{name})"
|
"(wildcard #{name})"
|
||||||
@@ -231,7 +231,7 @@ class PostQuery
|
|||||||
name
|
name
|
||||||
in [:tag, name]
|
in [:tag, name]
|
||||||
name
|
name
|
||||||
in [:metatag, name, value]
|
in [:metatag, name, value, quoted]
|
||||||
"#{name}:#{quoted_value}"
|
"#{name}:#{quoted_value}"
|
||||||
in :not, child
|
in :not, child
|
||||||
child.term? ? "-#{child.to_infix}" : "-(#{child.to_infix})"
|
child.term? ? "-#{child.to_infix}" : "-(#{child.to_infix})"
|
||||||
@@ -354,11 +354,16 @@ class PostQuery
|
|||||||
args.second if metatag?
|
args.second if metatag?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [String, nil] True if the metatag's value was enclosed in quotes.
|
||||||
|
def quoted?
|
||||||
|
args.third if metatag?
|
||||||
|
end
|
||||||
|
|
||||||
# @return [String, nil] The value of the metatag as a quoted string, if a metatag node.
|
# @return [String, nil] The value of the metatag as a quoted string, if a metatag node.
|
||||||
def quoted_value
|
def quoted_value
|
||||||
return nil unless metatag?
|
return nil unless metatag?
|
||||||
|
|
||||||
if value.include?(" ") || value.starts_with?('"') || value.starts_with?("'") || value.empty?
|
if quoted?
|
||||||
%Q{"#{value.gsub(/"/, '\\"')}"}
|
%Q{"#{value.gsub(/"/, '\\"')}"}
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ class PostQuery
|
|||||||
if accept(METATAG_NAME_REGEX)
|
if accept(METATAG_NAME_REGEX)
|
||||||
name = @scanner.matched.delete_suffix(":").downcase
|
name = @scanner.matched.delete_suffix(":").downcase
|
||||||
name = name.singularize + "_count" if name.in?(PostQueryBuilder::COUNT_METATAG_SYNONYMS)
|
name = name.singularize + "_count" if name.in?(PostQueryBuilder::COUNT_METATAG_SYNONYMS)
|
||||||
value = quoted_string
|
quoted, value = quoted_string
|
||||||
node(:metatag, name, value)
|
node(:metatag, name, value, quoted)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -173,13 +173,13 @@ class PostQuery
|
|||||||
if accept('"')
|
if accept('"')
|
||||||
a = accept(/([^"\\]|\\")*/).gsub(/\\"/, '"') # handle backslash escaped quotes
|
a = accept(/([^"\\]|\\")*/).gsub(/\\"/, '"') # handle backslash escaped quotes
|
||||||
expect('"')
|
expect('"')
|
||||||
a
|
[true, a]
|
||||||
elsif accept("'")
|
elsif accept("'")
|
||||||
a = accept(/([^'\\]|\\')*/).gsub(/\\'/, "'") # handle backslash escaped quotes
|
a = accept(/([^'\\]|\\')*/).gsub(/\\'/, "'") # handle backslash escaped quotes
|
||||||
expect("'")
|
expect("'")
|
||||||
a
|
[true, a]
|
||||||
else
|
else
|
||||||
string(/[^ ]+/)
|
[false, string(/[^ ]+/)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -69,14 +69,14 @@ class PostQueryParserTest < ActiveSupport::TestCase
|
|||||||
assert_parse_equals('source:""', 'source:""')
|
assert_parse_equals('source:""', 'source:""')
|
||||||
assert_parse_equals('source:"\""', 'source:"\""')
|
assert_parse_equals('source:"\""', 'source:"\""')
|
||||||
assert_parse_equals(%q{source:"don't say \"lazy\" okay"}, %q{source:"don't say \"lazy\" okay"})
|
assert_parse_equals(%q{source:"don't say \"lazy\" okay"}, %q{source:"don't say \"lazy\" okay"})
|
||||||
assert_parse_equals(%q{(and source:foo)bar a)}, %q{(a (source:"foo)bar"))})
|
assert_parse_equals(%q{(and source:"foo)bar" a)}, %q{(a (source:"foo)bar"))})
|
||||||
|
|
||||||
assert_parse_equals('source:"foo bar"', "source:'foo bar'")
|
assert_parse_equals('source:"foo bar"', "source:'foo bar'")
|
||||||
assert_parse_equals("source:foobar'(", "source:foobar'(")
|
assert_parse_equals("source:foobar'(", "source:foobar'(")
|
||||||
assert_parse_equals('source:""', "source:''")
|
assert_parse_equals('source:""', "source:''")
|
||||||
assert_parse_equals('source:"\'"', "source:'\\''")
|
assert_parse_equals('source:"\'"', "source:'\\''")
|
||||||
assert_parse_equals(%q{source:"don't say \"lazy\" okay"}, %q{source:'don\'t say "lazy" okay'})
|
assert_parse_equals(%q{source:"don't say \"lazy\" okay"}, %q{source:'don\'t say "lazy" okay'})
|
||||||
assert_parse_equals(%q{(and source:foo)bar a)}, %q{(a (source:'foo)bar'))})
|
assert_parse_equals(%q{(and source:"foo)bar" a)}, %q{(a (source:'foo)bar'))})
|
||||||
end
|
end
|
||||||
|
|
||||||
should "parse metatag synonyms correctly" do
|
should "parse metatag synonyms correctly" do
|
||||||
|
|||||||
Reference in New Issue
Block a user