Обертывание лидера XSL-FO

У меня есть список данных с пунктирной линией, разделяющей текст, выровненный по левому и правому краям. Для этого я использую следующий XSL-FO.

<fo:block text-align-last="justify">
    <xsl:value-of select="left-text"/>
    <fo:leader leader-pattern="dots"/>
    <xsl:value-of select="right-text"/>
</fo:block>
Some text on the left............................some text on the right

Это прекрасно работает, когда весь текст помещается в одну строку. Проблема, с которой я сталкиваюсь, заключается в правильной обработке того, как текст справа переносится на новую строку. У меня есть особое требование, чтобы он был отформатирован так, чтобы обернутый текст оставался выровненным по правому краю, как показано ниже:

Some text on the left.................a long piece of text on the right 
                                                       that has wrapped

Я пытался добиться этого с помощью лидеров и таблиц, но безрезультатно. Я использую форматер Antenna House. Любые советы очень приветствуются. Спасибо за помощь.


person Peter    schedule 21.07.2014    source источник
comment
Вы можете выровнять весь fo:block по правому краю?   -  person Joel M. Lamsen    schedule 22.07.2014
comment
К сожалению, это не сработало. Это не имело никакого значения для форматирования. Спасибо, в любом случае.   -  person Peter    schedule 22.07.2014
comment
1) Вы должны показать свою таблицу test и 2) на картинке, которую вы изображаете, у вас есть какое-то правило форматирования, которое вы не указали. Фактически вы нарисовали картину, которая подразумевает, что у вас есть некоторая ширина, меньше которой вы хотите, чтобы лидер никогда не был короче. Я имею в виду, что большая часть текста, который вы показываете, уместилась бы в строке с меньшим количеством точек. Каковы правила ... ?   -  person Kevin Brown    schedule 24.07.2014


Ответы (2)


Используйте это как вдохновение и установите свои собственные правила:

       <fo:block text-align="justify" text-align-last="right">
           <fo:inline>Some text on the left</fo:inline>
           <fo:leader leader-pattern="dots" leader-length.minimum="2in" leader-length.optimum="2in" leader-length.maximum="3in"/>
           <fo:inline>a long piece of text on the right that has wrapped</fo:inline>
       </fo:block>
        <fo:block text-align="justify" text-align-last="right">
           <fo:inline>Some text</fo:inline>
           <fo:leader leader-pattern="dots" leader-length.minimum="2in" leader-length.optimum="2in" leader-length.maximum="3in"/>
           <fo:inline>a long piece of text on the right that has wrapped and is even longer</fo:inline>
       </fo:block>

Единственное, что вы не сможете остановить, — это правая линия, настолько длинная, что она проходит под точками, но вы не указали это как требование. Если это так, я боюсь, что нет никакого решения для этого. Кроме того, если строка слишком короткая, она будет выровнена по правому краю. Вы должны использовать минимальные/максимальные значения только для принудительного переноса.

Если вы знаете размер шрифта, вы можете подсчитать символы в левом/правом элементах, а затем вызвать свой шаблон или этот образец в зависимости от общего количества символов.

Результат этого ФО

А для подсчета вы можете сделать что-то вроде этого шаблона, где «50» символов вы можете настроить с помощью длины выноски, чтобы получить правильные результаты.

<xsl:template name="processitem">
    <xsl:choose>
        <xsl:when test="string-length(left) + string-length(right) > 50">
            <fo:block text-align="justify" text-align-last="right">
                <fo:inline><xsl:value-of select="left"/></fo:inline>
                <fo:leader leader-pattern="dots" leader-length.minimum="2in" leader-length.optimum="2in" leader-length.maximum="4in"/>
                <fo:inline><xsl:value-of select="right"/></fo:inline>
            </fo:block>
        </xsl:when>
        <xsl:otherwise>
            <fo:block text-align-last="justify">
                <fo:inline><xsl:value-of select="left"/></fo:inline>
                <fo:leader leader-pattern="dots"/>
                <fo:inline><xsl:value-of select="right"/></fo:inline>
            </fo:block>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

С некоторыми примерами данных я получил это для рендеринга:

Использование приведенного выше шаблона с примерами данных

person Kevin Brown    schedule 23.07.2014
comment
Спасибо, это действительно большая помощь. Как вы предложили, мне просто нужно было настроить максимальное значение длины символа, и я заработал с моей таблицей стилей. Ваше здоровье! - person Peter; 08.08.2014

Вы можете использовать fo:inline-container (https://www.w3.org/TR/xsl11/#fo_inline-container) и свойство max-width (https://www.w3.org/TR/xsl11/#max-width), чтобы ограничить ширину любого длинного текста справа.

В этом примере используется расширение axf:text-align-first="justify" (см. https://www.antennahouse.com/product/ahf66/ahf-ext.html#axf.text-align-first), чтобы выровнять первую строку. Вместо этого вы можете использовать расширение axf:leader-expansion="force" (см. https://www.antennahouse.com/product/ahf66/ahf-ext.html#axf.leader-expansion). Без любого из них я думаю, что ваша единственная другая альтернатива - угадать leader-length.optimum второго fo:leader.

Обратите внимание, что в приведенном ниже примере нет значащих пробелов между двумя fo:leader. Это позволяет избежать разрыва между двумя лидерами при их форматировании.

<fo:block text-align="justify">
  <fo:inline>Some text</fo:inline><fo:leader
  leader-pattern="dots" leader-length.optimum="100%"
  leader-alignment="end"
  /><fo:inline-container
  max-width="1.5in" text-align="right"
  axf:text-align-first="justify" >
          <fo:block><fo:leader leader-pattern="dots"
  leader-length.minimum="0" />a long piece of text on the right that has wrapped
and is even longer</fo:block>
  </fo:inline-container>
</fo:block>

Пример нескольких строк текста, выровненного по правому краю после выноски.

person Tony Graham    schedule 12.10.2018