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
Beispiel #2
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
Beispiel #3
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
Beispiel #4
0
    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
Beispiel #5
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
Beispiel #6
0
    def test_url_path(self):
        expected_results = {
            'index.md': '/',
            'api-guide.md': '/api-guide/',
            'api-guide/index.md': '/api-guide/',
            'api-guide/testing.md': '/api-guide/testing/',
        }
        for file_path, expected_url_path in expected_results.items():
            url_path = utils.get_url_path(file_path, 'directory')
            self.assertEqual(url_path, expected_url_path)

        expected_results = {
            'index.md': '/index.html',
            'api-guide.md': '/api-guide/index.html',
            'api-guide/index.md': '/api-guide/index.html',
            'api-guide/testing.md': '/api-guide/testing/index.html',
        }
        for file_path, expected_url_path in expected_results.items():
            url_path = utils.get_url_path(file_path, 'index')
            self.assertEqual(url_path, expected_url_path)

        expected_results = {
            'index.md': '/index.html',
            'api-guide.md': '/api-guide.html',
            'api-guide/index.md': '/api-guide/index.html',
            'api-guide/testing.md': '/api-guide/testing.html',
        }
        for file_path, expected_url_path in expected_results.items():
            url_path = utils.get_url_path(file_path, 'file')
            self.assertEqual(url_path, expected_url_path)
Beispiel #7
0
def _generate_site_navigation(pages_config, url_context, use_directory_urls=True):
    """
    Returns a list of Page and Header instances that represent the
    top level site navigation.
    """
    nav_items = []
    pages = []
    previous = None

    for config_line in pages_config:
        if isinstance(config_line, str):
            path = config_line
            title, child_title = None, None
        elif len(config_line) in (1, 2, 3):
            # Pad any items that don't exist with 'None'
            padded_config = (list(config_line) + [None, None])[:3]
            path, title, child_title = padded_config
        else:
            msg = (
                "Line in 'page' config contained %d items.  "
                "Expected 1, 2 or 3 strings." % len(config_line)
            )
            assert False, msg

        if title is None:
            filename = path.split('/')[0]
            title = filename_to_title(filename)
        if child_title is None and '/' in path:
            filename = path.split('/')[1]
            child_title = filename_to_title(filename)

        url = utils.get_url_path(path, use_directory_urls)

        if not child_title:
            # New top level page.
            page = Page(title=title, url=url, path=path, url_context=url_context)
            if not utils.is_homepage(path):
                nav_items.append(page)
        elif not nav_items or (nav_items[-1].title != title):
            # New second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = Header(title=title, children=[page])
            nav_items.append(header)
            page.ancestors = [header]
        else:
            # Additional second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = nav_items[-1]
            header.children.append(page)
            page.ancestors = [header]

        # Add in previous and next information.
        if previous:
            page.previous_page = previous
            previous.next_page = page
        previous = page

        pages.append(page)

    return (nav_items, pages)
Beispiel #8
0
def _generate_site_navigation(pages_config, url_context, use_directory_urls=True):
    """
    Returns a list of Page and Header instances that represent the
    top level site navigation.
    """
    nav_items = []
    pages = []
    previous = None

    for config_line in pages_config:
        if isinstance(config_line, str):
            path = config_line
            title, child_title = None, None
        elif len(config_line) in (1, 2, 3):
            # Pad any items that don't exist with 'None'
            padded_config = (list(config_line) + [None, None])[:3]
            path, title, child_title = padded_config
        else:
            msg = (
                "Line in 'page' config contained %d items.  "
                "Expected 1, 2 or 3 strings." % len(config_line)
            )
            assert False, msg

        if title is None:
            filename = path.split('/')[0]
            title = filename_to_title(filename)
        if child_title is None and '/' in path:
            filename = path.split('/')[1]
            child_title = filename_to_title(filename)

        url = utils.get_url_path(path, use_directory_urls)

        if not child_title:
            # New top level page.
            page = Page(title=title, url=url, path=path, url_context=url_context)
            if not utils.is_homepage(path):
                nav_items.append(page)
        elif not nav_items or (nav_items[-1].title != title):
            # New second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = Header(title=title, children=[page])
            nav_items.append(header)
            page.ancestors = [header]
        else:
            # Additional second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = nav_items[-1]
            header.children.append(page)
            page.ancestors = [header]

        # Add in previous and next information.
        if previous:
            page.previous_page = previous
            previous.next_page = page
        previous = page

        pages.append(page)

    return (nav_items, pages)
