En finir avec le répertoire Word et attaquer la conception

Comme je vous l’avais promis, nous allons maintenant en finir avec le répertoire word/ et attaquer laconception (bon, ok, on va aussi parler des relations, mais pour le coup ça ira très vite). Il nous reste à parler des fichiers suivants : styles.xml, webSettings.xml et theme/theme1.xml, alors allons-y.

styles.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:styles xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:docDefaults>
        <w:rPrDefault>
            <w:rPr>
                <w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/>
                <w:sz w:val="24"/>
                <w:szCs w:val="24"/>
                <w:lang w:val="fr-FR" w:eastAsia="en-US" w:bidi="ar-SA"/>
            </w:rPr>
        </w:rPrDefault>
        <w:pPrDefault/>
    </w:docDefaults>
    <w:latentStyles w:defLockedState="0" w:defUIPriority="99" w:defSemiHidden="1" w:defUnhideWhenUsed="1" w:defQFormat="0" w:count="276">
        <w:lsdException w:name="Normal" w:semiHidden="0" w:uiPriority="0" w:unhideWhenUsed="0" w:qFormat="1"/>
        <w:lsdException w:name="heading 1" w:semiHidden="0" w:uiPriority="9" w:unhideWhenUsed="0" w:qFormat="1"/>
        <w:lsdException w:name="heading 2" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="heading 3" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="heading 4" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="heading 5" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="heading 6" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="heading 7" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="heading 8" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="heading 9" w:uiPriority="9" w:qFormat="1"/>
        <w:lsdException w:name="toc 1" w:uiPriority="39"/>
        <w:lsdException w:name="toc 2" w:uiPriority="39"/>
        <w:lsdException w:name="toc 3" w:uiPriority="39"/>
        <w:lsdException w:name="toc 4" w:uiPriority="39"/>
        <w:lsdException w:name="toc 5" w:uiPriority="39"/>
        <w:lsdException w:name="toc 6" w:uiPriority="39"/>
        <w:lsdException w:name="toc 7" w:uiPriority="39"/>
        <w:lsdException w:name="toc 8" w:uiPriority="39"/>
        <w:lsdException w:name="toc 9" w:uiPriority="39"/>
        <w:lsdException w:name="caption" w:uiPriority="35" w:qFormat="1"/>
        <w:lsdException w:name="Title" w:semiHidden="0" w:uiPriority="10" w:unhideWhenUsed="0" w:qFormat="1"/>
        <w:lsdException w:name="Default Paragraph Font" w:uiPriority="1"/>

        ...
        UN BON PAQUET DE LIGNES QUI SE RESSEMBLENT
        ...

    </w:latentStyles>
    <w:style w:type="paragraph" w:default="1" w:styleId="Normal">
        <w:name w:val="Normal"/>
        <w:qFormat/>
        <w:rsid w:val="00636351"/>
    </w:style>
    <w:style w:type="character" w:default="1" w:styleId="Policepardfaut">
        <w:name w:val="Default Paragraph Font"/>
        <w:semiHidden/>
        <w:unhideWhenUsed/>
    </w:style>
    <w:style w:type="table" w:default="1" w:styleId="TableauNormal">
        <w:name w:val="Normal Table"/>
        <w:semiHidden/>
        <w:unhideWhenUsed/>
        <w:qFormat/>
        <w:tblPr>
            <w:tblInd w:w="0" w:type="dxa"/>
            <w:tblCellMar>
                <w:top w:w="0" w:type="dxa"/>
                <w:left w:w="108" w:type="dxa"/>
                <w:bottom w:w="0" w:type="dxa"/>
                <w:right w:w="108" w:type="dxa"/>
            </w:tblCellMar>
        </w:tblPr>
    </w:style>
    <w:style w:type="numbering" w:default="1" w:styleId="Aucuneliste">
        <w:name w:val="No List"/>
        <w:semiHidden/>
        <w:unhideWhenUsed/>
    </w:style>
</w:styles>

Les plus attentifs parmi vous auront remarqué que je vous ai épargné un paquet de lignes de w:lsdException .

Structure du document

Sous le tag principal w:styles qui contient l’ensemble de ce document, on trouve :

w:docDefaults

