Getting the reST source of a section node in a Sphinx extension

Kayce Basques via Docutils-users <[email protected]> Thu, 2 Jan 2025 14:58:22 -0800
Newsgroups gmane.text.docutils.user
Message-ID <CAGBRUqUr=1LtNWY2ZEkOLHuAZ5S0qjk2Ftsir-aKXxarKzNpvQ@mail.gmail.com>
--===============6029887396602877728==
Content-Type: multipart/alternative; boundary="000000000000780787062ac11be2"

--000000000000780787062ac11be2
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello! I believe this is my first message in the Docutils community. I'm a
big fan of Sphinx and appreciate the core role that Docutils plays in
Sphinx. I subscribed to this list and am excited to be more active in the
community.

I'm working on a Sphinx extension. In my doctree-resolved handler I
recursively walk through all section nodes. When the extension detects
something that can be improved in the underlying content, it's often
possible for the extension to make the edits automatically. Is the line
property of the Node class the only reference back to the underlying
reStructuredText? Just wanted to check that there's no explicit reference
to the end line of the node, and I'm expected to manually compute the end
line. The manual computation has been kinda error-prone and brittle for me
so far. Seems like the implementation could be much simpler and bulletproof
if reST explicitly gave me the end line. Just wanted to make sure there's
no better way to do this.

One example of the manual computation I'm alluding to:


from docutils.nodes import section

def do_stuff(app, doc_tree, doc_name):
    for node in doc_tree.traverse(section):
        text =3D node.astext()
        start =3D node.line
        end =3D start + len(text.splitlines())  # Often incorrect
        =E2=80=A6
        # A better approach might be to get the first and last lines
        # of text and search for those delimiters in the source

def setup(app):
    app.connect('doctree-resolved', do_stuff)
    return {
        'version': '0.0.0',
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }

--000000000000780787062ac11be2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr">Hello! I believe this is=
 my first message in the Docutils community. I&#39;m a big fan of Sphinx an=
d appreciate the core role that Docutils plays in Sphinx. I subscribed to t=
his list and am excited to be more active in the community.<div><br></div><=
div>I&#39;m working on a Sphinx extension. In my <font face=3D"monospace">d=
octree-resolved</font> handler I recursively walk through all section nodes=
. When the extension detects something that can be improved in the underlyi=
ng content, it&#39;s often possible for the extension to make the edits aut=
omatically. Is the <font face=3D"monospace">line</font> property of the <fo=
nt face=3D"monospace">Node</font> class the only reference back to the unde=
rlying reStructuredText? Just wanted to check that there&#39;s no explicit =
reference to the end line of the node, and I&#39;m expected to manually com=
pute the end line. The manual computation has been kinda error-prone and br=
ittle for me so far. Seems like the implementation could be much simpler an=
d bulletproof if reST explicitly gave me the end line. Just wanted to make =
sure there&#39;s no better way to do this.</div><div><br></div><div>One exa=
mple of the manual computation I&#39;m alluding to:</div><div><br></div><di=
v><br></div><div><font face=3D"monospace">from docutils.nodes import sectio=
n<br><br></font></div><div><font face=3D"monospace">def do_stuff(app, doc_t=
ree, doc_name):<br>=C2=A0 =C2=A0 for node in doc_tree.traverse(section):<br=
></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 tex=
t =3D node.astext()</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 start =3D node.line</font></div><div><font face=3D"monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 end =3D start=C2=A0+ len(text.splitlines())=
=C2=A0 # Often incorrect</font></div><div><font face=3D"monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =E2=80=A6</font></div><div><span style=3D"font-family:=
monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 # A better approach might be to get =
the first and last lines</span></div><div><span style=3D"font-family:monosp=
ace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 # of text and search for those delimiters =
in the source</span></div><div><font face=3D"monospace"><br>def setup(app):=
<br>=C2=A0 =C2=A0 app.connect(&#39;doctree-resolved&#39;, do_stuff)<br>=C2=
=A0 =C2=A0 return {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 &#39;version&#39;: &#39;=
0.0.0&#39;,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 &#39;parallel_read_safe&#39;: Tr=
ue,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 &#39;parallel_write_safe&#39;: True,<br>=
=C2=A0 =C2=A0 }</font></div></div>
</div>
</div>

--000000000000780787062ac11be2--


--===============6029887396602877728==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


--===============6029887396602877728==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline