TL;DR; Summary and code
This little script replaces certain properties in an SVG. By default, it only looks first at the file you pass in. Be aware that the wrong replacement can break your SVG. For this reason, the script makes a new SVG by default. As always, the GitHub gist should be the up-to-date version.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ********** Careful, you may break SVG graphics with this************
# ********************** READ THE BELOW FIRST ************************
# ********************** No warranty is taken ************************
# By default nothing other than finding RGB codes in the SVG is done
# and only if you want to change something you can change what you want
# to change (inprop) to what it should be (outprop). For this to work
# set inspect to False.
def svg_property_replacer(file,
path='',
inspect='rgb',
inprop='rgb(0%,0%,0%)',
outprop='rgb(100%,0%,0%)',
outfile='',
force=False):
import os
if not outfile:
outfile = file[:-4]+'_replaced.svg'
# does the file even exist?
if not os.path.exists(path+file):
# answer no, it doesn't, report it, return False
print('File does not exist')
return False
elif not (path+file).endswith('.svg'):
# answer yes, it does, but isn't an svg, report False
print('File is not an SVG')
return False
else:
# yes the file exists
# read the file in
with open(path+file) as fo:
img = [line for line in fo.readlines()]
if 'svg' not in img[0] and 'svg' not in img[1]:
# it seemed like a svg, but is not a proper one, this may be
# a mistake by the program that produced it in the first place
print('Warning! No SVG tag has been found at the start of', file)
print('For safety reasons only inspection is done.',
'Set force to override.')
print('First lines were', img[0], img[1])
if not force:
inspect = 'svg'
if inspect:
# look for the inspect string in the lines and print them to stdout
found = 0
for _ in img:
if inspect in _:
print(inspect+_.split(inspect)[1].split(';')[0])
found = 1
return found
else:
# look for the inprop string in the lines and replace with outprop
for _ in range(len(img)):
img[_] = img[_].replace(inprop, outprop)
# write the outfile as _replaced
with open(path+outfile, 'w') as fo:
fo.writelines(img)
return outfile
if __name__ == '__main__':
###### EXAMPLE ######
# This example turns the SVG into "darkmode", but be careful
# the results may vary, depending on the original file, i.e. if there is
# some text in black it'll be white and that may not always make sense
# the same for big white areas. Just try it out
path = '~'
file = 'test.svg'
file = path+file
props = [['rgb(0%,0%,0%)','REPLACEMEAGAIN'],
['rgb(100%,100%,100%)', 'rgb(0%,0%,0%)'],
['REPLACEMEAGAIN', 'rgb(100%,100%,100%)'],
['<svg ', '<svg style="background-color: rgb(15%,15%,15%);" '],
]
# file will be named the same with appended _dark
outfile = file.split('.svg')
outfile = outfile[0] + '_dark.svg'
for inprop, outprop in props:
# make another file first, so we can try out different things
if [inprop,outprop] == props[0]:
infile = file
else:
# then overwrite the same file always to just have one
infile = outfile
svg_property_replacer(infile,
outfile=outfile,
inprop=inprop,
outprop=outprop,
inspect=False,
)
Background & motivation
Say you have an SVG, either made by yourself, from a colleague or by extracting from a PDF. This is a great starting point and editing vector graphics is often far more comfortable than raster graphics as you won’t have to edit single pixels. Now you could edit this file in Inkscape, illustrator, or any of the many other software solutions. But if all you want to do is change a certain color, or remove some part of the graphics, you can do that without installing any other software. Instead, you can open the SVG file with your text editor of choice and search for the colour you want to replace (note that colours in SVG files are generally in the hexadecimal form, i.e. #RRGGBB, a search for “colour picker” will generally help you figure out what to look for/pick as replacement). It might be a good idea to back up your file beforehand as well. So let’s say you have the following rectangle in your SVG:
<rect
style="opacity:0.89;fill:#ffffff;stroke-width:0.264583;stroke:#000000;stroke-opacity:1"
id="rect165"
width="50"
height="35"
x="90"
y="80" />
This will be a bit transparent, white filled with a black solid border (I added another rectangle just for show):
You can first search for “fill:” or for “stroke:” to see the occurrences of colour uses in your file and in other places. As you can see, it can also be useful and simple to change the opacity or similar by simply editing the file and changing that one value, for example, the red to light blue (replacing #ff0000 with #3399ff):
But most likely you want to do more/change more than one occurrence and/or more than one property. This is where the above script comes in, as you can run it like the example at the bottom of the script and change many properties in a row (note that the REPLACEME
is so that we don’t just change everything from white to black and then both previous ones back to black.
Enjoy using it and easily changing your SVGs!