Using hunspell -a instead of hunspell -l to ensure we report the error at the right line.
This commit is contained in:
parent
f7be80e6a6
commit
f5d70f6ed5
56
pospell.py
56
pospell.py
|
@ -1,13 +1,11 @@
|
||||||
"""pospell is a spellcheckers for po files containing reStructuedText.
|
"""pospell is a spellcheckers for po files containing reStructuedText.
|
||||||
"""
|
"""
|
||||||
from collections import defaultdict
|
|
||||||
import io
|
import io
|
||||||
from string import digits
|
from string import digits
|
||||||
from unicodedata import category
|
from unicodedata import category
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
|
||||||
from contextlib import redirect_stderr
|
from contextlib import redirect_stderr
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -33,7 +31,7 @@ try:
|
||||||
).split("\n")[0]
|
).split("\n")[0]
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print("hunspell not found, please install hunspell.", file=sys.stderr)
|
print("hunspell not found, please install hunspell.", file=sys.stderr)
|
||||||
exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
class DummyNodeClass(docutils.nodes.Inline, docutils.nodes.TextElement):
|
class DummyNodeClass(docutils.nodes.Inline, docutils.nodes.TextElement):
|
||||||
|
@ -109,7 +107,6 @@ def strip_rst(line):
|
||||||
# Drop :: at the end, it would cause Literal block expected
|
# Drop :: at the end, it would cause Literal block expected
|
||||||
line = line[:-2]
|
line = line[:-2]
|
||||||
parser = docutils.parsers.rst.Parser()
|
parser = docutils.parsers.rst.Parser()
|
||||||
components = (docutils.parsers.rst.Parser,)
|
|
||||||
settings = docutils.frontend.Values(
|
settings = docutils.frontend.Values(
|
||||||
{
|
{
|
||||||
"report_level": 2,
|
"report_level": 2,
|
||||||
|
@ -251,10 +248,10 @@ def parse_args():
|
||||||
if args.drop_capitalized and args.no_drop_capitalized:
|
if args.drop_capitalized and args.no_drop_capitalized:
|
||||||
print("Error: don't provide both --drop-capitalized AND --no-drop-capitalized.")
|
print("Error: don't provide both --drop-capitalized AND --no-drop-capitalized.")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(1)
|
sys.exit(1)
|
||||||
if not args.po_file and not args.modified:
|
if not args.po_file and not args.modified:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(1)
|
sys.exit(1)
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
@ -296,26 +293,41 @@ def spell_check(
|
||||||
texts_for_hunspell[po_file] = po_to_text(str(po_file), drop_capitalized)
|
texts_for_hunspell[po_file] = po_to_text(str(po_file), drop_capitalized)
|
||||||
try:
|
try:
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
["hunspell", "-d", language, "-l"] + personal_dict_arg,
|
["hunspell", "-d", language, "-a"] + personal_dict_arg,
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
input="\n".join(texts_for_hunspell.values()),
|
input="\n".join(texts_for_hunspell.values()),
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
return -1
|
return -1
|
||||||
if not output.stdout:
|
|
||||||
return 0
|
errors = 0
|
||||||
for misspelled_word in {
|
checked_files = iter(texts_for_hunspell.items())
|
||||||
word for word in output.stdout.split("\n") if look_like_a_word(word)
|
checked_file_name, checked_text = next(checked_files)
|
||||||
}:
|
checked_lines = iter(checked_text.split("\n"))
|
||||||
for po_file, text_for_hunspell in texts_for_hunspell.items():
|
currently_checked_line = next(checked_lines)
|
||||||
for line_number, line in enumerate(text_for_hunspell.split("\n"), start=1):
|
current_line_number = 1
|
||||||
if misspelled_word in line:
|
for line in output.stdout.split("\n")[1:]:
|
||||||
errors.append((po_file, line_number, misspelled_word))
|
if not line:
|
||||||
errors.sort()
|
try:
|
||||||
for error in errors:
|
currently_checked_line = next(checked_lines)
|
||||||
print(":".join(str(token) for token in error))
|
current_line_number += 1
|
||||||
return len(errors)
|
except StopIteration:
|
||||||
|
try:
|
||||||
|
checked_file_name, checked_text = next(checked_files)
|
||||||
|
checked_lines = iter(checked_text.split("\n"))
|
||||||
|
currently_checked_line = next(checked_lines)
|
||||||
|
current_line_number = 1
|
||||||
|
except StopIteration:
|
||||||
|
return errors
|
||||||
|
continue
|
||||||
|
if line == "*": # OK
|
||||||
|
continue
|
||||||
|
if line[0] == "&":
|
||||||
|
_, original, count, offset, *miss = line.split()
|
||||||
|
if look_like_a_word(original):
|
||||||
|
print(checked_file_name, current_line_number, original, sep=":")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
|
||||||
def gracefull_handling_of_missing_dicts(language):
|
def gracefull_handling_of_missing_dicts(language):
|
||||||
|
@ -349,7 +361,7 @@ https://github.com/JulienPalard/pospell/) so I can enhance this error message.
|
||||||
language=language
|
language=language
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -383,7 +395,7 @@ def main():
|
||||||
)
|
)
|
||||||
if errors == -1:
|
if errors == -1:
|
||||||
gracefull_handling_of_missing_dicts(args.language)
|
gracefull_handling_of_missing_dicts(args.language)
|
||||||
exit(0 if errors == 0 else -1)
|
sys.exit(0 if errors == 0 else -1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in New Issue
Block a user