package ocrmypdf import ( "bytes" "fmt" "io" "os/exec" "strings" ) type CLI struct { // The OCRmyPDF executable path can be overridden here. Otherwise the default path will be used. // Special cases: // - "py -m ocrmypdf": This will run "py -m ocrmypdf". ExecutablePath string } // executableAndArgs returns the executable name and its base arguments. func (c CLI) executableAndArgs() (string, []string) { // Get path of executable. execPath := ExecutablePath if c.ExecutablePath != "" { execPath = c.ExecutablePath } // Special cases. var args []string switch execPath { case "py -m ocrmypdf": execPath, args = "py", []string{"-m", "ocrmypdf"} } return execPath, args } // VersionString returns the version string as returned by OCRmyPDF. func (c CLI) VersionString() (string, error) { execPath, args := c.executableAndArgs() args = append(args, "--version") cmd := exec.Command(execPath, args...) var output, errBuffer bytes.Buffer cmd.Stdout = &output cmd.Stderr = &errBuffer if err := cmd.Run(); err != nil { switch err := err.(type) { case *exec.ExitError: return "", fmt.Errorf("OCRmyPDF stopped with exit code %v: %v", err.ExitCode(), errBuffer.String()) default: return "", err } } return strings.TrimRight(output.String(), "\n\r"), nil } // Run takes a document from input, and writes the resulting document into output. // The options parameter is optional. func (c CLI) Run(input io.Reader, output io.Writer, options *CLIOptions) error { execPath, args := c.executableAndArgs() if options != nil { args = append(args, options.Args()...) } args = append(args, "-", "-") cmd := exec.Command(execPath, args...) cmd.Stdin = input cmd.Stdout = output errBuffer := bytes.Buffer{} cmd.Stderr = &errBuffer if err := cmd.Run(); err != nil { switch err := err.(type) { case *exec.ExitError: return fmt.Errorf("OCRmyPDF stopped with exit code %v: %v", err.ExitCode(), errBuffer.String()) default: return err } } return nil }