@@ -461,6 +461,35 @@ def _backlink_concepts(wiki_dir: Path, doc_name: str, concept_slugs: list[str])
461461 path .write_text (text , encoding = "utf-8" )
462462
463463
464+ def _find_section_bounds (lines : list [str ], heading : str ) -> tuple [int , int ] | None :
465+ """Return [start, end) line indexes for a section headed by ``heading``."""
466+ for i , line in enumerate (lines ):
467+ if line != heading :
468+ continue
469+ start = i + 1
470+ end = len (lines )
471+ for j in range (start , len (lines )):
472+ if lines [j ].startswith ("## " ):
473+ end = j
474+ break
475+ return start , end
476+ return None
477+
478+
479+ def _find_index_entry_line (lines : list [str ], heading : str , link : str ) -> int | None :
480+ """Find an index entry that starts with ``- {link}`` inside one section only."""
481+ bounds = _find_section_bounds (lines , heading )
482+ if bounds is None :
483+ return None
484+
485+ start , end = bounds
486+ entry_prefix = f"- { link } "
487+ for i in range (start , end ):
488+ if lines [i ].startswith (entry_prefix ):
489+ return i
490+ return None
491+
492+
464493def _update_index (
465494 wiki_dir : Path , doc_name : str , concept_names : list [str ],
466495 doc_brief : str = "" , concept_briefs : dict [str , str ] | None = None ,
@@ -484,34 +513,32 @@ def _update_index(
484513 encoding = "utf-8" ,
485514 )
486515
487- text = index_path .read_text (encoding = "utf-8" )
516+ lines = index_path .read_text (encoding = "utf-8" ). split ( " \n " )
488517
489518 doc_link = f"[[summaries/{ doc_name } ]]"
490- if doc_link not in text :
519+ if _find_index_entry_line ( lines , "## Documents" , doc_link ) is None :
491520 doc_entry = f"- { doc_link } ({ doc_type } )"
492521 if doc_brief :
493522 doc_entry += f" — { doc_brief } "
494- if "## Documents" in text :
495- text = text .replace ("## Documents\n " , f"## Documents\n { doc_entry } \n " , 1 )
523+ doc_bounds = _find_section_bounds (lines , "## Documents" )
524+ if doc_bounds is not None :
525+ lines .insert (doc_bounds [0 ], doc_entry )
496526
497527 for name in concept_names :
498528 concept_link = f"[[concepts/{ name } ]]"
499529 concept_entry = f"- { concept_link } "
500530 if name in concept_briefs :
501531 concept_entry += f" — { concept_briefs [name ]} "
502- if concept_link in text :
532+ concept_line = _find_index_entry_line (lines , "## Concepts" , concept_link )
533+ if concept_line is not None :
503534 if name in concept_briefs :
504- lines = text .split ("\n " )
505- for i , line in enumerate (lines ):
506- if concept_link in line :
507- lines [i ] = concept_entry
508- break
509- text = "\n " .join (lines )
535+ lines [concept_line ] = concept_entry
510536 else :
511- if "## Concepts" in text :
512- text = text .replace ("## Concepts\n " , f"## Concepts\n { concept_entry } \n " , 1 )
537+ concept_bounds = _find_section_bounds (lines , "## Concepts" )
538+ if concept_bounds is not None :
539+ lines .insert (concept_bounds [0 ], concept_entry )
513540
514- index_path .write_text (text , encoding = "utf-8" )
541+ index_path .write_text (" \n " . join ( lines ) , encoding = "utf-8" )
515542
516543
517544# ---------------------------------------------------------------------------
0 commit comments