TEI » document (diple_split.xsl, Diple)

© 2010, École nationale des chartes, licence CeCILL-C (LGPL compatible droit français) Diple, factorisation d'outils utiles pour la division d'un fichier XML en plusieurs fichiers HTML Attention, cette transformation n'a d'intérêt qu'importée par un pilote qui importera aussi une transformation vers HTML
<xsl:param…
extension des fichiers générés, paramétrable de l'extérieurcf. [t1], [thref], [tdocument]
$_html=".html"
dossier de projection des fichiers générés, paramétrable de l'extérieurcf. [t1], [tdocument]
$dir="html/"
Dossier où retrouver des ressources de thèmecf. [t1], [tdocument]
$theme="theme/"
paramètre permettant de tester d'où fonctionne un template
$this="tei_split"
source
<xsl:template match="/">
<!-- Générer la navigation -->
<xsl:variable name="href">
<xsl:value-of select="$dir"/>
<xsl:if test="$bookId != ''">
<xsl:value-of select="$bookId"/>
</xsl:if>
<xsl:value-of select="$_html"/>
</xsl:variable>
<xsl:message>
<xsl:value-of select="$href"/>
</xsl:message>
<xsl:document href="{$href}" omit-xml-declaration="no" encoding="UTF-8" indent="yes" doctype-public="html">
<html lang="fr" xml:lang="fr">
<head>
<title>
<xsl:call-template name="title"/>
<xsl:text>, navigation</xsl:text>
</title>
<!-- lien à une CSS pour les fichiers statiques -->
<link rel="stylesheet" type="text/css" href="{$theme}html.css"/>
<link rel="stylesheet" type="text/css" href="{$theme}diple_html.css"/>
<link rel="stylesheet" type="text/css" href="{$theme}{$corpusId}.css"/>
<script type="text/javascript" src="{$theme}Tree.js">//</script>
</head>
<body class="nav {$corpusId}">
<xsl:call-template name="nav"/>
</body>
</html>
</xsl:document>
<!-- Traverser le document pour voir les documents à créer -->
<xsl:apply-templates mode="split"/>
<date>
<xsl:value-of select="$date"/>
</date>
<!-- le corpus en une seule page ne peut pas être généré ici car le contexte de résolution des liens est différent -->
</xsl:template>
(l. 42) /
<body>, <date>, <head>, <html>, <link>, <script>, <title>, "_", "nav", ", navigation", "//", $dir, $bookId, $_html, $href, $date
Racine
source
<xsl:template match="*" mode="href" name="href">
<xsl:choose>
<!-- Racine -->
<xsl:when test="(count(/|.) = 1) or (count(/*|.) = 1)">.</xsl:when>
<!-- Structure TEI, renommés par le template "id" -->
<xsl:when test="local-name(../..)='TEI'">
<xsl:call-template name="id"/>
<xsl:value-of select="$_html"/>
</xsl:when>
<!-- Contient ou est un élément à spliter, spliter -->
<xsl:when test="descendant-or-self::*[key('split', generate-id())]">
<xsl:call-template name="id"/>
<xsl:value-of select="$_html"/>
</xsl:when>
<!-- Enfant d'une page, id du parent splité + ancre -->
<xsl:when test="ancestor::*[key('split', generate-id())]">
<xsl:for-each select="ancestor::*[key('split', generate-id())][1]">
<xsl:call-template name="id"/>
<xsl:value-of select="$_html"/>
</xsl:for-each>
<xsl:call-template name="id"/>
</xsl:when>
<!-- A été rencontré, laissé pour mémoire -->
<xsl:when test="ancestor::tei:*[local-name(../..)='TEI']">
<xsl:for-each select="ancestor::tei:*[local-name(../..)='TEI'][1]">
<xsl:call-template name="id"/>
<xsl:value-of select="$_html"/>
</xsl:for-each>
<xsl:call-template name="id"/>
</xsl:when>
<!-- Pas de split, juste des ancres -->
<xsl:otherwise>
<xsl:call-template name="id"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
(l. 88) [href] * (href)
".", "#", "#", "#", $_html, $_html, $_html, $_html
Réécriture des liens
source
<xsl:template match="*" mode="split">
<xsl:apply-templates mode="split"/>
</xsl:template>
(l. 128) * (split)
Par défaut, traverser
source
<xsl:template match="text()" mode="split"/>
(l. 132) text() (split)
Arrêter le texte
source
<xsl:template match="tei:publicationStmt" mode="split">
<xsl:call-template name="document">
<xsl:with-param name="id">
<xsl:if test="$bookId != ''">
<xsl:value-of select="$bookId"/>
</xsl:if>
<xsl:text>licence</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
(l. 134) tei:publicationStmt (split)
"_", "licence", $bookId
Licence
source
<xsl:template match="/*/tei:text/*" mode="split">
<xsl:call-template name="document"/>
</xsl:template>
(l. 146) /*/tei:text/* (split)
Intro, corps, conclu : split
source
<xsl:template match="/* | /*/tei:text | tei:group/tei:text/tei:body " mode="split" priority="5">
<xsl:apply-templates mode="split"/>
</xsl:template>
(l. 150) /* | /*/tei:text | tei:group/tei:text/tei:body (split)
Prendre la main sur ci dessous pour bien passer à travers
source
<xsl:template match="tei:titleStmt" mode="split">
<xsl:call-template name="document">
<xsl:with-param name="id">
<xsl:if test="$bookId != ''">
<xsl:value-of select="$bookId"/>
</xsl:if>
<xsl:text>credits</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
(l. 154) tei:titleStmt (split)
"_", "credits", $bookId
Crédits
source
<xsl:template name="head"/>
(l. 166) [head]
head html
source
<xsl:template match="
tei:text | tei:body | tei:front | tei:back | tei:group | tei:div | tei:div0 | tei:div1 | tei:div2 | tei:div3 | tei:div4 | tei:div5 | tei:div6 | tei:div7
" mode="split">
<xsl:choose>
<!-- article, créer un document -->
<xsl:when test="
key('split', generate-id()) or descendant::*[key('split', generate-id())]
">
<xsl:call-template name="document"/>
</xsl:when>
<!-- sortir le html -->
<xsl:otherwise>
<xsl:apply-templates select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
(l. 173) tei:text | tei:body | tei:front | tei:back | tei:group | tei:div | tei:div0 | tei:div1 | tei:div2 | tei:div3 | tei:div4 | tei:div5 | tei:div6 | tei:div7 (split)
source
<xsl:template name="document">
<xsl:param name="id">
<xsl:call-template name="id"/>
</xsl:param>
<xsl:param name="href">
<xsl:value-of select="$dir"/>
<xsl:value-of select="$id"/>
<xsl:value-of select="$_html"/>
</xsl:param>
<xsl:param name="title">
<xsl:call-template name="titleBranch"/>
</xsl:param>
<!-- Un contenu généré par ailleurs -->
<xsl:param name="article"/>
<xsl:message>
<xsl:value-of select="$href"/>
<xsl:call-template name="idpath"/>
</xsl:message>
<xsl:document href="{$href}" omit-xml-declaration="no" encoding="UTF-8" indent="yes" doctype-public="html">
<html
xmlns:dbo="http://dbpedia.org/ontology/"
xmlns:dc="http://purl.org/dc/terms/"
xml:lang="fr">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>
<title>
<xsl:value-of select="normalize-space($title)"/>
</title>
<xsl:variable name="label">
<xsl:if test="ancestor::tei:text[@n]">
<xsl:value-of select="ancestor::tei:text/@n"/>
</xsl:if>
<xsl:apply-templates select="." mode="label"/>
</xsl:variable>
<meta name="label" content="{normalize-space($label)}"/>
<!-- lien à une CSS pour les fichiers statiques -->
<link rel="stylesheet" type="text/css" href="{$theme}html.css"/>
<link rel="stylesheet" type="text/css" href="{$theme}diple_html.css"/>
<link rel="stylesheet" type="text/css" href="{$theme}{$corpusId}.css"/>
<!-- Permet ici d'ajouter des metas -->
<xsl:apply-templates select="." mode="meta"/>
<!-- Nécessaire pour tous les items, notamment crédits ou licence, qui n'ont pas le titre de corpus dans leur héritage -->
<link rel="dc:isPartOf" href="." title="{normalize-space($corpusTitle)}"/>
<!-- utile au fil d'ariane, ne pas sortir le body, serait égal à ci-dessus -->
<xsl:for-each select="
ancestor::*[ancestor::tei:body or ancestor::tei:group][not(self::tei:body)]
">
<!-- URI (identifier) suppose flat file -->
<xsl:variable name="ancestorId">
<xsl:call-template name="id"/>
</xsl:variable>
<xsl:variable name="ancestorHref">
<xsl:choose>
<!-- @id="bookId_articleId" translate to @href="articleId" -->
<xsl:when test="contains($ancestorId, concat($bookId, '_'))">
<xsl:value-of select="substring-after($ancestorId, concat($bookId, '_'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ancestorId"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="ancestorLabel">
<xsl:apply-templates select="." mode="label"/>
</xsl:variable>
<link rel="dc:isPartOf" href="{$ancestorHref}" title="{normalize-space($ancestorLabel)}"/>
</xsl:for-each>
</head>
<body class="article {$corpusId}">
<xsl:choose>
<!-- Contenu passé en paramètre -->
<xsl:when test="$article">
<xsl:copy-of select="$article"/>
</xsl:when>
<!-- Page d'accueil, ajouter un peu de navigation -->
<xsl:when test="$id = 'index'">
<!-- Procéder les éléments qui ne splitent pas -->
<article>
<xsl:call-template name="atts"/>
<xsl:apply-templates select="
*[not(key('split', generate-id())) and not(descendant::*[key('split', generate-id())])]
"/>
</article>
<!-- table des matières complète -->
<xsl:if test="self::tei:front and tei:div">
<--
                <strong>
                  <xsl:call-template name="label">
                    <xsl:with-param name="id">front</xsl:with-param>
                  </xsl:call-template>
                </strong>
                -->
