diff --git a/main.go b/main.go index e20dd12..635a5ad 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,8 @@ import ( "strings" "time" "strconv" + "path" + "mime" ) type BookInfo struct { @@ -83,7 +85,7 @@ func validate(archive *zip.Reader) bool { fmt.Println("WARNING: No index provided, checking default index.gmi") return isValidContent("index.gmi") } else { - return isValidContent(bookInfo.Index) + return isValidContent(path.Join(bookInfo.Index)) } } else { fmt.Println("WARNING: This is not a book but a capsule archive") @@ -154,6 +156,7 @@ func isValidMetadata(file *zip.File) bool { _, err := strconv.ParseUint(value, 10, 32) if err != nil { fmt.Println("FATAL: Bad format in", key, err) + return false } bookInfo.Published = value case "publishDate": @@ -217,7 +220,53 @@ func isValidContent(filePath string) bool { return isValidContent(filePath + "index.gmi") } - //todo + reader, err := file.Open() + if err != nil { + fmt.Println("FATAL:", file.Name, "can't be opened") + return false + } + defer reader.Close() + + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + // we only check links + if strings.HasPrefix(scanner.Text(), "=>") && len(scanner.Text()) > 2 { + link := strings.Trim(scanner.Text()[2:], " ") + sepPosition := strings.Index(link, " ") + var location, text string + if sepPosition == -1 { + location = link + text = "" + } else { + location = strings.Trim(link[:sepPosition], " ") + text = strings.Trim(link[sepPosition+1:], " ") + } + + // transform location to have absolute gpub path + if strings.HasPrefix(location, "/") { // if begin with / we begin at root but without leading / and simplified (.. and .) + location = path.Join(location[1:]) + } else { // else join this file dir and link location + location = path.Join(path.Dir(filePath), location) + } + + if isImage(location) { + if text == "" { + fmt.Println("FATAL: image without alternative text in", file.Name, scanner.Text()) + return false + } + } + + if isGemtext(location) { + if !isValidContent(location) { + return false + } + } + } + } + if err := scanner.Err(); err != nil { + fmt.Println("FATAL: error while scanning", file.Name, err) + return false + } return true } @@ -225,3 +274,13 @@ func isValidContent(filePath string) bool { func isVersionValid() bool { return bookInfo.GpubVersion == "1.0.0" } + +func isImage(file string) bool { + ext := file[strings.LastIndex(file, "."):] + return strings.HasPrefix(mime.TypeByExtension(ext), "image") +} + +func isGemtext(file string) bool { + ext := file[strings.LastIndex(file, "."):] + return ext == ".gmi" || ext == ".gemini" +}