Download raw (2.8 KB)
# -*- coding: utf-8 -*- # """ UNIFY SVG STROKES ============= This plugin processes svg pictures to unify their stroke widths """ from __future__ import unicode_literals import copy import collections import functools import os.path import re import six from xml.dom import minidom from bs4 import BeautifulSoup from pelican import signals def harvest_images(path, context): # Set default value for 'IMAGE_PROCESS_DIR'. if 'UNIFIED_OUTPUT_DIR' not in context: context['UNIFIED_OUTPUT_DIR'] = 'unified' if 'UNIFIED_STROKE_WIDTH' not in context: context['UNIFIED_STROKE_WIDTH'] = '2px' with open(path, 'r+') as f: res = harvest_images_in_fragment(f, context) f.seek(0) f.truncate() f.write(res) def harvest_images_in_fragment(fragment, settings): parser = settings.get("UNIFIED_PARSER", "html.parser") soup = BeautifulSoup(fragment, parser) for img in soup.find_all('img'): if os.path.splitext(img['src'])[1] == '.svg': process_img_tag(img, settings) return str(soup) def process_img_tag(img, settings): process_dir = settings['UNIFIED_OUTPUT_DIR'] url_path, filename = os.path.split(img['src']) base_url = os.path.join(url_path, process_dir) source = os.path.join(settings['PATH'], img['src'][1:]) base_path = os.path.join(settings['OUTPUT_PATH'], base_url[1:]) img['src'] = os.path.join(base_url, filename) destination = os.path.join(base_path, filename) unify_strokes(source, destination, settings['UNIFIED_STROKE_WIDTH']) def set_vector_scale (node, width): if node.hasAttribute('style'): node.setAttribute('style', node.getAttribute('style') + ';vector-effect:non-scaling-stroke;stroke-width: {};'.format(width)) else: node.setAttribute('style', 'vector-effect:non-scaling-stroke;stroke-width: {};'.format(width)) def unify_strokes (source, destination, width): path, _ = os.path.split(destination) try: os.makedirs(path) except OSError as e: if e.errno == 17: # Already exists pass # If original image is older than existing derivative, skip # processing to save time, unless user explicitely forced # image generation. if (not os.path.exists(destination) or os.path.getmtime(source) > os.path.getmtime(destination)): doc = minidom.parse(source) # parseString also exists paths = doc.getElementsByTagName('path') for path in paths: set_vector_scale(path, width) lines = doc.getElementsByTagName('line') for line in lines: set_vector_scale(line, width) with open(destination, 'w') as o: doc.writexml(o) def register(): signals.content_written.connect(harvest_images)