#!/usr/bin/ruby -w
# Copyright 2007, P. Lutus
#
# Parts of this program are derived from:
#
# T E X T O G I F
# by John Walker
# http://www.fourmilab.ch/
#
# and is released under the GPL (to the degree that
# I can read the original author's intentions)
# this is a clipboard daemon that takes TeX clipboard content
# copied from within wxMaxima and automatically converts it into
# a GIF or PNG image.
# Just run this program and copy equations in TeX format
# from within wxMaxima, and each unique
# clipboard content will be turned into a separate graphic image
# Make $dpi larger for larger graphic images
$dpi = 100;
# Make $res smaller for more image quality
# (better antialiasing), but much more processing time
$res = 0.25;
# if $png = false, generate GIFs. PNG is preferred.
$png = true
# set $erasetemps = false to examine intermediate temporary files
$erasetemps = true
# set $debug = true to read error
# messages/diagnostics on standard output
$debug = false
# the transparent color
$transparent = "white"
# page width, inches, for TeX equation rendering
# increase this value to render large equations
$pagewidth = 16
# default destination for resulting graphic files
$dest = ENV['HOME']
# associate temporary file names with PID
$tfn="_temp#{$$}"
# bold format string
$bold = ""
# Make TeX happy by providing a wrapper
def get_template()
return "\\documentclass[12pt]{article}\n" \
+ "\\pagestyle{empty}\n" \
+ "\\usepackage[dvips,dvipdfm]{geometry}\n" \
+ "% a large page size can accommodate large equations\n" \
+ "\\geometry{papersize={#{$pagewidth}in,6in},includeall}\n" \
+ "\\begin{document}\n" \
+ "\\begin{displaymath}\n" \
+ "#{$bold} % boldface aids readability\n" \
+ "TEX_MATH\n" \
+ "\\end{displaymath}\n" \
+ "\\end{document}\n"
end
def help()
puts "usage: #{$0}"
puts "-dpi (dpi default #{$dpi})"
puts "\t(larger numbers make images larger)"
puts "-res (resolution number, now #{$res})"
puts "\t(smaller numbers improve antialiasing)"
puts "-pw (page width, now #{$pagewidth})"
puts "\t(bigger value renders large equations without truncation)"
puts "-png (select PNG output format (default))"
puts "-gif (select GIF output format)"
puts "-bold (boldfaces the TeX output)"
puts "-dest (destination path for graphic output, now #{$dest})"
puts "-keep (retain temporary files)"
puts "-debug (show detail and error messages)"
exit 0
end
def process_command_args(list)
until(list.empty?)
key = "" + list.shift
# allow variations in prefix style
key.sub!(/^--+/,"-")
key.downcase!
case key
when "-dpi"
$dpi = list.shift.to_i
when "-res"
$res = list.shift.to_f
when "-pw"
$pagewidth = list.shift.to_i
when "-gif"
$png = false # the default
when "-png"
$png = true
when "-bold"
$bold = "\\bf"
when "-dest"
$dest = list.shift
when "-keep"
$erasetemps = false
when "-debug"
$debug = true
when "-help"
help()
end
end
end
def get_output_name()
n = 0
suffix=($png)?".png":".gif"
while(true)
n += 1
fn = sprintf("tex_render%04d#{suffix}",n)
break unless FileTest.exists?(fn)
end
return fn
end
def process_clipboard_text(content)
content.chomp!
# if this content looks like wxMaxima TeX output
if(content =~ /^\$\$/)
suppress_string = ($debug)?"":" 2> /dev/null"
dres = ($dpi / $res).to_i
ofn = get_output_name()
final_app = ($png)?"pnmtopng":"ppmtogif"
# strip off the wxMaxima '$$' wrapper characters
content.sub!(/^\$+(.*?)\$+$/,"\\1")
# insert the content into the template
tex_content = get_template().sub(/TEX_MATH/,content)
File.open("#{$tfn}.tex","w") { |f| f.write tex_content }
if(system("echo x | latex #{$tfn} > /dev/null #{suppress_string}"))
print "Creating graphic file #{ofn} ..."
system("dvips -f #{$tfn} > #{$tfn}.ps #{suppress_string}")
$bigcmd = "echo quit | " \
+ "gs -q -dNOPAUSE -r#{dres}x#{dres}" \
+ " -sOutputFile=- -sDEVICE=pbmraw #{$tfn}.ps #{suppress_string} | " \
+ "pnmcrop -white #{suppress_string} | " \
+ "pnmdepth 255 #{suppress_string} | " \
+ "pnmscale #{$res} | " \
+ "#{final_app} -interlace -transparent=#{$transparent} > #{ofn} #{suppress_string}"
system($bigcmd)
puts "Done."
end
system("rm #{$tfn}*") if $erasetemps
end
end
# must have installed ruby-gtk2
require 'gtk2'
# initialize Ruby's GTK bindings
Gtk.init
process_command_args(ARGV)
puts "dpi #{$dpi}, resolution #{$res}, output format #{$png?"PNG":"GIF"}, page width #{$pagewidth}"
puts "debug mode #{$debug?"on":"off"}, dest path #{$dest},"
puts "entering daemon mode (Ctrl+C to quit)."
source = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD)
old_content = ""
Dir.chdir($dest)
# wait for clipboard content
while(true) # until stopped by Ctrl+C
# get the clipboard content
content = source.wait_for_text
if(content != old_content)
process_clipboard_text(content.clone)
old_content = content
end
sleep(1)
end