ajhahn.de
← eeco
Go 69 lines
// Package guide ships eeco's in-binary user manual. It embeds a
// verbatim mirror of docs/USAGE.md so any installation of eeco can
// read the full user-facing reference offline, regardless of install
// route or network access. The embedded copy is drift-gated against
// docs/USAGE.md (see TestUsageMirrorsDocs).
package guide

import (
	_ "embed"
	"io"
	"os"
	"os/exec"
	"strings"
)

//go:embed usage.md
var usage string

// Text returns the embedded guide content. Byte-identical to
// docs/USAGE.md at the tag the binary was built from.
func Text() string {
	return usage
}

// Dump writes the embedded guide to w verbatim, byte-identical to
// docs/USAGE.md. The non-TTY / piped entry point — machine consumers
// get raw Markdown with no ANSI.
func Dump(w io.Writer) error {
	_, err := io.WriteString(w, usage)
	return err
}

// DumpRendered writes the prettified guide (see Render) to w. The
// interactive fallback used when no pager is available, so a terminal
// user still gets box-drawing tables and styled headings.
func DumpRendered(w io.Writer, colour bool) error {
	_, err := io.WriteString(w, Render(colour))
	return err
}

// PagerCommand builds a paginator *exec.Cmd that reads content from
// stdin. It honours $PAGER (split on whitespace), falls back to
// `less -R`, and returns nil when neither is available. The returned
// command leaves Stdout / Stderr unset so the caller can attach the
// real terminal file descriptors. lookPath / getenv are injectable for
// tests.
func PagerCommand(content string, getenv func(string) string, lookPath func(string) (string, error)) *exec.Cmd {
	if getenv == nil {
		getenv = os.Getenv
	}
	if lookPath == nil {
		lookPath = exec.LookPath
	}
	if p := strings.TrimSpace(getenv("PAGER")); p != "" {
		fields := strings.Fields(p)
		if resolved, err := lookPath(fields[0]); err == nil {
			cmd := exec.Command(resolved, fields[1:]...)
			cmd.Stdin = strings.NewReader(content)
			return cmd
		}
	}
	if resolved, err := lookPath("less"); err == nil {
		cmd := exec.Command(resolved, "-R")
		cmd.Stdin = strings.NewReader(content)
		return cmd
	}
	return nil
}