Process SMIL directives in XML data: Difference between revisions

From Rosetta Code
Content added Content deleted
m (</smil> on its own line)
(→‎Tcl: Added implementation)
Line 60: Line 60:
</Scene>
</Scene>
</X3D></lang>
</X3D></lang>

=={{header|Tcl}}==
{{works with|Tcl|8.6}}
{{libheader|tDOM}}
<lang tcl>package require Tcl 8.6
package require tdom

# Applies a time-based interpolation to generate a space-separated list
proc interpolate {time info} {
dict with info {
scan $begin "%fs" begin
scan $dur "%fs" dur
}
if {$time < $begin} {
return $from
} elseif {$time > $begin+$dur} {
return $to
}
set delta [expr {($time - $begin) / $dur}]
return [lmap f $from t $to {expr {$f + ($t-$f)*$delta}}]
}

# Applies SMIL <transform> elements to their container
proc applySMILtransform {sourceDocument time} {
set doc [dom parse [$sourceDocument asXML]]
foreach smil [$doc selectNodes //smil] {
foreach context [$smil selectNodes {//*[animate]}] {
set animator [$context selectNodes animate]
set animated [$context selectNodes @[$animator @attributeName]]
$context removeChild $animator
$context setAttribute [$animator @attributeName] \
[interpolate $time [lindex [$animator asList] 1]]
}
if {[$smil parentNode] eq ""} {
set reparent 1
} else {
[$smil parentNode] replaceChild $smil [$smil firstChild]
}
}
if {[info exist reparent]} {
set doc [dom parse [[$smil firstChild] asXML]]
}
return $doc
}

set t [expr {[lindex $argv 0] + 0.0}]
set result [applySMILtransform [dom parse [read stdin]] $t]
puts {<?xml version="1.0" ?>}
puts -nonewline [$result asXML -indent 2]</lang>
{{out|Demonstration}}
Note that <tt>input.smil</tt> contains the source document from the task description.
<pre>
$ tclsh8.6 applySmil.tcl 0 < input.smil
<?xml version="1.0" ?>
<X3D>
<Scene>
<Viewpoint position="0 0 8" orientation="0 0 1 0"/>
<PointLight color="1 1 1" location="0 2 0"/>
<Shape>
<Box size="2.0 1.0 2.0"/>
<Appearance>
<Material diffuseColor="0.0 0.6 1.0"/>
</Appearance>
</Shape>
</Scene>
</X3D>
$ tclsh8.6 applySmil.tcl 2 < input.smil
<?xml version="1.0" ?>
<X3D>
<Scene>
<Viewpoint position="0 0 8" orientation="0 0 1 0"/>
<PointLight color="1 1 1" location="0 2 0"/>
<Shape>
<Box size="1.8 1.2 1.8"/>
<Appearance>
<Material diffuseColor="0.2 0.5599999999999999 0.8"/>
</Appearance>
</Shape>
</Scene>
</X3D>
</pre>

Revision as of 08:09, 27 May 2014

Process SMIL directives in XML data is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

In order to represent evolutions of contents over time, the SMIL standard provides a solution to record the animation of data. Smil animations can be added to any kind of contents formated in XML.

The task is to create an utility that given the first Smiled XML file, would return the following ones:

<lang xml><?xml version="1.0" ?> <smil> <X3D>

 <Scene>
   <Viewpoint position="0 0 8" orientation="0 0 1 0"/>
   <PointLight color='1 1 1' location='0 2 0'/>
   <Shape>
     <Box size='2 1 2'>
       <animate attributeName="size" from="2 1 2"
                                       to="1 2 1" begin="0s" dur="10s"/>
     </Box>
     <Appearance>
       <Material diffuseColor='0.0 0.6 1.0'>
         <animate attributeName="diffuseColor" from="0.0 0.6 1.0"
                                                 to="1.0 0.4 0.0" begin="0s" dur="10s"/>
       </Material>
     </Appearance>
   </Shape>
 </Scene>

</X3D> </smil></lang>

At t = 0 second here is the expected output:

<lang xml><?xml version="1.0" ?> <X3D>

 <Scene>
   <Viewpoint position="0 0 8" orientation="0 0 1 0"/>
   <PointLight color='1 1 1' location='0 2 0'/>
   <Shape>
     <Box size='2 1 2'/>
     <Appearance>
       <Material diffuseColor='0.0 0.6 1.0'/>
     </Appearance>
   </Shape>
 </Scene>

</X3D></lang>

At t = 2 second here is the expected output:

<lang xml><?xml version="1.0" ?> <X3D>

 <Scene>
   <Viewpoint position="0 0 8" orientation="0 0 1 0"/>
   <PointLight color='1 1 1' location='0 2 0'/>
   <Shape>
     <Box size='1.8 1.2 1.8'/>
     <Appearance>
       <Material diffuseColor='0.2 0.56 0.8'/>
     </Appearance>
   </Shape>
 </Scene>

</X3D></lang>

Tcl

Works with: Tcl version 8.6
Library: tDOM

<lang tcl>package require Tcl 8.6 package require tdom

  1. Applies a time-based interpolation to generate a space-separated list

proc interpolate {time info} {

   dict with info {

scan $begin "%fs" begin scan $dur "%fs" dur

   }
   if {$time < $begin} {

return $from

   } elseif {$time > $begin+$dur} {

return $to

   }
   set delta [expr {($time - $begin) / $dur}]
   return [lmap f $from t $to {expr {$f + ($t-$f)*$delta}}]

}

  1. Applies SMIL <transform> elements to their container

proc applySMILtransform {sourceDocument time} {

   set doc [dom parse [$sourceDocument asXML]]
   foreach smil [$doc selectNodes //smil] {

foreach context [$smil selectNodes {//*[animate]}] { set animator [$context selectNodes animate] set animated [$context selectNodes @[$animator @attributeName]] $context removeChild $animator $context setAttribute [$animator @attributeName] \ [interpolate $time [lindex [$animator asList] 1]] } if {[$smil parentNode] eq ""} { set reparent 1 } else { [$smil parentNode] replaceChild $smil [$smil firstChild] }

   }
   if {[info exist reparent]} {

set doc [dom parse [[$smil firstChild] asXML]]

   }
   return $doc

}

set t [expr {[lindex $argv 0] + 0.0}] set result [applySMILtransform [dom parse [read stdin]] $t] puts {<?xml version="1.0" ?>} puts -nonewline [$result asXML -indent 2]</lang>

Demonstration:

Note that input.smil contains the source document from the task description.

$ tclsh8.6 applySmil.tcl 0 < input.smil
<?xml version="1.0" ?>
<X3D>
  <Scene>
    <Viewpoint position="0 0 8" orientation="0 0 1 0"/>
    <PointLight color="1 1 1" location="0 2 0"/>
    <Shape>
      <Box size="2.0 1.0 2.0"/>
      <Appearance>
        <Material diffuseColor="0.0 0.6 1.0"/>
      </Appearance>
    </Shape>
  </Scene>
</X3D>
$ tclsh8.6 applySmil.tcl 2 < input.smil
<?xml version="1.0" ?>
<X3D>
  <Scene>
    <Viewpoint position="0 0 8" orientation="0 0 1 0"/>
    <PointLight color="1 1 1" location="0 2 0"/>
    <Shape>
      <Box size="1.8 1.2 1.8"/>
      <Appearance>
        <Material diffuseColor="0.2 0.5599999999999999 0.8"/>
      </Appearance>
    </Shape>
  </Scene>
</X3D>