#!/usr/bin/env nu # Linkify ADR mentions in outreach/web/src/*.html. # # Two passes per file: # 1. Fix href format: absolute https://ontoref.dev/adr/adr-NNN → site-relative /adr/NNN # 2. Wrap plain ADR-NNN text (not already inside ...) with a link # # All hrefs use site-relative paths (/adr/NNN) so links work in both localhost # and production without domain changes. # Single-quotes are used for injected href/title/class attributes so the link # is safe inside both text nodes and double-quoted data-en/data-es attributes. # # Usage (from outreach/site): # nu scripts/build/linkify-adrs.nu # nu scripts/build/linkify-adrs.nu --map site/public/r/adr-map.json --web ../../outreach/web --daemon https://ontoref.dev def escape-attr [s: string] { $s | str replace --all '&' '&' | str replace --all '<' '<' | str replace --all '>' '>' | str replace --all "'" ''' | str replace --all '"' '"' } def main [ --map: string = "site/public/r/adr-map.json" --web: string = "../../outreach/web" --daemon: string = "https://ontoref.dev" # used only to recognise existing absolute hrefs to fix ] { let adr_map = (open $map) let web_dir = ($web | path expand) let src_dir = ($web_dir | path join "src") if not ($src_dir | path exists) { error make { msg: $"src dir not found: ($src_dir)" } } let files = (glob $"($src_dir)/*.html" | sort) mut total_files = 0 mut total_changes = 0 for f in $files { mut content = (open --raw $f) let original = $content # Sort ADRs longest-id-first so adr-010 doesn't shadow adr-0100 (hypothetical), # and to process higher numbers first (safer for text replacement ordering). let adrs = ($adr_map | transpose key val | sort-by key --reverse) for entry in $adrs { let id = $entry.key # "adr-009" let val = $entry.val let num = ($id | str replace 'adr-' '') # "009" let adr_upper = $"ADR-($num)" # "ADR-009" let path = $"/adr/($num)" # "/adr/009" — site-relative, works everywhere let safe_name = (escape-attr ($val.name? | default "")) # Pass 1: fix existing absolute hrefs to the canonical site-relative path. # Handles double-quoted (original manual links) and single-quoted (injected links). $content = ($content | str replace --all $"href=\"($daemon)/adr/($id)\"" $"href=\"($path)\"") $content = ($content | str replace --all $"href=\"($daemon)/adr/($num)\"" $"href=\"($path)\"") $content = ($content | str replace --all $"href='($daemon)/adr/($id)'" $"href='($path)'") $content = ($content | str replace --all $"href='($daemon)/adr/($num)'" $"href='($path)'") # Pass 2: linkify plain ADR-NNN not already followed by # Uses single-quote attrs: safe inside double-quoted HTML attribute values. let link = $"($adr_upper)" let pattern = $"ADR-($num)\(?!\)" $content = ($content | str replace --all --regex $pattern $link) } if $content != $original { $content | save -f $f let linked_after = ($content | find --regex "ADR-[0-9]{3}" | length) print $" ($f | path basename): updated" $total_files = ($total_files + 1) $total_changes = ($total_changes + 1) } } print $"linkify-adrs: ($total_files) files updated" }