Jump to content

User:User A1/svgTinker.py

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by User A1 (talk | contribs) at 14:53, 6 July 2009 (Version 1 OK). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
  1. !/usr/bin/python


from BeautifulSoup import BeautifulStoneSoup import string import sys import re


def epsilon(): eps=float(1.0);

while eps + 1.0 > 1.0 : eps = eps//2;

return eps;


  1. Takes a stone-soup tag and applies various
  2. workaround fixes of dubious effectiveness

def fontFix(tag):

print type(tag); bold=False; italic=False; dejavu=False;

dejaVuRe=re.compile("'?(?i)dejavusans.*") boldRe=re.compile("(?i).*-bold.*"); italicRe=re.compile("(?i).*-italic.*"); fontRe=re.compile("(?i)-.*");

for i in tag.attrs :

print i if i[0] == "font-family" : #Check the font types and perform font substitution bold=boldRe.match(i[1]); italic=italicRe.match(i[1]); dejavu=dejaVuRe.match(i[1]); #Strip font bold/italic embed tmp = fontRe.split(i[1]); fontAttr=tmp[0]; i = (i[0],fontAttr) break;


#if none of the above apply we can skip if(not bold and not italic and not dejavu): return;

str=""

if (bold) : str=str+"bad bolding method "; if(italic): str=str+"bad italicising method "; if(dejavu): str=str+"wrong font name";

print "Fixing tag : " + str print tag #Otherwise we have work to do!

haveWeight=False; haveStyle=False;

for i in tag.attrs: #find any bold font-weight tag if i[0] == "font-weight": haveWeight=True; continue; if i[0] == "font-style": haveStyle=True; continue;


#Check for bold if(bold): if(haveWeight): if not re.match(i[1],".*(?i)bold.*"): tag["font-weight"]+=";Bold"; else: tag["font-weight"]="Bold";

tag["font-family"]=re.sub("(?i)-Bold","",tag["font-family"])


#Check for italics if(italic and haveStyle ): if not re.match(i[1],".*(?i)italic.*"): tag["font-style"]+=";Italic"; else: if italic and not haveStyle: tag["font-style"]="Italic";

#Fix dejavu vs Deja Vu if (dejavu): tag["font-family"]="DejaVu Sans";


  1. Check to see if a small font is being used in conjunction with

def fontSizeFix(tag):

#without a transformatio there is nothing we can do if(not tag["transform"] ) : return


#grab the matrix trans=re.sub(".*(?i)matrix\(","",tag["transform"]);

trans=re.sub("\)","",trans);

#split the transformation matirx m = re.split("(\ |,)",trans);

m=filter(lambda x: not (x=="" or x==" " or x==",") ,m);

#Transform should be of the form y=Mx+b print m assert(len(m) == 6);

mF=[]; for i in m: mF.append(float(i));

m=mF;


print m EPSILON=0.001; if(abs(m[1]) < EPSILON and abs(m[2]) < EPSILON ): #OK, so M is a diagonal matrix print "so far so good" if abs(m[0]) > abs(m[3]) : factor=m[0]; else: factor=m[3];


if (factor > 1 ): #Pump up the font size by factor, then reduce the matrix fontSize =float(tag["font-size"]); tag["font-size"] = fontSize*factor;


m[0] = m[0]/factor; m[3] = m[3]/factor;


tag["transform"] = "matrix(" + str(m[0]) + " " + str(m[1]) + " " + str(m[2]) + " " + str(m[3]) + " "+ str(m[4]) + " " + str(m[5]) + ")";

return;


  1. Crappy font substitution routine

def fontSub(tag):


preferredFont = []; preferredFont.append((re.compile("(?i)Arial.*"),"DejaVu Sans")); preferredFont.append((re.compile("(?i)Times new roman.*"),"Times"));

for i in tag.attrs : if i[0] == "font-family" : #Substitute fonts from our preferred font table for j in preferredFont: if j[0].match(i[1]): tag["font-family"]=j[1]; break; return;


def main():

if(not len(sys.argv) == 3): print "Usage: svgTinker.py inputFile outputFile" quit(1);

f = open(sys.argv[1]);

if not f : print "File does not exist or could not be read" quit(1)


xmlText = f.read();

soup=BeautifulStoneSoup(xmlText);


tags=soup.findAll("text");

#Correct all font tags for i in tags: fontTag=False; if(len(i.attrs)): for j in i.attrs : if re.match("(?i)font-family",j[0]): fontTag=True;

break;

if fontTag : fontFix(i); fontSizeFix(i); fontSub(i); continue;


tags=soup.findAll("tspan");

#Nuke the tspans, preserving children for i in tags: i.extract();


try: f=open(sys.argv[2],'w'); except: print('Unable to open file for writing. aborting'); quit(1);


#save modified svg data f.write(str(soup));


print("Wrote file : " + sys.argv[2]);


if __name__ == "__main__": main()