File: Synopsis/Formatters/__init__.py
 1#
 2# Copyright (C) 2008 Stefan Seefeld
 3# All rights reserved.
 4# Licensed to the public under the terms of the GNU LGPL (>= 2),
 5# see the file COPYING for details.
 6#
 7
 8import os, stat
 9try:
10    import hashlib
11    md5 = hashlib.md5
12except ImportError:
13    # 2.4 compatibility
14    import md5
15    md5 = md5.new
16
17
18def quote_name(name):
19    """Quotes a (file-) name to remove illegal characters and keep it
20    within a reasonable length for the filesystem.
21   
22    The md5 hash function is used if the length of the name after quoting is
23    more than 100 characters. If it is used, then as many characters at the
24    start of the name as possible are kept intact, and the hash appended to
25    make 100 characters.
26   
27    Do not pass filenames with meaningful extensions to this function, as the
28    hash could destroy them."""
29
30    original = name # save the old name
31
32    # a . is usually an extension, eg source page filename: "_page-foo.hpp" + .html
33    # name = re.sub('\.','_',name) 
34    # The . is arbitrary..
35    for p in [('<', '.L'), ('>', '.R'), ('(', '.l'), (')', '.r'), ('::', '-'),
36              (':', '.'), ('&', '.A'), ('*', '.S'), (' ', '.s'), (',', '.c'), (';', '.C')]:
37        name = name.replace(*p)
38
39    if len(name) > 100:
40        digest = md5(original).hexdigest()
41        # Keep as much of the name as possible
42        name = name[:100 - len(digest)] + digest
43
44    return name
45
46
47def open_file(path, mode=511):
48    """Open a file for writing. Create all intermediate directories."""
49
50    directory = os.path.dirname(path)
51    if directory and not os.path.isdir(directory):
52        os.makedirs(directory, mode)
53    return open(path, 'w+')
54
55
56def copy_file(src, dest):
57    """Copy src to dest, if dest doesn't exist yet or is outdated."""
58
59    filetime = os.stat(src)[stat.ST_MTIME]
60    if not os.path.exists(dest) or filetime > os.stat(dest)[stat.ST_MTIME]:
61        open_file(dest).write(open(src, 'r').read())
62
63
64def join_paths(prefix, path):
65    """
66    This function joins `prefix` and `path`, irrespectively of whether
67    `path` is absolute or not. To do this portably is non-trivial."""
68
69    # FIXME: Figure out how to do this portably.
70    if path.startswith('/'):
71        path = path[1:]
72    return os.path.join(prefix, path)
73