ulink fixes. (initial implementation of out-of-line handling of ulinks)
authorMichael Smith <xmldoc@users.sourceforge.net>
Sat, 9 Jul 2005 07:41:58 +0000 (07:41 +0000)
committerMichael Smith <xmldoc@users.sourceforge.net>
Sat, 9 Jul 2005 07:41:58 +0000 (07:41 +0000)
xsl/manpages/docbook.xsl
xsl/manpages/info.xsl
xsl/manpages/inline.xsl
xsl/manpages/other.xsl

index 6b5650fa1bf86ef594a618b0c78c65b11c4352b6..ae99863629ada395075eb5bf6d4cb129d2cf89f7 100644 (file)
   <xsl:include href="synop.xsl"/>
   <xsl:include href="lists.xsl"/>
 
-<!-- ==================================================================== -->
-<!-- * Set global variables -->
-<!-- ==================================================================== -->
-
-  <xsl:variable name="get.refentry.metadata.prefs">
-    <xsl:call-template name="get.refentry.metadata.prefs"/>
-  </xsl:variable>
-
-  <xsl:variable name="refentry.metadata.prefs"
-                select="exsl:node-set($get.refentry.metadata.prefs)"/>
-  
-<!-- ==================================================================== -->
-
-  <xsl:variable name="man.charmap.contents">
-    <xsl:if test="$man.charmap.enabled != 0">
-      <xsl:call-template name="read-character-map">
-        <xsl:with-param name="use.subset" select="$man.charmap.use.subset"/>
-        <xsl:with-param name="subset.profile" select="$man.charmap.subset.profile"/>
-        <xsl:with-param name="uri">
-          <xsl:choose>
-            <xsl:when test="$man.charmap.uri != ''">
-              <xsl:value-of select="$man.charmap.uri"/>
-            </xsl:when>
-            <xsl:otherwise>
-              <xsl:value-of select="'../manpages/charmap.groff.xsl'"/>
-            </xsl:otherwise>
-          </xsl:choose>
-        </xsl:with-param>
-      </xsl:call-template>
-    </xsl:if>
-  </xsl:variable>
-
-<!-- ==================================================================== -->
-<!-- * End global variables -->
 <!-- ==================================================================== -->
 
   <!-- * if document does not contain at least one refentry, then emit a -->
       <!-- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
       <xsl:apply-templates/>
       <!-- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-      <!-- * AUTHOR section (at end of man page) -->
+      <!-- * AUTHOR section -->
       <!-- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
       <xsl:call-template name="author.section">
         <xsl:with-param name="info" select="$info"/>
         <xsl:with-param name="parentinfo" select="$parentinfo"/>
       </xsl:call-template>
+      <!-- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+      <!-- * LINKS list (only generate if user wants links numbered) -->
+      <!-- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+      <xsl:if test="$man.links.list.enabled != 0">
+        <xsl:call-template name="links.list"/>
+      </xsl:if>
     </xsl:variable>
 
     <!-- * Prepare the page contents for final output, then store in -->
index 99f160e850f51ba3795ac978cf9df5f506517009..afdc7354fab5b6f42def8aeddc848643b3275057 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version='1.0'?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:date="http://exslt.org/dates-and-times"
-                exclude-result-prefixes="date"
+                xmlns:exsl="http://exslt.org/common"
+                exclude-result-prefixes="date exsl"
                 version='1.0'>
 
 <!-- ********************************************************************
 
      ******************************************************************** -->
 
-  <!-- * ============================================================== -->
+  <!-- ================================================================== -->
+  <!-- * Get user "refentry metadata" preferences -->
+  <!-- ================================================================== -->
+
+  <xsl:variable name="get.refentry.metadata.prefs">
+    <xsl:call-template name="get.refentry.metadata.prefs"/>
+  </xsl:variable>
+
+  <xsl:variable name="refentry.metadata.prefs"
+                select="exsl:node-set($get.refentry.metadata.prefs)"/>
+  
+  <!-- * =============================================================== -->
 
   <xsl:template name="author.section">
     <!-- * WARNING: The author.section API is slated for a rewrite and -->
index eec18bb9ab7622deff28c554baf35a0765da4505..34b6892d1b4ab70c21b8bfb8bac7797a5ada8810 100644 (file)
 
      ******************************************************************** -->
 
