A-  A  A+ RSS Feed

Deep Thoughts by Robert Felty

thoughts on wordpress, latex, cooking et alia

Archive for the '(x)html' Category

Thursday, February 18th, 2010

Multi-column balanced lists

List with balanced columns

List with balanced columns

List with unbalanced columns

List with unbalanced columns

Recently I was working on a project where a client wanted a list of items to be displayed over multiple columns, and requested that the columns be balanced (as balanced as possible). It didn’t take me too long to figure out how to do this for 3 columns, but I knew that there was a more general solution, which did take me a little time to figure out. I am sharing my solution here for my future reference. Perhaps some one else will find it useful too. The solution is in php, though the general algorithm should apply to any language.

The intuition that led me to this solution was to examine unbalanced columns. Let’s look at the case of 5 columns with 56 items, as shown in the figures. It quickly becomes obvious that you need 12 items per column (ceil(56/5)). However, this yields columns of lengths 12, 12, 12, 12 and 8. If you decrease the number of total items to 55, then you have balanced columns of 11. If you increase the number of items to 60, you have balanced columns of 12. Thus, it is possible for the last column to have n-1 items less than the other columns, where n is the number of columns. The preferred output is to have columns of 12, 11, 11, 11, and 11. So what we are doing is shifting over elements from columns 2, 3, and 4 to column 5 (note that we are not messing with the order of the elements). We can always achieve the desired result by simply decreasing the number of items from some of the columns by 1. To determine which columns to decrease, we simply look at the difference in the number of elements per column in the unbalanced solution. In the case of 5 columns with 56 items, the last column would only have 8 items, which is 4 less than 12. So we should start reducing the number of items per column at the 2nd column ((5-4)+1). If we had 57 items total, we would start reducing at the 3rd column ((5-3)+1).

Here is the snippet of code which takes care of figuring this out:

$numCols = 5;
$numItems = 56;
$itemsPerCol = ceil($numItems / $numCols);
$adjustedItemsPerCol=$itemsPerCol;
$blank =$itemsPerCol - ($numItems % $itemsPerCol);
if ($blank!=$itemsPerCol && $blank >0) {
  $adjustedItemsPerCol--;
}

While we are looping over our array of items (or, in my example case, using a while loop), we check to see which column we are on, and if we are on the column where we start to decrease the number of items per column, then we switch $itemsPerCol to $adjustedItemsPerCol.

if ($colNum == ($numCols - $blank)) {
  $itemsPerCol=$adjustedItemsPerCol;
}

Feel free to look at this working example, along with the code for it. I have used the CSS float property to make the divs act like columns, and added some colors to help them stand out.

Tuesday, August 18th, 2009

Blogging with LaTeX

The first question on reader’s mind must be — why use LaTeX to blog?

Well, I have a pretty specific instance in mind, but I can imagine that others might be interested as well. This fall I am teaching a course on computational corpus linguistics at CU Boulder. I like to have some materials online for the students, such as the syllabus, course notes, etc. I thought about setting up a simple webpage, but then I decided instead to use wordpress, because it would give me extra functionality, such as auto-generating rss feeds, and with some plugins, would allow me to notify students via e-mail when I post lecture notes or slides, or homework tips. The one drawback I could see is that it would be hard to update the syllabus throughout the semester, as I tend to change the calendar some throughout the semester. Then I thought that maybe I could hack up a quick xml-rpc solution to the problem, and about an hour later, I had it done. All I needed was the Wordpress::API perl module from CPAN.

Now I have a handy little publish script which first compiles my syllabus as pdf, then compiles it as html using plasTeX. Then I run it through tidy for formatting and hack in a few more things. Then I update the syllabus page on the course blog via xml-rpc. Finally, I rsync the pdf to the server. And with the post-notification plugin for wordpress, students will get an e-mail when the syllabus is updated.

Here are the scripts:

publish

#!/bin/bash
# this script compiles a pdf version, an html version, and then copies it to my
# webserver

# compile as pdf
pdflatex syllabus && pdflatex syllabus

# compile as html
plastex  -c syllabus.cfg syllabus
# clean up code a bit
tidy --show-body-only true --ascii-chars true  -asxhtml --input-encoding utf8 --output-encoding ascii -wrap 0 -indent --tab-size 4 syllabus/index.html > syllabus/syllabus.tmp

