1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
# coding: utf-8
from __future__ import absolute_import, unicode_literals
import os
import logging
from mkdocs import utils
from mkdocs.plugins import BasePlugin
from mkdocs.config import config_options
from mkdocs.contrib.search.search_index import SearchIndex
log = logging.getLogger(__name__)
base_path = os.path.dirname(os.path.abspath(__file__))
class LangOption(config_options.OptionallyRequired):
""" Validate Language(s) provided in config are known languages. """
def lang_file_exists(self, lang):
path = os.path.join(base_path, 'lunr-language', 'lunr.{}.js'.format(lang))
return os.path.isfile(path)
def run_validation(self, value):
if isinstance(value, utils.string_types):
value = [value]
elif not isinstance(value, (list, tuple)):
raise config_options.ValidationError('Expected a list of language codes.')
for lang in value:
if lang != 'en' and not self.lang_file_exists(lang):
raise config_options.ValidationError(
'"{}" is not a suported language code.'.format(lang)
)
return value
class SearchPlugin(BasePlugin):
""" Add a search feature to MkDocs. """
config_scheme = (
('lang', LangOption(default=['en'])),
('separator', config_options.Type(utils.string_types, default=r'[\s\-]+')),
('prebuild_index', config_options.Type(bool, default=False)),
)
def on_config(self, config, **kwargs):
"Add plugin templates and scripts to config."
if 'include_search_page' in config['theme'] and config['theme']['include_search_page']:
config['theme'].static_templates.add('search.html')
if not ('search_index_only' in config['theme'] and config['theme']['search_index_only']):
path = os.path.join(base_path, 'templates')
config['theme'].dirs.append(path)
if 'search/main.js' not in config['extra_javascript']:
config['extra_javascript'].append('search/main.js')
return config
def on_pre_build(self, config, **kwargs):
"Create search index instance for later use."
self.search_index = SearchIndex(**self.config)
def on_page_context(self, context, **kwargs):
"Add page to search index."
self.search_index.add_entry_from_context(context['page'])
def on_post_build(self, config, **kwargs):
"Build search index."
output_base_path = os.path.join(config['site_dir'], 'search')
search_index = self.search_index.generate_search_index()
json_output_path = os.path.join(output_base_path, 'search_index.json')
utils.write_file(search_index.encode('utf-8'), json_output_path)
if not ('search_index_only' in config['theme'] and config['theme']['search_index_only']):
# Include language support files in output. Copy them directly
# so that only the needed files are included.
files = []
if len(self.config['lang']) > 1 or 'en' not in self.config['lang']:
files.append('lunr.stemmer.support.js')
if len(self.config['lang']) > 1:
files.append('lunr.multi.js')
for lang in self.config['lang']:
if (lang != 'en'):
files.append('lunr.{}.js'.format(lang))
for filename in files:
from_path = os.path.join(base_path, 'lunr-language', filename)
to_path = os.path.join(output_base_path, filename)
utils.copy_file(from_path, to_path)
|