diff options
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/all | 6 | ||||
-rwxr-xr-x | bin/any | 6 | ||||
-rwxr-xr-x | bin/capitalise | 137 | ||||
-rwxr-xr-x | bin/clone | 24 | ||||
-rwxr-xr-x | bin/colourlist | 26 | ||||
-rwxr-xr-x | bin/countdown | 23 | ||||
-rwxr-xr-x | bin/countdown2 | 30 | ||||
-rwxr-xr-x | bin/ean13 | 22 | ||||
-rwxr-xr-x | bin/embolden | 390 | ||||
-rwxr-xr-x | bin/giteval | 15 | ||||
-rwxr-xr-x | bin/italicise | 269 | ||||
-rwxr-xr-x | bin/map | 11 | ||||
-rwxr-xr-x | bin/map-db | 60 | ||||
-rwxr-xr-x | bin/pf | 38 | ||||
-rwxr-xr-x | bin/pivot | 11 | ||||
-rwxr-xr-x | bin/radix | 39 | ||||
-rwxr-xr-x | bin/reduce | 9 | ||||
-rwxr-xr-x | bin/spt | 55 | ||||
-rwxr-xr-x | bin/strjoin | 6 | ||||
-rw-r--r-- | bin/sum-down | 14 | ||||
-rwxr-xr-x | bin/sum-up | 4 | ||||
-rwxr-xr-x | bin/xmlbrowser | 39 | ||||
-rwxr-xr-x | bin/yamlbrowser | 58 |
23 files changed, 1292 insertions, 0 deletions
@@ -0,0 +1,6 @@ +#!/bin/bash + +for i in $(seq 1 $#) +do + [[ ${!i} ]] || exit 1 +done @@ -0,0 +1,6 @@ +#!/bin/bash + +for i in $(seq 1 $#) +do + [[ ${!i} ]] && exit 0 +done diff --git a/bin/capitalise b/bin/capitalise new file mode 100755 index 0000000..479c55d --- /dev/null +++ b/bin/capitalise @@ -0,0 +1,137 @@ +#!/bin/bash + + +# Latin letter small capital a: UTF-8: e1 b4 80 UTF-16BE: 1d00 +# .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F +# 1D0. ᴀ ᴁ ᴂ ᴃ ᴄ ᴅ ᴆ ᴇ ᴈ ᴉ ᴊ ᴋ ᴌ ᴍ ᴎ ᴏ +# 1D1. ᴐ ᴑ ᴒ ᴓ ᴔ ᴕ ᴖ ᴗ ᴘ ᴙ ᴚ ᴛ ᴜ ᴝ ᴞ ᴟ +# 1D2. ᴠ ᴡ ᴢ ᴣ ᴤ ᴥ ᴦ ᴧ ᴨ ᴩ ᴪ ᴫ ᴬ ᴭ ᴮ ᴯ +# 1D3. ᴰ ᴱ ᴲ ᴳ ᴴ ᴵ ᴶ ᴷ ᴸ ᴹ ᴺ ᴻ ᴼ ᴽ ᴾ ᴿ +# 1D4. ᵀ ᵁ ᵂ ᵃ ᵄ ᵅ ᵆ ᵇ ᵈ ᵉ ᵊ ᵋ ᵌ ᵍ ᵎ ᵏ +# 1D5. ᵐ ᵑ ᵒ ᵓ ᵔ ᵕ ᵖ ᵗ ᵘ ᵙ ᵚ ᵛ ᵜ ᵝ ᵞ ᵟ +# 1D6. ᵠ ᵡ ᵢ ᵣ ᵤ ᵥ ᵦ ᵧ ᵨ ᵩ ᵪ ᵫ ᵬ ᵭ ᵮ ᵯ +# 1D7. ᵰ ᵱ ᵲ ᵳ ᵴ ᵵ ᵶ ᵷ ᵸ ᵹ ᵺ ᵻ ᵼ ᵽ ᵾ ᵿ +# 1D8. ᶀ ᶁ ᶂ ᶃ ᶄ ᶅ ᶆ ᶇ ᶈ ᶉ ᶊ ᶋ ᶌ ᶍ ᶎ ᶏ +# 1D9. ᶐ ᶑ ᶒ ᶓ ᶔ ᶕ ᶖ ᶗ ᶘ ᶙ ᶚ ᶛ ᶜ ᶝ ᶞ ᶟ +# 1DA. ᶠ ᶡ ᶢ ᶣ ᶤ ᶥ ᶦ ᶧ ᶨ ᶩ ᶪ ᶫ ᶬ ᶭ ᶮ ᶯ +# 1DB. ᶰ ᶱ ᶲ ᶳ ᶴ ᶵ ᶶ ᶷ ᶸ ᶹ ᶺ ᶻ ᶼ ᶽ ᶾ ᶿ +# TODO: Greek letter small capital +declare -A smallcaps=( + [a]=$'\xe1\xb4\x80' + [æ]=$'\xe1\xb4\x81' + [b]=$'\xca\x99' + [c]=$'\xe1\xb4\x84' + [d]=$'\xe1\xb4\x85' + [e]=$'\xe1\xb4\x87' + [f]=$'\xea\x9c\xb0' + [g]=$'\xc9\xa2' + [h]=$'\xca\x9c' + [i]=$'\xc9\xaa' + [j]=$'\xe1\xb4\x8a' + [k]=$'\xe1\xb4\x8b' + [l]=$'\xca\x9f' + [m]=$'\xe1\xb4\x8d' + [n]=$'\xc9\xb4' + [o]=$'\xe1\xb4\x8f' + [œ]=$'\xc9\xb6' + [p]=$'\xe1\xb4\x98' + [q]=$'\xea\x9e\xaf' + [r]=$'\xca\x80' + [s]=$'\xea\x9c\xb1' + [t]=$'\xe1\xb4\x9b' + [u]=$'\xe1\xb4\x9c' + [v]=$'\xe1\xb4\xa0' + [w]=$'\xe1\xb4\xa1' + [x]=x # Missing + [y]=$'\xca\x8f' + [z]=$'\xe1\xb4\xa2' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +# []=$'\x1d\x' +) + +while IFS= read -r line +do + replacement="" + for i in $(seq 0 "$((${#line}-1))") + do + c1=${line:$i:1} + # if [[ $c1 =~ [a-zA-Zα-ωΑ-Ω] ]] + if [[ $c1 =~ [a-zæœ] ]] + then replacement+=${smallcaps[$c1]} + else replacement+=$c1 + fi + done + echo "$replacement" +done diff --git a/bin/clone b/bin/clone new file mode 100755 index 0000000..cfad1af --- /dev/null +++ b/bin/clone @@ -0,0 +1,24 @@ +#!/bin/bash + +set -eu + +args=() +for url in "$@" +do + case $url in + https://*|git://*) + dir=${url#*//} + dir=${dir%/*} + ;; git@*) + dir=${url#git@} + dir=${dir/://} + dir=${dir%/*} + ;; *) + args+=("$url") + continue + esac + mkdir -vp ~/src/"$dir" + cd ~/src/"$dir" + git clone --verbose --progress "${args[@]}" "$url" + args=() +done diff --git a/bin/colourlist b/bin/colourlist new file mode 100755 index 0000000..49b8442 --- /dev/null +++ b/bin/colourlist @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import tkinter +from tkinter.constants import * + +window = tkinter.Tk () +window.wm_title ('X11 Colours') + +canvas = tkinter.Canvas (window) +frame = tkinter.Frame (canvas) +scrollbar = tkinter.Scrollbar (window, command=canvas.yview) +canvas.configure (yscrollcommand=scrollbar.set) + +scrollbar.pack(fill=Y, expand=1, side=RIGHT) +canvas.pack (fill=BOTH, expand=1, side=LEFT) +canvas.create_window ((0,0), window=frame, anchor=NW) +frame.bind ("<Configure>", lambda e: canvas.configure (scrollregion=canvas.bbox ('all'))) + +with open ("/etc/X11/rgb.txt") as txt: + colours = txt.readlines () + +for r,g,b,name in ((int(l[0]),int(l[1]),int(l[2]),l[3]) for l in (colour.rstrip ().split (maxsplit=3) for colour in colours[1:])): + # Each colour band should be weighted: Half red is not as bright as half green. + tkinter.Label (frame, text=f'{name} ({r+b+g})', bg=f'#{r:02x}{g:02x}{b:02x}',fg='black' if r+g+b > 381 else 'white').pack (fill=X, expand=1) + +window.mainloop () diff --git a/bin/countdown b/bin/countdown new file mode 100755 index 0000000..59daf56 --- /dev/null +++ b/bin/countdown @@ -0,0 +1,23 @@ +#!/bin/bash + +declare -i t=$1 + +while [ $((t--)) -ne 0 ]; do + if [ $t -gt 5400 ]; then + h=$((t/3600)) + m=$(((t-(h*3600))/60)) + if [ $m -lt 10 ]; then m=0$m; fi + s=$((t%60)) + if [ $s -lt 10 ]; then s=0$s; fi + echo -en "\r$h:$m:$s " + elif [ $t -gt 90 ]; then + m=$((t/60)) + s=$((t%60)) + if [ $s -lt 10 ]; then s=0$s; fi + echo -en "\r$m:$s " + else + echo -en "\r$t " + fi + sleep 1 +done +echo -en "\r" diff --git a/bin/countdown2 b/bin/countdown2 new file mode 100755 index 0000000..615f6eb --- /dev/null +++ b/bin/countdown2 @@ -0,0 +1,30 @@ +#!/bin/bash + +if [ -z "$1" ]; then echo "usage $0 date"; exit 1; fi + +declare -ir t=`date +%s -d "$1"`; + +declare -i d=t-`date +%s`; +while [ $d -gt 0 ]; do + #yyyy-mm-ddThh:mm:ss + #ww-dd hh:mm:ss + if [ $d -gt 5400 ]; then + h=$((d/3600)) + m=$(((d-(h*3600))/60)) + if [ $m -lt 10 ]; then m=0$m; fi + s=$((d%60)) + if [ $s -lt 10 ]; then s=0$s; fi + echo -en "\r$h:$m:$s " + elif [ $d -gt 90 ]; then + m=$((d/60)) + s=$((d%60)) + if [ $s -lt 10 ]; then s=0$s; fi + echo -en "\r$m:$s " + else + echo -en "\r$d " + fi + #echo -en "\r$d\t"; + sleep 1; + d=t-`date +%s`; +done +echo -en "\r" diff --git a/bin/ean13 b/bin/ean13 new file mode 100755 index 0000000..6fd125a --- /dev/null +++ b/bin/ean13 @@ -0,0 +1,22 @@ +#!/bin/bash +while [[ $1 ]] +do +[[ ${#1} -eq 13 ]] || [[ ${#1} -eq 12 ]] || { + printf >&2 'length is %d, should be 13\n' ${#1} + exit 1 +} +declare -i checksum=0 +declare -i factor=1 +for i in {0..11} +do + v=${1:i:1} + checksum=$((checksum+factor*v)) + factor=$((factor^2)) +#printf >&2 'v: %s : cs=%d f=%d\n' "$v" $checksum $factor +done +if [[ ${#1} -eq 12 ]] +then echo "$1"$((10-checksum%10)) +else [[ $((10-checksum%10)) -eq ${1:12} ]] || exit +fi +shift +done diff --git a/bin/embolden b/bin/embolden new file mode 100755 index 0000000..75df549 --- /dev/null +++ b/bin/embolden @@ -0,0 +1,390 @@ +#!/bin/bash + +# For bold and italic we can use the Mathematical font variant mappings, +# although those are only defined for Latin and Greek. +# Latin bold capital: u1d400 - u1d419 +# Latin bold small: u1d41a - u1d433 +# Latin italic capital: u1d434 - u1d44d +# Latin italic small: u1d44e - u1d467 +# Latin bold italic capital: u1d468 - u1d481 +# Latin bold italic small: u1d482 - u1d49b +# (Script capital, script small, bold script capital, bold script small) +# (Fraktur capital, fraktur small) +# (Double-struck capital, double-struck small) +# (some Hebrew symbol variants) +# (Bold fraktur capital, bold fraktur small) +# (Sans-serif capital, sans-serif small) +# (Sans-serif bold capital, sans-serif bold small) +# (Sans-serif italic capital, sans-serif italic small) +# (Sans-serif bold italic capital, sans-serif bold italic small) +# (Monospace capital, monospace small) +# Greek bold capital: u1d6a8 - u1d6c0 +# Greek bold small: u1d6c2 - u1d6da +# Greek italic capital: u1d6e2 - u1d6fa +# Greek italic small: u1dcfc - u1d714 +# Greek bold italic capital: u1d71c - u1d734 +# Greek bold italic small: u1d736 - u1d74e +# (Greek sans-serif bold capital: u1d756 - u1d76e) +# (Greek sans-serif bold small: u1d770 - u1d788) +# (Greek sans-serif bold italic capital: u1d790 - u1d7a8) +# (Greek sans-serif bold italic small: u1d7aa - u1d7c2) +# bold digits: u1d7ce - u1d7d7 +# (double-struck digits) +# (sans-serif digits) +# (sans-serif bold digits) +# (monospace digits) +# (Arabic mathematical) +# (Arabic stretched) +# (Arabic looped) +# (Arabic double-struck) +# +# It turns out there are no Unicode control codes for marking text +# bold or italic. There are for subscript and superscript, +# and ASCII has similar codes which nobody ever uses. + +declare -A bold=( + [0]=$'\xf0\x9d\x9f\x8e' + [1]=$'\xf0\x9d\x9f\x8f' + [2]=$'\xf0\x9d\x9f\x90' + [3]=$'\xf0\x9d\x9f\x91' + [4]=$'\xf0\x9d\x9f\x92' + [5]=$'\xf0\x9d\x9f\x93' + [6]=$'\xf0\x9d\x9f\x94' + [7]=$'\xf0\x9d\x9f\x95' + [8]=$'\xf0\x9d\x9f\x96' + [9]=$'\xf0\x9d\x9f\x97' + [A]=$'\xf0\x9d\x90\x80' + [B]=$'\xf0\x9d\x90\x81' + [C]=$'\xf0\x9d\x90\x82' + [D]=$'\xf0\x9d\x90\x83' + [E]=$'\xf0\x9d\x90\x84' + [F]=$'\xf0\x9d\x90\x85' + [G]=$'\xf0\x9d\x90\x86' + [H]=$'\xf0\x9d\x90\x87' + [I]=$'\xf0\x9d\x90\x88' + [J]=$'\xf0\x9d\x90\x89' + [K]=$'\xf0\x9d\x90\x8a' + [L]=$'\xf0\x9d\x90\x8b' + [M]=$'\xf0\x9d\x90\x8c' + [N]=$'\xf0\x9d\x90\x8d' + [O]=$'\xf0\x9d\x90\x8e' + [P]=$'\xf0\x9d\x90\x8f' + [Q]=$'\xf0\x9d\x90\x90' + [R]=$'\xf0\x9d\x90\x91' + [S]=$'\xf0\x9d\x90\x92' + [T]=$'\xf0\x9d\x90\x93' + [U]=$'\xf0\x9d\x90\x94' + [V]=$'\xf0\x9d\x90\x95' + [W]=$'\xf0\x9d\x90\x96' + [X]=$'\xf0\x9d\x90\x97' + [Y]=$'\xf0\x9d\x90\x98' + [Z]=$'\xf0\x9d\x90\x99' + [a]=$'\xf0\x9d\x90\x9a' + [b]=$'\xf0\x9d\x90\x9b' + [c]=$'\xf0\x9d\x90\x9c' + [d]=$'\xf0\x9d\x90\x9d' + [e]=$'\xf0\x9d\x90\x9e' + [f]=$'\xf0\x9d\x90\x9f' + [g]=$'\xf0\x9d\x90\xa0' + [h]=$'\xf0\x9d\x90\xa1' + [i]=$'\xf0\x9d\x90\xa2' + [j]=$'\xf0\x9d\x90\xa3' + [k]=$'\xf0\x9d\x90\xa4' + [l]=$'\xf0\x9d\x90\xa5' + [m]=$'\xf0\x9d\x90\xa6' + [n]=$'\xf0\x9d\x90\xa7' + [o]=$'\xf0\x9d\x90\xa8' + [p]=$'\xf0\x9d\x90\xa9' + [q]=$'\xf0\x9d\x90\xaa' + [r]=$'\xf0\x9d\x90\xab' + [s]=$'\xf0\x9d\x90\xac' + [t]=$'\xf0\x9d\x90\xad' + [u]=$'\xf0\x9d\x90\xae' + [v]=$'\xf0\x9d\x90\xaf' + [w]=$'\xf0\x9d\x90\xb0' + [x]=$'\xf0\x9d\x90\xb1' + [y]=$'\xf0\x9d\x90\xb2' + [z]=$'\xf0\x9d\x90\xb3' + [Α]=$'\xf0\x9d\x9a\xa8' + [Β]=$'\xf0\x9d\x9a\xa9' + [Γ]=$'\xf0\x9d\x9a\xaa' + [Δ]=$'\xf0\x9d\x9a\xab' + [Ε]=$'\xf0\x9d\x9a\xac' + [Ζ]=$'\xf0\x9d\x9a\xad' + [Η]=$'\xf0\x9d\x9a\xae' + [Θ]=$'\xf0\x9d\x9a\xaf' + [Ι]=$'\xf0\x9d\x9a\xb0' + [Κ]=$'\xf0\x9d\x9a\xb1' + [Λ]=$'\xf0\x9d\x9a\xb2' + [Μ]=$'\xf0\x9d\x9a\xb3' + [Ν]=$'\xf0\x9d\x9a\xb4' + [Ξ]=$'\xf0\x9d\x9a\xb5' + [Ο]=$'\xf0\x9d\x9a\xb6' + [Π]=$'\xf0\x9d\x9a\xb7' + [Ρ]=$'\xf0\x9d\x9a\xb8' + [Σ]=$'\xf0\x9d\x9a\xba' + [Τ]=$'\xf0\x9d\x9a\xbb' + [Υ]=$'\xf0\x9d\x9a\xbc' + [Φ]=$'\xf0\x9d\x9a\xbd' + [Χ]=$'\xf0\x9d\x9a\xbe' + [Ψ]=$'\xf0\x9d\x9a\xbf' + [Ω]=$'\xf0\x9d\x9b\x80' + [α]=$'\xf0\x9d\x9b\x82' + [β]=$'\xf0\x9d\x9b\x83' + [γ]=$'\xf0\x9d\x9b\x84' + [δ]=$'\xf0\x9d\x9b\x85' + [ε]=$'\xf0\x9d\x9b\x86' + [ζ]=$'\xf0\x9d\x9b\x87' + [η]=$'\xf0\x9d\x9b\x88' + [θ]=$'\xf0\x9d\x9b\x89' + [ι]=$'\xf0\x9d\x9b\x8a' + [κ]=$'\xf0\x9d\x9b\x8b' + [λ]=$'\xf0\x9d\x9b\x8c' + [μ]=$'\xf0\x9d\x9b\x8d' + [ν]=$'\xf0\x9d\x9b\x8e' + [ξ]=$'\xf0\x9d\x9b\x8f' + [ο]=$'\xf0\x9d\x9b\x90' + [π]=$'\xf0\x9d\x9b\x91' + [ρ]=$'\xf0\x9d\x9b\x92' + [ς]=$'\xf0\x9d\x9b\x93' + [σ]=$'\xf0\x9d\x9b\x94' + [τ]=$'\xf0\x9d\x9b\x95' + [υ]=$'\xf0\x9d\x9b\x96' + [φ]=$'\xf0\x9d\x9b\x97' + [χ]=$'\xf0\x9d\x9b\x98' + [ψ]=$'\xf0\x9d\x9b\x99' + [ω]=$'\xf0\x9d\x9b\x9a' +# [𝐴̱]= +# [𝐵̱]= +# [𝐶̱]= +# [𝐷̱]= +# [𝐸̱]= +# [𝐹̱]= +# [𝐺̱]= +# [𝐻̱]= +# [𝐼̱]= +# [𝐽̱]= +# [𝐾̱]= +# [𝐿̱]= +# [𝑀̱]= +# [𝑁̱]= +# [𝑂̱]= +# [𝑃̱]= +# [𝑄̱]= +# [𝑅̱]= +# [𝑆̱]= +# [𝑇̱]= +# [𝑈̱]= +# [𝑉̱]= +# [𝑊̱]= +# [𝑋̱]= +# [𝑌̱]= +# [𝑍̱]= +# [𝑎̱]= +# [𝑏̱]= +# [𝑐̱]= +# [𝑑̱]= +# [𝑒̱]= +# [𝑓̱]= +# [𝑔̱]= +# [𝘩̱]= +# [𝑖̱]= +# [𝑗̱]= +# [𝑘̱]= +# [𝑙̱]= +# [𝑚̱]= +# [𝑛̱]= +# [𝑜̱]= +# [𝑝̱]= +# [𝑞̱]= +# [𝑟̱]= +# [𝑠̱]= +# [𝑡̱]= +# [𝑢̱]= +# [𝑣̱]= +# [𝑤̱]= +# [𝑥̱]= +# [𝑦̱]= +# [𝑧]= + [𝟢]=$'\xf0\x9d\x9f\xac' + [𝟣]=$'\xf0\x9d\x9f\xad' + [𝟤]=$'\xf0\x9d\x9f\xae' + [𝟥]=$'\xf0\x9d\x9f\xaf' + [𝟦]=$'\xf0\x9d\x9f\xb0' + [𝟧]=$'\xf0\x9d\x9f\xb1' + [𝟨]=$'\xf0\x9d\x9f\xb2' + [𝟩]=$'\xf0\x9d\x9f\xb3' + [𝟪]=$'\xf0\x9d\x9f\xb4' + [𝟫]=$'\xf0\x9d\x9f\xb5' +) + +declare -A italic=( + [A]=$'\xf0\x9d\x90\xb4' + [B]=$'\xf0\x9d\x90\xb5' + [C]=$'\xf0\x9d\x90\xb6' + [D]=$'\xf0\x9d\x90\xb7' + [E]=$'\xf0\x9d\x90\xb8' + [F]=$'\xf0\x9d\x90\xb9' + [G]=$'\xf0\x9d\x90\xba' + [H]=$'\xf0\x9d\x90\xbb' + [I]=$'\xf0\x9d\x90\xbc' + [J]=$'\xf0\x9d\x90\xbd' + [K]=$'\xf0\x9d\x90\xbe' + [L]=$'\xf0\x9d\x90\xbf' + [M]=$'\xf0\x9d\x91\x80' + [N]=$'\xf0\x9d\x91\x81' + [O]=$'\xf0\x9d\x91\x82' + [P]=$'\xf0\x9d\x91\x83' + [Q]=$'\xf0\x9d\x91\x84' + [R]=$'\xf0\x9d\x91\x85' + [S]=$'\xf0\x9d\x91\x86' + [T]=$'\xf0\x9d\x91\x87' + [U]=$'\xf0\x9d\x91\x88' + [V]=$'\xf0\x9d\x91\x89' + [W]=$'\xf0\x9d\x91\x8a' + [X]=$'\xf0\x9d\x91\x8b' + [Y]=$'\xf0\x9d\x91\x8c' + [Z]=$'\xf0\x9d\x91\x8d' + [a]=$'\xf0\x9d\x91\x8e' + [b]=$'\xf0\x9d\x91\x8f' + [c]=$'\xf0\x9d\x91\x90' + [d]=$'\xf0\x9d\x91\x91' + [e]=$'\xf0\x9d\x91\x92' + [f]=$'\xf0\x9d\x91\x93' + [g]=$'\xf0\x9d\x91\x94' + [h]=$'\xf0\x9d\x98\xa9' # Sans-serif, because f0 9d 91 95 is not assigned. + [i]=$'\xf0\x9d\x91\x96' + [j]=$'\xf0\x9d\x91\x97' + [k]=$'\xf0\x9d\x91\x98' + [l]=$'\xf0\x9d\x91\x99' + [m]=$'\xf0\x9d\x91\x9a' + [n]=$'\xf0\x9d\x91\x9b' + [o]=$'\xf0\x9d\x91\x9c' + [p]=$'\xf0\x9d\x91\x9d' + [q]=$'\xf0\x9d\x91\x9e' + [r]=$'\xf0\x9d\x91\x9f' + [s]=$'\xf0\x9d\x91\xa0' + [t]=$'\xf0\x9d\x91\xa1' + [u]=$'\xf0\x9d\x91\xa2' + [v]=$'\xf0\x9d\x91\xa3' + [w]=$'\xf0\x9d\x91\xa4' + [x]=$'\xf0\x9d\x91\xa5' + [y]=$'\xf0\x9d\x91\xa6' + [z]=$'\xf0\x9d\x91\xa7' + [Α]=$'\xf0\x9d\x9b\xa2' + [Β]=$'\xf0\x9d\x9b\xa3' + [Γ]=$'\xf0\x9d\x9b\xa4' + [Δ]=$'\xf0\x9d\x9b\xa5' + [Ε]=$'\xf0\x9d\x9b\xa6' + [Ζ]=$'\xf0\x9d\x9b\xa7' + [Η]=$'\xf0\x9d\x9b\xa8' + [Θ]=$'\xf0\x9d\x9b\xa9' + [Ι]=$'\xf0\x9d\x9b\xaa' + [Κ]=$'\xf0\x9d\x9b\xab' + [Λ]=$'\xf0\x9d\x9b\xac' + [Μ]=$'\xf0\x9d\x9b\xad' + [Ν]=$'\xf0\x9d\x9b\xae' + [Ξ]=$'\xf0\x9d\x9b\xaf' + [Ο]=$'\xf0\x9d\x9b\xb0' + [Π]=$'\xf0\x9d\x9b\xb1' + [Ρ]=$'\xf0\x9d\x9b\xb2' + [Σ]=$'\xf0\x9d\x9b\xb4' + [Τ]=$'\xf0\x9d\x9b\xb5' + [Υ]=$'\xf0\x9d\x9b\xb6' + [Φ]=$'\xf0\x9d\x9b\xb7' + [Χ]=$'\xf0\x9d\x9b\xb8' + [Ψ]=$'\xf0\x9d\x9b\xb9' + [Ω]=$'\xf0\x9d\x9b\xba' + [α]=$'\xf0\x9d\x9b\xbc' + [β]=$'\xf0\x9d\x9b\xbd' + [γ]=$'\xf0\x9d\x9b\xbe' + [δ]=$'\xf0\x9d\x9b\xbf' + [ε]=$'\xf0\x9d\x9c\x80' + [ζ]=$'\xf0\x9d\x9c\x81' + [η]=$'\xf0\x9d\x9c\x82' + [θ]=$'\xf0\x9d\x9c\x83' + [ι]=$'\xf0\x9d\x9c\x84' + [κ]=$'\xf0\x9d\x9c\x85' + [λ]=$'\xf0\x9d\x9c\x86' + [μ]=$'\xf0\x9d\x9c\x87' + [ν]=$'\xf0\x9d\x9c\x88' + [ξ]=$'\xf0\x9d\x9c\x89' + [ο]=$'\xf0\x9d\x9c\x8a' + [π]=$'\xf0\x9d\x9c\x8b' + [ρ]=$'\xf0\x9d\x9c\x8c' + [ς]=$'\xf0\x9d\x9c\x8d' + [σ]=$'\xf0\x9d\x9c\x8e' + [τ]=$'\xf0\x9d\x9c\x8f' + [υ]=$'\xf0\x9d\x9c\x90' + [φ]=$'\xf0\x9d\x9c\x91' + [χ]=$'\xf0\x9d\x9c\x92' + [ψ]=$'\xf0\x9d\x9c\x93' + [ω]=$'\xf0\x9d\x9c\x94' +# [𝐀̱]= +# [𝐁̱]= +# [𝐂̱]= +# [𝐃̱]= +# [𝐄̱]= +# [𝐅̱]= +# [𝐆̱]= +# [𝐇̱]= +# [𝐈̱]= +# [𝐉̱]= +# [𝐊̱]= +# [𝐋̱]= +# [𝐌̱]= +# [𝐍̱]= +# [𝐎̱]= +# [𝐏̱]= +# [𝐐̱]= +# [𝐑̱]= +# [𝐒̱]= +# [𝐓̱]= +# [𝐔̱]= +# [𝐕̱]= +# [𝐖̱]= +# [𝐗̱]= +# [𝐘̱]= +# [𝐙̱]= +# [𝐚̱]= +# [𝐛̱]= +# [𝐜̱]= +# [𝐝̱]= +# [𝐞̱]= +# [𝐟̱]= +# [𝐠̱]= +# [𝐡̱]= +# [𝐢̱]= +# [𝐣̱]= +# [𝐤̱]= +# [𝐥̱]= +# [𝐦̱]= +# [𝐧̱]= +# [𝐨̱]= +# [𝐩̱]= +# [𝐪̱]= +# [𝐫̱]= +# [𝐬̱]= +# [𝐭̱]= +# [𝐮̱]= +# [𝐯̱]= +# [𝐰̱]= +# [𝐱̱]= +# [𝐲̱]= +# [𝐳]= +) + +# case $0 in embolden) italicise) script) fracture) double-strike) sans-serif) monospace) stretch) loop) mathise) + +while IFS= read -r line +do for i in $(seq 0 $((${#line}-1))) + do + c1=${line:$i:1} + # if [[ ${bold[$c1]} ]] + if [[ $c1 =~ [0-9a-zA-Zα-ωΑ-Ω𝐴̱-𝑍̱𝑎̱-𝑧] ]] + then replacement+=${bold[$c1]} + else replacement+=$'\u0331'$c1 + fi + done + echo "$replacement" +done diff --git a/bin/giteval b/bin/giteval new file mode 100755 index 0000000..48d35a8 --- /dev/null +++ b/bin/giteval @@ -0,0 +1,15 @@ +#!/bin/bash + +b=$(git branch --show-current 2> /dev/null) && { + case $(env - git status --no-ahead-behind | tail -n1) in + 'nothing to commit'*) + printf '\[\e[32m\][%s]\[\e[0m\]' "$b" + ;; 'no changes added to commit'*) + printf '\[\e[33m\][%s]\[\e[0m\]' "$b" + ;; 'nothing added to commit'*) + printf '\[\e[36m\][%s]\[\e[0m\]' "$b" + ;; *) + printf '\[\e[31m\][%s]\[\e[0m\]' "$b" + esac +} +echo diff --git a/bin/italicise b/bin/italicise new file mode 100755 index 0000000..d9fcb57 --- /dev/null +++ b/bin/italicise @@ -0,0 +1,269 @@ +#!/bin/bash + + +# For bold and italic we can use the Mathematical font variant mappings, +# although those are only defined for Latin and Greek. +# Latin letter small capital a: UTF-8: e1 b4 80 UTF-16BE: 1d00 Decimal: ᴀ Octal: \016400 +# Latin bold capital: u1d400 - u1d419 +# Latin bold small: u1d41a - u1d433 +# Latin italic capital: u1d434 - u1d44d +# Latin italic small: u1d44e - u1d467 +# Latin bold italic capital: u1d468 - u1d481 +# Latin bold italic small: u1d482 - u1d49b +# (Script capital, script small, bold script capital, bold script small) +# (Fraktur capital, fraktur small) +# (Double-struck capital, double-struck small) +# (some Hebrew symbol variants) +# (Bold fraktur capital, bold fraktur small) +# (Sans-serif capital, sans-serif small) +# (Sans-serif bold capital, sans-serif bold small) +# (Sans-serif italic capital, sans-serif italic small) +# (Sans-serif bold italic capital, sans-serif bold italic small) +# (Monospace capital, monospace small) +# Greek bold capital: u1d6a8 - u1d6c0 +# Greek bold small: u1d6c2 - u1d6da +# Greek italic capital: u1d6e2 - u1d6fa +# Greek italic small: u1dcfc - u1d714 +# Greek bold italic capital: u1d71c - u1d734 +# Greek bold italic small: u1d736 - u1d74e +# (Greek sans-serif bold capital: u1d756 - u1d76e) +# (Greek sans-serif bold small: u1d770 - u1d788) +# (Greek sans-serif bold italic capital: u1d790 - u1d7a8) +# (Greek sans-serif bold italic small: u1d7aa - u1d7c2) +# bold digits: u1d7ce - u1d7d7 +# (double-struck digits) +# (sans-serif digits) +# (sans-serif bold digits) +# (monospace digits) +# (Arabic mathematical) +# (Arabic stretched) +# (Arabic looped) +# (Arabic double-struck) +# +# It turns out there are no Unicode control codes for marking text +# bold or italic. There are for subscript and superscript, +# and ASCII has similar codes which nobody ever uses. + +declare -A bold=( + [A]=$'\xf0\x9d\x90\x80' + [B]=$'\xf0\x9d\x90\x81' + [C]=$'\xf0\x9d\x90\x82' + [D]=$'\xf0\x9d\x90\x83' + [E]=$'\xf0\x9d\x90\x84' + [F]=$'\xf0\x9d\x90\x85' + [G]=$'\xf0\x9d\x90\x86' + [H]=$'\xf0\x9d\x90\x87' + [I]=$'\xf0\x9d\x90\x88' + [J]=$'\xf0\x9d\x90\x89' + [K]=$'\xf0\x9d\x90\x8a' + [L]=$'\xf0\x9d\x90\x8b' + [M]=$'\xf0\x9d\x90\x8c' + [N]=$'\xf0\x9d\x90\x8d' + [O]=$'\xf0\x9d\x90\x8e' + [P]=$'\xf0\x9d\x90\x8f' + [Q]=$'\xf0\x9d\x90\x90' + [R]=$'\xf0\x9d\x90\x91' + [S]=$'\xf0\x9d\x90\x92' + [T]=$'\xf0\x9d\x90\x93' + [U]=$'\xf0\x9d\x90\x94' + [V]=$'\xf0\x9d\x90\x95' + [W]=$'\xf0\x9d\x90\x96' + [X]=$'\xf0\x9d\x90\x97' + [Y]=$'\xf0\x9d\x90\x98' + [Z]=$'\xf0\x9d\x90\x99' + [a]=$'\xf0\x9d\x90\x9a' + [b]=$'\xf0\x9d\x90\x9b' + [c]=$'\xf0\x9d\x90\x9c' + [d]=$'\xf0\x9d\x90\x9d' + [e]=$'\xf0\x9d\x90\x9e' + [f]=$'\xf0\x9d\x90\x9f' + [g]=$'\xf0\x9d\x90\xa0' + [h]=$'\xf0\x9d\x90\xa1' + [i]=$'\xf0\x9d\x90\xa2' + [j]=$'\xf0\x9d\x90\xa3' + [k]=$'\xf0\x9d\x90\xa4' + [l]=$'\xf0\x9d\x90\xa5' + [m]=$'\xf0\x9d\x90\xa6' + [n]=$'\xf0\x9d\x90\xa7' + [o]=$'\xf0\x9d\x90\xa8' + [p]=$'\xf0\x9d\x90\xa9' + [q]=$'\xf0\x9d\x90\xaa' + [r]=$'\xf0\x9d\x90\xab' + [s]=$'\xf0\x9d\x90\xac' + [t]=$'\xf0\x9d\x90\xad' + [u]=$'\xf0\x9d\x90\xae' + [v]=$'\xf0\x9d\x90\xaf' + [w]=$'\xf0\x9d\x90\xb0' + [x]=$'\xf0\x9d\x90\xb1' + [y]=$'\xf0\x9d\x90\xb2' + [z]=$'\xf0\x9d\x90\xb3' + [Α]=$'\xf0\x9d\x9a\xa8' + [Β]=$'\xf0\x9d\x9a\xa9' + [Γ]=$'\xf0\x9d\x9a\xaa' + [Δ]=$'\xf0\x9d\x9a\xab' + [Ε]=$'\xf0\x9d\x9a\xac' + [Ζ]=$'\xf0\x9d\x9a\xad' + [Η]=$'\xf0\x9d\x9a\xae' + [Θ]=$'\xf0\x9d\x9a\xaf' + [Ι]=$'\xf0\x9d\x9a\xb0' + [Κ]=$'\xf0\x9d\x9a\xb1' + [Λ]=$'\xf0\x9d\x9a\xb2' + [Μ]=$'\xf0\x9d\x9a\xb3' + [Ν]=$'\xf0\x9d\x9a\xb4' + [Ξ]=$'\xf0\x9d\x9a\xb5' + [Ο]=$'\xf0\x9d\x9a\xb6' + [Π]=$'\xf0\x9d\x9a\xb7' + [Ρ]=$'\xf0\x9d\x9a\xb8' + [Σ]=$'\xf0\x9d\x9a\xba' + [Τ]=$'\xf0\x9d\x9a\xbb' + [Υ]=$'\xf0\x9d\x9a\xbc' + [Φ]=$'\xf0\x9d\x9a\xbd' + [Χ]=$'\xf0\x9d\x9a\xbe' + [Ψ]=$'\xf0\x9d\x9a\xbf' + [Ω]=$'\xf0\x9d\x9b\x80' + [α]=$'\xf0\x9d\x9b\x82' + [β]=$'\xf0\x9d\x9b\x83' + [γ]=$'\xf0\x9d\x9b\x84' + [δ]=$'\xf0\x9d\x9b\x85' + [ε]=$'\xf0\x9d\x9b\x86' + [ζ]=$'\xf0\x9d\x9b\x87' + [η]=$'\xf0\x9d\x9b\x88' + [θ]=$'\xf0\x9d\x9b\x89' + [ι]=$'\xf0\x9d\x9b\x8a' + [κ]=$'\xf0\x9d\x9b\x8b' + [λ]=$'\xf0\x9d\x9b\x8c' + [μ]=$'\xf0\x9d\x9b\x8d' + [ν]=$'\xf0\x9d\x9b\x8e' + [ξ]=$'\xf0\x9d\x9b\x8f' + [ο]=$'\xf0\x9d\x9b\x90' + [π]=$'\xf0\x9d\x9b\x91' + [ρ]=$'\xf0\x9d\x9b\x92' + [ς]=$'\xf0\x9d\x9b\x93' + [σ]=$'\xf0\x9d\x9b\x94' + [τ]=$'\xf0\x9d\x9b\x95' + [υ]=$'\xf0\x9d\x9b\x96' + [φ]=$'\xf0\x9d\x9b\x97' + [χ]=$'\xf0\x9d\x9b\x98' + [ψ]=$'\xf0\x9d\x9b\x99' + [ω]=$'\xf0\x9d\x9b\x9a' +) + +declare -A italic=( + [A]=$'\xf0\x9d\x90\xb4' + [B]=$'\xf0\x9d\x90\xb5' + [C]=$'\xf0\x9d\x90\xb6' + [D]=$'\xf0\x9d\x90\xb7' + [E]=$'\xf0\x9d\x90\xb8' + [F]=$'\xf0\x9d\x90\xb9' + [G]=$'\xf0\x9d\x90\xba' + [H]=$'\xf0\x9d\x90\xbb' + [I]=$'\xf0\x9d\x90\xbc' + [J]=$'\xf0\x9d\x90\xbd' + [K]=$'\xf0\x9d\x90\xbe' + [L]=$'\xf0\x9d\x90\xbf' + [M]=$'\xf0\x9d\x91\x80' + [N]=$'\xf0\x9d\x91\x81' + [O]=$'\xf0\x9d\x91\x82' + [P]=$'\xf0\x9d\x91\x83' + [Q]=$'\xf0\x9d\x91\x84' + [R]=$'\xf0\x9d\x91\x85' + [S]=$'\xf0\x9d\x91\x86' + [T]=$'\xf0\x9d\x91\x87' + [U]=$'\xf0\x9d\x91\x88' + [V]=$'\xf0\x9d\x91\x89' + [W]=$'\xf0\x9d\x91\x8a' + [X]=$'\xf0\x9d\x91\x8b' + [Y]=$'\xf0\x9d\x91\x8c' + [Z]=$'\xf0\x9d\x91\x8d' + [a]=$'\xf0\x9d\x91\x8e' + [b]=$'\xf0\x9d\x91\x8f' + [c]=$'\xf0\x9d\x91\x90' + [d]=$'\xf0\x9d\x91\x91' + [e]=$'\xf0\x9d\x91\x92' + [f]=$'\xf0\x9d\x91\x93' + [g]=$'\xf0\x9d\x91\x94' + [h]=$'\xf0\x9d\x98\xa9' # Sans-serif, because f0 9d 91 95 is not assigned. + [i]=$'\xf0\x9d\x91\x96' + [j]=$'\xf0\x9d\x91\x97' + [k]=$'\xf0\x9d\x91\x98' + [l]=$'\xf0\x9d\x91\x99' + [m]=$'\xf0\x9d\x91\x9a' + [n]=$'\xf0\x9d\x91\x9b' + [o]=$'\xf0\x9d\x91\x9c' + [p]=$'\xf0\x9d\x91\x9d' + [q]=$'\xf0\x9d\x91\x9e' + [r]=$'\xf0\x9d\x91\x9f' + [s]=$'\xf0\x9d\x91\xa0' + [t]=$'\xf0\x9d\x91\xa1' + [u]=$'\xf0\x9d\x91\xa2' + [v]=$'\xf0\x9d\x91\xa3' + [w]=$'\xf0\x9d\x91\xa4' + [x]=$'\xf0\x9d\x91\xa5' + [y]=$'\xf0\x9d\x91\xa6' + [z]=$'\xf0\x9d\x91\xa7' + [Α]=$'\xf0\x9d\x9b\xa2' + [Β]=$'\xf0\x9d\x9b\xa3' + [Γ]=$'\xf0\x9d\x9b\xa4' + [Δ]=$'\xf0\x9d\x9b\xa5' + [Ε]=$'\xf0\x9d\x9b\xa6' + [Ζ]=$'\xf0\x9d\x9b\xa7' + [Η]=$'\xf0\x9d\x9b\xa8' + [Θ]=$'\xf0\x9d\x9b\xa9' + [Ι]=$'\xf0\x9d\x9b\xaa' + [Κ]=$'\xf0\x9d\x9b\xab' + [Λ]=$'\xf0\x9d\x9b\xac' + [Μ]=$'\xf0\x9d\x9b\xad' + [Ν]=$'\xf0\x9d\x9b\xae' + [Ξ]=$'\xf0\x9d\x9b\xaf' + [Ο]=$'\xf0\x9d\x9b\xb0' + [Π]=$'\xf0\x9d\x9b\xb1' + [Ρ]=$'\xf0\x9d\x9b\xb2' + [Σ]=$'\xf0\x9d\x9b\xb4' + [Τ]=$'\xf0\x9d\x9b\xb5' + [Υ]=$'\xf0\x9d\x9b\xb6' + [Φ]=$'\xf0\x9d\x9b\xb7' + [Χ]=$'\xf0\x9d\x9b\xb8' + [Ψ]=$'\xf0\x9d\x9b\xb9' + [Ω]=$'\xf0\x9d\x9b\xba' + [α]=$'\xf0\x9d\x9b\xbc' + [β]=$'\xf0\x9d\x9b\xbd' + [γ]=$'\xf0\x9d\x9b\xbe' + [δ]=$'\xf0\x9d\x9b\xbf' + [ε]=$'\xf0\x9d\x9c\x80' + [ζ]=$'\xf0\x9d\x9c\x81' + [η]=$'\xf0\x9d\x9c\x82' + [θ]=$'\xf0\x9d\x9c\x83' + [ι]=$'\xf0\x9d\x9c\x84' + [κ]=$'\xf0\x9d\x9c\x85' + [λ]=$'\xf0\x9d\x9c\x86' + [μ]=$'\xf0\x9d\x9c\x87' + [ν]=$'\xf0\x9d\x9c\x88' + [ξ]=$'\xf0\x9d\x9c\x89' + [ο]=$'\xf0\x9d\x9c\x8a' + [π]=$'\xf0\x9d\x9c\x8b' + [ρ]=$'\xf0\x9d\x9c\x8c' + [ς]=$'\xf0\x9d\x9c\x8d' + [σ]=$'\xf0\x9d\x9c\x8e' + [τ]=$'\xf0\x9d\x9c\x8f' + [υ]=$'\xf0\x9d\x9c\x90' + [φ]=$'\xf0\x9d\x9c\x91' + [χ]=$'\xf0\x9d\x9c\x92' + [ψ]=$'\xf0\x9d\x9c\x93' + [ω]=$'\xf0\x9d\x9c\x94' +) + +# TODO: bold italics. + +while IFS= read -r line +do + replacement="" + for i in $(seq 0 "$((${#line}-1))") + do + c1=${line:$i:1} + if [[ $c1 =~ [a-zA-Zα-ωΑ-Ω] ]] + then replacement+=${italic[$c1]} + else replacement+=$'\u0331'$c1 + fi + done + echo "$replacement" +done @@ -0,0 +1,11 @@ +#!/bin/bash + +fn=$1 +if [[ "$fn" = *\$1* ]] +then f(){ eval "$fn";} +else f(){ eval "$fn" "$1";} +fi +shift +for x in "$@" +do f "$x" +done diff --git a/bin/map-db b/bin/map-db new file mode 100755 index 0000000..feb528c --- /dev/null +++ b/bin/map-db @@ -0,0 +1,60 @@ +#!/bin/bash + +query(){ +# psql-gridware -A -F$'\t' -t -P pager=off -c "$@" +# psql-gridware -A -F$'\t' -P pager=off -P title=off -c "$@" + psql-gridware -A -F$'\t' -P pager=off -c "$@" +} + +exec {in}<&0 + +pforkey(){ + echo '</TABLE>>]' + open_table=0 + data=forkey +} +forkey(){ + # ${constraint name} FOREIGN KEY (${Column}) REFERENCES ${table}(${Column}) + read -ra line <<<"$Column" + this_column=${line[3]%)} + this_column=${this_column#(} + other_table=${line[5]%%(*} + other_column=${line[5]##*\(} + other_column=${other_column%)} + printf '%s:%s_out -> %s:%s_in\n' "$table" "$this_column" "$other_table" "$other_column" +} + +record(){ + if [[ $Nullable = 'not null' ]] + then + echo "<TR><TD PORT=\"${Column}_in\"><U>$Column</U></TD><TD PORT=\"${Column}_out\">$Type</TD></TR>" + else + echo "<TR><TD PORT=\"${Column}_in\">$Column</TD><TD PORT=\"${Column}_out\">$Type</TD></TR>" + fi +} + +echo 'strict digraph db {' +echo 'node[shape=plain]' +query '\d' -t | cut -f 2,3 | grep table\$ | cut -f1 | while read -r table +do + printf '\e[1m%s\e[0m\n' "$table" >&2 + data=record + open_table=1 + echo + echo "$table [label=<<TABLE BORDER=\"0\"><TR><TD COLSPAN=\"2\">\\N</TD></TR>" + echo '<HR/>' + while IFS=$'\t' read -r Column Type Collation Nullable Default + do + case $Column in + Foreign-key\ constraints:) + echo >&2 'foreign keys' + data=pforkey + ;; *:) + echo >&2 '… skipping '"$Column" + data=: + esac + $data + done < <(query '\d '"$table" <&${in} | tail -n+3 | tr -d $'\r') + [[ $open_table = 1 ]] && echo '</TABLE>>]' +done +echo '}' @@ -0,0 +1,38 @@ +#!/bin/bash + +set -ue + +get_parent () { + ps hoppid p$1 +} + +get_children () { + ps hopid --ppid "$1" +} + +get_ancestors () { + case $1 in + 0|1|'') : + ;; *) get_ancestors $(get_parent $1) + esac + echo "$1" +} + +get_descendents () { + for c in $(get_children "$1") + do echo "$c" + get_descendents "$c" + done +} + +declare -i p +for p in "$@" +do + [[ $p -ne 0 ]] && { + get_ancestors "$p" + get_descendents "$p" + } | { + readarray -t pids + ps -Hf "${pids[@]}" | sed "/^[^ ]* *$p /s/.*/[1m&[0m/" + } +done diff --git a/bin/pivot b/bin/pivot new file mode 100755 index 0000000..3c750f2 --- /dev/null +++ b/bin/pivot @@ -0,0 +1,11 @@ +#!/usr/bin/awk -f + +{ + split ($0, _columns, "\t") + for (i=0;i<length(_columns);++i) { + columns[i] = columns[i] "\t" _columns[i] +} } +END { + for (i=0;i<length(columns);++i) { + print substr(columns[i],2) +} } diff --git a/bin/radix b/bin/radix new file mode 100755 index 0000000..670107d --- /dev/null +++ b/bin/radix @@ -0,0 +1,39 @@ +#!/bin/bash + +# bc -q <<<"obase=$1;$2" + +set -eu + +if [[ $# -eq 0 ]] || [[ $# -gt 2 ]] +then + cat >&2 <<-HERE + usage: $0 radix decimal + HERE + exit +fi + +declare -i radix=$1 +declare -i decimal=$2 + +[[ radix -gt 0 ]] || exit 1 + +if [[ $decimal -lt 0 ]] +then + printf -- - + decimal=-$decimal +fi + +if [[ $radix -eq 12 ]] +then digits=({0..9} ↊ ↋) +else digits=({0..9} {a..z}) +fi +number='' + +while [[ $decimal -gt 0 ]] +do + digit=$((decimal%radix)) + number=${digits[$digit]}$number +# decimal=$((decimal-(digit*radix))) + decimal=$((decimal/radix)) +done +echo "$number" diff --git a/bin/reduce b/bin/reduce new file mode 100755 index 0000000..b9b69fe --- /dev/null +++ b/bin/reduce @@ -0,0 +1,9 @@ +#!/bin/bash + +fn=$1 +f() { eval "$fn" "$@"; } +a=$2 +b=$3 +shift 3 +[[ -z "$b" ]] && exec echo "$a" +exec "$0" "$fn" "$(f "$a" "$b")" "${@@Q}" @@ -0,0 +1,55 @@ +#!/bin/bash + +### +# Single pass tabulate. +# +# Turn grid-aligned tables into tab-separated values +# using the first line as a template. +# Pre-existing tabs are preserved, +# which is probably not good. +## +# TODO: +# - Optionally require more than one space for column separation. + +shopt -s extglob + +spitline(){ + declare -i prevtab=0 + for tabstop in ${tabstops[@]} + do + # Strip trailing spaces. + field=${line:$prevtab:$((tabstop-prevtab))} + field=${field%%*( )} + printf '%s\t' "$field" + prevtab=$tabstop + done + printf '%s\n' "${line:$prevtab}" +} + +## +# First line: +## +# The tab stops are where stretches of empty space end. +IFS=$'\n' +read -r firstline +declare -i skip=1 +for ((i=0;i<${#firstline};i++)) +do + case ${firstline:$i:1} in + \ ) + skip=0 + ;; *) + [[ $skip -eq 0 ]] && tabstops+=($i) + skip=1 + esac +done +#echo >&2 ${tabstops[@]} +line=$firstline +spitline + +## +# All other lines: +declare -i prevtab +while read -r line +do spitline +done diff --git a/bin/strjoin b/bin/strjoin new file mode 100755 index 0000000..83b2a9c --- /dev/null +++ b/bin/strjoin @@ -0,0 +1,6 @@ +#!/bin/sh +sep=$1 +shift +printf '%s' "$1" +shift +printf "$sep"'%s' "$@" diff --git a/bin/sum-down b/bin/sum-down new file mode 100644 index 0000000..49717ea --- /dev/null +++ b/bin/sum-down @@ -0,0 +1,14 @@ +#!/usr/bin/awk -E + +{ split($0, _columns, "\t") + for(i in _columns){ + columns[i] += _columns[i] + } +} +END { + output=columns[0] + for(i in columns){ + output = output "\t" columns[i] + } + print output +} diff --git a/bin/sum-up b/bin/sum-up new file mode 100755 index 0000000..1d035d7 --- /dev/null +++ b/bin/sum-up @@ -0,0 +1,4 @@ +#!/bin/bash + +#sed 's/\t/ + /g'| bc -q +sed 's/\t/ + /g'| python3 -qqIi 2> /dev/null diff --git a/bin/xmlbrowser b/bin/xmlbrowser new file mode 100755 index 0000000..731b466 --- /dev/null +++ b/bin/xmlbrowser @@ -0,0 +1,39 @@ +#!/usr/bin/python3 + +import sys +import xml.etree.ElementTree as ET + +from qtpy import QtGui, QtWidgets, QtCore +from qtpy.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem, QLabel + +def _make_item(element) -> QTreeWidgetItem: + r = QTreeWidgetItem([element.tag, None, element.text]) + r.addChildren([QTreeWidgetItem([None, name, value]) for name, value in element.attrib.items()]) + r.addChildren([_make_item(child) for child in element]) + return r + +def main(): + app = QApplication(sys.argv) + # TODO: Check for suitable arguments first. + # Parameter may be a Qt option. + if len(sys.argv) == 1: + print("Usage:", sys.argv[0], "[file …]", file=sys.stderr) + return + + items = [] + for arg in sys.argv[1:]: + with open(arg) as xmlfile: + xmltree = ET.parse(xmlfile) + fileItem = QTreeWidgetItem([arg]) + items.append(fileItem) + fileItem.addChildren([_make_item(xmltree.getroot())]) + + tree = QTreeWidget() + tree.setColumnCount(2) + tree.setHeaderLabels(["Element", "attribute", "text"]) + tree.insertTopLevelItems(0, items) + tree.show() + sys.exit(app.exec_()) # Main loop. + +if __name__ == '__main__': + main() diff --git a/bin/yamlbrowser b/bin/yamlbrowser new file mode 100755 index 0000000..92068b4 --- /dev/null +++ b/bin/yamlbrowser @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import sys +import yaml +from qtpy import QtGui, QtWidgets, QtCore +from qtpy.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem, QLabel + +def _make_children (parent:QTreeWidgetItem, d) -> QTreeWidgetItem: + """ + If the item is a container item, i.e. list or dict, + its contents are added as children to the parent. + + If the item is not a container item, + it becomes the value to its parent. + """ + def transform_l (p:QTreeWidgetItem, d:list) -> QTreeWidgetItem: + p.addChildren (_make_children (QTreeWidgetItem (), x) for x in d) + return p + def transform_d (p:QTreeWidgetItem, d:dict) -> QTreeWidgetItem: + p.addChildren (_make_children (QTreeWidgetItem ([key]), value) for key, value in d.items ()) + return p + return { + list: lambda p, d : transform_l (p, d) + , dict: lambda p, d : transform_d (p, d) + , str: lambda p, d : QTreeWidgetItem ([p.text (0), d]) + , int: lambda p, d : QTreeWidgetItem ([p.text (0), str(d)]) + , float: lambda p, d : QTreeWidgetItem ([p.text (0), str(d)]) + , bool: lambda p, d : QTreeWidgetItem ([p.text (0), str(d)]) + , type(None): lambda p, d : QTreeWidgetItem ([p.text (0), str(d)]) + }[type (d)] (parent, d) + +def main (): + app = QApplication (sys.argv) + # TODO: Check for suitable arguments first. + # Parameter may be a Qt option. + if len (sys.argv) == 1: + print ("Usage:", sys.argv[0], "[file …]", file=sys.stderr) + return + try: + items = [] + for arg in sys.argv[1:]: + with open (arg) as file: + data = list (yaml.safe_load_all (file)) + items.append (_make_children (QTreeWidgetItem ([arg]), data[0] if len (data) == 1 else data)) + + tree = QTreeWidget () + tree.setColumnCount (2) + tree.setHeaderLabels (["Key", "Value"]) + tree.insertTopLevelItems(0, items) + tree.show () + except Exception as x: + print (x, file=sys.stderr) + label = QtWidgets.QLabel (str(x)) + label.show () # Opens window. + sys.exit (app.exec_()) # Main loop. Display the label. + +if __name__=='__main__': + main () |