feat(ingestion): add wiki package with Page types and slug generation
This commit is contained in:
28
ingestion/internal/wiki/slug.go
Normal file
28
ingestion/internal/wiki/slug.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// ingestion/internal/wiki/slug.go
|
||||
package wiki
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Slug converts a title to a kebab-case slug suitable for wiki filenames.
|
||||
// Rules: lowercase, spaces/hyphens/underscores → hyphens, strip everything else.
|
||||
func Slug(title string) string {
|
||||
var b strings.Builder
|
||||
prevHyphen := true // start true to trim leading hyphens
|
||||
for _, r := range strings.ToLower(title) {
|
||||
switch {
|
||||
case r == ' ' || r == '-' || r == '_':
|
||||
if !prevHyphen {
|
||||
b.WriteRune('-')
|
||||
prevHyphen = true
|
||||
}
|
||||
case unicode.IsLetter(r) || unicode.IsDigit(r):
|
||||
b.WriteRune(r)
|
||||
prevHyphen = false
|
||||
// all other characters (apostrophes, colons, dots, etc.) are dropped
|
||||
}
|
||||
}
|
||||
return strings.TrimRight(b.String(), "-")
|
||||
}
|
||||
29
ingestion/internal/wiki/slug_test.go
Normal file
29
ingestion/internal/wiki/slug_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// ingestion/internal/wiki/slug_test.go
|
||||
package wiki
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSlug(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
want string
|
||||
}{
|
||||
{"Domain Driven Design", "domain-driven-design"},
|
||||
{"It's Complicated", "its-complicated"},
|
||||
{"gRPC", "grpc"},
|
||||
{"GPT-4o", "gpt-4o"},
|
||||
{"Property 1: It's Rough", "property-1-its-rough"},
|
||||
{" leading spaces ", "leading-spaces"},
|
||||
{"multiple spaces", "multiple-spaces"},
|
||||
{"already-kebab", "already-kebab"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
assert.Equal(t, tc.want, Slug(tc.input))
|
||||
})
|
||||
}
|
||||
}
|
||||
24
ingestion/internal/wiki/types.go
Normal file
24
ingestion/internal/wiki/types.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// ingestion/internal/wiki/types.go
|
||||
package wiki
|
||||
|
||||
// PageType identifies the wiki subdirectory for a page.
|
||||
type PageType string
|
||||
|
||||
const (
|
||||
PageTypeConcept PageType = "concepts"
|
||||
PageTypeEntity PageType = "entities"
|
||||
PageTypeSource PageType = "sources"
|
||||
)
|
||||
|
||||
// Page is a wiki page to be written to disk.
|
||||
type Page struct {
|
||||
Path string // relative to brainDir, e.g. "wiki/sources/foo.md"
|
||||
Content string // full markdown including YAML frontmatter
|
||||
}
|
||||
|
||||
// Entry is a summary of an existing wiki page used to build the inventory.
|
||||
type Entry struct {
|
||||
Slug string
|
||||
Title string
|
||||
Type PageType
|
||||
}
|
||||
Reference in New Issue
Block a user