<xsl:apply-templates select="." mode="ul"/>
<hr/>
</xsl:if>
<xsl:apply-templates select="../tei:body | ../tei:group " mode="ul"/>
<xsl:if test="../tei:back/tei:div">
<hr/>
<xsl:apply-templates select="../tei:back " mode="ul"/>
</xsl:if>
</xsl:when>
<!-- avec des enfants à spliter -->
<xsl:when test="descendant::*[key('split', generate-id())]">
<xsl:call-template name="prevnext"/>
<article>
<xsl:call-template name="atts"/>
<!-- sortir les enfants qui ne sont pas des feuilles de split -->
<xsl:apply-templates select="*[not(key('split', generate-id()))]"/>
<!-- les notes, passer les noeud sur lesquels générer -->
<xsl:variable name="notes">
<xsl:call-template name="notes">
<xsl:with-param name="text" select="*[not(key('split', generate-id()))]"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$notes != ''">
<footer>
<xsl:copy-of select="$notes"/>
</footer>
</xsl:if>
<!-- Sert aussi en cas de section vide -->
</article>
<ul>
<xsl:choose>
<xsl:when test="tei:body">
<xsl:for-each select="tei:body/*[key('split', generate-id())]">
<li>
<xsl:apply-templates select="." mode="a"/>
</li>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="
*[ descendant-or-self::*[key('split', generate-id())]]
">
<li>
<xsl:apply-templates select="." mode="a"/>
</li>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</ul>
</xsl:when>
<!-- Feuille de l'arbre à split -->
<xsl:otherwise>
<xsl:variable name="prevnext">
<xsl:call-template name="prevnext"/>
</xsl:variable>
<xsl:copy-of select="$prevnext"/>
<article>
<xsl:call-template name="atts"/>
<-- 
Tester si saut de page en milieu de texte pour récupérer le précédent.
Attention, pas .//tei:pb[1] (= tous les pb ainés) ni ./following:: (= saut de page après la section)
si du texte avant le premier saut de page, prendre le précédent
                -->
