File size: 8,882 Bytes
b0503ee
84669bc
b7577da
7feda08
90fff6b
7fc55d1
 
9ea0d50
96d6bc7
6d0ac04
90fff6b
 
 
9ea0d50
 
 
 
7fc55d1
51568dc
6ba2176
9ea0d50
6ba2176
 
 
fbc26ed
6ba2176
7feda08
59b2b8e
 
 
 
 
9ea0d50
55748cc
 
 
 
 
 
 
8013380
 
 
 
 
 
 
9ea0d50
1cf3f25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90fff6b
7c294cd
92af867
 
 
 
 
2b58aa4
 
 
 
 
 
 
 
 
 
 
 
 
 
9ea0d50
 
 
 
 
 
 
 
 
 
 
 
 
55748cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96d6bc7
 
55748cc
96d6bc7
55748cc
96d6bc7
 
55748cc
 
96d6bc7
 
59b2b8e
 
 
 
 
 
 
 
 
 
 
 
 
96d6bc7
59b2b8e
96d6bc7
 
 
 
 
 
 
 
 
 
 
59b2b8e
 
 
 
 
96d6bc7
2b58aa4
 
 
 
 
 
 
 
 
 
 
 
 
96d6bc7
2b58aa4
 
96d6bc7
 
90fff6b
96d6bc7
 
 
92af867
2b58aa4
90fff6b
 
 
e21ee90
 
59b2b8e
96d6bc7
59b2b8e
847e3e1
90fff6b
c163eb2
90fff6b
 
 
 
 
 
 
c35eed6
 
 
 
 
 
90fff6b
c35eed6
96d6bc7
aed9390
96d6bc7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import os
import gradio as gr
from transformers import pipeline
import spacy
import subprocess
import nltk
from nltk.corpus import wordnet
from spellchecker import SpellChecker
import random

# Initialize the English text classification pipeline for AI detection
pipeline_en = pipeline(task="text-classification", model="Hello-SimpleAI/chatgpt-detector-roberta")

# Initialize the spell checker
spell = SpellChecker()

# Ensure necessary NLTK data is downloaded
nltk.download('wordnet')
nltk.download('omw-1.4')

# Ensure the SpaCy model is installed
try:
    nlp = spacy.load("en_core_web_sm")
except OSError:
    subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])
    nlp = spacy.load("en_core_web_sm")

# Function to predict the label and score for English text (AI Detection)
def predict_en(text):
    res = pipeline_en(text)[0]
    return res['label'], res['score']

# Function to get synonyms using NLTK WordNet
def get_synonyms_nltk(word, pos):
    synsets = wordnet.synsets(word, pos=pos)
    if synsets:
        lemmas = synsets[0].lemmas()
        return [lemma.name() for lemma in lemmas]
    return []

# Function to remove redundant and meaningless words
def remove_redundant_words(text):
    doc = nlp(text)
    meaningless_words = {"actually", "basically", "literally", "really", "very", "just"}
    filtered_text = [token.text for token in doc if token.text.lower() not in meaningless_words]
    return ' '.join(filtered_text)

# Function to capitalize the first letter of sentences and proper nouns
def capitalize_sentences_and_nouns(text):
    doc = nlp(text)
    corrected_text = []

    for sent in doc.sents:
        sentence = []
        for token in sent:
            if token.i == sent.start:  # First word of the sentence
                sentence.append(token.text.capitalize())
            elif token.pos_ == "PROPN":  # Proper noun
                sentence.append(token.text.capitalize())
            else:
                sentence.append(token.text)
        corrected_text.append(' '.join(sentence))

    return ' '.join(corrected_text)

# Function to force capitalization of the first letter of every sentence
def force_first_letter_capital(text):
    sentences = text.split(". ")  # Split by period to get each sentence
    capitalized_sentences = [sentence[0].capitalize() + sentence[1:] if sentence else "" for sentence in sentences]
    return ". ".join(capitalized_sentences)

# Function to handle possessive 's and retain original meaning
def handle_possessives(text):
    doc = nlp(text)
    corrected_text = []

    for token in doc:
        # If token is a possessive form (e.g., 'Earth's'), retain its original form
        if token.text.endswith("'s") or token.text == "'s":
            corrected_text.append(token.text)  # Keep it as is, even if a synonym is found
        else:
            corrected_text.append(token.text)

    return ' '.join(corrected_text)

# Function to correct tense errors in a sentence
def correct_tense_errors(text):
    doc = nlp(text)
    corrected_text = []
    for token in doc:
        if token.pos_ == "VERB" and token.dep_ in {"aux", "auxpass"}:
            lemma = wordnet.morphy(token.text, wordnet.VERB) or token.text
            corrected_text.append(lemma)
        else:
            corrected_text.append(token.text)
    return ' '.join(corrected_text)