C’est le tout premier; comme son nom l’indique, il déclare un certain nombre de propriétés par défaut du document, notamment, dans notre cas :

  • w:rPrDefault : les propriétés par défaut des w:r [ les text runs ]; on y trouve des propriétés classiques de runs, sous :
  • w:rPr : on y trouve des propriétés de police, de taille, de langue, etc. On détaillera tout ça le moment venu.
w:latentStyles
Avant de rentrer dans le détail, il est nécessaire de spécifier un peu les choses (si vous voulez spécifier beaucoup les choses, voyez cette page); un style est défini par deux types d’informations :
  • le comportement du style
  • le formatage du style
Afin d’éviter de déclarer l’ensemble de tous les styles disponibles dans l’application (je rappelle que le format OpenXML étant censé être un standard, on ne sait pas à l’avance de quelle application on parle), on va déclarer des styles « latents » et spécifier un certain nombre d’exceptions; c’est à dire que, faute de spécifications, on utilise les styles par défaut utilisés par l’application (pour faire une analogie, vous pouvez faire une page html et mettre un titre en <h1> sans pour autant avoir spécifié en CSS ce à quoi ressemble l’interprétation du h1; chaque navigateur en a déjà sa version; c’est ainsi qu’on peut faire des fichiers CSS légers — en théorie).
Donc, dans notre styles.xml on a un w:latentStyles avec une série d’attributs qu’on va maintenant lister :
  • w:defLockedState : définit l’état du verrou à appliquer à n’importe quel style disponible dans l’application mais pas explicitement détaillé dans le document lui-même. Ce n’est pas clair, et vous m’en voyez désolé ! Voyez ça différemment : si on ouvre votre document, souhaitez-vous que d’autres styles que ceux déclarés dans ledit document soient accessibles ?
  • w:defUIPriority : définit la priorité d’affichage, par défaut, des styles qui sont disponibles dans l’application mais pas explicitement déclarés dans le document;
  • w:defSemiHidden : de plus en plus obscur…cet attribut détermine si, oui ou non, les styles disponibles dans l’application mais non explicitement déclarés dans le document doivent être rendus à moitié cachés
  • w:defUnhideWhenUsed : de pire en pire…les styles en question doivent-ils être rendus visibles lorsqu’on les utilise ?
  • w:defQFormat : de son petit nom « default primary style setting », cet attribut détermine si les sempiternels styles dont on parle depuis tout à l’heure doivent apparaître comme des styles primaires;
  • w:count : enfin un attribut clair; il désigne le nombre de styles latents à charger lors de l’ouverture du document (par défaut : 20, et vous voyez que notre petit Hello World de rien du tout en charge 276).
Ensuite, à l’intérieur des latentStyles, on va lister les exceptions; ce sont donc les styles qu’on « impose » à l’application; par défaut, sur notre petit fichier Hello world, il y en a tellement que j’en ai viré la majeure partie plus haut; j’ai toutefois laissé les premières pour que vous voyiez qu’il s’agit des styles qu’on connaît bien, par défaut, dans Ms Word : « normal », « Heading 1″, « Heading 2″, etc.
Ils sont décrits, un par exception, via le tag w:lsdException (pour latentStyleDefaultException) et ont les mêmes attributs que latentStyles (sauf pour le count, évidemment).
w:style
Ensuite, le fichier déclare quand même un certain nombre de styles qui ne sont ni latents ni d’exception aux latents; leurs attributs et propriétés sont assez explicites, désormais; ceci étant, nous allons quand même regarder de plus près le style de type « table » et dont le styleId est « TableauNormal »; il ne vous aura pas échappé que ce style décrit le style, par défaut, des tableaux :
    <w:style w:type="table" w:default="1" w:styleId="TableauNormal">
        <w:name w:val="Normal Table"/>
        <w:semiHidden/>
        <w:unhideWhenUsed/>
        <w:qFormat/>
        <w:tblPr>
            <w:tblInd w:w="0" w:type="dxa"/>
            <w:tblCellMar>
                <w:top w:w="0" w:type="dxa"/>
                <w:left w:w="108" w:type="dxa"/>
                <w:bottom w:w="0" w:type="dxa"/>
                <w:right w:w="108" w:type="dxa"/>
            </w:tblCellMar>
        </w:tblPr>
    </w:style>

