pg.ddx.io  pgsql-docs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Alexander Lakhin <exclusion@gmail.com>
To: Alvaro Herrera <alvherre@alvh.no-ip.org>
To: Erik Wienhold <ewie@ewie.name>
Cc: Anton Voloshin <a.voloshin@postgrespro.ru>
Cc: pgsql-docs <pgsql-docs@lists.postgresql.org>
Subject: Re: nested <a> tags in glossary entries in html docs
Date: Thu, 25 Apr 2024 23:00:00 +0300
Message-ID: <672a27ae-0d77-2b28-62ea-83c9ccf2b424@gmail.com> (raw)
In-Reply-To: <202404250924.wg5n655fdbar@alvherre.pgsql>
References: <202404250924.wg5n655fdbar@alvherre.pgsql>

Hello,

25.04.2024 12:24, Alvaro Herrera wrote:
> On 2024-Apr-12, Erik Wienhold wrote:
>
>> There's this bug[1] in the DocBook XSLT stylesheets.  Looks like the
>> fix[2] landed in 1.79.2 (latest version on Arch,
> Maybe one of these days we should get going with the migration to
> Docbook 5.x that Jürgen Purtz proposed.
>
> https://postgr.es/m/21ed3fd9-9020-4b53-b04f-a08a831b6085@purtz.de
>
> In the meantime, if anyone wants to suggest a XSLT patch to carry in our
> local definition, we could try that.

Please try the attached patch, which adds <xsl:template match="glossterm"
name="glossterm">, borrowed from /usr/share/xml/docbook/stylesheet/
docbook-xsl/xhtml/inline.xsl (I have docbook-xsl 1.79.2 installed), to our
local stylesheet-html-common.xsl.

I applied the modification from [1] (in two places) and it looks like the
nested <a> issue is gone.

[1] https://github.com/docbook/xslt10-stylesheets/pull/72/commits/62144252364492aecd71a3c8d5e6e1624af847...

Best regards,
Alexander

Attachments:

  [text/x-patch] fix-bad-nested-anchor-elements-for-glossterm.patch (6.1K, ../672a27ae-0d77-2b28-62ea-83c9ccf2b424@gmail.com/2-fix-bad-nested-anchor-elements-for-glossterm.patch)
  download | inline diff:
diff --git a/doc/src/sgml/stylesheet-html-common.xsl b/doc/src/sgml/stylesheet-html-common.xsl
index 9dcf96c02e..641a384812 100644
--- a/doc/src/sgml/stylesheet-html-common.xsl
+++ b/doc/src/sgml/stylesheet-html-common.xsl
@@ -674,4 +674,163 @@ set       toc,title
   </xsl:for-each>
 </xsl:template>
 
+<xsl:template match="glossterm" name="glossterm">
+  <xsl:param name="firstterm" select="0"/>
+
+  <!-- To avoid extra <a name=""> anchor from inline.italicseq -->
+  <xsl:variable name="content">
+    <xsl:apply-templates/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="($firstterm.only.link = 0 or $firstterm = 1) and @linkend">
+      <xsl:variable name="targets" select="key('id',@linkend)"/>
+      <xsl:variable name="target" select="$targets[1]"/>
+
+      <xsl:call-template name="check.id.unique">
+        <xsl:with-param name="linkend" select="@linkend"/>
+      </xsl:call-template>
+
+      <xsl:choose>
+        <xsl:when test="$target">
+          <a>
+            <xsl:apply-templates select="." mode="common.html.attributes"/>
+
+            <xsl:attribute name="href">
+              <xsl:call-template name="href.target">
+                <xsl:with-param name="object" select="$target"/>
+              </xsl:call-template>
+            </xsl:attribute>
+
+            <xsl:call-template name="inline.italicseq">
+              <xsl:with-param name="contentwithlink" select="$content"/>
+            </xsl:call-template>
+          </a>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="inline.italicseq">
+            <xsl:with-param name="content" select="$content"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <xsl:when test="not(@linkend)                     and ($firstterm.only.link = 0 or $firstterm = 1)                     and ($glossterm.auto.link != 0)                     and $glossary.collection != ''">
+      <xsl:variable name="term">
+        <xsl:choose>
+          <xsl:when test="@baseform"><xsl:value-of select="@baseform"/></xsl:when>
+          <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:variable name="cterm" select="(document($glossary.collection,.)//glossentry[glossterm=$term])[1]"/>
+
+      <!-- HACK HACK HACK! But it works... -->
+      <!-- You'd need to do more work if you wanted to chunk on glossdiv, though -->
+
+      <xsl:variable name="glossary" select="//glossary[@role='auto']"/>
+
+      <xsl:if test="count($glossary) != 1">
+        <xsl:message>
+          <xsl:text>Warning: glossary.collection specified, but there are </xsl:text>
+          <xsl:value-of select="count($glossary)"/>
+          <xsl:text> automatic glossaries</xsl:text>
+        </xsl:message>
+      </xsl:if>
+
+      <xsl:variable name="glosschunk">
+        <xsl:call-template name="href.target">
+          <xsl:with-param name="object" select="$glossary"/>
+        </xsl:call-template>
+      </xsl:variable>
+
+      <xsl:variable name="chunkbase">
+        <xsl:choose>
+          <xsl:when test="contains($glosschunk, '#')">
+            <xsl:value-of select="substring-before($glosschunk, '#')"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$glosschunk"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:choose>
+        <xsl:when test="not($cterm)">
+          <xsl:message>
+            <xsl:text>There's no entry for </xsl:text>
+            <xsl:value-of select="$term"/>
+            <xsl:text> in </xsl:text>
+            <xsl:value-of select="$glossary.collection"/>
+          </xsl:message>
+          <xsl:call-template name="inline.italicseq"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:variable name="id">
+            <xsl:call-template name="object.id">
+              <xsl:with-param name="object" select="$cterm"/>
+            </xsl:call-template>
+          </xsl:variable>
+          <a href="{$chunkbase}#{$id}">
+            <xsl:apply-templates select="." mode="common.html.attributes"/>
+            <xsl:call-template name="inline.italicseq">
+              <xsl:with-param name="content" select="$content"/>
+            </xsl:call-template>
+          </a>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <xsl:when test="not(@linkend)                     and ($firstterm.only.link = 0 or $firstterm = 1)                     and $glossterm.auto.link != 0">
+      <xsl:variable name="term">
+        <xsl:choose>
+          <xsl:when test="@baseform">
+            <xsl:value-of select="normalize-space(@baseform)"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="normalize-space(.)"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="targets" select="key('glossentries', $term)"/>
+      <xsl:variable name="target" select="$targets[1]"/>
+
+      <xsl:choose>
+        <xsl:when test="count($targets)=0">
+          <xsl:message>
+            <xsl:text>Error: no glossentry for glossterm: </xsl:text>
+            <xsl:value-of select="."/>
+            <xsl:text>.</xsl:text>
+          </xsl:message>
+          <xsl:call-template name="inline.italicseq"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <a>
+            <xsl:apply-templates select="." mode="common.html.attributes"/>
+            <xsl:if test="@id or @xml:id">
+              <xsl:attribute name="id">
+                <xsl:value-of select="(@id|@xml:id)[1]"/>
+              </xsl:attribute>
+            </xsl:if>
+
+            <xsl:attribute name="href">
+              <xsl:call-template name="href.target">
+                <xsl:with-param name="object" select="$target"/>
+              </xsl:call-template>
+            </xsl:attribute>
+
+            <xsl:call-template name="inline.italicseq">
+              <xsl:with-param name="contentwithlink" select="$content"/>
+            </xsl:call-template>
+          </a>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <xsl:otherwise>
+      <xsl:call-template name="inline.italicseq"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
 </xsl:stylesheet>


view thread (9+ messages)  latest in thread

Message-ID: <672a27ae-0d77-2b28-62ea-83c9ccf2b424@gmail.com>
Permalink:  ../672a27ae-0d77-2b28-62ea-83c9ccf2b424@gmail.com/
Also on:    postgresql.org/message-id/672a27ae-0d77-2b28-62ea-83c9ccf2b424@gmail.com

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-docs@postgresql.org
  Cc: exclusion@gmail.com, alvherre@alvh.no-ip.org, ewie@ewie.name, a.voloshin@postgrespro.ru, pgsql-docs@lists.postgresql.org
  Subject: Re: nested <a> tags in glossary entries in html docs
  In-Reply-To: <672a27ae-0d77-2b28-62ea-83c9ccf2b424@gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox