Skip to content

Instantly share code, notes, and snippets.

@jude
Created November 29, 2009 02:05
Show Gist options
  • Save jude/244752 to your computer and use it in GitHub Desktop.
Save jude/244752 to your computer and use it in GitHub Desktop.
src2png.py and experiment in source code visualization
#!/usr/bin/python
"""
src2png.py - a source code to png visualization experiment.
I wrote this after listening to Software Engineering Radio's
podcast on software archeology.
(http://www.se-radio.net/podcast/2009-11/episode-148-software-archaeology-dave-thomas)
The podcast mentions the idea of viewing source code in a small font size
in order to get some understanding of the overall structure. I wondered what
it would be like if instead of a very small font size, each character was
replaced by a single pixle in a png file.
Eventually I found the amazing pygments project, and easily added syntax
coloring
http://pygments.org/
But then I found out about the emacs minimap feature, and started
using that instead.
http://www.emacswiki.org/emacs/MiniMap
Maybe this code would be useful non-emacs users.
"""
import Image
import ImageColor
import os
import sys
from pygments.lexers import guess_lexer_for_filename
from pygments.styles import get_style_by_name
if len(sys.argv) != 2:
print 'usage: sys.argv[0] _src_file_name'
print 'Builds _src_file_name.png from _src_file_name'
sys.exit(1)
## get the input file
src_file_name = sys.argv[1]
fptr_Input = open(src_file_name,"r")
l_Input = fptr_Input.readlines()
fptr_Input.close()
i_NumLines = 0
i_MaxLength = 0
for a_Line in l_Input:
i_NumLines += 1
a_Line.expandtabs(8)
i_Len = len(a_Line)
if i_Len > i_MaxLength:
i_MaxLength = i_Len
## get a style
style = get_style_by_name('default')
bg = ImageColor.getrgb(style.background_color)
## build up the size of the image
## (longest line, # of lines)
image = Image.new("RGB", (i_MaxLength, i_NumLines), bg)
## build the image
pix = image.load()
t = ''.join(l_Input)
lexer = guess_lexer_for_filename(src_file_name, t)
the_iter = lexer.get_tokens(t)
i_Y = 0
i_X = 0
for(tokentype, value) in the_iter:
color = (0, 0, 0)
t = style.style_for_token(tokentype)
if t != None and t['color'] != None:
color = ImageColor.getrgb('#'+ t['color'])
for c in value:
if c == '\n' or c == '\r':
i_Y += 1
i_X = 0
elif c == ' ':
i_X += 1
else:
pix[i_X, i_Y] = color
i_X += 1
image.save(src_file_name+".png","PNG")
print 'Source compressed into ' + src_file_name + '.png '
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment