Thread: Lettered lists
View Single Post
Old 06-18-2011, 03:32 PM   #20
Christopher Wood
Christopher Wood began at the beginning.
Christopher Wood's Avatar
Posts: 28
Karma: 10
Join Date: May 2011
Device: Kindle 3
source code & theory

Theory behind the source code:

A boiled-down overview of the challenge:
There's nothing similar to a CSS's position:relative in Mobi; there's only positive or negative "width," which becomes (positive) all-paragraph block indent or (negative) block indent with first-line outdent that goes all the way back to the left edge, always, period. For an outdent used as a numbered list or hanging asterisks such as footnotes, we're left with the problem of making the first character of the following text line up with the following lines, and also of positioning the list-numbering or the footnote asterisk to the left of the block. The reader (human operator of the ereader hardware) can change font size at will, and the only thing we can have in that outdented space is characters (HTML has rarely known "tabs," and never well), so the problem becomes how to match the total width of the first line's outdented characters with the block indent (the negative "width") of the following lines; and we must achieve a solution that allows us to use any characters we want in that space, and still know their width: we might want * or ** or iv. or who-knows-what. And before you say, "just use a table!" note that the Kindle won't pagebreak in a table cell, so if you have a long list element or footnote, it'll render off the bottom edge of the screen, unreadable no matter what you do.

My solution is multifold.

First, to guarantee that we know the width of the outdented characters, we (a) use a <CODE> tag to force the text into a monospace font, and then a <FONT SIZE="-99"> tag to force the ereader hardware (this is for Kindle 3, remember) to use its smallest font size, no matter what size the (human) reader has set his Kindle for. (You'd think, because the Kindle only has 8 font sizes, that SIZE="-7" would be enough; but -7 and even -9 both embiggen when the Kindle is set for very large type; so, if I must go beyond the single digit of -9, I'll go all the way to -99, which works.) These smallest characters, I call "tmc" for "tiny monospace characters."

Next, having made careful measurements and determined that a tmc is 11points wide at all times, no matter what font size or face the Kindle is set for, we set the paragraph's (negative) width to some multiple of 11: say, <p width="-66pt">, which outdents the first line by 6tmc. (Using ems results in variable indent widths depending on Kindle font size settings, but pts is a fixed unit.)

Lastly, we add the appropriate number of tmcs to the beginning of the outdents paragraph. Call that number, X (here, 6). The last tmc will be a &nbsp;, so that our outdented text doesn't crash into the first character of the block. That leaves X-1 tmcs to fill (here, 5). Some of those will be our outdented text -- say, iv. or some such object -- from the X-1 we subtract that number of tmcs (here, 3), leaving some number (here, 2) to fill in with more &nbsp; characters. And we must use &nbsp;, because, despite the <CODE> tag, multiple plain spaces don't render, as we might expect with HTML's <pre>. Go figure.

We end up with a left-indented block of text, rendered in whatever font face & size the Kindle is set for, with some outdented text, consistently right-aligned, albeit rendered in the Kindle's smallest size, in its monospace font.

Not a perfect solution -- rather old-school -- but it's all text, no tables, no images (III.jpg hahaha), fully reflowable and resizable (except the outdented text). Until Mobi better supports <OL> types and values, and/or tables, this is all I've got. At least it works!

Source code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http: //">
<html lang="EN-US">
<meta http-equiv="Content-Type" content="text/html">
<title>Acid Test 213x</title>
<p width="0">A Roman-numeral list. Try it at any font size or face. All numerals should remain right-aligned, all lists elements left-aligned.
<p width="0">&emsp;This is a <i>Kindle3-specific effort</i>. It is not intended as a universal Mobi solution because the diverse Mobi readers render formatting so differently from device to device.</p>
	<p width="-66"><font size="-99"><code>&nbsp;&nbsp;&nbsp;I.&nbsp;</code></font>This is the first list element.</p> 
	<p width="-66"><font size="-99"><code>&nbsp;&nbsp;II.&nbsp;</code></font>This is the second list element. This one is very long to cause line wrap. Lorem ipsum, lorem ipsum, lorem ipsum, lorem ipsum!</p> 
	<p width="-66"><font size="-99"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code></font>&emsp;This second element has a second paragraph, of which the first line is indented. Lorem ipsum!</p> 
	<p width="-66"><font size="-99"><code>&nbsp;III.&nbsp;</code></font>This is the third list element.</p> 
	<p width="-110"><font size="-99"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.&nbsp;</code></font>This is the third list element's first subpoint.</p> 
	<p width="-110"><font size="-99"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.&nbsp;</code></font>This is the third list element's second subpoint.</p> 
	<p width="-154"><font size="-99"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i.&nbsp;</code></font>This is the nitty gritty stuff! a third level.</p> 
	<p width="-154"><font size="-99"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ii.&nbsp;</code></font>More nitty gritty. Who reads it? Same people who read the fine print on contracts.</p> 
	<p width="-154"><font size="-99"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code></font>&emsp;This is a second paragraph of the nitty gritty, with a first-line indent.</p> 
	<p width="-110"><font size="-99"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.&nbsp;</code></font>I've had enough of this now.</p> 
<p width="0">&emsp;The above multi-level list should format well at any font size or face. All numerals should remain right-aligned, all lists elements left-aligned.
Christopher Wood is offline   Reply With Quote