# add in link to pdf version in the html version
cat pdflink syllabus/syllabus.tmp > syllabus/syllabus.html

# update the syllabus page via xml-rpc
./updateSyllabusPage.pl

# upload the newest version of the pdf
rsync -avzu syllabus.pdf robfelty.com:/var/www/html/robfelty/teaching/ling5200Fall2009/ling5200Fall2009-syllabus.pdf

updateSyllabusPage.pl

#!/usr/bin/perl -w
use WordPress::API;

# get new syllabus content
my $contentFile = 'syllabus/syllabus.html';
open(CONTENT, $contentFile);

# slurp in content
$content = do {local ( $/ ); <CONTENT> };

my $w = WordPress::API->new({
   proxy => 'http://robfelty.com/teaching/ling5200Fall2009/xmlrpc.php',
   username => 'myusername',
   password => 'mypassword',
});

my $page = $w->page(3);

$page->description($content);
$page->save;

Finally, if you want to see how I customize content for pdf and html separately, you can check out the LaTeX source file

Friday, July 24th, 2009

On blog navigation

A few navigation choices after reading an article on a blog

A few navigation choices after reading an article on a blog

I was recently debating with my friend Danny how people navigate sites, especially blogs. As the author of 3 plugins designed to enhance site navigation (collapsing archives, categories, and pages), I of course had my opinions, but what is really compelling is data. So I finally decided to modify my links on my site a bit in order to figure out more exactly how people are navigating my site. There are several different ways in which people can navigate to a particular page on my site.

  • external
    • search
    • social network (digg, reddit, friendfeed, etc.)
  • internal
    • collapsing archives widget
    • collpsing categorries widget
    • collapsing pages widget
    • category page
    • archive page
    • search
    • index page link
    • prev page link
    • next page link

I added a ?nav query to each of these particular options, so that I could then find those values in the server logs. I wrote a little bash script which mostly does some grepping of the log. Here is the script, and the results for the last 12 hours or so. My plan is to collect about 30 days worth of data, and see what the data shows. I think the results will be informative.

#!/bin/bash
# calculate how people navigate my site

# first we filter out all spiders, any internal blog stuff, and requests from
# my own ip, and then pipe that to filter out page refreshes
grep -vEi '(Mediapartners-Google|bot|spider|crawler|slurp|scoutjet|httpunit|htmlparser|favicon|wp-cron.php|wp-content|wp-photos|wp-comments|feed|fail\.php|wp-login.php|POST|\/images|wp-includes|forum|71\.237\.102\.16)' experiment_log |grep -Ev '"GET (.*) .*\1' > nobots

# next we separate into internal and external referers
grep 'http://blog.robfelty.com' nobots > INTERNAL
grep -v 'http://blog.robfelty.com' nobots > EXTERNAL

