1. | New element on right hand page |
> 2. I need chapters and some elements of the front matter to start on a > right hand page. I am currently attempting to apply the break-before > ="odd-page" attribute to the fo:block element corresponding to the element > that needs to start on the right page but it is not working - all I get is > a standard page break. Am I doing something wrong or is there another way > to achieve this? An alternative solution would be to put chapters in separate page sequences and control the length of the preceding page sequence: <fo:page-sequence force-page-count="end-on-even">.... This eventually adds a blank page so that the last page in the sequence is always even-numbered. (That's how it is done in the PDF for XSL CR). | |
2. | Vertical positioning of page contents in XSL FO |
To vertically align at the bottom, you need to set the display-align property on the fo:region-body formatting object to 'after'. That aligns the content of the page to the bottom of the page, but if the page can be filled up, then it will be completely filled up, so I'm not sure that's what you want to do. Instead, I think you want to set the margin-top of the fo:region-body in the fo:simple-page-master used for the first page of the chapter to 33% or 50%, so that the region in which the content can be placed only starts a third or half way down the page in the first place. Obviously that means having different fo:simple-page-masters for different pages, so you need to use a fo:page-sequence-master to control it. | |
3. | right to left writing mode |
Look at the Writing Mode properties at The rec Cyrilo rognon adds First answer : You can use the reference-orientation property if your fo processor supports it. Second answer : What are you trying to do ? do you want the whole document to be re-oriented or just some part of it ? ref orientation may be applied to region, so it does a good job if you want start region with a verticaly aligned text. If the whole document is targeted (an entire page I mean), you could use the page size setting to simulate the reference-orientation property, since it is not very well supported by now. | |
4. | Vertical centred text. |
The following works for me in Antenna House where the first page sequence centres text in a two-inch high box and the second page sequence centres the text on the page: <page-sequence master-reference="frame-pages"> <flow flow-name="frame-body"> <block-container border-style="solid" height="2in" display-align="center"> <block text-align="center">Centred text</block> </block-container> </flow> </page-sequence> <page-sequence master-reference="frame-pages"> <flow flow-name="frame-body"> <block-container border-style="solid" height="100%" display-align="center"> <block text-align="center">Centred text</block> </block-container> </flow> </page-sequence> Of course the border is optional, but it helps me see what is going on. | |
5. | Text align vs text-align-last |
This is not a question of priorities or precedences. text-align does not apply to the last line of a paragraph; if text-align-last is not set, it is the same as text-align unless text-align is justify; in which case text-align-last is start. The Recommendation is unambigious:
Values have the following meanings: relative If text-align is justify, then the alignment of the last line, and of any line ending in U+000A, will be start. If text-align is not justify, text-align-last will use the value of text-align. Ken adds >The question: which alignation should be used for the 1-line blocks if text-align-last= only applies to the last line in a block and a 1-line block is considered the last line for justification (note that it is also considered the first line for other things like text-indent=, <initial-property-set>, etc.).
Think about paragraph printing in a newspaper or in a novel: You read a long 7-line paragraph and the first 6-lines are justified side-to-side, the last line is not justified and just ends in the middle of the line. The next paragraph is short at, say, only 5 words ... would you expect those words to be justified from side to side? Nope! You would expect it to be short, just like the last line of a multiple line block. The nuance about this issue is the use of justify ... if you use anything other than justify, say "center" or "end", it applies to all lines of the block. But if you use "justify" it *doesn't* apply to the last line of the block, for the reasons described above. If you wanted the entire block to be justified side to side (and you *do* when doing entries in tables of content that have leaders on the last line) you have to specify *both* text-align= and text-align-last=. | |
6. | Is there a way to introduce soft line breaks into XSL:FO output? |
Soft linebreaks are called zero-width space in Unicode, 200B hexadecimal. Insert &\x200B; during preprocessing at points where you want the URL to be broken, turn hyphenation off for that part of the text and don't use an FO processor that breaks line when it is not asked to. | |
7. | White space problems? |
There are four parameters to play with, not just one ... there is also a shorthand that sets all four parameters: - the shorthand: white-space="pre" If you use a monospaced font and the shorthand or the explicit properties you will get the effect usually desired for program code listings in reports, which is what I think you are asking for. | |
8. | left to right and right to left, perhaps for Arabic or Hebrew? |
XSLFO supports Unicode BIDI. Check out the BIDI properties of the arrow, if it's mirrored, it will flip automatically in a rl writing mode context. I suspect it isn't mirrored though. The properties can be found here | |
9. | Capitalize first letter |
If you need it in the presentation form, then it can be done by text-transform="capitalize" in XSL 1.0 (XSL FO). I think text-transform: capitalize is present in CSS too. This will not create capitalized text, but rather will represent the text as capitalized. Use XSLT to select the first letter, (substring function) then use the text-transform property. | |
10. | Vertical alignment of fo:inlines |
Take a look at "7.13.2. alignment-baseline" chapter in the XSL-FO specification. The value "central" or "middle" is might be what you are looking for. | |
11. | Preserve all spaces |
To make the text appear just as it is in the xml file do the following. <fo:block white-space-treatment="preserve" linefeed-treatment="preserve" whitespace-collapse="false" font-family="monospace"> <!-- YOUR CODE HERE --> <fo:block> | |
12. | Handling white space, of varying size! |
Indeed. You can use Unicode characters to specify these fine tuned spacing and add following XSLT code into transformation to get proper spacing in output. <xsl:template match="text()"> <xsl:call-template name="space.2000.subst"> <xsl:with-param name="string" select="."/> </xsl:call-template> </xsl:template> <!-- You can adjust width of spaces by parameters. Empty value means that space is not converted to fo:leader --> <xsl:param name="space.enquad.width">0.5em</xsl:param> <!-- U+2000 --> <xsl:param name="space.emquad.width">1em</xsl:param> <!-- U+2001 --> <xsl:param name="space.enspace.width">0.5em</xsl:param><!-- U+2002 --> <xsl:param name="space.emspace.width">1em</xsl:param><!-- U+2003 --> <xsl:param name="space.3emspace.width">0.33em</xsl:param><!-- U+2004 --> <xsl:param name="space.4emspace.width">0.25em</xsl:param><!-- U+2005 --> <xsl:param name="space.6emspace.width">0.16em</xsl:param><!-- U+2006 --> <xsl:param name="space.figspace.width"></xsl:param><!-- U+2007 --> <xsl:param name="space.punctspace.width"></xsl:param><!-- U+2008 --> <xsl:param name="space.thinspace.width">0.2em</xsl:param><!-- U+2009 --> <xsl:param name="space.hairspace.width">0.1em</xsl:param><!-- U+200A --> <xsl:template name="space.2000.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.enquad.width != ''"> <xsl:call-template name="space.2001.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.enquad.width}"/> <xsl:call-template name="space.2000.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2001.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2001.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.emquad.width != ''"> <xsl:call-template name="space.2002.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.emquad.width}"/> <xsl:call-template name="space.2001.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2002.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2002.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.enspace.width != ''"> <xsl:call-template name="space.2003.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.enspace.width}"/> <xsl:call-template name="space.2002.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2003.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2003.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.emspace.width != ''"> <xsl:call-template name="space.2004.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.emspace.width}"/> <xsl:call-template name="space.2003.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2004.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2004.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.3emspace.width != ''"> <xsl:call-template name="space.2005.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.3emspace.width}"/> <xsl:call-template name="space.2004.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2005.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2005.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.4emspace.width != ''"> <xsl:call-template name="space.2006.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.4emspace.width}"/> <xsl:call-template name="space.2005.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2006.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2006.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.6emspace.width != ''"> <xsl:call-template name="space.2007.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.6emspace.width}"/> <xsl:call-template name="space.2006.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2007.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2007.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.figspace.width != ''"> <xsl:call-template name="space.2008.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.figspace.width}"/> <xsl:call-template name="space.2007.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2008.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2008.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.punctspace.width != ''"> <xsl:call-template name="space.2009.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.punctspace.width}"/> <xsl:call-template name="space.2008.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.2009.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.2009.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.thinspace.width != ''"> <xsl:call-template name="space.200A.subst"> <xsl:with-param name="string" select="substring-before($string, ' ')"/> </xsl:call-template> <fo:leader leader-length="{$space.thinspace.width}"/> <xsl:call-template name="space.2009.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="space.200A.subst"> <xsl:with-param name="string" select="$string"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="space.200A.subst"> <xsl:param name="string"/> <xsl:choose> <xsl:when test="contains($string, ' ') and $space.hairspace.width != ''"> <xsl:value-of select="substring-before($string, ' ')"/> <fo:leader leader-length="{$space.hairspace.width}"/> <xsl:call-template name="space.200A.subst"> <xsl:with-param name="string" select="substring-after($string, ' ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string"/> </xsl:otherwise> </xsl:choose> </xsl:template> I will add this code into the DocBook XSL stylesheets, so it will just works for them. | |
13. | Text flow round a shape |
There is no automatic way to do this in XSL-FO--the best you can do is flow text around two sides of a box using side floats. With care you might be able to simulate it by using side floats, one per line of text, to move the text out of the way of the shape and then use an absolutely-positioned block container to overlay the shape where you've created a void in the text, but I can't imagine this could be done automatically, at least not without a lot of effort. Eliot later added It just occurs to me that with XSL 1.1 you could do it by having a sequence of one-line-high body regions that go around the shape, connected using a flow map. It would be tedious to code but it should work. It would require a separate page master just for that page, which implies a very specialized page sequence to use the master (unless it's a repeating style element like an article opener or something). Hmmm. Now that I think about it, it should be possible to achieve a number of graphical layout effects using this approach that are not possible in 1.0. |