1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-08-16 18:01:37 +00:00

First commit

This commit is contained in:
Frédéric Guillot 2017-11-19 21:10:04 -08:00
commit 8ffb773f43
2121 changed files with 1118910 additions and 0 deletions

View file

@ -0,0 +1,32 @@
package benchmarks
import (
"testing"
"github.com/tdewolff/minify/css"
)
var cssSamples = []string{
"sample_bootstrap.css",
"sample_gumby.css",
}
func init() {
for _, sample := range cssSamples {
load(sample)
}
}
func BenchmarkCSS(b *testing.B) {
for _, sample := range cssSamples {
b.Run(sample, func(b *testing.B) {
b.SetBytes(int64(r[sample].Len()))
for i := 0; i < b.N; i++ {
r[sample].Reset()
w[sample].Reset()
css.Minify(m, w[sample], r[sample], nil)
}
})
}
}

View file

@ -0,0 +1,36 @@
package benchmarks
import (
"testing"
"github.com/tdewolff/minify/html"
)
var htmlSamples = []string{
"sample_amazon.html",
"sample_bbc.html",
"sample_blogpost.html",
"sample_es6.html",
"sample_stackoverflow.html",
"sample_wikipedia.html",
}
func init() {
for _, sample := range htmlSamples {
load(sample)
}
}
func BenchmarkHTML(b *testing.B) {
for _, sample := range htmlSamples {
b.Run(sample, func(b *testing.B) {
b.SetBytes(int64(r[sample].Len()))
for i := 0; i < b.N; i++ {
r[sample].Reset()
w[sample].Reset()
html.Minify(m, w[sample], r[sample], nil)
}
})
}
}

View file

@ -0,0 +1,35 @@
package benchmarks
import (
"testing"
"github.com/tdewolff/minify/js"
)
var jsSamples = []string{
"sample_ace.js",
"sample_dot.js",
"sample_jquery.js",
"sample_jqueryui.js",
"sample_moment.js",
}
func init() {
for _, sample := range jsSamples {
load(sample)
}
}
func BenchmarkJS(b *testing.B) {
for _, sample := range jsSamples {
b.Run(sample, func(b *testing.B) {
b.SetBytes(int64(r[sample].Len()))
for i := 0; i < b.N; i++ {
r[sample].Reset()
w[sample].Reset()
js.Minify(m, w[sample], r[sample], nil)
}
})
}
}

View file

@ -0,0 +1,33 @@
package benchmarks
import (
"testing"
"github.com/tdewolff/minify/json"
)
var jsonSamples = []string{
"sample_large.json",
"sample_testsuite.json",
"sample_twitter.json",
}
func init() {
for _, sample := range jsonSamples {
load(sample)
}
}
func BenchmarkJSON(b *testing.B) {
for _, sample := range jsonSamples {
b.Run(sample, func(b *testing.B) {
b.SetBytes(int64(r[sample].Len()))
for i := 0; i < b.N; i++ {
r[sample].Reset()
w[sample].Reset()
json.Minify(m, w[sample], r[sample], nil)
}
})
}
}

View file

@ -0,0 +1,18 @@
package benchmarks
import (
"io/ioutil"
"github.com/tdewolff/minify"
"github.com/tdewolff/parse/buffer"
)
var m = minify.New()
var r = map[string]*buffer.Reader{}
var w = map[string]*buffer.Writer{}
func load(filename string) {
sample, _ := ioutil.ReadFile(filename)
r[filename] = buffer.NewReader(sample)
w[filename] = buffer.NewWriter(make([]byte, 0, len(sample)))
}

