Как добиться того, чтобы фрагменты DocBook XSL генерировали полное оглавление для каждой страницы?

У меня есть куча XML-файлов DocBook, которые все объединены в один файл DocBook для преобразования в HTML. Каждый отдельный документ является справочной страницей (для функции или аналогичной конструкции). Я использую генерацию фрагментированного HTML, так что каждая справочная страница становится отдельной HTML-страницей.

Проблема в следующем: мне нужно оглавление на каждой странице. Но мне не нужно оглавление для < em> эту страницу. Мне нужен полный оглавление для всего справочного руководства.

То есть с любой страницы я хочу иметь возможность переходить на любую другую страницу, используя оглавление. Я могу использовать стили CSS, чтобы разместить оглавление с левой стороны (и даже скрыть его для просмотра на мобильных устройствах или чего-то еще).

Есть очевидный способ справиться с этим. Я мог бы извлечь основное оглавление с помощью сценария постобработки и заставить сценарий скопировать его в каждый из выходных HTML-документов. Я ищу способ сделать это, работающий в DocBook XSL.

Я хочу, чтобы результаты были похожи на новую веб-справку DocBook XSL, но с меньшим явным участием JavaScript.


person Nicol Bolas    schedule 25.12.2015    source источник


Ответы (2)


Есть относительно простой способ получить это, хотя я уверен, что вы не сможете без создание слоя настройки DocBook XSL или просто изменение установленных (системных) таблиц стилей.

В любом случае, я думаю, что фактический шаблон docbook-xsl, который вам нужно изменить или переопределить, называется make.toc и находится в дистрибутиве таблиц стилей в файле html/autotoc.xsl.

Это большой шаблон - почти сотня строк, но вам нужно всего лишь изменить его в одну строку:

--- /usr/share/xml/docbook/stylesheet/docbook-xsl/html/autotoc.xsl  2012-12-16 11:35:12.000000000 +0900
+++ /opt/workspace/autotoc.xsl  2015-12-26 09:19:36.000000000 +0900
@@ -28,7 +28,7 @@
 </xsl:variable>

 <xsl:template name="make.toc">
-  <xsl:param name="toc-context" select="."/>
+  <xsl:param name="toc-context" select="/"/>
   <xsl:param name="toc.title.p" select="true()"/>
   <xsl:param name="nodes" select="/NOT-AN-ELEMENT"/>

То есть вам нужно вызвать этот шаблон с параметром toc-context, установленным на «/» (вместо «.»).

Значение по умолчанию «.» сообщает шаблону, что при создании оглавления для фрагмента он должен смотреть только на (дочернее) содержимое того элемента, который он обрабатывает в данный момент (то есть на корень этого конкретного фрагмента); например, если он обрабатывает section, он смотрит только на дочерние элементы этого section.

Но если вместо этого вы измените это значение на «/», вы укажете шаблону каждый раз (пере) просматривать все содержимое исходного документа. Поэтому, если ваш документ book, он будет каждый раз давать вам полное оглавление для всей книги, а если ваш документ - это article, вся статья и т. Д.

Так что я думаю, это должно дать вам то, чего вы хотите.

Если вы решили просто изменить установленные таблицы стилей и установили их из любого менеджера пакетов для конкретной ОС, который вы используете, вам нужно найти, где установлен html/autotoc.xsl файл.

В моей системе Debian Linux html/autotoc.xsl файл находится здесь:

/usr/share/xml/docbook/stylesheet/docbook-xsl/html/autotoc.xsl

А в моей системе OS X, установленной из пакета homebrew, он находится здесь:

/usr/local/opt/docbook-xsl/docbook-xsl/html/autotoc.xsl

Если вместо этого вы решите создать уровень настройки, вам необходимо скопировать его весь шаблон make.toc в ваш уровень настройки (но с этим toc-context параметром, измененным на "/").

person sideshowbarker    schedule 26.12.2015

По состоянию на 2019-07-06 с docbook-xsl-1.79.2 принятого в настоящее время ответа недостаточно для завершения каждого оглавления.

Однако следующий шаблон XSL это делает. Ключевым моментом было прохождение отладчика редактора Oxygen XML и обнаружение того, что, хотя toc-context был правильно установлен как корневой элемент, переменная nodes все еще оставалась локальным подмножеством.

