Rcjp's Weblog

October 17, 2007

Show Nearest X11 System Colours

Filed under: python, utils — rcjp @ 1:16 pm

ColourInfo
Just a little utility to show the nearest system rgb colours (taken from rgb.txt) on an X11 system compared to the one under the cursor.

I couldn’t work out how to listen to mouse messages when I don’t own the window under the mouse pointer (on X Windows anyway) – so I cheated and this code takes a snapshot of the screen and displays it in the background. Obviously you can’t move/click on any windows when this thing is running! quit with ‘q’ or ‘ESC’ or just close the window.

#!/usr/bin/env python
#
# Takes a screenshot image of the root window and display a table of 
# nearest system colours compared to that under the mouse pointer
# can specify an argument 1..29 to show more colours (default 6)
# The window title shows the exact rgb values of pointer in hex
#
import gtk, re
from sys import argv

RGBCOLOURS = '/etc/X11/rgb.txt'   # rgb colour data

class ScreenColour(object):

    syscolours = {}  # hold system rgb.txt relating colours to names

    def __init__(self, rgbfile=RGBCOLOURS):
        # 1 pixel buffer for pixel under mouse pointer
        self.pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False, 8, 1, 1)
        for line in file(rgbfile).readlines():
            if not line.startswith('!'):
                rgbname = re.compile(r'\s*(\d+)\s*(\d+)\s*(\d+)\s*(.+)')
                (r,g,b,name) = rgbname.match(line).groups()
                self.syscolours[name.rstrip()] = (int(r),int(g),int(b))

    def cmp_screencolour(self,col,basecol):
        """Numerical difference between colours col(name) and basecol(r,g,b)"""
        return sum(abs(a-b) for a, b in zip(basecol, ScreenColour.syscolours[col]))

    def pixelinfo(self):
        """Returns the (r,g,b) value of colour under mouse pointer"""
        (_, x, y, _) = gtk.gdk.display_get_default().get_pointer()
        self.pix.get_from_drawable(gtk.gdk.screen_get_default().get_root_window(),
                                   gtk.gdk.colormap_get_system(),
                                   x,y, 0,0, 1,1)
        col = self.pix.get_pixels_array()
        return (int(col[0,0,0]), int(col[0,0,1]), int(col[0,0,2]))

    def nearest_colours(self, n, basecol):
        """Return the nearest n system colours compared to basecol"""
        nearest = self.syscolours.keys()
        nearest.sort(key=lambda (c): self.cmp_screencolour(c, basecol))
        return nearest[:n]


class ColourInfoWindow(ScreenColour):

    """Draw a table of colours nearest to that under mouse pointer"""
    label = []
    eb = []
    oldrgb = (-1,-1,-1)

    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def __init__(self, tablesize):
        self.tablesize = tablesize
        self.image = gtk.Window()
        self.image.set_decorated(False)
        self.image.add_events(gtk.gdk.POINTER_MOTION_MASK)
        self.image.connect("motion_notify_event", self.event_handler)
        #
        # set background from a screen shot of the root window
        #
        screen = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
                                gtk.gdk.screen_width(), gtk.gdk.screen_height())
        screen.get_from_drawable(gtk.gdk.get_default_root_window(),
                                 gtk.gdk.colormap_get_system(), 0, 0, 0, 0,
                                 gtk.gdk.screen_width(), gtk.gdk.screen_height())
        pixmap, mask = screen.render_pixmap_and_mask()
        self.image.set_app_paintable(True)
        self.image.realize()
        self.image.window.set_back_pixmap(pixmap, False)
        del pixmap
        self.image.fullscreen()
        self.image.show()

        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_size_request(200, 40*self.tablesize)
        self.window.set_resizable(False)
        self.window.set_transient_for(self.image)  # stay above screen image
        self.window.set_title("Colour Info")
        self.window.connect("delete_event", self.delete_event)
        self.window.add_events(gtk.gdk.KEY_PRESS_MASK)
        self.window.connect("key-press-event", self.event_keys)

        self.Colour = ScreenColour()
        vbox = gtk.VBox(True,2)
        for i in range(self.tablesize):
            self.label.append(gtk.Label("Unknown"))
            self.eb.append(gtk.EventBox())
            self.eb[i].add(self.label[i])
            vbox.add(self.eb[i])
        self.window.add(vbox)
        self.window.show_all()
        self.update_colours()

    def update_colours(self):
        rgb = self.Colour.pixelinfo()
        if self.oldrgb != rgb:
            self.oldrgb = rgb
            nearest = self.Colour.nearest_colours(self.tablesize, rgb)
            self.window.set_title("%02X %02X %02X" % rgb)
            for i in range(self.tablesize):
                try:
                    self.eb[i].modify_bg(gtk.STATE_NORMAL,
                                         gtk.gdk.color_parse(nearest[i]))
                    #
                    # if brighter than 128,128,128 switch to 
                    # a black background so text is visable
                    #
                    if (sum(self.syscolours[nearest[i]]) > 384):
                        w = '<span foreground="black">%s</span>' % nearest[i]
                    else:
                        w = '<span foreground="white">%s</span>' % nearest[i]
                    self.label[i].set_markup(w)
                except ValueError:
                    print 'unknown colour... ', nearest[i]

    def event_handler(self, widget, event=None):
        if event and event.type == gtk.gdk.MOTION_NOTIFY:
            self.update_colours()

    def event_keys(self, widget, event=None):
        if event:
            if event.keyval == gtk.gdk.keyval_from_name("Escape") \
               or event.keyval == gtk.gdk.keyval_from_name("q"):
                  self.window.destroy()
                  self.image.destroy()
                  gtk.main_quit()


