Subject: Re: doc: add missing "id" attributes to extension packaging page

From: Alvaro Herrera <[email-masked]>
Date: Thu, 23 Mar 2023 10:35:55 +0100

Thanks, Brar and Karl, I hope we can get this done soon.

As with the <simplelist> patch, we'll need to patch the CSS used in the
website for the docs too, as that's the most important place where docs
are visited.  See this commit for an example:
https://git.postgresql.org/gitweb/?p=pgweb.git;a=commitdiff;h=0b89ea0fff28d29ed177c82a274144453e3c7f82

In order to test locally that your patched stylesheet works correctly,
you'd have to compile the docs with "make html STYLE=website" in the doc
subdir, and tweak one of the CSS files there (I think it's
docs-complete.css) so that it references your local copy instead of
fetching it from the website.

> 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;
> +}

I'm not clear on what exactly becomes visible when one hovers over what.
Can you please share a screenshot?

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/

---

From: Brar Piening <[email-masked]>
Date: Thu, 23 Mar 2023 11:13:49 +0100

> fetching it from the website.

Thanks I'll take care of this tonight.

> Can you please share a screenshot?

I could, but since hover effects don't really come across in screenshots
I've posted a build of the docs including the patch to
https://pgdocs.piening.info

See https://pgdocs.piening.info/app-psql.html as an example.

---

From: "Karl O. Pinc" <[email-masked]>
Date: Thu, 23 Mar 2023 08:02:07 -0500

On Thu, 23 Mar 2023 10:35:55 +0100
Alvaro Herrera <[email-masked]> wrote:

