def box (self, hdr, bdy, clr='#c4c4ff'): #if hasattr (self, boxcolor): # clr = self.boxcolor #else: # clr = boxcolor #images = getimages (self) #pix = str (images.pix) t = type (bdy) insert = '' if isFolder (bdy): bdy = bdy.__dict__ t = DictionaryType if t in (ListType, TupleType): for x in bdy: insert = insert + tr (boxside (clr) + tdcenter (x) + boxside (clr)) elif t is DictionaryType: for (k,v) in bdy.items(): insert = insert + tr (boxside (clr) + tdcenter (html_quote (str(k))) + tdcenter (html_quote (str(v))) + boxside (clr)) else: #insert = tr (boxside (clr) + tdcenter (html_quote (str (bdy))) + tdcenter (bdy) + boxside (clr)) #insert = tr (boxside (clr) + tdcenter (html_quote (str (bdy))) + boxside (clr)) insert = tr (boxside (clr) + tdcenter (str (bdy(self))) + boxside (clr)) result = boxtop (clr, hdr) + \ insert + \ boxbottom (clr, pix) return result
def checklink(match): matched = match.group(0) newlink = link = decodeEntities(match.group('href')) classification, uid, relpath, tail = self.classifyLink(link, base) if self.action=='check': if classification=='bad': abslink = urljoin(base, link) before, after = self.link_summary(data, match.start(), link) summary = {'text':link, 'url':abslink, 'before': before, 'after': after, } info.append(summary) elif self.action=='touid': if classification=='internal': if uid and uid==objuid: newlink = tail elif uid: newlink = 'resolveuid/%s%s' % (uid, tail) else: newlink = relpath+tail elif self.action=='topath': if classification=='internal': newlink = relpath+tail if newlink != link: prefix = match.group('prefix') newlink = html_quote(newlink).encode('ascii', 'xmlcharrefreplace') changes.append((match.start()+len(prefix), match.end(), newlink)) return prefix + newlink return matched
def _edit(self, text): """ Edit the Document and cook the body. """ self._size = len(text) text_format = self.text_format if not text_format: text_format = self.text_format if text_format != 'html': normalizer = queryUtility(ILinebreakNormalizer) if normalizer is not None: self.text = normalizer.normalizeIncoming(self, text) else: self.text = text else: self.text = text if text_format == 'html': self.cooked_text = text elif text_format == 'plain': self.cooked_text = html_quote(text).replace('\n', '<br />') elif text_format == 'restructured-text': self.cooked_text = ReST(text, initial_header_level=self._rest_level) else: self.cooked_text = stx2html(text, level=self._stx_level, header=0)
def handle_captioned_image(self, attributes, image, fullimage, elem, caption): """Handle captioned image. The img element is replaced by a definition list as created by the template ../browser/captioned_image.pt """ klass = ' '.join(attributes['class']) del attributes['class'] del attributes['src'] if 'width' in attributes: attributes['width'] = int(attributes['width']) if 'height' in attributes: attributes['height'] = int(attributes['height']) view = fullimage.unrestrictedTraverse('@@images', None) if view is not None: original_width, original_height = view.getImageSize() else: original_width, original_height = fullimage.width, fullimage.height if image is not fullimage: # image is a scale object tag = image.tag width = image.width else: if hasattr(aq_base(image), 'tag'): tag = image.tag else: tag = view.scale().tag width = original_width options = { 'class': klass, 'originalwidth': attributes.get('width', None), 'originalalt': attributes.get('alt', None), 'url_path': fullimage.absolute_url_path(), 'caption': newline_to_br(html_quote(caption)), 'image': image, 'fullimage': fullimage, 'tag': tag(**attributes), 'isfullsize': image is fullimage or ( image.width == original_width and image.height == original_height), 'width': attributes.get('width', width), } captioned = BeautifulSoup( self.captioned_image_template(**options), 'html.parser') # if we are a captioned image within a link, remove and occurrences # of a tags inside caption template to preserve the outer link if bool(elem.find_parent('a')): captioned.a.unwrap() elem.replace_with(captioned)
def _edit(self, text): """ Edit the Document and cook the body. """ self.text = text self._size = len(text) text_format = self.text_format if text_format == 'html': self.cooked_text = text elif text_format == 'plain': self.cooked_text = html_quote(text).replace('\n', '<br />') else: self.cooked_text = HTML(text, level=self._stx_level, header=0)
def handle_captioned_image(self, attributes, image, fullimage, caption): """Handle captioned image. """ klass = attributes['class'] del attributes['class'] del attributes['src'] if 'width' in attributes: attributes['width'] = int(attributes['width']) if 'height' in attributes: attributes['height'] = int(attributes['height']) view = fullimage.unrestrictedTraverse('@@images', None) if view is not None: original_width, original_height = view.getImageSize() else: original_width, original_height = fullimage.width, fullimage.height if image is not fullimage: # image is a scale object tag = image.tag width = image.width else: if hasattr(aq_base(image), 'tag'): tag = image.tag else: tag = view.scale().tag width = original_width options = { 'class': klass, 'originalwidth': attributes.get('width', None), 'originalalt': attributes.get('alt', None), 'url_path': fullimage.absolute_url_path(), 'caption': newline_to_br(html_quote(caption)), 'image': image, 'fullimage': fullimage, 'tag': tag(**attributes), 'isfullsize': image is fullimage or ( image.width == original_width and image.height == original_height), 'width': attributes.get('width', width), } if self.in_link: # Must preserve original link, don't overwrite # with a link to the image options['isfullsize'] = True captioned_html = self.captioned_image_template(**options) if isinstance(captioned_html, unicode): captioned_html = captioned_html.encode('utf8') self.append_data(captioned_html)
def getDocumentComparisons(self, max=10, filterComment=0): """Get history as unified diff """ mTool = getToolByName(self, 'portal_membership') histories = list(self.getHistories()) if max > len(histories): max = len(histories) lst = [] for revisivon in range(1, max): oldObj, oldTime, oldDesc, oldUser = histories[revisivon] newObj, newTime, newDesc, newUser = histories[revisivon - 1] oldText = oldObj.getHistorySource().split("\n") newText = newObj.getHistorySource().split("\n") # newUser is a string 'user' or 'folders to acl_users user' member = mTool.getMemberById(newUser.split(' ')[-1]) lines = [ html_quote(line) for line in difflib.unified_diff(oldText, newText) ][3:] description = newDesc if filterComment: relativUrl = self.absolute_url(1) description = '<br />\n'.join( [line for line in description.split('\n') if line.find(relativUrl) != -1] ) else: description.replace('\n', '<br />\n') if lines: lst.append({ 'lines': lines, 'oldTime': oldTime, 'newTime': newTime, 'description': description, 'user': newUser, 'member': member }) return lst
def handle_captioned_image(self, attributes, image, fullimage, caption): """Handle captioned image. """ klass = attributes["class"] del attributes["class"] del attributes["src"] if "width" in attributes: attributes["width"] = int(attributes["width"]) if "height" in attributes: attributes["height"] = int(attributes["height"]) view = fullimage.unrestrictedTraverse("@@images", None) if view is not None: original_width, original_height = view.getImageSize() else: original_width, original_height = fullimage.width, fullimage.height if image is not fullimage: # image is a scale object tag = image.tag width = image.width else: if hasattr(aq_base(image), "tag"): tag = image.tag else: tag = view.scale().tag width = original_width options = { "class": klass, "originalwidth": attributes.get("width", None), "originalalt": attributes.get("alt", None), "url_path": fullimage.absolute_url_path(), "caption": newline_to_br(html_quote(caption)), "image": image, "fullimage": fullimage, "tag": tag(**attributes), "isfullsize": image is fullimage or (image.width == original_width and image.height == original_height), "width": attributes.get("width", width), } if self.in_link: # Must preserve original link, don't overwrite # with a link to the image options["isfullsize"] = True captioned_html = self.captioned_image_template(**options) if isinstance(captioned_html, unicode): captioned_html = captioned_html.encode("utf8") self.append_data(captioned_html)
def test_Htmltag_removal_and_formatchange(self): # Test for http://www.zope.org/Collectors/CMF/214 d = self._makeOne('foo') quoted_html = html_quote(BASIC_HTML) # Put HTML into a plain text document d.edit(text_format='plain', text=BASIC_HTML) new_body = d.CookedBody() self.failIf(new_body==BASIC_HTML) self.failUnless(new_body.startswith(quoted_html[:5])) # Now we change the format. The body *must* change because # the format change will trigger re-cooking old_body = d.CookedBody() d.setFormat('html') new_body = d.CookedBody() self.failIf(old_body==new_body) self.failIf(new_body==BASIC_HTML)
def format_tokenizer(self, toktype, toktext, sx, ex, line): """ Token handler. """ (srow, scol) = sx (erow, ecol) = ex oldpos = self.pos newpos = self.lines[srow] + scol self.pos = newpos + len(toktext) # skip encoding if six.PY3 and toktype == tokenize.ENCODING: return # handle newlines if toktype in [token.NEWLINE, tokenize.NL]: self.out.write(b'\n') return # send the original whitespace, if needed if newpos > oldpos: self.out.write(self.raw[oldpos:newpos]) # skip indenting tokens if toktype in [token.INDENT, token.DEDENT]: self.pos = newpos return # map token type to a group if token.LPAR <= toktype and toktype <= token.OP: toktype = 'OP' elif toktype == token.NAME and keyword.iskeyword(toktext): toktype = 'KEYWORD' else: toktype = tokenize.tok_name[toktype] open_tag = self.tags.get('OPEN_' + toktype, self.tags['OPEN_TEXT']) close_tag = self.tags.get('CLOSE_' + toktype, self.tags['CLOSE_TEXT']) # send text self.out.write(open_tag) self.out.write(six.b(html_quote(toktext))) self.out.write(close_tag)
def pt_render(self, source=0, extra_context={}): self._updateFromFS() # Make sure the template has been loaded. try: if not source: # Hook up to caching policy. REQUEST = getattr( self, 'REQUEST', None ) if REQUEST: content = aq_parent( self ) mgr = getToolByName( content , 'caching_policy_manager' , None ) if mgr: view_name = self.getId() RESPONSE = REQUEST[ 'RESPONSE' ] headers = mgr.getHTTPCachingHeaders( content , view_name , extra_context ) for key, value in headers: RESPONSE.setHeader( key, value ) return FSPageTemplate.inheritedAttribute('pt_render')( self, source, extra_context ) except RuntimeError: if Globals.DevelopmentMode: err = FSPageTemplate.inheritedAttribute( 'pt_errors' )( self ) if not err: err = sys.exc_info() err_type = err[0] err_msg = '<pre>%s</pre>' % replace( str(err[1]), "\'", "'" ) msg = 'FS Page Template %s has errors: %s.<br>%s' % ( self.id, err_type, html_quote(err_msg) ) raise RuntimeError, msg else: raise
def _edit(self, text, text_format='', safety_belt=''): """ Edit the Document and cook the body. """ if not self._safety_belt_update(safety_belt=safety_belt): msg = ("Intervening changes from elsewhere detected." " Please refetch the document and reapply your changes." " (You may be able to recover your version using the" " browser 'back' button, but will have to apply them" " to a freshly fetched copy.)") raise EditingConflict(msg) self.text = text if not text_format: text_format = self.text_format if text_format == 'html': self.cooked_text = text elif text_format == 'plain': self.cooked_text = html_quote(text).replace('\n', '<br />') else: self.cooked_text = HTML(text, level=self._stx_level, header=0)
def pt_render(self, source=0, extra_context={}): self._updateFromFS() # Make sure the template has been loaded. try: result = FSPageTemplate.inheritedAttribute('pt_render')( self, source, extra_context ) if not source: _setCacheHeaders(self, extra_context) return result except RuntimeError: if Globals.DevelopmentMode: err = FSPageTemplate.inheritedAttribute( 'pt_errors' )( self ) if not err: err = sys.exc_info() err_type = err[0] err_msg = '<pre>%s</pre>' % replace( str(err[1]), "\'", "'" ) msg = 'FS Page Template %s has errors: %s.<br>%s' % ( self.id, err_type, html_quote(err_msg) ) raise RuntimeError, msg else: raise
def _edit(self, text, text_format='', safety_belt=''): """ Edit the Document and cook the body. """ if not self._safety_belt_update(safety_belt=safety_belt): msg = ("Intervening changes from elsewhere detected." " Please refetch the document and reapply your changes." " (You may be able to recover your version using the" " browser 'back' button, but will have to apply them" " to a freshly fetched copy.)") raise EditingConflict(msg) self.text = text self._size = len(text) if not text_format: text_format = self.text_format if text_format == 'html': self.cooked_text = text elif text_format == 'plain': self.cooked_text = html_quote(text).replace('\n', '<br />') else: self.cooked_text = HTML(text, level=self._stx_level, header=0)
def __call__(self, toktype, toktext, sx, ex, line): """ Token handler. """ (srow, scol) = sx (erow, ecol) = ex oldpos = self.pos newpos = self.lines[srow] + scol self.pos = newpos + len(toktext) # handle newlines if toktype in [token.NEWLINE, tokenize.NL]: self.out.write('\n') return # send the original whitespace, if needed if newpos > oldpos: self.out.write(self.raw[oldpos:newpos]) # skip indenting tokens if toktype in [token.INDENT, token.DEDENT]: self.pos = newpos return # map token type to a group if token.LPAR <= toktype and toktype <= token.OP: toktype = 'OP' elif toktype == token.NAME and keyword.iskeyword(toktext): toktype = 'KEYWORD' else: toktype = tokenize.tok_name[toktype] open_tag = self.tags.get('OPEN_' + toktype, self.tags['OPEN_TEXT']) close_tag = self.tags.get('CLOSE_' + toktype, self.tags['CLOSE_TEXT']) # send text self.out.write(open_tag) self.out.write(html_quote(toktext)) self.out.write(close_tag)
def _edit(self, text, text_format='', safety_belt=''): """ Edit the Document - Parses headers and cooks the body""" headers = {} level = self._stx_level if not text_format: text_format = self.text_format if not safety_belt: safety_belt = headers.get('SafetyBelt', '') if not self._safety_belt_update(safety_belt=safety_belt): msg = ("Intervening changes from elsewhere detected." " Please refetch the document and reapply your changes." " (You may be able to recover your version using the" " browser 'back' button, but will have to apply them" " to a freshly fetched copy.)") raise 'EditingConflict', msg if text_format == 'html': self.text = self.cooked_text = text elif text_format == 'plain': self.text = text self.cooked_text = html_quote(text).replace('\n', '<br>') else: self.cooked_text = _format_stx(text=text, level=level) self.text = text
def _isReadOnlyEditor(self, html_text, document, text_content): """ Tries to find in the HTML page string portions which show that text content is displayed in read only mode with 'page' CSS class in a <div> html_text -- the HTML string to analyze document -- the document which content is displayed in read only mode """ html_text = html_text.encode('utf-8') match_string1 = "data-gadget-editable=" match_string2 = 'data-gadget-value="%s"' % html_quote(text_content) if html_text.find(match_string1) != -1: print html_text print match_string1 return False if html_text.find(match_string2) == -1: print html_text print match_string2 return False return True
def _edit(self, text, text_format='', safety_belt=''): """ Edit the Document - Parses headers and cooks the body""" headers = {} level = self._stx_level if not text_format: text_format = self.text_format if not safety_belt: safety_belt = headers.get('SafetyBelt', '') if not self._safety_belt_update(safety_belt=safety_belt): msg = ("Intervening changes from elsewhere detected." " Please refetch the document and reapply your changes." " (You may be able to recover your version using the" " browser 'back' button, but will have to apply them" " to a freshly fetched copy.)") raise 'EditingConflict', msg if text_format == 'html': self.text = self.cooked_text = text elif text_format == 'plain': self.text = text self.cooked_text = html_quote(text).replace('\n','<br>') else: self.cooked_text = _format_stx(text=text, level=level) self.text = text
def pt_render(self, source=0, extra_context={}): self._updateFromFS() # Make sure the template has been loaded. try: if not source: # Hook up to caching policy. REQUEST = getattr(self, 'REQUEST', None) if REQUEST: content = aq_parent(self) mgr = getToolByName(content, 'caching_policy_manager', None) if mgr: view_name = self.getId() RESPONSE = REQUEST['RESPONSE'] headers = mgr.getHTTPCachingHeaders( content, view_name, extra_context) for key, value in headers: RESPONSE.setHeader(key, value) return FSPageTemplate.inheritedAttribute('pt_render')( self, source, extra_context) except RuntimeError: if Globals.DevelopmentMode: err = FSPageTemplate.inheritedAttribute('pt_errors')(self) if not err: err = sys.exc_info() err_type = err[0] err_msg = '<pre>%s</pre>' % replace(str(err[1]), "\'", "'") msg = 'FS Page Template %s has errors: %s.<br>%s' % ( self.id, err_type, html_quote(err_msg)) raise RuntimeError, msg else: raise
def _isFCKEditor(self, html_text, field_id, text_content): """ Tries to find in the HTML page string portions which show that text content is displayed using FCKEditor for the given field_id html_text -- the HTML string to analyze field_id -- the id of the field in the form text_content -- the embedded text content """ html_text = html_text.encode('utf-8') match_string1 = 'data-gadget-editable="field_%s"' % field_id match_string2 = 'data-gadget-value="%s"' % html_quote(text_content) if html_text.find(match_string1) == -1: print html_text print match_string1 return False if html_text.find(match_string2) == -1: print html_text print match_string2 return False return True
def htmlchanges(data, changes): out = [] prev = 0 lastend = 0 for s,e,new in changes: start = max(prev, s-10) if start != prev: if start-10 > prev: out.append(html_quote(data[prev:prev+10])) out.append('...') else: out.append(html_quote(data[prev:start])) out.append(html_quote(data[start:s])) out.append('<del>%s</del>' % html_quote(data[s:e])) out.append('<ins>%s</ins>' % html_quote(new)) prev = e if prev: out.append(html_quote(data[prev:prev+10])) if prev+10 < len(data): out.append('...') return ''.join(out)
return ## map token type to a group if token.LPAR <= toktype and toktype <= token.OP: toktype = 'OP' elif toktype == token.NAME and keyword.iskeyword(toktext): toktype = 'KEYWORD' else: toktype = tokenize.tok_name[toktype] open_tag = self.tags.get('OPEN_'+toktype, self.tags['OPEN_TEXT']) close_tag = self.tags.get('CLOSE_'+toktype, self.tags['CLOSE_TEXT']) ## send text self.out.write(open_tag) self.out.write(html_quote(toktext)) self.out.write(close_tag) class PythonTransform: """Colorize Python source files """ implements(ITransform) __name__ = "python_to_html" inputs = ("text/x-python",) output = "text/html" config = { 'OPEN_NUMBER': '<span style="color: #0080C0;">', 'CLOSE_NUMBER': '</span>',
return ## map token type to a group if token.LPAR <= toktype and toktype <= token.OP: toktype = 'OP' elif toktype == token.NAME and keyword.iskeyword(toktext): toktype = 'KEYWORD' else: toktype = tokenize.tok_name[toktype] open_tag = self.tags.get('OPEN_'+toktype, self.tags['OPEN_TEXT']) close_tag = self.tags.get('CLOSE_'+toktype, self.tags['CLOSE_TEXT']) ## send text self.out.write(open_tag) self.out.write(html_quote(toktext)) self.out.write(close_tag) class PythonTransform: """Colorize Python source files """ implements(ITransform) __name__ = "python_to_html" inputs = ("text/x-python",) output = "text/html" config = { 'OPEN_NUMBER': '<span style="color: #0080C0;">',
def convert(self, orig, data, **kwargs): data.setData('<pre class="data">%s</pre>' % html_quote(orig)) return data
def replaceImage(match): """ Replace image """ tag = match.group('pat0') or match.group('pat1') attrs = ATTR_PATTERN.match(tag) atag = match.group('atag0') or match.group('atag1') src = attrs.group('src') subtarget = None m = SRC_TAIL.match(tag, attrs.end('src')) if m is not None: srctail = m.group(1) else: srctail = None if src is not None: d = attrs.groupdict() target = self.resolveuid(context, rc, src) if target is not None: d['class'] = attrs.group('class') d['originalwidth'] = attrs.group('width') d['originalalt'] = attrs.group('alt') d['url_path'] = target.absolute_url_path() d['caption'] = \ newline_to_br(html_quote(target.Description())) d['image'] = d['fullimage'] = target d['tag'] = None d['isfullsize'] = True d['width'] = target.width if srctail: if isinstance(srctail, unicode): # restrictedTraverse doesn't accept unicode srctail = srctail.encode('utf8') try: subtarget = target.restrictedTraverse(srctail) except Exception: subtarget = getattr(target, srctail, None) if subtarget is not None: d['image'] = subtarget if srctail.startswith('image_'): d['tag'] = \ target.getField('image').tag(target, scale=srctail[6:]) elif subtarget: d['tag'] = subtarget.tag() if d['tag'] is None: d['tag'] = target.tag() if subtarget is not None: d['isfullsize'] = subtarget.width == \ target.width and subtarget.height == \ target.height d['width'] = subtarget.width # Strings that may contain non-ascii characters # need to be decoded to unicode for key in ('caption', 'tag'): if isinstance(d[key], str): d[key] = d[key].decode('utf8') # Must preserve original link, don't overwrite with # a link to the image if atag is not None: d['isfullsize'] = True d['tag'] = "%s%s</a>" % (atag, d['tag']) result = template(**d) if isinstance(result, str): result = result.decode('utf8') return result return match.group(0) # No change
class Parser: """ Send colored python source. """ def __init__(self, raw, tags, out): """ Store the source text. """ self.raw = string.strip(string.expandtabs(raw)) self.out = out self.tags = tags def format(self): """ Parse and send the colored source. """ # store line offsets in self.lines self.lines = [0, 0] pos = 0 while 1: pos = string.find(self.raw, '\n', pos) + 1 if not pos: break self.lines.append(pos) self.lines.append(len(self.raw)) # parse the source and write it self.pos = 0 text = StringIO(self.raw) self.out.write('<pre class="python">\n') try: tokenize.tokenize(text.readline, self) except tokenize.TokenError as ex: msg = ex[0] line = ex[1][0] self.out.write("<h5 class='error>'ERROR: %s%s</h5>" % ( msg, self.raw[self.lines[line]:])) self.out.write('\n</pre>\n') def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line): """ Token handler. """ #print "type", toktype, token.tok_name[toktype], "text", toktext, #print "start", srow,scol, "end", erow,ecol, "<br>" ## calculate new positions oldpos = self.pos newpos = self.lines[srow] + scol self.pos = newpos + len(toktext) ## handle newlines if toktype in [token.NEWLINE, tokenize.NL]: self.out.write('\n') return ## send the original whitespace, if needed if newpos > oldpos: self.out.write(self.raw[oldpos:newpos]) ## skip indenting tokens if toktype in [token.INDENT, token.DEDENT]: self.pos = newpos return ## map token type to a group if token.LPAR <= toktype and toktype <= token.OP: toktype = 'OP' elif toktype == token.NAME and keyword.iskeyword(toktext): toktype = 'KEYWORD' else: toktype = tokenize.tok_name[toktype] open_tag = self.tags.get('OPEN_'+toktype, self.tags['OPEN_TEXT']) close_tag = self.tags.get('CLOSE_'+toktype, self.tags['CLOSE_TEXT']) ## send text self.out.write(open_tag) self.out.write(html_quote(toktext)) self.out.write(close_tag)
def handle_captioned_image(self, attributes, image, fullimage, elem, caption): """Handle captioned image. The img element is replaced by a definition list as created by the template ../browser/captioned_image.pt """ klass = ' '.join(attributes['class']) del attributes['class'] del attributes['src'] if 'width' in attributes and attributes['width']: attributes['width'] = int(attributes['width']) if 'height' in attributes and attributes['height']: attributes['height'] = int(attributes['height']) view = fullimage.unrestrictedTraverse('@@images', None) if view is not None: original_width, original_height = view.getImageSize() else: original_width, original_height = fullimage.width, fullimage.height if image is not fullimage: # image is a scale object tag = image.tag width = image.width else: if hasattr(aq_base(image), 'tag'): tag = image.tag else: tag = view.scale().tag width = original_width options = { 'class': klass, 'originalwidth': attributes.get('width', None), 'originalalt': attributes.get('alt', None), 'url_path': fullimage.absolute_url_path(), 'caption': newline_to_br(html_quote(caption)), 'image': image, 'fullimage': fullimage, 'tag': tag(**attributes), 'isfullsize': image is fullimage or (image.width == original_width and image.height == original_height), 'width': attributes.get('width', width), } captioned = BeautifulSoup(self.captioned_image_template(**options), 'html.parser') # if we are a captioned image within a link, remove and occurrences # of a tags inside caption template to preserve the outer link if bool(elem.find_parent('a')): captioned.a.unwrap() elem.replace_with(captioned)
def html(self): return '<div style="color: %s">%s</div>\n' % (self.color, html_quote(self.msg))
def convert(self, orig, data, **kwargs): # Replaces all line breaks with a br tag, and wraps it in a p tag. data.setData('<p>%s</p>' % html_quote(orig.strip()).replace('\n', '<br />')) return data
def text2html(text): """Replaces all line breaks with a br tag, and wraps it in a p tag. """ return '<p>%s</p>' % html_quote(text.strip()).replace('\n', '<br />')