Thursday, December 3, 2015

Declarative Index Proposal for Printing with CSS

This proposal is about formatting an index with HTML and CSS. It’s something you can’t do today in a standard, cross-implementation way.

The part you can’t do today is getting the lists of page numbers right. The same problem occurs in an index and in cross references. There are vendor extensions to do it, but they are not compatible, so it’s a good candidate for standardization.

A back of the book index looks like this:

Friday, December 26, 2014

Christmas 1976 (give or take a bit)

When I was seven , back in 1970, my father took a new placement as Vicar at the village of Haynes, in Bedfordshire. We went to look at the house in Winter; I was so cold that my mother put plastic bags over my socks, inside my shoes, to try and warm me up. I don’t remember whether it worked very well, but at any rate later that year we moved into the vast, crumbling old vicarage in Haynes Church End.

I hope Terry Stevens won’t mind me using his photograph of the vicarage and the church:

At holidays, and especially at Christmas, the family would descend. One year we had fifteen people to Christmas Lunch, most of them stayed for at least a week. We didn’t have enough bedrooms: there were people on sofas and couches, and others staying at nearby Hawnes School (later Clarendon School) or with Henry and Penrose Green or another neighbour.

That was the year the water in the toilets froze: the crumbling mansion had what I called “central heating” consisting of a total of three radiators for the entire house, placed in hallways as a sort of mockery of actual heating. My older brother Robert took away the cast iron Victorian fireplace from the front room to reveal the sixteenth century brick and stone fireplace behind it; at least after that we could have a roaring log fire in that room as well as the smaller coal fire in the living room. The fires did not, however, heat the whole house, and rubber hot water bottles were used at bedtime. Grandma made sure we knew about it the next morning when the pee in her chamber pot froze.

Christmas for so many people was tempting fate a little too much, and the ’fridge broke down. The repair man kindly came out to the vicarage—it turns out that a lot of people will go an extra mile to a vicarage, possibly as a sort of spiritual insurance plan—and told us that the problem was the ’fridge wouldn’t work when it was colder in the kitchen than the temperature to which we had set the ’fridge.  Which was fine except that it meant the freezer part of the ’fridge also didn’t work!

We also had a year when the turkey wouldn’t fit in the oven, and another when the oven actually went wrong; the village came to the rescue and on each occasion the turkey was roasted in the ovens at the village hall (or possibly the “mission hall”), a couple of miles away.

Another year there were power cuts, and we cooked the food on a gas camping stove in the kitchen. We hadn’t heard about carbon monoxide poisoning but I suspect the house was so drafty that we were perfectly safe. There were two-inch gaps between the two halves of the sash windows in places.

Mum hated cooking at the best of times; a lot of that came from an incident early on in my parents’ marriage: we’re shaped not only by genetics but also by experience. At the worst of times, cooking for fifteen adults and five under-fives, Mum never really complained, at least as long as everyone pitched in and helped. But in retrospect part of that was because she wanted everyone to be happy at Christmas, so she summoned extra strength.

The house was large enough that you could always get away from people; there would be a room with television and a room with people playing parlour games or sitting and reading or chatting. Of course, the rooms could be fairly full. When Grandma had to go to the toilet she made sure to make her way to the door slowly, leaning heavily on each person’s knees in turn as if she could hardly walk. The illusion didn’t last: when she got out of the room you could hear her footsteps speed up.

Christmas day also had a church service in the morning (distressingly close to the Christmas Eve midnight service the night before!), and, after lunch, the ritual opening of the obscenely large pile of presents under the artificial flame-resistant   tree. Yes, artificial, because, long before I was born, Robert came home with a candle they’d made at school and, dancing proudly, fell over. The village (St. Ippollits then, and no-one there can spell Saint Ippolytts either; even the street signs were all different) helped out with new presents and a replacement tree from the primary school, but ever after the tree had to be artificial.

No presents were opened until the dishes were all done and everything was clean and tidy. And afterwards was a walk.

