]> Git — Sourcephile - julm/rezine-rfcs.git/blob - scripts/lib.sh
d6b6ebef7b1e58a2bd9844f70c8add7e679ae354
[julm/rezine-rfcs.git] / scripts / lib.sh
1 #!/usr/bin/env bash
2 # SPDX-FileCopyrightText: 2024 Julien Moutinho (adh14) <julm+rezine@autogeree.net>
3 # SPDX-License-Identifier: AGPL-3.0-or-later
4 # shellcheck disable=SC2034
5 # shellcheck disable=SC2046
6 # shellcheck disable=SC2086
7 # shellcheck disable=SC2119
8 # shellcheck disable=SC2154
9 rfcOrga=Rézine
10 rfcRepo=rezine-rfcs
11 rfcList=rfcs
12 rfcDomain=rezine.org
13 # FIXME: host it on rezine.org?
14 rfcGitweb="https://git.sourcephile.fr/julm/$rfcRepo.git"
15
16 removeAtExit=()
17 exitHook () {
18 rm -rf "${removeAtExit[@]}"
19 }
20 trap exitHook EXIT
21
22 rfcDirMetadata () {
23 rfcRoot=$(realpath --relative-to . "${0%/*}"/..)
24 rfcDir=$(realpath --relative-to "$rfcRoot" "$rfcDir")
25 rfcBranch=$(realpath --relative-to "$rfcRoot"/rfcs "$rfcDir")
26 rfcYear=$(git log -1 --pretty=%cd --date=format:%Y "$rfcDir/advocacy.md")
27 rfcDate=$(git log -1 --pretty=%cd --date=short "$rfcDir/advocacy.md")
28 }
29
30 rfcRevision () {
31 local advocacyLatestCommit criticismsLatestCommit
32 advocacyLatestCommit=$(git rev-list --max-count=1 HEAD -- "$rfcDir/advocacy.html")
33 criticismsLatestCommit=$(git rev-list --max-count=1 HEAD -- "$rfcDir/criticisms.html")
34 rfcTagAdvocacyOld="$(git describe --tags "$advocacyLatestCommit")" || true
35 rfcTagCriticismsOld="$(git describe --tags "$criticismsLatestCommit")" || true
36 if test "${rfcTagAdvocacyOld#"${rfcBranch}v"}" != "$rfcTagAdvocacyOld"
37 then IFS=psvc read -r _ _num rfcRevAdvocacy _ <<<"$rfcTagAdvocacyOld"
38 else rfcRevAdvocacy=0; rfcTagAdvocacyOld=init
39 fi
40 if test "${rfcTagCriticismsOld#"${rfcBranch}v"}" != "$rfcTagCriticismsOld"
41 then IFS=psvc read -r _ _num _rfcRevAdvocacy rfcRevCriticisms _ <<<"$rfcTagCriticismsOld"
42 else rfcRevCriticisms=0; rfcTagCriticismsOld=init
43 fi
44 rfcBranchRevision="${rfcBranch}v${rfcRevAdvocacy}"
45 rfcTag="${rfcBranch}c$rfcRevCriticisms"
46 }
47
48 rfcCitation () {
49 local templateFile metaFile
50 templateFile=$(mktemp --suffix ".md")
51 metaFile=$(mktemp --suffix ".md")
52 removeAtExit+=("$templateFile" "$metaFile")
53 # \${rfcOrga} <[RFC\${rfcTag}](mailto:\${rfcList}+\${rfcTag}@\${rfcDomain})>
54 # — « *\${title}* » — \${rfcDate} — série *Requests for Criticisms*
55 # — \${RFC-Category} « \` \${rfcBranch}\` »,
56 # plaidoirie « \` \${rfcRevisionAdvocacy}\` »,
57 # critiques « \` \${rfcRevisionCriticisms}\` »
58 # — \${for(RFC-Compasses)}boussole \${it}\${sep} & \${endfor}
59 # — <<\${rfcGitweb}/blob_plain/\${rfcTag}:/rfcs/\${rfcBranch}/index.html>>.
60 cat >"$templateFile" <<EOF
61 [
62 {
63 "id": "\${rfcOrga}RFC\${rfcBranchRevision}",
64 "title": "RFC\${rfcBranchRevision} — \${title}",
65 "title-short": "RFC\${rfcBranchRevision}",
66 "type": "article-journal",
67 "publisher": "\${rfcOrga}",
68 "genre": "Requests for Criticisms",
69 "collection-title": "\${RFC-Category}",
70 "volume": "\${rfcBranch}",
71 "issue": "v\${rfcRevAdvocacy}",
72 "issued": { "date-parts": [ [ \${rfcYear} ] ] },
73 "URL": "\${rfcGitweb}/blob_plain/\${rfcBranchRevision}:/rfcs/\${rfcBranch}/index.html",
74 "author": [
75 \${for(RFC-Authors)}
76 {
77 "non-dropping-particle": "boussole",
78 "family": "\${it.boussole}",
79 "given": "\${it.nom}",
80 "email": "\${it.email}"
81 }
82 \${sep},
83 \${endfor}
84 ]
85 }
86 ]
87 EOF
88 mkdir -p "$rfcRoot/rfcs/$rfcBranch/citation"
89 pandoc \
90 --wrap none \
91 $(rfcMetadata) \
92 --template "$templateFile" \
93 "$sourceFile" >"$rfcRoot/rfcs/$rfcBranch/citation/v${rfcRevAdvocacy}.script.csl.json"
94 }
95
96 rfcSource () {
97 if test ! "${rfcNoAdvocacy:+set}"; then
98 cat - "$rfcDir"/advocacy.md <<EOF
99 ::: information
100 Ce document est publié sous licence
101 [\${SPDX-License-Identifier}](https://spdx.org/licenses/\${SPDX-License-Identifier}.html).
102
103 Pour le citer :
104
105 > \${rfcOrga} <[RFC\${rfcTag}](mailto:\${rfcList}+\${rfcTag}@\${rfcDomain})>
106 > — « *\${title}* » — \${rfcDate} — série *Requests for Criticisms*
107 > — \${RFC-Category} « \` \${rfcBranch}\` »,
108 > plaidoirie « \` \${rfcRevisionAdvocacy}\` »,
109 > critiques « \` \${rfcRevisionCriticisms}\` »
110 > — \${for(RFC-Authors)}boussole \${it.boussole} ([\${it.nom}](mailto:\${it.email}))\${sep} & \${endfor}
111 > — <<\${rfcGitweb}/blob_plain/\${rfcTag}:/rfcs/\${rfcBranch}/index.html>>.
112
113 Vous _devriez_ consulter en priorité sa dernière version
114 qui est disponible en ligne à l'adresse :
115 <<\${rfcGitweb}/blob_plain/\${rfcBranch}:/rfcs/\${rfcBranch}/index.html>>
116
117 - Statut de cette révision : « \${RFC-Phase} »
118 :::
119
120 EOF
121 printf '\n'
122 fi
123 if test ! "${rfcNoHistory:+set}"; then
124 cat "$rfcDir"/history.md
125 printf '\n'
126 fi
127 if test ! "${rfcNoCriticisms:+set}"; then
128 cat "$rfcDir"/criticisms.md
129 fi
130 cat <<EOF
131
132 # Références
133
134 ::: {#refs}
135 :::
136
137 EOF
138 }
139
140 rfcMetadata () {
141 printf ' --metadata %s' \
142 rfcBranch="$rfcBranch" \
143 rfcDate="$rfcDate" \
144 rfcDir="$rfcDir" \
145 rfcDomain="$rfcDomain" \
146 rfcGitweb="$rfcGitweb" \
147 rfcList="$rfcList" \
148 rfcOrga="$rfcOrga" \
149 rfcRepo="$rfcRepo" \
150 rfcBranchRevision="$rfcBranchRevision" \
151 rfcRevAdvocacy="$rfcRevAdvocacy" \
152 rfcRevisionAdvocacy="v$rfcRevAdvocacy" \
153 rfcRevisionCriticisms="c$rfcRevCriticisms" \
154 rfcTag="$rfcTag" \
155 rfcYear="$rfcYear"
156 # --metadata-file provides defaults,
157 # its metadata do not override the document's metadata.
158 printf ' --metadata-file %s' "$metaFile"
159 cat >"$metaFile" <<EOF
160 ---
161 title: "[RFC${rfcBranch}]"
162 ...
163 EOF
164 }
165
166 rfcTemplate () {
167 local sourceFile metaFile
168 sourceFile=$(mktemp --suffix ".md")
169 metaFile=$(mktemp --suffix ".md")
170 removeAtExit+=("$sourceFile" "$metaFile")
171 rfcSource >"$sourceFile"
172 rfcCitation
173 pandoc \
174 --wrap none \
175 $(rfcMetadata) \
176 --template "$sourceFile" \
177 "$sourceFile" | "$@"
178 }
179
180 rfcPlain () {
181 rfcTemplate \
182 pandoc --from markdown+emoji --to plain \
183 --citeproc \
184 --csl "$rfcRoot"/styles/rfc.csl \
185 $(printf " --bibliography %s" "$rfcRoot"/refs/*.json \
186 "$rfcRoot"/rfcs/*/citation/*.csl.json) \
187 --lua-filter "$rfcRoot"/styles/rfc.lua \
188 --variable lang=fr-FR \
189 "$@"
190 }
191
192 rfcMarkdown () {
193 rfcTemplate \
194 pandoc --from markdown+emoji --to markdown+emoji \
195 --table-of-contents \
196 --toc-depth 6 \
197 --number-sections \
198 --citeproc \
199 --csl "$rfcRoot"/styles/rfc.csl \
200 $(printf " --bibliography %s" "$rfcRoot"/refs/*.json \
201 "$rfcRoot"/rfcs/*/citation/*.csl.json) \
202 --lua-filter "$rfcRoot"/styles/rfc.lua \
203 --variable lang=fr-FR \
204 "$@"
205 }
206
207 rfcHTML () {
208 rfcTemplate \
209 pandoc --from markdown+emoji --to html5 \
210 --standalone \
211 --embed-resources \
212 --include-in-header "$rfcRoot"/styles/rfc.header.html \
213 --table-of-contents \
214 --toc-depth 6 \
215 --number-sections \
216 --citeproc \
217 --csl "$rfcRoot"/styles/rfc.csl \
218 $(printf " --bibliography %s" "$rfcRoot"/refs/*.json \
219 "$rfcRoot"/rfcs/*/citation/*.csl.json) \
220 --lua-filter "$rfcRoot"/styles/rfc.lua \
221 --variable lang=fr-FR \
222 "$@"
223 }
224
225 rfcPDF () {
226 rfcTemplate \
227 pandoc --from markdown+emoji --to pdf \
228 --pdf-engine lualatex \
229 --include-in-header "$rfcRoot"/styles/rfc.header.tex \
230 --standalone \
231 --embed-resources \
232 --table-of-contents \
233 --toc-depth 6 \
234 --number-sections \
235 --citeproc \
236 --csl "$rfcRoot"/styles/rfc.csl \
237 $(printf " --bibliography %s" "$rfcRoot"/refs/*.json) \
238 --lua-filter "$rfcRoot"/styles/rfc.lua \
239 --variable colorlinks=true \
240 --variable lang=fr-FR \
241 --variable links-as-notes=true \
242 "$@"
243 }
244
245 rfcTag () {
246 git reset
247 git diff --exit-code -- "$rfcDir" :'!*.html'
248
249 : "Check if \$rfcRevAdvocacy must be increased."
250 rfcNoCriticisms="set" \
251 rfcNoHistory="set" \
252 rfcHTML -o "$rfcDir"/advocacy.html
253 git add "$rfcDir"/advocacy.html
254 rfcRevAdvocacyIncrement=0
255 if ! git diff --cached --quiet "$rfcDir"/advocacy.html; then
256 rfcRevAdvocacyIncrement=1
257 # Note that $rfcRevCriticisms is not reset:
258 # criticisms have their own independant revisions
259 # because, in practice, criticisms to an old $rfcRevAdvocacy
260 # can be received and added after a new $rfcRevAdvocacy has been tagged.
261 fi
262
263 : "Check if \$rfcRevCriticisms must be increased."
264 rfcRevAdvocacy="1" \
265 rfcNoAdvocacy="set" \
266 rfcNoHistory="set" \
267 rfcHTML -o "$rfcDir"/criticisms.html
268 git add "$rfcDir"/criticisms.html
269 rfcRevCriticismsIncrement=0
270 if ! git diff --cached --quiet "$rfcDir"/criticisms.html; then
271 rfcRevCriticismsIncrement=1
272 fi
273
274 if test "$rfcRevAdvocacyIncrement" -gt 0 ||
275 test "$rfcRevCriticismsIncrement" -gt 0
276 then
277 rfcRevAdvocacy=$((rfcRevAdvocacy + rfcRevAdvocacyIncrement))
278 rfcRevCriticisms=$((rfcRevCriticisms + rfcRevCriticismsIncrement))
279 rfcBranchRevision="${rfcBranch}v$rfcRevAdvocacy"
280 rfcTag="${rfcBranchRevision}c$rfcRevCriticisms"
281 rfcNoCriticisms="set" \
282 rfcNoHistory="set" \
283 rfcHTML -o "$rfcDir"/advocacy.html
284 rfcRevAdvocacy="1" \
285 rfcNoAdvocacy="set" \
286 rfcNoHistory="set" \
287 rfcHTML -o "$rfcDir"/criticisms.html
288 rfcHTML -o "$rfcDir"/index.html
289 #rfcPDF -o "$rfcDir/${rfcRepo}-${rfcBranch}".pdf
290 git add "$rfcDir"/{advocacy,criticisms,index}.html
291 #git add "$rfcDir/${rfcRepo}-${rfcBranch}".pdf
292 git diff --cached --quiet ||
293 git commit -m "$rfcBranch: v$rfcRevAdvocacy c$rfcRevCriticisms"
294 git tag --force --sign --message "${rfcOrga} RFC${rfcTag}" "$rfcTag"
295 fi
296 }