Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Sass syntax option to the compiler fixes #48 #50

Merged
merged 1 commit into from May 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
202 changes: 29 additions & 173 deletions compiler.go
Expand Up @@ -50,160 +50,11 @@ type Compiler interface {
// Payload returns the attached spritewell information attached
// to the compiler context
Payload() context.Context
}

// CacheBust append timestamps to static assets to prevent caching
func CacheBust(t string) option {
return func(c *sass) error {
if t == "ts" {
t = "timestamp"
}
c.cachebust = t
return nil
}
}

// LineComments removes the line by line playby of the Sass compiler
func LineComments(b bool) option {
return func(c *sass) error {
c.cmt = b
return nil
}
}

// OutputStyle controls the presentation of the CSS available option:
// nested, expanded, compact, compressed
func OutputStyle(style int) option {
return func(c *sass) error {
c.ctx.OutputStyle = style
return nil
}
}

// Precision specifies the number of points beyond the decimal place is
// preserved during math calculations.
func Precision(prec int) option {
return func(c *sass) error {
c.ctx.Precision = prec
return nil
}
}

// Comments toggles whether comments should be included in the output
func Comments(b bool) option {
return func(c *sass) error {
c.ctx.Comments = b
return nil
}
}

// IncludePaths adds additional directories to search for Sass files
func IncludePaths(includes []string) option {
return func(c *sass) error {
c.includePaths = includes
c.ctx.IncludePaths = includes
return nil
}
}

// HTTPPath prefixes all sprites and generated images with this uri.
// Enabling wellington to serve images when used in HTTP mode
func HTTPPath(u string) option {
return func(c *sass) error {
c.httpPath = u
c.ctx.HTTPPath = u
return nil
}
}

// SourceMap behaves differently depending on compiler used. For
// compile, it will embed sourcemap into the source. For file compile,
// it will include a separate file with the source map.
func SourceMap(b bool, path, sourceMapRoot string) option {
return func(c *sass) error {
c.ctx.includeMap = b
c.mappath = path
if len(sourceMapRoot) > 0 {
c.sourceMapRoot = sourceMapRoot
}
return nil
}
}

// FontDir specifies where to find fonts
func FontDir(path string) option {
return func(c *sass) error {
c.ctx.FontDir = path
return nil
}
}

// BasePath sets the internal path provided to handlers requiring
// a base path for http calls. This is useful for hosted solutions that
// need to provided absolute paths to assets.
func BasePath(basePath string) option {
return func(c *sass) error {
c.httpPath = basePath
// FIXME: remove from context
c.ctx.HTTPPath = basePath
return nil
}
}

// Path specifies a file to read instead of using the provided
// io.Reader. This activates file compiling that includes line numbers
// in the resulting output.
func Path(path string) option {
return func(c *sass) error {
c.srcFile = path
c.ctx.MainFile = path
return nil
}
}

// Payload gives access to sprite and image information for handlers
// to perform spriting functions.
func Payload(load context.Context) option {
return func(c *sass) error {
c.ctx.Payload = load
return nil
}
}

// ImgBuildDir specifies the destination directory for images
func ImgBuildDir(path string) option {
return func(c *sass) error {
c.ctx.GenImgDir = path
return nil
}
}

// ImgDir specifies where to locate images for spriting
func ImgDir(path string) option {
return func(c *sass) error {
c.ctx.ImageDir = path
return nil
}
}

// BuildDir only used for spriting, how terrible!
func BuildDir(path string) option {
return func(c *sass) error {
c.ctx.BuildDir = path
return nil
}
}

// ImportsOption specifies configuration for import resolution
func ImportsOption(imports *Imports) option {
return func(c *sass) error {
c.ctx.Imports = imports
return nil
}
// Syntax represents the style of code Sass or SCSS
Syntax() Syntax
}

type option func(*sass) error

