public inbox for [email protected]  
help / color / mirror / Atom feed
From: Brar Piening <[email protected]>
To: Peter Eisentraut <[email protected]>
To: Alvaro Herrera <[email protected]>
To: Karl O. Pinc <[email protected]>
Cc: Tom Lane <[email protected]>
Cc: vignesh C <[email protected]>
Cc: Ian Lawrence Barwick <[email protected]>
Cc: pgsql-hackers <[email protected]>
Subject: Re: doc: add missing "id" attributes to extension packaging page
Date: Thu, 6 Apr 2023 16:19:30 +0200
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>

On 06.04.2023 at 11:06, Peter Eisentraut wrote:
> On 04.04.23 21:52, Brar Piening wrote:
>>> The XSLT implementation looks sound to me.  It would be a touch better
>>> if it had some comments about which parts of the templates were copied
>>> from upstream stylesheets and which were changed.  There are examples
>>> of such commenting in the existing customization layer.  Also, avoid
>>> introducing whitespace differences during said copying.
>>
>> I will amend the patch if we agree that this is the way forward.
>
> Ok, it appears everyone agrees that this is the correct approach.
> Please post an updated patch.  There have been so many partial patches
> posted recently, I'm not sure which one is the most current one and
> who is really the author.
>
Attached are two patches:

001-make_html_ids_discoverable_v5.postgresql.patch which needs to be
applied to the postgresql repository. It adds the XSLT to generate the
id links and the CSS to hide/display them. I've added comments as
suggested above.

002-add-discoverable-id-style_v1.pgweb.patch which needs to be applied
to the pgweb repository. It adds the CSS to the offical documentation site.

At the moment (commit 983ec23007) there are no missing ids, so the build
should just work after applying the patch but, as we already know, this
may change with every commit that gets added.

Reviewer is Karl O. Pink

Author is Brar Piening (with some additions from Karl O. Pink)

Best regards,

Brar

diff --git a/media/css/main.css b/media/css/main.css
index 5f8bfdd5..c3464cd0 100644
--- a/media/css/main.css
+++ b/media/css/main.css
@@ -1175,6 +1175,16 @@ code,
   padding-right: 2em;
 }
 
+/** Links to ids of headers and definition terms */
+#docContent a.id_link {
+  color: inherit;
+  visibility: hidden;
+}
+
+#docContent *:hover > a.id_link {
+  visibility: visible;
+}
+
 /**
   * Various callout boxes for docs, including warning, caution, note, tip
   */

diff --git a/doc/src/sgml/stylesheet-html-common.xsl b/doc/src/sgml/stylesheet-html-common.xsl
index bb6429ef7c..8e5d9912d5 100644
--- a/doc/src/sgml/stylesheet-html-common.xsl
+++ b/doc/src/sgml/stylesheet-html-common.xsl
@@ -309,4 +309,137 @@ set       toc,title
   </xsl:choose>
 </xsl:template>
 
