1- import { ARABIC_DOTLESS_DICT , TASHKEEL } from '../constants' ;
1+ import { ARABIC_DOTLESS_DICT , PANNED_WORDS , TASHKEEL } from '../constants' ;
22import {
33 ALEF ,
44 ALONE_LETTERS ,
@@ -10,7 +10,7 @@ import {
1010 WAW ,
1111 YAA ,
1212} from '../constants/arabic-letters' ;
13- import { setCharAt } from '../utils' ;
13+ import { setCharAt , similarityScore } from '../utils' ;
1414
1515/**
1616 * Remove all tashkeel from text
@@ -71,6 +71,35 @@ export function removeTatweel(text: string): string {
7171 return text . replace ( / ـ / g, '' ) ;
7272}
7373
74+ /**
75+ * Converts a word to its pronounced letter representations based on PRONOUNCED_LETTERS.
76+ * @param {string } word - The word to convert.
77+ * @returns {string } The word with pronounced letters separated by spaces.
78+ */
79+ export function wordToLetters ( word : string ) : string {
80+ let newWord = '' ;
81+
82+ // Loop through each character in the input word
83+ for ( let i = 0 ; i < word . length ; i ++ ) {
84+ const letter = word [ i ] ;
85+
86+ // Check if the current letter has a pronunciation in PRONOUNCED_LETTERS
87+ if ( PRONOUNCED_LETTERS . hasOwnProperty ( letter ) ) {
88+ newWord += PRONOUNCED_LETTERS [ letter ] ;
89+
90+ // Add a space after the pronounced letter unless it's the last letter in the word
91+ if ( i !== word . length - 1 ) {
92+ newWord += ' ' ;
93+ }
94+ } else {
95+ // If the letter is not in PRONOUNCED_LETTERS, keep it unchanged
96+ newWord += letter ;
97+ }
98+ }
99+
100+ return newWord . trim ( ) ;
101+ }
102+
74103/**
75104 * Removes predefined affixes (prefixes and suffixes) from an Arabic word if it starts or ends with those affixes.
76105 * This function is designed specifically for processing Arabic text, where certain affixes might need to be removed
@@ -199,6 +228,23 @@ function tashfeerCharacter(character: string): string {
199228 return replacementCharacter ;
200229}
201230
231+ /**
232+ * Performs tashfeer encryption on a given word.
233+ * @param {string } word - The input word to be encrypted.
234+ * @param {number } [level=0] - The encryption level (default is 0).
235+ * @returns {string } The encrypted word.
236+ */
237+ function tashfeerHandler ( word : string , level : number = 0 ) : string {
238+ const wordLength = word . length ;
239+ // Calculate the encryption level based on the input level and word length
240+ const n = calculateEncryptionLevel ( level , wordLength ) ;
241+ // Generate a list of random indexes for encryption
242+ const randomIndexes = getRandomIndexes ( n , wordLength ) ;
243+ // Process the word for encryption using random indexes
244+ const outputWord = tashfeerWord ( word , randomIndexes ) ;
245+ return outputWord ;
246+ }
247+
202248/**
203249 * Performs tashfeer encryption on a given sentence.
204250 * @param {string } sentence - The input sentence to be encrypted.
@@ -207,44 +253,55 @@ function tashfeerCharacter(character: string): string {
207253export function tashfeer ( sentence : string , levelOfTashfeer : number = 1 ) : string {
208254 let new_sentence = '' ;
209255 for ( const word of sentence . split ( ' ' ) ) {
210- const wordLength = word . length ;
211- // Calculate the encryption level based on the input level and word length
212- // encryptionLevel is used to determine the number of characters to be replaced (encrypted)
213- const encryptionLevel = calculateEncryptionLevel ( levelOfTashfeer , wordLength ) ;
214- // Generate a list of random indexes for encryption
215- const randomIndexes = getRandomIndexes ( encryptionLevel , wordLength ) ;
216- // Process the word for encryption using random indexes
217- const outputWord = tashfeerWord ( word , randomIndexes ) ;
218- new_sentence += outputWord + ' ' ;
256+ new_sentence += tashfeerHandler ( word , levelOfTashfeer ) + ' ' ;
219257 }
220258 return new_sentence . trim ( ) ;
221259}
222260
223261/**
224- * Converts a word to its pronounced letter representations based on PRONOUNCED_LETTERS.
225- * @param {string } word - The word to convert.
226- * @returns {string } The word with pronounced letters separated by spaces.
262+ * Calculates a ratio that likely represents the degree of similarity of a given string to elements in a 'panned' array.
263+ *
264+ * @param {string } string - The string to be compared against the elements in the 'panned' array.
265+ * @returns {number } The highest similarity ratio found between the string and elements in 'panned'.
227266 */
228- export function wordToLetters ( word : string ) : string {
229- let newWord = '' ;
230-
231- // Loop through each character in the input word
232- for ( let i = 0 ; i < word . length ; i ++ ) {
233- const letter = word [ i ] ;
267+ function pannedSimilarityRatio ( string : string ) : number {
268+ let maximumSimilarity = - 1 ;
269+ for ( const i in PANNED_WORDS ) {
270+ const calculatedSimilarity = similarityScore ( string , PANNED_WORDS [ i ] ) ;
271+ if ( calculatedSimilarity > maximumSimilarity ) {
272+ maximumSimilarity = calculatedSimilarity ;
273+ }
274+ }
275+ return maximumSimilarity * 100 ;
276+ }
234277
235- // Check if the current letter has a pronunciation in PRONOUNCED_LETTERS
236- if ( PRONOUNCED_LETTERS . hasOwnProperty ( letter ) ) {
237- newWord += PRONOUNCED_LETTERS [ letter ] ;
278+ /**
279+ * Checks if a string is similar to any 'panned' words based on a predefined similarity ratio.
280+ *
281+ * @param {string } string - The string to be checked.
282+ * @returns {boolean } True if the string is similar to any 'panned' word, false otherwise.
283+ */
284+ function checkIfPannedWord ( string : string ) : boolean {
285+ const std_ratio = 70 ;
286+ return pannedSimilarityRatio ( removeArabicAffixes ( string ) ) >= std_ratio ;
287+ }
238288
239- // Add a space after the pronounced letter unless it's the last letter in the word
240- if ( i !== word . length - 1 ) {
241- newWord += ' ' ;
242- }
289+ /**
290+ * Performs tashfeer encryption on a given sentence, but only for words that are considered "panned" words.
291+ * Panned words are determined based on a predefined similarity ratio.
292+ *
293+ * @param {string } sentence - The input sentence to be encrypted.
294+ * @param {number } [levelOfTashfeer=2] - The encryption level (default is 2).
295+ * @returns {string } The encrypted sentence with tashfeer applied to panned words.
296+ */
297+ export function tashfeerPannedWords ( sentence : string , levelOfTashfeer : number = 2 ) : string {
298+ let new_sentence = '' ;
299+ for ( const word of sentence . split ( ' ' ) ) {
300+ if ( checkIfPannedWord ( word ) ) {
301+ new_sentence += tashfeerHandler ( word , levelOfTashfeer ) + ' ' ;
243302 } else {
244- // If the letter is not in PRONOUNCED_LETTERS, keep it unchanged
245- newWord += letter ;
303+ new_sentence += word + ' ' ;
246304 }
247305 }
248-
249- return newWord . trim ( ) ;
306+ return new_sentence . trim ( ) ;
250307}
0 commit comments