99from __future__ import annotations
1010from typing import override
1111from abc import abstractmethod , ABC
12+ from dataclasses import dataclass
1213
1314from docutils import nodes
14- from docutils .parsers . rst import directives
15+ from docutils .nodes import fully_normalize_name
1516from sphinx .util import logging
1617from sphinx .util .docutils import SphinxDirective , SphinxRole
1718from sphinx .application import Sphinx
1819from sphinx .transforms import SphinxTransform
20+ from sphinx .util .nodes import make_id
21+ from sphinx .environment import BuildEnvironment
1922
20- from .data import Field , Schema , Data
23+
24+ from .data import Field , Schema , RawData , ParsedData
2125from .template import Template , Phase , MarkupParser
2226from . import extra_contexts
2327from . import utils
2630
2731
2832class BaseNode (nodes .Node ):
29- data : Data
3033 template : Template
3134 schema : Schema
3235
@@ -35,6 +38,7 @@ class BaseNode(nodes.Node):
3538
3639
3740class pending_node (BaseNode , nodes .Invisible , nodes .meta ):
41+ data : RawData
3842 name_external : bool = False
3943 content_external : bool = False
4044
@@ -58,6 +62,7 @@ def render(self, caller: Caller, replace: bool = False) -> rendered_node:
5862
5963 renderer = self ._get_caller_markup_parser (caller )
6064 rendered = rendered_node ()
65+ rendered .data = parsed
6166 rendered += self .template .render (
6267 renderer ,
6368 parsed ,
@@ -68,6 +73,7 @@ def render(self, caller: Caller, replace: bool = False) -> rendered_node:
6873 },
6974 )
7075 rendered .update_all_atts (self )
76+ # TODO: check tmpl schema line no
7177
7278 if replace :
7379 self .replace_self (rendered )
@@ -120,9 +126,44 @@ def _get_caller_reporter(self, caller: Caller, e: ValueError) -> Exception:
120126 ... # TODO
121127
122128
129+ @dataclass
130+ class _Caller :
131+ v : Caller
132+
133+ @property
134+ def env (self ) -> BuildEnvironment :
135+ return self .v .env
136+
137+ @property
138+ def doctree (self ) -> nodes .document :
139+ if isinstance (self .v , SphinxDirective ):
140+ return self .v .state .document
141+ elif isinstance (self .v , SphinxRole ):
142+ return self .v .inliner .document
143+ elif isinstance (self .v , SphinxTransform ):
144+ return self .v .document
145+ else :
146+ raise NotImplemented
147+
148+
123149class rendered_node (BaseNode , nodes .container ):
124- anchor : nodes .Element | None
150+ data : ParsedData
151+
152+ def setup_anchor (self , caller : Caller , ahrnode : nodes .Element , prefix : str = '' , term : str | None = None ) -> str :
153+ _caller = _Caller (caller )
154+ ahrid = make_id (_caller .env , _caller .doctree , prefix = prefix , term = term )
155+ ahrnode ['ids' ].append (ahrid )
156+ _caller .doctree .note_explicit_target (ahrnode )
125157
158+ def append_name (name ):
159+ ahrnode ['names' ].append (fully_normalize_name (str (name )))
160+
161+ if isinstance (self .data .name , list ):
162+ [append_name (x ) for x in self .data .name ]
163+ else :
164+ append_name (self .data .name )
165+
166+ return ahrid
126167
127168class BaseDataMarkup (ABC ):
128169 """Methods to be overrided."""
@@ -133,13 +174,14 @@ def current_template(self) -> Template: ...
133174 @abstractmethod
134175 def current_schema (self ) -> Schema : ...
135176
136- def process_data (self , data : Data ) -> None : ...
177+ def process_raw_data (self , data : RawData ) -> None : ...
178+
179+ def process_paresd_data (self , data : ParsedData ) -> None : ...
137180
138181 def process_pending_node (self , n : pending_node ) -> None : ...
139182
140183 def process_rendered_node (self , n : rendered_node ) -> None : ...
141184
142-
143185class BaseDataDirective (BaseDataMarkup , SphinxDirective ):
144186 """Methods overridden from parent."""
145187
@@ -153,12 +195,12 @@ def run(self) -> list[nodes.Node]:
153195 """Methods used internal."""
154196
155197 def build_pending_node (self ) -> pending_node :
156- data = Data (
198+ data = RawData (
157199 self .arguments [0 ] if self .arguments else None ,
158200 self .options .copy (),
159201 '\n ' .join (self .content ) if self .has_content else None ,
160202 )
161- self .process_data (data )
203+ self .process_raw_data (data )
162204
163205 tmpl = self .current_template ()
164206 schema = self .current_schema ()
@@ -172,9 +214,13 @@ def build_pending_node(self) -> pending_node:
172214
173215 def render_pending_node (self , pending : pending_node ) -> rendered_node :
174216 rendered = pending .render (self )
217+ self .process_paresd_data (rendered .data )
175218 self .process_rendered_node (rendered )
219+
176220 return rendered
177221
222+ """Helper methods to be subclasses."""
223+
178224
179225class BaseDataRole (BaseDataMarkup , SphinxRole ):
180226 """Methods overridden from parent."""
@@ -190,8 +236,8 @@ def run(self) -> tuple[list[nodes.Node], list[nodes.system_message]]:
190236
191237 def build_pending_node (self ) -> pending_node :
192238 # TODO: self.content. self.options
193- data = Data (None , {}, self .text )
194- self .process_data (data )
239+ data = RawData (None , {}, self .text )
240+ self .process_raw_data (data )
195241
196242 tmpl = self .current_template ()
197243 schema = self .current_schema ()
0 commit comments