File size: 5,798 Bytes
25a72c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a22a061
25a72c4
a22a061
25a72c4
 
a22a061
25a72c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
from database import db  # Import Firestore client
import html
import re
import numpy as np
import torch
from transformers import pipeline
import soundfile as sf

def get_text_from_firebase(text_id):
    """Retrieve text from Firebase Firestore."""
    try:
        doc = db.collection("texts").document(text_id).get()
        if doc.exists:
            return doc.to_dict()["content"]
        else:
            return None
    except Exception as e:
        st.error(f"Error retrieving text from Firebase: {e}")
        return None

def process_text(text):
    """Clean and structure the extracted text."""
    text = re.sub(r'\n\s*\n', '\n\n', text)
    text = re.sub(r'^(\s*•\s+)(.*)$', r'<li>\2</li>', text, flags=re.MULTILINE)
    text = re.sub(r'(<li>.*</li>\n)+', r'<ul>\g<0></ul>\n', text)
    text = re.sub(r'^([A-Z][A-Z\s]+:?)\s*$', r'<h3 class="heading">\1</h3>', text, flags=re.MULTILINE)
    text = re.sub(r'(https?://\S+)', r'<a href="\1" target="_blank">\1</a>', text)

    paragraphs = text.split('\n\n')
    processed = []

    for p in paragraphs:
        p = p.strip()
        if p:
            if p.startswith('<ul>') or p.startswith('<h3'):
                processed.append(p)
            else:
                processed.append(f'<p>{p}</p>')

    return '\n'.join(processed)

def text_to_speech(text):
    """Convert text to speech using Hugging Face's SpeechBrain model."""
    try:
        tts_pipeline = pipeline("text-to-speech", model="speechbrain/tts-tacotron2-ljspeech", device=0 if torch.cuda.is_available() else -1)
        output = tts_pipeline(text)

        audio_array = np.array(output["audio"])
        sample_rate = output["sampling_rate"]

        audio_file = "output.wav"
        sf.write(audio_file, audio_array, sample_rate)
        return audio_file
    except Exception as e:
        st.error(f"Error during text-to-speech conversion: {e}")
        return None

def main():
    st.title("Accessibility-Optimized Viewer")

    # Ask user for Document ID
    text_id = st.text_input("Enter Document ID to view text:")

    if text_id:
        text = get_text_from_firebase(text_id)
        if text:
            col1, col2, col3 = st.columns(3)
            with col1:
                font_size = st.slider("Font Size", 8, 48, 16)
                line_height = st.slider("Line Height", 1.0, 2.5, 1.5)
            with col2:
                font_color = st.color_picker("Text Color", "#000000")
                bg_color = st.color_picker("Background Color", "#FFFFFF")
            with col3:
                contrast_mode = st.checkbox("High Contrast Mode")
                dyslexia_font = st.checkbox("Dyslexia-Friendly Font")

            if contrast_mode:
                font_color = "#FFFFFF"
                bg_color = "#000000"

            font_family = "Arial" if not dyslexia_font else "OpenDyslexic, sans-serif"

            custom_css = f"""
            <style>
                .content {{
                    font-size: {font_size}px;
                    color: {font_color};
                    background-color: {bg_color};
                    line-height: {line_height};
                    font-family: {font_family};
                    padding: 20px;
                    border-radius: 10px;
                    margin: 10px 0;
                    white-space: pre-wrap;
                    word-wrap: break-word;
                    hyphens: auto;
                }}

                .content p {{
                    margin: 0.8em 0;
                }}

                .content ul {{
                    margin: 0.8em 20px;
                    padding-left: 20px;
                    list-style-type: disc;
                }}

                .content h3 {{
                    font-size: 1.2em;
                    margin: 1.2em 0 0.5em;
                    padding-bottom: 3px;
                    border-bottom: 2px solid {font_color};
                }}

                .content a {{
                    color: {font_color};
                    text-decoration: underline;
                    word-break: break-all;
                }}

                @keyframes highlight {{ 0% {{background: yellow;}} 100% {{background: transparent;}} }}
                .highlight {{ animation: highlight 2s; }}
            </style>
            """
            st.markdown(custom_css, unsafe_allow_html=True)

            processed_text = process_text(html.escape(text))
            st.markdown(f'<div class="content">{processed_text}</div>', unsafe_allow_html=True)

            with st.expander("More Accessibility Options"):
                col1, col2 = st.columns(2)
                with col1:
                    letter_spacing = st.slider("Letter Spacing (px)", -1, 5, 0)
                    word_spacing = st.slider("Word Spacing (px)", 0, 10, 0)
                with col2:
                    text_align = st.selectbox("Text Alignment", ["left", "justify", "center"])
                    text_transform = st.selectbox("Text Case", ["none", "uppercase", "lowercase"])

                st.markdown(f"""
                <style>
                    .content {{
                        letter-spacing: {letter_spacing}px;
                        word-spacing: {word_spacing}px;
                        text-align: {text_align};
                        text-transform: {text_transform};
                    }}
                </style>
                """, unsafe_allow_html=True)

            # **Text-to-Speech Button**
            if st.button("Read Aloud"):
                audio_file = text_to_speech(text)
                if audio_file:
                    st.audio(audio_file, format="audio/wav")

        else:
            st.error("Text not found. Please check the ID.")

if __name__ == "__main__":
    main()