if __name__ == "__main__":
    if len(argv) == 2 and (0<int(argv[1])<30):
        ColourInfoWindow(int(argv[1]))
    else:
        ColourInfoWindow(6)
    gtk.main()

Advertisements

September 20, 2007

Posting Code

Filed under: utils — rcjp @ 5:42 pm

After spending several frustrating sessions trying to find a solution to posting sourcecode on this blog I think I’ve got something workable.

Most of the methods I tried, including the one in the WordPress FAQ, fail on some operator characters found in lisp or C++ (like e.g.<<) and although I don’t use vim much these days, tending to prefer nvi, it does have a handy htmlize function :TOhtml. This, with some tweaking, generates html acceptable to WordPress from a buffer of code (or some lines marked in Visual Mode).

I used some vim scripting given below to strip out the <pre> section from the generated html, wrap <code> just inside it and copy it to the clipboard ready for pasting into the browser. I have it bound to the keystroke Alt-l. One further complication was that WordPress, trying to be helpful, swaps out some characters even though they are in a <code> block, so I do a search/replace for apostrophes.


func Convert2HTMLClip(line1, line2)
    if a:line2 >= a:line1
        let g:html_start_line = a:line1
        let g:html_end_line = a:line2
    else
        let g:html_start_line = a:line2
        let g:html_end_line = a:line1
    endif
    runtime syntax/2html.vim
    unlet g:html_start_line
    unlet g:html_end_line
    normal! gg
    exe ":0,/<pre>/- d"
    normal! A<code>
    normal! G
    exe ":?</pre>?+,$ d"
    normal! I</code>
    exe ":%s/'/\\&#39;/eg"
    exe ":%s/&amp;#39;/\\&amp;\\&#35;39;/eg"
    exe ":%s/&amp;#35;/\\&amp;\\&#35;35;/eg"
    normal! ggVG"+y
    exe ":bd!"
endfunc
command -range=% TohtmlClip :call Convert2HTMLClip(<line1>, <line2>)
map <M-l> :TohtmlClip<CR>

September 10, 2007

Blogging

Filed under: utils — rcjp @ 6:13 pm

I’ve been trying to decide between blogging from blogger.com or wordpress.com; here are a few of the features that swung the decision:

  • bigger blogging window: I don’t like typing through a letterbox and thankfully wordpress has Options->Writing->’Size of the post box’; couldn’t see anything similar in blogger though
  • private entries: amazingly blogger only lets you mark the whole blog as private, not individual entries like wordpress does
  • wordpress’s built in latex: its great to be able to type
    $latex \partial_{x}\alpha&s=2$

    and get \partial_{x}\alpha (the s=2 increases the size) see the faq entry