EXTSEARCH=`grep -ciE '(yahoo|bing|google)' EXTERNAL`
SOCIAL=`grep -ciE '(fark|reddit|digg|slashdot|friendfeed|facebook|twitter)' EXTERNAL`
NOREFERER=`grep -c '"-"' EXTERNAL`
EXTREMAINING=`grep -viE '(yahoo|bing|google|fark|reddit|digg|slashdot|friendfeed|facebook|twitter)' EXTERNAL|grep -cv '"-"'`
COLLARCH=`grep -c '?nav=collapsing-archives' INTERNAL`
COLLCAT=`grep -c '?nav=collapsing-category' INTERNAL`
YEARLY=`grep -c '?nav=yearly' INTERNAL`
MONTHLY=`grep -c '?nav=monthly' INTERNAL`
CAT=`grep -c '?nav=category' INTERNAL`
COLLPAGE=`grep -c '?nav=collapsing-pages' INTERNAL`
SEARCH=`grep -c '?nav=search' INTERNAL`
INDEX=`grep -c '?nav=index' INTERNAL`
PREV=`grep -c '?nav=previous' INTERNAL`
NEXT=`grep -c '?nav=next' INTERNAL`
TOTAL=`wc -l nobots|cut -f1 -d ' '`
INTERNAL=`wc -l INTERNAL|cut -f1 -d ' '`
EXTERNAL=`wc -l EXTERNAL|cut -f1 -d ' '`
# Only firefox prefetches
PREFETCH=`grep -vE '\?nav=(collapsing-category|collapsing-archives|search|index|previous|next)' INTERNAL|grep -c 'Firefox'`
INTREMAINING=`grep -vE '\?nav=(collapsing-category|collapsing-archives|search|index|previous|next)' INTERNAL|grep -cv 'Firefox'`
echo "TOTAL PAGES = $TOTAL"
echo "  EXTERNAL= $EXTERNAL"
echo "    EXTSEARCH = $EXTSEARCH"
echo "    SOCIAL = $SOCIAL"
echo "    NOREFERER = $NOREFERER"
echo "    REMAINING = $EXTREMAINING"
echo "  INTERNAL= $INTERNAL"
echo "    COLLARCH = $COLLARCH"
echo "    YEARLY = $YEARLY"
echo "    MONTHLY = $MONTHLY"
echo "    COLLCAT = $COLLCAT"
echo "    CAT = $CAT"
echo "    COLLPAGE = $COLLPAGE"
echo "    SEARCH = $SEARCH"
echo "    INDEX = $INDEX"
echo "    PREV = $PREV"
echo "    NEXT = $NEXT"
echo "    PREFETCH = $PREFETCH"
echo "    REMAINING = $INTREMAINING"
TOTAL PAGES = 197
  EXTERNAL= 131
    EXTSEARCH = 51
    SOCIAL = 0
    NOREFERER = 43
    REMAINING = 37
  INTERNAL= 66
    COLLARCH = 3
    YEARLY = 0
    MONTHLY = 0
    COLLCAT = 4
    CAT = 0
    COLLPAGE = 0
    SEARCH = 1
    INDEX = 1
    PREV = 0
    NEXT = 0
    PREFETCH = 52
    REMAINING = 5
Thursday, June 11th, 2009

wordpress 2.8 is out, and my plugins are ready

As I mentioned a few months back, wordpress 2.8 has a completely new widget API, which means that I had to do quite a bit of work to get my widgetized plugins ready for 2.8. Fortunately, the new API is much better than the old style. I won’t guarantee that they are without bugs, which is why I am calling them beta. But they should all work with the defaults at any rate. They also have some new features, including several default style templates, which should make styling easier for most users. And for people who don’t like widgets, now you can enter all the options into your template manually, meaning you can use different options in different parts of your theme if you wish.

Also I will be on vacation for a few days, so I won’t be answering questions in the forum until Monday the 15th.

Friday, June 5th, 2009

Releasing Postie 1.3.alpha, packed with new features

Thanks to all the users who helped me test out the 1.3.testing version of postie, the wordpress plugin which allows you to post by e-mail. I now feel that it is stable enough to call it 1.3.alpha. There are probably still some bugs, but I think that the new features probably warrant giving it a try for most users. Here is a summary of the new features and fixes:

  • Now using default wordpress image and upload handling, which means:
    • No more creating special directories for postie
    • No more confusion about imagemagick
    • Can now use the gallery feature of wordpress
    • Attachments are now connected to posts in the database
    • All image resizing uses wordpress’s default settings (under media)
  • Configuration, settings and documentation improvements
    • Completely redesigned settings page (mostly thanks to Rainman)
    • Reset configuration no longer deletes mailserver settings
    • Now including help files and faq directly in settings page
  • More media features
    • Automatically turn links to youtube into an embedded player
    • Added option to embed audio files with custom templates
    • Video options are now template based
    • Image options are now solely template based, with several new default
      templates
  • Bug fixes
    • Uploading images from vodafone phones should now work
    • Correctly handling Windows-1252 encoding
    • Correctly handling non-ascii characters in subject line

I still need your help! As I mentioned there are bound to be some bugs, and I would appreciate if you give me feedback in the postie forum. Several people have also provided localizations. That is a big help. Some of the current localizations now need some updating. If you are familiar with that, I would be grateful. A .pot file is included with the postie distribution.

I have mostly stopped development on the 1.2 branch of postie. I will be adding new updates to postie in the development version.

Below is a screenshot of the new options page for postie.

Screenshot of the new postie options page, showing the video and audio templates

Screenshot of the new postie options page, showing the video and audio templates