8000 Add the ability to check for po files. · sphinx-contrib/sphinx-lint@d945968 · GitHub
[go: up one dir, main page]

Skip to content

Commit d945968

Browse files
committed
Add the ability to check for po files.
1 parent 3ad70a4 commit d945968

File tree

2 files changed

+41
-24
lines changed

2 files changed

+41
-24
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ classifiers = [
2222
requires-python = ">= 3.7"
2323
dependencies = [
2424
"regex",
25+
"polib",
2526
]
2627
dynamic = ["version"]
2728

sphinxlint.py

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
__version__ = "0.6.6"
1414

1515
import argparse
16+
import io
1617
import multiprocessing
1718
import os
1819
import sys
@@ -21,9 +22,9 @@
2122
from itertools import chain, starmap
2223
from os.path import exists, isfile, join, splitext
2324

25+
from polib import pofile, POFile
2426
import regex as re
2527

26-
2728
# The following chars groups are from docutils:
2829
CLOSING_DELIMITERS = "\\\\.,;!?"
2930
DELIMITERS = (
@@ -193,7 +194,7 @@ def check_python_syntax(file, lines, options=None):
193194
role_missing_closing_backtick = re.compile(rf"({ROLE_HEAD}`[^`]+?)[^`]*$")
194195

195196

196-
@checker(".rst")
197+
@checker(".rst", ".po")
197198
def check_missing_backtick_after_role(file, lines, options=None):
198199
"""Search for roles missing their closing backticks.
199200
@@ -246,7 +247,7 @@ def clean_paragraph(paragraph):
246247
return paragraph.replace("\x00", "\\")
247248

248249

249-
@checker(".rst")
250+
@checker(".rst", ".po")
250251
def check_missing_space_after_literal(file, lines, options=None):
251252
r"""Search for inline literals immediately followed by a character.
252253
@@ -267,7 +268,7 @@ def check_missing_space_after_literal(file, lines, options=None):
267268
)
268269

269270

270-
@checker(".rst")
271+
@checker(".rst", ".po")
271272
def check_unbalanced_inline_literals_delimiters(file, lines, options=None):
272273
r"""Search for unbalanced inline literals delimiters.
273274
@@ -445,7 +446,7 @@ def inline_markup_gen(start_string, end_string, extra_allowed_before=""):
445446
)
446447

447448

448-
@checker(".rst", enabled=False)
449+
@checker(".rst", ".po", enabled=False)
449450
def check_default_role(file, lines, options=None):
450451
"""Search for default roles (but they are allowed in many projects).
451452
@@ -471,7 +472,7 @@ def check_default_role(file, lines, options=None):
471472
yield lno, "default role used (hint: for inline literals, use double backticks)"
472473

473474

474-
@checker(".rst")
475+
@checker(".rst", ".po")
475476
def check_directive_with_three_dots(file, lines, options=None):
476477
"""Search for directives with three dots instead of two.
477478
@@ -483,7 +484,7 @@ def check_directive_with_three_dots(file, lines, options=None):
483484
yield lno, "directive should start with two dots, not three."
484485

485486

486-
@checker(".rst")
487+
@checker(".rst", ".po")
487488
def check_directive_missing_colons(file, lines, options=None):
488489
"""Search for directive wrongly typed as comments.
489490
@@ -495,7 +496,7 @@ def check_directive_missing_colons(file, lines, options=None):
495496
yield lno, "comment seems to be intended as a directive"
496497

497498

498-
@checker(".rst")
499+
@checker(".rst", ".po")
499500
def check_missing_space_after_role(file, lines, options=None):
500501
r"""Search for roles immediately followed by a character.
501502
@@ -515,7 +516,7 @@ def check_missing_space_after_role(file, lines, options=None):
515516
yield lno, f"role missing (escaped) space after role: {role.group(0)!r}"
516517

517518

518-
@checker(".rst")
519+
@checker(".rst", ".po")
519520
def check_role_without_backticks(file, lines, options=None):
520521
"""Search roles without backticks.
521522
@@ -528,7 +529,7 @@ def check_role_without_backticks(file, lines, options=None):
528529
yield lno, f"role with no backticks: {no_backticks.group(0)!r}"
529530

530531

531-
@checker(".rst")
532+
@checker(".rst", ".po")
532533
def check_backtick_before_role(file, lines, options=None):
533534
"""Search for roles preceded by a backtick.
534535
@@ -542,7 +543,7 @@ def check_backtick_before_role(file, lines, options=None):
542543
yield lno, "superfluous backtick in front of role"
543544

544545

545-
@checker(".rst")
546+
@checker(".rst", ".po")
546547
def check_missing_space_in_hyperlink(file, lines, options=None):
547548
"""Search for hyperlinks missing a space.
548549
@@ -557,7 +558,7 @@ def check_missing_space_in_hyperlink(file, lines, options=None):
557558
yield lno, "missing space before < in hyperlink"
558559

559560

560-
@checker(".rst")
561+
@checker(".rst", ".po")
561562
def check_missing_underscore_after_hyperlink(file, lines, options=None):
562563
"""Search for hyperlinks missing underscore after their closing backtick.
563564
@@ -572,7 +573,7 @@ def check_missing_underscore_after_hyperlink(file, lines, options=None):
572573
yield lno, "missing underscore after closing backtick in hyperlink"
573574

574575

575-
@checker(".rst")
576+
@checker(".rst", ".po")
576577
def check_role_with_double_backticks(file, lines, options=None):
577578
"""Search for roles with double backticks.
578579
@@ -638,7 +639,7 @@ def looks_like_glued(match):
638639
return True
639640

640641

641-
@checker(".rst")
642+
@checker(".rst", ".po")
642643
def check_missing_space_before_role(file, lines, options=None):
643644
"""Search for missing spaces before roles.
644645
@@ -658,7 +659,7 @@ def check_missing_space_before_role(file, lines, options=None):
658659
yield paragraph_lno + error_offset, f"role missing opening tag colon ({match.group(0)})."
659660

660661

661-
@checker(".rst")
662+
@checker(".rst", ".po")
662663
def check_missing_space_before_default_role(file, lines, options=None):
663664
"""Search for missing spaces before default role.
664665
@@ -681,7 +682,7 @@ def check_missing_space_before_default_role(file, lines, options=None):
681682
)
682683

