File size: 3,283 Bytes
e0171fd
 
b054a29
24d2316
e0171fd
24d2316
e0171fd
 
 
 
 
478fdb3
e0171fd
bd23bae
c14d215
bd23bae
 
 
478fdb3
c14d215
bd23bae
 
fa2e050
 
 
 
6b49f37
bd23bae
6b49f37
fa2e050
bd23bae
 
c14d215
 
24d2316
6b49f37
 
478fdb3
bd23bae
 
 
b054a29
 
 
c14d215
 
 
478fdb3
c14d215
 
bd23bae
b054a29
6b49f37
478fdb3
c14d215
bd23bae
6b49f37
478fdb3
6b49f37
478fdb3
b054a29
4f51398
b054a29
4f51398
e14c302
478fdb3
 
bd23bae
 
 
478fdb3
e0171fd
bd23bae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
478fdb3
 
 
e0171fd
bd23bae
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
import pronouncing
import string
import itertools
import gradio as gr

CONSONANTS = set(string.ascii_uppercase) - set('AEIOU')

def get_phones(word):
    phones_for_word = pronouncing.phones_for_word(word)
    if not phones_for_word:
        return None
    return phones_for_word[0].split()

def _get_rhyming_tail(phones):
    vowels = [phone for phone in phones if phone[0] in 'AEIOU']
    syllable_count = len(vowels)
    if syllable_count < 1:
        return None
    return phones[-syllable_count * 2:]

def get_exact_rhymes(phones):
    rhyming_tail = _get_rhyming_tail(phones)
    if not rhyming_tail:
        return []
    
    rhyming_tail_str = " ".join(rhyming_tail)
    matches = pronouncing.search(rhyming_tail_str + "$")
    exact_rhymes = [match for match in matches if rhyming_tail == _get_rhyming_tail(get_phones(match))]
    return exact_rhymes

def get_filtered_loose_rhymes(phones):
    rhyming_tail = _get_rhyming_tail(phones)
    if not rhyming_tail:
        return []
    
    search_pattern = " ".join(phone[:-1] + "." for phone in rhyming_tail)
    matches = pronouncing.search(search_pattern)
    filtered_rhymes = [match for match in matches if get_phones(match)]
    return filtered_rhymes

def find_rhymes_for_phrase(phrase):
    words = phrase.split()
    rhyming_options = []

    for word in words:
        phones = get_phones(word)
        if phones is None:
            rhyming_options.append([[f"{word} (Not recognized)"]])
            continue
        
        exact_rhymes = get_exact_rhymes(phones)
        
        if exact_rhymes:
            rhyming_options.append([[rhyme] for rhyme in exact_rhymes])
        else:
            loose_rhymes = get_filtered_loose_rhymes(phones)
            if loose_rhymes:
                rhyming_options.append([[rhyme] for rhyme in loose_rhymes])
            else:
                rhyming_options.append([[f"{word} (No rhymes found)"]])
    
    # Flatten each combination into strings
    combined_results = list(itertools.product(*rhyming_options))
    unique_results = set(" ".join(item[0] for item in combination) for combination in combined_results)
    
    # Return a list of unique rhyming combinations, each wrapped in a list for DataFrame compatibility
    return [[rhyme] for rhyme in unique_results]

# Function to update the notepad with a selected rhyme
def add_to_notepad(notepad, selected_rhyme):
    return notepad + "\n" + selected_rhyme

# Gradio Interface
with gr.Blocks() as demo:
    gr.Markdown("## Interactive Rhyming Generator with Notepad")
    
    # Inputs for the rhyming generator
    phrase_input = gr.Textbox(label="Enter phrase (space-separated words)")
    
    # Output areas
    rhyme_output = gr.Dataframe(headers=["Rhyming Phrases"], interactive=False)
    notepad = gr.Textbox(label="Notepad", lines=10, placeholder="Write your lyrics here...")
    
    # Button for generating rhymes
    generate_btn = gr.Button("Generate Rhymes")
    
    # Display rhyming results and update notepad on button click
    generate_btn.click(find_rhymes_for_phrase, inputs=[phrase_input], outputs=rhyme_output)
    
    # Functionality to select a rhyme and add it to the notepad
    rhyme_output.select(add_to_notepad, inputs=[notepad, rhyme_output], outputs=notepad)

demo.launch()