Ce qui va nous intéresser particulièrement ici, c’est le tag w:tblPr qui décrit les propriétés spécifiques aux tableaux.

On y trouve les tags suivants :

  • w:tblInd : décrit l’indentation d’une table; on y trouve une largeur w:w en twips (vingtièmes de pouce) lorsque le type w:type vaut dxa puisque, et c’est bien naturel, apparemment dxa signifie « vingtièmes de pouce »;
  • w:tblCellMar : définit les marges d’une cellule; on y trouve les quatre côtés (top, left, bottom et right) qui disposent des mêmes attributs w:w et w:type.
Ceci conclut le fichier styles.xml (ouf).

webSettings.xml

Alors là, c’est les vacances :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:webSettings xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
               xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:allowPNG/>
    <w:doNotSaveAsSingleFile/>
</w:webSettings>

On ne va pas s’intéresser à ce fichier (on le fera peut-être en post-dossier); on constate simplement qu’il est là, on conservera ses valeurs en l’état lors de la génération.

theme/theme1.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Thème Office">
        <a:themeElements>
            <a:clrScheme name="Bureau">
                <a:dk1>
                    <a:sysClr val="windowText" lastClr="000000"/>
                </a:dk1>
                <a:lt1>
                    <a:sysClr val="window" lastClr="FFFFFF"/>
                </a:lt1>
                <a:dk2>
                    <a:srgbClr val="1F497D"/>
                </a:dk2>
                <a:lt2>
                    <a:srgbClr val="EEECE1"/>
                </a:lt2>
                <a:accent1>
                    <a:srgbClr val="4F81BD"/>
                </a:accent1>
                <a:accent2>
                    <a:srgbClr val="C0504D"/>
                </a:accent2>
                <a:accent3>
                    <a:srgbClr val="9BBB59"/>
                </a:accent3>
                <a:accent4>
                    <a:srgbClr val="8064A2"/>
                </a:accent4>
                <a:accent5>
                    <a:srgbClr val="4BACC6"/>
                </a:accent5>
                <a:accent6>
                    <a:srgbClr val="F79646"/>
                </a:accent6>
                <a:hlink>
                    <a:srgbClr val="0000FF"/>
                </a:hlink>
                <a:folHlink>
                    <a:srgbClr val="800080"/>
                </a:folHlink>
            </a:clrScheme>
            <a:fontScheme name="Bureau">
                <a:majorFont>
                    <a:latin typeface="Calibri"/>
                    <a:ea typeface=""/>
                    <a:cs typeface=""/>
                    <a:font script="Jpan" typeface="MS ゴシック"/>
                    <a:font script="Hang" typeface="맑은 고딕"/>
                    <a:font script="Hans" typeface="宋体"/>
                    <a:font script="Hant" typeface="新細明體"/>
                    <a:font script="Arab" typeface="Times New Roman"/>
                    <a:font script="Hebr" typeface="Times New Roman"/>
                    <a:font script="Thai" typeface="Angsana New"/>
                    <a:font script="Ethi" typeface="Nyala"/>
                    <a:font script="Beng" typeface="Vrinda"/>
                    <a:font script="Gujr" typeface="Shruti"/>
                    <a:font script="Khmr" typeface="MoolBoran"/>
                    <a:font script="Knda" typeface="Tunga"/>
                    <a:font script="Guru" typeface="Raavi"/>
                    <a:font script="Cans" typeface="Euphemia"/>
                    <a:font script="Cher" typeface="Plantagenet Cherokee"/>
                    <a:font script="Yiii" typeface="Microsoft Yi Baiti"/>
                    <a:font script="Tibt" typeface="Microsoft Himalaya"/>
                    <a:font script="Thaa" typeface="MV Boli"/>
                    <a:font script="Deva" typeface="Mangal"/>
                    <a:font script="Telu" typeface="Gautami"/>
                    <a:font script="Taml" typeface="Latha"/>
                    <a:font script="Syrc" typeface="Estrangelo Edessa"/>
                    <a:font script="Orya" typeface="Kalinga"/>
                    <a:font script="Mlym" typeface="Kartika"/>
                    <a:font script="Laoo" typeface="DokChampa"/>
                    <a:font script="Sinh" typeface="Iskoola Pota"/>
                    <a:font script="Mong" typeface="Mongolian Baiti"/>
                    <a:font script="Viet" typeface="Times New Roman"/>
                    <a:font script="Uigh" typeface="Microsoft Uighur"/>
                </a:majorFont>
                <a:minorFont>
                    <a:latin typeface="Cambria"/>
                    <a:ea typeface=""/>
                    <a:cs typeface=""/>
                    <a:font script="Jpan" typeface="MS 明朝"/>
                    <a:font script="Hang" typeface="맑은 고딕"/>
                    <a:font script="Hans" typeface="宋体"/>
                    <a:font script="Hant" typeface="新細明體"/>
                    <a:font script="Arab" typeface="Arial"/>
                    <a:font script="Hebr" typeface="Arial"/>
                    <a:font script="Thai" typeface="Cordia New"/>
                    <a:font script="Ethi" typeface="Nyala"/>
                    <a:font script="Beng" typeface="Vrinda"/>
                    <a:font script="Gujr" typeface="Shruti"/>
                    <a:font script="Khmr" typeface="DaunPenh"/>
                    <a:font script="Knda" typeface="Tunga"/>
                    <a:font script="Guru" typeface="Raavi"/>
                    <a:font script="Cans" typeface="Euphemia"/>
                    <a:font script="Cher" typeface="Plantagenet Cherokee"/>
                    <a:font script="Yiii" typeface="Microsoft Yi Baiti"/>
                    <a:font script="Tibt" typeface="Microsoft Himalaya"/>
                    <a:font script="Thaa" typeface="MV Boli"/>
                    <a:font script="Deva" typeface="Mangal"/>
                    <a:font script="Telu" typeface="Gautami"/>
                    <a:font script="Taml" typeface="Latha"/>
                    <a:font script="Syrc" typeface="Estrangelo Edessa"/>
                    <a:font script="Orya" typeface="Kalinga"/>
                    <a:font script="Mlym" typeface="Kartika"/>
                    <a:font script="Laoo" typeface="DokChampa"/>
                    <a:font script="Sinh" typeface="Iskoola Pota"/>
                    <a:font script="Mong" typeface="Mongolian Baiti"/>
                    <a:font script="Viet" typeface="Arial"/>
                    <a:font script="Uigh" typeface="Microsoft Uighur"/>
                </a:minorFont>
            </a:fontScheme>
            <a:fmtScheme name="Bureau">
                <a:fillStyleLst>
                    <a:solidFill>
                        <a:schemeClr val="phClr"/>
                    </a:solidFill>
                    <a:gradFill rotWithShape="1">
                        <a:gsLst>
                            <a:gs pos="0">
                                <a:schemeClr val="phClr">
                                    <a:tint val="50000"/>
                                    <a:satMod val="300000"/>
                                </a:schemeClr>
                            </a:gs>
                            <a:gs pos="35000">
                                <a:schemeClr val="phClr">
                                    <a:tint val="37000"/>
                                    <a:satMod val="300000"/>
                                </a:schemeClr>
                            </a:gs>
                            <a:gs pos="100000">
                                <a:schemeClr val="phClr">
                                    <a:tint val="15000"/>
                                    <a:satMod val="350000"/>
                                </a:schemeClr>
                            </a:gs>
                        </a:gsLst>
                        <a:lin ang="16200000" scaled="1"/>
                    </a:gradFill>
                    <a:gradFill rotWithShape="1">
                        <a:gsLst>
                            <a:gs pos="0">
                                <a:schemeClr val="phClr">
                                    <a:tint val="100000"/>
                                    <a:shade val="100000"/>
                                    <a:satMod val="130000"/>
                                </a:schemeClr>
                            </a:gs>
                            <a:gs pos="100000">
                                <a:schemeClr val="phClr">
                                    <a:tint val="50000"/>
                                    <a:shade val="100000"/>
                                    <a:satMod val="350000"/>
                                </a:schemeClr>
                            </a:gs>
                        </a:gsLst>
                        <a:lin ang="16200000" scaled="0"/>
                    </a:gradFill>
                </a:fillStyleLst>
                <a:lnStyleLst>
                    <a:ln w="9525" cap="flat" cmpd="sng" algn="ctr">
                        <a:solidFill>
                            <a:schemeClr val="phClr">
                                <a:shade val="95000"/>
                                <a:satMod val="105000"/>
                            </a:schemeClr>
                        </a:solidFill>
                        <a:prstDash val="solid"/>
                    </a:ln>
                    <a:ln w="25400" cap="flat" cmpd="sng" algn="ctr">
                        <a:solidFill>
                            <a:schemeClr val="phClr"/>
                        </a:solidFill>
                        <a:prstDash val="solid"/>
                    </a:ln>
                    <a:ln w="38100" cap="flat" cmpd="sng" algn="ctr">
                        <a:solidFill>
                            <a:schemeClr val="phClr"/>
                        </a:solidFill>
                        <a:prstDash val="solid"/>
                    </a:ln>
                </a:lnStyleLst>
                <a:effectStyleLst>
                    <a:effectStyle>
                        <a:effectLst>
                            <a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0">
                                <a:srgbClr val="000000">
                                    <a:alpha val="38000"/>
                                </a:srgbClr>
                            </a:outerShdw>
                        </a:effectLst>
                    </a:effectStyle>
                    <a:effectStyle>
                        <a:effectLst>
                            <a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0">
                                <a:srgbClr val="000000">
                                    <a:alpha val="35000"/>
                                </a:srgbClr>
                            </a:outerShdw>
                        </a:effectLst>
                    </a:effectStyle>
                    <a:effectStyle>
                        <a:effectLst>
                            <a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0">
                                <a:srgbClr val="000000">
                                    <a:alpha val="35000"/>
                                </a:srgbClr>
                            </a:outerShdw>
                        </a:effectLst>
                        <a:scene3d>
                            <a:camera prst="orthographicFront">
                                <a:rot lat="0" lon="0" rev="0"/>
                            </a:camera>
                            <a:lightRig rig="threePt" dir="t">
                                <a:rot lat="0" lon="0" rev="1200000"/>
                            </a:lightRig>
                        </a:scene3d>
                        <a:sp3d>
                            <a:bevelT w="63500" h="25400"/>
                        </a:sp3d>
                    </a:effectStyle>
                </a:effectStyleLst>
                <a:bgFillStyleLst>
                    <a:solidFill>
                        <a:schemeClr val="phClr"/>
                    </a:solidFill>
                    <a:gradFill rotWithShape="1">
                        <a:gsLst>
                            <a:gs pos="0">
                                <a:schemeClr val="phClr">
                                    <a:tint val="40000"/>
                                    <a:satMod val="350000"/>
                                </a:schemeClr>
                            </a:gs>
                            <a:gs pos="40000">
                                <a:schemeClr val="phClr">
                                    <a:tint val="45000"/>
                                    <a:shade val="99000"/>
                                    <a:satMod val="350000"/>
                                </a:schemeClr>
                            </a:gs>
                            <a:gs pos="100000">
                                <a:schemeClr val="phClr">
                                    <a:shade val="20000"/>
                                    <a:satMod val="255000"/>
                                </a:schemeClr>
                            </a:gs>
                        </a:gsLst>
                        <a:path path="circle">
                            <a:fillToRect l="50000" t="-80000" r="50000" b="180000"/>
                        </a:path>
                    </a:gradFill>
                    <a:gradFill rotWithShape="1">
                        <a:gsLst>
                            <a:gs pos="0">
                                <a:schemeClr val="phClr">
                                    <a:tint val="80000"/>
                                    <a:satMod val="300000"/>
                                </a:schemeClr>
                            </a:gs>
                            <a:gs pos="100000">
                                <a:schemeClr val="phClr">
                                    <a:shade val="30000"/>
                                    <a:satMod val="200000"/>
                                </a:schemeClr>
                            </a:gs>
                        </a:gsLst>
                        <a:path path="circle">
                            <a:fillToRect l="50000" t="50000" r="50000" b="50000"/>
                        </a:path>
                    </a:gradFill>
                </a:bgFillStyleLst>
            </a:fmtScheme>
        </a:themeElements>
        <a:objectDefaults>
            <a:spDef>
                <a:spPr/>
                <a:bodyPr/>
                <a:lstStyle/>
                <a:style>
                    <a:lnRef idx="1">
                        <a:schemeClr val="accent1"/>
                    </a:lnRef>
                    <a:fillRef idx="3">
                        <a:schemeClr val="accent1"/>
                    </a:fillRef>
                    <a:effectRef idx="2">
                        <a:schemeClr val="accent1"/>
                    </a:effectRef>
                    <a:fontRef idx="minor">
                        <a:schemeClr val="lt1"/>
                    </a:fontRef>
                </a:style>
            </a:spDef>
            <a:lnDef>
                <a:spPr/>
                <a:bodyPr/>
                <a:lstStyle/>
                <a:style>
                    <a:lnRef idx="2">
                        <a:schemeClr val="accent1"/>
                    </a:lnRef>
                    <a:fillRef idx="0">
                        <a:schemeClr val="accent1"/>
                    </a:fillRef>
                    <a:effectRef idx="1">
                        <a:schemeClr val="accent1"/>
                    </a:effectRef>
                    <a:fontRef idx="minor">
                        <a:schemeClr val="tx1"/>
                    </a:fontRef>
                </a:style>
            </a:lnDef>
        </a:objectDefaults>
        <a:extraClrSchemeLst/>
    </a:theme>

