def test_find_toc_by_id(self): """ Test finding the relevant TOC item by the tag ID. """ index = search.SearchIndex() md = dedent(""" # Heading 1 ## Heading 2 ### Heading 3 """) toc = markdown_to_toc(md) toc_item = index._find_toc_by_id(toc, "heading-1") self.assertEqual(toc_item.url, "#heading-1") self.assertEqual(toc_item.title, "Heading 1") toc_item2 = index._find_toc_by_id(toc, "heading-2") self.assertEqual(toc_item2.url, "#heading-2") self.assertEqual(toc_item2.title, "Heading 2") toc_item3 = index._find_toc_by_id(toc, "heading-3") self.assertEqual(toc_item3.url, "#heading-3") self.assertEqual(toc_item3.title, "Heading 3")
def build_pages(config, dump_json=False): """ Builds all the pages and writes them into the build directory. """ site_navigation = nav.SiteNavigation(config['pages'], config['use_directory_urls']) loader = jinja2.FileSystemLoader(config['theme_dir']) env = jinja2.Environment(loader=loader) search_index = search.SearchIndex() build_template('404.html', env, config, site_navigation) if not build_template('search.html', env, config, site_navigation): log.debug("Search is enabled but the theme doesn't contain a " "search.html file. Assuming the theme implements search " "within a modal.") for page in site_navigation.walk_pages(): try: log.debug("Building page %s", page.input_path) html_content, table_of_contents, meta = _build_page( page, config, site_navigation, env, dump_json) search_index.add_entry_from_context( page, html_content, table_of_contents) except: log.error("Error building page %s", page.input_path) raise search_index = search_index.generate_search_index() json_output_path = os.path.join(config['site_dir'], 'mkdocs', 'search_index.json') utils.write_file(search_index.encode('utf-8'), json_output_path)
def test_create_search_index(self): html_content = """ <h1 id="heading-1">Heading 1</h1> <p>Content 1</p> <h2 id="heading-2">Heading 2</h1> <p>Content 2</p> <h3 id="heading-3">Heading 3</h1> <p>Content 3</p> """ pages = [('index.md', 'Home'), ('about.md', 'About')] site_navigation = nav.SiteNavigation(pages) md = dedent(""" # Heading 1 ## Heading 2 ### Heading 3 """) toc = _markdown_to_toc(md) full_content = ''.join("""Heading{0}Content{0}""".format(i) for i in range(1, 4)) for page in site_navigation: index = search.SearchIndex() index.add_entry_from_context(page, html_content, toc) self.assertEqual(len(index._entries), 3) loc = page.abs_url self.assertEqual(index._entries[0]['title'], page.title) self.assertEqual(strip_whitespace(index._entries[0]['text']), full_content) self.assertEqual(index._entries[0]['tags'], "") self.assertEqual(index._entries[0]['loc'], loc) self.assertEqual(index._entries[1]['title'], "Heading 1") self.assertEqual(index._entries[1]['text'], "Content 1") self.assertEqual(index._entries[1]['tags'], "") self.assertEqual(index._entries[1]['loc'], "{0}#heading-1".format(loc)) self.assertEqual(index._entries[2]['title'], "Heading 2") self.assertEqual(strip_whitespace(index._entries[2]['text']), "Content2Heading3Content3") self.assertEqual(index._entries[2]['tags'], "") self.assertEqual(index._entries[2]['loc'], "{0}#heading-2".format(loc))
def build_pages(config, dump_json=False, dirty=False): """ Builds all the pages and writes them into the build directory. """ site_navigation = nav.SiteNavigation(config['pages'], config['use_directory_urls']) loader = jinja2.FileSystemLoader(config['theme_dir'] + [config['mkdocs_templates'], ]) env = jinja2.Environment(loader=loader) # TODO: remove DeprecationContext in v1.0 when all deprecated vars have been removed from jinja2.runtime import Context deprecated_vars = [ 'page_title', 'content', 'toc', 'meta', 'current_page', 'canonical_url', 'previous_page', 'next_page' ] class DeprecationContext(Context): def resolve(self, key): """ Log a warning when acessing any deprecated variable name. """ if key in deprecated_vars: replacement = "page" if key == 'current_page' else "page.{0}".format(key) log.warn( "Template variable warning: '{0}' is being deprecated and will not be " "available in a future version. Use '{1}' instead.".format(key, replacement) ) return super(DeprecationContext, self).resolve(key) env.context_class = DeprecationContext # TODO: end remove DeprecationContext env.filters['tojson'] = filters.tojson search_index = search.SearchIndex() # Force absolute URLs in the nav of error pages and account for the # possability that the docs root might be different than the server root. # See https://github.com/mkdocs/mkdocs/issues/77 site_navigation.url_context.force_abs_urls = True default_base = site_navigation.url_context.base_path site_navigation.url_context.base_path = utils.urlparse(config['site_url']).path build_template('404.html', env, config, site_navigation) # Reset nav behavior to the default site_navigation.url_context.force_abs_urls = False site_navigation.url_context.base_path = default_base if not build_template('search.html', env, config, site_navigation): log.debug("Search is enabled but the theme doesn't contain a " "search.html file. Assuming the theme implements search " "within a modal.") build_template('sitemap.xml', env, config, site_navigation) build_extra_templates(config['extra_templates'], config, site_navigation) # append extra pages not including in [email protected] append_extra_pages(config, env, dump_json, site_navigation) for page in site_navigation.walk_pages(): try: # When --dirty is used, only build the page if the markdown has been modified since the # previous build of the output. input_path, output_path = get_complete_paths(config, page) if dirty and (utils.modified_time(input_path) < utils.modified_time(output_path)): continue log.debug("Building page %s", page.input_path) build_result = _build_page(page, config, site_navigation, env, dump_json) html_content, table_of_contents, _ = build_result search_index.add_entry_from_context( page, html_content, table_of_contents) except Exception: log.error("Error building page %s", page.input_path) raise search_index = search_index.generate_search_index() json_output_path = os.path.join(config['site_dir'], 'mkdocs', 'search_index.json') utils.write_file(search_index.encode('utf-8'), json_output_path)
def build_pages(config, dump_json=False): """ Builds all the pages and writes them into the build directory. """ site_navigation = nav.SiteNavigation(config['pages'], config['use_directory_urls']) loader = jinja2.FileSystemLoader(config['theme_dir']) env = jinja2.Environment(loader=loader) search_index = search.SearchIndex() build_template('404.html', env, config, site_navigation) if config['include_search']: if not build_template('search.html', env, config, site_navigation): log.debug("Search is enabled but the theme doesn't contain a " "search.html file. Assuming the theme implements search " "within a modal.") for page in site_navigation.walk_pages(): # Read the input file input_path = os.path.join(config['docs_dir'], page.input_path) try: input_content = open(input_path, 'r').read() except IOError: log.error('file not found: %s' % input_path) if PY2: input_content = input_content.decode('utf-8') # Process the markdown text html_content, table_of_contents, meta = convert_markdown( input_content, site_navigation, extensions=config['markdown_extensions'], strict=config['strict']) context = get_global_context(site_navigation, config) context.update( get_page_context(page, html_content, site_navigation, table_of_contents, meta, config)) # Allow 'template:' override in md source files. if 'template' in meta: template = env.get_template(meta['template'][0]) else: template = env.get_template('base.html') # Render the template. output_content = template.render(context) # Write the output file. output_path = os.path.join(config['site_dir'], page.output_path) if dump_json: json_context = { 'content': context['content'], 'title': context['current_page'].title, 'url': context['current_page'].abs_url, 'language': 'en', } utils.write_file( json.dumps(json_context, indent=4).encode('utf-8'), output_path.replace('.html', '.json')) else: utils.write_file(output_content.encode('utf-8'), output_path) search_index.add_entry_from_context(page, html_content, table_of_contents) if config['include_search']: search_index = search_index.generate_search_index() json_output_path = os.path.join(config['site_dir'], 'mkdocs', 'js', 'tipuesearch_content.json') utils.write_file(search_index.encode('utf-8'), json_output_path) build_template('mkdocs/js/tipuesearch_content.js', env, config, extra_context={'search_index': search_index})
def build_pages(config, dump_json=False): """ Builds all the pages and writes them into the build directory. """ site_navigation = nav.SiteNavigation(config['pages'], config['use_directory_urls']) loader = jinja2.FileSystemLoader(config['theme_dir'] + [ config['mkdocs_templates'], ]) env = jinja2.Environment(loader=loader) # TODO: remove DeprecationContext in v1.0 when all deprecated vars have been removed from jinja2.runtime import Context deprecated_vars = [ 'page_title', 'content', 'toc', 'meta', 'current_page', 'canonical_url', 'previous_page', 'next_page' ] class DeprecationContext(Context): def resolve(self, key): """ Log a warning when acessing any deprecated variable name. """ if key in deprecated_vars: replacement = "page" if key == 'current_page' else "page.{0}".format( key) log.warn( "Template variable warning: '{0}' is being deprecated and will not be " "available in a future version. Use '{1}' instead.".format( key, replacement)) return super(DeprecationContext, self).resolve(key) env.context_class = DeprecationContext # TODO: end remove DeprecationContext env.filters['tojson'] = filters.tojson search_index = search.SearchIndex() build_template('404.html', env, config, site_navigation) if not build_template('search.html', env, config, site_navigation): log.debug("Search is enabled but the theme doesn't contain a " "search.html file. Assuming the theme implements search " "within a modal.") build_template('sitemap.xml', env, config, site_navigation) build_extra_templates(config['extra_templates'], config, site_navigation) for page in site_navigation.walk_pages(): try: log.debug("Building page %s", page.input_path) build_result = _build_page(page, config, site_navigation, env, dump_json) html_content, table_of_contents, _ = build_result search_index.add_entry_from_context(page, html_content, table_of_contents) except Exception: log.error("Error building page %s", page.input_path) raise search_index = search_index.generate_search_index() json_output_path = os.path.join(config['site_dir'], 'mkdocs', 'search_index.json') utils.write_file(search_index.encode('utf-8'), json_output_path)
def build_pages(config, dump_json=False): """ Builds all the pages and writes them into the build directory. """ site_navigation = nav.SiteNavigation(config['pages'], config['use_directory_urls']) loader = jinja2.FileSystemLoader(config['theme_dir']) env = jinja2.Environment(loader=loader) search_index = search.SearchIndex() build_template('404.html', env, config, site_navigation) build_template('search.html', env, config, site_navigation) nav_pages = [] for page in site_navigation.walk_pages(): nav_pages.append(page.input_path) # Read the input file input_path = os.path.join(config['docs_dir'], page.input_path) input_content = open(input_path, 'r').read() if PY2: input_content = input_content.decode('utf-8') # Process the markdown text html_content, table_of_contents, meta = convert_markdown( input_content, site_navigation, extensions=config['markdown_extensions'], strict=config['strict']) context = get_global_context(site_navigation, config) context.update( get_page_context(page, html_content, site_navigation, table_of_contents, meta, config)) # Allow 'template:' override in md source files. if 'template' in meta: template = env.get_template(meta['template'][0]) else: template = env.get_template('base.html') if not utils.is_markdown_file(page.input_path): template = env.get_template('base_without_toc.html') # Render the template. output_content = template.render(context) # Write the output file. output_path = os.path.join(config['site_dir'], page.output_path) if dump_json: json_context = { 'content': context['content'], 'title': context['current_page'].title, 'url': context['current_page'].abs_url, 'language': 'en', } utils.write_file( json.dumps(json_context, indent=4).encode('utf-8'), output_path.replace('.html', '.json')) else: utils.write_file(output_content.encode('utf-8'), output_path) search_index.add_entry_from_context(page, html_content, table_of_contents) # generate html for other md files files = ListFilesByTxt(os.path.join(config['docs_dir']), '.md') for mdf in files: title = os.path.basename(mdf) title = os.path.splitext(title)[0] path = os.path.relpath(mdf, config['docs_dir']) url = utils.get_url_path(path, config['use_directory_urls']) output_path = utils.get_html_path(path) if (path in nav_pages): continue input_content = open(mdf, 'r').read() if PY2: input_content = input_content.decode('utf-8') site_navigation.url_context.set_current_url(url) # Process the markdown text html_content, table_of_contents, meta = convert_markdown( input_content, site_navigation, extensions=config['markdown_extensions']) context = get_global_context(site_navigation, config) page = nav.Page(title=title, url=url, path=path, url_context=site_navigation.url_context) context.update( get_page_context(page, html_content, site_navigation, table_of_contents, meta, config)) if 'template' in meta: template = env.get_template(meta['template'][0]) else: template = env.get_template('base.html') if not utils.is_markdown_file(mdf): template = env.get_template('base_without_toc.html') # Render the template. output_content = template.render(context) # Write the output file. output_path = os.path.join(config['site_dir'], output_path) utils.write_file(output_content.encode('utf-8'), output_path) #search_index.add_entry_from_context(page, html_content, table_of_contents) build_template( 'js/tipuesearch/tipuesearch_content.js', env, config, extra_context={'search_index': search_index.generate_search_index()})