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.
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 |