People stayed for several days after Christmas, and lived off cold pheasant and turkey and after that turkey soup. We always had a brace of pheasant from the local farmer, Tom Davies at Home Farm, and we always loved them. They’d arrive a week to ten days before Christmas so they could hang, which improves the taste. Really, it does. Sometimes there was also a large box of brussel sprouts, always tasting best after the first frost. The Christmas Pudding would sometimes be one that had been given to us the year before by the Scotts from St. Ippolytts, as you’re supposed to let them age. One year we had a new one, but the person who steamed it didn’t realize you had to take it out of the plastic pot first. No problem, there was one from the previous year in the cupboard, and once the pressure cooker was cleaned of melted plastic it was all systems go.

Living here in Canada, in Eastern Ontario, it seems hard to remember that some years we hadn’t had the first frost by Christmas; other years the house froze up. The winters in England were mostly cold and damp, which is vastly more unpleasant than the Ontario cold and dry winters. But we had the coal and log fires and we had the church, and at night we could close the eighteenth century wooden shutters and the wartime blackout curtains and make it less spooky; at Christmas the house came alive. I slept in the attic, and after I went up the stairs each night I'd hear someone else coming behind me, maybe five or ten minutes later. It was the boards creaking.

So the house was always cold in the winter, but it was full of people at Christmas, and, being a vicarage, often full of people at other times too. I loved it there, even if I hated the cold. Of course, I wasn’t the one paying the food and heating bills!

Thursday, October 2, 2014

Some Myths About XML and RDF

It doesn't make sense to compare XML and RDF any more than it makes sense to compare poetry and paper, or a tax bill and a bottle of ink. But people do it.

XML here is like blank paper, a medium. It doesn’t give give meaning to the poem, and you could write the poem on something else, but that doesn’t diminish the usefulness and value of paper. Which brings me to the first myth, one I have heard often:

1. XML has no semantics, therefore XML cannot express RDF

This makes no sense if you think of XML as the paper, or as the electrical cable carrying a telephone conversation. Er, OK, if you’re young and use these new-fangled portable telephones, the radio waves carrying a telephone conversation.

But if it did make sense your RDF would lose all its meaning when you serialized your RDF graph as RDF/XML. When you send that XML to someone else and they reconstitute an RDF graph, they say there’s meaning in that RDF graph. How was the meaning transmittted if XML cannot store meaning?  I call this the XML Phlogiston argument.

2. XML is about trees and cannot represent graphs.

One RDF advocate accused me of not knowing what a graph was when I said this was not the case, but the existence of RDF/XML, and for that matter GraphML, proves otherwise. XML can store graphs just fine.

3. RDF lets you concatenate graphs to combine them but XML cannot do this.

This is a more subtle myth. First, you can’t concatenate two RDF/XML documents as-is, because the result would not be well-formed XML. But you can use a simple XQuery expression such as
    <rdf xmlns:ref="
>{ doc('a.xml')/*/*, doc('b.xml')/*/* }</rdf>
to return a single combined document.

The hard part is called schema mapping or ontology matching - if one document uses vehicle, automotive, four-wheeled, short, sports-car, and another uses car, green, you can’t assume all green cars are sports cars, and no automatic combination of the graphs is possible, regardless of whether you use n3 or turtle or sparql or strawberry jam,and it’s as true in JSON and XML as in RDF.

4. XML Failed

I’ve heard this one even from colleagues, some of who believed the goal of XML was to replace HTML. That wasn’t our goal at all, and XML is doing very nicely in its original intended use of technical documentation, thank you. So this isn’t really about RDF and XML except that I sometimes hear it in that context.

Are there other RDF and XML myths?

[update: yes, no. 2 should have read, and now does read, graphs, thank you to those who pointed it out.]

Sunday, August 17, 2014

Back-of-the-book Indexes and CSS

An index in the context of printed books is a list of topics with associated page numbers, usually printed at or near the end of the book.