Я отменил toc-context изменение. Вместо этого я создал новую переменную root-nodes, выбрав /, и отредактировал шаблон make.toc, чтобы использовать root-nodes вместо nodes..

Помещение этого в мой уровень настройки теперь превращает каждое оглавление в полное оглавление.

<xsl:template name="make.toc">
  <xsl:param name="toc-context" select="."/>
  <xsl:param name="toc.title.p" select="true()"/>
  <xsl:param name="nodes" select="/NOT-AN-ELEMENT"/>
  <xsl:variable name="root-nodes" select="/"/>

  <xsl:variable name="nodes.plus" select="$root-nodes | d:qandaset"/>

  <xsl:variable name="toc.title">
   <xsl:if test="$toc.title.p">
    <xsl:choose>
     <xsl:when test="$make.clean.html != 0">
      <div class="toc-title">
       <xsl:call-template name="gentext">
        <xsl:with-param name="key">TableofContents</xsl:with-param>
       </xsl:call-template>
      </div>
     </xsl:when>
     <xsl:otherwise>
      <p>
       <strong>
        <xsl:call-template name="gentext">
         <xsl:with-param name="key">TableofContents</xsl:with-param>
        </xsl:call-template>
       </strong>
      </p>
     </xsl:otherwise>
    </xsl:choose>
   </xsl:if>
  </xsl:variable>

  <xsl:choose>
   <xsl:when test="$manual.toc != ''">
    <xsl:variable name="id">
     <xsl:call-template name="object.id"/>
    </xsl:variable>
    <xsl:variable name="toc" select="document($manual.toc, .)"/>
    <xsl:variable name="tocentry" select="$toc//d:tocentry[@linkend=$id]"/>
    <xsl:if test="$tocentry and $tocentry/*">
     <div class="toc">
      <xsl:copy-of select="$toc.title"/>
      <xsl:element name="{$toc.list.type}" namespace="http://www.w3.org/1999/xhtml">
       <xsl:call-template name="toc.list.attributes">
        <xsl:with-param name="toc-context" select="$toc-context"/>
        <xsl:with-param name="toc.title.p" select="$toc.title.p"/>
        <xsl:with-param name="nodes" select="$root-nodes"/>
       </xsl:call-template>
       <xsl:call-template name="manual-toc">
        <xsl:with-param name="tocentry" select="$tocentry/*[1]"/>
       </xsl:call-template>
      </xsl:element>
     </div>
    </xsl:if>
   </xsl:when>
   <xsl:otherwise>
    <xsl:choose>
     <xsl:when test="$qanda.in.toc != 0">
      <xsl:if test="$nodes.plus">
       <div class="toc">
        <xsl:copy-of select="$toc.title"/>
        <xsl:element name="{$toc.list.type}" namespace="http://www.w3.org/1999/xhtml">
         <xsl:call-template name="toc.list.attributes">
          <xsl:with-param name="toc-context" select="$toc-context"/>
          <xsl:with-param name="toc.title.p" select="$toc.title.p"/>
          <xsl:with-param name="nodes" select="$root-nodes"/>
         </xsl:call-template>
         <xsl:apply-templates select="$nodes.plus" mode="toc">
          <xsl:with-param name="toc-context" select="$toc-context"/>
         </xsl:apply-templates>
        </xsl:element>
       </div>
      </xsl:if>
     </xsl:when>
     <xsl:otherwise>
      <xsl:if test="$root-nodes">
       <div class="toc">
        <xsl:copy-of select="$toc.title"/>
        <xsl:element name="{$toc.list.type}" namespace="http://www.w3.org/1999/xhtml">
         <xsl:call-template name="toc.list.attributes">
          <xsl:with-param name="toc-context" select="$toc-context"/>
          <xsl:with-param name="toc.title.p" select="$toc.title.p"/>
          <xsl:with-param name="nodes" select="$root-nodes"/>
         </xsl:call-template>
         <xsl:apply-templates select="$root-nodes" mode="toc">
          <xsl:with-param name="toc-context" select="$toc-context"/>
         </xsl:apply-templates>
        </xsl:element>
       </div>
      </xsl:if>
     </xsl:otherwise>
    </xsl:choose>

   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

Примечание. остается проблема, при которой не каждая фрагментированная страница получает свои собственные ToC, но это не связано с этим конкретным. Если я сортирую, я добавлю комментарий о том, как я это сделал.

person Graham Christensen    schedule 06.07.2019