示例#1
0
def path_to_url(url, nav):
    scheme, netloc, path, query, query, fragment = urlparse(url)

    if scheme or netloc or not path:
        # Ignore URLs unless they are a relative link to a markdown file.
        return url

    if nav and not utils.is_markdown_file(path):
        path = utils.create_media_urls(nav, [path])[0]
    elif nav:
        # If the site navigation has been provided, then validate
        # the internal hyperlink, making sure the target actually exists.
        target_file = nav.file_context.make_absolute(path)
        if target_file not in nav.source_files:
            source_file = nav.file_context.current_file
            msg = (
                'The page "%s" contained a hyperlink to "%s" which '
                'is not listed in the "pages" configuration.'
            )
            assert False, msg % (source_file, target_file)
        path = utils.get_url_path(target_file, nav.use_directory_urls)
        path = nav.url_context.make_relative(path)
    else:
        path = utils.get_url_path(path).lstrip('/')

    # Convert the .md hyperlink to a relative hyperlink to the HTML page.
    url = urlunparse((scheme, netloc, path, query, query, fragment))
    return url
示例#2
0
    def __call__(self, match):
        url = match.groups()[0]
        scheme, netloc, path, query, query, fragment = urlparse(url)

        if (scheme or netloc or not utils.is_markdown_file(path)):
            # Ignore URLs unless they are a relative link to a markdown file.
            return 'a href="%s"' % url

        if self.nav:
            # If the site navigation has been provided, then validate
            # the internal hyperlink, making sure the target actually exists.
            target_file = self.nav.file_context.make_absolute(path)
            if target_file not in self.nav.source_files:
                source_file = self.nav.file_context.current_file
                msg = (
                    'The page "%s" contained a hyperlink to "%s" which '
                    'is not listed in the "pages" configuration.'
                )
                assert False, msg % (source_file, target_file)
            path = utils.get_url_path(target_file)
            path = self.nav.url_context.make_relative(path)
        else:
            path = utils.get_url_path(path).lstrip('/')

        # Convert the .md hyperlink to a relative hyperlink to the HTML page.
        url = urlunparse((scheme, netloc, path, query, query, fragment))
        return 'a href="%s"' % url
示例#3
0
def path_to_url(url, nav, strict):
    scheme, netloc, path, query, query, fragment = urlparse(url)

    if scheme or netloc or not path:
        # Ignore URLs unless they are a relative link to a markdown file.
        return url

    if nav and not utils.is_markdown_file(path):
        path = utils.create_relative_media_url(nav, path)
    elif nav:
        # If the site navigation has been provided, then validate
        # the internal hyperlink, making sure the target actually exists.
        target_file = nav.file_context.make_absolute(path)
        if target_file not in nav.source_files:
            source_file = nav.file_context.current_file
            msg = (
                'The page "%s" contained a hyperlink to "%s" which '
                'is not listed in the "pages" configuration.'
            ) % (source_file, target_file)

            # In strict mode raise an error at this point.
            if strict:
                raise MarkdownNotFound(msg)
            # Otherwise, when strict mode isn't enabled, print out a warning
            # to the user and leave the URL as it is.
            #print(msg)
            #return url
        path = utils.get_url_path(target_file, nav.use_directory_urls)
        path = nav.url_context.make_relative(path)
    else:
        path = utils.get_url_path(path).lstrip('/')

    # Convert the .md hyperlink to a relative hyperlink to the HTML page.
    url = urlunparse((scheme, netloc, path, query, query, fragment))
    return url
示例#4
0
文件: build.py 项目: the-jxc/mkdocs
    def __call__(self, match):
        url = match.groups()[0]
        scheme, netloc, path, query, query, fragment = urlparse.urlparse(url)

        if (scheme or netloc or not utils.is_markdown_file(path)):
            # Ignore URLs unless they are a relative link to a markdown file.
            return 'a href="%s"' % url

        if self.nav:
            # If the site navigation has been provided, then validate
            # the internal hyperlink, making sure the target actually exists.
            target_file = self.nav.file_context.make_absolute(path)
            if target_file not in self.nav.source_files:
                source_file = self.nav.file_context.current_file
                msg = (
                    'The page "%s" contained a hyperlink to "%s" which '
                    'is not listed in the "pages" configuration.'
                )
                assert False, msg % (source_file, target_file)
            path = utils.get_url_path(target_file, self.url_format)
            path = self.nav.url_context.make_relative(path)
        else:
            path = utils.get_url_path(path, self.url_format).lstrip('/')

        # Convert the .md hyperlink to a relative hyperlink to the HTML page.
        url = urlparse.urlunparse((scheme, netloc, path, query, query, fragment))
        return 'a href="%s"' % url
