@@ -527,50 +527,63 @@ func (l localLinksCache) addRelLinks(localLink string) error {
527527
528528 // File present, cache presence.
529529 ids := make ([]string , 0 )
530-
531- var b []byte
530+ idDup := map [string ]struct {}{}
532531 reader := bufio .NewReader (file )
532+
533533 for {
534- b , err = reader .ReadBytes ('\n' )
534+ line , err : = reader .ReadBytes ('\n' )
535535 if err != nil {
536536 if err != io .EOF {
537537 return fmt .Errorf ("failed to read file %v: %w" , localLink , err )
538538 }
539539 break
540540 }
541541
542- if bytes .HasPrefix (b , []byte (`#` )) {
543- ids = append (ids , toHeaderID (b ))
542+ if ! bytes .HasPrefix (line , []byte ("#" )) {
543+ if err == io .EOF {
544+ break
545+ }
546+ continue
547+ }
548+
549+ headerID := toHeaderID (line )
550+ uniqueID := headerID
551+ for i := 1 ; ; i ++ {
552+ if _ , exists := idDup [uniqueID ]; ! exists {
553+ break
554+ }
555+ uniqueID = fmt .Sprintf ("%s-%d" , headerID , i )
556+ }
557+ idDup [uniqueID ] = struct {}{}
558+ ids = append (ids , uniqueID )
559+
560+ if err == io .EOF {
561+ break
544562 }
545563 }
546564
547565 l [localLink ] = & ids
548566 return nil
549567}
550568
569+ var punctuationRe = regexp .MustCompile (`[^\p{L}\p{N}\p{M}-# ]` )
570+
551571func toHeaderID (header []byte ) string {
572+ clean := punctuationRe .ReplaceAll (header , nil )
573+ text := bytes .TrimLeft (bytes .ToLower (clean ), "# " )
574+
552575 var id []byte
553- // Remove punctuation from header except '-' or '#'.
554- // '\p{L}\p{N}\p{M}' is the Unicode equivalent of '\w', https://www.regular-expressions.info/unicode.html.
555- punctuation := regexp .MustCompile (`[^\p{L}\p{N}\p{M}-# ]` )
556- header = punctuation .ReplaceAll (header , []byte ("" ))
557- headerText := bytes .TrimLeft (bytes .ToLower (header ), "#" )
558- // If header is just punctuation it comes up empty, so it cannot be linked.
559- if len (headerText ) <= 1 {
560- return ""
561- }
562-
563- for _ , h := range headerText [1 :] {
564- switch h {
576+ for _ , r := range string (text ) {
577+ switch r {
565578 case '{' :
566579 return string (id )
567- case ' ' , '-' :
580+ case ' ' , '-' , '\n' , '\r' :
568581 id = append (id , '-' )
569582 default :
570- id = append (id , h )
583+ id = append (id , string ( r ) ... )
571584 }
572585 }
573- return string (id )
586+ return strings . Trim ( string (id ), "-" )
574587}
575588
576589func absLocalLink (anchorDir string , docPath string , destination string ) string {
0 commit comments