+  <!-- * Grab the set of all Ulinks in the document -->
+  <!-- * and that have -->
+  <!-- * child content and that aren't in suppressed content or in -->
+  <!-- * content that gets rendered out of document order -->
+  <!-- * Only generate a LINKS section if we actually have at least -->
+  <!-- * one Ulink node to process -->
+<xsl:key name="link"
+         match="*"
+         use="ulink[node()
+              and not(ancestor::refentryinfo)
+              and not(ancestor::info)
+              and not(ancestor::docinfo)
+              and not(ancestor::refmeta)
+              and not(ancestor::refnamediv)
+              and not(ancestor::indexterm)]"/>
+
+<xsl:param name="man.links.list.enabled">1</xsl:param>
+
 <!-- ==================================================================== -->
 
 <xsl:template match="filename|replaceable|varname">
   </xsl:call-template>
 </xsl:template>
 
-<!-- * handle ulink here instead of in xref.xsl, because xref.xsl is -->
-<!-- * auto-generated from html/xref.xsl, and we need to do something -->
-<!-- * a little different for ulink in manpages output -->
-<xsl:template match="ulink">
-  <xsl:variable name="content">
-    <xsl:apply-templates/>
-  </xsl:variable>
-  <xsl:variable name="url" select="@url"/>
-  <xsl:if test="$url != $content and $content != ''">
-    <xsl:value-of select="$content"/>
-    <xsl:text>: </xsl:text>
-  </xsl:if>
-  <xsl:variable name="url.wrapper">
-    <italic><xsl:value-of select="@url"/></italic>
-  </xsl:variable>
-  <xsl:apply-templates mode="italic" select="exsl:node-set($url.wrapper)"/>
-</xsl:template>
-
 <xsl:template match="trademark|productname">
   <xsl:apply-templates/>
   <xsl:choose>
-    <!-- * Just use true Unicode chars for copyright and registered -->
+    <!-- * Just use true Unicode chars for copyright, trademark, etc., -->
     <!-- * symbols (by default, we later automatically translate them -->
     <!-- * with the apply-string-subst-map template, or with the -->
     <!-- * default character map, if man.charmap.enabled is true). -->
     <xsl:when test="@class = 'registered'">
       <xsl:text>&#x00ae;</xsl:text>
     </xsl:when>
-    <!-- * There is no groff equivalent for the servicemark symbol. -->
     <xsl:when test="@class = 'service'">
-      <xsl:text>(SM)</xsl:text>
+      <xsl:text>&#x2120;</xsl:text>
     </xsl:when>
     <xsl:when test="self::trademark" >
-      <!-- * by default, render trademark symbol for <trademark> -->
-      <!-- * -->
-      <!-- * We don't do "\(tm" for &#x2122; because for console -->
-      <!-- * output, groff just renders that as "tm", without any -->
-      <!-- * preceding space, parens, or anything. So it just gets -->
-      <!-- * run into the preceding word; i.e.: -->
-      <!-- * -->
-      <!-- *  Product&#x2122; -> Producttm -->
-      <!-- * -->
-      <!-- * That it probably not what most people would want. So -->
-      <!-- * we just render it as (TM) instead, Thus: -->
-      <!-- * -->
-      <!-- *  Product&#x2122; -> Product(TM) -->
-      <!-- * -->
-      <xsl:text>(TM)</xsl:text>
+      <xsl:text>&#x2122;</xsl:text>
     </xsl:when>
     <xsl:otherwise>
       <!-- * don't render any default symbol after productname -->
   </xsl:choose>
 </xsl:template>
 