示例#5
0
def path_to_url(url, nav):
    scheme, netloc, path, query, query, fragment = urlparse(url)

    if scheme or netloc or not path:
        # Ignore URLs unless they are a relative link to a markdown file.
        return url

    if nav and not utils.is_markdown_file(path):
        path = utils.create_media_urls(nav, [path])[0]
    elif nav:
        # If the site navigation has been provided, then validate
        # the internal hyperlink, making sure the target actually exists.
        target_file = nav.file_context.make_absolute(path)
        if target_file not in nav.source_files:
            source_file = nav.file_context.current_file
            msg = ('The page "%s" contained a hyperlink to "%s" which '
                   'is not listed in the "pages" configuration.')
            assert False, msg % (source_file, target_file)
        path = utils.get_url_path(target_file, nav.use_directory_urls)
        path = nav.url_context.make_relative(path)
    else:
        path = utils.get_url_path(path).lstrip('/')

    # Convert the .md hyperlink to a relative hyperlink to the HTML page.
    url = urlunparse((scheme, netloc, path, query, query, fragment))
    return url
示例#6
0
 def test_is_markdown_file(self):
     expected_results = {
         'index.md': True,
         'index.MARKDOWN': True,
         'index.txt': False,
         'indexmd': False
     }
     for path, expected_result in expected_results.items():
         is_markdown = utils.is_markdown_file(path)
         self.assertEqual(is_markdown, expected_result)
示例#7
0
 def test_is_markdown_file(self):
     expected_results = {
         'index.md': True,
         'index.MARKDOWN': True,
         'index.txt': False,
         'indexmd': False
     }
     for path, expected_result in expected_results.items():
         is_markdown = utils.is_markdown_file(path)
         self.assertEqual(is_markdown, expected_result)
示例#8
0
    def on_files(self, files, config, **kwargs):
        self.redirects = self.config.get('redirect_maps', {})

        # SHIM! Produce a warning if the old root-level 'redirects' config is present
        if config.get('redirects'):
            log.warn("The root-level 'redirects:' setting is not valid and has been changed in version 1.0! "
                     "The plugin-level 'redirect-map' must be used instead. See https://git.io/fjdBN")

        # Validate user-provided redirect "old files"
        for page_old in self.redirects.keys():
            if not utils.is_markdown_file(page_old):
                log.warn("redirects plugin: '%s' is not a valid markdown file!", page_old)

        # Build a dict of known document pages to validate against later
        self.doc_pages = {}
        for page in files.documentation_pages():  # object type: mkdocs.structure.files.File
            self.doc_pages[page.src_path.replace('\\', '/')] = page
示例#9
0
def path_to_url(url, nav, strict):

    scheme, netloc, path, params, query, fragment = (utils.urlparse(url))

    if scheme or netloc or not path or AMP_SUBSTITUTE in url:
        # Ignore URLs unless they are a relative link to a markdown file.
        # AMP_SUBSTITUTE is used internally by Markdown only for email,which is
        # not a relative link. As urlparse errors on them, skip explicitly
        return url

    if nav and not utils.is_markdown_file(path):
        path = utils.create_relative_media_url(nav, path)
    elif nav:
        # If the site navigation has been provided, then validate
        # the internal hyperlink, making sure the target actually exists.
        target_file = nav.file_context.make_absolute(path)

        if target_file.startswith(os.path.sep):
            target_file = target_file[1:]

        if target_file not in nav.source_files:
            source_file = nav.file_context.current_file
            msg = ('The page "%s" contained a hyperlink to "%s" which '
                   'is not listed in the "pages" configuration.') % (
                       source_file, target_file)

            # In strict mode raise an error at this point.
            if strict:
                raise MarkdownNotFound(msg)
            # Otherwise, when strict mode isn't enabled, log a warning
            # to the user and leave the URL as it is.

            # suppress the Warning
            # log.warning(msg)
            # return url
        path = utils.get_url_path(target_file, nav.use_directory_urls)
        path = nav.url_context.make_relative(path)
    else:
        path = utils.get_url_path(path).lstrip('/')

    # Convert the .md hyperlink to a relative hyperlink to the HTML page.
    fragments = (scheme, netloc, path, params, query, fragment)
    url = utils.urlunparse(fragments)
    return url
