better_figures_and_images.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """
  2. Better Figures & Images
  3. ------------------------
  4. This plugin:
  5. - Adds a style="width: ???px; height: auto;" to each image in the content
  6. - Also adds the width of the contained image to any parent div.figures.
  7. - If RESPONSIVE_IMAGES == True, also adds style="max-width: 100%;"
  8. - Corrects alt text: if alt == image filename, set alt = ''
  9. TODO: Need to add a test.py for this plugin.
  10. """
  11. from os import path, access, R_OK
  12. from pelican import signals
  13. from bs4 import BeautifulSoup
  14. from PIL import Image
  15. import logging
  16. logger = logging.getLogger(__name__)
  17. def content_object_init(instance):
  18. if instance._content is not None:
  19. content = instance._content
  20. soup = BeautifulSoup(content)
  21. if 'img' in content:
  22. for img in soup('img'):
  23. logger.debug('Better Fig. PATH: %s', instance.settings['PATH'])
  24. logger.debug('Better Fig. img.src: %s', img['src'])
  25. img_path, img_filename = path.split(img['src'])
  26. logger.debug('Better Fig. img_path: %s', img_path)
  27. logger.debug('Better Fig. img_fname: %s', img_filename)
  28. # Strip off {filename}, |filename| or /static
  29. if img_path.startswith(('{filename}', '|filename|')):
  30. img_path = img_path[10:]
  31. elif img_path.startswith('/static'):
  32. img_path = img_path[7:]
  33. else:
  34. logger.warning('Better Fig. Error: img_path should start with either {filename}, |filename| or /static')
  35. # Build the source image filename
  36. src = instance.settings['PATH'] + img_path + '/' + img_filename
  37. logger.debug('Better Fig. src: %s', src)
  38. if not (path.isfile(src) and access(src, R_OK)):
  39. logger.error('Better Fig. Error: image not found: {}'.format(src))
  40. # Open the source image and query dimensions; build style string
  41. im = Image.open(src)
  42. extra_style = 'width: {}px; height: auto;'.format(im.size[0])
  43. if instance.settings['RESPONSIVE_IMAGES']:
  44. extra_style += ' max-width: 100%;'
  45. if img.get('style'):
  46. img['style'] += extra_style
  47. else:
  48. img['style'] = extra_style
  49. if img['alt'] == img['src']:
  50. img['alt'] = ''
  51. fig = img.find_parent('div', 'figure')
  52. if fig:
  53. if fig.get('style'):
  54. fig['style'] += extra_style
  55. else:
  56. fig['style'] = extra_style
  57. instance._content = soup.decode()
  58. def register():
  59. signals.content_object_init.connect(content_object_init)