def json_command(clean, config_file, strict, site_dir): """Build the MkDocs documentation to JSON files Rather than building your documentation to HTML pages, this outputs each page in a simple JSON format. This command is useful if you want to index your documentation in an external search engine. """ log.warning("The json command is deprecated and will be removed in a " "future MkDocs release. For details on updating: " "http://www.mkdocs.org/about/release-notes/") # Don't override config value if user did not specify --strict flag # Conveniently, load_config drops None values strict = strict or None try: build.build(config.load_config( config_file=config_file, strict=strict, site_dir=site_dir ), dump_json=True, dirty=not clean) except exceptions.ConfigurationError as e: # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def test_copying_media(self): with TemporaryDirectory() as docs_dir, TemporaryDirectory() as site_dir: # Create a non-empty markdown file, image, html file, dot file and dot directory. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write(dedent(""" page_title: custom title # Heading 1 This is some text. # Heading 2 And some more text. """)) f.close() open(os.path.join(docs_dir, 'img.jpg'), 'w').close() open(os.path.join(docs_dir, 'example.html'), 'w').close() open(os.path.join(docs_dir, '.hidden'), 'w').close() os.mkdir(os.path.join(docs_dir, '.git')) open(os.path.join(docs_dir, '.git/hidden'), 'w').close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only the markdown (coverted to html) and the image are copied. self.assertTrue(os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isfile(os.path.join(site_dir, 'img.jpg'))) self.assertTrue(os.path.isfile(os.path.join(site_dir, 'example.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '.hidden'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '.git/hidden')))
def test_BOM(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create an UTF-8 Encoded file with BOM (as Micorsoft editors do). See #1186. f = io.open(os.path.join(docs_dir, 'index.md'), 'w', encoding='utf-8-sig') f.write('# An UTF-8 encoded file with a BOM') f.close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify that the file was generated properly. # If the BOM is not removed, Markdown will return: # `<p>\ufeff# An UTF-8 encoded file with a BOM</p>`. f = io.open(os.path.join(site_dir, 'index.html'), 'r', encoding='utf-8') output = f.read() f.close() self.assertTrue( '<h1 id="an-utf-8-encoded-file-with-a-bom">An UTF-8 encoded file with a BOM</h1>' in output) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def publish(context, skip_update_ipns): Printer.start("Publishing your site to IPFS...") with cd(DEFAULT_SITE_DIR): Printer.info("Building site...") build(load_config(config_file='./mkdocs.yml')) if not os.path.exists(IPFS_BIN): Printer.error("Please run 'hfs2018 init' first") context.abort() Printer.info( 'Uploading to IPFS and updating IPNS record (optional). This may take some time...' ) with ipfs_daemon(IPFS_BIN): site_output_dir = os.path.join(DEFAULT_SITE_DIR, "site") Printer.info("We are uploading the site to IPFS now...") site_hash = add_to_ipfs(site_output_dir) Printer.info( f"The site is available at https://gateway.ipfs.io/ipfs/{site_hash}" ) if not skip_update_ipns: Printer.info("We are updating the IPNS record now...") ipns_hash = update_ipns_record(site_hash) Printer.ready( f'Your site is available on IPNS! You can reach it via:' f' https://gateway.ipfs.io/ipns/{ipns_hash}')
def mkdocs_site(tmpdir): mkdocs_root = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test_data') cfg = config.load_config(os.path.join(mkdocs_root, 'mkdocs.yml')) cfg['site_dir'] = tmpdir build.build(cfg)
def builder(): log.info("Building documentation...") config = load_config( config_file=config_file, dev_addr=dev_addr, strict=strict, theme=theme, theme_dir=theme_dir, site_dir=site_dir, **kwargs ) # combine CLI watch arguments with config file values if config["watch"] is None: config["watch"] = watch else: config["watch"].extend(watch) # Override a few config settings after validation config['site_url'] = 'http://{}{}'.format(config['dev_addr'], mount_path(config)) live_server = livereload in ['dirty', 'livereload'] dirty = livereload == 'dirty' build(config, live_server=live_server, dirty=dirty) return config
def builder(lang): log.info(f'Building {lang}...') pre_build(lang, docs_dir) lang_path = os.path.join(docs_dir, lang) config = load_config(config_file=os.path.join(lang_path, 'mkdocs.yml'), dev_addr=f'{host}:{port}', strict=True, site_dir=os.path.join(site_dir, lang)) config['site_url'] = f'http://{host}:{port}/{lang}/' # mkdocs is usually launched from the docs root directory, so it doesn't resolve relative paths smart enough, # leading to some bugs when launched from another place. # For example, custom_icons don't work without this dirty hack, and our neat Flipper buttons fail to load :( # I could've filled an issue to mkdocs-material-extensions regarding this, but I believe it's more reliable # to just switch the working directory, cause there might be other features that rely on it. # # It was kinda hard to figure this out, and it's actually 9 AM right now and I haven't slept yet, so please # satisfy my praise kink by saying 'good girl' telepathically cwd = os.getcwd() os.chdir(lang_path) build(config, live_server=True, dirty=False) os.chdir(cwd)
def test_BOM(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create an UTF-8 Encoded file with BOM (as Micorsoft editors do). See #1186. f = io.open(os.path.join(docs_dir, 'index.md'), 'w', encoding='utf-8-sig') f.write('# An UTF-8 encoded file with a BOM') f.close() cfg = load_config( docs_dir=docs_dir, site_dir=site_dir ) build.build(cfg) # Verify that the file was generated properly. # If the BOM is not removed, Markdown will return: # `<p>\ufeff# An UTF-8 encoded file with a BOM</p>`. f = io.open(os.path.join(site_dir, 'index.html'), 'r', encoding='utf-8') output = f.read() f.close() self.assertTrue( '<h1 id="an-utf-8-encoded-file-with-a-bom">An UTF-8 encoded file with a BOM</h1>' in output ) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def build_single_page_version(lang, args, cfg): logging.info('Building single page version for ' + lang) with autoremoved_file(os.path.join(args.docs_dir, lang, 'single.md')) as single_md: concatenate(lang, args.docs_dir, single_md) with temp_dir() as temp: cfg.load_dict({ 'docs_dir': os.path.join(args.docs_dir, lang), 'site_dir': temp, 'extra': { 'single_page': True, 'search': { 'language': 'en, ru' } }, 'pages': [{ cfg.data.get('site_name'): 'single.md' }] }) mkdocs_build.build(cfg) shutil.copytree(os.path.join(temp, 'single'), os.path.join(args.output_dir, lang, 'single'))
def test_copy_theme_files(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create a non-empty markdown file. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write(dedent(""" page_title: custom title # Heading 1 This is some text. """)) f.close() cfg = load_config({ 'docs_dir': docs_dir, 'site_dir': site_dir }) build.build(cfg) # Verify only theme media are copied, not templates or Python files. self.assertTrue(os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'js'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'css'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'img'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '__init__.py'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '__init__.pyc'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'base.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'content.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'nav.html'))) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def test_plugin_builds_newsletters(full_repo: Repo, config: Config) -> None: """ Given: * A correct mkdocs directory structure. * A correct mkdocs.yml file. * Many files under `docs/`. * The mkdocs_newsletter plugin configured. * A git repository with commits. When: the site is built Then: * The newsletter files are created. * The newsletter navigation section is created. * The next and previos page sections are created. """ build.build(config) # act newsletter_path = f"{full_repo.working_dir}/site/newsletter/2021_02/index.html" with open(newsletter_path, "r") as newsletter_file: newsletter = newsletter_file.read() assert "<title>February of 2021 - The Blue Book</title>" in newsletter assert ( '<nav class="md-nav" aria-label="February of 2021" data-md-level="3">' in newsletter ) assert ( '<a href="../2021_03_02/" class="md-footer__link ' 'md-footer__link--prev" aria-label="Previous: 2nd March 2021" rel="prev">' in newsletter ) assert ( '<a href="../2021_w06/" class="md-footer__link ' 'md-footer__link--next" aria-label="Next: 6th Week of 2021" rel="next">' in newsletter )
def json_command(clean, config_file, strict, site_dir): """Build the MkDocs documentation to JSON files Rather than building your documentation to HTML pages, this outputs each page in a simple JSON format. This command is useful if you want to index your documentation in an external search engine. """ log.warning("The json command is deprecated and will be removed in a " "future MkDocs release. For details on updating: " "http://www.mkdocs.org/about/release-notes/") # Don't override config value if user did not specify --strict flag # Conveniently, load_config drops None values strict = strict or None try: build.build(config.load_config( config_file=config_file, strict=strict, site_dir=site_dir ), dump_json=True, dirty=not clean) except exceptions.ConfigurationError as e: # pragma: no cover # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def test_copy_theme_files(self): with TemporaryDirectory() as docs_dir, TemporaryDirectory( ) as site_dir: # Create a non-empty markdown file. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write( dedent(""" page_title: custom title # Heading 1 This is some text. """)) f.close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only theme media are copied, not templates or Python files. self.assertTrue( os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'js'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'css'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'img'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, '__init__.py'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, '__init__.pyc'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, 'base.html'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, 'content.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'nav.html')))
def test_copy_theme_files(self): with TemporaryDirectory() as docs_dir, TemporaryDirectory() as site_dir: # Create a non-empty markdown file. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write(dedent(""" page_title: custom title # Heading 1 This is some text. """)) f.close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only theme media are copied, not templates or Python files. self.assertTrue(os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'js'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'css'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'img'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '__init__.py'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '__init__.pyc'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'base.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'content.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'nav.html')))
def handle_mkdocs_ghdeploy(): delete_branch('gh-pages') cfg = config.load_config( config_file=os.path.join(CWD, "docs/mkdocs.yml"), repo_url='[email protected]:sumeetpatil/TravisTest.git') build.build(cfg) print('Deploying {} Github Pages to {}#gh-pages') gh_deploy.gh_deploy(cfg, force=True)
def build_command(clean, **kwargs): """Build the MkDocs documentation""" try: build.build(config.load_config(**kwargs), dirty=not clean) except exceptions.ConfigurationError as e: # pragma: no cover # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def test_run_build_error_event(self): build_errors = [] class PluginRaisingError(plugins.BasePlugin): def __init__(self, error_on): self.error_on = error_on def on_pre_page(self, page, **kwargs): if self.error_on == 'pre_page': raise BuildError('pre page error') return page def on_page_markdown(self, markdown, **kwargs): if self.error_on == 'page_markdown': raise BuildError('page markdown error') return markdown def on_page_content(self, html, **kwargs): if self.error_on == 'page_content': raise PluginError('page content error') return html def on_post_page(self, html, **kwargs): if self.error_on == 'post_page': raise ValueError('post page error') def on_build_error(self, error, **kwargs): build_errors.append(error) cfg = load_config() cfg['plugins']['errorplugin'] = PluginRaisingError(error_on='pre_page') self.assertRaises(Abort, build.build, cfg) cfg = load_config() cfg['plugins']['errorplugin'] = PluginRaisingError(error_on='page_markdown') self.assertRaises(Abort, build.build, cfg) cfg = load_config() cfg['plugins']['errorplugin'] = PluginRaisingError(error_on='page_content') self.assertRaises(Abort, build.build, cfg) cfg = load_config() cfg['plugins']['errorplugin'] = PluginRaisingError(error_on='post_page') self.assertRaises(ValueError, build.build, cfg) cfg = load_config() cfg['plugins']['errorplugin'] = PluginRaisingError(error_on='') build.build(cfg) self.assertEqual(len(build_errors), 4) self.assertIs(build_errors[0].__class__, BuildError) self.assertEqual(str(build_errors[0]), 'pre page error') self.assertIs(build_errors[1].__class__, BuildError) self.assertEqual(str(build_errors[1]), 'page markdown error') self.assertIs(build_errors[2].__class__, PluginError) self.assertEqual(str(build_errors[2]), 'page content error') self.assertIs(build_errors[3].__class__, ValueError) self.assertEqual(str(build_errors[3]), 'post page error')
def handle_mkdocs_ghdeploy(to_ghdeploy, kind, remote): if to_ghdeploy: delete_branch('gh-pages') cfg = config.load_config(config_file=os.path.join( CWD, select_config(kind)), remote_name=remote) build.build(cfg) print('Deploying {} Github Pages to {}#gh-pages'.format(kind, remote)) gh_deploy.gh_deploy(cfg, force=True)
def test_plugin_creates_monthly_rss_feed(full_repo: Repo, config: Config) -> None: """ Given: * A correct mkdocs directory structure. * A correct mkdocs.yml file. * Many files under `docs/`. * The mkdocs_newsletter plugin configured. * A git repository with commits. When: the site is built. Then: RSS valid monthly feed is created with the expected information. """ now = datetime.now(tz=tz.tzlocal()) build.build(config) # act # -------------- # - Monthly feed - # -------------- rss_path = f"{full_repo.working_dir}/site/monthly.xml" with open(rss_path, "r") as rss_file: feed = feedparser.parse(rss_file.read()) # Channel attributes assert feed.feed.title == "The Blue Book" assert feed.feed.description == "My second brain" assert feed.feed.link == "https://lyz-code.github.io/blue-book" assert feed.feed.links[1].href == "https://lyz-code.github.io/blue-book/monthly.xml" # We need to do the transformation as sometimes feed.feed.published is created # with a different timezone assert parser.parse(feed.feed.published) == now assert feed.feed.author == "Lyz" assert feed.feed.ttl == "43200" assert feed.feed.generator == f"mkdocs-newsletter - v{__version__}" assert feed.feed.image.href == "https://lyz-code.github.io/blue-book/img/logo.bmp" # Entry attributes assert len(feed.entries) == 2 assert feed.entries[0].title == "March of 2021" assert ( feed.entries[0].link == "https://lyz-code.github.io/blue-book/newsletter/2021_03/" ) assert feed.entries[0].description == ( '<article class="md-content__inner md-typeset">\n\n' '<h2 id="coding">Coding</h2>\n' '<h3 id="tdd"><a href="https://lyz-code.github.io/blue-book/coding/tdd/">TDD' "</a></h3>\n" "<ul>\n<li>New: Define test driven development.</li>\n</ul>\n" '<h3 id="python">Python</h3>\n' '<h4 id="gitpython">' '<a href="https://lyz-code.github.io/blue-book/coding/python/gitpython/">' "GitPython</a>" "</h4>\n" "<ul>\n<li>New: Present the python library.</li>\n" "</ul>\n<hr />\n\n" "</article>" ) assert parser.parse(feed.entries[0].published) == now assert feed.entries[0].author == "Lyz"
def gh_deploy_command(clean, message, remote_branch, remote_name, force, ignore_version, shell, **kwargs): """Deploy your documentation to GitHub Pages""" cfg = config.load_config( remote_branch=remote_branch, remote_name=remote_name, **kwargs ) build.build(cfg, dirty=not clean) gh_deploy.gh_deploy(cfg, message=message, force=force, ignore_version=ignore_version, shell=shell)
def test_plugin(): """Build our own documentation.""" config = load_config() build(config) site_coverage_dir = Path(config["site_dir"]) / "coverage" for html_file in site_coverage_dir.iterdir(): if html_file.suffix == ".html" and html_file.name != "index.html" and "tests" not in html_file.name: text = html_file.read_text() assert not re.search("covcovindex", text) assert not re.search('href="index.html"', text)
def gh_deploy_command(config_file, clean, message, remote_branch, remote_name): """Deploy your documentation to GitHub Pages""" try: config = load_config(config_file=config_file, remote_branch=remote_branch, remote_name=remote_name) build.build(config, clean_site_dir=clean) gh_deploy.gh_deploy(config, message=message) except exceptions.ConfigurationError as e: # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def test_copying_media(self, site_dir, docs_dir): cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify that only non-empty md file (coverted to html), static HTML file and image are copied. self.assertPathIsFile(site_dir, 'index.html') self.assertPathIsFile(site_dir, 'img.jpg') self.assertPathIsFile(site_dir, 'static.html') self.assertPathNotExists(site_dir, 'empty.md') self.assertPathNotExists(site_dir, '.hidden') self.assertPathNotExists(site_dir, '.git/hidden')
def builder(): log.info("Building documentation...") config = load_config( config_file=config_file, dev_addr=dev_addr, strict=strict, theme=theme, ) config['site_dir'] = tempdir build(config, live_server=True, clean_site_dir=True) return config
def build_command(clean, config_file, strict, theme, site_dir): """Build the MkDocs documentation""" try: build.build(load_config(config_file=config_file, strict=strict, theme=theme, site_dir=site_dir), clean_site_dir=clean) except exceptions.ConfigurationError as e: # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def build_for_lang(lang, args): logging.info('Building %s docs' % lang) config_path = os.path.join(args.docs_dir, 'toc_%s.yml' % lang) try: theme_cfg = { 'name': None, 'custom_dir': 'mkdocs-material-theme', 'language': lang, 'feature': { 'tabs': False }, 'palette': { 'primary': 'white', 'accent': 'white' }, 'font': False, 'logo': 'images/logo.svg', 'favicon': 'assets/images/favicon.ico', 'include_search_page': False, 'search_index_only': True, 'static_templates': ['404.html'], 'extra': { 'single_page': False, 'opposite_lang': 'en' if lang == 'ru' else 'ru', 'search': { 'language': 'en' if lang == 'en' else 'en, %s' % lang } } } cfg = config.load_config( config_file=config_path, site_name='ClickHouse Documentation' if lang == 'en' else 'Документация ClickHouse', docs_dir=os.path.join(args.docs_dir, lang), site_dir=os.path.join(args.output_dir, lang), strict=True, theme=theme_cfg, copyright='©2016–2018 Yandex LLC', use_directory_urls=True, repo_name='yandex/ClickHouse', repo_url='https://github.com/yandex/ClickHouse/', edit_uri='edit/master/docs/%s' % lang, extra_css=['assets/stylesheets/custom.css'], markdown_extensions=['admonition', 'attr_list', 'codehilite']) mkdocs_build.build(cfg) if not args.skip_single_page: build_single_page_version(lang, args, cfg) except exceptions.ConfigurationError as e: raise SystemExit('\n' + str(e))
def build_command(clean, config_file, strict, theme, site_dir): """Build the MkDocs documentation""" try: build.build(load_config( config_file=config_file, strict=strict, theme=theme, site_dir=site_dir ), clean_site_dir=clean) except exceptions.ConfigurationError as e: # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def _mkdocsBuild(self, **options): # register project with pkg_resources so mkdocs picks it up as a plugin (before mkdocs module import!) self._registerPluginDist() from mkdocs.commands.build import build from mkdocs.config import load_config with warnings.catch_warnings(): # ignore deprecation warnings within mkdocs warnings.filterwarnings('ignore', category=DeprecationWarning) build(load_config(**options))
def builder(): log.info("Building documentation...") config = load_config(config_file=config_file, dev_addr=dev_addr, strict=strict, theme=theme, theme_dir=theme_dir) config['site_dir'] = tempdir live_server = livereload in ['dirty', 'livereload'] dirty = livereload == 'dirty' build(config, live_server=live_server, dirty=dirty) return config
def gh_deploy_command(config_file, clean, message, remote_branch, remote_name, force): """Deploy your documentation to GitHub Pages""" try: cfg = config.load_config(config_file=config_file, remote_branch=remote_branch, remote_name=remote_name) build.build(cfg, dirty=not clean) gh_deploy.gh_deploy(cfg, message=message, force=force) except exceptions.ConfigurationError as e: # pragma: no cover # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def gh_deploy_command(config_file, clean, message, remote_branch, remote_name, force): """Deploy your documentation to GitHub Pages""" try: cfg = config.load_config( config_file=config_file, remote_branch=remote_branch, remote_name=remote_name ) build.build(cfg, dirty=not clean) gh_deploy.gh_deploy(cfg, message=message, force=force) except exceptions.ConfigurationError as e: # pragma: no cover # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def gh_deploy_command(config_file, clean, message, remote_branch, remote_name): """Deploy your documentation to GitHub Pages""" try: config = load_config( config_file=config_file, remote_branch=remote_branch, remote_name=remote_name ) build.build(config, clean_site_dir=clean) gh_deploy.gh_deploy(config, message=message) except exceptions.ConfigurationError as e: # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def build_single_page_version(lang, args, cfg): logging.info('Building single page version for ' + lang) with autoremoved_file(os.path.join(args.docs_dir, lang, 'single.md')) as single_md: concatenate(lang, args.docs_dir, single_md) with temp_dir() as site_temp: with temp_dir() as docs_temp: docs_temp_lang = os.path.join(docs_temp, lang) shutil.copytree(os.path.join(args.docs_dir, lang), docs_temp_lang) for root, _, filenames in os.walk(docs_temp_lang): for filename in filenames: if filename != 'single.md' and filename.endswith( '.md'): os.unlink(os.path.join(root, filename)) cfg.load_dict({ 'docs_dir': docs_temp_lang, 'site_dir': site_temp, 'extra': { 'single_page': True }, 'nav': [{ cfg.data.get('site_name'): 'single.md' }] }) mkdocs_build.build(cfg) single_page_output_path = os.path.join(args.docs_dir, args.output_dir, lang, 'single') if os.path.exists(single_page_output_path): shutil.rmtree(single_page_output_path) shutil.copytree(os.path.join(site_temp, 'single'), single_page_output_path) single_page_index_html = os.path.abspath( os.path.join(single_page_output_path, 'index.html')) single_page_pdf = single_page_index_html.replace( 'index.html', 'clickhouse_%s.pdf' % lang) create_pdf_command = [ 'wkhtmltopdf', '--print-media-type', single_page_index_html, single_page_pdf ] logging.debug(' '.join(create_pdf_command)) subprocess.check_call(' '.join(create_pdf_command), shell=True)
def test_sphinx_load_mkdocstrings_inventory_file(): """Perform the 'live' inventory load test on mkdocstrings own inventory.""" mkdocs_config = load_config() build(mkdocs_config) own_inv = mkdocs_config["plugins"]["mkdocstrings"].handlers.inventory with open("site/objects.inv", "rb") as fp: sphinx_inv = sphinx.InventoryFile.load(fp, "", join) sphinx_inv_length = sum(len(sphinx_inv[key]) for key in sphinx_inv) assert sphinx_inv_length == len(own_inv.values()) for item in own_inv.values(): assert item.name in sphinx_inv[f"{item.domain}:{item.role}"]
def builder(): log.info("Building documentation...") config = load_config( config_file=config_file, dev_addr=dev_addr, strict=strict, theme=theme, theme_dir=theme_dir ) config['site_dir'] = tempdir live_server = livereload in ['dirty', 'livereload'] dirty = livereload == 'dirty' build(config, live_server=live_server, dirty=dirty) return config
def builder(): log.info("Building documentation...") config = load_config(config_file=config_file, dev_addr=dev_addr, strict=strict, theme=theme, theme_dir=theme_dir) # Override a few config settings after validation config['site_dir'] = tempdir config['site_url'] = 'http://{0}/'.format(config['dev_addr']) live_server = livereload in ['dirty', 'livereload'] dirty = livereload == 'dirty' build(config, live_server=live_server, dirty=dirty) return config
def test_copy_theme_files(self, site_dir, docs_dir): cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only theme media are copied, not templates or Python files. self.assertPathIsFile(site_dir, 'index.html') self.assertPathIsFile(site_dir, '404.html') self.assertPathIsDir(site_dir, 'js') self.assertPathIsDir(site_dir, 'css') self.assertPathIsDir(site_dir, 'img') self.assertPathIsDir(site_dir, 'fonts') self.assertPathNotExists(site_dir, '__init__.py') self.assertPathNotExists(site_dir, '__init__.pyc') self.assertPathNotExists(site_dir, 'base.html') self.assertPathNotExists(site_dir, 'content.html') self.assertPathNotExists(site_dir, 'main.html')
def builder(): log.info("Building documentation...") config = load_config( config_file=config_file, dev_addr=dev_addr, strict=strict, theme=theme, theme_dir=theme_dir, site_dir=site_dir ) # Override a few config settings after validation config['site_url'] = 'http://{0}/'.format(config['dev_addr']) live_server = livereload in ['dirty', 'livereload'] dirty = livereload == 'dirty' build(config, live_server=live_server, dirty=dirty) return config
def build_command(clean, config_file, strict, theme, theme_dir, site_dir): """Build the MkDocs documentation""" # Don't override config value if user did not specify --strict flag # Conveniently, load_config drops None values strict = strict or None try: build.build(config.load_config(config_file=config_file, strict=strict, theme=theme, theme_dir=theme_dir, site_dir=site_dir), dirty=not clean) except exceptions.ConfigurationError as e: # pragma: no cover # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def build_command(clean, config_file, strict, theme, theme_dir, site_dir): """Build the MkDocs documentation""" # Don't override config value if user did not specify --strict flag # Conveniently, load_config drops None values strict = strict or None try: build.build(config.load_config( config_file=config_file, strict=strict, theme=theme, theme_dir=theme_dir, site_dir=site_dir ), dirty=not clean) except exceptions.ConfigurationError as e: # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def build_single_page_version(lang, args, cfg): logging.info('Building single page version for ' + lang) with autoremoved_file(os.path.join(args.docs_dir, lang, 'single.md')) as single_md: concatenate(lang, args.docs_dir, single_md) with temp_dir() as site_temp: with temp_dir() as docs_temp: docs_temp_lang = os.path.join(docs_temp, lang) shutil.copytree(os.path.join(args.docs_dir, lang), docs_temp_lang) for root, _, filenames in os.walk(docs_temp_lang): for filename in filenames: if filename != 'single.md' and filename.endswith('.md'): os.unlink(os.path.join(root, filename)) cfg.load_dict({ 'docs_dir': docs_temp_lang, 'site_dir': site_temp, 'extra': { 'single_page': True }, 'nav': [ {cfg.data.get('site_name'): 'single.md'} ] }) mkdocs_build.build(cfg) single_page_output_path = os.path.join(args.docs_dir, args.output_dir, lang, 'single') if os.path.exists(single_page_output_path): shutil.rmtree(single_page_output_path) shutil.copytree( os.path.join(site_temp, 'single'), single_page_output_path ) single_page_index_html = os.path.abspath(os.path.join(single_page_output_path, 'index.html')) single_page_pdf = single_page_index_html.replace('index.html', 'clickhouse_%s.pdf' % lang) create_pdf_command = ['wkhtmltopdf', '--print-media-type', single_page_index_html, single_page_pdf] logging.debug(' '.join(create_pdf_command)) subprocess.check_call(' '.join(create_pdf_command), shell=True)
def json_command(clean, config_file, strict, site_dir): """Build the MkDocs documentation to JSON files Rather than building your documentation to HTML pages, this outputs each page in a simple JSON format. This command is useful if you want to index your documentation in an external search engine. """ log.warning("The json command is deprecated and will be removed in a future " "MkDocs release. For details on updating: " "http://www.mkdocs.org/about/release-notes/") try: build.build(load_config( config_file=config_file, strict=strict, site_dir=site_dir ), dump_json=True, clean_site_dir=clean) except exceptions.ConfigurationError as e: # Avoid ugly, unhelpful traceback raise SystemExit('\n' + str(e))
def test_copying_media(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create a non-empty markdown file, image, dot file and dot directory. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write(dedent(""" page_title: custom title # Heading 1 This is some text. # Heading 2 And some more text. """)) f.close() open(os.path.join(docs_dir, 'img.jpg'), 'w').close() open(os.path.join(docs_dir, '.hidden'), 'w').close() os.mkdir(os.path.join(docs_dir, '.git')) open(os.path.join(docs_dir, '.git/hidden'), 'w').close() cfg = load_config({ 'docs_dir': docs_dir, 'site_dir': site_dir }) build.build(cfg) # Verify only the markdown (coverted to html) and the image are copied. self.assertTrue(os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isfile(os.path.join(site_dir, 'img.jpg'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '.hidden'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '.git/hidden'))) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def build_for_lang(lang, args): logging.info('Building %s docs' % lang) config_path = os.path.join(args.docs_dir, 'toc_%s.yml' % lang) try: theme_cfg = { 'name': 'mkdocs', 'custom_dir': os.path.join(os.path.dirname(__file__), args.theme_dir), 'language': lang, 'direction': 'rtl' if lang == 'fa' else 'ltr', 'feature': { 'tabs': False }, 'palette': { 'primary': 'white', 'accent': 'white' }, 'font': False, 'logo': 'images/logo.svg', 'favicon': 'assets/images/favicon.ico', 'include_search_page': False, 'search_index_only': True, 'static_templates': ['404.html'], 'extra': { 'single_page': False, 'now': int(time.mktime(datetime.datetime.now().timetuple())) # TODO better way to avoid caching } } site_names = { 'en': 'ClickHouse Documentation', 'ru': 'Документация ClickHouse', 'zh': 'ClickHouse文档', 'fa': 'مستندات ClickHouse' } cfg = config.load_config( config_file=config_path, site_name=site_names.get(lang, site_names['en']), site_url='https://clickhouse.yandex/docs/%s/' % lang, docs_dir=os.path.join(args.docs_dir, lang), site_dir=os.path.join(args.output_dir, lang), strict=True, theme=theme_cfg, copyright='©2016–2018 Yandex LLC', use_directory_urls=True, repo_name='yandex/ClickHouse', repo_url='https://github.com/yandex/ClickHouse/', edit_uri='edit/master/docs/%s' % lang, extra_css=['assets/stylesheets/custom.css'], markdown_extensions=[ 'clickhouse', 'admonition', 'attr_list', 'codehilite', 'extra' ], plugins=[{ 'search': { 'lang': ['en', 'ru'] if lang == 'ru' else ['en'] } }], extra={ 'search': { 'language': 'en,ru' if lang == 'ru' else 'en' } } ) mkdocs_build.build(cfg) if not args.skip_single_page: build_single_page_version(lang, args, cfg) except exceptions.ConfigurationError as e: raise SystemExit('\n' + str(e))
def build_single_page_version(lang, args, cfg): logging.info('Building single page version for ' + lang) os.environ['SINGLE_PAGE'] = '1' with util.autoremoved_file(os.path.join(args.docs_dir, lang, 'single.md')) as single_md: concatenate(lang, args.docs_dir, single_md) with util.temp_dir() as site_temp: with util.temp_dir() as docs_temp: docs_src_lang = os.path.join(args.docs_dir, lang) docs_temp_lang = os.path.join(docs_temp, lang) shutil.copytree(docs_src_lang, docs_temp_lang) for root, _, filenames in os.walk(docs_temp_lang): for filename in filenames: if filename != 'single.md' and filename.endswith('.md'): os.unlink(os.path.join(root, filename)) cfg.load_dict({ 'docs_dir': docs_temp_lang, 'site_dir': site_temp, 'extra': { 'single_page': True }, 'nav': [ {cfg.data.get('site_name'): 'single.md'} ] }) mkdocs_build.build(cfg) if args.version_prefix: single_page_output_path = os.path.join(args.docs_dir, args.docs_output_dir, args.version_prefix, lang, 'single') else: single_page_output_path = os.path.join(args.docs_dir, args.docs_output_dir, lang, 'single') if os.path.exists(single_page_output_path): shutil.rmtree(single_page_output_path) shutil.copytree( os.path.join(site_temp, 'single'), single_page_output_path ) if not args.skip_pdf: single_page_index_html = os.path.abspath(os.path.join(single_page_output_path, 'index.html')) single_page_pdf = single_page_index_html.replace('index.html', 'clickhouse_%s.pdf' % lang) create_pdf_command = ['wkhtmltopdf', '--print-media-type', single_page_index_html, single_page_pdf] logging.debug(' '.join(create_pdf_command)) subprocess.check_call(' '.join(create_pdf_command), shell=True) with util.temp_dir() as test_dir: cfg.load_dict({ 'docs_dir': docs_temp_lang, 'site_dir': test_dir, 'extra': { 'single_page': False }, 'nav': [ {cfg.data.get('site_name'): 'single.md'} ] }) mkdocs_build.build(cfg) if not args.version_prefix: # maybe enable in future test.test_single_page(os.path.join(test_dir, 'single', 'index.html'), lang) if args.save_raw_single_page: shutil.copytree(test_dir, args.save_raw_single_page)