diff --git a/asciidiagram.cabal b/asciidiagram.cabal
--- a/asciidiagram.cabal
+++ b/asciidiagram.cabal
@@ -1,10 +1,10 @@
 -- Initial hitaa.cabal generated by cabal init.  For further documentation,
 --  see http://haskell.org/cabal/users-guide/
 name:                asciidiagram
-version:             1.2
+version:             1.3
 synopsis:            Pretty rendering of Ascii diagram into svg or png.
 description:         
-    Asciidiagram Ascii art diagram like this:
+    Transform Ascii art diagram like this:
     .
     @
     ,               \/---------+
@@ -40,17 +40,19 @@
 Source-Repository this
     Type:      git
     Location:  git://github.com/Twinside/asciidiagram.git
-    Tag:       v1.2
+    Tag:       v1.3
 
 library
   ghc-options: -O2 -Wall
   exposed-modules: Text.AsciiDiagram
 
   other-modules: Text.AsciiDiagram.DiagramCleaner
+               , Text.AsciiDiagram.DefaultContext
                , Text.AsciiDiagram.Geometry
                , Text.AsciiDiagram.Graph
                , Text.AsciiDiagram.Parser
                , Text.AsciiDiagram.Reconstructor
+               , Text.AsciiDiagram.BoundingBoxEstimation
                , Text.AsciiDiagram.SvgRender
 
   -- containers >= 0.5.2.1 for Set.elemAt
@@ -62,7 +64,7 @@
                , containers >= 0.5
                , mtl        >= 2.1 && < 2.3
                , lens       >= 4.6 && < 5.0
-               , svg-tree       >= 0.4.1 && < 0.5
+               , svg-tree       >= 0.5 && < 0.6
                , rasterific-svg >= 0.3 && < 0.4
                , FontyFruity    >= 0.5 && < 0.6
                , JuicyPixels    >= 3.2
