def test_find_toc_by_id(self): """ Test finding the relevant TOC item by the tag ID. """ index = search_index.SearchIndex() md = dedent(""" # Heading 1 ## Heading 2 ### Heading 3 """) toc = get_toc(get_markdown_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 get_nb_toc(fpath): """Returns a TOC for the Notebook It does that by converting first to MD """ body = convert.nb2md(fpath) md_toc_tokens = get_markdown_toc(body) toc = get_toc(md_toc_tokens) return toc
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> """ cfg = load_config() pages = [ Page('Home', File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg), Page('About', File('about.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg) ] md = dedent(""" # Heading 1 ## Heading 2 ### Heading 3 """) toc = get_toc(get_markdown_toc(md)) full_content = ''.join("""Heading{0}Content{0}""".format(i) for i in range(1, 4)) for page in pages: # Fake page.read_source() and page.render() page.markdown = md page.toc = toc page.content = html_content index = search_index.SearchIndex() index.add_entry_from_context(page) self.assertEqual(len(index._entries), 4) loc = page.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']), "Content2") self.assertEqual(index._entries[2]['location'], "{0}#heading-2".format(loc)) self.assertEqual(index._entries[3]['title'], "Heading 3") self.assertEqual(strip_whitespace(index._entries[3]['text']), "Content3") self.assertEqual(index._entries[3]['location'], "{0}#heading-3".format(loc))
def get_nb_toc(fpath): """Returns a TOC for the Notebook It does that by converting first to MD """ body = convert.nb2md(fpath) md_toc_tokens = get_markdown_toc(body) toc = get_toc(md_toc_tokens) title = None for token in md_toc_tokens: if token["level"] == 1 and title is None: title = token["name"] return toc, title
def render(self, config, files): """ Convert the Markdown source file to HTML as per the config. """ extensions = [_RelativePathExtension(self.file, files) ] + config['markdown_extensions'] md = markdown.Markdown(extensions=extensions, extension_configs=config['mdx_configs'] or {}) self.content = md.convert(self.markdown) self.toc = get_toc(getattr(md, 'toc', ''))
def test_skip_no_href(self): html = dedent(""" <div class="toc"> <ul> <li><a>Header 1</a></li> <li><a href="#foo">Header 2</a></li> </ul> </div> """) expected = 'Header 2 - #foo' toc = get_toc(html) self.assertEqual(str(toc).strip(), expected) self.assertEqual(len(toc), 1)
def test_flat_h2_toc(self): md = dedent(""" ## Heading 1 ## Heading 2 ## Heading 3 """) expected = dedent(""" Heading 1 - #heading-1 Heading 2 - #heading-2 Heading 3 - #heading-3 """) toc = get_toc(get_markdown_toc(md)) self.assertEqual(str(toc).strip(), expected) self.assertEqual(len(toc), 3)
def test_indented_toc_html(self): md = dedent(""" # Heading 1 ## <code>Heading</code> 2 ## Heading 3 """) expected = dedent(""" Heading 1 - #heading-1 Heading 2 - #heading-2 Heading 3 - #heading-3 """) toc = get_toc(get_markdown_toc(md)) self.assertEqual(str(toc).strip(), expected) self.assertEqual(len(toc), 1)
def test_entityref(self): md = dedent(""" # Heading & 1 ## Heading > 2 ### Heading < 3 """) expected = dedent(""" Heading & 1 - #heading-1 Heading > 2 - #heading-2 Heading < 3 - #heading-3 """) toc = get_toc(get_markdown_toc(md)) self.assertEqual(str(toc).strip(), expected) self.assertEqual(len(toc), 1)
def render(self, config, files): """ Convert the Markdown source file to HTML as per the config. """ extensions = [ _RelativePathExtension(self.file, files) ] + config['markdown_extensions'] md = markdown.Markdown( extensions=extensions, extension_configs=config['mdx_configs'] or {} ) self.content = md.convert(self.markdown) self.toc = get_toc(getattr(md, 'toc', ''))
def test_html_toc(self): html = dedent(""" <div class="toc"> <ul> <li><a href="#foo">Heading 1</a></li> <li><a href="#bar">Heading 2</a></li> </ul> </div> """) expected = dedent(""" Heading 1 - #foo Heading 2 - #bar """) toc = get_toc(html) self.assertEqual(str(toc).strip(), expected) self.assertEqual(len(toc), 2)
def test_level(self): md = dedent(""" # Heading 1 ## Heading 1.1 ### Heading 1.1.1 ### Heading 1.1.2 ## Heading 1.2 """) toc = get_toc(get_markdown_toc(md)) def get_level_sequence(items): for item in items: yield item.level yield from get_level_sequence(item.children) self.assertEqual(tuple(get_level_sequence(toc)), (1, 2, 3, 3, 2))
def get_nb_toc(fpath): """Converts the notebook to md and get the toc """ body = convert.nb2md(fpath) extensions = ["toc", "fenced_code"] # config['markdown_extensions'] mdx_configs = { "toc": { "permalink": True } } # config['mdx_configs'] or {'toc': {'permalink': True}} md = markdown.Markdown(extensions=extensions, extension_configs=mdx_configs) content = md.convert(body) toc = get_toc(getattr(md, "toc", "")) return toc
def render(self, config, files): """ Convert the Markdown source file to HTML as per the config. """ extensions = [] if config['source_code_link']: extensions.append( SourceCodeLinkExtension(self.file, config['source_code_link'])) extensions.append(_RelativePathExtension(self.file, files)) extensions.extend(config['markdown_extensions']) md = markdown.Markdown(extensions=extensions, extension_configs=config['mdx_configs'] or {}) self.content = md.convert(self.markdown) self.toc = get_toc(getattr(md, 'toc_tokens', []))
def test_level(self): md = dedent(""" # Heading 1 ## Heading 1.1 ### Heading 1.1.1 ### Heading 1.1.2 ## Heading 1.2 """) toc = get_toc(get_markdown_toc(md)) def get_level_sequence(items): for item in items: yield item.level for c in get_level_sequence(item.children): yield c self.assertEqual(tuple(get_level_sequence(toc)), (0, 1, 2, 2, 1))
def test_mixed_toc(self): md = dedent(""" # Heading 1 ## Heading 2 # Heading 3 ### Heading 4 ### Heading 5 """) expected = dedent(""" Heading 1 - #heading-1 Heading 2 - #heading-2 Heading 3 - #heading-3 Heading 4 - #heading-4 Heading 5 - #heading-5 """) toc = get_toc(get_markdown_toc(md)) self.assertEqual(str(toc).strip(), expected) self.assertEqual(len(toc), 2)
def test_page(title, filename, config): test_page = Page( title, File(filename, config['docs_dir'], config['site_dir'], config['use_directory_urls']), config) test_page.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>""" test_page.markdown = dedent(""" # Heading 1 ## Heading 2 ### Heading 3""") test_page.toc = get_toc(get_markdown_toc(test_page.markdown)) return test_page
def on_page_content(self, html: str, page: Page, config: MkDocsConfig, files: Files): if str(page.file.abs_src_path).endswith("ipynb") and not ( "markdown.extensions.md_in_html" in config["markdown_extensions"] or "markdown.extensions.extra" in config["markdown_extensions"]): log.debug(f"Re-rendering page with markdown in divs: {page}") extensions = [ _RelativePathExtension(page.file, files), "markdown.extensions.md_in_html", ] + config["markdown_extensions"] md = markdown.Markdown(extensions=extensions, extension_configs=config["mdx_configs"] or {}) html = md.convert(page.markdown) page.toc = get_toc(getattr(md, "toc_tokens", [])) return html
def render(self, config, files): """ Convert the Markdown source file to HTML as per the config. """ this_base_path = os.path.dirname(self.file.src_path) mdx_configs = copy.deepcopy(config['mdx_configs']) or {} for extension in mdx_configs: base_path = mdx_configs[extension].get('base_path') if base_path == '$relative': mdx_configs[extension]['base_path'] = os.path.join( config['docs_dir'], this_base_path) extensions = [_RelativePathExtension(self.file, files) ] + config['markdown_extensions'] md = markdown.Markdown(extensions=extensions, extension_configs=mdx_configs) self.content = md.convert(self.markdown) self.toc = get_toc(getattr(md, 'toc_tokens', []))
def on_page_content(self, html, page, **kwargs): if page.abs_url not in self.pages_with_docstrings: return html extensions, configs = self.get_combined_extensions() md = Markdown(extensions=extensions, extension_configs=configs) lines = page.markdown.split("\n") modified_lines = lines[::] for i, line in enumerate(lines): if line.startswith("::: "): renderer = MarkdownRenderer(dict(config)) import_string = line.replace("::: ", "") root_object = self.objects[import_string]["object"] heading = 2 if config["show_top_object_heading"] else 1 modified_lines[i] = "\n".join( renderer.render(root_object, heading)) modified_lines.append(self.references) markdown_contents = "\n".join(modified_lines) html = insert_divs(md.convert(markdown_contents)) page.toc = get_toc(getattr(md, "toc_tokens", [])) return html
def test_charref(self): md = '# @Header' expected = '@Header - #header' toc = get_toc(get_markdown_toc(md)) self.assertEqual(str(toc).strip(), expected) self.assertEqual(len(toc), 1)