rename module to something less generic.
[blender.git] / release / scripts / modules / bl_i18n_utils / settings.py
1 # ***** BEGIN GPL LICENSE BLOCK *****
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ***** END GPL LICENSE BLOCK *****
18
19 # <pep8 compliant>
20
21 # Global settings used by all scripts in this dir.
22 # XXX Before any use of the tools in this dir, please make a copy of this file
23 #     named "setting.py"
24 # XXX This is a template, most values should be OK, but some you’ll have to
25 #     edit (most probably, BLENDER_EXEC and SOURCE_DIR).
26
27 import os.path
28
29
30 ###############################################################################
31 # MISC
32 ###############################################################################
33
34 # The min level of completeness for a po file to be imported from /branches
35 # into /trunk, as a percentage. -1 means "import everything".
36 IMPORT_MIN_LEVEL = -1
37
38 # The comment prefix used in generated messages.txt file.
39 COMMENT_PREFIX = "#~ "
40
41 # The comment prefix used to mark sources of msgids, in po's.
42 COMMENT_PREFIX_SOURCE = "#: "
43
44 # The comment prefix used in generated messages.txt file.
45 CONTEXT_PREFIX = "MSGCTXT:"
46
47 # Default context.
48 CONTEXT_DEFAULT = ""
49
50 # Undocumented operator placeholder string.
51 UNDOC_OPS_STR = "(undocumented operator)"
52
53 # The gettext domain.
54 DOMAIN = "blender"
55
56 # Our own "gettext" stuff.
57 # File type (ext) to parse.
58 PYGETTEXT_ALLOWED_EXTS =  {".c", ".cpp", ".cxx", ".hpp", ".hxx", ".h"}
59
60 # Where to search contexts definitions, relative to SOURCE_DIR (defined below).
61 PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blenfont",
62                                          "BLF_translation.h")
63
64 # Regex to extract contexts defined in BLF_translation.h
65 # XXX Not full-proof, but should be enough here!
66 PYGETTEXT_CONTEXTS = "#define\\s+(BLF_I18NCONTEXT_[A-Z_0-9]+)\\s+\"([^\"]*)\""
67
68 # Keywords' regex.
69 # XXX Most unfortunately, we can't use named backreferences inside character sets,
70 #     which makes the regexes even more twisty... :/
71 _str_base = (
72     # Match void string
73     "(?P<{_}1>[\"'])(?P={_}1)"  # Get opening quote (' or "), and closing immediately.
74     "|"
75     # Or match non-void string
76     "(?P<{_}2>[\"'])"  # Get opening quote (' or ").
77         "(?{capt}(?:"
78             # This one is for crazy things like "hi \\\\\" folks!"...
79             r"(?:(?!<\\)(?:\\\\)*\\(?=(?P={_}2)))|"
80             # The most common case.
81             ".(?!(?P={_}2))"
82         ")+.)"  # Don't forget the last char!
83     "(?P={_}2)"  # And closing quote.
84 )
85 str_clean_re = _str_base.format(_="g", capt="P<clean>")
86 # Here we have to consider two different cases (empty string and other).
87 _str_whole_re = (
88     _str_base.format(_="{_}1_", capt=":") +
89     # Optional loop start, this handles "split" strings...
90     "(?:(?<=[\"'])\\s*(?=[\"'])(?:"
91         + _str_base.format(_="{_}2_", capt=":") +
92     # End of loop.
93     "))*"
94 )
95 _ctxt_re = r"(?P<ctxt_raw>(?:" + _str_whole_re.format(_="_ctxt") + r")|(?:[A-Z_0-9]+))"
96 _msg_re = r"(?P<msg_raw>" + _str_whole_re.format(_="_msg") + r")"
97 PYGETTEXT_KEYWORDS = (() +
98     tuple((r"{}\(\s*" + _msg_re + r"\s*\)").format(it)
99           for it in ("IFACE_", "TIP_", "N_")) +
100     tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*"+ _msg_re + r"\s*\)").format(it)
101           for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_N_"))
102 )
103 #GETTEXT_KEYWORDS = ("IFACE_", "CTX_IFACE_:1c,2", "TIP_", "CTX_TIP_:1c,2",
104 #                    "N_", "CTX_N_:1c,2")
105
106 # Should po parser warn when finding a first letter not capitalized?
107 WARN_MSGID_NOT_CAPITALIZED = True
108
109 # Strings that should not raise above warning!
110 WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
111     "",  # Simplifies things... :p
112     "sin(x) / x",
113     "fBM",
114     "sqrt(x*x+y*y+z*z)",
115     "iTaSC",
116     "bItasc",
117     "px",
118     "mm",
119     "fStop",
120     "sRGB",
121     "iso-8859-15",
122     "utf-8",
123     "ascii",
124     "re",
125     "y",
126     "ac3",
127     "flac",
128     "mkv",
129     "mp2",
130     "mp3",
131     "ogg",
132     "wav",
133     "iTaSC parameters",
134     "vBVH",
135     "rv",
136     "en_US",
137     "fr_FR",
138     "it_IT",
139     "ru_RU",
140     "zh_CN",
141     "es",
142     "zh_TW",
143     "ar_EG",
144     "pt",
145     "bg_BG",
146     "ca_AD",
147     "hr_HR",
148     "cs_CZ",
149     "nl_NL",
150     "fi_FI",
151     "de_DE",
152     "el_GR",
153     "id_ID",
154     "ja_JP",
155     "ky_KG",
156     "ko_KR",
157     "ne_NP",
158     "fa_IR",
159     "pl_PL",
160     "ro_RO",
161     "sr_RS",
162     "sr_RS@latin",
163     "sv_SE",
164     "uk_UA",
165     "tr_TR",
166     "hu_HU",
167     "available with",                # Is part of multi-line msg.
168     "virtual parents",               # Is part of multi-line msg.
169     "description",                   # Addons' field. :/
170     "location",                      # Addons' field. :/
171     "author",                        # Addons' field. :/
172     "in memory to enable editing!",  # Is part of multi-line msg.
173     "iScale",
174     "dx",
175     "p0",
176     "res",
177 }
178
179
180 ###############################################################################
181 # PATHS
182 ###############################################################################
183
184 # The tools path, should be OK.
185 TOOLS_DIR = os.path.join(os.path.dirname(__file__))
186
187 # The Python3 executable.You’ll likely have to edit it in your user_settings.py
188 # if you’re under Windows.
189 PYTHON3_EXEC = "python3"
190
191 # The Blender executable!
192 # This is just an example, you’ll most likely have to edit it in your
193 # user_settings.py!
194 BLENDER_EXEC = os.path.abspath(os.path.join(TOOLS_DIR, "..", "..", "..", "..",
195                                             "blender"))
196
197 # The xgettext tool. You’ll likely have to edit it in your user_settings.py
198 # if you’re under Windows.
199 GETTEXT_XGETTEXT_EXECUTABLE = "xgettext"
200
201 # The gettext msgmerge tool. You’ll likely have to edit it in your
202 # user_settings.py if you’re under Windows.
203 GETTEXT_MSGMERGE_EXECUTABLE = "msgmerge"
204
205 # The gettext msgfmt "compiler". You’ll likely have to edit it in your
206 # user_settings.py if you’re under Windows.
207 GETTEXT_MSGFMT_EXECUTABLE = "msgfmt"
208
209 # The svn binary... You’ll likely have to edit it in your
210 # user_settings.py if you’re under Windows.
211 SVN_EXECUTABLE = "svn"
212
213 # The FriBidi C compiled library (.so under Linux, .dll under windows...).
214 # You’ll likely have to edit it in your user_settings.py if you’re under
215 # Windows., e.g. using the included one:
216 #     FRIBIDI_LIB = os.path.join(TOOLS_DIR, "libfribidi.dll")
217 FRIBIDI_LIB = "libfribidi.so.0"
218
219 # The name of the (currently empty) file that must be present in a po's
220 # directory to enable rtl-preprocess.
221 RTL_PREPROCESS_FILE = "is_rtl"
222
223 # The Blender source root path.
224 # This is just an example, you’ll most likely have to override it in your
225 # user_settings.py!
226 SOURCE_DIR = os.path.abspath(os.path.join(TOOLS_DIR, "..", "..", "..", "..",
227                                           "..", "..", "blender_msgs"))
228
229 # The bf-translation repository (you'll likely have to override this in your
230 # user_settings.py).
231 I18N_DIR = os.path.abspath(os.path.join(TOOLS_DIR, "..", "..", "..", "..",
232                                         "..", "..", "i18n"))
233
234 # The /branches path (overriden in bf-translation's i18n_override_settings.py).
235 BRANCHES_DIR = os.path.join(I18N_DIR, "branches")
236
237 # The /trunk path (overriden in bf-translation's i18n_override_settings.py).
238 TRUNK_DIR = os.path.join(I18N_DIR, "trunk")
239
240 # The /trunk/po path (overriden in bf-translation's i18n_override_settings.py).
241 TRUNK_PO_DIR = os.path.join(TRUNK_DIR, "po")
242
243 # The /trunk/mo path (overriden in bf-translation's i18n_override_settings.py).
244 TRUNK_MO_DIR = os.path.join(TRUNK_DIR, "locale")
245
246 # The file storing Blender-generated messages.
247 FILE_NAME_MESSAGES = os.path.join(TRUNK_PO_DIR, "messages.txt")
248
249 # The Blender source path to check for i18n macros.
250 POTFILES_SOURCE_DIR = os.path.join(SOURCE_DIR, "source")
251
252 # The "source" file storing which files should be processed by xgettext,
253 # used to create FILE_NAME_POTFILES
254 FILE_NAME_SRC_POTFILES = os.path.join(TRUNK_PO_DIR, "_POTFILES.in")
255
256 # The final (generated) file storing which files
257 # should be processed by xgettext.
258 FILE_NAME_POTFILES = os.path.join(TRUNK_PO_DIR, "POTFILES.in")
259
260 # The template messages file.
261 FILE_NAME_POT = os.path.join(TRUNK_PO_DIR, ".".join((DOMAIN, "pot")))
262
263 # Other py files that should be searched for ui strings, relative to SOURCE_DIR.
264 # Needed for Cycles, currently...
265 CUSTOM_PY_UI_FILES = [os.path.join("intern", "cycles", "blender",
266                                    "addon", "ui.py"),
267                      ]
268
269
270 # A cache storing validated msgids, to avoid re-spellchecking them.
271 SPELL_CACHE = os.path.join("/tmp", ".spell_cache")
272
273
274 # Custom override settings must be one dir above i18n tools itself!
275 import sys
276 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
277 try:
278     from i18n_override_settings import *
279 except ImportError:  # If no i18n_override_settings available, it’s no error!
280     pass
281
282 # Override with custom user settings, if available.
283 try:
284     from user_settings import *
285 except ImportError:  # If no user_settings available, it’s no error!
286     pass