> As with the <simplelist> patch, we'll need to patch the CSS used in
> the website for the docs too, as that's the most important place
> where docs are visited.  See this commit for an example:
> you'd have to compile the docs with "make html STYLE=website" in the
> doc subdir, and tweak one of the CSS files there (I think it's

I should have known to put the css in a separate patch.

> I'm not clear on what exactly becomes visible when one hovers over
> what. Can you please share a screenshot?

Attached are 2 screenshots.  I don't know why, but for
some reason you can't see the mouse pointer.

"#' shows up when the mouse is anywhere over the html heading element.

Regards,

Karl <[email-masked]>
Free Software:  "You don't pay back, you pay forward."
                 -- Robert A. Heinlein

---

From: Brar Piening <[email-masked]>
Date: Thu, 23 Mar 2023 20:08:52 +0100

On 23.03.2023 at 10:35, Alvaro Herrera wrote:
> are visited.

Ok, I've created and tested a patch for this too.

Since the need for ids is starting to grow again (ecb696527c added an id
to a varlistentry in doc/src/sgml/ref/create_subscription.sgml) I've
also amended the add-needed-ids patch once again so that the build does
not fail after applying the make_html_ids_discoverable patch.

I've also attached the (unchanged)  make_html_ids_discoverable patch for
convenience so this email now contains two patches for postgresql
(ending with .postgresql.patch) and one patch for pgweb (ending with
.pgweb.patch).

TBH I'm a bit afraid that people will immediately start complaining
about the failing docs builds after this got applied since it forces
them to add ids to all varlistenries in a variablelist if they add one,
which can be perceived as quite a burden (also committers and reviewers
will have to get used to always watch out for failing docs builds
because of this).

Since breaking the build on missing ids was an intentional decision we
can theoretically soften this by only issuing a warning or removing the
check for missing id's altogether but this would probably defeat the
purpose since it would lead to an increasing number of entries that lack
an id after a while.

Regards,

Brar
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
index 3836d13ad3..1432c67c2a 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -252,7 +252,7 @@
    additional columns not provided by the published table.  Any such columns
    will be filled with the default value as specified in the definition of the
    target table. However, logical replication in binary format is more
-   restrictive. See the <link linkend="sql-createsubscription-binary"><literal>binary</literal>
+   restrictive. See the <link linkend="sql-createsubscription-with-binary"><literal>binary</literal>
    option</link> of <command>CREATE SUBSCRIPTION</command> for details.
   </para>
 
diff --git a/doc/src/sgml/pgwalinspect.sgml b/doc/src/sgml/pgwalinspect.sgml
index 9a0241a8d6..62d9f9eb22 100644
--- a/doc/src/sgml/pgwalinspect.sgml
+++ b/doc/src/sgml/pgwalinspect.sgml
@@ -157,7 +157,7 @@ combined_size_percentage     | 2.8634072910530795
     </listitem>
    </varlistentry>
 
-   <varlistentry>
+   <varlistentry id="pgwalinspect-funcs-pg-get-wal-block-info">
     <term>
      <function>pg_get_wal_block_info(start_lsn pg_lsn, end_lsn pg_lsn) returns setof record</function>
     </term>
diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml
index e92346edef..f0ab6a918e 100644
--- a/doc/src/sgml/ref/alter_subscription.sgml
+++ b/doc/src/sgml/ref/alter_subscription.sgml
@@ -178,7 +178,7 @@ ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <
           <literal>origin</literal> parameter.
          </para>
          <para>
-          See the <link linkend="sql-createsubscription-binary"><literal>binary</literal>
+          See the <link linkend="sql-createsubscription-with-binary"><literal>binary</literal>
           option</link> of <command>CREATE SUBSCRIPTION</command> for details
           about copying pre-existing data in binary format.
          </para>
diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml
index 9d4b9d4e33..605b11bc67 100644
--- a/doc/src/sgml/ref/create_subscription.sgml
+++ b/doc/src/sgml/ref/create_subscription.sgml
@@ -61,7 +61,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
   <title>Parameters</title>
 
   <variablelist>
-   <varlistentry>
+   <varlistentry id="sql-createsubscription-subscription-name">
     <term><replaceable class="parameter">subscription_name</replaceable></term>
     <listitem>
      <para>
@@ -70,7 +70,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
     </listitem>
    </varlistentry>
 
-   <varlistentry>
+   <varlistentry id="sql-createsubscription-connection">
     <term><literal>CONNECTION '<replaceable class="parameter">conninfo</replaceable>'</literal></term>
     <listitem>
      <para>
@@ -81,7 +81,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
     </listitem>
    </varlistentry>
 
-   <varlistentry>
+   <varlistentry id="sql-createsubscription-publication">
     <term><literal>PUBLICATION <replaceable class="parameter">publication_name</replaceable> [, ...]</literal></term>
     <listitem>
      <para>
@@ -90,7 +90,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
     </listitem>
    </varlistentry>
 
-   <varlistentry>
+   <varlistentry id="sql-createsubscription-with">
     <term><literal>WITH ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
     <listitem>
      <para>
@@ -102,7 +102,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
 
       <variablelist>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-connect">
         <term><literal>connect</literal> (<type>boolean</type>)</term>
         <listitem>
          <para>
@@ -129,7 +129,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-create-slot">
         <term><literal>create_slot</literal> (<type>boolean</type>)</term>
         <listitem>
          <para>
@@ -145,7 +145,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-enabled">
         <term><literal>enabled</literal> (<type>boolean</type>)</term>
         <listitem>
          <para>
@@ -156,7 +156,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-slot-name">
         <term><literal>slot_name</literal> (<type>string</type>)</term>
         <listitem>
          <para>
@@ -185,7 +185,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
 
       <variablelist>
 
-       <varlistentry id="sql-createsubscription-binary" xreflabel="binary">
+       <varlistentry id="sql-createsubscription-with-binary" xreflabel="binary">
         <term><literal>binary</literal> (<type>boolean</type>)</term>
         <listitem>
          <para>
@@ -222,7 +222,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-copy-data">
         <term><literal>copy_data</literal> (<type>boolean</type>)</term>
         <listitem>
          <para>
@@ -243,7 +243,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-streaming">
         <term><literal>streaming</literal> (<type>enum</type>)</term>
         <listitem>
          <para>
@@ -271,7 +271,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-synchronous-commit">
         <term><literal>synchronous_commit</literal> (<type>enum</type>)</term>
         <listitem>
          <para>
@@ -303,7 +303,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-two-phase">
         <term><literal>two_phase</literal> (<type>boolean</type>)</term>
         <listitem>
          <para>
@@ -334,7 +334,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-disable-on-error">
         <term><literal>disable_on_error</literal> (<type>boolean</type>)</term>
         <listitem>
          <para>
@@ -346,7 +346,7 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
         </listitem>
        </varlistentry>
 
-       <varlistentry>
+       <varlistentry id="sql-createsubscription-with-origin">
         <term><literal>origin</literal> (<type>string</type>)</term>
         <listitem>
          <para>
diff --git a/doc/src/sgml/stylesheet-html-common.xsl b/doc/src/sgml/stylesheet-html-common.xsl
index 9df2782ce4..65c58ba750 100644
--- a/doc/src/sgml/stylesheet-html-common.xsl
+++ b/doc/src/sgml/stylesheet-html-common.xsl
@@ -301,4 +301,126 @@ set       toc,title
   </xsl:choose>
 </xsl:template>
 
+
+<!-- Override the standard section heading generation to add an id link -->
+<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"/>
+    <xsl:call-template name="pg.id.link">
+      <xsl:with-param name="object" select="$section"/>
+    </xsl:call-template>
+  </xsl:element>
+</xsl:template>
+
+
+<!-- Override the standard varlistentry/term generation to add an id link
+     after the last term -->
+<xsl:template match="varlistentry/term">
+  <xsl:apply-imports/>
+  <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>
+
+
+<!-- Creates 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;
+}
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
   */

