public inbox for [email protected]help / color / mirror / Atom feed
Moving documentation to XML 9+ messages / 8 participants [nested] [flat]
* Moving documentation to XML @ 2015-04-02 21:22 Luzanov Pavel <[email protected]> 0 siblings, 1 reply; 9+ messages in thread From: Luzanov Pavel @ 2015-04-02 21:22 UTC (permalink / raw) To: [email protected] <[email protected]>; +Cc: pgsql-docs Peter, I found this message in archives: http://www.postgresql.org/message-id/flat/[email protected]#[email protected] and, as you recommend, tested a speed of building docs on a fresh Ubuntu installation. 50sec for make html and 14min 50sec for make xslthtml 17 times slower! Is it still a main stopper for moving to XML? ----- Pavel Luzanov [email protected] ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-04-06 20:02 Peter Eisentraut <[email protected]> parent: Luzanov Pavel <[email protected]> 0 siblings, 1 reply; 9+ messages in thread From: Peter Eisentraut @ 2015-04-06 20:02 UTC (permalink / raw) To: Luzanov Pavel <[email protected]>; +Cc: pgsql-docs On 4/2/15 5:22 PM, Luzanov Pavel wrote: > Peter, > > > I found this message in archives: > > http://www.postgresql.org/message-id/flat/[email protected]#[email protected] > > > and, as you recommend, tested a speed of building docs on a fresh Ubuntu > installation. > > 50sec for make html > and 14min 50sec for make xslthtml > 17 times slower! > > > Is it still a main stopper for moving to XML? Yes :) -- Sent via pgsql-docs mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-docs ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-10-26 10:53 Alexander Lakhin <[email protected]> parent: Peter Eisentraut <[email protected]> 0 siblings, 2 replies; 9+ messages in thread From: Alexander Lakhin @ 2015-10-26 10:53 UTC (permalink / raw) To: Peter Eisentraut <[email protected]>; +Cc: Luzanov Pavel <[email protected]>; pgsql-docs Hello, Peter. I've managed to speed up html generation from xml (make xslthtml) from 32 min. (in my environment) to 4 min. by modifying slowest XSL templates. All my modifications incorporated in a single file stylesheet-xhtml-speedup.xsl, which is included in stylesheet.xsl. I performed optimization by analyzing output of: xsltproc --profile --stringparam pg.version '9.6devel' stylesheet.xsl postgres.xml Initial statistics: number match name mode Calls Tot 100us Avg 0 appendix label.markup 23090 90677526 3927 1 chapter label.markup 28870 39740757 1376 2 chunk-all-sections 1289 23845066 18498 3 make.legalnotice.head.links 2578 9630258 3735 4 indexterm reference 2579 4126513 1600 5 html.head 1289 3112534 2414 ... index % time self children called name 0.479 1326.034 22/23090 toc.line [61] 5.128 1308.245 21944/23090 sect1[label.markup] [13] 3.772 1318.264 850/23090 substitute-markup [15] 1.355 1304.631 274/23090 figure|table|example[label.markup] [32] [0] 47.95 906.775 1.613 23090 appendix[label.markup] [0] 1.613 0.000 23090/23090 autolabel.format [29] ----------------------------------------------- 5.128 1308.245 24708/28870 sect1[label.markup] [13] 0.479 1326.034 130/28870 toc.line [61] 3.772 1318.264 2112/28870 substitute-markup [15] 1.355 1304.631 1920/28870 figure|table|example[label.markup] [32] [1] 21.01 397.408 1.613 28870 chapter[label.markup] [1] 1.613 0.000 28870/28870 autolabel.format [29] ----------------------------------------------- 0.164 238.606 1289/1289 process-chunk-element [98] [2] 12.61 238.451 0.225 1289 chunk-all-sections [2] 0.225 7.117 1289/1289 process-chunk [86] ----------------------------------------------- 31.125 112.261 1289/2578 html.head [5] 96.303 96.726 1289/2578 make.legalnotice.head.links [3] [3] 5.09 96.303 96.726 2578 make.legalnotice.head.links [3] 96.303 96.726 1289/3867 make.legalnotice.head.links [3] 0.339 0.494 1289/3867 *[object.title.markup.textonly] [69] 0.085 0.781 1289/3867 ln.or.rh.filename [116] ----------------------------------------------- Currrent statistics: number match name mode Calls Tot 100us Avg 0 chunk-all-sections 1289 5405958 4193 1 make.legalnotice.head.links 1289 3159538 2451 2 html.head 1289 3068417 2380 3 gentext.template 689835 2327761 3 4 l10n.language 564453 1455253 2 5 href.target 29881 1344063 44 --- index % time self children called name 0.136 54.207 1289/1289 process-chunk-element [95] [0] 20.40 54.060 0.312 1289 chunk-all-sections [0] 0.312 6.468 1289/1289 process-chunk [67] ----------------------------------------------- 30.684 45.458 1289/1289 html.head [2] [1] 11.92 31.595 0.448 1289 make.legalnotice.head.links [1] 0.290 0.403 1289/2578 *[object.title.markup.textonly] [71] 0.159 0.828 1289/2578 ln.or.rh.filename [91] ----------------------------------------------- 0.330 31.617 1289/1289 chunk-element-content [65] [2] 11.58 30.684 45.458 1289 html.head [2] 31.595 0.448 1289/15462 make.legalnotice.head.links [1] 13.441 4.726 5153/15462 href.target [5] 0.290 0.403 5153/15462 *[object.title.markup.textonly] [71] 0.115 1.576 1289/15462 head.content [99] 0.012 0.000 1289/15462 system.head.content [186] 0.006 0.000 1289/15462 user.head.content [228] To make sure that result of the transformation is the same, I've compared original .html's with .html's generated with modified templates. Unfortunately xslt generates random id's, so it's needed to exclude them before comparing. I do that with: for f in */*.html; do sed -e 's/id=\"\(ftn\.\)\?id[a-z][0-9]\+\"/id=\"id\"/g' -i $f ; sed -e 's/href=\"[^#]*#\(ftn\.\)\?id[a-z][0-9]\+\"/href=\"#\"/g' -i $f; done So if it's acceptable way to speed up generation of HTML (and maybe some other formats), what other steps should we take to move away from SGML? If the performance is still not satisfying, please let me know, I'll continue to optimize xslt. Beside performance issues, I can see some difference in results of 'make html' and 'make xslthtml'. For example, see doc/src/sgml/html/spi.html (xslt-generated version doesn't contain the lists of functions). Best regards, Alexander 06.04.2015 23:02, Peter Eisentraut wrote: > On 4/2/15 5:22 PM, Luzanov Pavel wrote: >> Peter, >> >> >> I found this message in archives: >> >> http://www.postgresql.org/message-id/flat/[email protected]#[email protected] >> >> >> and, as you recommend, tested a speed of building docs on a fresh Ubuntu >> installation. >> >> 50sec for make html >> and 14min 50sec for make xslthtml >> 17 times slower! >> >> >> Is it still a main stopper for moving to XML? > Yes :) > > > -- Sent via pgsql-docs mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-docs Attachments: [text/x-patch] xslt-speedup.patch (20.6K, 2-xslt-speedup.patch) download | inline diff: diff --git a/doc/src/sgml/stylesheet-xhtml-speedup.xsl b/doc/src/sgml/stylesheet-xhtml-speedup.xsl new file mode 100644 index 0000000..d52b48e --- /dev/null +++ b/doc/src/sgml/stylesheet-xhtml-speedup.xsl @@ -0,0 +1,327 @@ +<?xml version="1.0" encoding="utf-8"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0" + xmlns="http://www.w3.org/1999/xhtml" + exclude-result-prefixes="#default"> + +<!-- common/labels.xsl --> +<xsl:template match="appendix" mode="label.markup"> + <xsl:choose> + <xsl:when test="@label"> + <xsl:value-of select="@label"/> + </xsl:when> + <xsl:when test="string($appendix.autolabel) != 0"> + <xsl:if test="$component.label.includes.part.label != 0 and + ancestor::part"> + <xsl:variable name="part.label"> + <xsl:apply-templates select="ancestor::part" + mode="label.markup"/> + </xsl:variable> + <xsl:if test="$part.label != ''"> + <xsl:value-of select="$part.label"/> + <xsl:apply-templates select="ancestor::part" + mode="intralabel.punctuation"/> + </xsl:if> + </xsl:if> + <xsl:variable name="format"> + <xsl:call-template name="autolabel.format"> + <xsl:with-param name="format" select="$appendix.autolabel"/> + </xsl:call-template> + </xsl:variable> + <xsl:choose> + <xsl:when test="$label.from.part != 0 and ancestor::part"> + <xsl:number from="part" count="appendix" format="{$format}" level="any"/> + </xsl:when> + <xsl:otherwise> +<!-- speed optimizations for pgsql-docs --> + <xsl:number value="count(../preceding-sibling::part/appendix) + count(preceding-sibling::appendix) + 1" format="{$format}" /> +<!-- <xsl:number from="book|article" + count="appendix" format="{$format}" level="any"/> --> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- common/labels.xsl --> +<xsl:template match="chapter" mode="label.markup"> + <xsl:choose> + <xsl:when test="@label"> + <xsl:value-of select="@label"/> + </xsl:when> + <xsl:when test="string($chapter.autolabel) != 0"> + <xsl:if test="$component.label.includes.part.label != 0 and + ancestor::part"> + <xsl:variable name="part.label"> + <xsl:apply-templates select="ancestor::part" + mode="label.markup"/> + </xsl:variable> + <xsl:if test="$part.label != ''"> + <xsl:value-of select="$part.label"/> + <xsl:apply-templates select="ancestor::part" + mode="intralabel.punctuation"/> + </xsl:if> + </xsl:if> + <xsl:variable name="format"> + <xsl:call-template name="autolabel.format"> + <xsl:with-param name="format" select="$chapter.autolabel"/> + </xsl:call-template> + </xsl:variable> + <xsl:choose> + <xsl:when test="$label.from.part != 0 and ancestor::part"> + <xsl:number from="part" count="chapter" format="{$format}" level="any"/> + </xsl:when> + <xsl:otherwise> +<!-- speed optimizations for pgsql-docs --> + <xsl:number value="count(../preceding-sibling::part/chapter) + count(preceding-sibling::chapter) + 1" format="{$format}" /> +<!-- <xsl:number from="book" count="chapter" format="{$format}" level="any"/> --> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- xhtml/autoidx.xsl --> +<xsl:template match="indexterm" mode="reference"> + <xsl:param name="scope" select="."/> + <xsl:param name="role" select="''"/> + <xsl:param name="type" select="''"/> + <xsl:param name="position"/> + <xsl:param name="separator" select="''"/> + + <xsl:variable name="term.separator"> + <xsl:call-template name="index.separator"> + <xsl:with-param name="key" select="'index.term.separator'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="number.separator"> + <xsl:call-template name="index.separator"> + <xsl:with-param name="key" select="'index.number.separator'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="range.separator"> + <xsl:call-template name="index.separator"> + <xsl:with-param name="key" select="'index.range.separator'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:choose> + <xsl:when test="$separator != ''"> + <xsl:value-of select="$separator"/> + </xsl:when> + <xsl:when test="$position = 1"> + <xsl:value-of select="$term.separator"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$number.separator"/> + </xsl:otherwise> + </xsl:choose> + + <xsl:choose> + <xsl:when test="@zone and string(@zone)"> + <xsl:call-template name="reference"> + <xsl:with-param name="zones" select="normalize-space(@zone)"/> + <xsl:with-param name="position" select="position()"/> + <xsl:with-param name="scope" select="$scope"/> + <xsl:with-param name="role" select="$role"/> + <xsl:with-param name="type" select="$type"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <a> + <xsl:apply-templates select="." mode="class.attribute"/> + <xsl:variable name="title"> + <xsl:choose> + <xsl:when test="$index.prefer.titleabbrev != 0"> + <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="titleabbrev.markup"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="title.markup"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:attribute name="href"> + <xsl:choose> + <xsl:when test="$index.links.to.section = 1"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]"/> +<!-- speed optimizations for pgsql-docs --> + <xsl:with-param name="context" select="(/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="."/> + <xsl:with-param name="context" select="(//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))] | //setindex[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + + </xsl:attribute> + + <xsl:value-of select="$title"/> <!-- text only --> + </a> + + <xsl:variable name="id" select="(@id|@xml:id)[1]"/> + <xsl:if test="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))]"> + <xsl:apply-templates select="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][last()]" mode="reference"> + <xsl:with-param name="position" select="position()"/> + <xsl:with-param name="scope" select="$scope"/> + <xsl:with-param name="role" select="$role"/> + <xsl:with-param name="type" select="$type"/> + <xsl:with-param name="separator" select="$range.separator"/> + </xsl:apply-templates> + </xsl:if> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- xhtml/chunk-common.xsl --> +<xsl:template name="chunk-all-sections"> + <xsl:param name="content"> + <xsl:apply-imports/> + </xsl:param> + +<!-- speed optimizations for pgsql-docs --> + <xsl:variable name="prev-v1" select="preceding::*[(self::sect1 and $chunk.section.depth > 0) or (self::sect2 and $chunk.section.depth > 1) or (self::sect3 and $chunk.section.depth > 2) or (self::sect4 and $chunk.section.depth > 3) or (self::sect5 and $chunk.section.depth > 4)][1]"/> + + <xsl:variable name="prev-v2" select="(ancestor::sect1[$chunk.section.depth > 0 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect2[$chunk.section.depth > 1 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect3[$chunk.section.depth > 2 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect4[$chunk.section.depth > 3 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect5[$chunk.section.depth > 4 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::section[$chunk.section.depth > count(ancestor::section) and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1])[last()]"/> + + <xsl:variable name="prev" select="(preceding::book[1] |preceding::preface[1] |preceding::chapter[1] |preceding::appendix[1] |preceding::part[1] |preceding::reference[1] |preceding::refentry[1] |preceding::colophon[1] |preceding::article[1] |preceding::topic[1] |preceding::bibliography[parent::article or parent::book or parent::part][1] |preceding::glossary[parent::article or parent::book or parent::part][1] |preceding::index[$generate.index != 0] [parent::article or parent::book or parent::part][1] |preceding::setindex[$generate.index != 0][1] |ancestor::set |ancestor::book[1] |ancestor::preface[1] |ancestor::chapter[1] |ancestor::appendix[1] |ancestor::part[1] |ancestor::reference[1] |ancestor::article[1] |ancestor::topic[1] |$prev-v1 |$prev-v2)[last()]"/> + +<!-- speed optimizations for pgsql-docs --> + <xsl:variable name="next-v1" select="following::*[self::sect1 or self::sect2 or self::sect3 or self::sect4 or self::sect5][1]"/> + + <xsl:variable name="next-v2" select="(descendant::sect1[$chunk.section.depth > 0 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect2[$chunk.section.depth > 1 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect3[$chunk.section.depth > 2 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect4[$chunk.section.depth > 3 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect5[$chunk.section.depth > 4 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::section[$chunk.section.depth > count(ancestor::section) and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1])[1]"/> + + <xsl:variable name="next" select="(following::book[1] |following::preface[1] |following::chapter[1] |following::appendix[1] |following::part[1] |following::reference[1] |following::refentry[1] |following::colophon[1] |following::bibliography[parent::article or parent::book or parent::part][1] |following::glossary[parent::article or parent::book or parent::part][1] |following::index[$generate.index != 0] [parent::article or parent::book][1] |following::article[1] |following::topic[1] |following::setindex[$generate.index != 0][1] |descendant::book[1] |descendant::preface[1] |descendant::chapter[1] |descendant::appendix[1] |descendant::article[1] |descendant::topic[1] |descendant::bibliography[parent::article or parent::book][1] |descendant::glossary[parent::article or parent::book or parent::part][1] |descendant::index[$generate.index != 0] [parent::article or parent::book][1] |descendant::colophon[1] |descendant::setindex[$generate.index != 0][1] |descendant::part[1] |descendant::reference[1] |descendant::refentry[1] |$next-v1 |$next-v2)[1]"/> + + + <xsl:call-template name="process-chunk"> + <xsl:with-param name="prev" select="$prev"/> + <xsl:with-param name="next" select="$next"/> + <xsl:with-param name="content" select="$content"/> + </xsl:call-template> + +</xsl:template> + + +<xsl:template name="make.legalnotice.head.links"> + <!-- * the following ID is used as part of the legalnotice filename; --> + <!-- * we need it in order to construct the filename for use in the --> + <!-- * value of the href attribute on the link --> + + <xsl:param name="ln-node" select="(//legalnotice)[1]"/> + + <xsl:param name="linktype"> + <xsl:choose> + <xsl:when test="contains($html.head.legalnotice.link.types, ' ')"> + <xsl:value-of select="normalize-space( substring-before($html.head.legalnotice.link.types, ' '))"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$html.head.legalnotice.link.types"/> + </xsl:otherwise> + </xsl:choose> + </xsl:param> + <xsl:param name="remaining.linktypes" select="concat( normalize-space( substring-after($html.head.legalnotice.link.types, ' ')),' ')"/> + <xsl:if test="not($linktype = '')"> + <!-- Compute name of legalnotice file (see titlepage.xsl) --> + <xsl:variable name="file"> + <xsl:call-template name="ln.or.rh.filename"> + <xsl:with-param name="node" select="$ln-node"/> + </xsl:call-template> + </xsl:variable> + + <link rel="{$linktype}"> + <xsl:attribute name="href"> + <xsl:value-of select="$file"/> + </xsl:attribute> + <xsl:attribute name="title"> +<!-- speed optimizations for pgsql-docs --> + <xsl:apply-templates select="/book/bookinfo/legalnotice" mode="object.title.markup.textonly"/> + </xsl:attribute> + </link> +<!-- speed optimizations for pgsql-docs --> +<!-- <xsl:call-template name="make.legalnotice.head.links"> + < ! - - * pop the next value off the list of link types - - > + <xsl:with-param name="linktype" select="substring-before($remaining.linktypes, ' ')"/> + < ! - - * remove the link type from the list of remaining link types - - > + <xsl:with-param name="remaining.linktypes" select="substring-after($remaining.linktypes, ' ')"/> + </xsl:call-template> --> + </xsl:if> +</xsl:template> + +<!-- xhtml/html.xsl (needed for the following "reference" template) --> +<xsl:template name="id.attribute"> + <xsl:param name="node" select="."/> + <xsl:param name="conditional" select="1"/> + <xsl:choose> + <xsl:when test="$generate.id.attributes = 0"> + <!-- No id attributes when this param is zero --> + </xsl:when> + <xsl:when test="$conditional = 0 or $node/@id or $node/@xml:id"> + <xsl:attribute name="id"> + <xsl:call-template name="object.id"> + <xsl:with-param name="object" select="$node"/> + </xsl:call-template> + </xsl:attribute> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- xhtml/autoidx.xsl --> +<xsl:template name="reference"> + <xsl:param name="scope" select="."/> + <xsl:param name="role" select="''"/> + <xsl:param name="type" select="''"/> + <xsl:param name="zones"/> + + <xsl:choose> + <xsl:when test="contains($zones, ' ')"> + <xsl:variable name="zone" select="substring-before($zones, ' ')"/> + <xsl:variable name="target" select="key('sections', $zone)"/> + + <a> + <xsl:apply-templates select="." mode="class.attribute"/> + <xsl:call-template name="id.attribute"/> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$target[1]"/> + <xsl:with-param name="context" select="//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/> + </xsl:call-template> + </xsl:attribute> + <xsl:apply-templates select="$target[1]" mode="index-title-content"/> + </a> + <xsl:text>, </xsl:text> + <xsl:call-template name="reference"> + <xsl:with-param name="zones" select="substring-after($zones, ' ')"/> + <xsl:with-param name="position" select="position()"/> + <xsl:with-param name="scope" select="$scope"/> + <xsl:with-param name="role" select="$role"/> + <xsl:with-param name="type" select="$type"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="zone" select="$zones"/> + <xsl:variable name="target" select="key('sections', $zone)"/> + + <a> + <xsl:apply-templates select="." mode="class.attribute"/> + <xsl:call-template name="id.attribute"/> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$target[1]"/> +<!-- speed optimizations for pgsql-docs --> + <xsl:with-param name="context" select="/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/> + </xsl:call-template> + </xsl:attribute> + <xsl:apply-templates select="$target[1]" mode="index-title-content"/> + </a> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +</xsl:stylesheet> diff --git a/doc/src/sgml/stylesheet.xsl b/doc/src/sgml/stylesheet.xsl index 7967b36..8b01f41 100644 --- a/doc/src/sgml/stylesheet.xsl +++ b/doc/src/sgml/stylesheet.xsl @@ -6,6 +6,7 @@ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/> <xsl:include href="stylesheet-common.xsl" /> +<xsl:include href="stylesheet-xhtml-speedup.xsl" /> <!-- Parameters --> ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-10-28 11:46 Guillaume Lelarge <[email protected]> parent: Alexander Lakhin <[email protected]> 1 sibling, 0 replies; 9+ messages in thread From: Guillaume Lelarge @ 2015-10-28 11:46 UTC (permalink / raw) To: Alexander Lakhin <[email protected]>; +Cc: pgsql-docs; Luzanov Pavel <[email protected]>; Peter Eisentraut <[email protected]> Le 26 oct. 2015 6:40 PM, "Alexander Lakhin" <[email protected]> a écrit : > > Hello, Peter. > > I've managed to speed up html generation from xml (make xslthtml) from 32 min. (in my environment) to 4 min. by modifying slowest XSL templates. > All my modifications incorporated in a single file stylesheet-xhtml-speedup.xsl, which is included in stylesheet.xsl. > I performed optimization by analyzing output of: > xsltproc --profile --stringparam pg.version '9.6devel' stylesheet.xsl postgres.xml > Initial statistics: > number match name mode Calls Tot 100us Avg > > 0 appendix label.markup > 23090 90677526 3927 > 1 chapter label.markup > 28870 39740757 1376 > 2 chunk-all-sections 1289 23845066 18498 > 3 make.legalnotice.head.links > 2578 9630258 3735 > 4 indexterm reference 2579 4126513 1600 > 5 html.head 1289 3112534 2414 > ... > index % time self children called name > 0.479 1326.034 22/23090 toc.line [61] > 5.128 1308.245 21944/23090 sect1[label.markup] [13] > 3.772 1318.264 850/23090 substitute-markup [15] > 1.355 1304.631 274/23090 figure|table|example[label.markup] [32] > [0] 47.95 906.775 1.613 23090 appendix[label.markup] [0] > 1.613 0.000 23090/23090 autolabel.format [29] > ----------------------------------------------- > 5.128 1308.245 24708/28870 sect1[label.markup] [13] > 0.479 1326.034 130/28870 toc.line [61] > 3.772 1318.264 2112/28870 substitute-markup [15] > 1.355 1304.631 1920/28870 figure|table|example[label.markup] [32] > [1] 21.01 397.408 1.613 28870 chapter[label.markup] [1] > 1.613 0.000 28870/28870 autolabel.format [29] > ----------------------------------------------- > 0.164 238.606 1289/1289 process-chunk-element [98] > [2] 12.61 238.451 0.225 1289 chunk-all-sections [2] > 0.225 7.117 1289/1289 process-chunk [86] > ----------------------------------------------- > 31.125 112.261 1289/2578 html.head [5] > 96.303 96.726 1289/2578 make.legalnotice.head.links [3] > [3] 5.09 96.303 96.726 2578 make.legalnotice.head.links [3] > 96.303 96.726 1289/3867 make.legalnotice.head.links [3] > 0.339 0.494 1289/3867 *[object.title.markup.textonly] [69] > 0.085 0.781 1289/3867 ln.or.rh.filename [116] > > ----------------------------------------------- > > > Currrent statistics: > number match name mode Calls Tot 100us Avg > > 0 chunk-all-sections 1289 5405958 4193 > 1 make.legalnotice.head.links > 1289 3159538 2451 > 2 html.head 1289 3068417 2380 > 3 gentext.template 689835 2327761 3 > 4 l10n.language 564453 1455253 2 > 5 href.target 29881 1344063 44 > --- > index % time self children called name > 0.136 54.207 1289/1289 process-chunk-element [95] > [0] 20.40 54.060 0.312 1289 chunk-all-sections [0] > 0.312 6.468 1289/1289 process-chunk [67] > ----------------------------------------------- > 30.684 45.458 1289/1289 html.head [2] > [1] 11.92 31.595 0.448 1289 make.legalnotice.head.links [1] > 0.290 0.403 1289/2578 *[object.title.markup.textonly] [71] > 0.159 0.828 1289/2578 ln.or.rh.filename [91] > ----------------------------------------------- > 0.330 31.617 1289/1289 chunk-element-content [65] > [2] 11.58 30.684 45.458 1289 html.head [2] > 31.595 0.448 1289/15462 make.legalnotice.head.links [1] > 13.441 4.726 5153/15462 href.target [5] > 0.290 0.403 5153/15462 *[object.title.markup.textonly] [71] > 0.115 1.576 1289/15462 head.content [99] > 0.012 0.000 1289/15462 system.head.content [186] > 0.006 0.000 1289/15462 user.head.content [228] > > To make sure that result of the transformation is the same, I've compared original .html's with .html's generated with modified templates. > Unfortunately xslt generates random id's, so it's needed to exclude them before comparing. I do that with: > for f in */*.html; do sed -e 's/id=\"\(ftn\.\)\?id[a-z][0-9]\+\"/id=\"id\"/g' -i $f ; sed -e 's/href=\"[^#]*#\(ftn\.\)\?id[a-z][0-9]\+\"/href=\"#\"/g' -i $f; done > > > So if it's acceptable way to speed up generation of HTML (and maybe some other formats), what other steps should we take to move away from SGML? > If the performance is still not satisfying, please let me know, I'll continue to optimize xslt. > Beside performance issues, I can see some difference in results of 'make html' and 'make xslthtml'. For example, see doc/src/sgml/html/spi.html (xslt-generated version doesn't contain the lists of functions). > What you've done is awesome. I can't wait to test it on the french translation. Nice work! ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-10-30 13:40 Alexander Lakhin <[email protected]> 0 siblings, 1 reply; 9+ messages in thread From: Alexander Lakhin @ 2015-10-30 13:40 UTC (permalink / raw) To: pgsql-docs Hello, Guillaume. We have plans to use this for russian translation, too. We translate the docs by converting (with xml2po) the single xml to postgres-ru.po and after translating it we convert it back to xml (we get postres-ru.xml here). (Until now we had to perform one more conversion (postgres-ru.xml -> set of sgml's).) So now we can get russian html/* with: python xml2po.py -l ru -k -p postgres-ru.po postgres.xml >postgres-ru.xml xsltproc --stringparam pg.version '9.4.1' stylesheet.xsl postgres-ru.xml But I had some doubts about DSSSL and XSL differences. As I noted previously there was at least one visible difference. So I decided to customize XSL templates to make sure that html's are generated without a loss or corruption. I thought that comparing two HTML sources will not work, as they are too different, but maybe we can compare text generated from html by lynx, for example. So I use the following procedure to look for differences: 0. Get dsssl-generated html's make html 1. Extract text content from html's: for f in html/*.html; do fn=`basename $f`; echo $fn; cat $f | perl -0pi -pe 's/<B\s*>Note:\s*<\/B\s*>/\<h3>Note<\/h3>/g' | perl -0pi -pe 's/><BLOCKQUOTE\s*CLASS="NOTE"/><div/ig' >/tmp/$fn; lynx /tmp/$fn --dump >html-text/$fn; * Some differences are not significant so it's not reasonable to modify XSL templates to eliminate them. Difference in "Note" placement and spelling is one of them, so I just filter it out. 2. Rename html to html-o and html-text to html-o-text. 3. Generate html's with XSL (use modified templates): rm -r html; xsltproc --stringparam pg.version '9.4.1' stylesheet.xsl postgres.xml 4. Extract text content from html's as above. 5. Make sure that two text html's are identical: diff -s -u -b -I '^\s*_\+\s*$' html-o-text/xtypes.html html-text/xtypes.html * Differences in whitespaces and length of "____" lines are not significant, too. For now, I've managed to get the same xtypes.html (I tested my XSL customizations with it), but I think, we can eliminate other most outstanding (or maybe all) differences likewise. I can describe XSL customizations in more details, if needed. Best regards, Alexander P.S. I couldn't post the message as a reply due to error on the postgresql.org side. (<[email protected]>: host makus.postgresql.org[174.143.35.229] said: 550 Message headers fail syntax check (in reply to end of DATA command)) 28.10.2015 14:46, Guillaume Lelarge wrote: > > Le 26 oct. 2015 6:40 PM, "Alexander Lakhin" <[email protected]> > a écrit : > > > ... > > To make sure that result of the transformation is the same, I've > compared original .html's with .html's generated with modified templates. > > Unfortunately xslt generates random id's, so it's needed to exclude > them before comparing. I do that with: > > for f in */*.html; do sed -e > 's/id=\"\(ftn\.\)\?id[a-z][0-9]\+\"/id=\"id\"/g' -i $f ; sed -e > 's/href=\"[^#]*#\(ftn\.\)\?id[a-z][0-9]\+\"/href=\"#\"/g' -i $f; done > > > > > > So if it's acceptable way to speed up generation of HTML (and maybe > some other formats), what other steps should we take to move away from > SGML? > > If the performance is still not satisfying, please let me know, I'll > continue to optimize xslt. > > Beside performance issues, I can see some difference in results of > 'make html' and 'make xslthtml'. For example, see > doc/src/sgml/html/spi.html (xslt-generated version doesn't contain the > lists of functions). > > > > What you've done is awesome. I can't wait to test it on the french > translation. > > Nice work! > -- Sent via pgsql-docs mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-docs Attachments: [text/x-patch] xslt-customize.patch (33.5K, 2-xslt-customize.patch) download | inline diff: diff --git a/doc/src/sgml/stylesheet-xhtml-dsssl-like.xsl b/doc/src/sgml/stylesheet-xhtml-dsssl-like.xsl new file mode 100644 index 0000000..95ca042 --- /dev/null +++ b/doc/src/sgml/stylesheet-xhtml-dsssl-like.xsl @@ -0,0 +1,266 @@ +<?xml version="1.0" encoding="utf-8"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" + version="1.0" + xmlns="http://www.w3.org/1999/xhtml" + exclude-result-prefixes="#default"> + +<!-- align with dsssl --> +<xsl:template name="header.navigation"> + <xsl:param name="prev" select="/foo"/> + <xsl:param name="next" select="/foo"/> + <xsl:param name="nav.context"/> + + <xsl:variable name="home" select="/*[1]"/> + <xsl:variable name="up" select="parent::*"/> + + <xsl:variable name="row1" select="$navig.showtitles != 0"/> + <xsl:variable name="row2" select="count($prev) > 0 or (count($up) > 0 and generate-id($up) != generate-id($home) and $navig.showtitles != 0) or count($next) > 0"/> + + <xsl:if test="$suppress.navigation = '0' and $suppress.header.navigation = '0'"> + <div class="navheader"> + <xsl:if test="$row1 or $row2"> + <table width="100%" summary="Navigation header"> + <xsl:if test="$row1"> + <tr> + <th colspan="4" align="center"> + <a> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$home"/> + </xsl:call-template> + </xsl:attribute> + <xsl:apply-templates select="$home" mode="object.title.markup.textonly"/> + </a> + </th> + </tr> + </xsl:if> + + <xsl:if test="$row2"> + <tr> + <td width="10%" align="{$direction.align.start}"> + <xsl:if test="count($prev)>0"> + <a accesskey="p"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$prev"/> + </xsl:call-template> + </xsl:attribute> + <xsl:call-template name="navig.content"> + <xsl:with-param name="direction" select="'prev'"/> + </xsl:call-template> + </a> + </xsl:if> + <xsl:text> </xsl:text> + </td> + <td width="10%" align="center"> + <xsl:choose> + <xsl:when test="count($up)>0 and generate-id($up) != generate-id($home)"> + <a accesskey="u"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$up"/> + </xsl:call-template> + </xsl:attribute> + <xsl:call-template name="navig.content"> + <xsl:with-param name="direction" select="'up'"/> + </xsl:call-template> + </a> + </xsl:when> + <xsl:otherwise> </xsl:otherwise> + </xsl:choose> + </td> + <th width="60%" align="center"> + <xsl:choose> + <xsl:when test="count($up) > 0 and generate-id($up) != generate-id($home) and $navig.showtitles != 0"> + <xsl:apply-templates select="$up" mode="object.title.markup"/> + </xsl:when> + <xsl:otherwise> </xsl:otherwise> + </xsl:choose> + </th> + <td width="20%" align="{$direction.align.end}"> + <xsl:text> </xsl:text> + <xsl:if test="count($next)>0"> + <a accesskey="n"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$next"/> + </xsl:call-template> + </xsl:attribute> + <xsl:call-template name="navig.content"> + <xsl:with-param name="direction" select="'next'"/> + </xsl:call-template> + </a> + </xsl:if> + </td> + </tr> + </xsl:if> + </table> + </xsl:if> + <xsl:if test="$header.rule != 0"> + <hr/> + </xsl:if> + </div> + </xsl:if> +</xsl:template> + +<!-- align with dsssl --> +<xsl:template name="footer.navigation"> + <xsl:param name="prev" select="/foo"/> + <xsl:param name="next" select="/foo"/> + <xsl:param name="nav.context"/> + + <xsl:variable name="home" select="/*[1]"/> + <xsl:variable name="up" select="parent::*"/> + + <xsl:variable name="row1" select="count($prev) > 0 or count($up) > 0 or count($next) > 0"/> + + <xsl:variable name="row2" select="($prev and $navig.showtitles != 0) or (generate-id($home) != generate-id(.) or $nav.context = 'toc') or ($chunk.tocs.and.lots != 0 and $nav.context != 'toc') or ($next and $navig.showtitles != 0)"/> + + <xsl:if test="$suppress.navigation = '0' and $suppress.footer.navigation = '0'"> + <div class="navfooter"> + <xsl:if test="$footer.rule != 0"> + <hr/> + </xsl:if> + + <xsl:if test="$row1 or $row2"> + <table width="100%" summary="Navigation footer"> + <xsl:if test="$row1"> + <tr> + <td width="40%" align="{$direction.align.start}"> + <xsl:if test="count($prev)>0"> + <a accesskey="p"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$prev"/> + </xsl:call-template> + </xsl:attribute> + <xsl:call-template name="navig.content"> + <xsl:with-param name="direction" select="'prev'"/> + </xsl:call-template> + </a> + </xsl:if> + <xsl:text> </xsl:text> + </td> + <td width="20%" align="center"> + <xsl:choose> + <xsl:when test="$home != . or $nav.context = 'toc'"> + <a accesskey="h"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$home"/> + </xsl:call-template> + </xsl:attribute> + <xsl:call-template name="navig.content"> + <xsl:with-param name="direction" select="'home'"/> + </xsl:call-template> + </a> + <xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'"> + <xsl:text> | </xsl:text> + </xsl:if> + </xsl:when> + <xsl:otherwise> </xsl:otherwise> + </xsl:choose> + + <xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'"> + <a accesskey="t"> + <xsl:attribute name="href"> + <xsl:value-of select="$chunked.filename.prefix"/> + <xsl:apply-templates select="/*[1]" mode="recursive-chunk-filename"> + <xsl:with-param name="recursive" select="true()"/> + </xsl:apply-templates> + <xsl:text>-toc</xsl:text> + <xsl:value-of select="$html.ext"/> + </xsl:attribute> + <xsl:call-template name="gentext"> + <xsl:with-param name="key" select="'nav-toc'"/> + </xsl:call-template> + </a> + </xsl:if> + </td> + <td width="40%" align="{$direction.align.end}"> + <xsl:text> </xsl:text> + <xsl:if test="count($next)>0"> + <a accesskey="n"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$next"/> + </xsl:call-template> + </xsl:attribute> + <xsl:call-template name="navig.content"> + <xsl:with-param name="direction" select="'next'"/> + </xsl:call-template> + </a> + </xsl:if> + </td> + </tr> + </xsl:if> + + <xsl:if test="$row2"> + <tr> + <td width="40%" align="{$direction.align.start}" valign="top"> + <xsl:if test="$navig.showtitles != 0"> + <xsl:apply-templates select="$prev" mode="object.title.markup.textonly"/> + </xsl:if> + <xsl:text> </xsl:text> + </td> + <td width="20%" align="center"> + <xsl:choose> + <xsl:when test="count($up)>0 and generate-id($up) != generate-id($home)"> + <a accesskey="u"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$up"/> + </xsl:call-template> + </xsl:attribute> + <xsl:call-template name="navig.content"> + <xsl:with-param name="direction" select="'up'"/> + </xsl:call-template> + </a> + </xsl:when> + <xsl:otherwise> </xsl:otherwise> + </xsl:choose> + </td> + <td width="40%" align="{$direction.align.end}" valign="top"> + <xsl:text> </xsl:text> + <xsl:if test="$navig.showtitles != 0"> + <xsl:apply-templates select="$next" mode="object.title.markup.textonly"/> + </xsl:if> + </td> + </tr> + </xsl:if> + </table> + </xsl:if> + </div> + </xsl:if> +</xsl:template> + + +<xsl:template match="*" mode="object.title.markup.textonly"> + <xsl:variable name="template"> + <xsl:call-template name="gentext.template"> + <xsl:with-param name="context"><xsl:choose> + <xsl:when test="local-name()='chapter' or + local-name()='sect1' or + local-name()='sect2' or + local-name()='sect3' or + local-name()='sect4' or + local-name()='sect5' or + local-name()='simplesect'">title-unnumbered</xsl:when> + <xsl:otherwise>title</xsl:otherwise> + </xsl:choose></xsl:with-param> + <xsl:with-param name="name"> + <xsl:call-template name="xpath.location"/> + </xsl:with-param> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="title"> + <xsl:call-template name="substitute-markup"> + <xsl:with-param name="allow-anchors" select="0"/> + <xsl:with-param name="template" select="$template"/> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="normalize-space($title)"/> +</xsl:template> + +</xsl:stylesheet> diff --git a/doc/src/sgml/stylesheet-xhtml-speedup.xsl b/doc/src/sgml/stylesheet-xhtml-speedup.xsl new file mode 100644 index 0000000..d52b48e --- /dev/null +++ b/doc/src/sgml/stylesheet-xhtml-speedup.xsl @@ -0,0 +1,327 @@ +<?xml version="1.0" encoding="utf-8"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0" + xmlns="http://www.w3.org/1999/xhtml" + exclude-result-prefixes="#default"> + +<!-- common/labels.xsl --> +<xsl:template match="appendix" mode="label.markup"> + <xsl:choose> + <xsl:when test="@label"> + <xsl:value-of select="@label"/> + </xsl:when> + <xsl:when test="string($appendix.autolabel) != 0"> + <xsl:if test="$component.label.includes.part.label != 0 and + ancestor::part"> + <xsl:variable name="part.label"> + <xsl:apply-templates select="ancestor::part" + mode="label.markup"/> + </xsl:variable> + <xsl:if test="$part.label != ''"> + <xsl:value-of select="$part.label"/> + <xsl:apply-templates select="ancestor::part" + mode="intralabel.punctuation"/> + </xsl:if> + </xsl:if> + <xsl:variable name="format"> + <xsl:call-template name="autolabel.format"> + <xsl:with-param name="format" select="$appendix.autolabel"/> + </xsl:call-template> + </xsl:variable> + <xsl:choose> + <xsl:when test="$label.from.part != 0 and ancestor::part"> + <xsl:number from="part" count="appendix" format="{$format}" level="any"/> + </xsl:when> + <xsl:otherwise> +<!-- speed optimizations for pgsql-docs --> + <xsl:number value="count(../preceding-sibling::part/appendix) + count(preceding-sibling::appendix) + 1" format="{$format}" /> +<!-- <xsl:number from="book|article" + count="appendix" format="{$format}" level="any"/> --> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- common/labels.xsl --> +<xsl:template match="chapter" mode="label.markup"> + <xsl:choose> + <xsl:when test="@label"> + <xsl:value-of select="@label"/> + </xsl:when> + <xsl:when test="string($chapter.autolabel) != 0"> + <xsl:if test="$component.label.includes.part.label != 0 and + ancestor::part"> + <xsl:variable name="part.label"> + <xsl:apply-templates select="ancestor::part" + mode="label.markup"/> + </xsl:variable> + <xsl:if test="$part.label != ''"> + <xsl:value-of select="$part.label"/> + <xsl:apply-templates select="ancestor::part" + mode="intralabel.punctuation"/> + </xsl:if> + </xsl:if> + <xsl:variable name="format"> + <xsl:call-template name="autolabel.format"> + <xsl:with-param name="format" select="$chapter.autolabel"/> + </xsl:call-template> + </xsl:variable> + <xsl:choose> + <xsl:when test="$label.from.part != 0 and ancestor::part"> + <xsl:number from="part" count="chapter" format="{$format}" level="any"/> + </xsl:when> + <xsl:otherwise> +<!-- speed optimizations for pgsql-docs --> + <xsl:number value="count(../preceding-sibling::part/chapter) + count(preceding-sibling::chapter) + 1" format="{$format}" /> +<!-- <xsl:number from="book" count="chapter" format="{$format}" level="any"/> --> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- xhtml/autoidx.xsl --> +<xsl:template match="indexterm" mode="reference"> + <xsl:param name="scope" select="."/> + <xsl:param name="role" select="''"/> + <xsl:param name="type" select="''"/> + <xsl:param name="position"/> + <xsl:param name="separator" select="''"/> + + <xsl:variable name="term.separator"> + <xsl:call-template name="index.separator"> + <xsl:with-param name="key" select="'index.term.separator'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="number.separator"> + <xsl:call-template name="index.separator"> + <xsl:with-param name="key" select="'index.number.separator'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="range.separator"> + <xsl:call-template name="index.separator"> + <xsl:with-param name="key" select="'index.range.separator'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:choose> + <xsl:when test="$separator != ''"> + <xsl:value-of select="$separator"/> + </xsl:when> + <xsl:when test="$position = 1"> + <xsl:value-of select="$term.separator"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$number.separator"/> + </xsl:otherwise> + </xsl:choose> + + <xsl:choose> + <xsl:when test="@zone and string(@zone)"> + <xsl:call-template name="reference"> + <xsl:with-param name="zones" select="normalize-space(@zone)"/> + <xsl:with-param name="position" select="position()"/> + <xsl:with-param name="scope" select="$scope"/> + <xsl:with-param name="role" select="$role"/> + <xsl:with-param name="type" select="$type"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <a> + <xsl:apply-templates select="." mode="class.attribute"/> + <xsl:variable name="title"> + <xsl:choose> + <xsl:when test="$index.prefer.titleabbrev != 0"> + <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="titleabbrev.markup"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="title.markup"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:attribute name="href"> + <xsl:choose> + <xsl:when test="$index.links.to.section = 1"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]"/> +<!-- speed optimizations for pgsql-docs --> + <xsl:with-param name="context" select="(/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="."/> + <xsl:with-param name="context" select="(//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))] | //setindex[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + + </xsl:attribute> + + <xsl:value-of select="$title"/> <!-- text only --> + </a> + + <xsl:variable name="id" select="(@id|@xml:id)[1]"/> + <xsl:if test="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))]"> + <xsl:apply-templates select="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][last()]" mode="reference"> + <xsl:with-param name="position" select="position()"/> + <xsl:with-param name="scope" select="$scope"/> + <xsl:with-param name="role" select="$role"/> + <xsl:with-param name="type" select="$type"/> + <xsl:with-param name="separator" select="$range.separator"/> + </xsl:apply-templates> + </xsl:if> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- xhtml/chunk-common.xsl --> +<xsl:template name="chunk-all-sections"> + <xsl:param name="content"> + <xsl:apply-imports/> + </xsl:param> + +<!-- speed optimizations for pgsql-docs --> + <xsl:variable name="prev-v1" select="preceding::*[(self::sect1 and $chunk.section.depth > 0) or (self::sect2 and $chunk.section.depth > 1) or (self::sect3 and $chunk.section.depth > 2) or (self::sect4 and $chunk.section.depth > 3) or (self::sect5 and $chunk.section.depth > 4)][1]"/> + + <xsl:variable name="prev-v2" select="(ancestor::sect1[$chunk.section.depth > 0 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect2[$chunk.section.depth > 1 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect3[$chunk.section.depth > 2 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect4[$chunk.section.depth > 3 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect5[$chunk.section.depth > 4 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::section[$chunk.section.depth > count(ancestor::section) and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1])[last()]"/> + + <xsl:variable name="prev" select="(preceding::book[1] |preceding::preface[1] |preceding::chapter[1] |preceding::appendix[1] |preceding::part[1] |preceding::reference[1] |preceding::refentry[1] |preceding::colophon[1] |preceding::article[1] |preceding::topic[1] |preceding::bibliography[parent::article or parent::book or parent::part][1] |preceding::glossary[parent::article or parent::book or parent::part][1] |preceding::index[$generate.index != 0] [parent::article or parent::book or parent::part][1] |preceding::setindex[$generate.index != 0][1] |ancestor::set |ancestor::book[1] |ancestor::preface[1] |ancestor::chapter[1] |ancestor::appendix[1] |ancestor::part[1] |ancestor::reference[1] |ancestor::article[1] |ancestor::topic[1] |$prev-v1 |$prev-v2)[last()]"/> + +<!-- speed optimizations for pgsql-docs --> + <xsl:variable name="next-v1" select="following::*[self::sect1 or self::sect2 or self::sect3 or self::sect4 or self::sect5][1]"/> + + <xsl:variable name="next-v2" select="(descendant::sect1[$chunk.section.depth > 0 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect2[$chunk.section.depth > 1 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect3[$chunk.section.depth > 2 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect4[$chunk.section.depth > 3 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect5[$chunk.section.depth > 4 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::section[$chunk.section.depth > count(ancestor::section) and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1])[1]"/> + + <xsl:variable name="next" select="(following::book[1] |following::preface[1] |following::chapter[1] |following::appendix[1] |following::part[1] |following::reference[1] |following::refentry[1] |following::colophon[1] |following::bibliography[parent::article or parent::book or parent::part][1] |following::glossary[parent::article or parent::book or parent::part][1] |following::index[$generate.index != 0] [parent::article or parent::book][1] |following::article[1] |following::topic[1] |following::setindex[$generate.index != 0][1] |descendant::book[1] |descendant::preface[1] |descendant::chapter[1] |descendant::appendix[1] |descendant::article[1] |descendant::topic[1] |descendant::bibliography[parent::article or parent::book][1] |descendant::glossary[parent::article or parent::book or parent::part][1] |descendant::index[$generate.index != 0] [parent::article or parent::book][1] |descendant::colophon[1] |descendant::setindex[$generate.index != 0][1] |descendant::part[1] |descendant::reference[1] |descendant::refentry[1] |$next-v1 |$next-v2)[1]"/> + + + <xsl:call-template name="process-chunk"> + <xsl:with-param name="prev" select="$prev"/> + <xsl:with-param name="next" select="$next"/> + <xsl:with-param name="content" select="$content"/> + </xsl:call-template> + +</xsl:template> + + +<xsl:template name="make.legalnotice.head.links"> + <!-- * the following ID is used as part of the legalnotice filename; --> + <!-- * we need it in order to construct the filename for use in the --> + <!-- * value of the href attribute on the link --> + + <xsl:param name="ln-node" select="(//legalnotice)[1]"/> + + <xsl:param name="linktype"> + <xsl:choose> + <xsl:when test="contains($html.head.legalnotice.link.types, ' ')"> + <xsl:value-of select="normalize-space( substring-before($html.head.legalnotice.link.types, ' '))"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$html.head.legalnotice.link.types"/> + </xsl:otherwise> + </xsl:choose> + </xsl:param> + <xsl:param name="remaining.linktypes" select="concat( normalize-space( substring-after($html.head.legalnotice.link.types, ' ')),' ')"/> + <xsl:if test="not($linktype = '')"> + <!-- Compute name of legalnotice file (see titlepage.xsl) --> + <xsl:variable name="file"> + <xsl:call-template name="ln.or.rh.filename"> + <xsl:with-param name="node" select="$ln-node"/> + </xsl:call-template> + </xsl:variable> + + <link rel="{$linktype}"> + <xsl:attribute name="href"> + <xsl:value-of select="$file"/> + </xsl:attribute> + <xsl:attribute name="title"> +<!-- speed optimizations for pgsql-docs --> + <xsl:apply-templates select="/book/bookinfo/legalnotice" mode="object.title.markup.textonly"/> + </xsl:attribute> + </link> +<!-- speed optimizations for pgsql-docs --> +<!-- <xsl:call-template name="make.legalnotice.head.links"> + < ! - - * pop the next value off the list of link types - - > + <xsl:with-param name="linktype" select="substring-before($remaining.linktypes, ' ')"/> + < ! - - * remove the link type from the list of remaining link types - - > + <xsl:with-param name="remaining.linktypes" select="substring-after($remaining.linktypes, ' ')"/> + </xsl:call-template> --> + </xsl:if> +</xsl:template> + +<!-- xhtml/html.xsl (needed for the following "reference" template) --> +<xsl:template name="id.attribute"> + <xsl:param name="node" select="."/> + <xsl:param name="conditional" select="1"/> + <xsl:choose> + <xsl:when test="$generate.id.attributes = 0"> + <!-- No id attributes when this param is zero --> + </xsl:when> + <xsl:when test="$conditional = 0 or $node/@id or $node/@xml:id"> + <xsl:attribute name="id"> + <xsl:call-template name="object.id"> + <xsl:with-param name="object" select="$node"/> + </xsl:call-template> + </xsl:attribute> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- xhtml/autoidx.xsl --> +<xsl:template name="reference"> + <xsl:param name="scope" select="."/> + <xsl:param name="role" select="''"/> + <xsl:param name="type" select="''"/> + <xsl:param name="zones"/> + + <xsl:choose> + <xsl:when test="contains($zones, ' ')"> + <xsl:variable name="zone" select="substring-before($zones, ' ')"/> + <xsl:variable name="target" select="key('sections', $zone)"/> + + <a> + <xsl:apply-templates select="." mode="class.attribute"/> + <xsl:call-template name="id.attribute"/> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$target[1]"/> + <xsl:with-param name="context" select="//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/> + </xsl:call-template> + </xsl:attribute> + <xsl:apply-templates select="$target[1]" mode="index-title-content"/> + </a> + <xsl:text>, </xsl:text> + <xsl:call-template name="reference"> + <xsl:with-param name="zones" select="substring-after($zones, ' ')"/> + <xsl:with-param name="position" select="position()"/> + <xsl:with-param name="scope" select="$scope"/> + <xsl:with-param name="role" select="$role"/> + <xsl:with-param name="type" select="$type"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="zone" select="$zones"/> + <xsl:variable name="target" select="key('sections', $zone)"/> + + <a> + <xsl:apply-templates select="." mode="class.attribute"/> + <xsl:call-template name="id.attribute"/> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> + <xsl:with-param name="object" select="$target[1]"/> +<!-- speed optimizations for pgsql-docs --> + <xsl:with-param name="context" select="/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/> + </xsl:call-template> + </xsl:attribute> + <xsl:apply-templates select="$target[1]" mode="index-title-content"/> + </a> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +</xsl:stylesheet> diff --git a/doc/src/sgml/stylesheet.xsl b/doc/src/sgml/stylesheet.xsl index 7967b36..07be4a7 100644 --- a/doc/src/sgml/stylesheet.xsl +++ b/doc/src/sgml/stylesheet.xsl @@ -6,6 +6,8 @@ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/> <xsl:include href="stylesheet-common.xsl" /> +<xsl:include href="stylesheet-xhtml-speedup.xsl" /> +<xsl:include href="stylesheet-xhtml-dsssl-like.xsl" /> <!-- Parameters --> @@ -13,7 +15,7 @@ <xsl:param name="use.id.as.filename" select="'1'"></xsl:param> <xsl:param name="make.valid.html" select="1"></xsl:param> <xsl:param name="generate.id.attributes" select="1"></xsl:param> -<xsl:param name="generate.legalnotice.link" select="1"></xsl:param> +<xsl:param name="generate.legalnotice.link" select="0"></xsl:param> <xsl:param name="link.mailto.url">[email protected]</xsl:param> <xsl:param name="chunk.first.sections" select="1"/> <xsl:param name="chunk.quietly" select="1"></xsl:param> @@ -21,6 +23,9 @@ <xsl:param name="website.stylesheet" select="0"/> +<xsl:param name="generate.section.toc.level" select="1"></xsl:param> +<xsl:param name="xref.with.number.and.title" select="0"></xsl:param> + <xsl:param name="html.stylesheet"> <xsl:choose> <xsl:when test="$website.stylesheet = 0">stylesheet.css</xsl:when> ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-11-02 20:15 Stefan Kaltenbrunner <[email protected]> parent: Alexander Lakhin <[email protected]> 0 siblings, 0 replies; 9+ messages in thread From: Stefan Kaltenbrunner @ 2015-11-02 20:15 UTC (permalink / raw) To: Alexander Lakhin <[email protected]>; +Cc: pgsql-docs On 10/30/2015 02:40 PM, Alexander Lakhin wrote: > Hello, Guillaume. > > We have plans to use this for russian translation, too. We translate the > docs by converting (with xml2po) the single xml to postgres-ru.po and > after translating it we convert it back to xml (we get postres-ru.xml > here). (Until now we had to perform one more conversion > (postgres-ru.xml -> set of sgml's).) > So now we can get russian html/* with: > python xml2po.py -l ru -k -p postgres-ru.po postgres.xml >postgres-ru.xml > xsltproc --stringparam pg.version '9.4.1' stylesheet.xsl postgres-ru.xml > > But I had some doubts about DSSSL and XSL differences. As I noted > previously there was at least one visible difference. So I decided to > customize XSL templates to make sure that html's are generated without a > loss or corruption. > I thought that comparing two HTML sources will not work, as they are too > different, but maybe we can compare text generated from html by lynx, > for example. > So I use the following procedure to look for differences: > 0. Get dsssl-generated html's > make html > 1. Extract text content from html's: > for f in html/*.html; do fn=`basename $f`; echo $fn; cat $f | perl -0pi > -pe 's/<B\s*>Note:\s*<\/B\s*>/\<h3>Note<\/h3>/g' | perl -0pi -pe > 's/><BLOCKQUOTE\s*CLASS="NOTE"/><div/ig' >/tmp/$fn; lynx /tmp/$fn --dump >>html-text/$fn; > * Some differences are not significant so it's not reasonable to modify > XSL templates to eliminate them. Difference in "Note" placement and > spelling is one of them, so I just filter it out. > 2. Rename html to html-o and html-text to html-o-text. > 3. Generate html's with XSL (use modified templates): > rm -r html; xsltproc --stringparam pg.version '9.4.1' stylesheet.xsl > postgres.xml > 4. Extract text content from html's as above. > 5. Make sure that two text html's are identical: > diff -s -u -b -I '^\s*_\+\s*$' html-o-text/xtypes.html > html-text/xtypes.html > * Differences in whitespaces and length of "____" lines are not > significant, too. > > For now, I've managed to get the same xtypes.html (I tested my XSL > customizations with it), but I think, we can eliminate other most > outstanding (or maybe all) differences likewise. > I can describe XSL customizations in more details, if needed. > > Best regards, > Alexander > > P.S. I couldn't post the message as a reply due to error on the > postgresql.org side. > (<[email protected]>: host makus.postgresql.org[174.143.35.229] > said: > 550 Message headers fail syntax check (in reply to end of DATA > command)) Sorry for not replying earlier but most of the sysadmin team is not tracking pgsql-docs that closely for issues - afaiks there was a typo in your mail - the "To" in your mail looked like this: To: pgsql-docs@postgresql org <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <CAECtzeWiOkS=wVnk4T+4Bg3-z-5DGL09jp7ks5QAiDEO4d10+Q@mail.gmail.com> notice that there is a space after "pgsql-docs@postgresql" instead of what I suspect should be a "." causing the header syntax check in exim to barf on the mail. Stefan -- Sent via pgsql-docs mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-docs ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-11-03 17:46 Oleg Bartunov <[email protected]> parent: Alexander Lakhin <[email protected]> 1 sibling, 1 reply; 9+ messages in thread From: Oleg Bartunov @ 2015-11-03 17:46 UTC (permalink / raw) To: Alexander Lakhin <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Luzanov Pavel <[email protected]>; pgsql-docs On Mon, Oct 26, 2015 at 11:53 AM, Alexander Lakhin <[email protected]> wrote: > Hello, Peter. > > I've managed to speed up html generation from xml (make xslthtml) from 32 > min. (in my environment) to 4 min. by modifying slowest XSL templates. > All my modifications incorporated in a single file > stylesheet-xhtml-speedup.xsl, which is included in stylesheet.xsl. > I performed optimization by analyzing output of: > xsltproc --profile --stringparam pg.version '9.6devel' stylesheet.xsl > postgres.xml > Initial statistics: > number match name mode Calls Tot 100us > Avg > > 0 appendix label.markup > 23090 90677526 3927 > 1 chapter label.markup > 28870 39740757 1376 > 2 chunk-all-sections 1289 23845066 18498 > 3 make.legalnotice.head.links > 2578 9630258 3735 > 4 indexterm reference 2579 4126513 1600 > 5 html.head 1289 3112534 2414 > ... > index % time self children called name > 0.479 1326.034 22/23090 toc.line [61] > 5.128 1308.245 21944/23090 sect1[label.markup] [13] > 3.772 1318.264 850/23090 substitute-markup [15] > 1.355 1304.631 274/23090 > figure|table|example[label.markup] [32] > [0] 47.95 906.775 1.613 23090 appendix[label.markup] [0] > 1.613 0.000 23090/23090 autolabel.format [29] > ----------------------------------------------- > 5.128 1308.245 24708/28870 sect1[label.markup] [13] > 0.479 1326.034 130/28870 toc.line [61] > 3.772 1318.264 2112/28870 substitute-markup [15] > 1.355 1304.631 1920/28870 > figure|table|example[label.markup] [32] > [1] 21.01 397.408 1.613 28870 chapter[label.markup] [1] > 1.613 0.000 28870/28870 autolabel.format [29] > ----------------------------------------------- > 0.164 238.606 1289/1289 process-chunk-element [98] > [2] 12.61 238.451 0.225 1289 chunk-all-sections [2] > 0.225 7.117 1289/1289 process-chunk [86] > ----------------------------------------------- > 31.125 112.261 1289/2578 html.head [5] > 96.303 96.726 1289/2578 make.legalnotice.head.links [3] > [3] 5.09 96.303 96.726 2578 make.legalnotice.head.links [3] > 96.303 96.726 1289/3867 make.legalnotice.head.links [3] > 0.339 0.494 1289/3867 *[object.title.markup.textonly] > [69] > 0.085 0.781 1289/3867 ln.or.rh.filename [116] > > ----------------------------------------------- > > > Currrent statistics: > number match name mode Calls Tot 100us > Avg > > 0 chunk-all-sections 1289 5405958 4193 > 1 make.legalnotice.head.links > 1289 3159538 > 2451 > 2 html.head 1289 3068417 2380 > 3 gentext.template 689835 2327761 3 > 4 l10n.language 564453 1455253 2 > 5 href.target 29881 1344063 44 > --- > index % time self children called name > 0.136 54.207 1289/1289 process-chunk-element [95] > [0] 20.40 54.060 0.312 1289 chunk-all-sections [0] > 0.312 6.468 1289/1289 process-chunk [67] > ----------------------------------------------- > 30.684 45.458 1289/1289 html.head [2] > [1] 11.92 31.595 0.448 1289 make.legalnotice.head.links [1] > 0.290 0.403 1289/2578 *[object.title.markup.textonly] > [71] > 0.159 0.828 1289/2578 ln.or.rh.filename [91] > ----------------------------------------------- > 0.330 31.617 1289/1289 chunk-element-content [65] > [2] 11.58 30.684 45.458 1289 html.head [2] > 31.595 0.448 1289/15462 make.legalnotice.head.links [1] > 13.441 4.726 5153/15462 href.target [5] > 0.290 0.403 5153/15462 > *[object.title.markup.textonly] [71] > 0.115 1.576 1289/15462 head.content [99] > 0.012 0.000 1289/15462 system.head.content [186] > 0.006 0.000 1289/15462 user.head.content [228] > > To make sure that result of the transformation is the same, I've compared > original .html's with .html's generated with modified templates. > Unfortunately xslt generates random id's, so it's needed to exclude them > before comparing. I do that with: > for f in */*.html; do sed -e > 's/id=\"\(ftn\.\)\?id[a-z][0-9]\+\"/id=\"id\"/g' -i $f ; sed -e > 's/href=\"[^#]*#\(ftn\.\)\?id[a-z][0-9]\+\"/href=\"#\"/g' -i $f; done > > > So if it's acceptable way to speed up generation of HTML (and maybe some > other formats), what other steps should we take to move away from SGML? > If the performance is still not satisfying, please let me know, I'll > continue to optimize xslt. > Beside performance issues, I can see some difference in results of 'make > html' and 'make xslthtml'. For example, see doc/src/sgml/html/spi.html > (xslt-generated version doesn't contain the lists of functions). > > Best regards, > Alexander I think this is great result and it's worth to start moving to xml. I want to note, that it's 21-th century and we should think about including pictures into our documentation, which will greatly improve it. XML makes this easier. > > > > > 06.04.2015 23:02, Peter Eisentraut wrote: > >> On 4/2/15 5:22 PM, Luzanov Pavel wrote: >> >>> Peter, >>> >>> >>> I found this message in archives: >>> >>> >>> http://www.postgresql.org/message-id/flat/[email protected]#[email protected] >>> >>> >>> and, as you recommend, tested a speed of building docs on a fresh Ubuntu >>> installation. >>> >>> 50sec for make html >>> and 14min 50sec for make xslthtml >>> 17 times slower! >>> >>> >>> Is it still a main stopper for moving to XML? >>> >> Yes :) >> >> >> >> > > > -- > Sent via pgsql-docs mailing list ([email protected]) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-docs > > ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-11-03 20:10 Dmitry Igrishin <[email protected]> parent: Oleg Bartunov <[email protected]> 0 siblings, 1 reply; 9+ messages in thread From: Dmitry Igrishin @ 2015-11-03 20:10 UTC (permalink / raw) To: Oleg Bartunov <[email protected]>; +Cc: Alexander Lakhin <[email protected]>; Peter Eisentraut <[email protected]>; Luzanov Pavel <[email protected]>; pgsql-docs 2015-11-03 20:46 GMT+03:00 Oleg Bartunov <[email protected]>: > > > On Mon, Oct 26, 2015 at 11:53 AM, Alexander Lakhin < > [email protected]> wrote: > >> Hello, Peter. >> >> I've managed to speed up html generation from xml (make xslthtml) from 32 >> min. (in my environment) to 4 min. by modifying slowest XSL templates. >> All my modifications incorporated in a single file >> stylesheet-xhtml-speedup.xsl, which is included in stylesheet.xsl. >> I performed optimization by analyzing output of: >> xsltproc --profile --stringparam pg.version '9.6devel' stylesheet.xsl >> postgres.xml >> Initial statistics: >> number match name mode Calls Tot 100us >> Avg >> >> 0 appendix label.markup >> 23090 90677526 3927 >> 1 chapter label.markup >> 28870 39740757 1376 >> 2 chunk-all-sections 1289 23845066 18498 >> 3 make.legalnotice.head.links >> 2578 9630258 3735 >> 4 indexterm reference 2579 4126513 1600 >> 5 html.head 1289 3112534 2414 >> ... >> index % time self children called name >> 0.479 1326.034 22/23090 toc.line [61] >> 5.128 1308.245 21944/23090 sect1[label.markup] [13] >> 3.772 1318.264 850/23090 substitute-markup [15] >> 1.355 1304.631 274/23090 >> figure|table|example[label.markup] [32] >> [0] 47.95 906.775 1.613 23090 appendix[label.markup] [0] >> 1.613 0.000 23090/23090 autolabel.format [29] >> ----------------------------------------------- >> 5.128 1308.245 24708/28870 sect1[label.markup] [13] >> 0.479 1326.034 130/28870 toc.line [61] >> 3.772 1318.264 2112/28870 substitute-markup [15] >> 1.355 1304.631 1920/28870 >> figure|table|example[label.markup] [32] >> [1] 21.01 397.408 1.613 28870 chapter[label.markup] [1] >> 1.613 0.000 28870/28870 autolabel.format [29] >> ----------------------------------------------- >> 0.164 238.606 1289/1289 process-chunk-element [98] >> [2] 12.61 238.451 0.225 1289 chunk-all-sections [2] >> 0.225 7.117 1289/1289 process-chunk [86] >> ----------------------------------------------- >> 31.125 112.261 1289/2578 html.head [5] >> 96.303 96.726 1289/2578 make.legalnotice.head.links [3] >> [3] 5.09 96.303 96.726 2578 make.legalnotice.head.links [3] >> 96.303 96.726 1289/3867 make.legalnotice.head.links [3] >> 0.339 0.494 1289/3867 >> *[object.title.markup.textonly] [69] >> 0.085 0.781 1289/3867 ln.or.rh.filename [116] >> >> ----------------------------------------------- >> >> >> Currrent statistics: >> number match name mode Calls Tot 100us >> Avg >> >> 0 chunk-all-sections 1289 5405958 4193 >> 1 make.legalnotice.head.links >> 1289 3159538 >> 2451 >> 2 html.head 1289 3068417 2380 >> 3 gentext.template 689835 2327761 3 >> 4 l10n.language 564453 1455253 2 >> 5 href.target 29881 1344063 44 >> --- >> index % time self children called name >> 0.136 54.207 1289/1289 process-chunk-element [95] >> [0] 20.40 54.060 0.312 1289 chunk-all-sections [0] >> 0.312 6.468 1289/1289 process-chunk [67] >> ----------------------------------------------- >> 30.684 45.458 1289/1289 html.head [2] >> [1] 11.92 31.595 0.448 1289 make.legalnotice.head.links [1] >> 0.290 0.403 1289/2578 >> *[object.title.markup.textonly] [71] >> 0.159 0.828 1289/2578 ln.or.rh.filename [91] >> ----------------------------------------------- >> 0.330 31.617 1289/1289 chunk-element-content [65] >> [2] 11.58 30.684 45.458 1289 html.head [2] >> 31.595 0.448 1289/15462 make.legalnotice.head.links >> [1] >> 13.441 4.726 5153/15462 href.target [5] >> 0.290 0.403 5153/15462 >> *[object.title.markup.textonly] [71] >> 0.115 1.576 1289/15462 head.content [99] >> 0.012 0.000 1289/15462 system.head.content [186] >> 0.006 0.000 1289/15462 user.head.content [228] >> >> To make sure that result of the transformation is the same, I've compared >> original .html's with .html's generated with modified templates. >> Unfortunately xslt generates random id's, so it's needed to exclude them >> before comparing. I do that with: >> for f in */*.html; do sed -e >> 's/id=\"\(ftn\.\)\?id[a-z][0-9]\+\"/id=\"id\"/g' -i $f ; sed -e >> 's/href=\"[^#]*#\(ftn\.\)\?id[a-z][0-9]\+\"/href=\"#\"/g' -i $f; done >> >> >> So if it's acceptable way to speed up generation of HTML (and maybe some >> other formats), what other steps should we take to move away from SGML? >> If the performance is still not satisfying, please let me know, I'll >> continue to optimize xslt. >> Beside performance issues, I can see some difference in results of 'make >> html' and 'make xslthtml'. For example, see doc/src/sgml/html/spi.html >> (xslt-generated version doesn't contain the lists of functions). >> >> Best regards, >> Alexander > > > I think this is great result and it's worth to start moving to xml. > I think that moving to XML is step backward, because XML is ugly. > I want to note, that it's 21-th century and we should think about > including pictures into our documentation, which will greatly improve it. > Yeah, +1. > XML makes this easier. > And I think that Lisp is much better for this puprose. -- // Dmitry. ^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: Moving documentation to XML @ 2015-11-04 03:15 Tair Sabirgaliev <[email protected]> parent: Dmitry Igrishin <[email protected]> 0 siblings, 0 replies; 9+ messages in thread From: Tair Sabirgaliev @ 2015-11-04 03:15 UTC (permalink / raw) To: Dmitry Igrishin <[email protected]>; Oleg Bartunov <[email protected]>; +Cc: Alexander Lakhin <[email protected]>; Peter Eisentraut <[email protected]>; Luzanov Pavel <[email protected]>; pgsql-docs Then there is asciidoc.. On Ср, 4 нояб. 2015 г. at 2:11 Dmitry Igrishin <[email protected]> wrote: > 2015-11-03 20:46 GMT+03:00 Oleg Bartunov <[email protected]>: > >> >> >> On Mon, Oct 26, 2015 at 11:53 AM, Alexander Lakhin < >> [email protected]> wrote: >> >>> Hello, Peter. >>> >>> I've managed to speed up html generation from xml (make xslthtml) from >>> 32 min. (in my environment) to 4 min. by modifying slowest XSL templates. >>> All my modifications incorporated in a single file >>> stylesheet-xhtml-speedup.xsl, which is included in stylesheet.xsl. >>> I performed optimization by analyzing output of: >>> xsltproc --profile --stringparam pg.version '9.6devel' stylesheet.xsl >>> postgres.xml >>> Initial statistics: >>> number match name mode Calls Tot 100us >>> Avg >>> >>> 0 appendix label.markup >>> 23090 90677526 3927 >>> 1 chapter label.markup >>> 28870 39740757 1376 >>> 2 chunk-all-sections 1289 23845066 18498 >>> 3 make.legalnotice.head.links >>> 2578 9630258 3735 >>> 4 indexterm reference 2579 4126513 1600 >>> 5 html.head 1289 3112534 2414 >>> ... >>> index % time self children called name >>> 0.479 1326.034 22/23090 toc.line [61] >>> 5.128 1308.245 21944/23090 sect1[label.markup] [13] >>> 3.772 1318.264 850/23090 substitute-markup [15] >>> 1.355 1304.631 274/23090 >>> figure|table|example[label.markup] [32] >>> [0] 47.95 906.775 1.613 23090 appendix[label.markup] [0] >>> 1.613 0.000 23090/23090 autolabel.format [29] >>> ----------------------------------------------- >>> 5.128 1308.245 24708/28870 sect1[label.markup] [13] >>> 0.479 1326.034 130/28870 toc.line [61] >>> 3.772 1318.264 2112/28870 substitute-markup [15] >>> 1.355 1304.631 1920/28870 >>> figure|table|example[label.markup] [32] >>> [1] 21.01 397.408 1.613 28870 chapter[label.markup] [1] >>> 1.613 0.000 28870/28870 autolabel.format [29] >>> ----------------------------------------------- >>> 0.164 238.606 1289/1289 process-chunk-element [98] >>> [2] 12.61 238.451 0.225 1289 chunk-all-sections [2] >>> 0.225 7.117 1289/1289 process-chunk [86] >>> ----------------------------------------------- >>> 31.125 112.261 1289/2578 html.head [5] >>> 96.303 96.726 1289/2578 make.legalnotice.head.links >>> [3] >>> [3] 5.09 96.303 96.726 2578 make.legalnotice.head.links [3] >>> 96.303 96.726 1289/3867 make.legalnotice.head.links >>> [3] >>> 0.339 0.494 1289/3867 >>> *[object.title.markup.textonly] [69] >>> 0.085 0.781 1289/3867 ln.or.rh.filename [116] >>> >>> ----------------------------------------------- >>> >>> >>> Currrent statistics: >>> number match name mode Calls Tot 100us >>> Avg >>> >>> 0 chunk-all-sections 1289 5405958 4193 >>> 1 make.legalnotice.head.links >>> 1289 3159538 >>> 2451 >>> 2 html.head 1289 3068417 2380 >>> 3 gentext.template 689835 2327761 3 >>> 4 l10n.language 564453 1455253 2 >>> 5 href.target 29881 1344063 44 >>> --- >>> index % time self children called name >>> 0.136 54.207 1289/1289 process-chunk-element [95] >>> [0] 20.40 54.060 0.312 1289 chunk-all-sections [0] >>> 0.312 6.468 1289/1289 process-chunk [67] >>> ----------------------------------------------- >>> 30.684 45.458 1289/1289 html.head [2] >>> [1] 11.92 31.595 0.448 1289 make.legalnotice.head.links [1] >>> 0.290 0.403 1289/2578 >>> *[object.title.markup.textonly] [71] >>> 0.159 0.828 1289/2578 ln.or.rh.filename [91] >>> ----------------------------------------------- >>> 0.330 31.617 1289/1289 chunk-element-content [65] >>> [2] 11.58 30.684 45.458 1289 html.head [2] >>> 31.595 0.448 1289/15462 make.legalnotice.head.links >>> [1] >>> 13.441 4.726 5153/15462 href.target [5] >>> 0.290 0.403 5153/15462 >>> *[object.title.markup.textonly] [71] >>> 0.115 1.576 1289/15462 head.content [99] >>> 0.012 0.000 1289/15462 system.head.content [186] >>> 0.006 0.000 1289/15462 user.head.content [228] >>> >>> To make sure that result of the transformation is the same, I've >>> compared original .html's with .html's generated with modified templates. >>> Unfortunately xslt generates random id's, so it's needed to exclude them >>> before comparing. I do that with: >>> for f in */*.html; do sed -e >>> 's/id=\"\(ftn\.\)\?id[a-z][0-9]\+\"/id=\"id\"/g' -i $f ; sed -e >>> 's/href=\"[^#]*#\(ftn\.\)\?id[a-z][0-9]\+\"/href=\"#\"/g' -i $f; done >>> >>> >>> So if it's acceptable way to speed up generation of HTML (and maybe some >>> other formats), what other steps should we take to move away from SGML? >>> If the performance is still not satisfying, please let me know, I'll >>> continue to optimize xslt. >>> Beside performance issues, I can see some difference in results of 'make >>> html' and 'make xslthtml'. For example, see doc/src/sgml/html/spi.html >>> (xslt-generated version doesn't contain the lists of functions). >>> >>> Best regards, >>> Alexander >> >> >> I think this is great result and it's worth to start moving to xml. >> > I think that moving to XML is step backward, because XML is ugly. > >> I want to note, that it's 21-th century and we should think about >> including pictures into our documentation, which will greatly improve it. >> > Yeah, +1. > >> XML makes this easier. >> > And I think that Lisp is much better for this puprose. > > -- > // Dmitry. > > ^ permalink raw reply [nested|flat] 9+ messages in thread
end of thread, other threads:[~2015-11-04 03:15 UTC | newest] Thread overview: 9+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2015-04-02 21:22 Moving documentation to XML Luzanov Pavel <[email protected]> 2015-04-06 20:02 ` Peter Eisentraut <[email protected]> 2015-10-26 10:53 ` Alexander Lakhin <[email protected]> 2015-10-28 11:46 ` Guillaume Lelarge <[email protected]> 2015-11-03 17:46 ` Oleg Bartunov <[email protected]> 2015-11-03 20:10 ` Dmitry Igrishin <[email protected]> 2015-11-04 03:15 ` Tair Sabirgaliev <[email protected]> 2015-10-30 13:40 Re: Moving documentation to XML Alexander Lakhin <[email protected]> 2015-11-02 20:15 ` Stefan Kaltenbrunner <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox