1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3# SPDX-FileCopyrightText: 2005 Maurizio Paolini-Daniele Zambelli 4# SPDX-FileCopyrightText: 2011 Bartosz Dziewoński 5# (licensed under GPL) 6 7version="0.2.11" 8 9##### 10# Type constants 11##### 12TI=type(0) 13TF=type(0.) 14TS=type("") 15TT=type((0, 0)) 16 17##### 18# Constants: Point Style, Line Style, default values... 19##### 20PS=("Round", "RoundEmpty", "Rectangular", "RectangularEmpty", "Cross") 21LS=("SolidLine", "DashLine", "DashDotLine", "DashDotDotLine", "DotLine") 22KIGTRUE="true" 23KIGFALSE="false" 24DEFWIDTH=-1 25DEFCOLOR="#0000ff" 26DEFNAME="none" 27PROPERTY_INI="Property which" 28OBJECT_INI="Object type" 29PROPERTY_END="Property" 30OBJECT_END="Object" 31 32# 33# this is a trick to allow definitions like "p=Point(0,0,HIDDEN)" 34# 35HIDDEN=KIGFALSE 36VISIBLE=KIGTRUE 37 38##### 39# Validating parameters 40##### 41 42def parameter(val, defval): 43 if val==None: return defval 44 else: return val 45 46def validshown(shown): 47 if shown==KIGTRUE or shown==KIGFALSE: return shown 48 49def validwidth(width): 50 if type(width)==TI: return width 51 52def validpointstyle(ps): 53 if ps in PS: return ps 54 55def validname(name): 56 if type(name)==TS: return name 57 58def validlinestyle(ls): 59 if ls in LS: return ls 60 61def validcolor(color): 62 if type(color)==TS: return color 63 64##### 65# if as a function 66##### 67 68def rif(condition, val1, val2): 69 """Return val1 if condition is True; else return val2.""" 70 if condition: return val1 71 else: return val2 72 73##### 74# Force some Python variables as kig variables 75##### 76 77def kig_double(val): 78 tp=type(val) 79 if tp==TI or tp==TF: return Double(val) 80 else: return val 81 82def kig_int(val): 83 tp=type(val) 84 if tp==TI: return Int(val) 85 else: return val 86 87def kig_string(val): 88 tp=type(val) 89 if tp==TS: return String(val) 90 else: return val 91 92def kig_point(val): 93 tp=type(val) 94 if tp==TT: 95 x, y = val 96 return Point(x, y, internal=True) 97 else: 98 return val 99 100def kig_relpoint(obj, displ): 101 x, y = displ 102 return RelativePoint(x, y, obj, internal=True) 103 104##### 105# base classes 106##### 107 108##### 109# KigDocument class 110##### 111 112class KigDocument(object): 113 """A class representing a Kig document. 114 115 ancestor chain: 116 KigDocument <- object 117 118 class attributes: 119 120 attributes: 121 axes 122 grid 123 outfilename 124 outfile 125 callkig 126 of 127 viewkig 128 hierarchy 129 internal 130 width 131 pointstyle 132 name 133 linestyle 134 shown 135 color 136 137 methods: 138 viewappend 139 hierarchyappend 140 setcallkig 141 setof 142 str_open 143 close 144 noaxes 145 nogrid 146 hideobjects 147 showobjects 148 setwidth 149 setpointstyle 150 setname 151 setlinestyle 152 setshown 153 setcolor 154 setinternal 155 """ 156 157 def __init__(self, outfilename, callkig=True, of=False): 158# print "KigDocument.__init__()" 159 self.axes = "1" 160 self.grid = "1" 161 self.outfilename=outfilename 162 self.callkig=callkig 163 self.of=of 164 try: 165 self.outfile = open(outfilename, 'w') 166 except IOError as value: 167# print >> sys.stderr, outfilename, 'unwritable' 168 print(value, file=sys.stderr) 169 sys.exit(2) 170# KigOut._kigdocument=self 171 KigDOP._kd=self 172 KigView._kd=self 173 self.viewkig=[] 174 self.hierarchy=[] 175# Default values 176 self.internal=False 177 self.width=DEFWIDTH 178 self.pointstyle=PS[0] 179 self.name=DEFNAME 180 self.linestyle=LS[0] 181 self.shown=VISIBLE 182 self.color=DEFCOLOR 183 184 185 def viewappend(self, e): self.viewkig.append(e) 186 def hierarchyappend(self, e): self.hierarchy.append(e) 187 def setcallkig(v): self.callkig=v 188 def setof(v): self.of=v 189 190 def str_open(self): 191 return """<?xml version="1.0" encoding="utf-8"?> 192<!DOCTYPE KigDocument> 193<KigDocument axes="%s" grid="%s" CompatibilityVersion="0.7.0" Version="0.9.1" > 194 <CoordinateSystem>Euclidean</CoordinateSystem> 195 <Hierarchy> 196""" % (self.axes, self.grid) 197 198 def close(self): 199 try: 200 self.outfile.write(self.str_open()) 201 self.outfile.writelines(self.hierarchy) 202 self.outfile.write(" </Hierarchy>\n <View>\n") 203 for f in self.viewkig: 204 self.outfile.write(f.str_view()) 205 self.outfile.write(" </View>\n</KigDocument>\n") 206 if self.outfile != sys.stdout: 207 self.outfile.close() 208 except IOError as value: 209 print(value, file=sys.stderr) 210 sys.exit(2) 211 try: 212 if self.callkig: 213 err = os.system('kig ' + self.outfilename) 214 except Exception as value: 215 print(value, file=sys.stderr) 216 if not self.of: 217 os.system('rm ' + self.outfilename) 218 219 def noaxes(self): self.axes="0" 220 def nogrid(self): self.grid="0" 221 def hideobjects(self): self.shown=HIDDEN 222 def showobjects(self): self.shown=VISIBLE 223 def setwidth(self, w): self.width=w 224 def setpointstyle(self, ps): self.pointstyle=ps 225 def setname(self, n): self.name=n 226 def setlinestyle(self, ls): self.linestyle=ls 227 def setshown(self, s): self.shown=s 228 def setcolor(self, c): self.color=c 229 def setinternal(self, v): self.internal=v 230 231##### 232# KigDOP class 233##### 234 235#class KigDOP(KigOut): 236class KigDOP(object): 237 """An class from which all elements having an id (Data, Object, Property) inherit. 238 239 ancestor chain: 240 KigDOP <- object 241 242 class attributes: 243 id-counter 244 245 attributes: 246 id 247 type 248 249 methods: 250 getid 251 str_hierarchy 252 """ 253 _kd=None 254 _id_counter=0 255 256 def __init__(self, type): 257 KigDOP._id_counter+=1 258 self.id=KigDOP._id_counter 259 self._type=type 260# self.getkigdocument().hierarchyappend(self.str_hierarchy()) 261 KigDOP._kd.hierarchyappend(self.str_hierarchy()) 262 263 def getid(self): return str(self.id) 264 def str_hierarchy(self): pass 265 266##### 267# KigView class 268##### 269 270#class KigView(KigOut): 271class KigView(object): 272 """A class containing visualization data. 273 274 ancestor chain: 275 KigView <- object 276 277 class attributes: 278 _kd 279 280 attributes: 281 shown 282 width 283 style 284 color 285 name 286 pointstyle 287 288 methods: 289 str_view 290 show 291 hide 292 """ 293 _kd=None 294 295 def __init__(self, object, shown, name, width, pointstyle, linestyle, color): 296 self.object=object 297 self.shown = parameter(shown, KigView._kd.shown) 298 self.width = parameter(width, KigView._kd.width) 299 self.pointstyle = parameter(pointstyle, KigView._kd.pointstyle) 300 self.linestyle = parameter(linestyle, KigView._kd.linestyle) 301 self.color = parameter(color, KigView._kd.color) 302 self.name = parameter(name, KigView._kd.name) 303 KigView._kd.viewappend(self) 304 305 def str_view(self): 306 """Returns a string which can be placed inside <View> tags. 307 308 example: 309 <Draw width="-1" point-style="Round" namecalcer="none" 310style="SolidLine" shown=None color="#0000ff" object="3" /> 311""" 312 313 return ' <Draw width="%s" point-style="%s" namecalcer="%s"\ 314 style="%s" shown="%s" color="%s" object="%s" />\n' %\ 315 (self.width, self.pointstyle, self.name, 316 self.linestyle, self.shown, self.color, self.object.getid()) 317 318##### 319# Data class 320##### 321 322class Data(KigDOP): 323 """An class from which all Data elements inherit. 324 325 ancestor chain: 326 Data <- KigDOP <- object 327 328 attributes: 329 val 330 331 methods: 332 str_hierarchy 333""" 334 def __init__(self, type, val): 335 self.val=val 336 KigDOP.__init__(self, type) 337 338 def str_hierarchy(self): 339 """Returns a string which can be placed inside <Hierarchy> tags. 340 341 example: 342 <Data type="double" id="170" >0.1</Data> 343""" 344 return ' <Data type="%s" id="%s" >%s</Data>\n' % \ 345 (self._type, self.getid(), self.val) 346 347##### 348# PropObj class 349##### 350 351class PropObj(KigDOP): 352 """A class from which all visible elements inherit. 353 354 ancestor chain: 355 PropObj <- KigDOP <- object 356 357 class attributes: 358 359 attributes: 360 prop 361 objvec 362 view 363 364 methods: 365 str_hierarchy 366 showname(self, n) 367 show(self) 368 hide(self) 369 setwidth(self, width) 370 setcolor(self, color) 371 setlinestyle(self, linestyle) 372 setpointstyle(self, pointstyle) 373 setname(self, n) 374 setshown(self, s) 375 getwidth(self) 376 getcolor(self) 377 getlinestyle(self) 378 getpointstyle(self) 379 """ 380 381 def __init__(self, prop, type, objvec, shown, name, internal, 382 width, pointstyle, linestyle, color): 383 self.prop=prop 384 self.objvec=objvec 385 self.n_lb=None 386 KigDOP.__init__(self, type) 387 internal=parameter(internal, KigDOP._kd.internal) 388 if internal: 389 self.view = None 390 else: 391# Here we assume that, if we're given a name of an object, 392# we want to visualize the name as well 393 if name: n_id=self.showname(name, shown, width, pointstyle, linestyle, 394 color) 395 else: n_id=None 396 self.view = KigView(self, shown, n_id, width, pointstyle, linestyle, 397 color) 398 399 def str_hierarchy(self): 400 """Returns a string which can be placed inside <Hierarchy> tags. 401 402 example: 403 <Property which="mid-point" id="170" > 404 <Parent id="..." /> 405 </Property> 406 407 example: 408 <Object type="ConstrainedPoint" id="14" > 409 <Parent id="13" /> 410 <Parent id="10" /> 411 </Object> 412""" 413 retstring = ' <%s="%s" id="%s" >' %\ 414 ((self.prop and PROPERTY_INI or OBJECT_INI), 415 self._type, self.getid()) 416 for p in self.objvec: 417 retstring = retstring + '\n <Parent id="%s" />' % p.getid() 418 retstring = retstring + '\n </%s>\n' % (self.prop and PROPERTY_END or 419 OBJECT_END) 420 return retstring 421 422 def showname(self, name, shown, width, pointstyle, linestyle, color): 423 n=String(name) 424 self.n_lb=Label(self, (0, 0), n, 0, shown, None, False, 425 width, pointstyle, linestyle, color) 426 return n.getid() 427 428 def show(self): 429 if self.view: self.view.shown=None 430 def hide(self): 431 if self.view: self.view.shown=KIGFALSE 432 def setwidth(self, width): self.view.width=width 433 def setcolor(self, color): self.view.color=color 434 def setlinestyle(self, linestyle): 435 if linestyle in LS: self.view.linestyle=linestyle 436 def setpointstyle(self, pointstyle): 437 if pointstyle in PS: self.view.pointstyle=pointstyle 438 def type(self): return Type(self) 439 def setname(self, n): 440 v=self.view 441 v.name=self.showname(n, v.shown, v.width, v.pointstyle, v.linestyle, 442 v.color) 443 def setshown(self, s): self.view.shown=s 444 445##### 446# Property class 447##### 448 449class Property(PropObj): 450 """A class from which all Property elements inherit. 451 452 ancestor chain: 453 Property <- PropObj <- KigDOP <- object 454 """ 455 def __init__(self, type, parent, shown, name, internal, 456 width, pointstyle, linestyle, color): 457 PropObj.__init__(self, True, type, (parent,), shown, name, internal, 458 width, pointstyle, linestyle, color) 459# print shown 460 461##### 462# Object class 463##### 464 465class Object(PropObj): 466 """A class from which all Object elements inherit. 467 468 ancestor chain: 469 Object <- PropObj <- KigDOP <- object 470 """ 471 472 def __init__(self, type, objvec, shown, name, internal, 473 width, pointstyle, linestyle, color): 474 PropObj.__init__(self, False, type, objvec, shown, name, internal, 475 width, pointstyle, linestyle, color) 476 477##### 478# Data 479##### 480 481data=(\ 482("Int", "int", "val"), 483("Double", "double", "val"), 484("String", "string", "xml.sax.saxutils.escape(val)"), 485) 486 487def databuild(nomeclasse, nomekig, v="val"): 488 """Create string with a Data class definition.""" 489 return """class %s(Data): 490 491 def __init__(self, val): 492 Data.__init__(self, "%s", %s) 493""" % (nomeclasse, nomekig, v) 494 495for d in data: 496 p1, p2, p3 = d 497 exec (databuild(p1, p2, p3)) 498 499##### 500# Objects 501##### 502"""To add: 503("ConvexHull", "ConvexHull", "polygon,", "(polygon,),"), 504("EllipseByFocusFocusPoint", "EllipseBFFP", "p1, p2, p3,", "(p1, p2, p3,),"), 505("HyperbolaByFocusFocusPoint", "HyperbolaBFFP", "p1, p2, p3,", "(p1, p2, p3,),"), 506("ConicBy5Points", "ConicB5P", "p1, p2, p3, p4, p5,", "(p1, p2, p3, p4, p5),"), 507("ParabolaBy3Points", "ParabolaBTP", "p1, p2, p3,", "(p1, p2, p3,),"), 508("CocCurve", "CocCurve", "line, point,", "(line, point,),"), 509""" 510objects=(\ 511###### Points class 512("Point", "FixedPoint", "x, y,", "(kig_double(x), kig_double(y)),"), 513("ConstrainedPoint", "ConstrainedPoint", 514 "t, curve,", "(kig_double(t), curve),"), 515("RelativePoint", "RelativePoint", 516 "x, y, p,", "(kig_double(x), kig_double(y), p),"), 517###### Segments, rays, lines 518("Line", "LineAB", "p1, p2,", "(p1, p2),"), 519("Segment", "SegmentAB", "p1, p2,", "(p1, p2),"), 520("Ray", "RayAB", "p1, p2,", "(p1, p2),"), 521("Orthogonal", "LinePerpend", "line, point,", "(line, point,),"), 522("Parallel", "LineParallel", "line, point,", "(line, point,),"), 523###### Circles, arcs, ... 524("Circle", "CircleBCP", "center, point,", "(center, point,),"), 525("CircleByCenterPoint", "CircleBCP", "center, point,", "(center, point,),"), 526("CircleByCenterRadius", "CircleBPR", "center, radius,", "(center, radius,),"), 527("CircleBy3Points", "CircleBTP", "p1, p2, p3,", "(p1, p2, p3,),"), 528("ArcBy3Points", "ArcBTP", "p1, p2, p3,", "(p1, p2, p3,),"), 529("ArcByCenterPointAngle", "ArcBCPA", 530 "center, point, angle,", "(center, point, angle),"), 531###### Conics... 532("ParabolaByDirectrixFocus", "ParabolaBDP", "line, point,", "(line, point,),"), 533("VerticalCubic", "VerticalCubicB4P", "p1, p2, p3, p4,", "(p1, p2, p3, p4,),"), 534("ConicArc", "ConicArcBTPC", "p1, p2, p3, center,", "(p1, p2, p3, center),"), 535("ConicBy5Points", "ConicB5P", "p1, p2, p3, p4, p5,", "(p1, p2, p3, p4, p5,),"), 536("EllipseByFocusFocusPoint", "EllipseBFFP", "p1, p2, p3,", "(p1, p2, p3,),"), 537("ParabolaBy3Points", "ParabolaBTP", "p1, p2, p3,", "(p1, p2, p3,),"), 538("HyperbolaByFocusFocusPoint", "HyperbolaBFFP", "p1, p2, p3,", "(p1, p2, p3,),"), 539#### Cubics 540("CubicBy9Points", "CubicB9P", "p1, p2, p3, p4, p5, p6, p7, p8, p9,","(p1, p2, p3, p4, p5, p6, p7, p8, p9,)," ), 541##### 542# Intersections. The only standard object is the intersection 543# of two lines, which always gives one single point. 544##### 545("LineLineIntersection", "LineLineIntersection", "l1, l2,", "(l1, l2),"), 546##### 547# CircleCircleIntersection and ConicLineIntersection classes 548# The "which" argument takes values of 1 or -1, to indicate 549# which of the intersections you want to get. 550##### 551("CircleCircleIntersection", "CircleCircleIntersection", 552 "c1, c2, which,", "(c1, c2, Int(which),),"), 553("ConicLineIntersection", "ConicLineIntersection", 554 "conic, line, which,", "(conic, line, Int(which),),"), 555("ConicLineOtherIntersection", "ConicLineOtherIntersection", 556 "conic, line, p,", "(conic, line, p),"), 557("LineCubicIntersection", "CubicLineIntersection", 558 "cubic, line, which,", "(cubic, line, Int(which),),"), 559("CubicLineIntersection", "CubicLineIntersection", 560 "cubic, line, which,", "(cubic, line, Int(which),),"), 561("CubicLineOtherIntersection", "CubicLineOtherIntersection", "cubic, line, p1, p2,", "(cubic, line, p1, p2),"), 562###### Triangle class 563("Triangle", "TriangleB3P", "p1, p2, p3,", "(p1, p2, p3),"), 564###### Polygon class (the only argument is a points vect) 565("Polygon", "PolygonBNP", "pvec,", "pvec,"), 566###### PolygonBCV class 567# Regular polygon data - center and a vertex. The third argument 568# is an integer signifying the number of sides. 569("PolygonBCV", "PoligonBCV", 570 "center, vertex, n,", "(center, vertex, Int(n)),"), 571##### PolygonVertex class (polygon, integer >= 0) 572("PolygonVertex", "PolygonVertex", 573 "polygon, i,", "(polygon, Int(i)),"), 574##### PolygonSide class (polygon, integer >= 0) 575("PolygonSide", "PolygonSide", 576 "polygon, i,", "(polygon, Int(i)),"), 577###### Vector, angle,... 578("Vector", "Vector", "p1, p2,", "(p1, p2),"), 579("Angle", "Angle", "p1, v, p2,", "(p1, v, p2),"), 580###### Transformations 581("Translate", "Translation", "obj, vector,", "(obj, vector),"), 582("CentralSymmetry", "PointReflection", "obj, center,", "(obj, center),"), 583("AxialSymmetry", "LineReflection", "obj, center,", "(obj, center),"), 584("Rotate", "Rotation", 585 "obj, center, angle,", "(obj, center, angle),"), 586("Scale", "ScalingOverCenter", 587 "obj, center, segment,", "(obj, center, segment),"), 588("Scale2", "ScalingOverCenter2", 589 "obj, center, s1, s2,", "(obj, center, s1, s2),"), 590("Stretch", "ScalingOverLine", 591 "obj, line, segment,", "(obj, line, segment),"), 592("Stretch2", "ScalingOverLine2", 593 "obj, line, s1, s2,", "(obj, line, s1, s2),"), 594("InvertPoint", "InvertPoint", 595 "point, circle,", "(point, circle),"), 596("CircularInversion", "CircularInversion", 597 "objecttoinvert, circle,", "(objecttoinvert, circle),"), 598("InvertLine", "InvertLine", 599 "line, circle,", "(line, circle),"), 600("InvertCircle", "InvertCircle", 601 "circletoinvert, circle,", "(circletoinvert, circle),"), 602("InvertArc", "InvertArc", 603 "arctoinvert, circle,", "(arctoinvert, circle),"), 604("InvertSegment", "InvertSegment", 605 "segment, circle,", "(segment, circle),"), 606###### Text, Label, ... 607("Text", "Label", 608 "point, string, boxed=0,", 609 "(Int(boxed), kig_point(point), kig_string(string)),"), 610("Label", "Label", 611 "obj, displ, string, boxed=0,", 612 "(Int(boxed),kig_relpoint(obj, displ),kig_string(string)),"), 613("VarText", "Label", 614 "point, string, vars, boxed=0,", 615 "(Int(boxed), kig_point(point), \ 616 kig_string(string))+tuple(vars),"), 617("VarLabel", "Label", 618 "obj, displ, string, vars, boxed=0,", 619 "(Int(boxed), kig_relpoint(obj, displ), \ 620 kig_string(string))+tuple(vars),"), 621###### Python scripting... we need some work here... 622("PythonScript", "PythonExecuteType", 623 "script, argvec,", 624 '(Object("PythonCompileType", (kig_string(script),), shown,\ 625 name, internal, width, pointstyle, linestyle,\ 626 color),)+tuple(argvec),'), 627) 628 629def objectbuild(nameclass, namekig, params, objparams): 630 """Create string with a Object class definition.""" 631 return """class %s(Object): 632 633 def __init__(self, %s shown=None, name=None, internal=None, 634 width=None, pointstyle=None, linestyle=None, color=None): 635 Object.__init__(self, "%s", %s shown, name, internal, 636 width, pointstyle, linestyle, color) 637""" % (nameclass, params, namekig, objparams) 638 639for o in objects: 640 p1, p2, p3, p4 = o 641 exec (objectbuild(p1, p2, p3, p4)) 642 643##### 644# Properties 645##### 646 647property=(\ 648("Type", "base-object-type", "o,", "o,"), 649("Coordinate", "coordinate", "point,", "point,"), 650("XCoord", "coordinate-x", "point,", "point,"), 651("YCoord", "coordinate-y", "point,", "point,"), 652("MidPoints", "mid-point", "a, b,", "Segment(a, b, internal=True),"), 653("MidPoint", "mid-point", "segment,", "segment,"), 654("MidPointAB", "mid-point", "a, b,", "Segment(a, b, internal=True),"), 655("MidPointSegment", "mid-point", "segment,", "segment,"), 656("EndPointA", "end-point-A", "segment,", "segment,"), 657("EndPointB", "end-point-B", "segment,", "segment,"), 658("Length", "length", "segment,", "segment,"), 659("Equation", "equation", "segment,", "segment,"), 660("Slope", "slope", "segment,", "segment,"), 661("NumOfSides", "polygon-number-of-sides", "poly,", "poly,"), 662("Perimeter", "polygon-perimeter", "poly,", "poly,"), 663("Surface", "polygon-surface", "poly,", "poly,"), 664("CenterOfMass", "polygon-center-of-mass", "poly,", "poly,"), 665("WindingNumber", "polygon-winding-number", "poly,", "poly,"), 666("Radius", "radius", "circle,", "circle,"), 667("Center", "center", "circle,", "circle,"), 668("Bisector", "angle-bisector", "angle,", "angle,"), 669("Support", "support", "object,", "object,"), 670) 671 672def propertybuild(nameclass, namekig, params, objparams): 673 """Create string with a Property class definition.""" 674 return """class %s(Property): 675 676 def __init__(self, %s shown=None, name=None, internal=False, 677 width=None, pointstyle=None, linestyle=None, color=None): 678 Property.__init__(self, "%s", %s shown, name, internal, 679 width, pointstyle, linestyle, color) 680""" % (nameclass, params, namekig, objparams) 681 682for p in property: 683 p1, p2, p3, p4 = p 684 exec (propertybuild(p1, p2, p3, p4)) 685 686##### 687# Start of properties definitions as Object's methods 688##### 689# to be cleaned up! 690points =(Point, ConstrainedPoint, RelativePoint, PolygonVertex) 691lines=(Segment, Ray, Vector, InvertLine) 692segments=(Segment, Vector, PolygonSide, InvertSegment) 693circles =(CircleByCenterPoint, CircleBy3Points, CircularInversion, ArcBy3Points, 694 ArcByCenterPointAngle, InvertCircle) 695polygons=(Polygon, PolygonBCV, Triangle) 696angles =(Angle,) 697supp = circles+lines 698 699methods=(\ 700("coordinate", "coordinate", points), 701("coordinate-x", "xcoord", points), 702("coordinate-y", "ycoord", points), 703("mid-point", "midpoint", segments), 704("end-point-A", "endpointA", segments), 705("end-point-B", "endpointB", segments), 706("length", "length", segments), 707("equation", "equation", lines), 708("slope", "slope", lines), 709("polygon-number-of-sides", "numofsides", polygons), 710("polygon-perimeter", "perimeter", polygons), 711("polygon-surface", "surface", polygons), 712("polygon-center-of-mass", "centerofmass", polygons), 713("polygon-winding-number", "windingnumber", polygons), 714("center", "center", polygons), 715("center", "center", circles), 716("angle-bisector", "bisector", angles), 717("support", "support", supp), 718) 719 720def methodsbuild(namekig): 721 """Create string with a method class definition.""" 722 return """def method(self,shown=None, name=None, internal=False, 723 width=None, pointstyle=None, linestyle=None, color=None): 724 return Property("%s", self, shown, name, internal, 725 width, pointstyle, linestyle, color) 726""" % (namekig, ) 727 728for p in methods: 729 p1, p2, cl = p 730 exec (methodsbuild(p1)) 731 for c in cl: 732 setattr(c, p2, method) 733 734##### 735# Usage 736##### 737 738def usage(codexit): 739 print (""" 740usage: pykig.py [options...] file ... 741 742Options: 743 -h, --help Show this text. 744 -o <kig_file> 745 --output <kig_file> Output to <kig_file> and don't call Kig. 746 -v, --version Output version and exit. 747 -n, --nokig Don't call Kig. 748 749examples: 750 $ pykig.py my_file.kpy 751 $ pykig.py -o output_file.kig my_file.kpy 752 $ ... 753""", file=sys.stderr) 754 sys.exit(codexit) 755 756##### 757# Main body 758##### 759 760import sys, traceback, os 761#from math import * # for user's programs 762import math # for user's programs 763import getopt 764import atexit 765import xml.sax.saxutils 766 767def prog(): 768 try: 769 _opts, _args = getopt.getopt(sys.argv[1:], "hvno:",\ 770 ["help", "version", "nokig", "output="]) 771 except getopt.GetoptError: 772 print ("GetoptError") 773 usage(2) 774 _callKig=True 775 _of=False 776 for _opt, _arg in _opts: 777 if _opt in ("-h", "--help"): 778 usage(0) 779 if _opt in ("-v", "--version"): 780 print ("Version:", version) 781 sys.exit(0) 782 if _opt in ("-n", "--nokig"): 783 _callKig=False 784 elif _opt in ("-o", "--output"): 785 _outfilename=_arg 786 _of=True 787 _callKig=False # if there's an output file, don't call Kig 788 if len(_args)==0: 789 _infilename=input("Input file name: ") 790 if not _infilename: 791 print ("No input file name.") 792 usage(2) 793 elif len(_args)==1: 794 _infilename=_args[0] 795 else: 796 print ("No input file name.") 797 usage(2) 798 try: 799 _infile = open(_infilename, 'r') 800 except: 801 print (_infilename, "input file can't be read.", file=sys.stderr) 802 sys.exit(2) 803 if _of: 804 if _outfilename=="-": 805 _n, _e = os.path.splitext(_infilename) 806 _outfilename=_n+'.kig' 807 else: 808 _outfilename="/tmp/pykig" + str(os.getpid()) + ".kig" 809 global kigdocument 810 kigdocument=KigDocument(_outfilename, _callKig, _of) 811 kd=kigdocument 812 try: 813 exec(open(_infilename).read(), globals()) 814 except: 815 print ('Syntax error in', _infilename, file=sys.stderr) 816 _info = sys.exc_info() # print out the traceback 817 traceback.print_exc() 818 sys.exit(3) 819 kigdocument.close() 820 821 if _infile != sys.stdin: 822 _infile.close() 823 824def lib(): 825 _outfilename="/tmp/pykig" + str(os.getpid()) + ".kig" 826 global kigdocument 827 kigdocument=KigDocument(_outfilename) 828 kd=kigdocument 829 atexit.register(kigdocument.close) 830 831if __name__ == "__main__": 832 prog() 833else: 834 lib() 835