#!/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