buildframework/helium/external/python/lib/common/Sphinx-0.5.1-py2.5.egg/sphinx/util/__init__.py
author wbernard
Wed, 23 Dec 2009 19:29:07 +0200
changeset 179 d8ac696cc51f
permissions -rw-r--r--
helium_7.0-r14027
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
179
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     2
"""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     3
    sphinx.util
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     4
    ~~~~~~~~~~~
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     5
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     6
    Utility functions for Sphinx.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     7
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     8
    :copyright: 2007-2008 by Georg Brandl.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     9
    :license: BSD.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    10
"""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    11
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    12
import os
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    13
import re
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    14
import sys
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    15
import time
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    16
import fnmatch
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    17
import tempfile
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    18
import traceback
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    19
from os import path
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    20
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    21
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    22
# Generally useful regular expressions.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    23
ws_re = re.compile(r'\s+')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    24
caption_ref_re = re.compile(r'^([^<]+?)\s*<(.+)>$')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    25
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    26
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    27
# SEP separates path elements in the canonical file names
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    28
#
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    29
# Define SEP as a manifest constant, not so much because we expect it to change
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    30
# in the future as to avoid the suspicion that a stray "/" in the code is a
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    31
# hangover from more *nix-oriented origins.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    32
SEP = "/"
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    33
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    34
def os_path(canonicalpath):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    35
    return canonicalpath.replace(SEP, os.path.sep)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    36
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    37
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    38
def relative_uri(base, to):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    39
    """Return a relative URL from ``base`` to ``to``."""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    40
    b2 = base.split(SEP)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    41
    t2 = to.split(SEP)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    42
    # remove common segments
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    43
    for x, y in zip(b2, t2):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    44
        if x != y:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    45
            break
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    46
        b2.pop(0)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    47
        t2.pop(0)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    48
    return ('..' + SEP) * (len(b2)-1) + SEP.join(t2)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    49
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    50
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    51
def ensuredir(path):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    52
    """Ensure that a path exists."""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    53
    try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    54
        os.makedirs(path)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    55
    except OSError, err:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    56
        if not err.errno == 17:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    57
            raise
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    58
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    59
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    60
def walk(top, topdown=True, followlinks=False):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    61
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    62
    Backport of os.walk from 2.6, where the followlinks argument was added.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    63
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    64
    names = os.listdir(top)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    65
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    66
    dirs, nondirs = [], []
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    67
    for name in names:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    68
        if path.isdir(path.join(top, name)):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    69
            dirs.append(name)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    70
        else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    71
            nondirs.append(name)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    72
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    73
    if topdown:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    74
        yield top, dirs, nondirs
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    75
    for name in dirs:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    76
        fullpath = path.join(top, name)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    77
        if followlinks or not path.islink(fullpath):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    78
            for x in walk(fullpath, topdown, followlinks):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    79
                yield x
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    80
    if not topdown:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    81
        yield top, dirs, nondirs
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    82
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    83
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    84
def get_matching_docs(dirname, suffix, exclude_docs=(), exclude_dirs=(),
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    85
                      exclude_trees=(), exclude_dirnames=()):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    86
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    87
    Get all file names (without suffix) matching a suffix in a
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    88
    directory, recursively.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    89
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    90
    Exclude docs in *exclude_docs*, exclude dirs in *exclude_dirs*,
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    91
    prune dirs in *exclude_trees*, prune dirnames in *exclude_dirnames*.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    92
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    93
    pattern = '*' + suffix
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    94
    # dirname is a normalized absolute path.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    95
    dirname = path.normpath(path.abspath(dirname))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    96
    dirlen = len(dirname) + 1    # exclude slash
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    97
    for root, dirs, files in walk(dirname, followlinks=True):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    98
        if root[dirlen:] in exclude_dirs:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    99
            continue
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   100
        if root[dirlen:] in exclude_trees:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   101
            del dirs[:]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   102
            continue
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   103
        dirs.sort()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   104
        files.sort()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   105
        for prunedir in exclude_dirnames:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   106
            if prunedir in dirs:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   107
                dirs.remove(prunedir)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   108
        for sfile in files:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   109
            if not fnmatch.fnmatch(sfile, pattern):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   110
                continue
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   111
            qualified_name = path.join(root[dirlen:], sfile[:-len(suffix)])
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   112
            qualified_name = qualified_name.replace(os.path.sep, SEP)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   113
            if qualified_name in exclude_docs:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   114
                continue
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   115
            yield qualified_name
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   116
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   117
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   118
def mtimes_of_files(dirnames, suffix):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   119
    for dirname in dirnames:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   120
        for root, dirs, files in os.walk(dirname):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   121
            for sfile in files:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   122
                if sfile.endswith(suffix):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   123
                    try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   124
                        yield path.getmtime(path.join(root, sfile))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   125
                    except EnvironmentError:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   126
                        pass
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   127
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   128
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   129
def shorten_result(text='', keywords=[], maxlen=240, fuzz=60):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   130
    if not text:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   131
        text = ''
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   132
    text_low = text.lower()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   133
    beg = -1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   134
    for k in keywords:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   135
        i = text_low.find(k.lower())
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   136
        if (i > -1 and i < beg) or beg == -1:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   137
            beg = i
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   138
    excerpt_beg = 0
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   139
    if beg > fuzz:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   140
        for sep in ('.', ':', ';', '='):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   141
            eb = text.find(sep, beg - fuzz, beg - 1)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   142
            if eb > -1:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   143
                eb += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   144
                break
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   145
        else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   146
            eb = beg - fuzz
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   147
        excerpt_beg = eb
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   148
    if excerpt_beg < 0:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   149
        excerpt_beg = 0
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   150
    msg = text[excerpt_beg:beg+maxlen]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   151
    if beg > fuzz:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   152
        msg = '... ' + msg
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   153
    if beg < len(text)-maxlen:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   154
        msg = msg + ' ...'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   155
    return msg
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   156
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   157
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   158
class attrdict(dict):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   159
    def __getattr__(self, key):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   160
        return self[key]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   161
    def __setattr__(self, key, val):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   162
        self[key] = val
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   163
    def __delattr__(self, key):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   164
        del self[key]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   165
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   166
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   167
def fmt_ex(ex):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   168
    """Format a single line with an exception description."""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   169
    return traceback.format_exception_only(ex.__class__, ex)[-1].strip()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   170
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   171
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   172
def rpartition(s, t):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   173
    """Similar to str.rpartition from 2.5, but doesn't return the separator."""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   174
    i = s.rfind(t)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   175
    if i != -1:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   176
        return s[:i], s[i+len(t):]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   177
    return '', s
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   178
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   179
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   180
def format_exception_cut_frames(x=1):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   181
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   182
    Format an exception with traceback, but only the last x frames.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   183
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   184
    typ, val, tb = sys.exc_info()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   185
    #res = ['Traceback (most recent call last):\n']
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   186
    res = []
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   187
    tbres = traceback.format_tb(tb)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   188
    res += tbres[-x:]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   189
    res += traceback.format_exception_only(typ, val)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   190
    return ''.join(res)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   191
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   192
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   193
def save_traceback():
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   194
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   195
    Save the current exception's traceback in a temporary file.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   196
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   197
    exc = traceback.format_exc()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   198
    fd, path = tempfile.mkstemp('.log', 'sphinx-err-')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   199
    os.write(fd, exc)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   200
    os.close(fd)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   201
    return path
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   202
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   203
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   204
def _translate_pattern(pat):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   205
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   206
    Translate a shell-style glob pattern to a regular expression.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   207
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   208
    Adapted from the fnmatch module, but enhanced so that single stars don't
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   209
    match slashes.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   210
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   211
    i, n = 0, len(pat)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   212
    res = ''
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   213
    while i < n:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   214
        c = pat[i]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   215
        i += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   216
        if c == '*':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   217
            if i < n and pat[i] == '*':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   218
                # double star matches slashes too
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   219
                i += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   220
                res = res + '.*'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   221
            else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   222
                # single star doesn't match slashes
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   223
                res = res + '[^/]*'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   224
        elif c == '?':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   225
            # question mark doesn't match slashes too
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   226
            res = res + '[^/]'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   227
        elif c == '[':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   228
            j = i
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   229
            if j < n and pat[j] == '!':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   230
                j += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   231
            if j < n and pat[j] == ']':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   232
                j += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   233
            while j < n and pat[j] != ']':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   234
                j += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   235
            if j >= n:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   236
                res = res + '\\['
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   237
            else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   238
                stuff = pat[i:j].replace('\\', '\\\\')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   239
                i = j + 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   240
                if stuff[0] == '!':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   241
                    # negative pattern mustn't match slashes too
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   242
                    stuff = '^/' + stuff[1:]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   243
                elif stuff[0] == '^':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   244
                    stuff = '\\' + stuff
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   245
                res = '%s[%s]' % (res, stuff)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   246
        else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   247
            res += re.escape(c)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   248
    return res + '$'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   249
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   250
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   251
_pat_cache = {}
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   252
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   253
def patfilter(names, pat):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   254
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   255
    Return the subset of the list NAMES that match PAT.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   256
    Adapted from fnmatch module.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   257
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   258
    result = []
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   259
    if pat not in _pat_cache:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   260
        _pat_cache[pat] = re.compile(_translate_pattern(pat))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   261
    match = _pat_cache[pat].match
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   262
    return filter(match, names)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   263
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   264
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   265
no_fn_re = re.compile(r'[^a-zA-Z0-9_-]')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   266
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   267
def make_filename(string):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   268
    return no_fn_re.sub('', string)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   269
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   270
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   271
def nested_parse_with_titles(state, content, node):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   272
    # hack around title style bookkeeping
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   273
    surrounding_title_styles = state.memo.title_styles
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   274
    surrounding_section_level = state.memo.section_level
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   275
    state.memo.title_styles = []
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   276
    state.memo.section_level = 0
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   277
    state.nested_parse(content, 0, node, match_titles=1)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   278
    state.memo.title_styles = surrounding_title_styles
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   279
    state.memo.section_level = surrounding_section_level
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   280
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   281
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   282
def ustrftime(format, *args):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   283
    # strftime for unicode strings
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   284
    return time.strftime(unicode(format).encode('utf-8'), *args).decode('utf-8')