2
# -*- coding: iso-8859-15 -*-
3
#-------------------------------python------------------------pykig.py--#
7
#--Maurizio Paolini-Daniele Zambelli-----------------------------2005---#
22
# Constants: Point Style, Line Style, defaults values...
24
PS=("Round", "RoundEmpty", "Rectangular", "RectangularEmpty", "Cross")
25
LS=("SolidLine", "DashLine", "DashDotLine", "DashDotDotLine", "DotLine")
31
PROPERTY_INI="Property which"
32
OBJECT_INI="Object type"
33
PROPERTY_END="Property"
35
DICT=(("&","&"), ("<","<"), (">",">"),
36
("�","à"), ("�","è"), ("�","ì"), ("�","ò"), ("�","ù"), ("�","é"))
39
# this is a trick to allow definitions like "p=Point(0,0,HIDDEN)"
45
# Validation parameters
48
def parameter(val, defval):
49
if val==None: return defval
52
def validshown(shown):
53
if shown==KIGTRUE or shown==KIGFALSE: return shown
55
def validwidth(width):
56
if type(width)==TI: return width
58
def validpointstyle(ps):
59
if ps in PS: return ps
62
if type(name)==TS: return name
64
def validlinestyle(ls):
65
if ls in LS: return ls
67
def validcolor(color):
68
if type(color)==TS: return color
74
def rif(condition, val1, val2):
75
"""Return val1 if condition is True else return val2."""
76
if condition: return val1
80
# Force some Python variables as kig variables
85
if tp==TI or tp==TF: return Double(val)
90
if tp==TI: return Int(val)
95
if tp==TS: return String(val)
102
return Point(x, y, internal=True)
106
def kig_relpoint(obj, displ):
108
return RelativePoint(x, y, obj, internal=True)
118
class KigDocument(object):
119
""" Classe che produce il documento kig.
122
KigDocument <- object
163
def __init__(self, outfilename, callkig=True, of=False):
164
# print "KigDocument.__init__()"
167
self.outfilename=outfilename
171
self.outfile = open(outfilename, 'w')
172
except IOError, value:
173
# print >> sys.stderr, outfilename, 'unwritable'
174
print >> sys.stderr, value
176
# KigOut._kigdocument=self
184
self.pointstyle=PS[0]
191
def viewappend(self, e): self.viewkig.append(e)
192
def hierarchyappend(self, e): self.hierarchy.append(e)
193
def setcallkig(v): self.callkig=v
194
def setof(v): self.of=v
197
return """<!DOCTYPE KigDocument>
198
<KigDocument axes="%s" grid="%s" CompatibilityVersion="0.7.0" Version="0.9.1" >
199
<CoordinateSystem>Euclidean</CoordinateSystem>
201
""" % (self.axes, self.grid)
205
self.outfile.write(self.str_open())
206
self.outfile.writelines(self.hierarchy)
207
self.outfile.write(" </Hierarchy>\n <View>\n")
208
for f in self.viewkig:
209
self.outfile.write(f.str_view())
210
self.outfile.write(" </View>\n</KigDocument>\n")
211
if self.outfile != sys.stdout:
213
except IOError, value:
214
print >> sys.stderr, value
218
err = os.system('kig --nofork ' + self.outfilename)
219
except Exception, value:
220
print >> sys.stderr, value
222
os.system('rm ' + self.outfilename)
224
def noaxes(self): self.axes="0"
225
def nogrid(self): self.grid="0"
226
def hideobjects(self): self.shown=HIDDEN
227
def showobjects(self): self.shown=VISIBLE
228
def setwidth(self, w): self.width=w
229
def setpointstyle(self, ps): self.pointstyle=ps
230
def setname(self, n): self.name=n
231
def setlinestyle(self, ls): self.linestyle=ls
232
def setshown(self, s): self.shown=s
233
def setcolor(self, c): self.color=c
234
def setinternal(self, v): self.internal=v
240
#class KigDOP(KigOut):
241
class KigDOP(object):
242
"""Classe da cui deriva ogni elemento che ha un id: Data, Object, Property.
261
def __init__(self, type):
262
KigDOP._id_counter+=1
263
self.id=KigDOP._id_counter
265
# self.getkigdocument().hierarchyappend(self.str_hierarchy())
266
KigDOP._kd.hierarchyappend(self.str_hierarchy())
268
def getid(self): return str(self.id)
269
def str_hierarchy(self): pass
275
#class KigView(KigOut):
276
class KigView(object):
277
""" Classe con i dati di visualizzazione
300
def __init__(self, object, shown, name, width, pointstyle, linestyle, color):
302
self.shown = parameter(shown, KigView._kd.shown)
303
self.width = parameter(width, KigView._kd.width)
304
self.pointstyle = parameter(pointstyle, KigView._kd.pointstyle)
305
self.linestyle = parameter(linestyle, KigView._kd.linestyle)
306
self.color = parameter(color, KigView._kd.color)
307
self.name = parameter(name, KigView._kd.name)
308
KigView._kd.viewappend(self)
311
"""Produce la stringa che viene scritta sotto <View>.
314
<Draw width="-1" point-style="Round" namecalcer="none"
315
style="SolidLine" shown=None color="#0000ff" object="3" />
318
return ' <Draw width="%s" point-style="%s" namecalcer="%s"\
319
style="%s" shown="%s" color="%s" object="%s" />\n' %\
320
(self.width, self.pointstyle, self.name,
321
self.linestyle, self.shown, self.color, self.object.getid())
328
""" Classe da cui deriva ogni elemento Data
331
Data <- KigDOP <- object
339
def __init__(self, type, val):
341
KigDOP.__init__(self, type)
343
def str_hierarchy(self):
344
"""Produce la stringa che viene scritta sotto <Data>.
347
<Data type="double" id="170" >0.1</Data>
349
return ' <Data type="%s" id="%s" >%s</Data>\n' % \
350
(self._type, self.getid(), self.val)
356
class PropObj(KigDOP):
357
""" Classe da cui deriva ogni elemento visibile
360
PropObj <- KigDOP <- object
374
setwidth(self, width)
375
setcolor(self, color)
376
setlinestyle(self, linestyle)
377
setpointstyle(self, pointstyle)
386
def __init__(self, prop, type, objvec, shown, name, internal,
387
width, pointstyle, linestyle, color):
391
KigDOP.__init__(self, type)
392
internal=parameter(internal, KigDOP._kd.internal)
396
# Qui si assume che, se viene dato un nome ad un oggetto,
397
# si voglia anche visualizzare questo nome
398
if name: n_id=self.showname(name, shown, width, pointstyle, linestyle,
401
self.view = KigView(self, shown, n_id, width, pointstyle, linestyle,
404
def str_hierarchy(self):
405
"""Produce la stringa che viene scritta sotto <Data>.
408
<Property which="mid-point" id="170" >
413
<Object type="ConstrainedPoint" id="14" >
418
retstring = ' <%s="%s" id="%s" >' %\
419
((self.prop and PROPERTY_INI or OBJECT_INI),
420
self._type, self.getid())
421
for p in self.objvec:
422
retstring = retstring + '\n <Parent id="%s" />' % p.getid()
423
retstring = retstring + '\n </%s>\n' % (self.prop and PROPERTY_END or
427
def showname(self, name, shown, width, pointstyle, linestyle, color):
429
self.n_lb=Label(self, (0, 0), n, 0, shown, None, False,
430
width, pointstyle, linestyle, color)
434
if self.view: self.view.shown=None
436
if self.view: self.view.shown=KIGFALSE
437
def setwidth(self, width): self.view.width=width
438
def setcolor(self, color): self.view.color=color
439
def setlinestyle(self, linestyle):
440
if linestyle in LS: self.view.linestyle=linestyle
441
def setpointstyle(self, pointstyle):
442
if pointstyle in PS: self.view.pointstyle=pointstyle
443
def type(self): return Type(self)
444
def setname(self, n):
446
v.name=self.showname(n, v.shown, v.width, v.pointstyle, v.linestyle,
448
def setshown(self, s): self.view.shown=s
454
class Property(PropObj):
455
""" Classe da cui deriva ogni elemento Property
458
Property <- PropObj <- KigDOP <- object
460
def __init__(self, type, parent, shown, name, internal,
461
width, pointstyle, linestyle, color):
462
PropObj.__init__(self, True, type, (parent,), shown, name, internal,
463
width, pointstyle, linestyle, color)
470
class Object(PropObj):
471
""" Classe da cui deriva ogni elemento Oggetto
474
Object <- PropObj <- KigDOP <- object
477
def __init__(self, type, objvec, shown, name, internal,
478
width, pointstyle, linestyle, color):
479
PropObj.__init__(self, False, type, objvec, shown, name, internal,
480
width, pointstyle, linestyle, color)
487
("Int", "int", "val"),
488
("Double", "double", "val"),
489
("String", "string", "convstr(val)"),
497
def databuild(nomeclasse, nomekig, v="val"):
498
"""Create string with a Data class definition."""
499
return """class %s(Data):
501
def __init__(self, val):
502
Data.__init__(self, "%s", %s)
503
""" % (nomeclasse, nomekig, v)
507
exec databuild(p1, p2, p3)
513
("ConvexHall", "ConvexHall", "polygon,", "(polygon,),"),
514
("EllipseByFocusFocusPoint", "EllipseBFFP", "p1, p2, p3,", "(p1, p2, p3,),"),
515
("HyperbolaByFocusFocusPoint", "HyperbolaBFFP", "p1, p2, p3,", "(p1, p2, p3,),"),
516
(ConicsBy5Points", "ConicB5P", "p1, p2, p3, p4, p5,", "(p1, p2, p3, p4, p5),"),
517
("ParabolaBy3Points", "ParabolaBTP", "p1, p2, p3,", "(p1, p2, p3,),"),
518
("CocCurve", "CocCurve", "line, point,", "(line, point,),"),
522
("Point", "FixedPoint", "x, y,", "(kig_double(x), kig_double(y)),"),
523
("ConstrainedPoint", "ConstrainedPoint",
524
"t, curve,", "(kig_double(t), curve),"),
525
("RelativePoint", "RelativePoint",
526
"x, y, p,", "(kig_double(x), kig_double(y), p),"),
527
###### segments, rays, lines
528
("Line", "LineAB", "p1, p2,", "(p1, p2),"),
529
("Segment", "SegmentAB", "p1, p2,", "(p1, p2),"),
530
("Ray", "RayAB", "p1, p2,", "(p1, p2),"),
531
("Orthogonal", "LinePerpend", "line, point,", "(line, point,),"),
532
("Parallel", "LineParallel", "line, point,", "(line, point,),"),
533
###### Circles, arcs, ...
534
("Circle", "CircleBCP", "center, point,", "(center, point,),"),
535
("CircleByCenterPoint", "CircleBCP", "center, point,", "(center, point,),"),
536
("CircleByCenterRadius", "CircleBPR", "center, radius,", "(center, radius,),"),
537
("CircleBy3Points", "CircleBTP", "p1, p2, p3,", "(p1, p2, p3,),"),
538
("ArcBy3Points", "ArcBTP", "p1, p2, p3,", "(p1, p2, p3,),"),
539
("ArcByCenterPointAngle", "ArcBCPA",
540
"center, point, angle,", "(center, point, angle),"),
542
("ParabolaByDirectrixFocus", "ParabolaBDP", "line, point,", "(line, point,),"),
543
("VerticalCubic", "VerticalCubicB4P", "p1, p2, p3, p4,", "(p1, p2, p3, p4,),"),
544
("ConicArc", "ConicArcBTPC", "p1, p2, p3, center,", "(p1, p2, p3, center),"),
545
("ConicBy5Points", "ConicB5P", "p1, p2, p3, p4, p5,", "(p1, p2, p3, p4, p5,),"),
546
("EllipseByFocusFocusPoint", "EllipseBFFP", "p1, p2, p3,", "(p1, p2, p3,),"),
547
("ParabolaBy3Points", "ParabolaBTP", "p1, p2, p3,", "(p1, p2, p3,),"),
548
("HyperbolaByFocusFocusPoint", "HyperbolaBFFP", "p1, p2, p3,", "(p1, p2, p3,),"),
550
("CubicBy9Points", "CubicB9P", "p1, p2, p3, p4, p5, p6, p7, p8, p9,","(p1, p2, p3, p4, p5, p6, p7, p8, p9,)," ),
552
# intersections. The only standard object is the intersection
553
# of two lines, which always gives one single point
555
("LineLineIntersection", "LineLineIntersection", "l1, l2,", "(l1, l2),"),
557
# Classe CircleCircleIntersection e ConicLineIntersection
558
# l'intero "which" puo' assumere i valori 1 o -1 per indicare quale
559
# delle due intersezioni si desidera ottenere
560
# si potrebbe mettere un controllo...
562
("CircleCircleIntersection", "CircleCircleIntersection",
563
"c1, c2, which,", "(c1, c2, Int(which),),"),
564
("ConicLineIntersection", "ConicLineIntersection",
565
"conic, line, which,", "(conic, line, Int(which),),"),
566
("ConicLineOtherIntersection", "ConicLineOtherIntersection",
567
"conic, line, p,", "(conic, line, p),"),
568
("CubicLineIntersection", "CubicLineIntersection",
569
"cubic, line, which,", "(cubic, line, Int(which),),"),
570
("CubicLineOtherIntersection", "CubicLineOtherIntersection", "cubic, line, p1, p2,", "(cubic, line, p1, p2),"),
571
###### Classe Triangle
572
("Triangle", "TriangleB3P", "p1, p2, p3,", "(p1, p2, p3),"),
573
###### Classe Polygon (the only argument is a points vect)
574
("Polygon", "PolygonBNP", "pvec,", "pvec,"),
575
###### Classe PolygonBCV
576
# Poligono regolare dati il centro e un vertice; il terzo argomento
577
# e' un intero contenente il numero di lati
578
("PolygonBCV", "PoligonBCV",
579
"center, vertex, n,", "(center, vertex, Int(n)),"),
580
##### Classe PolygonVertex (poligono, intero >= 0)
581
("PolygonVertex", "PolygonVertex",
582
"polygon, i,", "(polygon, Int(i)),"),
583
##### Classe PolygonSide (poligono, intero >= 0)
584
("PolygonSide", "PolygonSide",
585
"polygon, i,", "(polygon, Int(i)),"),
586
###### vector, angle,...
587
("Vector", "Vector", "p1, p2,", "(p1, p2),"),
588
("Angle", "Angle", "p1, v, p2,", "(p1, v, p2),"),
589
###### Transformations
590
("Translate", "Translation", "obj, vector,", "(obj, vector),"),
591
("CentralSymmetry", "PointReflection", "obj, center,", "(obj, center),"),
592
("AxialSymmetry", "LineReflection", "obj, center,", "(obj, center),"),
593
("Rotate", "Rotation",
594
"obj, center, angle,", "(obj, center, angle),"),
595
("Scale", "ScalingOverCenter",
596
"obj, center, segment,", "(obj, center, segment),"),
597
("Scale2", "ScalingOverCenter2",
598
"obj, center, s1, s2,", "(obj, center, s1, s2),"),
599
("InvertPoint", "InvertPoint",
600
"point, circle,", "(point, circle),"),
601
("CircularInversion", "CircularInversion",
602
"objecttoinvert, circle,", "(objecttoinvert, circle),"),
603
("InvertLine", "InvertLine",
604
"line, circle,", "(line, circle),"),
605
("InvertCircle", "InvertCircle",
606
"circletoinvert, circle,", "(circletoinvert, circle),"),
607
("InvertArc", "InvertArc",
608
"arctoinvert, circle,", "(arctoinvert, circle),"),
609
("InvertSegment", "InvertSegment",
610
"segment, circle,", "(segment, circle),"),
611
###### Text, Label, ...
613
"point, string, boxed=0,",
614
"(Int(boxed), kig_point(point), kig_string(string)),"),
616
"obj, displ, string, boxed=0,",
617
"(Int(boxed),kig_relpoint(obj, displ),kig_string(string)),"),
619
"point, string, vars, boxed=0,",
620
"(Int(boxed), kig_point(point), \
621
kig_string(string))+tuple(vars),"),
622
("VarLabel", "Label",
623
"obj, displ, string, vars, boxed=0,",
624
"(Int(boxed), kig_relpoint(obj, displ), \
625
kig_string(string))+tuple(vars),"),
626
###### Python scripting... we need some work here...
627
("PythonScript", "PythonExecuteType",
629
'(Object("PythonCompileType", (kig_string(script),), shown,\
630
name, internal, width, pointstyle, linestyle,\
631
color),)+tuple(argvec),'),
634
def objectbuild(nameclass, namekig, params, objparams):
635
"""Create string with a Object class definition."""
636
return """class %s(Object):
638
def __init__(self, %s shown=None, name=None, internal=None,
639
width=None, pointstyle=None, linestyle=None, color=None):
640
Object.__init__(self, "%s", %s shown, name, internal,
641
width, pointstyle, linestyle, color)
642
""" % (nameclass, params, namekig, objparams)
646
exec objectbuild(p1, p2, p3, p4)
653
("Type", "base-object-type", "o,", "o,"),
654
("Coordinate", "coordinate", "point,", "point,"),
655
("XCoord", "coordinate-x", "point,", "point,"),
656
("YCoord", "coordinate-y", "point,", "point,"),
657
("MidPoints", "mid-point", "a, b,", "Segment(a, b, internal=True),"),
658
("MidPoint", "mid-point", "segment,", "segment,"),
659
("MidPointAB", "mid-point", "a, b,", "Segment(a, b, internal=True),"),
660
("MidPointSegment", "mid-point", "segment,", "segment,"),
661
("EndPointA", "end-point-A", "segment,", "segment,"),
662
("EndPointB", "end-point-B", "segment,", "segment,"),
663
("Length", "length", "segment,", "segment,"),
664
("Equation", "equation", "segment,", "segment,"),
665
("Slope", "slope", "segment,", "segment,"),
666
("NumOfSides", "polygon-number-of-sides", "poly,", "poly,"),
667
("Perimeter", "polygon-perimeter", "poly,", "poly,"),
668
("Surface", "polygon-surface", "poly,", "poly,"),
669
("CenterOfMass", "polygon-center-of-mass", "poly,", "poly,"),
670
("WindingNumber", "polygon-winding-number", "poly,", "poly,"),
671
("Radius", "radius", "circle,", "circle,"),
672
("Center", "center", "circle,", "circle,"),
673
("Bisector", "angle-bisector", "angle,", "angle,"),
674
("Support", "support", "object,", "object,"),
677
def propertybuild(nameclass, namekig, params, objparams):
678
"""Create string with a Property class definition."""
679
return """class %s(Property):
681
def __init__(self, %s shown=None, name=None, internal=False,
682
width=None, pointstyle=None, linestyle=None, color=None):
683
Property.__init__(self, "%s", %s shown, name, internal,
684
width, pointstyle, linestyle, color)
685
""" % (nameclass, params, namekig, objparams)
689
exec propertybuild(p1, p2, p3, p4)
692
# Start of properties definitions as Object's metod
695
points =(Point, ConstrainedPoint, RelativePoint, PolygonVertex)
696
lines=(Segment, Ray, Vector, InvertLine)
697
segments=(Segment, Vector, PolygonSide, InvertSegment)
698
circles =(CircleByCenterPoint, CircleBy3Points, CircularInversion, ArcBy3Points,
699
ArcByCenterPointAngle, InvertCircle)
700
polygons=(Polygon, PolygonBCV, Triangle)
705
("coordinate", "coordinate", points),
706
("coordinate-x", "xcoord", points),
707
("coordinate-y", "ycoord", points),
708
("mid-point", "midpoint", segments),
709
("end-point-A", "endpointA", segments),
710
("end-point-B", "endpointB", segments),
711
("length", "length", segments),
712
("equation", "equation", lines),
713
("slope", "slope", lines),
714
("polygon-number-of-sides", "numofsides", polygons),
715
("polygon-perimeter", "perimeter", polygons),
716
("polygon-surface", "surface", polygons),
717
("polygon-center-of-mass", "centerofmass", polygons),
718
("polygon-winding-number", "windingnumber", polygons),
719
("center", "center", polygons),
720
("center", "center", circles),
721
("angle-bisector", "bisector", angles),
722
("support", "support", supp),
725
def methodsbuild(namekig):
726
"""Create string with a method class definition."""
727
return """def method(self,shown=None, name=None, internal=False,
728
width=None, pointstyle=None, linestyle=None, color=None):
729
return Property("%s", self, shown, name, internal,
730
width, pointstyle, linestyle, color)
735
exec methodsbuild(p1)
737
setattr(c, p2, method)
744
print >> sys.stderr, """
745
usage: pykig.py [options...] file ...
748
-h, --help Show this text.
750
--output <kig_file> output <kig_file> no call Kig
751
-v, --version output version
752
-n, --nokig no call Kig
755
$ pykig.py my_file.kpy
756
$ pykig.py -o output_file.kig my_file.kpy
765
import sys, traceback, os
766
#from math import * # for user's programs
767
import math # for user's programs
773
_opts, _args = getopt.getopt(sys.argv[1:], "hvno:",\
774
["help", "version", "nokig", "output="])
775
except getopt.GetoptError:
780
for _opt, _arg in _opts:
781
if _opt in ("-h", "--help"):
783
if _opt in ("-v", "--version"):
784
print "version:", version
786
if _opt in ("-n", "--nokig"):
788
elif _opt in ("-o", "--output"):
791
_callKig=False # se c'� il file di output, non viene chiamato Kig
793
_infilename=raw_input("Nome del file di input: ")
795
print "No Input filename"
800
print "No infilename"
803
_infile = open(_infilename, 'r')
805
print >> sys.stderr, _infilename, 'unreadable'
808
if _outfilename=="-":
809
_n, _e = os.path.splitext(_infilename)
810
_outfilename=_n+'.kig'
812
_outfilename="/tmp/pykig" + str(os.getpid()) + ".kig"
814
kigdocument=KigDocument(_outfilename, _callKig, _of)
817
execfile(_infilename, globals())
819
print >> sys.stderr, 'syntax error in', _infilename
820
_info = sys.exc_info() # vorrei stampare il traceback...
821
traceback.print_exc()
825
if _infile != sys.stdin:
829
_outfilename="/tmp/pykig" + str(os.getpid()) + ".kig"
831
kigdocument=KigDocument(_outfilename)
833
atexit.register(kigdocument.close)
835
if __name__ == "__main__":