import gradio as gr import unicodeconverter as uc from weasyprint import HTML import os import tempfile import shutil import re from groq import Groq from docx import Document from docx.shared import Pt, RGBColor from docx.enum.text import WD_ALIGN_PARAGRAPH # Default font (fallback) DEFAULT_FONT_PATH = os.path.abspath("SolaimanLipi_22-02-2012.ttf") HAS_DEFAULT_FONT = os.path.exists(DEFAULT_FONT_PATH) def detect_and_preserve_english(text, groq_api_key): """ Use Groq AI to identify English segments in mixed Bijoy-English text Returns a list of tuples: (text_segment, is_english) """ try: client = Groq(api_key=groq_api_key) prompt = f"""You are a text analyzer. Analyze this text and identify which parts are English and which are Bijoy-encoded Bengali. Text: {text} Return a JSON array where each element is an object with: - "text": the text segment - "is_english": true if English, false if Bijoy Bengali Rules: 1. English segments include: letters (a-z, A-Z), common punctuation, numbers in English context 2. Bijoy segments include: Bengali-encoded characters with special symbols 3. Preserve exact spacing and punctuation 4. Split at language boundaries Example output format: [ {{"text": "bijoy text here", "is_english": false}}, {{"text": " This is English.", "is_english": true}}, {{"text": " more bijoy", "is_english": false}} ] Return ONLY the JSON array, nothing else.""" response = client.chat.completions.create( messages=[{"role": "user", "content": prompt}], model="llama-3.3-70b-versatile", temperature=0.1, max_tokens=2000 ) result_text = response.choices[0].message.content.strip() # Extract JSON from response json_match = re.search(r'\[.*\]', result_text, re.DOTALL) if json_match: import json segments = json.loads(json_match.group()) return segments else: return [{"text": text, "is_english": False}] except Exception as e: print(f"Groq API Error: {e}") return [{"text": text, "is_english": False}] def create_txt_file(unicode_text): """Create a TXT file with the converted Unicode text""" temp_txt = tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode='w', encoding='utf-8') temp_txt.write(unicode_text) temp_txt.close() return temp_txt.name def create_docx_file(unicode_text): """Create a DOCX file with the converted Unicode text""" doc = Document() # Add paragraph with Bengali text paragraph = doc.add_paragraph(unicode_text) # Format the paragraph paragraph_format = paragraph.paragraph_format paragraph_format.line_spacing = 1.5 paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT # Format the text run for run in paragraph.runs: run.font.size = Pt(12) run.font.name = 'Noto Sans Bengali' run.font.color.rgb = RGBColor(0, 0, 0) # Save to temp file temp_docx = tempfile.NamedTemporaryFile(delete=False, suffix=".docx") temp_docx.close() doc.save(temp_docx.name) return temp_docx.name def bijoy_to_all_formats(bijoy_text, uploaded_font, groq_api_key): try: if not groq_api_key or groq_api_key.strip() == "": return "Error: Please enter your Groq API key.", None, None, None # Detect and separate English and Bijoy segments segments = detect_and_preserve_english(bijoy_text, groq_api_key) # Convert only Bijoy segments to Unicode converted_segments = [] for segment in segments: if segment["is_english"]: converted_segments.append(segment["text"]) else: try: unicode_segment = uc.convert_bijoy_to_unicode(segment["text"]) converted_segments.append(unicode_segment) except: converted_segments.append(segment["text"]) unicode_text = "".join(converted_segments) # Generate TXT file txt_path = create_txt_file(unicode_text) # Generate DOCX file docx_path = create_docx_file(unicode_text) # Determine font path for PDF if uploaded_font is not None: temp_font_dir = tempfile.mkdtemp() font_path = os.path.join(temp_font_dir, os.path.basename(uploaded_font.name)) shutil.copy(uploaded_font.name, font_path) else: if not HAS_DEFAULT_FONT: raise FileNotFoundError( "No font uploaded and default SolaimanLipi font not found." ) font_path = DEFAULT_FONT_PATH # HTML content for PDF html_content = f"""
{unicode_text}
""" # Create PDF temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") temp_pdf.close() HTML(string=html_content).write_pdf( temp_pdf.name, presentational_hints=True ) return unicode_text, temp_pdf.name, docx_path, txt_path except Exception as e: return f"Error: {str(e)}", None, None, None # ------------------------------------------------- # BIJOY TEXT EXAMPLES # ------------------------------------------------- bijoy_examples = [ """‡nj‡g‡Ui wb‡P mvbMvm| mKvj‡eLv‡b cÖwZw`b gvbyl ‡Kvyvi g‡Zv RvqMv _v‡K bv| ‡divi c‡_ Zviv Avcbvi mgq, kÖg Ges AwfÁZv‡K GKmv‡_ wb‡q Rxeb cÖwZ‡e`b K‡i|""", """evsjv‡`‡ki cÖK…wZ gvby‡li g‡b wewfbœ Av‡eM m„wó K‡i| b`x, cvnv‡o Ges meyR gvwUi mv‡_ gvby‡li AvZœxq m¤úK© AvMvb _v‡K| G mgqB Zviv cÖK…wZi m~ÿ wQšÍv K‡i|""", """wkÿv gvb‡e Rxeb‡K cÖKvwkZ K‡i Ges gvbwmK w`K _v‡K m„wó K‡i| wkÿv Qvov gvbyl AwbðqZvi g‡a¨ _v‡K Ges mvgvwRK weKv‡k cÖwZKzjZvi m¤§yLxb nq|""", """AvaywbK cÖhyw³ gvby‡li `xN©Rxeb‡K m¤ú~Y©iƒ‡c cwieZ©b K‡i‡Q| cÖhyw³i e¨envi Avgv‡`i KvR‡K mnR K‡i Ges mgq euvPvq, Z‡e myweav m¤ú‡K© mZK© _vKvI cÖ‡qvRb|""", """mvgvwRK g~j¨‡eva gvby‡li AvPiY Ges AvPib‡K wbqš¿Y K‡i| mZ¨Zv, b¨vq Ges m¤§vb gvb‡ei g‡a¨ GK‡gvmZ cÖKvk K‡i Ges mvgvwRK m¤úªxwZi Dci AwZ¸i"Z¡c~Y©|""" ] # ------------------------------------------------- # GRADIO UI # ------------------------------------------------- with gr.Blocks(title="Bijoy to Unicode Bengali Converter", theme=gr.themes.Ocean()) as app: gr.Markdown("## 📝 Bijoy → Unicode Bengali Converter (PDF + DOCX + TXT)") gr.Markdown( "**Features:**\n" "- Convert Bijoy Bangla to Unicode using AI\n" "- Automatically detects and preserves English text\n" "- Generate PDF, DOCX, and TXT files\n" "- Upload your preferred Bengali font (.ttf)\n\n" "**Note:** You need a free Groq API key. Get one at [https://console.groq.com](https://console.groq.com)" ) groq_key_input = gr.Textbox( label="Groq API Key", placeholder="Enter your Groq API key here (e.g., gsk_...)", type="password" ) bijoy_input = gr.Textbox( label="Bijoy Text (Mixed Bengali & English)", placeholder="Paste Bijoy-encoded Bangla text with English here...", lines=10 ) font_input = gr.File( label="Optional Bengali Font (.ttf)", file_types=[".ttf"] ) convert_btn = gr.Button("Convert & Generate All Files", variant="primary") unicode_output = gr.Textbox( label="Converted Unicode Text", lines=10, show_copy_button=True ) with gr.Row(): pdf_output = gr.File(label="📄 Download PDF") docx_output = gr.File(label="📝 Download DOCX") txt_output = gr.File(label="📃 Download TXT") gr.Examples( examples=bijoy_examples, inputs=bijoy_input, label="📌 Example Bijoy Texts" ) convert_btn.click( fn=bijoy_to_all_formats, inputs=[bijoy_input, font_input, groq_key_input], outputs=[unicode_output, pdf_output, docx_output, txt_output] ) gr.Markdown( "---\n" "### How to get Groq API Key:\n" "1. Visit [console.groq.com](https://console.groq.com)\n" "2. Sign up for free\n" "3. Create an API key\n" "4. Paste it above\n\n" "### Output Files:\n" "- **PDF**: Print-ready with custom font support\n" "- **DOCX**: Editable Word document\n" "- **TXT**: Plain text Unicode file\n\n" "The app uses the free **llama-3.3-70b-versatile** model to detect English text." ) app.launch()