File: plugin.py

package info (click to toggle)
mkdocs-test 0.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 436 kB
  • sloc: python: 938; sh: 34; makefile: 5
file content (135 lines) | stat: -rw-r--r-- 3,768 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# --------------------------------------------
# Main part of the plugin
# Defines the MacrosPlugin class
#
# Laurent Franceschetti (c) 2018
# MIT License
# --------------------------------------------

import os
import json
import logging

from bs4 import BeautifulSoup 
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.files import Files
from super_collections import SuperDict

from mkdocs.plugins import BasePlugin
from mkdocs.structure.pages import Page
from mkdocs.structure.nav import Navigation
try:
    from mkdocs.plugins import event_priority
except ImportError:
    event_priority = lambda priority: lambda f: f  # No-op fallback

from .common import TEST_DIRNAME, DOCS_DEFAULT_DIRNAME, PAGE_MAP, get_frontmatter




LOWEST_PRIORITY = -90


# ------------------------------------------
# Utilities
# ------------------------------------------

log = logging.getLogger(f"mkdocs.plugins.test")

def fmt(*args):
    "Format text for the log"
    items = ['[test] - '] + [str(arg) for arg in args]
    return ' '.join(items)


def convert_object(object) -> SuperDict:
    "Convert an object to a dictionary"
    d = {key: value for key, value in object.__dict__.items()
                if not key.startswith('_') and
                isinstance(value, (str, int, float, dict))}
    return SuperDict(d)

def check_dir(dest_file:str):
    "Check that the directories of a destination file exist"
    os.makedirs(os.path.dirname(dest_file), exist_ok=True)

# ------------------------------------------
# Plugin
# ------------------------------------------
class TestPlugin(BasePlugin):
    """
    This plugin generates information necessary
    for testing MkDocs project
    """

    # ----------------------------
    # Directories
    # ----------------------------

    @property
    def docs_dir(self) -> str:
        "The docs directory (relative to project dir)"
        return self.config.get('docs_dir', DOCS_DEFAULT_DIRNAME)

    @property
    def test_dir(self) -> str:
        "Return the test dir"
        return TEST_DIRNAME


    @property
    def nav(self):
        "Get the nav"
        try:
            return self._nav
        except AttributeError:
            raise AttributeError("Trying to access the nav attribute too early")

    @property
    def source_markdown(self) -> SuperDict:
        "The table raw (target) markdown (used to complement the page table)"
        try:
            return self._source_markdown
        except AttributeError:
            self._source_markdown = SuperDict()
            return self._source_markdown      

    # ----------------------------
    # Pages
    # ----------------------------
    def get_page_map(self) -> SuperDict:
        """
        Recursively build the mapping of pages from 
        self.nav: all pages, created by on_nav().
        """
        pages = []
        for page in self.nav.pages:
            d = convert_object(page)
            d.file = convert_object(page.file)
            pages.append(d)
        return SuperDict({page.file.src_uri: page for page in pages})

    # ----------------------------
    # Handling events
    # ----------------------------
    @event_priority(LOWEST_PRIORITY)
    def on_nav(self, nav, config, files):
        "Set the nav"
        self._nav = nav

    @event_priority(LOWEST_PRIORITY)
    def on_post_build(self, config):
        """
        The most important action: export all pages
        This method is called at the end of the build process
        """
        mapping = self.get_page_map()
        out_file = os.path.join(self.test_dir, PAGE_MAP)
        log.info(fmt("Debug file:", out_file))
        check_dir(out_file)
        with open(out_file, 'w') as f:
            json.dump(mapping, f, indent=4)