GitRoot

Craft your forge, Build your project, Grow your community freely
 1// SPDX-FileCopyrightText: 2026 Romain Maneschi <romain@gitroot.dev>
 2//
 3// SPDX-License-Identifier: EUPL-1.2
 4
 5package main
 6
 7import (
 8	"fmt"
 9	"strconv"
10	"strings"
11)
12
13type renderer interface {
14	renderPage(pageBuilder *strings.Builder, lines []CacheLineRelativeLink)
15}
16
17type globalRenderer struct {
18	conf     Conf
19	renderer renderer
20}
21
22func (p *Plugin) NewRenderer(conf Conf) globalRenderer {
23	var renderer renderer
24	switch conf.Format {
25	case "table":
26		renderer = NewRendererTable(conf)
27	case "embed":
28		renderer = NewRendererEmbed(conf, p.server)
29	case "list":
30		renderer = NewRendererList(conf)
31	case "task":
32		renderer = NewRendererList(conf)
33	case "alphabetic":
34		renderer = NewRendererAlphabetic(conf)
35	case "custom":
36		renderer = NewRendererCustom(conf)
37	}
38
39	return globalRenderer{
40		conf:     conf,
41		renderer: renderer,
42	}
43}
44
45type CacheLineRelativeLink struct {
46	line         CacheLine
47	relativePath string
48}
49
50func (r globalRenderer) renderPage(lines []CacheLine) string {
51	pageBuilder := strings.Builder{}
52	if len(r.conf.Metadata) > 0 {
53		pageBuilder.WriteString("---\n")
54		fmt.Fprintf(&pageBuilder, "title: %s\n", r.interpolateVars(r.conf.Title, lines))
55		for k, v := range r.conf.Metadata {
56			pageBuilder.WriteString(k)
57			pageBuilder.WriteString(": ")
58			pageBuilder.WriteString(r.interpolateVars(v, lines))
59			pageBuilder.WriteString("\n")
60		}
61		pageBuilder.WriteString("---\n\n")
62	}
63	fmt.Fprintf(&pageBuilder, "# %s\n\n", r.interpolateVars(r.conf.Title, lines))
64	if r.conf.Description != "" {
65		fmt.Fprintf(&pageBuilder, "%s\n\n", r.interpolateVars(r.conf.Description, lines))
66	}
67	linesRel := make([]CacheLineRelativeLink, len(lines))
68	for i, line := range lines {
69		linesRel[i] = CacheLineRelativeLink{line: line, relativePath: r.conf.relativePath(line.fp)}
70	}
71	r.renderer.renderPage(&pageBuilder, linesRel)
72	return pageBuilder.String()
73}
74
75func (r globalRenderer) interpolateVars(toInterpolate string, lines []CacheLine) string {
76	if len(lines) > 0 {
77		if before, numSelect, ok := strings.Cut(toInterpolate, "$select["); ok {
78			if numSelect, after, ok2 := strings.Cut(numSelect, "]"); ok2 {
79				i, err := strconv.Atoi(numSelect)
80				if err == nil {
81					return fmt.Sprintf("%s%s%s", before, lines[0].selects[i], after)
82				}
83			}
84		}
85	}
86	return toInterpolate
87}