2018-07-23 15:37:50 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
|
|
|
|
import tempfile
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
from pathlib import Path
|
|
|
|
import polib
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
|
|
|
def strip_rst(line):
|
|
|
|
return re.sub(
|
2018-07-23 22:00:52 +00:00
|
|
|
r"""(C-)?:[^:]*?:`[^`]*?` |
|
2018-07-27 08:02:43 +00:00
|
|
|
``.*?`` |
|
|
|
|
\b[A-Z][a-zA-Z-]{2,}[a-zA-Z.-]*\b | # Strip capitalized words and accronyms
|
|
|
|
{[a-z]*?} | # reStructuredText tag
|
|
|
|
\|[a-z]+?\| | # reStructuredText substitution
|
|
|
|
-[A-Za-z]\b |
|
|
|
|
`[^`]*?`_ |
|
2018-07-23 15:37:50 +00:00
|
|
|
\*[^*]*?\*
|
|
|
|
""", '', line, flags=re.VERBOSE)
|
|
|
|
|
|
|
|
|
|
|
|
def po_to_text(po):
|
|
|
|
buffer = []
|
2018-07-23 17:24:10 +00:00
|
|
|
lines = 0
|
2018-07-23 15:37:50 +00:00
|
|
|
entries = polib.pofile(po)
|
|
|
|
for entry in entries:
|
2018-07-27 08:03:21 +00:00
|
|
|
if entry.msgid == entry.msgstr:
|
|
|
|
continue
|
2018-07-23 17:24:10 +00:00
|
|
|
while lines < entry.linenum:
|
|
|
|
buffer.append('')
|
|
|
|
lines += 1
|
2018-07-23 15:37:50 +00:00
|
|
|
buffer.append(strip_rst(entry.msgstr))
|
2018-07-23 17:24:10 +00:00
|
|
|
lines += 1
|
2018-07-23 15:37:50 +00:00
|
|
|
return '\n'.join(buffer)
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description='Check spelling in po files containing restructuredText.')
|
|
|
|
parser.add_argument('-l', '--language', type=str, default='fr')
|
|
|
|
parser.add_argument('--glob', type=str, default='**/*.po')
|
2018-07-23 22:00:52 +00:00
|
|
|
parser.add_argument('--debug', action='store_true')
|
2018-07-23 20:05:57 +00:00
|
|
|
parser.add_argument('-p', '--personal-dict', type=str)
|
2018-07-23 15:37:50 +00:00
|
|
|
args = parser.parse_args()
|
2018-07-23 20:05:57 +00:00
|
|
|
personal_dict = ['-p', args.personal_dict] if args.personal_dict else []
|
2018-07-23 22:28:13 +00:00
|
|
|
errors = 0
|
2018-07-23 15:37:50 +00:00
|
|
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
|
|
tmpdir = Path(tmpdirname)
|
|
|
|
for po_file in Path('.').glob(args.glob):
|
2018-07-23 22:00:52 +00:00
|
|
|
if args.debug:
|
|
|
|
print(po_to_text(str(po_file)))
|
|
|
|
continue
|
2018-07-23 15:37:50 +00:00
|
|
|
(tmpdir / po_file.name).write_text(po_to_text(str(po_file)))
|
|
|
|
output = subprocess.check_output(
|
2018-07-23 20:05:57 +00:00
|
|
|
['hunspell', '-d', args.language] + personal_dict + ['-u3',
|
2018-07-23 15:37:50 +00:00
|
|
|
str(tmpdir / po_file.name)],
|
|
|
|
universal_newlines=True)
|
2018-07-23 17:24:10 +00:00
|
|
|
for line in output.split('\n'):
|
|
|
|
match = re.match(r'(?P<path>.*):(?P<line>[0-9]+): Locate: (?P<error>.*) \| Try: .*$', line)
|
|
|
|
if match:
|
2018-07-23 22:28:13 +00:00
|
|
|
errors += 1
|
2018-07-23 17:24:10 +00:00
|
|
|
print(match.group('path').replace(str(tmpdir), '').lstrip('/'),
|
|
|
|
match.group('line'),
|
|
|
|
match.group('error'),
|
|
|
|
sep=':')
|
2018-07-23 22:28:13 +00:00
|
|
|
exit(0 if errors == 0 else -1)
|
2018-07-23 15:37:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|