Browse Source

reorganized and update user guide

Gilbert Brault 5 years ago
parent
commit
358143743b

+ 4 - 1
doc/design/readme.md

@@ -11,4 +11,7 @@
 
    In a point of time, we need to verify the syntax of yaml sketch definition, here are some parser which might help
    
-   - Paul McGuire [pyparsing](https://github.com/pyparsing/pyparsing)
+   - Paul McGuire [pyparsing](https://github.com/pyparsing/pyparsing)
+
+   in fact this is solved (an now implemented this summer 8/5/2020) with the ast module
+   see the function sketchParse in the shapes.py module

+ 46 - 21
jupysketch-doc/docs/learningbyexample.md

@@ -51,23 +51,33 @@ The general layout of a sketcher file is as follow:
         * One mandatory action is the setting of the drawing frame (drawing_tool.set_coordinate_system): it must be declared before any other pysketcher object is used.
         * Other use case of action is the setting of global parameters like default line color: (drawing_tool.set_linecolor('black')) for example
     * this is stored in the head string thereafter
+    * The example uses the following objects
+        * libraries: setting the libraries used for this sketch
+        * constants: all the sketch dimensionning data
+        * frame: all the shapes or geometric objects which will be used by the other shapes
 * **Sketcher Objects**
     * Usually starting with the declaration of Pysketcher leaf objects (Geometry object like Line, Circle, Rectangle...)
     * May be aggregated using the composition object
     * Composition can be made of composition object (recursive behaviour)
     * Grouping leafs and composition will be further used to apply transformation latter on (based on the "physics")
-    * The example presents three group of objects
+    * The example uese three group of shapes
         * The body object
         * The plan object
         * The friction main object
     * The plan includes the body
     * The friction includes the plan (that will be able to rotate as a group) and the ground (will stay fixed)
 
-#### Libraries, Construction Variables, Frame
+#### Libraries
 ```python
-head = """\
-libraries: ["from math import tan, radians, sin, cos","from pysketcher import *"]
-fontsize: 18
+libraries = {'name': "head",
+'shapes':"""\
+libraries: ["from math import tan, radians, sin, cos","from pysketcher import *"]"""}
+```
+#### Constants: Construction parameters
+```python
+constants = {'name': "constants",
+'shapes':"""\
+fontsize: 18         # size of the characters
 g: 9.81              # constant gravity
 theta: 30.0          # inclined plane angle
 L: 10.0              # sketch sizing parameter
@@ -76,6 +86,12 @@ xmin: 0.0            # sketech min Abscissa
 ymin: -3.0           # sketech min Ordinate     
 rl: 2.0              # rectangle width
 rL: 1.0              # rectangle length
+"""}
+```
+#### Frame: core geometric parameters
+```python
+frame = {'name': "frame",
+'shapes':"""\
 setframe:            # sketch setup
     action: "drawing_tool.set_coordinate_system(xmin=xmin-L/5, xmax=xmin+1.5*L,ymin=ymin, ymax=ymin+1.5*L,instruction_file='tmp_mpl_friction.py')"
 setblackline:        # default frame values and actions
@@ -85,15 +101,16 @@ A: point(a,tan(radians(theta))*L)    # wall left end
 normal_vec: point(sin(radians(theta)),cos(radians(theta)))     # Vector normal to wall
 tangent_vec: point(cos(radians(theta)),-sin(radians(theta)))   # Vector tangent to wall
 help_line: Line(A,B)                 # wall line
-x: a + 3*L/10.
-y: help_line(x=x)    
-contact: point(x, y)    
+x: a + 3*L/10.                       # contact point Abscissa
+y: help_line(x=x)                    # contact point Ordinate
+contact: point(x, y)                 # contact point: middle of the rectangle bottom edge
 c: contact + rL/2*normal_vec
-"""
+"""}
 ```
 #### The body object
 ```python
-body="""\
+body={'name': "body",
+'shapes':"""\
 rectangle: 
     formula: Rectangle(contact, rl, rL)
     style:
@@ -115,11 +132,12 @@ body:
     formula: "Composition({'wheel': wheel, 'N': N, 'mc': mc})"
     style:
         linecolor: black
-"""
+"""}
 ```
 #### The plan object
 ```python
-plan="""\
+plan={'name': "plan",
+'shapes':"""\
 mB:
     formula: Text(r'$B$',B)
 mA:
@@ -137,11 +155,12 @@ x_axis:
     formula: "Axis(start=contact+ 2*rl*normal_vec, length=2*rl,label='$x$', rotation_angle=-theta)"
 plan: 
     formula: "Composition({'body': body, 'inclined wall': wall, 'x start': x_const, 'x axis': x_axis, 'mA': mA, 'mB': mB})"
-"""
+"""}
 ```
 #### The friction sketch
 ```python
-friction="""\
+friction={'name': "friction",
+'shapes':"""\
 mg: 
     formula: Gravity(c, rl, text='$Mg$')
     style:
@@ -159,22 +178,28 @@ ground:
          linewidth: 1
 friction: 
     formula: "Composition({'plan': plan, 'ground': ground, 'mg': mg, 'angle': angle})"
-"""
+"""}
 ```
 
 ### Using the parser
 
 To parse the above example, the following code do the job.
-1. the head must be used first as all the other bits needs one or more variable it defines.
-2. After, any other string can be parsed, the order just need to respect precedence (if one object uses another one it must be parsed after)
+
+1. libraries, constants and frame must be used first as all the other bits needs one or more variable they defines.
+2. After, any other sketch can be parsed, the order just need to respect precedence (if one object uses another it must be parsed after)
 3. this setting allows naturally a modular definition of sketch objects
 
+The parser checks for syntax precedence and warns of any detected error.
+
 ```python
 myfig = {}
-sketchParse(head,myfig)
-sketchParse(body,myfig)
-sketchParse(plan,myfig)
-sketchParse(friction,myfig)
+if sketchParse(libraries,myfig):
+    if sketchParse(constants,myfig):
+        if sketchParse(frame,myfig):
+            if sketchParse(body,myfig):
+                if sketchParse(plan,myfig):
+                    if sketchParse(friction,myfig):
+                        print("success")
 ```
 
 ### "friction" sketch hierarchy

File diff suppressed because it is too large
+ 556 - 61
jupysketch-doc/docs/resources/DryFriction.html


File diff suppressed because it is too large
+ 526 - 63
jupysketch-doc/docs/resources/DryFriction.ipynb


+ 82 - 27
jupysketch-doc/site/learningbyexample/index.html

@@ -255,8 +255,22 @@
       <ul class="md-nav__list">
         
           <li class="md-nav__item">
-  <a href="#libraries-construction-variables-frame" class="md-nav__link">
-    Libraries, Construction Variables, Frame
+  <a href="#libraries" class="md-nav__link">
+    Libraries
+  </a>
+  
+</li>
+        
+          <li class="md-nav__item">
+  <a href="#constants-construction-parameters" class="md-nav__link">
+    Constants: Construction parameters
+  </a>
+  
+</li>
+        
+          <li class="md-nav__item">
+  <a href="#frame-core-geometric-parameters" class="md-nav__link">
+    Frame: core geometric parameters
   </a>
   
 </li>
@@ -386,8 +400,22 @@
       <ul class="md-nav__list">
         
           <li class="md-nav__item">
-  <a href="#libraries-construction-variables-frame" class="md-nav__link">
-    Libraries, Construction Variables, Frame
+  <a href="#libraries" class="md-nav__link">
+    Libraries
+  </a>
+  
+</li>
+        
+          <li class="md-nav__item">
+  <a href="#constants-construction-parameters" class="md-nav__link">
+    Constants: Construction parameters
+  </a>
+  
+</li>
+        
+          <li class="md-nav__item">
+  <a href="#frame-core-geometric-parameters" class="md-nav__link">
+    Frame: core geometric parameters
   </a>
   
 </li>
@@ -501,6 +529,12 @@ A skertcher object is composed as follow:</p>
 </ul>
 </li>
 <li>this is stored in the head string thereafter</li>
+<li>The example uses the following objects<ul>
+<li>libraries: setting the libraries used for this sketch</li>
+<li>constants: all the sketch dimensionning data</li>
+<li>frame: all the shapes or geometric objects which will be used by the other shapes</li>
+</ul>
+</li>
 </ul>
 </li>
 <li><strong>Sketcher Objects</strong><ul>
@@ -508,7 +542,7 @@ A skertcher object is composed as follow:</p>
 <li>May be aggregated using the composition object</li>
 <li>Composition can be made of composition object (recursive behaviour)</li>
 <li>Grouping leafs and composition will be further used to apply transformation latter on (based on the "physics")</li>
-<li>The example presents three group of objects<ul>
+<li>The example uese three group of shapes<ul>
 <li>The body object</li>
 <li>The plan object</li>
 <li>The friction main object</li>
@@ -519,10 +553,16 @@ A skertcher object is composed as follow:</p>
 </ul>
 </li>
 </ul>
-<h4 id="libraries-construction-variables-frame">Libraries, Construction Variables, Frame</h4>
-<pre><code class="python">head = &quot;&quot;&quot;\
-libraries: [&quot;from math import tan, radians, sin, cos&quot;,&quot;from pysketcher import *&quot;]
-fontsize: 18
+<h4 id="libraries">Libraries</h4>
+<pre><code class="python">libraries = {'name': &quot;head&quot;,
+'shapes':&quot;&quot;&quot;\
+libraries: [&quot;from math import tan, radians, sin, cos&quot;,&quot;from pysketcher import *&quot;]&quot;&quot;&quot;}
+</code></pre>
+
+<h4 id="constants-construction-parameters">Constants: Construction parameters</h4>
+<pre><code class="python">constants = {'name': &quot;constants&quot;,
+'shapes':&quot;&quot;&quot;\
+fontsize: 18         # size of the characters
 g: 9.81              # constant gravity
 theta: 30.0          # inclined plane angle
 L: 10.0              # sketch sizing parameter
@@ -531,6 +571,12 @@ xmin: 0.0            # sketech min Abscissa
 ymin: -3.0           # sketech min Ordinate     
 rl: 2.0              # rectangle width
 rL: 1.0              # rectangle length
+&quot;&quot;&quot;}
+</code></pre>
+
+<h4 id="frame-core-geometric-parameters">Frame: core geometric parameters</h4>
+<pre><code class="python">frame = {'name': &quot;frame&quot;,
+'shapes':&quot;&quot;&quot;\
 setframe:            # sketch setup
     action: &quot;drawing_tool.set_coordinate_system(xmin=xmin-L/5, xmax=xmin+1.5*L,ymin=ymin, ymax=ymin+1.5*L,instruction_file='tmp_mpl_friction.py')&quot;
 setblackline:        # default frame values and actions
@@ -540,15 +586,16 @@ A: point(a,tan(radians(theta))*L)    # wall left end
 normal_vec: point(sin(radians(theta)),cos(radians(theta)))     # Vector normal to wall
 tangent_vec: point(cos(radians(theta)),-sin(radians(theta)))   # Vector tangent to wall
 help_line: Line(A,B)                 # wall line
-x: a + 3*L/10.
-y: help_line(x=x)    
-contact: point(x, y)    
+x: a + 3*L/10.                       # contact point Abscissa
+y: help_line(x=x)                    # contact point Ordinate
+contact: point(x, y)                 # contact point: middle of the rectangle bottom edge
 c: contact + rL/2*normal_vec
-&quot;&quot;&quot;
+&quot;&quot;&quot;}
 </code></pre>
 
 <h4 id="the-body-object">The body object</h4>
-<pre><code class="python">body=&quot;&quot;&quot;\
+<pre><code class="python">body={'name': &quot;body&quot;,
+'shapes':&quot;&quot;&quot;\
 rectangle: 
     formula: Rectangle(contact, rl, rL)
     style:
@@ -570,11 +617,12 @@ body:
     formula: &quot;Composition({'wheel': wheel, 'N': N, 'mc': mc})&quot;
     style:
         linecolor: black
-&quot;&quot;&quot;
+&quot;&quot;&quot;}
 </code></pre>
 
 <h4 id="the-plan-object">The plan object</h4>
-<pre><code class="python">plan=&quot;&quot;&quot;\
+<pre><code class="python">plan={'name': &quot;plan&quot;,
+'shapes':&quot;&quot;&quot;\
 mB:
     formula: Text(r'$B$',B)
 mA:
@@ -592,11 +640,12 @@ x_axis:
     formula: &quot;Axis(start=contact+ 2*rl*normal_vec, length=2*rl,label='$x$', rotation_angle=-theta)&quot;
 plan: 
     formula: &quot;Composition({'body': body, 'inclined wall': wall, 'x start': x_const, 'x axis': x_axis, 'mA': mA, 'mB': mB})&quot;
-&quot;&quot;&quot;
+&quot;&quot;&quot;}
 </code></pre>
 
 <h4 id="the-friction-sketch">The friction sketch</h4>
-<pre><code class="python">friction=&quot;&quot;&quot;\
+<pre><code class="python">friction={'name': &quot;friction&quot;,
+'shapes':&quot;&quot;&quot;\
 mg: 
     formula: Gravity(c, rl, text='$Mg$')
     style:
@@ -614,19 +663,25 @@ ground:
          linewidth: 1
 friction: 
     formula: &quot;Composition({'plan': plan, 'ground': ground, 'mg': mg, 'angle': angle})&quot;
-&quot;&quot;&quot;
+&quot;&quot;&quot;}
 </code></pre>
 
 <h3 id="using-the-parser">Using the parser</h3>
-<p>To parse the above example, the following code do the job.
-1. the head must be used first as all the other bits needs one or more variable it defines.
-2. After, any other string can be parsed, the order just need to respect precedence (if one object uses another one it must be parsed after)
-3. this setting allows naturally a modular definition of sketch objects</p>
+<p>To parse the above example, the following code do the job.</p>
+<ol>
+<li>libraries, constants and frame must be used first as all the other bits needs one or more variable they defines.</li>
+<li>After, any other sketch can be parsed, the order just need to respect precedence (if one object uses another it must be parsed after)</li>
+<li>this setting allows naturally a modular definition of sketch objects</li>
+</ol>
+<p>The parser checks for syntax precedence and warns of any detected error.</p>
 <pre><code class="python">myfig = {}
-sketchParse(head,myfig)
-sketchParse(body,myfig)
-sketchParse(plan,myfig)
-sketchParse(friction,myfig)
+if sketchParse(libraries,myfig):
+    if sketchParse(constants,myfig):
+        if sketchParse(frame,myfig):
+            if sketchParse(body,myfig):
+                if sketchParse(plan,myfig):
+                    if sketchParse(friction,myfig):
+                        print(&quot;success&quot;)
 </code></pre>
 
 <h3 id="friction-sketch-hierarchy">"friction" sketch hierarchy</h3>

File diff suppressed because it is too large
+ 556 - 61
jupysketch-doc/site/resources/DryFriction.html


File diff suppressed because it is too large
+ 526 - 63
jupysketch-doc/site/resources/DryFriction.ipynb


File diff suppressed because it is too large
+ 1 - 1
jupysketch-doc/site/search/search_index.json


+ 5 - 5
jupysketch-doc/site/sitemap.xml

@@ -1,23 +1,23 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url>
      <loc>None</loc>
-     <lastmod>2020-08-04</lastmod>
+     <lastmod>2020-08-05</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-08-04</lastmod>
+     <lastmod>2020-08-05</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-08-04</lastmod>
+     <lastmod>2020-08-05</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-08-04</lastmod>
+     <lastmod>2020-08-05</lastmod>
      <changefreq>daily</changefreq>
     </url><url>
      <loc>None</loc>
-     <lastmod>2020-08-04</lastmod>
+     <lastmod>2020-08-05</lastmod>
      <changefreq>daily</changefreq>
     </url>
 </urlset>

BIN
jupysketch-doc/site/sitemap.xml.gz


File diff suppressed because it is too large
+ 104 - 68
notebooks/.ipynb_checkpoints/DryFriction-checkpoint.ipynb


File diff suppressed because it is too large
+ 104 - 68
notebooks/DryFriction.ipynb


+ 14 - 21
notebooks/Reference.ipynb

@@ -177,7 +177,7 @@
     "line: Line(A,B)\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(line,myfig)\n",
+    "sketchParse(\"line\",myfig)\n",
     "# replace 'object' by the actual one\n",
     "d = myfig['line'].draw() \n",
     "drawing_tool.display()\n",
@@ -240,8 +240,7 @@
     "rectangle: Rectangle(p,L,h)\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(rectangle,myfig)\n",
-    "# replace 'object' by the actual one\n",
+    "sketchParse(\"rectangle\",myfig)\n",
     "d = myfig['rectangle'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -303,8 +302,7 @@
     "triangle: Triangle(p1=(W/2,0), p2=(3*W/2,W/2), p3=(4*W/5.,L))\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(triangle,myfig)\n",
-    "# replace 'object' by the actual one\n",
+    "sketchParse(\"triangle\",myfig)\n",
     "d = myfig['triangle'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -363,8 +361,7 @@
     "circle: Circle(point(0,0),5)\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(circle,myfig)\n",
-    "# replace 'object' by the actual one\n",
+    "sketchParse(\"circle\",myfig)\n",
     "d = myfig['circle'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -423,8 +420,7 @@
     "dwt: Distance_wText((-4,0), (8, 5), t, fontsize)\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(dwt,myfig)\n",
-    "# replace 'object' by the actual one\n",
+    "sketchParse(\"dwt\",myfig)\n",
     "d = myfig['dwt'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -483,7 +479,7 @@
     "text: Text(r'$c$', point(0,0))\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(text,myfig)\n",
+    "sketchParse(\"text\",myfig)\n",
     "# replace 'object' by the actual one\n",
     "d = myfig['text'].draw() \n",
     "drawing_tool.display()\n",
@@ -549,7 +545,7 @@
     "        linewidth: 1\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(cross,myfig)\n",
+    "sketchParse(\"cross\",myfig)\n",
     "d = myfig['cross'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -565,7 +561,7 @@
     "cross1: Cross(point(0,0))\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(cross1,myfig)\n",
+    "sketchParse(\"cross1\",myfig)\n",
     "d = myfig['cross1'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -622,8 +618,7 @@
     "axis: Axis((0,0), 5, 'x', rotation_angle=0)\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(axis,myfig)\n",
-    "# replace 'object' by the actual one\n",
+    "sketchParse(\"axis\",myfig)\n",
     "d = myfig['axis'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -684,7 +679,7 @@
     "arc_angle: angle\n",
     "arc: Arc(center, radius, start_angle, arc_angle)\n",
     "\"\"\"\n",
-    "sketchParse(arc,myfig)\n",
+    "sketchParse(\"arc\",myfig)\n",
     "d = myfig['arc'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -751,7 +746,7 @@
     "arc_wtxt: \"Arc_wText(r'$<bslash>theta$', center, radius, start_angle, arc_angle)\"\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(arc_wtxt,myfig)\n",
+    "sketchParse(\"arc_wtxt\",myfig)\n",
     "d = myfig['arc_wtxt'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -815,7 +810,7 @@
     "arrow1: Arrow1(start, end, style='<->')\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(arrow1,myfig)\n",
+    "sketchParse(\"arrow1\",myfig)\n",
     "d = myfig['arrow1'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -878,8 +873,7 @@
     "force: Force(contact - vector, contact, r'$Force$', text_pos='start')\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(force,myfig)\n",
-    "# replace 'object' by the actual one\n",
+    "sketchParse(\"force\",myfig)\n",
     "d = myfig['force'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"
@@ -947,8 +941,7 @@
     "        linecolor: black\n",
     "\"\"\"\n",
     "drawing_tool.erase()\n",
-    "sketchParse(wall,myfig)\n",
-    "# replace 'object' by the actual one\n",
+    "sketchParse(\"wall\",myfig)\n",
     "d = myfig['wall'].draw() \n",
     "drawing_tool.display()\n",
     "display(SVG(sketch2SVG()))"

BIN
notebooks/friction.png


BIN
notebooks/home.png


notebooks/Introduction.ipynb → notebooks/other examples/Introduction.ipynb


notebooks/Oscillator1.ipynb → notebooks/other examples/Oscillator1.ipynb


notebooks/beam1.ipynb → notebooks/other examples/beam1.ipynb


notebooks/beam2.ipynb → notebooks/other examples/beam2.ipynb


notebooks/fig.dot → notebooks/other examples/fig.dot


notebooks/fig.png → notebooks/other examples/fig.png


notebooks/fig1.png → notebooks/other examples/fig1.png


notebooks/flowovergaussian.ipynb → notebooks/other examples/flowovergaussian.ipynb


notebooks/pendulum1.ipynb → notebooks/other examples/pendulum1.ipynb


notebooks/svg_filter_pie.svg → notebooks/other examples/svg_filter_pie.svg


notebooks/testmatplotlib.ipynb → notebooks/other examples/testmatplotlib.ipynb


notebooks/wheelonInclinedPlane.ipynb → notebooks/other examples/wheelonInclinedPlane.ipynb


notebooks/yamlDesign.ipynb → notebooks/other examples/yamlDesign.ipynb


notebooks/yamlTest.ipynb → notebooks/other examples/yamlTest.ipynb


+ 50 - 17
pysketcher/shapes.py

@@ -32,45 +32,74 @@ def sketch2PNG():
     img = Image.open(f)
     return img
 
-def sVe(key, expression, container):
-    root = ast.parse(expression)
+def sVe(key, expression, container, sketch):
+    """
+    sVe: sketch Validate expression
+    given an expression from a sketch, check if valid or not
+    provides a string feedback if error else return 1
+    """
+    try:
+        root = ast.parse(expression)
+    except Exception as e:
+        return f"{sketch}/{key}: '''{expression}''' parse error {str(e)}"
     names = {node.id for node in ast.walk(root) if isinstance(node, ast.Name)}
     for name in names:
         if name not in container:
-            return f"in key {key}: {name} in {expression} is not defined"
+            return f"{sketch}/{key}: {name} in {expression} is not defined"
     return 1
 
 def sketchParse(sketch, container):
+    """
+    Parse a string sketch into a container.
+    name specifices the 'name' of the sketch
+    A container is a name space which holds 
+        - all the libraries references needed to create pysketcher shapes
+        - all the variable providing shapes dimensions or position
+        - all the shapes needed to create the shapes it defines
+    """
     yaml = YAML()
-    gwd = yaml.load(sketch)
+    gwd = yaml.load(sketch["shapes"])
+    
     for _k in list(gwd.keys()):
         if _k == "stop":
-            break
+            return True
         _c = gwd[_k]
         _t = str(type(_c))
         if _k == "libraries":
             for l in _c:
+                _r = sVe(_k, l, container, sketch["name"])
+                if type(_r) == str:
+                    print(_r)
+                    return False
                 exec(l,container)
         #print(_k, _c, _t)
         if _t == "<class 'ruamel.yaml.scalarfloat.ScalarFloat'>" or \
         _t == "<class 'str'>" or _t == "<class 'int'>":
-            _formula = f"{_k} = {_c}".replace("<bslash>","\\") 
+            _expression = f"{_c}".replace("<bslash>","\\") 
+            _formula = f"{_k} = {_expression}"
             #print(_formula)
-            if type(_r = sVe(_k, _formula, container)) == str:
+            _r = sVe(_k, _expression, container, sketch["name"])
+            if type(_r) == str:
                 print(_r)
-                break
+                return False
             exec(_formula,container)
         elif _t == "<class 'ruamel.yaml.comments.CommentedMap'>":
             #print(_c)
             _keys = list(_c.keys())
             #print(_keys)
             if 'formula' in _keys:
-                _formula = f"{_k} = {_c['formula']}".replace("<bslash>","\\")
+                _expression = f"{_c['formula']}".replace("<bslash>","\\") 
+                _formula = f"{_k} = {_expression}"
                 #print(_formula)
-                if type(_r = sVe(_k, _formula, container)) == str:
+                _r = sVe(_k, _expression, container, sketch["name"])
+                if type(_r) == str:
                     print(_r)
-                    break
+                    return False
                 exec(_formula,container)
+                # if the new object is a shape and has the sketch name, set this shape name as the sketch name
+                if issubclass(type(container[_k]), Shape):
+                    if _k == sketch['name']:
+                        container[_k].set_name(sketch['name'])
             if 'style' in _keys:
                 for _style in _c["style"]:
                     #  x_const.set_linestyle('dotted')
@@ -88,26 +117,30 @@ def sketchParse(sketch, container):
                 if str(type(_c['transform'])) == "<class 'str'>":
                     _t = f"{_k}.{_c['transform']}"
                     #print(_t)
-                    if type(_r = sVe(_k, _t, container)) == str:
+                    _r = sVe(_k, _formula, container, sketch["name"])
+                    if type(_r) == str:
                         print(_r)
-                        break
+                        return False
                     exec(_t,container)
                 else:
                     for _transform in _c["transform"]:
                     #  x_const.rotate(-theta, contact)
                         _t = f"{_k}.{_transform}"
                         #print(_t)
-                        if type(_r = sVe(_k, _t, container)) == str:
+                        _r = sVe(_k, _t, container, sketch["name"])
+                        if type(_r) == str:
                             print(_r)
-                            break
+                            return False
                         exec(_t,container)
             if "action" in _keys:
                 _action = _c["action"]
                 #print(_action)
-                if type(_r = sVe(_k, _action, container)) == str:
+                _r = sVe(_k, _action, container, sketch["name"])
+                if type(_r) == str:
                     print(_r)
-                    break
+                    return False
                 exec(_action,container)
+    return True
 
 def point(x, y, check_inside=False):
     for obj, name in zip([x, y], ['x', 'y']):