def check_header(self, entry, fields): comment_lines = entry.translator_comment.split('\n') r = [] for k in self.keywords: try: if k in fields['Last-Translator'].lower(): r.append(Error(self.errmsg % fields['Last-Translator'])) if k in fields['Language-Team'].lower(): r.append(Error(self.errmsg % fields['Language-Team'])) for l in comment_lines: if k in l.lower(): r.append(Error(self.errmsg % l)) except KeyError: pass return r
class KDECheck(BaseCheck): name_error = Error('KDE 번역 규칙에 따라 번역자 이름을 써야 합니다') email_error = Error('KDE 번역 규칙에 따라 번역자 메일 주소를 써야 합니다') def check(self, entry, context): msgstr = entry.msgstr msgctxt = entry.msgctxt if msgctxt == 'NAME OF TRANSLATORS': # msgid "Your names" if '이름' in msgstr or '성함' in msgstr: return [self.name_error] elif msgctxt == 'EMAIL OF TRANSLATORS': # msgid "Your emails" if '메일' in msgstr or '편지' in msgstr: return [self.email_error] return []
def check(self, entry, context): msgid = entry.msgid msgstr = entry.msgstr if msgstr[-1].isspace() and msgid != '' and msgstr[-1] != msgid[-1]: return [Error('끝에 불필요하게 공백 문자가 있습니다')] return []
def check(self, entry, context): if not self.is_keyword(entry): return [] msgid_keywords = entry.msgid[:-1].split(';') if entry.msgstr[-1] != ';': return [Error(err_fmt)] msgstr_keywords = entry.msgstr[:-1].split(';') for k in msgid_keywords: if k not in msgstr_keywords: return [Error(err_org % k)] s = set() for k in msgstr_keywords: if k in s: return [Error(err_dup % k)] s.add(k) return []
def check(self, entry, context): if True not in [('.gschema' in p) for p in entry.references]: return [] for d in data: if entry.msgid.lower() != d['msgid'].lower(): continue if entry.msgstr != d['msgstr']: return [Error(self.errstr % d['msgstr'])] return []
def check(self, entry, context): if len(entry.msgid) == 0 or entry.msgid == entry.msgstr: return [] lines = entry.extracted_comment.split('\n') for line in lines: if dnt_re.match(line.lower()): return [Error(self.errstr)] else: return []
def check(self, entry, context): msgstr = entry.msgstr errors = [] for i in check_list: if 'check' in i and not i['check'](entry): continue mo = i['re'].search(msgstr) if mo: errors.append(Error(i['msg'])) return errors
def check(self, entry, context): if not entry.references or '.xml:' not in entry.references[0]: # not from an XML file return [] msgid = entry.msgid msgstr = entry.msgstr if msgid == 'translator-credits': # gnome-doc-utils magic return [] parser = ParserCreate() parser.StartElementHandler = start_element parser.EndElementHandler = end_element parser.UseForeignDTD(True) try: parser.Parse('<KPC_DummyTag>' + msgstr + '</KPC_DummyTag>') except ExpatError as e: return [Error(tag_error_string)] except NotDocBook as e: return [Error(notdb_error_string % e)] return []
def check(self, entry, context): if not entry.references or '.page:' not in entry.references[0]: # not from an XML file return [] msgid = entry.msgid msgstr = entry.msgstr if msgid == 'translator-credits': # gnome-doc-utils magic return [] parser = ParserCreate() parser.StartElementHandler = start_element parser.EndElementHandler = end_element parser.UseForeignDTD(True) try: parser.Parse('<_:ko-po-check>' + msgstr + '</_:ko-po-check>') except ExpatError as e: return [Error(tag_error_string)] except UnknownTag as e: return [Error(unknown_tag_error_string % e)] return []
class CopyrightCheck(BaseCheck): copyright_re = re.compile('^([Cc]opyright )?\([Cc]\) ') error = Error('copyright notice는 번역하면 안 됩니다') def check(self, entry, context): msgid_lines = entry.msgid.split('\n') msgstr_lines = entry.msgstr.split('\n') for (msgid, msgstr) in zip(msgid_lines, msgstr_lines): if self.copyright_re.match(msgid) and msgid != msgstr: return [self.error] return []
def check(self, entry, context): for p in entry.references: if '.page' in p or '.xml' in p: break else: return [] for d in data: if not re.match(d['msgid'], entry.msgid, re.IGNORECASE): continue if entry.msgstr != d['msgstr']: return [Error(self.errstr % d['msgstr'])] return []
def check(self, entry, context): msgstr = entry.msgstr errors = [] s = msgstr while 1: mo = typo_re.search(s) if mo: errors.append(Error(typo_error % mo.group(1))) s = s[mo.end():] else: break return errors
def check(self, entry, context): msgid = entry.msgid msgstr = entry.msgstr errors = [] msgid_l = msgid.replace('_', '').replace('&', '').lower() for (id, right, wrong) in data: if (wrong not in msgstr) or (id not in msgid_l): continue if (right not in wrong) and (right in msgstr): continue errors.append(Error(self.errstr % (wrong, id, right.strip()))) return errors
def check(self, entry, context): msgstr = entry.msgstr errors = [] for entry in data: r = entry['re'] errmsg = entry['error'] mo = r.search(msgstr) if mo: if ('except' in entry) and entry['except'].match(mo.group(0)): continue errors.append(Error(errmsg % mo.group(0))) return errors
def check(self, entry, context): msgid = entry.msgid msgstr = entry.msgstr errors = [] msgid_n, msgid_d = normalize_msgid(msgid) msgid_ak = find_access_key(msgid) for (orig, trans) in data: # 모두 대문자로 된 단어는 option argument 따위로 쓰이므로 넘어간다 if msgid_n.lower() == orig and not msgid_n.isupper(): good_msgstr = make_msgstr(trans, msgid_ak, msgid_d) if good_msgstr != msgstr: errors.append(Error(self.errstr % (msgstr, good_msgstr))) return errors
def check(self, entry, context): msgid = entry.msgid msgstr = entry.msgstr gnome_mo = re_accesskey_gnome.match(msgid) kde_mo = re_accesskey_kde.match(msgid) # doubts if the string really contains a access key if gnome_mo and re_accesskey_gnome_unlikely.match(msgid): gnome_mo = None if kde_mo and re_accesskey_kde_unlikely.match(msgid): kde_mo = None if gnome_mo or kde_mo: # too long string to be a label string if len(msgid) > 60: return [] # GConf schema or GSettings schema file if entry.references and ('.schemas' in entry.references[0] or '.gschema' in entry.references[0]): return [] if gnome_mo: letter = gnome_mo.group(1).upper() else: letter = kde_mo.group(1).upper() # check 1: if it's translated with the access key mo = re_accesskey.match(msgstr) if not mo: return [Error(errstr_no_accesskey)] # check 2: check if it's same if letter != mo.group(1).upper(): return [Error(errstr_wrong % (letter, mo.group(1)))] # check 3: check if it's uppercase in "(_X)" form mo = re_lowercase_accesskey.search(msgstr) if mo: return [Error(errstr_lowercase % mo.group(1))] return []
def check(self, entry, context): msgid = entry.msgid msgstr = entry.msgstr mo = re_markup.search(msgid) while mo: tagname = mo.group(group_opentagname) opentag = mo.group(group_opentag) mo = re.search('<' + opentag + '>.+</' + tagname + '>', msgstr, re.M | re.S) if not mo: return [Error(error_string % opentag)] msgid = msgid[mo.start(0) + 1:] mo = re_markup.search(msgid) return []
class TeamMailCheck(HeaderCheck): new_addr = '<*****@*****.**>' old_addr = '<*****@*****.**>' error = Error('새 번역팀 주소를 사용하십시오: %s' % new_addr) def check_header(self, entry, fields): try: value = fields['Language-Team'] if self.old_addr in value: return [self.error] if value.startswith('GNOME Korea') and self.new_addr not in value: return [self.error] except KeyError: pass return []
def check(self, entry, context): if not self.identify(entry): return [] errors = [] for (origre, transfmt) in data: m = origre.search(entry.msgid) if not m: continue orig = m.group(0) matched = [m.group(i + 1) or '' for i in range(0, origre.groups)] trans = transfmt.format(*matched) if trans not in entry.msgstr: errors.append(Error(self.errstr % (orig, trans))) return errors
def check(self, entry, context): msgstr = entry.msgstr errors = [] for data in misspell_data: misspell_re = data['re'] misspell_error = data['error'] s = msgstr while 1: mo = misspell_re.search(s) if mo: if ('func' in data and data['func'](mo.group(1))): s = s[mo.end():] continue errors.append(Error(misspell_error % mo.group(1))) s = s[mo.end():] else: break return errors
def check_header(self, entry, fields): result = [] # Report-Msgid-Bugs-To: 내용이 없는 경우 try: if fields['Report-Msgid-Bugs-To'] == '': errmsg = 'Report-Msgid-Bugs-To: 비어 있습니다. ' \ '버그 보고하는 메일 혹은 웹 주소를 쓰십시오' result.append(Error(errmsg)) except KeyError: pass # 기본값 그대로 쓴 경우 if fields['Last-Translator'].startswith('FULL NAME'): errmsg = 'Last-Translator: 기본값을 바꾸지 않았습니다. 번역자 이름을 쓰십시오' result.append(Error(errmsg)) if 'EMAIL@ADDRESS' in fields['Last-Translator']: errmsg = 'Last-Translator: 기본값을 바꾸지 않았습니다. 번역자 메일 주소를 쓰십시오' result.append(Error(errmsg)) # Language-Team: 쓰지 않았거나 gettext 기본값을 바꾸지 않은 경우 if 'Language-Team' not in fields: errmsg = 'Language-Team: 필드가 없습니다. 번역 팀이 따로 없으면 본인 주소를 쓰십시오' result.append(Error(errmsg)) elif fields['Language-Team'] == '': errmsg = 'Language-Team: 비어 있습니다. 번역 팀이 따로 없으면 본인 주소를 쓰십시오' result.append(Error(errmsg)) elif '*****@*****.**' in fields['Language-Team']: errmsg = 'Language-Team: 기본값을 바꾸지 않았습니다. 해당 번역팀 메일 주소를 쓰십시오' result.append(Error(errmsg)) # Content-Type: UTF-8 추천 if 'charset=utf-8' not in fields['Content-Type'].lower(): errmsg = 'Content-Type: UTF-8 사용을 추천합니다 (charset=UTF-8)' result.append(Error(errmsg)) # Plural-Forms: 한국어에 대한 복수형이 아닌 경우 correct_value = 'nplurals=1; plural=0;' try: if fields['Plural-Forms'] != correct_value: errmsg = 'Plural-Forms: 한국어는 다음과 같이 씁니다: "%s"' result.append(Error(errmsg % correct_value)) except KeyError: pass return result
def check(self, entry, context): if entry.check_flag('c-format'): josa_re = josa_c_re elif entry.check_flag('javascript-format'): josa_re = josa_c_re elif entry.check_flag('python-format'): josa_re = josa_py_re else: return [] msgstr = entry.msgstr errors = [] while True: mo = josa_re.search(msgstr) if mo: sug = mo.group('fmt') + josa_suggest(mo.group('josa')) errors.append(Error(self.errstr % (mo.group('case'), sug))) msgstr = msgstr[mo.end():] else: break return errors
def check(self, entry, context): if not self.identify(entry): return [] msgid = normalize_msg(entry.msgid) msgstr = normalize_msg(entry.msgstr) for d in data: re_msgid = d['re_msgid'] re_msgstr = d['re_msgstr'] label_msgid = d['label_msgid'] label_msgstr = d['label_msgstr'] re_except = d['re_exception'] if re_msgid.match(msgid): if re_msgstr.match(msgstr): break if re_except and re_except.match(msgid): break return [ Error(self.errstr % (entry.msgstr, label_msgid, label_msgstr)) ] return []
# -*- coding: utf-8 -*- import re from KPC.classes import Error, BaseCheck data = [ { 're': re.compile('.*[^\.]\.$'), 'except': re.compile('.*(\)|etc|No|a\.m|p\.m)\.$'), 'error': Error('번역문이 원문과 같이 .으로 끝나야 합니다') }, { 're': re.compile('.*:$'), 'error': Error('번역문이 원문과 같이 :으로 끝나야 합니다') }, { 're': re.compile('.*[^\s]\.\.\.$'), 'except': re.compile('.*(etc)\.\.\.$'), 'error': Error('번역문이 원문과 같이 ...으로 끝나야 합니다') }, { 're': re.compile('.*…$'), 'error': Error('번역문이 원문과 같이 …으로 끝나야 합니다') }, ] class ConsistencyCheck(BaseCheck): def check(self, entry, context): msgid = entry.msgid msgstr = entry.msgstr
def check(self, entry, context): for d in data: if [x for x in entry.references if (d['ref'] + ':') in x]: if entry.msgid == d['msgid'] and entry.msgstr != d['msgstr']: return [Error(self.errstr % d['msgstr'])] return []
# -*- coding: utf-8 -*- import re from KPC.classes import Error, BaseCheck data = [ { 're': re.compile('.*[^\.]\.$'), 'except': re.compile('.*(\)|etc|No|a\.m|p\.m)\.$'), 'error': Error('번역문이 원문과 같이 .으로 끝나야 합니다') }, { 're': re.compile('.*:$'), 'error': Error('번역문이 원문과 같이 :으로 끝나야 합니다') }, { 're': re.compile('.*[^\s]\.\.\.$'), 'except': re.compile('.*(etc)\.\.\.$'), 'error': Error('번역문이 원문과 같이 ...으로 끝나야 합니다') }, { 're': re.compile('.*…$'), 'error': Error('번역문이 원문과 같이 …으로 끝나야 합니다') }, { 're': re.compile('^[^"]*\u201c[^"]*\u201d[^"]*$'), 'error': Error('원문과 같은 유니코드 따옴표를 (U+201C, U+201D) 써야 합니다') }, ]