From: Alexander Lakhin <exclusion@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-docs@lists.postgresql.org
Subject: Re: Getting our tables to render better in PDF output
Date: Wed, 12 Feb 2020 07:05:06 +0300
Message-ID: <8a99bdca-85ab-27d6-83b4-9fc7113839f2@gmail.com> (raw)
In-Reply-To: <9326.1581457869@sss.pgh.pa.us>
References: <9326.1581457869@sss.pgh.pa.us>
Hello Tom,
12.02.2020 00:51, Tom Lane wrote:
> The crummy formatting of our tables of functions and operators has
> been an issue for a long time. To my mind, there are several things
> that need to be addressed:
>
> * The layout is completely unfriendly to function descriptions that
> run to more than a few words.
>
> * It's not very practical to have more than one example per function
> (or at least, we seldom do so).
>
> * The results look completely awful in PDF format, because of the
> narrow effectively-available space, plus the fact that the toolchain
> will prefer to overprint following columns instead of breaking text
> where there's no whitespace.
Please look at a less invasive approach that we use at Postgres Pro for
some time (mainly for improving the translated documentation, but it
works for the original one too). The idea is to add zero-width spaces
after/before some chars ('(', ',', '[', etc) to let fop split lines
where desired. It has one disadvantage - it's not search-friendly
(though maybe that is application-dependent).
But if it's feasible, I think this approach can at least complement a
manual tables reformatting. Decreasing a font size in the tables seems
appropriate to me too.
Best regards,
Alexander
Attachments:
[text/x-patch] fix-pdf-overflow.patch (5.9K, ../8a99bdca-85ab-27d6-83b4-9fc7113839f2@gmail.com/2-fix-pdf-overflow.patch)
download | inline diff:diff --git a/doc/src/sgml/Makefile b/doc/src/sgml/Makefileindex 0401a515df8..3be29dba9f1 100644--- a/doc/src/sgml/Makefile+++ b/doc/src/sgml/Makefile@@ -169,10 +169,14 @@ XSLTPROC_FO_FLAGS += --stringparam img.src.path '$(srcdir)/'
%-A4.fo: stylesheet-fo.xsl %.sgml $(ALLSGML)
$(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
$(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type A4 -o $@ $(wordlist 1,2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) -o $@.tmp $(@D)/pg-customize-fo.xsl $@+ mv $@.tmp $@
%-US.fo: stylesheet-fo.xsl %.sgml $(ALLSGML)
$(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
$(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type USletter -o $@ $(wordlist 1,2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) -o $@.tmp $(@D)/pg-customize-fo.xsl $@+ mv $@.tmp $@
%.pdf: %.fo $(ALL_IMAGES)
$(FOP) -fo $< -pdf $@
diff --git a/doc/src/sgml/pg-customize-fo.xsl b/doc/src/sgml/pg-customize-fo.xslnew file mode 100644index 00000000000..48978880126--- /dev/null+++ b/doc/src/sgml/pg-customize-fo.xsl@@ -0,0 +1,118 @@+<?xml version="1.0" encoding="UTF-8"?>+<xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0"+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">++ <xsl:template match="@*|node()">+ <xsl:copy>+ <xsl:apply-templates select="@*|node()"/>+ </xsl:copy>+ </xsl:template>++ <xsl:template match="fo:table-cell/fo:block//text()">+ <xsl:variable name="str1">+<!-- insert &zwsp; after '_' to allow wrapping of strings like 'CURRENT_DEFAULT_TRANSFORM_GROUP' -->+ <xsl:call-template name="replace-string">+ <xsl:with-param name="text" select="."/>+ <xsl:with-param name="replace" select="'_'" />+ <xsl:with-param name="with" select="'_​'"/>+ </xsl:call-template>+ </xsl:variable>+ <xsl:variable name="str2">+<!-- insert &zwsp; after '(' to allow wrapping of strings like 'round(42.4382, 2)' -->+ <xsl:call-template name="replace-string">+ <xsl:with-param name="text" select="$str1"/>+ <xsl:with-param name="replace" select="'('" />+ <xsl:with-param name="with" select="'(​'"/>+ </xsl:call-template>+ </xsl:variable>+ <xsl:variable name="str3">+<!-- insert &zwsp; after ',' to allow wrapping of strings like '{red,orange,yellow,green,blue,purple}' -->+ <xsl:call-template name="replace-string">+ <xsl:with-param name="text" select="$str2"/>+ <xsl:with-param name="replace" select="','" />+ <xsl:with-param name="with" select="',​'"/>+ </xsl:call-template>+ </xsl:variable>+ <xsl:variable name="str4">+<!-- insert &zwsp; after '[' to allow wrapping of strings like 'ARRAY['foo','bar','baz']' -->+ <xsl:call-template name="replace-string">+ <xsl:with-param name="text" select="$str3"/>+ <xsl:with-param name="replace" select="'['" />+ <xsl:with-param name="with" select="'[​'"/>+ </xsl:call-template>+ </xsl:variable>+ <xsl:variable name="str5">+<!-- insert &zwsp; before '::' to allow wrapping of strings like 'E'\\\\001'::bytea' -->+ <xsl:call-template name="replace-string">+ <xsl:with-param name="text" select="$str4"/>+ <xsl:with-param name="replace" select="'::'" />+ <xsl:with-param name="with" select="'​::'"/>+ </xsl:call-template>+ </xsl:variable>+ <xsl:value-of select="$str5" />+ </xsl:template>+<!--+­ - soft hyphen adds hyphen when wrapping+​ - zero-width space doesn't add anything+-->++ <!-- remove leading spaces after fo:wrapper https://lists.oasis-open.org/archives/docbook-apps/201006/msg00112.html -->+ <xsl:template match="text()[preceding-sibling::*[1][self::fo:wrapper]]">+ <xsl:call-template name="string-ltrim">+ <xsl:with-param name="string" select="." />+ </xsl:call-template>+ </xsl:template>++ <xsl:template name="replace-string">+ <xsl:param name="text"/>+ <xsl:param name="replace"/>+ <xsl:param name="with"/>+ <xsl:choose>+ <xsl:when test="contains($text, $replace)">+ <xsl:value-of select="substring-before($text,$replace)"/>+ <xsl:value-of select="$with"/>+ <xsl:call-template name="replace-string">+ <xsl:with-param name="text" select="substring-after($text,$replace)"/>+ <xsl:with-param name="replace" select="$replace"/>+ <xsl:with-param name="with" select="$with"/>+ </xsl:call-template>+ </xsl:when>+ <xsl:otherwise>+ <xsl:value-of select="$text"/>+ </xsl:otherwise>+ </xsl:choose>+ </xsl:template>++ <xsl:template match="fo:block[@linefeed-treatment='preserve']/text()">+ <xsl:choose>+ <xsl:when test="(position() = 1 + count(../@*)) and starts-with(., '
')">+ <xsl:value-of select="substring(., 2)" />+ </xsl:when>+ <xsl:otherwise>+ <xsl:value-of select="." />+ </xsl:otherwise>+ </xsl:choose>+ </xsl:template>++ <xsl:variable name="whitespace" select="'	 '" />+<!-- Strips leading whitespace characters from 'string' -->+ <xsl:template name="string-ltrim">+ <xsl:param name="string" />+ <xsl:param name="trim" select="$whitespace" />++ <xsl:if test="string-length($string) > 0">+ <xsl:choose>+ <xsl:when test="contains($trim, substring($string, 1, 1))">+ <xsl:call-template name="string-ltrim">+ <xsl:with-param name="string" select="substring($string, 2)" />+ <xsl:with-param name="trim" select="$trim" />+ </xsl:call-template>+ </xsl:when>+ <xsl:otherwise>+ <xsl:value-of select="$string" />+ </xsl:otherwise>+ </xsl:choose>+ </xsl:if>+ </xsl:template>++</xsl:stylesheet>
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, tgl@sss.pgh.pa.us, pgsql-docs@lists.postgresql.org
Subject: Re: Getting our tables to render better in PDF output
In-Reply-To: <8a99bdca-85ab-27d6-83b4-9fc7113839f2@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