<?xml version="1.0"?>
<?xml-stylesheet href="/pool/xslt_ht.xslt" type="application/xml"?>
<xsl:stylesheet
  xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
  xmlns:d = "http://herbaer.de/xmlns/20051201/doc"
  xmlns:sk = "http://herbaer.de/xmlns/20150106/skeleton"
  xmlns:xl = "http://www.w3.org/1999/xlink"
  exclude-result-prefixes = "d xl"
  version = "1.0"
>
<d:info xmlns="http://herbaer.de/xmlns/20051201/doc">
  <title>skeleton_1.xslt</title>
  <subtitle>1. Schritt zur Erzeugung einer Gerüst-Datei</subtitle>
  <date>2015-02-12</date>
  <author>
    <personname>
      <firstname>Herbert</firstname>
      <surname>Schiemann</surname>
    </personname>
    <email>h.schiemann@herbaer.de</email>
  </author>
</d:info>

<d:section xmlns="http://herbaer.de/xmlns/20051201/doc" role="stylesheet">
<para>
Diese Datei enthält die wesentlichen Vorlagen zur Erzeugung einer "Gerüst"-Datei.
Die Transformation, die die Gerüst-Datei erzeugt,
definiert Vorlagen des Modus
<tag class="attvalue"><link xl:href="#skeleton_1.modus.check">check</link></tag>
zur Klassifizierung von Attributen
und Erstklassifizierung von Elementen
und bindet diese Datei ein.
</para>
</d:section>

<d:para>
Kommentare zur Fehlersuche einfügen? 1 ja, sonst nein
</d:para>
<xsl:param name="p_comments" select="0"/>

<xsl:output method="xml" encoding="utf-8" indent="yes"/>

<d:section xmlns="http://herbaer.de/xmlns/20051201/doc" role="mode.check">
<para>
Klassifizierung eines Attributs:
</para>
<variablelist>
  <varlistentry>
    <term><literal>l</literal></term>
    <listitem>
      <para>
Das Attribut gibt die Sprache an.
      </para>
    </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>t</literal></term>
    <listitem>
      <para>
Der Attributwert ist zu übersetzen.
      </para>
    </listitem>
  </varlistentry>
</variablelist>
<para>
Erstklassifizierung eines Elements
</para>
<variablelist>
  <varlistentry>
    <term><literal>s</literal></term>
    <listitem>
      <para>
Das Element trennt den Inhalt des Elternelements
in Teile, die getrennt übersetzt werden (können).
      </para>
    </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>t</literal></term>
    <listitem>
      <para>
Der Inhalt des Elements einschließlich seiner Kindelemente ist zu übersetzen.
      </para>
    </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>l</literal></term>
    <listitem>
      <para>
Der Inhalt des Elements ist eine unveränderliche Zeichenkette,
(ein Name oder eine URL).
      </para>
    </listitem>
  </varlistentry>
  <varlistentry>
    <term><literal>m</literal></term>
    <listitem>
      <para>
Der Inhalt des Elements kann direkt im Elternelement erscheinen,
und das Element selbst kann (mit leerem Inhalt) verschoben werden.
      </para>
    </listitem>
  </varlistentry>
</variablelist>
</d:section>

<d:para>
Attribute haben für die Übersetzung in der Regel keine Bedeutung.
</d:para>
<xsl:template match="@*" mode="check"/>

<d:para>
Elemente haben für die Übersetzung in der Regel keine Bedeutung.
</d:para>
<xsl:template match="*" mode="check"/>

<d:para>
Das Attribut
<d:tag class="attribute">xml:lang</d:tag>
bezeichnet die Sprache.
</d:para>
<xsl:template match="@xml:lang" mode="check">l</xsl:template>

<d:para>
Besondere Behandlung von Attributen, die übersetzt werden oder die Sprache angeben.
</d:para>
<xsl:template match="@*" mode="special">
  <xsl:variable name="check">
    <xsl:apply-templates select="." mode="check"/>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$check = 'l'">
      <sk:lang name="{name (.)}">
        <xsl:value-of select="."/>
      </sk:lang>
    </xsl:when>
    <xsl:when test="$check = 't'">
      <sk:attribute name="{name (.)}">
        <xsl:value-of select="."/>
      </sk:attribute>
    </xsl:when>
    <xsl:otherwise/>
  </xsl:choose>
</xsl:template>

<d:para>
Attribute, die nicht die Sprache angeben und nicht übersetzt werden, werden kopiert.
</d:para>
<xsl:template match="@*">
  <xsl:variable name="check">
    <xsl:apply-templates select="." mode="check"/>
  </xsl:variable>
  <xsl:if test="string-length ($check) = 0">
    <xsl:copy-of select="."/>
  </xsl:if>
</xsl:template>

<d:para>
Alle Kommmentare und Verarbeitungsanweisungen in der Wurzel werden kopiert.
</d:para>
<xsl:template match="/">
  <xsl:apply-templates select="comment() | processing-instruction() | text() | *"/>
</xsl:template>

<d:section xmlns="http://herbaer.de/xmlns/20051201/doc">
<para>
Elemente.
</para>
<para>
Zu Elementen, die ein trennendes Kindelement enthalten,
werden gruppierende
<tag class="element">sk:part</tag>-Elemente eingefügt.
</para>
<para>
Das Attribut
<tag class="attribute">@sk:chk</tag>
enthält die Erstklassifizierung des Elements
(<literal>s</literal>
<literal>t</literal>
<literal>l</literal> oder
<literal>m</literal>)
</para>
<para>
Falls am Anfang leere Kindelemente vor weiterem Inhalt vorkommen,
werden zwei sk:contents-Elemente angelegt:
das erste Element kapselt die leeren Kindelemente,
das zweite Element den weiteren Inhalt.
So wird die richtige Reihenfolge der Elemente in der Übersetzung sichergestellt.
</para>
</d:section>
<xsl:template match="*">
  <!-- für trennende Elemente: IDs der folgenden Trenner -->
  <xsl:param name="psep" select="''"/>
  <xsl:variable name="check">
    <xsl:apply-templates select="." mode="check"/>
  </xsl:variable>
  <xsl:variable name="wrap">
    <xsl:choose>
      <xsl:when test="not (*)">text</xsl:when>
      <xsl:when test="text() [string-length(normalize-space(.)) &gt; 0]">mixed</xsl:when>
      <xsl:when test="count(*) = 1">wrap</xsl:when>
      <xsl:when test="count(*) &gt; 1">container</xsl:when>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="sep">
    <xsl:for-each select="*">
      <xsl:variable name="c">
        <xsl:apply-templates select="." mode="check"/>
      </xsl:variable>
      <xsl:if test="$c = 's'">
        <xsl:value-of select="concat (generate-id(.), '||')"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>
  <xsl:variable name="sid">
    <xsl:choose>
      <xsl:when test="contains ($psep, '||')">
        <xsl:value-of select="substring-before ($psep, '||')"/>
      </xsl:when>
      <xsl:when test="contains ($sep, '||')">
        <xsl:value-of select="substring-before ($sep, '||')"/>
      </xsl:when>
      <xsl:otherwise/>
    </xsl:choose>
  </xsl:variable>
  <!-- Anzahl der "leeren" Kindknoten am Anfang -->
  <xsl:variable
    name = "ec"
    select = "
      count( (text() | *) [not ( (
      descendant-or-self::text()
      | preceding-sibling::text()
      | preceding-sibling::*/descendant::text()
      )
      [string-length (normalize-space(.)) &gt; 0] )] )
    "
  />
  <!-- Anzahl der leeren Kindelemente am Anfang -->
  <xsl:variable
    name = "ece"
    select = "
      count( * [not ( (
      descendant::text()
      | preceding-sibling::text()
      | preceding-sibling::*/descendant::text()
      )
      [string-length (normalize-space(.)) &gt; 0] )] )
    "
  />
  <!-- Anzahl aller Text-Kinder oder Kindelemente -->
  <xsl:variable name="ect" select="count ( text() | * )"/>
  <xsl:copy>
    <xsl:if test="string-length ($check) &gt; 0">
      <xsl:attribute name="sk:chk">
        <xsl:value-of select="$check"/>
      </xsl:attribute>
    </xsl:if>
    <xsl:if test="string-length ($wrap) &gt; 0">
      <xsl:attribute name="sk:wrap">
        <xsl:value-of select="$wrap"/>
      </xsl:attribute>
    </xsl:if>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select="@*" mode="special"/>
    <xsl:if test="$p_comments">
      <xsl:comment>
        <xsl:value-of select="concat (' ec: ', $ec, ', ece: ', $ece, ', ect: ', $ect, ' ')"
        />
      </xsl:comment>
    </xsl:if>
    <xsl:choose>
      <xsl:when test="contains ($sep, '||')">
        <sk:contents>
          <sk:part>
            <xsl:apply-templates select="(text() | *) [following-sibling::* [generate-id(.) = $sid]]"
            />
          </sk:part>
          <xsl:apply-templates select="* [generate-id(.) = $sid]">
            <xsl:with-param name="psep" select="substring-after ($sep, '||')"/>
          </xsl:apply-templates>
        </sk:contents>
      </xsl:when>
      <xsl:when test="text() [string-length (normalize-space(.)) &gt; 0] | *">
        <sk:contents>
          <xsl:if test="string-length ($wrap) &gt; 0">
            <xsl:attribute name="wrap">
              <xsl:value-of select="$wrap"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:choose>
            <!-- mehrere part-Elemente -->
            <xsl:when test="string-length ($wrap) = 0 and 0 &lt; $ece and $ec &lt; $ect">
              <sk:part>
                <xsl:apply-templates select="(text()|*) [position() &lt;= $ec]"/>
              </sk:part>
              <sk:part>
                <xsl:apply-templates select="(text()|*) [position() &gt; $ec]"/>
              </sk:part>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="text() | *"/>
            </xsl:otherwise>
          </xsl:choose>
        </sk:contents>
      </xsl:when>
    </xsl:choose>
  </xsl:copy>
  <!-- Der folgende Teil nach einem Trenner -->
  <xsl:if test="$check = 's'">
    <sk:part>
      <xsl:choose>
        <xsl:when test="string-length ($sid) &gt; 0">
          <xsl:apply-templates
            select = "
              (following-sibling::text() | following-sibling::*) [following-sibling::* [generate-id(.) = $sid]]
            "
          />
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="following-sibling::text() | following-sibling::*"/>
        </xsl:otherwise>
      </xsl:choose>
    </sk:part>
    <xsl:if test="string-length ($sid) &gt; 0">
      <xsl:apply-templates select="following-sibling::* [generate-id(.) = $sid]">
        <xsl:with-param name="psep" select="substring-after ($psep, '||')"/>
      </xsl:apply-templates>
    </xsl:if>
  </xsl:if>
</xsl:template>

<d:para>
Kommentare und Verarbeitungsanweisungen werden kopiert.
</d:para>
<xsl:template match="comment() | processing-instruction()">
  <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>
