From 56e10f64707348f0a60144549cbba9cbb7070332 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@lysator.liu.se>
Date: Mon, 25 Sep 2023 21:37:38 +0200
Subject: [PATCH] Remove type specific TOC entries.

P(reviously each type of TOC entry had it's own type, which was extremely
unvildely. This merges all instances to their lowest common denominator,
which actually REDUCED the code complexity quite a bit.
---
 muppet/output/__init__.py                     | 371 +++---------------
 muppet/output/toc.py                          | 307 +++++++++++++++
 muppet/output/util.py                         |   6 +-
 templates/module_index.html                   |   2 +-
 .../snippets/ResourceType-index-entry.html    |  20 -
 .../snippets/ResourceType-list-entry.html     |  10 -
 6 files changed, 363 insertions(+), 353 deletions(-)
 create mode 100644 muppet/output/toc.py
 delete mode 100644 templates/snippets/ResourceType-index-entry.html
 delete mode 100644 templates/snippets/ResourceType-list-entry.html

diff --git a/muppet/output/__init__.py b/muppet/output/__init__.py
index d03a471..611ac4c 100644
--- a/muppet/output/__init__.py
+++ b/muppet/output/__init__.py
@@ -4,7 +4,6 @@ Generate all output files.
 The primary entry point of this module is the class
 :class:`PuppetEnvironment`.
 """
-from dataclasses import dataclass, field
 import html
 import logging
 import os.path
@@ -17,10 +16,6 @@ from typing import (
     Sequence,
     cast,
 )
-from jinja2 import (
-    Environment,
-    FileSystemLoader,
-)
 
 from muppet.syntax_highlight import highlight
 from muppet.puppet.strings import (
@@ -43,15 +38,22 @@ from muppet.breadcrumbs import Breadcrumbs, breadcrumbs
 from muppet.util import group_by, partition
 from muppet.cache import AbstractCache
 
+from jinja2 import (
+    Environment,
+    FileSystemLoader,
+)
 
 from .docstring import format_docstring
 from .puppet_source import hyperlink_puppet_source
-from .util import HtmlSerializable
+from .toc import (
+    Toc,
+    # TocEntry,
+    TocHeader,
 
+    type_aliases_index,
+    resource_type_index,
+    index_item,
 
-jinja = Environment(
-    loader=FileSystemLoader('templates'),
-    autoescape=False,
 )
 
 
@@ -139,7 +141,7 @@ class Templates:
 
     def module_index(self, *,
                      # content: list[],  # something with to_html_list and to_html
-                     content: Sequence[HtmlSerializable],
+                     content: Sequence[Toc],
                      module_author: Optional[str],
                      module_name: str,
                      doc_files: list[tuple[str, str]],
@@ -186,188 +188,6 @@ class Templates:
                 right_sidebar=right_sidebar)
 
 
-@dataclass
-class ResourceTypeOutput:
-
-    title: str
-    module_name: str
-    children: list[HtmlSerializable] = field(default_factory=list)
-    link: Optional[str] = None
-    summary: Optional[str] = None
-
-    def base(self) -> str:
-        """
-        Return base text of the node.
-
-        If the node has a link, create a hyperlink, otherwise return
-        it's title directly.
-        """
-        # TODO make links absolute to root, to allow inclusion anywhere
-        if self.link:
-            return f'<a href="{ self.link }">{ self.title }</a>'
-        else:
-            return self.title
-
-    def to_html(self) -> str:
-        """Return HTML string."""
-        # self.__class__.__name__
-        return jinja \
-            .get_template('snippets/ResourceType-index-entry.html') \
-            .render(item=self,
-                    module_name=self.module_name,
-                    # TODO don't hardcode prefix
-                    prefix='/code/muppet-strings/output')
-
-    def to_html_list(self) -> str:
-        """Return HTML suitable for a list."""
-        return jinja \
-            .get_template('snippets/ResourceType-list-entry.html') \
-            .render(item=self)
-
-
-@dataclass
-class IndexItem:
-    """
-    A concrete type, on an index page.
-
-    This will be something like a class or resource type.
-
-    :param name:
-        Name of the resource or similar
-    :param file:
-        Relative path to the resource.
-    :param summary:
-        One line summary of the resource, will be displayed in the UI.
-    """
-
-    name: str
-    file: str
-    summary: Optional[str] = None
-
-    def base(self) -> str:
-        """Return link to self."""
-        # TODO make links absolute to root, to allow inclusion anywhere
-        return f'<a href="{self.file}">{ self.name }</a>'
-
-    def to_html(self) -> str:
-        """Convert item to an HTML string."""
-        out: str = ''
-        out += f'<dt>{self.base()}</dt>'
-
-        if self.summary:
-            out += f"<dd>{self.summary}</dd>"
-
-        return out
-
-    def to_html_list(self) -> str:
-        """Convert itom to an HTML string sutibale for a list."""
-        out: str = ''
-        out += f'<li>{self.base()}</li>'
-        return out
-
-
-@dataclass
-class IndexSubcategory:
-    """
-    Subheading on index page.
-
-    Will most likely be 'Public' or 'Private' objects for the given
-    top heading.
-    """
-
-    title: str
-    list: list[IndexItem]
-
-    def to_html(self) -> str:
-        """Convert subcategory to an HTML string."""
-        out: str = ''
-        out += f'<h3>{html.escape(self.title)}</h3>'
-        out += '<dl class="overview-list">'
-
-        for item in self.list:
-            out += item.to_html()
-
-        out += '</dl>'
-
-        return out
-
-    def to_html_list(self) -> str:
-        """Convert itom to an html string suitable for a list."""
-        pass
-        out: str = ''
-        out += f'<li>{html.escape(self.title)}<ul>'
-        for item in self.list:
-            out += item.to_html_list()
-        out += '</ul></li>'
-
-        return out
-
-
-@dataclass
-class IndexCategory:
-    """
-    Top level heading in index.
-
-    This should be something like 'Classes', 'Types', ...
-    Each entry contains a set of subentries, which can either be
-    distinct entries, or sometimes subcategories (such as 'Public' and
-    'Private').
-    """
-
-    title: str
-    list: list[IndexSubcategory]
-
-    def base(self) -> str:
-        """Return HTML escaped title."""
-        return html.escape(self.title)
-
-    def to_html(self) -> str:
-        """Return class as an HTML string."""
-        out: str = ''
-        out += f'<h2>{self.base()}</h2>'
-
-        for item in self.list:
-            out += item.to_html()
-
-        return out
-
-    def to_html_list(self) -> str:
-        """Return class as an HTML string suitable for a list."""
-        out: str = ''
-        out += f'<li>{self.base()}<ul>'
-        for item in self.list:
-            out += item.to_html_list()
-        out += '</ul></li>'
-
-        return out
-
-
-@dataclass
-class ResourceIndex:
-
-    title: str
-    children: list[HtmlSerializable]
-
-    def to_html(self) -> str:
-        """Return something."""
-        out: str = ''
-        out += f'<h2>{self.title}</h2>'
-        out += '<dl>'
-        for child in self.children:
-            out += child.to_html()
-        out += '</dl>'
-        return out
-
-    def to_html_list(self) -> str:
-        """Return something."""
-        out: str = ''
-        out += f'<li>{self.title}<ul>'
-        for child in self.children:
-            out += child.to_html_list()
-        out += '</ul></li>'
-        return out
-
-
 class PuppetModule:
     """
     A representation of an entire Puppet module.
@@ -425,10 +245,10 @@ class PuppetModule:
 
         self.module_toc: str = ''.join([
             '<ul class="toc">',
-            *(e.to_html_list() for e in self._build_module_toc()),
+            *(e.to_html_list(path_base=self.output_prefix) for e in self._build_module_toc()),
             '</ul>'])
 
-    def _build_module_toc(self) -> Sequence[ResourceIndex | IndexCategory]:
+    def _build_module_toc(self) -> Sequence[Toc]:
         """
         Build the TOC of the module.
 
@@ -440,41 +260,38 @@ class PuppetModule:
         :returns:
             A list of categories.
         """
-        content: list[ResourceIndex | IndexCategory] = []
+        content: list[Toc] = []
 
         if puppet_classes := self.strings_output.puppet_classes:
-            content.append(class_index(puppet_classes))
+            content.append(class_index(self.name, puppet_classes))
 
         # data_types
         if _ := self.strings_output.data_types:
-            content.append(IndexCategory(
-                title='Data types not yet implmented',
-                list=[]))
+            content.append(TocHeader(
+                name='Data types not yet implmented'))
 
         if data_type_aliases := self.strings_output.data_type_aliases:
-            content.append(type_aliases_index(data_type_aliases))
+            content.append(type_aliases_index(self.name, data_type_aliases))
 
         if defined_types := self.strings_output.defined_types:
-            content.append(defined_types_index(defined_types))
+            content.append(defined_types_index(self.name, defined_types))
 
         if resource_types := self.strings_output.resource_types:
-            content.append(ResourceIndex(
-                title='Resource Types',
+            content.append(TocHeader(
+                name='Resource Types',
                 children=resource_type_index(
                     resource_types,
                     self.name)))
 
         # providers
         if _ := self.strings_output.providers:
-            content.append(IndexCategory(
-                title='Providers not yet implmented',
-                list=[]))
+            content.append(TocHeader(
+                name='Providers not yet implmented'))
 
         # puppet_functions
         if _ := self.strings_output.puppet_functions:
-            content.append(IndexCategory(
-                title='Puppet Functions not yet implmented',
-                list=[]))
+            content.append(TocHeader(
+                name='Puppet Functions not yet implmented'))
 
         # templates/
         # files/
@@ -488,16 +305,13 @@ class PuppetModule:
 
         # puppet_tasks
         if _ := self.strings_output.puppet_tasks:
-            content.append(IndexCategory(
-                title='Puppet Tasks not yet implmented',
-                list=[]))
+            content.append(TocHeader(
+                name='Puppet Tasks not yet implmented'))
 
         # puppet_plans
         if _ := self.strings_output.puppet_plans:
-            content.append(IndexCategory(
-                title='Puppet Plans not yet implmented',
-                list=[],
-            ))
+            content.append(TocHeader(
+                name='Puppet Plans not yet implmented'))
 
         return content
 
@@ -770,29 +584,29 @@ class PuppetEnvironment:
             module.output(destination)
 
 
-def class_index(class_list: list[PuppetClass]) -> IndexCategory:
+def class_index(module_name: str, class_list: list[PuppetClass]) -> Toc:
     """Prepage class index list."""
     publics, privates = partition(isprivate, class_list)
 
-    lst: list[IndexSubcategory] = []
+    lst: list[TocHeader] = []
 
     if publics:
-        lst.append(IndexSubcategory(
-            title='Public Classes',
-            list=[index_item(i) for i in publics]))
+        lst.append(TocHeader(
+            name='Public Classes',
+            children=[index_item(module_name, i) for i in publics]))
 
     if privates:
-        lst.append(IndexSubcategory(
-            title='Private Classes',
-            list=[index_item(i) for i in privates]))
+        lst.append(TocHeader(
+            name='Private Classes',
+            children=[index_item(module_name, i) for i in privates]))
 
-    return IndexCategory(
-        title='Classes',
-        list=lst
+    return TocHeader(
+        name='Classes',
+        children=lst
     )
 
 
-def defined_types_index(defined_list: list[DefinedType]) -> IndexCategory:
+def defined_types_index(module_name: str, defined_list: list[DefinedType]) -> TocHeader:
     """
     Prepare defined types index list.
 
@@ -801,107 +615,26 @@ def defined_types_index(defined_list: list[DefinedType]) -> IndexCategory:
     """
     groups = group_by(isprivate, defined_list)
 
-    lst: list[IndexSubcategory] = []
-
-    if publics := groups.get(False):
-        lst.append(IndexSubcategory(
-            title='Public Defined Types',
-            list=[index_item(i) for i in publics],
-        ))
-
-    if privates := groups.get(True):
-        lst.append(IndexSubcategory(
-            title='Private Defined Types',
-            list=[index_item(i) for i in privates],
-        ))
-
-    return IndexCategory(
-        title='Defined Types',
-        list=lst
-    )
-
+    lst: list[TocHeader] = []
 
-def type_aliases_index(alias_list: list[DataTypeAlias]) -> IndexCategory:
-    """Prepare type alias index list."""
-    groups = group_by(isprivate, alias_list)
-    lst: list[IndexSubcategory] = []
     if publics := groups.get(False):
-        lst.append(IndexSubcategory(
-            title='Public Type Aliases',
-            list=[IndexItem(name=i.name,
-                            file=os.path.splitext(i.file)[0])
-                  for i in publics],
+        lst.append(TocHeader(
+            name='Public Defined Types',
+            children=[index_item(module_name, i) for i in publics],
         ))
 
     if privates := groups.get(True):
-        lst.append(IndexSubcategory(
-            title='Private Type Aliases',
-            list=[IndexItem(name=i.name,
-                            file=os.path.splitext(i.file)[0])
-                  for i in privates],
+        lst.append(TocHeader(
+            name='Private Defined Types',
+            children=[index_item(module_name, i) for i in privates],
         ))
 
-    return IndexCategory(
-        title='Type Aliases',
-        list=lst,
+    return TocHeader(
+        name='Defined Types',
+        children=lst
     )
 
 
-def resource_type_index(resource_types: list[ResourceType],
-                        module_name: str) -> list[HtmlSerializable]:
-    """
-    Generate index of all known resource types.
-    """
-    lst: list[HtmlSerializable] = []
-
-    for resource_type in resource_types:
-        # resource_type['file']
-        # resource_type['docstring']
-
-        items: list[HtmlSerializable] = []
-        if providers := resource_type.providers:
-            for provider in providers:
-                # TODO summary tag?
-                # TODO, instead, render markdown and take first paragraph
-                documentation = provider.docstring.text.split('\n')[0]
-                items.append(ResourceTypeOutput(
-                    title=provider.name,
-                    link=provider.file,
-                    module_name=module_name,
-                    summary=documentation))
-
-        lst.append(ResourceTypeOutput(title=resource_type.name,
-                                      module_name=module_name,
-                                      children=items))
-
-    return lst
-
-
-def index_item(obj: PuppetClass | DefinedType) -> IndexItem:
-    """
-    Format a puppet type declaration into an index entry.
-
-    :param obj:
-        A dictionary at least containing the keys 'name' and 'file',
-        and optionally containing 'docstring'. If docstring is present
-        then a summary tag is searched for, and added to the resulting
-        object.
-    """
-    name = obj.name
-
-    out: IndexItem = IndexItem(
-        file=os.path.splitext(obj.file)[0],
-        name=name,
-    )
-
-    for tag in obj.docstring.tags:
-        if tag.tag_name == 'summary':
-            out.summary = markdown(tag.text)
-            break
-
-    return out
-
-
 def format_class(d_type: DefinedType | PuppetClass) -> tuple[str, str]:
     """Format Puppet class."""
     out = ''
diff --git a/muppet/output/toc.py b/muppet/output/toc.py
new file mode 100644
index 0000000..517a017
--- /dev/null
+++ b/muppet/output/toc.py
@@ -0,0 +1,307 @@
+"""
+Procedures for generating a table of contents.
+
+This is both used for the main page, containing everything, including
+summary of them. As well as the sidebar summary which only contains
+(hyperlinked) names.
+
+A table of contents here is defined as a list of :class:`TocHeader`
+objects, where each one is a top level entry.
+Each entry may then contain subheading, or :class:`TocEntry` entries,
+which represent concrete data which may have summaries (in our cases,
+puppet classes, functions, ...)
+"""
+
+from dataclasses import dataclass, field
+from typing import (
+    Any,
+    TypeAlias,
+    Union,
+    cast,
+)
+import html
+import os.path
+
+from muppet.puppet.strings import (
+    DataTypeAlias,
+    DefinedType,
+    PuppetClass,
+    ResourceType,
+    isprivate,
+)
+from muppet.util import group_by
+from muppet.markdown import markdown
+
+from jinja2 import (
+    Environment,
+    FileSystemLoader,
+)
+
+
+jinja = Environment(
+    loader=FileSystemLoader('templates'),
+    autoescape=False,
+)
+
+
+"""
+---
+- name: Classes
+  children:
+    - name: Public classes
+      children:
+        - name: apt
+          url: apt/manifests/init
+          summary: "Main class, includes all other classes."
+- name: Resource Types
+  children:
+    - name: apt_key
+      url: lib/puppet/type/apt_key
+      summary: "A summary of apt_key would have gone here"
+      children:
+        - name: apt_key
+          url: lib/puppet/provider/apt_key/apt_key
+          summary: "Summary of this specific provider"
+
+"""
+
+
+def html_tag(tag: str, content: str, **attributes: str) -> str:
+    """
+    Generate the string of an HTML tag.
+
+    .. code-block:: python
+        :caption: Example invocation and output
+
+        >>> html_tag('a', 'A link', href='example.com')
+        '<a href="example.com">A link</a>'
+
+
+    *NOTE* none of the arguments will be escaped.
+
+    :param tag:
+        The containing tag.
+
+    :param content:
+        The body of the HTML. Note that this is NOT escaped, to allow
+        nesting. Use ``html.escape`` if escaping is wanted.
+
+    :param attributes:
+        Remaining key-value attributes are passed along as HTML
+        attributes.
+    """
+    out = f'<{tag}'
+    for key, value in attributes.items():
+        out += f' {key}="{value}"'
+    out += '>'
+    out += content
+    out += f'</{tag}>'
+    return out
+
+
+Toc: TypeAlias = Union['TocHeader', 'TocEntry']
+TocList: TypeAlias = list['TocHeader'] | list['TocEntry']
+
+
+@dataclass
+class TocHeader:
+    """
+    A header entry in a TOC list.
+
+    This is an entry which which will in "rich" form be generated with
+    a header tag. Either way, it can't contain further data, except
+    for children.
+
+    :param name:
+        The header of the entry. Think of this as the ``<h[2-6]>`` tag.
+
+    :param children:
+        A list of either only other TocHeader objects, or only
+        TocEntry objects, the distinction since I don't think it makes
+        sense to allow both at the same level.
+    """
+
+    name: str
+    # children: list['Toc'] = field(default_factory=list)
+    children: TocList = field(default_factory=lambda: cast(TocList, []))
+
+    def to_html(self, *, path_base: str, level: int, **args: Any) -> str:
+        """Generate an HTML representation suitable for a standalone toc page."""
+        out = []
+        out.append(html_tag(f'h{level}', html.escape(self.name)))
+        if ch := self.children:
+            if isinstance(ch[0], TocHeader):
+                out += [c.to_html(path_base=path_base, level=level + 1, **args) for c in ch]
+            elif isinstance(ch[0], TocEntry):
+                out.append(html_tag(
+                    'dl', ''.join(c.to_html(path_base=path_base, **args) for c in ch)))
+        return ''.join(out)
+
+    def to_html_list(self, path_base: str) -> str:
+        """Generate an HTML representation suitable for a compact list."""
+        out = '<li>'
+        out += html.escape(self.name)
+        if ch := self.children:
+            out += html_tag('ul', ''.join(c.to_html_list(path_base=path_base) for c in ch))
+        out += '</li>'
+        return out
+
+
+@dataclass
+class TocEntry:
+    """
+    An entry in a TOC list which may contain data.
+
+    In Puppet's case, this is anything which actually links to a file
+    (or similar).
+
+    :param name:
+        Name of the object, should be something like a class name.
+
+    :param url:
+        Relative URL to where the documentation for that object will be located.
+
+    :param summary:
+        An (optional) short summary of the object. Will most likely be
+        extracted from an ``@summary`` tag.
+
+    :param children:
+        Even these can have children. Mostly used by resource types for their providers.
+    """
+
+    name: str
+    url: str
+    summary: str = ''
+    children: list['TocEntry'] = field(default_factory=list)
+
+    def to_html(self, *, path_base: str, **_: Any) -> str:
+        """
+        Generate an HTML representation suitable for a standalone toc page.
+
+        Varargs are taken to be compatible with other implementations
+        actually taking arguments.
+        """
+        out = []
+        out.append(html_tag('dt',
+                            html_tag('a', html.escape(self.name),
+                                     href=f'{path_base}/{self.url}')))
+        out.append('<dd>')
+        out.append(self.summary)
+        if ch := self.children:
+            out.append(html_tag(
+                'dl', ''.join(c.to_html(path_base=path_base) for c in ch)))
+        out.append('</dd>')
+        return ''.join(out)
+
+    def to_html_list(self, *, path_base: str) -> str:
+        """Generate an HTML representation suitable for a compact list."""
+        out = '<li>'
+        out += html_tag('a', html.escape(self.name), href=f'{path_base}/{self.url}')
+        # Summary intentionally ignored
+        if ch := self.children:
+            out += html_tag('ul', ''.join(c.to_html_list(path_base=path_base) for c in ch))
+        out += '</li>'
+        return out
+
+
+def type_aliases_index(module_name: str, alias_list: list[DataTypeAlias]) -> TocHeader:
+    """
+    Prepare type alias index list.
+
+    A concrete type, on an index page.
+
+    This will be something like a class or resource type.
+
+    Subheading on index page.
+
+    Will most likely be 'Public' or 'Private' objects for the given
+    top heading.
+
+    Top level heading in index.
+
+    This should be something like 'Classes', 'Types', ...
+    Each entry contains a set of subentries, which can either be
+    distinct entries, or sometimes subcategories (such as 'Public' and
+    'Private').
+
+    :param name:
+        Name of the resource or similar
+    :param file:
+        Relative path to the resource.
+    :param summary:
+        One line summary of the resource, will be displayed in the UI.
+    """
+    groups = group_by(isprivate, alias_list)
+    lst: list[TocHeader] = []
+    if publics := groups.get(False):
+        lst.append(TocHeader(
+            name='Public Type Aliases',
+            children=[TocEntry(name=i.name,
+                               url=f"{module_name}/{os.path.splitext(i.file)[0]}")
+                      for i in publics],
+            ))
+
+    if privates := groups.get(True):
+        lst.append(TocHeader(
+            name='Private Type Aliases',
+            children=[TocEntry(name=i.name,
+                               url=f"{module_name}/{os.path.splitext(i.file)[0]}")
+                      for i in privates],
+            ))
+
+    return TocHeader(
+        name='Type Aliases',
+        children=lst,
+    )
+
+
+def resource_type_index(resource_types: list[ResourceType],
+                        module_name: str) -> list[TocEntry]:
+    """Generate index of all known resource types."""
+    lst: list[TocEntry] = []
+
+    for resource_type in resource_types:
+        # resource_type['file']
+        # resource_type['docstring']
+
+        items: list[TocEntry] = []
+        if providers := resource_type.providers:
+            for provider in providers:
+                # TODO summary tag?
+                # TODO, instead, render markdown and take first paragraph
+                documentation = provider.docstring.text.split('\n')[0]
+                items.append(TocEntry(
+                    name=provider.name,
+                    url=provider.file,
+                    summary=documentation))
+
+        lst.append(TocEntry(name=resource_type.name,
+                            url='#TODO',
+                            children=items))
+
+    return lst
+
+
+def index_item(module_name: str, obj: PuppetClass | DefinedType) -> TocEntry:
+    """
+    Format a puppet type declaration into an index entry.
+
+    :param obj:
+        A dictionary at least containing the keys 'name' and 'file',
+        and optionally containing 'docstring'. If docstring is present
+        then a summary tag is searched for, and added to the resulting
+        object.
+    """
+    name = obj.name
+
+    out: TocEntry = TocEntry(
+        name=name,
+        url=f'{module_name}/{os.path.splitext(obj.file)[0]}',
+    )
+
+    for tag in obj.docstring.tags:
+        if tag.tag_name == 'summary':
+            out.summary = markdown(tag.text)
+            break
+
+    return out
diff --git a/muppet/output/util.py b/muppet/output/util.py
index 2c3c3a3..cdb0fa8 100644
--- a/muppet/output/util.py
+++ b/muppet/output/util.py
@@ -7,7 +7,7 @@ useful than other.
 The aim is to only have pure functions here.
 """
 
-from typing import Protocol
+from typing import Any, Protocol
 from muppet.parser_combinator import (
     MatchCompound,
     MatchObject,
@@ -48,10 +48,10 @@ def inner_text(obj: MatchObject | list[MatchObject]) -> str:
 class HtmlSerializable(Protocol):
     """Classes which can be serialized as HTML."""
 
-    def to_html(self) -> str:  # pragma: no cover
+    def to_html(self, **_: Any) -> str:  # pragma: no cover
         """Return HTML string."""
         ...
 
-    def to_html_list(self) -> str:  # pragma: no cover
+    def to_html_list(self, **_: Any) -> str:  # pragma: no cover
         """Return HTML suitable for a list."""
         ...
diff --git a/templates/module_index.html b/templates/module_index.html
index d00e73a..05d92e4 100644
--- a/templates/module_index.html
+++ b/templates/module_index.html
@@ -35,7 +35,7 @@ Parameters:
 </ul>
 
 {% for entry in content %}
-	{{ entry.to_html() }}
+	{{ entry.to_html(path_base=path_base, level=2) }}
 {% endfor %}
 
 {% endblock %}
diff --git a/templates/snippets/ResourceType-index-entry.html b/templates/snippets/ResourceType-index-entry.html
deleted file mode 100644
index 45501f4..0000000
--- a/templates/snippets/ResourceType-index-entry.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{#
-:param item: An instance of ResourceTypeOutput
-:param prefix: Prefix for HTTP output path,
-	(e.g. '/code/muppet-strings/output')
-:param module_name:
-
-#}
-<dt><a href="{{ prefix }}/{{ module_name }}/lib/puppet/types/{{ item.base() }}.rb">{{ item.base() }}</a></dt>
-<dd>
-	{% if item.summary %}
-		<!-- TODO docstring.text -->
-	{{ item.summary }}
-	{% endif %}
-	<dl>
-		{% for provider in item.children %}
-		{{ provider.to_html() }}
-		{% endfor %}
-	</dl>
-</dd>
-{# ft:jinja2 #}
diff --git a/templates/snippets/ResourceType-list-entry.html b/templates/snippets/ResourceType-list-entry.html
deleted file mode 100644
index dedb1a0..0000000
--- a/templates/snippets/ResourceType-list-entry.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{#
-#}
-<li><a href="#">{{ item.base() }}</a>
-	<ul>
-		{% for provider in item.children %}
-		{{ provider.to_html_list() }}
-		{% endfor %}
-	</ul>
-</li>
-{# ft:jinja2 #}
-- 
GitLab