Comme l’aurait dit Billy Shakespeare, beaucoup de bruit pour rien. Ou alors, pour pas grand chose. Lorsqu’on s’attaquera à ce fichier, ça va être une boucherie; il est clair qu’un paquet de propriétés vont voler; ce fichier permet de mettre toutes les propriétés de style de tous les types possibles d’affichage par défaut, afin de garantir à l’ouverture du document que tous les paramètres sont identiques à la précédente ouverture (le style de trait lorsqu’on dessine un cercle, par exemple, ou la position de la caméra dans un rendu 3d).

On va simplement se concentrer sur les points qui, clairement, vont nous intéresser à un moment où à un autre, quelle que soit la nature de notre document Word (donc pour un usage classique de traitement de texte).

À noter que le namespace a correspond à l’espace principal (main) des déclarations concernant le dessin (drawingml).

a:themeElements

Les éléments du thème; on va retrouver un certain nombre d’éléments qu’on a déjà croisés, et ce qu’on va faire avec va furieusement ressembler à du CSS; tout d’abord le schéma des couleurs

a:clrScheme

On y définit, pour les éléments qu’on avait — rappelez-vous — déclarés dans settings.xml > w:clrSchemeMapping, les couleurs sRGB au format bien connu hexadécimal, par exemple :

                <a:accent1>
                    <a:srgbClr val="4F81BD"/>
                </a:accent1>