The plural is indexes, unlike the mathematical indices, which are different beasts that happen to share the same singular form, index.

To make an index for a digital document, you:
  1. Mark the targets, the topics, in the main book itself;
  2. Extract the list of topics, or index headings as they are called, and sort them;
  3. For each topic, collect the list of appropriate page numbers;
  4. Collapse runs of adjacent page numbers into ranges.
All of this can easily be done declaratively. There are some minor complications to resolve, but they are not too hard:
  1. Sorting multilingual headings, symbols, and other items;
  2. Multi-level indexes;
  3. Mixtures of references of differing types;
  4. References to footnotes;
  5. Balanced column formatting.


Books might well have multiple scripts in use, such as Latin for English and Spanish and Devanagari for Hindi. It may be necessary to use different collations for different parts of the index, for example to get an index of Spanish names to sort names starting with Ch properly without affecting the index of French names on the next page. It may be appropriate to provide a sort key for an individual index heading to get it to go where you (as author) want it.

Even a moderate sized book can have hundreds or thousands of index entries, so sorting them obviously should be done automatically.  However, it is possible to do that outside of CSS, for example with JavaScript or XSLT, before formatting. A minimal proposal for supporting indexes in CSS therefore does not need to address sorting the index.

Multi-level indexes

It’s not uncommon to see sub-topics collated together in an index:
    Socks, black, 28, 73; argyle, 24-56, 72; white: 24

This is done partly to save space in the index, partly to make using the index more efficient (everything to do with socks is in one place, instead of under A for argyle,, B for black and so forth) and partly to avoid ugly and potentially confusing repetition of the main head (socks) for each sub-entry.

The consequence for software is just that you need a multi-level sort.

As with sorting the index itself, collation and sorting of sub-entries can  be done before formatting the document and doesn’t need to be specified with CSS. We only need to bother ourselves about the page numbers, which must of course be supplied by the formatter.

Mixtures of references of differing types

It’s common to indicate in an index more than just the page number but also what the reader might find there: a discussion, a definition of a term, a figure, a table, a mention in passing. Note that the actual index heading might not appear in the text; a discussion of argyle socks might not mention the word “sock” but only talk about the pattern, or perhaps use the word “stocking;” this is part of why a well-crafted index can be more valuable than automated searching for some applications.

The usual ways to distinguish the different types of reference are to use bold page numbers for definitions, italic for figures, and perhaps to prefix the page number with a symbol such as an asterisk (*) or dagger (†) for a table.

This means that if you have a figure that occurs in the middle of a discussion it’ll be listed separately:
    Socks, argyle, 24-28, 26, 72

References to footnotes and other page areas

A reference to a footnote usually has an annotation such as 46 note 1 so that the reader has warning both of where to look on the page and that the reference might not be part of the main discussion. If there are references to multiple footnotes on the same page they could be listed,
    Socks, argyle, 24-28, 26, 72 note 1, note 3.

Other areas that might have specific annotations in an index include sidebars, examples, tables, side-notes (marginalia) and other secondary content. Books with large, dense pages such as the Encyclopædia Britannica might divide the page into areas and have a reference like 46C to mean the bottom left quadrant of page 46 but these are specialized books, often produced with highly customized software.

Balanced Column Formatting

I’ll mention this for completeness, because the index-specific processing is all about the references. Indexes are usually printed in relatively narrow columns, three or more to a page. On the last page of the index the columns will probably all be balanced so they are the same height (give or take one or two lines in the last column).

It can be important with the back matter in a book to remember that the book must usually be a multiple of 16, 32 or 64 pages to be printed economically by folding large sheets of paper. So if you end up with two lines of index on the last page you’ll want to set a shorter page if that avoids having 63 blank pages after it!

Formatting with CSS

CSS doesn’t yet support index generation, but XSL-FO extended CSS 2.1 to add properties for indexes, and this was implemented and today is widely used in production. So maybe we can do something similar.

