Example #1
0
func (e extractContent) prepareHTMLOut(a *Article) error {
	if a.TopNode == nil {
		return nil
	}

	m := minify.New()
	m.AddFunc("text/html", minhtml.Minify)

	var b bytes.Buffer
	html, _ := a.TopNode.Html()

	m.Minify("text/html", &b, strings.NewReader(html))
	doc, _ := goquery.NewDocumentFromReader(&b)

	a.TopNode = doc.FindMatcher(bodyTag)

	// Quick-and-dirty node-to-text replacement
	a.TopNode.FindMatcher(replaceWithContentsTags).Each(
		func(i int, s *goquery.Selection) {
			s.Contents().Unwrap()
		})

	a.addInlineArticleImageHTML(a.Meta.Title)

	return nil
}
Example #2
0
func (*minify) Process(ctx goldsmith.Context, f goldsmith.File) error {
	var (
		buff bytes.Buffer
		err  error
	)

	switch m := min.New(); filepath.Ext(f.Path()) {
	case ".css":
		err = css.Minify(m, &buff, f, nil)
	case ".html", ".htm":
		err = html.Minify(m, &buff, f, nil)
	case ".js":
		err = js.Minify(m, &buff, f, nil)
	case ".json":
		err = json.Minify(m, &buff, f, nil)
	case ".svg":
		err = svg.Minify(m, &buff, f, nil)
	case ".xml":
		err = xml.Minify(m, &buff, f, nil)
	}

	if err != nil {
		return err
	}

	nf := goldsmith.NewFileFromData(f.Path(), buff.Bytes())
	nf.CopyValues(f)
	ctx.DispatchFile(nf)

	return nil
}
Example #3
0
func TestHTMLURL(t *testing.T) {
	var htmlTests = []struct {
		url      string
		html     string
		expected string
	}{
		{`http://example.com/`, `<a href=http://example.com/>link</a>`, `<a href=//example.com/>link</a>`},
		{`https://example.com/`, `<a href=http://example.com/>link</a>`, `<a href=http://example.com/>link</a>`},
		{`http://example.com/`, `<a href=https://example.com/>link</a>`, `<a href=https://example.com/>link</a>`},
		{`https://example.com/`, `<a href=https://example.com/>link</a>`, `<a href=//example.com/>link</a>`},
		{`http://example.com/`, `<a href="   http://example.com  ">x</a>`, `<a href=//example.com>x</a>`},
		{`http://example.com/`, `<link rel="stylesheet" type="text/css" href="http://example.com">`, `<link rel=stylesheet href=//example.com>`},
		{`http://example.com/`, `<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head profile="http://dublincore.org/documents/dcq-html/"> <!-- Barlesque 2.75.0 --> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />`,
			`<!doctype html><html xmlns=//www.w3.org/1999/xhtml xml:lang=en><head profile=//dublincore.org/documents/dcq-html/><meta charset=utf-8>`},
		{`http://example.com/`, `<svg xmlns="http://www.w3.org/2000/svg"></svg>`, `<svg xmlns=//www.w3.org/2000/svg></svg>`},
		{`https://example.com/`, `<svg xmlns="http://www.w3.org/2000/svg"></svg>`, `<svg xmlns=http://www.w3.org/2000/svg></svg>`},
		{`http://example.com/`, `<svg xmlns="https://www.w3.org/2000/svg"></svg>`, `<svg xmlns=https://www.w3.org/2000/svg></svg>`},
		{`https://example.com/`, `<svg xmlns="https://www.w3.org/2000/svg"></svg>`, `<svg xmlns=//www.w3.org/2000/svg></svg>`},
	}

	m := minify.New()
	m.AddFunc("text/html", Minify)
	for _, tt := range htmlTests {
		r := bytes.NewBufferString(tt.html)
		w := &bytes.Buffer{}
		m.URL, _ = url.Parse(tt.url)
		assert.Nil(t, Minify(m, w, r, nil), "Minify must not return error in "+tt.html)
		assert.Equal(t, tt.expected, w.String(), "Minify must give expected result in "+tt.html)
	}
}
Example #4
0
func TestWriterErrors(t *testing.T) {
	errorTests := []struct {
		css string
		n   []int
	}{
		{`@import 'file'`, []int{0, 2}},
		{`@media all{}`, []int{0, 2, 3, 4}},
		{`a[id^="L"]{margin:2in!important;color:red}`, []int{0, 4, 6, 7, 8, 9, 10, 11}},
		{`a{color:rgb(255,0,0)}`, []int{4}},
		{`a{color:rgb(255,255,255)}`, []int{4}},
		{`a{color:hsl(0,100%,50%)}`, []int{4}},
		{`a{color:hsl(360,100%,100%)}`, []int{4}},
		{`a{color:f(arg)}`, []int{4}},
		{`<!--`, []int{0}},
		{`/*!comment*/`, []int{0, 1, 2}},
	}

	m := minify.New()
	for _, tt := range errorTests {
		for _, n := range tt.n {
			r := bytes.NewBufferString(tt.css)
			w := test.NewErrorWriter(n)
			test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.css)
		}
	}
}
Example #5
0
func TestHTMLKeepWhitespace(t *testing.T) {
	htmlTests := []struct {
		html     string
		expected string
	}{
		{`cats  and 	dogs `, `cats and dogs`},
		{` <div> <i> test </i> <b> test </b> </div> `, `<div> <i> test </i> <b> test </b> </div>`},
		{`<strong>x </strong>y`, `<strong>x </strong>y`},
		{`<strong>x </strong> y`, `<strong>x </strong> y`},
		{"<strong>x </strong>\ny", "<strong>x </strong>\ny"},
		{`<p>x </p>y`, `<p>x </p>y`},
		{`x <p>y</p>`, `x <p>y`},
		{` <!doctype html> <!--comment--> <html> <body><p></p></body></html> `, `<!doctype html><p>`}, // spaces before html and at the start of html are dropped
		{`<p>x<br> y`, `<p>x<br> y`},
		{`<p>x </b> <b> y`, `<p>x </b> <b> y`},
		{`a <code>code</code> b`, `a <code>code</code> b`},
		{`a <code></code> b`, `a <code></code> b`},
		{`a <script>script</script> b`, `a <script>script</script> b`},
		{"text\n<!--comment-->\ntext", "text\ntext"},
		{"text\n<!--comment-->text<!--comment--> text", "text\ntext text"},
		{"abc\n</body>\ndef", "abc\ndef"},
		{"<x>\n<!--y-->\n</x>", "<x>\n</x>"},
		{"<style>lala{color:red}</style>", "<style>lala{color:red}</style>"},
	}

	m := minify.New()
	htmlMinifier := &Minifier{KeepWhitespace: true}
	for _, tt := range htmlTests {
		r := bytes.NewBufferString(tt.html)
		w := &bytes.Buffer{}
		test.Minify(t, tt.html, htmlMinifier.Minify(m, w, r, nil), w.String(), tt.expected)
	}
}
Example #6
0
func TestWriterErrors(t *testing.T) {
	errorTests := []struct {
		svg string
		n   []int
	}{
		{`<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "foo.dtd" [ <!ENTITY x "bar"> ]>`, []int{0}},
		{`abc`, []int{0}},
		{`<style>abc</style>`, []int{2}},
		{`<![CDATA[ <<<< ]]>`, []int{0}},
		{`<![CDATA[ <<<<< ]]>`, []int{0}},
		{`<path d="x"/>`, []int{0, 1, 2, 3, 4, 5}},
		{`<path></path>`, []int{1}},
		{`<svg>x</svg>`, []int{1, 3}},
		{`<svg>x</svg >`, []int{3}},
	}

	m := minify.New()
	for _, tt := range errorTests {
		for _, n := range tt.n {
			r := bytes.NewBufferString(tt.svg)
			w := test.NewErrorWriter(n)
			test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.svg)
		}
	}
}
Example #7
0
func createAppMinJsFile(appScripts []string, dir string) {
	appMinJsWrtr, err := os.Create(filepath.Join(dir, "app.min.js"))
	if err != nil {
		log.Fatal(err)
	}
	defer closeFile(appMinJsWrtr, true)
	var buffer bytes.Buffer
	for _, script := range appScripts {
		file, err := os.Open(filepath.Join(dir, script))
		if err != nil {
			log.Fatal(err)
		}
		defer closeFile(file, false)
		_, err = io.Copy(&buffer, file)
		if err != nil {
			log.Fatalf("Error copying script file '%v' to buffer: %v", script, err)
		}

	}
	mimetype := "text/javascript"
	minifier := minify.New()
	minifier.AddFunc(mimetype, js.Minify)
	minified, err := minify.Bytes(minifier, mimetype, buffer.Bytes())
	if err != nil {
		log.Fatalf("Error during minification: %v", err)
	}

	_, err = io.Copy(appMinJsWrtr, bytes.NewReader(minified))
	if err != nil {
		log.Fatalf("Error copying to file app.min.js: %v", err)
	}
}
Example #8
0
func TestJS(t *testing.T) {
	jsTests := []struct {
		js       string
		expected string
	}{
		{"/*comment*/", ""},
		{"// comment\na", "a"},
		{"/*! bang  comment */", "/*!bang comment*/"},
		{"function x(){}", "function x(){}"},
		{"function x(a, b){}", "function x(a,b){}"},
		{"a  b", "a b"},
		{"a\n\nb", "a\nb"},
		{"a// comment\nb", "a\nb"},
		{"''\na", "''\na"},
		{"''\n''", "''''"},
		{"]\n0", "]\n0"},
		{"a\n{", "a\n{"},
		{";\na", ";a"},
		{",\na", ",a"},
		{"}\na", "}\na"},
		{"+\na", "+\na"},
		{"+\n(", "+\n("},
		{"+\n\"\"", "+\"\""},
		{"a + ++b", "a+ ++b"},                                          // JSMin caution
		{"var a=/\\s?auto?\\s?/i\nvar", "var a=/\\s?auto?\\s?/i\nvar"}, // #14
		{"`\n", "`"}, // go fuzz
	}

	m := minify.New()
	for _, tt := range jsTests {
		r := bytes.NewBufferString(tt.js)
		w := &bytes.Buffer{}
		test.Minify(t, tt.js, Minify(m, w, r, nil), w.String(), tt.expected)
	}
}
Example #9
0
func assertSVG(t *testing.T, input, expected string) {
	m := minify.New()
	m.AddFunc("image/svg+xml", Minify)
	b := &bytes.Buffer{}
	assert.Nil(t, m.Minify("image/svg+xml", b, bytes.NewBufferString(input)), "Minify must not return error in "+input)
	assert.Equal(t, expected, b.String(), "Minify must give expected result in "+input)
}
Example #10
0
File: css.go Project: go-gonzo/css
func Minify() 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(), ".css") + ".min.css"
				ctx.Infof("Compiling %s to %s", file.FileInfo().Name(), name)
				m := minify.New()
				m.AddFunc("text/css", css.Minify)
				err := m.Minify("text/css", buff, file)
				if err != nil {
					return err
				}

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

				out <- file
			case <-ctx.Done():
				return ctx.Err()
			}
		}
	}
}
Example #11
0
func TestJS(t *testing.T) {
	var jsTests = []struct {
		js       string
		expected string
	}{
		{"/*comment*/", ""},
		{"// comment\na", "a"},
		{"function x(){}", "function x(){}"},
		{"function x(a, b){}", "function x(a,b){}"},
		{"a  b", "a b"},
		{"a\n\nb", "a\nb"},
		{"a// comment\nb", "a\nb"},
		{"''\na", "''\na"},
		{"''\n''", "''''"},
		{"]\n0", "]\n0"},
		{"a\n{", "a\n{"},
		{";\na", ";a"},
		{",\na", ",a"},
		{"}\na", "}\na"},
		{"+\na", "+\na"},
		{"+\n(", "+\n("},
		{"+\n\"\"", "+\"\""},
		{"a + ++b", "a+ ++b"},                                          // JSMin caution
		{"var a=/\\s?auto?\\s?/i\nvar", "var a=/\\s?auto?\\s?/i\nvar"}, // #14
	}

	m := minify.New()
	for _, tt := range jsTests {
		b := &bytes.Buffer{}
		assert.Nil(t, Minify(m, b, bytes.NewBufferString(tt.js), nil), "Minify must not return error in "+tt.js)
		assert.Equal(t, tt.expected, b.String(), "Minify must give expected result in "+tt.js)
	}
}
Example #12
0
func Min(c *slurp.C, mediatype string) slurp.Stage {
	return func(in <-chan slurp.File, out chan<- slurp.File) {

		supported := make(map[string]uint8)
		supported["text/css"] = 1
		supported["text/html"] = 1
		supported["text/javascript"] = 1

		var wg sync.WaitGroup
		defer wg.Wait()

		_, ok := supported[mediatype]
		if ok {
			for file := range in {
				m := minify.New()
				m.AddFunc("text/css", css.Minify)
				m.AddFunc("text/html", html.Minify)
				m.AddFunc("text/javascript", js.Minify)
				wg.Add(1)
				go func(file slurp.File) {
					defer wg.Done()

					minified := new(bytes.Buffer)
					if err := m.Minify(mediatype, minified, file.Reader); err != nil {
						log.Fatal("js.Minify:", err)
					}

					file.Reader = minified
					file.FileInfo.SetSize(int64(minified.Len()))
					out <- file
				}(file)
			}
		}
	}
}
Example #13
0
func TestWriterErrors(t *testing.T) {
	var errorTests = []struct {
		css string
		n   []int
	}{
		{`@import 'file'`, []int{0, 2}},
		{`@media all{}`, []int{0, 2, 3, 4}},
		{`a[id^="L"]{margin:2in!important;color:red}`, []int{0, 4, 6, 7, 8, 9, 10, 11}},
		{`a{color:rgb(255,0,0)}`, []int{4}},
		{`a{color:rgb(255,255,255)}`, []int{4}},
		{`a{color:hsl(0,100%,50%)}`, []int{4}},
		{`a{color:hsl(360,100%,100%)}`, []int{4}},
		{`a{color:f(arg)}`, []int{4}},
		{`<!--`, []int{0}},
	}

	m := minify.New()
	for _, tt := range errorTests {
		for _, n := range tt.n {
			r := bytes.NewBufferString(tt.css)
			w := test.NewErrorWriter(n)
			assert.Equal(t, test.ErrPlain, Minify(m, w, r, nil), "Minify must return error in "+tt.css+" at write "+strconv.FormatInt(int64(n), 10))
		}
	}
}
Example #14
0
func TestXML(t *testing.T) {
	var xmlTests = []struct {
		xml      string
		expected string
	}{
		{"<!-- comment -->", ""},
		{"<A>x</A>", "<A>x</A>"},
		{"<a><b>x</b></a>", "<a><b>x</b></a>"},
		{"<a><b>x\ny</b></a>", "<a><b>x\ny</b></a>"},
		{"<a> <![CDATA[ a ]]> </a>", "<a>a</a>"},
		{"<a >a</a >", "<a>a</a>"},
		{"<?xml  version=\"1.0\" ?>", "<?xml version=\"1.0\"?>"},
		{"<x></x>", "<x/>"},
		{"<x> </x>", "<x/>"},
		{"<x a=\"b\"></x>", "<x a=\"b\"/>"},
		{"<x a=\"\"></x>", "<x a=\"\"/>"},
		{"<x a=a></x>", "<x a=a/>"},
		{"<x a=\" a \n\r\t b \"/>", "<x a=\" a     b \"/>"},
		{"<x a=\"&apos;b&quot;\"></x>", "<x a=\"'b&#34;\"/>"},
		{"<x a=\"&quot;&quot;'\"></x>", "<x a='\"\"&#39;'/>"},
		{"<!DOCTYPE foo SYSTEM \"Foo.dtd\">", "<!DOCTYPE foo SYSTEM \"Foo.dtd\">"},
		{"text <!--comment--> text", "text text"},
	}

	m := minify.New()
	for _, tt := range xmlTests {
		b := &bytes.Buffer{}
		assert.Nil(t, Minify(m, b, bytes.NewBufferString(tt.xml), nil), "Minify must not return error in "+tt.xml)
		assert.Equal(t, tt.expected, b.String(), "Minify must give expected result in "+tt.xml)
	}
}
Example #15
0
func ExampleMinify() {
	m := minify.New()
	m.AddFunc("text/css", Minify)

	if err := m.Minify("text/css", os.Stdout, os.Stdin); err != nil {
		fmt.Println("minify.Minify:", err)
	}
}
Example #16
0
func ExampleMinify() {
	m := minify.New()
	m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), Minify)

	if err := m.Minify("text/xml", os.Stdout, os.Stdin); err != nil {
		panic(err)
	}
}
Example #17
0
func init() {
	minifier = minify.New()
	minifier.AddFunc("text/css", css.Minify)
	minifier.AddFunc("text/html", html.Minify)
	minifier.AddFunc("text/javascript", js.Minify)

	mediaType = regexp.MustCompile("text/[html|css|javascript]")
}
Example #18
0
func Fuzz(data []byte) int {
	r := bytes.NewBuffer(data)
	err := xml.Minify(minify.New(), ioutil.Discard, r, nil)
	if err != nil {
		panic(err)
	}
	return 1
}
Example #19
0
func ExampleMinify() {
	m := minify.New()
	m.AddFunc("text/css", Minify)

	if err := m.Minify("text/css", os.Stdout, os.Stdin); err != nil {
		panic(err)
	}
}
Example #20
0
func ExampleMinify() {
	m := minify.New()
	m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), Minify)

	if err := m.Minify("application/json", os.Stdout, os.Stdin); err != nil {
		fmt.Println("minify.Minify:", err)
	}
}
Example #21
0
func Fuzz(data []byte) int {
	r := bytes.NewBuffer(data)
	err := json.Minify(minify.New(), ioutil.Discard, r, nil)
	if err != nil {
		return 0
	}
	return 1
}
Example #22
0
func TestCSSInlineMediatype(t *testing.T) {
	css := `color:red`
	m := minify.New()

	r := bytes.NewBufferString(css)
	w := &bytes.Buffer{}
	assert.Nil(t, Minify(m, "text/css ; inline = 1", w, r), "Minify must not return error in "+css)
	assert.Equal(t, css, w.String(), "Minify must give expected result in "+css)
}
Example #23
0
// Helper function to minify code
func minifyScript(script string) string {
	m := minify.New()
	m.AddFunc("text/javascript", js.Minify)
	miny, err := m.String("text/javascript", script)
	if err != nil {
		log.Fatal("minify.String:", err)
	}
	return miny
}
Example #24
0
func ExampleMinify_writer() {
	m := minify.New()
	m.Add("text/html", &Minifier{})

	w := m.Writer("text/html", os.Stdout)
	w.Write([]byte("<html><body><h1>Example</h1></body></html>"))
	w.Close()
	// Output: <h1>Example</h1>
}
Example #25
0
func Minify(input string, mime string) (result string) {
	if minifier == nil {
		log.Print("initializing minifier")
		minifier = minify.New()
		minifier.AddFunc("js", js.Minify)
	}
	result, err := minify.String(minifier, mime, input)
	CheckErrorPanic(err)
	return
}
Example #26
0
func initMinifier() {

	if m != nil {
		return
	}

	m = minify.New()
	m.AddFunc("text/css", css.Minify)
	m.AddFunc("text/javascript", js.Minify)
}
Example #27
0
func getMinifier() *minify.M {
	if minifier == nil {
		minifier = minify.New()
		minifier.AddFunc("text/css", css.Minify)
		minifier.AddFunc("application/javascript", js.Minify)
		minifier.AddFunc("application/json", json.Minify)
		minifier.AddFunc("image/svg+xml", svg.Minify)
	}

	return minifier
}
Example #28
0
func TestWriterErrors(t *testing.T) {
	var errorTests = []int{0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 18, 19}

	m := minify.New()
	for _, n := range errorTests {
		// writes:                  0             1    2 3 45678901    23 4 5 6    7   8                    9
		r := bytes.NewBufferString(`<!DOCTYPE foo><?xml?><a x=y z="val"><b/><c></c></a><![CDATA[data<<<<<]]>text`)
		w := test.NewErrorWriter(n)
		assert.Equal(t, test.ErrPlain, Minify(m, w, r, nil), "Minify must return error at write "+strconv.FormatInt(int64(n), 10))
	}
}
Example #29
0
func TestWriterErrors(t *testing.T) {
	var errorTests = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14}

	m := minify.New()
	for _, n := range errorTests {
		// writes:                  0         1   2     34   56  78  9       0    12   3      4
		r := bytes.NewBufferString(`<!doctype>text<style attr=val>css</style><code>code</code><!--comment-->`)
		w := test.NewErrorWriter(n)
		assert.Equal(t, test.ErrPlain, Minify(m, w, r, nil), "Minify must return error at write "+strconv.FormatInt(int64(n), 10))
	}
}
Example #30
0
func ExampleMinify_options() {
	m := minify.New()
	m.Add("text/html", &Minifier{
		KeepDefaultAttrVals: true,
		KeepWhitespace:      true,
	})

	if err := m.Minify("text/html", os.Stdout, os.Stdin); err != nil {
		panic(err)
	}
}