示例#10
0
def path_to_url(url, nav, strict):

    scheme, netloc, path, params, query, fragment = (
        utils.urlparse(url))

    if scheme or netloc or not path or AMP_SUBSTITUTE in url:
        # Ignore URLs unless they are a relative link to a markdown file.
        # AMP_SUBSTITUTE is used internally by Markdown only for email,which is
        # not a relative link. As urlparse errors on them, skip explicitly
        return url

    if nav and not utils.is_markdown_file(path):
        path = utils.create_relative_media_url(nav, path)
    elif nav:
        # If the site navigation has been provided, then validate
        # the internal hyperlink, making sure the target actually exists.
        target_file = nav.file_context.make_absolute(path)

        if target_file.startswith(os.path.sep):
            target_file = target_file[1:]

        if target_file not in nav.source_files:
            source_file = nav.file_context.current_file
            msg = (
                'The page "%s" contained a hyperlink to "%s" which '
                'is not listed in the "pages" configuration.'
            ) % (source_file, target_file)

            # In strict mode raise an error at this point.
            if strict:
                raise MarkdownNotFound(msg)
            # Otherwise, when strict mode isn't enabled, log a warning
            # to the user and leave the URL as it is.
            log.warning(msg)
            return url
        path = utils.get_url_path(target_file, nav.use_directory_urls)
        path = nav.url_context.make_relative(path)
    else:
        path = utils.get_url_path(path).lstrip('/')

    # Convert the .md hyperlink to a relative hyperlink to the HTML page.
    fragments = (scheme, netloc, path, params, query, fragment)
    url = utils.urlunparse(fragments)
    return url
示例#11
0
文件: config.py 项目: jpadilla/mkdocs
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()
    config.update(user_config)

    assert config['site_name'], "Config must contain 'site_name' setting."

    if not config['pages']:
        # If not specified, then the 'pages' config simply includes all
        # markdown files in the docs dir, without generating any header items
        # for them.
        pages = []
        for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):
            for filename in sorted(filenames):
                if not utils.is_markdown_file(filename):
                    continue

                fullpath = os.path.join(dirpath, filename)
                relpath = os.path.relpath(fullpath, config['docs_dir'])

                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == 'index':
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)

        config['pages'] = pages

    if not config['theme_dir']:
        package_dir = os.path.dirname(__file__)
        config['theme_dir'] = os.path.join(package_dir, 'themes', config['theme'])

    if config['repo_url'] and not config['repo_name']:
        repo_host = urlparse.urlparse(config['repo_url']).netloc.lower()
        if repo_host == 'github.com':
            config['repo_name'] = 'GitHub'
        elif repo_host == 'bitbucket.com':
            config['repo_name'] = 'Bitbucket'
        else:
            config['repo_name'] = repo_host.split('.')[0].title()

    return config
示例#12
0
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()

    theme_in_config = 'theme' in user_config

    config.update(user_config)

    if not config['site_name']:
        raise ConfigurationError("Config must contain 'site_name' setting.")

    # Validate that the docs_dir and site_dir don't contain the
    # other as this will lead to copying back and forth on each
    # and eventually make a deep nested mess.
    abs_site_dir = os.path.abspath(config['site_dir'])
    abs_docs_dir = os.path.abspath(config['docs_dir'])
    if abs_docs_dir.startswith(abs_site_dir):
        raise ConfigurationError(
            "The 'docs_dir' can't be within the 'site_dir'.")
    elif abs_site_dir.startswith(abs_docs_dir):
        raise ConfigurationError(
            "The 'site_dir' can't be within the 'docs_dir'.")

    # If not specified, then the 'pages' config simply includes all
    # markdown files in the docs dir, without generating any header items
    # for them.
    pages = []
    extra_css = []
    extra_javascript = []
    for (dirpath, _, filenames) in os.walk(config['docs_dir']):
        for filename in sorted(filenames):
            fullpath = os.path.join(dirpath, filename)
            relpath = os.path.normpath(
                os.path.relpath(fullpath, config['docs_dir']))

            if utils.is_markdown_file(filename):
                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == 'index':
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)
            elif utils.is_css_file(filename):
                extra_css.append(relpath)
            elif utils.is_javascript_file(filename):
                extra_javascript.append(relpath)

    if config['pages'] is None:
        config['pages'] = pages
    else:
        """
        If the user has provided the pages config, then iterate through and
        check for Windows style paths. If they are found, output a warning
        and continue.
        """
        for page_config in config['pages']:
            if isinstance(page_config, str):
                path = page_config
            elif len(page_config) in (1, 2, 3):
                path = page_config[0]

            if ntpath.sep in path:
                log.warning("The config path contains Windows style paths (\\ "
                            " backward slash) and will have comparability "
                            "issues if it is used on another platform.")
                break

    if config['extra_css'] is None:
        config['extra_css'] = extra_css

    if config['extra_javascript'] is None:
        config['extra_javascript'] = extra_javascript

    package_dir = os.path.dirname(__file__)
    theme_dir = [
        os.path.join(package_dir, 'themes', config['theme']),
    ]

    if config['theme_dir'] is not None:
        # If the user has given us a custom theme but not a
        # builtin theme name then we don't want to merge them.
        if not theme_in_config:
            theme_dir = []
        theme_dir.insert(0, config['theme_dir'])

    config['theme_dir'] = theme_dir

    # Add the search assets to the theme_dir, this means that
    # they will then we copied into the output directory but can
    # be overwritten by themes if needed.
    config['theme_dir'].append(os.path.join(package_dir, 'assets', 'search'))

    if config['repo_url'] is not None and config['repo_name'] is None:
        repo_host = urlparse(config['repo_url']).netloc.lower()
        if repo_host == 'github.com':
            config['repo_name'] = 'GitHub'
        elif repo_host == 'bitbucket.org':
            config['repo_name'] = 'Bitbucket'
        else:
            config['repo_name'] = repo_host.split('.')[0].title()

    if config['include_next_prev'] is None:
        config['include_next_prev'] = len(config['pages']) > 1

    if config['include_nav'] is None:
        config['include_nav'] = len(config['pages']) > 1

    # To Do:

    # The docs dir must exist.
    # The theme dir must exist.
    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
    # A homepage 'index' must exist.
    # The theme 'base.html' file must exist.
    # Cannot set repo_name without setting repo_url.
    # Cannot set 'include_next_prev: true' when only one page exists.
    # Cannot set 'include_nav: true' when only one page exists.
    # Error if any config keys provided that are not in the DEFAULT_CONFIG.

    return config
