@@ -86,50 +86,33 @@ def _read_program_source_by_search(env, progname: str, *, doc_markers: list[str]
8686 return (None , None )
8787
8888
89- def _split_out_examples_sections (text : str | None ) -> tuple [str | None , str | None ]:
90- """Split docstring into (main, examples) where examples are ' ## Example(s)' sections .
89+ def _split_out_doc_section_blocks (text : str | None ) -> tuple [str | None , str | None ]:
90+ """Split a docstring into (preamble, sections) based on our " ## Title" markers .
9191
92- We treat sections introduced by our lightweight marker syntax ("## Title").
93- If the title is "Example" or "Examples" (case-insensitive), we extract that
94- section (including its content until the next "##" marker) and return it
95- separately so callers can render it at the end.
92+ - preamble: everything before the first "##" section marker
93+ - sections: from the first "##" marker to the end
94+
95+ This is used to control placement: the preamble stays near the top of object
96+ documentation, while section blocks (Notes/References/See Also/...) can be
97+ placed after intrinsic blocks (Arguments/Returns/Attributes/Procedures).
9698 """
9799 if not text :
98100 return None , None
99101
100102 lines = str (text ).splitlines ()
101- main : list [str ] = []
102- examples : list [str ] = []
103- i = 0
104- while i < len (lines ):
105- line = lines [i ]
106- m = _RE_DOC_SECTION .match (line )
107- if not m :
108- main .append (line )
109- i += 1
110- continue
111-
112- title = (m .group ("title" ) or "" ).strip ().lower ()
113- is_examples = title in {"example" , "examples" }
114-
115- # Capture this section (header + body until next section header).
116- section_lines : list [str ] = [line ]
117- i += 1
118- while i < len (lines ) and not _RE_DOC_SECTION .match (lines [i ]):
119- section_lines .append (lines [i ])
120- i += 1
103+ first = None
104+ for i , line in enumerate (lines ):
105+ if _RE_DOC_SECTION .match (line ):
106+ first = i
107+ break
121108
122- if is_examples :
123- # Ensure examples start on a clean boundary when appended.
124- if examples and examples [- 1 ].strip () != "" :
125- examples .append ("" )
126- examples .extend (section_lines )
127- else :
128- main .extend (section_lines )
109+ if first is None :
110+ preamble = "\n " .join (lines ).strip () or None
111+ return preamble , None
129112
130- main_text = "\n " .join (main ).strip () or None
131- examples_text = "\n " .join (examples ).strip () or None
132- return main_text , examples_text
113+ preamble = "\n " .join (lines [: first ] ).strip () or None
114+ sections = "\n " .join (lines [ first :] ).strip () or None
115+ return preamble , sections
133116
134117
135118def _preprocess_fortran_docstring (text : str ) -> str :
@@ -546,15 +529,16 @@ def _append_object_description(
546529 desc += signode
547530
548531 content = addnodes .desc_content ()
549- main_doc , examples_doc = _split_out_examples_sections (doc )
550- _append_doc (content , main_doc , state )
532+ preamble_doc , section_blocks_doc = _split_out_doc_section_blocks (doc )
533+ # Keep the opening free-text docstring at the top.
534+ _append_doc (content , preamble_doc , state )
551535 _append_argument_docs (content , args , state )
552536 if objtype == "function" :
553537 _append_return_docs (content , result , state )
554538 _append_component_docs (content , components , state )
555539 _append_type_bound_procedures (content , bindings , all_procedures , state )
556- # Always put Examples at the end of the object documentation .
557- _append_doc (content , examples_doc , state )
540+ # Place all "## ..." section blocks (including "## Examples") after intrinsic blocks .
541+ _append_doc (content , section_blocks_doc , state )
558542 desc += content
559543
560544 section += desc
0 commit comments