File: Synopsis/Formatters/HTML/Tags.py
  1#
  2# Copyright (C) 2000 Stephen Davies
  3# Copyright (C) 2000 Stefan Seefeld
  4# All rights reserved.
  5# Licensed to the public under the terms of the GNU LGPL (>= 2),
  6# see the file COPYING for details.
  7#
  8
  9"""HTML Tag generation utilities.
 10You will probably find it easiest to import * from this module."""
 11
 12using_frames = True #overwritten by Formatter...
 13
 14def attributes(keys):
 15    "Convert a name/value dict to a string of attributes"
 16
 17    return ' '.join(['%s="%s"'%(k,v) for k,v in keys.items()])
 18
 19def rel(origin, target):
 20    "Find link to target relative to origin."
 21
 22    origin, target = origin.split('/'), target.split('/')
 23    if len(origin) < len(target): check = len(origin) - 1
 24    else: check = len(target) - 1
 25    for l in range(check):
 26        if target[0] == origin[0]:
 27            del target[0]
 28            del origin[0]
 29        else: break
 30    # If origin is a directory, and target is in that directory, origin[0] == target[0]
 31    if len(origin) == 1 and len(target) > 1 and origin[0] == target[0]:
 32        # Remove directory from target, but respect len(origin) - 1 below
 33        del target[0]
 34    if origin: target = ['..'] * (len(origin) - 1) + target
 35    return '/'.join(target)
 36
 37def href(_ref, _label, **attrs):
 38    "Return a href to 'ref' with name 'label' and attributes"
 39
 40    # Remove target if not using frames
 41    if attrs.has_key('target') and not using_frames:
 42        del attrs['target']
 43    return '<a href="%s" %s>%s</a>'%(_ref,attributes(attrs),_label)
 44
 45def img(**attrs):
 46    "Return an img element."
 47
 48    return '<img %s/>'%attributes(attrs)
 49
 50def name(ref, label):
 51    "Return a name anchor with given reference and label"
 52    if '(' in ref: raise error
 53    return '<a class="name" id="%s">%s</a>'%(ref,label)
 54
 55def span(class_, body):
 56    "Wrap the body in a span of the given class"
 57
 58    if class_:
 59        return '<span class="%s">%s</span>'%(class_,body)
 60    else:
 61        return '<span>%s</span>'%body
 62
 63def div(class_, body):
 64    "Wrap the body in a div of the given class"
 65
 66    if class_:
 67        return '<div class="%s">%s</div>'%(class_,body)
 68    else:
 69        return '<div>%s</div>'%body
 70
 71def element(_, body = None, **keys):
 72    "Wrap the body in a tag of given type and attributes"
 73
 74    if body:
 75        return '<%s %s>%s</%s>'%(_, attributes(keys), body, _)
 76    else:
 77        return '<%s %s />'%(_, attributes(keys))
 78
 79def desc(text):
 80    "Create a description div for the given text"
 81
 82    return text and div("desc", text) or ''
 83
 84
 85def escape(text):
 86
 87    for p in [('&', '&amp;'), ('"', '&quot;'), ('<', '&lt;'), ('>', '&gt;'),
 88              ('(', '&#40;'), (')', '&#41;'), (',', '&#44;'), (',', '&#59;')]:
 89        text = text.replace(*p)
 90    return text
 91
 92def quote_as_id(text):
 93
 94    for p in [(' ', '.'),
 95              ('<', '_L'), ('>', '_R'), ('(', '_l'), (')', '_r'), ('::', '-'), ('~', '_t'),
 96              (':', '.'), ('&', '_A'), ('*', '_S'), (' ', '_s'), (',', '_c'), (';', '_C'),
 97              ('!', '_n'), ('[', '_b'), (']', '_B'), ('=', '_e'), ('+', '_p'), ('-', '_m')]:
 98        text = text.replace(*p)
 99    return text
100
101
102def replace_spaces(text):
103    """Replaces spaces in the given string with &#160; sequences. Does NOT
104    replace spaces inside tags"""
105
106    # original "hello <there stuff> fool <thing me bob>yo<a>hi"
107    tags = text.split('<')
108    # now ['hello ', 'there stuff> fool ', 'thing me bob>yo', 'a>hi']
109    tags = [x.split('>') for x in tags]
110    # now [['hello '], ['there stuff', ' fool '], ['thing me bob', 'yo'], ['a', 'hi']]
111    tags = reduce(lambda x,y: x+y, tags)
112    # now ['hello ', 'there stuff', ' fool ', 'thing me bob', 'yo', 'a', 'hi']
113    for i in range(0,len(tags),2):
114        tags[i] = tags[i].replace(' ', '&#160;')
115    for i in range(1,len(tags),2):
116        tags[i] = '<' + tags[i] + '>'
117    return ''.join(tags)
118