You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by bu...@apache.org on 2004/07/06 02:23:43 UTC

DO NOT REPLY [Bug 29924] New: - [PATCH] XML CSS engine

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=29924>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=29924

[PATCH] XML CSS engine

           Summary: [PATCH] XML CSS engine
           Product: Cocoon 2
           Version: Current CVS 2.2
          Platform: Other
        OS/Version: Other
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: Samples
        AssignedTo: dev@cocoon.apache.org
        ReportedBy: eburghar@free.fr


XML CSS engine with macro preprocessor and agent targeting. patch follows 
----------- 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/samples.xml 
cocoon-2.2.new/src/webapp/samples/samples.xml 
56a57,63 
>     <sample name="CSS subsystem" href="xmlcss/"> 
>       CSS interpretation is far from beeing uniform among browsers. The 
>       proposed XMLCSS subsystem is able to serve, from one centralized xml 
description, 
>       well suited text/css files for a specific browser or a browser family. 
The preprocessor 
>       engine let you easily define values (eg. colors, fonts) that can be 
shared with other 
>       xmlcss files. 
>     </sample> 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/css/defines_css.xml 
cocoon-2.2.new/src/webapp/samples/xmlcss/css/defines_css.xml 
0a1,31 
> <?xml version="1.0" encoding="UTF-8"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
> <css> 
>     <define name="large-r" value="2"/> 
>     <define name="large-rm" value="{$large-r}" agent="! ie6"/> 
>     <!-- ie6 doubles the relative horizontal margins on a floated box ??? --> 
>     <define name="large-rm" value="{$large-r div 2}" agent="ie6"/> 
>     <!-- total width of a float box with relative left and right paddind of 
$medium-r% --> 
>     <define name="wlarge-rm" value="{100 - (2 * $large-r)}"/> 
>     <define name="wlarge-rp" value="{100 - (2 * $large-r)}" agent="! ie6"/> 
>     <!--width on floated box with relative padding is alway 100 for ie ?? --> 
>     <define name="wlarge-rp" value="100" agent="ie6"/> 
>     <define name="large-rp" value="{$large-r}"/> 
>     <define name="debug-br" value="1px dotted red"/> 
>     <!-- large horizontal relatives margins --> 
>     <define name="large-hrm" left="{$large-rm}%" right="{$large-rm}%"/> 
> </css> 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/css/example_css.xml 
cocoon-2.2.new/src/webapp/samples/xmlcss/css/example_css.xml 
0a1,97 
> <?xml version="1.0" encoding="UTF-8"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
> <css> 
>     <!-- defines or rules can be put in a separate file --> 
>     <include src="defines_css.xml"/> 
>     <!-- --> 
>     <rule select="#container"> 
>         <padding value="0"/> 
>         <margin value="{@large-hrm}"/> 
>         <float value="left"/> 
>         <width value="{$wlarge-rm}%"/> 
>         <!-- <border value="{$debug-br}"/> --> 
>     </rule> 
>     <!-- --> 
>     <rule select="#browser-scale"> 
>         <padding value="0"/> 
>         <margin value="0"/> 
>         <margin bottom="20pt"/> 
>         <float value="left"/> 
>         <width value="100%"/> 
>         <background color="blue"/> 
>         <!-- <border value="{$debug-br}"/> --> 
>     </rule> 
>     <!-- --> 
>     <rule select="#browser-rate"> 
>         <marging value="0"/> 
>         <padding value="0"/> 
>         <float value="left"/> 
>         <width value="50%"/> 
>         <width value="95%" agent="konqueror"/> 
>         <width value="90%" agent="opera mozilla"/> 
>         <width value="50%" agent="ie5"/> 
>         <width value="40%" agent="ie5mac"/> 
>         <width value="20%" agent="ie6"/> 
>         <height value="20pt"/> 
>         <background color="red"/> 
>         <!-- <border value="{$debug-br}"/> --> 
>     </rule> 
>     <!-- --> 
>     <rule select="#desc"> 
>         <text align="center"/> 
>     </rule> 
>     <!-- --> 
>     <rule select="#legend"> 
>         <margin value="0"/> 
>         <padding value="0"/> 
>         <float value="left"/> 
>         <width value="100%"/> 
>         <background color="white"/> 
>     </rule> 
>     <!-- --> 
>     <rule select="#min"> 
>         <margin value="0"/> 
>         <padding value="0"/> 
>         <float value="left"/> 
>         <text transform="uppercase"/> 
>         <font weight="bold"/> 
>     </rule> 
>     <!-- --> 
>     <rule select="#max"> 
>         <margin value="0"/> 
>         <padding value="0"/> 
>         <float value="right"/> 
>         <text weigth="bold" transform="uppercase"/> 
>         <font weight="bold"/> 
>     </rule> 
>     <!-- --> 
>     <rule select="h1"> 
>          <clear value="left"/> 
>          <border bottom="2px solid blue"/> 
>     </rule> 
>     <!-- --> 
>     <rule select="h2"> 
>          <clear value="left"/> 
>          <color value="red"/> 
>          <text decoration="underline"/> 
>     </rule> 
>     <!-- --> 
>     <rule select="code"> 
>         <color value="blue"/> 
>         <font family="typewriter"/> 
>     </rule> 
> </css> 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/example.xhtml 
cocoon-2.2.new/src/webapp/samples/xmlcss/example.xhtml 
0a1,80 
> <?xml version="1.0" encoding="UTF-8"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
> <html xmlns="http://www.w3.org/1999/xhtml"> 
>     <head> 
>         <meta http-equiv="Content-Type" content="text/html; 
charset=iso-8859-1"/> 
>         <title>Browser Rating</title> 
>         <link href="example.css" type="text/css" rel="stylesheet"><!-- 
--></link> 
>     </head> 
>     <body> 
>         <div id="container"> 
>         <h1>Browser rating</h1> 
>     <p id="desc">The rule below show my preferences over some famliar 
browsers. Test this page on different ones.</p> 
>     <div id="browser-scale"><div id="legend"><span id="min">min</span><span 
id="max">max</span></div><div id="browser-rate"><!-- --></div></div> 
>     <h2>Description</h2> 
>     <p>An xmlcss file is just an xmlifaction of a css file:</p> 
>     <ul> 
>         <li>The root must be &lt;css/&gt;</li> 
>         <li>You define rules which can contains any number of attributes<br/> 
>             <code> 
>             &lt;rule select="body"&gt;<br/> 
>             &lt;margin value="0"/&gt;<br/> 
>             &lt;/rule&gt; 
>             </code> 
>         </li> 
>         <li>You can use <code>&lt;include src="file.xml"/&gt;</code> at top 
level</li> 
>         <li>You can define some macros at top level 
>             <ul> 
>                 <li>single attribute: <code>&lt;define name="foo" 
value="white"/&gt;</code></li> 
>                 <li>multiple attributes: <code>&lt;define name="bar" 
left="10pt" right="10pt"/&gt;</code></li> 
>             </ul> 
>         </li> 
>         <li>You can use expressions in values an attributes 
>             <ul> 
>                 <li>single attribute: <code>&lt;background 
color="{$foo}"/&gt;</code></li> 
>                 <li>multiple attributes: <code>&lt;margin 
value="{@bar}"/&gt;</code></li> 
>                 <li>expression (xpath): <code>&lt;width value="{100 - (2 * 
$hmargin)}%"&gt;</code></li> 
>             </ul> 
>         </li> 
>         <li>You can use an agent attribute on any element (css, include, rule 
or attributes) to target a 
>             specific browser. agent are defined in agent.xsl. agent is a list 
or an exclusion list if it begins with !. 
>             <ul> 
>                 <li><code>&lt;float value="left" agent="ie5mac 
ie4"/&gt;</code></li> 
>                 <li><code>&lt;float value="non" agent="! ie5mac 
ie4"/&gt;</code></li> 
>             </ul> 
>         </li> 
>     </ul> 
>     <h2>Bugs</h2> 
>     <ul> 
>         <li>Use some exsl extension (node-set, dynamic, func), not always 
stable or user-friendly but enhance 
>         readability and reduce the amount of lines code.</li> 
>         <li>It's based entirely on xslt via a metastylesheet. Errors are 
generaly hidden. Proceed step by step, look directly at the 
>         generated css, consult the logs.</li> 
>         <li>CSS like multiple definition, XSLT normally don't. Xalan don't 
complains about multiple defined variable 
>         (at least it takes the last and this what we want in cascading 
policy). Try to avoid multiple define (define are 
>         handled with xslt variables) with the same name at the same time (use 
agent="something" and agent="! something" 
>         for the default define).</li> 
>     </ul> 
>     <h2>TODO</h2> 
>     <ul> 
>         <li>Syntax checking (XML Schema ?).</li> 
>         <li>Agent aliasing is done throught an xslt variable which is defined 
in a standalone xslt file. Perhaps could we made 
>         an action to setup things in the sitemap.</li> 
>     </ul> 
>     </div> 
>     </body> 
> </html> 
\ Pas de fin de ligne à la fin du fichier. 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/samples.xml 
cocoon-2.2.new/src/webapp/samples/xmlcss/samples.xml 
0a1,31 
> <?xml version="1.0"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
>  
> <samples name="Hello, World!"> 
>  
>   <group name="Back"> 
>    <sample name="Back" href="../"> 
>     Back to the samples home page. 
>    </sample> 
>   </group> 
>  
>   <group name="XMLCSS"> 
>    <sample name="Example" href="example.xhtml"> 
>     This page is showned differently on mozilla, konqueror, opera and ie5. 
>    </sample> 
>   </group> 
> </samples> 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/sitemap.xmap 
cocoon-2.2.new/src/webapp/samples/xmlcss/sitemap.xmap 
0a1,80 
> <?xml version="1.0" encoding="UTF-8"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
>  
> <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"> 
>      
>   <!-- =========================== Views =================================== 
--> 
>  
>   <map:views> 
>     <map:view name="content" from-label="content"> 
>       <map:serialize type="xml"/> 
>     </map:view> 
>  
>     <map:view from-label="content" name="pretty-content"> 
>       <map:transform src="context://stylesheets/system/xml2html.xslt"/> 
>       <map:serialize type="html"/> 
>     </map:view> 
>  
>     <map:view name="links" from-position="last"> 
>       <map:serialize type="links"/> 
>     </map:view> 
>   </map:views> 
>  
>   <!-- =========================== Pipelines 
================================= --> 
>  
>   <map:pipelines> 
>     <map:pipeline> 
>  
>       <map:match pattern=""> 
>         <map:generate src="samples.xml"/> 
>         <map:transform 
src="context://samples/common/style/xsl/html/simple-samples2html.xsl"> 
>            <map:parameter name="contextPath" value="{request:contextPath}"/> 
>         </map:transform> 
>         <map:serialize/> 
>       </map:match> 
>        
>       <map:match pattern="example.xhtml"> 
>           <map:generate src="example.xhtml"/> 
>           <map:serialize type="xhtml"/> 
>       </map:match> 
>     </map:pipeline> 
>        
>     <!-- type is noncaching because we use the xslt document() function which 
>     gives pains to cocoon caching subsystem. Revert to caching when your 
xmlcss are stable --> 
>     <map:pipeline type="noncaching"> 
>          
>       <!-- dump the css --> 
>       <map:match pattern="*.css"> 
>           <map:generate src="css/{1}_css.xml"/> 
>           <map:transform src="cocoon:/stylesheets/xml2css-{1}.xsl"/> 
>           <map:serialize type="text" mime-type="text/css"/> 
>       </map:match> 
>              
>       <!-- return the stylesheet responsible of macros substitutions and css 
dumping --> 
>       <map:match pattern="stylesheets/xml2css-*.xsl"> 
> 	      <map:generate src="css/{1}_css.xml"/> 
> 	      <!-- filter the defines --> 
> 	      <map:transform src="context://stylesheets/css/cssdefines.xsl"> 
> 	          <map:parameter name="user-agent" 
value="{request-header:User-Agent}"/> 
> 	      </map:transform> 
> 	      <map:transform src="context://stylesheets/css/metaxml2css.xsl"/> 
> 	      <map:serialize type="xml"/> 
>       </map:match> 
>    </map:pipeline> 
>     
>    </map:pipelines> 
> </map:sitemap> 
\ Pas de fin de ligne à la fin du fichier. 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/style/cssdefines.xsl 
cocoon-2.2.new/src/webapp/samples/xmlcss/style/cssdefines.xsl 
1,38d0 
< <?xml version="1.0" encoding="UTF-8"?> 
< <!-- 
<   Copyright 1999-2004 The Apache Software Foundation 
<  
<   Licensed under the Apache License, Version 2.0 (the "License"); 
<   you may not use this file except in compliance with the License. 
<   You may obtain a copy of the License at 
<  
<       http://www.apache.org/licenses/LICENSE-2.0 
<  
<   Unless required by applicable law or agreed to in writing, software 
<   distributed under the License is distributed on an "AS IS" BASIS, 
<   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
<   See the License for the specific language governing permissions and 
<   limitations under the License. 
< --> 
< <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
<     <xsl:output method="xml" indent="yes"/> 
<     <xsl:strip-space elements="*"/> 
<     <!-- --> 
<     <xsl:template match="/css"> 
<         <css> 
<             <xsl:apply-templates/> 
<         </css> 
<     </xsl:template> 
<     <!-- xslt inclusion: this simple rule handle include of include (very 
tricky to do with cinclude and near impossible 
<     with xinclude). Include only define --> 
<     <xsl:template match="include"> 
<         <xsl:apply-templates select="document(@src)/css/define"/> 
<     </xsl:template> 
<     <!-- copy only defines 
<     --> 
<     <xsl:template match="@*|define|text()|processing-instruction()"> 
<         <xsl:copy> 
<             <xsl:apply-templates select="@*|*|text()|
processing-instruction()"/> 
<         </xsl:copy> 
<     </xsl:template> 
< </xsl:stylesheet> 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/style/metaxml2css.xsl 
cocoon-2.2.new/src/webapp/samples/xmlcss/style/metaxml2css.xsl 
1,281d0 
< <?xml version="1.0" encoding="ISO-8859-1"?> 
< <!-- 
<   Copyright 1999-2004 The Apache Software Foundation 
<  
<   Licensed under the Apache License, Version 2.0 (the "License"); 
<   you may not use this file except in compliance with the License. 
<   You may obtain a copy of the License at 
<  
<       http://www.apache.org/licenses/LICENSE-2.0 
<  
<   Unless required by applicable law or agreed to in writing, software 
<   distributed under the License is distributed on an "AS IS" BASIS, 
<   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
<   See the License for the specific language governing permissions and 
<   limitations under the License. 
< --> 
< <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
<     xmlns:xso="http://alias/Transform" 
<     xmlns:func="http://exslt.org/functions" 
<     xmlns:funo="http://alias/functions" 
<     xmlns:exsl="http://exslt.org/common" 
<     xmlns:dyn="http://exslt.org/dynamic" 
<     xmlns:my="http://cocoon.apache.org/functions" 
<     version="1.0" exclude-result-prefixes="func"> 
<     <xsl:output method="xml" indent="yes"/> 
<     <xsl:namespace-alias stylesheet-prefix="xso" result-prefix="xsl"/> 
<     <xsl:namespace-alias stylesheet-prefix="funo" result-prefix="func"/> 
<     <xsl:param name="agent"/> 
<     <!-- variable for agent recognition (externalized for easy access) 
<     --> 
<     <xsl:include href="short-agent.xsl"/> 
<     <!-- 
<     functions for agent targeting 
<     --> 
<     <!-- return true if an element is targeted to the desired agent 
(expression is a set or an exclusion set if it begins with !) --> 
<     <func:function name="my:is-for-agent" copy="true"> 
<         <xsl:param name="str"/> 
<         <xsl:param name="agent"/> 
<         <xsl:choose> 
<             <xsl:when test="$str != ''"> 
<                 <xsl:variable name="word"> 
<                     <xsl:choose> 
<                         <xsl:when test="substring-before($str,' ') = 
''"><xsl:value-of select="$str"/></xsl:when> 
<                         <xsl:otherwise><xsl:value-of 
select="substring-before($str,' ')"/></xsl:otherwise> 
<                     </xsl:choose> 
<                 </xsl:variable> 
<                 <!-- evaluate --> 
<                 <xsl:choose> 
<                     <!-- recursion if not already true (logical or) --> 
<                     <xsl:when test="$word = $agent"><func:result 
select="true()"/></xsl:when> 
<                     <xsl:when test="$word = '!'"><func:result 
select="not(my:_is-for-agent(substring-after($str,' '), $agent))"/></xsl:when> 
<                     <xsl:otherwise><func:result 
select="my:_is-for-agent(substring-after($str,' '), $agent)"/></xsl:otherwise> 
<                 </xsl:choose> 
<             </xsl:when> 
<             <xsl:otherwise><func:result select="false()"/></xsl:otherwise> 
<         </xsl:choose> 
<     </func:function> 
<     <!-- is-for-agent without inversion test --> 
<     <func:function name="my:_is-for-agent" copy="true"> 
<         <xsl:param name="str"/> 
<         <xsl:param name="agent"/> 
<         <xsl:choose> 
<             <xsl:when test="$str != ''"> 
< 	            <xsl:variable name="word"> 
< 	                <xsl:choose> 
< 	                    <xsl:when test="substring-before($str,' ') = 
''"><xsl:value-of select="$str"/></xsl:when> 
< 	                    <xsl:otherwise><xsl:value-of 
select="substring-before($str,' ')"/></xsl:otherwise> 
< 	                </xsl:choose> 
< 	            </xsl:variable> 
< 	            <xsl:choose> 
< 	                <xsl:when test="$word = $agent"><func:result 
select="true()"/></xsl:when> 
< 	                <xsl:otherwise><func:result 
select="my:_is-for-agent(substring-after($str,' '), $agent)"/></xsl:otherwise> 
< 	            </xsl:choose> 
<             </xsl:when> 
<             <xsl:otherwise><func:result select="false()"/></xsl:otherwise> 
<         </xsl:choose> 
<     </func:function> 
<     <!-- write the stylesheet 
<      --> 
<     <xsl:template match="/"> 
<         <xso:stylesheet version="1.0"> 
<             <xso:output method="text"/> 
<             <xso:strip-space elements="*"/> 
<             <!-- copy all the common functions between metastylesheet and the 
stylesheet itself 
<             --> 
<             <xsl:copy-of select="document(' 
')/xsl:stylesheet/func:*[@copy='true']"/> 
<             <!-- define the already valuated short-agent variable 
<             --> 
<             <xso:variable name="short-agent"><xsl:attribute 
name="select">'<xsl:value-of 
select="$short-agent"/>'</xsl:attribute></xso:variable> 
<             <!-- copy variables 
<             --> 
<             <xsl:for-each select="/css/define[@value and (not(@agent) or 
my:is-for-agent(@agent, $short-agent))]"> 
<                 <xsl:choose> 
<                     <xsl:when test="contains(@value, '{')"> 
<                         <xso:variable name="{@name}"> 
<                             <xso:call-template name="subst-word"> 
<                                 <xso:with-param name="word"><xsl:value-of 
select="@value"/></xso:with-param> 
<                             </xso:call-template> 
<                         </xso:variable> 
<                     </xsl:when> 
<                     <xsl:otherwise> 
<                         <xso:variable name="{@name}" select="'{@value}'"/> 
<                     </xsl:otherwise> 
<                 </xsl:choose> 
<             </xsl:for-each> 
<             <!-- copy attributes sets 
<             --> 
<             <xso:variable name="sets"> 
<                 <xsl:for-each select="/css/define[not(@value) and 
(not(@agent) or my:is-for-agent(@agent, $short-agent))]"> 
<                     <xsl:element name="{@name}"><xsl:copy-of 
select="@*[local-name() != 'name']"/></xsl:element> 
<                 </xsl:for-each> 
<             </xso:variable> 
<             <!-- root rule 
<             --> 
<             <xso:template match="/css"> 
<                 <xso:apply-templates select="rule[not(@agent) or 
my:is-for-agent(@agent, $short-agent)]"/> 
<             </xso:template> 
<             <!-- selectors rule 
<             --> 
<             <xso:template match="rule"> 
<                 <xso:value-of select="@select"/> 
<                 <xso:text xml:space="preserve"> { 
< </xso:text> 
<                 <xso:apply-templates select="*[not(@agent) or 
my:is-for-agent(@agent, $short-agent)]"/> 
<                 <xso:text xml:space="preserve">} 
<  
< </xso:text> 
<             </xso:template> 
<             <!-- attributes rule 
<              --> 
<             <xso:template match="*"> 
<                 <xso:variable name="name" select="local-name()"/> 
<                 <xso:choose> 
<                     <xso:when test="@value"> 
<                         <xso:variable name="word" 
select="normalize-space(@value)"/> 
<                         <xso:choose> 
<                             <xso:when> 
<                                 <xsl:attribute name="test" 
xml:space="preserve">starts-with($word, '&#x7B;@')</xsl:attribute> 
<                                 <xso:variable name="setname" 
select="substring($word, 3, string-length($word)-3)"/> 
<                                 <xso:for-each 
select="exsl:node-set($sets)/*[local-name()=$setname][position()=last()]/@*"> 
<                                     <xso:value-of 
select="my:print-rule(concat($name, '-', local-name()), .)"/> 
<                                 </xso:for-each> 
<                             </xso:when> 
<                             <xso:otherwise> 
<                                 <xso:value-of select="my:print-rule($name, 
@value)"/> 
<                             </xso:otherwise> 
<                         </xso:choose> 
<                     </xso:when> 
<                     <xso:otherwise> 
<                         <xso:apply-templates select="@*"/> 
<                     </xso:otherwise> 
<                 </xso:choose> 
<             </xso:template> 
<             <!-- avoid @agent dumping 
<             --> 
<             <xso:template match="@agent"/> 
<             <!-- xslt inclusion: this simple rule handle include of include 
(very tricky to do with cinclude and near impossible 
<             with xinclude). Include only rules --> 
<             <xso:template match="include"> 
<                <xso:apply-templates 
select="document(@src)/css/*[local-name() != 'define']"/> 
<             </xso:template> 
<             <!-- a new rule for each xml attributes 
<             --> 
<             <xso:template match="@*"> 
<                 <xso:value-of select="my:print-rule(concat(name(..), '-', 
local-name()), .)"/> 
<             </xso:template> 
<             <!-- substitute all words beginning with {$ 
<             --> 
<             <funo:function name="my:subst"> 
<                 <xso:param name="str"/> 
<                 <xso:choose> 
<                     <!-- trivial case --> 
<                     <xso:when> 
<                         <xsl:attribute name="test">not(contains($str, 
'&#x7B;'))</xsl:attribute> 
<                         <funo:result select="$str"/> 
<                     </xso:when> 
<                     <xso:when test="$str != ''"> 
<                         <!-- substitute the first word --> 
<                         <xso:variable name="word-value" 
select="my:subst-word(my:first-word($str))"/> 
<                         <!-- recursion --> 
<                         <xso:variable name="res" 
select="my:subst(substring-after($str,' '))"/> 
<                         <xso:choose> 
<                             <!-- concat words --> 
<                             <xso:when test="$res != ''"><funo:result 
select="concat($word-value, ' ', $res)"/></xso:when> 
<                             <xso:otherwise><funo:result 
select="$word-value"/></xso:otherwise> 
<                         </xso:choose> 
<                     </xso:when> 
<                 </xso:choose> 
<             </funo:function> 
< 		    <!-- return the first word of a string 
<             --> 
< 		    <funo:function name="my:first-word"> 
< 		        <xso:param name="str"/> 
< 		        <xso:choose> 
< 		            <xso:when test="substring-before($str,' ')=''"> 
< 		                <funo:result select="$str"/> 
< 		            </xso:when> 
< 		            <xso:otherwise> 
< 		                <funo:result select="substring-before($str,' 
')"/> 
< 		            </xso:otherwise> 
< 		        </xso:choose> 
< 		    </funo:function> 
<             <!-- substitute expressions inside a word eg. '{$var}.{$foo}%' 
<             --> 
<             <xso:template name="subst-word"> 
<                 <xso:param name="word"/> 
<                 <xso:choose> 
<                     <xso:when> 
<                         <xsl:attribute name="test" 
xml:space="preserve">not(contains($word, '&#x7B;'))</xsl:attribute> 
<                         <xso:value-of select="$word"/> 
<                     </xso:when> 
<                     <xso:otherwise> 
<                         <xso:variable name="bword"> 
<                             <xsl:attribute name="select" 
xml:space="preserve">substring-before($word, '&#x7B;')</xsl:attribute> 
<                         </xso:variable> 
<                         <xso:choose> 
<                             <xso:when test="$bword != ''"> 
<                                 <xso:variable name="res"> 
<                                     <xso:call-template name="subst-word"> 
<                                         <xso:with-param> 
<                                         <xsl:attribute name="name" 
xml:space="preserve">word</xsl:attribute> 
<                                         <xsl:attribute name="select" 
xml:space="preserve">concat('&#x7B;', substring-after($word, 
'&#x7B;'))</xsl:attribute> 
<                                         </xso:with-param> 
<                                     </xso:call-template> 
<                                 </xso:variable> 
<                                 <xso:value-of select="concat($bword, $res)"/> 
<                             </xso:when> 
<                             <xso:otherwise> 
<                                 <xso:variable name="exp"> 
<                                         <xsl:attribute name="select" 
xml:space="preserve">substring-before($word, '&#x7D;')</xsl:attribute> 
<                                 </xso:variable> 
<                                 <xso:variable name="exp-val" 
select="dyn:evaluate(substring($exp, 2))"/> 
<                                 <xso:variable name="res"> 
<                                     <xso:call-template name="subst-word"> 
<                                         <xso:with-param> 
<                                         <xsl:attribute name="name" 
xml:space="preserve">word</xsl:attribute> 
<                                         <xsl:attribute name="select" 
xml:space="preserve">substring-after($word, '&#x7D;')</xsl:attribute> 
<                                         </xso:with-param> 
<                                     </xso:call-template> 
<                                 </xso:variable> 
<                                 <xso:value-of select="concat($exp-val, 
$res)"/> 
<                             </xso:otherwise> 
<                         </xso:choose> 
<                     </xso:otherwise> 
<                 </xso:choose> 
<             </xso:template> 
<             <!-- subst-word function wrapper --> 
<             <funo:function name="my:subst-word"> 
< 		        <xso:param name="word"/> 
< 		        <funo:result> 
< 			        <xso:call-template name="subst-word"> 
< 			            <xso:with-param name="word" 
select="$word"/> 
< 			        </xso:call-template> 
< 		        </funo:result> 
< 		    </funo:function>     
<             <!-- print a css rule 
<             --> 
<             <funo:function name="my:print-rule"> 
<                 <xso:param name="name"/> 
<                 <xso:param name="value"/> 
<                 <funo:result> 
<                     <xso:text xml:space="preserve">  </xso:text> 
<                     <xso:value-of select="$name"/> 
<                     <xso:text xml:space="preserve">: </xso:text> 
<                     <xso:value-of 
select="my:subst(normalize-space($value))"/>;<xso:text xml:space="preserve"> 
< </xso:text> 
<                 </funo:result> 
<             </funo:function> 
<         </xso:stylesheet> 
<     </xsl:template> 
<     <!--avoid @agent dumping 
<      --> 
<     <xsl:template match="@agent"/> 
<     <!-- blind copy 
<      --> 
<     <xsl:template match="@*|*|text()|processing-instruction()"> 
<         <xsl:copy> 
<             <xsl:apply-templates select="@*|*|text()|
processing-instruction()"/> 
<         </xsl:copy> 
<     </xsl:template> 
< </xsl:stylesheet> 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/samples/xmlcss/style/short-agent.xsl 
cocoon-2.2.new/src/webapp/samples/xmlcss/style/short-agent.xsl 
1,35d0 
< <?xml version="1.0" encoding="UTF-8"?> 
< <!-- 
<   Copyright 1999-2004 The Apache Software Foundation 
<  
<   Licensed under the Apache License, Version 2.0 (the "License"); 
<   you may not use this file except in compliance with the License. 
<   You may obtain a copy of the License at 
<  
<       http://www.apache.org/licenses/LICENSE-2.0 
<  
<   Unless required by applicable law or agreed to in writing, software 
<   distributed under the License is distributed on an "AS IS" BASIS, 
<   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
<   See the License for the specific language governing permissions and 
<   limitations under the License. 
< --> 
< <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
<     <xsl:param name="agent"/> 
<     <!-- variable for agent recognition 
<     TODO: perhaps could we use an agent action instead ? 
<     --> 
<     <xsl:variable name="short-agent"> 
<         <xsl:choose> 
< 		    <xsl:when test="contains($agent, 'Opera')">opera</xsl:when> 
< 		    <xsl:when test="contains($agent, 
'Gecko/')">mozilla</xsl:when> 
< 		    <xsl:when test="contains($agent, 
'Konqueror/')">konqueror</xsl:when> 
< 	        <xsl:when test="contains($agent, 'MSIE 4')">ie4</xsl:when> 
< 	        <xsl:when test="contains($agent, 'MSIE 5') and contains($agent, 
'Mac_PowerPC')">ie5mac</xsl:when> 
< 	        <xsl:when test="contains($agent, 'MSIE 5')">ie5</xsl:when> 
< 	        <xsl:when test="contains($agent, 'MSIE 6')">ie6</xsl:when> 
< 	        <xsl:when test="contains($agent, 'MSIE')">ie</xsl:when> 
< 	        <xsl:otherwise>unknown</xsl:otherwise> 
<         </xsl:choose> 
<     </xsl:variable> 
< </xsl:stylesheet> 
\ Pas de fin de ligne à la fin du fichier. 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/stylesheets/css/agent.xsl 
cocoon-2.2.new/src/webapp/stylesheets/css/agent.xsl 
0a1,35 
> <?xml version="1.0" encoding="UTF-8"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
>     <xsl:param name="user-agent"/> 
>     <!-- variable for agent recognition 
>     TODO: perhaps could we use an agent action instead ? 
>     --> 
>     <xsl:variable name="agent"> 
>         <xsl:choose> 
> 		    <xsl:when test="contains($user-agent, 
'Opera')">opera</xsl:when> 
> 		    <xsl:when test="contains($user-agent, 
'Gecko/')">mozilla</xsl:when> 
> 		    <xsl:when test="contains($user-agent, 
'Konqueror/')">konqueror</xsl:when> 
> 	        <xsl:when test="contains($user-agent, 'MSIE 4')">ie4</xsl:when> 
> 	        <xsl:when test="contains($user-agent, 'MSIE 5') and 
contains($user-agent, 'Mac_PowerPC')">ie5mac</xsl:when> 
> 	        <xsl:when test="contains($user-agent, 'MSIE 5')">ie5</xsl:when> 
> 	        <xsl:when test="contains($user-agent, 'MSIE 6')">ie6</xsl:when> 
> 	        <xsl:when test="contains($user-agent, 'MSIE')">ie</xsl:when> 
> 	        <xsl:otherwise>unknown</xsl:otherwise> 
>         </xsl:choose> 
>     </xsl:variable> 
> </xsl:stylesheet> 
\ Pas de fin de ligne à la fin du fichier. 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/stylesheets/css/cssdefines.xsl 
cocoon-2.2.new/src/webapp/stylesheets/css/cssdefines.xsl 
0a1,50 
> <?xml version="1.0" encoding="UTF-8"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> xmlns:func="http://exslt.org/functions" 
xmlns:my="http://cocoon.apache.org/functions" 
> version="1.0" exclude-result-prefixes="func my"> 
>     <xsl:output method="xml" indent="yes"/> 
>     <xsl:strip-space elements="*"/> 
>     <xsl:param name="user-agent"/> 
>     <!-- variable for agent recognition (externalized for easy access) 
>     --> 
>     <xsl:include href="agent.xsl"/> 
>     <!-- 
>     functions for agent targeting (externalisation for reusability) 
>     --> 
>     <xsl:include href="is-for-agent.xsl"/> 
>     <!-- --> 
>     <xsl:template match="/css"> 
>         <css agent="{$agent}"> 
>             <xsl:if test="not(../@agent) or my:is-for-agent(../@agent, 
$agent)"> 
> 	            <xsl:apply-templates select="*[not(@agent) or 
my:is-for-agent(@agent, $agent)]"/> 
>             </xsl:if> 
>         </css> 
>     </xsl:template> 
>     <!-- xslt recursive inclusion: very tricky to do with cinclude and near 
impossible with xinclude. Include only defines 
>     --> 
>     <xsl:template match="include[not(@agent) or my:is-for-agent(@agent, 
$agent)]"> 
>         <xsl:apply-templates select="document(@src)/css/define"/> 
>     </xsl:template> 
>     <!-- copy only defines 
>     --> 
>     <xsl:template match="define[not(@agent) or my:is-for-agent(@agent, 
$agent)]"> 
>         <xsl:copy> 
>             <xsl:copy-of select="@*[local-name() != 'agent']"/> 
>         </xsl:copy> 
>     </xsl:template> 
> </xsl:stylesheet> 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/stylesheets/css/is-for-agent.xsl 
cocoon-2.2.new/src/webapp/stylesheets/css/is-for-agent.xsl 
0a1,65 
> <?xml version="1.0" encoding="UTF-8"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:func="http://exslt.org/functions" 
>     xmlns:my="http://cocoon.apache.org/functions" version="1.0"> 
>     <!-- 
>     functions for agent targeting 
>     --> 
>     <!-- return true if an element is targeted to the desired agent 
(expression is a set or an exclusion set if 1st word is !) --> 
>     <func:function name="my:is-for-agent"> 
>         <xsl:param name="str"/> 
>         <xsl:param name="agent"/> 
>         <xsl:choose> 
>             <xsl:when test="$str != ''"> 
>                 <xsl:variable name="word"> 
>                     <xsl:choose> 
>                         <xsl:when test="substring-before($str,' ') = 
''"><xsl:value-of select="$str"/></xsl:when> 
>                         <xsl:otherwise><xsl:value-of 
select="substring-before($str,' ')"/></xsl:otherwise> 
>                     </xsl:choose> 
>                 </xsl:variable> 
>                 <!-- evaluate --> 
>                 <xsl:choose> 
>                     <!-- recursion if not already true (logical or) --> 
>                     <xsl:when test="$word = $agent"><func:result 
select="true()"/></xsl:when> 
>                     <xsl:when test="$word = '!'"><func:result 
select="not(my:_is-for-agent(substring-after($str,' '), $agent))"/></xsl:when> 
>                     <xsl:otherwise><func:result 
select="my:_is-for-agent(substring-after($str,' '), $agent)"/></xsl:otherwise> 
>                 </xsl:choose> 
>             </xsl:when> 
>             <xsl:otherwise><func:result select="false()"/></xsl:otherwise> 
>         </xsl:choose> 
>     </func:function> 
>     <!-- is-for-agent without inversion test --> 
>     <func:function name="my:_is-for-agent"> 
>         <xsl:param name="str"/> 
>         <xsl:param name="agent"/> 
>         <xsl:choose> 
>             <xsl:when test="$str != ''"> 
> 	            <xsl:variable name="word"> 
> 	                <xsl:choose> 
> 	                    <xsl:when test="substring-before($str,' ') = 
''"><xsl:value-of select="$str"/></xsl:when> 
> 	                    <xsl:otherwise><xsl:value-of 
select="substring-before($str,' ')"/></xsl:otherwise> 
> 	                </xsl:choose> 
> 	            </xsl:variable> 
> 	            <xsl:choose> 
> 	                <xsl:when test="$word = $agent"><func:result 
select="true()"/></xsl:when> 
> 	                <xsl:otherwise><func:result 
select="my:_is-for-agent(substring-after($str,' '), $agent)"/></xsl:otherwise> 
> 	            </xsl:choose> 
>             </xsl:when> 
>             <xsl:otherwise><func:result select="false()"/></xsl:otherwise> 
>         </xsl:choose> 
>     </func:function> 
> </xsl:stylesheet> 
\ Pas de fin de ligne à la fin du fichier. 
diff -r --new-file --exclude='*.class' 
cocoon-2.2/src/webapp/stylesheets/css/metaxml2css.xsl 
cocoon-2.2.new/src/webapp/stylesheets/css/metaxml2css.xsl 
0a1,216 
> <?xml version="1.0" encoding="ISO-8859-1"?> 
> <!-- 
>   Copyright 1999-2004 The Apache Software Foundation 
>  
>   Licensed under the Apache License, Version 2.0 (the "License"); 
>   you may not use this file except in compliance with the License. 
>   You may obtain a copy of the License at 
>  
>       http://www.apache.org/licenses/LICENSE-2.0 
>  
>   Unless required by applicable law or agreed to in writing, software 
>   distributed under the License is distributed on an "AS IS" BASIS, 
>   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
>   See the License for the specific language governing permissions and 
>   limitations under the License. 
> --> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
>     xmlns:xso="http://alias/Transform" 
>     xmlns:func="http://exslt.org/functions" 
>     xmlns:funo="http://alias/functions" 
>     xmlns:exsl="http://exslt.org/common" 
>     xmlns:dyn="http://exslt.org/dynamic" 
>     xmlns:my="http://cocoon.apache.org/functions" 
>     version="1.0" exclude-result-prefixes="func"> 
>     <xsl:output method="xml" indent="yes"/> 
>     <xsl:namespace-alias stylesheet-prefix="xso" result-prefix="xsl"/> 
>     <xsl:namespace-alias stylesheet-prefix="funo" result-prefix="func"/> 
>     <!-- write the stylesheet 
>      --> 
>     <xsl:template match="/css"> 
>         <xso:stylesheet version="1.0"> 
>             <xso:output method="text"/> 
>             <xso:strip-space elements="*"/> 
>             <!-- copy the is-for-agent functions 
>             --> 
>             <xsl:copy-of 
select="document('is-for-agent.xsl')/xsl:stylesheet/func:*"/> 
>             <!-- define the already valuated short-agent variable 
>             --> 
>             <xso:variable name="agent"><xsl:attribute 
name="select">'<xsl:value-of select="@agent"/>'</xsl:attribute></xso:variable> 
>             <!-- copy variables 
>             --> 
>             <xsl:for-each select="define[@value]"> 
>                 <xsl:choose> 
>                     <!-- xpath expression --> 
>                     <xsl:when test="starts-with(@value,'{') and 
substring(@value, string-length(@value))='}'"> 
>                         <xso:variable name="{@name}" 
select="{substring(@value, 2, string-length(@value)-2)}"/> 
>                     </xsl:when> 
>                     <!-- string expression --> 
>                     <xsl:when test="contains(@value, '{') and 
contains(@value, '}')"> 
>                         <xso:variable name="{@name}"> 
> 	                        <xso:call-template name="subst-word"> 
> 	                            <xso:with-param name="word"><xsl:value-of 
select="@value"/></xso:with-param> 
> 	                        </xso:call-template> 
> 	                    </xso:variable> 
>                     </xsl:when> 
>                     <!-- string --> 
>                     <xsl:otherwise> 
>                         <xso:variable name="{@name}" select="'{@value}'"/> 
>                     </xsl:otherwise> 
>                 </xsl:choose> 
>             </xsl:for-each> 
>             <!-- copy attributes sets 
>             --> 
>             <xso:variable name="sets"> 
>                 <xsl:for-each select="define[not(@value)]"> 
>                     <xsl:element name="{@name}"><xsl:copy-of 
select="@*[local-name() != 'name']"/></xsl:element> 
>                 </xsl:for-each> 
>             </xso:variable> 
>             <!-- root rule 
>             --> 
>             <xso:template match="/css[not(@agent) or my:is-for-agent(@agent, 
$agent)]"> 
>                 <xso:apply-templates select="rule[not(@agent) or 
my:is-for-agent(@agent, $agent)]"/> 
>             </xso:template> 
>             <!-- xslt recursive inclusion: very tricky to do with cinclude 
and near impossible with xinclude. Include only rules 
>             --> 
>             <xso:template match="include"> 
>                <xso:apply-templates 
select="document(@src)/css/*[local-name() != 'define']"/> 
>             </xso:template> 
>             <!-- selectors rule 
>             --> 
>             <xso:template match="rule"> 
>                 <xso:value-of select="@select"/> 
>                 <xso:text xml:space="preserve"> { 
> </xso:text> 
>                 <xso:apply-templates select="*[not(@agent) or 
my:is-for-agent(@agent, $agent)]"/> 
>                 <xso:text xml:space="preserve">} 
>  
> </xso:text> 
>             </xso:template> 
>             <!-- attributes rule 
>              --> 
>             <xso:template match="*"> 
>                 <xso:variable name="name" select="local-name()"/> 
>                 <xso:choose> 
>                     <xso:when test="@value"> 
>                         <xso:variable name="word" 
select="normalize-space(@value)"/> 
>                         <xso:choose> 
>                             <xso:when> 
>                                 <xsl:attribute name="test" 
xml:space="preserve">starts-with($word, '&#x7B;@')</xsl:attribute> 
>                                 <xso:variable name="setname" 
select="substring($word, 3, string-length($word)-3)"/> 
>                                 <xso:for-each 
select="exsl:node-set($sets)/*[local-name()=$setname][position()=last()]/@*"> 
>                                     <xso:value-of 
select="my:print-rule(concat($name, '-', local-name()), .)"/> 
>                                 </xso:for-each> 
>                             </xso:when> 
>                             <xso:otherwise> 
>                                 <xso:value-of select="my:print-rule($name, 
@value)"/> 
>                             </xso:otherwise> 
>                         </xso:choose> 
>                     </xso:when> 
>                     <xso:otherwise> 
>                         <xso:apply-templates select="@*"/> 
>                     </xso:otherwise> 
>                 </xso:choose> 
>             </xso:template> 
>             <!-- avoid @agent dumping 
>             --> 
>             <xso:template match="@agent"/> 
>             <!-- a new rule for each xml attributes 
>             --> 
>             <xso:template match="@*"> 
>                 <xso:value-of select="my:print-rule(concat(name(..), '-', 
local-name()), .)"/> 
>             </xso:template> 
>             <!-- substitute expressions inside a word eg. '{$var}.{$foo}%' 
>             --> 
>             <xso:template name="subst-word"> 
>                 <xso:param name="word"/> 
>                 <xso:choose> 
>                     <xso:when> 
>                         <xsl:attribute name="test" 
xml:space="preserve">not(contains($word, '&#x7B;'))</xsl:attribute> 
>                         <xso:value-of select="$word"/> 
>                     </xso:when> 
>                     <xso:otherwise> 
>                         <xso:variable name="bword"> 
>                             <xsl:attribute name="select" 
xml:space="preserve">substring-before($word, '&#x7B;')</xsl:attribute> 
>                         </xso:variable> 
>                         <xso:choose> 
>                             <xso:when test="$bword != ''"> 
>                                 <xso:variable name="res"> 
>                                     <xso:call-template name="subst-word"> 
>                                         <xso:with-param> 
>                                         <xsl:attribute name="name" 
xml:space="preserve">word</xsl:attribute> 
>                                         <xsl:attribute name="select" 
xml:space="preserve">concat('&#x7B;', substring-after($word, 
'&#x7B;'))</xsl:attribute> 
>                                         </xso:with-param> 
>                                     </xso:call-template> 
>                                 </xso:variable> 
>                                 <xso:value-of select="concat($bword, $res)"/> 
>                             </xso:when> 
>                             <xso:otherwise> 
>                                 <xso:variable name="exp"> 
>                                         <xsl:attribute name="select" 
xml:space="preserve">substring-before($word, '&#x7D;')</xsl:attribute> 
>                                 </xso:variable> 
>                                 <xso:variable name="exp-val" 
select="dyn:evaluate(substring($exp, 2))"/> 
>                                 <xso:variable name="res"> 
>                                     <xso:call-template name="subst-word"> 
>                                         <xso:with-param> 
>                                         <xsl:attribute name="name" 
xml:space="preserve">word</xsl:attribute> 
>                                         <xsl:attribute name="select" 
xml:space="preserve">substring-after($word, '&#x7D;')</xsl:attribute> 
>                                         </xso:with-param> 
>                                     </xso:call-template> 
>                                 </xso:variable> 
>                                 <xso:value-of select="concat($exp-val, 
$res)"/> 
>                             </xso:otherwise> 
>                         </xso:choose> 
>                     </xso:otherwise> 
>                 </xso:choose> 
>             </xso:template> 
>             <!-- subst-word function wrapper --> 
>             <funo:function name="my:subst-word"> 
> 		        <xso:param name="word"/> 
> 		        <funo:result> 
> 			        <xso:call-template name="subst-word"> 
> 			            <xso:with-param name="word" 
select="$word"/> 
> 			        </xso:call-template> 
> 		        </funo:result> 
> 		    </funo:function>     
>             <!-- print a css rule 
>             --> 
>             <funo:function name="my:print-rule"> 
>                 <xso:param name="name"/> 
>                 <xso:param name="value"/> 
>                 <funo:result> 
>                     <xso:text xml:space="preserve">  </xso:text> 
>                     <xso:value-of select="$name"/> 
>                     <xso:text xml:space="preserve">: </xso:text> 
> 	                <xso:choose> 
> 	                    <!-- xpath expression --> 
> 		                <xso:when> 
> 		                    <xsl:attribute 
name="test">starts-with($value,'&#x7B;') and substring($value, 
string-length($value))='&#x7D;'</xsl:attribute> 
> 		                    <xso:value-of 
select="dyn:evaluate(substring($value, 2, string-length($value)-2))"/> 
> 		                </xso:when> 
> 		                <!-- string expression --> 
> 		                <xso:when> 
> 		                    <xsl:attribute name="test">contains($value, 
'&#x7B;') and contains($value, '&#x7D;')</xsl:attribute> 
> 		                    <xso:value-of 
select="my:subst-word($value)"/> 
> 		                </xso:when> 
> 		                <!-- string --> 
> 		                <xso:otherwise> 
> 		                    <xso:value-of select="$value"/> 
> 		                </xso:otherwise> 
> 	                </xso:choose>;<xso:text xml:space="preserve"> 
> </xso:text> 
>                 </funo:result> 
>             </funo:function> 
>         </xso:stylesheet> 
>     </xsl:template> 
>     <!--avoid @agent dumping 
>      --> 
>     <xsl:template match="@agent"/> 
>     <!-- blind copy 
>      --> 
>     <xsl:template match="@*|*|text()|processing-instruction()"> 
>         <xsl:copy> 
>             <xsl:apply-templates select="@*|*|text()|
processing-instruction()"/> 
>         </xsl:copy> 
>     </xsl:template> 
> </xsl:stylesheet>