示例#13
0
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()

    theme_in_config = 'theme' in user_config

    config.update(user_config)

    if not config['site_name']:
        raise ConfigurationError("Config must contain 'site_name' setting.")

    # Validate that the docs_dir and site_dir don't contain the
    # other as this will lead to copying back and forth on each
    # and eventually make a deep nested mess.
    abs_site_dir = os.path.abspath(config['site_dir'])
    abs_docs_dir = os.path.abspath(config['docs_dir'])
    if abs_docs_dir.startswith(abs_site_dir):
        raise ConfigurationError(
            "The 'docs_dir' can't be within the 'site_dir'.")
    elif abs_site_dir.startswith(abs_docs_dir):
        raise ConfigurationError(
            "The 'site_dir' can't be within the 'docs_dir'.")

    # If not specified, then the 'pages' config simply includes all
    # markdown files in the docs dir, without generating any header items
    # for them.
    pages = []
    extra_css = []
    extra_javascript = []
    extra_templates = []
    for (dirpath, _, filenames) in os.walk(config['docs_dir']):
        for filename in sorted(filenames):
            fullpath = os.path.join(dirpath, filename)
            relpath = os.path.normpath(os.path.relpath(fullpath, config['docs_dir']))

            if utils.is_markdown_file(filename):
                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == 'index':
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)
            elif utils.is_css_file(filename):
                extra_css.append(relpath)
            elif utils.is_javascript_file(filename):
                extra_javascript.append(relpath)
            elif utils.is_template_file(filename):
                extra_templates.append(filename)

    if config['pages'] is None:
        config['pages'] = pages
    else:
        """
        If the user has provided the pages config, then iterate through and
        check for Windows style paths. If they are found, output a warning
        and continue.
        """
        for page_config in config['pages']:
            if isinstance(page_config, str):
                path = page_config
            elif len(page_config) in (1, 2, 3):
                path = page_config[0]

            if ntpath.sep in path:
                log.warning("The config path contains Windows style paths (\\ "
                            " backward slash) and will have comparability "
                            "issues if it is used on another platform.")
                break

    if config['extra_css'] is None:
        config['extra_css'] = extra_css

    if config['extra_javascript'] is None:
        config['extra_javascript'] = extra_javascript

    if config['extra_templates'] is None:
        config['extra_templates'] = extra_templates

    package_dir = os.path.dirname(__file__)
    theme_dir = [os.path.join(package_dir, 'themes', config['theme']), ]
    config['mkdocs_templates'] = os.path.join(package_dir, 'templates')

    if config['theme_dir'] is not None:
        # If the user has given us a custom theme but not a
        # builtin theme name then we don't want to merge them.
        if not theme_in_config:
            theme_dir = []
        theme_dir.insert(0, config['theme_dir'])

    config['theme_dir'] = theme_dir

    # Add the search assets to the theme_dir, this means that
    # they will then we copied into the output directory but can
    # be overwritten by themes if needed.
    config['theme_dir'].append(os.path.join(package_dir, 'assets', 'search'))

    if config['repo_url'] is not None and config['repo_name'] is None:
        repo_host = urlparse(config['repo_url']).netloc.lower()
        if repo_host == 'github.com':
            config['repo_name'] = 'GitHub'
        elif repo_host == 'bitbucket.org':
            config['repo_name'] = 'Bitbucket'
        else:
            config['repo_name'] = repo_host.split('.')[0].title()

    if config['include_next_prev'] is None:
        config['include_next_prev'] = len(config['pages']) > 1

    if config['include_nav'] is None:
        config['include_nav'] = len(config['pages']) > 1

    # To Do:

    # The docs dir must exist.
    # The theme dir must exist.
    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
    # A homepage 'index' must exist.
    # The theme 'base.html' file must exist.
    # Cannot set repo_name without setting repo_url.
    # Cannot set 'include_next_prev: true' when only one page exists.
    # Cannot set 'include_nav: true' when only one page exists.
    # Error if any config keys provided that are not in the DEFAULT_CONFIG.

    return config