ensuite, le schéma des polices utilisées

a:fontScheme

On y trouve les polices dites majeures, et les polices dites mineures. Leur déclaration est pour ainsi dire explicite.

Ensuite le schéma de formatage

a:fmtScheme

On a y trouver plusieurs déclarations de styles, les styles de trait a:lnStyleLst, les styles de remplissage (par couleur, gradient, etc.) a:fillStyleLst, les styles d’effets (ombrage, lueurs, etc.) a:effectStyleLst, etc.

a:objectDefault

On trouve ensuite quelques déclarations sur des styles par défaut pour des « objets » donnés, tels qu’une ligne a:lnDef (line default)ou qu’une forme a:spDef (shape default).

Et les relations ?

les fichiers de relations, situés dans :

  • _rels/.rels
  • word/_rels/document.xml.rels
décrivent les relations existant entre les différents éléments techniques déclarés au sein du package docx.
Ainsi, pour le fichier .rels :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
    <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
    <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
    <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
    <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail" Target="docProps/thumbnail.jpeg"/>
</Relationships>

Rien de bien passionnant ici; il faut juste bien connaître les types de chaque relation, par exemple pour pouvoir dire que le fichier docProps/core.xml est lié par le type relationships/metadata/core-properties.

Petit bilan

Bon, c’est vrai, il semble que j’ai pas mal bâclé les derniers fichiers, mais en fait vous verrez rapidement que ceux-ci contiennent un nombre invraisemblable d’informations qui ne nous intéresseront pour ainsi dire jamais (on ne les vois déjà faire leur apparition dans notre package qu’en v2). Ceci étant, on a couvert beaucoup de choses, mine de rien, et il serait bon de tout mettre à plat pour commencer proprement notre réflexion sur l’architecture du package qu’on va monter.

