1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
package main
import (
"encoding/json"
"fmt"
"io/fs"
"net/url"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
)
func main() {
externalLinks := countExternalLinks("content")
writeJSON("data/externallinks.json", externalLinks)
fmt.Println("✅ External link rank data generated.")
}
// countExternalLinks scans markdown files and counts occurrences of each external domain.
func countExternalLinks(root string) [][2]interface{} {
linkRegex := regexp.MustCompile(`https?://[^\s)>"']+`)
counts := make(map[string]int)
filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
if err != nil || d.IsDir() || !strings.HasSuffix(path, ".md") {
return nil
}
data, err := os.ReadFile(path)
if err != nil {
return nil
}
matches := linkRegex.FindAllString(string(data), -1)
for _, match := range matches {
u, err := url.Parse(match)
if err == nil && u.Host != "" {
// skip my domains
if strings.HasSuffix(u.Host, "eltr.ac") || strings.HasSuffix(u.Host, "guhub.cn") {
continue
}
counts[u.Host]++
}
}
return nil
})
// convert map to sorted array (alphabetically by domain)
type kv struct {
Key string
Value int
}
var list []kv
for k, v := range counts {
list = append(list, kv{k, v})
}
sort.Slice(list, func(i, j int) bool { return list[i].Key < list[j].Key })
result := make([][2]interface{}, len(list))
for i, kv := range list {
result[i] = [2]interface{}{kv.Key, kv.Value}
}
return result
}
// writeJSON writes the result to file with indentation.
func writeJSON(path string, data interface{}) {
file, err := os.Create(path)
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
enc := json.NewEncoder(file)
enc.SetIndent("", " ")
enc.Encode(data)
}
|