You can also refer to the XSL-FO 2.0 draft for a much more detailed explanation that I am going to give; we don’t need as much because CSS already has ways to do most of what we need. I think there may also be a mistake in the summary of generated page numbers as page 14 doesn’t appear anywhere; if so, sorry.

Let’s suppose for now that we have an HTML (or XHTML) document containing a sorted index ready to format. it might have markup like this, to generate
    Socks, argyle, 24-28, 26, 72

<li class="index-entry">
    <span class="head">Socks</span>
    <span class="subhead">argyle</span>
    <a href="#ie41" class="ie"></a>

    <a href="#ie42" class="ie"></a>
    <a href="#ie46" class="ie"></a>
    <a href="#ie50" class="ie"></a>
    <a href="#fig17" class="ie figure-ref"></a>
    <a href="#ie51" class="ie"></a>
    <a href="#ie52" class="ie"></a>
    <a href="#ie53" class="ie"></a>
    <a href="#ie141" class="ie"></a>
    <a href="#ie142" class="ie"></a>

We don’t know the page numbers in advance so we can’t put them there. They’ll be supplied by the content property.

Suppose when the document is formatted the targets referred to end up being on pages 24, 24, 25, 26, 26, 26 (the figure), 26, 27, 28, 72 and 72.

The formatter will need to process this list:
  1. separate out the figure reference
  2. collapse duplicate numbers in the list
  3. collapse ranges into a start and end with a separator
  4. merge the separate streams (here, references to text and to figures) by sorting on the first number in each range.
A complication is that the page number used for sorting will presumably be the page built-in variable, but the value printed will be as it might appear on the page running header or footer, so that an introduction page might get roman numerals (Socks, white: xxiii) and an appendix might get a preceding letter, known as a folio prefix, such as B for Appendix B (Socks, internet proxy: B-42). This is the same as for general cross-references within a book, of course.

When eliminating duplicates, the value of the index-merge property determines whether a sequence of three or more consecutive page numbers are merged together to form a range, or if they are kept separate.

A second complication is that if there were ranges in the example instead of just individual references, the formatter would typically expand the ranges into a list of individual pages first (in practice this will be a short list) between steps one and two in the process, because that simplifies the process of eliminating duplicates.

In addition, items with different index-class values are normally kept separate, but a property index-merge-differing-classes can be set so that the figure reference in the example would vanish, as it’s contained with the 24-28 page range.

After handling page ranges the index entries are formatted normally, with the content property and :before and :after being available to support the various page number formats, and to allow marking index entries to colour plates (say) in [square brackets], just as for a normal cross-reference. However, the number of “a” elements/nodes may in general  be fewer than in the original document before index processing. It can never be more: references within a range that were expanded to simplify processing in an implementation do not result in new elements being created.

Issue: should the transformation from original list to sorted, merged list use the shadow DOM?

Issue: how best to supply the comma, en dash or “ and ” between entries? XSL-FO just inserts a text node with no standard way to change the en dash or comma and space.

Properties (proposed)

index-class: a user-defined “ASCII-lower-case” string; entries with different index class values do not by default get merged together, so that you can keep figure references even when they fall within a range of text pages, of keep a definition even if it, too, falls within, say, a range of figures.

index-item (none, begin, end, span, point): set this on the “a” element. It does not inherit. “span” means that all of the pages generated by the target element are added to the index; otherwise the page on which the element starts is used. The begin and end values are used in pairs to mark index ranges and point is used for a stand-alone page reference. None turns off index processing on the given element.

index-list: Use index-list for the containing element to indicate that its children are to be processed as index citations; this would be used on the “p” element in the sample markup above. Values are none (don’t do index processing), no-merge, same-index-class, all). A value of same-index-class means page ranges are merged only when they have the same associated index-class value. A value of  between-classes means index-class values are ignored for the purpose of merging. A value of no-merge enables index processing but not merging of adjacent pages into a range. In all cases page numbers that are explicitly marked as being a range using index-item begin and end are kept as a range.