---

From: Corey Huinker <[email-masked]>
Date: Thu, 23 Mar 2023 15:40:45 -0400

> will have to get used to always watch out for failing docs builds

As a person who had to re-rebase a patch because I discovered that id tags
had been added to one of the files I was working on, I can confidently say
"don't worry". It wasn't that big of a deal, I wasn't even following this
thread at the time and I immediately figured out what had happened and what
was expected of me. So it isn't that much of an inconvenience. If there is
a negative consequence to this change, it would be that it might
incentivize patch writers to omit documentation completely at the early
stages. But I don't think that's a problem because people generally see a
lack of documentation as a clue that maybe the patch isn't ready to be
reviewed, and this change would only reinforce that litmus test.

I had suggested we do something like this a few years back (the ids, that
is. the idea that we could check for compliance was beyond my imagination
at the time), and I'm glad to see both finally happening.

While I can foresee people overlooking the docs build, such oversights
won't go long before being caught, and the fix is simple.  Now if we can
just get a threaded version of xlstproc to make the builds faster...

p.s. I'm "Team Paperclip" when it comes to the link hint, but let's get the
feature in first and worry about the right character later.

---

From: "Karl O. Pinc" <[email-masked]>
Date: Thu, 23 Mar 2023 17:31:23 -0500

Hi Brar,

It occurs to me that I had not actually tested the
way the anchor is put only after the last term in a
varlistentry.  (The code looked obviously right
and should work if any varlistentry terms have anchors,
which they do, but....)

Have you tested this?  If not, catalog.sgml, the
DEPENDENCY_PARTITION_SEC term is a 2nd term and usable
for at test case.  But, at the moment there are no ids
for any of these varlistentries so you'd have to hack
them in.

Apologies for missing this.

Regards,

Karl <[email-masked]>

---

From: "Karl O. Pinc" <[email-masked]>
Date: Thu, 23 Mar 2023 17:55:30 -0500

This is for the committer, as an FYI.

I cut out the <xsl:template name="section.heading"> portion
of the docbook XSLT and diffed it with the code for the
same template in the patch.  The diff looks like:

-- /tmp/sections.xsl	2023-03-22 13:00:33.432968357 -0500
+++ /tmp/make_html_ids_discoverable_v3.patch	2023-03-22 13:03:39.776930603 -0500
@@ -52,5 +52,8 @@
       </xsl:call-template>
     </xsl:if>
     <xsl:copy-of select="$title"/>
+    <xsl:call-template name="pg.id.link">
+      <xsl:with-param name="object" select="$section"/>
+    </xsl:call-template>
   </xsl:element>
 </xsl:template>

(So, this output would start with line 52 of the template,
not from the top of the stock sections.xsl file.)

However, I am not really familiar with exactly what flavor
of docbook, version, namespace-d or not, etc., that PG
uses.  So I could be diffing with the wrong thing.

Hope this helps and is not just noise.

Regards,

Karl <[email-masked]>

---

From: "Karl O. Pinc" <[email-masked]>
Date: Thu, 23 Mar 2023 23:09:25 -0500