There were problems with wordpress though: I had to disable the wysiwyg editing of entries Users->Your Profile->’Use the visual rich editor when writing’ (at the top of the page) because switching between it and the code view kept messing things up; I prefer the code view anyway tbh.

The editor is a bit sluggish sometimes, pausing for something, but at least there are a few handy shorcuts – mark some text then press the keys:

Characters Code Lists
Bold: Alt+Shift+B Blockquote: Alt+Shift+Q Unordered List (ul): Alt+Shift+U
Italics: Alt+Shift+I Code: Alt+Shift+C Ordered List (ol): Alt+Shift +O
Link: Alt+Shift+A Read More: Alt+Shift+T List Item (li): Alt+Shift+L
Keyboard Shortcuts

Hopefully I’ll get around to coding something that’ll allow you to write in reStructuredText from within emacs and upload using the meta weblog api converting to html. All that is pretty easy I think, I’ve done parts of that process for my old blog; the hard part would be doing the reverse to allow you to edit existing posts parsed back to rst.

April 27, 2007

Producing Slides with Beamer

Filed under: utils — Tags: — rcjp @ 10:29 am

Next time I need to do some slides, I’m definitely going to use the latex beamer package. It seems really easy to use

    \documentclass{beamer}
    \usepackage[latin1]{inputenc}
    \usepackage{amssymb,amsmath}  % use mathematical symbols
    \usepackage{ccfonts, eulervm} % concrete fonts but with nicer upright maths
    \usetheme{Warsaw}

    \title{Title of my talk}
    \author{me}\institute{work}

    \begin{document}
    \begin{frame}
    \titlepage
    \end{frame}

    \begin{frame}
    I am the text located on the first content slide
    \begin{equation}
    x+y_2={1\over 2\pi}\int^\alpha_\infty \tan^2\beta = \Gamma\quad eqn1
    \end{equation}
    \end{frame}

    \begin{frame}
    And I am the text located in the second content slide
    \end{frame}
    \end{document}

I need to play with this some more. Some nice notes here

April 17, 2007

reStructured Text

Filed under: python, utils — rcjp @ 4:20 pm

rst is a very easy to use ascii markup language. With some python script or the rst2html tool you can quickly generate html. For example, the following html (between the horizontal lines) was generated by the program below and uses the python docutils module on the ascii testtext python variable (but would normally be a file read in from somewhere):


The Title

My first sentence and some more.

  • bullet one
  • two
    • sublists, just like bullet lists must be separated by blank lines
    • second sublist
  • three

and more paragraph text.

Referees: A.N. Other
Boo Boo

Some literal indented code:

program(1)
for i = 1, 10
    nothing
done

And some more text

Header 1 Header 2 Header 3
body row 1 column 2 column 3
body row 2 Cells may span columns.
body row 3 Cells may
span rows.
  • Cells
  • contain
  • blocks.
body row 4

Run with:

rst2html ttt2 > k.html

For more details look at docutils quickref. and also check the latest
developments validator and latex


and the python code…

#
# some example rst text manipulated with python below...
#
testtext="""
The Title
=========

My first sentence and some more.

- bullet one
- two 

  - sublists, just like bullet lists must be separated by blank lines
  - second sublist

- three

and more paragraph text.

:Referees:
    A.N. Other
    Boo Boo

Some literal indented code::

    program(1)
    for i = 1, 10
        nothing
    done

And some more text


+------------+------------+-----------+
| Header 1   | Header 2   | Header 3  |
+============+============+===========+
| body row 1 | column 2   | column 3  |
+------------+------------+-----------+
| body row 2 | Cells may span columns.|
+------------+------------+-----------+
| body row 3 | Cells may  | - Cells   |
+------------+ span rows. | - contain |
| body row 4 |            | - blocks. |
+------------+------------+-----------+

Run with::

    rst2html ttt2 > k.html

For more details look at docutils_ quickref. and also check the latest 
developments validator_ and latex_

.. _Python: http://www.python.org/
.. _docutils: http://docutils.sourceforge.net/docs/user/rst/quickref.html#bullet-lists
.. _validator: http://docutils.sourceforge.net/sandbox/dugui/
.. _latex: http://docutils.sourceforge.net/sandbox/latex_directive/
"""

