// Compile reads in and writes the libsass compiled result to out. // Options and custom functions are applied as specified in Context. func (ctx *Context) Compile(in io.Reader, out io.Writer) error { defer ctx.Reset() bs, err := ioutil.ReadAll(in) if err != nil { return err } if len(bs) == 0 { return errors.New("No input provided") } src := C.CString(string(bs)) dc := C.sass_make_data_context(src) defer C.sass_delete_data_context(dc) options := C.sass_data_context_get_options(dc) opts := ctx.Init((*SassOptions)(options)) // TODO: Manually free options memory without throwing // malloc errors // defer C.free(unsafe.Pointer(opts)) C.sass_data_context_set_options(dc, opts) cc := C.sass_data_context_get_context(dc) compiler := C.sass_make_data_compiler(dc) C.sass_compiler_parse(compiler) C.sass_compiler_execute(compiler) defer C.sass_delete_compiler(compiler) cout := C.GoString(C.sass_context_get_output_string(cc)) io.WriteString(out, cout) ctx.Status = int(C.sass_context_get_error_status(cc)) errJSON := C.sass_context_get_error_json(cc) err = ctx.ProcessSassError([]byte(C.GoString(errJSON))) if err != nil { return err } if ctx.error() != "" { lines := bytes.Split(bs, []byte("\n")) var out string for i := -7; i < 7; i++ { if i+ctx.Errors.Line >= 0 && i+ctx.Errors.Line < len(lines) { out += fmt.Sprintf("%s\n", string(lines[i+ctx.Errors.Line])) } } // TODO: this is weird, make something more idiomatic return errors.New(ctx.error() + "\n" + out) } return nil }
// SassDataContextGetContext returns a context from a data context. // These are useful for calling generic methods like compiling. func SassDataContextGetContext(godc SassDataContext) SassContext { opts := C.sass_data_context_get_context(godc) return (SassContext)(opts) }
func (dc *datacontext) Context() Context { cc := (*C.struct_Sass_Data_Context)(dc) return (*context)(C.sass_data_context_get_context(cc)) }