<xsl:if test=".//tei:pb and local-name(*[1])!='pb'">
<xsl:variable name="pb" select="node()[1]/following::tei:pb[1]"/>
<xsl:if test="
.//text()[count($pb|following::tei:pb[1])=1][normalize-space(.) != '']
">
<xsl:apply-templates select="preceding::tei:pb[1]"/>
</xsl:if>
</xsl:if>
<xsl:if test="$id = 'credits'">
<!-- Histoire des modifications (si pas public, mettre display none en CSS) -->
<xsl:apply-templates select="/*/tei:teiHeader/tei:revisionDesc"/>
</xsl:if>
<xsl:variable name="notes">
<xsl:call-template name="notes"/>
</xsl:variable>
<xsl:if test="$notes != ''">
<footer>
<xsl:copy-of select="$notes"/>
</footer>
</xsl:if>
</article>
<xsl:copy-of select="$prevnext"/>
</xsl:otherwise>
</xsl:choose>
</body>
</html>
</xsl:document>
<!-- Autres sections susceptibles de produire des pages -->
<xsl:apply-templates select="
*[ descendant-or-self::*[key('split', generate-id())] ]
" mode="split"/>
</xsl:template>
(l. 186) [document]
<article>, <body>, <footer>, <head>, <hr>, <html>, <li>, <link>, <meta>, <title>, <ul>, " : ", ", ", $article, $notes, $prevnext, $notes, $prevnext, $dir, $id, $_html, $href, normalize-space($title), ancestor::tei:text/@n, substring-after($ancestorId, concat($bookId, '_')), $ancestorId
  • $id :
  • $href :
  • $title :
  • $article : Un contenu généré par ailleurs
