1
<?xml version="1.0" encoding="UTF-8"?>
2
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3
  version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink"
4
  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
5
  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
6
  xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"
7
  xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:h="http://www.w3.org/1999/xhtml">
8
9
  <xsl:strip-space elements="*" />
10
  <xsl:output method="xml" indent="yes" />
11
12
  <xsl:template name="getPersistOffset">
13
    <xsl:param name="persistId" />
14
    <xsl:param name="userEditAtom" />
15
    <xsl:variable name="persistDirectoryAtom"
16
      select="/ppt/PowerPointStructs/anon[@type='PowerPointStruct']/anon[@offset=$userEditAtom/offsetPersistDirectory][@type='PersistDirectoryAtom']" />
17
    <xsl:variable name="entry"
18
      select="$persistDirectoryAtom/rgPersistDirEntry[persistId&lt;=$persistId][persistId+cPersist&gt;$persistId]" />
19
    <xsl:variable name="offset"
20
      select="$entry/rgPersistOffset[position()=$persistId - ../persistId + 1]/anon" />
21
    <xsl:choose>
22
      <!-- the right entry was found -->
23
      <xsl:when test="$offset">
24
        <xsl:value-of select="$offset" />
25
      </xsl:when>
26
      <!--
27
        if it was not found there should be and another persistDirectoryAtom
28
      -->
29
      <xsl:when test="number($userEditAtom)&gt;0">
30
        <xsl:call-template name="getPersistOffset">
31
          <xsl:with-param name="persistId" select="$persistId" />
32
          <xsl:with-param name="userEditAtom"
33
            select="PowerPointStructs/anon[@type='PowerPointStruct']/anon[@offset=$userEditAtom/offsetLastEdit][@type='UserEditAtom']" />
34
        </xsl:call-template>
35
      </xsl:when>
36
      <xsl:otherwise>
37
        <!-- error -->
38
        <xsl:message terminate="yes">
39
          No offset was found for persistId
40
          <xsl:value-of select="$persistId" />
41
        </xsl:message>
42
      </xsl:otherwise>
43
    </xsl:choose>
44
  </xsl:template>
45
46
  <xsl:template match="/ppt">
47
    <!-- parsing according to page 26 of [MS-PPT].pdf -->
48
    <xsl:variable name="currentUserAtom" select="CurrentUserStream/anon1" />
49
    <!-- get the 'live' (last versions of) the important structures -->
50
    <xsl:variable name="userEditAtom"
51
      select="PowerPointStructs/anon[@type='PowerPointStruct']/anon[@offset=$currentUserAtom/offsetToCurrentEdit][@type='UserEditAtom']" />
52
    <xsl:variable name="documentContainerOffset">
53
      <xsl:call-template name="getPersistOffset">
54
        <xsl:with-param name="persistId" select="$userEditAtom/docPersistIdRef" />
55
        <xsl:with-param name="userEditAtom" select="$userEditAtom" />
56
      </xsl:call-template>
57
    </xsl:variable>
58
    <xsl:variable name="documentContainer"
59
      select="PowerPointStructs/anon[@type='PowerPointStruct']/anon[@offset=$documentContainerOffset][@type='DocumentContainer']" />
60
    <!--
61
      <xsl:message terminate="yes"> hello <xsl:value-of
62
      select="$documentContainer/slideList/rgChildRec/slidePersistAtom/persistIdRef/anon"/>
63
      world </xsl:message>
64
    -->
65
    <office:document-content>
66
      <office:body>
67
        <office:presentation>
68
          <xsl:for-each
69
            select="$documentContainer/slideList/rgChildRec/slidePersistAtom">
70
            <xsl:call-template name="processSlidePersistAtom">
71
              <xsl:with-param name="documentContainer" select="$documentContainer" />
72
              <xsl:with-param name="userEditAtom" select="$userEditAtom" />
73
            </xsl:call-template>
74
          </xsl:for-each>
75
        </office:presentation>
76
      </office:body>
77
    </office:document-content>
78
  </xsl:template>
79
80
  <xsl:template name="processSlidePersistAtom">
81
    <xsl:param name="userEditAtom" />
82
    <xsl:param name="documentContainer" />
83
    <xsl:variable name="slideContainerOffset">
84
      <xsl:call-template name="getPersistOffset">
85
        <xsl:with-param name="persistId" select="persistIdRef/anon" />
