*: glide for vendoring

This commit is contained in:
Gyu-Ho Lee 2016-05-29 11:57:18 -07:00
parent ade19344a1
commit 747d55fe19
5766 changed files with 3354460 additions and 2503 deletions

448
Godeps/Godeps.json generated
View File

@ -1,448 +0,0 @@
{
"ImportPath": "github.com/coreos/dbtester",
"GoVersion": "go1.6",
"GodepVersion": "v71",
"Deps": [
{
"ImportPath": "bitbucket.org/zombiezen/gopdf/pdf",
"Comment": "go.weekly.2012-02-22-18",
"Rev": "'1c63dc69751bc45441c2ce1f56b631c55294b4d5'"
},
{
"ImportPath": "github.com/Sirupsen/logrus",
"Comment": "v0.10.0-18-g6d9ae30",
"Rev": "6d9ae300aaf85d6acd2e5424081c7fcddb21dab8"
},
{
"ImportPath": "github.com/ajstarks/svgo",
"Comment": "go.weekly.2012-01-27-130-g672fe54",
"Rev": "672fe547df4e49efc6db67a74391368bcb149b37"
},
{
"ImportPath": "github.com/cheggaaa/pb",
"Comment": "v1.0.3-1-gc1f48d5",
"Rev": "c1f48d5ce4f292dfb775ef52aaedd15be323510d"
},
{
"ImportPath": "github.com/coreos/etcd/auth/authpb",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/client",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/clientv3",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/mvcc/mvccpb",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/pkg/pathutil",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/pkg/tlsutil",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/coreos/etcd/pkg/types",
"Comment": "v3.0.0-beta.0-234-g20fc3e9",
"Rev": "20fc3e968fc9f742a9eb32f8eb44e70a822e9ae4"
},
{
"ImportPath": "github.com/cpuguy83/go-md2man/md2man",
"Comment": "v1.0.4",
"Rev": "71acacd42f85e5e82f70a55327789582a5200a90"
},
{
"ImportPath": "github.com/dustin/go-humanize",
"Rev": "8929fe90cee4b2cb9deb468b51fb34eba64d1bf0"
},
{
"ImportPath": "github.com/fatih/color",
"Comment": "v0.1-17-g533cd7f",
"Rev": "533cd7fd8a85905f67a1753afb4deddc85ea174f"
},
{
"ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
},
{
"ImportPath": "github.com/gogo/protobuf/gogoproto",
"Comment": "v0.2-13-gc3995ae",
"Rev": "c3995ae437bb78d1189f4f147dfe5f87ad3596e4"
},
{
"ImportPath": "github.com/gogo/protobuf/proto",
"Comment": "v0.2-13-gc3995ae",
"Rev": "c3995ae437bb78d1189f4f147dfe5f87ad3596e4"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
"Comment": "v0.2-13-gc3995ae",
"Rev": "c3995ae437bb78d1189f4f147dfe5f87ad3596e4"
},
{
"ImportPath": "github.com/golang/freetype",
"Comment": "release-130-ga31d014",
"Rev": "a31d0146dac6f09aa27eda40995aeca7d7adc293"
},
{
"ImportPath": "github.com/golang/freetype/raster",
"Comment": "release-130-ga31d014",
"Rev": "a31d0146dac6f09aa27eda40995aeca7d7adc293"
},
{
"ImportPath": "github.com/golang/freetype/truetype",
"Comment": "release-130-ga31d014",
"Rev": "a31d0146dac6f09aa27eda40995aeca7d7adc293"
},
{
"ImportPath": "github.com/golang/protobuf/proto",
"Rev": "6aaa8d47701fa6cf07e914ec01fde3d4a1fe79c3"
},
{
"ImportPath": "github.com/gonum/floats",
"Rev": "856ee8119ad91596c5394fa0a5c0470b6f16e676"
},
{
"ImportPath": "github.com/gonum/internal/asm",
"Rev": "b5df70d76416ba52f34f94cb3bfbab2a3d958e4e"
},
{
"ImportPath": "github.com/gonum/plot",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/palette",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/plotter",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/plotutil",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/vg",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/vg/draw",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/vg/fonts",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/vg/vgeps",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/vg/vgimg",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/vg/vgpdf",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gonum/plot/vg/vgsvg",
"Rev": "754210960d0ffa304547dcfeafac8583698d0e1a"
},
{
"ImportPath": "github.com/gyuho/dataframe",
"Rev": "573cd728a011e5473510a6a1df0f39023c305e04"
},
{
"ImportPath": "github.com/gyuho/psn/ps",
"Rev": "88c9e2a3a8857e3be57fe67694db47bb23f29c31"
},
{
"ImportPath": "github.com/hashicorp/consul/api",
"Comment": "v0.6.4-341-g22938ab",
"Rev": "22938ab8b3ca069e490a4897a8ec13308ac61605"
},
{
"ImportPath": "github.com/hashicorp/go-cleanhttp",
"Rev": "ad28ea4487f05916463e2423a55166280e8254b5"
},
{
"ImportPath": "github.com/hashicorp/serf/coordinate",
"Comment": "v0.7.0-62-gb60a6d9",
"Rev": "b60a6d928fe726a588f79a1d500582507f9d79de"
},
{
"ImportPath": "github.com/inconshreveable/mousetrap",
"Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
},
{
"ImportPath": "github.com/llgcode/draw2d",
"Comment": "v1-71-g5e675a3",
"Rev": "5e675a3055a6f81f9b014b1dc2d5bb5fb8890618"
},
{
"ImportPath": "github.com/llgcode/draw2d/draw2dbase",
"Comment": "v1-71-g5e675a3",
"Rev": "5e675a3055a6f81f9b014b1dc2d5bb5fb8890618"
},
{
"ImportPath": "github.com/llgcode/draw2d/draw2dimg",
"Comment": "v1-71-g5e675a3",
"Rev": "5e675a3055a6f81f9b014b1dc2d5bb5fb8890618"
},
{
"ImportPath": "github.com/mattn/go-colorable",
"Comment": "v0.0.4-1-ge8a10dd",
"Rev": "e8a10ddc7d2a7fe255f6fd7f501070a4cb62c183"
},
{
"ImportPath": "github.com/mattn/go-isatty",
"Rev": "56b76bdf51f7708750eac80fa38b952bb9f32639"
},
{
"ImportPath": "github.com/mattn/go-runewidth",
"Comment": "v0.0.1",
"Rev": "d6bea18f789704b5f83375793155289da36a3c7f"
},
{
"ImportPath": "github.com/olekukonko/tablewriter",
"Rev": "cca8bbc0798408af109aaaa239cbd2634846b340"
},
{
"ImportPath": "github.com/russross/blackfriday",
"Comment": "v1.4-2-g300106c",
"Rev": "300106c228d52c8941d4b3de6054a6062a86dda3"
},
{
"ImportPath": "github.com/samuel/go-zookeeper/zk",
"Rev": "6eb1b09c6ce23f305f4c81bf748b22fbc6f3f9e9"
},
{
"ImportPath": "github.com/shurcooL/sanitized_anchor_name",
"Rev": "10ef21a441db47d8b13ebcc5fd2310f636973c77"
},
{
"ImportPath": "github.com/spf13/cobra",
"Rev": "1c44ec8d3f1552cac48999f9306da23c4d8a288b"
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "08b1a584251b5b62f458943640fc8ebd4d50aaa5"
},
{
"ImportPath": "github.com/ugorji/go/codec",
"Rev": "f1f1a805ed361a0e078bb537e4ea78cd37dcf065"
},
{
"ImportPath": "golang.org/x/image/draw",
"Rev": "f551d3a6b7fc11df315ad9e18b404280680f8bec"
},
{
"ImportPath": "golang.org/x/image/font",
"Rev": "f551d3a6b7fc11df315ad9e18b404280680f8bec"
},
{
"ImportPath": "golang.org/x/image/math/f64",
"Rev": "f551d3a6b7fc11df315ad9e18b404280680f8bec"
},
{
"ImportPath": "golang.org/x/image/math/fixed",
"Rev": "f551d3a6b7fc11df315ad9e18b404280680f8bec"
},
{
"ImportPath": "golang.org/x/image/tiff",
"Rev": "f551d3a6b7fc11df315ad9e18b404280680f8bec"
},
{
"ImportPath": "golang.org/x/image/tiff/lzw",
"Rev": "f551d3a6b7fc11df315ad9e18b404280680f8bec"
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
},
{
"ImportPath": "golang.org/x/net/context/ctxhttp",
"Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
},
{
"ImportPath": "golang.org/x/net/internal/timeseries",
"Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
},
{
"ImportPath": "golang.org/x/net/trace",
"Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
},
{
"ImportPath": "golang.org/x/oauth2",
"Rev": "c406a4cc4ba462e5dc2f16225c5bd9488f9cbe10"
},
{
"ImportPath": "golang.org/x/oauth2/google",
"Rev": "c406a4cc4ba462e5dc2f16225c5bd9488f9cbe10"
},
{
"ImportPath": "golang.org/x/oauth2/internal",
"Rev": "c406a4cc4ba462e5dc2f16225c5bd9488f9cbe10"
},
{
"ImportPath": "golang.org/x/oauth2/jws",
"Rev": "c406a4cc4ba462e5dc2f16225c5bd9488f9cbe10"
},
{
"ImportPath": "golang.org/x/oauth2/jwt",
"Rev": "c406a4cc4ba462e5dc2f16225c5bd9488f9cbe10"
},
{
"ImportPath": "golang.org/x/sys/unix",
"Rev": "9c60d1c508f5134d1ca726b4641db998f2523357"
},
{
"ImportPath": "golang.org/x/time/rate",
"Rev": "a4bde12657593d5e90d0533a3e4fd95e635124cb"
},
{
"ImportPath": "google.golang.org/api/gensupport",
"Rev": "aa89374d6f4a7f9ab85dcb3b01c95d2d3bd7f10a"
},
{
"ImportPath": "google.golang.org/api/googleapi",
"Rev": "aa89374d6f4a7f9ab85dcb3b01c95d2d3bd7f10a"
},
{
"ImportPath": "google.golang.org/api/googleapi/internal/uritemplates",
"Rev": "aa89374d6f4a7f9ab85dcb3b01c95d2d3bd7f10a"
},
{
"ImportPath": "google.golang.org/api/storage/v1",
"Rev": "aa89374d6f4a7f9ab85dcb3b01c95d2d3bd7f10a"
},
{
"ImportPath": "google.golang.org/appengine",
"Rev": "7f59a8c76b8594d06044bfe0bcbe475cb2020482"
},
{
"ImportPath": "google.golang.org/appengine/internal",
"Rev": "7f59a8c76b8594d06044bfe0bcbe475cb2020482"
},
{
"ImportPath": "google.golang.org/appengine/internal/app_identity",
"Rev": "7f59a8c76b8594d06044bfe0bcbe475cb2020482"
},
{
"ImportPath": "google.golang.org/appengine/internal/base",
"Rev": "7f59a8c76b8594d06044bfe0bcbe475cb2020482"
},
{
"ImportPath": "google.golang.org/appengine/internal/datastore",
"Rev": "7f59a8c76b8594d06044bfe0bcbe475cb2020482"
},
{
"ImportPath": "google.golang.org/appengine/internal/modules",
"Rev": "7f59a8c76b8594d06044bfe0bcbe475cb2020482"
},
{
"ImportPath": "google.golang.org/appengine/internal/remote_api",
"Rev": "7f59a8c76b8594d06044bfe0bcbe475cb2020482"
},
{
"ImportPath": "google.golang.org/cloud",
"Rev": "4da660f59adf463f364fca03a6f8422758101a84"
},
{
"ImportPath": "google.golang.org/cloud/compute/metadata",
"Rev": "4da660f59adf463f364fca03a6f8422758101a84"
},
{
"ImportPath": "google.golang.org/cloud/internal",
"Rev": "4da660f59adf463f364fca03a6f8422758101a84"
},
{
"ImportPath": "google.golang.org/cloud/internal/opts",
"Rev": "4da660f59adf463f364fca03a6f8422758101a84"
},
{
"ImportPath": "google.golang.org/cloud/internal/transport",
"Rev": "4da660f59adf463f364fca03a6f8422758101a84"
},
{
"ImportPath": "google.golang.org/cloud/storage",
"Rev": "4da660f59adf463f364fca03a6f8422758101a84"
},
{
"ImportPath": "google.golang.org/grpc",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/codes",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/credentials",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/credentials/oauth",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/grpclog",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/internal",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/metadata",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/naming",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/peer",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "google.golang.org/grpc/transport",
"Rev": "15e50a43c679d14f4f83a83d3177864cfd751cdd"
},
{
"ImportPath": "gopkg.in/yaml.v2",
"Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
}
]
}

187
glide.lock generated Normal file
View File

@ -0,0 +1,187 @@
hash: 5d55e960cf32753438f359a810a38dc01a952faa491ec376f51cb6ea2e47ef0d
updated: 2016-05-29T11:48:49.670861703-07:00
imports:
- name: bitbucket.org/zombiezen/gopdf
version: 1c63dc69751bc45441c2ce1f56b631c55294b4d5
subpackages:
- pdf
- name: github.com/ajstarks/svgo
version: 672fe547df4e49efc6db67a74391368bcb149b37
- name: github.com/cheggaaa/pb
version: c1f48d5ce4f292dfb775ef52aaedd15be323510d
- name: github.com/cloudfoundry-incubator/candiedyaml
version: 99c3df83b51532e3615f851d8c2dbb638f5313bf
- name: github.com/coreos/etcd
version: 84e7fa149e37272899e495a357c580fc5feddec9
subpackages:
- client
- clientv3
- pkg/pathutil
- pkg/types
- auth/authpb
- etcdserver/api/v3rpc/rpctypes
- etcdserver/etcdserverpb
- mvcc/mvccpb
- pkg/tlsutil
- name: github.com/dustin/go-humanize
version: 9436b7a0ebd4b3a35fb30aa244f8f85244088bfa
- name: github.com/fatih/color
version: 533cd7fd8a85905f67a1753afb4deddc85ea174f
- name: github.com/ghodss/yaml
version: e8e0db9016175449df0e9c4b6e6995a9433a395c
- name: github.com/gogo/protobuf
version: c18eea6ad611eecf94a9ba38471f59706199409e
subpackages:
- gogoproto
- proto
- protoc-gen-gogo/descriptor
- name: github.com/golang/freetype
version: a31d0146dac6f09aa27eda40995aeca7d7adc293
subpackages:
- truetype
- raster
- name: github.com/golang/protobuf
version: 9e6977f30c91c78396e719e164e57f9287fff42c
subpackages:
- proto
- name: github.com/gonum/floats
version: 856ee8119ad91596c5394fa0a5c0470b6f16e676
- name: github.com/gonum/internal
version: b5df70d76416ba52f34f94cb3bfbab2a3d958e4e
subpackages:
- asm
- name: github.com/gonum/plot
version: 15005ec89f739168a773c3571bc1b852eb94bf8b
subpackages:
- plotter
- plotutil
- vg
- vg/draw
- palette
- vg/fonts
- vg/vgeps
- vg/vgimg
- vg/vgpdf
- vg/vgsvg
- name: github.com/gyuho/dataframe
version: 573cd728a011e5473510a6a1df0f39023c305e04
- name: github.com/gyuho/psn
version: 88c9e2a3a8857e3be57fe67694db47bb23f29c31
subpackages:
- ps
- name: github.com/hashicorp/consul
version: b43f900766ad92eebbd5a8f931fe0fe244f9969d
subpackages:
- api
- name: github.com/hashicorp/go-cleanhttp
version: 875fb671b3ddc66f8e2f0acc33829c8cb989a38d
- name: github.com/hashicorp/serf
version: e4ec8cc423bbe20d26584b96efbeb9102e16d05f
subpackages:
- coordinate
- serf
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/llgcode/draw2d
version: 5e675a3055a6f81f9b014b1dc2d5bb5fb8890618
subpackages:
- draw2dimg
- draw2dbase
- name: github.com/mattn/go-colorable
version: 9cbef7c35391cca05f15f8181dc0b18bc9736dbb
repo: https://github.com/mattn/go-colorable
- name: github.com/mattn/go-isatty
version: 56b76bdf51f7708750eac80fa38b952bb9f32639
- name: github.com/mattn/go-runewidth
version: d6bea18f789704b5f83375793155289da36a3c7f
- name: github.com/olekukonko/tablewriter
version: 8d0265a48283795806b872b4728c67bf5c777f20
- name: github.com/samuel/go-zookeeper
version: 6eb1b09c6ce23f305f4c81bf748b22fbc6f3f9e9
subpackages:
- zk
- name: github.com/Sirupsen/logrus
version: 6d9ae300aaf85d6acd2e5424081c7fcddb21dab8
- name: github.com/spf13/cobra
version: f368244301305f414206f889b1735a54cfc8bde8
- name: github.com/spf13/pflag
version: cb88ea77998c3f024757528e3305022ab50b43be
- name: github.com/ugorji/go
version: a396ed22fc049df733440d90efe17475e3929ccb
subpackages:
- codec
- name: golang.org/x/image
version: 97680175a5267bb8b31f1923e7a66df98013b11a
subpackages:
- math/fixed
- font
- tiff
- draw
- math/f64
- tiff/lzw
- name: golang.org/x/net
version: 30db96677b74e24b967e23f911eb3364fc61a011
subpackages:
- context
- http2
- trace
- http2/hpack
- lex/httplex
- internal/timeseries
- context/ctxhttp
- name: golang.org/x/oauth2
version: c406a4cc4ba462e5dc2f16225c5bd9488f9cbe10
subpackages:
- google
- jwt
- internal
- jws
- name: golang.org/x/sys
version: d4feaf1a7e61e1d9e79e6c4e76c6349e9cab0a03
subpackages:
- unix
- name: golang.org/x/time
version: a4bde12657593d5e90d0533a3e4fd95e635124cb
subpackages:
- rate
- name: google.golang.org/api
version: aa89374d6f4a7f9ab85dcb3b01c95d2d3bd7f10a
subpackages:
- googleapi
- storage/v1
- googleapi/internal/uritemplates
- gensupport
- name: google.golang.org/appengine
version: 7f59a8c76b8594d06044bfe0bcbe475cb2020482
subpackages:
- urlfetch
- internal
- internal/app_identity
- internal/modules
- internal/urlfetch
- internal/base
- internal/datastore
- internal/remote_api
- name: google.golang.org/cloud
version: 4da660f59adf463f364fca03a6f8422758101a84
subpackages:
- storage
- compute/metadata
- internal
- internal/opts
- internal/transport
- name: google.golang.org/grpc
version: 8213ee577a465c1f314d85748fb29e4eeed59baf
subpackages:
- codes
- credentials
- grpclog
- internal
- metadata
- naming
- transport
- peer
- credentials/oauth
- name: gopkg.in/yaml.v2
version: a83829b6f1293c91addabc89d0571c246397bbf4
devImports: []

43
glide.yaml Normal file
View File

@ -0,0 +1,43 @@
package: github.com/coreos/dbtester
import:
- package: github.com/Sirupsen/logrus
- package: github.com/cheggaaa/pb
- package: github.com/coreos/etcd
subpackages:
- client
- clientv3
- package: github.com/dustin/go-humanize
- package: github.com/gogo/protobuf
subpackages:
- gogoproto
- package: github.com/golang/protobuf
subpackages:
- proto
- package: github.com/gonum/plot
subpackages:
- plotter
- plotutil
- vg
- package: github.com/gyuho/dataframe
- package: github.com/gyuho/psn
subpackages:
- ps
- package: github.com/hashicorp/consul
subpackages:
- api
- package: github.com/samuel/go-zookeeper
subpackages:
- zk
- package: github.com/spf13/cobra
- package: golang.org/x/net
subpackages:
- context
- package: golang.org/x/oauth2
subpackages:
- google
- jwt
- package: google.golang.org/cloud
subpackages:
- storage
- package: google.golang.org/grpc
- package: gopkg.in/yaml.v2

BIN
vendor/bitbucket.org/zombiezen/gopdf/.hg/00changelog.i generated vendored Normal file

Binary file not shown.

1
vendor/bitbucket.org/zombiezen/gopdf/.hg/branch generated vendored Normal file
View File

@ -0,0 +1 @@
default

View File

@ -0,0 +1,4 @@
1c63dc69751bc45441c2ce1f56b631c55294b4d5 100
1c63dc69751bc45441c2ce1f56b631c55294b4d5 default
d9caad8ab6e8668628f6559454dd13ce4695c7dc go.r60
4cc534bed36a0bbdba404e3fe481de5569161222 go.weekly.2011-11-01

10
vendor/bitbucket.org/zombiezen/gopdf/.hg/cache/tags generated vendored Normal file
View File

@ -0,0 +1,10 @@
100 1c63dc69751bc45441c2ce1f56b631c55294b4d5 7931f9f2de065e6924fd82c20c21f6919051a4af
61f2f88960fd453c40d1655472cb201a6917f226 go.weekly.2011-12-22
641e2e5bd59c136d6e78cba91839aa3f96f4430a go.weekly.2012-02-22
678fd0e19f2de643e44e52a131920733d75d400d go.weekly.2011-11-01
678fd0e19f2de643e44e52a131920733d75d400d go.weekly.2011-11-01
0000000000000000000000000000000000000000 go.weekly.2011-11-01
d21733eb8d7dac896bbc3fb4f7a31cbd6edc4f22 go.weekly.2011-11-02
d21733eb8d7dac896bbc3fb4f7a31cbd6edc4f22 go.weekly.2011-11-02
d53f28b5260733b2d4d865c8dd00bfd451fbd373 go.weekly.2011-11-02

BIN
vendor/bitbucket.org/zombiezen/gopdf/.hg/dirstate generated vendored Normal file

Binary file not shown.

2
vendor/bitbucket.org/zombiezen/gopdf/.hg/hgrc generated vendored Normal file
View File

@ -0,0 +1,2 @@
[paths]
default = https://bitbucket.org/zombiezen/gopdf

4
vendor/bitbucket.org/zombiezen/gopdf/.hg/requires generated vendored Normal file
View File

@ -0,0 +1,4 @@
dotencode
fncache
revlogv1
store

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

33
vendor/bitbucket.org/zombiezen/gopdf/.hg/store/fncache generated vendored Normal file
View File

@ -0,0 +1,33 @@
data/AUTHORS.i
data/CONTRIBUTORS.i
data/pdf/doc.go.i
data/pdf/pdf.go.i
data/buildmetrics.bash.i
data/pdf/image_test.go.i
data/pdf/canvas.go.i
data/pdf/marshal_test.go.i
data/pdf/testdata/suzanne.bmp.i
data/pdf/stream.go.i
data/pdf/objects.go.i
data/pdf/testdata/suzanne.jpg.i
data/pdf/encode_test.go.i
data/pdf/testdata/suzanne.png.i
data/LICENSE.i
data/pdf/stream_test.go.i
data/pdf/Makefile.i
data/pdf/encode.go.i
data/pdf/testdata/suzanne.png.pdf.i
data/.hgignore.i
data/pdf/text_test.go.i
data/pdf/marshal.go.i
data/pdf/canvas_test.go.i
data/pdf/testdata/suzanne.jpg.pdf.i
data/pdf/image.go.i
data/pdf/text.go.i
data/generate-image-testdata/main.go.i
data/pdf/testdata/suzanne.jpg.pdf.d
data/.hgtags.i
data/pdf/pdf_test.go.i
data/README.rst.i
data/pdf/testdata/suzanne.bmp.pdf.i
data/pdf/metrics.go.i