Architecture du package

Résumé des épisodes précédents

Pour faire simple, notre package va générer les éléments suivants :

  • un fichier [Content_Types].xml qui décrit ce que contient notre document en terme de « langages »;
  • un répertoire docProps, qui contient des fichiers de propriétés parmi lesquelles certaines sont directement liées au document, et d’autres pas du tout (liées uniquement à l’application);
  • un répertoire word qui contient tous les fichiers permettant de décrire le contenu, la forme et les styles, utilisés ou non, de notre document;
  • à la racine et dans le répertoire word un répertoire _rels contenant des fichiers décrivant les relations existant entre les éléments de notre docx.
Par ailleurs, les informations que nous allons devoir générer sont de types différents :
  • descriptions liées à l’application;
  • descriptions liées au document;
  • contenu du document;
  • descriptions techniques (permettant de lier les éléments entre eux);
  • le tout dans une arborescence parfaitement établie et des fichiers parfaitement idenfitiés.
Enfin, la cerise, c’est que, parmi tous les éléments évoqués, certains sont spécifiques aux applications de traitement de texte, tandis que d’autres sont communs aux suites bureautiques en général et à la suite Office en particulier.

 

De là à commencer à construire une architecture, il n’y a qu’un pas…

 

Étape précédente : Comprendre le répertoire word/

