This repository has been archived by the owner on Mar 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 70
/
util.go
94 lines (82 loc) · 2.45 KB
/
util.go
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"fmt"
"net/url"
"path/filepath"
"strings"
"unicode"
)
func trim(source, prefix, suffix string) string {
return strings.TrimPrefix(strings.TrimSuffix(source, suffix), prefix)
}
func hugoPathTrim(source string) string {
return strings.TrimSuffix(strings.TrimSuffix(source, "/index"), "_index")
}
func processTarget(source string) string {
if !isInternal(source) {
return source
}
if strings.HasPrefix(source, "/") {
return strings.TrimSuffix(source, ".md")
}
res := strings.Split(source, "#")[0]
res = "/" + strings.TrimSuffix(strings.TrimSuffix(res, ".html"), ".md")
res, _ = url.PathUnescape(res)
res = strings.TrimSpace(res)
res = UnicodeSanitize(res)
return strings.ReplaceAll(url.PathEscape(res), "%2F", "/")
}
func processSource(source string) string {
res := filepath.ToSlash(hugoPathTrim(source))
res = UnicodeSanitize(res)
return strings.ReplaceAll(url.PathEscape(res), "%2F", "/")
}
func isInternal(link string) bool {
return !strings.HasPrefix(link, "http")
}
// From https://golang.org/src/net/url/url.go
func ishex(c rune) bool {
switch {
case '0' <= c && c <= '9':
return true
case 'a' <= c && c <= 'f':
return true
case 'A' <= c && c <= 'F':
return true
}
return false
}
// UnicodeSanitize sanitizes string to be used in Hugo URL's
// from https://github.com/gohugoio/hugo/blob/93aad3c543828efca2adeb7f96cf50ae29878593/helpers/path.go#L94
func UnicodeSanitize(s string) string {
source := []rune(s)
target := make([]rune, 0, len(source))
var prependHyphen bool
for i, r := range source {
isAllowed := r == '.' || r == '/' || r == '\\' || r == '_' || r == '#' || r == '+' || r == '~'
isAllowed = isAllowed || unicode.IsLetter(r) || unicode.IsDigit(r) || unicode.IsMark(r)
isAllowed = isAllowed || (r == '%' && i+2 < len(source) && ishex(source[i+1]) && ishex(source[i+2]))
if isAllowed {
if prependHyphen {
target = append(target, '-')
prependHyphen = false
}
target = append(target, r)
} else if len(target) > 0 && (r == '-' || unicode.IsSpace(r)) {
prependHyphen = true
}
}
return string(target)
}
// filter out certain links (e.g. to media)
func filter(links []Link) (res []Link) {
for _, l := range links {
// filter external and non-md
isMarkdown := filepath.Ext(l.Target) == "" || filepath.Ext(l.Target) == ".md"
if isInternal(l.Target) && isMarkdown {
res = append(res, l)
}
}
fmt.Printf("Removed %d external and non-markdown links\n", len(links)-len(res))
return res
}