Forum Samples, Tips and Tricks

XHTML Ruby in Prince

Lynx
One can render XHTML Ruby annotations in Prince using the following CSS (it can be added to default XHTML style sheet located in /engine/style directory)
	ruby
		{display:inline-table;}
	ruby > rt, rtc
		{display:table-caption;
		text-align:center;}
	ruby > rb, rbc, ruby > rt + rt, rtc + rtc
		{display:table-row;}
	rb, rbc, rt, rtc
		{white-space:nowrap;}
	ruby > rt, rtc
		{font-size:0.5em;
		line-height:1.2em;}
	rp
		{display:none;}

Inline tables can not fully replace ruby (especially complex one) but they provide good approximation that in many cases is quite sufficient. Here is XHTML example and PDF output produced by Prince.

Edit: updated broken links

Edited by Lynx

mikeday
That is really very clever! :D

I never guessed it would be possible to implement XHTML ruby so well with only inline tables; I especially like the trick with using the table-caption to move the second row to the top.

(One side effect of your neat hack is that it reduces the pressure for us to implement CSS ruby! I wonder what other things you can implement directly in the default style sheet in this way...)

Cheers,

Michael
Lynx
Since you like it, one can go further and improve support for complex ruby as follows:
	ruby
		{display:inline-table;
		text-align:center;}
	ruby > rt, rtc
		{display:table-caption;}
	ruby > rb, rbc, ruby > rt + rt, rtc + rtc
		{display:table-row;}
	rb, rbc, rt, rtc
		{white-space:nowrap;}
	rtc + rtc > rt, rbc > rb
		{display:table-cell;}
	rtc + rtc > rt[rbspan]
		{column-span:attr(rbspan);}
	ruby > rt, rtc
		{font-size:0.5em;
		line-height:1.2em;}
	rp
		{display:none;}

This improves horisontal alignment of ruby text placed under the base. Unfortunately this implementation does not handle text placed above the base as perfectly (due to display:table-caption used to format it). Here is XHTML example and PDF output.

To settle issue with complex annotations placed above the base one can write alternative implementation that handles horisontal alignment of ruby text better. Note however that if in previous two style sheets vertical alignment of ruby base was bullet proof regardless its content, this implementation assumes that ruby carries only simple content (no other complex layouts nested inside):
	ruby
		{display:inline-table;
		text-align:center;
		border-collapse:collapse;
		/* border collapse mechanism 
		will be used to adjust vertical alignment */
		vertical-align:middle;
		/* if ruby text contains text only 
		and there are two ruby annotations 
		(one placed above the base and one below) 
		then vertical centering roughly aligns baseline of 
		base 	with baseline of parent */
		border-bottom:solid 0.75em transparent; 
		/* o.75em is height of ruby text (0.5×1.2em = 0.6em) 
		plus space between baseline and text-bottom (about 0.15em)
		this extra border is counter-weight used 
		to restore vertical centering broken 
		by presence of ruby text 
		(in case if there is only one ruby annotation, 
		if there are two annotations 
		then counter-weight is no longer 
		necessary and can be annihilated 
		using border collapse mechanism) */}
	ruby > rt, rtc
		{display:table-header-group;}
		/* used to move first ruby 
		container above the base */
	ruby > rb, rbc, ruby > rt + rt, rtc + rtc
		{display:table-row;}
		/* base and second ruby 
		are formatted as table-rows */
	ruby > rt + rt, rtc + rtc
		{border-bottom:hidden;} 
		/* if there are two annotations then extra 
		border is no longer 	necessary 
		and can be annihilated 
		using border collapse mechanism  */
	rb, rbc, rt, rtc
		{white-space:nowrap;}
		/* prohibits line breaks inside ruby text  */
	rtc > rt, rbc > rb
		{display:table-cell;}
		/* used to distribute annotations 
		in table like manner */
	rtc > rt[rbspan]
		{column-span:attr(rbspan);}
		/* ruby text may span several cells */
	ruby > rt, rtc
		{font-size:0.5em;
		line-height:1.2em;}
		/* font-size of ruby text is reduced */
	rp
		{display:none;}
		/* fallback markup is no longer necessary */


Here is XHTML example of complex ruby and PDF output.
carl johnson
I’m trying to use this CSS to let me mark up some Chinese text with pinyin ruby, but for some reason my characters end up getting incredibly spaced out, even with text-align set to right or if I set the width of the ruby to 0. Any ideas why?
mikeday
Can you paste a simple example of your markup?
carl johnson
I think the problem might be with marking individual characters. If I mark a couple of them, it works out OK.

Maybe there’s a minimum width for a ruby item for some reason? Or maybe my massive CSS file is junking up somewhere.

Edited by carl johnson

mikeday
Very obscure. Turns out that text-indent is an inherited property, so it is being inherited by the <ruby> inline table and its children. As a result, every cell gets left padding! (You can see the effect by adding a border to the ruby elements). Because the first example only has one ruby element, it only gets one text indent, and doesn't look spaced out. The solution:
ruby { text-indent: 0 }
carl johnson
Thanks Mike!
Lynx
In Prince 7.1 it is much easier to format complex Ruby. Below is updated stylesheet that takes advantage of recenly implemented table-baseline property (thanks to Mike and Xuehong!). It should be able to handle arbitrary complex XHTML Ruby.

ruby 
	{display:inline-table;
	text-align:center;
	white-space:nowrap;
	text-indent:0;
	table-baseline:2;}
ruby > rb, rbc, rtc
	{display:table-row;} 
ruby > rt, rbc + rtc
	{display:table-header-group;}
rbc > rb, rtc > rt
	{display:table-cell;
	padding:1px;}
rt
	{font-size:0.5em;
	line-height:1.2em;} 
rp 
	{display:none;}
rt[rbspan]
	{table-column-span:attr(rbspan)}


Here is XHTML example and PDF output produced by Prince 7.1 (updated links in first post too, since they were broken).