From 98a2940b81b50014bddcb304669ff833ab6b1c75 Mon Sep 17 00:00:00 2001 From: Mehdi104797 <92753457+Mehdi104797@users.noreply.github.com> Date: Mon, 28 Apr 2025 13:21:24 +0330 Subject: [PATCH] . --- plugins/persianNumber.js | 380 +++++++++++++++++++++++++++++++++++++++ systems/task_ui | 2 +- 2 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 plugins/persianNumber.js diff --git a/plugins/persianNumber.js b/plugins/persianNumber.js new file mode 100644 index 0000000..84a4794 --- /dev/null +++ b/plugins/persianNumber.js @@ -0,0 +1,380 @@ +const oneDigit = [ + "صفر", + "یک", + "دو", + "سه", + "چهار", + "پنج", + "شش", + "هفت", + "هشت", + "نه", +]; +const twoDigits = { + 10: "ده", + 11: "یازده", + 12: "دوازده", + 13: "سیزده", + 14: "چهارده", + 15: "پانزده", + 16: "شانزده", + 17: "هفده", + 18: "هجده", + 19: "نوزده", + 20: "بیست", + 30: "سی", + 40: "چهل", + 50: "پنجاه", + 60: "شصت", + 70: "هفتاد", + 80: "هشتاد", + 90: "نود", +}; +const threeDigits = { + 100: "صد", + 200: "دویست", + 300: "سیصد", + 400: "چهارصد", + 500: "پانصد", + 600: "شش صد", + 700: "هفت صد", + 800: "هشت صد", + 900: "نه صد", +}; + +const types = ["تلیارد", "میلیارد", "میلیون", "هزار", ""]; +const decimalTypes = ["دهم", "صدم", "هزارم", "ده هزارم"]; +let numbers = []; +let decimals = []; + +//Convert Number To Words +const convert = (number) => { + let negative = ""; + let decNumber = ""; + let decimal = ""; + let percent = ""; + + if (isPercent(number)) { + number = number.replace("%", ""); + percent = " درصد"; + } + + number = getString(number); + if (number == "") return ""; + sliceNumber(number); + if (isNegative(number)) negative = "منفی "; + number = number.replace("-", ""); + + if (isDecimal(number)) { + let index = number.indexOf("."); + let decNumberStr = ""; + + decNumber = number.substr(index + 1, number.length); + number = number.substr(0, index); + decNumberStr = parseInt(decNumber).toString(); + + if (decNumberStr.length === 1 && decNumberStr != "0") { + decimal += oneDigit[decNumberStr] + " "; + decimal += decimalTypes[decNumber.length - 1]; + } else { + decimal = calculateDigits(decimals); + decimal += " " + decimalTypes[decNumber.length - 1]; + } + } + + if (number.length === 1) { + if (!decimal) { + return negative + oneDigit[number] + percent; + } + + if (number == "0") { + return negative + decimal + percent; + } + + return negative + oneDigit[number] + " ممیز " + decimal + percent; + } + + if (!decimal) { + return negative + calculateDigits(numbers) + percent; + } + + return negative + calculateDigits(numbers) + " ممیز " + decimal + percent; +}; + +//split number 3 by 3 with a separator (123456789.3025=>123,456,789.3,025) Do Not Give It Persian Numbers +const sliceNumber = (number, separator = ",") => { + let percent = ""; + let neg = ""; + let dNum = ""; + let n = ""; + let d = ""; + + if (isPercent(number)) { + number = number.replace("%", ""); + percent = "%"; + } + + number = getString(number); + + if (number == "") return ""; + if (isNegative(number)) neg = "-"; + + number = number.replace("-", ""); + + if (isDecimal(number)) { + let index = number.indexOf("."); + dNum = number.substr(index + 1, number.length); + number = number.substr(0, index); + } + + n = putSeparator(number, separator); + numbers = n.split(separator); + + if (!dNum) return neg + n + percent; + + d = putSeparator(dNum, separator); + decimals = d.split(separator); + + return neg + n + "." + d + percent; +}; + +//Puts a separator between the chunks of the given numString. +const putSeparator = (numString, separator = ",") => { + if (typeof numString !== "string") return ""; + if (numString.length < 4) return numString; + + let result = ""; + for (let i = numString.length - 1, counter = 0; i >= 0; i--) { + if (counter == 3) { + result += separator; + counter = 0; + } + result += numString[i]; + counter++; + } + + result = result.split("").reverse().join(""); + return result; +}; + +//Processing on Digits of A Number +const calculateDigits = (arrNum) => { + let result = ""; + for (let i = 0; i < arrNum.length; i++) { + let parsedNum = parseInt(arrNum[i]); + let number = parsedNum; + let sadgan = Math.floor(number / 100) * 100; + number = number % 100; + let dahgan = Math.floor(number / 10) * 10; + let yekan = number % 10; + result += i !== 0 && parsedNum ? " و " : ""; + + result += + getPersian(sadgan, dahgan, yekan, i, arrNum) + " " + getType(i, arrNum); + } + + return result.trim(); +}; + +//Main Process That Turn a Number Into a String(122=>100+20+2) +const getPersian = (sadgan, dahgan, yekan, index, numbers) => { + let flag = false; + let result = ""; + let dahganPlusYekan = dahgan + yekan; + + if (threeDigits[sadgan]) { + result += + yekan > 0 || dahgan > 0 + ? threeDigits[sadgan] + " و " + : threeDigits[sadgan]; + } + + if (twoDigits[dahganPlusYekan]) { + result += twoDigits[dahganPlusYekan] + " "; + return result; + } + + if (twoDigits[dahgan]) { + result += twoDigits[dahgan] + " و "; + } + + if ( + numbers.length === 2 && + index === 0 && + yekan === 1 && + dahgan === 0 && + sadgan === 0 + ) { + return result; + } + + if ( + numbers.length > 2 && + index === numbers.length - 2 && + yekan === 1 && + dahgan === 0 && + sadgan === 0 + ) { + return result; + } + + if (yekan > 0) result += oneDigit[yekan] + " "; + + return result; +}; + +//getting The Type Of Each Number (Billion, Million,...) +const getType = (i, numbers) => { + let parsedNum = parseInt(numbers[i]); + if (isNaN(parsedNum)) return ""; + if (!parsedNum) return ""; + let length = numbers.length - i; + let index = types.length - length; + return types[index]; +}; + +//Calculate if number:String is Negative Or Not +const isNegative = (number) => { + number = getString(number); + if (!number) return false; + if (number[0] != "-") return false; + number = number.replace("-", ""); + return number != "0"; +}; + +//Calculate if number:String has '%' as Percent +const isPercent = (string) => { + if (typeof string !== "string") return false; + let index = string.indexOf("%"); + let lIndex = string.lastIndexOf("%"); + if (index != lIndex) return false; + return index > 0; +}; + +//is number:String:Number is a Valid Number? if type is Number turn it to String And Return it +const getString = (number) => { + if (number === undefined) return ""; + if (number === null) return ""; + if (isNaN(number)) return ""; + if (typeof number === "number") return number.toString(); + return number.trim(); +}; + +//Calculate if number:String has Decimal Point Or Not +const isDecimal = (number) => { + number = getString(number); + if (number == "") return false; + let index = number.indexOf("."); + let lIndex = number.lastIndexOf("."); + if (index != lIndex) return false; + return index > 0; +}; +//Convert English Numbers To Persian Numbers +const convertEnToPe = (number) => { + if (number == null || number == undefined) return ""; + if (typeof number == "number") number = number.toString(); + let res = ""; + for (let i = 0; i < number.length; i++) { + switch (number[i]) { + case "\u0030": + res += "\u06F0"; + break; + case "\u0031": + res += "\u06F1"; + break; + case "\u0032": + res += "\u06F2"; + break; + case "\u0033": + res += "\u06F3"; + break; + case "\u0034": + res += "\u06F4"; + break; + case "\u0035": + res += "\u06F5"; + break; + case "\u0036": + res += "\u06F6"; + break; + case "\u0037": + res += "\u06F7"; + break; + case "\u0038": + res += "\u06F8"; + break; + case "\u0039": + res += "\u06F9"; + break; + default: + res += number[i]; + } + } + return res; +}; +//Convert Persian Numbers To English Numbers +const convertPeToEn = (number) => { + if (number == null || number == undefined) return ""; + let res = ""; + for (let i = 0; i < number.length; i++) { + switch (number[i]) { + case "\u06F0": + res += "\u0030"; + break; + case "\u06F1": + res += "\u0031"; + break; + case "\u06F2": + res += "\u0032"; + break; + case "\u06F3": + res += "\u0033"; + break; + case "\u06F4": + res += "\u0034"; + break; + case "\u06F5": + res += "\u0035"; + break; + case "\u06F6": + res += "\u0036"; + break; + case "\u06F7": + res += "\u0037"; + break; + case "\u06F8": + res += "\u0038"; + break; + case "\u06F9": + res += "\u0039"; + break; + default: + res += number[i]; + } + } + return res; +}; + +const e2p = (s) => s.replace(/\d/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[d]); +const e2a = (s) => s.replace(/\d/g, (d) => "٠١٢٣٤٥٦٧٨٩"[d]); + +const p2e = (s) => s.replace(/[۰-۹]/g, (d) => "۰۱۲۳۴۵۶۷۸۹".indexOf(d)); +const a2e = (s) => s.replace(/[٠-٩]/g, (d) => "٠١٢٣٤٥٦٧٨٩".indexOf(d)); + +const p2a = (s) => + s.replace(/[۰-۹]/g, (d) => "٠١٢٣٤٥٦٧٨٩"["۰۱۲۳۴۵۶۷۸۹".indexOf(d)]); +const a2p = (s) => + s.replace(/[٠-٩]/g, (d) => "۰۱۲۳۴۵۶۷۸۹"["٠١٢٣٤٥٦٧٨٩".indexOf(d)]); + +export { + convert, + sliceNumber, + convertEnToPe, + convertPeToEn, + e2p, + e2a, + p2e, + a2e, + p2a, + a2p, +}; diff --git a/systems/task_ui b/systems/task_ui index 03122c1..fd3221e 160000 --- a/systems/task_ui +++ b/systems/task_ui @@ -1 +1 @@ -Subproject commit 03122c1c6270667382c4e21d6798530c542e680a +Subproject commit fd3221ea12a68031a9ed39d82d083ee0d6b3d352