I definitely prefer the CSS approach if possible, but this seems to work…
In your templates, replace .Content
with:
{{ $c := .Content }}
{{ range $k, $_ := findRE `<p>.*?</p>` $c }}
{{ $paragraphId := printf "p-%03d" (add 1 $k) }}
{{ $newParagraph := replaceRE `<p>` (printf "<p id=%q>" $paragraphId) . }}
{{ $c = strings.Replace $c . $newParagraph 1 }}
{{ end }}
{{ $c | safeHTML}}
For a smallish site, OK. For a large site, no (performance).