示例#14
0
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()

    theme_in_config = 'theme' in user_config

    config.update(user_config)

    if not config['site_name']:
        raise ConfigurationError("Config must contain 'site_name' setting.")

    # Validate that the docs_dir and site_dir don't contain the
    # other as this will lead to copying back and forth on each
    # and eventually make a deep nested mess.
    abs_site_dir = os.path.abspath(config['site_dir'])
    abs_docs_dir = os.path.abspath(config['docs_dir'])
    if abs_docs_dir.startswith(abs_site_dir):
        raise ConfigurationError(
            "The 'docs_dir' can't be within the 'site_dir'.")
    elif abs_site_dir.startswith(abs_docs_dir):
        raise ConfigurationError(
            "The 'site_dir' can't be within the 'docs_dir'.")

    # If not specified, then the 'pages' config simply includes all
    # markdown files in the docs dir, without generating any header items
    # for them.
    pages = []
    extra_css = []
    extra_javascript = []
    for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):
        for filename in sorted(filenames):
            fullpath = os.path.join(dirpath, filename)
            relpath = os.path.relpath(fullpath, config['docs_dir'])

            if utils.is_markdown_file(filename):
                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == 'index':
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)
            elif utils.is_css_file(filename):
                extra_css.append(relpath)
            elif utils.is_javascript_file(filename):
                extra_javascript.append(relpath)

    if config['pages'] is None:
        config['pages'] = pages

    if config['extra_css'] is None:
        config['extra_css'] = extra_css

    if config['extra_javascript'] is None:
        config['extra_javascript'] = extra_javascript

    package_dir = os.path.dirname(__file__)
    theme_dir = [os.path.join(package_dir, 'themes', config['theme'])]

    if config['theme_dir'] is not None:
        # If the user has given us a custom theme but not a
        # builtin theme name then we don't want to merge them.
        if not theme_in_config:
            theme_dir = []
        theme_dir.insert(0, config['theme_dir'])

    config['theme_dir'] = theme_dir

    if config['repo_url'] is not None and config['repo_name'] is None:
        repo_host = urlparse(config['repo_url']).netloc.lower()
        if repo_host == 'github.com':
            config['repo_name'] = 'GitHub'
        elif repo_host == 'bitbucket.org':
            config['repo_name'] = 'Bitbucket'
        else:
            config['repo_name'] = repo_host.split('.')[0].title()

    if config['include_next_prev'] is None:
        config['include_next_prev'] = len(config['pages']) > 1

    if config['include_nav'] is None:
        config['include_nav'] = len(config['pages']) > 1

    # To Do:

    # The docs dir must exist.
    # The theme dir must exist.
    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
    # A homepage 'index' must exist.
    # The theme 'base.html' file must exist.
    # Cannot set repo_name without setting repo_url.
    # Cannot set 'include_next_prev: true' when only one page exists.
    # Cannot set 'include_nav: true' when only one page exists.
    # Error if any config keys provided that are not in the DEFAULT_CONFIG.

    return config