Beispiel #9
0
    def __init__(self, title, path, url_context, config):

        self._title = title

        self.classTitle = utils.get_html_title_class(title, path)
        self.htmlTitle = "Bmob后端云"
        if path.find("data/") != -1:
            self.htmlTitle = "数据存储 · " + self.classTitle + " – Bmob后端云"
        elif path.find("cloud_function/") != -1:
            self.htmlTitle = "云函数 · " + self.classTitle + " – Bmob后端云"
        elif path.find("sms/") != -1:
            self.htmlTitle = "短信服务 · " + self.classTitle + " – Bmob后端云"
        elif path.find("game/") != -1:
            self.htmlTitle = "游戏实时后端 · " + self.classTitle + " – Bmob后端云"
        elif path.find("im/") != -1:
            self.htmlTitle = "即时通讯 · " + self.classTitle + " – Bmob后端云"
        elif path.find("push/") != -1:
            self.htmlTitle = "推送服务 · " + self.classTitle + " – Bmob后端云"
        elif path.find("other/") != -1:
            self.htmlTitle = self.classTitle + " – Bmob后端云"

        self.abs_url = utils.get_url_path(path, config['use_directory_urls'])
        self.active = False
        self.url_context = url_context

        # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds.
        # See https://reproducible-builds.org/specs/source-date-epoch/
        if 'SOURCE_DATE_EPOCH' in os.environ:
            self.update_date = datetime.datetime.utcfromtimestamp(
                int(os.environ['SOURCE_DATE_EPOCH'])).strftime("%Y-%m-%d")
        else:
            self.update_date = datetime.datetime.now().strftime("%Y-%m-%d")

        # Relative and absolute paths to the input markdown file and output html file.
        self.input_path = path
        self.output_path = utils.get_html_path(path)
        self.abs_input_path = os.path.join(config['docs_dir'], self.input_path)
        self.abs_output_path = os.path.join(config['site_dir'],
                                            self.output_path)

        self.canonical_url = None
        if config['site_url']:
            self._set_canonical_url(config['site_url'])

        self.edit_url = None
        if config['repo_url'] and config['edit_uri']:
            self._set_edit_url(config['repo_url'], config['edit_uri'])

        # Placeholders to be filled in later in the build
        # process when we have access to the config.
        self.markdown = ''
        self.meta = {}
        self.content = None
        self.toc = None

        self.previous_page = None
        self.next_page = None
        self.ancestors = []
Beispiel #10
0
def _generate_site_navigation(pages_config, url_context, use_directory_urls=True):
    """
    Returns a list of Page and Header instances that represent the
    top level site navigation.
    """
    nav_items = []
    pages = []
    previous = None

    for config_line in pages_config:
        if isinstance(config_line, str):
            path = config_line
            title, child_title = None, None
        elif len(config_line) in (1, 2, 3):
            # Pad any items that don't exist with 'None'
            padded_config = (list(config_line) + [None, None])[:3]
            path, title, child_title = padded_config
        else:
            msg = (
                "Line in 'page' config contained %d items.  "
                "Expected 1, 2 or 3 strings." % len(config_line)
            )
            assert False, msg

        url = utils.get_url_path(path, use_directory_urls)

        if not child_title:
            # New top level page.
            page = Page(title=title, url=url, path=path, url_context=url_context)
            if page.title is not None:
                # Page config lines that do not include a title, such as:
                #    - ['index.md']
                # Will not be added to the nav items heiarchy, although they
                # are included in the full list of pages, and have the
                # appropriate 'next'/'prev' links generated.
                nav_items.append(page)
        elif not nav_items or (nav_items[-1].title != title):
            # New second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = Header(title=title, children=[page])
            nav_items.append(header)
            page.ancestors = [header]
        else:
            # Additional second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = nav_items[-1]
            header.children.append(page)
            page.ancestors = [header]

        # Add in previous and next information.
        if previous:
            page.previous_page = previous
            previous.next_page = page
        previous = page

        pages.append(page)

    return (nav_items, pages)
