forked from mirror/oddmu
This puts the parser setup in one place for easy modification since the parser is being used in more than one place.
96 lines
2.4 KiB
Go
96 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"io/fs"
|
|
"path/filepath"
|
|
"github.com/google/subcommands"
|
|
"github.com/gomarkdown/markdown"
|
|
"github.com/gomarkdown/markdown/ast"
|
|
"io"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type missingCmd struct {
|
|
}
|
|
|
|
func (*missingCmd) Name() string { return "missing" }
|
|
func (*missingCmd) Synopsis() string { return "Listing the missing pages." }
|
|
func (*missingCmd) Usage() string {
|
|
return `missing:
|
|
Listing pages with links to missing pages.
|
|
`
|
|
}
|
|
|
|
func (cmd *missingCmd) SetFlags(f *flag.FlagSet) {
|
|
}
|
|
|
|
func (cmd *missingCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
|
return missingCli(os.Stdout, f.Args())
|
|
}
|
|
|
|
func missingCli(w io.Writer, args []string) subcommands.ExitStatus {
|
|
names := make(map[string]bool);
|
|
err := filepath.Walk(".", func(path string, info fs.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
filename := path
|
|
if info.IsDir() || strings.HasPrefix(filename, ".") || !strings.HasSuffix(filename, ".md") {
|
|
return nil
|
|
}
|
|
name := strings.TrimSuffix(filename, ".md")
|
|
names[name] = true
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return subcommands.ExitFailure
|
|
}
|
|
fmt.Println("Page\tMissing")
|
|
for name := range names {
|
|
p, err := loadPage(name)
|
|
if err != nil {
|
|
fmt.Printf("Loading %s: %s\n", name, err)
|
|
return subcommands.ExitFailure
|
|
}
|
|
for _, link := range p.links() {
|
|
if !strings.HasPrefix(link, "/") &&
|
|
!strings.HasPrefix(link, "http:") &&
|
|
!strings.HasPrefix(link, "https:") &&
|
|
!strings.HasPrefix(link, "mailto:") &&
|
|
!strings.HasPrefix(link, "gopher:") &&
|
|
!strings.HasPrefix(link, "gemini:") {
|
|
destination, err := url.PathUnescape(link)
|
|
if err != nil {
|
|
fmt.Printf("Cannot decode %s: %s\n", link, err)
|
|
return subcommands.ExitFailure
|
|
}
|
|
_, ok := names[destination]
|
|
if !ok {
|
|
fmt.Printf("%s\t%s\n", name, link)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return subcommands.ExitSuccess
|
|
}
|
|
|
|
func (p *Page) links() []string {
|
|
var links []string
|
|
parser, _ := wikiParser()
|
|
doc := markdown.Parse(p.Body, parser)
|
|
ast.WalkFunc(doc, func(node ast.Node, entering bool) ast.WalkStatus {
|
|
switch v := node.(type) {
|
|
case *ast.Link:
|
|
links = append(links, string(v.Destination))
|
|
}
|
|
return ast.GoToNext
|
|
})
|
|
return links
|
|
}
|