18655
vendor/github.com/tdewolff/minify/benchmarks/sample_ace.js generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 1.4 MiB

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,580 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>research!rsc: My Go Resolutions for 2017</title>
<link rel="alternate" type="application/atom+xml" title="research!rsc - Atom" href="http://research.swtch.com/feed.atom" />
<link href='https://fonts.googleapis.com/css?family=Inconsolata:400,700' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="https://use.typekit.com/skm6yij.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<style>
body {
padding: 0;
margin: 0;
font-size: 100%;
}
.header {
height: 1.25em;
background-color: #dff;
margin: 0;
padding: 0.1em 0.1em 0.2em;
border-top: 1px solid black;
border-bottom: 1px solid #8ff;
}
.header h3 {
margin: 0;
padding: 0 2em;
display: inline-block;
padding-right: 2em;
font-style: italic;
font-family: "adobe-text-pro" !important;
font-size: 90%;
}
.rss {
float: right;
padding-top: 0.2em;
padding-right: 2em;
display: none;
}
.toc {
margin-top: 2em;
}
.toc-title {
font-family: "caflisch-script-pro";
font-size: 300%;
line-height: 50%;
}
.toc-subtitle {
display: block;
margin-bottom: 1em;
font-size: 83%;
}
@media only screen and (max-width: 550px) { .toc-subtitle { display: none; } }
.header h3 a {
color: black;
}
.header h4 {
margin: 0;
padding: 0;
display: inline-block;
font-weight: normal;
font-size: 83%;
}
@media only screen and (max-width: 550px) { .header h4 { display: none; } }
.main {
padding: 0 2em;
}
@media only screen and (max-width: 479px) { .article { font-size: 120%; } }
.article h1 {
text-align: center;
}
.article h1, .article h2, .article h3 {
font-family: 'Myriad Pro';
}
.normal {
font-size: medium;
font-weight: normal;
}
.when {
text-align: center;
font-size: 100%;
margin: 0;
padding: 0;
}
.when p {
margin: 0;
padding: 0;
}
.article h2 {
font-size: 100%;
padding-top: 0.25em;
}
pre {
margin-left: 4em;
margin-right: 4em;
}
pre, code {
font-family: 'Inconsolata', monospace;
font-size: 100%;
}
.footer {
margin-top: 10px;
font-size: 83%;
font-family: sans-serif;
}
.comments {
margin-top: 2em;
background-color: #ffe;
border-top: 1px solid #aa4;
border-left: 1px solid #aa4;
border-right: 1px solid #aa4;
}
.comments-header {
padding: 0 5px 0 5px;
}
.comments-header p {
padding: 0;
margin: 3px 0 0 0;
}
.comments-body {
padding: 5px 5px 5px 5px;
}
#plus-comments {
border-bottom: 1px dotted #ccc;
}
.plus-comment {
width: 100%;
font-size: 14px;
border-top: 1px dotted #ccc;
}
.me {
background-color: #eec;
}
.plus-comment ul {
margin: 0;
padding: 0;
list-style: none;
width: 100%;
display: inline-block;
}
.comment-when {
color:#999;
width:auto;
padding:0 5px;
}
.old {
font-size: 83%;
}
.plus-comment ul li {
display: inline-block;
vertical-align: top;
margin-top: 5px;
margin-bottom: 5px;
padding: 0;
}
.plus-icon {
width: 45px;
}
.plus-img {
float: left;
margin: 4px 4px 4px 4px;
width: 32px;
height: 32px;
}
.plus-comment p {
margin: 0;
padding: 0;
}
.plus-clear {
clear: left;
}
.toc-when {
font-size: 83%;
color: #ccc;
}
.toc {
list-style: none;
}
.toc li {
margin-bottom: 0.5em;
}
.toc-head {
margin-bottom: 1em !important;
font-size: 117%;
}
.toc-summary {
margin-left: 2em;
}
.favorite {
font-weight: bold;
}
.article p {
line-height: 144%;
}
sup, sub {
vertical-align: baseline;
position: relative;
font-size: 83%;
}
sup {
bottom: 1ex;
}
sub {
top: 0.8ex;
}
.main {
position: relative;
margin: 0 auto;
padding: 0;
width: 900px;
}
@media only screen and (min-width: 768px) and (max-width: 959px) { .main { width: 708px; } }
@media only screen and (min-width: 640px) and (max-width: 767px) { .main { width: 580px; } }
@media only screen and (min-width: 480px) and (max-width: 639px) { .main { width: 420px; } }
@media only screen and (max-width: 479px) { .main { width: 300px; } }
</style>
</head>
<body>
<div class="header">
<h3><a href="/">research!rsc</a></h3>
<h4>Thoughts and links about programming,
by <a href="https://swtch.com/~rsc/" rel="author">Russ Cox</a> </h4>
<a class="rss" href="/feed.atom"><img src="/feed-icon-14x14.png" /></a>
</div>
<div class="main">
<div class="article">
<h1>My Go Resolutions for 2017
<div class="normal">
<div class="when">
Posted on Wednesday, January 18, 2017.
</div>
</div>
</h1>
<p class=lp>Tis the season for resolutions,
and I thought it would make sense to write a little
about what I hope to work on this year as far as Go is concerned.</p>
<p class=pp>My goal every year is to <em>help Go developers</em>.
I want to make sure that the work we do on the Go team
has a significant, positive impact on Go developers.
That may sound obvious, but there are a variety of common ways to fail to achieve that:
for example, spending too much time cleaning up or optimizing code that doesnt need it;
responding only to the most common or recent complaints or requests;
or focusing too much on short-term improvements.
Its important to step back and make sure were focusing
our development work where it does the most good.</p>
<p class=pp>This post outlines a few of my own major focuses for this year.
This is only my personal list, not the Go teams list.</p>
<p class=pp>One reason for posting this is to gather feedback.
If these spark any ideas or suggestions of your own,
please feel free to comment below or on the linked GitHub issues.</p>
<p class=pp>Another reason is to make clear that Im aware of these issues as important.
I think too often people interpret lack of action by the Go team
as a signal that we think everything is perfect, when instead
there is simply other, higher priority work to do first.</p>
<h2><a name="alias"></a>Type aliases</h2>
<p class=lp>There is a recurring problem with moving types
from one package to another during large codebase refactorings.
We tried to solve it last year with <a href="https://golang.org/issue/16339">general aliases</a>,
which didnt work for at least two reasons: we didnt explain the change well enough,
and we didnt deliver it on time, so it wasnt ready for Go 1.8.
Learning from that experience,
I <a href="https://www.youtube.com/watch?v=h6Cw9iCDVcU">gave a talk</a>
and <a href="https://talks.golang.org/2016/refactor.article">wrote an article</a>
about the underlying problem,
and that started a <a href="https://golang.org/issue/18130">productive discussion</a>
on the Go issue tracker about the solution space.
It looks like more limited <a href="https://golang.org/design/18130-type-alias">type aliases</a>
are the right next step.
I want to make sure those land smoothly in Go 1.9. <a href="https://golang.org/issue/18130">#18130</a>.</p>
<h2><a name="package"></a>Package management</h2>
<p class=lp>I designed the Go support for downloading published packages
(“goinstall”, which became “go get”) in February 2010.
A lot has happened since then.
In particular, other language ecosystems have really raised the bar
for what people expect from package management,
and the open source world has mostly agreed on
<a href="http://semver.org/">semantic versioning</a>, which provides a useful base
for inferring version compatibility.
Go needs to do better here, and a group of contributors have been
<a href="https://blog.gopheracademy.com/advent-2016/saga-go-dependency-management/">working on a solution</a>.
I want to make sure these ideas are integrated well
into the standard Go toolchain and to make package management
a reason that people love Go.</p>
<h2><a name="build"></a>Build improvements</h2>
<p class=lp>There are a handful of shortcomings in the design of
the go commands build system that are overdue to be fixed.
Here are three representative examples that I intend to
address with a bit of a redesign of the internals of the go command.</p>
<p class=pp>Builds can be too slow,
because the go command doesnt cache build results as aggressively as it should.
Many people dont realize that <code>go</code> <code>install</code> saves its work while <code>go</code> <code>build</code> does not,
and then they run repeated <code>go</code> <code>build</code> commands that are slow
because the later builds do more work than they should need to.
The same for repeated <code>go</code> <code>test</code> without <code>go</code> <code>test</code> <code>-i</code> when dependencies are modified.
All builds should be as incremental as possible.
<a href="https://golang.org/issue/4719">#4719</a>.</p>
<p class=pp>Test results should be cached too:
if none of the inputs to a test have changed,
then usually there is no need to rerun the test.
This will make it very cheap to run “all tests” when little or nothing has changed.
<a href="https://golang.org/issue/11193">#11193</a>.</p>
<p class=pp>Work outside GOPATH should be supported nearly as well
as work inside GOPATH.
In particular, it should be possible to <code>git</code> <code>clone</code> a repo,
<code>cd</code> into it, and run <code>go</code> commands and have them work fine.
Package management only makes that more important:
youll need to be able to work on different versions of a package (say, v1 and v2)
without having entirely separate GOPATHs for them.
<a href="https://golang.org/issue/17271">#17271</a>.</p>
<h2><a name="corpus"></a>Code corpus</h2>
<p class=lp>I think it helped to have concrete examples from real projects
in the talk and article I prepared about codebase refactoring (see <a href="#alias">above</a>).
We&rsquo;ve also defined that <a href="https://golang.org/src/cmd/vet/README">additions to vet</a>
must target problems that happen frequently in real programs.
I&rsquo;d like to see that kind of analysis of actual practice—examining
the effects on and possible improvements to real programs—become a
standard way we discuss and evaluate changes to Go.</p>
<p class=pp>Right now there&rsquo;s not an agreed-upon representative corpus of code to use for
those analyses: everyone must first create their own, which is too much work.
I&rsquo;d like to put together a single, self-contained Git repo people can check out that
contains our official baseline corpus for those analyses.
A possible starting point could be the top 100 Go language repos
on GitHub by stars or forks or both.</p>
<h2><a name="vet"></a>Automatic vet</h2>
<p class=lp>The Go distribution ships with this powerful tool,
<a href="https://golang.org/cmd/vet/"><code>go</code> <code>vet</code></a>,
that points out correctness bugs.
We have a high bar for checks, so that when vet speaks, you should listen.
But everyone has to remember to run it.
It would be better if you didnt have to remember.
In particular, I think we could probably run vet
in parallel with the final compile and link of the test binary
during <code>go</code> <code>test</code> without slowing the compile-edit-test cycle at all.
If we can do that, and if we limit the enabled vet checks to a subset
that is essentially 100% accurate,
we can make passing vet a precondition for running a test at all.
Then developers dont need to remember to run <code>go</code> <code>vet</code>.
They run <code>go</code> <code>test</code>,
and once in a while vet speaks up with something important
and avoids a debugging session.
<a href="https://golang.org/issue/18084">#18084</a>,
<a href="https://golang.org/issue/18085">#18085</a>.</p>
<h2><a name="error"></a>Errors &amp; best practices</h2>
<p class=lp>Part of the intended contract for error reporting in Go is that functions
include relevant available context, including the operation being attempted
(such as the function name and its arguments).
For example, this program:</p>
<pre><code>err := os.Remove(&quot;/tmp/nonexist&quot;)
fmt.Println(err)
</code></pre>
<p class=lp>prints this output:</p>
<pre><code>remove /tmp/nonexist: no such file or directory
</code></pre>
<p class=lp>Not enough Go code adds context like <code>os.Remove</code> does. Too much code does only</p>
<pre><code>if err != nil {
return err
}
</code></pre>
<p class=lp>all the way up the call stack,
discarding useful context that should be reported
(like <code>remove</code> <code>/tmp/nonexist:</code> above).
I would like to try to understand whether our expectations
for including context are wrong, or if there is something
we can do to make it easier to write code that returns better errors.</p>
<p class=pp>There are also various discussions in the community about
agreed-upon interfaces for stripping error context.
I would like to try to understand when that makes sense and
whether we should adopt an official recommendation.</p>
<h2><a name="context"></a>Context &amp; best practices</h2>
<p class=lp>We added the new <a href="https://golang.org/pkg/context/">context package</a>
in Go 1.7 for holding request-scoped information like
<a href="https://blog.golang.org/context">timeouts, cancellation state, and credentials</a>.
An individual context is immutable (like an individual string or int):
it is only possible to derive a new, updated context and
pass that context explicitly further down the call stack or
(less commonly) back up to the caller.
The context is now carried through APIs such as
<a href="https://golang.org/pkg/database/sql">database/sql</a>
and
<a href="https://golang.org/pkg/net/http">net/http</a>,
mainly so that those can stop processing a request when the caller
is no longer interested in the result.
Timeout information is appropriate to carry in a context,
but—to use a <a href="https://golang.org/issue/18284">real example we removed</a>—database options
are not, because they are unlikely to apply equally well to all possible
database operations carried out during a request.
What about the current clock source, or logging sink?
Is either of those appropriate to store in a context?
I would like to try to understand and characterize the
criteria for what is and is not an appropriate use of context.</p>
<h2><a name="memory"></a>Memory model</h2>
<p class=lp>Gos <a href="https://golang.org/ref/mem">memory model</a> is intentionally low-key,
making few promises to users, compared to other languages.
In fact it starts by discouraging people from reading the rest of the document.
At the same time, it demands more of the compiler than other languages:
in particular, a race on an integer value is not sufficient license
for your program to misbehave in arbitrary ways.
But there are some complete gaps, in particular no mention of
the <a href="https://golang.org/pkg/sync/atomic/">sync/atomic package</a>.
I think the core compiler and runtime developers all agree
that the behavior of those atomics should be roughly the same as
C++ seqcst atomics or Java volatiles,
but we still need to write that down carefully in the memory model,
and probably also in a long blog post.
<a href="https://golang.org/issue/5045">#5045</a>,
<a href="https://golang.org/issue/7948">#7948</a>,
<a href="https://golang.org/issue/9442">#9442</a>.</p>
<h2><a name="immutability"></a>Immutability</h2>
<p class=lp>The <a href="https://golang.org/doc/articles/race_detector.html">race detector</a>
is one of Gos most loved features.
But not having races would be even better.
I would love it if there were some reasonable way to integrate
<a href="https://www.google.com/search?q=%22reference+immutability%22">reference immutability</a> into Go,
so that programmers can make clear, checked assertions about what can and cannot
be written and thereby eliminate certain races at compile time.
Go already has one immutable type, <code>string</code>; it would
be nice to retroactively define that
<code>string</code> is a named type (or type alias) for <code>immutable</code> <code>[]byte</code>.
I dont think that will happen this year,
but Id like to understand the solution space better.
Javari, Midori, Pony, and Rust have all staked out interesting points
in the solution space, and there are plenty of research papers
beyond those.</p>
<p class=pp>In the long-term, if we could statically eliminate the possibility of races,
that would eliminate the need for most of the memory model.
That may well be an impossible dream,
but again Id like to understand the solution space better.</p>
<h2><a name="generics"></a>Generics</h2>
<p class=lp>Nothing sparks more <a href="https://research.swtch.com/dogma">heated arguments</a>
among Go and non-Go developers than the question of whether Go should
have support for generics (or how many years ago that should have happened).
I dont believe the Go team has ever said “Go does not need generics.”
What we <em>have</em> said is that there are higher-priority issues facing Go.
For example, I believe that better support for package management
would have a much larger immediate positive impact on most Go developers
than adding generics.
But we do certainly understand that for a certain subset of Go use cases,
the lack of parametric polymorphism is a significant hindrance.</p>
<p class=pp>Personally, I would like to be able to write general channel-processing
functions like:</p>
<pre><code>// Join makes all messages received on the input channels
// available for receiving from the returned channel.
func Join(inputs ...&lt;-chan T) &lt;-chan T
// Dup duplicates messages received on c to both c1 and c2.
func Dup(c &lt;-chan T) (c1, c2 &lt;-chan T)
</code></pre>
<p class=lp>I would also like to be able to write
Go support for high-level data processing abstractions,
analogous to
<a href="https://research.google.com/pubs/archive/35650.pdf">FlumeJava</a> or
C#s <a href="https://en.wikipedia.org/wiki/Language_Integrated_Query">LINQ</a>,
in a way that catches type errors at compile time instead of at run time.
There are also any number of data structures or generic algorithms
that might be written,
but I personally find these broader applications more compelling.</p>
<p class=pp>Weve <a href="https://research.swtch.com/generic">struggled</a> off and on
<a href="https://golang.org/design/15292-generics">for years</a>
to find the right way to add generics to Go.
At least a few of the past proposals got hung up on trying to design
something that provided both general parametric polymorphism
(like <code>chan</code> <code>T</code>) and also a unification of <code>string</code> and <code>[]byte</code>.
If the latter is handled by parameterization over immutability,
as described in the previous section, then maybe that simplifies
the demands on a design for generics.</p>
<p class=pp>When I first started thinking about generics for Go in 2008,
the main examples to learn from were C#, Java, Haskell, and ML.
None of the approaches in those languages seemed like a
perfect fit for Go.
Today, there are newer attempts to learn from as well,
including Dart, Midori, Rust, and Swift.</p>
<p class=pp>Its been a few years since we ventured out and explored the design space.
It is probably time to look around again,
especially in light of the insight about mutability and
the additional examples set by newer languages.
I dont think generics will happen this year,
but Id like to be able to say I understand the solution space better.</p>
</div>
<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = "https://research.swtch.com/go2017";
this.page.identifier = "blog/go2017";
};
(function() {
var d = document, s = d.createElement('script');
s.src = '//swtch.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</div>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-3319603-2");
pageTracker._initData();
pageTracker._trackPageview();
</script>
</body>
</html>

View file

@ -0,0 +1,120 @@
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<book id="bk103">
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-11-17</publish_date>
<description>After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.</description>
</book>
<book id="bk104">
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-03-10</publish_date>
<description>In post-apocalypse England, the mysterious
agent known only as Oberon helps to create a new life
for the inhabitants of London. Sequel to Maeve
Ascendant.</description>
</book>
<book id="bk105">
<author>Corets, Eva</author>
<title>The Sundered Grail</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-09-10</publish_date>
<description>The two daughters of Maeve, half-sisters,
battle one another for control of England. Sequel to
Oberon's Legacy.</description>
</book>
<book id="bk106">
<author>Randall, Cynthia</author>
<title>Lover Birds</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-09-02</publish_date>
<description>When Carla meets Paul at an ornithology
conference, tempers fly as feathers get ruffled.</description>
</book>
<book id="bk107">
<author>Thurman, Paula</author>
<title>Splish Splash</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-11-02</publish_date>
<description>A deep sea diver finds true love twenty
thousand leagues beneath the sea.</description>
</book>
<book id="bk108">
<author>Knorr, Stefan</author>
<title>Creepy Crawlies</title>
<genre>Horror</genre>
<price>4.95</price>
<publish_date>2000-12-06</publish_date>
<description>An anthology of horror stories about roaches,
centipedes, scorpions and other insects.</description>
</book>
<book id="bk109">
<author>Kress, Peter</author>
<title>Paradox Lost</title>
<genre>Science Fiction</genre>
<price>6.95</price>
<publish_date>2000-11-02</publish_date>
<description>After an inadvertant trip through a Heisenberg
Uncertainty Device, James Salway discovers the problems
of being quantum.</description>
</book>
<book id="bk110">
<author>O'Brien, Tim</author>
<title>Microsoft .NET: The Programming Bible</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-09</publish_date>
<description>Microsoft's .NET initiative is explored in
detail in this deep programmer's reference.</description>
</book>
<book id="bk111">
<author>O'Brien, Tim</author>
<title>MSXML3: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-01</publish_date>
<description>The Microsoft MSXML3 parser is covered in
detail, with attention to XML DOM interfaces, XSLT processing,
SAX and more.</description>
</book>
<book id="bk112">
<author>Galos, Mike</author>
<title>Visual Studio 7: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>49.95</price>
<publish_date>2001-04-16</publish_date>
<description>Microsoft Visual Studio 7 is explored in depth,
looking at how Visual Basic, Visual C++, C#, and ASP+ are
integrated into a comprehensive development
environment.</description>
</book>
</catalog>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,42 @@
<?xml version="1.0"?>
<?xml-stylesheet href="catalog.xsl" type="text/xsl"?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<catalog>
<product description="Cardigan Sweater" product_image="cardigan.jpg">
<catalog_item gender="Men's">
<item_number>QWZ5671</item_number>
<price>39.95</price>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Large">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
</catalog_item>
<catalog_item gender="Women's">
<item_number>RRX9856</item_number>
<price>42.50</price>
<size description="Small">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
<size description="Large">
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
<size description="Extra Large">
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
</catalog_item>
</product>
</catalog>

View file

@ -0,0 +1,140 @@
// doT.js
// 2011-2014, Laura Doktorova, https://github.com/olado/doT
// Licensed under the MIT license.
(function() {
"use strict";
var doT = {
version: "1.0.3",
templateSettings: {
evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\s\S]+?)\}\}/g,
use: /\{\{#([\s\S]+?)\}\}/g,
useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
defineParams:/^\s*([\w$]+):([\s\S]+)/,
conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
varname: "it",
strip: true,
append: true,
selfcontained: false,
doNotSkipEncoded: false
},
template: undefined, //fn, compile template
compile: undefined //fn, for express
}, _globals;
doT.encodeHTMLSource = function(doNotSkipEncoded) {
var encodeHTMLRules = { "&": "&#38;", "<": "&#60;", ">": "&#62;", '"': "&#34;", "'": "&#39;", "/": "&#47;" },
matchHTML = doNotSkipEncoded ? /[&<>\/]/g : /&(?!#?\w+;)|<|>|\//g;
return function(code) {
return code ? code.toString().replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : "";
};
};
_globals = (function(){ return this || (0,eval)("this"); }());
if (typeof module !== "undefined" && module.exports) {
module.exports = doT;
} else if (typeof define === "function" && define.amd) {
define(function(){return doT;});
} else {
_globals.doT = doT;
}
var startend = {
append: { start: "'+(", end: ")+'", startencode: "'+encodeHTML(" },
split: { start: "';out+=(", end: ");out+='", startencode: "';out+=encodeHTML(" }
}, skip = /$^/;
function resolveDefs(c, block, def) {
return ((typeof block === "string") ? block : block.toString())
.replace(c.define || skip, function(m, code, assign, value) {
if (code.indexOf("def.") === 0) {
code = code.substring(4);
}
if (!(code in def)) {
if (assign === ":") {
if (c.defineParams) value.replace(c.defineParams, function(m, param, v) {
def[code] = {arg: param, text: v};
});
if (!(code in def)) def[code]= value;
} else {
new Function("def", "def['"+code+"']=" + value)(def);
}
}
return "";
})
.replace(c.use || skip, function(m, code) {
if (c.useParams) code = code.replace(c.useParams, function(m, s, d, param) {
if (def[d] && def[d].arg && param) {
var rw = (d+":"+param).replace(/'|\\/g, "_");
def.__exp = def.__exp || {};
def.__exp[rw] = def[d].text.replace(new RegExp("(^|[^\\w$])" + def[d].arg + "([^\\w$])", "g"), "$1" + param + "$2");
return s + "def.__exp['"+rw+"']";
}
});
var v = new Function("def", "return " + code)(def);
return v ? resolveDefs(c, v, def) : v;
});
}
function unescape(code) {
return code.replace(/\\('|\\)/g, "$1").replace(/[\r\t\n]/g, " ");
}
doT.template = function(tmpl, c, def) {
c = c || doT.templateSettings;
var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv,
str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;
str = ("var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ")
.replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""): str)
.replace(/'|\\/g, "\\$&")
.replace(c.interpolate || skip, function(m, code) {
return cse.start + unescape(code) + cse.end;
})
.replace(c.encode || skip, function(m, code) {
needhtmlencode = true;
return cse.startencode + unescape(code) + cse.end;
})
.replace(c.conditional || skip, function(m, elsecase, code) {
return elsecase ?
(code ? "';}else if(" + unescape(code) + "){out+='" : "';}else{out+='") :
(code ? "';if(" + unescape(code) + "){out+='" : "';}out+='");
})
.replace(c.iterate || skip, function(m, iterate, vname, iname) {
if (!iterate) return "';} } out+='";
sid+=1; indv=iname || "i"+sid; iterate=unescape(iterate);
return "';var arr"+sid+"="+iterate+";if(arr"+sid+"){var "+vname+","+indv+"=-1,l"+sid+"=arr"+sid+".length-1;while("+indv+"<l"+sid+"){"
+vname+"=arr"+sid+"["+indv+"+=1];out+='";
})
.replace(c.evaluate || skip, function(m, code) {
return "';" + unescape(code) + "out+='";
})
+ "';return out;")
.replace(/\n/g, "\\n").replace(/\t/g, '\\t').replace(/\r/g, "\\r")
.replace(/(\s|;|\}|^|\{)out\+='';/g, '$1').replace(/\+''/g, "");
//.replace(/(\s|;|\}|^|\{)out\+=''\+/g,'$1out+=');
if (needhtmlencode) {
if (!c.selfcontained && _globals && !_globals._encodeHTML) _globals._encodeHTML = doT.encodeHTMLSource(c.doNotSkipEncoded);
str = "var encodeHTML = typeof _encodeHTML !== 'undefined' ? _encodeHTML : ("
+ doT.encodeHTMLSource.toString() + "(" + (c.doNotSkipEncoded || '') + "));"
+ str;
}
try {
return new Function(c.varname, str);
} catch (e) {
if (typeof console !== "undefined") console.log("Could not create a template function: " + str);
throw e;
}
};
doT.compile = function(tmpl, def) {
return doT.template(tmpl, null, def);
};
}());

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="401.98px" height="559.472px" viewBox="0 0 401.98 559.472" enable-background="new 0 0 401.98 559.472"
xml:space="preserve">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#F6D2A2" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M10.634,300.493c0.764,15.751,16.499,8.463,23.626,3.539c6.765-4.675,8.743-0.789,9.337-10.015
c0.389-6.064,1.088-12.128,0.744-18.216c-10.23-0.927-21.357,1.509-29.744,7.602C10.277,286.542,2.177,296.561,10.634,300.493"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#C6B198" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M10.634,300.493c2.29-0.852,4.717-1.457,6.271-3.528"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#6AD7E5" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M46.997,112.853C-13.3,95.897,31.536,19.189,79.956,50.74L46.997,112.853z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#6AD7E5" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M314.895,44.984c47.727-33.523,90.856,42.111,35.388,61.141L314.895,44.984z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#F6D2A2" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M325.161,494.343c12.123,7.501,34.282,30.182,16.096,41.18c-17.474,15.999-27.254-17.561-42.591-22.211
C305.271,504.342,313.643,496.163,325.161,494.343z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M341.257,535.522c-2.696-5.361-3.601-11.618-8.102-15.939"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#F6D2A2" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M108.579,519.975c-14.229,2.202-22.238,15.039-34.1,21.558c-11.178,6.665-15.454-2.134-16.461-3.92
c-1.752-0.799-1.605,0.744-4.309-1.979c-10.362-16.354,10.797-28.308,21.815-36.432C90.87,496.1,100.487,509.404,108.579,519.975z"
/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M58.019,537.612c0.542-6.233,5.484-10.407,7.838-15.677"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M49.513,91.667c-7.955-4.208-13.791-9.923-8.925-19.124
c4.505-8.518,12.874-7.593,20.83-3.385L49.513,91.667z"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M337.716,83.667c7.955-4.208,13.791-9.923,8.925-19.124
c-4.505-8.518-12.874-7.593-20.83-3.385L337.716,83.667z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#F6D2A2" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M392.475,298.493c-0.764,15.751-16.499,8.463-23.626,3.539c-6.765-4.675-8.743-0.789-9.337-10.015
c-0.389-6.064-1.088-12.128-0.744-18.216c10.23-0.927,21.357,1.509,29.744,7.602C392.831,284.542,400.932,294.561,392.475,298.493"
/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#C6B198" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M392.475,298.493c-2.29-0.852-4.717-1.457-6.271-3.528"/>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#6AD7E5" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M195.512,13.124c60.365,0,116.953,8.633,146.452,66.629c26.478,65.006,17.062,135.104,21.1,203.806
c3.468,58.992,11.157,127.145-16.21,181.812c-28.79,57.514-100.73,71.982-160,69.863c-46.555-1.666-102.794-16.854-129.069-59.389
c-30.826-49.9-16.232-124.098-13.993-179.622c2.652-65.771-17.815-131.742,3.792-196.101
C69.999,33.359,130.451,18.271,195.512,13.124"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" stroke="#000000" stroke-width="2.9081" stroke-linecap="round" d="
M206.169,94.16c10.838,63.003,113.822,46.345,99.03-17.197C291.935,19.983,202.567,35.755,206.169,94.16"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" stroke="#000000" stroke-width="2.8214" stroke-linecap="round" d="
M83.103,104.35c14.047,54.85,101.864,40.807,98.554-14.213C177.691,24.242,69.673,36.957,83.103,104.35"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M218.594,169.762c0.046,8.191,1.861,17.387,0.312,26.101c-2.091,3.952-6.193,4.37-9.729,5.967c-4.89-0.767-9.002-3.978-10.963-8.552
c-1.255-9.946,0.468-19.576,0.785-29.526L218.594,169.762z"/>
<g>
<ellipse fill-rule="evenodd" clip-rule="evenodd" cx="107.324" cy="95.404" rx="14.829" ry="16.062"/>
<ellipse fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" cx="114.069" cy="99.029" rx="3.496" ry="4.082"/>
</g>
<g>
<ellipse fill-rule="evenodd" clip-rule="evenodd" cx="231.571" cy="91.404" rx="14.582" ry="16.062"/>
<ellipse fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" cx="238.204" cy="95.029" rx="3.438" ry="4.082"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" stroke="#000000" stroke-width="3" stroke-linecap="round" d="
M176.217,168.87c-6.47,15.68,3.608,47.035,21.163,23.908c-1.255-9.946,0.468-19.576,0.785-29.526L176.217,168.87z"/>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#F6D2A2" stroke="#231F20" stroke-width="3" stroke-linecap="round" d="
M178.431,138.673c-12.059,1.028-21.916,15.366-15.646,26.709c8.303,15.024,26.836-1.329,38.379,0.203
c13.285,0.272,24.17,14.047,34.84,2.49c11.867-12.854-5.109-25.373-18.377-30.97L178.431,138.673z"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M176.913,138.045c-0.893-20.891,38.938-23.503,43.642-6.016
C225.247,149.475,178.874,153.527,176.913,138.045C175.348,125.682,176.913,138.045,176.913,138.045z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,52 @@
[{
"created_at": "Thu Jun 22 21:00:00 +0000 2017",
"id": 877994604561387500,
"id_str": "877994604561387520",
"text": "Creating a Grocery List Manager Using Angular, Part 1: Add &amp; Display Items https://t.co/xFox78juL1 #Angular",
"truncated": false,
"entities": {
"hashtags": [{
"text": "Angular",
"indices": [103, 111]
}],
"symbols": [],
"user_mentions": [],
"urls": [{
"url": "https://t.co/xFox78juL1",
"expanded_url": "http://buff.ly/2sr60pf",
"display_url": "buff.ly/2sr60pf",
"indices": [79, 102]
}]
},
"source": "<a href=\"http://bufferapp.com\" rel=\"nofollow\">Buffer</a>",
"user": {
"id": 772682964,
"id_str": "772682964",
"name": "SitePoint JavaScript",
"screen_name": "SitePointJS",
"location": "Melbourne, Australia",
"description": "Keep up with JavaScript tutorials, tips, tricks and articles at SitePoint.",
"url": "http://t.co/cCH13gqeUK",
"entities": {
"url": {
"urls": [{
"url": "http://t.co/cCH13gqeUK",
"expanded_url": "http://sitepoint.com/javascript",
"display_url": "sitepoint.com/javascript",
"indices": [0, 22]
}]
},
"description": {
"urls": []
}
},
"protected": false,
"followers_count": 2145,
"friends_count": 18,
"listed_count": 328,
"created_at": "Wed Aug 22 02:06:33 +0000 2012",
"favourites_count": 57,
"utc_offset": 43200,
"time_zone": "Wellington"
}
}]

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 999 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,33 @@
package benchmarks
import (
"testing"
"github.com/tdewolff/minify/svg"
)
var svgSamples = []string{
"sample_arctic.svg",
"sample_gopher.svg",
"sample_usa.svg",
}
func init() {
for _, sample := range svgSamples {
load(sample)
}
}
func BenchmarkSVG(b *testing.B) {
for _, sample := range svgSamples {
b.Run(sample, func(b *testing.B) {
b.SetBytes(int64(r[sample].Len()))
for i := 0; i < b.N; i++ {
r[sample].Reset()
w[sample].Reset()
svg.Minify(m, w[sample], r[sample], nil)
}
})
}
}

View file

@ -0,0 +1,33 @@
package benchmarks
import (
"testing"
"github.com/tdewolff/minify/xml"
)
var xmlSamples = []string{
"sample_books.xml",
"sample_catalog.xml",
"sample_omg.xml",
}
func init() {
for _, sample := range xmlSamples {
load(sample)
}
}
func BenchmarkXML(b *testing.B) {
for _, sample := range xmlSamples {
b.Run(sample, func(b *testing.B) {
b.SetBytes(int64(r[sample].Len()))
for i := 0; i < b.N; i++ {
r[sample].Reset()
w[sample].Reset()
xml.Minify(m, w[sample], r[sample], nil)
}
})
}
}