[yelp-xsl] mal2html-gloss: Merge gloss:term based on id attribute



commit aeac15f1d977aecab468dc9914229f8ea7c9557b
Author: Shaun McCance <shaunm gnome org>
Date:   Mon Jul 11 09:50:08 2011 -0400

    mal2html-gloss: Merge gloss:term based on id attribute

 xslt/mallard/common/mal-gloss.xsl    |  124 +++++++++++++++++++++++-----------
 xslt/mallard/html/mal2html-gloss.xsl |   82 ++++++++++-------------
 xslt/mallard/html/mal2html-page.xsl  |    8 +-
 3 files changed, 125 insertions(+), 89 deletions(-)
---
diff --git a/xslt/mallard/common/mal-gloss.xsl b/xslt/mallard/common/mal-gloss.xsl
index 9234821..8e7ef4a 100644
--- a/xslt/mallard/common/mal-gloss.xsl
+++ b/xslt/mallard/common/mal-gloss.xsl
@@ -20,8 +20,9 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                 xmlns:mal="http://projectmallard.org/1.0/";
                 xmlns:cache="http://projectmallard.org/cache/1.0/";
                 xmlns:gloss="http://projectmallard.org/experimental/gloss/";
+                xmlns:exsl="http://exslt.org/common";
                 xmlns:str="http://exslt.org/strings";
-                exclude-result-prefixes="mal cache gloss str"
+                exclude-result-prefixes="mal cache gloss exsl str"
                 version="1.0">
 
 <!--!!==========================================================================
@@ -34,12 +35,12 @@ with the Mallard Glossary extension.
 
 
 <xsl:key name="mal.gloss.key"
-         match="/cache:cache//mal:info/gloss:term"
-         use="mal:title[1]"/>
+         match="/cache:cache//mal:info/gloss:term[ id]"
+         use="@id"/>
 
 
 <!--**==========================================================================
-mal.gloss.terms
+mal.gloss.match
 Determine whether a glossary term matches a criterion.
 $match: A #{gloss:match} element containing criteria.
 $term: A #{gloss:term} element to attempt to match.
@@ -65,49 +66,94 @@ mal.gloss.terms
 Output the glossary terms for a page or section.
 $node: The glossary #{page} or #{section} to output terms for.
 
-This template outputs the terms that should be displayed for ${node}. Terms are
-output as full copies from @{mal.cache}, except they the #{gloss:id} attribute
-added. This attribute contains an ID for the #{term} element in the cache, as
-generated by the #{generate-id} function.
-
-This template filters the results based on any #{gloss:match} elements in the
-#{info} child of ${node}, and also excludes terms that are matched by child
-sections of ${node}. Terms with the same primary title are all included. It
-is the responsibility of the caller to merge these.
-
-The results are not sorted. The output is a result tree fragment.  To use these
-results, call #{exsl:node-set} on them.
+This template outputs the terms that should be displayed for ${node}.This output
+is a result tree fragment. To use these results, call #{exsl:node-set} on them.
+This template locates all terms throughout all pages and filters them based on
+any #{gloss:match} elements in the #{info} child of ${node}, and also excludes
+terms that are matched by child sections of ${node}.
+
+The filtered terms are then grouped by matching ID. For each unique ID, this
+template outputs a #{gloss:term} element with the corresponding #{id} attribute.
+Each of these elements contains #{title} elements reflecting the titles in the
+actual term definitions. These titles have duplicates removed, compared by the
+space-normalized string value, and are sorted.
+
+These #{gloss:term} elements then contain further #{gloss:term} elements, which
+are copies of the actual terms with the same ID. These elements have an #{xref}
+attribute added containing the ID of the containing page.
+
+The top-level #{gloss:term} elements and the #{gloss:term} elements they contain
+are not sorted. Only the #{title} elements in the top-level #{gloss:term}
+elements are sorted.
 -->
 <xsl:template name="mal.gloss.terms">
   <xsl:param name="node" select="."/>
-  <xsl:for-each select="$mal.cache//mal:info/gloss:term">
-    <xsl:variable name="term" select="."/>
-    <xsl:variable name="exclude">
-      <xsl:for-each select="$node/ancestor-or-self::*/mal:info/gloss:match">
-        <xsl:call-template name="mal.gloss.match">
-          <xsl:with-param name="match" select="."/>
-          <xsl:with-param name="term" select="$term"/>
-        </xsl:call-template>
-      </xsl:for-each>
-      <xsl:for-each select="$node/mal:section/mal:info/gloss:match">
-        <xsl:variable name="secmatch">
+  <xsl:variable name="allterms_">
+    <xsl:for-each select="$mal.cache//mal:info/gloss:term[ id]">
+      <xsl:variable name="term" select="."/>
+      <xsl:variable name="exclude">
+        <xsl:for-each select="$node/ancestor-or-self::*/mal:info/gloss:match">
           <xsl:call-template name="mal.gloss.match">
             <xsl:with-param name="match" select="."/>
             <xsl:with-param name="term" select="$term"/>
           </xsl:call-template>