Beispiel #11
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
Beispiel #12
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
Beispiel #13
0
 def test_url_path(self):
     expected_results = {
         'index.md': '/',
         'api-guide.md': '/api-guide/',
         'api-guide/index.md': '/api-guide/',
         'api-guide/testing.md': '/api-guide/testing/',
     }
     for file_path, expected_html_path in expected_results.items():
         html_path = utils.get_url_path(file_path)
         self.assertEqual(html_path, expected_html_path)
Beispiel #14
0
 def test_url_path(self):
     expected_results = {
         'index.md': '/',
         'api-guide.md': '/api-guide/',
         'api-guide/index.md': '/api-guide/',
         'api-guide/testing.md': '/api-guide/testing/',
     }
     for file_path, expected_html_path in expected_results.items():
         html_path = utils.get_url_path(file_path)
         self.assertEqual(html_path, expected_html_path)
Beispiel #15
0
def _generate_site_navigation(pages_config, url_context, use_directory_urls=True):
    """
    Returns a list of Page and Header instances that represent the
    top level site navigation.
    """
    nav_items = []
    pages = []
    previous = None

    for config_line in pages_config:
        if len(config_line) == 2:
            path, title = config_line
            child_title = None
        elif len(config_line) == 3:
            path, title, child_title = config_line
        else:
            msg = (
                "Line in 'page' config contained %d items.  "
                "Expected 2 or 3." % len(config_line)
            )
            assert False, msg

        url = utils.get_url_path(path, use_directory_urls)

        if not child_title:
            # New top level page.
            page = Page(title=title, url=url, path=path, url_context=url_context)
            nav_items.append(page)
        elif not nav_items or (nav_items[-1].title != title):
            # New second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = Header(title=title, children=[page])
            nav_items.append(header)
            page.ancestors = [header]
        else:
            # Additional second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = nav_items[-1]
            header.children.append(page)
            page.ancestors = [header]

        # Add in previous and next information.
        if previous:
            page.previous_page = previous
            previous.next_page = page
        previous = page

        pages.append(page)

    return (nav_items, pages)
Beispiel #16
0
def create_tree(event):
    """
    Processes all the auto-generated API pages for the documentation.

    ### Parameters
        event | <mkdocs.events.PreBuild>

    ### Returns
        <bool>
    """
    # generate a set of autodoc pages
    match = re.match('^tree:(.*)$', event.path)
    if match:
        root = match.group(1)
        path = os.path.abspath(os.path.join(config.docs_dir, root))
        base = path[:-(len(root) + 1)]
        pages = []
        for base_path, folder, files in os.walk(path):
            files.sort()
            if 'index.md' in files:
                files.remove('index.md')
                files.insert(0, 'index.md')

            for file in files:
                filepath = os.path.join(base_path, file)
                filepath = filepath.replace('\\', '/')
                if file == 'index.md':
                    title = nav.filename_to_title(os.path.basename(base_path))
                else:
                    title = nav.filename_to_title(file)

                base_file_path = filepath[len(base) + 1:].replace('\\', '/')
                url = utils.get_url_path(base_file_path, True)
                page = nav.Page(title=title,
                                url=url,
                                path=base_file_path,
                                url_context=event.url_context)

                page.base_path = base_path

                # Add in previous and next information.
                if pages:
                    pages[-1].next_page = page
                    page.previous_page = pages[-1]
                pages.append(page)

        event.pages = pages
        event.consumed = True
Beispiel #17
0
def create_tree(event):
    """
    Processes all the auto-generated API pages for the documentation.

    ### Parameters
        event | <mkdocs.events.PreBuild>

    ### Returns
        <bool>
    """
    # generate a set of autodoc pages
    match = re.match('^tree:(.*)$', event.path)
    if match:
        root = match.group(1)
        path = os.path.abspath(os.path.join(config.docs_dir, root))
        base = path[:-(len(root) + 1)]
        pages = []
        for base_path, folder, files in os.walk(path):
            files.sort()
            if 'index.md' in files:
                files.remove('index.md')
                files.insert(0, 'index.md')

            for file in files:
                filepath = os.path.join(base_path, file)
                filepath = filepath.replace('\\', '/')
                if file == 'index.md':
                    title = nav.filename_to_title(os.path.basename(base_path))
                else:
                    title = nav.filename_to_title(file)

                base_file_path = filepath[len(base) + 1:].replace('\\', '/')
                url = utils.get_url_path(base_file_path, True)
                page = nav.Page(title=title,
                                url=url,
                                path=base_file_path,
                                url_context=event.url_context)

                page.base_path = base_path

                # Add in previous and next information.
                if pages:
                    pages[-1].next_page = page
                    page.previous_page = pages[-1]
                pages.append(page)

        event.pages = pages
        event.consumed = True
