sysmodellibs/sysmodelgen/core/layout-module.xsl
changeset 7 3c36c452f013
parent 6 5b32dc297d05
equal deleted inserted replaced
6:5b32dc297d05 7:3c36c452f013
       
     1 <?xml version="1.0"?>
       
     2  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       
     3  	xmlns:s="http://www.w3.org/2000/svg" xmlns:exslt="http://exslt.org/common"
       
     4  	xmlns:date="http://exslt.org/dates-and-times"
       
     5  	exclude-result-prefixes="s exslt date">
       
     6  	<xsl:output method="xml" indent="yes"/>
       
     7 
       
     8 
       
     9 <xsl:variable name="abbrevs" select="document(/model/layout/info/@href,/)/display-names//abbrev"/> <!-- the abbreviations list -->
       
    10 
       
    11 <xsl:template match="/SystemDefinition" mode="add-id-ns">
       
    12 <xsl:attribute name="id-namespace"><xsl:value-of select="$defaultns"/></xsl:attribute>
       
    13 </xsl:template>
       
    14 
       
    15 <!-- merging -->
       
    16 
       
    17 
       
    18 <xsl:include href="mergesysdef-module.xsl"/>
       
    19 
       
    20 
       
    21 <xsl:template match="/model">
       
    22 	<xsl:variable name="model" select="."/>
       
    23 	
       
    24 	<xsl:variable name="sysdef"> <!-- all the merged sysdefs -->
       
    25 		<xsl:apply-templates select="." mode="first-merge"/>
       
    26 	</xsl:variable>
       
    27 	
       
    28 	<!-- now create the output by putting all global attributes into <SystemDefinition>
       
    29 		 and any global meta sections into the systemModel or other root model item 
       
    30 		this contains all the layout data needed to build the model -->
       
    31 	<xsl:for-each select="exslt:node-set($sysdef)/*">
       
    32 		<xsl:copy><xsl:copy-of select="@*"/>
       
    33 			<xsl:apply-templates select="$model" mode="layout-attributes"/>
       
    34 			<xsl:for-each select="*">
       
    35 				<xsl:copy><xsl:copy-of select="@*"/>
       
    36 					<xsl:apply-templates select="$model/*[not(self::sysdef)]" mode="layout-meta"/>
       
    37 					<xsl:copy-of select="*"/>			
       
    38 				</xsl:copy>
       
    39 			</xsl:for-each>
       
    40 		</xsl:copy>
       
    41 	</xsl:for-each>
       
    42 </xsl:template>
       
    43 
       
    44 
       
    45 <xsl:template match="/model" mode="first-merge">
       
    46 	<xsl:apply-templates select="sysdef[1]" mode="join-sysdef-from-model"/>
       
    47 </xsl:template>
       
    48 
       
    49 <xsl:template match="/model[count(sysdef) &gt; 1]" mode="first-merge">
       
    50 	<xsl:variable name="prev">
       
    51 		<xsl:apply-templates select="sysdef[1]" mode="join-sysdef-from-model"/>
       
    52 	</xsl:variable>
       
    53 	
       
    54 	<xsl:apply-templates select="sysdef[2]" mode="mergewith">
       
    55 		<xsl:with-param name="upstream" select="exslt:node-set($prev)/*"/>
       
    56 		<xsl:with-param name="up" select="current()/sysdef[1]"/>
       
    57 	</xsl:apply-templates>
       
    58 </xsl:template>
       
    59 
       
    60 <xsl:template match="sysdef" mode="mergewith">
       
    61 	<xsl:param name="upstream"/>
       
    62 	<xsl:param name="up"/>
       
    63 	<xsl:variable name="downstream">
       
    64 		<xsl:apply-templates select="." mode="join-sysdef-from-model"/>
       
    65 	</xsl:variable>	
       
    66 	
       
    67 	<xsl:variable name="merged">
       
    68 		<xsl:apply-templates mode="merge-models" select="$upstream">
       
    69 			<xsl:with-param name="other" select="exslt:node-set($downstream)/*"/>
       
    70 			<xsl:with-param name="up" select="$up"/>
       
    71 			<xsl:with-param name="down" select="current()"/>
       
    72 		</xsl:apply-templates>
       
    73 	</xsl:variable>
       
    74 	<xsl:choose>
       
    75 		<xsl:when test="following-sibling::sysdef">
       
    76 			<!-- more to come -->
       
    77 			<xsl:apply-templates select="following-sibling::sysdef[1]" mode="mergewith">
       
    78 				<xsl:with-param name="upstream" select="exslt:node-set($merged)/*"/>
       
    79 				<xsl:with-param name="up" select="$up"/> <!-- technically not needed since everything in upstram model is allready populated with root and name data, but needed for completeness -->
       
    80 			</xsl:apply-templates>			
       
    81 		</xsl:when>
       
    82 		<xsl:otherwise><xsl:copy-of select="$merged"/></xsl:otherwise> <!-- we're done, just print-->
       
    83 	</xsl:choose>	
       
    84 </xsl:template>
       
    85 
       
    86 <!-- /merging -->
       
    87 
       
    88 <xsl:template match="*" mode="layout-meta">
       
    89 	<xsl:apply-templates select="*[not(self::sysdef)]" mode="global-meta"/>
       
    90 </xsl:template>
       
    91 
       
    92 <xsl:template match="* | @*" mode="layout-attributes">
       
    93 	<xsl:apply-templates select="." mode="global-attributes"/>
       
    94 </xsl:template>
       
    95 
       
    96 <xsl:template match="/model" mode="layout-attributes">
       
    97 	<xsl:apply-templates select="*[not(self::sysdef)] | @*" mode="layout-attributes"/>
       
    98 	<xsl:if test="not(layout/@detail or @detail)">
       
    99 		<xsl:attribute name="detail">component</xsl:attribute>
       
   100 	</xsl:if>
       
   101 	<!--<xsl:if test="not(layout/@placeholder-detail or @placeholder-detail )">
       
   102 		<xsl:attribute name="placeholder-detail">component</xsl:attribute>
       
   103 	</xsl:if>-->
       
   104 </xsl:template>
       
   105 
       
   106 <xsl:template match="layout" mode="layout-meta"> <!-- ensure it's grouped properly -->
       
   107 	<xsl:if test="info or ../@shapes">
       
   108 		<xsl:element name="meta"><xsl:attribute name="rel">styling</xsl:attribute>
       
   109 			<xsl:apply-templates select="../@shapes | info" mode="styling"/>
       
   110 		</xsl:element>
       
   111 	</xsl:if>
       
   112 	<xsl:apply-templates select="*[not(self::sysdef)]" mode="layout-meta"/>
       
   113 </xsl:template>
       
   114 
       
   115 
       
   116 
       
   117 <xsl:template match="/model[@revision-type='date']/@revision[contains(.,'%') and function-available('date:month-abbreviation')]" mode="layout-attributes">
       
   118 <xsl:attribute name="revision"><xsl:call-template name="format-date"/></xsl:attribute>
       
   119 </xsl:template>
       
   120 
       
   121 
       
   122 <xsl:template match="/model[@revision-type='date' and not(@revision) or @revision='%Y-%m-%d']/@revision-type" mode="layout-attributes" priority="4">
       
   123 	<xsl:copy-of select="."/>
       
   124 	<xsl:if test="function-available('date:date-time')">
       
   125 		<xsl:attribute name="revision"><xsl:value-of select="substring-before(date:date-time(),'T')"/></xsl:attribute>
       
   126 	</xsl:if>
       
   127 </xsl:template>
       
   128 
       
   129 <xsl:template mode="layout-attributes" match="layout">
       
   130 	<xsl:copy-of select="@*"/> 
       
   131 </xsl:template>
       
   132 
       
   133 
       
   134 <!-- new attribute: <values rank="list" default="..."> where list is a space-spearated list of system model item names. 
       
   135 	If not present default applies to all items not referenced by an entry. If present, default only applies to unreferenced items of the specified type --> 
       
   136 
       
   137 
       
   138 <xsl:template match="/values" mode="overlay-meta">
       
   139 	<xsl:param name="item"/><xsl:param name="ns"/><xsl:param name="id"/><xsl:param name="from"/>
       
   140 	<xsl:if test="$from[@type='style' or @type='color' or @type='overlay'] "> <!-- at this point, only pattern, style and color can have multiple values -->
       
   141 		<xsl:variable name="join"><xsl:if test="$from/@type!=''">-</xsl:if></xsl:variable>
       
   142 		<xsl:variable name="value">
       
   143 			<xsl:for-each select="/values/item/*[@ref=$id or substring-after(@ref,':')=$id]">
       
   144 				<xsl:variable name="myns"><xsl:apply-templates select="@ref" mode="my-namespace"/></xsl:variable>
       
   145 				<xsl:if test="$myns = $ns"> <!-- actual match -->
       
   146 					<xsl:element name="generator{$join}{$from/@type}">
       
   147 						 <xsl:attribute name="ref">
       
   148 							<xsl:apply-templates select=".." mode="style-id">
       
   149 								<xsl:with-param select="$from" name="base"/>
       
   150 							</xsl:apply-templates>
       
   151 						</xsl:attribute>
       
   152 					</xsl:element>
       
   153 				</xsl:if>
       
   154 			</xsl:for-each>
       
   155 		</xsl:variable>
       
   156 		<xsl:if test="exslt:node-set($value)/* or (@default and (not(@rank) or contains(concat(' ',normalize-space(@rank),' '), concat(' ',local-name($item),' ')) ))"> 
       
   157 			<xsl:element name="meta"><xsl:attribute name="rel">styling</xsl:attribute>
       
   158 				<xsl:choose>
       
   159 					<xsl:when test="exslt:node-set($value)/*"><xsl:copy-of select="$value"/></xsl:when>
       
   160 					<xsl:when test="@default">
       
   161 						<xsl:element name="generator{$join}{$from/@type}">
       
   162 						 	<xsl:attribute name="ref">
       
   163 								<xsl:apply-templates select="$from" mode="style-id"/>
       
   164 							</xsl:attribute>
       
   165 						</xsl:element>
       
   166 					</xsl:when>
       
   167 				</xsl:choose>
       
   168 			</xsl:element>
       
   169 		</xsl:if>		
       
   170 	</xsl:if>
       
   171 </xsl:template>
       
   172 
       
   173 <xsl:template match="/model/layout/display" mode="overlay-attributes">
       
   174 	<xsl:param name="item"/><xsl:param name="ns"/><xsl:param name="id"/>
       
   175 		<xsl:variable name="myns"><xsl:apply-templates select="@ref" mode="my-namespace"/></xsl:variable>
       
   176 		<xsl:if test="@ref=$id or substring-after(@ref,':')=$id and $myns=$ns">
       
   177 			<xsl:copy-of select="@*[name()!='ref']"/>
       
   178 		</xsl:if>
       
   179 </xsl:template>
       
   180 
       
   181 
       
   182 <xsl:template match="/values" mode="overlay-attributes">
       
   183 	<xsl:param name="item"/><xsl:param name="ns"/><xsl:param name="id"/><xsl:param name="from"/>
       
   184 	<xsl:if test="$from[@type!='style' and @type!='color' and @type!='overlay']"> <!-- style, pattern and colour can have any number of values, so it needs to be captured in an element -->
       
   185 		<xsl:variable name="join"><xsl:if test="$from/@type!=''">-</xsl:if></xsl:variable>
       
   186 		<xsl:for-each select="/values/item/*[@ref=$id or substring-after(@ref,':')=$id]">
       
   187 			<xsl:variable name="myns"><xsl:apply-templates select="@ref" mode="my-namespace"/></xsl:variable>
       
   188 			<xsl:if test="$myns = $ns"> <!-- actual match -->
       
   189 				<xsl:attribute name="generator{$join}{$from/@type}">
       
   190 					<xsl:apply-templates select=".." mode="style-id">
       
   191 						<xsl:with-param select="$from" name="base"/>
       
   192 					</xsl:apply-templates>
       
   193 				</xsl:attribute>
       
   194 			</xsl:if>
       
   195 		</xsl:for-each>
       
   196 	</xsl:if>
       
   197 </xsl:template>
       
   198 
       
   199 <xsl:template match="info" mode="style-id">
       
   200 	<xsl:value-of select="concat('i',count(preceding-sibling::info))"/>
       
   201 </xsl:template>
       
   202 
       
   203 <xsl:template match="/values" mode="style-id"><xsl:param name="base"/>
       
   204 	<xsl:apply-templates select="$base" mode="style-id"/>
       
   205 </xsl:template>
       
   206 
       
   207 <xsl:template match="/values/item" mode="style-id"><xsl:param name="base"/>
       
   208 	<xsl:apply-templates select="$base" mode="style-id"/>-<xsl:value-of select="name()"/>
       
   209 	<xsl:value-of select="count(preceding-sibling::*)"/>
       
   210 </xsl:template>
       
   211 
       
   212 <xsl:template match="info" mode="style-id">
       
   213 	<xsl:value-of select="concat('i',count(preceding-sibling::info))"/>
       
   214 </xsl:template>
       
   215 
       
   216 <xsl:template match="colors|borders|patterns|styles" mode="style-id">
       
   217 	<xsl:value-of select="concat('s',count(preceding-sibling::*))"/>
       
   218 </xsl:template>
       
   219 
       
   220 <xsl:template match="examples/cmp" mode="style-id">
       
   221 	<xsl:value-of select="concat('e',count(preceding::cmp[parent::examples]))"/>
       
   222 </xsl:template>
       
   223 
       
   224 <xsl:template match="note" mode="style-id">
       
   225 	<xsl:value-of select="concat('n',count(preceding::note))"/>
       
   226 </xsl:template>
       
   227 
       
   228 <xsl:template match="legend" mode="style-id">
       
   229 	<xsl:value-of select="concat('L',count(preceding::legend))"/>
       
   230 </xsl:template>
       
   231 
       
   232 <xsl:template match="colors/color|borders/border|patterns/overlay|styles/style" mode="style-id">
       
   233 	<xsl:apply-templates select=".." mode="style-id"/>-<xsl:value-of select="name()"/>
       
   234 	<xsl:value-of select="count(preceding-sibling::*)"/>
       
   235 </xsl:template>
       
   236 
       
   237 <xsl:template match="layout/layer-group" mode="layout-meta">
       
   238 	<xsl:element name="meta"><xsl:attribute name="rel">layer-group</xsl:attribute>
       
   239 	<xsl:copy-of select="."/>
       
   240 	</xsl:element>
       
   241 </xsl:template>
       
   242 
       
   243 <xsl:template match="layout/logo" mode="layout-meta">
       
   244 	<xsl:element name="meta"><xsl:attribute name="rel">model-logo</xsl:attribute>
       
   245 		<xsl:copy><xsl:copy-of select="@width | @height"/>
       
   246 			<xsl:choose>
       
   247 				<xsl:when test="@embed='yes' or @embed='true' ">
       
   248 					<xsl:for-each select="document(@src,.)/s:svg">
       
   249 						<xsl:copy-of select="@viewBox"/>
       
   250 						<xsl:copy-of select="*"/>
       
   251 					</xsl:for-each>
       
   252 				</xsl:when>
       
   253 				<xsl:otherwise><xsl:copy-of select="@src"/></xsl:otherwise>
       
   254 			</xsl:choose>
       
   255 		</xsl:copy>
       
   256 	</xsl:element>
       
   257 </xsl:template>
       
   258 
       
   259 <!-- legend follows -->
       
   260 <xsl:template match="layout/legend" mode="layout-meta">
       
   261 	<xsl:element name="meta"><xsl:attribute name="rel">model-legend</xsl:attribute>
       
   262 		<xsl:copy><xsl:copy-of select="@*[name()!='literal']"/>
       
   263 			<xsl:if test="not(@literal='yes' or @literal='true') and contains(@label,'{')">
       
   264 				<xsl:attribute name="label-ref"><xsl:apply-templates mode="style-id" select="."/></xsl:attribute>
       
   265 			</xsl:if>	
       
   266 			<xsl:apply-templates select="*" mode="layout-meta"/>
       
   267 		</xsl:copy>
       
   268 	</xsl:element>
       
   269 	
       
   270 	<!-- put footer outside of the legend since technically it should be on the bottom of the diagram -->
       
   271 	<xsl:variable name="footer">
       
   272 		<xsl:for-each select="/model/@copyright|/model/@distribution">
       
   273 			<xsl:variable name="a" select="concat('@',name())"/>
       
   274 			<!-- only use footer items if they are not referenced elsewhere in a label -->
       
   275 			<xsl:if test="not(/model/layout//legend[contains(@label,$a)]) and not(/model/layout//legend/note[contains(.,$a)])">
       
   276 				<xsl:value-of select="concat(' ',name(),' ')"/>
       
   277 			</xsl:if>
       
   278 		</xsl:for-each>
       
   279 	</xsl:variable>
       
   280 	<xsl:if test="$footer!=''">
       
   281 		<xsl:element name="meta"><xsl:attribute name="rel">model-footer</xsl:attribute>
       
   282 			<xsl:for-each select="/model/@*[contains($footer,concat(' ',name(),' '))]">
       
   283 				<xsl:element name="{name()}"/>
       
   284 			</xsl:for-each>
       
   285 		</xsl:element>
       
   286 	</xsl:if>
       
   287 </xsl:template>
       
   288 
       
   289 <xsl:template match="legend" mode="layout-meta">
       
   290 	<xsl:copy>
       
   291 		<xsl:copy-of select="@*[name()!='literal']"/>
       
   292 		<xsl:if test="not(@literal='yes' or @literal='true') and contains(@label,'{')">
       
   293 			<xsl:attribute name="label-ref"><xsl:apply-templates mode="style-id" select="."/></xsl:attribute>
       
   294 		</xsl:if>	
       
   295 		<xsl:apply-templates select="*" mode="layout-meta"/>
       
   296 	</xsl:copy>
       
   297 </xsl:template>
       
   298 
       
   299 <xsl:template match="legend/note|legend/s:svg" mode="layout-meta">
       
   300 	<xsl:copy><xsl:copy-of select="@*[name()!='literal']"/>
       
   301 		<xsl:if test="self::note and not(@literal='yes' or @literal='true') and contains(.,'{')">
       
   302 			<xsl:attribute name="label-ref"><xsl:apply-templates mode="style-id" select="."/></xsl:attribute>
       
   303 		</xsl:if>
       
   304 		<xsl:copy-of select="node()"/>
       
   305 	</xsl:copy>
       
   306 </xsl:template>
       
   307 
       
   308 <xsl:template match="legend[s:g]" mode="layout-meta">
       
   309 <xsl:copy-of select="."/>
       
   310 </xsl:template>
       
   311 
       
   312 
       
   313 
       
   314 
       
   315 <xsl:template match="@label" mode="legend-abbrev">
       
   316 	<xsl:variable name="n" select="."/>
       
   317 	<xsl:variable name="match" select="$abbrevs[@name=$n]"/>
       
   318 	<xsl:choose>
       
   319 		<xsl:when test="not($match)"><xsl:copy-of select="."/></xsl:when>
       
   320 		<xsl:otherwise>
       
   321 			<xsl:attribute name="label"><xsl:value-of select="$match/@abbrev"/></xsl:attribute>
       
   322 			<xsl:copy-of select="$match/@font"/>
       
   323 			<xsl:if test="not($match/@font)">
       
   324 				<xsl:copy-of select="$match/ancestor::display-names/@font"/>
       
   325 			</xsl:if>
       
   326 		</xsl:otherwise>
       
   327 	</xsl:choose>
       
   328 </xsl:template>
       
   329 
       
   330 
       
   331 
       
   332 <xsl:template match="legend" mode="legend-copy">
       
   333 	<xsl:copy-of select="@*[name()!='use' or name()='literal']"/>
       
   334 	<xsl:if test="not(@literal='yes' or @literal='true') and contains(@label,'{')">
       
   335 		<xsl:attribute name="label-ref"><xsl:apply-templates mode="style-id" select="."/></xsl:attribute>
       
   336 	</xsl:if>	
       
   337 </xsl:template>
       
   338 
       
   339 <xsl:template match="legend[@use]" mode="layout-meta">
       
   340 	
       
   341 	<!-- 	$tag = bit after the # (can be empty)
       
   342 		$pre is bit before the # (can be empty)
       
   343 		$file is file pointed to by pre (can be empty) -->
       
   344 
       
   345 	<xsl:variable name="tag" select="substring-after(@use,'#')"/>
       
   346 	<xsl:variable name="pre">
       
   347 		<xsl:choose>
       
   348 			<xsl:when test="$tag!=''"><xsl:value-of select="substring-before(@use,'#')"/></xsl:when>
       
   349 			<xsl:otherwise><xsl:value-of select="@use"/></xsl:otherwise>
       
   350 		</xsl:choose>
       
   351 	</xsl:variable>
       
   352 
       
   353 	<xsl:variable name="file">
       
   354 		<xsl:choose>
       
   355 			<xsl:when test="starts-with($pre,'@')"><xsl:value-of select="//model/@*[name()=substring($pre,2)]"/></xsl:when>
       
   356 			<xsl:otherwise><xsl:value-of select="$pre"/></xsl:otherwise>
       
   357 		</xsl:choose>
       
   358 	</xsl:variable>
       
   359 	
       
   360 	<xsl:variable name="model" select="/model"/>  <!--  hack for xsltproc -->
       
   361 	<xsl:variable name="legend" select="."/>  <!--  hack for xsltproc -->
       
   362 
       
   363 	<xsl:variable name="this" select="."/>  <!--  save node just in case need to use more than once -->
       
   364 
       
   365 	
       
   366 	<xsl:choose>
       
   367 		<xsl:when test="$tag!='' and $pre=''">
       
   368 			<!-- pre is empty, but tag is not, so this legend is an info in this file -->
       
   369 			<xsl:for-each select="ancestor::layout/info[@type=$tag]">
       
   370 				<xsl:element name="legend">
       
   371 					<xsl:apply-templates select="$this" mode="legend-copy"/>
       
   372 					<xsl:apply-templates select="." mode="legend-layout">
       
   373 						<xsl:with-param name="model" select="$model"/>
       
   374 						<xsl:with-param name="legend" select="$legend"/>
       
   375 					</xsl:apply-templates>
       
   376 				</xsl:element>
       
   377 			</xsl:for-each>
       
   378 		</xsl:when>
       
   379 		<xsl:when test="$tag!=''">
       
   380 			<xsl:for-each select="document($file,/)/*/*[name()=$tag]">
       
   381 				<xsl:element name="legend">
       
   382 					<xsl:apply-templates select="$this" mode="legend-copy"/>
       
   383 					<xsl:apply-templates select="." mode="legend-layout">
       
   384 						<xsl:with-param name="model" select="$model"/>
       
   385 						<xsl:with-param name="legend" select="$legend"/>
       
   386 					</xsl:apply-templates>
       
   387 				</xsl:element>			
       
   388 			</xsl:for-each>
       
   389 		</xsl:when>
       
   390 		<xsl:otherwise>
       
   391 			<xsl:for-each select="document($file,/)/*">
       
   392 				<xsl:element name="legend">
       
   393 					<xsl:apply-templates select="$this" mode="legend-copy"/>
       
   394 					<xsl:apply-templates select="." mode="legend-layout">
       
   395 						<xsl:with-param name="model" select="$model"/>
       
   396 						<xsl:with-param name="legend" select="$legend"/>
       
   397 					</xsl:apply-templates>
       
   398 				</xsl:element>			
       
   399 			</xsl:for-each>			
       
   400 			</xsl:otherwise>
       
   401 	</xsl:choose>
       
   402 </xsl:template>
       
   403 
       
   404 
       
   405 <xsl:template match="info[(@type='color'  or @type='overlay' or @type='style' or @type='border') and document(@href,.)/values]" mode="legend-layout">
       
   406 	<xsl:attribute name="use"><xsl:apply-templates select="." mode="style-id"/></xsl:attribute>
       
   407 	<xsl:attribute name="type">
       
   408 		<xsl:choose>
       
   409 			<xsl:when test="@type='color'">cbox</xsl:when>
       
   410 			<xsl:otherwise>cmp</xsl:otherwise>
       
   411 		</xsl:choose>
       
   412 	</xsl:attribute>
       
   413 </xsl:template>
       
   414 
       
   415 <xsl:template match="text()" mode="legend-layout"/>
       
   416 
       
   417 <!-- Any ref with a type attribute that starts with a # indicates a literal ref, so just copy it -->
       
   418 <xsl:template match="*[starts-with(@type,'#')]" mode="layout-ref" priority="1"><xsl:value-of select="@type"/></xsl:template>
       
   419 
       
   420 <!-- Borders in legend -->
       
   421 
       
   422 <xsl:template match="border" mode="layout-ref">#Border<xsl:choose>
       
   423 		<xsl:when test="@type"><xsl:value-of select="@type"/></xsl:when>
       
   424 		<xsl:otherwise>Shape<xsl:value-of select="count(preceding::border)"/></xsl:otherwise>
       
   425 	</xsl:choose>
       
   426 </xsl:template>
       
   427 
       
   428 <!-- Colours in legend -->
       
   429 <xsl:template match="color[../@type='highlight' or ../@type='text-highlight']" mode="layout-ref">
       
   430 	<xsl:value-of select="concat('#',../@type,count(preceding::color[../@type]))"/>
       
   431 </xsl:template>
       
   432 
       
   433 <xsl:template match="/shapes/colors/color[not(@value|@label)]" mode="legend-layout" priority="3"/> 	<!-- use value if no label, but don't show if neither -->
       
   434 
       
   435 
       
   436 <!-- can have any number of these, so put in a sub-legend -->
       
   437 <xsl:template match="/shapes/examples" mode="legend-layout"><xsl:param name="model"/>
       
   438 	<xsl:param name="legend"/>	<!-- label on legend overrides label in values document -->
       
   439 	<xsl:variable name="tag" select="name()"/>
       
   440 	<xsl:variable name="content">
       
   441 		<!-- don't show this label if there is a label defined in the Model XML doc *and* this is the first legend item of this type (e.g colors, styles, etc)	 -->
       
   442 		<xsl:choose>
       
   443 			<xsl:when test="@sort='yes'">
       
   444 				<xsl:apply-templates mode="legend-layout">
       
   445 					<xsl:sort select="@label"/>
       
   446 					<xsl:with-param name="model" select="$model"/>
       
   447 				</xsl:apply-templates>
       
   448 			</xsl:when>
       
   449 			<xsl:otherwise>
       
   450 				<xsl:apply-templates mode="legend-layout"><xsl:with-param name="model" select="$model"/></xsl:apply-templates>
       
   451 			</xsl:otherwise>
       
   452 		</xsl:choose>
       
   453 	</xsl:variable>
       
   454 	<xsl:choose>
       
   455 		<xsl:when test="count(//*[name()=$tag]) != 1">
       
   456 			<legend>
       
   457 				<xsl:if test="not($legend) or not($legend/@label) or preceding-sibling::*[name()=$tag]"><xsl:apply-templates select="@label"  mode="legend-abbrev"/></xsl:if>
       
   458 				<xsl:copy-of select="$content"/>
       
   459 			</legend>
       
   460 		</xsl:when>
       
   461 		<xsl:otherwise>
       
   462 			<xsl:copy-of select="@sort|@show-unused"/>
       
   463 			<xsl:if test="not($legend) or not($legend/@label) or preceding-sibling::*[name()=$tag]"><xsl:apply-templates select="@label"  mode="legend-abbrev"/></xsl:if>
       
   464 			<xsl:copy-of select="$content"/></xsl:otherwise>
       
   465 	</xsl:choose>
       
   466 </xsl:template>
       
   467 
       
   468 
       
   469 <!-- can have any number of these, so put in a sub-legend -->
       
   470 <xsl:template match="/shapes/styles|/shapes/colors|/shapes/patterns|/shapes/borders" mode="legend-layout">
       
   471 	<xsl:variable name="tag" select="name()"/>
       
   472 	<xsl:choose>
       
   473 		<xsl:when test="count(//*[name()=$tag]) != 1">
       
   474 			<xsl:element name="legend">
       
   475 				<xsl:copy-of select="@sort|@show-unused"/>
       
   476 				<xsl:attribute name="use"><xsl:apply-templates select="." mode="style-id"/></xsl:attribute>		
       
   477 				<xsl:attribute name="type">cmp</xsl:attribute>
       
   478 			</xsl:element>
       
   479 		</xsl:when>
       
   480 		<xsl:otherwise>
       
   481 			<xsl:copy-of select="@sort|@show-unused"/>
       
   482 			<xsl:attribute name="use"><xsl:apply-templates select="." mode="style-id"/></xsl:attribute>		
       
   483 			<xsl:attribute name="type">cmp</xsl:attribute>		
       
   484 		</xsl:otherwise>
       
   485 	</xsl:choose>
       
   486 </xsl:template>
       
   487 
       
   488 
       
   489 <xsl:template match="overlay" mode="layout-ref">#Pattern<xsl:choose>
       
   490 		<xsl:when test="@type"><xsl:value-of select="@type"/></xsl:when>
       
   491 		<xsl:otherwise>Overlay<xsl:value-of select="count(preceding::overlay)"/></xsl:otherwise>
       
   492 	</xsl:choose>
       
   493 </xsl:template>
       
   494 
       
   495 	
       
   496 <xsl:template match="/shapes/*/*[not(@label)]" mode="legend-layout"/> <!--  don't show legend items with no label -->
       
   497 	
       
   498 
       
   499 
       
   500 <xsl:template match="/shapes" mode="as-example"><xsl:param name="at"/>
       
   501 	<xsl:choose>
       
   502 		<xsl:when test="name($at)='border' or name($at)='overlay'">
       
   503 			<xsl:attribute name="generator-{name($at)}">
       
   504 				<xsl:apply-templates  select="//*[name()=name($at) and @label=$at]" mode="style-id"/>
       
   505 			</xsl:attribute>
       
   506 		</xsl:when>
       
   507 		<xsl:when test="name($at)='style'">
       
   508 			<xsl:attribute name="generator-{name($at)}"><xsl:apply-templates  select="//style[@label=$at]" mode="style-id"/></xsl:attribute>			
       
   509 		</xsl:when>	
       
   510 		<xsl:when test="name($at)='color-highlight'">
       
   511 			<xsl:attribute name="generator-highlight">
       
   512 				<xsl:apply-templates select="//colors[@type='highlight']/color[@label=$at]" mode="style-id"/>
       
   513 			</xsl:attribute>
       
   514 		</xsl:when>	
       
   515 		<xsl:when test="name($at)='color-text-highlight'">
       
   516 			<xsl:attribute name="generator-text-highlight">
       
   517 				<xsl:apply-templates select="//colors[@type='text-highlight']/color[@label=$at]" mode="style-id"/>
       
   518 			</xsl:attribute>
       
   519 		</xsl:when>	
       
   520 		<xsl:when test="name($at)='color'">
       
   521 			<xsl:attribute name="generator-color">
       
   522 				<xsl:apply-templates select="//colors[not(@type) or @type='background']/color[@label=$at]/@color" mode="style-id"/>
       
   523 			</xsl:attribute>
       
   524 		</xsl:when>	
       
   525 	</xsl:choose>
       
   526 </xsl:template>
       
   527 
       
   528 
       
   529 
       
   530 <xsl:template match="@color" mode="generated-value"><xsl:param name="model"/>
       
   531 	<xsl:variable name="v" select="."/>
       
   532 	<xsl:variable name="m" select="//color[@label=$v]"/>
       
   533 	<xsl:choose>
       
   534 		<xsl:when test="count($m)">
       
   535 			<xsl:attribute name="generator-color"><xsl:apply-templates select="$m" mode="style-id"/></xsl:attribute>
       
   536 		</xsl:when>
       
   537 		<xsl:when test="$model//info[@type='color']">
       
   538 			<xsl:attribute name="generator-color">
       
   539 				<xsl:variable name="m0" select="$model//info[@type='color']/@href"/>
       
   540 				<xsl:apply-templates select="document($m0/@href,$m0)//item[@label=$v]" mode="style-id">
       
   541 					<xsl:with-param name="base" select="$m0"/>
       
   542 				</xsl:apply-templates>
       
   543 			</xsl:attribute>
       
   544 		</xsl:when>		
       
   545 	</xsl:choose>
       
   546 </xsl:template>
       
   547 
       
   548 <xsl:template match="examples/cmp" mode="legend-layout"><xsl:param name="model"/><xsl:param name="shapes" select="/shapes"/>
       
   549 	<cmp>
       
   550 		<xsl:if test="not(@literal='yes' or @literal='true') and contains(.,'{')">
       
   551 			<xsl:attribute name="label-ref"><xsl:apply-templates mode="style-id" select="."/></xsl:attribute>
       
   552 		</xsl:if>	
       
   553 		<xsl:for-each select="@*">
       
   554 			<xsl:apply-templates select="$shapes" mode="as-example">
       
   555 				<xsl:with-param name="at" select="."/>
       
   556 			</xsl:apply-templates>
       
   557 		</xsl:for-each>
       
   558 		<xsl:apply-templates mode="generated-value" select="@color">
       
   559 			<xsl:with-param name="model" select="$model"/>
       
   560 		</xsl:apply-templates>
       
   561 		<xsl:copy-of select="text()"/>
       
   562 	</cmp>
       
   563 </xsl:template>
       
   564 
       
   565 
       
   566 <xsl:template match="/shapes/colors[not(*)]" mode="legend-layout"><xsl:param name="model"/>
       
   567 <!-- special known type which can be generated -->
       
   568 	<xsl:choose>
       
   569 		<xsl:when test="count(//colors) != 1 and @match='@ts' and $model">
       
   570 			<legend>
       
   571 				<xsl:attribute name="use"><xsl:apply-templates select="." mode="style-id"/></xsl:attribute>
       
   572 				<xsl:attribute name="sort">yes</xsl:attribute>
       
   573 				<xsl:attribute name="type">cbox</xsl:attribute>
       
   574 			</legend>
       
   575 		</xsl:when>
       
   576 		<xsl:when test="@match='@ts' and $model">
       
   577 			<xsl:attribute name="use"><xsl:apply-templates select="." mode="style-id"/></xsl:attribute>
       
   578 			<xsl:attribute name="sort">yes</xsl:attribute>
       
   579 			<xsl:attribute name="type">cbox</xsl:attribute>
       
   580 		</xsl:when>
       
   581 		<xsl:otherwise>
       
   582 		<!--	<xsl:call-template name="Caller-Warning"><xsl:with-param name="text">no colour data</xsl:with-param></xsl:call-template> -->
       
   583 		</xsl:otherwise>
       
   584 	</xsl:choose>
       
   585 </xsl:template>
       
   586 
       
   587 <!-- styling stuff  -->
       
   588 <xsl:template match="node()" mode="styling"/>
       
   589 
       
   590 <xsl:template match="@shapes" mode="styling">
       
   591 	<xsl:variable name="model" select=".."/> <!-- hack for xsltproc -->
       
   592 	<xsl:apply-templates select="document(.,.)/shapes/*" mode="styling">
       
   593 		<xsl:with-param name="model" select="$model"/>
       
   594 	</xsl:apply-templates>
       
   595 </xsl:template>
       
   596 
       
   597 
       
   598 <xsl:template match="layout/info[@type='color' or @type='border' or @type='overlay' or @type='style']" mode="styling">
       
   599 	<xsl:variable name="id"><xsl:apply-templates select="." mode="style-id"/></xsl:variable>
       
   600 	<xsl:variable name="base" select="."/>
       
   601 	<group style-id="{$id}">
       
   602 		<xsl:copy-of select="@type | @show-unused"/>
       
   603 		<xsl:for-each select="document(@href,.)/values">
       
   604 		<xsl:choose>
       
   605 			<xsl:when test="contains(normalize-space(@rank),' ')"/>
       
   606 			<xsl:when test="@rank"><xsl:attribute name="detail"><xsl:value-of select="@rank"/></xsl:attribute></xsl:when>
       
   607 			<xsl:otherwise><xsl:attribute name="detail">component</xsl:attribute></xsl:otherwise>
       
   608 		</xsl:choose>
       
   609 		</xsl:for-each>
       
   610 		<xsl:for-each select="document(@href,.)/values">
       
   611 			<xsl:copy-of select="@default"/>
       
   612 			<xsl:apply-templates select="@label"  mode="legend-abbrev"/>				
       
   613 			<xsl:for-each select="item">
       
   614 				<xsl:variable name="el">
       
   615 					<xsl:choose>
       
   616 						<xsl:when test="$base/@type='color'">cbox</xsl:when>
       
   617 						<xsl:otherwise>cmp</xsl:otherwise>
       
   618 					</xsl:choose>
       
   619 				</xsl:variable>
       
   620 				<xsl:element name="{$el}">
       
   621 					<xsl:attribute name="style-id">
       
   622 						<xsl:apply-templates select="." mode="style-id">
       
   623 							<xsl:with-param name="base" select="$base"/>
       
   624 						</xsl:apply-templates>
       
   625 					</xsl:attribute>
       
   626 					<xsl:apply-templates select="@label"  mode="legend-abbrev"/>	
       
   627 					<xsl:attribute name="value">
       
   628 					<xsl:choose>
       
   629 						<xsl:when test="not(starts-with(@value,'#')) and $base/@type='border' ">#Border<xsl:value-of select="@value"/></xsl:when> 
       
   630 						<xsl:when test="not(starts-with(@value,'#')) and $base/@type='overlay' ">#Pattern<xsl:value-of select="@value"/></xsl:when>
       
   631 							<!-- highlight not allowed in values files, but put here anyway -->
       
   632 						<xsl:when test="contains($base/@type,'highlight')">#<xsl:value-of select="$base/@type"/>
       
   633 							<xsl:apply-templates select="." mode="style-id">
       
   634 								<xsl:with-param name="base" select="$base"/>
       
   635 							</xsl:apply-templates></xsl:when>
       
   636 						<xsl:otherwise><xsl:value-of select="@value"/></xsl:otherwise>
       
   637 					</xsl:choose>
       
   638 					</xsl:attribute>
       
   639 				</xsl:element>
       
   640 			</xsl:for-each>
       
   641 		</xsl:for-each>
       
   642 	</group>
       
   643 </xsl:template>
       
   644 
       
   645 <xsl:template name="lgd-group-detail">
       
   646 	<xsl:choose>
       
   647 		<xsl:when test="@detail"><xsl:copy-of select="@detail"/></xsl:when>
       
   648 		<xsl:when test="self::borders or  not(@match)"><xsl:attribute name="detail">component</xsl:attribute></xsl:when>
       
   649 		<xsl:when test="@match='component' or @match='collection' or @match='package' or @match='layer'">
       
   650 			<xsl:attribute name="detail"><xsl:value-of select="@match"/></xsl:attribute>
       
   651 		</xsl:when>
       
   652 	</xsl:choose>
       
   653 </xsl:template>
       
   654 
       
   655 <xsl:template match="/shapes/colors[@match='@ts' and not(*)]" mode="styling" priority="4"/> <!-- no longer supported -->
       
   656 
       
   657 <xsl:template match="/shapes/borders|/shapes/patterns|/shapes/styles|/shapes/colors" mode="styling"><xsl:param name="model"/>
       
   658 	<xsl:variable name="id"><xsl:apply-templates select="." mode="style-id"/></xsl:variable>
       
   659 	<group type="{name(*)}" style-id="{$id}">
       
   660 		<xsl:attribute name="type">
       
   661 			<xsl:choose>
       
   662 				<xsl:when test="self::colors and @type='background' ">color</xsl:when>
       
   663 				<xsl:when test="@type"><xsl:value-of select="@type"/></xsl:when>
       
   664 				<xsl:otherwise><xsl:value-of select="name(*)"/></xsl:otherwise>
       
   665 			</xsl:choose>
       
   666 		</xsl:attribute>
       
   667 		<xsl:call-template name="lgd-group-detail"/>
       
   668 		<xsl:copy-of select="@default"/>
       
   669 		<xsl:apply-templates select="@label"  mode="legend-abbrev"/>	
       
   670 		<xsl:apply-templates mode="styling"><xsl:with-param name="id" select="$id"/></xsl:apply-templates>
       
   671 	</group>
       
   672 </xsl:template>
       
   673 
       
   674 <xsl:template match="/shapes/colors/color|/shapes/borders/border|/shapes/patterns/overlay|/shapes/styles/style" mode="styling">
       
   675 	<xsl:variable name="my-id"><xsl:apply-templates select="." mode="style-id"/></xsl:variable>
       
   676 	<xsl:variable name="el">
       
   677 		<xsl:choose>
       
   678 			<xsl:when test="self::color[../@type='highlight' or ../@type='text-highlight']">cmp</xsl:when>
       
   679 			<xsl:when test="self::color">cbox</xsl:when>
       
   680 			<xsl:otherwise>cmp</xsl:otherwise>
       
   681 		</xsl:choose>
       
   682 	</xsl:variable>
       
   683 	<xsl:element name="{$el}">
       
   684 		<xsl:attribute name="style-id"><xsl:value-of select="$my-id"/></xsl:attribute>
       
   685 		<xsl:apply-templates select="@label"  mode="legend-abbrev"/>
       
   686 		<xsl:if test="contains(@label,'{') or @count">
       
   687 			<xsl:attribute name="label-ref"><xsl:value-of select="$my-id"/></xsl:attribute>
       
   688 		</xsl:if>
       
   689 		<xsl:if test="@value">
       
   690 			<xsl:attribute name="lookup"><xsl:value-of select="@value"/></xsl:attribute>
       
   691 		</xsl:if>
       
   692 		<xsl:attribute name="value">	
       
   693 			<xsl:choose>
       
   694 				<xsl:when test="self::style"><xsl:value-of select="."/></xsl:when>
       
   695 				<xsl:when test="self::color[not(../@type) or ../@type='background']"><xsl:value-of select="@color"/></xsl:when>
       
   696 				<xsl:otherwise><xsl:apply-templates select="." mode="layout-ref"/></xsl:otherwise>
       
   697 			</xsl:choose>
       
   698 		</xsl:attribute>
       
   699 	</xsl:element>
       
   700 </xsl:template>
       
   701 
       
   702 
       
   703 <!-- consider making this just an optional call to template so it does nothing if it's not needed -->
       
   704 <xsl:template mode="is-content-filtered" match="*" priority="5"><xsl:param name="content"/>
       
   705 	<xsl:if test="function-available('exslt:node-set') and count(exslt:node-set($content)/*[not(self::meta)])!=count(*[not(self::meta)])"> 
       
   706 		<xsl:attribute name="filtered">yes</xsl:attribute>
       
   707 	</xsl:if>
       
   708 </xsl:template>
       
   709 
       
   710 
       
   711 
       
   712 <!-- internal routines follows -->
       
   713 
       
   714 <!-- for date formatting: only use if the date functions are *fully* supported (ie not by xalan)
       
   715 Uses unix date %-encoding, but only a few are supported (see comments)
       
   716 -->  
       
   717 <xsl:template name="format-date"><xsl:param name="date" select="."/>
       
   718 	<xsl:choose>
       
   719 		<xsl:when test="contains($date,'%')">
       
   720 			<xsl:value-of select="substring-before($date,'%')"/>
       
   721 			<xsl:variable name="rest" select="substring-after($date,'%')"/>
       
   722 			<xsl:choose>
       
   723 				<xsl:when test="starts-with($rest,'%') or $rest=''">%</xsl:when> <!-- %%     a literal % -->
       
   724 				<xsl:when test="starts-with($rest,'a')"><xsl:value-of select="date:day-abbreviation()"/></xsl:when> <!--      %a     locale’s abbreviated weekday name (e.g., Sun) -->
       
   725 				<xsl:when test="starts-with($rest,'A')"><xsl:value-of select="date:day-name()"/></xsl:when> <!--  %A     locale’s full weekday name (e.g., Sunday)-->
       
   726 				<xsl:when test="starts-with($rest,'b') or starts-with($rest,'h')"><xsl:value-of select="date:month-abbreviation()"/></xsl:when><!--       %b     locale’s abbreviated month name (e.g., Jan)-->
       
   727 				<xsl:when test="starts-with($rest,'B')"><xsl:value-of select="date:month-name()"/></xsl:when><!--       %B     locale’s full month name (e.g., January)-->
       
   728 				<xsl:when test="starts-with($rest,'d')"><xsl:number format="01" value="date:day-in-month()"/></xsl:when><!--%d     day of month (e.g, 01)-->
       
   729 				<xsl:when test="starts-with($rest,'e')"><xsl:number format=" 1" value="date:day-in-month()"/></xsl:when><!--%d     day of month (e.g, 01)-->
       
   730 				<xsl:when test="starts-with($rest,'F')"><xsl:value-of select="date:date()"/></xsl:when><!--%F     full date; same as %Y-%m-%d-->
       
   731 				<xsl:when test="starts-with($rest,'H')"><xsl:number format="01" value="date:hour-in-day()"/></xsl:when><!--%H     hour (00..23)-->
       
   732 				<xsl:when test="starts-with($rest,'I')"><xsl:number format="01" value="((24 + date:hour-in-day() - 1) mod 12) + 1"/></xsl:when><!--%I     hour (01..12)-->
       
   733 				<xsl:when test="starts-with($rest,'j')"><xsl:number format="001" value="date:day-in-year()"/></xsl:when><!--%j     day of year (001..366)-->
       
   734 				<xsl:when test="starts-with($rest,'k')"><xsl:number format=" 1" value="date:hour-in-day()"/></xsl:when><!--%k     hour ( 0..23)-->
       
   735 				<xsl:when test="starts-with($rest,'l')"><xsl:number format=" 1" value="((24 + date:hour-in-day() - 1) mod 12) + 1"/></xsl:when><!--%l     hour ( 1..12)-->
       
   736 				<xsl:when test="starts-with($rest,'m')"><xsl:number format="01" value="date:month-in-year()"/></xsl:when><!--%m     month (01..12)-->
       
   737 				<xsl:when test="starts-with($rest,'M')"><xsl:number format="01" value="date:minute-in-hour()"/></xsl:when><!--%M     minute (00..59)-->
       
   738 				<xsl:when test="starts-with($rest,'p') and date:hour-in-day() &lt; 12">AM</xsl:when><!--%p     locale’s equivalent of either AM or PM; blank if not known-->
       
   739 				<xsl:when test="starts-with($rest,'p')">PM</xsl:when><!--%p     locale's equivalent of either AM or PM; blank if not known-->
       
   740 				<xsl:when test="starts-with($rest,'P') and date:hour-in-day() &lt; 12">am</xsl:when><!--%P     like %p, but lower case-->
       
   741 				<xsl:when test="starts-with($rest,'P')">pm</xsl:when><!--%P     like %p, but lower case-->
       
   742 				<xsl:when test="starts-with($rest,'S')"><xsl:number format="01" value="date:second-in-minute()"/></xsl:when><!--%S     second (00..60)-->
       
   743 				<xsl:when test="starts-with($rest,'T')"><xsl:value-of select="date:time()"/></xsl:when><!--%T     time; same as %H:%M:%S-->
       
   744 				<xsl:when test="starts-with($rest,'u')"><xsl:value-of select="((date:day-in-week() +5) mod 7) + 1"/></xsl:when><!--%u     day of week (1..7); 1 is Monday-->
       
   745 				<xsl:when test="starts-with($rest,'V')"><xsl:value-of select="date:week-in-year()"/></xsl:when><!--%V     ISO week number, with Monday as first day of week (01..53)-->
       
   746 				<xsl:when test="starts-with($rest,'w')"><xsl:value-of select="date:day-in-week() - 1"/></xsl:when><!--%w     day of week (0..6); 0 is Sunday-->
       
   747 				<xsl:when test="starts-with($rest,'y')"><xsl:value-of select="date:year() mod 100"/></xsl:when><!--%y     last two digits of year (00..99)-->
       
   748 				<xsl:when test="starts-with($rest,'Y')"><xsl:value-of select="date:year()"/></xsl:when><!--%Y     year-->
       
   749 				<xsl:otherwise><xsl:value-of select="substring($rest,1,1)"/></xsl:otherwise>
       
   750 			</xsl:choose>
       
   751 			<xsl:if test="string-length($rest) &gt; 1">
       
   752 				<xsl:call-template name="format-date">
       
   753 					<xsl:with-param name="date" select="substring($rest,2)"/>
       
   754 				</xsl:call-template>
       
   755 			</xsl:if>
       
   756 		</xsl:when>
       
   757 		<xsl:otherwise><xsl:value-of select="$date"/></xsl:otherwise>
       
   758 	</xsl:choose>
       
   759 </xsl:template>
       
   760 
       
   761 
       
   762 </xsl:stylesheet>