@@ -413,6 +413,8 @@ def _setup_extras(self):
413413 if "header-ids" in self .extras :
414414 if not hasattr (self , '_count_from_header_id' ) or self .extras ['header-ids' ].get ('reset-count' , False ):
415415 self ._count_from_header_id = defaultdict (int )
416+ if not hasattr (self , '_header_ids_seen' ) or self .extras ['header-ids' ].get ('reset-count' , False ):
417+ self ._header_ids_seen = set ()
416418 if "metadata" in self .extras :
417419 self .metadata : dict [str , Any ] = {}
418420
@@ -1583,9 +1585,17 @@ def header_id_from_text(self,
15831585 if prefix and isinstance (prefix , str ):
15841586 header_id = prefix + '-' + header_id
15851587
1586- self ._count_from_header_id [header_id ] += 1
1587- if 0 == len (header_id ) or self ._count_from_header_id [header_id ] > 1 :
1588- header_id += '-%s' % self ._count_from_header_id [header_id ]
1588+ base_id = header_id
1589+ self ._count_from_header_id [base_id ] += 1
1590+ if 0 == len (base_id ) or self ._count_from_header_id [base_id ] > 1 :
1591+ header_id = '%s-%s' % (base_id , self ._count_from_header_id [base_id ])
1592+ # A suffixed id may still collide with a differently-named header
1593+ # (e.g. "# Chapter" twice yields "chapter-2", which clashes with
1594+ # "# Chapter 2"). Keep bumping until the id is genuinely unique.
1595+ while header_id in self ._header_ids_seen :
1596+ self ._count_from_header_id [base_id ] += 1
1597+ header_id = '%s-%s' % (base_id , self ._count_from_header_id [base_id ])
1598+ self ._header_ids_seen .add (header_id )
15891599
15901600 return header_id
15911601
0 commit comments