Beispiel #18
0
    def __init__(self, title, path, url_context, config):

        self._title = title
        self.abs_url = utils.get_url_path(path, config['use_directory_urls'])
        self.active = False
        self.url_context = url_context

        # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds.
        # See https://reproducible-builds.org/specs/source-date-epoch/
        if 'SOURCE_DATE_EPOCH' in os.environ:
            self.update_date = datetime.datetime.utcfromtimestamp(
                int(os.environ['SOURCE_DATE_EPOCH'])).strftime("%Y-%m-%d")
        else:
            self.update_date = datetime.datetime.now().strftime("%Y-%m-%d")

        # Relative and absolute paths to the input markdown file and output html file.
        self.input_path = path
        self.output_path = utils.get_html_path(path)
        self.abs_input_path = os.path.join(config['docs_dir'], self.input_path)
        self.abs_output_path = os.path.join(config['site_dir'],
                                            self.output_path)

        self.canonical_url = None
        if config['site_url']:
            self._set_canonical_url(config['site_url'])

        self.edit_url = None
        if config['repo_url']:
            self._set_edit_url(config['repo_url'], config['edit_uri'])

        # Placeholders to be filled in later in the build
        # process when we have access to the config.
        self.markdown = ''
        self.meta = {}
        self.content = None
        self.toc = None

        self.previous_page = None
        self.next_page = None
        self.ancestors = []
Beispiel #19
0
    def __init__(self, title, path, url_context, config):

        self._title = title
        self.abs_url = utils.get_url_path(path, config['use_directory_urls'])
        self.active = False
        self.url_context = url_context

        # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds.
        # See https://reproducible-builds.org/specs/source-date-epoch/
        if 'SOURCE_DATE_EPOCH' in os.environ:
            self.update_date = datetime.datetime.utcfromtimestamp(
                int(os.environ['SOURCE_DATE_EPOCH'])
            ).strftime("%Y-%m-%d")
        else:
            self.update_date = datetime.datetime.now().strftime("%Y-%m-%d")

        # Relative and absolute paths to the input markdown file and output html file.
        self.input_path = path
        self.output_path = utils.get_html_path(path)
        self.abs_input_path = os.path.join(config['docs_dir'], self.input_path)
        self.abs_output_path = os.path.join(config['site_dir'], self.output_path)

        self.canonical_url = None
        if config['site_url']:
            self._set_canonical_url(config['site_url'])

        self.edit_url = None
        if config['repo_url'] and config['edit_uri']:
            self._set_edit_url(config['repo_url'], config['edit_uri'])

        # Placeholders to be filled in later in the build
        # process when we have access to the config.
        self.markdown = ''
        self.meta = {}
        self.content = None
        self.toc = None

        self.previous_page = None
        self.next_page = None
        self.ancestors = []
Beispiel #20
0
def _follow(config_line, url_context, use_dir_urls, header=None, title=None):

    if isinstance(config_line, utils.string_types):
        path = os.path.normpath(config_line)
        page = _path_to_page(path, title, url_context, use_dir_urls)

        if header:
            page.ancestors = header.ancestors + [
                header,
            ]
            header.children.append(page)

        yield page
        raise StopIteration

    elif not isinstance(config_line, dict):
        msg = ("Line in 'page' config is of type {0}, dict or string "
               "expected. Config: {1}").format(type(config_line), config_line)
        raise exceptions.ConfigurationError(msg)

    if len(config_line) > 1:
        raise exceptions.ConfigurationError(
            "Page configs should be in the format 'name: markdown.md'. The "
            "config contains an invalid entry: {0}".format(config_line))
    elif len(config_line) == 0:
        log.warning("Ignoring empty line in the pages config.")
        raise StopIteration

    next_cat_or_title, subpages_or_path = next(iter(config_line.items()))

    if isinstance(subpages_or_path, utils.string_types):
        path = subpages_or_path
        for sub in _follow(path,
                           url_context,
                           use_dir_urls,
                           header=header,
                           title=next_cat_or_title):
            yield sub
        raise StopIteration

    elif not isinstance(subpages_or_path, list):
        msg = ("Line in 'page' config is of type {0}, list or string "
               "expected for sub pages. Config: {1}").format(
                   type(config_line), config_line)
        raise exceptions.ConfigurationError(msg)

    subpages = subpages_or_path

    if len(subpages) and isinstance(
            subpages[0],
            utils.string_types) and subpages[0].endswith('index.md'):
        # The first child is an index page. Use it as the URL of the header.
        path = os.path.normpath(subpages.pop(0))
        url = utils.get_url_path(path, use_dir_urls)
        next_header = HeaderPage(next_cat_or_title,
                                 url,
                                 path,
                                 url_context,
                                 children=[])
    else:
        next_header = Header(title=next_cat_or_title, children=[])

    if header:
        next_header.ancestors = [header]
        header.children.append(next_header)
    yield next_header

    for subpage in subpages:
        for sub in _follow(subpage, url_context, use_dir_urls, next_header):
            yield sub
