import io import os import re import glob import textwrap from datetime import datetime from pathlib import Path import streamlit as st import pandas as pd from PIL import Image from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import letter from reportlab.lib.utils import ImageReader import mistune from gtts import gTTS # Page config st.set_page_config(page_title="PDF & Code Interpreter", layout="wide", page_icon="๐") def delete_asset(path): try: os.remove(path) except: pass st.rerun() # Tabs setup tab1, tab2 = st.tabs(["๐ PDF Composer", "๐งช Code Interpreter"]) with tab1: st.header("๐ PDF Composer & Voice Generator ๐") # Sidebar PDF text settings columns = st.sidebar.slider("Text columns", 1, 3, 1) font_family = st.sidebar.selectbox("Font", ["Helvetica","Times-Roman","Courier"]) font_size = st.sidebar.slider("Font size", 6, 24, 12) # Markdown input md_file = st.file_uploader("Upload Markdown (.md)", type=["md"]) if md_file: md_text = md_file.getvalue().decode("utf-8") stem = Path(md_file.name).stem else: md_text = st.text_area("Or enter markdown text directly", height=200) stem = datetime.now().strftime('%Y%m%d_%H%M%S') # Convert Markdown to plain text renderer = mistune.HTMLRenderer() markdown = mistune.create_markdown(renderer=renderer) html = markdown(md_text or "") plain_text = re.sub(r'<[^>]+>', '', html) # Voice settings languages = {"English (US)": "en", "English (UK)": "en-uk", "Spanish": "es"} voice_choice = st.selectbox("Voice Language", list(languages.keys())) voice_lang = languages[voice_choice] slow = st.checkbox("Slow Speech") if st.button("๐ Generate & Download Voice MP3 from Text"): if plain_text.strip(): voice_file = f"{stem}.mp3" tts = gTTS(text=plain_text, lang=voice_lang, slow=slow) tts.save(voice_file) st.audio(voice_file) with open(voice_file, 'rb') as mp3: st.download_button("๐ฅ Download MP3", data=mp3, file_name=voice_file, mime="audio/mpeg") else: st.warning("No text to generate voice from.") # Image uploads and ordering imgs = st.file_uploader("Upload Images for PDF", type=["png", "jpg", "jpeg"], accept_multiple_files=True) ordered_images = [] if imgs: df_imgs = pd.DataFrame([{"name": f.name, "order": i} for i, f in enumerate(imgs)]) edited = st.data_editor(df_imgs, use_container_width=True) for _, row in edited.sort_values("order").iterrows(): for f in imgs: if f.name == row['name']: ordered_images.append(f) break if st.button("๐๏ธ Generate PDF with Markdown & Images"): buf = io.BytesIO() c = canvas.Canvas(buf) # Render text with columns page_w, page_h = letter margin = 40 gutter = 20 col_w = (page_w - 2*margin - (columns-1)*gutter) / columns c.setFont(font_family, font_size) line_height = font_size * 1.2 col = 0 x = margin y = page_h - margin wrap_width = int(col_w / (font_size * 0.6)) for paragraph in plain_text.split("\n"): for line in textwrap.wrap(paragraph, wrap_width): if y < margin: col += 1 if col >= columns: c.showPage() c.setFont(font_family, font_size) col = 0 x = margin + col*(col_w+gutter) y = page_h - margin c.drawString(x, y, line) y -= line_height y -= line_height # Autosize pages to each image for img_f in ordered_images: try: img = Image.open(img_f) w, h = img.size c.showPage() c.setPageSize((w, h)) c.drawImage(ImageReader(img), 0, 0, w, h, preserveAspectRatio=True, mask='auto') except: continue c.save() buf.seek(0) pdf_name = f"{stem}.pdf" st.download_button("โฌ๏ธ Download PDF", data=buf, file_name=pdf_name, mime="application/pdf") st.markdown("---") st.subheader("๐ Available Assets") assets = sorted(glob.glob("*.*")) for a in assets: ext = a.split('.')[-1].lower() cols = st.columns([3, 1, 1]) cols[0].write(a) if ext == 'pdf': with open(a, 'rb') as fp: cols[1].download_button("๐ฅ", data=fp, file_name=a, mime="application/pdf") elif ext == 'mp3': cols[1].audio(a) with open(a, 'rb') as mp3: cols[1].download_button("๐ฅ", data=mp3, file_name=a, mime="audio/mpeg") cols[2].button("๐๏ธ", key=f"del_{a}", on_click=delete_asset, args=(a,)) with tab2: st.header("๐งช Python Code Executor & Demo") import io, sys from contextlib import redirect_stdout DEFAULT_CODE = '''import streamlit as st import random st.title("๐ Demo App") st.markdown("Random number and color demo") col1, col2 = st.columns(2) with col1: num = st.number_input("Number:", 1, 100, 10) mul = st.slider("Multiplier:", 1, 10, 2) if st.button("Calc"): st.write(num * mul) with col2: color = st.color_picker("Pick color","#ff0000") st.markdown(f'