1<?xml version='1.0'?>
2<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                xmlns:fo="http://www.w3.org/1999/XSL/Format"
4                xmlns:sverb="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Verbatim"
5                xmlns:xverb="com.nwalsh.xalan.Verbatim"
6                xmlns:lxslt="http://xml.apache.org/xslt"
7                xmlns:exsl="http://exslt.org/common"
8                exclude-result-prefixes="sverb xverb lxslt exsl"
9                version='1.0'>
10
11<!-- ********************************************************************
12     $Id: verbatim.xsl,v 1.19 2005/11/20 01:39:49 bobstayton Exp $
13     ********************************************************************
14
15     This file is part of the XSL DocBook Stylesheet distribution.
16     See /README or http://nwalsh.com/docbook/xsl/ for copyright
17     and other information.
18
19     ******************************************************************** -->
20
21<lxslt:component prefix="xverb"
22                 functions="numberLines"/>
23
24<xsl:template match="programlisting|screen|synopsis">
25  <xsl:param name="suppress-numbers" select="'0'"/>
26  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
27
28  <xsl:variable name="content">
29    <xsl:choose>
30      <xsl:when test="$suppress-numbers = '0'
31                      and @linenumbering = 'numbered'
32                      and $use.extensions != '0'
33                      and $linenumbering.extension != '0'">
34        <xsl:call-template name="number.rtf.lines">
35          <xsl:with-param name="rtf">
36            <xsl:apply-templates/>
37          </xsl:with-param>
38        </xsl:call-template>
39      </xsl:when>
40      <xsl:otherwise>
41        <xsl:apply-templates/>
42      </xsl:otherwise>
43    </xsl:choose>
44  </xsl:variable>
45
46  <xsl:choose>
47    <xsl:when test="$shade.verbatim != 0">
48      <fo:block id="{$id}"
49                white-space-collapse='false'
50                white-space-treatment='preserve'
51                linefeed-treatment='preserve'
52                xsl:use-attribute-sets="monospace.verbatim.properties shade.verbatim.style">
53        <xsl:choose>
54          <xsl:when test="$hyphenate.verbatim != 0 and function-available('exsl:node-set')">
55            <xsl:apply-templates select="exsl:node-set($content)" mode="hyphenate.verbatim"/>
56          </xsl:when>
57          <xsl:otherwise>
58            <xsl:copy-of select="$content"/>
59          </xsl:otherwise>
60        </xsl:choose>
61      </fo:block>
62    </xsl:when>
63    <xsl:otherwise>
64      <fo:block id="{$id}"
65                white-space-collapse='false'
66                white-space-treatment='preserve'
67                linefeed-treatment="preserve"
68                xsl:use-attribute-sets="monospace.verbatim.properties">
69        <xsl:choose>
70          <xsl:when test="$hyphenate.verbatim != 0 and function-available('exsl:node-set')">
71            <xsl:apply-templates select="exsl:node-set($content)" mode="hyphenate.verbatim"/>
72          </xsl:when>
73          <xsl:otherwise>
74            <xsl:copy-of select="$content"/>
75          </xsl:otherwise>
76        </xsl:choose>
77      </fo:block>
78    </xsl:otherwise>
79  </xsl:choose>
80</xsl:template>
81
82<xsl:template match="literallayout">
83  <xsl:param name="suppress-numbers" select="'0'"/>
84
85  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
86
87  <xsl:variable name="content">
88    <xsl:choose>
89      <xsl:when test="$suppress-numbers = '0'
90                      and @linenumbering = 'numbered'
91                      and $use.extensions != '0'
92                      and $linenumbering.extension != '0'">
93        <xsl:call-template name="number.rtf.lines">
94          <xsl:with-param name="rtf">
95            <xsl:apply-templates/>
96          </xsl:with-param>
97        </xsl:call-template>
98      </xsl:when>
99      <xsl:otherwise>
100        <xsl:apply-templates/>
101      </xsl:otherwise>
102    </xsl:choose>
103  </xsl:variable>
104
105  <xsl:choose>
106    <xsl:when test="@class='monospaced'">
107      <xsl:choose>
108        <xsl:when test="$shade.verbatim != 0">
109          <fo:block id="{$id}"
110                    white-space-collapse='false'
111                    white-space-treatment='preserve'
112                    linefeed-treatment="preserve"
113                    xsl:use-attribute-sets="monospace.verbatim.properties shade.verbatim.style">
114
115            <xsl:copy-of select="$content"/>
116          </fo:block>
117        </xsl:when>
118        <xsl:otherwise>
119          <fo:block id="{$id}"
120                    white-space-collapse='false'
121                    white-space-treatment='preserve'
122                    linefeed-treatment="preserve"
123                    xsl:use-attribute-sets="monospace.verbatim.properties">
124            <xsl:copy-of select="$content"/>
125          </fo:block>
126        </xsl:otherwise>
127      </xsl:choose>
128    </xsl:when>
129    <xsl:otherwise>
130      <xsl:choose>
131        <xsl:when test="$shade.verbatim != 0">
132          <fo:block id="{$id}"
133                    wrap-option='no-wrap'
134                    white-space-collapse='false'
135                    white-space-treatment='preserve'
136                    text-align='start'
137                    linefeed-treatment="preserve"
138                    xsl:use-attribute-sets="verbatim.properties shade.verbatim.style">
139            <xsl:copy-of select="$content"/>
140          </fo:block>
141        </xsl:when>
142        <xsl:otherwise>
143          <fo:block id="{$id}"
144                    wrap-option='no-wrap'
145                    white-space-collapse='false'
146                    white-space-treatment='preserve'
147                    text-align='start'
148                    linefeed-treatment="preserve"
149                    xsl:use-attribute-sets="verbatim.properties">
150            <xsl:copy-of select="$content"/>
151          </fo:block>
152        </xsl:otherwise>
153      </xsl:choose>
154    </xsl:otherwise>
155  </xsl:choose>
156</xsl:template>
157
158<xsl:template match="address">
159  <xsl:param name="suppress-numbers" select="'0'"/>
160
161  <xsl:variable name="content">
162    <xsl:choose>
163      <xsl:when test="$suppress-numbers = '0'
164                      and @linenumbering = 'numbered'
165                      and $use.extensions != '0'
166                      and $linenumbering.extension != '0'">
167        <xsl:call-template name="number.rtf.lines">
168          <xsl:with-param name="rtf">
169            <xsl:apply-templates/>
170          </xsl:with-param>
171        </xsl:call-template>
172      </xsl:when>
173      <xsl:otherwise>
174        <xsl:apply-templates/>
175      </xsl:otherwise>
176    </xsl:choose>
177  </xsl:variable>
178
179  <fo:block wrap-option='no-wrap'
180            white-space-collapse='false'
181            white-space-treatment='preserve'
182            linefeed-treatment="preserve"
183            xsl:use-attribute-sets="verbatim.properties">
184    <xsl:copy-of select="$content"/>
185  </fo:block>
186</xsl:template>
187
188<xsl:template name="number.rtf.lines">
189  <xsl:param name="rtf" select="''"/>
190  <xsl:param name="pi.context" select="."/>
191
192  <!-- Save the global values -->
193  <xsl:variable name="global.linenumbering.everyNth"
194                select="$linenumbering.everyNth"/>
195
196  <xsl:variable name="global.linenumbering.separator"
197                select="$linenumbering.separator"/>
198
199  <xsl:variable name="global.linenumbering.width"
200                select="$linenumbering.width"/>
201
202  <!-- Extract the <?dbfo linenumbering.*?> PI values -->
203  <xsl:variable name="pi.linenumbering.everyNth">
204    <xsl:call-template name="dbfo-attribute">
205      <xsl:with-param name="pis"
206                      select="$pi.context/processing-instruction('dbfo')"/>
207      <xsl:with-param name="attribute" select="'linenumbering.everyNth'"/>
208    </xsl:call-template>
209  </xsl:variable>
210
211  <xsl:variable name="pi.linenumbering.separator">
212    <xsl:call-template name="dbfo-attribute">
213      <xsl:with-param name="pis"
214                      select="$pi.context/processing-instruction('dbfo')"/>
215      <xsl:with-param name="attribute" select="'linenumbering.separator'"/>
216    </xsl:call-template>
217  </xsl:variable>
218
219  <xsl:variable name="pi.linenumbering.width">
220    <xsl:call-template name="dbfo-attribute">
221      <xsl:with-param name="pis"
222                      select="$pi.context/processing-instruction('dbfo')"/>
223      <xsl:with-param name="attribute" select="'linenumbering.width'"/>
224    </xsl:call-template>
225  </xsl:variable>
226
227  <!-- Construct the 'in-context' values -->
228  <xsl:variable name="linenumbering.everyNth">
229    <xsl:choose>
230      <xsl:when test="$pi.linenumbering.everyNth != ''">
231        <xsl:value-of select="$pi.linenumbering.everyNth"/>
232      </xsl:when>
233      <xsl:otherwise>
234        <xsl:value-of select="$global.linenumbering.everyNth"/>
235      </xsl:otherwise>
236    </xsl:choose>
237  </xsl:variable>
238
239  <xsl:variable name="linenumbering.separator">
240    <xsl:choose>
241      <xsl:when test="$pi.linenumbering.separator != ''">
242        <xsl:value-of select="$pi.linenumbering.separator"/>
243      </xsl:when>
244      <xsl:otherwise>
245        <xsl:value-of select="$global.linenumbering.separator"/>
246      </xsl:otherwise>
247    </xsl:choose>
248  </xsl:variable>
249
250  <xsl:variable name="linenumbering.width">
251    <xsl:choose>
252      <xsl:when test="$pi.linenumbering.width != ''">
253        <xsl:value-of select="$pi.linenumbering.width"/>
254      </xsl:when>
255      <xsl:otherwise>
256        <xsl:value-of select="$global.linenumbering.width"/>
257      </xsl:otherwise>
258    </xsl:choose>
259  </xsl:variable>
260
261  <xsl:variable name="linenumbering.startinglinenumber">
262    <xsl:choose>
263      <xsl:when test="$pi.context/@startinglinenumber">
264        <xsl:value-of select="$pi.context/@startinglinenumber"/>
265      </xsl:when>
266      <xsl:when test="$pi.context/@continuation='continues'">
267        <xsl:variable name="lastLine">
268          <xsl:choose>
269            <xsl:when test="$pi.context/self::programlisting">
270              <xsl:call-template name="lastLineNumber">
271                <xsl:with-param name="listings"
272                     select="preceding::programlisting[@linenumbering='numbered']"/>
273              </xsl:call-template>
274            </xsl:when>
275            <xsl:when test="$pi.context/self::screen">
276              <xsl:call-template name="lastLineNumber">
277                <xsl:with-param name="listings"
278                     select="preceding::screen[@linenumbering='numbered']"/>
279              </xsl:call-template>
280            </xsl:when>
281            <xsl:when test="$pi.context/self::literallayout">
282              <xsl:call-template name="lastLineNumber">
283                <xsl:with-param name="listings"
284                     select="preceding::literallayout[@linenumbering='numbered']"/>
285              </xsl:call-template>
286            </xsl:when>
287            <xsl:when test="$pi.context/self::address">
288              <xsl:call-template name="lastLineNumber">
289                <xsl:with-param name="listings"
290                     select="preceding::address[@linenumbering='numbered']"/>
291              </xsl:call-template>
292            </xsl:when>
293            <xsl:when test="$pi.context/self::synopsis">
294              <xsl:call-template name="lastLineNumber">
295                <xsl:with-param name="listings"
296                     select="preceding::synopsis[@linenumbering='numbered']"/>
297              </xsl:call-template>
298            </xsl:when>
299            <xsl:otherwise>
300              <xsl:message>
301                <xsl:text>Unexpected verbatim environment: </xsl:text>
302                <xsl:value-of select="local-name(.)"/>
303              </xsl:message>
304              <xsl:value-of select="0"/>
305            </xsl:otherwise>
306          </xsl:choose>
307        </xsl:variable>
308
309        <xsl:value-of select="$lastLine + 1"/>
310      </xsl:when>
311      <xsl:otherwise>1</xsl:otherwise>
312    </xsl:choose>
313  </xsl:variable>
314
315  <xsl:choose>
316    <xsl:when test="function-available('sverb:numberLines')">
317      <xsl:copy-of select="sverb:numberLines($rtf)"/>
318    </xsl:when>
319    <xsl:when test="function-available('xverb:numberLines')">
320      <xsl:copy-of select="xverb:numberLines($rtf)"/>
321    </xsl:when>
322    <xsl:otherwise>
323      <xsl:message terminate="yes">
324        <xsl:text>No numberLines function available.</xsl:text>
325      </xsl:message>
326    </xsl:otherwise>
327  </xsl:choose>
328</xsl:template>
329
330<!-- ======================================================================== -->
331
332<xsl:template name="lastLineNumber">
333  <xsl:param name="listings"/>
334  <xsl:param name="number" select="0"/>
335
336  <xsl:variable name="lines">
337    <xsl:call-template name="countLines">
338      <xsl:with-param name="listing" select="string($listings[1])"/>
339    </xsl:call-template>
340  </xsl:variable>
341
342  <xsl:choose>
343    <xsl:when test="not($listings)">
344      <xsl:value-of select="$number"/>
345    </xsl:when>
346    <xsl:when test="$listings[1]/@startinglinenumber">
347      <xsl:value-of select="$number + $listings[1]/@startinglinenumber + $lines - 1"/>
348    </xsl:when>
349    <xsl:when test="$listings[1]/@continuation='continues'">
350      <xsl:call-template name="lastLineNumber">
351        <xsl:with-param name="listings" select="listings[position() &gt; 1]"/>
352        <xsl:with-param name="number" select="$number + $lines"/>
353      </xsl:call-template>
354    </xsl:when>
355    <xsl:otherwise>
356      <xsl:value-of select="$lines"/>
357    </xsl:otherwise>
358  </xsl:choose>
359</xsl:template>
360
361<xsl:template name="countLines">
362  <xsl:param name="listing"/>
363  <xsl:param name="count" select="1"/>
364
365  <xsl:choose>
366    <xsl:when test="contains($listing, '&#10;')">
367      <xsl:call-template name="countLines">
368        <xsl:with-param name="listing" select="substring-after($listing, '&#10;')"/>
369        <xsl:with-param name="count" select="$count + 1"/>
370      </xsl:call-template>
371    </xsl:when>
372    <xsl:otherwise>
373      <xsl:value-of select="$count"/>
374    </xsl:otherwise>
375  </xsl:choose>
376</xsl:template>
377
378<!-- ======================================================================== -->
379
380<xsl:template match="node()|@*" mode="hyphenate.verbatim">
381  <xsl:copy>
382    <xsl:apply-templates select="node()|@*" mode="hyphenate.verbatim"/>
383  </xsl:copy>
384</xsl:template>
385
386<xsl:template match="text()" mode="hyphenate.verbatim" priority="2">
387  <xsl:call-template name="hyphenate.verbatim">
388    <xsl:with-param name="content" select="."/>
389  </xsl:call-template>
390</xsl:template>
391
392<xsl:template name="hyphenate.verbatim">
393  <xsl:param name="content"/>
394  <xsl:variable name="head" select="substring($content, 1, 1)"/>
395  <xsl:variable name="tail" select="substring($content, 2)"/>
396  <xsl:choose>
397    <!-- Place soft-hyphen after space or non-breakable space. -->
398    <xsl:when test="$head = ' ' or $head = '&#160;'">
399      <xsl:text>&#160;</xsl:text>
400      <xsl:text>&#x00AD;</xsl:text>
401    </xsl:when>
402    <xsl:when test="$hyphenate.verbatim.characters != '' and
403                    translate($head, $hyphenate.verbatim.characters, '') = '' and not($tail = '')">
404      <xsl:value-of select="$head"/>
405      <xsl:text>&#x00AD;</xsl:text>
406    </xsl:when>
407    <xsl:otherwise>
408      <xsl:value-of select="$head"/>
409    </xsl:otherwise>
410  </xsl:choose>
411  <xsl:if test="$tail">
412    <xsl:call-template name="hyphenate.verbatim">
413      <xsl:with-param name="content" select="$tail"/>
414    </xsl:call-template>
415  </xsl:if>
416</xsl:template>
417
418
419</xsl:stylesheet>
420