示例#15
0
文件: config.py 项目: lu-chi/mkdocs
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()
    config.update(user_config)

    assert config['site_name'], "Config must contain 'site_name' setting."

    # If not specified, then the 'pages' config simply includes all
    # markdown files in the docs dir, without generating any header items
    # for them.
    pages = []
    extra_css = []
    extra_javascript = []
    for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):
        for filename in sorted(filenames):
            fullpath = os.path.join(dirpath, filename)
            relpath = os.path.relpath(fullpath, config['docs_dir'])

            if utils.is_markdown_file(filename):
                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == 'index':
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)
            elif utils.is_css_file(filename):
                extra_css.append(relpath)
            elif utils.is_javascript_file(filename):
                extra_javascript.append(relpath)

    if config['pages'] is None:
        config['pages'] = pages

    if config['extra_css'] is None:
        config['extra_css'] = extra_css

    if config['extra_javascript'] is None:
        config['extra_javascript'] = extra_javascript

    if config['theme_dir'] is None:
        package_dir = os.path.dirname(__file__)
        config['theme_dir'] = os.path.join(package_dir, 'themes',
                                           config['theme'])

    if config['repo_url'] is not None and config['repo_name'] is None:
        repo_host = urlparse(config['repo_url']).netloc.lower()
        if repo_host == 'github.com':
            config['repo_name'] = 'GitHub'
        elif repo_host == 'bitbucket.com':
            config['repo_name'] = 'Bitbucket'
        else:
            config['repo_name'] = repo_host.split('.')[0].title()

    if config['include_next_prev'] is None:
        config['include_next_prev'] = len(config['pages']) > 1

    if config['include_nav'] is None:
        config['include_nav'] = len(config['pages']) > 1

    # To Do:

    # The docs dir must exist.
    # The theme dir must exist.
    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
    # A homepage 'index' must exist.
    # The theme 'base.html' file must exist.
    # Cannot set repo_name without setting repo_url.
    # Cannot set 'include_next_prev: true' when only one page exists.
    # Cannot set 'include_nav: true' when only one page exists.
    # Error if any config keys provided that are not in the DEFAULT_CONFIG.

    return config
示例#16
0
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()
    config.update(user_config)

    if not config['site_name']:
        sys.stderr.write("Config must contain 'site_name' setting.")
        sys.exit(errno.EINVAL)

    # If not specified, then the 'pages' config simply includes all
    # markdown files in the docs dir, without generating any header items
    # for them.
    pages = []
    extra_css = []
    extra_javascript = []
    for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):
        for filename in sorted(filenames):
            fullpath = os.path.join(dirpath, filename)
            relpath = os.path.relpath(fullpath, config['docs_dir'])

            if utils.is_markdown_file(filename):
                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == 'index':
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)
            elif utils.is_css_file(filename):
                extra_css.append(relpath)
            elif utils.is_javascript_file(filename):
                extra_javascript.append(relpath)

    if config['pages'] is None:
        config['pages'] = pages

    if config['extra_css'] is None:
        config['extra_css'] = extra_css

    if config['extra_javascript'] is None:
        config['extra_javascript'] = extra_javascript

    package_dir = os.path.dirname(__file__)
    theme_dir = [os.path.join(package_dir, 'themes', config['theme'])]

    if config['theme_dir'] is not None:
        theme_dir.insert(0, config['theme_dir'])

    config['theme_dir'] = theme_dir

    if config['repo_url'] is not None and config['repo_name'] is None:
        repo_host = urlparse(config['repo_url']).netloc.lower()
        if repo_host == 'github.com':
            config['repo_name'] = 'GitHub'
        elif repo_host == 'bitbucket.com':
            config['repo_name'] = 'Bitbucket'
        else:
            config['repo_name'] = repo_host.split('.')[0].title()

    if config['include_next_prev'] is None:
        config['include_next_prev'] = len(config['pages']) > 1

    if config['include_nav'] is None:
        config['include_nav'] = len(config['pages']) > 1

    # To Do:

    # The docs dir must exist.
    # The theme dir must exist.
    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
    # A homepage 'index' must exist.
    # The theme 'base.html' file must exist.
    # Cannot set repo_name without setting repo_url.
    # Cannot set 'include_next_prev: true' when only one page exists.
    # Cannot set 'include_nav: true' when only one page exists.
    # Error if any config keys provided that are not in the DEFAULT_CONFIG.

    return config
示例#17
0
文件: build.py 项目: itech001/mkdocs
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()
    })
