Eric TF Bat's Journal

It's People Like You What Causes Unrest

Python PDF Generation Libraries? Anyone? Anyone?
the-dark-batpup-returns
[info]etfb

As part of my ongoing efforts to stave off living in a cardboard box in the middle of a lake, I took on a project for a friend and former cow-orker last year, to produce PDF files from a database for a client. I did it in PHP, because that was the only tool available that looked like it might work, but I now regret it. Apparently, when it tries to generate the whole 400-odd page on the friend's server, it crashes Apache and the whole server needs to be rebooted (!). Even running on my laptop causes interesting side-effects, often requiring a Level Two Diagnostic*. I suspect the third-party library really isn't up to the sort of contortions I put it through, sadly.

So I'm looking for an alternative. Mr Death, the aforementioned friend, has control over the server, so he can install whatever I need, but I really should try to stick with languages that other people know. That and the Linuxness of the system mean no Delphi, no Common Lisp and no hand-coded PostScript. My best bet is probably Python. So if any Pythonistas out there can recommend a good, fast, open-source PDF generation library for Python, please let me know. The features it needs, in increasing order of trickiness, are:

  1. Scaled images in the text
  2. Table-based layouts in some sections
  3. Header and footer definition
  4. Widow/orphan prevention, so that if a paragraph is going to be broken before the end of its column, it "moves" to the top of the next column.
  5. Two columns per page in some sections
  6. Image watermarks behind the text
  7. Multiple font styles within the one fully-justified paragraph
  8. Page numbers in the form "Page X of Y", filled in after you actually find out how many pages there are.
  9. Out-of-order page generation, since I'll need to create a table of contents on the fly and then stick it at the start of the document.

The library I used (and extended) had these features, but it got horribly slow, largely because the widow/orphan control forced it to generate nearly every paragraph twice. The underlying library didn't have caching of pre-calculated paragraphs, and the code is so badly written that I couldn't begin to add that sort of feature.

Can anyone advise? I'm already aware of ReportLab, and I've asked on their mailing list if it can handle the last and greatest of those features, but actual experience from real live users would be nice too.


* For those of my audience unfamiliar with the ways of system administration:

Level One Diagnostic: is it plugged in?
Level Two Diagnostic: have you tried rebooting?
Level Three Diagnostic: we've reformatted your hard disk for you; would you like it back?


PHP: Or else?
the-dark-batpup-returns
[info]etfb

In Perl and other languages, there's a useful idiom that goes like this:

  $x = [some input];
  $y = $x || 'no answer';

This sets $y to the value of $x if there is one, or else to the fallback of 'no answer'. It's a good time-saver: you can express yourself in a simple, unambiguous way, and anyone familiar with the idiom will understand your code.

Naturally, PHP gets this wrong. PHP follows the principle that strings should be converted to boolean values, so the expression $y = $x || 'no answer' is interpreted as something like $y = convert_to_boolean($x) || convert_to_boolean('no answer'). Since the second string, at least, is not empty or null or zero or one of a zillion other boolean FALSE values, this evaluates to TRUE, or one, every time. Unhelpful.

I wanted to check this, though. PHP, like Perl, has its boolean operators in pairs: || and or, && and and, and so on. I'm not sure why, since it lacks the open FILE,$name or die syntax that makes the lower-precedence operators useful. So I thought maybe the difference related to the problematical conversion. Maybe $x or 'no  answer' was what I needed! Certainly worth a try. I wrote a quick test harness, and for completeness' sake I threw in the binary or operator, "|".

  $x = 'hello';
  $y = 'goodbye';

  print "\$x || \$y = " . ($x || $y) . "<br>\n";
  print "\$x or \$y = " . ($x or $y) . "<br>\n";
  print "\$x | \$y = " . ($x | $y) . "<br>\n";

What results would you expect? Think about it before you read on. I'll give you a clue: you can imagine some language designer thinking it's a fun idea, though it's not a feature you could imagine actually wanting.

Ready? Here's the result, straight off the browser page:

  $x || $y = 1
  $x or $y = 1
  $x | $y = oooloye

"Oooloye"??? The what na who???

