XSL-FO: принудительное наложение на таблицы
У меня возникла проблема, когда я публикую свои моды в формате PDF (XSL-FO). В моих таблицах возникают проблемы, когда содержимое ячейки переполняет свой столбец в следующий. Как сделать разрыв текста, чтобы вместо него была создана новая строка?
Я не могу вручную вставить символы пробела, так как записи в таблице вводятся программно. Я ищу простое решение, которое я могу просто добавить в docbook_pdf.xsl (в виде атрибута xsl:param или xsl:)
РЕДАКТИРОВАТЬ: Вот где я в настоящее время:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:import href="urn:docbkx:stylesheet"/>
...(the beginning of my stylesheet for pdf generation, e.g. header and footer content stuff)
<xsl:template match="text()">
<xsl:call-template name="intersperse-with-zero-spaces">
<xsl:with-param name="str" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="intersperse-with-zero-spaces">
<xsl:param name="str"/>
<xsl:variable name="spacechars">
	

      
     ​
</xsl:variable>
<xsl:if test="string-length($str) > 0">
<xsl:variable name="c1" select="substring($str, 1, 1)"/>
<xsl:variable name="c2" select="substring($str, 2, 1)"/>
<xsl:value-of select="$c1"/>
<xsl:if test="$c2 != '' and
not(contains($spacechars, $c1) or
contains($spacechars, $c2))">
<xsl:text>​</xsl:text>
</xsl:if>
<xsl:call-template name="intersperse-with-zero-spaces">
<xsl:with-param name="str" select="substring($str, 2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
При этом длинные слова успешно разбиваются в ячейках таблицы! К сожалению, побочным эффектом является то, что обычный текст в другом месте (например, в нижнем разделе X) теперь разбивает слова так, что они появляются в отдельных строках. Есть ли способ изолировать вышеуказанный процесс только от таблиц?
3 ответа
В длинных словах попробуйте вставить символ пробела нулевой ширины между символами, где допускается разрыв.
Вы можете использовать XSLT, чтобы вставить пробел нулевой ширины между каждым символом. Вот один из способов сделать это: http://groups.yahoo.com/neo/groups/XSL-FO/conversations/topics/1177.
Вот ветка списка рассылки, где обсуждаются различные подходы к проблеме: http://www.stylusstudio.com/xsllist/200201/post80920.html.
Таблицы стилей SourceForge DocBook содержат шаблон для разбиения длинных URL-адресов в выводе FO; см. http://www.sagehill.net/docbookxsl/Ulinks.html. Шаблон (
hyphenate-url
) находится в xref.xsl.
Поскольку вы используете XSLT 2.0:
<xsl:template match="text()">
<xsl:value-of
select="replace(replace(., '(\P{Zs})(\P{Zs})', '$1​$2'),
'([^\p{Zs}​])([^\p{Zs}​])',
'$1​$2')" />
</xsl:template>
При этом используется экранирование категории ( http://www.w3.org/TR/xmlschema-2/), а не явный список символов для сопоставления, но вместо этого вы можете сделать это таким образом. Нужно два replace()
потому что внутренний replace()
можно вставить только символ между каждым вторым символом. Внешний replace()
соответствует символам, которые не являются пробелами или символами, добавленными внутренним replace()
,
Вставка после каждого тринадцатого непробельного символа:
<xsl:template match="text()">
<xsl:value-of
select="replace(replace(., '(\P{Zs}{13})', '$1​'),
'​(\p{Zs})',
'$1')" />
</xsl:template>
Внутренний replace()
вставляет символ после каждых 13 непробельных символов, а внешний replace()
исправляет это, если 14-й символ был пробелом.
Если вы используете AH Formatter, то вы можете использовать axf:word-break="break-all"
чтобы позволить AH Formatter разрывать в любом месте слова. См. https://www.antennahouse.com/product/ahf64/ahf-ext.html.
<xsl:template match="text()[parent::entry]"> отлично подходит для переноса текста только в таблицу.