+
+<!-- Override the standard section heading generation in /xhtml/sections.xsl
+     to add an id link to each section heading. -->
+<xsl:template name="section.heading">
+  <xsl:param name="section" select="."/>
+  <xsl:param name="level" select="1"/>
+  <xsl:param name="allow-anchors" select="1"/>
+  <xsl:param name="title"/>
+  <xsl:param name="class" select="'title'"/>
+
+  <xsl:variable name="id">
+    <xsl:choose>
+      <!-- Make sure the subtitle doesn't get the same id as the title -->
+      <xsl:when test="self::subtitle">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="."/>
+        </xsl:call-template>
+      </xsl:when>
+      <!-- if title is in an *info wrapper, get the grandparent -->
+      <xsl:when test="contains(local-name(..), 'info')">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="../.."/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select=".."/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- HTML H level is one higher than section level -->
+  <xsl:variable name="hlevel">
+    <xsl:choose>
+      <!-- highest valid HTML H level is H6; so anything nested deeper
+           than 5 levels down just becomes H6 -->
+      <xsl:when test="$level &gt; 5">6</xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$level + 1"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:element name="h{$hlevel}" namespace="http://www.w3.org/1999/xhtml";
+    <xsl:attribute name="class"><xsl:value-of select="$class"/></xsl:attribute>
+    <xsl:if test="$css.decoration != '0'">
+      <xsl:if test="$hlevel&lt;3">
+        <xsl:attribute name="style">clear: both</xsl:attribute>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="$allow-anchors != 0">
+      <xsl:call-template name="anchor">
+        <xsl:with-param name="node" select="$section"/>
+        <xsl:with-param name="conditional" select="0"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:copy-of select="$title"/>
+
+    <!--
+      The following code calls the template adding the links.
+      Everything else is copied from the original template.
+    -->
+    <xsl:call-template name="pg.id.link">
+      <xsl:with-param name="object" select="$section"/>
+    </xsl:call-template>
+
+  </xsl:element>
+</xsl:template>
+
+
+<!-- Override the standard template for varlistentry/term in /xhtml/lists.xsl
+     to add an id link after the last term. -->
+<xsl:template match="varlistentry/term">
+  <!-- Apply the original template -->
+  <xsl:apply-imports/>
+
+  <!-- Add the link after the last term -->
+  <xsl:if test="position() = last()">
+    <xsl:call-template name="pg.id.link">
+      <xsl:with-param name="object" select="parent::varlistentry"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+
+<!-- Create a link pointing to an id within the document -->
+<xsl:template name="pg.id.link">
+  <xsl:param name="object" select="."/>
+  <xsl:choose>
+    <xsl:when test="$object/@id or $object/@xml:id">
+      <xsl:text> </xsl:text>
+      <a>
+        <xsl:attribute name="href">
+          <xsl:text>#</xsl:text>
+          <xsl:call-template name="object.id">
+            <xsl:with-param name="object" select="$object"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:attribute name="class">
+          <xsl:text>id_link</xsl:text>
+        </xsl:attribute>
+        <xsl:text>#</xsl:text>
+      </a>
+    </xsl:when>
+    <xsl:otherwise>
+      <!-- Only complain about varlistentries if at least one entry in
+           the list has an id -->
+      <xsl:if test="name($object) != 'varlistentry'
+                    or $object/parent::variablelist/varlistentry[@id]">
+        <xsl:message terminate="yes">
+          <xsl:text>&#10;</xsl:text>  <!-- leading newline -->
+          <xsl:text>Ids are required in order to provide the public</xsl:text>
+          <xsl:text> HTML documentation with stable URLs for &lt;</xsl:text>
+          <xsl:value-of select ="name($object)"/>
+          <xsl:text>&gt; element content; id missing at: </xsl:text>
+          <xsl:for-each select="$object/ancestor::*">
+            <xsl:text>/</xsl:text>
+            <xsl:value-of select ="name(.)"/>
+            <xsl:if test="@id|@xml:id">
+              <xsl:text>[@</xsl:text>
+              <xsl:value-of select ="name(@id|@xml:id)"/>
+              <xsl:text> = '</xsl:text>
+              <xsl:value-of select ="@id"/>
+              <xsl:text>']</xsl:text>
+            </xsl:if>
+          </xsl:for-each>
+          <xsl:text>&#10; </xsl:text>  <!-- trailing newline -->
+        </xsl:message>
+      </xsl:if>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
 </xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet.css b/doc/src/sgml/stylesheet.css
index cc14efa1ca..15bcc95d41 100644
--- a/doc/src/sgml/stylesheet.css
+++ b/doc/src/sgml/stylesheet.css
@@ -169,3 +169,13 @@ acronym		{ font-style: inherit; }
     width: 75%;
   }
 }
+
+/* Links to ids of headers and definition terms */
+a.id_link {
+        color: inherit;
+        visibility: hidden;
+}
+
+*:hover > a.id_link {
+        visibility: visible;
+}


Attachments:

  [text/plain] 002-add-discoverable-id-style_v1.pgweb.patch (467B, ../[email protected]/2-002-add-discoverable-id-style_v1.pgweb.patch)
  download | inline diff:
diff --git a/media/css/main.css b/media/css/main.css
index 5f8bfdd5..c3464cd0 100644
--- a/media/css/main.css
+++ b/media/css/main.css
@@ -1175,6 +1175,16 @@ code,
   padding-right: 2em;
 }
 
+/** Links to ids of headers and definition terms */
+#docContent a.id_link {
+  color: inherit;
+  visibility: hidden;
+}
+
+#docContent *:hover > a.id_link {
+  visibility: visible;
+}
+
 /**
   * Various callout boxes for docs, including warning, caution, note, tip
   */


  [text/plain] 001-make_html_ids_discoverable_v5.postgresql.patch (5.5K, ../[email protected]/3-001-make_html_ids_discoverable_v5.postgresql.patch)
  download | inline diff:
diff --git a/doc/src/sgml/stylesheet-html-common.xsl b/doc/src/sgml/stylesheet-html-common.xsl
index bb6429ef7c..8e5d9912d5 100644
--- a/doc/src/sgml/stylesheet-html-common.xsl
+++ b/doc/src/sgml/stylesheet-html-common.xsl
@@ -309,4 +309,137 @@ set       toc,title
   </xsl:choose>
 </xsl:template>
 