func New(dst io.Writer, src io.Reader, opts ...option) (Compiler, error) {

c := &sass{
Expand All @@ -223,13 +74,18 @@ func New(dst io.Writer, src io.Reader, opts ...option) (Compiler, error) {
// sass implements compiler interface for Sass and Scss stylesheets. To
// configure the compiler, use the option method.
type sass struct {
// FIXME: old context for storing state, use compiler instead
ctx *compctx
dst io.Writer
mappath string

src io.Reader
// src is the input stream to compile
src io.Reader
// path to the input file
srcFile string

// cachebust instructs the compiler to generate new paths
// preventing browser caching
cachebust string
httpPath string
includePaths []string
Expand All @@ -238,6 +94,9 @@ type sass struct {
sourceMapRoot string
// payload is passed around for handlers to have context
payload context.Context

// current syntax of the compiler, Sass or SCSS
syntax Syntax
}

var _ Compiler = &sass{}
Expand All @@ -253,18 +112,21 @@ func (c *sass) run() error {
return c.ctx.compile(c.dst, c.src)
}

func (c *sass) CacheBust() string {
return c.cachebust
}

// BuildDir is where CSS is written to disk
func (s *sass) BuildDir() string {
return s.ctx.BuildDir
}

// CacheBust reveals the current cache busting state
func (c *sass) CacheBust() string {
return c.cachebust
}

func (s *sass) HTTPPath() string {
return s.ctx.HTTPPath
}

// ImgBuildDir fetch the image build directory
func (s *sass) ImgBuildDir() string {
return s.ctx.GenImgDir
}
Expand All @@ -274,20 +136,20 @@ func (c *sass) ImgDir() string {
return c.ctx.ImageDir
}

// Imports returns the full list of partials used to build the
// output stylesheet.
func (c *sass) Imports() []string {
return c.imports
}

// FontDir returns the font directory option
func (c *sass) FontDir() string {
return c.ctx.FontDir
}

// Option allows the modifying of internal compiler state
func (c *sass) Option(opts ...option) error {
for _, opt := range opts {
err := opt(c)
if err != nil {
return err
}
}
return nil
// LineComments returns the source comment status
func (c *sass) LineComments() bool {
return c.cmt
}

func (c *sass) Payload() context.Context {
Expand All @@ -299,12 +161,6 @@ func (c *sass) Run() error {
return c.run()
}

// Imports returns the full list of partials used to build the output
// stylesheet.
func (c *sass) Imports() []string {
return c.imports
}

func (c *sass) LineComments() bool {
return c.cmt
func (c *sass) Syntax() Syntax {
return c.syntax
}
27 changes: 20 additions & 7 deletions compiler_test.go
Expand Up @@ -20,20 +20,33 @@ func ExampleCompiler_stdin() {
log.Fatal(err)
}

// e := `div p {
// color: red; }
// `
// if e != dst.String() {
// t.Errorf("got: %s wanted: %s", dst.String(), e)
// }

// Output:
// div p {
// color: red; }
//

}

func ExampleComipler_sass() {
src := bytes.NewBufferString(`
html
font-family: 'MonoSocial'
`)
comp, err := New(os.Stdout, src, WithSyntax(SassSyntax))
if err != nil {
log.Fatal(err)
}
err = comp.Run()
if err != nil {
log.Fatal(err)
}

// Output:
// html {
// font-family: 'MonoSocial'; }

}

func TestCompiler_path(t *testing.T) {
var dst bytes.Buffer

Expand Down
27 changes: 22 additions & 5 deletions context.go
Expand Up @@ -198,11 +198,29 @@ func (ctx *compctx) fileCompile(path string, out io.Writer, mappath, sourceMapRo
func (ctx *compctx) compile(out io.Writer, in io.Reader) error {

defer ctx.Reset()
bs, err := ioutil.ReadAll(in)

if err != nil {
return err
var (
bs []byte
err error
)

// libSass will fail on Sass syntax given as non-file input
// convert the input on its behalf
if ctx.compiler.Syntax() == SassSyntax {
// this is memory intensive
var buf bytes.Buffer
err := ToScss(in, &buf)
if err != nil {
return err
}
bs = buf.Bytes()
} else {
// ScssSyntax
bs, err = ioutil.ReadAll(in)
if err != nil {
return err
}
}

if len(bs) == 0 {
return errors.New("No input provided")
}
Expand All @@ -229,7 +247,6 @@ func (ctx *compctx) compile(out io.Writer, in io.Reader) error {
ctx.Status = libs.SassContextGetErrorStatus(goctx)
errJSON := libs.SassContextGetErrorJSON(goctx)
err = ctx.ProcessSassError([]byte(errJSON))

if err != nil {
return err
}
Expand Down