Принудительный разрыв строки после длины строки

Я хочу установить разрыв строки после строки длиной 14 символов в PDF-файле, созданном с помощью AH Formatter. Итак, это мой код xsl без какой-либо попытки разрыва строки:

<xsl:attribute-set name="big" use-attribute-sets="bold">
  <xsl:attribute name="font-size">38pt</xsl:attribute>
  <xsl:attribute name="line-height">28.84pt</xsl:attribute>
  <xsl:attribute name="text-align">center</xsl:attribute>
  <xsl:attribute name="letter-spacing">1mm</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="small" use-attribute-sets="bold">
  <xsl:attribute name="font-size">27pt</xsl:attribute>
  <xsl:attribute name="line-height">27pt</xsl:attribute>
  <xsl:attribute name="text-align">center</xsl:attribute>
  <xsl:attribute name="letter-spacing">1mm</xsl:attribute>
</xsl:attribute-set>

<xsl:choose>
   <xsl:when test="string-length($count_cover)>=14">
      <fo:block xsl:use-attribute-sets="small">
         <xsl:apply-templates/>
      </fo:block>
    </xsl:when>
    <xsl:otherwise>          
      <fo:block xsl:use-attribute-sets="big">
         <xsl:apply-templates/>
      </fo:block>
   </xsl:otherwise>
</xsl:choose>

Можно ли принудительно разорвать строку с помощью XSL-FO?


person papastavro    schedule 23.04.2016    source источник


Ответы (3)


Если заголовок можно преобразовать в строку, вы можете вставить <fo:block/> в качестве разрыва строки.

<xsl:variable name="cover_title" as="xs:string" select="'Very Long Cover Title! Very Long Cover Title! Very Long Cover Title! '"/>
<xsl:variable name="count_cover" as="xs:integer" select="string-length($cover_title)"/>
<xsl:variable name="lf_position" as="xs:integer" select="14"/>

<xsl:template match="/">
    <xsl:choose>
        <xsl:when test="$count_cover gt $lf_position">
            <fo:block xsl:use-attribute-sets="small">
                <xsl:analyze-string select="$cover_title" regex=".{{1}}">
                    <xsl:matching-substring>
                        <xsl:value-of select="."/>
                        <xsl:if test="position() eq $lf_position">
                            <fo:block/>
                        </xsl:if>
                    </xsl:matching-substring>
                    <xsl:non-matching-substring/>
                </xsl:analyze-string>
            </fo:block>
        </xsl:when>
        <xsl:otherwise>
            <fo:block xsl:use-attribute-sets="big">
                <xsl:value-of select="$cover_title"/>
            </fo:block>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

Результат:

<fo:block font-weight="bold" font-size="27pt" line-height="27pt" text-align="center" letter-spacing="1mm">Very Long Cove<fo:block/>r Title! Very Long Cover Title! Very Long Cover Title! </fo:block>

Однако этот метод игнорирует границы слов и управление переносами. Если вы собираетесь сделать заголовок обложки книги, лучше ввести расширения AH Formatter с помощью fo:block-container.

  1. Используйте fo:block-container для заголовка в фиксированном положении и размере на титульной странице.
  2. Задайте свойство @overflow="конденсат" с помощью @axf:overflow-convense="font-size". https://www.antennahouse.com/product/ahf60/docs/ahf-ext.html#axf.overflow-конденсат
  3. Внутри контейнера fo:block поместите fo:block, в котором хранится содержимое заголовков.
  4. Вы можете получить желаемый результат, потому что AH Formatter автоматически настраивает размер шрифта в соответствии с объемом содержимого.

[Пример]

<fo:block-container position="absolute" top="..." left="..." width="..." height="..." overflow="condense" axf:overflow-condense="font-size" font-size="27pt" text-align="center">
    <fo:block>
       <fo:inline>Very Long Cover Title! Very Long Cover Title! Very Long Cover Title!</fo:inline>
    </fo:block>
</fo:block-container>
person tmakita    schedule 27.04.2016

  1. Если вы пытаетесь разбить слова (а не, например, номера деталей), то включение переноса может дать вам лучший результат, чем разбиение после фиксированного количества символов.

  2. Вы можете использовать linefeed-treatment="preserve" и вставить &#xA; вместо fo:block, так как этот ответ на Вставка разрыва строки в PDF-файл, сгенерированный из XSL FO с использованием примечаний ‹xsl:value-of›. Что вы можете сделать с <xsl:value-of select="replace(., '(.{14})', '$1&#xA;')" />

  3. Вместо этого вы можете вставить пробел нулевой ширины, &#x200B;, после каждого 14-го символа и позволить AH Formatter разбить пробел нулевой ширины:

    <xsl:template match="text()"> <xsl:value-of select="replace(replace(., '(\P{Zs}{14})', '$1&#x200B;'), '&#x200B;(\p{Zs})', '$1')" /> </xsl:template>

    Внутренний replace() вставляет символ после каждых 14 символов, отличных от пробела, а внешний replace() исправляет это, если 15-й символ был пробелом.

    Если вы используете шрифт пропорциональной ширины, некоторые последовательности из 14 символов (исключая, например, 14 цифр постоянной ширины) будут иметь большую или меньшую ширину, чем другие, поэтому вы можете вставить &#x200B; между большим количеством символов, чтобы AH Formatter может сделать все возможное, чтобы заполнить строку до разрыва.

  4. Вы можете использовать axf:word-break="break-all", чтобы включить разрыв строки даже внутри слова. См. https://www.antennahouse.com/product/ahf63/ahf-ext.html#axf.word-break
person Tony Graham    schedule 27.04.2016

Вы не можете принудительно разбить строку в FO, но вы можете разделить строку на отдельные блоки FO.

<xsl:choose>
  <xsl:when test="string-length($count_cover) &gt;= 14">
    <fo:block><xsl:value-of select="substring($count_cover, 1, 13)"/></fo:block>
    <fo:block><xsl:value-of select="substring($count_cover, 14)"/></fo:block>
  </when>
  <xsl:otherwise>
    <fo:block>
      <xsl:value-of select="$count_cover"/>
    </fo:block>
  </xsl:otherwise>
</xsl:choose>
person Steven Laidlaw    schedule 23.04.2016