Beispiel #1
0
// ImageWidth takes a file path (or sprite glob) and returns the
// width in pixels of the image being referenced.
func ImageWidth(mainctx context.Context, usv libsass.SassValue) (rsv *libsass.SassValue, err error) {
	var (
		glob, name string
	)
	comp, err := libsass.CompFromCtx(mainctx)
	if err != nil {
		return
	}

	err = libsass.Unmarshal(usv, &name)
	// Check for sprite-file override first
	if err != nil {
		var inf interface{}
		var infs []interface{}
		// Can't unmarshal to []interface{}, so unmarshal to
		// interface{} then reflect it into a []interface{}
		err = libsass.Unmarshal(usv, &inf)
		k := reflect.ValueOf(&infs).Elem()
		k.Set(reflect.ValueOf(inf))

		if err != nil {
			return
		}
		glob = infs[0].(string)
		name = infs[1].(string)
	}
	paths := comp.(libsass.Pather)
	imgs := sw.New(&sw.Options{
		ImageDir:  paths.ImgDir(),
		BuildDir:  paths.BuildDir(),
		GenImgDir: paths.ImgBuildDir(),
	})

	loadctx := comp.Payload()
	var images payload.Payloader

	if len(glob) == 0 {
		images = payload.Image(loadctx)
		hit := images.Get(name)
		if hit != nil {
			imgs = hit
		} else {
			imgs.Decode(name)
			images.Set(name, imgs)
		}
	} else {
		// Glob present, look up in sprites
		sprites := payload.Sprite(loadctx)
		imgs = sprites.Get(glob)
	}
	w := imgs.SImageWidth(name)
	ww := libs.SassNumber{
		Value: float64(w),
		Unit:  "px",
	}
	res, err := libsass.Marshal(ww)
	return &res, err
}
Beispiel #2
0
// Run is the main entrypoint for the cli.
func run(paths []string, pMap *wt.SafePartialMap, gba *wt.BuildArgs) {

	// No paths given, read from stdin and wait
	if len(paths) == 0 {

		log.Println("Reading from stdin, -h for help")
		out := os.Stdout
		in := os.Stdin
		comp, err := wt.FromBuildArgs(out, nil, in, gba)
		if err != nil {
			log.Fatal(err)
		}
		err = comp.Run()
		if err != nil {
			color.Red(err.Error())
		}
		return
	}

	bOpts := wt.NewBuild(paths, gba, pMap)

	err := bOpts.Run()
	if err != nil {
		log.Fatal(err)
	}

	// FIXME: move this to a Payload.Close() method

	// Before shutting down, check that every sprite has been
	// flushed to disk.
	img := sync.WaitGroup{}
	pMap.RLock()
	// It's not currently possible to wait on Image. This is often
	// to inline images, so it shouldn't be a factor...
	// for _, s := range gba.Payload.Image().M {
	// 	img.Add(1)
	// 	err := s.Wait()
	// 	img.Done()
	// 	if err != nil {
	// 		log.Printf("error writing image: %s\n", err)
	// 	}
	// }
	sprites := payload.Sprite(gba.Payload)
	sprites.ForEach(func(k string, sprite *spritewell.Sprite) {
		img.Add(1)
		err := sprite.Wait()
		img.Done()
		if err != nil {
			log.Printf("error writing sprite: %s\n", err)
		}
	})
	img.Wait()
	pMap.RUnlock()

}
Beispiel #3
0
// SpritePosition returns the position of the image in the sprite-map.
// This is useful for passing directly to background-position
func SpritePosition(mainctx context.Context, usv libsass.SassValue) (rsv *libsass.SassValue, err error) {
	comp, err := libsass.CompFromCtx(mainctx)
	if err != nil {
		return
	}

	var glob, name string
	err = libsass.Unmarshal(usv, &glob, &name)
	if err != nil {
		return
	}

	loadctx := comp.Payload()
	if loadctx == nil {
		err = ErrPayloadNil
		return
	}

	sprites := payload.Sprite(loadctx)
	if sprites == nil {
		err = errors.New("Sprites missing")
		return
	}

	imgs := sprites.Get(glob)
	if imgs == nil {
		err = fmt.Errorf(
			"Variable not found matching glob: %s sprite:%s", glob, name)
		return
	}

	if imgs.Lookup(name) == -1 {
		err = fmt.Errorf("image %s not found\n"+
			"   try one of these: %v", name, imgs.Paths())
		return
	}

	// This is an odd name for what it does
	pos := imgs.GetPack(imgs.Lookup(name))
	if err != nil {
		return
	}

	x := libs.SassNumber{Unit: "px", Value: float64(-pos.X)}
	y := libs.SassNumber{Unit: "px", Value: float64(-pos.Y)}

	str, err := libsass.Marshal(
		[]libs.SassNumber{x, y},
	)
	return &str, err
}
Beispiel #4
0
// Sprite returns the source and background position for an image in the
// spritesheet.
func Sprite(ctx context.Context, usv libsass.SassValue) (rsv *libsass.SassValue, err error) {

	comp, err := libsass.CompFromCtx(ctx)
	if err != nil {
		return nil, err
	}

	pather := comp.(libsass.Pather)

	var glob, name string
	var offsetX, offsetY libs.SassNumber
	err = libsass.Unmarshal(usv, &glob, &name, &offsetX, &offsetY)
	if err != nil {
		if err == libsass.ErrSassNumberNoUnit {
			err := fmt.Errorf(
				"Please specify unit for offset ie. (2px)")
			return nil, err
		}
		return nil, err
	}

	loadctx := comp.Payload()

	sprites := payload.Sprite(loadctx)

	imgs := sprites.Get(glob)
	if imgs == nil {
		err := fmt.Errorf(
			"Variable not found matching glob: %s sprite:%s", glob, name)
		return nil, err
	}

	path, err := imgs.OutputPath()
	if err != nil {
		return nil, err
	}

	buildDir := pather.BuildDir()
	genImgDir := pather.ImgBuildDir()
	httpPath := pather.HTTPPath()

	// FIXME: path directory can not be trusted, rebuild this from the context
	if len(httpPath) == 0 {
		ctxPath, err := filepath.Rel(buildDir, genImgDir)
		if err != nil {
			return nil, err
		}
		path = strings.Join([]string{ctxPath, filepath.Base(path)}, "/")
	} else {
		u, err := url.Parse(httpPath)
		if err != nil {
			return nil, err
		}
		u.Path = strings.Join([]string{u.Path, "build", filepath.Base(path)}, "/")
		path = u.String()
	}
	if err != nil {
		return nil, err
	}

	if imgs.Lookup(name) == -1 {
		return nil, fmt.Errorf("image %s not found\n"+
			"   try one of these: %v", name, imgs.Paths())
	}
	// This is an odd name for what it does
	pos := imgs.GetPack(imgs.Lookup(name))

	if err != nil {
		return nil, err
	}

	x := libs.SassNumber{Unit: "px", Value: float64(-pos.X)}
	x = x.Add(offsetX)

	y := libs.SassNumber{Unit: "px", Value: float64(-pos.Y)}
	y = y.Add(offsetY)

	str, err := libsass.Marshal(
		fmt.Sprintf(`url("%s") %s %s`,
			path, x, y,
		))
	if err != nil {
		return nil, err
	}

	return &str, nil
}
Beispiel #5
0
// SpriteMap returns a sprite from the passed glob and sprite
// parameters.
func SpriteMap(mainctx context.Context, usv libsass.SassValue) (*libsass.SassValue, error) {
	var glob string
	var spacing libs.SassNumber
	err := libsass.Unmarshal(usv, &glob, &spacing)
	if err != nil {
		return nil, err
	}
	comp, err := libsass.CompFromCtx(mainctx)
	if err != nil {
		return nil, err
	}
	paths := comp.(libsass.Pather)
	imgs := sw.New(&sw.Options{
		ImageDir:  paths.ImgDir(),
		BuildDir:  paths.BuildDir(),
		GenImgDir: paths.ImgBuildDir(),
		Padding:   int(spacing.Value),
	})
	if cglob, err := strconv.Unquote(glob); err == nil {
		glob = cglob
	}

	key := glob + strconv.FormatInt(int64(spacing.Value), 10)

	loadctx := comp.Payload()
	sprites := payload.Sprite(loadctx)

	// FIXME: wtf is this?
	// sprites.RLock()
	// if _, ok := sprites.M[key]; ok {
	// 	defer sprites.RUnlock()
	// 	res, err := libsass.Marshal(key)
	// 	if err != nil {
	// 		return setErrorAndReturn(err, rsv)
	// 	}
	// 	if rsv != nil {
	// 		*rsv = res
	// 	}
	// 	return nil
	// }
	// sprites.RUnlock()

	err = imgs.Decode(glob)
	if err != nil {
		return nil, err
	}

	_, err = imgs.Export()
	if err != nil {
		return nil, err
	}

	res, err := libsass.Marshal(key)
	if err != nil {
		return nil, err
	}

	sprites.Set(key, imgs)

	return &res, nil
}
Beispiel #6
0
// ImageHeight takes a file path (or sprite glob) and returns the
// height in pixels of the image being referenced.
func ImageHeight(mainctx context.Context, usv libsass.SassValue) (*libsass.SassValue, error) {
	var (
		glob string
		name string
	)

	comp, err := libsass.CompFromCtx(mainctx)
	if err != nil {
		return nil, err
	}

	err = libsass.Unmarshal(usv, &name)
	// Check for sprite-file override first
	if err != nil {
		var inf interface{}
		var infs []interface{}
		// Can't unmarshal to []interface{}, so unmarshal to
		// interface{} then reflect it into a []interface{}
		err = libsass.Unmarshal(usv, &inf)
		k := reflect.ValueOf(&infs).Elem()
		k.Set(reflect.ValueOf(inf))

		if err != nil {
			return nil, err
		}
		glob = infs[0].(string)
		name = infs[1].(string)
	}
	paths := comp.(libsass.Pather)
	imgs := sw.New(&sw.Options{
		ImageDir:  paths.ImgDir(),
		BuildDir:  paths.BuildDir(),
		GenImgDir: paths.ImgBuildDir(),
	})

	loadctx := comp.Payload()
	if loadctx == nil {
		return nil, ErrPayloadNil
	}

	images := payload.Image(loadctx)
	if images == nil {
		return nil, errors.New("inline payload not available")
	}

	if len(glob) == 0 {
		exst := images.Get(name)
		if exst != nil {
			imgs = exst
		} else {
			imgs.Decode(name)
			// Store images in global cache
			images.Set(name, imgs)
		}
	} else {
		sprites := payload.Sprite(loadctx)
		imgs = sprites.Get(glob)
		if imgs == nil {
			return nil, errors.New("Sprite not found")
		}
	}
	height := imgs.SImageHeight(name)
	Hheight := libs.SassNumber{
		Value: float64(height),
		Unit:  "px",
	}
	res, err := libsass.Marshal(Hheight)
	return &res, err
}