+        </xsl:for-each>
+        <xsl:for-each select="$node/mal:section/mal:info/gloss:match">
+          <xsl:variable name="secmatch">
+            <xsl:call-template name="mal.gloss.match">
+              <xsl:with-param name="match" select="."/>
+              <xsl:with-param name="term" select="$term"/>
+            </xsl:call-template>
+          </xsl:variable>
+          <xsl:if test="$secmatch = ''">
+            <xsl:text>x</xsl:text>
+          </xsl:if>
+        </xsl:for-each>
+      </xsl:variable>
+      <xsl:if test="$exclude = ''">
+        <xsl:copy>
+          <xsl:attribute name="xref">
+            <xsl:value-of select="ancestor::mal:page[1]/@id"/>
+          </xsl:attribute>
+          <xsl:for-each select="@*[name() != 'xref'] | *">
+            <xsl:choose>
+              <xsl:when test="self::mal:title">
+                <xsl:copy>
+                  <xsl:attribute name="title">
+                    <xsl:value-of select="normalize-space(.)"/>
+                  </xsl:attribute>
+                  <xsl:copy-of select="node()"/>
+                </xsl:copy>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:copy-of select="."/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </xsl:copy>
+      </xsl:if>
+    </xsl:for-each>
+  </xsl:variable>
+  <xsl:variable name="allterms" select="exsl:node-set($allterms_)/gloss:term"/>
+  <xsl:for-each select="$allterms">
+    <xsl:if test="not(@id = preceding-sibling::gloss:term/@id)">
+      <xsl:variable name="id" select="@id"/>
+      <gloss:term id="{$id}">
+        <xsl:variable name="entries" select="$allterms/self::gloss:term[ id = $id]"/>
+        <xsl:variable name="titles_">
+          <xsl:for-each select="$entries/mal:title">
+            <xsl:copy-of select="."/>
+          </xsl:for-each>
         </xsl:variable>
-        <xsl:if test="$secmatch = ''">
-          <xsl:text>x</xsl:text>
-        </xsl:if>
-      </xsl:for-each>
-    </xsl:variable>
-    <xsl:if test="$exclude = ''">
-      <xsl:copy>
-        <xsl:attribute name="gloss:id">
-          <xsl:value-of select="generate-id(.)"/>
-        </xsl:attribute>
-        <xsl:copy-of select="node()"/>
-      </xsl:copy>
+        <xsl:variable name="titles" select="exsl:node-set($titles_)/mal:title"/>
+        <xsl:for-each select="$titles">
+          <xsl:sort select="string(.)"/>
+          <xsl:if test="not(@title = preceding-sibling::mal:title/@title)">
+            <xsl:copy-of select="."/>
+          </xsl:if>
+        </xsl:for-each>
+        <xsl:copy-of select="$entries"/>
+      </gloss:term>
     </xsl:if>
   </xsl:for-each>
 </xsl:template>
diff --git a/xslt/mallard/html/mal2html-gloss.xsl b/xslt/mallard/html/mal2html-gloss.xsl
index fc6660d..e196698 100644
--- a/xslt/mallard/html/mal2html-gloss.xsl
+++ b/xslt/mallard/html/mal2html-gloss.xsl
@@ -53,55 +53,45 @@ include a link to their defining page.
       <xsl:with-param name="node" select="$node"/>
     </xsl:call-template>
   </xsl:variable>
-  <xsl:variable name="terms" select="exsl:node-set($terms_)/*"/>
+  <xsl:variable name="terms" select="exsl:node-set($terms_)/gloss:term"/>
   <xsl:if test="count($terms) > 0">
     <dl class="list gloss-list">
       <xsl:for-each select="$terms">
-        <xsl:sort select="string(mal:title)"/>
-        <xsl:variable name="term" select="."/>
-        <xsl:for-each select="$mal.cache">
-          <xsl:variable name="primaryid" select="generate-id(
-                                                 key('mal.gloss.key', $term/mal:title[1])
-                                                 [generate-id(.) = $terms/@gloss:id][1])"/>
-          <xsl:if test="not($primaryid = $terms/@gloss:id) or $term/@gloss:id = $primaryid">
-            <dt class="gloss-term">
-              <xsl:apply-templates mode="mal2html.inline.mode"
-                                   select="$term/mal:title/node()"/>
-            </dt>
-            <xsl:variable name="defs" select="key('mal.gloss.key', $term/mal:title[1])
-                                              [generate-id(.) = $terms/@gloss:id]"/>
-            <xsl:for-each select="$defs">
-              <xsl:sort data-type="number" select="number(boolean(*[not(self::mal:title)]))"/>
-              <xsl:sort data-type="number" select="number(not(ancestor::mal:page[1]/@id = $pageid))"/>
-              <xsl:variable name="termpageid" select="ancestor::mal:page[1]/@id"/>
-              <xsl:if test="not($termpageid = $pageid)">
-                <dd class="gloss-link">
-                  <a>
-                    <xsl:attribute name="href">
-                      <xsl:call-template name="mal.link.target">
-                        <xsl:with-param name="xref" select="$termpageid"/>
-                      </xsl:call-template>
-                    </xsl:attribute>
-                    <xsl:attribute name="title">
-                      <xsl:call-template name="mal.link.tooltip">
-                        <xsl:with-param name="xref" select="$termpageid"/>
-                      </xsl:call-template>
-                    </xsl:attribute>
-                    <xsl:call-template name="mal.link.content">
-                      <xsl:with-param name="node" select="."/>
-                      <xsl:with-param name="xref" select="$termpageid"/>
-                      <xsl:with-param name="role" select="'gloss:page'"/>
-                    </xsl:call-template>
-                  </a>
-                </dd>
-              </xsl:if>
-              <xsl:if test="*[not(self::mal:title)]">
-                <dd class="gloss-def">
-                  <xsl:apply-templates mode="mal2html.block.mode"
-                                       select="*[not(self::mal:title)]"/>
-                </dd>
-              </xsl:if>
-            </xsl:for-each>
+        <xsl:sort select="normalize-space(mal:title[1])"/>
+        <xsl:for-each select="mal:title">
+          <dt class="gloss-term">
+            <xsl:apply-templates mode="mal2html.inline.mode" select="node()"/>
+          </dt>
+        </xsl:for-each>
+        <xsl:for-each select="gloss:term">
+          <xsl:sort data-type="number" select="number(boolean(*[not(self::mal:title)]))"/>
+          <xsl:sort data-type="number" select="number(not(ancestor::mal:page[1]/@id = $pageid))"/>
+          <xsl:if test="not(@xref = $pageid)">
+            <dd class="gloss-link">
+              <a>
+                <xsl:attribute name="href">
+                  <xsl:call-template name="mal.link.target">
+                    <xsl:with-param name="xref" select="@xref"/>
+                  </xsl:call-template>
+                </xsl:attribute>
+                <xsl:attribute name="title">
+                  <xsl:call-template name="mal.link.tooltip">
+                    <xsl:with-param name="xref" select="@xref"/>
+                  </xsl:call-template>
+                </xsl:attribute>
+                <xsl:call-template name="mal.link.content">
+                  <xsl:with-param name="node" select="."/>
+                  <xsl:with-param name="xref" select="@xref"/>
+                  <xsl:with-param name="role" select="'gloss:page'"/>
+                </xsl:call-template>
+              </a>
+            </dd>
+          </xsl:if>
+          <xsl:if test="*[not(self::mal:title)]">
+            <dd class="gloss-def">
+              <xsl:apply-templates mode="mal2html.block.mode"
+                                   select="*[not(self::mal:title)]"/>
+            </dd>
           </xsl:if>
         </xsl:for-each>
       </xsl:for-each>
diff --git a/xslt/mallard/html/mal2html-page.xsl b/xslt/mallard/html/mal2html-page.xsl
index dbf3ea1..0a6b0ac 100644
--- a/xslt/mallard/html/mal2html-page.xsl
+++ b/xslt/mallard/html/mal2html-page.xsl
@@ -783,9 +783,12 @@ div.facet input {
   margin: 0;
 }
 dt.gloss-term {
+  margin-top: 1.2em;
   font-weight: bold;
   color: </xsl:text><xsl:value-of select="$color.text_light"/><xsl:text>;
 }
+dt.gloss-term:first-child, dt.gloss-term + dt.gloss-term { margin-top: 0; }
+dt.gloss-term + dd { margin-top: 0.2em; }
 dd.gloss-link {
   margin: 0 0.2em 0 0.2em;
   border-</xsl:text><xsl:value-of select="$left"/><xsl:text>: solid 4px </xsl:text>
@@ -793,14 +796,11 @@ dd.gloss-link {
   padding-</xsl:text><xsl:value-of select="$left"/><xsl:text>: 1em;
 }
 dd.gloss-def {
-  margin: 0 0.2em 0 0.2em;
+  margin: 0 0.2em 1em 0.2em;
   border-</xsl:text><xsl:value-of select="$left"/><xsl:text>: solid 4px </xsl:text>
     <xsl:value-of select="$color.gray_border"/><xsl:text>;
   padding-</xsl:text><xsl:value-of select="$left"/><xsl:text>: 1em;
 }
-dd.gloss-def + dd.gloss-link {
-  margin-top: 1em;
-}
 </xsl:text>
 <xsl:if test="$mal2html.editor_mode">
 <xsl:text>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]