Forum Bugs

Issue with very simple tables

mwiik
I have a need to create pdfs containing numerous simple tables in legacy html. All this legacy html has been made xhtml 1.0 strict compliant (via the W3 html validator) but isn't intended as great code (tables are used for layout). It seems PrinceXML is not rendering these tables correctly. What can I do to make this work? Please refer to the example page at http://messagenet.com/tableissue/simpletabletest.html . Any help would be appreciated, but recoding such tables is not a realistic option for us.

Thanks.
mikeday
The issue is that the tables are relying on HTML presentational attributes to control the styling, but Prince does not yet support all of these attributes. In particular, your example file uses the following attributes:

<table border="1" cellpadding="4" cellspacing="0" width="300">
<tr valign="top">

Prince 5.1 rev 5 which we just released today supports the HTML width and height attributes, but the other presentational attributes must still be specified using CSS properties, like this:

table {
    border-spacing: 0;          /* equiv. to cellspacing attribute */
}

td {
    vertical-align: top;        /* equiv. to valign attribute */
    border: solid black 1px;    /* equiv. to border attribute */
    padding: 4px;               /* equiv. to cellpadding attribute */
}

Alternatively, they can be placed directly in a style attribute on the element itself:

<td style="vertical-align: top; padding: 4px">

In future we hope to extend Prince to support more of the HTML presentational attributes, but in the meantime the CSS properties are the recommended option, and they should work fine in web browsers as well.
mwiik
Thanks for the response. I had figured some of this out when I looked at the default xhtml stylesheet included with Prince.

I added this to our own stylesheet:
tr[valign=top] > td { vertical-align: top; }
tr[valign=bottom] > td { vertical-align: bottom; }


which made the html 'tr' row-level attributes work for the cells. I imagine similar stuff will work for horizontal alignment:
tr[align=left] > td { text-align: left; }
tr[align=right] > td { text-align: right; }
tr[align=center] > td { text-align: center; }


Though I'm not sure how to pass attribute values from html attributes to css, I was hoping the new release's default xhtml stylesheet would reveal this technique. But I don't see anything relevant regarding width. Perhaps this is handled internally by the program and not by translation into css? I'm not sure how to do such translation, or if it is even possible in css.

Can I somehow 'pick up' the values for say, cellpadding, cellspacing, bgcolor, and border, similar to the way the values for alignment are 'picked up' by such as:
	tr[align=left]


I did find I could do:

	table[border] td { border: 1px solid black; border-collapse: separate; }
	table[cellpadding] td { padding: 4px; }


to assign some defaults and get the table borders I wanted, but don't know if it's possible to pick up the actual attribute values so I can create the css accordingly.

I hope my questions are clear, and again appreciate the response. As I said, recoding the tables is not a realistic option for us but getting close to what we want may suffice.
mikeday
Though I'm not sure how to pass attribute values from html attributes to css, I was hoping the new release's default xhtml stylesheet would reveal this technique. But I don't see anything relevant regarding width. Perhaps this is handled internally by the program and not by translation into css? I'm not sure how to do such translation, or if it is even possible in css.

In the future this will be possible using the attr() function, like this:
td { width: attr(width, px); }

which says to take the width attribute, interpret it as a pixel length and use it as the value of the width property. However, Prince does not support this general syntax for all properties yet; only specific properties such as the content property can use attr:
a::after { content: attr(href); } /* append link URL after link text */

This means that it is not possible to write a single style sheet that will support every possible cellpadding/cellspacing value, although it is possible to support a subset of values that you might commonly use, like this:
table[cellpadding="1"] > tr > td { padding: 1px }
table[cellpadding="2"] > tr > td { padding: 2px }
...

This looks a bit silly, but will work fine if you don't have that many values to support.

In a future release of Prince we will support the generalised attr() function, which will make it much easier to support the HTML presentational attributes and solve this issue. :)