86
        <xsl:with-param name="userEditAtom" select="$userEditAtom" />
87
      </xsl:call-template>
88
    </xsl:variable>
89
    <xsl:variable name="slideContainer"
90
      select="/ppt/PowerPointStructs/anon[@type='PowerPointStruct']/anon[@type='MasterOrSlideContainer']/anon[@offset=$slideContainerOffset][@type='SlideContainer']" />
91
    <xsl:variable name="masterName" select="concat('master',$slideContainer/slideAtom/masterIdRef)" />
92
    <draw:page>
93
      <xsl:attribute name="draw:master-page-name">
94
        <xsl:value-of select="$masterName" />
95
      </xsl:attribute>
96
      <xsl:apply-templates select="$slideContainer/drawing/OfficeArtDg/groupShape" />
97
    </draw:page>
98
  </xsl:template>
99
100
  <xsl:template match="*[@type='OfficeArtSpgrContainer']">
101
    <xsl:param name="x" select="rgfb/anon/clientAnchor/*/left div 576" />
102
    <xsl:param name="y" select="rgfb/anon/clientAnchor/*/top div 576" />
103
    <xsl:param name="width"
104
      select="(number(rgfb/anon/clientAnchor/*/right)-$x) div 576" />
105
    <xsl:param name="height"
106
      select="(number(rgfb/anon/clientAnchor/*/bottom)-$y) div 576" />
107
    <xsl:param name="vx" select="rgfb/anon/shapeGroup/xLeft" />
108
    <xsl:param name="vy" select="rgfb/anon/shapeGroup/yTop" />
109
    <xsl:param name="vwidth" select="number(rgfb/anon/shapeGroup/xRight)-$vx" />
110
    <xsl:param name="vheight" select="number(rgfb/anon/shapeGroup/yBottom)-$vy" />
111
    <xsl:variable name="scale" select="$vwidth div $width" />
112
    <draw:frame svg:x="{$x}in" svg:y="{$y}in" svg:width="{$width}in"
113
        svg:height="{$height}in">
114
      <!--
115
        if the first OfficeArtSpContainer has a clientAnchor, a new
116
        coordinate system is introduced.
117
      -->
118
        <xsl:attribute name="svg:viewBox">
119
          <xsl:value-of select="concat($vx,' ',$vy,' ',$vwidth,' ',$vheight)"/>
120
        </xsl:attribute>
121
      <xsl:if test="rgfb[position()=1]/anon/clientAnchor">
122
        <xsl:attribute name="svg:viewBox">
123
          <xsl:value-of select="concat($vx,' ',$vy,' ',$vwidth,' ',$vheight)"/>
124
        </xsl:attribute>
125
      </xsl:if>
126
    <xsl:choose>
127
      <xsl:when test="rgfb[position()=1]/anon/clientAnchor">
128
        <svg overflow="visible" x="{$x}" y="{$y}" width="{$width}"
129
          height="{$height}" viewBox="{$vx} {$vy} {$vwidth} {$vheight}"
130
          font-size="{100*$scale}%">
131
          <xsl:apply-templates select="rgfb[position()>1]/anon" />
132
        </svg>
133
      </xsl:when>
134
      <xsl:otherwise>
135
  <!--      <xsl:apply-templates select="rgfb[position()>1]/anon" />-->
136
      </xsl:otherwise>
137
    </xsl:choose>
138
    </draw:frame>
139
  </xsl:template>
140
141
  <!--
142
    <draw:frame draw:layer="layout" svg:x="{$x}in" svg:y="{$y}in"
143
    svg:width="{$width}in" svg:height="{$height}in"> <draw:text-box>
144
    <text:p>hello</text:p> </draw:text-box> </draw:frame>
145
  -->
146
  <xsl:template match="atoms[@type='TextContainer']">
147
    <draw:frame draw:layer="layout">
148
      <xsl:choose>
149
        <xsl:when test="textHeaderAtom/textType=0">
150
          <xsl:attribute name="presentation:class">title</xsl:attribute>
151
        </xsl:when>
152
      </xsl:choose>
153
      <draw:text-box>
154
        <text:p>
155
          <xsl:value-of select="text/textChars" />
156
        </text:p>
157
      </draw:text-box>
158
    </draw:frame>
159
  </xsl:template>
160
161
</xsl:stylesheet>