4 réponses à to “En finir avec le répertoire Word et attaquer la conception”

  • Manu112358:

    Bonjour, comme tu le disais dans l’article « ne pas réinventer la roue », pourquoi refaire complètement un générateur de fichiers word, alors qu’il en existe certainement des très bons disponibles sur le web ?

  • Bonjour, et avant toute chose félicitations pour le fibonacci dans ton pseudo (fait exprès ?).

    En effet, il existe des packages complets disponibles en freeware ou à la vente permettant de générer du Word docx en PHP; par exemple, j’en ai vu un que je n’ai pas franchement testé mais qui semble assez remarquable, PHPDocX (disponible sur http://www.phpdocx.com/ ), qui permet entre autres choses :

    - de générer du Word (docx);
    - de générer de l’Excel (xlsx);
    - de transformer en PDF.

    Il en existe une version gratuite (licence LGPL) et une version plus complète et payante (90 $).

    Je précise évidemment que je n’ai strictement rien à voir avec eux, et que je ne fais en aucune manière de publicité pour eux autre qu’à titre informatif.

    Ceci étant, les raison pour lesquelles on se repaluche l’ensemble des développements nécessaires à cette génération sont multiples :

    - d’abord, c’est un exercice très intéressant en terme de conception;
    - ensuite, cela permet de comprendre comment décortiquer des fichiers désormais aussi communs que les docx;
    - enfin, et ce sera probablement intéressant de comparer, on se rendra vite compte qu’à un problème donné il peut exister plusieurs solutions, et peut-être allons-nous faire des choix très différents de ceux opérés par phpdocx.

    Si quelqu’un a essayé phpdocx, un feedback sur les qualités de ce logiciel sera très apprécié.

  • Futaba:

    Hello,

    Super article complet et qui m’a permis de faire mes premiers pas avec des fichiers Word.. :)

    Pour info y’a ça aussi, pas encore essayé je m’y atèle maintenant.. :)

    http://phpword.codeplex.com/

  • Sylvain:

    Bon travail, intéressant, utile.

    Pour ma part je suis en train de générer du xlsx. Pour que ça marche quelque soit la config du serveur, j’utilise pclzip.lib.php.

    Par contre, j’aimerai bien trouver une solution pour avoir + de détails sur les messages d’erreur lors de l’ouverture avec Excel.
    Il me dit « certaines partie peuvent avoir été réparées ou supprimées », mais sans préciser laquelle, et je ne trouve rien qui manque.

    J’ai essayer de l’ouvrir avec autre chose (libreoffice, googledocuments), pas d’erreur, pas de message.

    Dans l’observateur d’évènements, il y a un historique des messages, mais il ne donne rien de plus que la boite de dialogue.