def test_walk_empty_toc(self): pages = legacy.pages_compat_shim([('index.md', ), ('about.md', 'About')]) expected = [ dedent(""" Home - / [*] About - /about/ """), dedent(""" Home - / About - /about/ [*] """) ] site_navigation = nav.SiteNavigation(pages) for index, page in enumerate(site_navigation.walk_pages()): self.assertEqual(str(site_navigation).strip(), expected[index])
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 = [ {'Home': 'index.md'}, {'About': 'about.md'}, ] 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]['location'], loc) self.assertEqual(index._entries[1]['title'], "Heading 1") self.assertEqual(index._entries[1]['text'], "Content 1") self.assertEqual(index._entries[1]['location'], "{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]['location'], "{0}#heading-2".format(loc))
def test_convert_internal_media(self): pages = [('index.md', ), ('internal.md', ), ('sub/internal.md')] site_navigation = nav.SiteNavigation(pages) expected_results = ( '<p><img alt="The initial MkDocs layout" src="./img/initial-layout.png" /></p>\n', '<p><img alt="The initial MkDocs layout" src="../img/initial-layout.png" /></p>\n', '<p><img alt="The initial MkDocs layout" src="../../img/initial-layout.png" /></p>\n', ) for (page, expected) in zip(site_navigation.walk_pages(), expected_results): md_text = '![The initial MkDocs layout](img/initial-layout.png)' html, _, _ = build.convert_markdown( md_text, site_navigation=site_navigation) self.assertEqual(html, expected)
def test_walk_simple_toc(self): pages = [ ('index.md', 'Home'), ('about.md', 'About') ] expected = [ dedent(""" Home - / [*] About - /about/ """), dedent(""" Home - / About - /about/ [*] """) ] site_navigation = nav.SiteNavigation(pages) for index, page in enumerate(site_navigation.walk_pages()): self.assertEqual(str(site_navigation).strip(), expected[index])
def test_dont_convert_code_block_urls(self): pages = [ ('index.md',), ('internal.md',), ('sub/internal.md') ] site_navigation = nav.SiteNavigation(pages) expected = dedent(""" <p>An HTML Anchor::</p> <pre><code><a href="index.md">My example link</a> </code></pre> """) for page in site_navigation.walk_pages(): markdown = 'An HTML Anchor::\n\n <a href="index.md">My example link</a>\n' html, _, _ = build.convert_markdown(markdown, site_navigation=site_navigation) self.assertEqual(dedent(html), expected)
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) build_404(config, env, site_navigation) for page in site_navigation.walk_pages(): try: log.debug("Building page %s", page.input_path) _build_page(page, config, site_navigation, env, dump_json) except: log.error("Error building page %s", page.input_path) raise
def test_convert_internal_media(self): pages = [ ('index.md',), ('internal.md',), ('sub/internal.md') ] site_navigation = nav.SiteNavigation(pages) expected_results = ( '<p><img alt="The initial MkDocs layout" src="./img/initial-layout.png" /></p>', '<p><img alt="The initial MkDocs layout" src="../img/initial-layout.png" /></p>', '<p><img alt="The initial MkDocs layout" src="../../img/initial-layout.png" /></p>', ) for (page, expected) in zip(site_navigation.walk_pages(), expected_results): html = '<p><img alt="The initial MkDocs layout" src="img/initial-layout.png" /></p>' html = build.post_process_html(html, site_navigation) self.assertEqual(html, expected)
def test_convert_internal_asbolute_media(self): """Test absolute image URL's are correct for different base_urls""" pages = [('index.md', ), ('internal.md', ), ('sub/internal.md')] site_navigation = nav.SiteNavigation(pages) expected_results = ( './img/initial-layout.png', '../img/initial-layout.png', '../../img/initial-layout.png', ) template = '<p><img alt="The initial MkDocs layout" src="%s" /></p>\n' for (page, expected) in zip(site_navigation.walk_pages(), expected_results): md_text = '![The initial MkDocs layout](/img/initial-layout.png)' html, _, _ = build.convert_markdown( md_text, site_navigation=site_navigation) self.assertEqual(html, template % expected)
def test_dont_convert_code_block_urls(self): pages = [ 'index.md', 'internal.md', 'sub/internal.md', ] config = load_config(pages=pages) site_navigation = nav.SiteNavigation(config) expected = dedent(""" <p>An HTML Anchor::</p> <pre><code><a href="index.md">My example link</a> </code></pre> """) for page in site_navigation.walk_pages(): page.markdown = 'An HTML Anchor::\n\n <a href="index.md">My example link</a>\n' page.render(config, site_navigation) self.assertEqual(page.content, expected)
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) 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 test_nested_ungrouped(self): pages = [ { 'Home': 'index.md' }, { 'Contact': 'about/contact.md' }, { 'License Title': 'about/sub/license.md' }, ] expected = dedent(""" Home - / Contact - /about/contact/ License Title - /about/sub/license/ """) site_navigation = nav.SiteNavigation(pages) self.assertEqual(str(site_navigation).strip(), expected) self.assertEqual(len(site_navigation.nav_items), 3) self.assertEqual(len(site_navigation.pages), 3)
def test_indented_toc(self): pages = [('index.md', 'Home'), ('api-guide/running.md', 'API Guide', 'Running'), ('api-guide/testing.md', 'API Guide', 'Testing'), ('api-guide/debugging.md', 'API Guide', 'Debugging'), ('about/release-notes.md', 'About', 'Release notes'), ('about/license.md', 'About', 'License')] expected = dedent(""" Home - / API Guide Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About Release notes - /about/release-notes/ License - /about/license/ """) site_navigation = nav.SiteNavigation(pages) self.assertEqual(str(site_navigation).strip(), expected) self.assertEqual(len(site_navigation.nav_items), 3) self.assertEqual(len(site_navigation.pages), 6)
def test_ancestors(self): pages = [('index.md', 'Home'), ('api-guide/running.md', 'API Guide', 'Running'), ('api-guide/testing.md', 'API Guide', 'Testing'), ('api-guide/debugging.md', 'API Guide', 'Debugging'), ('about/release-notes.md', 'About', 'Release notes'), ('about/license.md', 'About', 'License')] site_navigation = nav.SiteNavigation(pages) ancestors = ( [], [site_navigation.nav_items[1]], [site_navigation.nav_items[1]], [site_navigation.nav_items[1]], [site_navigation.nav_items[2]], [site_navigation.nav_items[2]], ) for page, expected_ancestor in zip(site_navigation.pages, ancestors): self.assertEqual(page.ancestors, expected_ancestor)
def build_pages(config, dirty=False): """ Build all pages and write them into the build directory. """ site_navigation = nav.SiteNavigation(config) # Run `nav` plugin events. site_navigation = config['plugins'].run_event('nav', site_navigation, config=config) env = config['theme'].get_env() # Run `env` plugin events. env = config['plugins'].run_event('env', env, config=config, site_navigation=site_navigation) for template in config['theme'].static_templates: if utils.is_error_template(template): build_error_template(template, env, config, site_navigation) else: build_template(template, env, config, site_navigation) build_extra_templates(config['extra_templates'], config, site_navigation) log.debug("Building markdown pages.") 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. if dirty and (utils.modified_time(page.abs_input_path) < utils.modified_time(page.abs_output_path)): continue log.debug("Building page %s", page.input_path) _build_page(page, config, site_navigation, env) except Exception: log.error("Error building page %s", page.input_path) raise
def test_create_relative_media_url_sub_index(self): ''' test special case where there's a sub/index.md page ''' site_navigation = nav.SiteNavigation([ {'Home': 'index.md'}, {'Sub': [ {'Sub Home': '/subpage/index.md'}, ]} ]) site_navigation.url_context.set_current_url('/subpage/') site_navigation.file_context.current_file = "subpage/index.md" def assertPathGenerated(declared, expected): url = utils.create_relative_media_url(site_navigation, declared) self.assertEqual(url, expected) assertPathGenerated("img.png", "./img.png") assertPathGenerated("./img.png", "./img.png") assertPathGenerated("/img.png", "../img.png")
def test_create_media_urls(self): pages = [ {'Home': 'index.md'}, {'About': 'about.md'}, {'Sub': [ {'Sub Home': 'index.md'}, {'Sub About': 'about.md'}, ]} ] expected_results = { 'https://media.cdn.org/jq.js': 'https://media.cdn.org/jq.js', 'http://media.cdn.org/jquery.js': 'http://media.cdn.org/jquery.js', '//media.cdn.org/jquery.js': '//media.cdn.org/jquery.js', 'media.cdn.org/jquery.js': './media.cdn.org/jquery.js', 'local/file/jquery.js': './local/file/jquery.js', 'image.png': './image.png', } site_navigation = nav.SiteNavigation(pages) for path, expected_result in expected_results.items(): urls = utils.create_media_urls(site_navigation, [path]) self.assertEqual(urls[0], expected_result)
def build_pages(config): """ Builds all the pages and writes them into the build directory. """ site_navigation = nav.SiteNavigation(config['pages']) loader = jinja2.FileSystemLoader(config['theme_dir']) env = jinja2.Environment(loader=loader) for page in site_navigation.walk_pages(): # 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, extensions=config['markdown_extensions'] ) html_content = post_process_html(html_content, site_navigation) context = get_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) utils.write_file(output_content.encode('utf-8'), output_path)
def test_indented_toc(self): pages = [{ 'Home': 'index.md' }, { 'API Guide': [ { 'Running': 'api-guide/running.md' }, { 'Testing': 'api-guide/testing.md' }, { 'Debugging': 'api-guide/debugging.md' }, ] }, { 'About': [ 'about/index.md', { 'Release notes': 'about/release-notes.md' }, { 'License': 'about/license.md' } ] }] expected = dedent(""" Home - / API Guide Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About - /about/ Release notes - /about/release-notes/ License - /about/license/ """) site_navigation = nav.SiteNavigation(pages) self.assertEqual(str(site_navigation).strip(), expected) self.assertEqual(len(site_navigation.nav_items), 3) self.assertEqual(len(site_navigation.pages), 7)
def test_create_relative_media_url_sub_index_windows(self): ''' test special case where there's a sub/index.md page and we are on Windows. current_file paths uses backslash in Windows ''' site_navigation = nav.SiteNavigation([ {'Home': 'index.md'}, {'Sub': [ {'Sub Home': '/level1/level2/index.md'}, ]} ]) site_navigation.url_context.set_current_url('/level1/level2') site_navigation.file_context.current_file = "level1\\level2\\index.md" def assertPathGenerated(declared, expected): url = utils.create_relative_media_url(site_navigation, declared) self.assertEqual(url, expected) assertPathGenerated("img.png", "./img.png") assertPathGenerated("./img.png", "./img.png") assertPathGenerated("/img.png", "../img.png")
def test_convert_internal_asbolute_media(self): """Test absolute image URL's are correct for different base_urls""" pages = [ 'index.md', 'internal.md', 'sub/internal.md', ] config = load_config(pages=pages) site_navigation = nav.SiteNavigation(config) expected_results = ( './img/initial-layout.png', '../img/initial-layout.png', '../../img/initial-layout.png', ) template = '<p><img alt="The initial MkDocs layout" src="%s" /></p>' for (page, expected) in zip(site_navigation.walk_pages(), expected_results): page.markdown = '![The initial MkDocs layout](/img/initial-layout.png)' page.render(config, site_navigation) self.assertEqual(page.content, template % expected)
def test_edit_uri(self): """ Ensure that set_edit_url creates well formed URLs for edit_uri """ pages = [ 'index.md', 'internal.md', 'sub/internal.md', 'sub1/sub2/internal.md', ] # Basic test repo_url = 'http://example.com/' edit_uri = 'edit/master/docs/' site_navigation = nav.SiteNavigation( load_config(pages=pages, repo_url=repo_url, edit_uri=edit_uri, docs_dir='docs', site_dir='site', site_url='', use_directory_urls=True)) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2], repo_url + edit_uri + pages[3], ) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx]) # Ensure the '/' is added to the repo_url and edit_uri repo_url = 'http://example.com' edit_uri = 'edit/master/docs' site_navigation = nav.SiteNavigation( load_config(pages=pages, repo_url=repo_url, edit_uri=edit_uri, docs_dir='docs', site_dir='site', site_url='', use_directory_urls=True)) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx]) # Ensure query strings are supported repo_url = 'http://example.com' edit_uri = '?query=edit/master/docs/' site_navigation = nav.SiteNavigation( load_config(pages=pages, repo_url=repo_url, edit_uri=edit_uri, docs_dir='docs', site_dir='site', site_url='', use_directory_urls=True)) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2], repo_url + edit_uri + pages[3], ) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx]) # Ensure fragment strings are supported repo_url = 'http://example.com' edit_uri = '#fragment/edit/master/docs/' site_navigation = nav.SiteNavigation( load_config(pages=pages, repo_url=repo_url, edit_uri=edit_uri, docs_dir='docs', site_dir='site', site_url='', use_directory_urls=True)) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2], repo_url + edit_uri + pages[3], ) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx])
def test_walk_indented_toc(self): pages = [('index.md', 'Home'), ('api-guide/running.md', 'API Guide', 'Running'), ('api-guide/testing.md', 'API Guide', 'Testing'), ('api-guide/debugging.md', 'API Guide', 'Debugging'), ('about/release-notes.md', 'About', 'Release notes'), ('about/license.md', 'About', 'License')] expected = [ dedent(""" Home - / [*] API Guide Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About Release notes - /about/release-notes/ License - /about/license/ """), dedent(""" Home - / API Guide [*] Running - /api-guide/running/ [*] Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About Release notes - /about/release-notes/ License - /about/license/ """), dedent(""" Home - / API Guide [*] Running - /api-guide/running/ Testing - /api-guide/testing/ [*] Debugging - /api-guide/debugging/ About Release notes - /about/release-notes/ License - /about/license/ """), dedent(""" Home - / API Guide [*] Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ [*] About Release notes - /about/release-notes/ License - /about/license/ """), dedent(""" Home - / API Guide Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About [*] Release notes - /about/release-notes/ [*] License - /about/license/ """), dedent(""" Home - / API Guide Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About [*] Release notes - /about/release-notes/ License - /about/license/ [*] """) ] site_navigation = nav.SiteNavigation(pages) for index, page in enumerate(site_navigation.walk_pages()): self.assertEqual(str(site_navigation).strip(), expected[index])
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 test_base_url(self): pages = [('index.md', )] site_navigation = nav.SiteNavigation(pages, use_directory_urls=False) base_url = site_navigation.url_context.make_relative('/') self.assertEqual(base_url, '.')
def test_edit_uri_windows(self): """ Ensure that set_edit_url creates well formed URLs for edit_uri with a windows path """ pages = [ 'index.md', 'internal.md', 'sub\\internal.md', 'sub1\\sub2\\internal.md', ] # Basic test repo_url = 'http://example.com/' edit_uri = 'edit/master/docs/' site_navigation = nav.SiteNavigation(pages) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2].replace('\\', '/'), repo_url + edit_uri + pages[3].replace('\\', '/'), ) for idx, page in enumerate(site_navigation.walk_pages()): page.set_edit_url(repo_url, edit_uri) self.assertEqual(page.edit_url, expected_results[idx]) # Ensure the '/' is added to the repo_url and edit_uri repo_url = 'http://example.com' edit_uri = 'edit/master/docs/' site_navigation = nav.SiteNavigation(pages) for idx, page in enumerate(site_navigation.walk_pages()): page.set_edit_url(repo_url, edit_uri) self.assertEqual(page.edit_url, expected_results[idx]) # Ensure query strings are supported repo_url = 'http://example.com' edit_uri = '?query=edit/master/docs/' site_navigation = nav.SiteNavigation(pages) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2].replace('\\', '/'), repo_url + edit_uri + pages[3].replace('\\', '/'), ) for idx, page in enumerate(site_navigation.walk_pages()): page.set_edit_url(repo_url, edit_uri) self.assertEqual(page.edit_url, expected_results[idx]) # Ensure fragment strings are supported repo_url = 'http://example.com' edit_uri = '#fragment/edit/master/docs/' site_navigation = nav.SiteNavigation(pages) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2].replace('\\', '/'), repo_url + edit_uri + pages[3].replace('\\', '/'), ) for idx, page in enumerate(site_navigation.walk_pages()): page.set_edit_url(repo_url, edit_uri) self.assertEqual(page.edit_url, expected_results[idx])
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 test_nesting(self): pages_config = [{ 'Home': 'index.md' }, { 'Install': [ { 'Pre-install': 'install/install-pre.md' }, { 'The install': 'install/install-actual.md' }, { 'Post install': 'install/install-post.md' }, ] }, { 'Guide': [ { 'Tutorial': [ { 'Getting Started': 'guide/tutorial/running.md' }, { 'Advanced Features': 'guide/tutorial/testing.md' }, { 'Further Reading': 'guide/tutorial/debugging.md' }, ] }, { 'API Reference': [ { 'Feature 1': 'guide/api-ref/running.md' }, { 'Feature 2': 'guide/api-ref/testing.md' }, { 'Feature 3': 'guide/api-ref/debugging.md' }, ] }, { 'Testing': 'guide/testing.md' }, { 'Deploying': 'guide/deploying.md' }, ] }] site_navigation = nav.SiteNavigation(pages_config) self.assertEqual([n.title for n in site_navigation.nav_items], ['Home', 'Install', 'Guide']) self.assertEqual(len(site_navigation.pages), 12) expected = dedent(""" Home - / Install Pre-install - /install/install-pre/ The install - /install/install-actual/ Post install - /install/install-post/ Guide Tutorial Getting Started - /guide/tutorial/running/ Advanced Features - /guide/tutorial/testing/ Further Reading - /guide/tutorial/debugging/ API Reference Feature 1 - /guide/api-ref/running/ Feature 2 - /guide/api-ref/testing/ Feature 3 - /guide/api-ref/debugging/ Testing - /guide/testing/ Deploying - /guide/deploying/ """) self.maxDiff = None self.assertEqual(str(site_navigation).strip(), expected)
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()})
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})