@@ -485,50 +485,63 @@ func (l localLinksCache) addRelLinks(localLink string) error {
485485
486486 // File present, cache presence.
487487 ids := make ([]string , 0 )
488-
489- var b []byte
488+ idDup := map [string ]struct {}{}
490489 reader := bufio .NewReader (file )
490+
491491 for {
492- b , err = reader .ReadBytes ('\n' )
492+ line , err : = reader .ReadBytes ('\n' )
493493 if err != nil {
494494 if err != io .EOF {
495495 return fmt .Errorf ("failed to read file %v: %w" , localLink , err )
496496 }
497497 break
498498 }
499499
500- if bytes .HasPrefix (b , []byte (`#` )) {
501- ids = append (ids , toHeaderID (b ))
500+ if ! bytes .HasPrefix (line , []byte ("#" )) {
501+ if err == io .EOF {
502+ break
503+ }
504+ continue
505+ }
506+
507+ headerID := toHeaderID (line )
508+ uniqueID := headerID
509+ for i := 1 ; ; i ++ {
510+ if _ , exists := idDup [uniqueID ]; ! exists {
511+ break
512+ }
513+ uniqueID = fmt .Sprintf ("%s-%d" , headerID , i )
514+ }
515+ idDup [uniqueID ] = struct {}{}
516+ ids = append (ids , uniqueID )
517+
518+ if err == io .EOF {
519+ break
502520 }
503521 }
504522
505523 l [localLink ] = & ids
506524 return nil
507525}
508526
527+ var punctuationRe = regexp .MustCompile (`[^\p{L}\p{N}\p{M}-# ]` )
528+
509529func toHeaderID (header []byte ) string {
530+ clean := punctuationRe .ReplaceAll (header , nil )
531+ text := bytes .TrimLeft (bytes .ToLower (clean ), "# " )
532+
510533 var id []byte
511- // Remove punctuation from header except '-' or '#'.
512- // '\p{L}\p{N}\p{M}' is the Unicode equivalent of '\w', https://www.regular-expressions.info/unicode.html.
513- punctuation := regexp .MustCompile (`[^\p{L}\p{N}\p{M}-# ]` )
514- header = punctuation .ReplaceAll (header , []byte ("" ))
515- headerText := bytes .TrimLeft (bytes .ToLower (header ), "#" )
516- // If header is just punctuation it comes up empty, so it cannot be linked.
517- if len (headerText ) <= 1 {
518- return ""
519- }
520-
521- for _ , h := range headerText [1 :] {
522- switch h {
534+ for _ , r := range string (text ) {
535+ switch r {
523536 case '{' :
524537 return string (id )
525- case ' ' , '-' :
538+ case ' ' , '-' , '\n' , '\r' :
526539 id = append (id , '-' )
527540 default :
528- id = append (id , h )
541+ id = append (id , string ( r ) ... )
529542 }
530543 }
531- return string (id )
544+ return strings . Trim ( string (id ), "-" )
532545}
533546
534547func absLocalLink (anchorDir string , docPath string , destination string ) string {
0 commit comments