2
2
3
3
from __future__ import annotations
4
4
5
- import contextlib
6
5
from re import DOTALL , match
7
6
from textwrap import indent
8
7
from typing import TYPE_CHECKING , Any , TypeVar
9
8
9
+ import docutils .utils
10
10
from docutils import nodes
11
- from docutils .io import StringInput
12
11
13
12
from sphinx import addnodes
14
13
from sphinx .domains .std import make_glossary_term , split_term_classifiers
15
14
from sphinx .errors import ConfigError
16
- from sphinx .io import SphinxBaseReader
17
15
from sphinx .locale import __
18
16
from sphinx .locale import init as init_locale
19
- from sphinx .transforms import AutoIndexUpgrader , DoctreeReadEvent , SphinxTransform
20
- from sphinx .transforms .references import SphinxDomains
17
+ from sphinx .transforms import SphinxTransform
21
18
from sphinx .util import get_filetype , logging
19
+ from sphinx .util .docutils import LoggingReporter
22
20
from sphinx .util .i18n import docname_to_domain
23
21
from sphinx .util .index_entries import split_index_msg
24
22
from sphinx .util .nodes import (
28
26
extract_messages ,
29
27
traverse_translatable_index ,
30
28
)
31
- from sphinx .versioning import UIDTransform
32
29
33
30
if TYPE_CHECKING :
34
31
from collections .abc import Sequence
35
32
33
+ from docutils .frontend import Values
34
+
36
35
from sphinx .application import Sphinx
37
36
from sphinx .config import Config
38
37
from sphinx .environment import BuildEnvironment
52
51
N = TypeVar ('N' , bound = nodes .Node )
53
52
54
53
55
- class _SphinxI18nReader (SphinxBaseReader ):
56
- """A document reader for internationalisation (i18n).
57
-
58
- This returns the source line number of the original text
59
- as the current source line number to let users know where
60
- the error happened, because the translated texts are
61
- partial and they don't have correct line numbers.
62
- """
63
-
64
- def __init__ (
65
- self , * args : Any , registry : SphinxComponentRegistry , ** kwargs : Any
66
- ) -> None :
67
- super ().__init__ (* args , ** kwargs )
68
- unused = frozenset ({
69
- PreserveTranslatableMessages ,
70
- Locale ,
71
- RemoveTranslatableInline ,
72
- AutoIndexUpgrader ,
73
- SphinxDomains ,
74
- DoctreeReadEvent ,
75
- UIDTransform ,
76
- })
77
- transforms = self .transforms + registry .get_transforms ()
78
- self .transforms = [
79
- transform for transform in transforms if transform not in unused
80
- ]
81
-
82
-
83
- def publish_msgstr (
54
+ def _publish_msgstr (
84
55
source : str ,
85
56
source_path : str ,
86
57
source_line : int ,
87
- config : Config ,
88
- settings : Any ,
89
58
* ,
59
+ config : Config ,
90
60
env : BuildEnvironment ,
91
61
registry : SphinxComponentRegistry ,
62
+ settings : Values ,
92
63
) -> nodes .Element :
93
64
"""Publish msgstr (single line) into docutils document
94
65
95
66
:param str source: source text
96
67
:param str source_path: source path for warning indication
97
68
:param source_line: source line for warning indication
98
- :param sphinx.config.Config config: sphinx config
99
69
:param docutils.frontend.Values settings: docutils settings
100
- :return: document
101
- :rtype: docutils.nodes.document
70
+ :param sphinx.config.Config config: sphinx config
102
71
:param sphinx.environment.BuildEnvironment env: sphinx environment
103
72
:param sphinx.registry.SphinxComponentRegistry registry: sphinx registry
73
+ :return: document
74
+ :rtype: docutils.nodes.document
104
75
"""
76
+ filetype = get_filetype (config .source_suffix , source_path )
77
+ doc = docutils .utils .new_document (
78
+ f'{ source_path } :{ source_line } :<translated>' , settings
79
+ )
80
+ doc .reporter = LoggingReporter .from_reporter (doc .reporter )
81
+
82
+ # clear rst_prolog temporarily
83
+ rst_prolog = config .rst_prolog
84
+ config .rst_prolog = None
105
85
try :
106
- # clear rst_prolog temporarily
107
- rst_prolog = config .rst_prolog
108
- config .rst_prolog = None
109
-
110
- reader = _SphinxI18nReader (registry = registry )
111
- filetype = get_filetype (config .source_suffix , source_path )
112
86
parser = registry .create_source_parser (filetype , config = config , env = env )
113
- doc = reader .read (
114
- source = StringInput (
115
- source = source , source_path = f'{ source_path } :{ source_line } :<translated>'
116
- ),
117
- parser = parser ,
118
- settings = settings ,
119
- )
120
- with contextlib .suppress (IndexError ): # empty node
121
- return doc [0 ]
122
- return doc
87
+ parser .parse (source , doc )
88
+ doc .current_source = doc .current_line = None
123
89
finally :
124
90
config .rst_prolog = rst_prolog
125
91
92
+ try :
93
+ return doc [0 ] # type: ignore[return-value]
94
+ except IndexError : # empty node
95
+ return doc
96
+
126
97
127
98
def parse_noqa (source : str ) -> tuple [str , bool ]:
128
99
m = match (r'(.*)(?<!\\)#\s*noqa\s*$' , source , DOTALL )
@@ -470,14 +441,14 @@ def apply(self, **kwargs: Any) -> None:
470
441
if isinstance (node , LITERAL_TYPE_NODES ):
471
442
msgstr = '::\n \n ' + indent (msgstr , ' ' * 3 )
472
443
473
- patch = publish_msgstr (
444
+ patch = _publish_msgstr (
474
445
msgstr ,
475
446
source ,
476
447
node .line , # type: ignore[arg-type]
477
- self .config ,
478
- settings ,
448
+ config = self .config ,
479
449
env = self .env ,
480
450
registry = self .env ._registry ,
451
+ settings = settings ,
481
452
)
482
453
# FIXME: no warnings about inconsistent references in this part
483
454
# XXX doctest and other block markup
@@ -491,14 +462,14 @@ def apply(self, **kwargs: Any) -> None:
491
462
if isinstance (node , nodes .term ):
492
463
for _id in node ['ids' ]:
493
464
term , first_classifier = split_term_classifiers (msgstr )
494
- patch = publish_msgstr (
465
+ patch = _publish_msgstr (
495
466
term or '' ,
496
467
source ,
497
468
node .line , # type: ignore[arg-type]
498
- self .config ,
499
- settings ,
469
+ config = self .config ,
500
470
env = self .env ,
501
471
registry = self .env ._registry ,
472
+ settings = settings ,
502
473
)
503
474
updater .patch = make_glossary_term (
504
475
self .env ,
@@ -569,14 +540,14 @@ def apply(self, **kwargs: Any) -> None:
569
540
# This generates: <section ...><title>msgstr</title></section>
570
541
msgstr = msgstr + '\n ' + '=' * len (msgstr ) * 2
571
542
572
- patch = publish_msgstr (
543
+ patch = _publish_msgstr (
573
544
msgstr ,
574
545
source ,
575
546
node .line , # type: ignore[arg-type]
576
- self .config ,
577
- settings ,
547
+ config = self .config ,
578
548
env = self .env ,
579
549
registry = self .env ._registry ,
550
+ settings = settings ,
580
551
)
581
552
# Structural Subelements phase2
582
553
if isinstance (node , nodes .title ):
0 commit comments