summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorTadas Vilkeliskis <vilkeliskis.t@gmail.com>2025-12-30 21:12:39 -0500
committerTadas Vilkeliskis <vilkeliskis.t@gmail.com>2025-12-30 21:12:53 -0500
commite6156c67d0bb1fc5cc9f8069283ae4d7f364f476 (patch)
treeea7dae56fa8121eef93e518d775eb530cf4bf564 /main.go
implement query
Diffstat (limited to 'main.go')
-rw-r--r--main.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..8e3243d
--- /dev/null
+++ b/main.go
@@ -0,0 +1,109 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/PuerkitoBio/goquery"
+ "golang.org/x/net/html"
+)
+
+type Mode string
+
+const (
+ ModeQuery Mode = "query"
+ ModeReplace Mode = "replace"
+ ModeAppend Mode = "append"
+ ModePrepend Mode = "prepend"
+ ModeInvalid Mode = "invalid"
+
+ FilenameStdin string = "-"
+)
+
+func main() {
+ selector := flag.String("selector", "", "DOM query")
+ mode := flag.String("mode", "query", "Operation mode: query, replace, append, prepend")
+ filename := flag.String("filename", "", "Path to HTML file")
+ flag.Parse()
+
+ //args := flag.Args()
+
+ parsedMode, err := parseMode(*mode)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to parse -mode: %s", err.Error())
+ os.Exit(1)
+ }
+
+ doc, err := parseFilename(*filename)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to parse -filename: %s", err.Error())
+ os.Exit(1)
+ }
+
+ switch parsedMode {
+ case ModeQuery:
+ if *selector == "" {
+ // if selector is not specified return whole doc by default
+ htmlStr, err := doc.Html()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to construct HTML string: %s", err.Error())
+ os.Exit(1)
+ }
+ fmt.Println(htmlStr)
+ } else {
+ doc.Find(*selector).Each(func(i int, s *goquery.Selection) {
+ var buf strings.Builder
+ err := html.Render(&buf, s.Get(0))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to render node: %s", err.Error())
+ os.Exit(1)
+ }
+
+ output := buf.String()
+ fmt.Println(output)
+ })
+ }
+ case ModeReplace:
+ case ModeAppend:
+ case ModePrepend:
+ }
+}
+
+func parseMode(mode string) (Mode, error) {
+ validModes := map[string]any{
+ string(ModeQuery): nil,
+ string(ModeReplace): nil,
+ string(ModeAppend): nil,
+ string(ModePrepend): nil,
+ }
+
+ if _, ok := validModes[mode]; !ok {
+ return ModeInvalid, fmt.Errorf("invalid mode: %s", mode)
+ }
+
+ return Mode(mode), nil
+}
+
+func parseFilename(fileName string) (*goquery.Document, error) {
+ var fd *os.File
+ var err error
+
+ if fileName == FilenameStdin {
+ fd = os.Stdin
+ } else {
+ fd, err = os.Open(fileName)
+ if err != nil {
+ return nil, fmt.Errorf("error opening file: %s", err.Error())
+ }
+ defer fd.Close()
+ }
+
+ doc, err := goquery.NewDocumentFromReader(fd)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing HTML: %s", err.Error())
+ }
+
+ return doc, nil
+}