Hi Brar,

An observation:  The # that shows up when hovering
over section-level headings is styled as the
section-level heading is.  But the # that shows
up when hovering over varlistentrys has the default
text style.

This works for me.  It's nice to have the "section #"s
look like the section heading.  But the varlistentry's
terms are smaller than the normal font, and their
line width is less heavy than normal.  I'm not really
invested one way or the other, but I find it kind of
nice that the varlistentry's #s are easier to click
on and more noticable because they're slightly larger
than might be expected.

Regards,

Karl <[email-masked]>

---

From: Brar Piening <[email-masked]>
Date: Fri, 24 Mar 2023 06:05:06 +0100

On 23.03.2023 at 23:31, Karl O. Pinc wrote:
> Have you tested this?

Yes, I have. See
https://pgdocs.piening.info/app-psql.html#APP-PSQL-META-COMMAND-DE for
an extreme case.

---

From: Brar Piening <[email-masked]>
Date: Fri, 24 Mar 2023 06:48:17 +0100

> on and more noticable because they're slightly larger

TBH I didn't bother a lot with this.

Most of the time it's actually not the font size but rather the
font-family which gets inherited from the parent element if you don't
set it explicitly.

The link just inherits everithing (including the color, which I have set
to inherit explicitly since links don't inherit the parent's color by
default) from it's parent, which is the HTML <dt> element (ultimately
the inheritance probably goes up to the <body> element style in pretty
much all cases).

In some instances the input <term> element contains elements that are
styled differently in the output (e.g.: <literal> which translates to
HTML <code> which has "font-family: monospace;") which makes the # from
the link appear differently than the visible element it appears after.

Since (after tweaking the color) the general visual appearence looked ok
to me, I didn't bother with this any further.

Regards,

Brar

---

From: Brar Piening <[email-masked]>
Date: Fri, 24 Mar 2023 06:59:33 +0100

On 24.03.2023 at 06:48, Brar Piening wrote:
>
> Since (after tweaking the color) the general visual appearence looked
> ok to me, I didn't bother with this any further.

Also, if we go on with this we'll probably end up in an almost
prototypical bikeshedding scenario where PostgreSQL itself is the
nuclear power plant and the visual appearence of the hover links on the
documentation website is the color of the bikeshed.

;-)

---

From: Alvaro Herrera <[email-masked]>
Date: Fri, 24 Mar 2023 10:45:03 +0100

> https://pgdocs.piening.info/app-psql.html#APP-PSQL-META-COMMAND-DE for

But why are there no anchors next to <h3> items on that page?  For
example, how do I get the link for the "Meta Commands" subsection?

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
<inflex> really, I see PHP as like a strange amalgamation of C, Perl, Shell
<crab> inflex: you know that "amalgam" means "mixture with mercury",
       more or less, right?
<crab> i.e., "deadly poison"

---

From: Brar Piening <[email-masked]>
Date: Mon, 27 Mar 2023 19:05:52 +0200

On 23.03.2023 at 20:08, Brar Piening wrote:
> Since the need for ids is starting to grow again (ecb696527c added an
> id to a varlistentry in doc/src/sgml/ref/create_subscription.sgml)
> I've also amended the add-needed-ids patch once again so that the
> build does not fail after applying the make_html_ids_discoverable patch.

New add-needed-ids patch since it was outdated again.

Regards,

Brar

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 71730cc52f..b0546f47b4 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1132,7 +1132,7 @@ include_dir 'conf.d'
       </listitem>
      </varlistentry>
 
-     <varlistentry>
+     <varlistentry id="guc-scram-iterations">
       <term><varname>scram_iterations</varname> (<type>integer</type>)
       <indexterm>
        <primary><varname>scram_iterations</varname> configuration parameter</primary>
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
index 3836d13ad3..1432c67c2a 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -252,7 +252,7 @@
    additional columns not provided by the published table.  Any such columns
    will be filled with the default value as specified in the definition of the
    target table. However, logical replication in binary format is more
-   restrictive. See the <link linkend="sql-createsubscription-binary"><literal>binary</literal>
+   restrictive. See the <link linkend="sql-createsubscription-with-binary"><literal>binary</literal>
    option</link> of <command>CREATE SUBSCRIPTION</command> for details.
   </para>