Issue: is this enough? I’ve proposed merging XSL-FO merge-pages-across-index-key-references and merge-ranges-across-index-key-references into the values of index-list but I have lost the ability to merge between index classes and not within a class; I think that combination never made sense. The page-number-prefix and suffix can be done with before/after.

Other items

Indexes might contain cross-references such as “Stockings: see under socks” which do not need special formatting. One might make the text be a link, of course.

Column balancing is outside the scope of index processing.

Formatters are not expected to support index entries that point back into the index itself.

If you reset the global page counter, the index facility proposed here will give you strange results.


Monday, August 11, 2014

Some typographic history

I recently encountered “Bablestone”, a blog with some carefully researched articles about typographic history. Rules for the long s (the ſ symbol, if you have it in a font) was the first one I read, but the site is worth exploring. Probably it would have been better to have talked about Conventions rather than Rules.

mentalfloss has a less scholarly and rather more popularist article that introduces the long s and several old letters Latin scribal abbreviations, although it’s probably worth reminding readers that æ and œ at least are still in use in British English, although less widely than thirty years ago.

Saturday, May 17, 2014

Drop Caps: Other Writing Systems, Other Styles

In this entry I’ll start with some more Latin script examples in order to illustrate some principles, and then discuss some variants for other writing systems. This entry is very incomplete and needs a lot more research; I'm publishing it so people can help.

First, a cameo initial; that is, where the letter has a solid background:

The picture shows an SGML viewer I wrote a long time ago, displaying part of Thomas More’s Natural History. The initial is white on a dark reddish rectangular background and because the background is such a strong design element it is that background that aligns with the cap height and with the baseline, not the actual capital “I” inside it. If you are working with a font for decorative initials this is what will happen automatically. This example aligns with the small caps height, by the way; that would work if the entire first line, or at least the first two words had been set in small caps, but with just the “T” in “IT” in small caps the result is  somewhat unsatisfactory.

I am showing this example now because it gives a way of making your own decorative initial: you can draw a rectangle and put any letter inside it, and as long as the letter is well within the rectangle and as long as there is strong contrast you can get away with it. Note that you cannot do this with an img element and float, in general, as you don’t know what font size the user will have for the text and hence you don’t know how big to make your rectangle. With css calc() you could maybe say it is 2LH + 1CH, where CH is the cap height of the current font, but I don’t know as we have that unit yet, and LH (line height) is probably also not supported.

Next an example to show the idea of treating a “glyph” from a font as an image and then running the text around it:
This “A” is from an article by Allan Haley in U&lc Type Selection (London, 1992). It’s hard to see that the top of the A aligns with the cap height in the first line as there are no caps; the feet sit happily on the sixth baseline from the top, and the serif at bottom left protrudes a little further into the margin than would be normal, in order to make an effect. But the most important thing here is that the text abuts the edge of the A as closely as possible.

This is not the usual way to do a drop cap, partly because it wasn’t possible with earlier typesetting systems: with metal type and woodcut or metal initials this level of kerning involved filing (or kerfing) not only the initial but also the individial sorts, or pieces of type, for the first character on each line, and doing that with an apostrophe would be awfully hard. With film photosetters all the way to early laser printers the glyph outline shapes were not available to the renderer - only the character widths.

Today its possible to do this sort of work automatically, but the way to do it in CSS would probably be to be able to derive an image from a font glyph, and then use a runaround. The alignment points of the image would have to be set just as for a regular bitmap or SVG image used as a drop cap.

Let’s look at some more Western examples before moving on; I’ll use examples from the same article.

The raised initial “r” here is thoroughly modern and very conscious: people reading the text will notice that letter. It’s again treated as an image, so that the text can be run up next to the letter. One more of these, showing a different alignment point. I think this does not need to be in scope for CSS, because you would probably have to set the whole paragraph so carefully that you would end up using SVG, or an image.
Notice the top bar of the “f” lining up with the heading to the left as well as to the x-height on the first line of text. This is not really a drop cap or initial letter at all.

