Saturday, October 25, 2008

haml.py

Combining YAML and (X)HTML via Python gets this script, haml.py. It takes in a specific set of YAML items, then turns it into (X)HTML based on HTTP_ACCEPT.

haml.py

#!/usr/bin/python
import cgi
import cgitb
cgitb.enable()
import sys
import os
import re
sys.path.append('/homes/abstract/nehodges')
import yaml
xhtmlmode = 'application/xhtml+xml' in os.environ['HTTP_ACCEPT']
query = cgi.FieldStorage()


def ErrorString(title, content = []):
ret = """<head>
<title>%s</title>
</head>\n<body\n>""" % cgi.escape(title, 1)
ret += '\n'.join(['<p>%s</p>' % cgi.escape(i, 1) for i in content])
ret += """</body>
</html>\n"""
return ret



def printHamlDocument(content, fname, xhtml):
def getHamlString(st):
st = st.replace("':'", ":")
st = st.replace("'''", "'")
st = st.replace("&", "&quot;")
p = re.compile('<([^<]+)>')
for match in p.finditer(st):
src = match.group()
inner = match.group(1)
parts = inner.partition('::')
if len(parts[2]) > 0: # We have a <..::..> syntax
st = st.replace(src, u'<a href="%s">%s</a>' % (parts[0], parts[2]))
else: # We have a <..> syntax
st = st.replace(src, u'<a href="%s">%s</a>' % (inner, inner))
return st
def printHamlListItem(content, xhtml, depth=1):
ret = ''
if unicode(content) == content or str(content) == content:
ret = '\t<li>%s</li>' % getHamlString(content)
else:
ret = '\t<li>%s</li>' % printHaml(content, xhtml, depth)
return ret
def printHaml(content, xhtml, depth=1):
ret = ''
try:
# For complex objects
if content.has_key('content'):
ret += '<div>\n'
if content.has_key('title'):
ret += '\t<h%d>%s</h%d>\n' % (depth, content['title'], depth)
ret += printHaml(content['content'], xhtml, depth + 1) + '\n'
ret += '</div>\n'
elif content.has_key('image'):
ret += '<img src="%s"' % content['image']
style = ''
if content.has_key('width'):
style += 'width:%s;' % content['width']
if content.has_key('height'):
style += 'height:%s;' % content['height']
if len(style) > 0:
ret += ' style="%s"' % style
ret += (xhtml and ' />' or '>') + '\n'
elif content.has_key('items'):
ret += '<ul>\n%s\n</ul>\n' % '\n'.join([printHamlListItem(i, xhtml, depth + 1) for i in content['items']])
except AttributeError:
if unicode(content) == content or str(content) == content:
# For strings
ret = '<p>%s</p>\n' % getHamlString(content)
else:
# For lists
ret += u'\n'.join([printHaml(i, xhtml, depth) for i in content])
ret += '\n'
return ret
ret = "<head>\n\t<title>%s</title>\n" % (content.has_key('title') and content['title'] or fname)
if content.has_key('style'):
ret += u''.join(('\t<link rel="stylesheet" href="%s"' % content['style'], xhtml and ' />' or '>', '\n'))
ret += "</head>\n"
if content.has_key('content'):
ret += '<body>\n%s</body>' % printHaml(content['content'], xhtml)
elif xhtml:
ret += '<body />\n'
else:
ret += '<body></body>\n'
ret += '</html>\n'
return ret



