##// END OF EJS Templates
py3: make i18n/hggettext use absolute_import
Pulkit Goyal -
r29170:2516bba6 default
parent child Browse files
Show More
@@ -1,137 +1,141
1 1 #!/usr/bin/env python
2 2 #
3 3 # hggettext - carefully extract docstrings for Mercurial
4 4 #
5 5 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
6 6 #
7 7 # This software may be used and distributed according to the terms of the
8 8 # GNU General Public License version 2 or any later version.
9 9
10 10 # The normalize function is taken from pygettext which is distributed
11 11 # with Python under the Python License, which is GPL compatible.
12 12
13 13 """Extract docstrings from Mercurial commands.
14 14
15 15 Compared to pygettext, this script knows about the cmdtable and table
16 16 dictionaries used by Mercurial, and will only extract docstrings from
17 17 functions mentioned therein.
18 18
19 19 Use xgettext like normal to extract strings marked as translatable and
20 20 join the message cataloges to get the final catalog.
21 21 """
22 22
23 import os, sys, inspect
23 from __future__ import absolute_import
24
25 import inspect
26 import os
27 import sys
24 28
25 29
26 30 def escape(s):
27 31 # The order is important, the backslash must be escaped first
28 32 # since the other replacements introduce new backslashes
29 33 # themselves.
30 34 s = s.replace('\\', '\\\\')
31 35 s = s.replace('\n', '\\n')
32 36 s = s.replace('\r', '\\r')
33 37 s = s.replace('\t', '\\t')
34 38 s = s.replace('"', '\\"')
35 39 return s
36 40
37 41
38 42 def normalize(s):
39 43 # This converts the various Python string types into a format that
40 44 # is appropriate for .po files, namely much closer to C style.
41 45 lines = s.split('\n')
42 46 if len(lines) == 1:
43 47 s = '"' + escape(s) + '"'
44 48 else:
45 49 if not lines[-1]:
46 50 del lines[-1]
47 51 lines[-1] = lines[-1] + '\n'
48 52 lines = map(escape, lines)
49 53 lineterm = '\\n"\n"'
50 54 s = '""\n"' + lineterm.join(lines) + '"'
51 55 return s
52 56
53 57
54 58 def poentry(path, lineno, s):
55 59 return ('#: %s:%d\n' % (path, lineno) +
56 60 'msgid %s\n' % normalize(s) +
57 61 'msgstr ""\n')
58 62
59 63
60 64 def offset(src, doc, name, default):
61 65 """Compute offset or issue a warning on stdout."""
62 66 # Backslashes in doc appear doubled in src.
63 67 end = src.find(doc.replace('\\', '\\\\'))
64 68 if end == -1:
65 69 # This can happen if the docstring contains unnecessary escape
66 70 # sequences such as \" in a triple-quoted string. The problem
67 71 # is that \" is turned into " and so doc wont appear in src.
68 72 sys.stderr.write("warning: unknown offset in %s, assuming %d lines\n"
69 73 % (name, default))
70 74 return default
71 75 else:
72 76 return src.count('\n', 0, end)
73 77
74 78
75 79 def importpath(path):
76 80 """Import a path like foo/bar/baz.py and return the baz module."""
77 81 if path.endswith('.py'):
78 82 path = path[:-3]
79 83 if path.endswith('/__init__'):
80 84 path = path[:-9]
81 85 path = path.replace('/', '.')
82 86 mod = __import__(path)
83 87 for comp in path.split('.')[1:]:
84 88 mod = getattr(mod, comp)
85 89 return mod
86 90
87 91
88 92 def docstrings(path):
89 93 """Extract docstrings from path.
90 94
91 95 This respects the Mercurial cmdtable/table convention and will
92 96 only extract docstrings from functions mentioned in these tables.
93 97 """
94 98 mod = importpath(path)
95 99 if mod.__doc__:
96 100 src = open(path).read()
97 101 lineno = 1 + offset(src, mod.__doc__, path, 7)
98 102 print poentry(path, lineno, mod.__doc__)
99 103
100 104 functions = list(getattr(mod, 'i18nfunctions', []))
101 105 functions = [(f, True) for f in functions]
102 106
103 107 cmdtable = getattr(mod, 'cmdtable', {})
104 108 if not cmdtable:
105 109 # Maybe we are processing mercurial.commands?
106 110 cmdtable = getattr(mod, 'table', {})
107 111 functions.extend((c[0], False) for c in cmdtable.itervalues())
108 112
109 113 for func, rstrip in functions:
110 114 if func.__doc__:
111 115 src = inspect.getsource(func)
112 116 name = "%s.%s" % (path, func.__name__)
113 117 lineno = func.func_code.co_firstlineno
114 118 doc = func.__doc__
115 119 if rstrip:
116 120 doc = doc.rstrip()
117 121 lineno += offset(src, doc, name, 1)
118 122 print poentry(path, lineno, doc)
119 123
120 124
121 125 def rawtext(path):
122 126 src = open(path).read()
123 127 print poentry(path, 1, src)
124 128
125 129
126 130 if __name__ == "__main__":
127 131 # It is very important that we import the Mercurial modules from
128 132 # the source tree where hggettext is executed. Otherwise we might
129 133 # accidentally import and extract strings from a Mercurial
130 134 # installation mentioned in PYTHONPATH.
131 135 sys.path.insert(0, os.getcwd())
132 136 from mercurial import demandimport; demandimport.enable()
133 137 for path in sys.argv[1:]:
134 138 if path.endswith('.txt'):
135 139 rawtext(path)
136 140 else:
137 141 docstrings(path)
General Comments 0
You need to be logged in to leave comments. Login now