View File

BIN
vendor/bitbucket.org/zombiezen/gopdf/.hg/store/undo generated vendored Normal file

Binary file not shown.

View File

View File

1
vendor/bitbucket.org/zombiezen/gopdf/.hg/undo.branch generated vendored Normal file
View File

@ -0,0 +1 @@
default

3
vendor/bitbucket.org/zombiezen/gopdf/.hg/undo.desc generated vendored Normal file
View File

@ -0,0 +1,3 @@
0
pull
https://bitbucket.org/zombiezen/gopdf

View File

11
vendor/bitbucket.org/zombiezen/gopdf/.hgignore generated vendored Normal file
View File

@ -0,0 +1,11 @@
syntax:glob
*.[568ao]
[568a].out
*.cgo*.go
*.cgo*.c
_cgo_*
_obj
_test
_testmain.go
build.out
test.out

8
vendor/bitbucket.org/zombiezen/gopdf/.hgtags generated vendored Normal file
View File

@ -0,0 +1,8 @@
678fd0e19f2de643e44e52a131920733d75d400d go.weekly.2011-11-01
d21733eb8d7dac896bbc3fb4f7a31cbd6edc4f22 go.weekly.2011-11-02
d21733eb8d7dac896bbc3fb4f7a31cbd6edc4f22 go.weekly.2011-11-02
d53f28b5260733b2d4d865c8dd00bfd451fbd373 go.weekly.2011-11-02
678fd0e19f2de643e44e52a131920733d75d400d go.weekly.2011-11-01
0000000000000000000000000000000000000000 go.weekly.2011-11-01
61f2f88960fd453c40d1655472cb201a6917f226 go.weekly.2011-12-22
641e2e5bd59c136d6e78cba91839aa3f96f4430a go.weekly.2012-02-22

13
vendor/bitbucket.org/zombiezen/gopdf/AUTHORS generated vendored Normal file
View File

@ -0,0 +1,13 @@
# This is the official list of gopdf authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.
# Names should be added to this file as
# Name or Organization <email address>
# The email address is not required for organizations.
# Please keep the list sorted.
Ross Light <ross@zombiezen.com>
Sheng Yu <yusheng.sjtu@gmail.com>
Tarmigan Casebolt <tarmigan@gmail.com>

14
vendor/bitbucket.org/zombiezen/gopdf/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,14 @@
# This is the official list of people who can contribute
# (and typically have contributed) code to the gopdf repository.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# Names should be added to this file like so:
# Name <email address>
# Please keep the list sorted.
Ross Light <ross@zombiezen.com>
Sheng Yu <yusheng.sjtu@gmail.com>
Tarmigan Casebolt <tarmigan@gmail.com>

11
vendor/bitbucket.org/zombiezen/gopdf/README.rst generated vendored Normal file
View File

@ -0,0 +1,11 @@
*********
gopdf
*********
gopdf is a Go library for creating PDF files.
To install gopdf::
go get bitbucket.org/zombiezen/gopdf/pdf
gopdf is released under a 2-clause BSD license.

28
vendor/bitbucket.org/zombiezen/gopdf/buildmetrics.bash generated vendored Executable file
View File

@ -0,0 +1,28 @@
#!/bin/bash
DIR="$(mktemp -d -t buildmetricsXXX)"
TARBALL="Core14_AFMs.tar"
URL="https://partners.adobe.com/public/developer/en/pdf/$TARBALL"
OUTPUT="pdf/metrics.go"
echo "$DIR"
curl "$URL" > "$DIR/$TARBALL"
(cd "$DIR" ; tar -xf "$TARBALL")
rm -f "$OUTPUT"
touch "$OUTPUT"
echo "package pdf" >> "$OUTPUT"
for afmFile in "$DIR"/*.afm
do
fontName="$(basename "$afmFile" .afm)"
varName="$(echo "$fontName" | sed 's/-//')Widths"
echo >> "$OUTPUT"
echo "// $fontName" >> "$OUTPUT"
echo "var $varName = []uint16{" >> "$OUTPUT"
sed -n 's/^C \([0-9]\|[0-9][0-9]\|1[012][0-9]\) ; WX \([0-9]\+\) ; N \([a-zA-Z]\+\).*/\1: \2, \/\/ \3/p' < "$afmFile" >> "$OUTPUT"
echo "}" >> "$OUTPUT"
done
gofmt -w "$OUTPUT"
rm -rf "$DIR"

View File

@ -0,0 +1,25 @@
// Copyright (C) 2011, Ross Light
package pdf
import (
"testing"
)
const pathExpectedOutput = `12.00000 34.00000 m
-56.00000 78.00000 l
h
3.10000 -5.90000 21.10000 80.90000 re
`
func TestPath(t *testing.T) {
path := new(Path)
path.Move(Point{12, 34})
path.Line(Point{-56, 78})
path.Close()
path.Rectangle(Rectangle{Point{3.1, -5.9}, Point{24.2, 75.0}})
if path.buf.String() != pathExpectedOutput {
t.Errorf("Output was %q, expected %q", path.buf.String(), pathExpectedOutput)
}
}

View File

@ -0,0 +1,46 @@
// Copyright (C) 2011, Ross Light
package pdf
import (
"bytes"
"reflect"
"testing"
)
const encodingTestData = "%PDF-1.7\r\n" +
"%\x93\x8c\x8b\x9e\r\n" +
"1 0 obj\r\n" +
"(Hello, World!)\r\n" +
"endobj\r\n" +
"2 0 obj\r\n" +
"42\r\n" +
"endobj\r\n" +
"xref\r\n" +
"0 3\r\n" +
"0000000000 65535 f\r\n" +
"0000000017 00000 n\r\n" +
"0000000051 00000 n\r\n" +
"trailer\r\n" +
"<< /Size 3 /Root 0 0 R >>\r\n" +
"startxref\r\n" +
"72\r\n" +
"%%EOF\r\n"
func TestEncoder(t *testing.T) {
var e encoder
if ref := e.add("Hello, World!"); !reflect.DeepEqual(ref, Reference{1, 0}) {
t.Errorf("After adding first object, reference is %#v", ref)
}
if ref := e.add(42); !reflect.DeepEqual(ref, Reference{2, 0}) {
t.Errorf("After adding second object, reference is %#v", ref)
}
var b bytes.Buffer
if err := e.encode(&b); err != nil {
t.Fatalf("Encoding error: %v", err)
}
if b.String() != encodingTestData {
t.Errorf("Encoding result %q, want %q", b.String(), encodingTestData)
}
}

220
vendor/bitbucket.org/zombiezen/gopdf/pdf/image_test.go generated vendored Normal file
View File

@ -0,0 +1,220 @@
package pdf
import (
"bytes"
"image"
"image/color"
"image/draw"
"image/jpeg"
"image/png"
"io/ioutil"
"os"
"testing"
"golang.org/x/image/bmp"
)
const suzanneBytes = 512 * 512 * 3
func loadSuzanneRGBA() (*image.RGBA, error) {
f, err := os.Open("testdata/suzanne.bmp")
if err != nil {
return nil, err
}
defer f.Close()
img, err := bmp.Decode(f)
if err != nil {
return nil, err
}
return img.(*image.RGBA), nil
}
func loadSuzanneNRGBA() (*image.NRGBA, error) {
f, err := os.Open("testdata/suzanne.png")
if err != nil {
return nil, err
}
defer f.Close()
img, err := png.Decode(f)
if err != nil {
return nil, err
}
return img.(*image.NRGBA), nil
}
func loadSuzanneYCbCr() (*image.YCbCr, error) {
f, err := os.Open("testdata/suzanne.jpg")
if err != nil {
return nil, err
}
defer f.Close()
img, err := jpeg.Decode(f)
if err != nil {
return nil, err
}
return img.(*image.YCbCr), nil
}
func BenchmarkEncodeRGBAGeneric(b *testing.B) {
b.StopTimer()
img, _ := loadSuzanneRGBA()
b.SetBytes(suzanneBytes)
b.StartTimer()
for i := 0; i < b.N; i++ {
encodeImageStream(ioutil.Discard, img)
}
}
func BenchmarkEncodeRGBA(b *testing.B) {
b.StopTimer()
img, _ := loadSuzanneRGBA()
b.SetBytes(suzanneBytes)
b.StartTimer()
for i := 0; i < b.N; i++ {
encodeRGBAStream(ioutil.Discard, img)
}
}
func BenchmarkEncodeNRGBAGeneric(b *testing.B) {
b.StopTimer()
img, _ := loadSuzanneNRGBA()
b.SetBytes(suzanneBytes)
b.StartTimer()
for i := 0; i < b.N; i++ {
encodeImageStream(ioutil.Discard, img)
}
}
func BenchmarkEncodeNRGBA(b *testing.B) {
b.StopTimer()
img, _ := loadSuzanneNRGBA()
b.SetBytes(suzanneBytes)
b.StartTimer()
for i := 0; i < b.N; i++ {
encodeNRGBAStream(ioutil.Discard, img)
}
}
func BenchmarkEncodeYCbCrGeneric(b *testing.B) {
b.StopTimer()
img, _ := loadSuzanneYCbCr()
b.SetBytes(suzanneBytes)
b.StartTimer()
for i := 0; i < b.N; i++ {
encodeImageStream(ioutil.Discard, img)
}
}
func BenchmarkEncodeYCbCr(b *testing.B) {
b.StopTimer()
img, _ := loadSuzanneYCbCr()
b.SetBytes(suzanneBytes)
b.StartTimer()
for i := 0; i < b.N; i++ {
encodeYCbCrStream(ioutil.Discard, img)
}
}
func expectImageBuffer(buf []byte, r image.Rectangle, c color.Color, t *testing.T) {
nc := color.NRGBAModel.Convert(c).(color.NRGBA)
if n := 3 * r.Dx() * r.Dy(); len(buf) != n {
t.Errorf("stream length = %d; want %d", len(buf), n)
}
for i := 0; i+2 < len(buf); i += 3 {
r, g, b := uint8(buf[i]), uint8(buf[i+1]), uint8(buf[i+2])
if r != nc.R || g != nc.G || b != nc.B {
t.Errorf("buf[%d:%d] = [%#02x %#02x %#02x]; want [%#02x %#02x %#02x]", i, i+3, r, g, b, nc.R, nc.G, nc.B)
}
}
}
func TestEncodeRGBAStream(t *testing.T) {
r := image.Rect(0, 0, 16, 16)
img := image.NewRGBA(r)
c := color.RGBA{R: 40, G: 9, B: 33, A: 85}
draw.Draw(img, r, image.NewUniform(c), image.ZP, draw.Src)
var buf bytes.Buffer
encodeImageStream(&buf, img)
expectImageBuffer(buf.Bytes(), r, c, t)
}
func TestEncodeRGBAStreamGeneric(t *testing.T) {
r := image.Rect(0, 0, 16, 16)
img := image.NewRGBA(r)
c := color.RGBA{R: 40, G: 9, B: 33, A: 85}
draw.Draw(img, r, image.NewUniform(c), image.ZP, draw.Src)
var buf bytes.Buffer
encodeRGBAStream(&buf, img)
expectImageBuffer(buf.Bytes(), r, c, t)
}
func TestEncodeNRGBAStream(t *testing.T) {
r := image.Rect(0, 0, 16, 16)
img := image.NewNRGBA(r)
c := color.NRGBA{R: 120, G: 27, B: 99, A: 85}
draw.Draw(img, r, image.NewUniform(c), image.ZP, draw.Src)
var buf bytes.Buffer
encodeNRGBAStream(&buf, img)
expectImageBuffer(buf.Bytes(), r, c, t)
}
func TestEncodeNRGBAStreamGeneric(t *testing.T) {
r := image.Rect(0, 0, 16, 16)
img := image.NewNRGBA(r)
c := color.NRGBA{R: 120, G: 27, B: 99, A: 85}
draw.Draw(img, r, image.NewUniform(c), image.ZP, draw.Src)
var buf bytes.Buffer
encodeImageStream(&buf, img)
expectImageBuffer(buf.Bytes(), r, c, t)
}
func TestEncodeYCbCrStream(t *testing.T) {
r := image.Rect(0, 0, 16, 16)
img := image.NewYCbCr(r, image.YCbCrSubsampleRatio444)
c := color.YCbCr{Y: 70, Cb: 146, Cr: 164}
for i := range img.Y {
img.Y[i] = c.Y
}
for i := range img.Cb {
img.Cb[i] = c.Cb
}
for i := range img.Cr {
img.Cr[i] = c.Cr
}
var buf bytes.Buffer
encodeYCbCrStream(&buf, img)
expectImageBuffer(buf.Bytes(), r, c, t)
}
func TestEncodeYCbCrStreamGeneric(t *testing.T) {
r := image.Rect(0, 0, 16, 16)
img := image.NewYCbCr(r, image.YCbCrSubsampleRatio444)
c := color.YCbCr{Y: 70, Cb: 146, Cr: 164}
for i := range img.Y {
img.Y[i] = c.Y
}
for i := range img.Cb {
img.Cb[i] = c.Cb
}
for i := range img.Cr {
img.Cr[i] = c.Cr
}
var buf bytes.Buffer
encodeImageStream(&buf, img)
expectImageBuffer(buf.Bytes(), r, c, t)
}

View File

@ -0,0 +1,76 @@
// Copyright (C) 2011, Ross Light
package pdf
import (
"testing"
)
type marshalTest struct {
Value interface{}
Expected string
}
type fooStruct struct {
Size int64
Params map[name]string
NotHere string `pdf:"-"`
Rename float64 `pdf:"Pi"`
TheVoid []int `pdf:",omitempty"`
}
var marshalTests = []marshalTest{
{nil, "null"},
{"", "()"},
{"This is a string", "(This is a string)"},
{"Strings may contain newlines\nand such.", "(Strings may contain newlines\nand such.)"},
{"Escape (this).", `(Escape \(this\).)`},
{int(123), "123"},
{int(-321), "-321"},
{float64(-3.141599), "-3.14160"},
{float64(1e9), "1000000000.00000"},
{name(""), "/"},
{name("foo"), "/foo"},
{[]interface{}{}, `[ ]`},
{[]string{"foo", "(parens)"}, `[ (foo) (\(parens\)) ]`},
{map[name]string{}, `<< >>`},
{map[name]string{name("foo"): "bar"}, `<< /foo (bar) >>`},
{indirectObject{Reference{42, 0}, "foo"}, "42 0 obj\r\n(foo)\r\nendobj"},
{Reference{42, 0}, `42 0 R`},
{
fooStruct{
Size: 42,
Params: map[name]string{name("this"): "that"},
NotHere: "XXX",
Rename: 3.141592,
TheVoid: []int{1, 2, 3},
},
`<< /Size 42 /Params << /this (that) >> /Pi 3.14159 /TheVoid [ 1 2 3 ] >>`,
},
{
fooStruct{
Size: 42,
Params: map[name]string{name("this"): "that"},
NotHere: "XXX",
Rename: 3.141592,
TheVoid: nil,
},
`<< /Size 42 /Params << /this (that) >> /Pi 3.14159 >>`,
},
{
Rectangle{Point{1, 2}, Point{3, 4}},
`[ 1.00000 2.00000 3.00000 4.00000 ]`,
},
}
func TestMarshal(t *testing.T) {
for i, tt := range marshalTests {
result, err := marshal(nil, tt.Value)
switch {
case err != nil:
t.Errorf("%d. Marshal(%#v) error: %v", i, tt.Value, err)
case string(result) != tt.Expected:
t.Errorf("%d. Marshal(%#v) != %q (got %q)", i, tt.Value, tt.Expected, result)
}
}
}

View File

@ -0,0 +1,56 @@
package pdf
import (
"compress/lzw"
"compress/zlib"
"io/ioutil"
"testing"
)
const streamTestString = "Hello, 世界!\n"
func TestUnfilteredStream(t *testing.T) {
st := newStream(streamNoFilter)
st.WriteString(streamTestString)
st.Close()
if st.String() != streamTestString {
t.Errorf("Stream is %q, wanted %q", st.String(), streamTestString)
}
}
func TestLZWStream(t *testing.T) {
st := newStream(streamLZWDecode)
st.WriteString(streamTestString)
st.Close()
output, _ := ioutil.ReadAll(lzw.NewReader(st, lzw.MSB, 8))
if string(output) != streamTestString {
t.Errorf("Stream is %q, wanted %q", output, streamTestString)
}
}
func TestFlateStream(t *testing.T) {
st := newStream(streamFlateDecode)
st.WriteString(streamTestString)
st.Close()
r, _ := zlib.NewReader(st)
output, _ := ioutil.ReadAll(r)
if string(output) != streamTestString {
t.Errorf("Stream is %q, wanted %q", output, streamTestString)
}
}
const expectedMarshalStreamOutput = "<< /Length 15 >> stream\r\n" + streamTestString + "\r\nendstream"
func TestMarshalStream(t *testing.T) {
b, err := marshalStream(nil, streamInfo{Length: len(streamTestString)}, []byte(streamTestString))
if err == nil {
if string(b) != expectedMarshalStreamOutput {
t.Errorf("marshalStream(...) != %q (got %q)", expectedMarshalStreamOutput, b)
}
} else {
t.Errorf("Error: %v", err)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

99
vendor/bitbucket.org/zombiezen/gopdf/pdf/text_test.go generated vendored Normal file
View File

@ -0,0 +1,99 @@
// Copyright (C) 2011, Ross Light
package pdf
import (
"math"
"testing"
)
const textExpectedOutput = `/Helvetica 12.00000 Tf
14.40000 TL
14.00000 TL
(Hello, World!) Tj
T*
(This is SPARTA!!1!) Tj
`
func TestText(t *testing.T) {
text := new(Text)
text.SetFont(Helvetica, 12)
text.SetLeading(14)
text.Text("Hello, World!")
text.NextLine()
text.Text("This is SPARTA!!1!")
if text.buf.String() != textExpectedOutput {
t.Errorf("Output was %q, expected %q", text.buf.String(), textExpectedOutput)
}
if len(text.fonts) == 1 {
if !text.fonts[Helvetica] {
t.Error("Helvetica missing from fonts")
}
} else {
t.Errorf("Got %d fonts, expected %d", len(text.fonts), 1)
}
}
func floatEq(a, b, epsilon float64) bool {
return math.Abs(a-b) < epsilon
}
func TestTextX(t *testing.T) {
text := new(Text)
if text.X() != 0 {
t.Errorf("Text does not start at X=0 (got %.5f)", text.X())
}
text.SetFont(Helvetica, 12)
text.Text("Hello!")
if !floatEq(float64(text.X()), 30.672, 1e-5) {
t.Errorf("\"Hello!\" has wrong X (=%.5f) when %.5f is desired", text.X(), 30.672)
}
text.NextLine()
if text.X() != 0 {
t.Errorf("Performing NextLine does not reset X (got %.5f)", text.X())
}
text.Text("Hello World")
if !floatEq(float64(text.X()), 62.004, 1e-5) {
t.Errorf("\"Hello World\" has wrong X (=%.5f) when %.5f is desired", text.X(), 62.004)
}
text.NextLineOffset(41.23, 55.555)
if !floatEq(float64(text.X()), 41.23, 1e-3) {
t.Errorf("NextLineOffset has wrong X (=%.5f) when %.5f is desired", text.X(), 41.23)
}
}
func TestTextY(t *testing.T) {
text := new(Text)
if text.Y() != 0 {
t.Errorf("Text does not start at Y=0 (got %.5f)", text.Y())
}
text.SetFont(Helvetica, 12)
text.Text("Hello!")
if text.Y() != 0 {
t.Errorf("\"Hello!\" changes baseline (got %.5f)", text.Y())
}
text.NextLine()
if !floatEq(float64(text.Y()), -14.400, 1e-4) {
t.Errorf("NextLine y = %.5f (expected %.5f)", text.Y(), -14.400)
}
text.SetLeading(41.23)
text.NextLine()
if !floatEq(float64(text.Y()), -55.630, 1e-4) {
t.Errorf("NextLine does not respect leading, y = %.5f (expected %.5f)", text.Y(), -55.630)
}
text.NextLineOffset(1.0, 5.5)
if !floatEq(float64(text.Y()), -50.130, 1e-4) {
t.Errorf("NextLineOffset does not set Y correctly, y = %.5f (expected %.5f)", text.Y(), -50.130)
}
}

77
vendor/github.com/Sirupsen/logrus/entry_test.go generated vendored Normal file
View File

@ -0,0 +1,77 @@
package logrus
import (
"bytes"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestEntryWithError(t *testing.T) {
assert := assert.New(t)
defer func() {
ErrorKey = "error"
}()
err := fmt.Errorf("kaboom at layer %d", 4711)
assert.Equal(err, WithError(err).Data["error"])
logger := New()
logger.Out = &bytes.Buffer{}
entry := NewEntry(logger)
assert.Equal(err, entry.WithError(err).Data["error"])
ErrorKey = "err"
assert.Equal(err, entry.WithError(err).Data["err"])
}
func TestEntryPanicln(t *testing.T) {
errBoom := fmt.Errorf("boom time")
defer func() {
p := recover()
assert.NotNil(t, p)
switch pVal := p.(type) {
case *Entry:
assert.Equal(t, "kaboom", pVal.Message)
assert.Equal(t, errBoom, pVal.Data["err"])
default:
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
}
}()
logger := New()
logger.Out = &bytes.Buffer{}
entry := NewEntry(logger)
entry.WithField("err", errBoom).Panicln("kaboom")
}
func TestEntryPanicf(t *testing.T) {
errBoom := fmt.Errorf("boom again")
defer func() {
p := recover()
assert.NotNil(t, p)
switch pVal := p.(type) {
case *Entry:
assert.Equal(t, "kaboom true", pVal.Message)
assert.Equal(t, errBoom, pVal.Data["err"])
default:
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
}
}()
logger := New()
logger.Out = &bytes.Buffer{}
entry := NewEntry(logger)
entry.WithField("err", errBoom).Panicf("kaboom %v", true)
}

View File

@ -0,0 +1,50 @@
package main
import (
"github.com/Sirupsen/logrus"
)
var log = logrus.New()
func init() {
log.Formatter = new(logrus.JSONFormatter)
log.Formatter = new(logrus.TextFormatter) // default
log.Level = logrus.DebugLevel
}
func main() {
defer func() {
err := recover()
if err != nil {
log.WithFields(logrus.Fields{
"omg": true,
"err": err,
"number": 100,
}).Fatal("The ice breaks!")
}
}()
log.WithFields(logrus.Fields{
"animal": "walrus",
"number": 8,
}).Debug("Started observing beach")
log.WithFields(logrus.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
log.WithFields(logrus.Fields{
"omg": true,
"number": 122,
}).Warn("The group's number increased tremendously!")
log.WithFields(logrus.Fields{
"temperature": -4,
}).Debug("Temperature changes")
log.WithFields(logrus.Fields{
"animal": "orca",
"size": 9009,
}).Panic("It's over 9000!")
}

View File

@ -0,0 +1,30 @@
package main
import (
"github.com/Sirupsen/logrus"
"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
)
var log = logrus.New()
func init() {
log.Formatter = new(logrus.TextFormatter) // default
log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
}
func main() {
log.WithFields(logrus.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
log.WithFields(logrus.Fields{
"omg": true,
"number": 122,
}).Warn("The group's number increased tremendously!")
log.WithFields(logrus.Fields{
"omg": true,
"number": 100,
}).Fatal("The ice breaks!")
}

View File

@ -0,0 +1,98 @@
package logrus
import (
"fmt"
"testing"
"time"
)
// smallFields is a small size data set for benchmarking
var smallFields = Fields{
"foo": "bar",
"baz": "qux",
"one": "two",
"three": "four",
}
// largeFields is a large size data set for benchmarking
var largeFields = Fields{
"foo": "bar",
"baz": "qux",
"one": "two",
"three": "four",
"five": "six",
"seven": "eight",
"nine": "ten",
"eleven": "twelve",
"thirteen": "fourteen",
"fifteen": "sixteen",
"seventeen": "eighteen",
"nineteen": "twenty",
"a": "b",
"c": "d",
"e": "f",
"g": "h",
"i": "j",
"k": "l",
"m": "n",
"o": "p",
"q": "r",
"s": "t",
"u": "v",
"w": "x",
"y": "z",
"this": "will",
"make": "thirty",
"entries": "yeah",
}
var errorFields = Fields{
"foo": fmt.Errorf("bar"),
"baz": fmt.Errorf("qux"),
}
func BenchmarkErrorTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields)
}
func BenchmarkSmallTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
}
func BenchmarkLargeTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
}
func BenchmarkSmallColoredTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
}
func BenchmarkLargeColoredTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
}
func BenchmarkSmallJSONFormatter(b *testing.B) {
doBenchmark(b, &JSONFormatter{}, smallFields)
}
func BenchmarkLargeJSONFormatter(b *testing.B) {
doBenchmark(b, &JSONFormatter{}, largeFields)
}
func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
entry := &Entry{
Time: time.Time{},
Level: InfoLevel,
Message: "message",
Data: fields,
}
var d []byte
var err error
for i := 0; i < b.N; i++ {
d, err = formatter.Format(entry)
if err != nil {
b.Fatal(err)
}
b.SetBytes(int64(len(d)))
}
}