+
+<!-- Override the standard section heading generation in /xhtml/sections.xsl
+     to add an id link to each section heading. -->
+<xsl:template name="section.heading">
+  <xsl:param name="section" select="."/>
+  <xsl:param name="level" select="1"/>
+  <xsl:param name="allow-anchors" select="1"/>
+  <xsl:param name="title"/>
+  <xsl:param name="class" select="'title'"/>
+
+  <xsl:variable name="id">
+    <xsl:choose>
+      <!-- Make sure the subtitle doesn't get the same id as the title -->
+      <xsl:when test="self::subtitle">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="."/>
+        </xsl:call-template>
+      </xsl:when>
+      <!-- if title is in an *info wrapper, get the grandparent -->
+      <xsl:when test="contains(local-name(..), 'info')">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="../.."/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select=".."/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- HTML H level is one higher than section level -->
+  <xsl:variable name="hlevel">
+    <xsl:choose>
+      <!-- highest valid HTML H level is H6; so anything nested deeper
+           than 5 levels down just becomes H6 -->
+      <xsl:when test="$level &gt; 5">6</xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$level + 1"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:element name="h{$hlevel}" namespace="http://www.w3.org/1999/xhtml">
+    <xsl:attribute name="class"><xsl:value-of select="$class"/></xsl:attribute>
+    <xsl:if test="$css.decoration != '0'">
+      <xsl:if test="$hlevel&lt;3">
+        <xsl:attribute name="style">clear: both</xsl:attribute>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="$allow-anchors != 0">
+      <xsl:call-template name="anchor">
+        <xsl:with-param name="node" select="$section"/>
+        <xsl:with-param name="conditional" select="0"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:copy-of select="$title"/>
+
+    <!--
+      The following code calls the template adding the links.
+      Everything else is copied from the original template.
+    -->
+    <xsl:call-template name="pg.id.link">
+      <xsl:with-param name="object" select="$section"/>
+    </xsl:call-template>
+
+  </xsl:element>
+</xsl:template>
+
+
+<!-- Override the standard template for varlistentry/term in /xhtml/lists.xsl
+     to add an id link after the last term. -->
+<xsl:template match="varlistentry/term">
+  <!-- Apply the original template -->
+  <xsl:apply-imports/>
+
+  <!-- Add the link after the last term -->
+  <xsl:if test="position() = last()">
+    <xsl:call-template name="pg.id.link">
+      <xsl:with-param name="object" select="parent::varlistentry"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+
+<!-- Create a link pointing to an id within the document -->
+<xsl:template name="pg.id.link">
+  <xsl:param name="object" select="."/>
+  <xsl:choose>
+    <xsl:when test="$object/@id or $object/@xml:id">
+      <xsl:text> </xsl:text>
+      <a>
+        <xsl:attribute name="href">
+          <xsl:text>#</xsl:text>
+          <xsl:call-template name="object.id">
+            <xsl:with-param name="object" select="$object"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:attribute name="class">
+          <xsl:text>id_link</xsl:text>
+        </xsl:attribute>
+        <xsl:text>#</xsl:text>
+      </a>
+    </xsl:when>
+    <xsl:otherwise>
+      <!-- Only complain about varlistentries if at least one entry in
+           the list has an id -->
+      <xsl:if test="name($object) != 'varlistentry'
+                    or $object/parent::variablelist/varlistentry[@id]">
+        <xsl:message terminate="yes">
+          <xsl:text>&#10;</xsl:text>  <!-- leading newline -->
+          <xsl:text>Ids are required in order to provide the public</xsl:text>
+          <xsl:text> HTML documentation with stable URLs for &lt;</xsl:text>
+          <xsl:value-of select ="name($object)"/>
+          <xsl:text>&gt; element content; id missing at: </xsl:text>
+          <xsl:for-each select="$object/ancestor::*">
+            <xsl:text>/</xsl:text>
+            <xsl:value-of select ="name(.)"/>
+            <xsl:if test="@id|@xml:id">
+              <xsl:text>[@</xsl:text>
+              <xsl:value-of select ="name(@id|@xml:id)"/>
+              <xsl:text> = '</xsl:text>
+              <xsl:value-of select ="@id"/>
+              <xsl:text>']</xsl:text>
+            </xsl:if>
+          </xsl:for-each>
+          <xsl:text>&#10; </xsl:text>  <!-- trailing newline -->
+        </xsl:message>
+      </xsl:if>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
 </xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet.css b/doc/src/sgml/stylesheet.css
index cc14efa1ca..15bcc95d41 100644
--- a/doc/src/sgml/stylesheet.css
+++ b/doc/src/sgml/stylesheet.css
@@ -169,3 +169,13 @@ acronym		{ font-style: inherit; }
     width: 75%;
   }
 }
+
+/* Links to ids of headers and definition terms */
+a.id_link {
+        color: inherit;
+        visibility: hidden;
+}
+
+*:hover > a.id_link {
+        visibility: visible;
+}


view thread (35+ messages)  latest in thread

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: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: doc: add missing "id" attributes to extension packaging page
  In-Reply-To: <[email protected]>

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

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