Beispiel #21
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()})
Beispiel #22
0
def _path_to_page(path, title, url_context, use_directory_urls):
    if title is None:
        title = filename_to_title(path.split(os.path.sep)[-1])
    url = utils.get_url_path(path, use_directory_urls)
    return Page(title=title, url=url, path=path, url_context=url_context)
Beispiel #23
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()
    })
Beispiel #24
0
def _generate_site_navigation(pages_config,
                              url_context,
                              use_directory_urls=True):
    """
    Returns a list of Page and Header instances that represent the
    top level site navigation.
    """
    nav_items = []
    pages = []
    previous = None

    for config_line in pages_config:
        if isinstance(config_line, str):
            path = os.path.normpath(config_line)
            title, child_title = None, None
        elif len(config_line) in (1, 2, 3):
            # Pad any items that don't exist with 'None'
            padded_config = (list(config_line) + [None, None])[:3]
            path, title, child_title = padded_config
            path = os.path.normpath(path)
        else:
            msg = ("Line in 'page' config contained %d items.  "
                   "Expected 1, 2 or 3 strings." % len(config_line))
            raise exceptions.ConfigurationError(msg)

        # If both the title and child_title are None, then we
        # have just been given a path. If that path contains a /
        # then lets automatically nest it.
        if title is None and child_title is None and os.path.sep in path:
            filename = path.split(os.path.sep)[-1]
            child_title = filename_to_title(filename)

        if title is None:
            filename = path.split(os.path.sep)[0]
            title = filename_to_title(filename)

        # If we don't have a child title but the other title is the same, we
        # should be within a section and the child title needs to be inferred
        # from the filename.
        if len(nav_items) and title == nav_items[
                -1].title == title and child_title is None:
            filename = path.split(os.path.sep)[-1]
            child_title = filename_to_title(filename)

        url = utils.get_url_path(path, use_directory_urls)

        if not child_title:
            # New top level page.
            page = Page(title=title,
                        url=url,
                        path=path,
                        url_context=url_context)
            nav_items.append(page)
        elif not nav_items or (nav_items[-1].title != title):
            # New second level page.
            page = Page(title=child_title,
                        url=url,
                        path=path,
                        url_context=url_context)
            header = Header(title=title, children=[page])
            nav_items.append(header)
            page.ancestors = [header]
        else:
            # Additional second level page.
            page = Page(title=child_title,
                        url=url,
                        path=path,
                        url_context=url_context)
            header = nav_items[-1]
            header.children.append(page)
            page.ancestors = [header]

        # Add in previous and next information.
        if previous:
            page.previous_page = previous
            previous.next_page = page
        previous = page

        pages.append(page)

    return (nav_items, pages)