View File

@ -0,0 +1,63 @@
package logstash
import (
"encoding/json"
"fmt"
"github.com/Sirupsen/logrus"
)
// Formatter generates json in logstash format.
// Logstash site: http://logstash.net/
type LogstashFormatter struct {
Type string // if not empty use for logstash type field.
// TimestampFormat sets the format used for timestamps.
TimestampFormat string
}
func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) {
fields := make(logrus.Fields)
for k, v := range entry.Data {
fields[k] = v
}
fields["@version"] = 1
timeStampFormat := f.TimestampFormat
if timeStampFormat == "" {
timeStampFormat = logrus.DefaultTimestampFormat
}
fields["@timestamp"] = entry.Time.Format(timeStampFormat)
// set message field
v, ok := entry.Data["message"]
if ok {
fields["fields.message"] = v
}
fields["message"] = entry.Message
// set level field
v, ok = entry.Data["level"]
if ok {
fields["fields.level"] = v
}
fields["level"] = entry.Level.String()
// set type field
if f.Type != "" {
v, ok = entry.Data["type"]
if ok {
fields["fields.type"] = v
}
fields["type"] = f.Type
}
serialized, err := json.Marshal(fields)
if err != nil {
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
}
return append(serialized, '\n'), nil
}

View File

@ -0,0 +1,52 @@
package logstash
import (
"bytes"
"encoding/json"
"github.com/Sirupsen/logrus"
"github.com/stretchr/testify/assert"
"testing"
)
func TestLogstashFormatter(t *testing.T) {
assert := assert.New(t)
lf := LogstashFormatter{Type: "abc"}
fields := logrus.Fields{
"message": "def",
"level": "ijk",
"type": "lmn",
"one": 1,
"pi": 3.14,
"bool": true,
}
entry := logrus.WithFields(fields)
entry.Message = "msg"
entry.Level = logrus.InfoLevel
b, _ := lf.Format(entry)
var data map[string]interface{}
dec := json.NewDecoder(bytes.NewReader(b))
dec.UseNumber()
dec.Decode(&data)
// base fields
assert.Equal(json.Number("1"), data["@version"])
assert.NotEmpty(data["@timestamp"])
assert.Equal("abc", data["type"])
assert.Equal("msg", data["message"])
assert.Equal("info", data["level"])
// substituted fields
assert.Equal("def", data["fields.message"])
assert.Equal("ijk", data["fields.level"])
assert.Equal("lmn", data["fields.type"])
// formats
assert.Equal(json.Number("1"), data["one"])
assert.Equal(json.Number("3.14"), data["pi"])
assert.Equal(true, data["bool"])
}

122
vendor/github.com/Sirupsen/logrus/hook_test.go generated vendored Normal file
View File

@ -0,0 +1,122 @@
package logrus
import (
"testing"
"github.com/stretchr/testify/assert"
)
type TestHook struct {
Fired bool
}
func (hook *TestHook) Fire(entry *Entry) error {
hook.Fired = true
return nil
}
func (hook *TestHook) Levels() []Level {
return []Level{
DebugLevel,
InfoLevel,
WarnLevel,
ErrorLevel,
FatalLevel,
PanicLevel,
}
}
func TestHookFires(t *testing.T) {
hook := new(TestHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
assert.Equal(t, hook.Fired, false)
log.Print("test")
}, func(fields Fields) {
assert.Equal(t, hook.Fired, true)
})
}
type ModifyHook struct {
}
func (hook *ModifyHook) Fire(entry *Entry) error {
entry.Data["wow"] = "whale"
return nil
}
func (hook *ModifyHook) Levels() []Level {
return []Level{
DebugLevel,
InfoLevel,
WarnLevel,
ErrorLevel,
FatalLevel,
PanicLevel,
}
}
func TestHookCanModifyEntry(t *testing.T) {
hook := new(ModifyHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
log.WithField("wow", "elephant").Print("test")
}, func(fields Fields) {
assert.Equal(t, fields["wow"], "whale")
})
}
func TestCanFireMultipleHooks(t *testing.T) {
hook1 := new(ModifyHook)
hook2 := new(TestHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook1)
log.Hooks.Add(hook2)
log.WithField("wow", "elephant").Print("test")
}, func(fields Fields) {
assert.Equal(t, fields["wow"], "whale")
assert.Equal(t, hook2.Fired, true)
})
}
type ErrorHook struct {
Fired bool
}
func (hook *ErrorHook) Fire(entry *Entry) error {
hook.Fired = true
return nil
}
func (hook *ErrorHook) Levels() []Level {
return []Level{
ErrorLevel,
}
}
func TestErrorHookShouldntFireOnInfo(t *testing.T) {
hook := new(ErrorHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
log.Info("test")
}, func(fields Fields) {
assert.Equal(t, hook.Fired, false)
})
}
func TestErrorHookShouldFireOnError(t *testing.T) {
hook := new(ErrorHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
log.Error("test")
}, func(fields Fields) {
assert.Equal(t, hook.Fired, true)
})
}

View File

@ -0,0 +1,39 @@
# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
## Usage
```go
import (
"log/syslog"
"github.com/Sirupsen/logrus"
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
)
func main() {
log := logrus.New()
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
if err == nil {
log.Hooks.Add(hook)
}
}
```
If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following.
```go
import (
"log/syslog"
"github.com/Sirupsen/logrus"
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
)
func main() {
log := logrus.New()
hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
if err == nil {
log.Hooks.Add(hook)
}
}
```

View File

@ -0,0 +1,54 @@
// +build !windows,!nacl,!plan9
package logrus_syslog
import (
"fmt"
"github.com/Sirupsen/logrus"
"log/syslog"
"os"
)
// SyslogHook to send logs via syslog.
type SyslogHook struct {
Writer *syslog.Writer
SyslogNetwork string
SyslogRaddr string
}
// Creates a hook to be added to an instance of logger. This is called with
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
// `if err == nil { log.Hooks.Add(hook) }`
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
w, err := syslog.Dial(network, raddr, priority, tag)
return &SyslogHook{w, network, raddr}, err
}
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
line, err := entry.String()
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
return err
}
switch entry.Level {
case logrus.PanicLevel:
return hook.Writer.Crit(line)
case logrus.FatalLevel:
return hook.Writer.Crit(line)
case logrus.ErrorLevel:
return hook.Writer.Err(line)
case logrus.WarnLevel:
return hook.Writer.Warning(line)
case logrus.InfoLevel:
return hook.Writer.Info(line)
case logrus.DebugLevel:
return hook.Writer.Debug(line)
default:
return nil
}
}
func (hook *SyslogHook) Levels() []logrus.Level {
return logrus.AllLevels
}

View File

@ -0,0 +1,26 @@
package logrus_syslog
import (
"github.com/Sirupsen/logrus"
"log/syslog"
"testing"
)
func TestLocalhostAddAndPrint(t *testing.T) {
log := logrus.New()
hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
if err != nil {
t.Errorf("Unable to connect to local syslog.")
}
log.Hooks.Add(hook)
for _, level := range hook.Levels() {
if len(log.Hooks[level]) != 1 {
t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
}
}
log.Info("Congratulations!")
}

67
vendor/github.com/Sirupsen/logrus/hooks/test/test.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
package test
import (
"io/ioutil"
"github.com/Sirupsen/logrus"
)
// test.Hook is a hook designed for dealing with logs in test scenarios.
type Hook struct {
Entries []*logrus.Entry
}
// Installs a test hook for the global logger.
func NewGlobal() *Hook {
hook := new(Hook)
logrus.AddHook(hook)
return hook
}
// Installs a test hook for a given local logger.
func NewLocal(logger *logrus.Logger) *Hook {
hook := new(Hook)
logger.Hooks.Add(hook)
return hook
}
// Creates a discarding logger and installs the test hook.
func NewNullLogger() (*logrus.Logger, *Hook) {
logger := logrus.New()
logger.Out = ioutil.Discard
return logger, NewLocal(logger)
}
func (t *Hook) Fire(e *logrus.Entry) error {
t.Entries = append(t.Entries, e)
return nil
}
func (t *Hook) Levels() []logrus.Level {
return logrus.AllLevels
}
// LastEntry returns the last entry that was logged or nil.
func (t *Hook) LastEntry() (l *logrus.Entry) {
if i := len(t.Entries) - 1; i < 0 {
return nil
} else {
return t.Entries[i]
}
}
// Reset removes all Entries from this test hook.
func (t *Hook) Reset() {
t.Entries = make([]*logrus.Entry, 0)
}

View File

@ -0,0 +1,39 @@
package test
import (
"testing"
"github.com/Sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
func TestAllHooks(t *testing.T) {
assert := assert.New(t)
logger, hook := NewNullLogger()
assert.Nil(hook.LastEntry())
assert.Equal(0, len(hook.Entries))
logger.Error("Hello error")
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
assert.Equal("Hello error", hook.LastEntry().Message)
assert.Equal(1, len(hook.Entries))
logger.Warn("Hello warning")
assert.Equal(logrus.WarnLevel, hook.LastEntry().Level)
assert.Equal("Hello warning", hook.LastEntry().Message)
assert.Equal(2, len(hook.Entries))
hook.Reset()
assert.Nil(hook.LastEntry())
assert.Equal(0, len(hook.Entries))
hook = NewGlobal()
logrus.Error("Hello error")
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
assert.Equal("Hello error", hook.LastEntry().Message)
assert.Equal(1, len(hook.Entries))
}

View File

@ -0,0 +1,120 @@
package logrus
import (
"encoding/json"
"errors"
"testing"
)
func TestErrorNotLost(t *testing.T) {
formatter := &JSONFormatter{}
b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
if err != nil {
t.Fatal("Unable to format entry: ", err)
}
entry := make(map[string]interface{})
err = json.Unmarshal(b, &entry)
if err != nil {
t.Fatal("Unable to unmarshal formatted entry: ", err)
}
if entry["error"] != "wild walrus" {
t.Fatal("Error field not set")
}
}
func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
formatter := &JSONFormatter{}
b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
if err != nil {
t.Fatal("Unable to format entry: ", err)
}
entry := make(map[string]interface{})
err = json.Unmarshal(b, &entry)
if err != nil {
t.Fatal("Unable to unmarshal formatted entry: ", err)
}
if entry["omg"] != "wild walrus" {
t.Fatal("Error field not set")
}
}
func TestFieldClashWithTime(t *testing.T) {
formatter := &JSONFormatter{}
b, err := formatter.Format(WithField("time", "right now!"))
if err != nil {
t.Fatal("Unable to format entry: ", err)
}
entry := make(map[string]interface{})
err = json.Unmarshal(b, &entry)
if err != nil {
t.Fatal("Unable to unmarshal formatted entry: ", err)
}
if entry["fields.time"] != "right now!" {
t.Fatal("fields.time not set to original time field")
}
if entry["time"] != "0001-01-01T00:00:00Z" {
t.Fatal("time field not set to current time, was: ", entry["time"])
}
}
func TestFieldClashWithMsg(t *testing.T) {
formatter := &JSONFormatter{}
b, err := formatter.Format(WithField("msg", "something"))
if err != nil {
t.Fatal("Unable to format entry: ", err)
}
entry := make(map[string]interface{})
err = json.Unmarshal(b, &entry)
if err != nil {
t.Fatal("Unable to unmarshal formatted entry: ", err)
}
if entry["fields.msg"] != "something" {
t.Fatal("fields.msg not set to original msg field")
}
}
func TestFieldClashWithLevel(t *testing.T) {
formatter := &JSONFormatter{}
b, err := formatter.Format(WithField("level", "something"))
if err != nil {
t.Fatal("Unable to format entry: ", err)
}
entry := make(map[string]interface{})
err = json.Unmarshal(b, &entry)
if err != nil {
t.Fatal("Unable to unmarshal formatted entry: ", err)
}
if entry["fields.level"] != "something" {
t.Fatal("fields.level not set to original level field")
}
}
func TestJSONEntryEndsWithNewline(t *testing.T) {
formatter := &JSONFormatter{}
b, err := formatter.Format(WithField("level", "something"))
if err != nil {
t.Fatal("Unable to format entry: ", err)
}
if b[len(b)-1] != '\n' {
t.Fatal("Expected JSON log entry to end with a newline")
}
}

361
vendor/github.com/Sirupsen/logrus/logrus_test.go generated vendored Normal file
View File

@ -0,0 +1,361 @@
package logrus
import (
"bytes"
"encoding/json"
"strconv"
"strings"
"sync"
"testing"
"github.com/stretchr/testify/assert"
)
func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
var buffer bytes.Buffer
var fields Fields
logger := New()
logger.Out = &buffer
logger.Formatter = new(JSONFormatter)
log(logger)
err := json.Unmarshal(buffer.Bytes(), &fields)
assert.Nil(t, err)
assertions(fields)
}
func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
var buffer bytes.Buffer
logger := New()
logger.Out = &buffer
logger.Formatter = &TextFormatter{
DisableColors: true,
}
log(logger)
fields := make(map[string]string)
for _, kv := range strings.Split(buffer.String(), " ") {
if !strings.Contains(kv, "=") {
continue
}
kvArr := strings.Split(kv, "=")
key := strings.TrimSpace(kvArr[0])
val := kvArr[1]
if kvArr[1][0] == '"' {
var err error
val, err = strconv.Unquote(val)
assert.NoError(t, err)
}
fields[key] = val
}
assertions(fields)
}
func TestPrint(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Print("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["level"], "info")
})
}
func TestInfo(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["level"], "info")
})
}
func TestWarn(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Warn("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["level"], "warning")
})
}
func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln("test", "test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test test")
})
}
func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln("test", 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test 10")
})
}
func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln(10, 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "10 10")
})
}
func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln(10, 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "10 10")
})
}
func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Info("test", 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test10")
})
}
func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Info("test", "test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "testtest")
})
}
func TestWithFieldsShouldAllowAssignments(t *testing.T) {
var buffer bytes.Buffer
var fields Fields
logger := New()
logger.Out = &buffer
logger.Formatter = new(JSONFormatter)
localLog := logger.WithFields(Fields{
"key1": "value1",
})
localLog.WithField("key2", "value2").Info("test")
err := json.Unmarshal(buffer.Bytes(), &fields)
assert.Nil(t, err)
assert.Equal(t, "value2", fields["key2"])
assert.Equal(t, "value1", fields["key1"])
buffer = bytes.Buffer{}
fields = Fields{}
localLog.Info("test")
err = json.Unmarshal(buffer.Bytes(), &fields)
assert.Nil(t, err)
_, ok := fields["key2"]
assert.Equal(t, false, ok)
assert.Equal(t, "value1", fields["key1"])
}
func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("msg", "hello").Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
})
}
func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("msg", "hello").Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["fields.msg"], "hello")
})
}
func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("time", "hello").Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["fields.time"], "hello")
})
}
func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("level", 1).Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["level"], "info")
assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
})
}
func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
LogAndAssertText(t, func(log *Logger) {
ll := log.WithField("herp", "derp")
ll.Info("hello")
ll.Info("bye")
}, func(fields map[string]string) {
for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
if _, ok := fields[fieldName]; ok {
t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
}
}
})
}
func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
var buffer bytes.Buffer
var fields Fields
logger := New()
logger.Out = &buffer
logger.Formatter = new(JSONFormatter)
llog := logger.WithField("context", "eating raw fish")
llog.Info("looks delicious")
err := json.Unmarshal(buffer.Bytes(), &fields)
assert.NoError(t, err, "should have decoded first message")
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
assert.Equal(t, fields["msg"], "looks delicious")
assert.Equal(t, fields["context"], "eating raw fish")
buffer.Reset()
llog.Warn("omg it is!")
err = json.Unmarshal(buffer.Bytes(), &fields)
assert.NoError(t, err, "should have decoded second message")
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
assert.Equal(t, fields["msg"], "omg it is!")
assert.Equal(t, fields["context"], "eating raw fish")
assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
}
func TestConvertLevelToString(t *testing.T) {
assert.Equal(t, "debug", DebugLevel.String())
assert.Equal(t, "info", InfoLevel.String())
assert.Equal(t, "warning", WarnLevel.String())
assert.Equal(t, "error", ErrorLevel.String())
assert.Equal(t, "fatal", FatalLevel.String())
assert.Equal(t, "panic", PanicLevel.String())
}
func TestParseLevel(t *testing.T) {
l, err := ParseLevel("panic")
assert.Nil(t, err)
assert.Equal(t, PanicLevel, l)
l, err = ParseLevel("PANIC")
assert.Nil(t, err)
assert.Equal(t, PanicLevel, l)
l, err = ParseLevel("fatal")
assert.Nil(t, err)
assert.Equal(t, FatalLevel, l)
l, err = ParseLevel("FATAL")
assert.Nil(t, err)
assert.Equal(t, FatalLevel, l)
l, err = ParseLevel("error")
assert.Nil(t, err)
assert.Equal(t, ErrorLevel, l)
l, err = ParseLevel("ERROR")
assert.Nil(t, err)
assert.Equal(t, ErrorLevel, l)
l, err = ParseLevel("warn")
assert.Nil(t, err)
assert.Equal(t, WarnLevel, l)
l, err = ParseLevel("WARN")
assert.Nil(t, err)
assert.Equal(t, WarnLevel, l)
l, err = ParseLevel("warning")
assert.Nil(t, err)
assert.Equal(t, WarnLevel, l)
l, err = ParseLevel("WARNING")
assert.Nil(t, err)
assert.Equal(t, WarnLevel, l)
l, err = ParseLevel("info")
assert.Nil(t, err)
assert.Equal(t, InfoLevel, l)
l, err = ParseLevel("INFO")
assert.Nil(t, err)
assert.Equal(t, InfoLevel, l)
l, err = ParseLevel("debug")
assert.Nil(t, err)
assert.Equal(t, DebugLevel, l)
l, err = ParseLevel("DEBUG")
assert.Nil(t, err)
assert.Equal(t, DebugLevel, l)
l, err = ParseLevel("invalid")
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
}
func TestGetSetLevelRace(t *testing.T) {
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
if i%2 == 0 {
SetLevel(InfoLevel)
} else {
GetLevel()
}
}(i)
}
wg.Wait()
}
func TestLoggingRace(t *testing.T) {
logger := New()
var wg sync.WaitGroup
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
logger.Info("info")
wg.Done()
}()
}
wg.Wait()
}
// Compile test
func TestLogrusInterface(t *testing.T) {
var buffer bytes.Buffer
fn := func(l FieldLogger) {
b := l.WithField("key", "value")
b.Debug("Test")
}
// test logger
logger := New()
logger.Out = &buffer
fn(logger)
// test Entry
e := logger.WithField("another", "value")
fn(e)
}

View File

@ -0,0 +1,61 @@
package logrus
import (
"bytes"
"errors"
"testing"
"time"
)
func TestQuoting(t *testing.T) {
tf := &TextFormatter{DisableColors: true}
checkQuoting := func(q bool, value interface{}) {
b, _ := tf.Format(WithField("test", value))
idx := bytes.Index(b, ([]byte)("test="))
cont := bytes.Contains(b[idx+5:], []byte{'"'})
if cont != q {
if q {
t.Errorf("quoting expected for: %#v", value)
} else {
t.Errorf("quoting not expected for: %#v", value)
}
}
}
checkQuoting(false, "abcd")
checkQuoting(false, "v1.0")
checkQuoting(false, "1234567890")
checkQuoting(true, "/foobar")
checkQuoting(true, "x y")
checkQuoting(true, "x,y")
checkQuoting(false, errors.New("invalid"))
checkQuoting(true, errors.New("invalid argument"))
}
func TestTimestampFormat(t *testing.T) {
checkTimeStr := func(format string) {
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
customStr, _ := customFormatter.Format(WithField("test", "test"))
timeStart := bytes.Index(customStr, ([]byte)("time="))
timeEnd := bytes.Index(customStr, ([]byte)("level="))
timeStr := customStr[timeStart+5 : timeEnd-1]
if timeStr[0] == '"' && timeStr[len(timeStr)-1] == '"' {
timeStr = timeStr[1 : len(timeStr)-1]
}
if format == "" {
format = time.RFC3339
}
_, e := time.Parse(format, (string)(timeStr))
if e != nil {
t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
}
}
checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
checkTimeStr("Mon Jan _2 15:04:05 2006")
checkTimeStr("")
}
// TODO add tests for sorting etc., this requires a parser for the text
// formatter output.

55
vendor/github.com/ajstarks/svgo/android/android.go generated vendored Normal file
View File

