Archive for March, 2008

Convert an image to XPM format suitable for embedding in Perl

Monday, March 24th, 2008

Recently I was working on a single file GTK/Perl program which used an external image file for a logo. I didn’t want to distribute the image file along side the actual program as this was a little messy and probably not worth it for just one logo. So before doing away with the logo, I investigated if there were any possible ways to embed the image data in the Perl code.

XPM

It seems that the defacto standard for representing image data in ASCII format is XPM or X PixMap. This is usually represented in a way that is compatible with programs written in C (the XPM2 format does away with any language specific details).

Getting the XPM data

Getting the image data in XPM format is relatively easy if you have the ImageMagick suite of tools installed. If so, then just run the following:

convert inputfile outputfile.xpm

The trick here is to make sure your output file ends with a .xpm extension. ImageMagick will recognize this and do the conversion to XPM for you.

Converting to Perl code

As you might have noticed if you looked at the resulting XPM file, it is in standard C notation. Not very useful for a Perl program. Never fear, a sprinkling of substitution and regex magic will bring us home.

“s/\’/\\\’/g”
s/\”/\’/g
“s|^/\*.*\n$||”
“s/^static.*$/my \@xpm_image = (/”
“s/^};$/);/”

In order from top to bottom we have:

  • Escape all the single quotes
  • Convert double quotes to single quotes
  • Remove lines that start with a C-style comment
  • Reformat the variable declaration for Perl
  • Fix up the closing brace on the array definition.

With all these substitutions done, we can embed the resulting code in a Perl program and use it with functions that expect XPM data, Gtk2::Gdk::Pixbuf->new_from_xpm_data() for example.

All together now…….

Ok, lets put it all together into a Bash script. As with any shell script, we need the shebang on the first line:

#!/bin/bash

then we have filename definitions:

inputfile=$1 # $1 is the first argument passed to the script
xpmfile=$inputfile.xpm
perlfile=$xpmfile.pl

ImageMagick conversion and rename:

convert $inputfile $xpmfile
mv $xpmfile $perlfile

and the substitutions (the “i” argument means substitutions are done in place, i.e. there is no separate output file)

perl -pi -w -e “s/\’/\\\’/g” $perlfile # All single quotes get escaped
perl -pi -w -e s/\”/\’/g $perlfile # Double quotes -> single quotes
perl -pi -w -e “s|^/\*.*\n$||” $perlfile # Remove c-style comment lines
perl -pi -w -e “s/^static.*$/my \@xpm_image = (/” $perlfile # Change variable declaration
perl -pi -w -e “s/^};$/);/” $perlfile # Change closing brace of array

If you want to download or view the script in it entirety, have a look at img2xpm_perl at omobos.com.

Color coded man pages with Vim

Sunday, March 23rd, 2008

Want a color coded man page viewer with hyperlink support? Well look no further. This simple script is a wrapper around the built in :Man function in Vim. Basically it allows Vim to be started up in man mode and adds some key shortcuts like the default man page viewer.

Have a look at this screenshot, it shows the color coding of various elements, hyperlinks for other commands and also shows the folding feature.

Using vim for man page viewing

Enabling the man plugin

Before we begin, we need to make sure the filetype plugin for man is enabled in Vim. To do this we need to source $VIMRUNTIME/ftplugin/man.vim from our .vimrc file.

I have the following line in mine:

source /usr/share/vim/vimcurrent/ftplugin/man.vim

Your location may vary depending on versions/distributions etc.

Using the :Man function

Once we have enabled the plugin, we can view man pages in Vim using the :Man command (i.e. :Man vim). We can now also use the below command in place of our standard man pager.

vim -R -c “:set foldmethod=indent” -c “:set foldnestmax=2″ -c “:set foldenable” -c “:Man $1″ -c “:normal ” -c “:q” -c “:set nomodifiable” -c “:map q :q<CR>” -c “:map <space> “