Beispiel #25
0
def _generate_site_navigation(pages_config, url_context, use_directory_urls=True):
    """
    Returns a list of Page and Header instances that represent the
    top level site navigation.
    """
    nav_items = []
    pages = []
    previous = None

    for config_line in pages_config:
        if isinstance(config_line, str):
            path = os.path.normpath(config_line)
            title, child_title = None, None
        elif len(config_line) in (1, 2, 3):
            # Pad any items that don't exist with 'None'
            padded_config = (list(config_line) + [None, None])[:3]
            path, title, child_title = padded_config
            path = os.path.normpath(path)
        else:
            msg = (
                "Line in 'page' config contained %d items.  "
                "Expected 1, 2 or 3 strings." % len(config_line)
            )
            raise exceptions.ConfigurationError(msg)

        # If both the title and child_title are None, then we
        # have just been given a path. If that path contains a /
        # then lets automatically nest it.
        if title is None and child_title is None and os.path.sep in path:
            filename = path.split(os.path.sep)[-1]
            child_title = file_to_tile(filename)

        if title is None:
            filename = path.split(os.path.sep)[0]
            title = file_to_tile(filename)

        # If we don't have a child title but the other title is the same, we
        # should be within a section and the child title needs to be inferred
        # from the filename.
        if len(nav_items) and title == nav_items[-1].title == title and child_title is None:
            filename = path.split(os.path.sep)[-1]
            child_title = file_to_tile(filename)

        url = utils.get_url_path(path, use_directory_urls)

        if not child_title:
            # New top level page.
            page = Page(title=title, url=url, path=path, url_context=url_context)
            nav_items.append(page)
        elif not nav_items or (nav_items[-1].title != title):
            # New second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = Header(title=title, children=[page])
            nav_items.append(header)
            page.ancestors = [header]
        else:
            # Additional second level page.
            page = Page(title=child_title, url=url, path=path, url_context=url_context)
            header = nav_items[-1]
            header.children.append(page)
            page.ancestors = [header]

        # Add in previous and next information.
        if previous:
            page.previous_page = previous
            previous.next_page = page
        previous = page

        pages.append(page)

    return (nav_items, pages)
Beispiel #26
0
 def __call__(self, match):
     path = match.groups()[0]
     return 'a href="%s"' % utils.get_url_path(path)
Beispiel #27
0
def _generate_site_navigation(pages_config,
                              url_context,
                              use_directory_urls=True):
    """
    Returns a list of Page and Header instances that represent the
    top level site navigation.
    """
    nav_items = []
    pages = []
    previous = None

    for config_line in pages_config:
        if isinstance(config_line, str):
            path = config_line
            title, child_title = None, None
        elif len(config_line) in (1, 2, 3):
            # Pad any items that don't exist with 'None'
            padded_config = (list(config_line) + [None, None])[:3]
            path, title, child_title = padded_config
        else:
            msg = ("Line in 'page' config contained %d items.  "
                   "Expected 1, 2 or 3 strings." % len(config_line))
            assert False, msg

        if title is None and os.path.splitext(path)[0] != 'index':
            title = path.split('/')[0]
            title = os.path.splitext(title)[0]
            title = title.replace('-', ' ').replace('_', ' ')
            title = title.capitalize()
        if child_title is None and '/' in path:
            child_title = path.split('/')[1]
            child_title = os.path.splitext(child_title)[0]
            child_title = child_title.replace('-', ' ').replace('_', ' ')
            child_title = child_title.capitalize()

        url = utils.get_url_path(path, use_directory_urls)

        if not child_title:
            # New top level page.
            page = Page(title=title,
                        url=url,
                        path=path,
                        url_context=url_context)
            if page.title is not None:
                # Page config lines that do not include a title, such as:
                #    - ['index.md']
                # Will not be added to the nav items heiarchy, although they
                # are included in the full list of pages, and have the
                # appropriate 'next'/'prev' links generated.
                nav_items.append(page)
        elif not nav_items or (nav_items[-1].title != title):
            # New second level page.
            page = Page(title=child_title,
                        url=url,
                        path=path,
                        url_context=url_context)
            header = Header(title=title, children=[page])
            nav_items.append(header)
            page.ancestors = [header]
        else:
            # Additional second level page.
            page = Page(title=child_title,
                        url=url,
                        path=path,
                        url_context=url_context)
            header = nav_items[-1]
            header.children.append(page)
            page.ancestors = [header]

        # Add in previous and next information.
        if previous:
            page.previous_page = previous
            previous.next_page = page
        previous = page

        pages.append(page)

    return (nav_items, pages)
Beispiel #28
0
def _path_to_page(path, title, url_context, use_directory_urls):
    if title is None:
        title = filename_to_title(path.split(os.path.sep)[-1])
    url = utils.get_url_path(path, use_directory_urls)
    return Page(title=title, url=url, path=path,
                url_context=url_context)