Transliterate to Inuktitut (with Bug Fixes)

Converts website text into Inuktitut syllabics, avoiding UI issues

  1. // ==UserScript==
  2. // @name Transliterate to Inuktitut (with Bug Fixes)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description Converts website text into Inuktitut syllabics, avoiding UI issues
  6. // @author You
  7. // @match *://*/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // Elements to ignore (search bars, buttons, UI elements)
  16. const ignoredTags = ["INPUT", "TEXTAREA", "BUTTON", "SELECT", "SCRIPT", "STYLE", "META"];
  17.  
  18. // English to Inuktitut syllabics substitutions
  19. const letterSubstitutions = {
  20. "ch": "ᑕᔭ", "sh": "ᓴ", "th": "ᓴ", "ng": "ᖕ", "wh": "Ꮩ", "w": "ᐍ",
  21. "y": "ᔨ", "j": "ᔭ", "k": "ᒃ", "d": "ᑕ", "b": "ᐱ", "c": "ᑐ",
  22. "f": "ᓴ", "p": "ᑉ", "g": "ᑕ", "q": "ᖯ", "z": "ᓯ"
  23. };
  24.  
  25. // Latin to Inuktitut syllabic mapping (lowercase)
  26. const translitMapLower = {
  27. "a": "ᐊ", "b": "ᐱ", "c": "ᑐ", "d": "ᑕ", "e": "ᐁ", "f": "ᓴ",
  28. "g": "ᑕ", "h": "ᐦ", "i": "ᐃ", "j": "ᔭ", "k": "ᒃ", "l": "ᓪ",
  29. "m": "ᒻ", "n": "ᓐ", "o": "ᐅ", "p": "ᑉ", "q": "ᖯ", "r": "ᕆ",
  30. "s": "ᓴ", "t": "ᑎ", "u": "ᐅ", "v": "ᐅ", "w": "ᐍ", "x": "ᕿ",
  31. "y": "ᔨ", "z": "ᓯ"
  32. };
  33.  
  34. // Latin to Inuktitut syllabic mapping (uppercase)
  35. const translitMapUpper = {
  36. "A": "ᐊ", "B": "ᐱ", "C": "ᑐ", "D": "ᑕ", "E": "ᐁ", "F": "ᓴ",
  37. "G": "ᑕ", "H": "ᐦ", "I": "ᐃ", "J": "ᔭ", "K": "ᒃ", "L": "ᓪ",
  38. "M": "ᒻ", "N": "ᓐ", "O": "ᐅ", "P": "ᑉ", "Q": "ᖯ", "R": "ᕆ",
  39. "S": "ᓴ", "T": "ᑎ", "U": "ᐅ", "V": "ᐅ", "W": "ᐍ", "X": "ᕿ",
  40. "Y": "ᔨ", "Z": "ᓯ"
  41. };
  42.  
  43. function adjustEnglishLetters(word) {
  44. for (const [key, value] of Object.entries(letterSubstitutions)) {
  45. word = word.replace(new RegExp(key, "gi"), value);
  46. }
  47. return word;
  48. }
  49.  
  50. function transliterateText(text) {
  51. return text.replace(/\b[a-zA-Z]+\b/g, word => {
  52. word = adjustEnglishLetters(word.toLowerCase()); // Adjust before mapping
  53.  
  54. let result = '';
  55. for (let char of word) {
  56. // Check for uppercase and apply the corresponding map
  57. if (char === char.toUpperCase()) {
  58. result += translitMapUpper[char] || translitMapLower[char.toLowerCase()] || char;
  59. } else {
  60. result += translitMapLower[char] || char;
  61. }
  62. }
  63. return result;
  64. });
  65. }
  66.  
  67. function transliterateNode(node) {
  68. if (node.nodeType === Node.TEXT_NODE && node.parentNode && !ignoredTags.includes(node.parentNode.tagName)) {
  69. node.nodeValue = transliterateText(node.nodeValue);
  70. } else if (node.nodeType === Node.ELEMENT_NODE) {
  71. for (let child of node.childNodes) {
  72. transliterateNode(child);
  73. }
  74. }
  75. }
  76.  
  77. function observeDOMChanges() {
  78. const observer = new MutationObserver(mutations => {
  79. mutations.forEach(mutation => {
  80. if (mutation.type === 'childList') {
  81. mutation.addedNodes.forEach(node => transliterateNode(node));
  82. }
  83. });
  84. });
  85.  
  86. observer.observe(document.body, { childList: true, subtree: true });
  87. }
  88.  
  89. transliterateNode(document.body);
  90. observeDOMChanges();
  91.  
  92. })();