[ Index ] |
|
Code source de Kupu-1.3.5 |
1 # Portal transform for images with captions 2 # 3 # We want to be able to support captions in images. 4 # The easiest way to do this is to define a Portal Transform which is 5 # applied to the HTML body text on output. 6 # 7 # The transform finds all the embedded images, and replaces them with 8 # an appropriate chunk of HTML to include the caption. 9 # 10 from Products.CMFCore.utils import getToolByName 11 from Products.PortalTransforms.interfaces import itransform 12 from DocumentTemplate.DT_Util import html_quote 13 from DocumentTemplate.DT_Var import newline_to_br 14 import re 15 16 __revision__ = '$Id$' 17 18 # IMAGE_PATTERN matches an image tag on its own, or an image tag 19 # enclosed in a simple <p> or <div>. In the latter case we strip out 20 # the enclosing tag since we are going to insert our own. 21 PATIMG = '\\<img[^>]+class=[^=>]*captioned[^>]+\\>' 22 PATA = '(?:\\<a[^>]*\\>'+PATIMG+'\\</a\\>)' + '|' + PATIMG 23 PAT0 = '('+PATA+')' 24 PAT1 = '<(?:p|div)[^>]*>'+PAT0 + '</(?:p|div)>' + '|' + PAT0 25 IMAGE_PATTERN = re.compile(PAT1, re.IGNORECASE) 26 27 # Regex to match stupid IE attributes. In IE generated HTML an 28 # attribute may not be enclosed by quotes if it doesn't contain 29 # certain punctuation. 30 ATTR_VALUE = '=(?:"?)(?P<%s>(?<=")[^"]*|[^ \/>]*)' 31 ATTR_CLASS = ATTR_VALUE % 'class' 32 ATTR_WIDTH = ATTR_VALUE % 'width' 33 34 ATTR_PATTERN = re.compile(''' 35 (?P<tag>\< 36 ( class%s 37 | src="resolveuid/(?P<src>([^/"#? ]*)) 38 | width%s 39 | . 40 )*\> 41 )''' % (ATTR_CLASS, ATTR_WIDTH), re.VERBOSE) 42 43 CLASS_PATTERN = re.compile('\s*class=("[^"]*captioned[^"]*"|[^" \/>]+)') 44 IMAGE_TEMPLATE = '''\ 45 <div class="%(class)s" style="width:%(width)spx;"> 46 <div style="width:%(width)spx;"> 47 %(tag)s 48 </div> 49 <div class="image-caption"> 50 %(caption)s 51 </div> 52 </div> 53 ''' 54 55 UID_PATTERN = re.compile('(?P<tag><(?:a|img) [^>]*(?:src|href)=")(?P<url>[^"]*resolveuid/(?P<uid>[^"#? ]*))') 56 57 class HTMLToCaptioned: 58 """Transform which adds captions to images embedded in HTML""" 59 __implements__ = itransform 60 __name__ = "html_to_captioned" 61 inputs = ('text/html',) 62 output = "text/x-html-captioned" 63 64 def __init__(self, name=None): 65 self.config_metadata = { 66 'inputs' : ('list', 'Inputs', 'Input(s) MIME type. Change with care.'), 67 } 68 if name: 69 self.__name__ = name 70 71 def name(self): 72 return self.__name__ 73 74 def __getattr__(self, attr): 75 if attr == 'inputs': 76 return self.config['inputs'] 77 if attr == 'output': 78 return self.config['output'] 79 raise AttributeError(attr) 80 81 def convert(self, data, idata, filename=None, **kwargs): 82 """convert the data, store the result in idata and return that 83 optional argument filename may give the original file name of received data 84 additional arguments given to engine's convert, convertTo or __call__ are 85 passed back to the transform 86 87 The object on which the translation was invoked is available as context 88 (default: None) 89 """ 90 context = kwargs.get('context', None) 91 if context: 92 at_tool = context.archetype_tool 93 94 if context and at_tool: 95 def replaceImage(match): 96 tag = match.group(1) or match.group(2) 97 attrs = ATTR_PATTERN.match(tag) 98 src = attrs.group('src') 99 klass = attrs.group('class') 100 width = attrs.group('width') 101 if src: 102 d = attrs.groupdict() 103 target = at_tool.reference_catalog.lookupObject(src) 104 if target: 105 d['caption'] = newline_to_br(target.Description()) 106 d['tag'] = CLASS_PATTERN.sub('', d['tag']) 107 if not width: 108 d['width'] = target.getWidth() 109 110 return IMAGE_TEMPLATE % d 111 return match.group(0) # No change 112 113 html = IMAGE_PATTERN.sub(replaceImage, data) 114 115 # Replace urls that use UIDs with human friendly urls. 116 def replaceUids(match): 117 tag = match.group('tag') 118 uid = match.group('uid') 119 target = at_tool.reference_catalog.lookupObject(uid) 120 if target: 121 return tag + target.absolute_url() 122 return match.group(0) 123 124 html = UID_PATTERN.sub(replaceUids, html) 125 126 idata.setData(html) 127 return idata 128 129 # No context to use for replacements, so don't bother trying. 130 return data 131 132 def register(): 133 return HTMLToCaptioned() 134 135 def initialize(): 136 engine = getToolByName(portal, 'portal_transforms') 137 engine.registerTransform(register())
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 15:30:41 2007 | par Balluche grâce à PHPXref 0.7 |