Tag Archives: Script

Quick Images with TikZ

How do you create high-quality technical images for documents, your website or posts on Stack Exchange? I have used tools in an ad-hoc manner for a while and have become frustrated lately. Once you have used TikZ1 with \(\LaTeX\) most other tools feel inferior. The only problem is: TikZ is a \(\LaTeX\) package and can not be used on its own. So how to convert TikZ to say PNG comfortably?

\(\TeX\)-guru Martin Scharrer comes to the rescue: he wrote the package standalone for exactly this use case. Based on his explanation on tex.SE I built a small bash script that does all the repetitive work for you. With one simple command, this

%p% \usetikzlibrary{arrows,automata,positioning}
\begin{tikzpicture}[shorten >=1pt,node distance=2cm,auto]
  \node[state,initial]    (q_0)                {$q_0$};
  \node[state,accepting]  (q_1) [right of=q_0] {$q_1$};

  \path[->] (q_0) edge [bend left]  node {$a$} (q_1)
            (q_1) edge [bend left]  node {$b$} (q_0);
\end{tikzpicture}

becomes this in a matter of seconds:
Example

GPL3

Get tikz2png on GitHub and enjoy!


  1. Check out the awesome gallery of examples and the comprehensive manual.

Download Photos From Canon EOS

My Canon EOS 450D is not recognised as mass storage by my system when connected via USB. In order to get photos from camera to PC, you can use gphoto2:

#!/bin/bash
echo -n "[pullphotos] Detecting camera ...";
gphoto2 --auto-detect > /dev/null;
sleep 1s;
echo " Done";

echo -n "[pullphotos] Pulling photos ...";
gphoto2 -P &> /dev/null;
sleep 1s;
echo " Done";

echo -n "[pullphotos] Rotating photos ...";
jhead -autorot * &> /dev/null;
echo " Done";

This script copies all images currently stored on the camera into the current folder and rotates them if necessary1. The necessary programs gphoto2 and jhead are available as packages with the same name from the Ubuntu repositories. Note that you have to empty your camera’s storage manually afterwards.

Furthermore, note that gphoto2 is a very powerful tool. It allows you to configure and control many aspects of your camera via USB, including remote capture—something you might want to employ?


  1. Employing some sensor trickery, modern cameras annotate image files with information about picture orientation.

Downloading Apple Trailers

I enjoy watching movie trailers and iTunes Movie Trailers is a wonderful resource for high-quality, current trailers. The problem is that I can not view Quicktime videos in my browser — and might not want to if I could — but downloading the files is not immediately possible.

Luckily, I found this guide on how to download trailers from Apple’s archive. Since it is tiresome to perform these steps by hand for every trailer, I put a little Ruby script together to ease the process:

#!/usr/bin/ruby

if ( ARGV.size > 0 )
  Dir.chdir("/path/to/target/dir")
  ARGV.each { |url|
    url = url.gsub(/_(\d+p)\.mov/, '_h\1.mov')
    IO::popen("wget -U \"QuickTime/7.6.5\" #{url}").readlines
  }
end

Calling this script with URLs you get from the Watch Now menus downloads trailers directly to the directory of your desire.

Where to get your trailer URL

Control Pulseaudio from Shell

As you know I mainly use Fluxbox on a minimal Ubuntu installation without access to all the every-day functionality provided by panel applets in Gnome, including volume control. Therefore, I have been using pavucontrol for controlling Pulseaudio. It is a really nice application that gives you very finegrained control, for instance over which application should be how loud. Lately I have been annoyed with opening a whole application just for the sake of adjusting volume a little bit, so I set out to find a way to control it via shell. Turns out there is no convenient interface to pulseaudio at all, leaving me to script something together, this time in Ruby. It uses a very unwieldy interface to Pulseaudio named pacmd, contained in Ubuntu package pulseaudio-utils.

