-
-
Save josch/1007600 to your computer and use it in GitHub Desktop.
A LaTeX filter for blogofile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Render TeX blocks to png | |
This is a Blogofile filter. Place it in your _filters directory. | |
""" | |
import tempfile | |
import subprocess | |
import shutil | |
import shlex | |
import os | |
import re | |
import hashlib | |
import blogofile_bf as bf | |
html_escape_table = {"&": "&",'"': ""","'": "'",">": ">","<": "<"} | |
html_escape = lambda text: "".join(html_escape_table.get(c,c) for c in text) | |
tex_template = r""" | |
\documentclass[12pt]{article} | |
\usepackage{ucs} | |
\usepackage[utf8x]{inputenc} | |
\usepackage{amsmath} | |
\usepackage{amsthm} | |
\usepackage{amssymb} | |
\pagestyle{empty} | |
\begin{document} | |
$%s$ | |
\end{document} | |
""" | |
latex_block_re = re.compile(r"\s\$\$latex\s(.*?)\s\$", re.DOTALL) | |
def render_tex_to_png(latex_block, png_location): | |
"""Render a TeX formatted string to an image file | |
Depends on 'latex' and 'dvipng' binaries on the system path | |
""" | |
#Create a temporary directory and go into it | |
tmp_dir = tempfile.mkdtemp() | |
previous_dir = os.getcwd() | |
os.chdir(tmp_dir) | |
tex_f = open(os.path.join(tmp_dir,"source.tex"),"w") | |
tex_f.write((tex_template % latex_block)) | |
tex_f.close() | |
try: | |
#Generate the .dvi | |
p = subprocess.Popen(shlex.split( | |
'latex -interaction=nonstopmode source.tex'), | |
stdout=subprocess.PIPE) | |
p.wait() | |
#Generate the .ps | |
try: | |
p = subprocess.Popen(shlex.split( | |
'dvipng -bg Transparent -gamma 1.5 -D 120 -T tight' | |
' --strict source.dvi -o rendered.png'), | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE) | |
p.wait() | |
except: | |
p = subprocess.Popen(shlex.split('dvips source.dvi'), | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE) | |
p.wait() | |
#Generate the .png | |
p = subprocess.Popen(shlex.split( | |
'convert -density 120 -trim -transparent' | |
' "#FFFFFF" source.ps rendered.png'),stdout=subprocess.PIPE) | |
p.wait() | |
#Copy the .png to the png_location | |
os.chdir(previous_dir) | |
shutil.copyfile(os.path.join(tmp_dir,"rendered.png"),png_location) | |
finally: | |
#Go back to the original directory and clean up the temp files | |
os.chdir(previous_dir) | |
shutil.rmtree(tmp_dir) | |
def render_latex_blocks(src, cache_dir="_tmp", site_images_dir="images"): | |
"""Render a document with LaTeX blocks | |
1) Extract all the $$latex blocks | |
2) Render each TeX block to an image to the cache | |
3) Copy the (pre)rendered image from the cache to the _site dir | |
4) Replace the $$latex blocks with <img> tags | |
""" | |
img_substitutions = {} | |
for m in latex_block_re.finditer(src): | |
tex_expr = m.groups()[0] | |
fn = hashlib.md5(tex_expr).hexdigest()+".png" | |
png_cached = os.path.join(cache_dir,fn) | |
site_png_dir = bf.util.path_join("_site",bf.util.fs_site_path_helper( | |
site_images_dir)) | |
site_png = bf.util.path_join(site_png_dir,fn) | |
#only render the image if the image is not already cached | |
if(not os.path.isfile(png_cached)): | |
bf.util.mkdir(cache_dir) | |
bf.filter.logger.info("Rendering LaTeX: "+tex_expr) | |
render_tex_to_png(tex_expr,png_cached) | |
#copy the rendered image to the site dir | |
bf.util.mkdir(site_png_dir) | |
shutil.copyfile(png_cached,site_png) | |
#record the $$latex block and it's replacement <img> tag | |
img_substitutions[m.group()] = "<img alt=\"%s\" src=\"%s%s\">" % \ | |
(html_escape(tex_expr), bf.config.site.url, | |
bf.util.site_path_helper(site_images_dir,fn)) | |
#Make the <img> tag replacements in a single pass | |
p = re.compile('|'.join(map(re.escape, img_substitutions))) | |
return p.sub(lambda x: img_substitutions[x.group(0)], src) | |
def run(src): | |
return render_latex_blocks(src) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
categories: Category 1, Category 2 | |
date: 2009/07/24 16:20:00 | |
title: Sample LaTeX post | |
filter: latex, markdown | |
tags: test, blogofile, cool-stuff | |
author: Ryan | |
--- | |
This is a sample post with TeX blocks. | |
This is a TeX block: | |
$$latex | |
y = \int_0^\infty \gamma^2 \cos(x) dx $ this is after the block. | |
This is an inline Tex block: $$latex \cos(x) $ and this is after. | |
This is two seperate inline Tex blocks: $$latex \sin(x) $ and then $$latex \tan(x) $ and this is after. | |
This is a mistyped TeX block because I didn't terminate it properly. $$latex \tan(x)$ and this text is rendered too because I didn't put a space before the dollar sign $ | |
This is a broken TeX block because I didn't put a space before it$$latex \tan(x) $ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment