marky

Lightweight bookmarking + plaintext archive
Log | Files | Refs | README | LICENSE

commit f4131c992e7e60795191bae870b3a3f5788942b3
parent 5f603fb84991b52ad00e9f75ecded99d83ed037a
Author: David Eisinger <[email protected]>
Date:   Tue,  7 Oct 2025 00:15:01 -0400

Prefer w3m if present

Diffstat:
MREADME.md | 2+-
Minternal/archiver.go | 24+++++++++++++++++++++++-
2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md @@ -11,7 +11,7 @@ A simple web API for bookmarking websites, written in Go. It stores bookmarks in - Go 1.24+ (tested with 1.24.5) - Make (optional, for the provided Makefile) - (No external tools required for archiving.) + (Optional) For archiving, if a `w3m` binary is available in `PATH`, marky uses it to render pages to plaintext; otherwise it falls back to the built‑in Go HTML‑to‑text renderer. ## Build diff --git a/internal/archiver.go b/internal/archiver.go @@ -7,6 +7,7 @@ import ( "io" "net/http" neturl "net/url" + "os/exec" "strings" "time" @@ -33,10 +34,31 @@ func TitleAndText(ctx context.Context, rawURL string) (string, string, error) { } htmlStr := string(body) title := extractTitle(htmlStr) - txt := strings.TrimSpace(htmlToText(htmlStr)) + // Prefer external w3m if available for robust text rendering; fall back to built-in. + var txt string + if path, err := exec.LookPath("w3m"); err == nil && path != "" { + if out, err := w3mDump(ctx, rawURL); err == nil && strings.TrimSpace(out) != "" { + txt = strings.TrimSpace(out) + } else { + txt = strings.TrimSpace(htmlToText(htmlStr)) + } + } else { + txt = strings.TrimSpace(htmlToText(htmlStr)) + } return title, txt, nil } +// w3mDump runs `w3m -dump` to render the given URL to plaintext. +func w3mDump(ctx context.Context, url string) (string, error) { + cmd := exec.CommandContext(ctx, "w3m", "-dump", "-T", "text/html", "-o", "display_link_number=1", url) + // Keep environment as-is; rely on user PATH. Capture stdout only. + b, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("w3m dump: %w", err) + } + return string(b), nil +} + func fetchHTML(ctx context.Context, rawURL string) ([]byte, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil) if err != nil {