main
html 58 lines 3.08 KB
Raw
1 {{- /*
2 Repo trend visualization — a lightweight, locally-rendered bar chart for a
3 numeric series (e.g. star history or weekly momentum). Deterministic and
4 dependency-free. Accessible: bars are aria-hidden decoration; the real data is
5 exposed as a visually-hidden description and an optional caption.
6
7 Params (dict):
8 values : slice of numbers (required)
9 labels : optional slice of strings, aligned to values
10 repo : optional repo slug for the heading/link
11 heading : optional heading text
12 level : optional heading level (default "h3")
13 caption : optional caption / source text
14 */ -}}
15 {{- $values := .values | default slice -}}
16 {{- $labels := .labels | default slice -}}
17 {{- $repo := .repo | default "" -}}
18 {{- /* An empty/omitted repo is treated as absent: fall back to the plain
19 heading rather than emitting a broken "<empty> — trend" string. */ -}}
20 {{- $heading := .heading | default (cond (ne $repo "") (printf "%s — trend" $repo) "Trend") -}}
21 {{- $level := .level | default "h3" | lower -}}
22 {{- if not (in (slice "h2" "h3" "h4" "h5" "h6") $level) }}{{ $level = "h3" }}{{ end -}}
23 {{- /* $level is strictly whitelisted above, so the tag name is safe to emit;
24 the heading text itself remains contextually auto-escaped. */ -}}
25 {{- $hOpen := printf `<%s class="repo-trend__heading">` $level | safeHTML -}}
26 {{- $hClose := printf "</%s>" $level | safeHTML -}}
27 {{- $caption := .caption -}}
28 {{- if gt (len $values) 0 -}}
29 {{- $max := 0.0 -}}
30 {{- range $values }}{{ if gt (float .) $max }}{{ $max = (float .) }}{{ end }}{{ end -}}
31 {{- if le $max 0.0 }}{{ $max = 1.0 }}{{ end -}}
32 {{- $n := len $values -}}
33 {{- $summary := slice -}}
34 {{- range $i, $v := $values -}}
35 {{- $lab := cond (gt (len $labels) $i) (index $labels $i) (printf "Point %d" (add $i 1)) -}}
36 {{- $summary = $summary | append (printf "%s: %s" $lab (lang.FormatNumber 0 $v)) -}}
37 {{- end -}}
38 <figure class="repo-trend" role="group" aria-label="{{ $heading }}">
39 {{ $hOpen }}
40 {{- if $repo }}<a href="https://github.com/{{ $repo }}" aria-label="Open GitHub repository {{ $repo }}">{{ $heading }}</a>{{ else }}{{ $heading }}{{ end -}}
41 {{ $hClose }}
42 <svg class="repo-trend__chart" viewBox="0 0 {{ mul $n 100 }} 320" preserveAspectRatio="none" aria-hidden="true" focusable="false">
43 {{- $slot := 100 -}}
44 {{- range $i, $v := $values -}}
45 {{- $h := math.Round (mul (div (float $v) $max) 300.0) -}}
46 {{- if lt $h 3.0 }}{{ $h = 3.0 }}{{ end -}}
47 {{- $x := add (mul $i $slot) 22 -}}
48 {{- $y := sub 320 $h -}}
49 <rect x="{{ $x }}" y="{{ $y }}" width="56" height="{{ $h }}" rx="4" />
50 {{- end -}}
51 </svg>
52 <p class="visually-hidden">{{ $heading }}. {{ delimit $summary "; " }}.</p>
53 {{- /* Render the caption as a safe inline subset (#329): allow simple
54 emphasis/links from Markdown, but strip any <img> the markdown image
55 syntax would emit so no third-party/hotlinked imagery can slip in. */ -}}
56 {{- with $caption }}<figcaption class="repo-trend__caption">{{ . | markdownify | replaceRE `(?i)<img[^>]*>` "" | safeHTML }}</figcaption>{{ end }}
57 </figure>
58 {{- end -}}