Spaces:
Running
Running
| import cairosvg | |
| import io | |
| import base64 | |
| import re | |
| from PIL import Image | |
| def svg_to_png_base64(svg_content: str, width=800, height=800) -> tuple[str, str]: | |
| """Convert SVG to PNG and return as base64 encoded string with media type. | |
| Args: | |
| svg_content: SVG markup string | |
| width: Desired PNG width | |
| height: Desired PNG height | |
| Returns: | |
| Tuple of (media_type, base64_string) | |
| """ | |
| try: | |
| # Convert SVG to PNG using cairosvg | |
| png_data = cairosvg.svg2png( | |
| bytestring=svg_content.encode("utf-8"), | |
| output_width=width, | |
| output_height=height, | |
| ) | |
| # Open PNG with Pillow to ensure correct format | |
| img = Image.open(io.BytesIO(png_data)) | |
| # Convert to RGB if needed | |
| if img.mode != "RGB": | |
| img = img.convert("RGB") | |
| # Save as PNG to bytes | |
| img_byte_arr = io.BytesIO() | |
| img.save(img_byte_arr, format="PNG") | |
| img_byte_arr = img_byte_arr.getvalue() | |
| # Encode to base64 | |
| base64_str = base64.b64encode(img_byte_arr).decode("utf-8") | |
| return "image/png", base64_str | |
| except Exception as e: | |
| print(f"Error converting SVG to PNG: {e}") | |
| return "", "" | |
| def normalize_html_content(html_content: str) -> str: | |
| """ | |
| Normalizes the body and svg styles in the HTML content to fixed values. | |
| """ | |
| fixed_body_style = """body { | |
| margin: 0; | |
| padding: 20px; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| min-height: 100%; | |
| overflow: hidden; | |
| }""" | |
| fixed_svg_style = """svg { | |
| max-width: 400px; | |
| height: auto; | |
| border-radius: 10px; | |
| }""" | |
| if '<meta name="viewport"' not in html_content: | |
| html_content = html_content.replace( | |
| "<head>", | |
| '<head>\n<meta name="viewport" content="width=device-width, initial-scale=1.0">', | |
| ) | |
| body_pattern = r"body\s*\{[^}]*\}" | |
| html_content = re.sub( | |
| body_pattern, | |
| fixed_body_style, | |
| html_content, | |
| flags=re.MULTILINE | re.DOTALL | re.IGNORECASE, | |
| ) | |
| # Match and replace svg style pattern | |
| svg_pattern = r"svg\s*\{[^}]*\}" | |
| html_content = re.sub( | |
| svg_pattern, | |
| fixed_svg_style, | |
| html_content, | |
| flags=re.MULTILINE | re.DOTALL | re.IGNORECASE, | |
| ) | |
| return html_content | |
| def fix_html_styles_for_preview(html_content: str) -> str: | |
| """ | |
| Main function to modify HTML styles for preview purposes. | |
| """ | |
| if not html_content or not html_content.strip(): | |
| return html_content | |
| try: | |
| normalized_html = normalize_html_content(html_content) | |
| if "<!DOCTYPE html>" not in normalized_html: | |
| normalized_html = "<!DOCTYPE html>\n" + normalized_html | |
| if "<meta charset=" not in normalized_html: | |
| normalized_html = normalized_html.replace( | |
| "<head>", '<head>\n<meta charset="utf-8">' | |
| ) | |
| return normalized_html | |
| except Exception as e: | |
| print(f"Error occurred while modifying HTML styles: {e}") | |
| return html_content | |