diff --git a/configs/packages/default.nix b/configs/packages/default.nix index 95ad03c..bfcdda8 100644 --- a/configs/packages/default.nix +++ b/configs/packages/default.nix @@ -107,6 +107,7 @@ in youtubeDL bc # calculator scripts.favicon + scripts.ipa # XSAMPA to IPA converter nur.repos.kmein.daybook nur.repos.kmein.mahlzeit nur.repos.kmein.slide diff --git a/packages/scripts/default.nix b/packages/scripts/default.nix index cc877e9..ef4a64d 100644 --- a/packages/scripts/default.nix +++ b/packages/scripts/default.nix @@ -111,6 +111,12 @@ in packages = [ pkgs.st pkgs.fzf pkgs.dash pkgs.bash ]; }; + ipa = wrapScript { + script = ./ipa.py; + name = "ipa"; + packages = [ pkgs.python3 ]; + }; + bvg = pkgs.callPackage ./bvg.nix {}; nav = pkgs.callPackage ./nav.nix {}; } diff --git a/packages/scripts/ipa.py b/packages/scripts/ipa.py new file mode 100755 index 0000000..261f76b --- /dev/null +++ b/packages/scripts/ipa.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 +import sys + +# https://www.phon.ucl.ac.uk/home/sampa/x-sampa.htm + +XSAMPA_TO_IPA = { + "t`": "\u0288", + "d`": "\u0256", + "F": "\u0271", + "n`": "\u0273", + "J": "\u0272", + "N": "\u014B", + "N\\": "\u0274", + "B\\": "\u0299", + "R\\": "\u0280", + "4": "\u027E", + "r` ": "\u027D", + "p\\": "\u0278", + "B": "\u03B2", + "T": "\u03B8", + "D": "\u00F0", + "S": "\u0283", + "Z": "\u0292", + "s`": "\u0282", + "z`": "\u0290", + "C": "\u00E7", + "j\\": "\u029D", + "G": "\u0263", + "X": "\u03C7", + "R": "\u0281", + "X\\": "\u0127", + "?\\": "\u0295", + "h\\": "\u0266", + "K": "\u026C", + "K\\": "\u026E", + "P": "\u028B", + "v\\": "\u028B", + "r\\": "\u0279", + "r\\`": "\u027B", + "M\\": "\u0270", + "l`": "\u026D", + "L": "\u028E", + "L\\": "\u029F", + "O\\": "\u0298", + "|\\": "\u01C0", + "!\\": "\u01C3", + "=\\": "\u01C2", + "|\\|\\": "\u01C1", + "_>": "\u02BC", + "b_<": "\u0253", + "d_<": "\u0257", + "d`_<": "\u1D91", + "J\\_<": "\u0284", + "g_<": "\u0260", + "G\\_<": "\u029B", + "M": "\u026F", + "1": "\u0268", + "}": "\u0289", + "I": "\u026A", + "Y": "\u028F", + "U": "\u028A", + "2": "\u00f8", + "@\\": "\u0258", + "8": "\u0275", + "7": "\u0264", + "@": "\u0259", + "E": "\u025B", + "9": "\u0153", + "3": "\u025C", + "3\\": "\u025E", + "V": "\u028C", + "O": "\u0254", + "{": "\u00E6", + "6": "\u0250", + "&": "\u0276", + "A": "\u0251", + "Q": "\u0252", + "W": "\u028D", + "H": "\u0265", + "H\\": "\u029C", + "<\\": "\u02A2", + ">\\": "\u02A1", + "s\\": "\u0255", + "z\\": "\u0291", + "l\\": "\u027A", + "x\\": "\u0267", + "_": "\u0361", + '"': "\u02C8", + "%": "\u02CC", + ":": "\u02D0", + ":\\": "\u02D1", + "_X": "\u0306", + "-\\": "\u203F", + "": "\u02E5", + "": "\u02E6", + "": "\u02E7", + "": "\u02E8", + "": "\u02E9", + "_T": "\u030B", + "_H": "\u0341", + "_M": "\u0304", + "_L": "\u0340", + "_B": "\u030F", + "!": "\uA71C", + "^": "\uA71B", + "_R": "\u030C", + "_F": "\u0302", + "": "\u2197", + "": "\u2198", + "_H_T": "\u1DC4", + "_B_L": "\u1DC5", + "_R_F": "\u1dc8", + "_F_R": "\u1dc9", + "_0": "\u0325", + "_v": "\u032C", + "_h": "\u02B0", + "_O": "\u0339", + "_c": "\u031C", + "_+": "\u031F", + "_-": "\u0320", + '_"': "\u0308", + "_=": "\u0329", + "=": "\u0329", + "_^": "\u032F", + "`": "\u02DE", + "_t": "\u0324", + "_k": "\u0330", + "_N": "\u033C", + "_w": "\u02B7", + "'": "\u02B2", + "_j": "\u02B2", + "_G": "\u02E0", + "_?\\": "\u02E4", + "_d": "\u032A", + "_a": "\u033A", + "_m": "\u033B", + "~": "\u0303", + "_~": "\u0303", + "_n": "\u207F", + "_l": "\u02E1", + "_}": "\u031A", + "_e": "\u0334", + "5": "\u026b", + "_r": "\u031D", + "_o": "\u031E", + "_A": "\u0318", + "_q": "\u0319", +} + +if __name__ == "__main__": + text = " ".join(sys.argv[1:]) + + for xsampa, ipa in sorted(XSAMPA_TO_IPA.items(), key=lambda item: -len(item[0])): + text = text.replace(xsampa, ipa) + + sys.stdout.write(text) diff --git a/packages/scripts/xsampa-ipa.js b/packages/scripts/xsampa-ipa.js new file mode 100755 index 0000000..20ac7bc --- /dev/null +++ b/packages/scripts/xsampa-ipa.js @@ -0,0 +1,371 @@ +#!/usr/bin/env node +"use strict"; +const { createInterface } = require("readline"); + +const xsampa = [ + "_R_F", + "J\\_<", + "_H_T", + "G\\_<", + "_B_L", + "|\\|\\", + "r\\`", + "", + "g_<", + "", + "d_<", + "b_<", + "_?\\", + "z\\", + "z`", + "X\\", + "x\\", + "_x", + "_X", + "_w", + "v\\", + "_v", + "U\\", + "t`", + "_t", + "_T", + "s\\", + "s`", + "r\\", + "r`", + "_r", + "R\\", + "_R", + "_q", + "p\\", + "_o", + "O\\", + "_O", + "n`", + "_n", + "N\\", + "_N", + "_m", + "M\\", + "_M", + "l\\", + "l`", + "_l", + "L\\", + "_L", + "_k", + "K\\", + "j\\", + "_j", + "J\\", + "I\\", + "h\\", + "_h", + "H\\", + "_H", + "G\\", + "_G", + "_F", + "_e", + "d`", + "_d", + "_c", + "B\\", + "_B", + "_a", + "_A", + "3\\", + "_0", + "@\\", + "?\\", + "!\\", + ":\\", + "-\\", + "_+", + "_\\", + "_}", + '_"', + "_/", + "_-", + "_>", + "_=", + "_~", + "_^", + "|\\", + "||", + ">\\", + "=\\", + "<\\", + "Z", + "z", + "y", + "Y", + "X", + "x", + "w", + "W", + "v", + "V", + "u", + "U", + "T", + "t", + "s", + "S", + "r", + "R", + "q", + "Q", + "p", + "P", + "O", + "o", + "N", + "n", + "m", + "M", + "l", + "L", + "k", + "K", + "j", + "J", + "i", + "I", + "h", + "H", + "g", + "G", + "f", + "F", + "E", + "e", + "@", + "D", + "d", + "C", + "c", + "B", + "b", + "{", + "a", + "A", + "9", + "8", + "7", + "6", + "5", + "4", + "3", + "2", + "1", + "%", + "&", + "}", + '"', + "'", + ".", + "?", + "!", + ":", + "|", + "=", + "~", + "^", + "`" +]; + +const ipa = [ + " ᷈", + "ʄ", + " ᷄", + "ʛ", + " ᷅", + "ǁ", + "ɻ", + "↗", + "ɠ", + "↘", + "ɗ", + "ɓ", + "ˤ", + "ʑ", + "ʐ", + "ħ", + "ɧ", + " ̽", + " ̆", + "ʷ", + "ʋ", + " ̬", + "ᵿ", + "ʈ", + " ̤", + " ̋", + "ɕ", + "ʂ", + "ɹ", + "ɽ", + " ̝", + "ʀ", + " ̌", + " ̙", + "ɸ", + " ̞", + "ʘ", + " ̹", + "ɳ", + "ⁿ", + "ɴ", + " ̼", + " ̻", + "ɰ", + " ̄", + "ɺ", + "ɭ", + "ˡ", + "ʟ", + " ̀", + " ̰", + "ɮ", + "ʝ", + "ʲ", + "ɟ", + "ᵻ", + "ɦ", + "ʰ", + "ʜ", + " ́", + "ɢ", + "ˠ", + " ̂", + " ̴", + "ɖ", + " ̪", + " ̜", + "ʙ", + " ̏", + " ̺", + " ̘", + "ɞ", + " ̥", + "ɘ", + "ʕ", + "ǃ", + "ˑ", + "‿", + " ̟", + "̂", + " ̚", + " ̈", + "̌", + " ̠", + "ʼ", + " ̩", + "̃", + " ̯", + "ǀ", + "‖", + "ʡ", + "ǂ", + "ʢ", + "ʒ", + "z", + "y", + "ʏ", + "χ", + "x", + "w", + "ʍ", + "v", + "ʌ", + "u", + "ʊ", + "θ", + "t", + "s", + "ʃ", + "r", + "ʁ", + "q", + "ɒ", + "p", + "ʋ", + "ɔ", + "o", + "ŋ", + "n", + "m", + "ɯ", + "l", + "ʎ", + "k", + "ɬ", + "j", + "ɲ", + "i", + "ɪ", + "h", + "ɥ", + "ɡ", + "ɣ", + "f", + "ɱ", + "ɛ", + "e", + "ə", + "ð", + "d", + "ç", + "c", + "β", + "b", + "æ", + "a", + "ɑ", + "œ", + "ɵ", + "ɤ", + "ɐ", + "ɫ", + "ɾ", + "ɜ", + "ø", + "ɨ", + "ˌ", + "ɶ", + "ʉ", + "ˈ", + "ʲ", + ".", + "ʔ", + "ꜜ", + "ː", + "|", + "̩", + "̃", + "ꜛ", + "˞" +]; + +const convertChar = (inputList, outputList) => input => { + const index = inputList.findIndex(letter => letter == input); + return index ? outputList[index] : input; +}; + +const convertString = (inputList, outputList) => string => + string + .split("") + .map(convertChar(inputList, outputList)) + .join(""); + +const ipaToXsampa = convertString(ipa, xsampa); +const xsampaToIpa = convertString(xsampa, ipa); + +const readlineInterface = createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false +}); + +readlineInterface.on("line", line => console.log(xsampaToIpa(line)));