class SearchPlugin(BasePlugin): """ Add a search feature to MkDocs. """ config_scheme = ( ('lang', LangOption(default=['en'])), ('separator', config_options.Type(str, default=r'[\s\-]+')), ('min_search_length', config_options.Type(int, default=3)), ('prebuild_index', config_options.Choice((False, True, 'node', 'python'), 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)
def test_length(self): option = config_options.Type(str, length=7) value = option.validate("Testing") self.assertEqual(value, "Testing") self.assertRaises(config_options.ValidationError, option.validate, "Testing Long")
def test_multiple_types(self): option = config_options.Type((list, tuple)) value = option.validate([1, 2, 3]) self.assertEqual(value, [1, 2, 3]) value = option.validate((1, 2, 3)) self.assertEqual(value, (1, 2, 3)) self.assertRaises(config_options.ValidationError, option.validate, {'a': 1})
def test_doc_dir_in_site_dir(self): j = os.path.join test_configs = ( { 'docs_dir': j('site', 'docs'), 'site_dir': 'site' }, { 'docs_dir': 'docs', 'site_dir': '.' }, { 'docs_dir': '.', 'site_dir': '.' }, { 'docs_dir': 'docs', 'site_dir': '' }, { 'docs_dir': '', 'site_dir': '' }, { 'docs_dir': 'docs', 'site_dir': 'docs' }, ) conf = {'config_file_path': j(os.path.abspath('..'), 'mkdocutils.yml')} for test_config in test_configs: patch = conf.copy() patch.update(test_config) # Same as the default schema, but don't verify the docs_dir exists. c = config.Config(schema=(('docs_dir', config_options.Dir(default='docs')), ('site_dir', config_options.SiteDir(default='site')), ('config_file_path', config_options.Type(str)))) c.load_dict(patch) errors, warnings = c.validate() self.assertEqual(len(errors), 1) self.assertEqual(warnings, [])
from mkdocutils.config import config_options # NOTE: The order here is important. During validation some config options # depend on others. So, if config option A depends on B, then A should be # listed higher in the schema. # Once we drop Python 2.6 support, this could be an OrderedDict, however, it # isn't really needed either as we always sequentially process the schema other # than at initialisation when we grab the full set of keys for convenience. DEFAULT_SCHEMA = ( # Reserved for internal use, stores the mkdocutils.yml config file. ('config_file_path', config_options.Type(str)), # The title to use for the documentation ('site_name', config_options.Type(str, required=True)), # Defines the structure of the navigation. ('nav', config_options.Nav()), # TODO: remove this when the `pages` config setting is fully deprecated. ('pages', config_options.Nav()), # The full URL to where the documentation will be hosted ('site_url', config_options.URL()), # A description for the documentation project that will be added to the # HTML meta tags. ('site_description', config_options.Type(str)), # The name of the author to add to the HTML meta tags ('site_author', config_options.Type(str)),
def test_single_type(self): option = config_options.Type(str) value = option.validate("Testing") self.assertEqual(value, "Testing")