Implementing horizontal scrollbars

saturday, march 8th, 2008 8:01am

[2008-03-16 update: I recently realized that IE6 does not display the horizontal scrollbars below properly (IE7 does, as do Firefox & Safari). My understanding is that IE6 does not respect the 'maxwidth' css setting, and that dokuwiki handles this via a section of javascript within a large block of javascript. I don't want to embed all the unnecessary javascript for this specific issue, so until I can learn about and implement an alternate solution, my apologies to those of you using IE6.]


The goal: To implement horizontal scrollbars for code containing long lines.

The reason: It's annoying when long code lines overrun right-hand sections of pages, or when they automatically widen the entire page, such that areas of normally-formatted text end up requiring horizontal scrolling.

Example of solution...

birkinbox:~ birkin$ 
birkinbox:~ birkin$ python
Python 2.4.1 (#1, Feb  1 2006, 18:35:57) 
[GCC 4.0.0 (Apple Computer, Inc. build 5026)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import urllib
>>> reference = urllib.urlopen('http://google.com')
>>> reference.read()
'<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{font-size:20px}.h{color:#3366cc}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}.lnc:link,.lnc:visited{color:#00c}.pgtab,.pgtab:hover,.pgtabselected,.pgtabside{text-align:center;text-decoration:none;color:#00c;display:block;height:27px;float:left;overflow:hidden;background:url(/intl/ja/images/productlinktabs.png) no-repeat;padding-top:8px}.pgtab{width:130px;background-position:-274px 0}.pgtab:hover{width:130px;background-position:-144px 0}.pgtabselected{width:144px}.pgtabside{width:3px;background-position:-404px 0}.ptr{cursor:pointer;cursor:hand}.iconl{background:url() no-repeat;overflow:hidden;height:px;width:px}#gbar{float:left;height:22px;padding-left:2px}.gbh,.gb2 div{border-top:1px solid #c9d7f1;font-size:0;height:0}.gbh{position:absolute;top:24px;width:100%}.gb2 div{margin:5px}#gbi{background:#fff;border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;font-size:13px;top:24px;z-index:1000}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}.gb2 a{display:block;padding:.2em .5em}}#gbi,.gb2{display:none;position:absolute;width:8em}.gb2{z-index:1001}#gbar a{color:#00c}.gb2 a,.gb3 a{text-decoration:none}#gbar .gb2 a:hover{background:#36c;color:#fff;display:block}</style><script>window.google={kEI:"XIjSR5-NKZz0iAHLxMxp",kEXPI:"0",kHL:"en"};\nfunction sf(){document.f.q.focus()}\nwindow.gbar={};(function(){var a=window.gbar,b,g,h;function l(c,f,e){c.display=h?"none":"block";c.left=f+"px";c.top=e+"px"}a.tg=function(c){var f=0,e=0,d,m=0,n,j=window.navExtra,k,i=document;g=g||i.getElementById("gbar").getElementsByTagName("span");(c||window.event).cancelBubble=!m;if(!b){b=i.createElement(Array.every||window.createPopup?"iframe":"DIV");b.frameBorder="0";b.scrolling="no";b.src="#";g[7].parentNode.appendChild(b).id="gbi";if(j&&g[7])for(n in j){k=i.createElement("span");k.appendChild(j[n]);g[7].parentNode.insertBefore(k,g[7]).className="gb2"}i.onclick=a.close}while(d=g[++m]){if(e){l(d.style,e+1,f+25);f+=d.firstChild.tagName=="DIV"?9:20}if(d.className=="gb3"){do e+=d.offsetLeft;while(d=d.offsetParent)}}b.style.height=f+"px";l(b.style,e,24);h=!h};a.close=function(c){h&&a.tg(c)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="sf();if(document.images){new Image().src=\'/images/nav_logo3.png\'}" topmargin=3 marginheight=3><div id=gbar><nobr><span class=gb1><b>Web</b></span> <span class=gb1><a href="http://images.google.com/imghp?hl=en&tab=wi">Images</a></span> <span class=gb1><a href="http://maps.google.com/maps?hl=en&tab=wl">Maps</a></span> <span class=gb1><a href="http://news.google.com/nwshp?hl=en&tab=wn">News</a></span> <span class=gb1><a href="http://www.google.com/prdhp?hl=en&tab=wf">Shopping</a></span> <span class=gb1><a href="http://mail.google.com/mail/?hl=en&tab=wm">Gmail</a></span> <span class=gb3><a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1"><u>more</u> <small>&#9660;</small></a></span> <span class=gb2><a href="http://video.google.com/?hl=en&tab=wv">Video</a></span> <span class=gb2><a href="http://groups.google.com/grphp?hl=en&tab=wg">Groups</a></span> <span class=gb2><a href="http://books.google.com/bkshp?hl=en&tab=wp">Books</a></span> <span class=gb2><a href="http://scholar.google.com/schhp?hl=en&tab=ws">Scholar</a></span> <span class=gb2><a href="http://finance.google.com/finance?hl=en&tab=we">Finance</a></span> <span class=gb2><a href="http://blogsearch.google.com/?hl=en&tab=wb">Blogs</a></span> <span class=gb2><div></div></a></span> <span class=gb2><a href="http://www.youtube.com/?hl=en&tab=w1">YouTube</a></span> <span class=gb2><a href="http://www.google.com/calendar/render?hl=en&tab=wc">Calendar</a></span> <span class=gb2><a href="http://picasaweb.google.com/home?hl=en&tab=wq">Photos</a></span> <span class=gb2><a href="http://docs.google.com/?hl=en&tab=wo">Documents</a></span> <span class=gb2><a href="http://www.google.com/reader/view/?hl=en&tab=wy">Reader</a></span> <span class=gb2><div></div></a></span> <span class=gb2><a href="http://www.google.com/intl/en/options/">even more &raquo;</a></span> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I\'m Feeling Lucky"></td><td nowrap width=25%><font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en>Advanced Search</a><br>&nbsp;&nbsp;<a href=/preferences?hl=en>Preferences</a><br>&nbsp;&nbsp;<a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><br><font size=-1><a href="/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>&copy;2008 Google</font></p></center></body></html>'
>>>

Solution

All credit goes to Dokuwiki, which implements this solution via CSS (I've also seen javascript solutions). I used the Firefox web-developer plug-in to figure out what part of the CSS works the magic, and came up with the adapted CSS below. (Note comment implying the second style may not be necessary.)

pre { /* allows horizontal scrollbars to appear; excellent for code */
    font-size: 120%;
    padding-top: 0.5em;
    padding-right: 0.5em;
    padding-bottom: 0.5em;
    padding-left: 0.5em;
    border-top-width: 1px;
    border-right-width: 1px;
    border-bottom-width: 1px;
    border-left-width: 1px;
    border-top-style: dashed;
    border-right-style: dashed;
    border-bottom-style: dashed;
    border-left-style: dashed;
    border-top-color: #8cacbb;
    border-right-color: #8cacbb;
    border-bottom-color: #8cacbb;
    border-left-color: #8cacbb;
    color: Black;
    background-color: #f7f9fa;
    overflow-x: auto;
    overflow-y: auto;
    }
* html .insitu-footnote pre.code, * html .insitu-footnote pre.file { /* 2008-03-08-Sat note to self: this was added for horizontal scrollbar support, but doesn't seem necessary for Safari/Mac or FF/Mac -- after reinstalling Parallels test in IE/Win and delete if it's not necessary */
    padding-bottom: 18px;
    }

Nice!

Website update

monday, march 3rd, 2008 5:50am

This website is about two months old. I started working on it shortly after a Christmas/New Year's vacation in small but steady increments of early-morning time. So, some of the highlights...

  • Set up hosting account with webfaction, because they offer django-hosting via mod-python and were highly recommended by numerous django folk
  • Set up domain name bspace.us (.org & .net were taken) with pair.com's domain registration division
  • Pointed domain name to hosting site
  • Set up django and mysql. My early db training was with postgres, which I'm partial to and which webfaction also offers, but I chose mysql thinking that it would give me experience useful in my work, where we use mysql. However, django abstracts direct database access so successfully that I may switch over to postgres.
  • Figured out how to utilize webfaction's tools to set up multiple django projects with subdomains
  • Implemented early version of this blog adapting the Simpla theme I had used for an old wordpress.com blog
  • Figured out how to set up webfaction static-page serving and point django admin to that, and make this work via https. As an aside, I cannot speak highly enough about the django ssl middleware that allows super-easy specification of pages which should only be able to be accessed via https.
  • Added some current content and a bit of old content
  • Added 'published' field to allow me to work on in-process articles using the django admin
  • Most recently, figured out how to integrate Markdown syntax into django. This allows me to edit a note entry with simple formatting markers which are saved to the database, and on display are automatically converted into appropriate html.

Possible future improvements

I have a couple of other personal projects I want to get to (not to mention the fact that most of my work projects are so compelling that I enjoy working on them at home when time permits) and thought I might put 'notes' development work on hold, but will continue to work on this site through March. The improvements I'm interested in exploring include...

  • Adding a comment architecture, possibly with captcha and other anti-comment-spam features
  • Implementing long-code css, to enable horizontal scrollbars to appear when a long string of code is entered. This allows page formatting to remain intact, and prevents a user from having to scroll an entire page back and forth horizontally simply because of a single line of long code. (example here)
  • Adding a previous-version or two, and enabling a user-friendly 'diff' feature
  • Learning about and implementing google analytics
  • Learning about and implementing google charting -- for instance, I could have a dynamically-generated pie-chart showing the top tag-areas in which I post
  • Learning about and exploring google ads
  • Enabling each tag to have its own RSS feed and implementing this with a user-friendly interface
  • Experimenting with microformats
  • Learning how to most easily incorporate COinS into book mentions. I understand how to use COinS, but would like to learn about the easiest ways to generate them.
  • Utilizing django's caching framework

Doubtless I'll think of other interesting work along the way.

Feed interfaces & urls

sunday, february 10th, 2008 2:46pm

I'm going to add feeds to the site, which django makes easy to do. But I want to think about the urls for the notes feeds. I had been thinking I'd manually create a feed that can flow to planet.code4lib.org that would have been a combination of tags (at the moment 'user-context' and 'api') so that things irrelevant to code4lib don't show up. But it'd be nice to generalize this, so that anyone coming to the site can easily select multiple tag-categories and get a feed from that.

So I want to think beyond an obvious simple elegant system for single tags. (Before the idea occurred for multiple-tag feeds the url for tag 'user-context' would have been 'http://bspace.us/notes/feeds/user-context' -- but that's not extensible.)

Tripod new titles list

The tripod newtitles list has a great interface for selecting multiple categories. Selecting a few options returns a fully-parameterized url, nicely explicit if a bit busy.

For the notes feeds, I'd like to offer combined-option feeds in two ways: as parameterized, but also in a tinyurl fashion, like:

http://bspace.us/notes/feeds/arzq

If that url returned (in addition to feed info, obviously) a documentation link, the documentation could note that the link

http://bspace.us/notes/feeds/arzq/info

...would return, among other things, the explicit url.

I'll think more on this and look for other examples of interestingly-crafted feed interfaces and urls.

Welcome

friday, november 9th, 2007 6:21am

I'm Birkin James Diana, and this is my personal website: a kind of experimental technology room.

I'm a programmer & web-developer for the Brown University Library, a terrific institution doing cool work. I code primarily in the languages python, java, and php, and increasingly (and happily) use django. My interests include extreme programming, test-driven development, instant-runoff-voting, weighted-randomization, solar power -- the list is long.

One reason for this site is to have a venue to focus and disseminate a sliver of the numerous ideas I have about how to make the world a better place, mostly in a geeky web-programmer realm. Another reason is to deepen my knowledge of the django web-framework. There's a tension here between using a pre-existing solid and feature-laden service like wordpress.com to communicate ideas, and 'rolling my own' site to deepen learning.

General email address, birkin.diana@gmail.com; work-specfic email address, birkin_diana@brown.edu.