示例#18
0
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()

    theme_in_config = 'theme' in user_config

    config.update(user_config)

    if not config['site_name']:
        raise ConfigurationError("Config must contain 'site_name' setting.")

    # Validate that the docs_dir and site_dir don't contain the
    # other as this will lead to copying back and forth on each
    # and eventually make a deep nested mess.
    abs_site_dir = os.path.abspath(config['site_dir'])
    abs_docs_dir = os.path.abspath(config['docs_dir'])
    if abs_docs_dir.startswith(abs_site_dir):
        raise ConfigurationError(
            "The 'docs_dir' can't be within the 'site_dir'.")
    elif abs_site_dir.startswith(abs_docs_dir):
        raise ConfigurationError(
            "The 'site_dir' can't be within the 'docs_dir'.")

    # If not specified, then the 'pages' config simply includes all
    # markdown files in the docs dir, without generating any header items
    # for them.
    pages = []
    extra_css = []
    extra_javascript = []
    for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):
        for filename in sorted(filenames):
            fullpath = os.path.join(dirpath, filename)
            relpath = os.path.relpath(fullpath, config['docs_dir'])

            if utils.is_markdown_file(filename):
                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == 'index':
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)
            elif utils.is_css_file(filename):
                extra_css.append(relpath)
            elif utils.is_javascript_file(filename):
                extra_javascript.append(relpath)

    if config['pages'] is None:
        config['pages'] = pages

    if config['extra_css'] is None:
        config['extra_css'] = extra_css

    if config['extra_javascript'] is None:
        config['extra_javascript'] = extra_javascript

    package_dir = os.path.dirname(__file__)
    theme_dir = [os.path.join(package_dir, 'themes', config['theme'])]

    if config['theme_dir'] is not None:
        # If the user has given us a custom theme but not a
        # builtin theme name then we don't want to merge them.
        if not theme_in_config:
            theme_dir = []
        theme_dir.insert(0, config['theme_dir'])

    config['theme_dir'] = theme_dir

    if config['repo_url'] is not None and config['repo_name'] is None:
        repo_host = urlparse(config['repo_url']).netloc.lower()
        if repo_host == 'github.com':
            config['repo_name'] = 'GitHub'
        elif repo_host == 'bitbucket.org':
            config['repo_name'] = 'Bitbucket'
        else:
            config['repo_name'] = repo_host.split('.')[0].title()

    if config['include_next_prev'] is None:
        config['include_next_prev'] = len(config['pages']) > 1

    if config['include_nav'] is None:
        config['include_nav'] = len(config['pages']) > 1

    # To Do:

    # The docs dir must exist.
    # The theme dir must exist.
    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
    # A homepage 'index' must exist.
    # The theme 'base.html' file must exist.
    # Cannot set repo_name without setting repo_url.
    # Cannot set 'include_next_prev: true' when only one page exists.
    # Cannot set 'include_nav: true' when only one page exists.
    # Error if any config keys provided that are not in the DEFAULT_CONFIG.

    return config
示例#19
0
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()})
示例#20
0
def documentation_in_temp_folder(config: dict) -> Iterator[Tuple[str, str]]:
    """Build documentation within a temp folder, returning that folder name before it is deleted."""
    if config["append_directory_to_python_path"] and not config[
            "directory"] in sys.path:
        sys.path.append(config["directory"])

    with tempfile.TemporaryDirectory() as input_dir:
        input_dir = os.path.join(input_dir, "input")
        os.mkdir(input_dir)
        with tempfile.TemporaryDirectory() as temp_output_dir:

            with yaspin(
                    text=
                    "Copying source documentation to temporary compilation directory"
            ) as spinner:
                for root_file in os.listdir(config["directory"]):
                    root_file_absolute = os.path.join(config["directory"],
                                                      root_file)
                    if os.path.isfile(root_file_absolute) and is_markdown_file(
                            root_file_absolute):
                        shutil.copyfile(root_file_absolute,
                                        os.path.join(input_dir, root_file))

                for source_directory in [config["docs_dir"]
                                         ] + config["extra_dirs"]:
                    directory_absolute = os.path.join(config["directory"],
                                                      source_directory)
                    if os.path.isdir(directory_absolute):
                        shutil.copytree(
                            directory_absolute,
                            os.path.join(input_dir, source_directory))

                spinner.ok("Done")

            if "docs_dir" not in config["mkdocs"]:
                config["mkdocs"]["docs_dir"] = input_dir
            if "site_dir" not in config["mkdocs"]:
                config["mkdocs"]["site_dir"] = temp_output_dir
            if "nav" not in config["mkdocs"]:
                nav = config["mkdocs"]["nav"] = []

                root_docs = sorted(glob(os.path.join(input_dir, "*.md")))
                readme_doc = os.path.join(input_dir, "README.md")
                if readme_doc in root_docs:
                    root_docs.remove(readme_doc)
                else:
                    with open(readme_doc, "w") as readme_doc_file:
                        readme_doc_file.write(NO_HOME_PAGE)

                nav.append({"Home": "README.md"})

                nav.extend(_doc(doc, input_dir, config) for doc in root_docs)

                nav.extend(
                    _nested_docs(os.path.join(input_dir, config["docs_dir"]),
                                 input_dir, config))
            else:
                nav = config["mkdocs"]["nav"]
                if nav:
                    index_nav = nav[0]
                    index_page: str = ""
                    if index_nav and isinstance(index_nav, dict):
                        index_page = tuple(index_nav.values())[0]
                    elif isinstance(index_nav, str):  # pragma: no cover
                        index_page = index_nav

                    if index_page:

                        destination_index_page = os.path.join(
                            input_dir, "index.md")
                        if (index_page != "README.md"
                                and index_page != "index.md" and
                                not os.path.exists(destination_index_page)):
                            shutil.copyfile(
                                os.path.join(input_dir, index_page),
                                destination_index_page)

            if config["include_reference_documentation"]:
                with yaspin(
                        text=
                        "Auto generating reference documentation using pdocs"
                ) as spinner:
                    if "output_dir" not in config["pdocs"]:
                        config["pdocs"]["output_dir"] = os.path.join(
                            input_dir, "reference")
                    pdocs(config["pdocs"])
                    reference_docs = _nested_docs(
                        config["pdocs"]["output_dir"], input_dir, config)
                    nav.append({"Reference": reference_docs})  # type: ignore
                    spinner.ok("Done")

            with yaspin(
                    text="Rendering complete website from Markdown using MkDocs"
            ) as spinner:
                mkdocs(config["mkdocs"])
                spinner.ok("Done")

            # remove any settings pointing to the temp dirs
            if config["mkdocs"]["docs_dir"].startswith(input_dir):
                del config["mkdocs"]["docs_dir"]
            if config["mkdocs"]["site_dir"].startswith(temp_output_dir):
                del config["mkdocs"]["site_dir"]
            if config["pdocs"]["output_dir"].startswith(input_dir):
                del config["pdocs"]["output_dir"]
            if config["include_reference_documentation"]:
                nav.pop()

            yield input_dir, temp_output_dir