#!/usr/bin/ruby
def current
  c = IO::popen("pacmd \"list-sinks\" | grep volume | head -1").readlines[0]
  return c.split(" ").last.sub("%", "").strip.to_i
end

def max
  c = IO::popen("pacmd \"list-sinks\" | grep \"volume steps\" | head -1").readlines[0]
  return c.split(" ").last.strip.to_i - 1
end

def index
  c = IO::popen("pacmd \"list-sinks\" | grep index | head -1").readlines[0]
  return c.split(" ").last.strip.to_i
end

def set(v)
  IO::popen("pacmd \"set-sink-volume #{index} #{v}\"").readlines
end

def muted
  c = IO::popen("pacmd \"list-sinks\" | grep muted | head -1").readlines[0]
  return c.split(" ").last.strip == "yes"
end

def toggle
  t = 1
  if ( muted )
    t = 0
  end
  IO::popen("pacmd \"set-sink-mute #{index} #{t}\"").readlines
end

interval = 5

if ( ARGV.size == 0 )
  puts current
elsif (ARGV[0] == "?" )
  puts muted
elsif ( ARGV[0] == "+" )
  set([current + interval, 100].min * (max / 100.0).round)
elsif ( ARGV[0] == "-" )
  set([current - interval, 0].max * (max / 100.0).round)
elsif ( ARGV[0] == "!" )
  toggle
end

This is certainly not the most efficient way to do it, retrieving all the info multiple times, but it works and I do not perceive any delays. Note that the script will just use the first sink that pacmd prints, so if you have a setup with multiple sinks you will have to be more clever.

Of course, the obligatory Fluxbox key bindings

None XF86AudioLowerVolume :execCommand pavol -
None XF86AudioRaiseVolume :execCommand pavol +
None XF86AudioMute :execCommand pavol !

and conky volume display:

Vol: ${exec if [ `pavol ?` != 'true' ]; then echo `pavol`%; else echo 'Muted'; fi}

Update: The script now has a home on GitHub.

Cover Art With conky And mpd

After one year of using mpd on my Fluxbox machine I have started to sift through my music collection, fixing tags and adding album covers. Since there is no need for having album art if you do not show it, I set out to make conky show the images on my disk. I was lucky to find script in the depth of some forum (reference lost) that inspired the following piece of bash code.

#!/bin/bash
IFS=$'\t' mpd_array=( $(MPD_HOST=localhost MPD_PORT=6600 \
          mpc --format "\t%artist%\t%album%\t%file%\t") );

filename="conky_cover.png";
placeholder="/path/to/placeholder.png"

if [[ ! -f /tmp/"${mpd_array[1]}".album ]] ; then
  rm -f /tmp/*.album &> /dev/null;
  >/tmp/"${mpd_array[1]}".album;

  album=`dirname "/path/to/music/${mpd_array[2]}"`;
  cover=$album"/"`ls $album | egrep "jpeg|jpg|png|gif" | head -n 1`;

  if [[ ! -f $cover ]]; then
    cp $placeholder /tmp/$filename;
  else
    convert $cover -resize "130>x" -alpha On -channel A \
                   -evaluate set 25% /tmp/$filename;
  fi
fi

When this script is run, the currently playing album’s artist and name are retrieved and the corresponding image — or a dummy — is copied to /tmp for conky to pick up. Note that always the first image in the album’s folder is chosen and then manipulated with imagemagick; you might have to do a little coding yourself if you store your music or covers differently. Note that all time consuming stuff is done only once per album run.

On the conky side, life is easy now. Just add something like this to your .conkyrc:

${if_running mpd}
MPD: ${alignr}${mpd_status}${if_mpd_playing}
 ${mpd_artist 25}
 ${mpd_album 25}
 ${mpd_title 25}
 ${mpd_bar 3,130}
 ${exec ~/bin/conky_mpd_art}${image /tmp/conky_cover.png -p 3,772 -s 130x130 -n}
${endif}
${endif}

You have to adapt the visual thingies to your liking, of course.