#!/bin/bash # Scriptum ad preces e Divinum Officium extrahendas # Auctor: Adam Kasprzak # Data: 2026-01-13 set -o pipefail if [ $# -eq 0 ]; then echo "Usus: $0 [laudes|prima|tertia|sexta|nona|vesperae]" exit 1 fi HORA_INPUT="$1" HORA="$(echo "${HORA_INPUT:0:1}" | tr '[:lower:]' '[:upper:]')$(echo "${HORA_INPUT:1}" | tr '[:upper:]' '[:lower:]')" case "$HORA" in Laudes|Prima|Tertia|Sexta|Nona|Vesperae) ;; *) echo "Error: Argumentum invalidum: '$HORA_INPUT'" echo "Valida: laudes, prima, tertia, sexta, nona, vesperae" exit 1 ;; esac BASE_URL="https://www.divinumofficium.com/cgi-bin/horas/officium.pl" URL="${BASE_URL}?command=pray${HORA}" USE_COLOR=1 if [ ! -t 1 ] || [ "${NO_COLOR:-0}" = "1" ]; then USE_COLOR=0 fi WRAP="${WRAP:-80}" # word-wrap width (no justify) echo echo echo " ?8888P" echo " \`88'" echo " 8b,_ 88 _,d8" echo " 88888SEAL88888" echo " 8P~ 88 ~?8" echo " ,88." echo " d8888b" echo "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-" echo "Hora: $HORA" echo "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-" echo HTML="$(curl -s "$URL")" if [ $? -ne 0 ] || [ -z "$HTML" ]; then echo "Error: Pagina recipi non potuit (curl error vel responsum vacuum)." exit 1 fi echo "$HTML" | awk ' /Incipit<\/I><\/B><\/FONT>/ { printing=1 } printing { if (/
[0-9]+/) in_english=1 if (/<\/TR>/) { in_english=0; print "" } if (!in_english) print } /<\/TABLE>/ && printing { exit } ' | \ sed 's/<[^>]*>//g' | \ sed -E 's/^[0-9]+:[0-9]+[[:space:]]*//' | \ sed 's/ / /g' | \ sed 's/ / /g' | \ sed 's/<//g' | \ sed 's/&/\&/g' | \ sed 's/&#[0-9]*;//g' | \ # remove parentheses ranges after Psalm number: Psalmus 54(17-24) -> Psalmus 54 sed -E 's/^(Psalmus[[:space:]]+[0-9]+)\([^)]*\)/\1/' | \ cat -s | \ grep -v "^Top" | \ grep -v "^Next" | \ grep -v "^[0-9]$" | \ # blank lines between antiphon and psalm title; and before closing antiphon after V/. R/. awk ' function is_ant(s) { return (s ~ /^Ant\./) } function is_psalm(s) { return (s ~ /^Psalmus[[:space:]]+[0-9]+/) } function is_vr(s) { return (s ~ /^[VR]\.\//) } { cur = $0 if (is_psalm(cur) && is_ant(prev) && prev != "") { print prev print "" print cur prev="" next } if (is_ant(cur) && is_vr(prev) && prev != "") { print prev print "" print cur prev="" next } if (prev != "") print prev prev = cur } END { if (prev != "") print prev } ' | \ # word-wrap (no justify), preserve indentation awk -v wrap="$WRAP" ' function ltrim(s){ sub(/^[[:space:]]+/, "", s); return s } function rtrim(s){ sub(/[[:space:]]+$/, "", s); return s } function trim(s){ return rtrim(ltrim(s)) } function wrap_line(indent, text, limit, n,i,words,line,tmp){ text = trim(text) if (text == "") { print ""; return } gsub(/[[:space:]]+/, " ", text) n = split(text, words, " ") line = "" for (i=1; i<=n; i++){ tmp = (line == "" ? words[i] : line " " words[i]) if (length(tmp) <= limit) { line = tmp } else { print indent line line = words[i] } } if (line != "") print indent line } { raw = $0 if (raw ~ /^[[:space:]]*$/) { print ""; next } # keep existing indentation indent = "" match(raw, /^[[:space:]]*/) indent = substr(raw, RSTART, RLENGTH) text = substr(raw, RLENGTH+1) # wrap only if needed if (length(raw) > wrap) { lim = wrap - length(indent) if (lim < 20) lim = 20 wrap_line(indent, text, lim) } else { print raw } } ' | \ # pretty print (colors + indentation unchanged; grey for [] and {}) awk -v use_color="$USE_COLOR" ' BEGIN{ reset="\033[0m"; bold="\033[1m"; dim="\033[2m" red="\033[31m"; green="\033[32m"; yellow="\033[33m" blue="\033[34m"; mag="\033[35m"; cyan="\033[36m" gray="\033[90m" if (!use_color) { reset=bold=dim=red=green=yellow=blue=mag=cyan=gray="" } } function trim(s){ gsub(/^[[:space:]]+|[[:space:]]+$/, "", s); return s } function gray_blocks(s, cur, rep){ rep = gray "&" cur gsub(/\[[^]]+\]/, rep, s) gsub(/\{[^}]*\}/, rep, s) return s } function blank_before_if_needed(t){ if (t ~ /^(Oremus\.?|Conclusio)$/ && prev_blank == 0) print "" } { raw = $0 if (raw ~ /^[[:space:]]*$/) { print ""; prev_blank=1; next } t = trim(raw) blank_before_if_needed(t) prev_blank=0 prefix="" # headings in RED if (t == "Incipit" || t == "Hymnus") { prefix = bold red } else if (t ~ /^Psalmus[[:space:]]+[0-9]+/) { prefix = bold red } else if (t ~ /^Psalmi[[:space:]]*\{/) { prefix = dim gray } else if (t == "Conclusio") { prefix = bold red } else if (t ~ /^Ant\./) { prefix = mag } else if (t ~ /^[VR]\.\//) { prefix = green } else if (t ~ /^Gl(รณ|o)ria Patri,/) { prefix = blue } else if (t ~ /^Sicut erat/) { prefix = blue } line = gray_blocks(raw, prefix) print prefix line reset } ' echo echo "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-" echo "Finis Horae: $HORA" echo "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-"