web-dev-qa-db-ja.com

xsl:foインライン行の折り返しと改行

Xsl:fo(Apache Fop 1.1)で苦労しています。改行文字を含む可能性のあるインライン画像とインラインテキスト要素を含むブロックを生成しようとしています。

<fo:block>
    <fo:inline>First Line&#10;Second Line, Image: </fo:inline>
    <fo:inline>
        <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/>
    </fo:inline>
    <fo:inline> some more Text on Line 2&#10;3rd Line</fo:inline>
</fo:block>

出力は次のようになると思います

FirstLine
SecondLine, Image: || some more Text on Line 2
3rd Line

私が得るものは:

FirstLine SecondLine, Image: || some more Text on Line 2 3rd Line

私はしばらくの間、fo:block要素および/またはfo:inline要素で次の属性を使用して遊んでいて、奇妙なまたは予期しない結果をもたらしています。

white-space-collapse="false" 
white-space-treatment="preserve" 
linefeed-treatment="preserve"

助言がありますか?

編集1:インライン要素を次のようなブロックに変更する

<fo:block white-space-treatment="ignore">
    <fo:block white-space="pre">First Line&#xA;Second Line, Image: </fo:block>
    <fo:block>
        <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/>
    </fo:block>
    <fo:block white-space="pre"> some more Text on Line 2&#10;3rd Line</fo:block>
</fo:block>

要素内で予想される折り返しが表示されますが、ブロックごとに新しい行が生成されます。これは、アーカイブしようとしているものではありません。

9
Kai

改行は、FOドキュメントに改行文字または数字エンティティ(&#x000A;または&#10;)として存在できます);次のFOブロックは完全に同等です:

<fo:block>Before the linefeed&#x000A;after the linefeed.</fo:block>

<fo:block>Before the linefeed
after the linefeed.</fo:block>

ラインフィードのデフォルトの処理は次のとおりです。

  1. それらを通常の空間に変換します。
  2. 折りたたみ他の隣接するスペースと一緒に。

これは、最初の入力で、すべてのコンテンツが同じ行に連続して配置される出力が生成される理由を説明しています。

プロパティlinefeed-treatment="preserve"を使用すると、両方の形式の改行が保持され、 行作成プロセス はそれらを尊重します(強制改行と呼ばれます)。 linefeed-treatmentfo:block要素にのみ適用されることに注意してください。 fo:inline要素には影響しません。

「edit1」ブロックには必要以上の改行があります。「... 2行目、画像:」、画像、「2行目のテキスト...」が3つの異なるfo:block内にあるためです。要素、および各ブロックは独自の行を生成します。

解決策1:解決策1:

目的の出力を取得する最も簡単な方法は、おそらくこれです。単一のfo:blockの改行が保持されます(これは、不要なfo:inlinesを削除し、すべてを同じ行に配置した後の元の入力です。

<fo:block linefeed-treatment="preserve">First Line&#xA;Second Line, Image: <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/> some more Text on Line 2&#10;3rd Line</fo:block>

このコードをインデントできないことに注意してください。余分な改行も出力に表示されるためです。

解決策2:解決策2:

linefeed-treatmentプロパティの使用を伴わず、より読みやすいコードを作成する2番目の解決策は、強制的な改行の代わりに空のブロックを使用することです。

<fo:block>
    First Line<fo:block/>Second Line, Image: 
    <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/> 
    some more Text on Line 2<fo:block/>3rd Line
</fo:block>

ラインフィードは保存されないため、自由に使用できます。

<fo:block>
    First Line
    <fo:block/>
    Second Line, Image: 
    <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/> 
    some more Text on Line 2
    <fo:block/>
    3rd Line
</fo:block>

空のブロックは、出力に何も作成せずに、外側のブロックのコンテンツを分割します。

15
lfurini

FOP 1536 のコメントで答えが見つかりました。

今使っています

linefeed-treatment="preserve"

ブロック要素で、テキストインライン内のすべてのスペースをxslのユニコードマジックに置き換えています。

replace(@text, ' ', '&#x00A0;&#x200B;') 

編集1:もう少し正確に言うと、これは私が使用しているxslの関連部分です。

<!DOCTYPE xsl:stylesheet [ 
    <!ENTITY nbsp "&#160;">
    <!ENTITY ZeroWidthSpace "&#x200B;"> 
]>

<fo:block linefeed-treatment="preserve">
    <fo:inline><xsl:value-of select="replace(@text, ' ', '&nbsp;&ZeroWidthSpace;')"/></fo:inline>
</fo:block>

このアプローチでは、改行と空白スペースを完全に制御しながら、かなりクリーンなインデントされたxmlを取得しています。

2
Kai