Preparing HTML for print

2011/05/09

The challenge

Getting a HTML out of a printer for book-production, for example, is quite a challenge: Getting the page-breaks right, getting the CSS right and so on and so on.

CSS standards

Luckily, CSS 2.1 supports Print-media-specific standards for this (for example: http://www.westciv.com/style_master/academy/css_tutorial/advanced/printing.html),  Sadly, this is not completely, or improperly supported, by most HTML clients we have at this moment. (see http://www.webdevout.net/browser-support-css#css2propsprint for a nice overview of support per browser, sadly not updated for Firefox version 4 yet, which DOES support some of it)

First: An example of what to include in your CSS for printing:

<style type="text/css">
@media print {
 .alwaysbreak {
   page-break-before: always;
 }
 .nobreak {
   page-break-inside: avoid;
 }
 @page :left {
   margin: 1cm;
   margin-right: 2cm;
 }

 @page :right {
   margin: 1cm;
   margin-left: 2cm;
 }
}
</style>

As you can see, above I tried to make each left page of the book have a wider right-margin, each right page of the book have a wider left-margin. Ideal for double-sided prints for books.

I also declared a class ‘nobreak’ that will make sure any contents of any <table> or <div> element using it, will no be broken up for a page break, but instead moved to the next page. Then there is the ‘alwaysbreak’ that does almost the opposite: It makes sure the inner contentst are always started at a new page. Both could be used like this:

<div class='alwaysbreak'>
  <h1>Always at a new page</h1>
</div>
<div class='nobreak'>
  <img src='mypicture.jpg' />
  <p>Caption, should never be broken from the image by a page-break</p>
</div>

Client support

You can imagine other classes too, like ‘neverbreakafter’ that will try to make sure your contents are not broken up in an ugly manner.

While preparing my children’s ‘first years’ book, I tried several clients to render my HTML to a proper PDF (also see this outdated article http://stackoverflow.com/questions/117772/which-browsers-support-page-break-manipulation-using-css-and-the-page-break-insid):

  • Internet Explorer: Only respects ‘page-break-after’ and ‘page-break-before’. And not in a very reliable way.
  • Chrome: Older versions accepted some of the standard, newer versions have broken it. iow: Not reliable
  • Firefox: Since version 4, which was JUST released, it finally supports all page-break-* tags in a nice way, but not the ‘widows/orphans’ and page-left / page-right margins, and rendering is flaky, to say the least.
  • Prince 2: http://www.princexml.com/ It promised to be the best, *does* support everything, but, with the latest beta 8, just renders my images-filled tables, the most important part of my books, completely wrong. Even worse: It renders the last column in the outer margins and even bleeding outside the page! Also, Prince is VERY ‘restrictive’ on the accepted incoming HTML, as it should be completely XHTML compliant. In practice, almost no webpage is *completely* xhtml compliant. For example: http://www.google.nl is not even accepted and it keeps complaining about ‘&nbsp;’ entities not being accepted. Ofcourse, this last error is fixable, but c’mon!!!! Just not practical and too much a ‘let the user sort it out’ approach. And then they ask money to NOT have a logo on your first page. 😦 On a sidenote, JavaScript support is ‘beta’, not supporting ‘innerHTML’, so jQuery
  • Opera: Tested with version 11, the latest, it supports everything!!!!!!!!!!!!!!!!!! One big problem with Opera: When rendering images to a printer, it uses the resolution of the screen-version of the images. Say you have an image of 1000×1000 pixels, and you include it as an IMG element with width=’250px’ height=’250px’, then it will just render it to the printer too as 250x250px. Whereas IE, Chrome, Firefox would just render it as a higher-density image! So, Opera is a no-go too. (And no, Print To File did not solve this either)
  • WKHTML2PDF: http://code.google.com/p/wkhtmltopdf/ IT DOES EVERYTHING! WOW! After one day of tweaking my HTML for almost every browser out there, THIS command-line tool just does it all. Be sure to get the ‘statically linked’ version, on my Windows test system if worked flawlessly. Supports higher density images for print, page-break-inside, page-break-after etc., correct header and footer, title page, generation of TOC. Wow!
Advertisements

AllSolutions’ WebSolutions: Uren loggen op Linux

2011/05/09

Want het werkt ‘alleen met IE6’, wat wel een BEETJE waar is.

Dus hoe toch te doen:
1. User Agent Switcher installeren in FireFox:
2. Naar deze pagina gaan:
  • https://ws.ict.nl/
  • Nu in adresbalk dit plakken:
    javascript:s=parent.login.appl.location.href;s=s.replace(‘start’,’launchmurreg’);window.open(s,’_newtab’);void(0);
  • En op enter drukken, de ‘urenregistratie’ opent in een nieuw tabje
3. Bookmarklet maken van javascript trucje:
  • Voeg een bookmark toe aan de “Bookmark bar” (rechtsklikken op bookmark bar -> Add Page)
  • Als URL hetzelfde JavaScript toevoegen, als naam wat jij wilt
  • Als je nu ooit weer naar https://ws.ict.nl toe gaat, dan gewoon de net aangemaakt bookmark kiezen om direct naar urenregistratie te gaan in een nieuw tabje.

Using Android SDK Manager with HTML proxy

2011/05/09

When you’re behind a NTLM proxy, or some other proxy requiring authorization, using the Android SDK Manager from Eclipse will not work to download, for example, Android packages.

Solution: Start the SDK manager from the command line (or Windows Explorer or Nautilus or whatever you use) in the tools/ directory of the downloaded Eclipse SDK you extracted on your zip. Configure the proxy settings there, accept possible errors popping up, and close the SDK Manager. Start the SDK Manager from the Eclipse environment again, and voila, the proxy CAN be configured.

All thanks and respect to my esteemed collegue who just started working for my company and already made quite a name in the hallway here, being buzzed around and chatted about by everyone, from technical staff upto and until higher management, who not only knows us this way, but also already is acquinted with famous people in our country, like Erik de Zwart, the Radio DJ, from his former employer. His name? Eric de Vries.


Ruby and Oracle Enhanced Adapter: Strange date values causing errors

2009/10/29

Seems that oracle not only allows ‘null’ dates, but also ’empty’ dates. On ’empty’ dates, the error would come up! I totally misjudged the results of the error then, it seems…

Below is what I changed in oracle_enhanced_oci_connection.rb in lib\ruby\gems\activerecord-oracle_enhanced-adapter-1.2.1\lib\connection_adapters\. The changed lines are marked with #MVR as comment above it. All I did is make ’empty’ dates detectable and skip converting them to a date too, effectively making them ‘null’ values too 😉 Starts around line 128:


# ruby-oci8 1.0 returns OraDate
when OraDate
# MVR: treat 'empty' date/time strings as null too!
if !(v.hour == 0 && v.minute == 0 && v.second == 0 && v.year == 0 && v.month == 0 && v.day == 0)
# RSI: added emulate_dates_by_column_name functionality
if OracleEnhancedAdapter.emulate_dates && (v.hour == 0 && v.minute == 0 && v.second == 0)
v.to_date
else
# code from Time.time_with_datetime_fallback
begin
Time.send(Base.default_timezone, v.year, v.month, v.day, v.hour, v.minute, v.second)
rescue
offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
::DateTime.civil(v.year, v.month, v.day, v.hour, v.minute, v.second, offset)
end
end
end
# ruby-oci8 2.0 returns Time or DateTime
when Time, DateTime
# MVR: treat 'empty' date/time strings as null too!
if !(v.hour == 0 && v.minute == 0 && v.second == 0 && v.year == 0 && v.month == 0 && v.day == 0)
if OracleEnhancedAdapter.emulate_dates && (v.hour == 0 && v.min == 0 && v.sec == 0)
v.to_date
else
# recreate Time or DateTime using Base.default_timezone
begin
Time.send(Base.default_timezone, v.year, v.month, v.day, v.hour, v.min, v.sec)
rescue
offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
::DateTime.civil(v.year, v.month, v.day, v.hour, v.min, v.sec, offset)
end
end
end
else v
end

Hope this is of any help to those fighting with Oracle 😉 Cheers


Ruby 1.9: Installing on Windows

2009/10/29

Below some notes I jotted down while trying to install a complete Ruby 1.9 environment for me to work with on…. *shudder* Windows *shudder.

Why the *shudder* ? Because some ‘plugins’ for Ruby (gems) require you to build it from sourcecode (make with mingw32 C++ compiler) which leads to all kinds of errors, the first one you’ll see is:  “You’ll have to install development tools first.”. So here’s what I did:

  1. Install the Ruby 1.9 one-click installer into D:\Ruby19 from http://rubyforge.org/frs/?group_id=167&release_id=38052, there select the rubyinstaller-1.9.1-p243-preview2.exe download.
  2. Add D:\Ruby19\bin to the environment PATH variable
  3. Open a command prompt and type ‘gem install scrubyt’. This leads to the above-mentioned error about no development tools found to create a make file etc. etc. etc.
  4. Find this post: http://programming-gone-awry.blogspot.com/2009/05/ruby-19-one-click-installer.html and follow it’s instructions.
  5. From the same RubyForge page as above, download the “devkit-3.4.5r3-20090411.7z” file too and unpack it into the D:\Ruby19 folder.
  6. Change paths in D:\Ruby19\devkit\msys\1.0.11\etc\fstab to point to D:\Rub19 instead of C:\Ruby
  7. Check installation of devkit with “gcc -v” in command prompt
  8. Check whether installation of binary gems work by using, for example, “gem install scrubyt”

I will post more messages regarding choosing a good IDE for Ruby on Rails development and any issues I encountered while developing my Oracle10 RoR application.


Fixing Oracle 8i ‘ORA-00904: invalid column name’ on export

2009/09/09

One of those days: You just want to migrate an ancient Oracle 8i database to a fresh ‘new’ Oracle 10g instance, when a simple bog-standard export (exp.exe) fails, displaying this dreaded error:

EXP-00008: ORACLE error 904 encountered
ORA-00904: invalid column name
EXP-00000: Export terminated unsuccessfully

---- start rant here ----

Ofcourse, no help provided as Oracle likes you to get your hands dirty (yes, pun intended): Tracing and monitoring SQL calls made by it’s exp.exe utility (and don’t even dare to use a utility for this they supplied themselves with Oracle 8), reading through log files, searching the internet to find what those SQL calls you finally found actually mean… the whole lot. Try that, if you’re not doing Oracle 24/7!

Somehow I always get somewhat ‘aggregated’ when a product is this ‘arrogant’, just assuming you live to work with it and have nothing else to be interested in! Even worse: When they supply tools with their product, that are as equally arrogant: If everything is configured OK, the tool works perfectly. But if something is wrong, you’ll tell the user nothing more than that something is wrong, leaving the user clueless and without a hint towards a solution. If there is one at all. Try letting the customer pay for that….

----- end rant here ----

Finding a solution:

Reading the error literally, I assumed one of my database’s column names were invalid, using some kind of Oracle / Java keyword that only on export would cause some kind of ‘clash’. As the error appeared while exporting Sequences, I searched through my primary key field names but found nothing wrong, from the looks of it. In the export’s parm file, I even tried exporting only specific tables, or just one table, to eliminate which table’s field names could cause the error…. Nothing.

As I knew my database was not using any of the Java magic internally, I searched the internet to find a way of ‘disabling’ support for Java in my database, trying to get the database to the most ‘basic’ state I could imagine. And then I arrived, after a long search, at this post on LazyDBA, referring to ORACLE MetaLink DocID 196921.1 (Oracle Meta…. WHAT? Geez…):

If Java is enabled, the Export utility uses DBMS_JAVA.LONGNAME in a query
while exporting synonyms. If the DBMS_JAVA or DBMS_JAVA_TEST package has not been
installed or somehow cannot be executed, this query will fail with and ORA-
00904: “invalid column name”.

Derived from the comments made in this post and the Oracle article, I came to the following steps to repair my Oracle database.

The solution:

Warning: Following these steps will complete remove the Java support for your database. In the Metalink article, and in the LazyDBA post, you’ll also find instructions on how to re-install the Java support, if your database needs it, but I have not tested this yet.

  1. Start SQL*Plus and log in as ‘sys’ to the database
  2. In SQL*Plus execute the following (ofcourse, use your own Oracle HOME path here):
    1. @D:\Oracle\ora81\javavm\install\rmjvm.sql
    2. @D:\Oracle\ora81\rdbms\admin\catalog.sql
    3. @D:\Oracle\ora81\rdbms\admin\catproc.sql
    4. @D:\Oracle\ora81\rdbms\admin\catexp.sql
    5. @D:\Oracle\ora81\rdbms\admin\utlrp.sql
  3. Stop and start your Oracle 8i database (I just used Oracle’s DBA Studio for this)

Rant / Conclusion:

Why does Oracle make me feel so…. ‘old-skool‘? Every Oracle-delivered tool to ‘administrate’ their database:

  1. Starts slowly, very slowly or just delivers a plain shell-like interface
  2. Their user interface tools do not conform to any User Interface Design guideline I have ever seen. Ever!
    1. I mean: I know it’s Java, I know it can look different and even more ugly if you really want it to. Though I have seen Java front-end applications that look and behave like you would expect them to.
    2. If you make a command-line interface, at least include some user-friendly support in it: Not being able to scroll back with the cursor (only with backspace), not being able to select text with the keyboard, not being able to get previously entered commands back… I mean, come on! It’s almost surprising you can copy and paste with this beast.
  3. Even TOAD, which seems to be the only ‘real’ alternative out there, while still being coded in Delphi by the way, is a commercial tool you have to pay for, if you want all the (so needed) features. That the license costs of Oracle do not even get you a normal DBA tool says enough for me. On a side note, though only user interface related: even TOAD makes me feel old-skool.

As the last line in this blog post, one positive comment:

At least Oracle knows how to make a fast database, if you configure and install it properly!


Preventing ‘Page 500’ errors with Drupal on www.mijndomein.nl

2009/09/08

This is a short post: http://www.mijndomein.nl is a cheap shared hosting provider. And as each shared hosting provider goes, they won’t allow specific settings in your .htaccess file. No problem, just that they won’t mention anywhere *what* they don’t allow. And the helpdesk is of no use in the middle of the night. So, here’s the solution:

  • In /.htaccess (so that’s in the root of your Drupal site) comment out the line that says ‘Options +FollowSymlinks’ (thanks to Ewout, below in the comments, for this correction)
  • in /sites/default/files/.htaccess do exactly the same.

Believe it or not, it works beautifully! See http://www.avalizas.com for the result 😉 Which is a shameless plug for the site of my sister and her husband, who just emigrated to Uruguay to start a new life there. Just look at the pictures on that site, that they actually made themselves. Isn’t internet great?

(PS: While I’m on the Drupal subject: May I recommend ‘Boost’ which saved an earlier project for me (http://www.civitas-advies.nl) ? It renders each page for an anonymous user as a ‘static’ page in it’s cache, making PHP-heavy pages being served to the visitor almost instantly!