Skip to content

Commit 41475e7

Browse files
committed
update
1 parent 8763b17 commit 41475e7

1 file changed

Lines changed: 38 additions & 27 deletions

File tree

src/sphinxnotes/data/__init__.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88

99
from __future__ import annotations
10+
from logging import warning
1011
from typing import Any, cast
1112
from textwrap import dedent
1213

@@ -59,10 +60,13 @@ class DataNode(nodes.Node):
5960
template: Template
6061
schema: Schema
6162

62-
class pending_data_node(DataNode, nodes.Invisible, nodes.Element):
63+
class pending_data_node(DataNode, nodes.Invisible, nodes.meta):
6364
need_external_data: bool = False
6465

6566
def render(self, caller: SphinxDirective | SphinxTransform, replace: bool = False) -> rendered_data_node:
67+
if self.need_external_data:
68+
self._complete_external_data()
69+
6670
try:
6771
parsed = self.schema.parse(self.data)
6872
except ValueError as e:
@@ -91,6 +95,17 @@ def render(self, caller: SphinxDirective | SphinxTransform, replace: bool = Fals
9195

9296
return rendered
9397

98+
def _complete_external_data(self):
99+
if not self.data.name:
100+
if title := find_titular_node_upward(self.parent):
101+
self.data.name = title.astext()
102+
103+
if not self.data.content:
104+
contnodes = []
105+
for i, child in enumerate(self.parent):
106+
if child == self:
107+
contnodes = self.parent[i:]
108+
self.data.content = '\n\n'.join([n.astext() for n in contnodes])
94109

95110

96111
class rendered_data_node(DataNode, nodes.container): ...
@@ -168,7 +183,7 @@ class DefineDirective(SphinxDirective):
168183
optional_arguments = 1
169184
has_content = True
170185

171-
def extract_data(self) -> Data:
186+
def _extract_data(self) -> Data:
172187
return Data(
173188
self.arguments[0] if self.arguments else None,
174189
self.options.copy(),
@@ -183,63 +198,55 @@ def current_schema(self) -> Schema:
183198
schema = self.env.current_document.get(SCHEMA_KEY, DEFAULT_SCHEMA)
184199
return cast(Schema, schema)
185200

186-
def run(self) -> list[nodes.Node]:
187-
data = self.extract_data()
201+
def new_pending_node(self) -> pending_data_node:
202+
data = self._extract_data()
188203
tmpl = self.current_template()
189204
schema = self.current_schema()
190205

191206
n = pending_data_node()
192207
self.set_source_info(n)
193208
n.data, n.template, n.schema = data, tmpl, schema
194209

195-
if tmpl.phase != Phase.Parsing:
210+
return n
211+
212+
def run(self) -> list[nodes.Node]:
213+
n = self.new_pending_node()
214+
if n.template.phase != Phase.Parsing:
196215
return [n]
197216

198217
return [n.render(self)]
199218

200-
class FreeDefineDirective(DefineDirective, FreeStyleDirective): ...
201-
202-
def complete_data(pending: pending_data_node):
203-
data = pending.data
204219

205-
if data.content_missing:
206-
contnodes = []
207-
for i, child in enumerate(pending.parent):
208-
if child == pending:
209-
contnodes = pending.parent[i:]
210-
data.content = '\n\n'.join([n.astext() for n in contnodes])
211-
data.content_missing = False
220+
class FreeDefineDirective(DefineDirective, FreeStyleDirective): ...
212221

213222

223+
class AutoDefineDirective(DefineDirective, FreeStyleDirective):
224+
def new_pending_node(self) -> pending_data_node:
225+
n = super().new_pending_node()
226+
n.need_external_data = True
227+
return n
214228

215229
class ParsedHook(SphinxDirective):
216230
def run(self) -> list[nodes.Node]:
217-
218231
# Save origin system_message method.
219232
orig_sysmsg = self.state_machine.reporter.system_message
220233

221234
for pending in self.state.document.findall(pending_data_node):
235+
if pending.template.phase != Phase.Parsed:
236+
continue
237+
222238
# Hook system_message method to let it report the
223239
# correct line number.
224240
def sysmsg_fixed_lineno(level, message, *children, **kwargs):
225241
kwargs['line'] = pending.line
226242
return orig_sysmsg(level, message, *children, **kwargs)
227243
self.state_machine.reporter.system_message = sysmsg_fixed_lineno
228244

229-
data = pending.data
230-
231-
if data.content_missing:
232-
contnodes = []
233-
for i, child in enumerate(pending.parent):
234-
if child == pending:
235-
contnodes = pending.parent[i:]
236-
data.content = '\n\n'.join([n.astext() for n in contnodes])
237-
data.content_missing = False
238-
239245
pending.render(self, replace=True)
240246

241247
# Restore system_message method.
242248
self.state_machine.reporter.system_message = orig_sysmsg
249+
243250
return [] # nothing to return
244251

245252
def on_source_read(app, docname, content):
@@ -255,6 +262,9 @@ class ResolvingHook(SphinxTransform):
255262

256263
def apply(self, **kwargs):
257264
for pending in self.document.findall(pending_data_node):
265+
if pending.template.phase != Phase.Resolving:
266+
continue
267+
258268
pending.render(self, replace=True)
259269

260270

@@ -264,6 +274,7 @@ def setup(app: Sphinx):
264274
app.add_directive('data:tmpl', TemplateDirective, False)
265275
app.add_directive('data:schema', DataSchemaDirective, False)
266276
app.add_directive('data:def', FreeDefineDirective, False)
277+
app.add_directive('data:autodef', AutoDefineDirective, False)
267278
app.add_directive('data:parsed-hook', ParsedHook, False)
268279

269280
app.connect('source-read', on_source_read)

0 commit comments

Comments
 (0)