go-typst/cli.go
David Vogel 755cee77ac Several changes
- Make VariableEncoder write* methods private
- Add VariableEncoder method to write correctly escaped string literals
- Fix error handling in VariableEncoder
- Add support for time.Time and time.Duration
- Fix MarshalText usage in VariableEncoder
- Encode byte slice so that it is a valid typst bytes object
- Extend tests
- Add functions to clean and check typst identifiers
- Split Error into Error and ErrorWithPath
- Add CLIOptions
2024-12-18 17:25:28 +01:00

72 lines
1.8 KiB
Go

package typst
import (
"bytes"
"fmt"
"io"
"os/exec"
)
type CLI struct {
ExecutablePath string // The typst executable path can be overridden here. Otherwise the default path will be used.
}
// TODO: Method for querying typst version
// Render takes a typst document from input, and renders it into the output writer.
// The options parameter is optional.
func (c CLI) Render(input io.Reader, output io.Writer, options *CLIOptions) error {
args := []string{"c"}
if options != nil {
args = append(args, options.Args()...)
}
args = append(args, "--diagnostic-format", "short", "-", "-")
// Get path of executable.
execPath := ExecutablePath
if c.ExecutablePath != "" {
execPath = c.ExecutablePath
}
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 ParseStderr(errBuffer.String(), err)
default:
return err
}
}
return nil
}
// Render takes a typst document from input, and renders it into the output writer.
// The options parameter is optional.
//
// Additionally this will inject the given map of variables into the global scope of the typst document.
func (c CLI) RenderWithVariables(input io.Reader, output io.Writer, options *CLIOptions, variables map[string]any) error {
varBuffer := bytes.Buffer{}
// TODO: Use io.pipe instead of a bytes.Buffer
enc := NewVariableEncoder(&varBuffer)
for k, v := range variables {
varBuffer.WriteString("#let " + CleanIdentifier(k) + " = ")
if err := enc.Encode(v); err != nil {
return fmt.Errorf("failed to encode variables with key %q: %w", k, err)
}
varBuffer.WriteRune('\n')
}
reader := io.MultiReader(&varBuffer, input)
return c.Render(reader, output, options)
}