# Function to correct singular/plural errors
def correct_singular_plural_errors(text):
    doc = nlp(text)
    corrected_text = []
    
    for token in doc:
        if token.pos_ == "NOUN":
            if token.tag_ == "NN":  # Singular noun
                if any(child.text.lower() in ['many', 'several', 'few'] for child in token.head.children):
                    corrected_text.append(token.lemma_ + 's')
                else:
                    corrected_text.append(token.text)
            elif token.tag_ == "NNS":  # Plural noun
                if any(child.text.lower() in ['a', 'one'] for child in token.head.children):
                    corrected_text.append(token.lemma_)
                else:
                    corrected_text.append(token.text)
        else:
            corrected_text.append(token.text)
    
    return ' '.join(corrected_text)

# Function to check and correct article errors
def correct_article_errors(text):
    doc = nlp(text)
    corrected_text = []
    for token in doc:
        if token.text in ['a', 'an']:
            next_token = token.nbor(1)
            if token.text == "a" and next_token.text[0].lower() in "aeiou":
                corrected_text.append("an")
            elif token.text == "an" and next_token.text[0].lower() not in "aeiou":
                corrected_text.append("a")
            else:
                corrected_text.append(token.text)
        else:
            corrected_text.append(token.text)
    return ' '.join(corrected_text)

# Function to dynamically choose synonyms with more options
def dynamic_synonyms(token, pos):
    synonyms = get_synonyms_nltk(token.lemma_, pos)
    # Choose a random synonym to increase variety
    if synonyms:
        random_synonym = random.choice(synonyms)
        return random_synonym
    return token.text

# Function to rephrase text and replace words with more versatile synonyms
def versatile_rephrase(text):
    doc = nlp(text)
    rephrased_text = []

    for token in doc:
        pos_tag = None
        if token.pos_ == "NOUN":
            pos_tag = wordnet.NOUN
        elif token.pos_ == "VERB":
            pos_tag = wordnet.VERB
        elif token.pos_ == "ADJ":
            pos_tag = wordnet.ADJ
        elif token.pos_ == "ADV":
            pos_tag = wordnet.ADV

        if pos_tag:
            synonym = dynamic_synonyms(token, pos_tag)
            if token.pos_ == "VERB":
                if token.tag_ == "VBG":  # Present participle (e.g., running)
                    synonym = synonym + 'ing'
                elif token.tag_ == "VBD" or token.tag_ == "VBN":  # Past tense or past participle
                    synonym = synonym + 'ed'
                elif token.tag_ == "VBZ":  # Third-person singular present
                    synonym = synonym + 's'
            elif token.pos_ == "NOUN" and token.tag_ == "NNS":  # Plural nouns
                synonym += 's' if not synonym ends with 's' else ""
            rephrased_text.append(synonym)
        else:
            rephrased_text.append(token.text)

    return ' '.join(rephrased_text)

# Function to retain the structure of the input text (headings, paragraphs, line breaks)
def retain_structure(text):
    lines = text.split("\n")
    formatted_lines = []
    
    for line in lines:
        if line.strip().isupper():  # Heading if all caps
            formatted_lines.append(f"# {line.strip()}")  # Treat it as a heading
        else:
            formatted_lines.append(line)  # Otherwise, it's a paragraph or normal text
    
    return "\n".join(formatted_lines)

# Function to paraphrase and correct grammar with enhanced accuracy and retain structure
def paraphrase_and_correct_with_structure(text):
    structured_text = retain_structure(text)
    
    # Rephrase with more versatile synonyms while maintaining grammatical forms
    paraphrased_text = versatile_rephrase(structured_text)
    
    # Apply grammatical corrections on the rephrased text
    paraphrased_text = remove_redundant_words(paraphrased_text)
    paraphrased_text = capitalize_sentences_and_nouns(paraphrased_text)
    paraphrased_text = force_first_letter_capital(paraphrased_text)
    paraphrased_text = handle_possessives(paraphrased_text)
    paraphrased_text = correct_article_errors(paraphrased_text)
    paraphrased_text = correct_singular_plural_errors(paraphrased_text)
    paraphrased_text = correct_tense_errors(paraphrased_text)
    paraphrased_text = correct_double_negatives(paraphrased_text)
    paraphrased_text = ensure_subject_verb_agreement(paraphrased_text)
    paraphrased_text = correct_spelling(paraphrased_text)

    return paraphrased_text

# Gradio app setup with two tabs
with gr.Blocks() as demo:
    with gr.Tab("AI Detection"):
        t1 = gr.Textbox(lines=5, label='Text')
        button1 = gr.Button("🤖 Predict!")
        label1 = gr.Textbox(lines=1, label='Predicted Label 🎃')
        score1 = gr.Textbox(lines=1, label='Prob')

        # Connect the prediction function to the button
        button1.click(fn=predict_en, inputs=t1, outputs=[label1, score1])

    with gr.Tab("Paraphrasing & Grammar Correction"):
        t2 = gr.Textbox(lines=5, label='Enter text for paraphrasing and grammar correction')
        button2 = gr.Button("🔄 Paraphrase and Correct")
        result2 = gr.Textbox(lines=5, label='Corrected Text')

        # Connect the paraphrasing and correction function to the button
        button2.click(fn=paraphrase_and_correct_with_structure, inputs=t2, outputs=result2)

demo.launch(share=True)