@@ -58,41 +58,42 @@ def classToFileName(cl):
5858# fileName
5959# imageSource
6060
61+ exp_float = '[+-]?\d+(?:.\d+)?(?:e[+-]?\d+)?'
62+
6163element_id = 0
6264regex_equal_key_value = re .compile ("([^ =]+) *= *(\" [^\" ]*\" |[^ ]*)" )
63- regex_points = re .compile ("{([+-]?\d+(?:.\d+)?), ([+-]?\d+(?:.\d+)?)}" )
6465
6566regex_type_value = re .compile ("(\w+.\w+)*" )
6667
6768# Compile regular expressions ONLY once!
6869# example: {-100.0,-100.0,100.0,100.0,true,0.16,2.0,2.0, {...
69- regex_coordSys = re .compile ('([+-]?\d+(?:.\d+)?),([+-]?\d+(?:.\d+)?),([+-]?\d+(?:.\d+)?),([+-]?\d+(?:.\d+)?) ,(\w+),([+-]?\d+(?:.\d+)?),([+-]?\d+(?:.\d+)?),([+-]?\d+(?:.\d+)? ),' )
70+ regex_coordSys = re .compile ('(' + exp_float + '),(' + exp_float + '),(' + exp_float + '),(' + exp_float + ') ,(\w+),(' + exp_float + '),(' + exp_float + '),(' + exp_float + ' ),' )
7071
7172# example: Rectangle(true, {35.0, 10.0}, 0, {0, 0, 0}, {255, 255, 255}, LinePattern.Solid, FillPattern.Solid, 0.25, BorderPattern.None, {{-15.0, -4.0}, {15.0, 4.0}}, 0
72- regex_rectangle = re .compile ('Rectangle\(([\w ]+), {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, ([+-]?\d+(?:.\d+)?) , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), ([+-]?\d+(?:.\d+)?) , (\w+.\w+), {{([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }}, ([+-]?\d+(?:.\d+)? )' )
73+ regex_rectangle = re .compile ('Rectangle\(([\w ]+), {(' + exp_float + ') , (' + exp_float + ') }, (' + exp_float + ') , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), (' + exp_float + ') , (\w+.\w+), {{(' + exp_float + ') , (' + exp_float + ') }, {(' + exp_float + ') , (' + exp_float + ') }}, (' + exp_float + ' )' )
7374
7475# example: Line(true, {0.0, 0.0}, 0, {{-30, -120}, {-10, -100}}, {0, 0, 0}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.None}, 3, Smooth.None
75- regex_line = re .compile ('Line\(([\w ]+), {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, ([+-]?\d+(?:.\d+)?) , ({{[+-]?\d+(?:.\d+)?, [+-]?\d+(?:.\d+)? }(?:, {[+-]?\d+(?:.\d+)?, [+-]?\d+(?:.\d+)? })*}), {(\d+), (\d+), (\d+)}, (\w+.\w+), ([+-]?\d+(?:.\d+)?) , {(\w+.\w+), (\w+.\w+)}, ([+-]?\d+(?:.\d+)? ), (\w+.\w+)' )
76+ regex_line = re .compile ('Line\(([\w ]+), {(' + exp_float + ') , (' + exp_float + ') }, (' + exp_float + ') , ({{' + exp_float + ', ' + exp_float + ' }(?:, {' + exp_float + ', ' + exp_float + ' })*}), {(\d+), (\d+), (\d+)}, (\w+.\w+), (' + exp_float + ') , {(\w+.\w+), (\w+.\w+)}, (' + exp_float + ' ), (\w+.\w+)' )
7677
7778# example: Ellipse(true, {0.0, 0.0}, 0, {0, 0, 0}, {95, 95, 95}, LinePattern.Solid, FillPattern.Solid, 0.25, {{-100, 100}, {100, -100}}, 0, 360)}}
78- regex_ellipse = re .compile ('Ellipse\(([\w ]+), {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, ([+-]?\d+(?:.\d+)?) , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), ([+-]?\d+(?:.\d+)?) , {{([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }}, ([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)? )' )
79+ regex_ellipse = re .compile ('Ellipse\(([\w ]+), {(' + exp_float + ') , (' + exp_float + ') }, (' + exp_float + ') , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), (' + exp_float + ') , {{(' + exp_float + ') , (' + exp_float + ') }, {(' + exp_float + ') , (' + exp_float + ') }}, (' + exp_float + ') , (' + exp_float + ' )' )
7980
8081# example: Text(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 0}, LinePattern.Solid, FillPattern.None, 0.25, {{-150, 110}, {150, 70}}, "%name", 0, TextAlignment.Center
81- regex_text = re .compile ('Text\(([\w ]+), {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, ([+-]?\d+(?:.\d+)?) , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), ([+-]?\d+(?:.\d+)?) , {{([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }}, ("[^"]*"), ([+-]?\d+(?:.\d+)? )(?:, ("[^"]*"))?(?:, {([^}]*)})?, (\w+.\w+)' )
82+ regex_text = re .compile ('Text\(([\w ]+), {(' + exp_float + ') , (' + exp_float + ') }, (' + exp_float + ') , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), (' + exp_float + ') , {{(' + exp_float + ') , (' + exp_float + ') }, {(' + exp_float + ') , (' + exp_float + ') }}, ("[^"]*"), (' + exp_float + ' )(?:, ("[^"]*"))?(?:, {([^}]*)})?, (\w+.\w+)' )
8283
8384# example: Text(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 0}, LinePattern.Solid, FillPattern.None, 0.25, {{-150, 110}, {150, 70}}, {"%name", y, 0}, 0, TextAlignment.Center
84- regex_text2 = re .compile ('Text\(([\w ]+), {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, ([+-]?\d+(?:.\d+)?) , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), ([+-]?\d+(?:.\d+)?) , {{([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }}, {("[^"]*"), [+-, \w\d]*}, ([+-]?\d+(?:.\d+)? )(?:, ("[^"]*"))?(?:, {([^}]*)})?, (\w+.\w+)' )
85+ regex_text2 = re .compile ('Text\(([\w ]+), {(' + exp_float + ') , (' + exp_float + ') }, (' + exp_float + ') , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), (' + exp_float + ') , {{(' + exp_float + ') , (' + exp_float + ') }, {(' + exp_float + ') , (' + exp_float + ') }}, {("[^"]*"), [+-, \w\d]*}, (' + exp_float + ' )(?:, ("[^"]*"))?(?:, {([^}]*)})?, (\w+.\w+)' )
8586
8687# example: Polygon(true, {0.0, 0.0}, 0, {0, 127, 255}, {0, 127, 255}, LinePattern.Solid, FillPattern.Solid, 0.25, {{-24, -34}, {-82, 40}, {-72, 46}, {-14, -26}, {-24, -34}}, Smooth.None
8788# Polygon(true, {-60, -40},90, {0, 0, 0}, {255, 128, 0}, LinePattern.Solid, FillPattern.VerticalCylinder, 0.25, {{-20.0, 10.0}, {0.0, -10.0}, {1.22465e-16, -50.0}, {-10.0, -60.0}, {-20.0, -60.0}, {-20.0, 10.0}}, Smooth.None
88- regex_polygon = re .compile ('Polygon\(([\w ]+), {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, ([+-]?\d+(?:.\d+)?) , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), ([+-]?\d+(?:.\d+)?) , ({{[+-]?\d+ (?:.\d+)?(?: e[+-]?\d+)?, [+-]?\d+ (?:.\d+)?(?: e[+-]?\d+)?}(?:, {[+-]?\d+(?:.\d+)?(?:e[+-]?\d+)?, [+-]?\d+(?:.\d+)?(?:e[+-]?\d+)? })*}), (\w+.\w+)' )
89+ regex_polygon = re .compile ('Polygon\(([\w ]+), {(' + exp_float + ') , (' + exp_float + ') }, (' + exp_float + ') , {(\d+), (\d+), (\d+)}, {(\d+), (\d+), (\d+)}, (\w+.\w+), (\w+.\w+), (' + exp_float + ') , ({{' + exp_float + ' (?:e[+-]?\d+)?, ' + exp_float + ' (?:e[+-]?\d+)?}(?:, {' + exp_float + ', ' + exp_float + ' })*}), (\w+.\w+)' )
8990
9091# example: {{-100.0, -100.0}, {-100.0, -30.0}, {0.0, -30.0}, {0.0, 0.0}}
91- regex_points = re .compile ('{([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)? )}' )
92+ regex_points = re .compile ('{(' + exp_float + ') , (' + exp_float + ' )}' )
9293
9394# example: Bitmap(true, {0.0, 0.0}, 0, {{-98, 98}, {98, -98}}, "modelica://Modelica/Resources/Images/Mechanics/MultiBody/Visualizers/TorusIcon.png"
9495# TODO: where is the imageSource?
95- regex_bitmap = re .compile ('Bitmap\(([\w ]+), {([+-]?\d+(?:.\d+)?) , ([+-]?\d+(?:.\d+)?) }, ([+-]?\d+(?:.\d+)?) , ({{[+-]?\d+(?:.\d+)?, [+-]?\d+(?:.\d+)? }(?:, {[+-]?\d+(?:.\d+)?, [+-]?\d+(?:.\d+)? })*}), ("[^"]*")' )
96+ regex_bitmap = re .compile ('Bitmap\(([\w ]+), {(' + exp_float + ') , (' + exp_float + ') }, (' + exp_float + ') , ({{' + exp_float + ', ' + exp_float + ' }(?:, {' + exp_float + ', ' + exp_float + ' })*}), ("[^"]*")' )
9697
9798# anything unknown that produces output should look like this: Trash(...
9899regex_any = re .compile ('(\w+)\(' )
@@ -297,7 +298,7 @@ def getGraphicsForClass(modelicaClass):
297298 for i in range (0 , len (gg )):
298299 points .append ([float (gg [i ][0 ]), float (gg [i ][1 ])])
299300 graphicsObj ['points' ] = points
300- graphicsObj ['href' ] = g [5 ].strip ('"' ). encode ( 'utf-8' )
301+ graphicsObj ['href' ] = g [5 ].strip ('"' )
301302
302303 if not 'type' in graphicsObj :
303304 r = regex_any .search (icon_line )
@@ -624,7 +625,7 @@ def getSvgFromGraphics(dwg, graphics, minX, maxY, includeInvisibleText, transfor
624625 extra ['font_family' ] = graphics ['fontName' ] or "Verdana"
625626
626627 if graphics ['fontSize' ] == 0 :
627- extra ['font_size' ] = "18"
628+ extra ['font_size' ] = str ( abs ( y1 - y0 )) # fit text into extent according to 18.6.5.5
628629 else :
629630 extra ['font_size' ] = graphics ['fontSize' ]
630631
@@ -1025,7 +1026,7 @@ def getSvgFromGraphics(dwg, graphics, minX, maxY, includeInvisibleText, transfor
10251026
10261027
10271028# generate svgs from graphics objects
1028- def generateSvg (filename , iconGraphics , includeInvisibleText ):
1029+ def generateSvg (filename , iconGraphics , includeInvisibleText , warn_duplicates ):
10291030 global element_id
10301031 element_id = 0
10311032
@@ -1133,13 +1134,19 @@ def generateSvg(filename, iconGraphics, includeInvisibleText):
11331134 hashName = hashlib .sha1 (dwg .tostring ().encode ("utf-8" )).hexdigest () + ".svg"
11341135 hashPath = os .path .join (os .path .dirname (filename ),hashName )
11351136 if not os .path .exists (hashPath ):
1136- dwg .saveas (hashPath )
1137- os .symlink (hashName , filename )
1137+ dwg .saveas (hashPath )
1138+ if not os .path .exists (filename ):
1139+ os .symlink (hashName , filename )
1140+ else :
1141+ if warn_duplicates :
1142+ logger .warning ('Target file {0} already exists' .format (filename ))
1143+ else :
1144+ logger .error ('Target file {0} already exists' .format (filename ))
11381145
11391146 return dwg
11401147
11411148
1142- def exportIcon (modelicaClass , base_classes , includeInvisbleText ):
1149+ def exportIcon (modelicaClass , base_classes , includeInvisbleText , warn_duplicates ):
11431150 # get all icons
11441151 iconGraphics = []
11451152
@@ -1153,7 +1160,7 @@ def exportIcon(modelicaClass, base_classes, includeInvisbleText):
11531160 json .dump (iconGraphics , f_p )
11541161
11551162 # export svgs
1156- dwg = generateSvg (os .path .join (output_dir , classToFileName (modelicaClass ) + ".svg" ), iconGraphics , includeInvisbleText )
1163+ dwg = generateSvg (os .path .join (output_dir , classToFileName (modelicaClass ) + ".svg" ), iconGraphics , includeInvisbleText , warn_duplicates )
11571164 return dwg
11581165
11591166# Note: The order of the base classes matters
@@ -1173,6 +1180,7 @@ def main():
11731180 parser .add_option ("--with-html" , help = "Generate an HTML report with all SVG-files" , action = "store_true" , dest = "with_html" , default = False )
11741181 parser .add_option ("--with-invisible-text" , action = "store_true" , help = "Includes invisible text containing the original text and bounding box, for debugging purposes" , dest = "includeInvisibleText" , default = False )
11751182 parser .add_option ("--output-dir" , help = "Directory to generate SVG-files in" , type = "string" , dest = "output_dir" , default = os .path .abspath ('ModelicaIcons' ))
1183+ parser .add_option ("--warn-dup" , help = "Warn about duplicate files instead of generating an error" , action = "store_true" , dest = "warn_duplicates" , default = False )
11761184 parser .add_option ("--quiet" , help = "Do not output to the console" , action = "store_true" , dest = "quiet" , default = False )
11771185 (options , args ) = parser .parse_args ()
11781186 if len (args ) == 0 :
@@ -1182,6 +1190,7 @@ def main():
11821190 output_dir = options .output_dir
11831191 with_html = options .with_html
11841192 includeInvisibleText = options .includeInvisibleText
1193+ warn_duplicates = options .warn_duplicates
11851194
11861195 # create logger with 'spam_application'
11871196 global logger
@@ -1251,7 +1260,7 @@ def main():
12511260 # try:
12521261 base_classes = []
12531262 getBaseClasses (modelica_class , base_classes )
1254- dwg = exportIcon (modelica_class , base_classes , includeInvisibleText )
1263+ dwg = exportIcon (modelica_class , base_classes , includeInvisibleText , warn_duplicates )
12551264 dwgs .append (dwg )
12561265
12571266 logger .info ('Done: ' + modelica_class )
0 commit comments