Пример #1
0
func main() {
	cmdline.Go(func() error {
		var bps basePathSlice
		srcCssFile := flag.String("i", "", "Input css file")
		dstCssFile := flag.String("o", "", "Output css file, can be the same as input css file")
		flag.Var(&bps, "base", "Base directory to resolve image files. Default to input css file directory. Can be specified multiple times, it is useful if the input css file is created by tools such as scss from multiple .css files in different directories.")

		flag.Parse()

		var (
			css []byte
			out string
			err error
		)

		if *srcCssFile == "" || *dstCssFile == "" {
			flag.Usage()
			return cmdline.NewExitError(2)
		}

		if len(bps) == 0 {
			bps = basePathSlice{filepath.Dir(*srcCssFile)}
		}

		if css, err = ioutil.ReadFile(*srcCssFile); err != nil {
			return errors.NewInput(err)
		}

		spriter := sprite.New(string(css), sprite.NewFileService(([]string)(bps), filepath.Dir(*dstCssFile)))
		if out, err = spriter.Gen(); err != nil {
			return err
		}

		if err = ioutil.WriteFile(*dstCssFile, ([]byte)(out), 0); err != nil {
			return errors.NewRuntime(err)
		}

		return nil
	})
}
Пример #2
0
// Do the generation, return translated css file content. Generated sprite
// image files are saved using Service interface.
func (s *Spriter) Gen() (css string, err error) {
	var tks []*scanner.Token
	tks, err = scan(s.css)
	if err != nil {
		return
	}

	needTranslate := false
	groups := make(map[string][]*cssImage)
	for _, tk := range tks {
		switch tk.Type {
		case scanner.TokenIdent:
			needTranslate = tk.Value == "background"
		case scanner.TokenURI:
			if needTranslate {
				var (
					st *cssImage
					g  string
				)
				if st, g, err = s.parseCssImage(tk); err != nil {
					return
				}

				if st != nil {
					groups[g] = append(groups[g], st)
				}
			}
		}
	}

	for _, sts := range groups {
		size := getSpriteSize(sts)
		var sprite = image.NewRGBA(image.Rectangle{Min: image.Point{}, Max: size})
		for _, st := range sts {
			b := st.img.bounds()
			draw.Draw(sprite, b.Add(image.Pt(-st.img.sp.X, st.img.sp.Y)), st.img.img, b.Min, draw.Src)
		}

		hash := md5.New()
		buf := &bytes.Buffer{}
		w := io.MultiWriter(buf, hash)
		if err = png.Encode(w, sprite); err != nil {
			err = errors.NewRuntime(err)
			return
		}
		token := base64.URLEncoding.EncodeToString(hash.Sum(nil)[:6])

		var f io.Writer
		f, err = s.sv.CreateSpriteImage(token + ".png")
		if err != nil {
			return
		}
		defer closeClosable(f)
		if _, err = f.Write(buf.Bytes()); err != nil {
			return
		}

		for _, st := range sts {
			st.tk.Value = "url(" + token + ".png) no-repeat"
			if st.img.sp.X != 0 {
				st.tk.Value += fmt.Sprintf(" %dpx 0", st.img.sp.X)
			}
		}
	}

	return writer.Dumps(tks)
}
Пример #3
0
		Ω(e.Error()).Should(Equal(msg))
		Ω(e.CausedBy()).Should(Equal(causedBy))
	}

	Context("Wrap error", func() {

		It("New", func() {
			assertError(errors.New("foo"), "foo", errors.ByBug)
		})

		It("NewBug", func() {
			assertError(errors.NewBug(syserr.New("foo")), "foo", errors.ByBug)
		})

		It("NewRuntime", func() {
			assertError(errors.NewRuntime(syserr.New("foo")), "foo", errors.ByRuntime)
		})

		It("NewExternal", func() {
			assertError(errors.NewExternal(syserr.New("foo")), "foo", errors.ByExternal)
		})

		It("NewInput", func() {
			assertError(errors.NewInput(syserr.New("foo")), "foo", errors.ByInput)
		})

		Context("Not wrap nil", func() {

			It("NewBug", func() {
				Ω(errors.NewBug(nil)).Should(BeNil())
			})