post queries: add #replace_aliases method.

This commit is contained in:
evazion
2022-04-04 02:14:23 -05:00
parent bf7c721815
commit 1957cb354e
3 changed files with 36 additions and 5 deletions

View File

@@ -47,5 +47,15 @@ class PostQuery
select_metatags(*names).first&.value
end
memoize :tags
# Return a new query AST, with aliased tags replaced with real tags.
def replace_aliases
ast.replace_tags(aliases)
end
# A hash mapping aliased tag names to real tag names.
def aliases
TagAlias.aliases_for(tag_names)
end
memoize :tags, :aliases
end

View File

@@ -254,6 +254,20 @@ class PostQuery
end
end
# Replace tags according to a hash mapping old tag names to new tag names.
#
# @param replacements [Hash<String, String>] A hash mapping old tag names to new tag names.
# @return [AST] A new AST with the tags replaced.
def replace_tags(replacements)
rewrite do |node|
if node.tag? && replacements.has_key?(node.name)
node(:tag, replacements[node.name])
else
node
end
end
end
# Call the block on the AST repeatedly until the output stops changing.
#
# `ast.repeat_until_unchanged(&:trim)` is like doing `ast.trim.trim.trim...`

View File

@@ -10,9 +10,9 @@ class TagAlias < TagRelationship
scope :empty, -> { joins(:consequent_tag).merge(Tag.empty) }
def self.to_aliased(names)
names = Array(names).map(&:to_s)
return [] if names.empty?
# Given a list of tag names, return a hash mapping aliased names to real names.
def self.aliases_for(names)
return {} if names.empty?
aliases = active.where(antecedent_name: names).map { |ta| [ta.antecedent_name, ta.consequent_name] }.to_h
@@ -22,7 +22,14 @@ class TagAlias < TagRelationship
aliases[abbrev] = tag.name if tag.present?
end
names.map { |name| aliases[name] || name }
aliases
end
# Given a list of tag names, return a new list with aliased tag names replaced by real tag names.
def self.to_aliased(names)
names = Array.wrap(names).map(&:to_s)
aliases = aliases_for(names)
names.map { |name| aliases.fetch(name, name) }
end
def process!