from docutils.core import publish_string, publish_parts
#
# quickly dump out the html using my own stylesheet
#
output = open("test-rst.html", 'w')
customcss = {'embed_stylesheet':False, 'stylesheet_path':'include/mystyle.css'}
output.write(publish_string(testtext, writer_name = 'html',
                            settings_overrides=customcss))
output.close()
#
# just dump the body part, no stylesheet at all
#
output = open("test-rst-body.html", 'w')
parts = publish_parts(testtext, writer_name = 'html',
                      settings_overrides=dict(embed_stylesheet=False,
                                              stylesheet_path=None,))
output.write(parts['html_body'])
output.close()


Pulling out the body text is handy for generating html that you are inserting inside another document, like this blog entry for example.

October 11, 2006

Find classes in java jar files

Filed under: lisp, utils — rcjp @ 1:57 pm

;;;
;;; Find classes in jar files
;;; Usage (findjar classname directory)
;;; e.g (findjar "session" "c:/Novell/ndk/njclv2/lib")
;;;
(defun findjar (classname dir)
  ;;  (if (not (directory dir))
  ;;(format t "Invalid directory syntax - remember a trailing slash")
  (dolist (file (directory (concatenate 'string dir "/**/*")))
    (when (string-equal (pathname-type file) "JAR")
      (format t "processing ~S~%" file)
      (with-open-stream (str
        #+cmu
        (run-program (concatenate 'string "jar tf " (namestring file)) :output :stream)
        #+ clisp
        (ext:run-program "jar" :arguments (list "tf" (namestring file)) :output :stream)
        #+ lispworks
        (sys:open-pipe (concatenate 'string "jar tf " (namestring file)))
                          )
        (loop for line = (read-line str nil nil)
              while line
              do
              (when (search classname line :test 'string-equal)
                (format t "   found->~S in file (~S)~%" line (namestring file))
                (return)))))))

September 18, 2006

Image of a Logfile

Filed under: python, utils — rcjp @ 10:57 am

Logfile

I needed some code to create an image which roughly gave an impression of the file contents for a log file analyser I was writing. The following code crudely looks for the shape of letters and draws some dots into a .png file.

import Image, ImageDraw
import os

def drawfilethumb(filename, imagex=80, imagey=200, border=5):
    """Create a png image representing the file"""
    log = []
    log = open(filename).readlines()
    loglen = len(log)

    logimage = Image.new('RGB', (imagex+10,imagey+10), (255,255,255))
    draw = ImageDraw.Draw(logimage)

    maxlen = max(len(x) for x in log)
    xscale = maxlen/float(imagex)
    yscale = loglen/float(imagey)

    y = 0
    while y < imagey and y*yscale < loglen:
        line = log[int(y*yscale)]
        linelen = len(line)
        x = 0
        while x < imagex and x*xscale < linelen:
            ch = line[int(x*xscale)]
            if ch.isupper() or ch.isdigit():
                draw.point([(border+x, border+y), (border+x, border+y-1)], fill=0)
            elif ch in ('t', 'd', 'f', 'h', 'k', 'l', 'b'):
                draw.point([(border+x, border+y), (border+x, border+y-1)], fill=128)
            elif ch in ('q', 'y', 'p', 'g', 'j'):
                draw.point([(border+x, border+y), (border+x, border+y+1)], fill=128)
            else:
                draw.point((border+x, border+y), fill=128)
            x+=1
        y += 4

    del draw
    f, ext = os.path.splitext(filename)
    logimage.save(f+'.png', "PNG")

September 5, 2006

Backup script

Filed under: python, unix, utils — rcjp @ 12:45 pm

Just a handy bit of code to backup a file.

#!/usr/bin/env python

import os, sys
from shutil import copyfile

def backup(filename):
        i = 1
        while os.path.exists('%s.old%d' % (filename,i)):
                i+=1
        backup = '%s.old%d' % (filename,i)
        print "Backing up %s to %s\n" % (filename, backup)
        copyfile(filename, backup)

if len(sys.argv) != 2:
        print "Usage: backup filename"
else:
        try:
                backup(sys.argv[1])
        except IOError, val:
                print "*** Backup Failed : %s ***\n" % val

Create a free website or blog at WordPress.com.