+<!-- ==================================================================== -->
+
+<!-- * Here we deal with Ulink... -->
+<!-- * -->
+<!-- * Other link types are handled by templates from html/xref.xsl, -->
+<!-- * which the manpages stylesheets import. But Ulinks - in -->
+<!-- * particular, non-empty Ulinks - must be handled differently. -->
+<!-- * -->
+<!-- * So this is what we do: -->
+<!-- * -->
+<!-- * We first find out if the Ulink is empty; if it is, we just -->
+<!-- * display the contents of its URL (that is, the value of its "Url" -->
+<!-- * attribute), and stop there. -->
+<!-- * -->
+<!-- * On the other hand, if it is NON-empty, we need to display its -->
+<!-- * contents AND (optionally) display its URL. We could display the -->
+<!-- * URL inline, after the contents (as we did previously), but that -->
+<!-- * ends up looking horrible if you have a lot of links. -->
+<!-- * -->
+<!-- * So, we instead need to display the URL out-of-line, in a way -->
+<!-- * that associates it with the content. How to do that in a -->
+<!-- * text-based output format that lacks hyperlinks? -->
+<!-- * -->
+<!-- * Here's how: Do it the way that most text/curses-based browsers -->
+<!-- * (e.g., w3m and lynx) do in the "-dump" output: Put a number -->
+<!-- * (in brackets) before the contents, and then put the URL, with -->
+<!-- * the corresponding number, in a generated section -->
+<!-- * at the end of the page. -->
+
+<xsl:template match="ulink[not(ancestor::refentryinfo)
+                     and not(ancestor::info)
+                     and not(ancestor::docinfo)
+                     and not(ancestor::refmeta)
+                     and not(ancestor::refnamediv)
+                     and not(ancestor::indexterm)]">
+  <!-- * Note that we don't do anything for Ulinks in *info sections -->
+  <!-- * or Refmeta or Refnamediv or Indexterm, because, in manpages -->
+  <!-- * output, contents of those are either suppressed or are -->
+  <!-- * displayed out of document order - for example, the Info/Author -->
+  <!-- * content gets moved to the end of the page. So, if we were to -->
+  <!-- * number links in the Author content, it would "throw off" the -->
+  <!-- * numbering at the beginning of the main text flow. -->
+  <xsl:variable name="link">
+    <xsl:choose>
+      <!-- * check to see if the element is empty or not; if it's non-empty, -->
+      <!-- * get the content -->
+      <xsl:when test="node()">
+        <xsl:apply-templates/>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- * the element is empty, so we just get the value of the URL; -->
+        <!-- * note that we don't number empty links -->
+        <xsl:value-of select="@url"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- * if link is non-empty AND user wants links numbered, output -->
+  <!-- * a number for it -->
+  <xsl:if test="node() and $man.links.are.numbered != 0">
+    <xsl:apply-templates select="." mode="link.number"/>
+  </xsl:if>
+  <xsl:choose>
+    <!-- * if user wants links underlined, underline (ital) it -->
+    <xsl:when test="$man.links.are.underlined != 0">
+      <xsl:variable name="link.wrapper">
+        <italic><xsl:value-of select="$link"/></italic>
+      </xsl:variable>
+      <xsl:apply-templates mode="italic" select="exsl:node-set($link.wrapper)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <!-- * user doesn't want links underlined, so just display content -->
+      <xsl:value-of select="$link"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="link.number">
+  <xsl:param name="format">[1]</xsl:param>
+  <!-- * we only number links that have child content and that aren't -->
+  <!-- * in suppressed content or in content that gets rendered out of -->
+  <!-- * document order -->
+  <xsl:number level="any"
+              count="ulink[node()
+                     and not(ancestor::refentryinfo)
+                     and not(ancestor::info)
+                     and not(ancestor::docinfo)
+                     and not(ancestor::refmeta)
+                     and not(ancestor::refnamediv)
+                     and not(ancestor::indexterm)]"
+              from="refentry"
+              format="{$format}"/>
+  <!-- * Note that we don't do anything for Ulinks in *info sections -->
+  <!-- * or Refmeta or Refnamediv or Indexterm, because, in manpages -->
+  <!-- * output, contents of those are either suppressed or are -->
+  <!-- * displayed out of document order - for example, the Info/Author -->
+  <!-- * content gets moved to the end of the page. So, if we were to -->
+  <!-- * number links in the Author content, it would "throw off" the -->
+  <!-- * numbering at the beginning of the main text flow. -->
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="links.list">
+  <xsl:variable name="links"
+                select=".//ulink[node()
+                     and not(ancestor::refentryinfo)
+                     and not(ancestor::info)
+                     and not(ancestor::docinfo)
+                     and not(ancestor::refmeta)
+                     and not(ancestor::refnamediv)
+                     and not(ancestor::indexterm)]"/>
+  <xsl:if test="$links/node()">
+    <xsl:call-template name="format.links.list">
+      <xsl:with-param name="links" select="$links"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="format.links.list">
+  <xsl:param name="links"/>
+  <xsl:param name="heading">
+    <xsl:choose>
+      <xsl:when test="$man.links.section.heading != ''">
+        <xsl:value-of select="$man.links.section.heading"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:text>Links</xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:param>
+    <!-- * The value of $padding.length is used for determining how much -->
+    <!-- * to right-pad numbers in the LINKS list. So, for $length, we -->
+    <!-- * count how many links there are, then take the number of digits -->
+    <!-- * in that count, and add 2 to it. The reason we add 2 is that we -->
+    <!-- * also prepend a dot and no-break space to each link number in -->
+    <!-- * the list, so we need to consider what length to pad out to. -->
+    <xsl:param name="padding.length">
+      <xsl:choose>
+        <xsl:when test="$man.links.are.numbered != 0">
+          <xsl:value-of select="string-length(count($links)) + 2"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="0"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:param>
+    <xsl:call-template name="mark.subheading"/>
+    <!-- * make the LINKS section heading -->
+    <xsl:text>.SH "</xsl:text>
+    <xsl:call-template name="string.upper">
+      <xsl:with-param name="string">
+        <xsl:choose>
+          <xsl:when test="$man.links.section.heading != ''">
+            <xsl:value-of select="$man.links.section.heading"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="gentext">
+              <xsl:with-param name="key" select="'Links'"/>
+            </xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:with-param>
+    </xsl:call-template>
+    <xsl:text>"&#10;</xsl:text>
+    <xsl:apply-templates select="$links" mode="links.list">
+      <xsl:with-param name="padding.length" select="$padding.length"/>
+    </xsl:apply-templates>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="ulink[node()
+                     and not(ancestor::refentryinfo)
+                     and not(ancestor::info)
+                     and not(ancestor::docinfo)
+                     and not(ancestor::refmeta)
+                     and not(ancestor::refnamediv)
+                     and not(ancestor::indexterm)]"
+              mode="links.list">
+  <xsl:param name="padding.length"/>
+  <xsl:variable name="link.number">
+    <xsl:apply-templates select="." mode="link.number">
+      <xsl:with-param name="format">1.&#160;</xsl:with-param>
+    </xsl:apply-templates>
+  </xsl:variable>
+  <xsl:text>.PP&#10;</xsl:text>
+  <!-- * right-pad each number out to the correct length -->
+  <xsl:call-template name="prepend-pad">
+    <xsl:with-param name="padVar" select="$link.number"/>
+    <xsl:with-param name="length" select="$padding.length"/>
+  </xsl:call-template>
+  <xsl:variable name="link.contents">
+    <xsl:apply-templates/>
+  </xsl:variable>
+  <xsl:value-of select="normalize-space($link.contents)"/>
+  <xsl:text>&#10;</xsl:text>
+  <xsl:text>.br&#10;</xsl:text>
+  <!-- * pad leader for URL -->
+  <xsl:call-template name="prepend-pad">
+    <xsl:with-param name="padVar" select="' '"/>
+    <xsl:with-param name="length" select="$padding.length"/>
+  </xsl:call-template>
+  <!-- * print the Ulink's URL -->
+  <xsl:value-of select="@url"/>
+  <xsl:text>&#10;</xsl:text>
+</xsl:template>
+
 </xsl:stylesheet>
index 671c1e81c83e7d89c58a64dcc9f7bf2a49ae2663..578aa9821f548cf09325425592fd51073b36ef1c 100644 (file)
 <!-- * each Refentry; they are just in a separate file for the purpose -->
 <!-- * of keeping things modular. -->
 
+<!-- ==================================================================== -->
+<!-- * Get character map contents -->
+<!-- ==================================================================== -->
+
+  <xsl:variable name="man.charmap.contents">
+    <xsl:if test="$man.charmap.enabled != 0">
+      <xsl:call-template name="read-character-map">
+        <xsl:with-param name="use.subset" select="$man.charmap.use.subset"/>
+        <xsl:with-param name="subset.profile" select="$man.charmap.subset.profile"/>
+        <xsl:with-param name="uri">
+          <xsl:choose>
+            <xsl:when test="$man.charmap.uri != ''">
+              <xsl:value-of select="$man.charmap.uri"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="'../manpages/charmap.groff.xsl'"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:variable>
+
 <!-- ==================================================================== -->
 
   <xsl:template name="top.comment">