Specification: Markdown Overview Renderer

This document defines the expected structure and content of the Overview.md artefact generated from GitLab project data. It complements the low-level Table Rendering & UI rules and is independent from the Quarto output (see separate spec).


1. Top-level Layout

The document is divided into two major parts – a summary and a detailed section – separated by an automatic table-of-contents marker.

# Overview over GitLab Readmes

## Summary

### <Group-A>

<Table>

<Optional explanatory note>

### <Group-B>

<Table>

<Optional explanatory note>

… (more groups)

[[_TOC_]]            ← literally this line, on its own, followed by a blank line

## Group <Group-A>

### <Project-1>

<Project details>

### <Project-2>

<Project details>

…

## Group <Group-B>

### <Project-n>

<Project details>

Key points:

  1. Static introduction (# Overview over GitLab Readmes followed by a blank line, followed by ## Summary with another blank line).

  2. Each summary group heading is level-3 (###).

  3. After all summary tables, the literal [[_TOC_]] marker is emitted (without spaces), enabling Markdown processors to inject a Table of Contents.

  4. The detailed part uses a level-2 heading ## Group <Name> (singular word Group included) and then level-3 headings ### <Project> for individual projects.


2. Summary Tables

  • The table follows all rules in Table Rendering & UI (m-dash placeholder, custom labels …).

  • Repository column value is a Markdown link to the projects web_url. If an avatar is available the link text is preceded by ![Avatar](<url>){width=16px}.

  • Immediately below the table after a blank line a generic explanatory note is included: Note: If no supervisors were found, authors of the README are named as supervisors. (localised wording may vary but must convey the same information).

  • A blank line separates this note from the next group heading.


3. Project Detail Sections

General: Callout blocks are using Obsidian-style syntax: > [!tip] Block-Title, > [!warning] Block-Title, > [!note] Block-Title … Each block may span multiple lines and include Markdown inside. All lines of this block must properly begin with > to make them part of the callout. The title are offset from the rest of the block by an empty line: >

  1. Description list with up to three entries in this order – Date, Status, Supervisors – each on its own line in definition-list syntax:

    Date
    : 2025-06-18
    
    Supervisors
    : Marty McFly
    : Doctor Brown
    

    If Supervisors are not Available it is substituded by Authors like so:

    Date
    : 2025-06-18
    
    Authors
    : Marty McFly
    : Doctor Brown
    

    Missing entries from the Project-Info are omitted.

    When using Readme.content in a Description call-out, the renderer must:

    1. Strip any YAML front-matter from the content

    2. Include only the first 10 non-empty lines

    3. If content was truncated, append “…continues…” on a new line

    Example:

    > [!warning] Description
    > # My Project
    > 
    > This is a great project that does many things.
    > It has multiple features:
    > 
    > - Feature 1
    > - Feature 2
    > - Feature 3
    > - Feature 4
    > …continues…
    
  2. Release badge – image linking to <web_url>/-/releases.

  3. Description callout titled Description with (first applicable)

    • If frontmatter has a description-key: callout-type tip and content frontmatter[“description”]

    • If Readme.content is not None or empty: callout-type warning and contend from Readme.content

    • If Readme.content is None: callout-type danger and content “No Readme found”

  4. Issues callout titled Open Issues with (first applicable)

    • If Project.issues is not None: callout-type tip and content containing bullet list items of opened issues, each item is a link to the GitLab issue. After the list one TOTAL: line summarises opened and closed counts. If no issues are opened, content is “No issues open.”

    • If Readme.todo is not None or empty: callout-type warning and content from Readme.todo

    • If Readme.todo is None: callout-type danger and content “No TODOs found.”

  5. Final paragraph: [Link to full readme](<readme_url>).

Blank lines separate each logical part; no extra thematic breaks.


4. Ordering Guarantees

  • Groups are ordered by the number of Projects rendered (alphabetically on a tie).

  • Summary project order mirror the incoming, already-sorted data (see Table Sorting).

  • In the detailed part, projects appear alphabetically by their name.


5. Relation to Other Specifications

  • Consumes sorted & grouped data from Table Rendering & UI.

  • Reuses placeholders and cell formatting rules defined there.

  • Reads metadata extracted by the Model Mapping and enriched by the Data Collector.


6. Out of Scope

  • Everything related to DataCollection, API or Network. This is only model ~> markdown.

  • No other renderer that output data on their own (i.e. quarto)


7. Implementation Interface (Class-based Contract)

All Markdown renderers must implement a class-based interface as follows:

  • Inherit from the abstract base class Renderer (see src/gitlab_overviewer/rendering/renderer_base.py).

  • Implement the following methods:

    • render(self, overview_data, ...) -> str: Render the output as a string.

    • write_files(self, overview_data, ...) -> None: Write the rendered output to files as specified.

  • Render-agnostic helpers (e.g., placeholder handling, star rating, safe conversion) are provided as @staticmethods on Renderer and should be used by all subclasses.

Rationale:

  • This contract enforces consistency and extensibility for all renderers.

  • It enables robust testing, code reuse, and future support for additional output formats (e.g., HTML, PDF).

  • The interface is enforced in code and validated by the test suite.

This is an internal code structure requirement and does not affect the output format, but all new renderers must comply.

Open Questions:

  • Should future renderers (e.g., HTML, PDF) follow this interface? (TBD)

  • Are there additional common methods that should be included in the base interface? (TBD)

    • See TODOs in Renderer base class for possible candidates.