Pour section à spliter
source
<xsl:template match="node()" mode="meta"/>
(l. 377) node() (meta)
Mode meta pour item, par défaut RIEN
source
<xsl:template match="*[tei:num or tei:head/tei:num]" mode="meta">
<meta name="num" content="{normalize-space(tei:num|tei:head/tei:num)}"/>
</xsl:template>
(l. 379) *[tei:num or tei:head/tei:num] (meta)
<meta>
Un exemple de surcharge de ce mode pour ajouter des métas spécifiques à un corpus
source
<xsl:template match="
tei:div/tei:head | tei:div0/tei:head | tei:div1/tei:head | tei:div2/tei:head | tei:div3/tei:head | tei:div4/tei:head | tei:div5/tei:head | tei:div6/tei:head | tei:div7/tei:head | tei:front/tei:head | tei:back/tei:head | tei:body/tei:head | tei:text/tei:head
">
<!-- Nombre d'ascendants, s'arrêter à la première page splitée -->
<xsl:variable name="niv" select="
count( ancestor::tei:*[not(descendant::*[key('split', generate-id())]) and local-name()!='front'] )
"/>
<xsl:choose>
<xsl:when test="number($niv) &lt;":&quot 2">
<h1>
<xsl:call-template name="atts"/>
</h1>
</xsl:when>
<xsl:when test="$niv &gt; 7">
<h6>
<xsl:call-template name="atts"/>
</h6>
</xsl:when>
<xsl:otherwise>
<xsl:element name="h{$niv}">
<xsl:call-template name="atts"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
(l. 397) tei:div/tei:head | tei:div0/tei:head | tei:div1/tei:head | tei:div2/tei:head | tei:div3/tei:head | tei:div4/tei:head | tei:div5/tei:head | tei:div6/tei:head | tei:div7/tei:head | tei:front/tei:head | tei:back/tei:head | tei:body/tei:head | tei:text/tei:head
<h1>, <h6>, <h{$niv}>
h1 en sommet d'item, et calcul relatif de hiérarchie
source
<xsl:template name="prevnext">
<nav class="prevnext" style="text-align:center;">
<span class="prev" style="float:left">
<-- lien vers l'élément juste avant, même si c'est un petit cousin
        laisser le test @xml:id, sinon risque d'aller dans des pages qui n'ont pas été générées 
        for-each a l'air moins gourmand qu'un apply-templates
        PERF : preceding::*[ descendant-or-self::*[key('split', generate-id())]][1]
        -->
