"Fossies" - the Fresh Open Source Software Archive

Member "cheetah3-3.2.6.post2/Cheetah/Filters.py" (20 Apr 2021, 7354 Bytes) of package /linux/www/cheetah3-3.2.6.post2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "Filters.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3-3.2.2_vs_3-3.2.3.

    1 #!/usr/bin/env python
    2 
    3 '''
    4     Filters for the #filter directive as well as #transform
    5 
    6     #filter results in output filters Cheetah's $placeholders .
    7     #transform results in a filter on the entirety of the output
    8 '''
    9 from Cheetah.compat import unicode
   10 
   11 # Additional entities WebSafe knows how to transform.  No need to include
   12 # '<', '>' or '&' since those will have been done already.
   13 webSafeEntities = {' ': '&nbsp;', '"': '&quot;'}
   14 
   15 
   16 class Filter(object):
   17     """A baseclass for the Cheetah Filters."""
   18 
   19     def __init__(self, template=None):
   20         """Setup a reference to the template that is using the filter instance.
   21         This reference isn't used by any of the standard filters, but is
   22         available to Filter subclasses, should they need it.
   23 
   24         Subclasses should call this method.
   25         """
   26         self.template = template
   27 
   28     def filter(self, val, encoding=None, str=str, **kw):
   29         '''
   30         Pass Unicode strings through unmolested,
   31         unless an encoding is specified.
   32         '''
   33         if val is None:
   34             return u''
   35         if isinstance(val, unicode):
   36             # ignore the encoding and return the unicode object
   37             return val
   38         else:
   39             try:
   40                 return unicode(val)
   41             except UnicodeDecodeError:
   42                 # we could put more fallbacks here, but we'll just pass the str
   43                 # on and let DummyTransaction worry about it
   44                 return str(val)
   45 
   46 
   47 RawOrEncodedUnicode = Filter
   48 
   49 EncodeUnicode = Filter
   50 
   51 
   52 class Markdown(EncodeUnicode):
   53     '''
   54         Markdown will change regular strings to `Markdown
   55         <http://daringfireball.net/projects/markdown/>`_
   56 
   57         Such that::
   58 
   59             My Header
   60             =========
   61 
   62         Becomes::
   63 
   64             <h1>My Header</h1>
   65 
   66         and so on.
   67 
   68         Markdown is meant to be used with the #transform
   69         tag, as it's usefulness with #filter is marginal at
   70         best
   71     '''
   72     def filter(self, value, **kwargs):
   73         # This is a bit of a hack to allow outright embedding
   74         # of the markdown module.
   75         import markdown
   76         encoded = super(Markdown, self).filter(value, **kwargs)
   77         return markdown.markdown(encoded)
   78 
   79 
   80 class CodeHighlighter(EncodeUnicode):
   81     '''
   82     The CodeHighlighter filter depends on the "pygments" module
   83     which you can download and install from: http://pygments.org/
   84 
   85     What the CodeHighlighter assumes the string that it's receiving
   86     is source code and uses pygments.lexers.guess_lexer() to try to guess
   87     which parser to use when highlighting it.
   88 
   89     CodeHighlighter will return the HTML and CSS to render the code block,
   90     syntax highlighted, in a browser
   91 
   92     NOTE: I had an issue installing pygments on Linux/amd64/Python 2.6
   93     dealing with importing of pygments.lexers. I was able to correct the
   94     failure by adding::
   95 
   96         raise ImportError
   97 
   98     to line 39 of pygments/plugin.py (since importing pkg_resources was
   99     causing issues).
  100     '''
  101     def filter(self, source, **kwargs):
  102         encoded = super(CodeHighlighter, self).filter(source, **kwargs)
  103         try:
  104             from pygments import highlight
  105             from pygments import lexers
  106             from pygments import formatters
  107         except ImportError as ex:
  108             print('<%s> - Failed to import pygments! (%s)'
  109                   % (self.__class__.__name__, ex))
  110             print('-- You may need to install it from: http://pygments.org')
  111             return encoded
  112 
  113         lexer = None
  114         try:
  115             lexer = lexers.guess_lexer(source)
  116         except lexers.ClassNotFound:
  117             lexer = lexers.PythonLexer()
  118 
  119         formatter = formatters.HtmlFormatter(cssclass='code_highlighter')
  120         encoded = highlight(encoded, lexer, formatter)
  121         css = formatter.get_style_defs('.code_highlighter')
  122         return '''<style type="text/css"><!--
  123                 %(css)s
  124             --></style>%(source)s''' % {'css': css, 'source': encoded}
  125 
  126 
  127 class MaxLen(Filter):
  128     def filter(self, val, **kw):
  129         """Replace None with '' and cut off at maxlen."""
  130 
  131         output = super(MaxLen, self).filter(val, **kw)
  132         if 'maxlen' in kw and len(output) > kw['maxlen']:
  133             return output[:kw['maxlen']]
  134         return output
  135 
  136 
  137 class WebSafe(Filter):
  138     """Escape HTML entities in $placeholders.
  139     """
  140     def filter(self, val, **kw):
  141         s = super(WebSafe, self).filter(val, **kw)
  142         # These substitutions are copied from cgi.escape().
  143         s = s.replace("&", "&amp;")  # Must be done first!
  144         s = s.replace("<", "&lt;")
  145         s = s.replace(">", "&gt;")
  146         # Process the additional transformations if any.
  147         if 'also' in kw:
  148             also = kw['also']
  149             entities = webSafeEntities   # Global variable.
  150             for k in also:
  151                 if k in entities:
  152                     v = entities[k]
  153                 else:
  154                     v = "&#%s;" % ord(k)
  155                 s = s.replace(k, v)
  156         return s
  157 
  158 
  159 class Strip(Filter):
  160     """Strip leading/trailing whitespace but preserve newlines.
  161 
  162     This filter goes through the value line by line, removing leading and
  163     trailing whitespace on each line.  It does not strip newlines, so every
  164     input line corresponds to one output line, with its trailing newline
  165     intact.
  166 
  167     We do not use val.split('\\n') because that would squeeze out consecutive
  168     blank lines.  Instead, we search for each newline individually.  This
  169     makes us unable to use the fast C .split method, but it makes the filter
  170     much more widely useful.
  171 
  172     This filter is intended to be usable both with the #filter directive and
  173     with the proposed #sed directive (which has not been ratified yet.)
  174     """
  175     def filter(self, val, **kw):
  176         s = super(Strip, self).filter(val, **kw)
  177         result = []
  178         start = 0   # The current line will be s[start:end].
  179         while True:  # Loop through each line.
  180             end = s.find('\n', start)  # Find next newline.
  181             if end == -1:  # If no more newlines.
  182                 break
  183             chunk = s[start:end].strip()
  184             result.append(chunk)
  185             result.append('\n')
  186             start = end + 1
  187         # Write the unfinished portion after the last newline, if any.
  188         chunk = s[start:].strip()
  189         result.append(chunk)
  190         return "".join(result)
  191 
  192 
  193 class StripSqueeze(Filter):
  194     """Canonicalizes every chunk of whitespace to a single space.
  195 
  196     Strips leading/trailing whitespace.  Removes all newlines, so multi-line
  197     input is joined into one ling line with NO trailing newline.
  198     """
  199     def filter(self, val, **kw):
  200         s = super(StripSqueeze, self).filter(val, **kw)
  201         s = s.split()
  202         return " ".join(s)
  203 
  204 ##################################################
  205 # MAIN ROUTINE -- testing
  206 
  207 
  208 def test():
  209     s1 = "abc <=> &"
  210     s2 = "   asdf  \n\t  1  2    3\n"
  211     print("WebSafe INPUT:", repr(s1))
  212     print("      WebSafe:", repr(WebSafe().filter(s1)))
  213 
  214     print()
  215     print(" Strip INPUT:", repr(s2))
  216     print("       Strip:", repr(Strip().filter(s2)))
  217     print("StripSqueeze:", repr(StripSqueeze().filter(s2)))
  218 
  219     print("Unicode:", repr(EncodeUnicode().filter(u'aoeu12345\u1234')))
  220 
  221 
  222 if __name__ == "__main__":
  223     test()
  224 
  225 # vim: shiftwidth=4 tabstop=4 expandtab