@ -0,0 +1,55 @@
// android draws bugdroid, the Android mascot
// +build !appengine
package main
import (
"fmt"
"os"
"github.com/ajstarks/svgo"
)
var (
width = 500
height = 500
canvas = svg.New(os.Stdout)
)
const androidcolor = "rgb(164,198,57)"
func background(v int) { canvas.Rect(0, 0, width, height, canvas.RGB(v, v, v)) }
func android(x, y int, fill string, opacity float64) {
var linestyle = []string{`stroke="` + fill + `"`, `stroke-linecap="round"`, `stroke-width="5"`}
globalstyle := fmt.Sprintf("fill:%s;opacity:%.2f", fill, opacity)
canvas.Gstyle(globalstyle)
canvas.Arc(x+30, y+70, 35, 35, 0, false, true, x+130, y+70) // head
canvas.Line(x+60, y+25, x+50, y+10, linestyle[0], linestyle[1], linestyle[2]) // left antenna
canvas.Line(x+100, y+25, x+110, y+10, linestyle[0], linestyle[1], linestyle[2]) // right antenna
canvas.Circle(x+60, y+45, 5, "fill:white") // left eye
canvas.Circle(x+100, y+45, 5, `fill="white"`) // right eye
canvas.Roundrect(x+30, y+75, 100, 90, 10, 10) // body
canvas.Rect(x+30, y+75, 100, 80)
canvas.Roundrect(x+5, y+80, 20, 70, 10, 10) // left arm
canvas.Roundrect(x+135, y+80, 20, 70, 10, 10) // right arm
canvas.Roundrect(x+50, y+150, 20, 50, 10, 10) // left leg
canvas.Roundrect(x+90, y+150, 20, 50, 10, 10) // right leg
canvas.Gend()
}
func main() {
canvas.Start(width, height)
canvas.Title("Android")
background(255)
android(100, 100, androidcolor, 1.0)
canvas.Scale(3.0)
android(50, 50, "gray", 0.5)
canvas.Gend()
canvas.Scale(0.5)
android(100, 100, "red", 1.0)
canvas.Gend()
canvas.End()
}

472
vendor/github.com/ajstarks/svgo/barchart/barchart.go generated vendored Executable file
View File

