docc.plugins.listing

Plugin that renders directory listings.

Listable

Mixin to change visibility of a Source in a directory listing.

class Listable:

show_in_listing

True if this Source should be shown in directory listings.

41
    @property
42
    @abstractmethod
def show_in_listing(self) -> bool:
44
        """
45
        `True` if this `Source` should be shown in directory listings.
46
        """
47
        raise NotImplementedError()

ListingDiscover

Creates listing sources for each directory.

class ListingDiscover:

__init__

def __init__(self, ​​config: PluginSettings) -> None:
56
        pass

discover

Find sources.

def discover(self, ​​known: FrozenSet[T]) -> Iterator["ListingSource"]:
59
        """
60
        Find sources.
61
        """
62
        listings = {}
63
64
        for source in known:
65
            path = source.relative_path
66
            if isinstance(source, Listable):
67
                if not source.show_in_listing:
68
                    continue
69
            elif not path:
70
                continue
71
72
            if not path:
73
                path = source.output_path
74
75
            for parent in path.parents:
76
                try:
77
                    listing = listings[parent]
78
                except KeyError:
79
                    listing = ListingSource(parent, parent / "index", set())
80
                    listings[parent] = listing
81
                    yield listing
82
83
                listing.sources.add(source)
84
                source = listing

ListingSource

A synthetic source that describes the contents of a directory.

class ListingSource:

_relative_path

92
    _relative_path: Final[PurePath]

_output_path

93
    _output_path: Final[PurePath]

sources

94
    sources: Final[Set[Source]]

__init__

def __init__(self, ​​relative_path: PurePath, ​​output_path: PurePath, ​​sources: Set[Source]) -> None:
102
        self._relative_path = relative_path
103
        self.sources = sources
104
        self._output_path = output_path

output_path

Where to write the output from this Source relative to the output path.

106
    @property
def output_path(self) -> PurePath:
108
        """
109
        Where to write the output from this Source relative to the output path.
110
        """
111
        return self._output_path

relative_path

Path to the Source (if one exists) relative to the project root.

113
    @property
def relative_path(self) -> PurePath:
115
        """
116
        Path to the Source (if one exists) relative to the project root.
117
        """
118
        return self._relative_path

ListingBuilder

Converts ListingSource instances into Documents.

class ListingBuilder:

__init__

Create a Builder with the given configuration.

def __init__(self, ​​config: PluginSettings) -> None:
127
        """
128
        Create a Builder with the given configuration.
129
        """

build

Consume unprocessed Sources and insert their Documents into processed.

def build(self, ​​unprocessed: Set[Source], ​​processed: Dict[Source, Document]) -> None:
136
        """
137
        Consume unprocessed Sources and insert their Documents into processed.
138
        """
139
        to_process = set(
140
            x for x in unprocessed if isinstance(x, ListingSource)
141
        )
142
        unprocessed -= to_process
143
144
        for source in to_process:
145
            processed[source] = Document(ListingNode(source.sources))

ListingNode

A node representing a directory listing.

class ListingNode:

sources

153
    sources: Final[Set[Source]]

__init__

def __init__(self, ​​sources: Set[Source]) -> None:
156
        self.sources = sources

children

Child nodes belonging to this node.

158
    @property
def children(self) -> Tuple[()]:
160
        """
161
        Child nodes belonging to this node.
162
        """
163
        return ()

replace_child

Replace the old node with the given new node.

def replace_child(self, ​​old: Node, ​​new: Node) -> None:
166
        """
167
        Replace the old node with the given new node.
168
        """
169
        raise TypeError()

render_html

Render a ListingNode as HTML.

def render_html(context: object, ​​parent: object, ​​node: object) -> docc.plugins.html.RenderResult:
177
    """
178
    Render a ListingNode as HTML.
179
    """
180
    assert isinstance(context, Context)
181
    assert isinstance(parent, (html.HTMLRoot, html.HTMLTag))
182
    assert isinstance(node, ListingNode)
183
184
    output_path = context[Source].output_path
185
    entries = []
186
187
    for source in node.sources:
188
        entry_path = source.output_path
189
190
        if output_path == entry_path:
191
            relative_path = ""
192
        else:
193
            common_path = commonpath((output_path, entry_path))
194
195
            parents = len(output_path.relative_to(common_path).parents) - 1
196
197
            relative_path = (
198
                str(
199
                    PurePath(*[".."] * parents)
200
                    / entry_path.relative_to(common_path)
201
                )
202
                + ".html"
203
            )  # TODO: Don't hardcode extension.
204
205
        path = source.relative_path or source.output_path
206
        entries.append((path, relative_path))
207
208
    entries.sort()
209
210
    env = Environment(
211
        loader=PackageLoader("docc.plugins.listing"),
212
        autoescape=select_autoescape(),
213
    )
214
    template = env.get_template("listing.html")
215
    parser = html.HTMLParser(context)
216
    parser.feed(template.render(context=context, entries=entries))
217
    for child in parser.root._children:
218
        parent.append(child)
219
    return None