lib/madness/search.rb
require 'shellwords'
module Madness
class Search
include ServerHelper
using StringRefinements
def initialize(path = nil)
@path = path || docroot
end
def index
@index ||= index!
end
def search(query)
query = query.downcase
words = Shellwords.split query
word_count = words.count
result = {}
return result if words.empty?
index.each do |file, content|
file = file.remove("#{@path}/").sub(/.md$/, '')
url = file_url file
label = file_label file
found = 0
words.each { |word| found += 1 if content.include? word }
next unless found == word_count
result[label] = url
end
result
end
private
def index!
results = {}
Dir["#{@path}/**/#{config.dir_glob}"].each do |file|
next if skip_index? file
filename = file_url(file.sub("#{@path}/", '')).downcase
index_content = File.extname(file) == '.md'
content = index_content ? File.read(file).downcase : ''
results[file] = "#{filename} #{content}"
end
results
end
# We are going to avoid indexing of README.md when there is also an
# index.md in the same directory, to keep behavior consistent with the
# display logic
def skip_index?(file)
if file.end_with? 'README.md'
dir = File.dirname file
File.exist? "#{dir}/index.md"
else
false
end
end
def file_label(filename)
filename
.remove(%r{/(index|README)$})
.split('/')
.map(&:to_label)
.join(' / ')
end
def config
@config ||= Settings.instance
end
def file_url(filename)
filename.remove(%r{/(index|README)$})
end
end
end