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

Kayce Basques via Docutils-users <[email protected]> Sat, 4 Jan 2025 09:45:22 -0800
Newsgroups gmane.text.docutils.user
Message-ID <CAGBRUqX6fZAW39hfrFkG4z7LvMT8v4WDKO3VaXxyhyZ4s6GhVA@mail.gmail.com>
--===============5747190391317612389==
Content-Type: multipart/alternative; boundary="000000000000d45280062ae4f7ef"

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

Adam Turner sent me this response on the Write The Docs Slack:

"Docutils isn=E2=80=99t a format preserving parser =E2=80=94 there have bee=
n various
experimental rST writers but nothing official yet. Your best bet is likely
using the source line information and reading from the source file
yourself."

https://writethedocs.slack.com/archives/C0899Q0G1/p1735852921645109

On Thu, Jan 2, 2025 at 2:58=E2=80=AFPM Kayce Basques <[email protected]> wro=
te:

> 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 m=
e
> so far. Seems like the implementation could be much simpler and bulletpro=
of
> 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,
>     }
>

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

<div dir=3D"ltr">Adam Turner sent me this response on the Write The Docs Sl=
ack:<div><br></div><div>&quot;Docutils isn=E2=80=99t a format preserving pa=
rser =E2=80=94 there have been various experimental rST writers but nothing=
 official yet. Your best bet is likely using the source line information an=
d reading from the source file yourself.&quot;</div><div><br></div><div><a =
href=3D"https://writethedocs.slack.com/archives/C0899Q0G1/p1735852921645109=
">https://writethedocs.slack.com/archives/C0899Q0G1/p1735852921645109</a></=
div></div><br><div class=3D"gmail_quote gmail_quote_container"><div dir=3D"=
ltr" class=3D"gmail_attr">On Thu, Jan 2, 2025 at 2:58=E2=80=AFPM Kayce Basq=
ues &lt;<a href=3D"mailto:[email protected]">[email protected]</a>&gt; wrote:=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr=
"><div dir=3D"ltr"><div dir=3D"ltr">Hello! I believe this is my first messa=
ge in the Docutils community. I&#39;m a big fan of Sphinx and appreciate th=
e core role that Docutils plays in Sphinx. I subscribed to this list and am=
 excited to be more active in the community.<div><br></div><div>I&#39;m wor=
king on a Sphinx extension. In my <font face=3D"monospace">doctree-resolved=
</font> handler I recursively walk through all section nodes. When the exte=
nsion detects something that can be improved in the underlying content, it&=
#39;s often possible for the extension to make the edits automatically. Is =
the <font face=3D"monospace">line</font> property of the <font face=3D"mono=
space">Node</font> class the only reference back to the underlying reStruct=
uredText? Just wanted to check that there&#39;s no explicit reference to th=
e end line of the node, and I&#39;m expected to manually compute the end li=
ne. The manual computation has been kinda error-prone and brittle for me so=
 far. Seems like the implementation could be much simpler and bulletproof i=
f 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 example of the man=
ual computation I&#39;m alluding to:</div><div><br></div><div><br></div><di=
v><font face=3D"monospace">from docutils.nodes import section<br><br></font=
></div><div><font face=3D"monospace">def do_stuff(app, doc_tree, 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 text =3D node.aste=
xt()</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 in=
correct</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 las=
t lines</span></div><div><span style=3D"font-family:monospace">=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 retu=
rn {<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;: True,<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>
</blockquote></div>

--000000000000d45280062ae4f7ef--


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


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