view zs_util.go @ 26:d966bcb229c0 draft

fixed math package
author zaitsev.serge
date Sun, 30 Aug 2015 12:45:06 +0000
parents d052f3a44195
children b2f491299cee
line wrap: on
line source

package main

import (
	"bytes"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

func varFunc(s string) func() string {
	return func() string {
		return s
	}
}

func pluginFunc(cmd string, vars Vars) func(args ...string) string {
	return func(args ...string) string {
		out := bytes.NewBuffer(nil)
		if err := run(filepath.Join(ZSDIR, cmd), args, vars, out); err != nil {
			return cmd + ":" + err.Error()
		} else {
			return string(out.Bytes())
		}
	}
}

func builtins() Funcs {
	exec := func(cmd string, args ...string) string {
		out := bytes.NewBuffer(nil)
		if err := run(cmd, args, Vars{}, out); err != nil {
			return cmd + ":" + err.Error()
		} else {
			return string(out.Bytes())
		}
		return ""
	}
	return Funcs{
		"exec": exec,
		"zs": func(args ...string) string {
			return exec(os.Args[0], args...)
		},
	}
}

func renameExt(path, from, to string) string {
	if from == "" {
		from = filepath.Ext(path)
	}
	if strings.HasSuffix(path, from) {
		return strings.TrimSuffix(path, from) + to
	} else {
		return path
	}
}

func globals() Vars {
	vars := Vars{}
	for _, e := range os.Environ() {
		pair := strings.Split(e, "=")
		if strings.HasPrefix(pair[0], "ZS_") {
			vars[strings.ToLower(pair[0][3:])] = pair[1]
		}
	}
	return vars
}

// Converts zs markdown variables into environment variables
func env(vars Vars) []string {
	env := []string{"ZS=" + os.Args[0], "ZS_OUTDIR=" + PUBDIR}
	env = append(env, os.Environ()...)
	if vars != nil {
		for k, v := range vars {
			env = append(env, "ZS_"+strings.ToUpper(k)+"="+v)
		}
	}
	return env
}

// Runs command with given arguments and variables, intercepts stderr and
// redirects stdout into the given writer
func run(cmd string, args []string, vars Vars, output io.Writer) error {
	var errbuf bytes.Buffer
	c := exec.Command(cmd, args...)
	c.Env = env(vars)
	c.Stdout = output
	c.Stderr = &errbuf

	err := c.Run()

	if errbuf.Len() > 0 {
		log.Println("ERROR:", errbuf.String())
	}

	if err != nil {
		return err
	}
	return nil
}

// Splits a string in exactly two parts by delimiter
// If no delimiter is found - the second string is be empty
func split2(s, delim string) (string, string) {
	parts := strings.SplitN(s, delim, 2)
	if len(parts) == 2 {
		return parts[0], parts[1]
	} else {
		return parts[0], ""
	}
}