Home | Mathematics | * Maxima |     Share This Page
TeX Clipboard Daemon Ruby Listing
P. Lutus Message Page

Copyright © 2007, P. Lutus

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

Home | Mathematics | * Maxima |     Share This Page