from reportlab.lib import colors from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from io import BytesIO import re class Exporter: def __init__(self): self.styles = getSampleStyleSheet() self.setup_styles() def _register_fonts(self): pdfmetrics.registerFont(TTFont("Helvetica", "Helvetica")) pdfmetrics.registerFont(TTFont("Helvetica-Bold", "Helvetica-Bold")) def setup_styles(self): self.styles.add( ParagraphStyle( name="Header", fontSize=14, textColor=colors.HexColor("#10B981"), spaceAfter=12, fontName="Helvetica-Bold", encoding="utf-8", ) ) self.styles.add( ParagraphStyle( name="Content", fontSize=11, textColor=colors.black, spaceAfter=8, fontName="Helvetica", encoding="utf-8", ) ) self.styles.add( ParagraphStyle( name="Bullet-Point", fontSize=11, leftIndent=20, bulletIndent=10, spaceAfter=5, fontName="Helvetica", encoding="utf-8", ) ) def clean_text(self, text: str) -> str: if not isinstance(text, str): text = text.decode("utf-8") text = text.replace("ı", "i").replace("İ", "I") text = text.replace("ğ", "g").replace("Ğ", "G") text = text.replace("ü", "u").replace("Ü", "U") text = text.replace("ş", "s").replace("Ş", "S") text = text.replace("ö", "o").replace("Ö", "O") text = text.replace("ç", "c").replace("Ç", "C") text = re.sub( r"\[header\](.*?)\[/header\]", r'\1', text ) text = re.sub(r"\[bold\](.*?)\[/bold\]", r"\1", text) return text def create_watermark(self, canvas, doc): canvas.saveState() canvas.setFillColor(colors.HexColor("#10B981")) canvas.setFont("Helvetica", 8) canvas.drawString(30, 20, "Generated by docklink.io") canvas.restoreState() def export_pdf(self, data: str) -> BytesIO: buffer = BytesIO() content = [] cleaned_text = self.clean_text(data) doc = SimpleDocTemplate( buffer, pagesize=A4, rightMargin=30, leftMargin=30, topMargin=30, bottomMargin=30, ) lines = cleaned_text.split("\n") for line in lines: if line.strip(): if ( line.startswith("

") or line.startswith('') or "header" in line ): # Header section text = line.replace("

", "").replace("

", "") content.append(Paragraph(text, self.styles["Header"])) elif line.startswith("-"): # Bullet point text = line.strip() content.append(Paragraph(f"- {text}", self.styles["Bullet-Point"])) else: # Normal text content.append(Paragraph(line, self.styles["Content"])) content.append(Spacer(1, 2)) try: doc.build( content, onFirstPage=self.create_watermark, onLaterPages=self.create_watermark, ) buffer.seek(0) return buffer except Exception as e: raise ValueError( f"Error: {e} Content too large or complex to export to PDF" )