@ -0,0 +1,472 @@
// barchart - bar chart
package main
import (
"encoding/xml"
"flag"
"fmt"
"github.com/ajstarks/svgo"
"io"
"math"
"os"
"strconv"
"strings"
)
var (
width, height, iscale, fontsize, barheight, gutter, cornerRadius, labelimit int
bgcolor, barcolor, title, inbar, valformat string
showtitle, showdata, showgrid, showscale, endtitle, trace bool
)
const (
gstyle = "font-family:Calibri,sans-serif;font-size:%dpx"
borderstyle = "stroke:lightgray;stroke-width:1px"
scalestyle = "text-anchor:middle;font-size:75%"
btitlestyle = "font-style:italic;font-size:150%;text-anchor:"
notestyle = "font-style:italic;text-anchor:"
datastyle = "text-anchor:end;fill:"
titlestyle = "text-anchor:start;font-size:300%"
labelstyle = "fill:black;baseline-shift:-25%"
)
// a Barchart Defintion
// <barchart title="Bullet Graph" top="50" left="250" right="50">
// <note>This is a note</note>
// <note>More expository text</note>
// <bdata title="Browser Market Share" scale="0,100,20" showdata="true" color="red" unit="%"/>
// <bitem name="Firefox" value="22.5" color="green"/>
// <bitem name="Chrome" value="12.3"/>
// <bitem name="IE8" value="63.5"/>
// <bdata>
// </barchart>
type Barchart struct {
Top int `xml:"top,attr"`
Left int `xml:"left,attr"`
Right int `xml:"right,attr"`
Title string `xml:"title,attr"`
Bdata []bdata `xml:"bdata"`
Note []note `xml:"note"`
}
type bdata struct {
Title string `xml:"title,attr"`
Scale string `xml:"scale,attr"`
Color string `xml:"color,attr"`
Unit string `xml:"unit,attr"`
Showdata bool `xml:"showdata,attr"`
Showgrid bool `xml:"showgrid,attr"`
Samebar bool `xml:"samebar,attr"`
Bitem []bitem `xml:"bitem"`
Bstack []bstack `xml:"bstack"`
Note []note `xml:"note"`
}
type bitem struct {
Name string `xml:"name,attr"`
Value float64 `xml:"value,attr"`
Color string `xml:"color,attr"`
Samebar bool `xml:"samebar,attr"`
}
type bstack struct {
Name string `xml:"name,attr"`
Value string `xml:"value,attr"`
Color string `xml:"color,attr"`
}
type note struct {
Text string `xml:",chardata"`
}
// dobc does file i/o
func dobc(location string, s *svg.SVG) {
var f *os.File
var err error
if len(location) > 0 {
f, err = os.Open(location)
} else {
f = os.Stdin
}
if err == nil {
readbc(f, s)
f.Close()
} else {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
}
// readbc reads and parses the XML specification
func readbc(r io.Reader, s *svg.SVG) {
var bc Barchart
if err := xml.NewDecoder(r).Decode(&bc); err == nil {
drawbc(bc, s)
} else {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
}
// drawbc draws the bar chart
func drawbc(bg Barchart, canvas *svg.SVG) {
if bg.Left == 0 {
bg.Left = 250
}
if bg.Right == 0 {
bg.Right = 50
}
if bg.Top == 0 {
bg.Top = 50
}
if len(title) > 0 {
bg.Title = title
}
labelimit = bg.Left/8
cr := cornerRadius
maxwidth := width - (bg.Left + bg.Right)
x := bg.Left
y := bg.Top
sep := 10
color := barcolor
scfmt := "%v"
canvas.Title(bg.Title)
// for each bdata element...
for _, b := range bg.Bdata {
if trace {
fmt.Fprintf(os.Stderr, "# %s\n", b.Title)
}
// overide the color if specified
if len(b.Color) > 0 {
color = b.Color
} else {
color = barcolor
}
// extract the scale data from the XML attributes
// if not specified, compute the scale factors
sc := strings.Split(b.Scale, ",")
var scalemin, scalemax, scaleincr float64
if len(sc) != 3 {
if len(b.Bitem) > 0 {
scalemin, scalemax, scaleincr = scalevalues(b.Bitem)
}
if len(b.Bstack) > 0 {
scalemin, scalemax, scaleincr = scalestack(b.Bstack)
}
} else {
scalemin, _ = strconv.ParseFloat(sc[0], 64)
scalemax, _ = strconv.ParseFloat(sc[1], 64)
scaleincr, _ = strconv.ParseFloat(sc[2], 64)
}
// label the graph
canvas.Text(x, y, b.Title, btitlestyle+anchor())
y += sep * 2
chartop := y
// draw the data items
canvas.Gstyle(datastyle + color)
// stacked bars
for _, stack := range b.Bstack {
if trace {
fmt.Fprintf(os.Stderr, "%s~%s\n", stack.Value, stack.Name)
}
stackdata := stackvalues(stack.Value)
if len(stackdata) < 1 {
continue
}
sx := x
canvas.Text(x-sep, y+barheight/2, textlimit(stack.Name, labelimit), labelstyle)
barop := colorange(1.0, 0.3, len(stackdata))
for ns, sd := range stackdata {
dw := vmap(sd, scalemin, scalemax, 0, float64(maxwidth))
if len(stack.Color) > 0 {
canvas.Roundrect(sx, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill:%s;fill-opacity:%.2f", stack.Color, barop[ns]))
} else {
canvas.Roundrect(sx, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill-opacity:%.2f", barop[ns]))
}
if (showdata || b.Showdata) && sd > 0 {
var valuestyle = "fill-opacity:1;font-style:italic;font-size:75%;text-anchor:middle;baseline-shift:-25%;"
var ditem string
var datax int
if len(b.Unit) > 0 {
ditem = fmt.Sprintf(valformat+"%s", sd, b.Unit)
} else {
ditem = fmt.Sprintf(valformat, sd)
}
if len(inbar) > 0 {
valuestyle += inbar
} else {
valuestyle += "fill:black"
}
datax = sx + int(dw)/2
canvas.Text(datax, y+barheight/2, ditem, valuestyle)
}
sx += int(dw)
}
y += barheight + gutter
}
// plain bars
for _, d := range b.Bitem {
if trace {
fmt.Fprintf(os.Stderr, "%.2f~%s\n", d.Value, d.Name)
}
canvas.Text(x-sep, y+barheight/2, textlimit(d.Name, labelimit), labelstyle)
dw := vmap(d.Value, scalemin, scalemax, 0, float64(maxwidth))
var barop float64
if b.Samebar {
barop = 0.3
} else {
barop = 1.0
}
if len(d.Color) > 0 {
canvas.Roundrect(x, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill:%s;fill-opacity:%.2f", d.Color, barop))
} else {
canvas.Roundrect(x, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill-opacity:%.2f", barop))
}
if showdata || b.Showdata {
var valuestyle = "fill-opacity:1;font-style:italic;font-size:75%;text-anchor:start;baseline-shift:-25%;"
var ditem string
var datax int
if len(b.Unit) > 0 {
ditem = fmt.Sprintf(valformat+"%s", d.Value, b.Unit)
} else {
ditem = fmt.Sprintf(valformat, d.Value)
}
if len(inbar) > 0 {
valuestyle += inbar
datax = x + fontsize/2
} else {
valuestyle += "fill:black"
datax = x + int(dw) + fontsize/2
}
canvas.Text(datax, y+barheight/2, ditem, valuestyle)
}
if !d.Samebar {
y += barheight + gutter
}
}
canvas.Gend()
// draw the scale and borders
chartbot := y + gutter
if showgrid || b.Showgrid {
canvas.Line(x, chartop, x+maxwidth, chartop, borderstyle) // top border
canvas.Line(x, chartbot-gutter, x+maxwidth, chartbot-gutter, borderstyle) // bottom border
}
if showscale {
if scaleincr < 1 {
scfmt = "%.1f"
} else {
scfmt = "%0.f"
}
canvas.Gstyle(scalestyle)
for sc := scalemin; sc <= scalemax; sc += scaleincr {
scx := vmap(sc, scalemin, scalemax, 0, float64(maxwidth))
canvas.Text(x+int(scx), chartbot+fontsize, fmt.Sprintf(scfmt, sc))
if showgrid || b.Showgrid {
canvas.Line(x+int(scx), chartbot, x+int(scx), chartop, borderstyle) // grid line
}
}
canvas.Gend()
}
// apply the note if present
if len(b.Note) > 0 {
canvas.Gstyle(notestyle + anchor())
y += fontsize * 2
leading := 3
for _, note := range b.Note {
canvas.Text(bg.Left, y, note.Text)
y += fontsize + leading
}
canvas.Gend()
}
y += sep * 7 // advance vertically for the next chart
}
// if requested, place the title below the last chart
if showtitle && len(bg.Title) > 0 {
y += fontsize * 2
canvas.Text(bg.Left, y, bg.Title, titlestyle)
}
// apply overall note if present
if len(bg.Note) > 0 {
canvas.Gstyle(notestyle + anchor())
y += fontsize * 2
leading := 3
for _, note := range bg.Note {
canvas.Text(bg.Left, y, note.Text)
y += fontsize + leading
}
canvas.Gend()
}
}
func anchor() string {
if endtitle {
return "end"
}
return "start"
}
// vmap maps one interval to another
func vmap(value float64, low1 float64, high1 float64, low2 float64, high2 float64) float64 {
return low2 + (high2-low2)*(value-low1)/(high1-low1)
}
// maxitem finds the maxima is a collection of bar items
func maxitem(data []bitem) float64 {
max := -math.SmallestNonzeroFloat64
for _, d := range data {
if d.Value > max {
max = d.Value
}
}
return max
}
// maxstack finds the maxima is a stack of bars
func maxstack(stacks []bstack) float64 {
max := -math.SmallestNonzeroFloat64
for _, s := range stacks {
sv := stackvalues(s.Value)
sum := 0.0
for _, d := range sv {
sum += d
}
if sum > max {
max = sum
}
}
return max
}
// scale values returns the min, max, increment from a set of bar items
func scalevalues(data []bitem) (float64, float64, float64) {
var m, max, increment float64
rui := 5
m = maxitem(data)
max = roundup(m, 100)
if max > 2 {
increment = roundup(max/float64(rui), 10)
} else {
increment = 0.4
}
return 0, max, increment
}
// scalestack returns the min, max, increment from a stack of bars
func scalestack(data []bstack) (float64, float64, float64) {
var m, max, increment float64
rui := 5
m = maxstack(data)
max = roundup(m, 100)
if max > 2 {
increment = roundup(max/float64(rui), 10)
} else {
increment = 0.4
}
return 0, max, increment
}
// roundup rouds a floating point number up
func roundup(n float64, m int) float64 {
i := int(n)
if i <= 2 {
return 2
}
for ; i%m != 0; i++ {
}
return float64(i)
}
// stack value returns the values from the value string of a stack
func stackvalues(s string) []float64 {
v := strings.Split(s, "/")
if len(v) <= 0 {
return nil
}
vals := make([]float64, len(v))
for i, x := range v {
f, err := strconv.ParseFloat(x, 64)
if err != nil {
vals[i] = 0
} else {
vals[i] = f
}
}
return vals
}
// colorange evenly distributes opacity across a range of values
func colorange(start, end float64, n int) []float64 {
v := make([]float64, n)
v[0] = start
v[n-1] = end
if n == 2 {
return v
}
incr := (end-start)/float64(n-1)
for i:=1; i < n-1; i++ {
v[i] = v[i-1] + incr
}
return v
}
func textlimit(s string, n int) string {
l := len(s)
if l <= n {
return s
}
return s[0:n-3]+"..."
}
// init sets up the command flags
func init() {
flag.StringVar(&bgcolor, "bg", "white", "background color")
flag.StringVar(&barcolor, "bc", "rgb(200,200,200)", "bar color")
flag.StringVar(&valformat, "vfmt", "%v", "value format")
flag.IntVar(&width, "w", 1024, "width")
flag.IntVar(&height, "h", 800, "height")
flag.IntVar(&barheight, "bh", 20, "bar height")
flag.IntVar(&gutter, "g", 5, "gutter")
flag.IntVar(&cornerRadius, "cr", 0, "corner radius")
flag.IntVar(&fontsize, "f", 18, "fontsize (px)")
flag.BoolVar(&showscale, "showscale", true, "show scale")
flag.BoolVar(&showgrid, "showgrid", false, "show grid")
flag.BoolVar(&showdata, "showdata", false, "show data values")
flag.BoolVar(&showtitle, "showtitle", false, "show title")
flag.BoolVar(&endtitle, "endtitle", false, "align title to the end")
flag.BoolVar(&trace, "trace", false, "show name/value pairs")
flag.StringVar(&inbar, "inbar", "", "data in bar format")
flag.StringVar(&title, "t", "", "title")
}
// for every input file (or stdin), draw a bar graph
// as specified by command flags
func main() {
flag.Parse()
canvas := svg.New(os.Stdout)
canvas.Start(width, height)
canvas.Rect(0, 0, width, height, "fill:"+bgcolor)
canvas.Gstyle(fmt.Sprintf(gstyle, fontsize))
if len(flag.Args()) == 0 {
dobc("", canvas)
} else {
for _, f := range flag.Args() {
dobc(f, canvas)
}
}
canvas.Gend()
canvas.End()
}

238
vendor/github.com/ajstarks/svgo/benchviz/benchviz.go generated vendored Normal file
View File

@ -0,0 +1,238 @@
// benchviz: visualize benchmark data from benchcmp
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"io"
"math"
"os"
"strconv"
"strings"
"github.com/ajstarks/svgo"
)
// geometry defines the layout of the visualization
type geometry struct {
top, left, width, height, vwidth, vp, barHeight int
dolines, coldata bool
title, rcolor, scolor, style string
deltamax, speedupmax float64
}
// process reads the input and calls the visualization function
func process(canvas *svg.SVG, filename string, g geometry) int {
if filename == "" {
return g.visualize(canvas, filename, os.Stdin)
}
f, err := os.Open(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return 0
}
defer f.Close()
return g.visualize(canvas, filename, f)
}
// vmap maps world to canvas coordinates
func vmap(value, low1, high1, low2, high2 float64) float64 {
return low2 + (high2-low2)*(value-low1)/(high1-low1)
}
// visualize performs the visualization of the input, reading a line a time
func (g *geometry) visualize(canvas *svg.SVG, filename string, f io.Reader) int {
var (
err error
line, vs, bmtitle string
dmin, dmax float64
)
bh := g.barHeight
vizwidth := g.vwidth
vspacing := g.barHeight + (g.barHeight / 3) // vertical spacing
bmtype := "delta"
in := bufio.NewReader(f)
canvas.Gstyle(fmt.Sprintf("font-size:%dpx;font-family:sans-serif", bh))
if g.title == "" {
bmtitle = filename
} else {
bmtitle = g.title
}
canvas.Text(g.left, g.top, bmtitle, "font-size:150%")
height := 0
for x, y, nr := g.left+g.vp, g.top+vspacing, 0; err == nil; nr++ {
line, err = in.ReadString('\n')
fields := strings.Split(strings.TrimSpace(line), ` `)
if len(fields) <= 1 || len(line) < 2 {
continue
}
name := fields[0]
value := fields[len(fields)-1]
if len(value) > 2 {
vs = value[:len(value)-1]
}
v, _ := strconv.ParseFloat(vs, 64)
av := math.Abs(v)
switch {
case strings.HasPrefix(value, "delt"):
bmtype = "delta"
dmin = 0.0
dmax = g.deltamax // 100.0
y += vspacing * 2
continue
case strings.HasPrefix(value, "speed"):
bmtype = "speedup"
dmin = 0.0
dmax = g.speedupmax // 10.0
y += vspacing * 2
continue
case strings.HasPrefix(name, "#"):
y += vspacing
canvas.Text(g.left, y, line[1:], "font-style:italic;fill:gray")
continue
}
bw := int(vmap(av, dmin, dmax, 0, float64(vizwidth)))
switch g.style {
case "bar":
g.bars(canvas, x, y, bw, bh, vspacing/2, bmtype, name, value, v)
case "inline":
g.inline(canvas, g.left, y, bw, bh, bmtype, name, value, v)
default:
g.bars(canvas, x, y, bw, bh, vspacing/2, bmtype, name, value, v)
}
y += vspacing
height = y
}
canvas.Gend()
return height
}
// inline makes the inline style pf visualization
func (g *geometry) inline(canvas *svg.SVG, x, y, w, h int, bmtype, name, value string, v float64) {
var color string
switch bmtype {
case "delta":
if v > 0 {
color = g.rcolor
} else {
color = g.scolor
}
case "speedup":
if v < 1.0 {
color = g.rcolor
} else {
color = g.scolor
}
}
canvas.Text(x-10, y, value, "text-anchor:end")
canvas.Text(x, y, name)
canvas.Rect(x, y-h, w, h, "fill-opacity:0.3;fill:"+color)
}
// bars creates barchart style visualization
func (g *geometry) bars(canvas *svg.SVG, x, y, w, h, vs int, bmtype, name, value string, v float64) {
canvas.Gstyle("font-style:italic;font-size:75%")
toffset := h / 4
var tx int
var tstyle string
switch bmtype {
case "delta":
if v > 0 {
canvas.Rect(x-w, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.rcolor)
tx = x - w - toffset
tstyle = "text-anchor:end"
} else {
canvas.Rect(x, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.scolor)
tx = x + w + toffset
tstyle = "text-anchor:start"
}
case "speedup":
if v < 1.0 {
canvas.Rect(x-w, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.rcolor)
tx = x - w - toffset
tstyle = "text-anchor:end"
} else {
canvas.Rect(x, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.scolor)
tx = x + w + toffset
tstyle = "text-anchor:start"
}
}
if g.coldata {
canvas.Text(x-toffset, y+toffset, value, "text-anchor:end")
} else {
canvas.Text(tx, y+toffset, value, tstyle)
}
canvas.Gend()
canvas.Text(g.left, y+(h/2), name, "text-anchor:start")
if g.dolines {
canvas.Line(g.left, y+vs, g.left+(g.width-g.left), y+vs, "stroke:lightgray;stroke-width:1")
}
}
func main() {
var (
width = flag.Int("w", 1024, "width")
top = flag.Int("top", 50, "top")
left = flag.Int("left", 100, "left margin")
vp = flag.Int("vp", 512, "visualization point")
vw = flag.Int("vw", 300, "visual area width")
bh = flag.Int("bh", 20, "bar height")
smax = flag.Float64("sm", 10, "maximum speedup")
dmax = flag.Float64("dm", 100, "maximum delta")
title = flag.String("title", "", "title")
speedcolor = flag.String("scolor", "green", "speedup color")
regresscolor = flag.String("rcolor", "red", "regression color")
style = flag.String("style", "bar", "set the style (bar or inline)")
lines = flag.Bool("line", false, "show lines between entries")
coldata = flag.Bool("col", false, "show data in a single column")
)
flag.Parse()
g := geometry{
width: *width,
top: *top,
left: *left,
vp: *vp,
vwidth: *vw,
barHeight: *bh,
title: *title,
scolor: *speedcolor,
rcolor: *regresscolor,
style: *style,
dolines: *lines,
coldata: *coldata,
speedupmax: *smax,
deltamax: *dmax,
}
// For every named file or stdin, render the SVG in memory, accumulating the height.
var b bytes.Buffer
canvas := svg.New(&b)
height := 0
if len(flag.Args()) > 0 {
for _, f := range flag.Args() {
height = process(canvas, f, g)
g.top = height + 50
}
} else {
height = process(canvas, "", g)
}
g.height = height + 15
// Write the rendered SVG to stdout
out := svg.New(os.Stdout)
out.Start(g.width, g.height)
out.Rect(0, 0, g.width, g.height, "fill:white;stroke-width:2px;stroke:lightgray")
b.WriteTo(os.Stdout)
out.End()
}

67
vendor/github.com/ajstarks/svgo/bubtrail/bubtrail.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
// bubtrail draws a randmonized trail of bubbles
// +build !appengine
package main
import (
"flag"
"fmt"
"math/rand"
"os"
"time"
"github.com/ajstarks/svgo"
)
var (
width = 1200
height = 600
opacity = 0.5
size = 40
niter = 200
canvas = svg.New(os.Stdout)
)
func init() {
flag.IntVar(&size, "s", 40, "bubble size")
flag.IntVar(&niter, "n", 200, "number of iterations")
flag.Float64Var(&opacity, "o", 0.5, "opacity")
flag.Parse()
rand.Seed(int64(time.Now().Nanosecond()) % 1e9)
}
func background(v int) { canvas.Rect(0, 0, width, height, canvas.RGB(v, v, v)) }
func random(howsmall, howbig int) int {
if howsmall >= howbig {
return howsmall
}
return rand.Intn(howbig-howsmall) + howsmall
}
func main() {
var style string
canvas.Start(width, height)
canvas.Title("Bubble Trail")
background(200)
canvas.Gstyle(fmt.Sprintf("fill-opacity:%.2f;stroke:none", opacity))
for i := 0; i < niter; i++ {
x := random(0, width)
y := random(height/3, (height*2)/3)
r := random(0, 10000)
switch {
case r >= 0 && r <= 2500:
style = "fill:rgb(255,255,255)"
case r > 2500 && r <= 5000:
style = "fill:rgb(127,0,0)"
case r > 5000 && r <= 7500:
style = "fill:rgb(127,127,127)"
case r > 7500 && r <= 10000:
style = "fill:rgb(0,0,0)"
}
canvas.Circle(x, y, size, style)
}
canvas.Gend()
canvas.End()
}

View File

@ -0,0 +1,233 @@
// bulletgraph - bullet graphs
// (Design Specification http://www.perceptualedge.com/articles/misc/Bullet_Graph_Design_Spec.pdf)
// +build !appengine
package main
import (
"encoding/xml"
"flag"
"fmt"
"io"
"os"
"strconv"
"strings"
"github.com/ajstarks/svgo"
)
var (
width, height, fontsize, barheight, gutter, circleradius int
bgcolor, barcolor, datacolor, compcolor, title, font string
showtitle, circlemark bool
gstyle = "font-family:'%s',sans-serif;font-size:%dpx"
)
// a Bulletgraph Defintion
// <bulletgraph title="Bullet Graph" top="50" left="250" right="50">
// <note>This is a note</note>
// <note>More expository text</note>
// <bdata title="Revenue 2005" subtitle="USD (1,000)" scale="0,300,50" qmeasure="150,225" cmeasure="250" measure="275"/>
// <bdata title="Profit" subtitle="%" scale="0,30,5" qmeasure="20,25" cmeasure="27" measure="22.5"/>
// <bdata title="Avg Order Size subtitle="USD" scale="0,600,100" qmeasure="350,500" cmeasure="550" measure="320"/>
// <bdata title="New Customers" subtitle="Count" scale="0,2500,500" qmeasure="1700,2000" cmeasure="2100" measure="1750"/>
// <bdata title="Cust Satisfaction" subtitle="Top rating of 5" scale="0,5,1" qmeasure="3.5,4.5" cmeasure="4.7" measure="4.85"/>
// </bulletgraph>
// Bulletgraph is the top-level drawing
type Bulletgraph struct {
Top int `xml:"top,attr"`
Left int `xml:"left,attr"`
Right int `xml:"right,attr"`
Title string `xml:"title,attr"`
Bdata []bdata `xml:"bdata"`
Note []note `xml:"note"`
}
type bdata struct {
Title string `xml:"title,attr"`
Subtitle string `xml:"subtitle,attr"`
Scale string `xml:"scale,attr"`
Qmeasure string `xml:"qmeasure,attr"`
Cmeasure float64 `xml:"cmeasure,attr"`
Measure float64 `xml:"measure,attr"`
}
type note struct {
Text string `xml:",chardata"`
}
// dobg does file i/o
func dobg(location string, s *svg.SVG) {
var f *os.File
var err error
if len(location) > 0 {
f, err = os.Open(location)
} else {
f = os.Stdin
}
if err == nil {
readbg(f, s)
f.Close()
} else {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
}
// readbg reads and parses the XML specification
func readbg(r io.Reader, s *svg.SVG) {
var bg Bulletgraph
if err := xml.NewDecoder(r).Decode(&bg); err == nil {
drawbg(bg, s)
} else {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
}
// drawbg draws the bullet graph
func drawbg(bg Bulletgraph, canvas *svg.SVG) {
qmheight := barheight / 3
if bg.Left == 0 {
bg.Left = 250
}
if bg.Right == 0 {
bg.Right = 50
}
if bg.Top == 0 {
bg.Top = 50
}
if len(title) > 0 {
bg.Title = title
}
maxwidth := width - (bg.Left + bg.Right)
x := bg.Left
y := bg.Top
scalesep := 4
tx := x - fontsize
canvas.Title(bg.Title)
// for each bdata element...
for _, v := range bg.Bdata {
// extract the data from the XML attributes
sc := strings.Split(v.Scale, ",")
qm := strings.Split(v.Qmeasure, ",")
// you must have min,max,increment for the scale, at least one qualitative measure
if len(sc) != 3 || len(qm) < 1 {
continue
}
// get the qualitative measures
qmeasures := make([]float64, len(qm))
for i, q := range qm {
qmeasures[i], _ = strconv.ParseFloat(q, 64)
}
scalemin, _ := strconv.ParseFloat(sc[0], 64)
scalemax, _ := strconv.ParseFloat(sc[1], 64)
scaleincr, _ := strconv.ParseFloat(sc[2], 64)
// label the graph
canvas.Text(tx, y+(barheight/2), fmt.Sprintf("%s (%g)", v.Title, v.Measure), "text-anchor:end;font-weight:bold")
canvas.Text(tx, y+(barheight/2)+fontsize, v.Subtitle, "fill:darkgray;text-anchor:end;font-size:75%")
// draw the scale
scfmt := "%g"
if fraction(scaleincr) > 0 {
scfmt = "%.1f"
}
canvas.Gstyle("text-anchor:middle;font-size:75%")
for sc := scalemin; sc <= scalemax; sc += scaleincr {
scx := vmap(sc, scalemin, scalemax, 0, float64(maxwidth))
canvas.Text(x+int(scx), y+scalesep+barheight+fontsize/2, fmt.Sprintf(scfmt, sc))
}
canvas.Gend()
// draw the qualitative measures
canvas.Gstyle("fill-opacity:0.5;fill:" + barcolor)
canvas.Rect(x, y, maxwidth, barheight)
for _, q := range qmeasures {
qbarlength := vmap(q, scalemin, scalemax, 0, float64(maxwidth))
canvas.Rect(x, y, int(qbarlength), barheight)
}
canvas.Gend()
// draw the measure and the comparative measure
barlength := int(vmap(v.Measure, scalemin, scalemax, 0, float64(maxwidth)))
canvas.Rect(x, y+qmheight, barlength, qmheight, "fill:"+datacolor)
cmx := int(vmap(v.Cmeasure, scalemin, scalemax, 0, float64(maxwidth)))
if circlemark {
canvas.Circle(x+cmx, y+barheight/2, circleradius, "fill-opacity:0.3;fill:"+compcolor)
} else {
cbh := barheight / 4
canvas.Line(x+cmx, y+cbh, x+cmx, y+barheight-cbh, "stroke-width:3;stroke:"+compcolor)
}
y += barheight + gutter // adjust vertical position for the next iteration
}
// if requested, place the title below the last bar
if showtitle && len(bg.Title) > 0 {
y += fontsize * 2
canvas.Text(bg.Left, y, bg.Title, "text-anchor:start;font-size:200%")
}
if len(bg.Note) > 0 {
canvas.Gstyle("font-size:100%;text-anchor:start")
y += fontsize * 2
leading := 3
for _, note := range bg.Note {
canvas.Text(bg.Left, y, note.Text)
y += fontsize + leading
}
canvas.Gend()
}
}
//vmap maps one interval to another
func vmap(value float64, low1 float64, high1 float64, low2 float64, high2 float64) float64 {
return low2 + (high2-low2)*(value-low1)/(high1-low1)
}
// fraction returns the fractions portion of a floating point number
func fraction(n float64) float64 {
i := int(n)
return n - float64(i)
}
// init sets up the command flags
func init() {
flag.StringVar(&bgcolor, "bg", "white", "background color")
flag.StringVar(&barcolor, "bc", "rgb(240,240,240)", "bar color")
flag.StringVar(&datacolor, "dc", "rgb(200,200,200)", "data color")
flag.StringVar(&compcolor, "cc", "rgb(127,0,0)", "comparative color")
flag.StringVar(&font, "font", "Calibri", "font")
flag.IntVar(&width, "w", 1024, "width")
flag.IntVar(&height, "h", 800, "height")
flag.IntVar(&barheight, "bh", 32, "bar height")
flag.IntVar(&circleradius, "cr", 8, "circle radius")
flag.IntVar(&gutter, "g", 36, "gutter")
flag.IntVar(&fontsize, "f", 18, "fontsize (px)")
flag.BoolVar(&circlemark, "circle", false, "circle mark")
flag.BoolVar(&showtitle, "showtitle", true, "show title")
flag.StringVar(&title, "t", "", "title")
flag.Parse()
}
// for every input file (or stdin), draw a bullet graph
// as specified by command flags
func main() {
canvas := svg.New(os.Stdout)
canvas.Start(width, height)
canvas.Rect(0, 0, width, height, "fill:"+bgcolor)
canvas.Gstyle(fmt.Sprintf(gstyle, font, fontsize))
if len(flag.Args()) == 0 {
dobg("", canvas)
} else {
for _, f := range flag.Args() {
dobg(f, canvas)
}
}
canvas.Gend()
canvas.End()
}

183
vendor/github.com/ajstarks/svgo/codepic/codepic.go generated vendored Normal file
View File

@ -0,0 +1,183 @@
// codepic -- produce code+output sample suitable for slides
// +build !appengine
package main
import (
"bufio"
"encoding/xml"
"flag"
"fmt"
"io"
"os"
"strings"
"github.com/ajstarks/svgo"
)
var (
canvas = svg.New(os.Stdout)
font string
codeframe, picframe, syntax bool
linespacing, fontsize, top, left, boxwidth, width, height int
)
const (
framestyle = "stroke:gray;stroke-dasharray:1,1;fill:none"
codefmt = "font-family:%s;font-size:%dpx"
labelfmt = "text-anchor:middle;" + codefmt
kwfmt = `<tspan %s>%s</tspan>`
commentfmt = `<tspan font-style="italic" fill="rgb(127,127,127)">%s</tspan>`
textfmt = "<text x=\"%d\" y=\"%d\" xml:space=\"preserve\">%s</text>\n"
svgofmt = `font-weight="bold" fill="rgb(0,0,127)"`
gokwfmt = `font-style="italic" fill="rgb(127,0,0)"`
)
// SVG is the incoming SVG file, capture everything into between <svg..> and </svg>
// in the Doc string. This code will be translated to form the "picture" portion
type SVG struct {
Width int `xml:"width,attr"`
Height int `xml:"height,attr"`
Doc string `xml:",innerxml"`
}
var gokw = []string{
"defer ", "go ", "range ", "chan ", " continue", "if ", "for ", "func ",
"uint8", "uint", "uint16", "uint32", "complex64", "complex128", " byte", "int8", "int16", "int32",
"int64", " int", "float64", "float32", " string", "import ", "const ",
"package ", "return", "var ", "type ", "switch ", "case ", "default:",
}
var svgokw = []string{
".Start", ".Startview,", ".End", ".Script", ".Gstyle", ".Gtransform", ".Scale", ".Offcolor",
".ScaleXY", ".SkewX", ".SkewY", ".SkewXY,", ".Rotate", ".TranslateRotate", ".RotateTranslate", ".Translate",
".Group", ".Gid", ".Gend", ".ClipPath", ".ClipEnd", ".DefEnd", ".Def", ".Desc", ".Title", ".Linkf",
".LinkEnd", ".Use", ".Mask", ".MaskEnd", ".Circle", ".Ellipse", ".Polygon", ".Rect", ".CenterRect",
".Roundrect", ".Square", ".Path", ".Arc", ".Bezier", ".Qbez", ".Qbezier", ".Line", ".Polyline", ".Image",
".Textpath", ".Textlines,", ".Text", ".RGBA", ".RGB", ".LinearGradient", ".RadialGradient", ".Grid",
}
// codepic makes a code+picture SVG file, given a go source file
// and conventionally named output -- given <name>.go, <name>.svg
func codepic(filename string) {
var basename string
bn := strings.Split(filename, ".")
if len(bn) > 0 {
basename = bn[0]
} else {
fmt.Fprintf(os.Stderr, "cannot get the basename for %s\n", filename)
return
}
canvas.Start(width, height)
canvas.Title(basename)
canvas.Rect(0, 0, width, height, "fill:white")
placepic(width/2, top, basename)
canvas.Gstyle(fmt.Sprintf(codefmt, font, fontsize))
placecode(left+fontsize, top+fontsize*2, filename)
canvas.Gend()
canvas.End()
}
// placecode places the code section on the left
func placecode(x, y int, filename string) {
var rerr error
var line string
var ic bool
f, err := os.Open(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
defer f.Close()
in := bufio.NewReader(f)
for xp := left + fontsize; rerr == nil; y += linespacing {
line, rerr = in.ReadString('\n')
if len(line) > 0 {
line, ic = svgtext(xp, y, line[0:len(line)-1])
if !ic && syntax {
line = keyword(line, gokwfmt, gokw)
line = keyword(line, svgofmt, svgokw)
}
io.WriteString(canvas.Writer, line)
}
}
if codeframe {
canvas.Rect(top, left, left+boxwidth, y, framestyle)
}
}
// keyword styles keywords in a line of code
func keyword(line string, style string, kw []string) string {
for _, k := range kw {
line = strings.Replace(line, k, fmt.Sprintf(kwfmt, style, k), 1)
}
return line
}
// svgtext
func svgtext(x, y int, s string) (string, bool) {
var iscomment = false
s = strings.Replace(s, "&", "&amp;", -1)
s = strings.Replace(s, "<", "&lt;", -1)
s = strings.Replace(s, ">", "&gt;", -1)
s = strings.Replace(s, "\t", " ", -1)
if syntax {
i := strings.Index(s, "// ")
if i >= 0 {
iscomment = true
s = strings.Replace(s, s[i:], fmt.Sprintf(commentfmt, s[i:]), 1)
}
}
return fmt.Sprintf(textfmt, x, y, s), iscomment
}
// placepic places the picture on the right
func placepic(x, y int, basename string) {
var s SVG
f, err := os.Open(basename + ".svg")
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
defer f.Close()
if err := xml.NewDecoder(f).Decode(&s); err != nil {
fmt.Fprintf(os.Stderr, "Unable to parse (%v)\n", err)
return
}
canvas.Text(x, height-10, basename+".go", fmt.Sprintf(labelfmt, font, fontsize*2))
canvas.Group(`clip-path="url(#pic)"`, fmt.Sprintf(`transform="translate(%d,%d)"`, x, y))
canvas.ClipPath(`id="pic"`)
canvas.Rect(0, 0, s.Width, s.Height)
canvas.ClipEnd()
io.WriteString(canvas.Writer, s.Doc)
canvas.Gend()
if picframe {
canvas.Rect(x, y, s.Width, s.Height, framestyle)
}
}
// init initializes flags
func init() {
flag.BoolVar(&codeframe, "codeframe", false, "frame the code")
flag.BoolVar(&picframe, "picframe", false, "frame the picture")
flag.BoolVar(&syntax, "syntax", false, "syntax coloring")
flag.IntVar(&width, "w", 1024, "width")
flag.IntVar(&height, "h", 768, "height")
flag.IntVar(&linespacing, "ls", 16, "linespacing")
flag.IntVar(&fontsize, "fs", 14, "fontsize")
flag.IntVar(&top, "top", 20, "top")
flag.IntVar(&left, "left", 20, "left")
flag.IntVar(&boxwidth, "boxwidth", 450, "boxwidth")
flag.StringVar(&font, "font", "Inconsolata", "font name")
flag.Parse()
}
// for every file, make a code+pic SVG file
func main() {
for _, f := range flag.Args() {
codepic(f)
}
}

89
vendor/github.com/ajstarks/svgo/colortab/colortab.go generated vendored Normal file
View File

@ -0,0 +1,89 @@
// colortab -- make a color/code placemat
// +build !appengine
package main
import (
"bufio"
"flag"
"fmt"
"os"
"strings"
"github.com/ajstarks/svgo"
)
func main() {
var (
canvas = svg.New(os.Stdout)
filename = flag.String("f", "svgcolors.txt", "input file")
fontname = flag.String("font", "Calibri,sans-serif", "fontname")
outline = flag.Bool("o", false, "outline")
neg = flag.Bool("n", false, "negative")
showrgb = flag.Bool("rgb", false, "show RGB")
showcode = flag.Bool("showcode", true, "only show colors")
circsw = flag.Bool("circle", true, "circle swatch")
fontsize = flag.Int("fs", 12, "fontsize")
width = flag.Int("w", 1600, "width")
height = flag.Int("h", 900, "height")
rowsize = flag.Int("r", 32, "rowsize")
colw = flag.Int("c", 320, "column size")
swatch = flag.Int("s", 16, "swatch size")
gutter = flag.Int("g", 11, "gutter")
err error
colorfmt, tcolor, line string
)
flag.Parse()
f, oerr := os.Open(*filename)
if oerr != nil {
fmt.Fprintf(os.Stderr, "%v\n", oerr)
return
}
canvas.Start(*width, *height)
canvas.Title("SVG Color Table")
if *neg {
canvas.Rect(0, 0, *width, *height, "fill:black")
tcolor = "white"
} else {
canvas.Rect(0, 0, *width, *height, "fill:white")
tcolor = "black"
}
top := 32
left := 32
in := bufio.NewReader(f)
canvas.Gstyle(fmt.Sprintf("font-family:%s;font-size:%dpt;fill:%s",
*fontname, *fontsize, tcolor))
for x, y, nr := left, top, 0; err == nil; nr++ {
line, err = in.ReadString('\n')
fields := strings.Split(strings.TrimSpace(line), "\t")
if nr%*rowsize == 0 && nr > 0 {
x += *colw
y = top
}
if len(fields) == 3 {
colorfmt = "fill:" + fields[1]
if *outline {
colorfmt = colorfmt + ";stroke-width:1;stroke:" + tcolor
}
if *circsw {
canvas.Circle(x, y, *swatch/2, colorfmt)
} else {
canvas.CenterRect(x, y, *swatch, *swatch, colorfmt)
}
canvas.Text(x+*swatch+*fontsize/2, y+(*swatch/4), fields[0], "stroke:none")
var label string
if *showcode {
if *showrgb {
label = fields[1]
} else {
label = fields[2]
}
canvas.Text(x+((*colw*4)/5), y+(*swatch/4), label, "text-anchor:end;fill:gray")
}
}
y += (*swatch + *gutter)
}
canvas.Gend()
canvas.End()
}

147
vendor/github.com/ajstarks/svgo/colortab/svgcolors.txt generated vendored Executable file
View File

@ -0,0 +1,147 @@
aliceblue #F0F8FF 240,248,255
antiquewhite #FAEBD7 250,235,215
aqua #00FFFF 0,255,25
aquamarine #7FFFD4 127,255,21
azure #F0FFFF 240,255,255
beige #F5F5DC 245,245,220
bisque #FFE4C4 255,228,196
black #000000 0,0,0
blanchedalmond #FFEBCD 255,235,205
blue #0000FF 0,0,255
blueviolet #8A2BE2 138,43,226
brown #A52A2A 165,42,42
burlywood #DEB887 222,184,135
cadetblue #5F9EA0 95,158,160
chartreuse #7FFF00 127,255,0
chocolate #D2691E 210,105,30
coral #FF7F50 255,127,80
cornflowerblue #6495ED 100,149,237
cornsilk #FFF8DC 255,248,220
crimson #DC143C 220,20,60
cyan #00FFFF 0,255,255
darkblue #00008B 0,0,139
darkcyan #008B8B 0,139,139
darkgoldenrod #B8860B 184,134,11
darkgray #A9A9A9 169,169,169
darkgreen #006400 0,100,0
darkgrey #A9A9A9 169,169,169
darkkhaki #BDB76B 189,183,107
darkmagenta #8B008B 139,0,139
darkolivegreen #556B2F 85,107,47
darkorange #FF8C00 255,140,0
darkorchid #9932CC 153,50,204
darkred #8B0000 139,0,0
darksalmon #E9967A 233,150,122
darkseagreen #8FBC8F 143,188,143
darkslateblue #483D8B 72,61,139
darkslategray #2F4F4F 47,79,79
darkslategrey #2F4F4F 47,79,79
darkturquoise #00CED1 0,206,209
darkviolet #9400D3 148,0,211
deeppink #FF1493 255,20,147
deepskyblue #00BFFF 0,191,255
dimgray #696969 105,105,105
dimgrey #696969 105,105,105
dodgerblue #1E90FF 30,144,255
firebrick #B22222 178,34,34
floralwhite #FFFAF0 255,250,240
forestgreen #228B22 34,139,34
fuchsia #FF00FF 255,0,255
gainsboro #DCDCDC 220,220,220
ghostwhite #F8F8FF 248,248,255
gold #FFD700 255,215,0
goldenrod #DAA520 218,165,32
gray #808080 128,128,128
green #008000 0,128,0
greenyellow #ADFF2F 173,255,47
grey #808080 128,128,128
honeydew #F0FFF0 240,255,240
hotpink #FF69B4 255,105,180
indianred #CD5C5C 205,92,92
indigo #4B0082 75,0,130
ivory #FFFFF0 255,255,240
khaki #F0E68C 240,230,140
lavender #E6E6FA 230,230,250
lavenderblush #FFF0F5 255,240,245
lawngreen #7CFC00 124,252,0
lemonchiffon #FFFACD 255,250,205
lightblue #ADD8E6 173,216,230
lightcoral #F08080 240,128,128
lightcyan #E0FFFF 224,255,255
lightgoldenrodyellow #FAFAD2 250,250,210
lightgray #D3D3D3 211,211,211
lightgreen #90EE90 144,238,144
lightgrey #D3D3D3 211,211,211
lightpink #FFB6C1 255,182,193
lightsalmon #FFA07A 255,160,122
lightseagreen #20B2AA 32,178,170
lightskyblue #87CEFA 135,206,250
lightslategray #778899 119,136,153
lightslategrey #778899 119,136,153
lightsteelblue #B0C4DE 176,196,222
lightyellow #FFFFE0 255,255,224
lime #00FF00 0,255,0
limegreen #32CD32 50,205,50
linen #FAF0E6 250,240,230
magenta #FF00FF 255,0,255
maroon #800000 128,0,0
mediumaquamarine #66CDAA 102,205,170
mediumblue #0000CD 0,0,205
mediumorchid #BA55D3 186,85,211
mediumpurple #9370DB 147,112,219
mediumseagreen #3CB371 60,179,113
mediumslateblue #7B68EE 123,104,238
mediumspringgreen #00FA9A 0,250,154
mediumturquoise #48D1CC 72,209,204
mediumvioletred #C71585 199,21,133
midnightblue #191970 25,25,112
mintcream #F5FFFA 245,255,250
mistyrose #FFE4E1 255,228,225
moccasin #FFE4B5 255,228,181
navajowhite #FFDEAD 255,222,173
navy #000080 0,0,128
oldlace #FDF5E6 253,245,230
olive #808000 128,128,0
olivedrab #6B8E23 107,142,35
orange #FFA500 255,165,0
orangered #FF4500 255,69,0
orchid #DA70D6 218,112,214
palegoldenrod #EEE8AA 238,232,170
palegreen #98FB98 152,251,152
paleturquoise #AFEEEE 175,238,238
palevioletred #DB7093 219,112,147
papayawhip #FFEFD5 255,239,213
peachpuff #FFDAB9 255,218,185
peru #CD853F 205,133,63
pink #FFC0CB 255,192,203
plum #DDA0DD 221,160,221
powderblue #B0E0E6 176,224,230
purple #800080 128,0,128
red #FF0000 255,0,0
rosybrown #BC8F8F 188,143,143
royalblue #4169E1 65,105,225
saddlebrown #8B4513 139,69,19
salmon #FA8072 250,128,114
sandybrown #F4A460 244,164,96
seagreen #2E8B57 46,139,87
seashell #FFF5EE 255,245,238
sienna #A0522D 160,82,45
silver #C0C0C0 192,192,192
skyblue #87CEEB 135,206,235
slateblue #6A5ACD 106,90,205
slategray #708090 112,128,144
slategrey #708090 112,128,144
snow #FFFAFA 255,250,250
springgreen #00FF7F 0,255,127
steelblue #4682B4 70,130,180
tan #D2B48C 210,180,140
teal #008080 0,128,128
thistle #D8BFD8 216,191,216
tomato #FF6347 255,99,71
turquoise #40E0D0 64,224,208
violet #EE82EE 238,130,238
wheat #F5DEB3 245,222,179
white #FFFFFF 255,255,255
whitesmoke #F5F5F5 245,245,245
yellow #FFFF00 255,255,0
yellowgreen #9ACD32 154,205,50

16
vendor/github.com/ajstarks/svgo/compx/comps.xml generated vendored Executable file
View File

@ -0,0 +1,16 @@
<components gutter="50" top="50" left="50" gc="black">
<comp id="plain" name="Plain" row="0" col="0" width="200" height="120" shape="plain"/>
<comp id="comp" name="Widget" row="0" col="1" width="200" height="120" shape="" sw="Dignus\nHere" os="Widget/OS"/>
<comp id="folder" name="Folder" row="0" col="2" width="200" height="120" shape="folder" sw="Nonsense" os="Stuff" />
<comp id="screen" name="Tablet" row="1" col="0" width="200" height="120" shape="screen" sw="Dignus Here" os="Widget/OS" />
<comp id="desktop" name="Desktop" row="1" col="1" width="200" height="120" shape="desktop" sw="Workstation" os="Computer" />
<comp id="db" name="Data" row="1" col="2" width="200" height="120" shape="db" sw="database" />
<comp id="server" name="Server" row="2" col="0" width="200" height="120" shape="server"/>
<comp id="cloud" name="Cloud" row="2" col="1" width="200" height="120" shape="cloud" />
<comp id="message" name="Envelope" row="2" col="2" width="200" height="120" shape="message" os="message"/>
<comp id="face" name="Face" row="3" col="0" width="200" height="120" shape="face"/>
<comp id="role" name="A Role" row="3" col="1" width="200" height="120" shape="role"/>
</components>

894
vendor/github.com/ajstarks/svgo/compx/compx.go generated vendored Normal file
View File

@ -0,0 +1,894 @@
// compx: display components and connections on a grid, given a XML description
// +build !appengine
package main
import (
"encoding/xml"
"flag"
"fmt"
"github.com/ajstarks/svgo"
"io"
"math"
"os"
"strconv"
"strings"
"time"
)
// Component XML structures
type Component struct {
Top int `xml:"top,attr"`
Left int `xml:"left,attr"`
Gutter int `xml:"gutter,attr"`
Gw int `xml:"gw,attr"`
Gh int `xml:"gh,attr"`
Gc string `xml:"gc,attr"`
Legend []legend `xml:"legend"`
Note []note `xml:"note"`
Group []group `xml:"group"`
Comp []comp `xml:"comp"`
}
type group struct {
Brow int `xml:"brow,attr"`
Bcol int `xml:"bcol,attr"`
Erow int `xml:"erow,attr"`
Ecol int `xml:"ecol,attr"`
Width int `xml:"width,attr"`
Height int `xml:"height,attr"`
Label string `xml:"label,attr"`
Color string `xml:"color,attr"`
Opacity float64 `xml:"opacity,attr"`
}
type note struct {
Row int `xml:"row,attr"`
Col int `xml:"col,attr"`
Width int `xml:"width,attr"`
Height int `xml:"height,attr"`
Size int `xml:"size,attr"`
Spacing int `xml:"spacing,attr"`
Align string `xml:"align,attr"`
Nitem []nitem `xml:"nitem"`
}
type legend struct {
Title string `xml:"title,attr"`
Row int `xml:"row,attr"`
Col int `xml:"col,attr"`
Width int `xml:"width,attr"`
Height int `xml:"height,attr"`
Size int `xml:"size,attr"`
Litem []litem `xml:"litem"`
}
type comp struct {
Id string `xml:"id,attr"`
Col int `xml:"col,attr"`
Row int `xml:"row,attr"`
Width int `xml:"width,attr"`
Height int `xml:"height,attr"`
Name string `xml:"name,attr"`
Os string `xml:"os,attr"`
Sw string `xml:"sw,attr"`
Color string `xml:"color,attr"`
Shape string `xml:"shape,attr"`
Image string `xml:"image,attr"`
Connect []Connect `xml:"connect"`
}
type litem struct {
Color string `xml:"color,attr"`
Type string `xml:"type,attr"`
Label string `xml:",chardata"`
}
type nitem struct {
Color string `xml:"color,attr"`
Align string `xml:"align,attr"`
Text string `xml:",chardata"`
}
// Connect defines connections
type Connect struct {
Sloc string `xml:"sloc,attr"`
Dloc string `xml:"dloc,attr"`
Dest string `xml:"dest,attr"`
Mark string `xml:"mark,attr"`
Color string `xml:"color,attr"`
Dir string `xml:"dir,attr"`
Label string `xml:",chardata"`
}
type gcomp struct {
x, y, w, h int
}
var (
width, height, fontscale int
linesize, labelfs, notchsize, groupmargin int
showtitle, showtimestamp, roundbox, arc, italiclabel bool
title, bgcolor, guide string
gridw = 0
gridh = 0
globalcolor = "black"
canvas = svg.New(os.Stdout)
)
const (
lcolor = "rgb(190,190,190)"
boxradius = 10
lopacity = "1.0"
defcolor = "black"
linefmt = "stroke:%s;fill:none"
globalstyle = "font-family:Calibri,sans-serif;font-size:%dpx;fill:black;text-anchor:middle;stroke-linecap:round;stroke-width:%dpx;stroke-opacity:%s"
ltstyle = "text-anchor:%s;fill:black"
legendstyle = "text-anchor:start;fill:black;font-size:%dpx"
gridstyle = "fill:none; stroke:gray; stroke-opacity:0.3"
notefmt = "font-size:%dpx"
ntfmt = "text-anchor:%s;fill:%s"
)
func background(fc string) { canvas.Rect(0, 0, width, height, "fill:"+fc) }
// docomp does XML file processing
func docomp(location string) {
var f *os.File
var err error
if len(location) > 0 {
f, err = os.Open(location)
} else {
f = os.Stdin
}
if err == nil {
readcomp(f)
f.Close()
} else {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
}
// readcomp reads the XML into the component data structure
func readcomp(r io.Reader) {
var c Component
if err := xml.NewDecoder(r).Decode(&c); err == nil {
drawc(c)
} else {
fmt.Fprintf(os.Stderr, "Unable to parse components (%v)\n", err)
}
}
// drawc interprets the compoment data structure, and displays it
func drawc(c Component) {
gridw = c.Gw
gridh = c.Gh
if len(c.Gc) == 0 {
globalcolor = c.Gc
} else {
globalcolor = c.Gc
}
// Groups
for _, group := range c.Group {
dogroup(group, c.Top, c.Left, c.Gutter)
}
// Legends
for _, leg := range c.Legend {
dolegend(leg, c.Top, c.Left, c.Gutter, labelfs, labelfs+4)
}
// Notes
for _, note := range c.Note {
donote(note, c.Top, c.Left, c.Gutter)
}
// Components
for _, x := range c.Comp {
for _, y := range x.Connect {
connect(gc(x, c.Top, c.Left, c.Gutter), y.Sloc,
lookup(y.Dest, c.Comp, c.Top, c.Left, c.Gutter),
y.Dloc, y.Label, y.Mark, y.Dir, y.Color)
}
display(x, c.Top, c.Left, c.Gutter)
}
if len(guide) > 0 {
grid(c.Top, c.Left, c.Gutter)
}
if showtitle {
dotitle(c.Left, 30, title)
}
if showtimestamp {
timestamp(30)
}
}
// lookup returns a graphic object given an id
func lookup(id string, c []comp, t, l, g int) gcomp {
var x gcomp
for _, v := range c {
if id == v.Id {
return gc(v, t, l, g)
}
}
return x
}
// dotitle positions the title relative to the bottom of the drawing
func dotitle(left, offset int, t string) {
canvas.Text(left, height-offset, t, "font-size:200%;text-anchor:start")
}
// timestamp draws a timestamp in the lower right of the drawing
func timestamp(offset int) {
t := time.Now()
canvas.Text(width-offset, height-offset, t.Format(time.ANSIC), "text-anchor:end")
}
// grid displays a grid overlay, useful for determining optimal positioning
func grid(top, left, gutter int) {
gs := strings.SplitN(guide, `x`, 4)
if len(gs) != 4 {
return
}
w, _ := strconv.Atoi(gs[0])
h, _ := strconv.Atoi(gs[1])
nr, _ := strconv.Atoi(gs[2])
nc, _ := strconv.Atoi(gs[3])
canvas.Gstyle(gridstyle)
y := top
for r := 0; r < nr; r++ {
x := left
for c := 0; c < nc; c++ {
canvas.Rect(x, y, w, h)
canvas.Text(x+w/2, y+h/2, fmt.Sprintf("%d,%d", r, c),
"font-size:150%;fill:lightgray;stroke:none")
x += w + gutter
}
y += h + gutter
}
canvas.Gend()
}
// dogroup displays a colored rectangular area
func dogroup(g group, top, left, gutter int) {
margin := groupmargin
bx := colx(g.Bcol, g.Width, gutter, left)
by := rowy(g.Brow, g.Height, gutter, top)
ex := colx(g.Ecol, g.Width, gutter, left)
ey := rowy(g.Erow, g.Height, gutter, top)
gw := (ex + g.Width) - bx
gh := (ey + g.Height) - by
var gop float64
if g.Opacity <= 0 {
gop = 1.0
} else {
gop = g.Opacity
}
canvas.Rect(bx-margin, by-margin, gw+margin*2, gh+margin*2,
fmt.Sprintf("fill-opacity:%.2f;fill:%s", gop, g.Color))
if len(g.Label) > 0 {
canvas.Text(bx+gw/2, by+gh/2, g.Label, "fill:gray")
}
}
// dolegend displays the legend
func dolegend(leg legend, top, left, gutter, fs, ls int) {
if leg.Size > 0 {
fs = leg.Size
ls = fs + 4
}
fsh := fs / 2
x := colx(leg.Col, leg.Width, gutter, left)
y := rowy(leg.Row, leg.Height, gutter, top)
canvas.Gstyle(fmt.Sprintf(legendstyle, fs))
for _, v := range leg.Litem {
if v.Type == "line" {
canvas.Rect(x, y+fs/4, fs, fs/4, "fill:"+v.Color)
} else {
canvas.Square(x, y, fs, "fill:"+v.Color)
}
canvas.Text(x+(fs*2), y+fsh, v.Label, "baseline-shift:-30%")
y += ls
}
canvas.Gend()
}
// donote displays a note
func donote(n note, top, left, gutter int) {
var align, color string
size := n.Size
ls := n.Spacing
x := colx(n.Col, n.Width, gutter, left)
y := rowy(n.Row, n.Height, gutter, top)
if n.Align == "middle" {
y += n.Height / 2
}
if size <= 0 {
size = labelfs
}
if ls == 0 {
ls = size + 2
}
xp := x
canvas.Gstyle(fmt.Sprintf(notefmt, size))
for _, v := range n.Nitem {
switch v.Align {
case "left", "start", "begin":
align = "start"
xp = x
case "right", "end":
align = "end"
xp = x + n.Width
case "middle", "mid", "center":
align = "middle"
xp = x + (n.Width / 2)
default:
align = "start"
xp = x
}
if len(v.Color) == 0 {
color = "black"
} else {
color = v.Color
}
canvas.Text(xp, y, v.Text, fmt.Sprintf(ntfmt, align, color))
y += ls
}
canvas.Gend()
}
// gc computes the components coordinates
func gc(c comp, top, left, gutter int) gcomp {
var g gcomp
// the object and grid dimensions equal, unless explicitly overridden
if gridw > 0 && gridh > 0 {
g.x = colx(c.Col, gridw, gutter, left)
g.y = rowy(c.Row, gridh, gutter, top)
} else {
g.x = colx(c.Col, c.Width, gutter, left)
g.y = rowy(c.Row, c.Height, gutter, top)
}
g.w = c.Width
g.h = c.Height
return g
}
// display a component in the context of the grid
func display(c comp, top, left, gutter int) {
g := gc(c, top, left, gutter)
component(g, c)
}
// component positions and draws a components and its attributes
func component(g gcomp, c comp) {
x := g.x
y := g.y
w := g.w
h := g.h
fs := w / fontscale
fs2 := fs / 2
w2 := w / 2
h3 := h / 3
var boxcolor string
if len(c.Color) == 0 {
boxcolor = globalcolor
} else {
boxcolor = c.Color
}
rectstyle := fmt.Sprintf("stroke:%s;stroke-width:1;fill:%s", boxcolor, boxcolor)
if len(c.Image) > 0 {
canvas.Image(x, y, w, h, c.Image)
if len(c.Name) > 0 {
canvas.Text(x+w2, y+h/3, c.Name,
fmt.Sprintf("font-size:%dpx;fill:%s;baseline-shift:50%%", fs, boxcolor))
}
return
}
if strings.HasPrefix(c.Shape, "#") {
uselibrary(x, y, w, h, c.Shape)
return
}
switch c.Shape {
case "mobile", "screen":
screen(x, y, w, h, 10, boxcolor, bgcolor)
canvas.Gstyle(fmt.Sprintf("font-size:%dpx", fs))
canvas.Text(x+w/2, y+h/3, c.Name)
if len(c.Os) > 0 {
canvas.Text(x+w/2, y+h3+fs+2, c.Os, "font-size:60%")
}
if len(c.Sw) > 0 {
canvas.Text(x+w/2, y+h3+fs*2, c.Sw, "font-size:75%")
}
canvas.Gend()
case "server":
server(x, y, w, h, 10, boxcolor, lcolor)
canvas.Text(x+w/2, y+h-10, c.Name, fmt.Sprintf("font-size:%dpx;fill:white", fs))
case "desktop":
l := h / 20
desktop(x, y, w, h, l, boxcolor, bgcolor)
canvas.Gstyle(fmt.Sprintf("font-size:%dpx", fs))
canvas.Text(x+w/2, y+h/3, c.Name)
if len(c.Os) > 0 {
canvas.Text(x+w/2, y+h3+fs+2, c.Os, "font-size:60%")
}
if len(c.Sw) > 0 {
canvas.Text(x+w/2, y+h3+fs*2, c.Sw, "font-size:75%")
}
canvas.Gend()
case "message":
l := h / 20
pmy := h / 8
message(x, y, w, h, l, lcolor, boxcolor)
canvas.Gstyle(fmt.Sprintf("font-size:%dpx;fill:white", fs))
if len(c.Os) > 0 {
canvas.Text(x+w2, y+pmy+fs, c.Os, "font-size:75%")
}
canvas.Text(x+w2, y+h-10, c.Name, fmt.Sprintf("font-size:%dpx;fill:%s", fs, bgcolor))
canvas.Gend()
case "cloud":
r := w / 3
xc := (x + w/2) + r/4
yc := y + h/2
cloud(xc, yc, r, boxcolor)
canvas.Text(xc-(r/4), yc+r/2, c.Name, fmt.Sprintf("font-size:%dpx;fill:white", fs))
case "db":
cylinder(x, y+(h/4), w, h-(h/2), h/4, lcolor, boxcolor)
canvas.Text(x+w2, y+h3, c.Name, fmt.Sprintf("font-size:%dpx;fill:white", fs))
if len(c.Sw) > 0 {
canvas.Text(x+w2, y+2*h3, c.Sw, "font-size:75%")
}
case "folder":
l := w / 10
folder(x, y, w, h, l, boxcolor, lcolor)
yp := y + h/2
canvas.Gstyle(fmt.Sprintf("font-size:%dpx;fill:white", fs))
canvas.Text(x+w/2, yp, c.Name)
if len(c.Os) > 0 {
canvas.Text(x+w/2, yp+fs+2, c.Os, "font-size:60%")
}
if len(c.Sw) > 0 {
canvas.Text(x+w/2, yp+fs*2, c.Sw, "font-size:75%")
}
canvas.Gend()
case "face":
fr := (w / 4) - (fs / 2) // (h*3)/8
face(x+w/2, y+h/2, fr, linesize, boxcolor, bgcolor)
canvas.Text(x+w/2, y+(h/2)+fr+15, c.Name, fmt.Sprintf("font-size:%dpx;fill:black", fs))
case "role":
role(x, y, w, h, boxcolor)
canvas.Text(x+w/2, y+h-5, c.Name, fmt.Sprintf("font-size:%dpx;fill:%s", fs, bgcolor))
case "eaec":
l := w / 10
eaec(x, y, w, h, l, boxcolor, bgcolor)
canvas.Text(x+w/2, y+h-5, c.Name, fmt.Sprintf("font-size:%dpx;fill:%s", fs, bgcolor))
case "plain":
if roundbox {
canvas.Roundrect(x, y, w, h, fs2, fs2, rectstyle)
} else {
canvas.Rect(x, y, w, h, rectstyle)
}
canvas.Text(x+w2, y+(h/2), c.Name, fmt.Sprintf("font-size:%dpx;fill:white;baseline-shift:-25%%", fs))
default:
canvas.Rect(x, y, w, h3, rectstyle)
canvas.Rect(x, y+h3, w, h-h3, "fill:white;stroke-width:1;stroke:gray")
canvas.Gstyle(fmt.Sprintf("font-size:%dpx", fs))
canvas.Text(x+w2, y+h3, c.Name, "fill:white;baseline-shift:50%")
canvas.Text(x+w2, y+h3+fs2, c.Os, "font-size:60%")
wordstack(x+w2, (y+h)-fs2, fs, strings.Split(c.Sw, `\n`), "fill-opacity:0.75;font-size:75%")
canvas.Gend()
}
}
// uselibrary draws a previously defined object
func uselibrary(x, y, w, h int, name string) {
canvas.Use(x, y, name, fmt.Sprintf(`width="%d"`, w), fmt.Sprintf(`height="%d"`, h))
}
// Object functions
func cylinder(x, y, w, h, eh int, fill, tfill string) {
f := "fill:" + fill
tf := "fill:" + tfill
canvas.Rect(x, y, w, h, f)
canvas.Ellipse(x+w/2, y+h, w/2, eh, f)
canvas.Ellipse(x+w/2, y, w/2, eh, tf)
}
// folder object
func folder(x, y, w, h, l int, bcolor, color string) {
nl := w / 10
xl := x + nl
xw := x + w
yl := y + nl
yh := y + h
l2 := nl * 2
l3 := nl * 3
lh := nl / 2
var (
xn = []int{xl, xl + l2, xl + l3, xw, xw, xl}
yn = []int{y, y, y + lh, y + lh, yh, yh}
xf = []int{xw, xw - l, x, x + l}
yf = []int{yh, yl + lh, yl + lh, yh}
)
canvas.Polygon(xn, yn, "fill:"+color)
canvas.Polygon(xf, yf, "fill:"+bcolor)
}
// cloud object
func cloud(x, y, r int, style string) {
small := r / 2
medium := (r * 6) / 10
canvas.Gstyle("fill:" + style)
canvas.Circle(x, y, r)
canvas.Circle(x+r, y+small, small)
canvas.Circle(x-r-small, y+small, small)
canvas.Circle(x-r, y, medium)
canvas.Rect(x-r-small, y, r*2+small, r)
canvas.Gend()
}
// message object
func message(x, y, w, h, l int, bcolor, scolor string) {
et := h / 3
w2 := w / 2
px := w / 8
py := h / 8
e1x := []int{x, x, x + w, x + w, x + w2, x}
e1y := []int{y + et, y + h, y + h, y + et, y + (et * 2), y + et}
e2x := []int{x, x + w2, x + w, x + w2, x}
e2y := []int{y + et, y, y + et, y + (et * 2), y + et}
canvas.Polygon(e2x, e2y, "fill:"+bcolor)
canvas.Polygon(e1x, e1y, "fill:"+scolor)
canvas.Roundrect(x+px, y+py, w-(px*2), h-py, l, l, "fill:"+scolor)
canvas.Line(x, y+et, x+w2, y+(et*2), "stroke-width:1;stroke:"+bcolor)
canvas.Line(x+w, y+et, x+w2, y+(et*2), "stroke-width:1;stroke:"+bcolor)
}
// eaec person object
func eaec(x, y, w, h, l int, scolor, bcolor string) {
wu := w / 8
hu := h / 12
wh := w / 2
hh := h / 2
sx := []int{x + wu*2, x + wu*6, x + wh}
sy := []int{y + hu*6, y + hu*6, y + hu*11}
tx := []int{x + wh, x + wh + wu, x + wh, x + wh - wu, x + wh}
ty := []int{y + hu*6, y + hu*7, y + hu*10, y + hu*7, y + hu*6}
canvas.Ellipse(x+wh, y+hu*4, wu+wu/2, hu*2, "fill:"+bcolor)
canvas.Roundrect(x+wu, y+hh, w-wu*2, hu*6, l, l, "fill:"+bcolor)
canvas.Polygon(sx, sy, "fill:"+scolor)
canvas.Polygon(tx, ty, "fill:"+bcolor)
}
// screen object
func screen(x, y, w, h, l int, bcolor, color string) {
canvas.Roundrect(x, y, w, h, l, l, "fill:"+bcolor)
canvas.Rect(x+l, y+l, w-(l*2), h-(l*2), "fill:"+color)
}
// kb (keyboard) object
func kb(x, y, w, h, l int, color string) {
var xp = []int{x + l, x, x + w, x + w - l}
var yp = []int{y, y + h, y + h, y}
canvas.Polygon(xp, yp, "fill:"+color)
}
// desktop object
func desktop(x, y, w, h, l int, bcolor, color string) {
screen(x, y, w, h-l*3, l, bcolor, color)
kb(x, y+h-(l*2), w+l, l*2, l*2, bcolor)
}
// face object
func face(x, y, r, l int, color, fcolor string) {
fu := r / 10 // "face unit"
ep := 3 * fu
my := y + ep
canvas.Circle(x, y, r, fmt.Sprintf("fill:%s;stroke-width:%dpx;stroke:%s", fcolor, l, color))
canvas.Circle(x+ep, y-ep, r/10, "fill:"+color)
canvas.Circle(x-ep, y-ep, r/10, "fill:"+color)
canvas.Qbez(x+ep, my, x, y+ep*2, x-ep, my, fmt.Sprintf("fill:%s;stroke-width:%dpx;stroke:%s", color, l, color))
}
// server object
func server(x, y, w, h, l int, bcolor, color string) {
var xp = []int{x + (l * 2), (x + w) - (l * 2), (x + w) - l, x + l}
var yp = []int{y, y, y + l, y + l}
canvas.Polygon(xp, yp, "fill:"+color)
canvas.Roundrect(x, y+l, w, h-l, 5, 5, "fill:"+bcolor)
canvas.Gstyle("stroke:" + color)
yl := y + (l / 2) + h/4
spacing := w / 5
for r := 0; r < 2; r++ {
xl := x + l
for c := 0; c < 2; c++ {
canvas.Line(xl, yl, xl+spacing, yl)
xl += spacing + 10
}
yl += h / 4
}
canvas.Gend()
canvas.Circle((x+w)-l, y+h/2, l/2, "fill:"+color)
}
// role object
func role(x, y, w, h int, color string) {
hs := h / 20
var xp = []int{x, x, x + w/3, x + w/2, x + (w / 2) + (w / 6), x + w, x + w}
var yp = []int{y + h, y + (16 * hs), y + (12 * hs), y + (14 * hs), y + (12 * hs), y + (16 * hs), y + h}
// var xp = []int{x, x, x + w/2, x + w, x + w}
// var yp = []int{y + h, y + (h5 * 4), y + (h5 * 2), y + (h5 * 4), y + h}
canvas.Gstyle("fill:" + color)
canvas.Polygon(xp, yp)
canvas.Ellipse(x+w/2, (y + h/3), w/5, h/3) // "stroke:white;stroke-width:2")
canvas.Gend()
}
// sloper computes the slope and r of a line
func sloper(x1, y1, x2, y2 int) (m, r float64) {
dy := float64(y1 - y2)
dx := float64(x1 - x2)
m = dy / dx
r = math.Atan2(dy, dx) * (180 / math.Pi)
return m, r
}
// rowy computes the y position of a row
func rowy(n, h, g, t int) int { return t + (n * g) + (n * h) }
// colx computes the x position of a column
func colx(n, w, g, l int) int { return l + (n * g) + (n * w) }
// compass returns the coordinates of a compass point
func compass(g gcomp, point string) (cx, cy int, dir string) {
switch point {
case "nw":
cx, cy, dir = g.x, g.y, "r"
case "nnw":
cx, cy, dir = g.x+g.w/4, g.y, "d"
case "nne":
cx, cy, dir = (g.x+g.w)-(g.w/4), g.y, "d"
case "n":
cx, cy, dir = g.x+(g.w/2), g.y, "d"
case "ne":
cx, cy, dir = g.x+g.w, g.y, "l"
case "w":
cx, cy, dir = g.x, g.y+g.h/2, "r"
case "wnw":
cx, cy, dir = g.x, g.y+g.h/4, "r"
case "wsw":
cx, cy, dir = g.x, (g.y+g.h)-(g.h/4), "r"
case "ese":
cx, cy, dir = g.x+g.w, (g.y+g.h)-(g.h/4), "l"
case "ene":
cx, cy, dir = g.x+g.w, g.y+(g.h/4), "l"
case "c":
cx, cy, dir = g.x+(g.w/2), g.y+(g.h/2), "n"
case "e":
cx, cy, dir = g.x+g.w, g.y+(g.h/2), "l"
case "sw":
cx, cy, dir = g.x, g.y+g.h, "r"
case "ssw":
cx, cy, dir = g.x+(g.w/4), g.y+g.h, "u"
case "sse":
cx, cy, dir = (g.x+g.w)-(g.w/4), g.y+g.h, "u"
case "s":
cx, cy, dir = g.x+(g.w/2), g.y+g.h, "u"
case "se":
cx, cy, dir = g.x+g.w, g.y+g.h, "l"
}
return cx, cy, dir
}
// connect two components
func connect(c1 gcomp, p1 string, c2 gcomp, p2 string, label string, mark string, dir string, color string) {
x1, y1, d1 := compass(c1, p1)
x2, y2, d2 := compass(c2, p2)
linelabel(x1, y1, x2, y2, label, mark, d1, d2, dir, color)
}
// linestyle returns the style for lines
func linestyle(color string) string {
return fmt.Sprintf(linefmt, color)
}
// linelabel determines the connection and arrow geometry
func linelabel(x1, y1, x2, y2 int, label string, mark string, d1 string, d2 string, dir string, color string) {
aw := linesize * 4
ah := linesize * 3
if len(color) == 0 {
color = lcolor
}
switch mark {
case "b":
lx1, ly1 := arrow(x1, y1, aw, ah, d1, color)
lx2, ly2 := arrow(x2, y2, aw, ah, d2, color)
doline(lx1, ly1, lx2, ly2, linestyle(color), dir, label)
case "s":
lx1, ly1 := arrow(x1, y1, aw, ah, d1, color)
doline(lx1, ly1, x2, y2, linestyle(color), dir, label)
case "d":
lx2, ly2 := arrow(x2, y2, aw, ah, d2, color)
doline(x1, y1, lx2, ly2, linestyle(color), dir, label)
default:
doline(x1, y1, x2, y2, linestyle(color), dir, label)
}
}
// doline draws a line between to coordinates
func doline(x1, y1, x2, y2 int, style, direction, label string) {
var labelstyle string
var upflag bool
if italiclabel {
labelstyle = "font-style:italic;"
}
tadjust := 6
mx := (x2 - x1) / 2
my := (y2 - y1) / 2
lx := x1 + mx
ly := y1 + my
m, _ := sloper(x1, y1, x2, y2)
hline := m == 0
vline := m == math.Inf(-1) || m == math.Inf(1)
straight := hline || vline
switch {
case m < 0: // upwards line
upflag = true
labelstyle += "text-anchor:end;"
lx -= tadjust
case hline: // horizontal line
labelstyle += "text-anchor:middle;baseline-shift:20%;"
ly -= tadjust
case m > 0: // downwards line
upflag = false
labelstyle += "text-anchor:start;"
lx += tadjust
}
if arc && !straight {
cx, cy := x1, y2 // initial control points
// fmt.Fprintf(os.Stderr, "%s slope = %.3f\n", label, m)
if upflag {
if direction == "ccw" {
cx, cy = x2, y1
} else {
cx, cy = x1, y2
}
} else {
if direction == "ccw" {
cx, cy = x1, y2
} else {
cx, cy = x2, y1
}
}
canvas.Qbez(x1, y1, cx, cy, x2, y2, style)
labelstyle += "text-anchor:middle"
canvas.Text(lx, ly, label, labelstyle)
} else {
canvas.Line(x1, y1, x2, y2, style)
canvas.Text(lx, ly, label, labelstyle) // midpoint
}
}
// wordstack displays text in a left-justified stack
func wordstack(x, y, fs int, s []string, style ...string) {
ls := fs + 2
for i := len(s); i > 0; i-- {
canvas.Text(x, y, s[i-1], style...)
y -= ls
}
}
// arrow constructs line-ending arrows according to connecting points
func arrow(x, y, w, h int, dir string, color string) (xl, yl int) {
var xp = []int{x, x, x, x}
var yp = []int{y, y, y, y}
n := notchsize
switch dir {
case "r":
xp[1] = x - w
yp[1] = y - h/2
xp[2] = (x - w) + n
yp[2] = y
xp[3] = x - w
yp[3] = y + h/2
xl, yl = xp[2], y
case "l":
xp[1] = x + w
yp[1] = y - h/2
xp[2] = (x + w) - n
yp[2] = y
xp[3] = x + w
yp[3] = y + h/2
xl, yl = xp[2], y
case "u":
xp[1] = x - w/2
yp[1] = y + h
xp[2] = x
yp[2] = (y + h) - n
xp[3] = x + w/2
yp[3] = y + h
xl, yl = x, yp[2]
case "d":
xp[1] = x - w/2
yp[1] = y - h
xp[2] = x
yp[2] = (y - h) + n
xp[3] = x + w/2
yp[3] = y - h
xl, yl = x, yp[2]
}
canvas.Polygon(xp, yp, "fill:"+color+";fill-opacity:"+lopacity)
return xl, yl
}
// init processes command line arguments
func init() {
flag.IntVar(&width, "w", 1024, "width")
flag.IntVar(&height, "h", 768, "height")
flag.IntVar(&linesize, "l", 4, "line weight")
flag.IntVar(&labelfs, "lf", 16, "label font size (px)")
flag.IntVar(&fontscale, "f", 10, "font scaling factor")
flag.IntVar(&notchsize, "n", 0, "arrow notch size")
flag.IntVar(&groupmargin, "gm", 10, "group margin")
flag.StringVar(&bgcolor, "bg", "white", "background color")
flag.StringVar(&title, "t", "comp grid", "title")
flag.BoolVar(&italiclabel, "il", false, "italic labels")
flag.BoolVar(&showtitle, "showtitle", false, "Show the title")
flag.BoolVar(&showtimestamp, "time", false, "Show a timestamp")
flag.BoolVar(&roundbox, "roundbox", false, "make boxes round")
flag.BoolVar(&arc, "arc", false, "use arcs to connect")
flag.StringVar(&guide, "g", "", "grid guide: WxHxRxC")
flag.Parse()
}
// for every file (or stdin) make a component diagram
func main() {
canvas.Start(width, height)
canvas.Title(title)
background(bgcolor)
canvas.Gstyle(fmt.Sprintf(globalstyle, labelfs, linesize, lopacity))
if len(flag.Args()) == 0 {
docomp("")
} else {
for _, f := range flag.Args() {
docomp(f)
}
}
canvas.Gend()
canvas.End()
}

69
vendor/github.com/ajstarks/svgo/compx/testcomp.xml generated vendored Executable file
View File

@ -0,0 +1,69 @@
<!-- compx test pattern -->
<components gutter="20" top="20" left="20" gc="black">
<legend row="3" col="0" width="200" height="120">
<litem color="rgb(0,0,0)">Component</litem>
<litem color="rgb(127,127,127)">Another Thing</litem>
</legend>
<legend row="4" col="1" width="200" height="120">
<litem color="rgb(0,127,0)" type="line">Public</litem>
<litem color="rgb(127,127,127)" type="line">Confidential</litem>
<litem color="rgb(0,0,127)" type="line">Restricted</litem>
<litem color="rgb(127,0,0)" type="line">Highly Restricted</litem>
</legend>
<note row="0" col="4" width="200" height="120" size="16" align="middle">
<nitem align="center" color="red">Note</nitem>
<nitem align="left">This is the test pattern for compx</nitem>
<nitem>for best results, set the width to be</nitem>
<nitem>at least 1300</nitem>
<nitem></nitem>
<nitem align="right" color="red">the management</nitem>
</note>
<note row="5" col="0" width="200" height="120" size="30">
<nitem>Here is another Note</nitem>
<nitem color="blue">This one is bigger</nitem>
</note>
<note>
<nitem>a stupid note</nitem>
<nitem>you did not specify anything</nitem>
</note>
<group brow="0" bcol="0" erow="4" ecol="3" width="200" height="120" color="lightgray"/>
<group brow="2" bcol="0" erow="2" ecol="4" width="200" height="120" color="lightsteelblue"/>
<group brow="0" bcol="3" erow="4" ecol="3" width="200" height="120" color="gray"/>
<comp id="screen" name="Tablet" row="3" col="4" width="200" height="120" sw="Dignus Here" os="Widget/OS" shape="screen"/>
<comp id="face" name="Face it" row="0" col="3" width="200" height="120" shape="face"></comp>
<comp id="role" name="A Role" row="4" col="3" width="200" height="120" shape="role" color="steelblue" />
<comp id="center" name="Envelope" row="2" col="2" width="200" height="120" shape="message" os="message" color="maroon" />
<comp id="dummy" name="Widget" row="4" col="4" width="200" height="120" sw="Dignus\nHere" os="Widget/OS" />
<comp id="cloud" name="Internet" row="4" col="0" width="200" height="120" sw="C" os="mid" color="gray" shape="cloud" />
<comp id="null" name="Nameless" row="1" col="0" width="200" height="60" sw="foo" shape="plain">
<connect mark="d" sloc="s" dloc="n" dest="west" />
</comp>
<comp id="north" name="North" row="0" col="2" width="200" height="120" sw="N" os="top" shape="db">
<connect mark="d" dest="center" sloc="ssw" dloc="nnw" color="rgb(127,0,0)">[1]</connect>
<connect mark="d" dest="center" sloc="s" dloc="n" color="rgb(127,0,0)">[2]</connect>
<connect mark="d" dest="center" sloc="sse" dloc="nne" color="rgb(127,0,0)">[3]</connect>
<connect mark="d" dest="east" sloc="e" dloc="n">North to East</connect>
</comp>
<comp id="west" name="West" row="2" col="0" width="200" height="120" sw="W" os="left" shape="server">
<connect mark="d" dest="center" sloc="ne" dloc="nw" color="rgb(0,0,127)">[4]</connect>
<connect mark="d" dest="center" sloc="ene" dloc="wnw" color="rgb(0,0,127)">[5]</connect>
<connect mark="d" dest="center" sloc="e" dloc="w" color="rgb(0,0,127)">[6]</connect>
<connect mark="d" dest="center" sloc="ese" dloc="wsw" color="rgb(0,0,127)">[7]</connect>
<connect mark="d" dest="center" sloc="se" dloc="sw" color="rgb(0,0,127)">[8]</connect>
<connect mark="d" dest="north" sloc="n" dloc="w">West to North</connect>
</comp>
<comp id="south" name="South" row="4" col="2" width="200" height="120" sw="S" os="bottom" color="gray" shape="folder">
<connect mark="d" dest="center" sloc="nnw" dloc="ssw" color="rgb(0,127,0)">[9]</connect>
<connect mark="d" dest="center" sloc="n" dloc="s" color="rgb(0,127,0)">[10]</connect>
<connect mark="d" dest="center" sloc="nne" dloc="sse" color="rgb(0,127,0)">[11]</connect>
<connect mark="d" dest="west" sloc="w" dloc="s">South to West</connect>
</comp>
<comp id="east" name="East" row="2" col="4" width="200" height="120" sw="E" os="right" shape="desktop">
<connect mark="d" dest="center" sloc="nw" dloc="ne" color="rgb(0,0,127)">[12]</connect>
<connect mark="d" dest="center" sloc="wnw" dloc="ene" color="rgb(0,0,127)">[13]</connect>
<connect mark="d" dest="center" sloc="w" dloc="e" color="rgb(0,0,127)">[14]</connect>
<connect mark="d" dest="center" sloc="wsw" dloc="ese" color="rgb(0,0,127)">[15]</connect>
<connect mark="d" dest="center" sloc="sw" dloc="se" color="rgb(0,0,127)">[16]</connect>
<connect mark="d" dest="south" sloc="s" dloc="e">East to South</connect>
</comp>
</components>

71
vendor/github.com/ajstarks/svgo/cube/cube.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
// cube: draw cubes
package main
import (
"crypto/rand"
"flag"
"fmt"
"os"
"github.com/ajstarks/svgo"
)
var canvas = svg.New(os.Stdout)
// randcolor returns a random color
func randcolor() string {
rgb := []byte{0, 0, 0} // read error returns black
rand.Read(rgb)
return fmt.Sprintf("fill:rgb(%d,%d,%d)", rgb[0], rgb[1], rgb[2])
}
// rcube makes a cube with three visible faces, each with a random color
func rcube(x, y, l int) {
tx := []int{x, x + (l * 3), x, x - (l * 3), x}
ty := []int{y, y + (l * 2), y + (l * 4), y + (l * 2), y}
lx := []int{x - (l * 3), x, x, x - (l * 3), x - (l * 3)}
ly := []int{y + (l * 2), y + (l * 4), y + (l * 8), y + (l * 6), y + (l * 2)}
rx := []int{x + (l * 3), x + (l * 3), x, x, x + (l * 3)}
ry := []int{y + (l * 2), y + (l * 6), y + (l * 8), y + (l * 4), y + (l * 2)}
canvas.Polygon(tx, ty, randcolor())
canvas.Polygon(lx, ly, randcolor())
canvas.Polygon(rx, ry, randcolor())
}
// lattice draws a grid of cubes, n rows deep.
// The grid begins at (xp, yp), with hspace between cubes in a row, and vspace between rows.
func lattice(xp, yp, w, h, size, hspace, vspace, n int, bgcolor string) {
if bgcolor == "" {
canvas.Rect(0, 0, w, h, randcolor())
} else {
canvas.Rect(0, 0, w, h, "fill:"+bgcolor)
}
y := yp
for r := 0; r < n; r++ {
for x := xp; x < w; x += hspace {
rcube(x, y, size)
}
y += vspace
}
}
func main() {
var (
width = flag.Int("w", 600, "canvas width")
height = flag.Int("h", 600, "canvas height")
x = flag.Int("x", 60, "begin x location")
y = flag.Int("y", 60, "begin y location")
size = flag.Int("size", 20, "cube size")
rows = flag.Int("rows", 3, "rows")
hs = flag.Int("hs", 120, "horizontal spacing")
vs = flag.Int("vs", 160, "vertical spacing")
bg = flag.String("bg", "", "background")
)
flag.Parse()
canvas.Start(*width, *height)
lattice(*x, *y, *width, *height, *size, *hs, *vs, *rows, *bg)
canvas.End()
}

120
vendor/github.com/ajstarks/svgo/f50/f50.go generated vendored Normal file
View File

@ -0,0 +1,120 @@
// f50 -- given a search term, display 10x5 image grid, sorted by interestingness
// +build !appengine
package main
import (
"encoding/xml"
"fmt"
"net/http"
"net/url"
"os"
"github.com/ajstarks/svgo"
)
// FlickrResp defines the Flickr response
type FlickrResp struct {
Stat string `xml:"stat,attr"`
Photos Photos `xml:"photos"`
}
// Photos defines a set of Flickr photos
type Photos struct {
Page string `xml:"page,attr"`
Pages string `xml:"pages,attr"`
Perpage string `xml:"perpage,attr"`
Total string `xml:"total,attr"`
Photo []Photo `xml:"photo"`
}
// Photo defines a Flickr photo
type Photo struct {
Id string `xml:"id,attr"`
Owner string `xml:"owner,attr"`
Secret string `xml:"secret,attr"`
Server string `xml:"server,attr"`
Farm string `xml:"farm,attr"`
Title string `xml:"title,attr"`
Ispublic string `xml:"ispublic,attr"`
Isfriend string `xml:"isfriend,attr"`
IsFamily string `xml:"isfamily,attr"`
}
var (
width = 805
height = 500
canvas = svg.New(os.Stdout)
)
const (
apifmt = "https://api.flickr.com/services/rest/?method=%s&api_key=%s&%s=%s&per_page=50&sort=interestingness-desc"
urifmt = "http://farm%s.static.flickr.com/%s/%s.jpg"
apiKey = "YOURKEY"
textStyle = "font-family:Calibri,sans-serif; font-size:48px; fill:white; text-anchor:start"
imageWidth = 75
imageHeight = 75
)
// FlickrAPI calls the API given a method with single name/value pair
func flickrAPI(method, name, value string) string {
return fmt.Sprintf(apifmt, method, apiKey, name, value)
}
// makeURI converts the elements of a photo into a Flickr photo URI
func makeURI(p Photo, imsize string) string {
im := p.Id + "_" + p.Secret
if len(imsize) > 0 {
im += "_" + imsize
}
return fmt.Sprintf(urifmt, p.Farm, p.Server, im)
}
// imageGrid reads the response from Flickr, and creates a grid of images
func imageGrid(f FlickrResp, x, y, cols, gutter int, imgsize string) {
if f.Stat != "ok" {
fmt.Fprintf(os.Stderr, "Status: %v\n", f.Stat)
return
}
xpos := x
for i, p := range f.Photos.Photo {
if i%cols == 0 && i > 0 {
xpos = x
y += (imageHeight + gutter)
}
canvas.Link(makeURI(p, ""), p.Title)
canvas.Image(xpos, y, imageWidth, imageHeight, makeURI(p, "s"))
canvas.LinkEnd()
xpos += (imageWidth + gutter)
}
}
// fs calls the Flickr API to perform a photo search
func fs(s string) {
var f FlickrResp
r, weberr := http.Get(flickrAPI("flickr.photos.search", "text", s))
if weberr != nil {
fmt.Fprintf(os.Stderr, "%v\n", weberr)
return
}
defer r.Body.Close()
xmlerr := xml.NewDecoder(r.Body).Decode(&f)
if xmlerr != nil || r.StatusCode != http.StatusOK {
fmt.Fprintf(os.Stderr, "%v (status=%d)\n", xmlerr, r.StatusCode)
return
}
canvas.Title(s)
imageGrid(f, 5, 5, 10, 5, "s")
canvas.Text(20, height-40, s, textStyle)
}
// for each search term on the commandline, create a photo grid
func main() {
for i := 1; i < len(os.Args); i++ {
canvas.Start(width, height)
canvas.Rect(0, 0, width, height, "fill:black")
fs(url.QueryEscape(os.Args[i]))
canvas.End()
}
}

53
vendor/github.com/ajstarks/svgo/fe/fe.go generated vendored Normal file
View File

@ -0,0 +1,53 @@
// fe: SVG Filter Effect example from http://www.w3.org/TR/SVG/filters.html#AnExample
// +build !appengine
package main
import (
"github.com/ajstarks/svgo"
"os"
)
func main() {
canvas := svg.New(os.Stdout)
width := 410
height := 120
canvas.Start(width, height)
canvas.Title(`SVGo Filter Example`)
canvas.Desc(`Combines multiple filter primitives to produce a 3D lighting effect`)
gfs := svg.Filterspec{In: "SourceAlpha", Result: "blur"}
ofs := svg.Filterspec{In: "blur", Result: "offsetBlur"}
sfs := svg.Filterspec{In: "blur", Result: "specOut"}
cfs1 := svg.Filterspec{In: "specOut", In2: "SourceAlpha", Result: "specOut"}
cfs2 := svg.Filterspec{In: "SourceGraphic", In2: "specOut", Result: "litPaint"}
// define the filters
canvas.Def()
canvas.Filter("myFilter")
canvas.FeGaussianBlur(gfs, 4, 4)
canvas.FeOffset(ofs, 4, 4)
canvas.FeSpecularLighting(sfs, 5, .75, 20, "#bbbbbb")
canvas.FePointLight(-5000, -10000, 20000)
canvas.FeSpecEnd()
canvas.FeComposite(cfs1, "in", 0, 0, 0, 0)
canvas.FeComposite(cfs2, "arithmetic", 0, 1, 1, 0)
canvas.FeMerge([]string{ofs.Result, cfs2.Result})
canvas.Fend()
canvas.DefEnd()
// specify the graphic
canvas.Gid("SVG")
canvas.Path("M50,90 C0,90 0,30 50,30 L150,30 C200,30 200,90 150,90 z", "fill:none;stroke:#D90000;stroke-width:10")
canvas.Path("M60,80 C30,80 30,40 60,40 L140,40 C170,40 170,80 140,80 z", "fill:#D90000")
canvas.Text(52, 76, "SVG", "fill:white;stroke:black;font-size:45;font-family:Verdana")
canvas.Gend()
canvas.Rect(0, 0, width, height, "stroke:black;fill:white")
canvas.Use(0, 0, "#SVG") // plain graphic
canvas.Use(200, 0, "#SVG", `filter="url(#myFilter)"`) // filter applied
canvas.End()
}

634
vendor/github.com/ajstarks/svgo/float/README.md generated vendored Normal file
View File

@ -0,0 +1,634 @@
#SVGo: A Go library for SVG generation#
The library generates SVG as defined by the Scalable Vector Graphics 1.1 Specification (<http://www.w3.org/TR/SVG11/>).
Output goes to the specified io.Writer, operation occur with Go's float64 type.
## Supported SVG elements and functions ##
### Shapes, lines, text
circle, ellipse, polygon, polyline, rect (including roundrects), line, text
### Paths
general, arc, cubic and quadratic bezier paths,
### Image and Gradients
image, linearGradient, radialGradient,
### Transforms ###
translate, rotate, scale, skewX, skewY
### Filter Effects
filter, feBlend, feColorMatrix, feColorMatrix, feComponentTransfer, feComposite, feConvolveMatrix, feDiffuseLighting,
feDisplacementMap, feDistantLight, feFlood, feGaussianBlur, feImage, feMerge, feMorphology, feOffset, fePointLight,
feSpecularLighting, feSpotLight,feTile, feTurbulence
### Metadata elements ###
desc, defs, g (style, transform, id), marker, mask, pattern, title, (a)ddress, link, script, use
## Building and Usage ##
See svgdef.[svg|png|pdf] for a graphical view of the function calls
Usage: (assuming GOPATH is set)
go get github.com/ajstarks/svgo/float
You can use godoc to browse the documentation from the command line:
$ go doc github.com/ajstarks/svgo/float
a minimal program, to generate SVG to standard output.
package main
import (
"github.com/ajstarks/svgo/float"
"os"
)
func main() {
width := 500.0
height := 500.0
canvas := svg.New(os.Stdout)
canvas.Start(width, height)
canvas.Circle(width/2, height/2, 100)
canvas.Text(width/2, height/2, "Hello, SVG", "text-anchor:middle;font-size:30px;fill:white")
canvas.End()
}
Drawing in a web server: (http://localhost:2003/circle)
package main
import (
"log"
"github.com/ajstarks/svgo/float"
"net/http"
)
func main() {
http.Handle("/circle", http.HandlerFunc(circle))
err := http.ListenAndServe(":2003", nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
func circle(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "image/svg+xml")
s := svg.New(w)
s.Start(500, 500)
s.Circle(250, 250, 125, "fill:none;stroke:black")
s.End()
}
You may view the SVG output with a browser that supports SVG (tested on Chrome, Opera, Firefox and Safari), or any other SVG user-agent such as Batik Squiggle.
### Graphics Sketching with SVGo and svgplay ###
Combined with the svgplay command, SVGo can be used to "sketch" with code in a browser.
To use svgplay and SVGo, first go to a directory with your code, and run:
$ svgplay -f # use the floating point version
2014/06/25 22:05:28 ☠ ☠ ☠ Warning: this server allows a client connecting to 127.0.0.1:1999 to execute code on this computer ☠ ☠ ☠
Next open your browser to the svgplay server you just started.
svgplay only listens on localhost, and uses port 1999 (guess which year SVG was first introduced) by default
http://localhost:1999/
Enter your code in the textarea, and when you are ready to run press Shift--Enter. The code will be compiled, with the results
on the right. To update, change the code and repeat. Note that compilation errors are shown in red under the code. In order for svgplay/SVGo to work, make sure that the io.Writer specified with the New function is os.Stdout.
If you want to sketch with an existing file, enter its URL:
http://localhost:1999/foo.go
![SVGplay](https://farm4.staticflickr.com/3859/14322978157_31c0114850.jpg)
### SVGo Papers and presentations ###
* SVGo paper from SVGOpen 2011 <http://www.svgopen.org/2011/papers/34-SVGo_a_Go_Library_for_SVG_generation>
* Programming Pictures with SVGo <https://speakerdeck.com/u/ajstarks/p/programming-pictures-with-svgo>
* SVGo Workshop <https://speakerdeck.com/u/ajstarks/p/svgo-workshop>
* The Other Side of Go: Programming Pictures <https://www.youtube.com/watch?v=nuDO1oQxARs>
## Functions and types ##
Many functions use x, y to specify an object's location, and w, h to specify the object's width and height.
Where applicable, a final optional argument specifies the style to be applied to the object.
The style strings follow the SVG standard; name:value pairs delimited by semicolons, or a
series of name="value" pairs. For example: `"fill:none; opacity:0.3"` or `fill="none" opacity="0.3"` (see: <http://www.w3.org/TR/SVG11/styling.html>)
The SVG type:
type SVG struct {
Writer io.Writer
Decimals int
}
Most operations are methods on this type, specifying the destination io.Writer and decimal precision.
The Offcolor type:
type Offcolor struct {
Offset uint8
Color string
Opacity float64
}
is used to specify the offset, color, and opacity of stop colors in linear and radial gradients
The Filterspec type:
type Filterspec struct {
In string
In2 string
Result string
}
is used to specify inputs and results for filter effects
### Structure, Scripting, Metadata, Transformation and Links ###
New(w io.Writer) *SVG
Constructor, Specify the output destination, and the number of digits after the decimal point (default 2)
Start(w float64, h float64, attributes ...string)
begin the SVG document with the width w and height h. Optionally add additional elements
(such as additional namespaces or scripting events)
<http://www.w3.org/TR/SVG11/struct.html#SVGElement>
Startview(w, h, minx, miny, vw, vh float64)
begin the SVG document with the width w, height h, with a viewBox at minx, miny, vw, vh.
<http://www.w3.org/TR/SVG11/struct.html#SVGElement>
Startunit(w float64, h float64, unit string, ns ...string)
begin the SVG document, with width and height in the specified units. Optionally add additional elements
(such as additional namespaces or scripting events)
<http://www.w3.org/TR/SVG11/struct.html#SVGElement>
Startpercent(w float64, h float64, ns ...string)
begin the SVG document, with width and height in percent. Optionally add additional elements
(such as additional namespaces or scripting events)
<http://www.w3.org/TR/SVG11/struct.html#SVGElement>
StartviewUnit(w, h float64, unit string, minx, miny, vw, vh float64)
begin the SVG document with the width w, height h, in the specified unit, with a viewBox at minx, miny, vw, vh.
<http://www.w3.org/TR/SVG11/struct.html#SVGElement>
End()
end the SVG document
Script(scriptype string, data ...string)
Script defines a script with a specified type, (for example "application/javascript").
if the first variadic argument is a link, use only the link reference.
Otherwise, treat variadic arguments as the text of the script (marked up as CDATA).
if no data is specified, simply close the script element.
<http://www.w3.org/TR/SVG/script.html>
Group(s ...string)
begin a group, with arbitrary attributes
<http://www.w3.org/TR/SVG11/struct.html#GElement>
Gstyle(s string)
begin a group, with the specified style.
<http://www.w3.org/TR/SVG11/struct.html#GElement>
Gid(s string)
begin a group, with the specified id.
Gtransform(s string)
begin a group, with the specified transform, end with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
Translate(x, y float64)
begins coordinate translation to (x,y), end with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
Scale(n float64)
scales the coordinate system by n, end with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
ScaleXY(x, y float64)
scales the coordinate system by x, y. End with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
SkewX(a float64)
SkewX skews the x coordinate system by angle a, end with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
SkewY(a float64)
SkewY skews the y coordinate system by angle a, end with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
SkewXY(ax, ay float64)
SkewXY skews x and y coordinate systems by ax, ay respectively, end with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
Rotate(r float64)
rotates the coordinate system by r degrees, end with Gend().
<http://www.w3.org/TR/SVG11/coords.html#TransformAttribute>
TranslateRotate(x, y float64, r float64)
translates the coordinate system to (x,y), then rotates to r degrees, end with Gend().
RotateTranslate(x, y float64, r float64)
rotates the coordinate system r degrees, then translates to (x,y), end with Gend().
Gend()
end the group (must be paired with Gstyle, Gtransform, Gid).
ClipPath(s ...string)
Begin a ClipPath
<http://www.w3.org/TR/SVG/masking.html#ClippingPaths>
ClipEnd()
End a ClipPath
<http://www.w3.org/TR/SVG/masking.html#ClippingPaths>
Def()
begin a definition block.
<http://www.w3.org/TR/SVG11/struct.html#DefsElement>
DefEnd()
end a definition block.
Marker(id string, x, y, w, h float64, s ...string)
define a marker
<http://www.w3.org/TR/SVG11/painting.html#MarkerElement>
MarkerEnd()
end a marker
Mask(id string, x float64, y float64, w float64, h float64, s ...string)
creates a mask with a specified id, dimension, and optional style.
<http://www.w3.org/TR/SVG/masking.html>
MaskEnd()
ends the Mask element.
Pattern(id string, x, y, width, height float64, putype string, s ...string)
define a Pattern with the specified dimensions, the putype can be either "user" or "obj", which sets the patternUnits
attribute to be either userSpaceOnUse or objectBoundingBox.
<http://www.w3.org/TR/SVG11/pservers.html#Patterns>
Desc(s string)
specify the text of the description.
<http://www.w3.org/TR/SVG11/struct.html#DescElement>
Title(s string)
specify the text of the title.
<http://www.w3.org/TR/SVG11/struct.html#TitleElement>
Link(href string, title string)
begin a link named "href", with the specified title.
<http://www.w3.org/TR/SVG11/linking.html#Links>
LinkEnd()
end the link.
Use(x float64, y float64, link string, s ...string)
place the object referenced at link at the location x, y.
<http://www.w3.org/TR/SVG11/struct.html#UseElement>
### Shapes ###
Circle(x float64, y float64, r float64, s ...string)
draw a circle, centered at x,y with radius r.
<http://www.w3.org/TR/SVG11/shapes.html#CircleElement>
![Circle](http://farm5.static.flickr.com/4144/5187953823_01a1741489_m.jpg)
Ellipse(x float64, y float64, w float64, h float64, s ...string)
draw an ellipse, centered at x,y with radii w, and h.
<http://www.w3.org/TR/SVG11/shapes.html#EllipseElement>
![Ellipse](http://farm2.static.flickr.com/1271/5187953773_a9d1fc406c_m.jpg)
Polygon(x []int, y []int, s ...string)
draw a series of line segments using an array of x, y coordinates.
<http://www.w3.org/TR/SVG11/shapes.html#PolygonElement>
![Polygon](http://farm2.static.flickr.com/1006/5187953873_337dc26597_m.jpg)
Rect(x float64, y float64, w float64, h float64, s ...string)
draw a rectangle with upper left-hand corner at x,y, with width w, and height h.
<http://www.w3.org/TR/SVG11/shapes.html#RectElement>
![Rect](http://farm2.static.flickr.com/1233/5188556032_86c90e354b_m.jpg)
CenterRect(x float64, y float64, w float64, h float64, s ...string)
draw a rectangle with its center at x,y, with width w, and height h.
Roundrect(x float64, y float64, w float64, h float64, rx float64, ry float64, s ...string)
draw a rounded rectangle with upper the left-hand corner at x,y,
with width w, and height h. The radii for the rounded portion
is specified by rx (width), and ry (height).
![Roundrect](http://farm2.static.flickr.com/1275/5188556120_e2a9998fee_m.jpg)
Square(x float64, y float64, s float64, style ...string)
draw a square with upper left corner at x,y with sides of length s.
![Square](http://farm5.static.flickr.com/4110/5187953659_54dcce242e_m.jpg)
### Paths ###
Path(p string, s ...style)
draw the arbitrary path as specified in p, according to the style specified in s. <http://www.w3.org/TR/SVG11/paths.html>
Arc(sx float64, sy float64, ax float64, ay float64, r float64, large bool, sweep bool, ex float64, ey float64, s ...string)
draw an elliptical arc beginning coordinate at sx,sy, ending coordinate at ex, ey
width and height of the arc are specified by ax, ay, the x axis rotation is r
if sweep is true, then the arc will be drawn in a "positive-angle" direction (clockwise),
if false, the arc is drawn counterclockwise.
if large is true, the arc sweep angle is greater than or equal to 180 degrees,
otherwise the arc sweep is less than 180 degrees.
<http://www.w3.org/TR/SVG11/paths.html#PathDataEllipticalArcCommands>
![Arc](http://farm2.static.flickr.com/1300/5188556148_df1a176074_m.jpg)
Bezier(sx float64, sy float64, cx float64, cy float64, px float64, py float64, ex float64, ey float64, s ...string)
draw a cubic bezier curve, beginning at sx,sy, ending at ex,ey
with control points at cx,cy and px,py.
<http://www.w3.org/TR/SVG11/paths.html#PathDataCubicBezierCommands>
![Bezier](http://farm2.static.flickr.com/1233/5188556246_a03e67d013.jpg)
Qbezier(sx float64, sy float64, cx float64, cy float64, ex float64, ey float64, tx float64, ty float64, s ...string)
draw a quadratic bezier curve, beginning at sx, sy, ending at tx,ty
with control points are at cx,cy, ex,ey.
<http://www.w3.org/TR/SVG11/paths.html#PathDataQuadraticBezierCommands>
![Qbezier](http://farm2.static.flickr.com/1018/5187953917_9a43cf64fb.jpg)
Qbez(sx float64, sy float64, cx float64, cy float64, ex float64, ey float64, s...string)
draws a quadratic bezier curver, with optional style beginning at sx,sy, ending at ex, sy
with the control point at cx, cy.
<http://www.w3.org/TR/SVG11/paths.html#PathDataQuadraticBezierCommands>
![Qbez](http://farm6.static.flickr.com/5176/5569879349_5f726aab5e.jpg)
### Lines ###
Line(x1 float64, y1 float64, x2 float64, y2 float64, s ...string)
draw a line segment between x1,y1 and x2,y2.
<http://www.w3.org/TR/SVG11/shapes.html#LineElement>
![Line](http://farm5.static.flickr.com/4154/5188556080_0be19da0bc.jpg)
Polyline(x []int, y []int, s ...string)
draw a polygon using coordinates specified in x,y arrays.
<http://www.w3.org/TR/SVG11/shapes.html#PolylineElement>
![Polyline](http://farm2.static.flickr.com/1266/5188556384_a863273a69.jpg)
### Image and Text ###
Image(x float64, y float64, w float64, h float64, link string, s ...string)
place at x,y (upper left hand corner), the image with width w, and height h, referenced at link.
<http://www.w3.org/TR/SVG11/struct.html#ImageElement>
![Image](http://farm5.static.flickr.com/4058/5188556346_e5ce3dcbc2_m.jpg)
Text(x float64, y float64, t string, s ...string)
Place the specified text, t at x,y according to the style specified in s.
<http://www.w3.org/TR/SVG11/text.html#TextElement>
Textlines(x, y float64, s []string, size, spacing float64, fill, align string)
Places lines of text in s, starting at x,y, at the specified size, fill, and alignment, and spacing.
Textpath(t string, pathid string, s ...string)
places optionally styled text along a previously defined path.
<http://www.w3.org/TR/SVG11/text.html#TextPathElement>
![Image](http://farm4.static.flickr.com/3149/5694580737_4b291df768_m.jpg)
### Color ###
RGB(r float64, g float64, b float64) string
creates a style string for the fill color designated
by the (r)ed, g(reen), (b)lue components.
<http://www.w3.org/TR/css3-color/>
RGBA(r float64, g float64, b float64, a float64) string
as above, but includes the color's opacity as a value
between 0.0 (fully transparent) and 1.0 (opaque).
### Gradients ###
LinearGradient(id string, x1, y1, x2, y2 uint8, sc []Offcolor)
constructs a linear color gradient identified by id,
along the vector defined by (x1,y1), and (x2,y2).
The stop color sequence defined in sc. Coordinates are expressed as percentages.
<http://www.w3.org/TR/SVG11/pservers.html#LinearGradients>
![LinearGradient](http://farm5.static.flickr.com/4153/5187954033_3972f63fa9.jpg)
RadialGradient(id string, cx, cy, r, fx, fy uint8, sc []Offcolor)
constructs a radial color gradient identified by id,
centered at (cx,cy), with a radius of r.
(fx, fy) define the location of the focal point of the light source.
The stop color sequence defined in sc.
Coordinates are expressed as percentages.
<http://www.w3.org/TR/SVG11/pservers.html#RadialGradients>
![RadialGradient](http://farm2.static.flickr.com/1302/5187954065_7ddba7b819.jpg)
### Filter Effects ###
Filter(id string, s ...string)
Filter begins a filter set
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#FilterElement>
Fend()
Fend ends a filter set
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#FilterElement>
FeBlend(fs Filterspec, mode string, s ...string)
FeBlend specifies a Blend filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feBlendElement>
FeColorMatrix(fs Filterspec, values [20]float64, s ...string)
FeColorMatrix specifies a color matrix filter primitive, with matrix values
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement>
FeColorMatrixHue(fs Filterspec, value float64, s ...string)
FeColorMatrix specifies a color matrix filter primitive, with hue values
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement>
FeColorMatrixSaturate(fs Filterspec, value float64, s ...string)
FeColorMatrix specifies a color matrix filter primitive, with saturation values
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement>
FeColorMatrixLuminence(fs Filterspec, s ...string)
FeColorMatrix specifies a color matrix filter primitive, with luminence values
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement>
FeComponentTransfer()
FeComponentTransfer begins a feComponent filter Element>
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement>
FeCompEnd()
FeCompEnd ends a feComponent filter Element>
FeComposite(fs Filterspec, operator string, k1, k2, k3, k4 float64, s ...string)
FeComposite specifies a feComposite filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feCompositeElement>
FeConvolveMatrix(fs Filterspec, matrix [9]int, s ...string)
FeConvolveMatrix specifies a feConvolveMatrix filter primitive
Standard referencd: <http://www.w3.org/TR/SVG11/filters.html#feConvolveMatrixElement>
FeDiffuseLighting(fs Filterspec, scale, constant float64, s ...string)
FeDiffuseLighting specifies a diffuse lighting filter primitive,
a container for light source Element>s, end with DiffuseEnd()
FeDiffEnd()
FeDiffuseEnd ends a diffuse lighting filter primitive container
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feDiffuseLightingElement>
FeDisplacementMap(fs Filterspec, scale float64, xchannel, ychannel string, s ...string)
FeDisplacementMap specifies a feDisplacementMap filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feDisplacementMapElement>
FeDistantLight(fs Filterspec, azimuth, elevation float64, s ...string)
FeDistantLight specifies a feDistantLight filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feDistantLightElement>
FeFlood(fs Filterspec, color string, opacity float64, s ...string)
FeFlood specifies a flood filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feFloodElement>
FeFuncLinear(channel string, slope, intercept float64)
FeFuncLinear is the linear form of feFunc
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement>
FeFuncGamma(channel, amplitude, exponent, offset float64)
FeFuncGamma is the gamma curve form of feFunc
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement>
FeFuncTable(channel string, tv []float64)
FeFuncGamma is the form of feFunc using a table of values
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement>
FeFuncDiscrete(channel string, tv []float64)
FeFuncGamma is the form of feFunc using discrete values
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement>
FeGaussianBlur(fs Filterspec, stdx, stdy float64, s ...string)
FeGaussianBlur specifies a Gaussian Blur filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement>
FeImage(href string, result string, s ...string)
FeImage specifies a feImage filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feImageElement>
FeMerge(nodes []string, s ...string)
FeMerge specifies a feMerge filter primitive, containing feMerge Element>s
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feMergeElement>
FeMorphology(fs Filterspec, operator string, xradius, yradius float64, s ...string)
FeMorphologyLight specifies a feMorphologyLight filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feMorphologyElement>
FeOffset(fs Filterspec, dx, dy float64, s ...string)
FeOffset specifies the feOffset filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feOffsetElement>
FePointLight(x, y, z float64, s ...string)
FePointLight specifies a fePpointLight filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#fePointLightElement>
FeSpecularLighting(fs Filterspec, scale, constant float64, exponent float64, color string, s ...string)
FeSpecularLighting specifies a specular lighting filter primitive,
a container for light source elements, end with SpecularEnd()
FeSpecEnd()
FeSpecularEnd ends a specular lighting filter primitive container
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feSpecularLightingElement>
FeSpotLight(fs Filterspec, x, y, z, px, py, pz float64, s ...string)
FeSpotLight specifies a feSpotLight filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feSpotLightElement>
FeTile(fs Filterspec, in string, s ...string)
FeTile specifies the tile utility filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feTileElement>
FeTurbulence(fs Filterspec, ftype string, bfx, bfy float64, octaves float64, seed int64, stitch bool, s ...string)
FeTurbulence specifies a turbulence filter primitive
Standard reference: <http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement>
### Filter convenience functions (modeled on CSS filter effects) ###
Blur(p float64)
Blur function by standard deviation
Brightness(p float64)
Brightness function (0-100)
Grayscale()
Apply a grayscale filter to the image
HueRotate(a float64)
Rotate Hues (0-360 degrees)
Invert()
Invert the image's colors
Saturate(p float64)
Percent saturation, 0 is grayscale
Sepia()
Apply sepia tone
### Utility ###
Grid(x float64, y float64, w float64, h float64, n float64, s ...string)
draws a grid of straight lines starting at x,y, with a width w, and height h, and a size of n.
![Grid](http://farm5.static.flickr.com/4133/5190957924_7a31d0db34.jpg)
### Credits ###
Thanks to Jonathan Wright for the io.Writer update.

125
vendor/github.com/ajstarks/svgo/float/doc.go generated vendored Normal file
View File

@ -0,0 +1,125 @@
/*
Package svg generates SVG as defined by the Scalable Vector Graphics 1.1 Specification (<http://www.w3.org/TR/SVG11/>).
Output goes to the specified io.Writer.
Supported SVG elements and functions
Shapes, lines, text
circle, ellipse, polygon, polyline, rect (including roundrects), line, text
Paths
general, arc, cubic and quadratic bezier paths,
Image and Gradients
image, linearGradient, radialGradient,
Transforms
translate, rotate, scale, skewX, skewY
Filter Effects
filter, feBlend, feColorMatrix, feColorMatrix, feComponentTransfer, feComposite, feConvolveMatrix, feDiffuseLighting,
feDisplacementMap, feDistantLight, feFlood, feGaussianBlur, feImage, feMerge, feMorphology, feOffset, fePointLight,
feSpecularLighting, feSpotLight,feTile, feTurbulence
Metadata elements
desc, defs, g (style, transform, id), mask, marker, pattern, title, (a)ddress, link, script, use
Usage: (assuming GOPATH is set)
go get github.com/ajstarks/svgo/float
You can use godoc to browse the documentation from the command line:
$ go doc github.com/ajstarks/svgo/float
a minimal program, to generate SVG to standard output.
package main
import (
"github.com/ajstarks/svgo/float"
"os"
)
func main() {
width := 500.0
height := 500.0
canvas := svg.New(os.Stdout)
canvas.Start(width, height)
canvas.Circle(width/2, height/2, 100)
canvas.Text(width/2, height/2, "Hello, SVG", "text-anchor:middle;font-size:30px;fill:white")
canvas.End()
}
Drawing in a web server: (http://localhost:2003/circle)
package main
import (
"log"
"github.com/ajstarks/svgo"
"net/http"
)
func main() {
http.Handle("/circle", http.HandlerFunc(circle))
err := http.ListenAndServe(":2003", nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
func circle(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "image/svg+xml")
s := svg.New(w)
s.Start(500, 500)
s.Circle(250, 250, 125, "fill:none;stroke:black")
s.End()
}
Functions and types
Many functions use x, y to specify an object's location, and w, h to specify the object's width and height.
Where applicable, a final optional argument specifies the style to be applied to the object.
The style strings follow the SVG standard; name:value pairs delimited by semicolons, or a
series of name="value" pairs. For example: `"fill:none; opacity:0.3"` or `fill="none" opacity="0.3"` (see: <http://www.w3.org/TR/SVG11/styling.html>)
The SVG type:
type SVG struct {
Writer io.Writer
}
Most operations are methods on this type, specifying the destination io.Writer.
The Offcolor type:
type Offcolor struct {
Offset uint8
Color string
Opacity float64
}
is used to specify the offset, color, and opacity of stop colors in linear and radial gradients
The Filterspec type:
type Filterspec struct {
In string
In2 string
Result string
}
is used to specify inputs and results for filter effects
*/
package svg

1002
vendor/github.com/ajstarks/svgo/float/svg.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More