Specification: Quarto Renderer (index.qmd + project sheets)

This document formalises the structure of the Quarto artefacts generated by the GitLab-Overview pipeline. The renderer emits one site root file (index.qmd) and a collection of per-project .qmd sheets organised in sub-directories that mirror GitLab groups. The output is meant to compile with Quarto for publishing on Confluence via the built-in confluence-html format.


1. Directory & Naming Conventions

quarto/
  index.qmd                ← overview landing page
  <group-dir>/             ← one directory per GitLab group (slug derived from group.path)
    <project-slug>.qmd     ← individual project sheet
    …
  • group-dir derives from group.path.

  • project-slug derives from project.path_with_namespace.

  • Some groups may have subgroups. This is reflected in the directory-structure. project.path_with_namespace has the complete structure for each project.


2. index.qmd

2.1 YAML Front-Matter

---
title: "Gitlab-Übersicht"
format: confluence-html
toc: true
---
  • No additional keys are added without explicit specification; stability of diff against snapshot is critical.

  • The built-in toc: true replaces the manual [[TOC]] marker used in the Markdown renderer.

2.2 Summary Section

The section follows the same rules as in Markdown Overview Renderer.

## Summary

### <Group-Name>
<Table>
<Explanatory note>

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

  • Repository column value is a Markdown link to the project’s sheet (<group-dir>/<project-slug>.qmd). If an avatar is available the link text is preceded by ![Avatar](<url>){width=16px}.

  • The explanatory note is a fixed sentence:

    Note: If no supervisors were found, authors of the README are named as supervisors.

  • Blank line between note and next ### heading.

2.3 Detailed Section

After the last summary table the renderer appends one detailed section for every project, grouped by the same GitLab group order:

## Group <Group-Name>

### <Project-Name>

<Project details block>

### <Next-Project>

Ordering:

  • Groups appear in the same order as in the summary section.

  • Projects keep their summary-table order.

2.3.1 Project details block

The section follows the same rules as in Markdown Overview Renderer with the only difference being the internal link to the full readme. Both have to stay in sync for all other aspects.

  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.

  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

      • The content is truncated to the first 10 non-blank lines. If the original content is longer, it is appended with …continues…. This truncation is applied to the plain text before any markdown rendering.

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

  4. Issues callout titled Open Issues containing bullet list items, each item is a link to the GitLab issue. After the list one TOTAL: line summarises opened and closed counts.

  5. Final paragraph: [Link to full readme](<group-dir>/<project-slug>.qmd) linking to the generated project-sheet.

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


3. Per-Project Sheet (<group-dir>[/subgroups/..]/<project-slug>.qmd)

3.1 YAML Front-Matter

---
title: "<Project name> (<Group-Name>)"
format:
  confluence-html:
    code-links:
      - text: GitLab
        href: <project_web_url>
        icon: gitlab
---
  • Only the code-links array is mandated; additional Quarto keys require a spec update.

3.2 Body Structure

# <Project name> (<Group-Name>)

> [!note] README
>
> ---            ← the complete README
> title: ...
> author: ...
> date: ...
> ...

## Issues

### <Issue-Title-1>

Status: <issue-status>

<description/acceptance criteria>

… (repeat per issue)
  • The first element is an H1 mirroring the file title.

  • Immediately afterwards in an Obsidian-style callout the whole Readme gets quoted with its markdown-content.

  • Remaining content are all issues still open (or the string No open Issues after the H2 heading)


4. Placeholder Rules & Encodings

  • Missing numeric / text values in tables are rendered as m-dash .

  • Dates are formatted YYYY-MM-DD.

  • Dates can come from multiple sources. Priority is: Project.last_activity_at > Readme.extra.raw_frontmatter["date"] > Em-Dash fallback.

  • Release badge URLs, avatar images and issue links are taken verbatim from GitLab meta data; renderer does not rewrite them.


5. Compatibility Contract

  • index.qmd plus all project sheets generated must compile with quarto render without warnings.

  • For regression tests, rendering single group “Alpha Group” from @gold_data/ must produce output identical to tests/snapshots/quarto_renderer_single.qmd.

  • Any deliberate deviation requires a snapshot update and changelog entry.


6. Error Handling

Situation

Behaviour

README missing

Project sheet still generated; [!note]-callout becomes a [!warning] No README found!

Release badge URL unreachable

Badge image is still emitted (broken link tolerated).

Issues API returns error

Omit issues callout; do not fail rendering.


7. Relationship to Other Specifications

  • Table cells & ordering rules follow Table Rendering & UI and Table Sorting.

  • Source data is provided by Data Collector and mapped via Model Mapping.


8. Implementation Interface (Class-based Contract)

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