Add pholcode support to annna. - annna - Annna the nice friendly bot.
HTML git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/annna/
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
---
DIR commit 7c69a018ae0f2c8a92922058333f86fe59d0af20
DIR parent 0da5bb56bf17635438234d4f055e53d0a831b81e
HTML Author: Annna Robert-Houdin <annna@bitreich.org>
Date: Sun, 6 Apr 2025 15:59:47 +0200
Add pholcode support to annna.
Thanks Ben Collver!
Diffstat:
M annna-message-common | 5 +++++
A pohlcode.awk | 265 +++++++++++++++++++++++++++++++
2 files changed, 270 insertions(+), 0 deletions(-)
---
DIR diff --git a/annna-message-common b/annna-message-common
@@ -720,6 +720,11 @@ case "${text}" in
suri="$(printf "%s\n" "${word}" | ghost -e)"
annna-say -s "${server}" -c "${channel}" "${suri}"
;;
+"${ircuser}, please pohlish "*)
+ word="$(printf "%s\n" "${text}" | cut -c 23- | sed 's,\t, ,g')"
+ suri="$(pohlcode.awk "${word}")"
+ annna-say -s "${server}" -c "${channel}" "${suri}"
+ ;;
"${ircuser}, what can I cook with "*)
ingredients="$(printf "%s\n" "${text}" | cut -c 29- | sed 's,\t, ,g')"
case "$ingredients" in
DIR diff --git a/pohlcode.awk b/pohlcode.awk
@@ -0,0 +1,265 @@
+#!/usr/bin/awk -f
+# pohlcode.awk version 3 by Ben Collver
+#
+# Implement spoken representation of binary numbers described in
+# On Binary Digits And Human Habits by Frederik Pohl, 1962.
+#
+# Dual license: WTFPL and Public Domain
+#
+# Pohl encode string from decimal number:
+# awk -f pohlcode.awk 31337
+#
+# Decode decimal number from Pohl encoded string:
+# awk -f pohlcode.awk tee two group totter-poot totter-poot
+
+# initialize tables used to convert between bases and encodings
+
+function init( hl, hu, i) {
+ split("pohl poot pahtah pod too tot dye tee", second, " ")
+ split("ohly ooty ahtah oddy too totter dye teeter", first, " ")
+ split("000 001 010 011 100 101 110 111", trip, " ")
+ split("zero one two three four five six seven eight nine", eng, " ")
+ split("0 1 2 3 4 5 6 7 8 9 A B C D E F", hex, " ")
+ split("0000 0001 0010 0011 0100 0101 0110 0111 " \
+ "1000 1001 1010 1011 1100 1101 1110 1111", bin, " ")
+
+ # bin/dec/hex conversion tables
+ for (i in hex) {
+ hu = hex[i]
+ hl = tolower(hu)
+ h2b[hl] = h2b[hu] = bin[i]
+ h2d[hl] = h2d[hu] = i - 1
+ b2h[bin[i]] = hu
+ }
+
+ # english digit conversion tables
+ for (i in eng) {
+ d2e[i - 1] = eng[i]
+ e2d[eng[i]] = i - 1
+ }
+
+ # Pohl code binary triplet conversion tables
+ for (i in trip) {
+ f2p[trip[i]] = first[i]
+ s2p[trip[i]] = second[i]
+ p2f[first[i]] = trip[i]
+ p2s[second[i]] = trip[i]
+ }
+
+ return
+}
+
+function bin2dec(str, dec, hex) {
+ hex = bin2hex(str)
+ dec = hex2dec(hex)
+ return dec
+}
+
+function bin2hex(str, chunk, n, i, hex, pad, rem) {
+ str = zpad4(str)
+ n = length(str)
+ for (i = 1; i <= n; i += 4) {
+ chunk = zpad4(substr(str, i, 4))
+ hex = hex b2h[chunk]
+ }
+ return hex
+}
+
+function bin2pohl(bin, bbuf, groups, p, parts, retval, val) {
+ groups = int(length(bin) / 6)
+ if (groups > 9) {
+ print "Error: groups out of bounds: " groups
+ exit 1
+ }
+ p = 0
+ bbuf = zpad6(bin)
+ if (length(bbuf) > length(bin)) {
+ val = substr(bbuf, 1, 6)
+ sub(/^000/, "", val)
+ bbuf = substr(bbuf, 7)
+ p++
+ parts[p] = pohlencode(val)
+ }
+ if (groups > 0) {
+ p++
+ parts[p] = d2e[groups] " group"
+ }
+ for (i = 1; i <= groups; i++) {
+ val = substr(bbuf, 1, 6)
+ bbuf = substr(bbuf, 7)
+ p++
+ parts[p] = pohlencode(val)
+ }
+ retval = ""
+ for (i = 1; i <= p; i++) {
+ if (length(retval) == 0) {
+ retval = parts[i]
+ } else {
+ retval = retval " " parts[i]
+
+ }
+ }
+ return retval
+}
+
+function dec2bin(dec, hex, bin) {
+ hex = sprintf("%x\n", dec)
+ bin = hex2bin(hex)
+ return bin
+}
+
+function hex2bin(hex, n, i, bin) {
+ n = length(hex)
+ for (i = 1; i <= n; i++) {
+ bin = bin h2b[substr(hex, i, 1)]
+ }
+ sub(/^0+/, "", bin)
+ if (length(bin) == 0) {
+ bin = "0"
+ }
+ return bin
+}
+
+function hex2dec(val, out, i, n) {
+ if (val ~ /^0x/) {
+ val = substr(val, 3)
+ }
+ n = length(val)
+ for (i = 1; i <= n; i++) {
+ out = (out * 16) + h2d[substr(val, i, 1)]
+ }
+ #return sprintf("%.0f", out)
+ return out
+}
+
+function pohl2bin(str, bbuf, eng, groups, i, prefix, result, wnum, \
+ words)
+{
+ bbuf = ""
+ groups = 1
+ result = match(str, /.* group /)
+ if (result > 0) {
+ prefix = substr(str, 1, RLENGTH)
+ str = substr(str, RLENGTH + 1)
+ wnum = split(prefix, words, " ")
+ if (wnum == 2) {
+ eng = words[1]
+ } else if (wnum == 3) {
+ eng = words[2]
+ bbuf = pohldecode(words[1])
+ sub(/^0*/, "", bbuf)
+ } else {
+ print "Bad Pohl code prefix: " prefix
+ exit 1
+ }
+ if (eng in e2d) {
+ groups = e2d[eng]
+ } else {
+ print "Invalid number of groups: " eng
+ exit 1
+ }
+ }
+ wnum = split(str, words, " ")
+ if (wnum != groups) {
+ print "Expected " groups " group(s) but got: " wnum
+ exit 1
+ }
+ for (i = 1; i <= wnum ; i++) {
+ bbuf = bbuf pohldecode(words[i])
+ }
+ return bbuf
+}
+
+# decode pohl-encoded 6-bit word
+
+function pohldecode(word, parts, pnum, retval) {
+ pnum = split(word, parts, "-")
+ if (pnum == 2 && parts[1] in p2f && parts[2] in p2s) {
+ retval = p2f[parts[1]] p2s[parts[2]]
+ } else if (pnum == 1 && parts[1] in p2s) {
+ retval = "000" p2s[parts[1]]
+ } else {
+ print "Invalid pohl code word: " word
+ exit 1
+ }
+ return retval
+}
+
+# pohl encode 6-bit word
+
+function pohlencode(digits, retval, triplet1, triplet2) {
+ if (length(digits) == 3) {
+ retval = s2p[digits]
+ } else {
+ triplet1 = substr(digits, 1, 3)
+ triplet2 = substr(digits, 4, 6)
+ retval = f2p[triplet1] "-" s2p[triplet2]
+ }
+ return retval
+}
+
+# zero pad number until length is a multiple of 4 digits
+
+function zpad4(str, pad, rem) {
+ rem = length(str) % 4
+ if (rem > 0) {
+ pad = substr("0000", 1, 4 - rem)
+ str = pad str
+ }
+ return str
+}
+
+# zero pad number until length is a multiple of 6 digits
+
+function zpad6(str, pad, rem) {
+ rem = length(str) % 6
+ if (rem > 0) {
+ pad = substr("000000", 1, 6 - rem)
+ str = pad str
+ }
+ return str
+}
+
+function main( i, result, val) {
+ for (i = 1; i < ARGC; i++) {
+ if (length(val) == 0) {
+ val = ARGV[i]
+ } else {
+ val = val " " ARGV[i]
+ }
+ }
+ if (length(val) == 0) {
+ print "Usage: pohlcode.awk [code|number|test]"
+ print ""
+ print "[code]: Converts Pohl code to decimal."
+ print "[number]: Converts decimal to Pohl code."
+ print "test: Print test output."
+ exit 1
+ }
+ sub(/\n$/, "", val)
+ init()
+ if (val == "test") {
+ test()
+ } else if (val ~ /^[0-9][0-9]*$/) {
+ result = bin2pohl(dec2bin(val))
+ } else {
+ result = bin2dec(pohl2bin(val))
+ }
+ print result
+ return
+}
+
+function test( code, i, j) {
+ return
+ for (i = 0; i < 1024; i++) {
+ code = bin2pohl(dec2bin(i))
+ j = bin2dec(pohl2bin(code))
+ printf "%d\t%s\t%d\n", i, code, j
+ }
+ return
+}
+
+BEGIN {
+ main()
+ exit 0
+}