File size: 3,114 Bytes
2720487 |
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 |
from playwright.sync_api import sync_playwright
from PIL import Image
import io
def latex_to_pil(latex_code, target_width, target_height, fontsize=18):
html_template = """
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.0/dist/katex.min.css">
<script src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
display: flex;
}
#content {
font-size: {fontsize}px;
}
</style>
</head>
<body>
<div id="content">{content}</div>
<script>
function renderMath() {
let content = document.getElementById('content');
let html = content.innerHTML;
// Replace display equations
html = html.replace(/\\$\\$(.*?)\\$\\$/gs, (match, equation) => {
let span = document.createElement('span');
katex.render(equation, span, { displayMode: true, throwOnError: false, errorColor: '#000' });
return span.outerHTML;
});
// Replace inline equations
html = html.replace(/\\$(.*?)\\$/g, (match, equation) => {
if(match.startsWith('\\\\$')) return match; // Ignore escaped dollars
let span = document.createElement('span');
katex.render(equation, span, { displayMode: false, throwOnError: false, errorColor: '#000' });
return span.outerHTML;
});
content.innerHTML = html;
}
renderMath();
</script>
</body>
</html>
"""
formatted_latex = latex_code.replace('\n', '\\n').replace('"', '\\"')
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.set_viewport_size({'width': target_width, 'height': target_height})
while fontsize <= 30:
html_content = html_template.replace("{content}", formatted_latex).replace("{fontsize}", str(fontsize))
page.set_content(html_content)
dimensions = page.evaluate("""() => {
const render = document.getElementById('content');
return {
width: render.offsetWidth,
height: render.offsetHeight
};
}""")
if dimensions['width'] >= target_width or dimensions['height'] >= target_height:
fontsize -= 1
break
else:
fontsize += 1
html_content = html_template.replace("{content}", formatted_latex).replace("{fontsize}", str(fontsize))
page.set_content(html_content)
screenshot_bytes = page.screenshot()
browser.close()
image_stream = io.BytesIO(screenshot_bytes)
pil_image = Image.open(image_stream)
pil_image.load()
return pil_image |