Replace Numbers on Webpages

Apply a math function of your choice to all numbers from 0-99 on a webpage. Inspired by JoeSimmons' "Replace Text On Webpages".

  1. // ==UserScript==
  2. // @name Replace Numbers on Webpages
  3. // @description Apply a math function of your choice to all numbers from 0-99 on a webpage. Inspired by JoeSimmons' "Replace Text On Webpages".
  4. // @include *
  5. // @copyright Anona
  6. // @version 1.0
  7. // @license http://creativecommons.org/licenses/by-nc-nd/3.0/us/
  8. // @namespace https://greasyfork.org/users/194312
  9. // ==/UserScript==
  10. (function () {
  11. 'use strict';
  12.  
  13. /////////////////////////////////// USER EDITABLE VARIABLES ///////////////////////////////////
  14. var minimum = 50; // Lowest number that will have the below function applied. (min value: 0)
  15. var maximum = 90; // Highest number that will have the below function applied. (max value: 99)
  16. function userDefinedFunction(numberToReplace) { // Example: 50-90 will be halved and rounded.
  17. return Math.round(numberToReplace / 2);
  18. }
  19. /////////////////////////////////// USER EDITABLE VARIABLES ///////////////////////////////////
  20.  
  21. var card = {0: "zero", 1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven", 8: "eight", 9: "nine", 10: "ten", 11: "eleven",
  22. 12: "twelve", 20: "twenty", 30: "thirty", 40: "forty", 50: "fifty", 60: "sixty", 70: "seventy", 80: "eighty", 90: "ninety"},
  23. ord = {0: "zero", 1: "fir", 2: "secon", 3: "thir", 4: "four", 5: "fif", 6: "six", 7: "seven", 8: "eigh", 9: "nine", 10: "ten", 11: "eleven",
  24. 12: "twelf", 20: "twentie", 30: "thirtie", 40: "fortie", 50: "fiftie", 60: "sixtie", 70: "seventie", 80: "eightie", 90: "ninetie"},
  25. tagsWhitelist = ['PRE', 'BLOCKQUOTE', 'CODE', 'INPUT', 'BUTTON', 'TEXTAREA'],
  26. text, texts, i;
  27.  
  28. // function to decide whether a parent tag will have its text replaced or not
  29. function isTagOk(tag) {
  30. return tagsWhitelist.indexOf(tag) === -1;
  31. }
  32.  
  33. function isUpperCase(str) {
  34. return str === str.toUpperCase();
  35. }
  36.  
  37. function wordToNum(word) {
  38. switch (word.toLowerCase()) {
  39. case card[1]: case ord[1]: return 1;
  40. case card[2]: case ord[2]: return 2;
  41. case card[3]: case ord[3]: return 3;
  42. case card[4]: case ord[4]: return 4;
  43. case card[5]: case ord[5]: return 5;
  44. case card[6]: case ord[6]: return 6;
  45. case card[7]: case ord[7]: return 7;
  46. case card[8]: case ord[8]: return 8;
  47. case card[9]: case ord[9]: return 9;
  48. case card[10]: case ord[10]: return 10;
  49. case card[11]: case ord[11]: return 11;
  50. case card[12]: case ord[12]: return 12;
  51. case card[20]: case ord[20]: return 20;
  52. case card[30]: case ord[30]: return 30;
  53. case card[40]: case ord[40]: return 40;
  54. case card[50]: case ord[50]: return 50;
  55. case card[60]: case ord[60]: return 60;
  56. case card[70]: case ord[70]: return 70;
  57. case card[80]: case ord[80]: return 80;
  58. case card[90]: case ord[90]: return 90;
  59. }
  60. return 0;
  61. }
  62.  
  63. function minusDigits(match, article, space, digits, ordinal) {
  64. if (Number(digits) < minimum || maximum < Number(digits)) return match;
  65. digits = userDefinedFunction(Number(digits)).toFixed();
  66. if (Number(digits) < 0 || 99 < Number(digits)) return match;
  67. if (digits.startsWith("8") || digits == "11" || digits == "18") {
  68. if (article.length == 1) article += "n";
  69. } else if (article.length == 2) article = article.slice(0, -1);
  70. if (ordinal) {
  71. if (digits.endsWith("1") && digits != "11") ordinal = "st";
  72. else if (digits.endsWith("2") && digits != "12") ordinal = "nd";
  73. else if (digits.endsWith("3") && digits != "13") ordinal = "rd";
  74. else ordinal = "th";
  75. }
  76. if (isUpperCase(match)) return (article + space + digits + ordinal).toUpperCase();
  77. return article + space + digits + ordinal;
  78. }
  79.  
  80. function minusWords(match, article, space, digitOne, dash, digitTwo, teen, ordinal) {
  81. var num = (teen ? 10 : 0);
  82. num += wordToNum(digitOne);
  83. num += wordToNum(digitTwo);
  84. if (num < minimum || maximum < num) return match;
  85. var digits = userDefinedFunction(num).toFixed();
  86. if (Number(digits) < 0 || 99 < Number(digits)) return match;
  87. if (digits.startsWith("8") || digits == "11" || digits == "18") {
  88. if (article.length == 1) article += "n";
  89. } else if (article.length == 2) article = article.slice(0, -1);
  90. teen = (12 < Number(digits) && Number(digits) < 20 ? "teen" : "");
  91. if (ordinal) {
  92. if (digits.endsWith("1") && digits != "11") ordinal = "st";
  93. else if (digits.endsWith("2") && digits != "12") ordinal = "d";
  94. else if (digits.endsWith("3") && digits != "13") ordinal = "d";
  95. else ordinal = "th";
  96. }
  97. var capital = ((digitOne && isUpperCase(digitOne[0])) || isUpperCase(digitTwo[0]));
  98. digitOne = (Number(digits) > 19 && digits[1] != "0" ? card[digits[0] * 10] : "");
  99. digitTwo = (Number(digits) > 12 ? (ordinal || teen ? ord[digits[1] % 10] : card[digits[1] % 10]) : (ordinal || teen ? ord[digits] : card[digits]));
  100. if (digitOne && num < 21) dash = "-";
  101. if (isUpperCase(match)) return (article + space + digitOne + dash + digitTwo + teen + ordinal).toUpperCase();
  102. else if (capital && digitOne) digitOne = digitOne[0].toUpperCase() + digitOne.slice(1);
  103. else if (capital) digitTwo = digitTwo[0].toUpperCase() + digitTwo.slice(1);
  104. return article + space + digitOne + dash + digitTwo + teen + ordinal;
  105. }
  106.  
  107. // do the replacement
  108. texts = document.evaluate('//body//text()[ normalize-space(.) != "" ]', document, null, 6, null);
  109. for (i = 0; text = texts.snapshotItem(i); i += 1) {
  110. if (isTagOk(text.parentNode.tagName)) {
  111. text.data = text.data.replace(/\b((?:a|an)?)(\s?)(\d?\d)((?:st|nd|rd|th)?)(?!\d|s|\W7|\W?something)/gi, minusDigits);
  112. text.data = text.data.replace(/(?:\b((?:a|an)?)(\s?))((?:(?:twent|thirt|fort|fift|sixt|sevent|eight|ninet)(?:y|ie)(?=\W?(?:one|fir|two|secon|three|thir|four|five|fif|six|seven|eight(?!h|een)|eigh|nine)))?)(\W?)(one|fir|two|secon|three|thir|four|five|fif|six|seven|eight(?!h|een)|eigh|nine|ten|eleven|twelve|twelf|(?:(?:twent|thirt|fort|fift|sixt|sevent|eight|ninet)(?:y|ie)))((?:teen)?)((?:st|d|th)?)(?!s|\W?something)/gi, minusWords);
  113. }
  114. }
  115.  
  116. }());