-   <varlistentry>
 
   <variablelist>
-   <varlistentry>
 
-   <varlistentry>
 
-   <varlistentry>
 
-   <varlistentry>
 
       <variablelist>
 
-       <varlistentry>
 
-       <varlistentry>
 
-       <varlistentry>
 
-       <varlistentry>
 
       <variablelist>

-       <varlistentry>
 
-       <varlistentry>
 
-       <varlistentry>
 
-       <varlistentry>
 
-       <varlistentry>
 
-       <varlistentry>

---

From: Peter Smith <[email-masked]>
Date: Tue, 28 Mar 2023 09:11:57 +1100

> New add-needed-ids patch since it was outdated again.

FYI, there is a lot of overlap between this last attachment and the
patches of Kuroda-san's current thread here [1] which is also adding
ids to create_subscription.sgml.

(Anyway, I guess you might already be aware of that other thread
because your new ids look like they have the same names as those
chosen by Kuroda-san)

------
[1] https://www.postgresql.org/message-id/flat/CAHut%2BPvzo6%3DKKLqMR6-mAQdM%2Bj_dse0eUreGmrFouL7gbLbv2w%40mail.gmail.com#7da8d0e3b73096375847c16c856b4aed

Kind Regards,
Peter Smith.
Fujitsu Australia

---

From: Brar Piening <[email-masked]>
Date: Tue, 28 Mar 2023 12:17:28 +0200

> [1] https://www.postgresql.org/message-id/flat/CAHut%2BPvzo6%3DKKLqMR6-mAQdM%2Bj_dse0eUreGmrFouL7gbLbv2w%40mail.gmail.com#7da8d0e3b73096375847c16c856b4aed

Thanks, I actually was not aware of this.

Also, kudos for capturing the missing id and advocating for consistency
regarding ids even before this is actively enforced. This nurtures my
optimism that consistency might actually be achieveable without
everybody getting angry at me because my patch will enforce it.

Regarding the overlap, I currently try to make it as easy as possible
for a potential committer and I'm happy to rebase my patch upon request
or if Kuroda-san's patch gets applied first.

Regards,

Brar

---

From: "Hayato Kuroda (Fujitsu)" <[email-masked]>
Date: Wed, 29 Mar 2023 04:52:56 +0000

Dear my comrade Brar,

> or if Kuroda-san's patch gets applied first.

FYI - my patch is pushed [1]. Could you please rebase your patch?
I think it's ok to just remove changes from logical-replication.sgml, ref/alter_subscription.sgml,
and ref/create_subscription.sgml.

