"""Python-Markdown extension: image sizing. Syntax (standard Markdown paths, relative to chapter file): ![alt](../assets/x.png){s=50%} → scale to 50% (width, auto height) ![alt](../assets/x.png){w=50%} → width 50%, auto height ![alt](../assets/x.png){w=50%, h=300} → width 50%, max-height 300px ![alt](../assets/x.png) → default: s=75% """ import re from markdown.extensions import Extension from markdown.inlinepatterns import ImageInlineProcessor IMG_RE = ( r'\!\[(?P.*?)\]\((?P[^)]+)\)' r'(?:\{' r'(?:s=(?P\d+%))?' r'(?:,\s*)?' r'(?:w=(?P\d+%))?' r'(?:,\s*h=(?P\d+)(?:px)?)?' r'\}?)?' ) class SizedImageProcessor(ImageInlineProcessor): def handleMatch(self, m, data): alt = m.group('alt') src = m.group('src') scale = m.group('s') width = m.group('w') height = m.group('h') # Normalize paths for HTML output src = src.replace('../assets/', 'assets/') src = src.replace('../circuits/output/', 'assets/') if scale: style = f'width:{scale}; height:auto; max-width:none; max-height:none' elif width: style = f'width:{width}; max-width:none' if height: style += f'; max-height:{height}px' else: style = 'width:75%; height:auto' img_tag = f'{alt}' el = self.md.htmlStash.store(img_tag) return el, m.start(0), m.end(0) class ImageRowProcessor(Extension): def extendMarkdown(self, md): md.inlinePatterns.register( SizedImageProcessor(IMG_RE, md), 'image_sized', 160, ) md.inlinePatterns.deregister('image_link') def makeExtension(**kwargs): return ImageRowProcessor(**kwargs)