diff --git a/docimages/arrows.svg b/docimages/arrows.svg
--- a/docimages/arrows.svg
+++ b/docimages/arrows.svg
@@ -1,5 +1,5 @@
 <?xml version='1.0' ?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="165.0" height="117.0">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="165.0" height="131.0">
   <style type="text/css">text {
   font-family: Consolas , &quot;DejaVu Sans Mono&quot; , monospace;
   font-size: 16.0px;
@@ -9,35 +9,59 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M60.0,56.0 L60.0,56.0" />
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M60.0,56.0 L60.0,56.0 L20.0,56.0 L10.0,56.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M10.0,49.0 L0.0,56.0 L10.0,63.0 Z" />
+  <text x="85.5" y="77.5">&lt; &gt; v ^</text>
+  <path class="line_element" d="M60.0,56.0 L60.0,56.0" />
+  <g class="line_element">
+    <path d="M60.0,56.0 L60.0,56.0 L20.0,56.0 L10.0,56.0" />
+    <path class="arrow_head" d="M10.0,49.0 L0.0,56.0 L10.0,63.0 Z" />
   </g>
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M60.0,56.0 L60.0,56.0 L60.0,28.0 L60.0,14.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M55.0,14.0 L65.0,14.0 L60.0,0.0 Z" />
+  <g class="line_element">
+    <path d="M60.0,56.0 L60.0,56.0 L60.0,28.0 L60.0,14.0" />
+    <path class="arrow_head" d="M55.0,14.0 L65.0,14.0 L60.0,0.0 Z" />
   </g>
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M60.0,56.0 L60.0,56.0 L100.0,56.0 L110.0,56.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M110.0,49.0 L120.0,56.0 L110.0,63.0 Z" />
+  <g class="line_element">
+    <path d="M60.0,56.0 L60.0,56.0 L100.0,56.0 L110.0,56.0" />
+    <path class="arrow_head" d="M110.0,49.0 L120.0,56.0 L110.0,63.0 Z" />
   </g>
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M60.0,98.0 L60.0,98.0 L60.0,70.0 L60.0,56.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M55.0,98.0 L65.0,98.0 L60.0,112.0 Z" />
+  <g class="line_element">
+    <path d="M60.0,98.0 L60.0,98.0 L60.0,70.0 L60.0,56.0" />
+    <path class="arrow_head" d="M55.0,98.0 L65.0,98.0 L60.0,112.0 Z" />
   </g>
-  <text class="" x="85.5" y="77.5">&lt; &gt; v ^</text>
 </svg>
diff --git a/docimages/baseExample.svg b/docimages/baseExample.svg
--- a/docimages/baseExample.svg
+++ b/docimages/baseExample.svg
@@ -1,5 +1,5 @@
 <?xml version='1.0' ?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="285.0" height="103.0">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="405.0" height="103.0">
   <style type="text/css">text {
   font-family: Consolas , &quot;DejaVu Sans Mono&quot; , monospace;
   font-size: 16.0px;
@@ -9,38 +9,65 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
-.flat {
-  fill: #DDDDDD;
+.arrow_head {
+  fill: #000000;
+  stroke: none;
 }
+.flat .filled_shape {
+  fill: #DDEEDD;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M11.5,42.0 L11.5,42.0 L11.5,54.5 L100.0,54.5 L108.5,54.5 L108.5,42.0 L108.5,29.5 L20.0,29.5 L11.5,29.5 Z" />
-  <g stroke-width="1.0" stroke="#000000" class="filled_shape">
+  <g class="line_element">
+    <path d="M160.0,42.0 L160.0,42.0 L120.0,42.0 L110.0,42.0" />
+    <path class="arrow_head" d="M160.0,35.0 L170.0,42.0 L160.0,49.0 Z" />
+  </g>
+  <path class="line_element" d="M200.0,70.0 L200.0,70.0" />
+  <g class="line_element">
+    <path class="dashed_elem" d="M200.0,70.0 L200.0,70.0 S200.0,84.0 190.0,84.0 L130.0,84.0 L120.0,84.0" />
+    <path class="arrow_head" d="M120.0,77.0 L110.0,84.0 L120.0,91.0 Z" />
+  </g>
+  <g>
+    <path class="filled_shape" d="M11.5,42.0 L11.5,42.0 L11.5,54.5 L100.0,54.5 L108.5,54.5 L108.5,42.0 L108.5,29.5 L20.0,29.5 L11.5,29.5 Z" />
+    <text x="35.5" y="49.5">ASCII </text>
+  </g>
+  <g class="filled_shape">
     <path class="flat" d="M11.5,70.0 L11.5,70.0 S10.0,84.0 20.0,82.5 L40.0,82.5 L50.0,82.5 L100.0,82.5 S110.0,84.0 108.5,70.0 L108.5,70.0 L108.5,57.5 L20.0,57.5 L11.5,57.5 Z" />
     <circle class="bullet" cx="50.0" cy="82.5" r="3.0" />
   </g>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M171.5,28.0 L171.5,56.0 L171.5,68.5 L190.0,68.5 L200.0,68.5 L260.0,68.5 S270.0,70.0 268.5,56.0 L268.5,28.0 L268.5,15.5 L180.0,15.5 S170.0,14.0 171.5,28.0 Z" />
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M160.0,42.0 L160.0,42.0 L120.0,42.0 L110.0,42.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M160.0,35.0 L170.0,42.0 L160.0,49.0 Z" />
-  </g>
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M200.0,70.0 L200.0,70.0" />
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="dashed_elem" d="M200.0,70.0 L200.0,70.0 S200.0,84.0 190.0,84.0 L130.0,84.0 L120.0,84.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M120.0,77.0 L110.0,84.0 L120.0,91.0 Z" />
+  <g>
+    <path class="filled_shape" d="M171.5,28.0 L171.5,56.0 L171.5,68.5 L190.0,68.5 L200.0,68.5 L260.0,68.5 S270.0,70.0 268.5,56.0 L268.5,28.0 L268.5,15.5 L180.0,15.5 S170.0,14.0 171.5,28.0 Z" />
+    <text x="185.5" y="49.5">Diagram </text>
   </g>
-  <text class="" x="35.5" y="49.5">ASCII </text>
-  <text class="" x="185.5" y="49.5">Diagram </text>
-  <text class="" x="85.5" y="77.5"></text>
 </svg>
diff --git a/docimages/bulletTest.svg b/docimages/bulletTest.svg
--- a/docimages/bulletTest.svg
+++ b/docimages/bulletTest.svg
@@ -9,30 +9,54 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <g stroke-width="1.0" stroke="#000000" class="filled_shape">
-    <path class="" d="M31.5,28.0 L31.5,28.0 L31.5,40.5 L60.0,40.5 S70.0,42.0 68.5,28.0 L68.5,28.0 L68.5,15.5 L60.0,15.5 L50.0,15.5 L40.0,15.5 L31.5,15.5 Z" />
-    <circle class="bullet" cx="68.5" cy="15.5" r="3.0" />
-    <circle class="bullet" cx="50.0" cy="15.5" r="3.0" />
-    <circle class="bullet" cx="31.5" cy="15.5" r="3.0" />
-  </g>
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M150.0,56.0 L150.0,56.0 L150.0,42.0 L150.0,28.0 L110.0,28.0 L100.0,28.0" />
+  <text x="105.5" y="63.5">* * </text>
+  <g class="line_element">
+    <path d="M150.0,56.0 L150.0,56.0 L150.0,42.0 L150.0,28.0 L110.0,28.0 L100.0,28.0" />
     <circle class="bullet" cx="150.0" cy="56.0" r="3.0" />
     <circle class="bullet" cx="150.0" cy="28.0" r="3.0" />
     <circle class="bullet" cx="100.0" cy="28.0" r="3.0" />
   </g>
-  <text class="" x="105.5" y="63.5">* * </text>
+  <g class="filled_shape">
+    <path d="M31.5,28.0 L31.5,28.0 L31.5,40.5 L60.0,40.5 S70.0,42.0 68.5,28.0 L68.5,28.0 L68.5,15.5 L60.0,15.5 L50.0,15.5 L40.0,15.5 L31.5,15.5 Z" />
+    <circle class="bullet" cx="68.5" cy="15.5" r="3.0" />
+    <circle class="bullet" cx="50.0" cy="15.5" r="3.0" />
+    <circle class="bullet" cx="31.5" cy="15.5" r="3.0" />
+  </g>
 </svg>
diff --git a/docimages/cabalSchema.svg b/docimages/cabalSchema.svg
--- a/docimages/cabalSchema.svg
+++ b/docimages/cabalSchema.svg
@@ -9,34 +9,62 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M11.5,42.0 L11.5,42.0 L11.5,54.5 L100.0,54.5 L108.5,54.5 L108.5,42.0 L108.5,29.5 L20.0,29.5 L11.5,29.5 Z" />
-  <g stroke-width="1.0" stroke="#000000" class="filled_shape">
-    <path class="" d="M11.5,70.0 L11.5,70.0 S10.0,84.0 20.0,82.5 L40.0,82.5 L50.0,82.5 L100.0,82.5 S110.0,84.0 108.5,70.0 L108.5,70.0 L108.5,57.5 L20.0,57.5 L11.5,57.5 Z" />
-    <circle class="bullet" cx="50.0" cy="82.5" r="3.0" />
-  </g>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M171.5,28.0 L171.5,56.0 L171.5,68.5 L190.0,68.5 L200.0,68.5 L260.0,68.5 S270.0,70.0 268.5,56.0 L268.5,28.0 L268.5,15.5 L180.0,15.5 S170.0,14.0 171.5,28.0 Z" />
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M160.0,42.0 L160.0,42.0 L120.0,42.0 L110.0,42.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M160.0,35.0 L170.0,42.0 L160.0,49.0 Z" />
+  <g class="line_element">
+    <path d="M160.0,42.0 L160.0,42.0 L120.0,42.0 L110.0,42.0" />
+    <path class="arrow_head" d="M160.0,35.0 L170.0,42.0 L160.0,49.0 Z" />
   </g>
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M200.0,70.0 L200.0,70.0" />
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
+  <path class="line_element" d="M200.0,70.0 L200.0,70.0" />
+  <g class="line_element">
     <path class="dashed_elem" d="M200.0,70.0 L200.0,70.0 S200.0,84.0 190.0,84.0 L130.0,84.0 L120.0,84.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M120.0,77.0 L110.0,84.0 L120.0,91.0 Z" />
+    <path class="arrow_head" d="M120.0,77.0 L110.0,84.0 L120.0,91.0 Z" />
   </g>
-  <text class="" x="35.5" y="49.5">ASCII </text>
-  <text class="" x="185.5" y="49.5">Diagram </text>
+  <g>
+    <path class="filled_shape" d="M11.5,42.0 L11.5,42.0 L11.5,54.5 L100.0,54.5 L108.5,54.5 L108.5,42.0 L108.5,29.5 L20.0,29.5 L11.5,29.5 Z" />
+    <text x="35.5" y="49.5">ASCII </text>
+  </g>
+  <g class="filled_shape">
+    <path d="M11.5,70.0 L11.5,70.0 S10.0,84.0 20.0,82.5 L40.0,82.5 L50.0,82.5 L100.0,82.5 S110.0,84.0 108.5,70.0 L108.5,70.0 L108.5,57.5 L20.0,57.5 L11.5,57.5 Z" />
+    <circle class="bullet" cx="50.0" cy="82.5" r="3.0" />
+  </g>
+  <g>
+    <path class="filled_shape" d="M171.5,28.0 L171.5,56.0 L171.5,68.5 L190.0,68.5 L200.0,68.5 L260.0,68.5 S270.0,70.0 268.5,56.0 L268.5,28.0 L268.5,15.5 L180.0,15.5 S170.0,14.0 171.5,28.0 Z" />
+    <text x="185.5" y="49.5">Diagram </text>
+  </g>
 </svg>
diff --git a/docimages/complexClosed.svg b/docimages/complexClosed.svg
--- a/docimages/complexClosed.svg
+++ b/docimages/complexClosed.svg
@@ -9,19 +9,43 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M31.5,28.0 L31.5,56.0 L31.5,68.5 L60.0,68.5 L70.0,68.5 L90.0,68.5 L98.5,68.5 L98.5,56.0 L98.5,42.0 L98.5,28.0 L98.5,15.5 L40.0,15.5 L31.5,15.5 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M71.5,84.0 L71.5,84.0 L71.5,96.5 L120.0,96.5 L128.5,96.5 L128.5,56.0 L128.5,43.5 L110.0,43.5 L101.5,43.5 L101.5,56.0 L101.5,71.5 L80.0,71.5 L71.5,71.5 Z" />
+  <path class="filled_shape" d="M31.5,28.0 L31.5,56.0 L31.5,68.5 L60.0,68.5 L70.0,68.5 L90.0,68.5 L98.5,68.5 L98.5,56.0 L98.5,42.0 L98.5,28.0 L98.5,15.5 L40.0,15.5 L31.5,15.5 Z" />
+  <path class="filled_shape" d="M71.5,84.0 L71.5,84.0 L71.5,96.5 L120.0,96.5 L128.5,96.5 L128.5,56.0 L128.5,43.5 L110.0,43.5 L101.5,43.5 L101.5,56.0 L101.5,71.5 L80.0,71.5 L71.5,71.5 Z" />
 </svg>
diff --git a/docimages/curvedCorner.svg b/docimages/curvedCorner.svg
--- a/docimages/curvedCorner.svg
+++ b/docimages/curvedCorner.svg
@@ -9,29 +9,53 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M31.5,28.0 L31.5,28.0 L31.5,40.5 L50.0,40.5 L58.5,40.5 L58.5,28.0 L58.5,15.5 L40.0,15.5 S30.0,14.0 31.5,28.0 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M31.5,84.0 L31.5,84.0 L31.5,96.5 L50.0,96.5 S60.0,98.0 58.5,84.0 L58.5,84.0 L58.5,71.5 L40.0,71.5 S30.0,70.0 31.5,84.0 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M31.5,140.0 L31.5,140.0 S30.0,154.0 40.0,152.5 L50.0,152.5 S60.0,154.0 58.5,140.0 L58.5,140.0 S60.0,126.0 50.0,127.5 L40.0,127.5 S30.0,126.0 31.5,140.0 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M91.5,28.0 L91.5,28.0 L91.5,40.5 L110.0,40.5 L118.5,40.5 L118.5,28.0 S120.0,14.0 110.0,15.5 L100.0,15.5 L91.5,15.5 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M91.5,84.0 L91.5,84.0 L91.5,96.5 L110.0,96.5 L118.5,96.5 L118.5,84.0 S120.0,70.0 110.0,71.5 L100.0,71.5 S90.0,70.0 91.5,84.0 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M151.5,28.0 L151.5,28.0 S150.0,42.0 160.0,40.5 L170.0,40.5 L178.5,40.5 L178.5,28.0 L178.5,15.5 L160.0,15.5 L151.5,15.5 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M151.5,84.0 L151.5,84.0 S150.0,98.0 160.0,96.5 L170.0,96.5 S180.0,98.0 178.5,84.0 L178.5,84.0 L178.5,71.5 L160.0,71.5 S150.0,70.0 151.5,84.0 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M211.5,28.0 L211.5,28.0 L211.5,40.5 L230.0,40.5 L238.5,40.5 L238.5,28.0 L238.5,15.5 L220.0,15.5 S210.0,14.0 211.5,28.0 Z" />
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M211.5,84.0 L211.5,84.0 L211.5,96.5 L230.0,96.5 S240.0,98.0 238.5,84.0 L238.5,84.0 S240.0,70.0 230.0,71.5 L220.0,71.5 S210.0,70.0 211.5,84.0 Z" />
-  <text class="" x="255.5" y="77.5">.</text>
-  <text class="" x="75.5" y="133.5">. </text>
-  <text class="" x="5.5" y="175.5">. </text>
+  <text x="5.5" y="175.5">. </text>
+  <text x="75.5" y="133.5">. </text>
+  <text x="255.5" y="77.5">.</text>
+  <path class="filled_shape" d="M31.5,28.0 L31.5,28.0 L31.5,40.5 L50.0,40.5 L58.5,40.5 L58.5,28.0 L58.5,15.5 L40.0,15.5 S30.0,14.0 31.5,28.0 Z" />
+  <path class="filled_shape" d="M31.5,84.0 L31.5,84.0 L31.5,96.5 L50.0,96.5 S60.0,98.0 58.5,84.0 L58.5,84.0 L58.5,71.5 L40.0,71.5 S30.0,70.0 31.5,84.0 Z" />
+  <path class="filled_shape" d="M31.5,140.0 L31.5,140.0 S30.0,154.0 40.0,152.5 L50.0,152.5 S60.0,154.0 58.5,140.0 L58.5,140.0 S60.0,126.0 50.0,127.5 L40.0,127.5 S30.0,126.0 31.5,140.0 Z" />
+  <path class="filled_shape" d="M91.5,28.0 L91.5,28.0 L91.5,40.5 L110.0,40.5 L118.5,40.5 L118.5,28.0 S120.0,14.0 110.0,15.5 L100.0,15.5 L91.5,15.5 Z" />
+  <path class="filled_shape" d="M91.5,84.0 L91.5,84.0 L91.5,96.5 L110.0,96.5 L118.5,96.5 L118.5,84.0 S120.0,70.0 110.0,71.5 L100.0,71.5 S90.0,70.0 91.5,84.0 Z" />
+  <path class="filled_shape" d="M151.5,28.0 L151.5,28.0 S150.0,42.0 160.0,40.5 L170.0,40.5 L178.5,40.5 L178.5,28.0 L178.5,15.5 L160.0,15.5 L151.5,15.5 Z" />
+  <path class="filled_shape" d="M151.5,84.0 L151.5,84.0 S150.0,98.0 160.0,96.5 L170.0,96.5 S180.0,98.0 178.5,84.0 L178.5,84.0 L178.5,71.5 L160.0,71.5 S150.0,70.0 151.5,84.0 Z" />
+  <path class="filled_shape" d="M211.5,28.0 L211.5,28.0 L211.5,40.5 L230.0,40.5 L238.5,40.5 L238.5,28.0 L238.5,15.5 L220.0,15.5 S210.0,14.0 211.5,28.0 Z" />
+  <path class="filled_shape" d="M211.5,84.0 L211.5,84.0 L211.5,96.5 L230.0,96.5 S240.0,98.0 238.5,84.0 L238.5,84.0 S240.0,70.0 230.0,71.5 L220.0,71.5 S210.0,70.0 211.5,84.0 Z" />
 </svg>
diff --git a/docimages/dashed_lines.svg b/docimages/dashed_lines.svg
--- a/docimages/dashed_lines.svg
+++ b/docimages/dashed_lines.svg
@@ -9,22 +9,46 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M20.0,112.0 L20.0,112.0 L20.0,56.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M20.0,14.0 L60.0,14.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element dashed_elem" d="M70.0,112.0 L30.0,112.0 L20.0,112.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element dashed_elem" d="M40.0,28.0 L100.0,28.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element dashed_elem" d="M90.0,84.0 L60.0,84.0 S50.0,84.0 50.0,70.0 L50.0,56.0" />
+  <path class="line_element" d="M20.0,112.0 L20.0,112.0 L20.0,56.0" />
+  <path class="line_element" d="M20.0,14.0 L60.0,14.0" />
+  <path class="line_element dashed_elem" d="M70.0,112.0 L30.0,112.0 L20.0,112.0" />
+  <path class="line_element dashed_elem" d="M40.0,28.0 L100.0,28.0" />
+  <path class="line_element dashed_elem" d="M90.0,84.0 L60.0,84.0 S50.0,84.0 50.0,70.0 L50.0,56.0" />
 </svg>
diff --git a/docimages/dashingClosed.svg b/docimages/dashingClosed.svg
--- a/docimages/dashingClosed.svg
+++ b/docimages/dashingClosed.svg
@@ -9,21 +9,45 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <rect stroke-width="1.0" stroke="#000000" class="filled_shape" width="27.0" height="25.0" x="31.5" y="15.5" />
-  <rect stroke-width="1.0" stroke="#000000" class="filled_shape dashed_elem" width="27.0" height="25.0" x="91.5" y="15.5" />
-  <rect stroke-width="1.0" stroke="#000000" class="filled_shape dashed_elem" width="27.0" height="25.0" x="151.5" y="15.5" />
-  <rect stroke-width="1.0" stroke="#000000" class="filled_shape dashed_elem" width="27.0" height="25.0" x="211.5" y="15.5" />
+  <rect class="filled_shape" width="27.0" height="25.0" x="31.5" y="15.5" />
+  <rect class="filled_shape dashed_elem" width="27.0" height="25.0" x="91.5" y="15.5" />
+  <rect class="filled_shape dashed_elem" width="27.0" height="25.0" x="151.5" y="15.5" />
+  <rect class="filled_shape dashed_elem" width="27.0" height="25.0" x="211.5" y="15.5" />
 </svg>
diff --git a/docimages/deepStyleExample.svg b/docimages/deepStyleExample.svg
new file mode 100644
--- /dev/null
+++ b/docimages/deepStyleExample.svg
@@ -0,0 +1,171 @@
+<?xml version='1.0' ?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="865.0" height="327.0">
+  <style type="text/css">text {
+  font-family: Consolas , &quot;DejaVu Sans Mono&quot; , monospace;
+  font-size: 16.0px;
+}
+.dashed_elem {
+  stroke-dasharray: 4.0 , 3.0;
+}
+.filled_shape {
+  fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
+.bullet {
+  stroke-width: 1.0px;
+  fill: #FFFFFF;
+  stroke: #000000;
+}
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
+.li .line_element {
+  stroke: #800080;
+}
+.li .arrow_head,
+.li text {
+  fill: #808080;
+}
+.lo .line_element {
+  stroke: #0000FF;
+}
+.lo .arrow_head,
+.lo text {
+  fill: #008000;
+}
+.lu .line_element {
+  stroke: #FF0000;
+}
+.lu .arrow_head,
+.lu text {
+  fill: #FFA500;
+}
+.ii .filled_shape {
+  fill: #DDDDFF;
+}
+.ii text {
+  fill: #0000FF;
+}
+.oo .filled_shape {
+  fill: #DDFFDD;
+}
+.oo text {
+  fill: #FFC0CB;
+}
+</style>
+  <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
+    <linearGradient id="shape_light" x2="0%" y2="100%">
+      <stop offset="0%" stop-color="#F5F5F5" />
+      <stop offset="100%" stop-color="#D8D8D8" />
+    </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
+  </defs>
+  <text x="585.5" y="21.5">. </text>
+  <text x="605.5" y="133.5">e0 </text>
+  <text x="845.5" y="133.5">.</text>
+  <g class="line_element">
+    <path d="M680.0,140.0 L680.0,140.0 L580.0,140.0 L570.0,140.0" />
+    <path class="arrow_head" d="M680.0,133.0 L690.0,140.0 L680.0,147.0 Z" />
+  </g>
+  <g class="li">
+    <path class="filled_shape li" d="M21.5,28.0 L21.5,280.0 S20.0,294.0 30.0,292.5 L560.0,292.5 S570.0,294.0 568.5,280.0 L568.5,154.0 L568.5,140.0 L568.5,28.0 S570.0,14.0 560.0,15.5 L30.0,15.5 S20.0,14.0 21.5,28.0 Z" />
+    <g class="lo">
+      <path class="filled_shape lo" d="M71.5,56.0 L71.5,70.0 L71.5,82.5 L110.0,82.5 L121.5,82.5 L121.5,98.0 L121.5,112.0 L121.5,127.5 L80.0,127.5 L71.5,127.5 L71.5,140.0 L71.5,152.5 L110.0,152.5 S120.0,154.0 121.5,168.0 L121.5,182.0 L121.5,194.5 L320.0,194.5 L330.0,194.5 L350.0,194.5 S360.0,196.0 358.5,182.0 L358.5,154.0 L358.5,140.0 L358.5,84.0 L358.5,70.0 L358.5,56.0 S360.0,42.0 350.0,43.5 L80.0,43.5 S70.0,42.0 71.5,56.0 Z" />
+      <g class="lu">
+        <path class="filled_shape lu" d="M201.5,154.0 L201.5,154.0 S200.0,168.0 210.0,166.5 L220.0,166.5 L230.0,166.5 L280.0,166.5 S290.0,168.0 288.5,154.0 L288.5,154.0 S290.0,140.0 280.0,141.5 L210.0,141.5 S200.0,140.0 201.5,154.0 Z" />
+        <text x="215.5" y="161.5">s3</text>
+      </g>
+      <g>
+        <path class="filled_shape" d="M191.5,70.0 L191.5,70.0 S190.0,84.0 200.0,82.5 L220.0,82.5 L230.0,82.5 L270.0,82.5 S280.0,84.0 278.5,70.0 L278.5,70.0 S280.0,56.0 270.0,57.5 L200.0,57.5 S190.0,56.0 191.5,70.0 Z" />
+        <text x="215.5" y="77.5">s2 </text>
+      </g>
+      <path class="line_element" d="M120.0,112.0 L120.0,112.0" />
+      <g class="line_element">
+        <path d="M120.0,112.0 L120.0,112.0 L210.0,112.0 S220.0,112.0 220.0,126.0 L220.0,126.0" />
+        <path class="arrow_head" d="M215.0,126.0 L225.0,126.0 L220.0,140.0 Z" />
+      </g>
+      <g class="line_element">
+        <path d="M180.0,70.0 L180.0,70.0 L150.0,70.0 L140.0,70.0" />
+        <path class="arrow_head" d="M180.0,63.0 L190.0,70.0 L180.0,77.0 Z" />
+        <circle class="bullet" cx="140.0" cy="70.0" r="3.0" />
+      </g>
+      <g class="line_element">
+        <path d="M230.0,126.0 L230.0,126.0 L230.0,98.0 L230.0,84.0" />
+        <path class="arrow_head" d="M225.0,126.0 L235.0,126.0 L230.0,140.0 Z" />
+      </g>
+      <path class="line_element" d="M230.0,168.0 L230.0,168.0" />
+      <g class="line_element">
+        <path d="M230.0,168.0 L230.0,168.0 S230.0,182.0 220.0,182.0 L140.0,182.0 L130.0,182.0" />
+        <path class="arrow_head" d="M130.0,175.0 L120.0,182.0 L130.0,189.0 Z" />
+      </g>
+      <path class="line_element" d="M360.0,140.0 L360.0,140.0" />
+      <path class="line_element" d="M360.0,140.0 L360.0,140.0 L360.0,84.0 L360.0,70.0" />
+      <text x="75.5" y="63.5">s1 </text>
+      <text x="245.5" y="119.5">e1 </text>
+      <text x="155.5" y="175.5">e2 </text>
+    </g>
+    <g class="oo">
+      <path class="filled_shape oo" d="M71.5,168.0 L71.5,182.0 S70.0,196.0 80.0,194.5 L80.0,194.5 L90.0,194.5 L110.0,194.5 L118.5,194.5 L118.5,168.0 S120.0,154.0 110.0,155.5 L80.0,155.5 L71.5,155.5 Z" />
+      <text x="85.5" y="175.5">o5 </text>
+    </g>
+    <g class="ii">
+      <path class="filled_shape ii" d="M71.5,98.0 L71.5,112.0 L71.5,124.5 L110.0,124.5 L118.5,124.5 L118.5,112.0 L118.5,98.0 L118.5,85.5 L80.0,85.5 L71.5,85.5 Z" />
+      <text x="85.5" y="105.5">i4 </text>
+    </g>
+    <g>
+      <path class="filled_shape" d="M451.5,70.0 L451.5,70.0 S450.0,84.0 460.0,82.5 L530.0,82.5 S540.0,84.0 538.5,70.0 L538.5,70.0 S540.0,56.0 530.0,57.5 L460.0,57.5 S450.0,56.0 451.5,70.0 Z" />
+      <text x="475.5" y="77.5">s10 </text>
+    </g>
+    <g>
+      <path class="filled_shape" d="M51.5,266.0 L51.5,266.0 S50.0,280.0 60.0,278.5 L130.0,278.5 S140.0,280.0 138.5,266.0 L138.5,266.0 S140.0,252.0 130.0,253.5 L60.0,253.5 S50.0,252.0 51.5,266.0 Z" />
+      <text x="75.5" y="273.5">s20 </text>
+    </g>
+    <path class="line_element" d="M90.0,196.0 L90.0,196.0 L110.0,196.0 L120.0,196.0" />
+    <g class="line_element">
+      <path d="M90.0,238.0 L90.0,238.0 L90.0,210.0 L90.0,196.0" />
+      <path class="arrow_head" d="M85.0,238.0 L95.0,238.0 L90.0,252.0 Z" />
+    </g>
+    <path class="line_element" d="M120.0,196.0 L120.0,196.0 L320.0,196.0 L330.0,196.0" />
+    <path class="line_element" d="M330.0,196.0 L330.0,196.0" />
+    <g class="line_element">
+      <path d="M330.0,196.0 L330.0,196.0 L330.0,210.0 S330.0,224.0 340.0,224.0 L380.0,224.0 S390.0,224.0 390.0,210.0 L390.0,196.0 S390.0,182.0 380.0,182.0 L380.0,182.0 L370.0,182.0" />
+      <path class="arrow_head" d="M370.0,175.0 L360.0,182.0 L370.0,189.0 Z" />
+    </g>
+    <path class="line_element" d="M330.0,196.0 L330.0,196.0 L350.0,196.0 S360.0,196.0 360.0,182.0 L360.0,154.0 L360.0,140.0" />
+    <g class="line_element">
+      <path d="M360.0,70.0 L360.0,70.0 L430.0,70.0 L440.0,70.0" />
+      <path class="arrow_head" d="M440.0,63.0 L450.0,70.0 L440.0,77.0 Z" />
+    </g>
+    <g class="line_element">
+      <path d="M360.0,140.0 L360.0,140.0 L470.0,140.0 S480.0,140.0 480.0,126.0 L480.0,112.0 L480.0,98.0" />
+      <path class="arrow_head" d="M475.0,98.0 L485.0,98.0 L480.0,84.0 Z" />
+    </g>
+    <text x="25.5" y="35.5">s100 </text>
+    <text x="385.5" y="63.5">e1 </text>
+    <text x="375.5" y="133.5">ealarm </text>
+    <text x="405.5" y="217.5">eReset </text>
+  </g>
+  <g>
+    <path class="filled_shape" d="M691.5,140.0 L691.5,140.0 S690.0,154.0 700.0,152.5 L820.0,152.5 S830.0,154.0 828.5,140.0 L828.5,140.0 S830.0,126.0 820.0,127.5 L700.0,127.5 S690.0,126.0 691.5,140.0 Z" />
+    <text x="735.5" y="147.5">s50 </text>
+  </g>
+</svg>
diff --git a/docimages/shapeExample.svg b/docimages/shapeExample.svg
new file mode 100644
--- /dev/null
+++ b/docimages/shapeExample.svg
@@ -0,0 +1,77 @@
+<?xml version='1.0' ?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="495.0" height="215.0">
+  <style type="text/css">text {
+  font-family: Consolas , &quot;DejaVu Sans Mono&quot; , monospace;
+  font-size: 16.0px;
+}
+.dashed_elem {
+  stroke-dasharray: 4.0 , 3.0;
+}
+.filled_shape {
+  fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
+.bullet {
+  stroke-width: 1.0px;
+  fill: #FFFFFF;
+  stroke: #000000;
+}
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
+.circle .filled_shape {
+  shape: circle;
+}
+.document .filled_shape {
+  shape: document;
+}
+.storage .filled_shape {
+  shape: storage;
+}
+.io .filled_shape {
+  shape: io;
+}
+</style>
+  <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
+    <linearGradient id="shape_light" x2="0%" y2="100%">
+      <stop offset="0%" stop-color="#F5F5F5" />
+      <stop offset="100%" stop-color="#D8D8D8" />
+    </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
+  </defs>
+  <g class="circle">
+    <use x="21.5" y="15.5" width="97.0" height="67.0" xlink:href="#circle" />
+    <text x="35.5" y="49.5">circle </text>
+  </g>
+  <g class="document">
+    <use x="21.5" y="113.5" width="107.0" height="67.0" xlink:href="#document" />
+    <text x="25.5" y="133.5">document </text>
+  </g>
+  <g class="io">
+    <use x="151.5" y="15.5" width="107.0" height="67.0" xlink:href="#io" />
+    <text x="195.5" y="63.5">io </text>
+  </g>
+  <g class="storage">
+    <use x="161.5" y="113.5" width="107.0" height="67.0" xlink:href="#storage" />
+    <text x="175.5" y="161.5">storage </text>
+  </g>
+</svg>
diff --git a/docimages/simple_lines.svg b/docimages/simple_lines.svg
--- a/docimages/simple_lines.svg
+++ b/docimages/simple_lines.svg
@@ -9,22 +9,46 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
+.arrow_head {
+  fill: #000000;
+  stroke: none;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M20.0,112.0 L20.0,112.0 L20.0,56.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M20.0,14.0 L60.0,14.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M70.0,112.0 L30.0,112.0 L20.0,112.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M40.0,28.0 L100.0,28.0" />
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M90.0,84.0 L60.0,84.0 S50.0,84.0 50.0,70.0 L50.0,56.0" />
+  <path class="line_element" d="M20.0,112.0 L20.0,112.0 L20.0,56.0" />
+  <path class="line_element" d="M20.0,14.0 L60.0,14.0" />
+  <path class="line_element" d="M70.0,112.0 L30.0,112.0 L20.0,112.0" />
+  <path class="line_element" d="M40.0,28.0 L100.0,28.0" />
+  <path class="line_element" d="M90.0,84.0 L60.0,84.0 S50.0,84.0 50.0,70.0 L50.0,56.0" />
 </svg>
diff --git a/docimages/styleExample.svg b/docimages/styleExample.svg
--- a/docimages/styleExample.svg
+++ b/docimages/styleExample.svg
@@ -9,50 +9,80 @@
 }
 .filled_shape {
   fill: url(#shape_light);
+  stroke: #000000;
+  stroke-width: 1.0px;
 }
+.line_element {
+  fill: none;
+  stroke: #000000;
+  stroke-width: 1.0px;
+}
 .bullet {
   stroke-width: 1.0px;
   fill: #FFFFFF;
   stroke: #000000;
 }
-.dst {
-  stroke: #FFAAAA;
-  stroke-width: 3.0px;
+.arrow_head {
+  fill: #000000;
+  stroke: none;
 }
 .src {
   fill: #AAAAFF;
 }
+.dst {
+  stroke: #FFAAAA;
+  stroke-width: 3.0px;
+}
 </style>
   <defs>
+    <symbol id="circle" viewBox="0.0 0.0 50.0 50.0" preserveAspectRatio="none">
+      <circle class="filled_shape" cx="25.0" cy="25.0" r="24.5" />
+    </symbol>
+    <symbol id="document" viewBox="0.0 0.0 51.0 51.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m49.98,0.79 -49.166,0.0 0.0,45.402 c15.92,12.45 30.4,-13.44 49.17,0.0 Z" />
+    </symbol>
+    <symbol id="io" viewBox="0.0 0.0 100.0 100.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m19.207,1.6 h79.414 l-17.192,97.297 h-79.414 Z" />
+    </symbol>
     <linearGradient id="shape_light" x2="0%" y2="100%">
       <stop offset="0%" stop-color="#F5F5F5" />
       <stop offset="100%" stop-color="#D8D8D8" />
     </linearGradient>
+    <symbol id="storage" viewBox="0.0 0.0 80.0 80.0" preserveAspectRatio="none">
+      <path class="filled_shape" d="m4.8122,67.74 v-53.769 c0.0,-3.2991 16.067,-5.9743 35.845,-5.9743 19.78,0.0 35.848,2.6752 35.848,5.9743 v53.769 c0.0,3.2925 -16.068,5.9743 -35.848,5.9743 -19.779,0.0 -35.845,-2.6818 -35.845,-5.9743 Z" />
+      <path class="filled_shape" d="m4.8122,13.97 4.779e-2,0.30672 0.13807,0.30272 0.22834,0.29872 0.31464,0.29344 0.40094,0.28944 0.48325,0.2828 0.56423,0.27744 0.64256,0.2708 0.71823,0.26416 0.79258,0.25752 0.86294,0.25096 0.9333,0.2416 0.99968,0.23496 1.0647,0.22568 1.1271,0.2164 1.1869,0.2084 1.2453,0.19784 1.301,0.1872 1.3555,0.17792 1.4046,0.16728 1.455,0.15536 1.5002,0.14336 1.5466,0.1328 1.5865,0.11952 1.6276,0.10752 1.6648,9.42e-2 1.7007,8.1e-2 1.7338,6.64e-2 1.7644,5.31e-2 1.7923,3.72e-2 1.8188,2.39e-2 1.8427,8.0e-3 c19.78,0.0 35.848,-2.6818 35.848,-5.9743" />
+    </symbol>
   </defs>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape src" d="M21.5,28.0 L21.5,42.0 L21.5,54.5 L100.0,54.5 L108.5,54.5 L108.5,42.0 L108.5,28.0 L108.5,15.5 L30.0,15.5 L21.5,15.5 Z" />
-  <rect stroke-width="1.0" stroke="#000000" class="filled_shape dst" width="67.0" height="39.0" x="21.5" y="85.5" />
-  <g stroke-width="1.0" stroke="#000000" class="filled_shape">
-    <path class="" d="M131.5,84.0 L131.5,84.0 L131.5,96.5 L200.0,96.5 L208.5,96.5 L208.5,84.0 L208.5,71.5 L140.0,71.5 L131.5,71.5 Z" />
-    <circle class="bullet" cx="208.5" cy="71.5" r="3.0" />
+  <g class="line_element">
+    <path d="M200.0,28.0 L200.0,28.0 L120.0,28.0 L110.0,28.0" />
+    <path class="arrow_head" d="M200.0,21.0 L210.0,28.0 L200.0,35.0 Z" />
   </g>
-  <path stroke-width="1.0" stroke="#000000" class="filled_shape" d="M211.5,28.0 L211.5,28.0 S210.0,42.0 220.0,40.5 L240.0,40.5 L250.0,40.5 L290.0,40.5 S300.0,42.0 298.5,28.0 L298.5,28.0 L298.5,15.5 L220.0,15.5 L211.5,15.5 Z" />
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M200.0,28.0 L200.0,28.0 L120.0,28.0 L110.0,28.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M200.0,21.0 L210.0,28.0 L200.0,35.0 Z" />
+  <path class="line_element" d="M250.0,42.0 L250.0,42.0" />
+  <g class="line_element">
+    <path d="M250.0,42.0 L250.0,42.0 L250.0,56.0 S250.0,70.0 240.0,70.0 L230.0,70.0 L220.0,70.0" />
+    <path class="arrow_head" d="M220.0,63.0 L210.0,70.0 L220.0,77.0 Z" />
   </g>
-  <path stroke-width="1.0" stroke="#000000" fill="none" class="line_element" d="M250.0,42.0 L250.0,42.0" />
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M250.0,42.0 L250.0,42.0 L250.0,56.0 S250.0,70.0 240.0,70.0 L230.0,70.0 L220.0,70.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M220.0,63.0 L210.0,70.0 L220.0,77.0 Z" />
+  <g class="src">
+    <path class="filled_shape src" d="M21.5,28.0 L21.5,42.0 L21.5,54.5 L100.0,54.5 L108.5,54.5 L108.5,42.0 L108.5,28.0 L108.5,15.5 L30.0,15.5 L21.5,15.5 Z" />
+    <text x="35.5" y="35.5">Source </text>
   </g>
-  <g stroke-width="1.0" stroke="#000000" fill="none" class="line_element">
-    <path class="" d="M120.0,84.0 L110.0,84.0 L100.0,84.0" />
-    <path stroke-width="0.0" stroke="none" fill="#000000" class="" d="M100.0,77.0 L90.0,84.0 L100.0,91.0 Z" />
+  <g class="dst">
+    <rect class="filled_shape dst" width="67.0" height="39.0" x="21.5" y="85.5" />
+    <text x="35.5" y="105.5">Dest </text>
   </g>
-  <text class="" x="35.5" y="35.5">Source </text>
-  <text class="" x="225.5" y="35.5">op1 </text>
-  <text class="" x="95.5" y="49.5"></text>
-  <text class="" x="145.5" y="91.5">op2 </text>
-  <text class="" x="35.5" y="105.5">Dest </text>
-  <text class="" x="85.5" y="119.5"></text>
+  <g class="line_element">
+    <path d="M120.0,84.0 L110.0,84.0 L100.0,84.0" />
+    <path class="arrow_head" d="M100.0,77.0 L90.0,84.0 L100.0,91.0 Z" />
+  </g>
+  <g>
+    <g class="filled_shape">
+      <path d="M131.5,84.0 L131.5,84.0 L131.5,96.5 L200.0,96.5 L208.5,96.5 L208.5,84.0 L208.5,71.5 L140.0,71.5 L131.5,71.5 Z" />
+      <circle class="bullet" cx="208.5" cy="71.5" r="3.0" />
+    </g>
+    <text x="145.5" y="91.5">op2 </text>
+  </g>
+  <g>
+    <path class="filled_shape" d="M211.5,28.0 L211.5,28.0 S210.0,42.0 220.0,40.5 L240.0,40.5 L250.0,40.5 L290.0,40.5 S300.0,42.0 298.5,28.0 L298.5,28.0 L298.5,15.5 L220.0,15.5 L211.5,15.5 Z" />
+    <text x="225.5" y="35.5">op1 </text>
+  </g>
 </svg>
diff --git a/exec-src/asciidiagram.hs b/exec-src/asciidiagram.hs
--- a/exec-src/asciidiagram.hs
+++ b/exec-src/asciidiagram.hs
@@ -17,6 +17,7 @@
                       , replaceExtension
                       , takeExtension )
 
+import Graphics.Svg( Document, loadSvgFile, saveXmlFile )
 import Graphics.Rasterific.Svg( loadCreateFontCache )
 import Graphics.Text.TrueType( FontCache )
 import Codec.Picture( writePng )
@@ -32,32 +33,59 @@
                           , info
                           , long
                           , metavar
+                          , optional
                           , progDesc
+                          , short
                           , str
+                          , strOption
                           , switch
                           )
+import Graphics.Rasterific.Svg( renderSvgDocument
+                              , pdfOfSvgDocument )
 import Text.AsciiDiagram
 
+data Mode
+  = Convert !(FilePath, FilePath)
+  | DumpLibrary !FilePath
+
 data Options = Options
-  { _inputFile  :: !FilePath
-  , _outputFile :: !FilePath
-  , _verbose    :: !Bool
-  , _format     :: !(Maybe Format)
+  { _workingMode :: !Mode
+  , _verbose     :: !Bool
+  , _withLibrary :: !(Maybe FilePath)
+  , _format      :: !(Maybe Format)
   }
 
 data Format = FormatSvg | FormatPng | FormatPdf
 
-argParser :: Parser Options
-argParser = Options
-  <$> ( argument str
-            (metavar "INPUTFILE"
-            <> help "Text file of the Ascii diagram to parse."))
-  <*> ( argument str
+ioParser :: Parser (String, String)
+ioParser = (,)
+    <$> argument str
+          (metavar "INPUTFILE"
+          <> help "Text file of the Ascii diagram to parse.")
+    <*> (argument str
             (metavar "OUTPUTFILE"
             <> help ("Output file name, same as input with"
                     <> " different extension if unspecified."))
-        <|> pure "" )
+        <|> pure "")
+
+modeParser :: Parser Mode
+modeParser = (Convert <$> ioParser) <|> (DumpLibrary <$> dumpParser)
+  where 
+    dumpParser = strOption 
+      ( long "dump-library"
+      <> short 'd'
+      <> metavar "FILENAME"
+      <> help "Dump the default shape library & styles in an SVG document") 
+
+argParser :: Parser Options
+argParser = Options
+  <$> modeParser
   <*> ( switch (long "verbose" <> help "Display more information") )
+  <*> ( optional $ strOption
+            ( long "with-library"
+            <> short 'l'
+            <> metavar "LIBRARY_FILENAME"
+            <> help "Use a custom shape & style library instead of the default one") )
   <*> ( flag Nothing (Just FormatSvg)
             (  long "svg"
             <> help "Force the use of the SVG format (deduced from extension otherwise)")
@@ -88,39 +116,63 @@
   tempDir <- getTemporaryDirectory 
   loadCreateFontCache $ tempDir </> "asciidiagram-fonty-fontcache"
 
-runConversion :: Options -> IO ()
-runConversion opt = do
-  verbose . putStrLn $ "Loading file " ++ _inputFile opt
-  inputData <- STIO.readFile $ _inputFile opt
+
+loadLibrary :: Options -> IO Document
+loadLibrary opt = case _withLibrary opt of
+   Nothing -> return defaultLib
+   Just p -> loadLib p
+  where
+    defaultLib = defaultLibrary defaultGridSize
+    loadLib p = do
+      f <- loadSvgFile p
+      case f of
+        Just doc -> return doc
+        Nothing -> do
+          putStrLn "Invalid library file, using default lib"
+          return defaultLib 
+
+runConversion :: Options -> FilePath -> FilePath -> IO ()
+runConversion opt inputFile outputFile = do
+  verbose . putStrLn $ "Loading file " ++ inputFile
+  inputData <- STIO.readFile inputFile
+  lib <- loadLibrary opt
   let diag = parseAsciiDiagram inputData
-      format = _format opt <|> (pure . formatOfOuputFilename $ _outputFile opt)
+      svg = svgOfDiagramAtSize defaultGridSize lib diag
+      format = _format opt <|> (pure $ formatOfOuputFilename outputFile)
   case format of
-    Nothing -> saveDoc diag
-    Just FormatSvg -> saveDoc diag
-    Just FormatPng -> savePng diag
-    Just FormatPdf -> savePdf diag
+    Nothing -> saveDoc svg
+    Just FormatSvg -> saveDoc svg
+    Just FormatPng -> savePng svg
+    Just FormatPdf -> savePdf svg
   where
     verbose = when $ _verbose opt
-    saveDoc diag = do
-      verbose . putStrLn $ "Writing SVG file " ++ _outputFile opt
-      saveAsciiDiagramAsSvg (savingPath "svg") diag
+    saveDoc svg = do
+      verbose . putStrLn $ "Writing SVG file " ++ outputFile
+      saveXmlFile (savingPath "svg") svg
 
-    savingPath ext = case _outputFile opt of
-      "" -> replaceExtension (_inputFile opt) ext
+    savingPath ext = case outputFile of
+      "" -> replaceExtension inputFile ext
       p -> p
 
-    savePdf diag = do
+    savePdf svg = do
       cache <- getFontCache  $ _verbose opt
-      verbose . putStrLn $ "Writing PDF file " ++ _outputFile opt
-      pdf <- pdfOfDiagram cache diag
+      verbose . putStrLn $ "Writing PDF file " ++ outputFile
+      (pdf, _) <- pdfOfSvgDocument cache Nothing 96 svg
       LB.writeFile (savingPath "pdf") pdf
 
-    savePng diag = do
+    savePng svg = do
       cache <- getFontCache  $ _verbose opt
-      verbose . putStrLn $ "Writing PNG file " ++ _outputFile opt
-      img <- imageOfDiagram cache diag
+      verbose . putStrLn $ "Writing PNG file " ++ outputFile
+      (img, _) <- renderSvgDocument cache Nothing 96 svg
       writePng (savingPath "png") img
 
+dumpLibrary :: FilePath -> IO ()
+dumpLibrary path =
+  saveXmlFile path $ defaultLibrary defaultGridSize
+
 main :: IO ()
-main = execParser progOptions >>= runConversion
+main = execParser progOptions >>= \opts ->
+  case _workingMode opts of
+    Convert (i, o) -> runConversion opts i o
+    DumpLibrary p -> dumpLibrary p
 
diff --git a/src/Text/AsciiDiagram.hs b/src/Text/AsciiDiagram.hs
--- a/src/Text/AsciiDiagram.hs
+++ b/src/Text/AsciiDiagram.hs
@@ -15,7 +15,7 @@
 -- +---------+     |         |
 -- |{flat}   |     +--+------\/
 -- \\---*-----\/\<=======\/
--- ::: .flat { fill: #DDD; }
+-- ::: .flat .filled_shape { fill: #DDD; }
 -- @
 -- <<docimages/baseExample.svg>>
 -- 
@@ -52,9 +52,12 @@
     -- ** Styles
     -- $styledoc
 
-    -- * Usage example
-    -- $example
+    -- ** Hierarchical styles
+    -- $hierarchicalDoc
 
+    -- ** Shapes
+    -- $shapeDoc
+
     -- * Functions
     svgOfDiagram
   , parseAsciiDiagram
@@ -70,6 +73,8 @@
   , imageOfDiagramAtSize
   , pdfOfDiagramAtSize
 
+    -- * Library
+  , defaultLibrary
 
     -- * Document description
   , Diagram( .. ) 
@@ -90,7 +95,6 @@
 import Data.Monoid( (<>))
 import Control.Monad( forM_ )
 import Control.Monad.ST( runST )
-import Control.Monad.State.Strict( runState, put, get )
 import Data.Function( on )
 import Data.List( partition, sortBy )
 import qualified Data.ByteString.Lazy as LB
@@ -154,27 +158,15 @@
 
       VU.unsafeFreeze emptyBoard
 
-data HorizontalPoints
-  = WithHorizontalSegments
-  | WithoutHorizontalSegments
-  deriving Eq
 
-allowsHorizontal :: HorizontalPoints -> Bool
-allowsHorizontal WithHorizontalSegments = True
-allowsHorizontal WithoutHorizontalSegments = False
-
-pointsOfShape :: F.Foldable f => HorizontalPoints -> f Shape -> [Point]
-pointsOfShape horizInfo = F.concatMap (F.concatMap go . shapeElements) where
-  withHorizontal = allowsHorizontal horizInfo
-
+pointsOfShape :: F.Foldable f => f Shape -> [Point]
+pointsOfShape = F.concatMap (F.concatMap go . shapeElements) where
   go (ShapeAnchor p _) = [p]
   go (ShapeSegment Segment { _segStart = V2 sx sy, _segEnd = V2 ex ey })
     | sx == ex && sy >= ey = [V2 sx yy | yy <- [ey .. sy]]
     | sx == ex             = [V2 sx yy | yy <- [sy .. ey]]
-    | withHorizontal && sy == ey && sx >= ex =
-        [V2 xx sy | xx <- [ex .. sx]]
-    | withHorizontal && sy == ey =
-        [V2 xx sy | xx <- [sx .. ex]]
+    | sy == ey && sx >= ex = [V2 xx sy | xx <- [ex .. sx]]
+    | sy == ey = [V2 xx sy | xx <- [sx .. ex]]
     | otherwise            = []
 
 cleanLines :: [Int] -> CharBoard -> CharBoard
@@ -189,8 +181,8 @@
 
 cleanupShapes :: (F.Foldable f) => f Shape -> CharBoard -> CharBoard
 cleanupShapes shapes board = board { _boardData = _boardData board VU.// toSet }
-  where toSet = [(x + y * _boardWidth board, ' ')
-                    | V2 x y <- pointsOfShape WithHorizontalSegments shapes]
+  where
+    toSet = [(x + y * _boardWidth board, ' ') | V2 x y <- pointsOfShape shapes]
 
 
 pointComp :: Point -> Point -> Ordering
@@ -198,8 +190,29 @@
   EQ -> compare x1 x2
   a -> a
 
-rangesOfShapes :: Shape -> [(Point, Point)]
-rangesOfShapes shape = pairAssoc sortedPoints
+featuresOfClosedShape :: Shape -> [Point]
+featuresOfClosedShape = F.fold . go . shapeElements where
+   go [] = []
+   -- If we got something like +----+ we skip the first anchor and
+   -- the segment.
+   go ( ShapeAnchor (V2 _ ay1) _
+      : ShapeSegment Segment { _segStart = V2 _ sy, _segEnd = V2 _ ey }
+      : rest@(ShapeAnchor (V2 _ ay2) _ : _)
+      )
+       | ay1 == ay2 && sy == ey && ay1 == sy = go rest
+   go (ShapeAnchor p _: rest) = [p] : go rest
+   go (ShapeSegment Segment { _segStart = V2 sx sy, _segEnd = V2 ex ey } : rest)
+     | sx == ex && sy >= ey = [V2 sx yy | yy <- [ey .. sy]] : after
+     | sx == ex             = [V2 sx yy | yy <- [sy .. ey]] : after
+     | otherwise           = after
+       where after = go rest
+
+rangesOfOpenedShape :: Shape -> [(Point, Point)]
+rangesOfOpenedShape s = fmap dup . sortBy pointComp $ pointsOfShape [s]
+  where dup a = (a, a)
+
+rangesOfClosedShape :: Shape -> [(Point, Point)]
+rangesOfClosedShape shape = pairAssoc sortedPoints
   where
    pairAssoc  [] = []
    pairAssoc [_] = []
@@ -207,56 +220,98 @@
       | y1 == y2 = (p1, p2) : pairAssoc rest
       | otherwise = pairAssoc lst
 
-   sortedPoints = sortBy pointComp
-                $ pointsOfShape WithoutHorizontalSegments [shape]
+   sortedPoints = sortBy pointComp $ featuresOfClosedShape shape
 
 
-associateTags :: [Shape] -> [TextZone] -> ([Shape], [TextZone])
-associateTags shapes tagZones =
-  expandTag $ runState (mapM go shapes) sortedZones where
+class RangeDecomposable a where
+  rangesOf :: a -> [(Point, Point)]
 
-  sortedZones =
-    sortBy (pointComp `on` _textZoneOrigin) tagZones
+instance RangeDecomposable Shape where
+  rangesOf s
+     | shapeIsClosed s = rangesOfClosedShape s
+     | otherwise = rangesOfOpenedShape s
 
-  isInRange (V2 px py) (V2 x1 y1, V2 x2 y2) =
-    py == y1 && py == y2 && x1 < px && px < x2
+instance RangeDecomposable TextZone where
+  rangesOf txt = [(orig, V2 (x + txtLength) y)] where
+    orig@(V2 x y) = _textZoneOrigin txt
+    txtLength = T.length $ _textZoneContent txt
+
+
+contains :: (RangeDecomposable a, RangeDecomposable b) => a -> b -> Bool
+contains sa sb = go (rangesOf sa) (rangesOf sb) where
+  go _      []    = True
+  go []     (_:_) = False
+  go ((V2 _ ya, _):rest1) rest2@((V2 _ yb, _):_)
+    -- A part of second shape is before potentially englobing shpae
+    -- so sa can't contain sb
+    | ya > yb = False   
+    -- sa may be bigger, just skip
+    | ya < yb = go rest1 rest2
+  -- here ya == yb
+  go sal@((V2 xa1 _, V2 xa2 _):rest1)
+     sar@((V2 xb1 _, V2 xb2 _):rest2)
+    -- sb is before any range of sa, so we must have
+    -- missed something, sa not containing sb
+    | xb1 < xa1 = False
+    -- sb is in the range bounds
+    | xa1 <= xb1 && xb2 <= xa2 = go sal rest2
+    -- Maybe sa has another range on the same line
+    | xb1 > xa2 = go rest1 sar
+    | otherwise = False
   
-  expandTag (s, zones) = (s, fmap expander zones) where
-    expander t = t { _textZoneContent = "{" <> _textZoneContent t <> "}" }
+areaOfShape :: Shape -> Int
+areaOfShape = F.sum . fmap dist . rangesOfClosedShape
+  where
+    -- we can use manathan distance here
+    dist (V2 x1 y1, V2 x2 y2) = abs (x1 - x2) + abs (y1 - y2)
 
-  insertAlls shape =
-    foldr S.insert (shapeTags shape) . fmap _textZoneContent
+sortByArea :: [Shape] -> [Shape]
+sortByArea shapes = sorted <> opened
+  where
+    (closed, opened) = partition shapeIsClosed shapes
+    sorted =
+        fmap snd . reverse $ sortBy (compare `on` fst) [(areaOfShape s, s) | s <- closed]
 
-  go shape | not $ shapeIsClosed shape = return shape
-  go shape = do
-    zones <- get
+hierarchise :: [Shape] -> [TextZone] -> [TextZone] -> [Element]
+hierarchise shapes allTexts = finalize . go areaSortedShapes allTexts where
+  areaSortedShapes = sortByArea shapes
 
-    let ranges = rangesOfShapes shape
-        isInShape TextZone { _textZoneOrigin = orig } =
-          any (isInRange orig) ranges
-        (inRanges, other) = partition isInShape zones
+  finalize (topShapes, topText, _topTags) =
+    (ElemShape <$> topShapes) <> (ElemText <$> topText)
 
-    put other
+  go [] texts tags = ([], texts, tags)
+  go (x:xs) texts tags | not (shapeIsClosed x) = (x:outShapes, outTexts, outTags)
+    where
+      (outShapes, outTexts, outTags) = go xs texts tags
+  go (x:xs) texts tags = (newShape : restShapes, restText, restTags)
+    where
+      (shapeInShape, shapeOutShape) = partition (x `contains`) xs
+      (textInShape, textOutShape) = partition (x `contains`) texts
+      (tagsInShape, tagsOutShape) = partition (x `contains`) tags
 
-    return shape { shapeTags = insertAlls shape inRanges }
+      (innerShapes, innerText, innerTags) = go shapeInShape textInShape tagsInShape
+      (restShapes, restText, restTags) = go shapeOutShape textOutShape tagsOutShape
 
+      newShape = x
+        { shapeChildren =
+            (ElemShape <$> innerShapes) <> (ElemText <$> innerText)
+        , shapeTags = S.fromList $ _textZoneContent <$> innerTags
+        }
 
 -- | Analyze an ascii diagram and extract all it's features.
 parseAsciiDiagram :: T.Text -> Diagram
 parseAsciiDiagram content = Diagram
-    { _diagramShapes = S.fromList taggedShape
-    , _diagramTexts = zones ++ unusedTags
+    { _diagramElements = S.fromList allElements
     , _diagramCellWidth = maximum $ fmap T.length textLines
     , _diagramCellHeight = length textLines - length styleLines
-    , _diagramStyles = styleLines
+    , _diagramStyles = reverse styleLines
     }
   where
     textLines = T.lines content
-    (taggedShape, unusedTags) = associateTags (S.toList validShapes) tags
-
-    (tags, zones) = detectTagFromTextZone
-                  $ extractTextZones shapeCleanedText 
+    allElements = hierarchise (S.toList validShapes) nonEmptyZones tags
 
+    nonEmptyZones = [t | t <- zones, not . T.null $ _textZoneContent t]
+    (tags, zones) = detectTagFromTextZone $ extractTextZones shapeCleanedText 
     (styleLineNumber, styleLines) = unzip $ styleLine parsed
 
     shapeCleanedText =
@@ -279,7 +334,7 @@
 -- a SVG file on disk with a customized grid size.
 saveAsciiDiagramAsSvgAtSize :: FilePath -> GridSize -> Diagram -> IO ()
 saveAsciiDiagramAsSvgAtSize fileName gridSize =
-  saveXmlFile fileName . svgOfDiagramAtSize gridSize
+  saveXmlFile fileName . svgOfDiagramAtSize gridSize (defaultLibrary gridSize)
 
 -- | Render a Diagram as an image. The Dpi
 -- is 96. The IO dependency is there to allow loading of the
@@ -293,7 +348,8 @@
 -- font files used in the document.
 imageOfDiagramAtSize :: FontCache -> GridSize -> Diagram -> IO (Image PixelRGBA8)
 imageOfDiagramAtSize cache gridSize =
-  fmap fst . renderSvgDocument cache Nothing 96 . svgOfDiagramAtSize gridSize
+  fmap fst . renderSvgDocument cache Nothing 96
+           . svgOfDiagramAtSize gridSize (defaultLibrary gridSize)
 
 -- | Render a Diagram into a PDF file. IO dependency to allow
 -- loading of the font files used in the document.
@@ -305,20 +361,40 @@
 -- IO dependency to allow loading of the font files used in the document.
 pdfOfDiagramAtSize :: FontCache -> GridSize -> Diagram -> IO LB.ByteString
 pdfOfDiagramAtSize cache size =
-  fmap fst . pdfOfSvgDocument cache Nothing 96 . svgOfDiagramAtSize size
+  fmap fst . pdfOfSvgDocument cache Nothing 96
+           . svgOfDiagramAtSize size (defaultLibrary size)
 
+-- $introDoc
+-- Ascii diagram, transform your ASCII art drawing to a nicer
+-- representation
+-- 
+-- 
+-- @
+--                 \/---------+
+-- +---------+     |         |
+-- |  ASCII  +----\>| Diagram |
+-- +---------+     |         |
+-- |{flat}   |     +--+------\/
+-- \\---*-----\/\<=======\/
+-- ::: .flat .filled_shape { fill: #DED; }
+-- @
+-- <<docimages/baseExample.svg>>
+-- 
+
 -- $linesdoc
 -- The basic syntax of asciidiagrams is made of lines made out\nof \'-\' and \'|\' characters. They can be connected with anchors\nlike \'+\' (direct connection) or \'\\\' and \'\/\' (smooth connections)\n
 -- 
--- >-----       
--- >  -------   
--- >            
--- >|  |        
--- >|  |        
--- >|  \----    
--- >|           
--- >+-----      
---
+-- 
+-- @
+--  -----       
+--    -------   
+--              
+--  |  |        
+--  |  |        
+--  |  \\----    
+--  |           
+--  +-----      
+-- @
 -- <<docimages/simple_lines.svg>>
 -- 
 -- You can use dashed lines by using ':' for vertical lines or '=' for\nhorizontal lines.
@@ -445,13 +521,102 @@
 -- The generated geometry also possess some predefined class
 -- which are overidable:
 -- 
---  * `dashed_elem` is applyied on every dashed element.
+--  * "dashed_elem" is applied on every dashed element.
 -- 
---  * `filled_shape` is applyied on every closed shape.
+--  * "filled_shape" is applied on every closed shape.
 -- 
---  * `bullet` on every bullet placed on a shape or line.
+--  * "arrow_head" is applied on arrow head.
 -- 
---  * `line_element` on every line element, this include the arrow head.
+--  * "bullet" on every bullet placed on a shape or line.
 -- 
+--  * "line_element" on every line element, this include the arrow head.
+-- 
 -- You can then customize the appearance of the diagram as you want.
+-- 
+
+-- $hierarchicalDoc
+-- Starting with version 1.3, all shapes, text and lines are
+-- hierachised, a shape within a shape will be integrated within
+-- the same group. This allows more complex styling: 
+-- 
+-- 
+-- @
+--  \/------------------------------------------------------\\ .
+--  |s100                                                  |
+--  |    \/----------------------------\\                    |
+--  |    |s1         \/--------\\       |  e1    \/--------\\  |
+--  |    |      *---\>|  s2    |       +-------\>|  s10   |  |
+--  |    +----+      \\---+----\/       |        \\--------\/  |
+--  |    | i4 |          |            |           ^        |
+--  |    |{ii}+---------\\| e1  {lo}   |           |        |
+--  |    +----+         vv            | ealarm    |        |   e0      \/-------------\\ .
+--  |    |            \/--------\\      +-----------\/        +----------\>|    s50      |
+--  |    +----\\       | s3 {lu}|      |                    |           \\-------------\/
+--  |    | o5 |   e2  \\--+-----\/      |                    |
+--  |    |{oo}|\<---------\/            |\<-\\                 |
+--  |    \\-+--+--------------------+--\/  |                 |
+--  |      |                       |     | eReset          |
+--  |      |                       \\-----\/                 |
+--  |      v                                               |
+--  |  \/--------\\                                          |
+--  |  |  s20   |                  {li}                    |
+--  |  \\--------\/                                          |
+--  \\------------------------------------------------------\/
+-- 
+-- ::: .li .line_element { stroke: purple; }
+-- ::: .li .arrow_head, .li text { fill: gray; }
+-- ::: .lo .line_element { stroke: blue; }
+-- ::: .lo .arrow_head, .lo text { fill: green; }
+-- ::: .lu .line_element { stroke: red; }
+-- ::: .lu .arrow_head, .lu text { fill: orange; }
+-- ::: .ii .filled_shape { fill: #DDF; }
+-- ::: .ii text { fill: blue; }
+-- ::: .oo .filled_shape { fill: #DFD; }
+-- ::: .oo text { fill: pink; }
+-- @
+-- <<docimages/deepStyleExample.svg>>
+-- 
+-- In the previous example, we can see that the lines color are
+-- 'shape scoped' and the tag applied to the shape above them
+-- applies to them
+-- 
+
+-- $shapeDoc
+-- From version 1.3, you can substitute the shape of your element
+-- with one from a shape library. Right now the shape library is
+-- relatively small:
+-- 
+-- 
+-- @
+--  +---------+  +----------+
+--  |         |  |          |
+--  | circle  |  |          |
+--  |         |  |    io    |
+--  |{circle} |  | {io}     |
+--  +---------+  +----------+
+-- 
+--  +----------+  +----------+
+--  |document  |  |          |
+--  |          |  |          |
+--  |          |  | storage  |
+--  |{document}|  | {storage}|
+--  +----------+  +----------+
+-- 
+-- ::: .circle .filled_shape { shape: circle; }
+-- ::: .document .filled_shape { shape: document; }
+-- ::: .storage .filled_shape { shape: storage; }
+-- ::: .io .filled_shape { shape: io; }
+-- @
+-- <<docimages/shapeExample.svg>>
+-- 
+-- The mechanism use CSS styling to change the shape, if a CSS rule
+-- possess a `shape` pseudo attribute, then the generated shape is replaced
+-- with a SVG `use` tag with the value of the shape attribute as `href`
+-- 
+-- But, you can create your own style library and change the default
+-- stylesheet. You can retrieve the default one with the shell command
+-- `asciidiagram --dump-library default-lib.svg`
+-- 
+-- You can then add your own symbols tag in it and use it by calling
+-- `asciidiagram --with-library your-lib.svg`.
 -- 
diff --git a/src/Text/AsciiDiagram/BoundingBoxEstimation.hs b/src/Text/AsciiDiagram/BoundingBoxEstimation.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/AsciiDiagram/BoundingBoxEstimation.hs
@@ -0,0 +1,124 @@
+{-# LANGUAGE CPP #-}
+module Text.AsciiDiagram.BoundingBoxEstimation where
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative( (<$>), (<*>)
+                          , pure
+                          )
+import Data.Foldable( foldMap )
+import Data.Monoid( Monoid( mappend, mempty )
+                  , mconcat
+                  )
+#endif
+
+import Data.Monoid( (<>) )
+import Linear( V2( .. )
+             , (^+^)
+             , (^-^)
+             )
+
+import Graphics.Svg.Types
+
+data BoundingBox = BoundingBox
+  { _boundingLow    :: !RPoint
+  , _boundingHight  :: !RPoint
+  }
+  deriving (Eq, Show)
+
+instance Monoid BoundingBox where
+  mempty = BoundingBox (V2 0 0) (V2 0 0)
+  mappend (BoundingBox min1 max1) (BoundingBox min2 max2) =
+    BoundingBox (min <$> min1 <*> min2) (max <$> max1 <*> max2)
+
+toEstimatedLength :: Number -> Coord
+toEstimatedLength n = case toUserUnit 96 n of
+  Num p -> p
+  _ -> 0
+
+toEstimatedPoint :: (Number, Number) -> RPoint
+toEstimatedPoint (a, b) = V2 a' b' where
+  a' = toEstimatedLength a
+  b' = toEstimatedLength b
+
+toB :: RPoint -> BoundingBox
+toB p = BoundingBox p p
+
+class WithBoundingBox a where
+  boundingBoxOf :: a -> BoundingBox
+
+instance WithBoundingBox PolyLine where
+  boundingBoxOf = foldMap toB . _polyLinePoints
+
+instance WithBoundingBox Polygon where
+  boundingBoxOf = foldMap toB . _polygonPoints
+
+instance WithBoundingBox Line where
+  boundingBoxOf (Line _ p1 p2) =
+      toB (toEstimatedPoint p1) <> toB (toEstimatedPoint p2)
+
+instance WithBoundingBox Rectangle where
+  boundingBoxOf (Rectangle _ base w h _) =
+      toB base' <> toB (base' ^+^ toEstimatedPoint (w, h))
+     where base' = toEstimatedPoint base
+
+pointOfPath :: PathCommand -> [RPoint]
+pointOfPath c = case c of
+ MoveTo _ l -> l
+ LineTo _ l -> l
+ HorizontalTo _ _ -> mempty
+ VerticalTo   _ _ -> mempty
+ CurveTo _ l -> mconcat [[a, b, cc] | (a, b, cc) <- l]
+ SmoothCurveTo _ l -> mconcat [[a, b] | (a, b) <- l]
+ QuadraticBezier _ l -> mconcat [[a, b] | (a, b) <- l]
+ SmoothQuadraticBezierCurveTo _ l -> l
+ EllipticalArc _ _ -> mempty
+ EndPath -> mempty
+
+instance WithBoundingBox Path where
+  boundingBoxOf (Path _ p) = foldMap (foldMap toB . pointOfPath) p
+
+instance WithBoundingBox a => WithBoundingBox (Group a) where
+  boundingBoxOf (Group _ child _ _) = foldMap boundingBoxOf child
+
+instance WithBoundingBox a => WithBoundingBox (Symbol a) where
+  boundingBoxOf (Symbol g) = boundingBoxOf g
+
+instance WithBoundingBox Text where
+  boundingBoxOf = boundingBoxOf . _textRoot
+
+instance WithBoundingBox TextSpan where
+  boundingBoxOf = boundingBoxOf . _spanInfo
+
+instance WithBoundingBox TextInfo where
+  boundingBoxOf t = case (_textInfoX t, _textInfoY t) of
+    (x1:_, y1:_) -> toB (toEstimatedPoint (x1, y1))
+    _ -> mempty
+
+instance WithBoundingBox Circle where
+  boundingBoxOf (Circle _ center rad) = BoundingBox (c ^-^ r) (c ^+^ r)
+    where
+     c = toEstimatedPoint center
+     r = pure $ toEstimatedLength rad
+
+instance WithBoundingBox Ellipse where
+  boundingBoxOf (Ellipse _ center xrad yrad) = BoundingBox (c ^-^ r) (c ^+^ r)
+    where
+     c = toEstimatedPoint center
+     r = V2 (toEstimatedLength xrad) (toEstimatedLength yrad)
+
+instance WithBoundingBox Tree where
+  boundingBoxOf t = case t of
+    None            -> mempty
+    UseTree _ _     -> mempty
+    PathTree p      -> boundingBoxOf p
+    CircleTree c    -> boundingBoxOf c
+    PolyLineTree pl -> boundingBoxOf pl
+    PolygonTree po  -> boundingBoxOf po
+    EllipseTree e   -> boundingBoxOf e
+    LineTree l      -> boundingBoxOf l
+    RectangleTree r -> boundingBoxOf r
+    TextTree  _ txt -> boundingBoxOf txt
+    ImageTree _     -> mempty
+    GroupTree g     -> boundingBoxOf g
+    SymbolTree s    -> boundingBoxOf s
+
diff --git a/src/Text/AsciiDiagram/DefaultContext.hs b/src/Text/AsciiDiagram/DefaultContext.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/AsciiDiagram/DefaultContext.hs
@@ -0,0 +1,151 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Text.AsciiDiagram.DefaultContext
+    ( defaultCss
+    , defaultCssRules
+    , defaultDefinitions
+    ) where
+
+import Control.Monad.State.Strict( execState )
+import Data.Monoid( (<>) )
+
+import Graphics.Svg.Types ( HasDrawAttributes( .. ), drawAttr )
+import Graphics.Svg( cssRulesOfText )
+
+import Codec.Picture( PixelRGBA8( PixelRGBA8 ) )
+import qualified Graphics.Svg.Types as Svg
+import qualified Graphics.Svg.CssTypes as Css
+import qualified Data.Map as M
+import qualified Data.Text as T
+import Text.Printf
+import Linear( V2( .. ) )
+import Control.Lens( (.=), (.~), (&) )
+
+
+defaultCss :: Float -> T.Text
+defaultCss textSize = T.pack $ printf
+  ("\n" <>
+   "text { font-family: Consolas, \"DejaVu Sans Mono\", monospace; font-size: %dpx }\n" <>
+   ".dashed_elem { stroke-dasharray: 4, 3 }\n" <>
+   ".filled_shape { fill: url(#shape_light); stroke: black; stroke-width: 1px; }\n" <>
+   ".line_element { fill: none; stroke: black; stroke-width: 1px; }\n" <>
+   ".bullet { stroke-width: 1px; fill: white; stroke: black }\n" <>
+   ".arrow_head { fill: black; stroke: none; }\n"
+  )
+  (2 + floor textSize :: Int)
+
+defaultCssRules :: Float -> [Css.CssRule]
+defaultCssRules = cssRulesOfText . defaultCss
+
+lightShapeGradient :: Svg.Element
+lightShapeGradient = Svg.ElementLinearGradient $
+    Svg.defaultSvg
+        { Svg._linearGradientStart = (Svg.Percent 0, Svg.Percent 0)
+        , Svg._linearGradientStop =  (Svg.Percent 0, Svg.Percent 1)
+        , Svg._linearGradientStops =
+            [ Svg.GradientStop 0 $ PixelRGBA8 245 245 245 255
+            , Svg.GradientStop 1 $ PixelRGBA8 216 216 216 255
+            ]
+        }
+
+toSymbol :: Double -> Double -> [Svg.Tree] -> Svg.Element
+toSymbol width height geom = element where
+  element = Svg.ElementGeometry $ Svg.SymbolTree tree
+  tree = Svg.Symbol $ execState build Svg.defaultSvg
+
+  build = do
+    Svg.groupChildren .= geom
+    Svg.groupViewBox .= Just (0, 0, width, height)
+    Svg.groupAspectRatio . Svg.aspectRatioAlign .= Svg.AlignNone
+
+asFilled :: (Svg.WithDrawAttributes a) => a -> a
+asFilled el = el & drawAttr.attrClass .~ ["filled_shape"]
+
+defaultCircle :: Svg.Element
+defaultCircle = toSymbol 50 50 [Svg.CircleTree $ asFilled circle] where
+  circle = Svg.defaultSvg
+    { Svg._circleCenter = (Css.Num 25, Css.Num 25)
+    , Svg._circleRadius = Css.Num 24.5
+    }
+
+h, v :: [Svg.Coord] -> Svg.PathCommand
+h = Svg.HorizontalTo Svg.OriginRelative
+v = Svg.VerticalTo Svg.OriginRelative
+
+m :: [Svg.RPoint] -> Svg.PathCommand
+m = Svg.MoveTo Svg.OriginRelative
+
+c :: [(Svg.RPoint, Svg.RPoint, Svg.RPoint)] -> Svg.PathCommand
+c = Svg.CurveTo Svg.OriginRelative
+
+l :: [Svg.RPoint] -> Svg.PathCommand
+l = Svg.LineTo Svg.OriginRelative
+
+z :: Svg.PathCommand
+z = Svg.EndPath
+
+defaultDocument :: Svg.Element
+defaultDocument = toSymbol 51 51 [Svg.PathTree $ asFilled path] where
+  path = Svg.defaultSvg
+    { Svg._pathDefinition =
+        [ m [V2 49.98 0.79, V2 (-49.166) 0, V2 0 45.402]
+        , c [(V2 15.92 12.45, V2 30.40 (-13.44), V2 49.17 0)]
+        , z
+        ]
+    }
+
+ioShape :: Svg.Element
+ioShape = toSymbol 100 100 [Svg.PathTree $ asFilled path] where
+  path = Svg.defaultSvg
+    { Svg._pathDefinition =
+        [ m [V2 19.207 1.6]
+        , h [79.414]
+        , l [V2 (-17.192) 97.297]
+        , h [-79.414]
+        , z
+        ]
+    }
+
+storageShape :: Svg.Element
+storageShape = toSymbol 80 80 geometry where
+  geometry = Svg.PathTree . asFilled <$> [path1, path2]
+  path1 = Svg.defaultSvg
+    { Svg._pathDefinition =
+        [ m [V2 4.8122 67.74]
+        , v [-53.769]
+        , c [ (V2 0.0 (-3.2991) , V2 16.067 (-5.9743), V2 35.845 (-5.9743))
+            , (V2 19.78 0.0, V2 35.848 2.6752, V2 35.848 5.9743)
+            ]
+       , v [53.769]
+       , c [(V2 0.0 3.2925, V2 (-16.068) 5.9743, V2 (-35.848) 5.9743)
+           , (V2 (-19.779) 0.0, V2 (-35.845) (-2.6818), V2 (-35.845) (-5.9743))
+           ]
+        , z
+        ]
+    }
+  path2 = Svg.defaultSvg
+    { Svg._pathDefinition =
+        [ m [ V2 4.8122 13.97, V2 4.779e-2 0.30672, V2 0.13807 0.30272
+            , V2 0.22834 0.29872, V2 0.31464 0.29344, V2 0.40094 0.28944
+            , V2 0.48325 0.2828, V2 0.56423 0.27744, V2 0.64256 0.2708
+            , V2 0.71823 0.26416, V2 0.79258 0.25752, V2 0.86294 0.25096
+            , V2 0.9333 0.2416, V2 0.99968 0.23496, V2 1.0647 0.22568
+            , V2 1.1271 0.2164, V2 1.1869 0.2084, V2 1.2453 0.19784
+            , V2 1.301 0.1872, V2 1.3555 0.17792, V2 1.4046 0.16728
+            , V2 1.455 0.15536, V2 1.5002 0.14336, V2 1.5466 0.1328
+            , V2 1.5865 0.11952, V2 1.6276 0.10752, V2 1.6648 9.42e-2
+            , V2 1.7007 8.1e-2, V2 1.7338 6.64e-2, V2 1.7644 5.31e-2
+            , V2 1.7923 3.72e-2, V2 1.8188 2.39e-2, V2 1.8427 8.0e-3
+            ]
+        , c [(V2 19.78 0.0, V2 35.848 (-2.6818), V2 35.848 (-5.9743))]
+        ]
+    }
+
+defaultDefinitions :: M.Map String Svg.Element
+defaultDefinitions = M.fromList
+  [ ("shape_light", lightShapeGradient)
+  , ("circle", defaultCircle)
+  , ("document", defaultDocument)
+  , ("io", ioShape)
+  , ("storage", storageShape)
+  ]
+
diff --git a/src/Text/AsciiDiagram/Geometry.hs b/src/Text/AsciiDiagram/Geometry.hs
--- a/src/Text/AsciiDiagram/Geometry.hs
+++ b/src/Text/AsciiDiagram/Geometry.hs
@@ -1,125 +1,132 @@
-{-# LANGUAGE CPP #-}
--- | Defines the geometry extracted from the asciidiagram.
-module Text.AsciiDiagram.Geometry( Point
-                                 , Vector
-                                 , Anchor( .. )
-                                 , Shape( .. )
-                                 , Segment( .. )
-                                 , SegmentDraw( .. )
-                                 , SegmentKind( .. )
-                                 , ShapeElement( .. )
-                                 , Diagram( .. )
-                                 , TextZone( .. )
-                                 ) where
-
-#if !MIN_VERSION_base(4,8,0)
-import Data.Monoid( Monoid( mappend, mempty ))
-#endif
-
-import qualified Data.Set as S
-import qualified Data.Text as T
-import Linear( V2( .. ) )
-
--- | Position of a an element in the character grids
-type Point = V2 Int
-
--- | Direction in the character grid.
-type Vector = V2 Int
-
--- | Describe the geomtry of a full Ascii Diagram
--- document
-data Diagram = Diagram
-  { -- | All the extracted tshapes
-    _diagramShapes     :: S.Set Shape
-    -- | All the extracted text zones
-  , _diagramTexts      :: [TextZone]
-    -- | Width in characters of the document
-  , _diagramCellWidth  :: !Int
-    -- | Height in characters of the document
-  , _diagramCellHeight :: !Int
-    -- | CSS styles associated to the document.
-  , _diagramStyles     :: [T.Text]
-  }
-  deriving (Eq, Show)
-
--- | Describe where to place a text snippet.
-data TextZone = TextZone
-  { _textZoneOrigin  :: Point
-  , _textZoneContent :: T.Text
-  }
-  deriving (Eq, Show)
-
--- | Define the different connection points
--- between the segments.
-data Anchor
-  = AnchorMulti       -- ^ Associated to '+'
-  | AnchorFirstDiag   -- ^ Associated to '/'
-  | AnchorSecondDiag  -- ^ Associated to '\'
-
-  | AnchorPoint       -- ^ Kind of "end anchor", without continuation.
-  | AnchorBullet      -- ^ Used as a '*'
-
-  | AnchorArrowUp     -- ^ Associated to '^'
-  | AnchorArrowDown   -- ^ Associated to 'V'
-  | AnchorArrowLeft   -- ^ Associated to '<'
-  | AnchorArrowRight  -- ^ Associated to '>'
-  deriving (Eq, Ord, Show)
-
--- | Helper data for segment composed of only
--- one character
-data SegmentKind
-  = SegmentHorizontal
-  | SegmentVertical
-  deriving (Eq, Ord, Show)
-
--- | Differentiate between elements drawn with a
--- solid line or with dashed lines.
-data SegmentDraw
-  = SegmentSolid
-  | SegmentDashed
-  deriving (Eq, Ord, Show)
-
--- | Define an horizontal or vertical segment.
-data Segment = Segment
-  { _segStart :: {-# UNPACK #-} !Point
-  , _segEnd   :: {-# UNPACK #-} !Point
-  , _segKind  :: !SegmentKind
-  , _segDraw  :: !SegmentDraw
-  }
-  deriving (Eq, Ord)
-
-instance Show Segment where
-    showsPrec d (Segment s e k dr) =
-      showParen (d >= 10) $
-          showString "Segment " . start . end . kind . (' ':) . draw
-      where
-        start = showParen True $ shows s
-        end = showParen True $ shows e
-        kind = shows k
-        draw = shows dr
-
-instance Monoid Segment where
-    mempty = Segment 0 0 SegmentVertical SegmentSolid
-    mappend (Segment a _ _ _) (Segment _ b k d) =
-        Segment a b k d
-
--- | Describe a composant of shapes. Can
--- be composed of anchors like "+*/\\" or
--- segments.
-data ShapeElement
-  = ShapeAnchor !Point !Anchor
-  | ShapeSegment !Segment
-  deriving (Eq, Ord, Show)
-
--- | Shape extracted from the text
-data Shape = Shape
-  { -- | Elements composing the shape.
-    shapeElements :: [ShapeElement]
-    -- | When False it's just lines possibly with
-    -- an arrow, when True it's a polygon.
-  , shapeIsClosed :: Bool
-    -- | Tags "{tagname}" placed inside the shape.
-  , shapeTags     :: S.Set T.Text
-  }
-  deriving (Eq, Ord, Show)
-
+{-# LANGUAGE CPP #-}
+-- | Defines the geometry extracted from the asciidiagram.
+module Text.AsciiDiagram.Geometry( Point
+                                 , Vector
+                                 , Anchor( .. )
+                                 , Shape( .. )
+                                 , Element( .. )
+                                 , Segment( .. )
+                                 , SegmentDraw( .. )
+                                 , SegmentKind( .. )
+                                 , ShapeElement( .. )
+                                 , Diagram( .. )
+                                 , TextZone( .. )
+                                 ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid( Monoid( mappend, mempty ))
+#endif
+
+import qualified Data.Set as S
+import qualified Data.Text as T
+import Linear( V2( .. ) )
+
+-- | Position of a an element in the character grids
+type Point = V2 Int
+
+-- | Direction in the character grid.
+type Vector = V2 Int
+
+-- | Describe the geomtry of a full Ascii Diagram
+-- document
+data Diagram = Diagram
+  { -- | All the extracted tshapes
+    _diagramElements   :: S.Set Element
+    -- | Width in characters of the document
+  , _diagramCellWidth  :: !Int
+    -- | Height in characters of the document
+  , _diagramCellHeight :: !Int
+    -- | CSS styles associated to the document.
+  , _diagramStyles     :: [T.Text]
+  }
+  deriving (Eq, Show)
+
+-- | Describe where to place a text snippet.
+data TextZone = TextZone
+  { _textZoneOrigin  :: Point
+  , _textZoneContent :: T.Text
+  }
+  deriving (Eq, Ord, Show)
+
+-- | Define the different connection points
+-- between the segments.
+data Anchor
+  = AnchorMulti       -- ^ Associated to '+'
+  | AnchorFirstDiag   -- ^ Associated to '/'
+  | AnchorSecondDiag  -- ^ Associated to '\'
+
+  | AnchorPoint       -- ^ Kind of "end anchor", without continuation.
+  | AnchorBullet      -- ^ Used as a '*'
+
+  | AnchorArrowUp     -- ^ Associated to '^'
+  | AnchorArrowDown   -- ^ Associated to 'V'
+  | AnchorArrowLeft   -- ^ Associated to '<'
+  | AnchorArrowRight  -- ^ Associated to '>'
+  deriving (Eq, Ord, Show)
+
+-- | Helper data for segment composed of only
+-- one character
+data SegmentKind
+  = SegmentHorizontal
+  | SegmentVertical
+  deriving (Eq, Ord, Show)
+
+-- | Differentiate between elements drawn with a
+-- solid line or with dashed lines.
+data SegmentDraw
+  = SegmentSolid
+  | SegmentDashed
+  deriving (Eq, Ord, Show)
+
+-- | Define an horizontal or vertical segment.
+data Segment = Segment
+  { _segStart :: {-# UNPACK #-} !Point
+  , _segEnd   :: {-# UNPACK #-} !Point
+  , _segKind  :: !SegmentKind
+  , _segDraw  :: !SegmentDraw
+  }
+  deriving (Eq, Ord)
+
+instance Show Segment where
+    showsPrec d (Segment s e k dr) =
+      showParen (d >= 10) $
+          showString "Segment " . start . end . kind . (' ':) . draw
+      where
+        start = showParen True $ shows s
+        end = showParen True $ shows e
+        kind = shows k
+        draw = shows dr
+
+instance Monoid Segment where
+    mempty = Segment 0 0 SegmentVertical SegmentSolid
+    mappend (Segment a _ _ _) (Segment _ b k d) =
+        Segment a b k d
+
+-- | Describe a composant of shapes. Can
+-- be composed of anchors like "+*/\\" or
+-- segments.
+data ShapeElement
+  = ShapeAnchor !Point !Anchor
+  | ShapeSegment !Segment
+  deriving (Eq, Ord, Show)
+
+-- | Shape extracted from the text
+data Shape = Shape
+  { -- | Elements composing the shape.
+    shapeElements :: ![ShapeElement]
+    -- | When False it's just lines possibly with
+    -- an arrow, when True it's a polygon.
+  , shapeIsClosed :: !Bool
+    -- | Tags "{tagname}" placed inside the shape.
+  , shapeTags        :: !(S.Set T.Text)
+
+  , shapeChildren    :: ![Element]
+  }
+  deriving (Eq, Ord, Show)
+
+-- | Define an element to be drawn.
+data Element
+  = ElemText  !TextZone
+  | ElemShape !Shape
+  deriving (Eq, Show, Ord)
+
diff --git a/src/Text/AsciiDiagram/Reconstructor.hs b/src/Text/AsciiDiagram/Reconstructor.hs
--- a/src/Text/AsciiDiagram/Reconstructor.hs
+++ b/src/Text/AsciiDiagram/Reconstructor.hs
@@ -260,7 +260,7 @@
             . fmap (`M.lookup` _vertices graph)
 
     toFilaments shapes =
-      [Shape piece False mempty | piece <- breakFilaments $ toElems shapes] 
+      [Shape piece False mempty mempty | piece <- breakFilaments $ toElems shapes] 
 
-    toShapes shapes = Shape (toElems shapes) True mempty
+    toShapes shapes = Shape (toElems shapes) True mempty mempty
 
diff --git a/src/Text/AsciiDiagram/SvgRender.hs b/src/Text/AsciiDiagram/SvgRender.hs
--- a/src/Text/AsciiDiagram/SvgRender.hs
+++ b/src/Text/AsciiDiagram/SvgRender.hs
@@ -1,32 +1,31 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
-module Text.AsciiDiagram.SvgRender( GridSize( .. )
-                                  , defaultGridSize
-                                  , svgOfDiagram
-                                  , svgOfDiagramAtSize
-                                  ) where
+module Text.AsciiDiagram.SvgRender
+    ( GridSize( .. )
+    , defaultGridSize
+    , svgOfDiagram
+    , svgOfDiagramAtSize
+    , defaultLibrary
+    ) where
 
 #if !MIN_VERSION_base(4,8,0)
 import Data.Monoid( mempty )
 import Control.Applicative( (<$>) )
 #endif
 
+import Data.Monoid( (<>) )
 import Control.Monad.State.Strict( execState )
-import Data.Monoid( Last( .. ), (<>) )
 
 import Graphics.Svg.Types
                    ( HasDrawAttributes( .. )
-                   , Texture( ColorRef )
                    , Document( .. )
                    , drawAttr )
 import Graphics.Svg( cssRulesOfText )
 
-import Codec.Picture( PixelRGBA8( PixelRGBA8 ) )
 import qualified Graphics.Svg.Types as Svg
-import qualified Data.Map as M
+import qualified Graphics.Svg.CssTypes as Css
 import qualified Data.Set as S
 import qualified Data.Text as T
-import Text.Printf
 import Linear( V2( .. )
              , (^+^)
              , (^-^)
@@ -34,10 +33,12 @@
              , perp
              , normalize
              )
-import Control.Lens( zoom, (.=), (%=), (%~), (&) )
+import Control.Lens( zoom, (^.), (.=), (%=), (%~), (&) )
 
-import Text.AsciiDiagram.Geometry
+import Text.AsciiDiagram.BoundingBoxEstimation
+import Text.AsciiDiagram.DefaultContext
 import Text.AsciiDiagram.DiagramCleaner
+import Text.AsciiDiagram.Geometry
 
 {-import Debug.Trace-}
 {-import Text.Groom-}
@@ -78,39 +79,24 @@
   isDashed (ShapeSegment Segment { _segDraw = SegmentDashed }) = True
 
 applyDefaultShapeDrawAttr :: (Svg.WithDrawAttributes a) => a -> a
-applyDefaultShapeDrawAttr = execState . zoom drawAttr $ do
-    strokeColor .= toLC 0 0 0 255
-    attrClass %= ("filled_shape":) 
-    strokeWidth .= toL (Svg.Num 1)
-  where
-    toL = Last . Just
-    toLC r g b a =
-        toL . ColorRef $ PixelRGBA8 r g b a
+applyDefaultShapeDrawAttr el =
+  el & drawAttr.attrClass %~ ("filled_shape":) 
 
 applyLineArrowDrawAttr :: (Svg.WithDrawAttributes a) => a -> a
-applyLineArrowDrawAttr = execState . zoom drawAttr $ do
-    fillColor .= toLC 0 0 0 255
-    strokeColor .= toL Svg.FillNone
-    strokeWidth .= toL (Svg.Num 0)
-  where
-    toL = Last . Just
-    toLC r g b a =
-        toL . ColorRef $ PixelRGBA8 r g b a
+applyLineArrowDrawAttr el =
+  el & drawAttr.attrClass %~ ("arrow_head":)
 
 applyBulletDrawAttr :: (Svg.WithDrawAttributes a) => a -> a
-applyBulletDrawAttr = execState . zoom drawAttr $ do
-    attrClass %= ("bullet":)
+applyBulletDrawAttr el =
+  el & drawAttr.attrClass %~ ("bullet":)
 
+cleanupUseAttributes ::  (Svg.WithDrawAttributes a) => a -> a
+cleanupUseAttributes = execState . zoom drawAttr $ do
+  attrClass .= []
+
 applyDefaultLineDrawAttr :: (Svg.WithDrawAttributes a) => a -> a
-applyDefaultLineDrawAttr = execState . zoom drawAttr $ do
-    attrClass %= ("line_element":)
-    fillColor .= toL Svg.FillNone
-    strokeColor .= toLC 0 0 0 255
-    strokeWidth .= toL (Svg.Num 1)
-  where
-    toL = Last . Just
-    toLC r g b a =
-        toL . ColorRef $ PixelRGBA8 r g b a
+applyDefaultLineDrawAttr el =
+  el & drawAttr.attrClass %~ ("line_element":)
 
 
 startPointOf :: ShapeElement -> Point
@@ -448,70 +434,101 @@
     V2 x y = toSvg gscale (_textZoneOrigin zone) ^+^ correction
     txt = Svg.textAt (Svg.Num (x+0.5), Svg.Num (y+0.5)) $ _textZoneContent zone
 
-defaultCss :: Float -> T.Text
-defaultCss textSize = T.pack $ printf
-  ("\n" <>
-   "text { font-family: Consolas, \"DejaVu Sans Mono\", monospace; font-size: %dpx }\n" <>
-   ".dashed_elem { stroke-dasharray: 4, 3 }\n" <>
-   ".filled_shape { fill: url(#shape_light) }\n" <>
-   ".bullet { stroke-width: 1px; fill: white; stroke: black }\n"
-  )
-  (2 + floor textSize :: Int)
 
-lightShapeGradient :: Svg.Element
-lightShapeGradient = Svg.ElementLinearGradient $
-    Svg.defaultSvg
-        { Svg._linearGradientStart = (Svg.Percent 0, Svg.Percent 0)
-        , Svg._linearGradientStop =  (Svg.Percent 0, Svg.Percent 1)
-        , Svg._linearGradientStops =
-            [ Svg.GradientStop 0 $ PixelRGBA8 245 245 245 255
-            , Svg.GradientStop 1 $ PixelRGBA8 216 216 216 255
-            ]
-        }
-
 -- | Transform an Ascii diagram to a SVG document which
 -- can be saved or converted to an image.
 svgOfDiagram :: Diagram -> Svg.Document
-svgOfDiagram = svgOfDiagramAtSize defaultGridSize where
+svgOfDiagram =
+    svgOfDiagramAtSize defaultGridSize (defaultLibrary defaultGridSize)
 
+svgOfShape :: GridSize -> Shape -> Svg.Tree
+svgOfShape scale shape
+  | shapeIsClosed shape =
+      applyDefaultShapeDrawAttr $ shapeToTree scale shape
+  | otherwise =
+      applyDefaultLineDrawAttr $ shapeToTree strokeScale shape
+  where
+    strokeScale = scale { _gridShapeContraction = 0 }
+
+
+svgOfElement :: GridSize -> Element -> Svg.Tree
+svgOfElement scale (ElemText txt) = textToTree scale txt
+svgOfElement scale (ElemShape shape) = 
+  case shapeChildren shape of
+    [] -> svgOfShape scale shape
+    _:_ -> Svg.GroupTree $ group
+  where
+    thisShape = svgOfShape scale shape
+    group = Svg.defaultSvg
+      { Svg._groupDrawAttributes =
+          mempty { Svg._attrClass = S.toList $ shapeTags shape }
+      , Svg._groupChildren =
+          thisShape : fmap (svgOfElement scale) (shapeChildren shape)
+      , Svg._groupViewBox = Nothing
+      }
+
+shapeRewriter :: [Css.CssRule] -> Svg.Tree -> Svg.Tree
+shapeRewriter rules = Svg.zipTree go where
+  go [] = Svg.None
+  go ([]:_) = Svg.None
+  go context@((t:_):_) = case reverse shapeDeclarations of
+      [] -> t
+      (([Css.CssIdent i]:_): _) -> Svg.UseTree (useInfo i) Nothing
+      _ -> t
+   where
+     useInfo name = cleanupUseAttributes $ Svg.Use
+        { Svg._useDrawAttributes = t ^. Svg.drawAttr
+        , Svg._useBase = (Css.Num x, Css.Num y)
+        , Svg._useName = T.unpack name
+        , Svg._useWidth = Just (Css.Num w)
+        , Svg._useHeight = Just (Css.Num h)
+        }
+
+     BoundingBox pMin@(V2 x y) pMax = boundingBoxOf t
+     V2 w h = pMax ^-^ pMin
+
+     shapeDeclarations = 
+        [el | Css.CssDeclaration "shape" el <- Css.findMatchingDeclarations rules context]
+
 -- | Transform an Ascii diagram to a SVG document which
 -- can be saved or converted to an image, with a customizable
 -- grid size.
-svgOfDiagramAtSize :: GridSize -> Diagram -> Svg.Document
-svgOfDiagramAtSize scale diagram = Document
+svgOfDiagramAtSize :: GridSize -> Svg.Document -> Diagram -> Svg.Document
+svgOfDiagramAtSize scale style diagram = Document
   { _viewBox = Nothing
   , _width =
       toSvgSize _gridCellWidth $ _diagramCellWidth diagram + 1
   , _height =
       toSvgSize _gridCellHeight $ _diagramCellHeight diagram + 1
-  , _elements = closedSvg ++ lineSvg ++ textSvg
-  , _definitions = M.fromList
-        [("shape_light", lightShapeGradient)]
+  , _elements =
+      shapeRewriter allRules . svgOfElement scale <$> shapes
+  , _definitions = _definitions style
   , _description = ""
-  , _styleRules = defaultCssRules ++ customCssRules
+  , _styleRules = allRules
   , _documentLocation = ""
   }
   where
-    (closed, opened) = S.partition shapeIsClosed shapes
-
-    defaultCssRules =
-      cssRulesOfText . defaultCss $ _gridCellHeight scale
-
+    allRules = _styleRules style <> customCssRules
     customCssRules = 
       cssRulesOfText . T.unlines $ _diagramStyles diagram
 
-    shapes = _diagramShapes diagram
-
-    closedSvg =
-        applyDefaultShapeDrawAttr . shapeToTree scale <$> filter isShapePossible
-                                                            (S.toList closed)
-    lineSvg =
-        applyDefaultLineDrawAttr . shapeToTree strokeScale <$> S.toList opened
+    isDrawable (ElemText _) = True
+    isDrawable (ElemShape shape) =
+      not (shapeIsClosed shape) || isShapePossible shape
+    shapes = filter isDrawable . S.toList $ _diagramElements diagram
 
     toSvgSize accessor var =
         Just . Svg.Num . realToFrac $ fromIntegral var * accessor scale + 5
 
-    textSvg = textToTree scale <$> _diagramTexts diagram
-
-    strokeScale = scale { _gridShapeContraction = 0 }
+defaultLibrary :: GridSize -> Svg.Document
+defaultLibrary size = Document
+  { _viewBox = Nothing
+  , _width = Nothing
+  , _height = Nothing
+  , _elements =  []
+  , _definitions = defaultDefinitions
+  , _description = ""
+  , _styleRules = defaultCssRules $ _gridCellHeight size
+  , _documentLocation = ""
+  }
 