The reason for the result was immediately obvious (I'm sure it was for you too). "H" is the eighth letter of the alphabet; "G" is the seventh. If you "or" the bit patterns of 8 and 7 -- 1000 or 0111 -- you get 1111, or 15: the letter "O". Similarly for the rest: it's taking each character of $x and $y, oring the bits together, and slapping the results into the answer.

As I said, it's possible to imagine a sufficiently naive, inexperienced programming language designer thinking this was clever and useful, but it's not possible to imagine it being more useful than the Perl idiom. Given that PHP was originally a set of Perl scripts thrown together to do web pages, there must have been a point in time when Rasmus explicitly decided to throw out the useful idiom and stick this one in instead. It was a choice.

And that, dear children, is reason #1,053,294 for Why PHP Is Too Stupid To Live. Thank you.


Bandwagon
the-dark-batpup-returns
[info]etfb
I don't want to be left out of the blame game, so I will just state here:

The Virginia Tech massacre would not have happened if more people used <?php tags in their PHP scripts instead of the deprecated <? tags.

Got that? Good.
Tags: ,

Mission Accomplished
the-dark-batpup-returns
[info]etfb

I got the work done for Mr Death, and he was suitably pleased. Actually, that's the short version. The long version is that he tried it out this morning about 6am (he's a mutant; go figure) and discovered some serious issues with the printing because I'd been too stupidtired to test it in Print Preview mode. He did some fiddling and sent a panicky email; I fixed the rest when I woke up, but there remained a problem.

Well? Don't keep us in suspense! )

Bloody Silly Thing To Be Doing When I'm Sick
mildly-retarded
[info]etfb
It's 1:00 in the morning. Just finished putting together some CSS and PHP for the Department of Yummy-Nummy Fishies and their "How To Brutally Slaughter, Cook and Eat Australia's Endangered Sealife" brochure. My one and only non-SCAdian, non-choral friend, Mr Death (aka Steve), is off to Brussels shortly where there will be some sort of presentation, and so the web version of the brochure absotively posilutely had to be indistinguishable from the printed version. Rounded corners and all.

That way lies madness. Photoshoppy, anti-Zeldmanny madness.

Still, I got it working, lurgi notwithstanding. I should have started a week earlier, but other things just got in the way, and as usual I underestimated the effort because I misread one of the emails and thought it was a completely different job. And because I've been sleeping large swathes of every day.

The lurgi has begun turning into bronchitis again, so I went to see our smug but loveable GP and got a script for some industrial strength antibiotics. I also got that most wonderful of mixed blessings, the medical certificate. It's mixed because of the incipient guilt: back when I was a contractor, if I were sick any day I'd call in sick, take the day off, recover and come in refreshed and generally better. Sure I'd lose a day's pay, but that's what being a contractor means: you get paid extra in general to make up for having to get paid nothing occasionally. Now that I'm a permanent employee, I feel hideously guilty about the fact that, what with Easter in the way and then ANZAC Day next week, I will have been paid for four full weeks of work and missed seven days out of it. It wouldn't be so bad if it were the government, but we have a mild case of Deadline Hell and I know the boss, and he doesn't drive a red Porsche. (Bosses who do drive red Porsches are pillocks, and deserve whatever happens to them, naturally.) So I feel like I need to apologise for not spreading leprosy of the lungs to my cow-orkers. sigh

Will be over the lurgi soon. There's a house to clean and lots of other stuff to do. Gratian - remember that? Have to get that handed over. And other things. So I shall keep at it. But now, bed beckons. G'night.

Rasmus Gets Brain Transplant From Gibbon; Immediate Improvement Seen!
the-dark-batpup-returns
[info]etfb
Truly we live in a world of wonders. First, I got a message back from the PHP bug tracker that my complaint about the Windows version of PHP has been dealt with, and the bug fix is now available in the latest downloadable CVS binaries. So if I were still using Windows, I'd be able to get back to work!

And second, a more serious limitation in PHP, related to adding functionality to XSLT, may possibly be solvable using the existing Streams module, meaning I won't have to cripple my libxslt-enabled version of the Xenolith Engine content manager. A shame I had to guess at the appropriate googlewords to find this, since the internal hyperlinking of the PHP "documentation" is so pitiful. But never mind; I'm there now. Come lunch time, I'll experiment and see how it works.

Edit: No dice with the Streams module. It seems it only works properly in PHP5, which no web host on earth has bothered to install because even the minor upgrades in PHP4 versions tended to cause too many headaches. So I'll have to use a much less powerful method to get stuff done. Bugger.
Tags:

Take That, Rasmus!
the-dark-batpup-returns
[info]etfb


Output from the PHP diagnostic function on Manticore, showing the two lines (highlighted) that eluded me totally in Windoze

Steps to achieve DOM/EXSLT functionality in Ubuntu:

  1. Install Apache.
  2. Install PHP.
  3. Enjoy the excitement that is XSLT.

