mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ added ngettext support
* updated russian translation git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@164 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
7601a8a27d
commit
f704ddd02b
41 changed files with 2294 additions and 1632 deletions
2
Makefile
2
Makefile
|
@ -29,7 +29,7 @@ rules:
|
|||
|
||||
pot:
|
||||
./scripts/all_games.py gettext > po/games.pot
|
||||
pygettext.py -k n_ -o po/pysol-1.pot $(PYSOLLIB_FILES)
|
||||
./scripts/pygettext.py -k n_ --ngettext-keyword ungettext -o po/pysol-1.pot $(PYSOLLIB_FILES)
|
||||
xgettext -L C --keyword=N_ -o po/pysol-2.pot data/glade-translations
|
||||
msgcat po/pysol-1.pot po/pysol-2.pot > po/pysol.pot
|
||||
rm -f po/pysol-1.pot po/pysol-2.pot
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PySol 0.0.1\n"
|
||||
"POT-Creation-Date: Thu May 10 14:22:52 2007\n"
|
||||
"POT-Creation-Date: Fri May 11 22:05:05 2007\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -741,7 +741,7 @@ msgstr ""
|
|||
msgid "Die Bildgallerie"
|
||||
msgstr ""
|
||||
|
||||
msgid "Die Königsbergerin"
|
||||
msgid "Die Koenigsbergerin"
|
||||
msgstr ""
|
||||
|
||||
msgid "Die Russische"
|
||||
|
@ -750,10 +750,7 @@ msgstr ""
|
|||
msgid "Die Schlange"
|
||||
msgstr ""
|
||||
|
||||
msgid "Die böse Sieben"
|
||||
msgstr ""
|
||||
|
||||
msgid "Die große Harfe"
|
||||
msgid "Die boese Sieben"
|
||||
msgstr ""
|
||||
|
||||
msgid "Die kleine Harfe"
|
||||
|
|
1395
po/pysol.pot
1395
po/pysol.pot
File diff suppressed because it is too large
Load diff
|
@ -5,8 +5,8 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PySol 0.0.1\n"
|
||||
"POT-Creation-Date: Thu May 10 14:22:52 2007\n"
|
||||
"PO-Revision-Date: 2007-03-05 18:01+0300\n"
|
||||
"POT-Creation-Date: Fri May 11 22:05:05 2007\n"
|
||||
"PO-Revision-Date: 2007-05-11 17:25+0400\n"
|
||||
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -211,16 +211,14 @@ msgstr "Баланс"
|
|||
msgid "Balarama"
|
||||
msgstr "Баларама"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Banner"
|
||||
msgstr "Баланс"
|
||||
msgstr "Флаг"
|
||||
|
||||
msgid "Baroness"
|
||||
msgstr "Баронесса"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Barrier"
|
||||
msgstr "Причудливый"
|
||||
msgstr "Барьер"
|
||||
|
||||
msgid "Bastille Day"
|
||||
msgstr "День Бастилии"
|
||||
|
@ -250,7 +248,7 @@ msgid "Beatle"
|
|||
msgstr "Жук"
|
||||
|
||||
msgid "Bebop"
|
||||
msgstr ""
|
||||
msgstr "Бибоп"
|
||||
|
||||
msgid "Beetle"
|
||||
msgstr "Жук"
|
||||
|
@ -663,7 +661,7 @@ msgid "Crossroads"
|
|||
msgstr "Перекрестки"
|
||||
|
||||
msgid "Crown"
|
||||
msgstr "Венец"
|
||||
msgstr "Корона"
|
||||
|
||||
msgid "Cruel"
|
||||
msgstr "Изнурительный"
|
||||
|
@ -729,9 +727,8 @@ msgstr "Der letzte Monarch"
|
|||
msgid "Deuces"
|
||||
msgstr "Двойки"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Devil's Solitaire"
|
||||
msgstr "Китайский пасьянс"
|
||||
msgstr "Дьявольский пасьянс"
|
||||
|
||||
msgid "Dhanpati"
|
||||
msgstr "Dhanpati"
|
||||
|
@ -748,8 +745,8 @@ msgstr "Алмазный рудник"
|
|||
msgid "Die Bildgallerie"
|
||||
msgstr "Die Bildgallerie"
|
||||
|
||||
msgid "Die Königsbergerin"
|
||||
msgstr "Die Königsbergerin"
|
||||
msgid "Die Koenigsbergerin"
|
||||
msgstr "Die Koenigsbergerin"
|
||||
|
||||
msgid "Die Russische"
|
||||
msgstr "Die Russische"
|
||||
|
@ -757,11 +754,8 @@ msgstr "Die Russische"
|
|||
msgid "Die Schlange"
|
||||
msgstr "Die Schlange"
|
||||
|
||||
msgid "Die böse Sieben"
|
||||
msgstr "Die böse Sieben"
|
||||
|
||||
msgid "Die große Harfe"
|
||||
msgstr "Die große Harfe"
|
||||
msgid "Die boese Sieben"
|
||||
msgstr "Die boese Sieben"
|
||||
|
||||
msgid "Die kleine Harfe"
|
||||
msgstr "Die kleine Harfe"
|
||||
|
@ -2581,11 +2575,10 @@ msgid "Napoleon"
|
|||
msgstr "Наполеон"
|
||||
|
||||
msgid "Napoleon Leaves Moscow"
|
||||
msgstr ""
|
||||
msgstr "Наполеон бежит из Москвы"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Napoleon Takes Moscow"
|
||||
msgstr "Гробница Наполеона"
|
||||
msgstr "Наполеон идет на Москву"
|
||||
|
||||
msgid "Napoleon at St.Helena"
|
||||
msgstr "Наполеон на острове св.Елена"
|
||||
|
@ -2825,13 +2818,11 @@ msgstr "Перпетуум-мобиле"
|
|||
msgid "Perseverance"
|
||||
msgstr "Настойчивость"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Persian Patience"
|
||||
msgstr "Алжирский пасьянс"
|
||||
msgstr "Персидский пасьянс"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Phalanx"
|
||||
msgstr "Реглан"
|
||||
msgstr "Фаланга"
|
||||
|
||||
msgid "Phantom Blockade"
|
||||
msgstr "Призрачная блокада"
|
||||
|
@ -3019,9 +3010,8 @@ msgstr "Свита"
|
|||
msgid "Right Triangle"
|
||||
msgstr "Правый треугольник"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Right and Left"
|
||||
msgstr "Верхний и нижний"
|
||||
msgstr "Справа и слева"
|
||||
|
||||
msgid "Rings"
|
||||
msgstr "Круги"
|
||||
|
@ -3139,7 +3129,7 @@ msgid "Scheidungsgrund"
|
|||
msgstr "Scheidungsgrund"
|
||||
|
||||
msgid "School"
|
||||
msgstr ""
|
||||
msgstr "Школьный"
|
||||
|
||||
msgid "Scorpion"
|
||||
msgstr "Скорпион"
|
||||
|
@ -3602,22 +3592,20 @@ msgstr "Тринадцать вверх"
|
|||
msgid "Thirteens"
|
||||
msgstr "По тринадцать"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Thirty"
|
||||
msgstr "Тридцать шесть"
|
||||
msgstr "Тридцать"
|
||||
|
||||
msgid "Thirty Six"
|
||||
msgstr "Тридцать шесть"
|
||||
|
||||
msgid "Thirty Two Cards"
|
||||
msgstr ""
|
||||
msgstr "Тридцать две карты"
|
||||
|
||||
msgid "Three Blind Mice"
|
||||
msgstr "Три слепые мышки"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Three Fir-trees"
|
||||
msgstr "Три пирата"
|
||||
msgstr "Три елки"
|
||||
|
||||
msgid "Three Peaks"
|
||||
msgstr "Три вершины"
|
||||
|
@ -3692,9 +3680,8 @@ msgstr "Маджонг Traditional Reviewed"
|
|||
msgid "Trapdoor"
|
||||
msgstr "Люк"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Trapdoor Spider"
|
||||
msgstr "Люк"
|
||||
msgstr "Люк Паука"
|
||||
|
||||
msgid "Treasure Trove"
|
||||
msgstr "Клад"
|
||||
|
@ -3976,9 +3963,3 @@ msgstr "Зигзагообразный курс"
|
|||
|
||||
msgid "Zodiac"
|
||||
msgstr "Зодиак"
|
||||
|
||||
#~ msgid "Alternations"
|
||||
#~ msgstr "Чередования"
|
||||
|
||||
#~ msgid "Mahjongg Hurricane"
|
||||
#~ msgstr "Маджонг Ураган"
|
||||
|
|
1440
po/ru_pysol.po
1440
po/ru_pysol.po
File diff suppressed because it is too large
Load diff
|
@ -66,7 +66,6 @@ from pysoltk import create_find_card_dialog
|
|||
from pysoltk import create_solver_dialog
|
||||
from help import help_about, help_html
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# // menubar
|
||||
|
@ -582,7 +581,7 @@ class PysolMenubarActions:
|
|||
else:
|
||||
player = self.app.opt.player
|
||||
p0, p1, p2 = player, "", _(" for ") + player
|
||||
n = gettext(self.game.gameinfo.short_name)
|
||||
n = _(self.game.gameinfo.short_name)
|
||||
#
|
||||
if mode == 100:
|
||||
d = Status_StatsDialog(self.top, game=self.game)
|
||||
|
|
|
@ -75,7 +75,6 @@ from pysoltk import destroy_solver_dialog
|
|||
from pysoltk import connect_game_solver_dialog
|
||||
from help import help_about, destroy_help_html
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# // Options
|
||||
|
@ -1350,12 +1349,12 @@ Please select a %s type %s.
|
|||
def getGameTitleName(self, id):
|
||||
gi = self.gdb.get(id)
|
||||
if gi is None: return None
|
||||
return gettext(gi.name)
|
||||
return _(gi.name)
|
||||
|
||||
def getGameMenuitemName(self, id):
|
||||
gi = self.gdb.get(id)
|
||||
if gi is None: return None
|
||||
return gettext(gi.short_name)
|
||||
return _(gi.short_name)
|
||||
|
||||
def getGameRulesFilename(self, id):
|
||||
gi = self.gdb.get(id)
|
||||
|
|
|
@ -30,8 +30,6 @@ from hint import AbstractHint, DefaultHint, CautiousDefaultHint, Yukon_Hint
|
|||
from wizardutil import WizardWidgets
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
|
|
@ -42,8 +42,6 @@ from mfxutil import Struct
|
|||
from resource import CSI
|
||||
from settings import CHECK_GAMES
|
||||
|
||||
gettext = _
|
||||
n_ = lambda x: x
|
||||
|
||||
# /***********************************************************************
|
||||
# // constants
|
||||
|
@ -563,13 +561,13 @@ class GameManager:
|
|||
if self.__games_by_name is None:
|
||||
l1, l2, l3 = [], [], []
|
||||
for id, gi in self.__games.items():
|
||||
name = gettext(gi.name).lower()
|
||||
name = _(gi.name).lower()
|
||||
l1.append((name, id))
|
||||
if gi.name != gi.short_name:
|
||||
name = gettext(gi.short_name).lower()
|
||||
name = _(gi.short_name).lower()
|
||||
l2.append((name, id))
|
||||
for n in gi.altnames:
|
||||
name = gettext(n).lower()
|
||||
name = _(n).lower()
|
||||
l3.append((name, id, n))
|
||||
l1.sort()
|
||||
l2.sort()
|
||||
|
|
|
@ -124,5 +124,5 @@ class DieBoeseSieben(Game):
|
|||
registerGame(GameInfo(120, DieBoeseSieben, "Bad Seven",
|
||||
GI.GT_2DECK_TYPE, 2, 1, GI.SL_MOSTLY_LUCK,
|
||||
ranks=(0, 6, 7, 8, 9, 10, 11, 12),
|
||||
altnames=("Die böse Sieben",) ))
|
||||
altnames=("Die boese Sieben",) ))
|
||||
|
||||
|
|
|
@ -978,7 +978,7 @@ registerGame(GameInfo(65, Giant, "Giant",
|
|||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(3, Irmgard, "Irmgard",
|
||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(119, DieKoenigsbergerin, "Die Königsbergerin",
|
||||
registerGame(GameInfo(119, DieKoenigsbergerin, "Die Koenigsbergerin",
|
||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(174, DieRussische, "Russian Patience",
|
||||
GI.GT_2DECK_TYPE | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL,
|
||||
|
|
|
@ -347,8 +347,7 @@ registerGame(GameInfo(28, DoubleKlondikeByThrees, "Double Klondike by Threes",
|
|||
registerGame(GameInfo(25, Gargantua, "Gargantua",
|
||||
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(15, BigHarp, "Big Harp",
|
||||
GI.GT_KLONDIKE, 2, 0, GI.SL_BALANCED,
|
||||
altnames=("Die große Harfe",) ))
|
||||
GI.GT_KLONDIKE, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(51, Steps, "Steps",
|
||||
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(273, TripleKlondike, "Triple Klondike",
|
||||
|
|
|
@ -29,7 +29,34 @@ import settings
|
|||
# // init
|
||||
# ************************************************************************/
|
||||
|
||||
def fix_gettext():
|
||||
def ugettext(message):
|
||||
# unicoded gettext
|
||||
domain = gettext._current_domain
|
||||
try:
|
||||
t = gettext.translation(domain,
|
||||
gettext._localedirs.get(domain, None))
|
||||
except IOError:
|
||||
return message
|
||||
return t.ugettext(message)
|
||||
gettext.ugettext = ugettext
|
||||
def ungettext(msgid1, msgid2, n):
|
||||
# unicoded ngettext
|
||||
domain = gettext._current_domain
|
||||
try:
|
||||
t = gettext.translation(domain,
|
||||
gettext._localedirs.get(domain, None))
|
||||
except IOError:
|
||||
if n == 1:
|
||||
return msgid1
|
||||
else:
|
||||
return msgid2
|
||||
return t.ungettext(msgid1, msgid2, n)
|
||||
gettext.ungettext = ungettext
|
||||
|
||||
|
||||
def init():
|
||||
fix_gettext()
|
||||
|
||||
if os.name == 'nt' and 'LANG' not in os.environ:
|
||||
try:
|
||||
|
@ -39,6 +66,7 @@ def init():
|
|||
pass
|
||||
##locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
## install gettext
|
||||
##locale_dir = 'locale'
|
||||
locale_dir = None
|
||||
if os.path.isdir(sys.path[0]):
|
||||
|
@ -49,8 +77,14 @@ def init():
|
|||
if os.path.exists(d) and os.path.isdir(d):
|
||||
locale_dir = d
|
||||
##if locale_dir: locale_dir = os.path.normpath(locale_dir)
|
||||
gettext.install('pysol', locale_dir, unicode=True)
|
||||
# debug
|
||||
#gettext.install('pysol', locale_dir, unicode=True) # ngettext don't work
|
||||
gettext.bindtextdomain('pysol', locale_dir)
|
||||
gettext.textdomain('pysol')
|
||||
import __builtin__
|
||||
__builtin__.__dict__['_'] = gettext.ugettext # use unicode
|
||||
__builtin__.__dict__['n_'] = lambda x: x
|
||||
|
||||
## debug
|
||||
if 'PYSOL_CHECK_GAMES' in os.environ or \
|
||||
'PYSOL_DEBUG' in os.environ:
|
||||
settings.CHECK_GAMES = True
|
||||
|
@ -61,6 +95,7 @@ def init():
|
|||
except:
|
||||
settings.DEBUG = 1
|
||||
print 'PySol debugging: set DEBUG to', settings.DEBUG
|
||||
|
||||
## init toolkit
|
||||
if '--gtk' in sys.argv:
|
||||
settings.TOOLKIT = 'gtk'
|
||||
|
|
|
@ -27,12 +27,6 @@ import gtk, gobject, pango
|
|||
import gtk.glade
|
||||
from gtk import gdk
|
||||
|
||||
# PySol imports
|
||||
|
||||
# Toolkit imports
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -125,5 +119,5 @@ class ColorsDialog:
|
|||
'label79',
|
||||
):
|
||||
w = self.widgets_tree.get_widget(n)
|
||||
w.set_text(gettext(w.get_text()))
|
||||
w.set_text(_(w.get_text()))
|
||||
|
||||
|
|
|
@ -28,13 +28,8 @@ import gtk, gobject, pango
|
|||
import gtk.glade
|
||||
|
||||
# PySol imports
|
||||
|
||||
from tkutil import create_pango_font_desc
|
||||
|
||||
# Toolkit imports
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -144,7 +139,7 @@ class FontsDialog:
|
|||
'label75',
|
||||
):
|
||||
w = self.widgets_tree.get_widget(n)
|
||||
w.set_text(gettext(w.get_text()))
|
||||
w.set_text(_(w.get_text()))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -50,11 +50,9 @@ from selecttile import SelectTileDialogWithPreview
|
|||
from selectgame import SelectGameDialogWithPreview
|
||||
from findcarddialog import connect_game_find_card_dialog, destroy_find_card_dialog
|
||||
|
||||
gettext = _
|
||||
|
||||
def ltk2gtk(s):
|
||||
# label tk to gtk
|
||||
return gettext(s).replace('&', '_')
|
||||
return _(s).replace('&', '_')
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -499,7 +497,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
label = gi.short_name
|
||||
else:
|
||||
label = gi.name
|
||||
label = gettext(label)
|
||||
label = _(label)
|
||||
menu_item = gtk.MenuItem(label)
|
||||
menu_item.set_data('user_data', gi.id)
|
||||
menu_item.connect('activate', self.mSelectGame)
|
||||
|
@ -521,7 +519,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
break
|
||||
m = min(n+d-1, len(games)-1)
|
||||
n1, n2 = games[n].name, games[m].name
|
||||
n1, n2 = gettext(n1), gettext(n2)
|
||||
n1, n2 = _(n1), _(n2)
|
||||
label = n1[:3]+' - '+n2[:3]
|
||||
submenu = self._createSubMenu(menu, label=label)
|
||||
self._addGamesSubMenu(games[n:n+d], submenu)
|
||||
|
@ -566,7 +564,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
#
|
||||
games = {}
|
||||
for gi in mahjongg_games:
|
||||
c = gettext(gi.short_name).strip()[0]
|
||||
c = _(gi.short_name).strip()[0]
|
||||
if c in games:
|
||||
games[c].append(gi)
|
||||
else:
|
||||
|
|
|
@ -116,7 +116,7 @@ class SelectCardsetDialogWithPreview(MfxDialog):
|
|||
store.set(iter, 0, root_label, 1, -1)
|
||||
for index, name in cardsets:
|
||||
child_iter = store.append(iter)
|
||||
##~ name = gettext(name)
|
||||
##~ name = _(name)
|
||||
store.set(child_iter, 0, name, 1, index)
|
||||
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ from tkwidget import MfxDialog
|
|||
from tkcanvas import MfxCanvas, MfxCanvasText
|
||||
from pysoltree import PysolTreeView
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Dialog
|
||||
|
@ -197,7 +195,7 @@ class SelectGameDialogWithPreview(MfxDialog):
|
|||
iter = store.append(root_iter)
|
||||
store.set(iter, 0, root_label, 1, -1)
|
||||
for label, games in gl:
|
||||
label = gettext(label)
|
||||
label = _(label)
|
||||
label = label.replace("&", "")
|
||||
self._addGames(store, iter, label, games)
|
||||
|
||||
|
@ -209,7 +207,7 @@ class SelectGameDialogWithPreview(MfxDialog):
|
|||
store.set(iter, 0, root_label, 1, -1)
|
||||
for id, name in games:
|
||||
child_iter = store.append(iter)
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
store.set(child_iter, 0, name, 1, id)
|
||||
|
||||
|
||||
|
@ -294,7 +292,7 @@ class SelectGameDialogWithPreview(MfxDialog):
|
|||
data = []
|
||||
for label, vg in GI.GAMES_BY_COMPATIBILITY:
|
||||
selecter = lambda gi, vg=vg: gi.id in vg
|
||||
label = gettext(label)
|
||||
label = _(label)
|
||||
data.append((label, selecter))
|
||||
self._addGamesFromData(data, store, root_iter,
|
||||
_("by Compatibility"), all_games)
|
||||
|
@ -475,12 +473,12 @@ class SelectGameDialogWithPreview(MfxDialog):
|
|||
def updateInfo(self, gameid):
|
||||
gi = self.app.gdb.get(gameid)
|
||||
# info
|
||||
name = gettext(gi.name)
|
||||
altnames = '\n'.join([gettext(n) for n in gi.altnames])
|
||||
category = gettext(CSI.TYPE[gi.category])
|
||||
name = _(gi.name)
|
||||
altnames = '\n'.join([_(n) for n in gi.altnames])
|
||||
category = _(CSI.TYPE[gi.category])
|
||||
type = ''
|
||||
if gi.si.game_type in GI.TYPE_NAMES:
|
||||
type = gettext(GI.TYPE_NAMES[gi.si.game_type])
|
||||
type = _(GI.TYPE_NAMES[gi.si.game_type])
|
||||
sl = {
|
||||
GI.SL_LUCK: _('Luck only'),
|
||||
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
||||
|
|
|
@ -30,8 +30,6 @@ from gtk import glade
|
|||
# Toolkit imports
|
||||
from tkwidget import MfxDialog
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -149,7 +147,7 @@ class SoundOptionsDialog:
|
|||
'label78',
|
||||
):
|
||||
w = self.widgets_tree.get_widget(n)
|
||||
w.set_text(gettext(w.get_text()))
|
||||
w.set_text(_(w.get_text()))
|
||||
w = self.widgets_tree.get_widget('enable_checkbutton')
|
||||
w.set_label(gettext(w.get_label()))
|
||||
w.set_label(_(w.get_label()))
|
||||
|
||||
|
|
|
@ -26,12 +26,6 @@ __all__ = ['TimeoutsDialog']
|
|||
import gtk, gobject, pango
|
||||
import gtk.glade
|
||||
|
||||
# PySol imports
|
||||
|
||||
# Toolkit imports
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -102,5 +96,5 @@ class TimeoutsDialog:
|
|||
'label30',
|
||||
):
|
||||
w = self.widgets_tree.get_widget(n)
|
||||
w.set_text(gettext(w.get_text()))
|
||||
w.set_text(_(w.get_text()))
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@ from pysollib.stats import PysolStatsFormatter
|
|||
# Toolkit imports
|
||||
from tkwidget import MfxDialog, MfxMessageDialog
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -50,7 +48,7 @@ class StatsFormatter(PysolStatsFormatter):
|
|||
for result in self.getStatResults(player, sort_by):
|
||||
iter = self.store.append(None)
|
||||
self.store.set(iter,
|
||||
0, gettext(result[0]),
|
||||
0, _(result[0]),
|
||||
1, result[1],
|
||||
2, result[2],
|
||||
3, result[3],
|
||||
|
@ -88,7 +86,7 @@ class LogFormatter(PysolStatsFormatter):
|
|||
for result in self.getLogResults(player, prev_games):
|
||||
iter = self.store.append(None)
|
||||
self.store.set(iter,
|
||||
0, gettext(result[0]),
|
||||
0, _(result[0]),
|
||||
1, result[1],
|
||||
2, result[2],
|
||||
3, result[3],
|
||||
|
@ -189,7 +187,7 @@ class Game_StatsDialog:
|
|||
'label18',
|
||||
):
|
||||
w = self.widgets_tree.get_widget(n)
|
||||
w.set_text_with_mnemonic(gettext(w.get_label()))
|
||||
w.set_text_with_mnemonic(_(w.get_label()))
|
||||
# simple
|
||||
for n in (
|
||||
'label5',
|
||||
|
@ -198,7 +196,7 @@ class Game_StatsDialog:
|
|||
'label14'
|
||||
):
|
||||
w = self.widgets_tree.get_widget(n)
|
||||
w.set_text(gettext(w.get_text()))
|
||||
w.set_text(_(w.get_text()))
|
||||
# markup
|
||||
for n in (
|
||||
'label8',
|
||||
|
@ -215,7 +213,7 @@ class Game_StatsDialog:
|
|||
'label24',
|
||||
):
|
||||
w = self.widgets_tree.get_widget(n)
|
||||
s = gettext(w.get_label())
|
||||
s = _(w.get_label())
|
||||
w.set_markup('<b>%s</b>' % s)
|
||||
|
||||
|
||||
|
@ -231,7 +229,7 @@ class Game_StatsDialog:
|
|||
current = 0
|
||||
for id in self.games_id:
|
||||
gi = self.app.gdb.get(id)
|
||||
combo.append_text(gettext(gi.name))
|
||||
combo.append_text(_(gi.name))
|
||||
if id == self.gameid:
|
||||
current = n
|
||||
n += 1
|
||||
|
|
|
@ -41,7 +41,6 @@ import os, glob
|
|||
from mfxutil import Struct, KwStruct, EnvError
|
||||
from settings import DEBUG
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# // Abstract
|
||||
|
|
|
@ -1517,10 +1517,10 @@ class Stack:
|
|||
return s
|
||||
|
||||
def getNumCards(self):
|
||||
from gettext import ungettext
|
||||
n = len(self.cards)
|
||||
if n == 0 : return _('No cards')
|
||||
elif n == 1 : return _('1 card')
|
||||
else : return str(n)+_(' cards')
|
||||
else: return ungettext('%d card', '%d cards', n) % n
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -1795,11 +1795,12 @@ class TalonStack(Stack,
|
|||
return self.game.app.gimages.redeal
|
||||
|
||||
def getHelp(self):
|
||||
from gettext import ungettext
|
||||
if self.max_rounds == -2: nredeals = _('Variable redeals.')
|
||||
elif self.max_rounds == -1: nredeals = _('Unlimited redeals.')
|
||||
elif self.max_rounds == 1: nredeals = _('No redeals.')
|
||||
elif self.max_rounds == 2: nredeals = _('One redeal.')
|
||||
else: nredeals = str(self.max_rounds-1)+_(' redeals.')
|
||||
else:
|
||||
n = self.max_rounds-1
|
||||
nredeals = ungettext('%d readeal', '%d redeals', n) % n
|
||||
##round = _('Round #%d.') % self.round
|
||||
return _('Talon.')+' '+nredeals ##+' '+round
|
||||
|
||||
|
|
|
@ -68,9 +68,6 @@ from tkwidget import MfxMessageDialog
|
|||
#from toolbar import TOOLBAR_BUTTONS
|
||||
from tkconst import TOOLBAR_BUTTONS
|
||||
|
||||
gettext = _
|
||||
n_ = lambda x: x
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -120,7 +117,7 @@ def createToolbarMenu(menubar, menu):
|
|||
menu.add_separator()
|
||||
submenu = MfxMenu(menu, label=n_('Visible buttons'), tearoff=tearoff)
|
||||
for w in TOOLBAR_BUTTONS:
|
||||
submenu.add_checkbutton(label=gettext(w.capitalize()),
|
||||
submenu.add_checkbutton(label=_(w.capitalize()),
|
||||
variable=menubar.tkopt.toolbar_vars[w],
|
||||
command=lambda m=menubar, w=w: m.mOptToolbarConfig(w))
|
||||
|
||||
|
@ -141,7 +138,7 @@ class MfxMenubar(Tkinter.Menu):
|
|||
def labeltoname(self, label):
|
||||
#print label, type(label)
|
||||
name = re.sub(r"[^0-9a-zA-Z]", "", label).lower()
|
||||
label = gettext(label)
|
||||
label = _(label)
|
||||
underline = label.find('&')
|
||||
if underline >= 0:
|
||||
label = label.replace('&', '')
|
||||
|
@ -705,7 +702,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
|
||||
games = {}
|
||||
for gi in mahjongg_games:
|
||||
c = gettext(gi.short_name).strip()[0]
|
||||
c = _(gi.short_name).strip()[0]
|
||||
if c in games:
|
||||
games[c].append(gi)
|
||||
else:
|
||||
|
@ -773,7 +770,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
if not games[n:n+d]:
|
||||
break
|
||||
m = min(n+d-1, len(games)-1)
|
||||
label = gettext(games[n].name)[:3]+' - '+gettext(games[m].name)[:3]
|
||||
label = _(games[n].name)[:3]+' - '+_(games[m].name)[:3]
|
||||
submenu = MfxMenu(menu, label=label, name=None)
|
||||
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
|
||||
command, variable)
|
||||
|
@ -790,9 +787,9 @@ class PysolMenubar(PysolMenubarActions):
|
|||
gi = games[i]
|
||||
columnbreak = i > 0 and (i % cb) == 0
|
||||
if short_name:
|
||||
label = gettext(gi.short_name)
|
||||
label = _(gi.short_name)
|
||||
else:
|
||||
label = gettext(gi.name)
|
||||
label = _(gi.name)
|
||||
## menu.add_radiobutton(command=command, variable=variable,
|
||||
## columnbreak=columnbreak,
|
||||
## value=gi.id, label=label, name=None)
|
||||
|
@ -809,7 +806,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
if len(games) == 0:
|
||||
menu.add_radiobutton(label='<none>', name=None, state='disabled')
|
||||
elif len(games) > self.__cb_max*4:
|
||||
games.sort(lambda a, b: cmp(gettext(a.name), gettext(b.name)))
|
||||
games.sort(lambda a, b: cmp(_(a.name), _(b.name)))
|
||||
self._addSelectAllGameSubMenu(games, menu,
|
||||
command=self.mSelectGame,
|
||||
variable=self.tkopt.gameid)
|
||||
|
|
|
@ -53,7 +53,6 @@ from tkcanvas import MfxCanvasText
|
|||
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
|
||||
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# // Nodes
|
||||
|
@ -70,7 +69,7 @@ class SelectGameNode(SelectDialogTreeNode):
|
|||
# key/value pairs
|
||||
for id, name in self.select_func:
|
||||
if id and name:
|
||||
name = gettext(name) # name of game
|
||||
name = _(name) # name of game
|
||||
node = SelectGameLeaf(self.tree, self, name, key=id)
|
||||
contents.append(node)
|
||||
else:
|
||||
|
@ -79,12 +78,12 @@ class SelectGameNode(SelectDialogTreeNode):
|
|||
# All games
|
||||
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
|
||||
name = gi.name
|
||||
name = gettext(name) # name of game
|
||||
name = _(name) # name of game
|
||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||
contents.append(node)
|
||||
elif gi and self.select_func(gi):
|
||||
name = gi.name
|
||||
name = gettext(name) # name of game
|
||||
name = _(name) # name of game
|
||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||
contents.append(node)
|
||||
return contents or self.tree.data.no_games
|
||||
|
@ -112,7 +111,7 @@ class SelectGameData(SelectDialogTreeData):
|
|||
for name, select_func in data:
|
||||
if name is None or not filter(select_func, self.all_games_gi):
|
||||
continue
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
name = name.replace("&", "")
|
||||
gg.append(SelectGameNode(None, name, select_func))
|
||||
g.append(gg)
|
||||
|
@ -139,7 +138,7 @@ class SelectGameData(SelectDialogTreeData):
|
|||
select_func = lambda gi, games=games: gi.id in games
|
||||
if name is None or not filter(select_func, self.all_games_gi):
|
||||
continue
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
gg.append(SelectGameNode(None, name, select_func))
|
||||
if 1 and gg:
|
||||
s_by_compatibility = SelectGameNode(None, _("by Compatibility"), tuple(gg))
|
||||
|
@ -514,12 +513,12 @@ class SelectGameDialogWithPreview(SelectGameDialog):
|
|||
def updateInfo(self, gameid):
|
||||
gi = self.app.gdb.get(gameid)
|
||||
# info
|
||||
name = gettext(gi.name)
|
||||
altnames = '\n'.join([gettext(n) for n in gi.altnames])
|
||||
category = gettext(CSI.TYPE[gi.category])
|
||||
name = _(gi.name)
|
||||
altnames = '\n'.join([_(n) for n in gi.altnames])
|
||||
category = _(CSI.TYPE[gi.category])
|
||||
type = ''
|
||||
if gi.si.game_type in GI.TYPE_NAMES:
|
||||
type = gettext(GI.TYPE_NAMES[gi.si.game_type])
|
||||
type = _(GI.TYPE_NAMES[gi.si.game_type])
|
||||
sl = {
|
||||
GI.SL_LUCK: _('Luck only'),
|
||||
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
||||
|
|
|
@ -42,8 +42,6 @@ from tkwidget import MfxDialog
|
|||
from tkwidget import PysolScale
|
||||
from tkutil import bind, unbind_destroy
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -82,7 +80,7 @@ class SolverDialog(MfxDialog):
|
|||
gamenames = ['']
|
||||
for id in games:
|
||||
name = app.getGameTitleName(id)
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
gamenames.append(name)
|
||||
self.games[name] = id
|
||||
gamenames.sort()
|
||||
|
@ -238,7 +236,7 @@ class SolverDialog(MfxDialog):
|
|||
|
||||
def connectGame(self, game):
|
||||
name = self.app.getGameTitleName(game.id)
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
if name in self.gamenames:
|
||||
self.start_button.config(state='normal')
|
||||
i = self.gamenames.index(name)
|
||||
|
|
|
@ -59,9 +59,6 @@ import sys, os
|
|||
import traceback
|
||||
import Tkinter
|
||||
|
||||
# Toolkit imports
|
||||
|
||||
n_ = lambda x: x
|
||||
|
||||
# /***********************************************************************
|
||||
# // constants
|
||||
|
|
|
@ -60,8 +60,6 @@ from tkutil import bind, unbind_destroy, loadImage
|
|||
from tkwidget import MfxDialog, MfxMessageDialog
|
||||
from tkwidget import MfxScrolledCanvas
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -376,7 +374,7 @@ class TreeFormatter(PysolStatsFormatter):
|
|||
for result in self.getStatResults(player, sort_by):
|
||||
# result == [name, won+lost, won, lost, time, moves, perc, id]
|
||||
t1, t2, t3, t4, t5, t6, t7, t8 = result
|
||||
t1=gettext(t1) # game name
|
||||
t1 = _(t1) # game name
|
||||
id = self.tree.insert(None, "end", text=t1,
|
||||
values=(t2, t3, t4, t5, t6, t7))
|
||||
self.parent_window.tree_items.append(id)
|
||||
|
@ -395,7 +393,7 @@ class TreeFormatter(PysolStatsFormatter):
|
|||
num_rows = 0
|
||||
for result in self.getLogResults(player, prev_games):
|
||||
t1, t2, t3, t4, t5, t6 = result
|
||||
t1=gettext(t1) # game name
|
||||
t1 = _(t1) # game name
|
||||
id = self.tree.insert(None, "end", text=t1, values=(t2, t3, t4))
|
||||
self.parent_window.tree_items.append(id)
|
||||
num_rows += 1
|
||||
|
|
|
@ -52,9 +52,6 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
|
|||
from tkwidget import MfxTooltip
|
||||
from menubar import createToolbarMenu, MfxMenu
|
||||
|
||||
gettext = _
|
||||
n_ = lambda x: x
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -288,7 +285,7 @@ class PysolToolbar(PysolToolbarActions):
|
|||
'toolbar_name' : name,
|
||||
'command' : command,
|
||||
'takefocus' : 0,
|
||||
'text' : gettext(label),
|
||||
'text' : _(label),
|
||||
}
|
||||
if image:
|
||||
kw['image'] = image
|
||||
|
|
|
@ -35,8 +35,6 @@ from tkwidget import MfxDialog
|
|||
from tkwidget import PysolScale
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
@ -68,8 +66,8 @@ class WizardDialog(MfxDialog):
|
|||
if w.widget == 'preset':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
values = [gettext(v) for v in w.values]
|
||||
default = gettext(w.default)
|
||||
values = [_(v) for v in w.values]
|
||||
default = _(w.default)
|
||||
values.remove(default)
|
||||
values.sort()
|
||||
values.insert(0, default)
|
||||
|
@ -87,7 +85,7 @@ class WizardDialog(MfxDialog):
|
|||
elif w.widget == 'menu':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
values = [gettext(v) for v in w.values]
|
||||
values = [_(v) for v in w.values]
|
||||
cb = Combobox(frame, values=tuple(values),
|
||||
textvariable=w.variable,
|
||||
state='readonly', width=32)
|
||||
|
@ -116,7 +114,7 @@ class WizardDialog(MfxDialog):
|
|||
else:
|
||||
v = w.current_value
|
||||
if w.widget in ('menu', 'preset'):
|
||||
v = gettext(v)
|
||||
v = _(v)
|
||||
w.variable.set(v)
|
||||
|
||||
row += 1
|
||||
|
@ -136,8 +134,8 @@ class WizardDialog(MfxDialog):
|
|||
v = p[w.var_name]
|
||||
else:
|
||||
v = w.default
|
||||
if w.widget in ('menu', 'preset'):
|
||||
v = gettext(v)
|
||||
if w.widget in ('menu', 'preset', 'entry'):
|
||||
v = _(v)
|
||||
w.variable.set(v)
|
||||
|
||||
|
||||
|
|
|
@ -66,9 +66,6 @@ from tkwrap import MfxRadioMenuItem, MfxCheckMenuItem, StringVar
|
|||
#from toolbar import TOOLBAR_BUTTONS
|
||||
from tkconst import TOOLBAR_BUTTONS
|
||||
|
||||
gettext = _
|
||||
n_ = lambda x: x
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -119,7 +116,7 @@ def createToolbarMenu(menubar, menu):
|
|||
menu.add_separator()
|
||||
submenu = MfxMenu(menu, label=n_('Visible buttons'), tearoff=tearoff)
|
||||
for w in TOOLBAR_BUTTONS:
|
||||
submenu.add_checkbutton(label=gettext(w.capitalize()),
|
||||
submenu.add_checkbutton(label=_(w.capitalize()),
|
||||
variable=menubar.tkopt.toolbar_vars[w],
|
||||
command=lambda m=menubar, w=w: m.mOptToolbarConfig(w))
|
||||
|
||||
|
@ -140,7 +137,7 @@ class MfxMenubar(Tkinter.Menu):
|
|||
def labeltoname(self, label):
|
||||
#print label, type(label)
|
||||
name = re.sub(r"[^0-9a-zA-Z]", "", label).lower()
|
||||
label = gettext(label)
|
||||
label = _(label)
|
||||
underline = label.find('&')
|
||||
if underline >= 0:
|
||||
label = label.replace('&', '')
|
||||
|
@ -709,7 +706,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
|
||||
games = {}
|
||||
for gi in mahjongg_games:
|
||||
c = gettext(gi.short_name).strip()[0]
|
||||
c = _(gi.short_name).strip()[0]
|
||||
if c in games:
|
||||
games[c].append(gi)
|
||||
else:
|
||||
|
@ -777,7 +774,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
if not games[n:n+d]:
|
||||
break
|
||||
m = min(n+d-1, len(games)-1)
|
||||
label = gettext(games[n].name)[:3]+' - '+gettext(games[m].name)[:3]
|
||||
label = _(games[n].name)[:3]+' - '+_(games[m].name)[:3]
|
||||
submenu = MfxMenu(menu, label=label, name=None)
|
||||
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
|
||||
command, variable)
|
||||
|
@ -794,9 +791,9 @@ class PysolMenubar(PysolMenubarActions):
|
|||
gi = games[i]
|
||||
columnbreak = i > 0 and (i % cb) == 0
|
||||
if short_name:
|
||||
label = gettext(gi.short_name)
|
||||
label = _(gi.short_name)
|
||||
else:
|
||||
label = gettext(gi.name)
|
||||
label = _(gi.name)
|
||||
## menu.add_radiobutton(command=command, variable=variable,
|
||||
## columnbreak=columnbreak,
|
||||
## value=gi.id, label=label, name=None)
|
||||
|
@ -813,7 +810,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
if len(games) == 0:
|
||||
menu.add_radiobutton(label='<none>', name=None, state='disabled')
|
||||
elif len(games) > self.__cb_max*4:
|
||||
games.sort(lambda a, b: cmp(gettext(a.name), gettext(b.name)))
|
||||
games.sort(lambda a, b: cmp(_(a.name), _(b.name)))
|
||||
self._addSelectAllGameSubMenu(games, menu,
|
||||
command=self.mSelectGame,
|
||||
variable=self.tkopt.gameid)
|
||||
|
|
|
@ -52,7 +52,6 @@ from tkcanvas import MfxCanvasText
|
|||
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
|
||||
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# // Nodes
|
||||
|
@ -69,7 +68,7 @@ class SelectGameNode(SelectDialogTreeNode):
|
|||
# key/value pairs
|
||||
for id, name in self.select_func:
|
||||
if id and name:
|
||||
name = gettext(name) # name of game
|
||||
name = _(name) # name of game
|
||||
node = SelectGameLeaf(self.tree, self, name, key=id)
|
||||
contents.append(node)
|
||||
else:
|
||||
|
@ -78,12 +77,12 @@ class SelectGameNode(SelectDialogTreeNode):
|
|||
# All games
|
||||
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
|
||||
name = gi.name
|
||||
name = gettext(name) # name of game
|
||||
name = _(name) # name of game
|
||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||
contents.append(node)
|
||||
elif gi and self.select_func(gi):
|
||||
name = gi.name
|
||||
name = gettext(name) # name of game
|
||||
name = _(name) # name of game
|
||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||
contents.append(node)
|
||||
return contents or self.tree.data.no_games
|
||||
|
@ -111,7 +110,7 @@ class SelectGameData(SelectDialogTreeData):
|
|||
for name, select_func in data:
|
||||
if name is None or not filter(select_func, self.all_games_gi):
|
||||
continue
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
name = name.replace("&", "")
|
||||
gg.append(SelectGameNode(None, name, select_func))
|
||||
g.append(gg)
|
||||
|
@ -138,7 +137,7 @@ class SelectGameData(SelectDialogTreeData):
|
|||
select_func = lambda gi, games=games: gi.id in games
|
||||
if name is None or not filter(select_func, self.all_games_gi):
|
||||
continue
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
gg.append(SelectGameNode(None, name, select_func))
|
||||
if 1 and gg:
|
||||
s_by_compatibility = SelectGameNode(None, _("by Compatibility"), tuple(gg))
|
||||
|
@ -523,12 +522,12 @@ class SelectGameDialogWithPreview(SelectGameDialog):
|
|||
def updateInfo(self, gameid):
|
||||
gi = self.app.gdb.get(gameid)
|
||||
# info
|
||||
name = gettext(gi.name)
|
||||
altnames = '\n'.join([gettext(n) for n in gi.altnames])
|
||||
category = gettext(CSI.TYPE[gi.category])
|
||||
name = _(gi.name)
|
||||
altnames = '\n'.join([_(n) for n in gi.altnames])
|
||||
category = _(CSI.TYPE[gi.category])
|
||||
type = ''
|
||||
if gi.si.game_type in GI.TYPE_NAMES:
|
||||
type = gettext(GI.TYPE_NAMES[gi.si.game_type])
|
||||
type = _(GI.TYPE_NAMES[gi.si.game_type])
|
||||
sl = {
|
||||
GI.SL_LUCK: _('Luck only'),
|
||||
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
||||
|
|
|
@ -41,8 +41,6 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
|
|||
from tkwidget import MfxDialog
|
||||
from tkutil import bind, unbind_destroy
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -81,7 +79,7 @@ class SolverDialog(MfxDialog):
|
|||
gamenames = ['']
|
||||
for id in games:
|
||||
name = app.getGameTitleName(id)
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
gamenames.append(name)
|
||||
self.games[name] = id
|
||||
gamenames.sort()
|
||||
|
@ -241,7 +239,7 @@ class SolverDialog(MfxDialog):
|
|||
|
||||
def connectGame(self, game):
|
||||
name = self.app.getGameTitleName(game.id)
|
||||
name = gettext(name)
|
||||
name = _(name)
|
||||
if name in self.gamenames:
|
||||
self.start_button.config(state='normal')
|
||||
i = self.gamenames.index(name)
|
||||
|
|
|
@ -58,9 +58,6 @@ __all__ = ['tkversion',
|
|||
import sys, os
|
||||
import Tkinter
|
||||
|
||||
# Toolkit imports
|
||||
|
||||
n_ = lambda x: x
|
||||
|
||||
# /***********************************************************************
|
||||
# // constants
|
||||
|
|
|
@ -59,8 +59,6 @@ from tkutil import bind, unbind_destroy, loadImage
|
|||
from tkwidget import MfxDialog, MfxMessageDialog
|
||||
from tkwidget import MfxScrolledCanvas
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# FIXME - this file a quick hack and needs a rewrite
|
||||
|
||||
|
@ -413,7 +411,7 @@ class CanvasFormatter(PysolStatsFormatter):
|
|||
y += 2*self.h
|
||||
for result in self.getStatResults(player, sort_by):
|
||||
gameid = result.pop()
|
||||
result[0]=gettext(result[0]) # game name
|
||||
result[0] = _(result[0]) # game name
|
||||
self.pstats(y, result, gameid)
|
||||
y += self.h
|
||||
#
|
||||
|
@ -434,7 +432,7 @@ class CanvasFormatter(PysolStatsFormatter):
|
|||
if not player or not prev_games:
|
||||
return 0
|
||||
for result in self.getLogResults(player, prev_games):
|
||||
result[0]=gettext(result[0]) # game name
|
||||
result[0] = _(result[0]) # game name
|
||||
s = "%-25s %-20s %-17s %s" % tuple(result[:4])
|
||||
id = self.canvas.create_text(1, y, text=s, anchor="nw",
|
||||
font=self.font, fill=self.fg)
|
||||
|
|
|
@ -52,9 +52,6 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
|
|||
from tkwidget import MfxTooltip
|
||||
from menubar import createToolbarMenu, MfxMenu
|
||||
|
||||
gettext = _
|
||||
n_ = lambda x: x
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -319,7 +316,7 @@ class PysolToolbar(PysolToolbarActions):
|
|||
'toolbar_name' : name,
|
||||
'command' : command,
|
||||
'takefocus' : 0,
|
||||
'text' : gettext(label),
|
||||
'text' : _(label),
|
||||
'bd' : bd,
|
||||
'relief' : button_relief,
|
||||
'padx' : padx,
|
||||
|
|
|
@ -35,8 +35,6 @@ from pysollib.wizardpresets import presets
|
|||
from tkwidget import MfxDialog
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
@ -69,8 +67,8 @@ class WizardDialog(MfxDialog):
|
|||
if w.widget == 'preset':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
values = [gettext(v) for v in w.values]
|
||||
default = gettext(w.default)
|
||||
values = [_(v) for v in w.values]
|
||||
default = _(w.default)
|
||||
values.remove(default)
|
||||
values.sort()
|
||||
values.insert(0, default)
|
||||
|
@ -86,7 +84,7 @@ class WizardDialog(MfxDialog):
|
|||
elif w.widget == 'menu':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
values = [gettext(v) for v in w.values]
|
||||
values = [_(v) for v in w.values]
|
||||
om = OptionMenu(frame, w.variable, *values)
|
||||
om.grid(row=row, column=1, sticky='ew', padx=2)
|
||||
elif w.widget == 'spin':
|
||||
|
@ -107,8 +105,8 @@ class WizardDialog(MfxDialog):
|
|||
v = w.default
|
||||
else:
|
||||
v = w.current_value
|
||||
if w.widget in ('menu', 'preset'):
|
||||
v = gettext(v)
|
||||
if w.widget in ('menu', 'preset', 'entry'):
|
||||
v = _(v)
|
||||
w.variable.set(v)
|
||||
|
||||
row += 1
|
||||
|
@ -130,7 +128,7 @@ class WizardDialog(MfxDialog):
|
|||
else:
|
||||
v = w.default
|
||||
if w.widget in ('menu', 'preset'):
|
||||
v = gettext(v)
|
||||
v = _(v)
|
||||
w.variable.set(v)
|
||||
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
##
|
||||
##---------------------------------------------------------------------------##
|
||||
|
||||
n_ = lambda x: x
|
||||
|
||||
presets = {
|
||||
'None': {
|
||||
'preset': 'None',
|
||||
|
|
|
@ -27,8 +27,6 @@ from stack import *
|
|||
from layout import Layout
|
||||
from wizardpresets import presets
|
||||
|
||||
gettext = _
|
||||
n_ = lambda x: x
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
@ -45,13 +43,13 @@ class WizSetting:
|
|||
self.values = []
|
||||
for k, v in self.values_map:
|
||||
self.values.append(k)
|
||||
self.translation_map[gettext(k)] = k
|
||||
self.translation_map[_(k)] = k
|
||||
assert self.default in self.values
|
||||
elif widget == 'preset':
|
||||
self.values = []
|
||||
for v in self.values_map:
|
||||
self.values.append(v)
|
||||
self.translation_map[gettext(v)] = v
|
||||
self.translation_map[_(v)] = v
|
||||
assert self.default in self.values
|
||||
else:
|
||||
self.values = self.values_map
|
||||
|
@ -71,7 +69,7 @@ WizardPresets = WizSetting(
|
|||
)
|
||||
GameName = WizSetting(
|
||||
values_map = (),
|
||||
default = 'My Game',
|
||||
default = _('My Game'),
|
||||
widget = 'entry',
|
||||
label = _('Name:'),
|
||||
var_name = 'name',
|
||||
|
@ -186,7 +184,7 @@ FoundMaxMove = WizSetting(
|
|||
FoundEqual = WizSetting(
|
||||
values_map = (0, 1),
|
||||
default = 1,
|
||||
label = _('First card sets base rank:'),
|
||||
label = _('First card sets base cards:'),
|
||||
var_name = 'found_equal',
|
||||
widget = 'check',
|
||||
)
|
||||
|
|
|
@ -6,8 +6,9 @@ import sys, os, re, time
|
|||
from pprint import pprint
|
||||
|
||||
os.environ['LANG'] = 'C'
|
||||
import gettext
|
||||
gettext.install('pysol', 'locale', unicode=True)
|
||||
import __builtin__
|
||||
__builtin__.__dict__['_'] = lambda x: x
|
||||
__builtin__.__dict__['n_'] = lambda x: x
|
||||
|
||||
pysollib_path = os.path.join(sys.path[0], '..')
|
||||
sys.path[0] = os.path.normpath(pysollib_path)
|
||||
|
|
715
scripts/pygettext.py
Normal file
715
scripts/pygettext.py
Normal file
|
@ -0,0 +1,715 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Originally written by Barry Warsaw <barry@zope.com>
|
||||
#
|
||||
# Minimally patched to make it even more xgettext compatible
|
||||
# by Peter Funk <pf@artcom-gmbh.de>
|
||||
#
|
||||
# 2002-11-22 Jürgen Hermann <jh@web.de>
|
||||
# Added checks that _() only contains string literals, and
|
||||
# command line args are resolved to module lists, i.e. you
|
||||
# can now pass a filename, a module or package name, or a
|
||||
# directory (including globbing chars, important for Win32).
|
||||
# Made docstring fit in 80 chars wide displays using pydoc.
|
||||
#
|
||||
# 2007-05-11 Scomoroh <scomoroh@gmail.com>
|
||||
# Added very simple support for ngettext
|
||||
#
|
||||
|
||||
# for selftesting
|
||||
try:
|
||||
import fintl
|
||||
_ = fintl.gettext
|
||||
except ImportError:
|
||||
_ = lambda s: s
|
||||
|
||||
__doc__ = _("""pygettext -- Python equivalent of xgettext(1)
|
||||
|
||||
Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
|
||||
internationalization of C programs. Most of these tools are independent of
|
||||
the programming language and can be used from within Python programs.
|
||||
Martin von Loewis' work[1] helps considerably in this regard.
|
||||
|
||||
There's one problem though; xgettext is the program that scans source code
|
||||
looking for message strings, but it groks only C (or C++). Python
|
||||
introduces a few wrinkles, such as dual quoting characters, triple quoted
|
||||
strings, and raw strings. xgettext understands none of this.
|
||||
|
||||
Enter pygettext, which uses Python's standard tokenize module to scan
|
||||
Python source code, generating .pot files identical to what GNU xgettext[2]
|
||||
generates for C and C++ code. From there, the standard GNU tools can be
|
||||
used.
|
||||
|
||||
A word about marking Python strings as candidates for translation. GNU
|
||||
xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
|
||||
and gettext_noop. But those can be a lot of text to include all over your
|
||||
code. C and C++ have a trick: they use the C preprocessor. Most
|
||||
internationalized C source includes a #define for gettext() to _() so that
|
||||
what has to be written in the source is much less. Thus these are both
|
||||
translatable strings:
|
||||
|
||||
gettext("Translatable String")
|
||||
_("Translatable String")
|
||||
|
||||
Python of course has no preprocessor so this doesn't work so well. Thus,
|
||||
pygettext searches only for _() by default, but see the -k/--keyword flag
|
||||
below for how to augment this.
|
||||
|
||||
[1] http://www.python.org/workshops/1997-10/proceedings/loewis.html
|
||||
[2] http://www.gnu.org/software/gettext/gettext.html
|
||||
|
||||
NOTE: pygettext attempts to be option and feature compatible with GNU
|
||||
xgettext where ever possible. However some options are still missing or are
|
||||
not fully implemented. Also, xgettext's use of command line switches with
|
||||
option arguments is broken, and in these cases, pygettext just defines
|
||||
additional switches.
|
||||
|
||||
Usage: pygettext [options] inputfile ...
|
||||
|
||||
Options:
|
||||
|
||||
-a
|
||||
--extract-all
|
||||
Extract all strings.
|
||||
|
||||
-d name
|
||||
--default-domain=name
|
||||
Rename the default output file from messages.pot to name.pot.
|
||||
|
||||
-E
|
||||
--escape
|
||||
Replace non-ASCII characters with octal escape sequences.
|
||||
|
||||
-D
|
||||
--docstrings
|
||||
Extract module, class, method, and function docstrings. These do
|
||||
not need to be wrapped in _() markers, and in fact cannot be for
|
||||
Python to consider them docstrings. (See also the -X option).
|
||||
|
||||
-h
|
||||
--help
|
||||
Print this help message and exit.
|
||||
|
||||
-k word
|
||||
--keyword=word
|
||||
Keywords to look for in addition to the default set, which are:
|
||||
%(DEFAULTKEYWORDS)s
|
||||
|
||||
You can have multiple -k flags on the command line.
|
||||
|
||||
-K
|
||||
--no-default-keywords
|
||||
Disable the default set of keywords (see above). Any keywords
|
||||
explicitly added with the -k/--keyword option are still recognized.
|
||||
|
||||
--no-location
|
||||
Do not write filename/lineno location comments.
|
||||
|
||||
-n
|
||||
--add-location
|
||||
Write filename/lineno location comments indicating where each
|
||||
extracted string is found in the source. These lines appear before
|
||||
each msgid. The style of comments is controlled by the -S/--style
|
||||
option. This is the default.
|
||||
|
||||
-o filename
|
||||
--output=filename
|
||||
Rename the default output file from messages.pot to filename. If
|
||||
filename is `-' then the output is sent to standard out.
|
||||
|
||||
-p dir
|
||||
--output-dir=dir
|
||||
Output files will be placed in directory dir.
|
||||
|
||||
-S stylename
|
||||
--style stylename
|
||||
Specify which style to use for location comments. Two styles are
|
||||
supported:
|
||||
|
||||
Solaris # File: filename, line: line-number
|
||||
GNU #: filename:line
|
||||
|
||||
The style name is case insensitive. GNU style is the default.
|
||||
|
||||
-v
|
||||
--verbose
|
||||
Print the names of the files being processed.
|
||||
|
||||
-V
|
||||
--version
|
||||
Print the version of pygettext and exit.
|
||||
|
||||
-w columns
|
||||
--width=columns
|
||||
Set width of output to columns.
|
||||
|
||||
-x filename
|
||||
--exclude-file=filename
|
||||
Specify a file that contains a list of strings that are not be
|
||||
extracted from the input files. Each string to be excluded must
|
||||
appear on a line by itself in the file.
|
||||
|
||||
-X filename
|
||||
--no-docstrings=filename
|
||||
Specify a file that contains a list of files (one per line) that
|
||||
should not have their docstrings extracted. This is only useful in
|
||||
conjunction with the -D option above.
|
||||
|
||||
If `inputfile' is -, standard input is read.
|
||||
""")
|
||||
|
||||
import os
|
||||
import imp
|
||||
import sys
|
||||
import glob
|
||||
import time
|
||||
import getopt
|
||||
import token
|
||||
import tokenize
|
||||
import operator
|
||||
|
||||
__version__ = '1.6con'
|
||||
|
||||
default_keywords = ['_']
|
||||
DEFAULTKEYWORDS = ', '.join(default_keywords)
|
||||
default_ngettext_keywords = ['ngettext']
|
||||
|
||||
EMPTYSTRING = ''
|
||||
|
||||
|
||||
|
||||
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
|
||||
# there.
|
||||
pot_header = _('''\
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\\n"
|
||||
"POT-Creation-Date: %(time)s\\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\\n"
|
||||
"MIME-Version: 1.0\\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\\n"
|
||||
"Content-Transfer-Encoding: ENCODING\\n"
|
||||
"Generated-By: pygettext.py %(version)s\\n"
|
||||
|
||||
''')
|
||||
|
||||
|
||||
def usage(code, msg=''):
|
||||
print >> sys.stderr, __doc__ % globals()
|
||||
if msg:
|
||||
print >> sys.stderr, msg
|
||||
sys.exit(code)
|
||||
|
||||
|
||||
|
||||
escapes = []
|
||||
|
||||
def make_escapes(pass_iso8859):
|
||||
global escapes
|
||||
if pass_iso8859:
|
||||
# Allow iso-8859 characters to pass through so that e.g. 'msgid
|
||||
# "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we
|
||||
# escape any character outside the 32..126 range.
|
||||
mod = 128
|
||||
else:
|
||||
mod = 256
|
||||
for i in range(256):
|
||||
if 32 <= (i % mod) <= 126:
|
||||
escapes.append(chr(i))
|
||||
else:
|
||||
escapes.append("\\%03o" % i)
|
||||
escapes[ord('\\')] = '\\\\'
|
||||
escapes[ord('\t')] = '\\t'
|
||||
escapes[ord('\r')] = '\\r'
|
||||
escapes[ord('\n')] = '\\n'
|
||||
escapes[ord('\"')] = '\\"'
|
||||
|
||||
|
||||
def escape(s):
|
||||
global escapes
|
||||
s = list(s)
|
||||
for i in range(len(s)):
|
||||
s[i] = escapes[ord(s[i])]
|
||||
return EMPTYSTRING.join(s)
|
||||
|
||||
|
||||
def safe_eval(s):
|
||||
# unwrap quotes, safely
|
||||
return eval(s, {'__builtins__':{}}, {})
|
||||
|
||||
|
||||
def normalize(s):
|
||||
# This converts the various Python string types into a format that is
|
||||
# appropriate for .po files, namely much closer to C style.
|
||||
lines = s.split('\n')
|
||||
if len(lines) == 1:
|
||||
s = '"' + escape(s) + '"'
|
||||
else:
|
||||
if not lines[-1]:
|
||||
del lines[-1]
|
||||
lines[-1] = lines[-1] + '\n'
|
||||
for i in range(len(lines)):
|
||||
lines[i] = escape(lines[i])
|
||||
lineterm = '\\n"\n"'
|
||||
s = '""\n"' + lineterm.join(lines) + '"'
|
||||
return s
|
||||
|
||||
|
||||
def containsAny(str, set):
|
||||
"""Check whether 'str' contains ANY of the chars in 'set'"""
|
||||
return 1 in [c in str for c in set]
|
||||
|
||||
|
||||
def _visit_pyfiles(list, dirname, names):
|
||||
"""Helper for getFilesForName()."""
|
||||
# get extension for python source files
|
||||
if not globals().has_key('_py_ext'):
|
||||
global _py_ext
|
||||
_py_ext = [triple[0] for triple in imp.get_suffixes()
|
||||
if triple[2] == imp.PY_SOURCE][0]
|
||||
|
||||
# don't recurse into CVS directories
|
||||
if 'CVS' in names:
|
||||
names.remove('CVS')
|
||||
|
||||
# add all *.py files to list
|
||||
list.extend(
|
||||
[os.path.join(dirname, file) for file in names
|
||||
if os.path.splitext(file)[1] == _py_ext]
|
||||
)
|
||||
|
||||
|
||||
def _get_modpkg_path(dotted_name, pathlist=None):
|
||||
"""Get the filesystem path for a module or a package.
|
||||
|
||||
Return the file system path to a file for a module, and to a directory for
|
||||
a package. Return None if the name is not found, or is a builtin or
|
||||
extension module.
|
||||
"""
|
||||
# split off top-most name
|
||||
parts = dotted_name.split('.', 1)
|
||||
|
||||
if len(parts) > 1:
|
||||
# we have a dotted path, import top-level package
|
||||
try:
|
||||
file, pathname, description = imp.find_module(parts[0], pathlist)
|
||||
if file: file.close()
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
# check if it's indeed a package
|
||||
if description[2] == imp.PKG_DIRECTORY:
|
||||
# recursively handle the remaining name parts
|
||||
pathname = _get_modpkg_path(parts[1], [pathname])
|
||||
else:
|
||||
pathname = None
|
||||
else:
|
||||
# plain name
|
||||
try:
|
||||
file, pathname, description = imp.find_module(
|
||||
dotted_name, pathlist)
|
||||
if file:
|
||||
file.close()
|
||||
if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]:
|
||||
pathname = None
|
||||
except ImportError:
|
||||
pathname = None
|
||||
|
||||
return pathname
|
||||
|
||||
|
||||
def getFilesForName(name):
|
||||
"""Get a list of module files for a filename, a module or package name,
|
||||
or a directory.
|
||||
"""
|
||||
if not os.path.exists(name):
|
||||
# check for glob chars
|
||||
if containsAny(name, "*?[]"):
|
||||
files = glob.glob(name)
|
||||
list = []
|
||||
for file in files:
|
||||
list.extend(getFilesForName(file))
|
||||
return list
|
||||
|
||||
# try to find module or package
|
||||
name = _get_modpkg_path(name)
|
||||
if not name:
|
||||
return []
|
||||
|
||||
if os.path.isdir(name):
|
||||
# find all python files in directory
|
||||
list = []
|
||||
os.path.walk(name, _visit_pyfiles, list)
|
||||
return list
|
||||
elif os.path.exists(name):
|
||||
# a single file
|
||||
return [name]
|
||||
|
||||
return []
|
||||
|
||||
|
||||
class TokenEater:
|
||||
def __init__(self, options):
|
||||
self.__options = options
|
||||
self.__messages = {}
|
||||
self.__state = self.__waiting
|
||||
self.__data = []
|
||||
self.__lineno = -1
|
||||
self.__freshmodule = 1
|
||||
self.__curfile = None
|
||||
self.__ngettext = False
|
||||
|
||||
def __call__(self, ttype, tstring, stup, etup, line):
|
||||
# dispatch
|
||||
## import token
|
||||
## print >> sys.stderr, 'ttype:', token.tok_name[ttype], \
|
||||
## 'tstring:', tstring
|
||||
self.__state(ttype, tstring, stup[0])
|
||||
|
||||
def __waiting(self, ttype, tstring, lineno):
|
||||
opts = self.__options
|
||||
# Do docstring extractions, if enabled
|
||||
if opts.docstrings and not opts.nodocstrings.get(self.__curfile):
|
||||
# module docstring?
|
||||
if self.__freshmodule:
|
||||
if ttype == tokenize.STRING:
|
||||
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
|
||||
self.__freshmodule = 0
|
||||
elif ttype not in (tokenize.COMMENT, tokenize.NL):
|
||||
self.__freshmodule = 0
|
||||
return
|
||||
# class docstring?
|
||||
if ttype == tokenize.NAME and tstring in ('class', 'def'):
|
||||
self.__state = self.__suiteseen
|
||||
return
|
||||
if ttype == tokenize.NAME and tstring in opts.keywords:
|
||||
self.__state = self.__keywordseen
|
||||
self.__ngettext = tstring in opts.ngettext_keywords
|
||||
|
||||
def __suiteseen(self, ttype, tstring, lineno):
|
||||
# ignore anything until we see the colon
|
||||
if ttype == tokenize.OP and tstring == ':':
|
||||
self.__state = self.__suitedocstring
|
||||
|
||||
def __suitedocstring(self, ttype, tstring, lineno):
|
||||
# ignore any intervening noise
|
||||
if ttype == tokenize.STRING:
|
||||
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
|
||||
self.__state = self.__waiting
|
||||
elif ttype not in (tokenize.NEWLINE, tokenize.INDENT,
|
||||
tokenize.COMMENT):
|
||||
# there was no class docstring
|
||||
self.__state = self.__waiting
|
||||
|
||||
def __keywordseen(self, ttype, tstring, lineno):
|
||||
if ttype == tokenize.OP and tstring == '(':
|
||||
self.__data = []
|
||||
self.__lineno = lineno
|
||||
self.__state = self.__openseen
|
||||
else:
|
||||
self.__state = self.__waiting
|
||||
|
||||
def __openseen(self, ttype, tstring, lineno):
|
||||
if ttype == tokenize.OP and tstring == ')':
|
||||
# We've seen the last of the translatable strings. Record the
|
||||
# line number of the first line of the strings and update the list
|
||||
# of messages seen. Reset state for the next batch. If there
|
||||
# were no strings inside _(), then just ignore this entry.
|
||||
if self.__data:
|
||||
if self.__ngettext:
|
||||
data = []
|
||||
msg = []
|
||||
for s in self.__data:
|
||||
if s is not None:
|
||||
msg.append(s)
|
||||
else:
|
||||
data.append(EMPTYSTRING.join(msg))
|
||||
msg = []
|
||||
if len(data) == 2 and data[0] and data[1]:
|
||||
self.__addentry(tuple(data))
|
||||
elif self.__options.verbose:
|
||||
print >> sys.stderr, _(
|
||||
'*** %(file)s:%(lineno)s: incorrect ngettext format'
|
||||
) % {
|
||||
'file': self.__curfile,
|
||||
'lineno': self.__lineno
|
||||
}
|
||||
else:
|
||||
self.__addentry(EMPTYSTRING.join(self.__data))
|
||||
self.__state = self.__waiting
|
||||
elif ttype == tokenize.STRING:
|
||||
self.__data.append(safe_eval(tstring))
|
||||
elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT,
|
||||
token.NEWLINE, tokenize.NL]:
|
||||
if self.__ngettext and ttype == tokenize.OP and tstring == ',':
|
||||
self.__data.append(None)
|
||||
elif self.__ngettext: # and ttype == tokenize.NUMBER:
|
||||
pass
|
||||
else:
|
||||
# warn if we see anything else than STRING or whitespace
|
||||
if self.__options.verbose:
|
||||
print >> sys.stderr, _(
|
||||
'*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
|
||||
) % {
|
||||
'token': tstring,
|
||||
'file': self.__curfile,
|
||||
'lineno': self.__lineno
|
||||
}
|
||||
self.__state = self.__waiting
|
||||
|
||||
def __addentry(self, msg, lineno=None, isdocstring=0):
|
||||
if lineno is None:
|
||||
lineno = self.__lineno
|
||||
if not msg in self.__options.toexclude:
|
||||
entry = (self.__curfile, lineno)
|
||||
self.__messages.setdefault(msg, {})[entry] = isdocstring
|
||||
|
||||
def set_filename(self, filename):
|
||||
self.__curfile = filename
|
||||
self.__freshmodule = 1
|
||||
|
||||
def write(self, fp):
|
||||
options = self.__options
|
||||
timestamp = time.ctime(time.time())
|
||||
# The time stamp in the header doesn't have the same format as that
|
||||
# generated by xgettext...
|
||||
print >> fp, pot_header % {'time': timestamp, 'version': __version__}
|
||||
# Sort the entries. First sort each particular entry's keys, then
|
||||
# sort all the entries by their first item.
|
||||
reverse = {}
|
||||
for k, v in self.__messages.items():
|
||||
keys = v.keys()
|
||||
keys.sort()
|
||||
reverse.setdefault(tuple(keys), []).append((k, v))
|
||||
rkeys = reverse.keys()
|
||||
rkeys.sort()
|
||||
for rkey in rkeys:
|
||||
rentries = reverse[rkey]
|
||||
rentries.sort()
|
||||
for k, v in rentries:
|
||||
isdocstring = 0
|
||||
# If the entry was gleaned out of a docstring, then add a
|
||||
# comment stating so. This is to aid translators who may wish
|
||||
# to skip translating some unimportant docstrings.
|
||||
if reduce(operator.__add__, v.values()):
|
||||
isdocstring = 1
|
||||
# k is the message string, v is a dictionary-set of (filename,
|
||||
# lineno) tuples. We want to sort the entries in v first by
|
||||
# file name and then by line number.
|
||||
v = v.keys()
|
||||
v.sort()
|
||||
if not options.writelocations:
|
||||
pass
|
||||
# location comments are different b/w Solaris and GNU:
|
||||
elif options.locationstyle == options.SOLARIS:
|
||||
for filename, lineno in v:
|
||||
d = {'filename': filename, 'lineno': lineno}
|
||||
print >>fp, _(
|
||||
'# File: %(filename)s, line: %(lineno)d') % d
|
||||
elif options.locationstyle == options.GNU:
|
||||
# fit as many locations on one line, as long as the
|
||||
# resulting line length doesn't exceeds 'options.width'
|
||||
locline = '#:'
|
||||
for filename, lineno in v:
|
||||
d = {'filename': filename, 'lineno': lineno}
|
||||
s = _(' %(filename)s:%(lineno)d') % d
|
||||
if len(locline) + len(s) <= options.width:
|
||||
locline = locline + s
|
||||
else:
|
||||
print >> fp, locline
|
||||
locline = "#:" + s
|
||||
if len(locline) > 2:
|
||||
print >> fp, locline
|
||||
if isdocstring:
|
||||
print >> fp, '#, docstring'
|
||||
if isinstance(k, basestring):
|
||||
print >> fp, 'msgid', normalize(k)
|
||||
print >> fp, 'msgstr ""\n'
|
||||
else:
|
||||
# ngettext
|
||||
assert isinstance(k, tuple)
|
||||
assert len(k) == 2
|
||||
print >> fp, 'msgid', normalize(k[0])
|
||||
print >> fp, 'msgid_plural', normalize(k[1])
|
||||
print >> fp, 'msgstr[0] ""'
|
||||
print >> fp, 'msgstr[1] ""\n'
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
global default_keywords
|
||||
try:
|
||||
opts, args = getopt.getopt(
|
||||
sys.argv[1:],
|
||||
'ad:DEhk:Kno:p:S:Vvw:x:X:',
|
||||
['extract-all', 'default-domain=', 'escape', 'help',
|
||||
'keyword=', 'no-default-keywords', 'ngettext-keyword=',
|
||||
'add-location', 'no-location', 'output=', 'output-dir=',
|
||||
'style=', 'verbose', 'version', 'width=', 'exclude-file=',
|
||||
'docstrings', 'no-docstrings',
|
||||
])
|
||||
except getopt.error, msg:
|
||||
usage(1, msg)
|
||||
|
||||
# for holding option values
|
||||
class Options:
|
||||
# constants
|
||||
GNU = 1
|
||||
SOLARIS = 2
|
||||
# defaults
|
||||
extractall = 0 # FIXME: currently this option has no effect at all.
|
||||
escape = 0
|
||||
keywords = []
|
||||
ngettext_keywords = []
|
||||
outpath = ''
|
||||
outfile = 'messages.pot'
|
||||
writelocations = 1
|
||||
locationstyle = GNU
|
||||
verbose = 0
|
||||
width = 78
|
||||
excludefilename = ''
|
||||
docstrings = 0
|
||||
nodocstrings = {}
|
||||
|
||||
options = Options()
|
||||
locations = {'gnu' : options.GNU,
|
||||
'solaris' : options.SOLARIS,
|
||||
}
|
||||
|
||||
# parse options
|
||||
for opt, arg in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
usage(0)
|
||||
elif opt in ('-a', '--extract-all'):
|
||||
options.extractall = 1
|
||||
elif opt in ('-d', '--default-domain'):
|
||||
options.outfile = arg + '.pot'
|
||||
elif opt in ('-E', '--escape'):
|
||||
options.escape = 1
|
||||
elif opt in ('-D', '--docstrings'):
|
||||
options.docstrings = 1
|
||||
elif opt in ('-k', '--keyword'):
|
||||
options.keywords.append(arg)
|
||||
elif opt in ('--ngettext-keyword'):
|
||||
options.ngettext_keywords.append(arg)
|
||||
elif opt in ('-K', '--no-default-keywords'):
|
||||
default_keywords = []
|
||||
elif opt in ('-n', '--add-location'):
|
||||
options.writelocations = 1
|
||||
elif opt in ('--no-location',):
|
||||
options.writelocations = 0
|
||||
elif opt in ('-S', '--style'):
|
||||
options.locationstyle = locations.get(arg.lower())
|
||||
if options.locationstyle is None:
|
||||
usage(1, _('Invalid value for --style: %s') % arg)
|
||||
elif opt in ('-o', '--output'):
|
||||
options.outfile = arg
|
||||
elif opt in ('-p', '--output-dir'):
|
||||
options.outpath = arg
|
||||
elif opt in ('-v', '--verbose'):
|
||||
options.verbose = 1
|
||||
elif opt in ('-V', '--version'):
|
||||
print _('pygettext.py (xgettext for Python) %s') % __version__
|
||||
sys.exit(0)
|
||||
elif opt in ('-w', '--width'):
|
||||
try:
|
||||
options.width = int(arg)
|
||||
except ValueError:
|
||||
usage(1, _('--width argument must be an integer: %s') % arg)
|
||||
elif opt in ('-x', '--exclude-file'):
|
||||
options.excludefilename = arg
|
||||
elif opt in ('-X', '--no-docstrings'):
|
||||
fp = open(arg)
|
||||
try:
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
options.nodocstrings[line[:-1]] = 1
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
# calculate escapes
|
||||
make_escapes(options.escape)
|
||||
|
||||
# calculate all keywords
|
||||
options.keywords.extend(default_keywords)
|
||||
|
||||
options.ngettext_keywords.extend(default_ngettext_keywords)
|
||||
options.keywords.extend(options.ngettext_keywords)
|
||||
|
||||
# initialize list of strings to exclude
|
||||
if options.excludefilename:
|
||||
try:
|
||||
fp = open(options.excludefilename)
|
||||
options.toexclude = fp.readlines()
|
||||
fp.close()
|
||||
except IOError:
|
||||
print >> sys.stderr, _(
|
||||
"Can't read --exclude-file: %s") % options.excludefilename
|
||||
sys.exit(1)
|
||||
else:
|
||||
options.toexclude = []
|
||||
|
||||
# resolve args to module lists
|
||||
expanded = []
|
||||
for arg in args:
|
||||
if arg == '-':
|
||||
expanded.append(arg)
|
||||
else:
|
||||
expanded.extend(getFilesForName(arg))
|
||||
args = expanded
|
||||
|
||||
# slurp through all the files
|
||||
eater = TokenEater(options)
|
||||
for filename in args:
|
||||
if filename == '-':
|
||||
if options.verbose:
|
||||
print _('Reading standard input')
|
||||
fp = sys.stdin
|
||||
closep = 0
|
||||
else:
|
||||
if options.verbose:
|
||||
print _('Working on %s') % filename
|
||||
fp = open(filename)
|
||||
closep = 1
|
||||
try:
|
||||
eater.set_filename(filename)
|
||||
try:
|
||||
tokenize.tokenize(fp.readline, eater)
|
||||
except tokenize.TokenError, e:
|
||||
print >> sys.stderr, '%s: %s, line %d, column %d' % (
|
||||
e[0], filename, e[1][0], e[1][1])
|
||||
finally:
|
||||
if closep:
|
||||
fp.close()
|
||||
|
||||
# write the output
|
||||
if options.outfile == '-':
|
||||
fp = sys.stdout
|
||||
closep = 0
|
||||
else:
|
||||
if options.outpath:
|
||||
options.outfile = os.path.join(options.outpath, options.outfile)
|
||||
fp = open(options.outfile, 'w')
|
||||
closep = 1
|
||||
try:
|
||||
eater.write(fp)
|
||||
finally:
|
||||
if closep:
|
||||
fp.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
# some more test strings
|
||||
_(u'a unicode string')
|
||||
# this one creates a warning
|
||||
_('*** Seen unexpected token "%(token)s"') % {'token': 'test'}
|
||||
_('more' 'than' 'one' 'string')
|
Loading…
Add table
Reference in a new issue