You can see the rest of that article at starting at page 18. There are quite a few more examples.

Now that we have seen some more complex Western examples, let’s consider other writing systems, starting with Arabic.  The initial capital does not work well with traditional Arabic calligraphy, because the individual letters are joined together and you can’t join a large thick letter to a small thin one without something looking really odd. The examples I have seen are mostly modern. Some use a modern sans-serif Arabic font, and it seems one approach is to draw the first letter large in a square, rather as I did with the cameo initial at the start of this blog entry, and to continue with a joiner such as “ـ” and the rest of the word small. If the square (whether cameo/reversed or not) is not used, the sane serif font seems to work best. A couple of examples (with kind thanks to Roozbeh Pournader and Shervin Afshar) can be found here and here. Typesetters and designers are still experimenting with alignment and positioning and style, as the initial cap seems relatively new. A larger initial word also occurs in Arabic, and in the examples I have seen so far is simply raised, like the raised initial “r” above.

The Arabic tradition of text as playful calligraphy suggests techniques like the “f” above will be common, and indeed they are common in calligraphy: I have seen a great many examples from Iran and Iraq especially. But they are not so common in typeset work, possibly because it quickly becomes too difficult. There are a couple of artistic calligraphic examples here and here by ibrahim abu touq of Jordan, or here is one by Malik Anas Al-Rajab in Iraq. You can’t do anything that wild with OpenType (although there are some sophisticated attempts) and the boundary between typography and calligraphy is fluid in the Arabic world, but the typography is only slowly starting to catch up with the calligraphy. The engines simply couldn’t take it.

See also this Google Group discussion.

For Chinese and Japanese I have seen examples with the first ideogram, or the first few characters, set in a box with a line round it, rather like some of the Arabic script examples. In this case, the box aligns with the character grid used for the text. However, it seems uncommon. A copy of GQ Magazine from Japan has nothing like a drop cap anywhere that I can see. I’d love to know more. The examples I have seen of a two-line drop cap in Japanese may just be a function of someone using InDesign or Microsoft Word (or JustSystems?) which supports the feature in some way. What about Korean? Mongolian?

For Indic languages such as Hindi (using the Devanagari writing system) the principal seems to be so use the top and bottom extent of the letter, just like an “A" in the simpler Latin script styles. Devanagari is interesting because the nominal baseline is actually not at the bottom of the characters, and the writing system does not really have the same alignment points as the Latin and Greek scripts. As with Hebrew (see below) it’s not just a single character that is made larger. For Hindi it’s generally a syllable, so that in स्थिति its the स्थि that is enlarged. I do not have information about alignment: does the result share a common “clothes line” baseline?

I do not yet have information on Indic scripts other than Devanagari (the example here came from Richard Ishida of W3C) but I have seen printed samples in other scripts. I had hoped that the W3C Indic language Requirements Document would clarify this, but the document didn’t really get far enough yet.

For languages like Slavonic and Vietnamese using Latin characters with lots of diacritical marks you end up having to decide what to do with accents. Accents, or diacritical marks, are entirely ignored when sizing and positioning an initial cap, but are taken into account when you have to avoid other things (such as text above or below) bumping into the letter. In practice this means that extra marks below a letter will probably cause an extra line of two of the main text to be indented, but the baseline of the main character aligns with the baseline of the nth line of text, and the cap height of the main character aligns with the cap height of the main text on the first line, even if that pushes accents up above the start of the text. This means that a 5-line drop cap (say) will use the same font size for the initial throughout a publication (assuming the body font and line spacing are the same), regardless of accents, and that’s what you want, following the graphic design principles of Similarity and Repetition.

