Пример #1
0
func Compile() gonzo.Stage {
	return func(ctx context.Context, in <-chan gonzo.File, out chan<- gonzo.File) error {

		for {
			select {
			case file, ok := <-in:
				if !ok {
					return nil
				}

				buff := new(bytes.Buffer)
				name := strings.TrimSuffix(file.FileInfo().Name(), ".gcss") + ".css"
				ctx.Infof("Compiling %s to %s", file.FileInfo().Name(), name)
				n, err := gcss.Compile(buff, file)
				if err != nil {
					return err
				}

				file = gonzo.NewFile(ioutil.NopCloser(buff), file.FileInfo())
				file.FileInfo().SetSize(int64(n))
				file.FileInfo().SetName(name)

				out <- file
			case <-ctx.Done():
				return nil
			}
		}
	}
}
Пример #2
0
// Write the given source bytes as GCSS converted to CSS, to a writer.
// filename is only used if there are errors.
func gcssPage(w http.ResponseWriter, req *http.Request, filename string, gcssdata []byte) {
	var buf bytes.Buffer
	if _, err := gcss.Compile(&buf, bytes.NewReader(gcssdata)); err != nil {
		if debugMode {
			fmt.Fprintf(w, "Could not compile GCSS:\n\n%s\n%s", err, string(gcssdata))
		} else {
			log.Errorf("Could not compile GCSS:\n%s\n%s", err, string(gcssdata))
		}
		return
	}
	// Write the resulting GCSS to the client
	NewDataBlock(buf.Bytes()).ToClient(w, req)
}
Пример #3
0
// compileCSS gets the CSS name from the URL, determines if there is a pre-built version
// and compiles the CSS if need be before serving it to the client
func compileCSS(w http.ResponseWriter, r *http.Request) {
	file := r.URL.Path[len("/css/"):]
	if file == "" {
		errorHandler(w, r, http.StatusInternalServerError, "did not get a name of a CSS file")
		return
	}

	if !appengine.IsDevAppServer() {
		_, err := os.Stat("static/css/" + file)
		if err == nil {
			http.ServeFile(w, r, "static/css/"+file)
			return
		}
	}

	// check if a generated version of the file exists
	_, err := os.Stat("static/css/" + file)
	if err == nil {
		http.ServeFile(w, r, "static/css/"+file)
		return
	}

	// convert the .css extension to .gcss and build out path to the file
	f := gcss.Path(file)
	f = fmt.Sprintf("static/css/%s", f)

	// read the GCSS file
	css, err := os.Open(f)
	if err != nil {
		errorHandler(w, r, http.StatusInternalServerError, err.Error())
		return
	}

	// close out the file resource once done
	defer func() {
		if err := css.Close(); err != nil {
			errorHandler(w, r, http.StatusInternalServerError, err.Error())
			return
		}
	}()

	// set the content type header so browsers will know how to handle it
	w.Header().Set("Content-Type", "text/css")

	// build out the CSS and serve it to the browser
	_, err = gcss.Compile(w, css)
	if err != nil {
		errorHandler(w, r, http.StatusInternalServerError, err.Error())
		return
	}
}
Пример #4
0
// CompileStylesheets compiles a set of stylesheet files into a single large
// file by appending them all to each other. Files are appended in alphabetical
// order so we depend on the fact that there aren't too many interdependencies
// between files. CSS reset in particular is given an underscore prefix so that
// it gets to load first.
//
// If a file has a ".sass" suffix, we attempt to render it as GCSS. This isn't
// a perfect symmetry, but works well enough for these cases.
func CompileStylesheets(inPath, outPath string) error {
	start := time.Now()
	defer func() {
		log.Debugf("Compiled stylesheet assets in %v.", time.Now().Sub(start))
	}()

	log.Debugf("Building: %v", outPath)

	stylesheetInfos, err := ioutil.ReadDir(inPath)
	if err != nil {
		return err
	}

	outFile, err := os.Create(outPath)
	if err != nil {
		return err
	}
	defer outFile.Close()

	for _, stylesheetInfo := range stylesheetInfos {
		if isHidden(stylesheetInfo.Name()) {
			continue
		}

		log.Debugf("Including: %v", stylesheetInfo.Name())

		inFile, err := os.Open(path.Join(inPath, stylesheetInfo.Name()))
		if err != nil {
			return err
		}

		outFile.WriteString("/* " + stylesheetInfo.Name() + " */\n\n")

		if strings.HasSuffix(stylesheetInfo.Name(), ".sass") {
			_, err := gcss.Compile(outFile, inFile)
			if err != nil {
				return fmt.Errorf("Error compiling %v: %v",
					stylesheetInfo.Name(), err)
			}
		} else {
			_, err := io.Copy(outFile, inFile)
			if err != nil {
				return err
			}
		}

		outFile.WriteString("\n\n")
	}

	return nil
}
Пример #5
0
func main() {
	v := flag.Bool("v", false, "Print the version and exit.")

	flag.Parse()

	if *v {
		writeTo(os.Stdout, gcss.Version)
		exit(0)
		return
	}

	args := flag.Args()
	argsL := len(args)

	if argsL > validArgsLen {
		writeTo(os.Stderr, "The number of the command line args should be 1.")
		exit(1)
		return
	}

	if argsL == 0 {
		if _, err := gcss.Compile(os.Stdout, stdin); err != nil {
			writeTo(os.Stderr, err.Error())
			exit(1)
			return
		}
	} else {
		pathc, errc := gcss.CompileFile(args[0])

		select {
		case path := <-pathc:
			writeTo(os.Stdout, "compiled "+path)
		case err := <-errc:
			writeTo(os.Stderr, err.Error())
			exit(1)
			return
		}
	}
}
Пример #6
0
func getStyles() string {
	if stylesheet != "" {
		return stylesheet
	}

	asset, err := os.Open("assets/stylesheet.gcss")
	if err != nil {
		log.Fatalln(err)
	}
	defer asset.Close()

	var buffer bytes.Buffer
	if _, err := gcss.Compile(&buffer, asset); err != nil {
		log.Fatalln(err)
	}

	result := buffer.String()

	if isDebugMode() != true {
		stylesheet = result
	}

	return result
}
Пример #7
0
// Expose functions that are related to rendering text, to the given Lua state
func exportRenderFunctions(w http.ResponseWriter, req *http.Request, L *lua.LState) {

	// Output Markdown as HTML
	L.SetGlobal("mprint", L.NewFunction(func(L *lua.LState) int {
		// Retrieve all the function arguments as a bytes.Buffer
		buf := arguments2buffer(L, true)
		// Convert the buffer to markdown and return the translated string
		w.Write(blackfriday.MarkdownCommon([]byte(buf.String())))
		return 0 // number of results
	}))

	// Output text as rendered amber.
	L.SetGlobal("aprint", L.NewFunction(func(L *lua.LState) int {
		// Retrieve all the function arguments as a bytes.Buffer
		buf := arguments2buffer(L, true)
		// Use the buffer as a template.
		// Options are "Pretty printing, but without line numbers."
		tpl, err := amber.Compile(buf.String(), amber.Options{PrettyPrint: true, LineNumbers: false})
		if err != nil {
			if debugMode {
				fmt.Fprint(w, "Could not compile Amber template:\n\t"+err.Error()+"\n\n"+buf.String())
			} else {
				log.Errorf("Could not compile Amber template:\n%s\n%s", err, buf.String())
			}
			return 0 // number of results
		}
		// Using "MISSING" instead of nil for a slightly better error message
		// if the values in the template should not be found.
		tpl.Execute(w, "MISSING")
		return 0 // number of results
	}))

	// Output text as rendered GCSS
	L.SetGlobal("gprint", L.NewFunction(func(L *lua.LState) int {
		// Retrieve all the function arguments as a bytes.Buffer
		buf := arguments2buffer(L, true)
		// Transform GCSS to CSS and output the result.
		// Ignoring the number of bytes written.
		if _, err := gcss.Compile(w, &buf); err != nil {
			if debugMode {
				fmt.Fprint(w, "Could not compile GCSS:\n\t"+err.Error()+"\n\n"+buf.String())
			} else {
				log.Errorf("Could not compile GCSS:\n%s\n%s", err, buf.String())
			}
			//return 0 // number of results
		}
		return 0 // number of results
	}))

	// Output text as rendered JSX
	L.SetGlobal("jprint", L.NewFunction(func(L *lua.LState) int {
		// Retrieve all the function arguments as a bytes.Buffer
		buf := arguments2buffer(L, true)
		// Transform JSX to JavaScript and output the result.
		prog, err := parser.ParseFile(nil, "<input>", &buf, parser.IgnoreRegExpErrors)
		if err != nil {
			if debugMode {
				// TODO: Use a similar error page as for Lua
				fmt.Fprint(w, "Could not parse JSX:\n\t"+err.Error()+"\n\n"+buf.String())
			} else {
				log.Errorf("Could not parse JSX:\n%s\n%s", err, buf.String())
			}
			return 0 // number of results
		}
		gen, err := generator.Generate(prog)
		if err != nil {
			if debugMode {
				// TODO: Use a similar error page as for Lua
				fmt.Fprint(w, "Could not generate JavaScript:\n\t"+err.Error()+"\n\n"+buf.String())
			} else {
				log.Errorf("Could not generate JavaScript:\n%s\n%s", err, buf.String())
			}
			return 0 // number of results
		}
		if gen != nil {
			io.Copy(w, gen)
		}
		return 0 // number of results
	}))

}
Пример #8
0
// Check if the given data is valid GCSS
func validGCSS(gcssdata []byte) error {
	buf := bytes.NewBuffer(gcssdata)
	var w bytes.Buffer
	_, err := gcss.Compile(&w, buf)
	return err
}