2016-04-23 3 views
0

Я хочу принудительно разбить строку после строки длиной 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?

ответ

1

Если заголовок может быть преобразован в строку, вы можете вставить <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. Установить свойство @ Переполнение = "конденсировать" с @axf: Переполнение-конденсироваться =»размер шрифта» https://www.antennahouse.com/product/ahf60/docs/ahf-ext.html#axf.overflow-condense
  3. Внутри фо:. Блок-контейнер, место ВОК:. Блок, который хранит содержимое заголовка
  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> 
0

Вы не можете форсировать разрыв линии в 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> 
1
  1. Если вы пытаетесь сломать слова (а не, например, номера деталей), то включение переносов может дать вам лучший результат, чем разрыв после фиксированного количества символов.

  2. Вы можете использовать linefeed-treatment="preserve" и вставить &#xA; вместо fo:block, так как это ответ на Inserting a line break in a PDF generated from XSL FO using <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