<xsl:for-each select="preceding::*[key('split', generate-id())][1]">
<xsl:call-template name="a-label"/>
</xsl:for-each>
<!-- Laisser l'espace insécable, si case vide -->
</span>
<span class="next" style="float:right">
<xsl:variable name="enfant">
<xsl:for-each select="
*[key('split', generate-id()) and local-name()!='body'][1]
">
<xsl:call-template name="a-label">
<xsl:with-param name="rel">next</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$enfant != ''">
<xsl:copy-of select="$enfant"/>
</xsl:when>
<xsl:otherwise>
<!-- premier descendant splité (attention à text/body/div[@split]) -->
<xsl:variable name="descendant">
<xsl:for-each select="
descendant::*[key('split', generate-id()) and local-name()!='body'][1]
">
<xsl:call-template name="a-label">
<xsl:with-param name="rel">next</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$descendant != ''">
<xsl:copy-of select="$descendant"/>
</xsl:when>
<!-- suivant -->
<xsl:otherwise>
<xsl:for-each select="following::*[key('split', generate-id())][1]">
<xsl:call-template name="a-label">
<xsl:with-param name="rel">next</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</span>
<!-- afficher les chapitres parents -->
<xsl:if test="
ancestor-or-self::tei:*[@xml:id|tei:head|@id][local-name()!='TEI']
">
<div class="up">
<xsl:for-each select="
ancestor-or-self::tei:*[@xml:id|tei:head|@id][local-name()!='TEI']
">
<div>
<xsl:call-template name="a-label">
</xsl:call-template>
</div>
</xsl:for-each>
</div>
</xsl:if>
</nav>
</xsl:template>
(l. 426) [prevnext]
<div>, <nav>, <span>, " ", " ", $enfant, $descendant
génération d'une navigation précédent/suivant
source
<xsl:template match="*" mode="prev" name="prev-a">
<xsl:param name="secure"/>
<xsl:choose>
<xsl:when test="not($secure)">
<xsl:apply-templates select="preceding::*[1]" mode="prev">
<xsl:with-param name="secure" select="true()"/>
</xsl:apply-templates>
</xsl:when>
<xsl:when test="descendant-or-self::*[key('split', generate-id())]">
<xsl:call-template name="a-label"/>
</xsl:when>
<xsl:when test="not(preceding::*[1])"/>
<xsl:otherwise>
<xsl:apply-templates select="preceding::*[1]" mode="prev">
<xsl:with-param name="secure" select="true()"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
(l. 509) [prev-a] * (prev)
  • $secure :
preceding:*[ descendant-or-self::*[key('split', generate-id())] ][1]
source
<xsl:template name="a-label">
<xsl:param name="rel"/>
<a>
<xsl:attribute name="href">
<xsl:call-template name="href"/>
</xsl:attribute>
<xsl:if test="$rel">
<xsl:attribute name="rel">
<xsl:value-of select="$rel"/>
</xsl:attribute>
</xsl:if>
<xsl:variable name="t">
<xsl:apply-templates select="." mode="title"/>
</xsl:variable>
<xsl:variable name="title" select="normalize-space($t)"/>
<xsl:choose>
<xsl:when test="$title &lt;":&quot 50">
<xsl:value-of select="$title"/>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="title">
<xsl:value-of select="$title"/>
</xsl:attribute>
<xsl:value-of select="substring($title, 1, 30)"/>
<xsl:value-of select="
substring-before(concat(substring($title, 31), ' '), ' ')
"/>
<!-- Quelque chose a été coupé -->
<xsl:if test="substring-after(substring($title, 30), ' ') != ''"></xsl:if>
</xsl:otherwise>
</xsl:choose>
</a>
</xsl:template>
(l. 529) [a-label]
<a>, @href, "…", $rel, $title, $title, substring($title, 1, 30), substring-before(concat(substring($title, 31), ' '), ' ')
  • $rel :
lien de section prevnext