This leads me round to Hebrew, where the entire first word of a paragraph is sometimes set larger making a “drop word.” Again I do not have information on alignment, especially of cantillation marks (John Hudson maybe?)

Cyrillic drop caps seem to work the same as Latin ones.

In almost all the cases I have seen the basic principle is the same: you line up the base character (or syllable or word) with the top of the base characters on the first line and the baseline, or bottom of the base characters (e.g. for Devanagari) on the bottom. For vertical scripts top and bottom are obviously rotated appropriately.

Wednesday, May 14, 2014

Using images as initial drop caps

Decorative initials are often sold as images, whether bitmap or vector, and whether as a set (such as one for each letter from A through Z to Æ) or singly. It’s common for alphabets to be incomplete, partly because J and W came relatively recently to our alphabet and partly because you often only get letters that occurred at the start of a chapter in the book for which they were designed.

Images lack some important information that is available for glyphs in a font. Fonts have information about where the baseline is to be found, and sometimes also the x-height and cap-height, and the character advance which is generally different from the bounding box. Images only have the bounding box: the size of the image. But we need that other information in order to position a drop cap correctly.

I’ll use an example from the GNU/Linux™ programmers’ manual to illustrate what I mean. Here, the blue and red “L” is a single image (a JPEG image in this case, from my own Web site at of course).

To make clearer exactly what’s going on I drew some lines:

Here, the image actually goes from just inside the left edge to line B; I darkened the image slightly so you could see the rectangle. Vertically it goes from line 1 at the top down to line 4 at the bottom. The image is positioned so that the top of the red “L” lines up exactly with the top of the first line of capital letters (line 2). The baseline of the “L” is harder to see, but lines up exactly with the baseline of the fourth line of text, (the line marked 3).

Because the first word is LSEEK, the rest of the first line (SEEK) is set close against the L. The remaining lines are flush against the edge of the image (line B) in this example. I’m not yet ready to describe non-rectangular images.

To get this right, we need to know the distance from line 1 to line 2, so that we can float the image backwards in the text until the top of the “L” lines up (I am assuming the reference to the image occurs just before the SEEK, in that paragraph, and not earlier in the page). We also need to know the position of line 3 so we can align the baseline to the text. In general, if you can't align everything, aligning the baselines is most important, although in this particular case you could reasonably argue that the curvy flourish of the “L” gives extra freedom. Don’t succumb to temptation: do it right.

There are actually three ways to set this initial and get everything aligned.

  1. Choose the size of the main body text and the line spacing so that you get an even number of lines (see below for the actual calculation);
  2. Scale the image so that it fits—this would work best for an SVG image rather than the JPEG that I have;
  3. Allow the image to rise above the start of the paragraph (least desirable but easiest to do).
The formula for the text size is that you want three times the full baseline-to-baseline distance plus the cap height of the text font to equal the height of the letter (not the height of the whole image, of course, which is almost never the same thing). Since in CSS you can never be certain which fonts will be used to display a document for any given user and browser/user agent, you cannot get this formula right for the Web. You can get it right for print, if you are printing your own document, of course.

Another difficulty is that CSS does not currently have a way to force lines to have their baselines glued to an invisible grid that’s a multiple of a line height (or a multiple of 0.5LH units, or ⅓rd for some designs). So the superscripted “e” on the first line may mess everything up.

The imaginative reader will also be wondering what should happen when the paragraph with the decorative initial should fall at the start of a page instead of the middle, so that there is no room for the blue flourishes above it. it would be nice to be able to supply alternate images for that case, but I am going to ignore it here, because it would be a separate mechanism entirely.

Scaling the image to fit also requires the same formula, but now instead of the cap height and line spacing being variable we have the image height being variable and the other quantities fixed.

As with drop caps made from fonts, it is always visible baselines that align, not invisible CSS line boxes. But with images, we need a way to mark the baseline, the indent (which we probably already have with text-indent) and the topmost (cap-height) alignment point, and to give a kern amount for the first line in the event that the letter forms art of a word.