if xhtmlmode:
print "Content-Type: application/xhtml+xml; charset=utf-8\n"
print """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml11.xsd" xml:lang="en">
"""
else:
print "Content-Type: text/html; charset=utf-8\n"
print """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-us">"""
if not query.has_key('file'):
print ErrorString('No Document Provided', ['Not much to see here.']);
elif len(query['file'].value) == 0 or not os.path.isfile(query['file'].value):
print ErrorString('No Such Document', ['Not much to see here'])
else:
fname = query['file'].value
f = open(fname, 'r')
try:
content = yaml.load(f)
# print ErrorString('All is Good!', [cgi.escape(repr(content), 1)])
print printHamlDocument(content, fname, xhtmlmode)
except yaml.YAMLError, e:
print ErrorString('Failed to Load Document', ['Looks like there\'s a problem here.', repr(e)])
finally:
f.close()
Here's a sample YAML file with all of the features:---
title: Foo balls
style: "test-style.css"
content:
- title: Test Section 1
content:
- Some useless content. What'''s new?
- Each paragraph is represented in an item here. Other optional types are':'
- content:
- Sub-divs
- title: Super 2
content:
- Sub-divs with titles
- 'For links, use the syntax. For more advanced links, try .'
- image: 'http://www.google.com/intl/en_ALL/images/logo.gif'
alt: The Google image!
- title: Test Section 2
content:
- Nothing special
- items:
- Don'''t forget an awesome list!
- Can'''t live without lists.
- title: Even Better!
content:
- Divs inside of lists!
- Likely not standard, but oh well.
...

It represents what I started earlier regarding Python object to HTML rendering, but I switched to YAML since those files are quicker to write.

Tuesday, June 17, 2008

Snohomish Bus Adventure

Today revolved around yet another bus adventure, this time to Snohomish.

I departed Bothell for downtown Seattle via the 120 and 522, and bought some new music at Uwajimaya, along with a snack. Despite taking my time, I still had an hour before my bus out came. To waste time, I rode the 36 up to Westlake Center, then the 194 in the tunnel back to the bus stop at Jackson.

When the 424 finally did come, I was dismayed to find out that the seats I wanted wouldn't recline, but did sit in them regardless. As my previous excursion via the 424, it was odd riding a CT bus over the floating bridge and through Kirkland. The scenery changed for the better as we got further out along SR-522, which itself turned into a super two closer to Monroe.

Just past Monroe, at the intersection with US-2, a train started crossing the road before the traffic light turned green, so we were stuck for five minutes or so. I was amazed, as I had never been on a bus when this happened before.

The trip back, via the 270, 201, and 535 was uneventful, though I do believe I saw someone from UW on the last leg.

Monday, June 16, 2008

Whidbey Island Bus Trip

Well, today was sure an adventure. I took my second bus trip around Whidbey Island ever.

The first bus in the run (532) wa driven by the same guy who drove the 535 I rode to Lynnwood in the mornings during the past couple of quarters at UW. He asked if I was trying to get to Lynnwood, since he recognized me too, but I let him know I wanted Everett. Also, the bus was number 9047.

Once in Everett, I had quite a while to wait, so I went to the cafe in the station building and bought this peach drink/dessert, which I quickly finished as the 412 came. The driver was kind enough to let me wait onboard while it was in layover.

Throughout each route past Everett, the views were amazing. So many trees, open fields, and places where the road was mere feet from the water. I took the 411C, 411W, and 1 to circumnavigate Whidbey Island. The same driver did the 412 and 411C, and let me stay onboard between the routes. The weather was amazing too, with deep blues in the ocean and bright greens everywhere. The bus even passed a black-tailed deer as it ran along the edge of the road.

The ferry from Whidbey Island to Mukilteo is free in that direction, so I was treated to a great boat ride. It seems odd riding in a car ferry as a passenger, since those particular boats don't have the pedestrian bridges.

In Mukilteo, I had a small lunch at Ivar's, which included prawn and fries. Fortunately, the 113 has short headways of only up to twenty minutes. My transfer in Lynnwood to the 121 was even shorter, as I didn't have to go all the way to the transit center.

The trip was a great deal of fun, and very relaxing. Can't wait until the next one.

Tuesday, June 10, 2008

fortweet.sh

While bored, I decided to write this little shell script:

fortweet.sh

#!/bin/sh
fortune -n 140 -s | perl stweet.pl "$@"

shash

While both bored and studying for my CSE303 final, I decided to write something that would count as good practice towards it, including profiling, debugging, and Subversion use. It ended up a hash system using a trie, with three different primary types:

  • SHash: A trie hash allowing all non-null characters in its search strings.
    • SCHash: A caching variant in order to speed up lookups.
  • TSHash: A trie hash allowing all non-null characters in its search strings, with mutexes built-in for multithreaded code.
    • TSCHash: A caching variant in order to speed up lookups.
  • LHash: A trie hash allowing all printable ASCII characters in its search string to reduce memory consumption.
    • LCHash: A caching variant in order to speed up lookups.

Here's a tar archive of it. I find it a lot of fun to play with, especially using the intense_test binary and adjusting its #define parameters.

Tuesday, June 3, 2008

qtevent: Using Signals for Event Handling

So it looks like Qt4 doesn't use signals for event handling. However, due to the nature of C++, it's trivial to extend the built-in widgets, which I did with this. To build, run qmake -project && qmake && make. Here's some sample output from a session:

% ./qtevent
76
83
32
45
76
65
32
16777248
36
72
79
77
69
16777220
`-> Captured: enter
ls -la $HOME

It makes programming similar to how I did my earlier launcher easier.

Monday, June 2, 2008

Seattle Transit Blog: One of my Photos!

It looks like my photo was used in a Seattle Transit Blog post! The topic of the post involved bus transfer fares.