Place this command inside a shell script, put it on your path and/or set up an alias to it like follows:

alias man=”/home/user/scripts/vimman.sh”

Note: the above command has some non-printing characters in it, such as “Control-W” and “Page-down”. As such, just copying the text from a web browser will probably not work. You can checkout the full script vimman.sh at omobos.com

Please explain…..

The above command is pretty simple if we break it down a little. To start with the ‘-R’ option puts us in read-only mode. The rest of the arguments are actually Vim commands, this is indicated with the “-c” option. The first three relate to folding and can be removed if you prefer not to have folding enabled. Following that we have our :Man command which opens the man page in a new split window. To remove the split window, we jump to the other window (“Control-W. Control-W” – not printed correctly above) and then execute “:q” to close it. The last two commands set up some keyboard shortcuts. Pressing “q” quits immediately and pressing “Space” gives us a “Page-Down”.

Hyperlinks

When viewing man pages in Vim, other referenced commands are highlighted (in blue usually). By placing the cursor on the command name and pressing Ctrl-] you will jump to the man page of that command. Ctrl-T will jump back to the original page.

Finding running processes

Sunday, March 23rd, 2008

Here is a simple alias to help track down running processes and their PID’s.

alias fproc=’ps aux | grep ‘

This uses the ps command to list running processes and then filters the result with grep using the keyword you specify. For example:

user@machine:~$ fproc firef
user 3413 2.9 12.8 256936 127640 ? Rl Mar23 14:38 /usr/lib/iceweasel/firefox-bin -a firefox
user 31952 0.0 0.0 3860 716 pts/2 R+ 01:16 0:00 grep –color firef

(Note: the grep command will always show up in the output as it too has the keyword in the process name.)

For more information on aliases checkout my previous post or have a look at my custom .bash_aliases file at omobos.com

Bash aliases

Sunday, March 23rd, 2008

The Bourne again shell (Bash) has a useful feature called aliases.

Aliases allow common commands (along with arguments) to be executed with an alternate command name. For instance using this command;

alias mv=”mv -iv”

means that whenever I use the mv command, the -iv argument will be automatically added resulting in interactive mode (prompting before overwriting) and verbose output. For example:

~$ touch test01.dat test02.dat
~$ mv test01.dat test02.dat
mv: overwrite `test02.dat’? y (Interactive mode)
`test01.dat’ -> `test02.dat’ (Verbose output)
~$

Many commands can have default behavior added to them by adding your most commonly used arguments. Some other examples:

alias grep=’grep –color’ # Highlight search word
alias df=’df -h’ # Display in human readable format
alias du=’du -h’ # i.e. 41G, 217M

But what if you use the ls command a lot but also in the form ls -la? To get around this we can introduce new commands (just make sure you don’t mask over existing commands). For example, I have the following aliases for the ls command.

alias ls=’ls –color=auto’ # Use colors
alias l=’ls -l’ # Long format, username, size etc.
alias la=’ls -la’ # Long format with hidden files
alias lsd=’ls */ -d’ # Only display directories

Making things permanent

When the alias command is used in a shell, the changes are only local to that shell and will be lost when it is exited (exit or Ctrl-D). To make changes permanent, we need to add the aliases to the bashrc file (~/.bashrc for the current user, or /etc/bash.bashrc to make the changes system wide). Similar config files exist for other shells.

But we can take this one step further and keep everything nice and organized. If we keep all the aliases in a separate file (~/.bash_aliases), we can source them from our shell config file and make them a lot easier to maintain. Most likely you already have the following lines in your bashrc file:

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.#if [ -f ~/.bash_aliases ]; then
# . ~/.bash_aliases
#fi

If so, just uncomment those last three lines and keep your aliases in ~/.bash_aliases.

You can check out my complete alias file at omobos.com/data/scripts/.bash_aliases

Welcome

Sunday, March 23rd, 2008

Welcome. This blog will mostly be oriented around tips and tricks for Linux like operating systems and general software development.