示例#21
0
 def is_source_code_link(self, path):
     return not is_markdown_file(path) and not is_image_file(path) and path.startswith(self.config['repos_prefix'])
示例#22
0
文件: config.py 项目: haf/mkdocs
def validate_config(user_config):
    config = DEFAULT_CONFIG.copy()
    config.update(user_config)

    assert config["site_name"], "Config must contain 'site_name' setting."

    # If not specified, then the 'pages' config simply includes all
    # markdown files in the docs dir, without generating any header items
    # for them.
    pages = []
    extra_css = []
    extra_javascript = []
    for (dirpath, dirnames, filenames) in os.walk(config["docs_dir"]):
        for filename in sorted(filenames):
            fullpath = os.path.join(dirpath, filename)
            relpath = os.path.relpath(fullpath, config["docs_dir"])

            if utils.is_markdown_file(filename):
                # index pages should always be the first listed page.
                if os.path.splitext(relpath)[0] == "index":
                    pages.insert(0, relpath)
                else:
                    pages.append(relpath)
            elif utils.is_css_file(filename):
                extra_css.append(relpath)
            elif utils.is_javascript_file(filename):
                extra_javascript.append(relpath)

    if config["pages"] is None:
        config["pages"] = pages

    if config["extra_css"] is None:
        config["extra_css"] = extra_css

    if config["extra_javascript"] is None:
        config["extra_javascript"] = extra_javascript

    if config["theme_dir"] is None:
        package_dir = os.path.dirname(__file__)
        config["theme_dir"] = os.path.join(package_dir, "themes", config["theme"])

    if config["repo_url"] is not None and config["repo_name"] is None:
        repo_host = urlparse(config["repo_url"]).netloc.lower()
        if repo_host == "github.com":
            config["repo_name"] = "GitHub"
        elif repo_host == "bitbucket.com":
            config["repo_name"] = "Bitbucket"
        else:
            config["repo_name"] = repo_host.split(".")[0].title()

    if config["include_next_prev"] is None:
        config["include_next_prev"] = len(config["pages"]) > 1

    if config["include_nav"] is None:
        config["include_nav"] = len(config["pages"]) > 1

    # To Do:

    # The docs dir must exist.
    # The theme dir must exist.
    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
    # A homepage 'index' must exist.
    # The theme 'base.html' file must exist.
    # Cannot set repo_name without setting repo_url.
    # Cannot set 'include_next_prev: true' when only one page exists.
    # Cannot set 'include_nav: true' when only one page exists.
    # Error if any config keys provided that are not in the DEFAULT_CONFIG.

    return config