33
44from sphinx .util import logging
55from sphinx .application import Sphinx
6- from sphinx .config import Config
6+ from sphinx .config import Config , ENUM
77from sphinx .util .docutils import SphinxDirective
88
99from docutils .parsers .rst import directives
@@ -24,43 +24,69 @@ def __getitem__(self, _):
2424 return directives .unchanged
2525
2626
27- class MockDirective (SphinxDirective ):
27+ class _MockDirectiveLiteral (SphinxDirective ):
28+ """Mock directive that shows the directive as a literal block."""
2829 optional_arguments = 1
2930 final_argument_whitespace = True
3031 option_spec = MockOptionSpec ()
3132 has_content = True
3233
3334 def run (self ) -> List [nodes .Node ]:
34- mode = None
35- for d in self .config .mock_directives :
36- name = d if isinstance (d , str ) else d [0 ]
37- if self .name != name :
38- continue
39- mode = self .config .mock_default_mode if isinstance (d , str ) else d [1 ]
40- break
35+ literal = nodes .literal_block (self .block_text , self .block_text )
36+ literal ['language' ] = 'rst'
37+ return [literal ]
4138
42- if mode == 'literal' :
43- literal = nodes .literal_block (self .block_text , self .block_text )
44- literal ['language' ] = 'rst'
45- return [literal ]
46- elif mode == 'hide' :
47- return []
48- else :
49- raise ValueError ('unsupported mock mode' )
5039
40+ class _MockDirectiveHide (SphinxDirective ):
41+ """Mock directive that hides the directive content."""
42+ optional_arguments = 1
43+ final_argument_whitespace = True
44+ option_spec = MockOptionSpec ()
45+ has_content = True
46+
47+ def run (self ) -> List [nodes .Node ]:
48+ return []
49+
50+
51+ _MOCK_DIRECTIVE_CLASSES = {
52+ 'literal' : _MockDirectiveLiteral ,
53+ 'hide' : _MockDirectiveHide ,
54+ }
5155
5256
5357def _config_inited (app :Sphinx , config :Config ) -> None :
5458 for d in config .mock_directives :
5559 name = d if isinstance (d , str ) else d [0 ]
56- app .add_directive (name , MockDirective , override = True )
60+ mode = config .mock_default_mode if isinstance (d , str ) else d [1 ]
61+
62+ if mode not in ('literal' , 'hide' ):
63+ raise ValueError (
64+ f'Invalid mock mode for directive "{ name } ": { mode } . '
65+ f'Must be "literal" or "hide"'
66+ )
67+
68+ directive_class = _MOCK_DIRECTIVE_CLASSES [mode ]
69+ app .add_directive (name , directive_class , override = True )
5770
5871
5972def setup (app :Sphinx ) -> Dict :
6073 """Sphinx extension entrypoint."""
6174
62- app .add_config_value ('mock_directives' , [], 'env' )
63- app .add_config_value ('mock_default_mode' , 'hide' , 'env' )
75+ app .add_config_value (
76+ 'mock_directives' ,
77+ default = [],
78+ rebuild = 'env' ,
79+ types = list ,
80+ description = 'List of directive names to mock. Each item can be a string (directive name) '
81+ 'or a tuple (directive name, mode).'
82+ )
83+ app .add_config_value (
84+ 'mock_default_mode' ,
85+ default = 'hide' ,
86+ rebuild = 'env' ,
87+ types = ENUM ('hide' , 'literal' ),
88+ description = 'Default mode for mocking directives. Valid values: "hide", "literal".'
89+ )
6490 app .connect ('config-inited' , _config_inited )
6591
6692 return {'version' : __version__ }
0 commit comments