683684

684-
@checker(".rst")
685+
@checker(".rst", ".po")
685686
def check_hyperlink_reference_missing_backtick(file, lines, options=None):
686687
"""Search for missing backticks in front of hyperlink references.
687688
@@ -702,7 +703,7 @@ def check_hyperlink_reference_missing_backtick(file, lines, options=None):
702703
)
703704

704705

705-
@checker(".rst")
706+
@checker(".rst", ".po")
706707
def check_missing_colon_in_role(file, lines, options=None):
707708
"""Search for missing colons in roles.
708709
@@ -715,23 +716,23 @@ def check_missing_colon_in_role(file, lines, options=None):
715716
yield lno, f"role missing colon before first backtick ({match.group(0)})."
716717

717718

718-
@checker(".py", ".rst", rst_only=False)
719+
@checker(".py", ".rst", ".po", rst_only=False)
719720
def check_carriage_return(file, lines, options=None):
720721
r"""Check for carriage returns (\r) in lines."""
721722
for lno, line in enumerate(lines):
722723
if "\r" in line:
723724
yield lno + 1, "\\r in line"
724725

725726

726-
@checker(".py", ".rst", rst_only=False)
727+
@checker(".py", ".rst", ".po", rst_only=False)
727728
def check_horizontal_tab(file, lines, options=None):
728729
r"""Check for horizontal tabs (\t) in lines."""
729730
for lno, line in en 10000 umerate(lines):
730731
if "\t" in line:
731732
yield lno + 1, "OMG TABS!!!1"
732733

733734

734-
@checker(".py", ".rst", rst_only=False)
735+
@checker(".py", ".rst", ".po", rst_only=False)
735736
def check_trailing_whitespace(file, lines, options=None):
736737
"""Check for trailing whitespaces at end of lines."""
737738
for lno, line in enumerate(lines):
@@ -740,14 +741,14 @@ def check_trailing_whitespace(file, lines, options=None):
740741
yield lno + 1, "trailing whitespace"
741742

742743

743-
@checker(".py", ".rst", rst_only=False)
744+
@checker(".py", ".rst", ".po", rst_only=False)
744745
def check_missing_final_newline(file, lines, options=None):
745746
"""Check that the last line of the file ends with a newline."""
746747
if lines and not lines[-1].endswith("\n"):
747748
yield len(lines), "No newline at end of file."
748749

749750

750-
@checker(".rst", enabled=False, rst_only=True)
751+
@checker(".rst", ".po", enabled=False, rst_only=True)
751752
def check_line_too_long(file, lines, options=None):
752753
"""Check for line length; this checker is not run by default."""
753754
for lno, line in enumerate(lines):
@@ -849,7 +850,7 @@ def type_of_explicit_markup(line):
849850
)
850851

851852

852-
@checker(".rst", enabled=False)
853+
@checker(".rst", ".po", enabled=False)
853854
def check_triple_backticks(file, lines, options=None):
854855
"""Check for triple backticks, like ```Point``` (but it's a valid syntax).
855856
@@ -866,7 +867,7 @@ def check_triple_backticks(file, lines, options=None):
866867
yield lno + 1, "There's no rst syntax using triple backticks"
867868

868869

869-
@checker(".rst", rst_only=False)
870+
@checker(".rst", ".po", rst_only=False)
870871
def check_bad_dedent(file, lines, options=None):
871872
"""Check for mis-alignment in indentation in code blocks.
872873
@@ -1023,13 +1024,28 @@ def check_text(filename, text, checkers, options=None):
10231024
return errors
10241025

10251026

1027+
def po2rst(text):
1028+
"""Extract msgstr entries from a po content, keeping linenos."""
1029+
output = []
1030+
po = pofile(text, encoding="UTF-8")
1031+
for entry in po.translated_entries():
1032+
# Don't check original msgid, assume it's checked directly.
1033+
while len(output) + 1 < entry.linenum:
1034+
output.append("\n")
1035+
for line in entry.msgstr.splitlines():
1036+
output.append(line + "\n")
1037+
return "".join(output)
1038+
1039+
10261040
def check_file(filename, checkers, options: CheckersOptions = None):
10271041
ext = splitext(filename)[1]
10281042
if not any(ext in checker.suffixes for checker in checkers):
10291043
return Counter()
10301044
try:
10311045
with open(filename, encoding="utf-8") as f:
10321046
text = f.read()
1047+
if filename.endswith(".po"):
1048+
text = po2rst(text)
10331049
except OSError as err:
10341050
print(f"{filename}: cannot open: {err}")
10351051
return Counter({4: 1})

0 commit comments

Comments
 (0)
0