[opt] search
This commit is contained in:
parent
95353cec00
commit
e9f9d0e560
|
@ -63,10 +63,11 @@ article:
|
||||||
|
|
||||||
search:
|
search:
|
||||||
service: local_search # local_search, todo...
|
service: local_search # local_search, todo...
|
||||||
local_search:
|
local_search: # 在 front-matter 中设置 indexing:false 来避免被搜索索引
|
||||||
field: all # post, page, all
|
field: all # post, page, all
|
||||||
path: /search.json
|
path: /search.json # 搜索文件存放位置
|
||||||
content: true
|
content: true # 是否搜索内容
|
||||||
|
codeblock: true # 是否搜索代码块(需要content: true)
|
||||||
|
|
||||||
|
|
||||||
######## Comments ########
|
######## Comments ########
|
||||||
|
|
|
@ -83,7 +83,7 @@ function layoutWidgets() {
|
||||||
if (name in theme.data.widgets) {
|
if (name in theme.data.widgets) {
|
||||||
Object.assign(widget, theme.data.widgets[name])
|
Object.assign(widget, theme.data.widgets[name])
|
||||||
}
|
}
|
||||||
if (typeof w == 'object' && w.override) {
|
if (typeof w == 'object' && (w.override || w.layout)) {
|
||||||
Object.assign(widget, w)
|
Object.assign(widget, w)
|
||||||
}
|
}
|
||||||
if (widget && widget.layout) {
|
if (widget && widget.layout) {
|
||||||
|
|
|
@ -5,15 +5,23 @@ function layoutDiv() {
|
||||||
el += '<div class="search-wrapper" id="search">'
|
el += '<div class="search-wrapper" id="search">'
|
||||||
el += '<form class="search-form">'
|
el += '<form class="search-form">'
|
||||||
var filter = ''
|
var filter = ''
|
||||||
if (item.filter == 'auto' && page.layout == 'wiki') {
|
if (item.filter == 'auto') {
|
||||||
let matches = page.path.match(/(.*?)\/(.*?)\//i)
|
if (page.layout == 'wiki') {
|
||||||
if (matches?.length > 0) {
|
let matches = page.path.match(/(.*?)\/(.*?)\//i)
|
||||||
filter = matches[0]
|
if (matches?.length > 0) {
|
||||||
|
filter = matches[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (item.filter?.length > 0) {
|
||||||
|
filter = item.filter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
el += '<input type="text" class="search-input" id="search-input"'
|
el += '<input type="text" class="search-input" id="search-input"'
|
||||||
if (filter.length > 0) {
|
if (filter.length > 0) {
|
||||||
filter = '/' + filter
|
if (!filter.startsWith('/')) {
|
||||||
|
filter = '/' + filter
|
||||||
|
}
|
||||||
el += ' data-filter="' + filter + '"'
|
el += ' data-filter="' + filter + '"'
|
||||||
el += ' placeholder="' + (item.placeholder || __('search.search_in', filter)) + '">'
|
el += ' placeholder="' + (item.placeholder || __('search.search_in', filter)) + '">'
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,101 +3,105 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hexo.extend.generator.register('search_json_generator', function (locals) {
|
hexo.extend.generator.register('search_json_generator', function (locals) {
|
||||||
if (this.theme.config.search.service != 'local_search') {
|
if (this.theme.config.search.service != 'local_search') { return {} }
|
||||||
return {}
|
const { root } = this.config
|
||||||
}
|
const { local_search: cfg } = this.theme.config.search
|
||||||
var config = this.config
|
cfg.sort = '-date'
|
||||||
const { local_search } = this.theme.config.search
|
cfg.field = cfg.field?.trim()
|
||||||
|
|
||||||
var searchfield = local_search.field
|
|
||||||
var content = local_search.content
|
|
||||||
|
|
||||||
var posts, pages
|
var posts, pages
|
||||||
|
if (cfg.field == 'post') {
|
||||||
if (searchfield.trim() != '') {
|
posts = locals.posts?.filter(p => p.content?.length > 0).sort(cfg.sort)
|
||||||
searchfield = searchfield.trim()
|
} else if (cfg.field == 'page') {
|
||||||
if (searchfield == 'post'){
|
pages = locals.pages?.filter(p => p.content?.length > 0)
|
||||||
posts = locals.posts.sort('-date')
|
|
||||||
} else if (searchfield == 'page') {
|
|
||||||
pages = locals.pages
|
|
||||||
} else {
|
|
||||||
posts = locals.posts.sort('-date')
|
|
||||||
pages = locals.pages
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
posts = locals.posts.sort('-date')
|
posts = locals.posts?.filter(p => p.content?.length > 0).sort(cfg.sort)
|
||||||
|
pages = locals.pages?.filter(p => p.content?.length > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var res = new Array()
|
var res = new Array()
|
||||||
var index = 0
|
|
||||||
|
function generateJson(post) {
|
||||||
if (posts) {
|
var temp_post = new Object()
|
||||||
posts.each(function(post) {
|
if (post.title) {
|
||||||
if (post.indexing != undefined && !post.indexing) return
|
temp_post.title = post.title.trim()
|
||||||
var temp_post = new Object()
|
}
|
||||||
if (post.title) {
|
if (post.path) {
|
||||||
temp_post.title = post.title
|
temp_post.path = root + post.path
|
||||||
}
|
}
|
||||||
if (post.path) {
|
if (cfg.content != false && post._content) {
|
||||||
temp_post.url = config.root + post.path
|
var content = post._content.trim()
|
||||||
}
|
// 过滤掉标签和注释
|
||||||
if (content != false && post._content) {
|
if (content.includes('{%')) {
|
||||||
temp_post.content = post._content
|
// 需要保留内容的的标签
|
||||||
}
|
content = content.replace(/{%\s*mark\s*(.*?)\s*%}/g, '$1')
|
||||||
if (post.tags && post.tags.length > 0) {
|
content = content.replace(/{%\s*folding\s*(.*?)\s*%}/g, '$1')
|
||||||
var tags = []
|
content = content.replace(/{%\s*copy\s*(.*?)\s*%}/g, '$1')
|
||||||
post.tags.forEach(function (tag) {
|
content = content.replace(/{%\s*note\s*(.*?)\s*%}/g, '$1')
|
||||||
tags.push(tag.name)
|
content = content.replace(/{%\s*kbd\s*(.*?)\s*%}/g, '$1')
|
||||||
})
|
content = content.replace(/{%\s*emp\s*(.*?)\s*%}/g, '$1')
|
||||||
temp_post.tags = tags
|
content = content.replace(/{%\s*wavy\s*(.*?)\s*%}/g, '$1')
|
||||||
}
|
content = content.replace(/{%\s*sub\s*(.*?)\s*%}/g, '$1')
|
||||||
if (post.categories && post.categories.length > 0) {
|
content = content.replace(/{%\s*sup\s*(.*?)\s*%}/g, '$1')
|
||||||
var categories = []
|
content = content.replace(/<!--\s*folder(.*?)\s*-->/g, '$1')
|
||||||
post.categories.forEach(function (cate) {
|
content = content.replace(/<!--\s*tab(.*?)\s*-->/g, '$1')
|
||||||
categories.push(cate.name)
|
content = content.replace(/<!--\s*node(.*?)\s*-->/g, '$1')
|
||||||
})
|
// 不保留内容的标签
|
||||||
temp_post.categories = categories
|
content = content.replace(/{%\s*(.*?)\s*%}/g, '')
|
||||||
}
|
// 注释
|
||||||
res[index] = temp_post
|
content = content.replace(/<!--\s*(.*?)\s*-->/g, '')
|
||||||
index += 1
|
// ## 标题
|
||||||
|
content = content.replace(/[#]{2,} /g, '')
|
||||||
|
// 部分HTML标签
|
||||||
|
content = content.replace(/<iframe[\s|\S]+iframe>/g, '')
|
||||||
|
// 图片
|
||||||
|
content = content.replace(/\!\[(.*?)\]\((.*?)\)/g, '')
|
||||||
|
// 链接
|
||||||
|
content = content.replace(/\[(.*?)\]\((.*?)\)/g, '$1')
|
||||||
|
// 过滤代码块
|
||||||
|
if (cfg.codeblock == false) {
|
||||||
|
content = content.replace(/```([^`]+)```/g, '')
|
||||||
|
}
|
||||||
|
// 多个连续空格换成单个空格
|
||||||
|
content = content.replace(/[\s]{2,} /g, ' ')
|
||||||
|
// 特殊字符
|
||||||
|
content = content.replace(/[\r|\n]+/g, '')
|
||||||
|
}
|
||||||
|
temp_post.content = content.trim()
|
||||||
|
}
|
||||||
|
if (post.tags && post.tags.length > 0) {
|
||||||
|
var tags = []
|
||||||
|
post.tags.forEach(function (tag) {
|
||||||
|
tags.push(tag.name)
|
||||||
|
})
|
||||||
|
temp_post.tags = tags
|
||||||
|
}
|
||||||
|
if (post.categories && post.categories.length > 0) {
|
||||||
|
var categories = []
|
||||||
|
post.categories.forEach(function (cate) {
|
||||||
|
categories.push(cate.name)
|
||||||
|
})
|
||||||
|
temp_post.categories = categories
|
||||||
|
}
|
||||||
|
return temp_post
|
||||||
|
}
|
||||||
|
|
||||||
|
if (posts) {
|
||||||
|
posts.each(function(post) {
|
||||||
|
if (post.indexing == false) return
|
||||||
|
let temp_post = generateJson(post)
|
||||||
|
res.push(temp_post)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (pages) {
|
if (pages) {
|
||||||
pages.each(function(page) {
|
pages.each(function(page) {
|
||||||
if (page.indexing != undefined && !page.indexing) return
|
if (page.indexing == false) return
|
||||||
var temp_page = new Object()
|
let temp_post = generateJson(page)
|
||||||
if (page.title) {
|
res.push(temp_post)
|
||||||
temp_page.title = page.title
|
})
|
||||||
}
|
}
|
||||||
if (page.path) {
|
|
||||||
temp_page.url = config.root + page.path
|
|
||||||
}
|
|
||||||
if (content != false && page._content) {
|
|
||||||
temp_page.content = page._content
|
|
||||||
}
|
|
||||||
if (page.tags && page.tags.length > 0) {
|
|
||||||
var tags = new Array()
|
|
||||||
var tag_index = 0
|
|
||||||
page.tags.each(function (tag) {
|
|
||||||
tags[tag_index] = tag.name
|
|
||||||
})
|
|
||||||
temp_page.tags = tags
|
|
||||||
}
|
|
||||||
if (page.categories && page.categories.length > 0) {
|
|
||||||
temp_page.categories = []
|
|
||||||
(page.categories.each || page.categories.forEach)(function (item) {
|
|
||||||
temp_page.categories.push(item)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
res[index] = temp_page
|
|
||||||
index += 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var json = JSON.stringify(res)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
path: local_search.path,
|
path: cfg.path,
|
||||||
data: json
|
data: JSON.stringify(res)
|
||||||
}
|
}
|
||||||
})
|
})
|
|
@ -24,20 +24,6 @@
|
||||||
/*exported searchFunc*/
|
/*exported searchFunc*/
|
||||||
var searchFunc = function(path, filter, searchId, contentId) {
|
var searchFunc = function(path, filter, searchId, contentId) {
|
||||||
|
|
||||||
function stripHtml(html) {
|
|
||||||
html = html.replace(/<style([\s\S]*?)<\/style>/gi, "");
|
|
||||||
html = html.replace(/<script([\s\S]*?)<\/script>/gi, "");
|
|
||||||
html = html.replace(/<figure([\s\S]*?)<\/figure>/gi, "");
|
|
||||||
html = html.replace(/<\/div>/ig, "\n");
|
|
||||||
html = html.replace(/<\/li>/ig, "\n");
|
|
||||||
html = html.replace(/<li>/ig, " * ");
|
|
||||||
html = html.replace(/<\/ul>/ig, "\n");
|
|
||||||
html = html.replace(/<\/p>/ig, "\n");
|
|
||||||
html = html.replace(/<br\s*[\/]?>/gi, "\n");
|
|
||||||
html = html.replace(/<[^>]+>/ig, "");
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAllCombinations(keywords) {
|
function getAllCombinations(keywords) {
|
||||||
var i, j, result = [];
|
var i, j, result = [];
|
||||||
|
|
||||||
|
@ -68,18 +54,17 @@ var searchFunc = function(path, filter, searchId, contentId) {
|
||||||
}
|
}
|
||||||
// perform local searching
|
// perform local searching
|
||||||
datas.forEach(function(data) {
|
datas.forEach(function(data) {
|
||||||
|
if (!data.title?.trim().length) { return }
|
||||||
|
if (!data.content?.trim().length) { return }
|
||||||
var matches = 0;
|
var matches = 0;
|
||||||
if (!data.title || data.title.trim() === "") {
|
if (filter && !data.path.includes(filter)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (filter && !data.url.includes(filter)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var dataTitle = data.title.trim().toLowerCase();
|
var dataTitle = data.title.trim().toLowerCase();
|
||||||
var dataTitleLowerCase = dataTitle.toLowerCase();
|
var dataTitleLowerCase = dataTitle.toLowerCase();
|
||||||
var dataContent = stripHtml(data.content.trim());
|
var dataContent = data.content;
|
||||||
var dataContentLowerCase = dataContent.toLowerCase();
|
var dataContentLowerCase = dataContent.toLowerCase();
|
||||||
var dataUrl = data.url;
|
var dataUrl = data.path;
|
||||||
var indexTitle = -1;
|
var indexTitle = -1;
|
||||||
var indexContent = -1;
|
var indexContent = -1;
|
||||||
var firstOccur = -1;
|
var firstOccur = -1;
|
||||||
|
|
Loading…
Reference in New Issue