Steps to achieve DOM/EXSLT functionality in Windows:

  1. Spend three days trying to get the bloody thing to do what the documentation says it should do.
  2. Give up and install Ubuntu.
  3. See above.

So there we go: mission accomplished. Now I just need to drag the baronial website kicking and screaming into the world of maintainable, valid HTML. Easy!


Travels With The Spaceman
the-dark-batpup-returns
[info]etfb
Mr Shuttleworth's little toy (the other one apart from the space station) is coming along nicely. I got VMWare where I like it by copying the VM back to the Beloved's laptop, which has a copy of the Windows version of VMWare Workstation, and adding an extra virtual 8Gb of hard disk space. So now I can run Windows when I want to, which will mainly be when I'm working on Gratian.

For the rest of the time, it's Linux all the way. Tonight I successfully built and installed GNU Emacs 22. It wasn't easy: I had to use the Emacs Wiki to get instructions on downloading the source, and then after I followed all those instructions, which required installing a lot of extra development tools via the excellent Synaptic Package Manager, I had to do it all again because Emacs relies on the obsolete termcap database instead of the terminfo that Ubuntu uses. Never mind; I got to play [info]uniqueid's favourite game Frozen Bubble while I waited, so the time flew.

Tomorrow, in between further house cleaning, I plan to install Apache 2.2 and PHP 4.4, and then get the libxslt/EXSLT add-in working, which is the thing I couldn't do for all the googlejuice in China and which led me to this radical departure in the first place. And I'd better get the appropriate extra stuff installed inside Mustang, my Windows VM, so I can work on Gratian this week.

As long as I get to spend more time with my daughters as well, like I did today, I'll be happy.
Tags: ,

PHP 4 and Apache 2.2
ping-my-cheese
[info]etfb

Picture if you will... you're trying to run PHP 4 as a module in the latest Apache 2.2 under Windows, and you keep getting an error message when you restart:

httpd.exe: Syntax error on line ### of C:/.../httpd.conf:
Cannot load C:/.../php4apache2.dll into server: The specified module could not be found.
Note the errors or messages above, and press the <ESC> key to exit.

What do you do? If you're like me, you look on the official PHP and Apache sites for an answer. It will elude you (although there's a line there mentioning problems with 2.2 that I found the third time I looked, but it doesn't seem to have made it to all the mirrors, or else my eye just kept skipping over it).

Fortunately, there's a hint in one of the user-supplied notes -- which I generally ignore, since they tend to be written by complete cretins -- that led me to the Download page on Apache Lounge. From there I downloaded php4apache2.dll-php4.4.x.zip, followed the instructions in the README file, and voila! It works, almost like real software made by grownups! It's amazing!

(Gods, I wish [info]vonstrassburg would put mod_python on the SCA server. I know he's a pelican, a system administrator and a former kingdom seneschal, and therefore has three excellent reasons to enjoy making people suffer, but it's getting old. PHP is for the retarded, really it is.)


Some Days I Hate PHP. Other Days I Just Loathe, Detest and Despise It
the-dark-batpup-returns
[info]etfb
Trying to get Apache 2 and PHP 4 working in Windows. Ugh. I want Rasmus Lerdorf beaten to death with the dismembered corpse of Robert McCool. That is all.

Ranty McRant of the Clan McRant
the-dark-batpup-returns
[info]etfb

I'm going to rant about geekly things again. Don't click through if you don't want vitriol-flavoured spittle on your eyeballs.

No, really. Go somewhere else. I imagine YouTube has some funny cat videos you could watch. )

Quiz: Are you a PHP moron?
the-dark-batpup-returns
[info]etfb

Here's a quiz for any PHP programmers who may have wandered in.

Ignore if you're not a geek )

Rasmus's Toy
the-dark-batpup-returns
[info]etfb

I use PHP. That doesn't mean I like it. In fact, if they were taking a collection to buy a copy of The Dragon Book to beat Rasmus Lerdorf to death with, I'd chip in extra if they promised to scream "use of uninitialised variables is an error, not a warning!!!" as he died.

So when the Rednex' Cotton-Eye Joe came up on my random rotation, I wrote this:

If it hadn't been for Rasmus's toy
I'd be done and set to deploy
What were you thinking, what was the ploy?
Why did you build it, Rasmus's toy?

It sits on the web like a steaming big turd
The hacks it relies on are plainly absurd
The rules that it breaks were already well known
When Rasmus's Pa wasn't even half grown

It brings disaster wherever it's used
Demanding that all common sense be abused
The script-kiddies say it's a wonder and joy
And that says it all about Rasmus's toy


Home