[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=de5a47af2d8003dee123815bb7e58913be9a03f3

Best Regards,
Hayato Kuroda
FUJITSU LIMITED

---

From: Brar Piening <[email-masked]>
Date: Wed, 29 Mar 2023 18:03:48 +0200

On 29.03.2023 at 06:52, Hayato Kuroda (Fujitsu) wrote:
> FYI - my patch is pushed

Thanks!

> Could you please rebase your patch?

Done and tested. Patch is attached.

Regards,

Brar
index fcb53c6997..5c50347c58 100644
 
-     <varlistentry>
 
-   <varlistentry>

---

From: "Hayato Kuroda (Fujitsu)" <[email-masked]>
Date: Thu, 30 Mar 2023 08:11:13 +0000

Dear Brar,

Thank you for updating the patch. The patch looks good to me.

Best Regards,
Hayato Kuroda
FUJITSU LIMITED

---

From: Peter Eisentraut <[email-masked]>
Date: Tue, 4 Apr 2023 16:22:14 +0200

> Done and tested. Patch is attached.

I have committed the most recent patch that added some missing IDs.  (I 
also added a missing xreflabel in passing.)

I'll look at the XSLT patch next.

---

From: Peter Eisentraut <[email-masked]>
Date: Tue, 4 Apr 2023 16:54:23 +0200

> (ending with .postgresql.patch) and one patch for pgweb (ending with

Here is my view on this:

First of all, it works very nicely and is very useful.  Very welcome.

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.

However, I wonder if this is the right way to approach this.  I don't 
think we should put these link markers directly into the HTML.  It feels 
like this is the wrong layer.  For example, if you have CSS turned off, 
then all these # marks show up by default.

It seems to me that the correct way to do this is to hook in some 
JavaScript that does this transformation directly on the DOM.  Then we 
don't need to carry this presentation detail in the HTML.  Moreover, it 
would avoid tight coupling between the website and the documentation 
sources.  You can produce the exact same DOM, that part seems okay, just 
do it elsewhere.  Was this approach considered?  I didn't see it in the 
thread.

---

From: Brar Piening <[email-masked]>
Date: Tue, 4 Apr 2023 21:52:31 +0200

> First of all, it works very nicely and is very useful.  Very welcome.

Thank you!

> from upstream stylesheets and which were changed.  There are examples
> of such commenting in the existing customization layer.  Also, avoid

I will amend the patch if we agree that this is the way forward.

> think we should put these link markers directly into the HTML.  It
> feels like this is the wrong layer.  For example, if you have CSS
> turned off, then all these # marks show up by default.

I'd consider this a feature rather than a problem but this is certainly
debatable. I cannot reliably predict what expectations a user who is
browsing the docs with CSS disabled might have. The opposite is true
too. If we'd move the id links feature to javascript, a user who has
javascript disabled will not see them. Is this what they'd want? I don't
know.

Also, while about 1-2% of users have Javascript disabled, I haven't
heard of disabling CSS except for debugging purposes.

In general I'd consider the fact that CSS or Javascript might be
disabled a niche problem that isn't really worth much debating but there
is definitely something to consider regarding people using screen
readers who might suffer from one or the other behavior and I'd
definitely be interested what behavior these users would expect. Would
they want to use the id link feature or would the links rather disrupt
their reading experience - I have no idea TBH and I hate speculating
about other people's preferences.

> sources.  You can produce the exact same DOM, that part seems okay,
> just do it elsewhere.  Was this approach considered?  I didn't see it
> in the thread.

I briefly touched the topic in [1] and [2] but we didin't really follow
up on the best approach.

Regards,

Brar

[1]
https://www.postgresql.org/message-id/68b9c435-d017-93cc-775a-c604db9ec683%40gmx.de

[2]
https://www.postgresql.org/message-id/a75b6d7c-3fa4-d6a8-cf23-6b5180237392%40gmx.de

---

From: "Karl O. Pinc" <[email-masked]>
Date: Tue, 4 Apr 2023 16:21:42 -0500

On Tue, 4 Apr 2023 21:52:31 +0200

> > 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.

I like this idea.  A lot. (Including which stylesheets were copied
from.)

> > However, I wonder if this is the right way to approach this.  I
> > don't think we should put these link markers directly into the
> > HTML.  It feels like this is the wrong layer.  For example, if you
> > have CSS turned off, then all these # marks show up by default.  
> 
> I'd consider this a feature rather than a problem but this is
> certainly debatable.

I too would consider this a feature.  If you don't style your
html presentation, you see everything.  The "#" links to content
are, well, content.

> > JavaScript that does this transformation directly on the DOM. Then
> > we don't need to carry this presentation detail in the HTML.

I would argue the opposite.  The HTML/CSS is delivered to the browser
which is then free to present the content to the user in the
form preferred by the user.  This puts control of presentation
in the hands of the end-user, where, IMO, it belongs.

Using JavaScript to manipulate the DOM is all well and good when
using AJAX to interact with the server to produce dynamic content.
But otherwise manipulating the DOM with JavaScript seems overly
heavy-handed, even though popular.  It seems like JavaScript is
used more because CSS is difficult and an "extra technology" when
instead JavaScript can "do everything".  So CSS is put aside.

I may be biased, not being a JavaScript fan.  (I tend to be one
of those cranky individuals who keep JavaScript turned off.)
I'd rather not have code executing when such overhead/complication
can be avoided.  (Insert here exciting argument about "what is code
and what is data".)

Glancing at the documentation source, I don't see JavaScript used
at all.  Introducing it would be adding something else to the mix.
Not that this would be bad if it provides value.

In the end, I don't _really_ care.  And don't do web development
all day either so my fundamentals could be just wrong.  But
this is my take.

> > Moreover, it would avoid tight coupling between the website and the
> > documentation sources. 

I don't really understand this statement.  Are you saying that
the documentation's source CSS needn't/shouldn't be the CSS used
on the website?  That seems counter-intuitive.  But then I don't
understand why the default CSS used when developing the documentation
is not the CSS used on the website.

I can imagine administrative arguments around server maintenance for
wanting to keep the website decoupled from the PG source code.
(I think.)  But I can't speak to any of that.

Regards,

Karl <[email-masked]>

---

From: Maciek Sakrejda <[email-masked]>
Date: Wed, 5 Apr 2023 15:00:45 -0700

For what it's worth, I think having the anchors be always-visible when
CSS disabled is a feature. The content is still perfectly readable,
and the core feature from this patch is available. Introducing
JavaScript to lose that functionality seems like a step backwards.

By the way, the latest patch attachment was not the full patch series,
which I think confused cfbot: [1]  (unless I'm misunderstanding the
state of the patch series).

And thanks for working on this. I've hunted in the page source for ids
to link to a number of times. I look forward to not doing that
anymore.

Thanks,
Maciek

[1]: https://commitfest.postgresql.org/42/4042/

---

From: Peter Eisentraut <[email-masked]>
Date: Thu, 6 Apr 2023 11:06:18 +0200

> 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.

---

From: Brar Piening <[email-masked]>
Date: Thu, 6 Apr 2023 16:19:30 +0200

On 06.04.2023 at 11:06, Peter Eisentraut wrote:
> 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
 
+/** 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. -->
+    <!--
+      The following code calls the template adding the links.
+      Everything else is copied from the original template.
+    -->
+<!-- Override the standard template for varlistentry/term in /xhtml/lists.xsl
+     to add an id link after the last term. -->
+  <!-- Apply the original template -->
+  <!-- Add the link after the last term -->
+<!-- Create a link pointing to an id within the document -->

---

From: "Karl O. Pinc" <[email-masked]>
Date: Thu, 6 Apr 2023 10:05:52 -0500

On Thu, 6 Apr 2023 16:19:30 +0200

> Reviewer is Karl O. Pink

"Karl O. Pinc" actually, with a "c".

Regards,

Karl <[email-masked]>

---

From: Peter Eisentraut <[email-masked]>
Date: Thu, 13 Apr 2023 10:31:43 +0200

> to the pgweb repository. It adds the CSS to the offical documentation site.

The first patch has been committed.

The second patch should be sent to pgsql-www for integrating into the 
web site.

Side project: I noticed that these new hover links don't appear in the 
single-page HTML output (make postgres.html), even though the generated 
HTML source code looks correct.  Maybe someone has an idea there.

---

From: Brar Piening <[email-masked]>
Date: Thu, 13 Apr 2023 16:01:35 +0200

> The first patch has been committed.

Yay - thank you!

> The second patch should be sent to pgsql-www for integrating into the
Done via [1]. Thanks for the hint.

> single-page HTML output (make postgres.html), even though the
> generated HTML source code looks correct.  Maybe someone has an idea
> there.
I feel responsible for the feature to work for all use cases where it
makes sense. I'll investigate this and post back.

Regards,
Brar

[1]
https://www.postgresql.org/message-id/d987a4a7-62c3-7e0c-860f-1c96fc2117d9%40gmx.de

---

From: Dagfinn Ilmari Mannsåker <[email-masked]>
Date: Thu, 13 Apr 2023 15:58:03 +0100

> HTML source code looks correct.  Maybe someone has an idea there.

Another side note: I notice the links don't appear on <refsectN> elements
(e.g. https://www.postgresql.org/docs/devel/sql-select.html#SQL-WITH),
only <sectN>.

- ilmari

---

From: "Karl O. Pinc" <[email-masked]>
Date: Thu, 13 Apr 2023 10:40:09 -0500

On Thu, 13 Apr 2023 15:58:03 +0100

> Another side note: I notice the links don't appear on <refsectN>
> elements (e.g.
> https://www.postgresql.org/docs/devel/sql-select.html#SQL-WITH), only
> <sectN>.

This we know.  Working with <refsectN> elements is a different
dive into the XSLT which was deliberately put off for future
work.

Regards,

Karl <[email-masked]>

---

From: "Karl O. Pinc" <[email-masked]>
Date: Thu, 13 Apr 2023 10:53:31 -0500

On Thu, 13 Apr 2023 16:01:35 +0200
Brar Piening <[email-masked]> wrote:

> > The second patch should be sent to pgsql-www for integrating into
> > the web site.  
> > Side project: I noticed that these new hover links don't appear in
> > the single-page HTML output (make postgres.html), even though the

Looks to me like the ">" in the CSS was transformed into the &gt;
HTML entity when the stylesheet was included into the single-file
HTML.

Regards,

Karl <[email-masked]>

---

From: "Karl O. Pinc" <[email-masked]>
Date: Fri, 14 Apr 2023 12:41:23 -0500

On Thu, 13 Apr 2023 10:53:31 -0500

> > > generated HTML source code looks correct.  Maybe someone has an
> > > idea there.    
> > I feel responsible for the feature to work for all use cases where
> > it makes sense. I'll investigate this and post back.  
> 

The XSLT 1.0 spec says that characters in <style> elements should
not be escaped when outputting HTML.  [4]  But (I think) the
generate.css.header parameter method [1][2] of 
inserting the CSS into the HTML expands the CSS content
in an XML context, not a HTML context.  

I've played around with it, going so far as to make stylesheet.css
look like:

--------------<snip>--------
<!DOCTYPE  xsl:stylesheet [
<!ENTITY css SYSTEM "stylesheet.css">
]>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  &css;
</xsl:stylesheet>
--------------<snip>--------

and even substituted the actual text of stylesheet.css in
place of the &css; entity reference.  In these cases the
"<" character is still entity expanded, resulting in broken CSS.

My conclusion is that this method is broken.

(The other possibility, I suppose, is that xsltproc is broken.)

I think the thing to try is the sagehill.net approach [4].
This overrides the user.head.content template.  My hope is
that because the &css; entity is seen in a <style> element
in the template, that xsltproc then recognizances style element
content in a HTML output context.

(I don't know how xsltproc is supposed to know that it is
in a HTML output context.  I suppose exploring this would
be another avenue should the above fail.)

1
https://docbook.sourceforge.net/release/xsl/current/doc/html/custom.css.source.html

2
https://docbook.sourceforge.net/release/xsl/current/doc/html/generate.css.header.html

3 http://sagehill.net/docbookxsl/HtmlHead.html#EmbedCSS

4 https://www.w3.org/TR/xslt-10/#section-HTML-Output-Method

Regards,

Karl <[email-masked]>

---

From: Alvaro Herrera <[email-masked]>
Date: Fri, 14 Nov 2025 11:59:51 +0100

> > https://www.postgresql.org/docs/devel/sql-select.html#SQL-WITH),
> > only <sectN>.
> 

Hi, has anybody been able to spend some time on the <refsectN> aspect of
these link things?

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
"No hay ausente sin culpa ni presente sin disculpa" (Prov. francés)

---

From: Brar Piening <[email-masked]>
Date: Sat, 15 Nov 2025 11:53:34 +0100

> Hi, has anybody been able to spend some time on the <refsectN> aspect of

Hi,

tbh, this has been in my backlog since I did the initial thing.

I haven't prioritized it since it is really a completely different area 
XSLT-wise that cannot build on the changes I have made and I wanted to 
see how well my initial work will prove its value and be accepted by the 
maintainers and the community before starting to work on this and 
introducing even more changes in this kind of ugly XSLT area that nobody 
really likes to touch.

I think, now that some  time has passed, everybody working on patches in 
the docs area should have some opinion on how annoying it is to be 
forced to provide ids for various elements and if the advantage of being 
able to refer to specific items in the HTML docs is really worth it.

Also, as we've learnt the last time, a patch that enforces the presence 
of ids in refsections would need to be applied in a quick and 
cooperative way once we agree on the general structure, since it needs 
to be rebased and enhanced whenever a new refsection without ids (or 
other element where it enforces ids) is added by some patch and will 
break all subsequent patches that try to add refsections without ids 
(forcing their developers/reviewers to rebase and add ids accordingly).

If we can build some consensus that we want this for the refsections as 
well, I'm willing to put some time aside and work on this (probably at 
some point next year since I'm currently drowning in work).

Regards,

Barr