From 4e6d69e7446a51cc135d4861db1611878f15a7cf Mon Sep 17 00:00:00 2001
From: Derek Parker
Date: Wed, 30 Sep 2015 17:31:01 -0700
Subject: [PATCH] all: Vendor with Godeps & GO15EXPERIMENT
Use godeps to vendor dependencies and the normal go toolchain, with
GO15VENDOREXPERIMENT=1 set to properly vendor dependencies for reproducible
builds.
---
Godeps/Godeps.json | 55 +
Godeps/Readme | 5 +
Makefile | 15 +-
.../cpuguy83/go-md2man/md2man/md2man.go | 19 +
.../cpuguy83/go-md2man/md2man/roff.go | 269 ++
vendor/github.com/davecheney/profile/AUTHORS | 1 +
vendor/github.com/davecheney/profile/LICENSE | 24 +
.../github.com/davecheney/profile/README.md | 50 +
.../github.com/davecheney/profile/profile.go | 169 +
.../davecheney/profile/profile_test.go | 11 +
.../inconshreveable/mousetrap/LICENSE | 13 +
.../inconshreveable/mousetrap/README.md | 23 +
.../inconshreveable/mousetrap/trap_others.go | 15 +
.../inconshreveable/mousetrap/trap_windows.go | 98 +
.../mousetrap/trap_windows_1.4.go | 46 +
vendor/github.com/peterh/liner/COPYING | 21 +
vendor/github.com/peterh/liner/README.md | 99 +
vendor/github.com/peterh/liner/bsdinput.go | 39 +
vendor/github.com/peterh/liner/common.go | 219 ++
.../github.com/peterh/liner/fallbackinput.go | 57 +
vendor/github.com/peterh/liner/input.go | 368 +++
.../github.com/peterh/liner/input_darwin.go | 39 +
vendor/github.com/peterh/liner/input_linux.go | 26 +
vendor/github.com/peterh/liner/input_test.go | 61 +
.../github.com/peterh/liner/input_windows.go | 321 ++
vendor/github.com/peterh/liner/line.go | 884 ++++++
vendor/github.com/peterh/liner/line_test.go | 90 +
vendor/github.com/peterh/liner/output.go | 63 +
.../github.com/peterh/liner/output_windows.go | 54 +
vendor/github.com/peterh/liner/prefix_test.go | 37 +
vendor/github.com/peterh/liner/race_test.go | 44 +
vendor/github.com/peterh/liner/signal.go | 12 +
.../github.com/peterh/liner/signal_legacy.go | 11 +
vendor/github.com/peterh/liner/unixmode.go | 37 +
vendor/github.com/peterh/liner/width.go | 60 +
vendor/github.com/peterh/liner/width_test.go | 102 +
.../russross/blackfriday/.gitignore | 8 +
.../russross/blackfriday/.travis.yml | 17 +
.../github.com/russross/blackfriday/README.md | 246 ++
.../github.com/russross/blackfriday/block.go | 1389 +++++++++
.../russross/blackfriday/block_test.go | 1407 +++++++++
.../github.com/russross/blackfriday/html.go | 948 ++++++
.../github.com/russross/blackfriday/inline.go | 1103 +++++++
.../russross/blackfriday/inline_test.go | 1016 ++++++
.../github.com/russross/blackfriday/latex.go | 332 ++
.../russross/blackfriday/markdown.go | 919 ++++++
.../russross/blackfriday/ref_test.go | 128 +
.../russross/blackfriday/smartypants.go | 398 +++
.../testdata/Amps and angle encoding.html | 17 +
.../testdata/Amps and angle encoding.text | 21 +
.../blackfriday/testdata/Auto links.html | 18 +
.../blackfriday/testdata/Auto links.text | 13 +
.../testdata/Backslash escapes.html | 123 +
.../testdata/Backslash escapes.text | 126 +
.../Blockquotes with code blocks.html | 15 +
.../Blockquotes with code blocks.text | 11 +
.../blackfriday/testdata/Code Blocks.html | 18 +
.../blackfriday/testdata/Code Blocks.text | 14 +
.../blackfriday/testdata/Code Spans.html | 5 +
.../blackfriday/testdata/Code Spans.text | 6 +
...like lines no empty line before block.html | 14 +
...like lines no empty line before block.text | 8 +
...apped paragraphs with list-like lines.html | 8 +
...apped paragraphs with list-like lines.text | 8 +
.../testdata/Horizontal rules.html | 71 +
.../testdata/Horizontal rules.text | 67 +
.../testdata/Inline HTML (Advanced).html | 15 +
.../testdata/Inline HTML (Advanced).text | 15 +
.../testdata/Inline HTML (Simple).html | 72 +
.../testdata/Inline HTML (Simple).text | 69 +
.../testdata/Inline HTML comments.html | 13 +
.../testdata/Inline HTML comments.text | 13 +
.../testdata/Links, inline style.html | 11 +
.../testdata/Links, inline style.text | 12 +
.../testdata/Links, reference style.html | 52 +
.../testdata/Links, reference style.text | 71 +
.../testdata/Links, shortcut references.html | 9 +
.../testdata/Links, shortcut references.text | 20 +
.../testdata/Literal quotes in titles.html | 3 +
.../testdata/Literal quotes in titles.text | 7 +
.../Markdown Documentation - Basics.html | 314 ++
.../Markdown Documentation - Basics.text | 306 ++
.../Markdown Documentation - Syntax.html | 946 ++++++
.../Markdown Documentation - Syntax.text | 888 ++++++
.../testdata/Nested blockquotes.html | 9 +
.../testdata/Nested blockquotes.text | 5 +
.../testdata/Ordered and unordered lists.html | 166 +
.../testdata/Ordered and unordered lists.text | 131 +
.../testdata/Strong and em together.html | 7 +
.../testdata/Strong and em together.text | 7 +
.../russross/blackfriday/testdata/Tabs.html | 26 +
.../russross/blackfriday/testdata/Tabs.text | 21 +
.../blackfriday/testdata/Tidyness.html | 9 +
.../blackfriday/testdata/Tidyness.text | 5 +
.../sanitized_anchor_name/.travis.yml | 10 +
.../shurcooL/sanitized_anchor_name/README.md | 31 +
.../shurcooL/sanitized_anchor_name/main.go | 29 +
.../sanitized_anchor_name/main_test.go | 35 +
vendor/github.com/spf13/cobra/.gitignore | 24 +
vendor/github.com/spf13/cobra/.travis.yml | 9 +
vendor/github.com/spf13/cobra/README.md | 513 ++++
.../spf13/cobra/bash_completions.go | 398 +++
.../spf13/cobra/bash_completions.md | 149 +
.../spf13/cobra/bash_completions_test.go | 87 +
vendor/github.com/spf13/cobra/cobra.go | 170 ++
vendor/github.com/spf13/cobra/cobra_test.go | 1046 +++++++
vendor/github.com/spf13/cobra/command.go | 1146 +++++++
vendor/github.com/spf13/cobra/command_test.go | 114 +
vendor/github.com/spf13/cobra/doc_util.go | 34 +
.../github.com/spf13/cobra/examples_test.go | 34 +
vendor/github.com/spf13/cobra/man_docs.go | 213 ++
vendor/github.com/spf13/cobra/man_docs.md | 25 +
.../github.com/spf13/cobra/man_docs_test.go | 68 +
vendor/github.com/spf13/cobra/md_docs.go | 157 +
vendor/github.com/spf13/cobra/md_docs.md | 81 +
vendor/github.com/spf13/cobra/md_docs_test.go | 67 +
vendor/github.com/spf13/pflag/.travis.yml | 17 +
vendor/github.com/spf13/pflag/LICENSE | 28 +
vendor/github.com/spf13/pflag/README.md | 256 ++
vendor/github.com/spf13/pflag/bool.go | 97 +
vendor/github.com/spf13/pflag/bool_test.go | 180 ++
vendor/github.com/spf13/pflag/count.go | 97 +
vendor/github.com/spf13/pflag/count_test.go | 55 +
vendor/github.com/spf13/pflag/duration.go | 86 +
vendor/github.com/spf13/pflag/example_test.go | 77 +
vendor/github.com/spf13/pflag/export_test.go | 29 +
vendor/github.com/spf13/pflag/flag.go | 836 +++++
vendor/github.com/spf13/pflag/flag_test.go | 874 ++++++
vendor/github.com/spf13/pflag/float32.go | 91 +
vendor/github.com/spf13/pflag/float64.go | 87 +
vendor/github.com/spf13/pflag/golangflag.go | 97 +
.../github.com/spf13/pflag/golangflag_test.go | 39 +
vendor/github.com/spf13/pflag/int.go | 87 +
vendor/github.com/spf13/pflag/int32.go | 91 +
vendor/github.com/spf13/pflag/int64.go | 87 +
vendor/github.com/spf13/pflag/int8.go | 91 +
vendor/github.com/spf13/pflag/int_slice.go | 128 +
.../github.com/spf13/pflag/int_slice_test.go | 162 +
vendor/github.com/spf13/pflag/ip.go | 96 +
vendor/github.com/spf13/pflag/ip_test.go | 63 +
vendor/github.com/spf13/pflag/ipmask.go | 122 +
vendor/github.com/spf13/pflag/ipnet.go | 100 +
vendor/github.com/spf13/pflag/ipnet_test.go | 70 +
vendor/github.com/spf13/pflag/string.go | 82 +
vendor/github.com/spf13/pflag/string_slice.go | 105 +
.../spf13/pflag/string_slice_test.go | 141 +
vendor/github.com/spf13/pflag/uint.go | 91 +
vendor/github.com/spf13/pflag/uint16.go | 89 +
vendor/github.com/spf13/pflag/uint32.go | 89 +
vendor/github.com/spf13/pflag/uint64.go | 91 +
vendor/github.com/spf13/pflag/uint8.go | 91 +
vendor/github.com/spf13/pflag/verify/all.sh | 69 +
vendor/github.com/spf13/pflag/verify/gofmt.sh | 19 +
.../github.com/spf13/pflag/verify/golint.sh | 15 +
vendor/golang.org/x/sys/unix/.gitignore | 1 +
vendor/golang.org/x/sys/unix/asm.s | 10 +
vendor/golang.org/x/sys/unix/asm_darwin_386.s | 29 +
.../golang.org/x/sys/unix/asm_darwin_amd64.s | 29 +
vendor/golang.org/x/sys/unix/asm_darwin_arm.s | 30 +
.../golang.org/x/sys/unix/asm_darwin_arm64.s | 30 +
.../golang.org/x/sys/unix/asm_dragonfly_386.s | 29 +
.../x/sys/unix/asm_dragonfly_amd64.s | 29 +
.../golang.org/x/sys/unix/asm_freebsd_386.s | 29 +
.../golang.org/x/sys/unix/asm_freebsd_amd64.s | 29 +
.../golang.org/x/sys/unix/asm_freebsd_arm.s | 29 +
vendor/golang.org/x/sys/unix/asm_linux_386.s | 35 +
.../golang.org/x/sys/unix/asm_linux_amd64.s | 29 +
vendor/golang.org/x/sys/unix/asm_linux_arm.s | 29 +
.../golang.org/x/sys/unix/asm_linux_arm64.s | 24 +
.../golang.org/x/sys/unix/asm_linux_ppc64x.s | 28 +
vendor/golang.org/x/sys/unix/asm_netbsd_386.s | 29 +
.../golang.org/x/sys/unix/asm_netbsd_amd64.s | 29 +
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s | 29 +
.../golang.org/x/sys/unix/asm_openbsd_386.s | 29 +
.../golang.org/x/sys/unix/asm_openbsd_amd64.s | 29 +
.../golang.org/x/sys/unix/asm_solaris_amd64.s | 17 +
vendor/golang.org/x/sys/unix/constants.go | 13 +
vendor/golang.org/x/sys/unix/creds_test.go | 121 +
vendor/golang.org/x/sys/unix/env_unix.go | 27 +
vendor/golang.org/x/sys/unix/env_unset.go | 14 +
vendor/golang.org/x/sys/unix/export_test.go | 9 +
vendor/golang.org/x/sys/unix/flock.go | 24 +
.../x/sys/unix/flock_linux_32bit.go | 13 +
vendor/golang.org/x/sys/unix/gccgo.go | 46 +
vendor/golang.org/x/sys/unix/gccgo_c.c | 41 +
.../x/sys/unix/gccgo_linux_amd64.go | 20 +
vendor/golang.org/x/sys/unix/mkall.sh | 274 ++
vendor/golang.org/x/sys/unix/mkerrors.sh | 466 +++
vendor/golang.org/x/sys/unix/mksyscall.pl | 323 ++
.../x/sys/unix/mksyscall_solaris.pl | 294 ++
.../golang.org/x/sys/unix/mksysctl_openbsd.pl | 264 ++
.../golang.org/x/sys/unix/mksysnum_darwin.pl | 39 +
.../x/sys/unix/mksysnum_dragonfly.pl | 50 +
.../golang.org/x/sys/unix/mksysnum_freebsd.pl | 63 +
.../golang.org/x/sys/unix/mksysnum_linux.pl | 58 +
.../golang.org/x/sys/unix/mksysnum_netbsd.pl | 58 +
.../golang.org/x/sys/unix/mksysnum_openbsd.pl | 50 +
.../golang.org/x/sys/unix/mmap_unix_test.go | 23 +
vendor/golang.org/x/sys/unix/race.go | 30 +
vendor/golang.org/x/sys/unix/race0.go | 25 +
.../golang.org/x/sys/unix/sockcmsg_linux.go | 36 +
vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 103 +
vendor/golang.org/x/sys/unix/str.go | 26 +
vendor/golang.org/x/sys/unix/syscall.go | 74 +
vendor/golang.org/x/sys/unix/syscall_bsd.go | 565 ++++
.../golang.org/x/sys/unix/syscall_bsd_test.go | 35 +
.../golang.org/x/sys/unix/syscall_darwin.go | 509 ++++
.../x/sys/unix/syscall_darwin_386.go | 79 +
.../x/sys/unix/syscall_darwin_amd64.go | 81 +
.../x/sys/unix/syscall_darwin_arm.go | 73 +
.../x/sys/unix/syscall_darwin_arm64.go | 79 +
.../x/sys/unix/syscall_dragonfly.go | 411 +++
.../x/sys/unix/syscall_dragonfly_386.go | 63 +
.../x/sys/unix/syscall_dragonfly_amd64.go | 63 +
.../golang.org/x/sys/unix/syscall_freebsd.go | 682 +++++
.../x/sys/unix/syscall_freebsd_386.go | 63 +
.../x/sys/unix/syscall_freebsd_amd64.go | 63 +
.../x/sys/unix/syscall_freebsd_arm.go | 63 +
vendor/golang.org/x/sys/unix/syscall_linux.go | 1086 +++++++
.../x/sys/unix/syscall_linux_386.go | 388 +++
.../x/sys/unix/syscall_linux_amd64.go | 146 +
.../x/sys/unix/syscall_linux_arm.go | 233 ++
.../x/sys/unix/syscall_linux_arm64.go | 150 +
.../x/sys/unix/syscall_linux_ppc64x.go | 96 +
.../golang.org/x/sys/unix/syscall_netbsd.go | 492 +++
.../x/sys/unix/syscall_netbsd_386.go | 44 +
.../x/sys/unix/syscall_netbsd_amd64.go | 44 +
.../x/sys/unix/syscall_netbsd_arm.go | 44 +
.../golang.org/x/sys/unix/syscall_no_getwd.go | 11 +
.../golang.org/x/sys/unix/syscall_openbsd.go | 303 ++
.../x/sys/unix/syscall_openbsd_386.go | 44 +
.../x/sys/unix/syscall_openbsd_amd64.go | 44 +
.../golang.org/x/sys/unix/syscall_solaris.go | 713 +++++
.../x/sys/unix/syscall_solaris_amd64.go | 37 +
vendor/golang.org/x/sys/unix/syscall_test.go | 50 +
vendor/golang.org/x/sys/unix/syscall_unix.go | 297 ++
.../x/sys/unix/syscall_unix_test.go | 318 ++
vendor/golang.org/x/sys/unix/types_darwin.go | 250 ++
.../golang.org/x/sys/unix/types_dragonfly.go | 242 ++
vendor/golang.org/x/sys/unix/types_freebsd.go | 353 +++
vendor/golang.org/x/sys/unix/types_linux.go | 399 +++
vendor/golang.org/x/sys/unix/types_netbsd.go | 232 ++
vendor/golang.org/x/sys/unix/types_openbsd.go | 244 ++
vendor/golang.org/x/sys/unix/types_solaris.go | 260 ++
.../x/sys/unix/zerrors_darwin_386.go | 1576 ++++++++++
.../x/sys/unix/zerrors_darwin_amd64.go | 1576 ++++++++++
.../x/sys/unix/zerrors_darwin_arm.go | 1293 ++++++++
.../x/sys/unix/zerrors_darwin_arm64.go | 1576 ++++++++++
.../x/sys/unix/zerrors_dragonfly_386.go | 1530 ++++++++++
.../x/sys/unix/zerrors_dragonfly_amd64.go | 1530 ++++++++++
.../x/sys/unix/zerrors_freebsd_386.go | 1743 +++++++++++
.../x/sys/unix/zerrors_freebsd_amd64.go | 1748 +++++++++++
.../x/sys/unix/zerrors_freebsd_arm.go | 1729 +++++++++++
.../x/sys/unix/zerrors_linux_386.go | 1761 +++++++++++
.../x/sys/unix/zerrors_linux_amd64.go | 1762 +++++++++++
.../x/sys/unix/zerrors_linux_arm.go | 1577 ++++++++++
.../x/sys/unix/zerrors_linux_arm64.go | 1843 +++++++++++
.../x/sys/unix/zerrors_linux_ppc64.go | 1922 ++++++++++++
.../x/sys/unix/zerrors_linux_ppc64le.go | 1921 ++++++++++++
.../x/sys/unix/zerrors_netbsd_386.go | 1712 +++++++++++
.../x/sys/unix/zerrors_netbsd_amd64.go | 1702 +++++++++++
.../x/sys/unix/zerrors_netbsd_arm.go | 1688 ++++++++++
.../x/sys/unix/zerrors_openbsd_386.go | 1584 ++++++++++
.../x/sys/unix/zerrors_openbsd_amd64.go | 1583 ++++++++++
.../x/sys/unix/zerrors_solaris_amd64.go | 1436 +++++++++
.../x/sys/unix/zsyscall_darwin_386.go | 1426 +++++++++
.../x/sys/unix/zsyscall_darwin_amd64.go | 1442 +++++++++
.../x/sys/unix/zsyscall_darwin_arm.go | 1426 +++++++++
.../x/sys/unix/zsyscall_darwin_arm64.go | 1426 +++++++++
.../x/sys/unix/zsyscall_dragonfly_386.go | 1412 +++++++++
.../x/sys/unix/zsyscall_dragonfly_amd64.go | 1412 +++++++++
.../x/sys/unix/zsyscall_freebsd_386.go | 1664 ++++++++++
.../x/sys/unix/zsyscall_freebsd_amd64.go | 1664 ++++++++++
.../x/sys/unix/zsyscall_freebsd_arm.go | 1664 ++++++++++
.../x/sys/unix/zsyscall_linux_386.go | 1618 ++++++++++
.../x/sys/unix/zsyscall_linux_amd64.go | 1812 +++++++++++
.../x/sys/unix/zsyscall_linux_arm.go | 1746 +++++++++++
.../x/sys/unix/zsyscall_linux_arm64.go | 1740 +++++++++++
.../x/sys/unix/zsyscall_linux_ppc64.go | 1782 +++++++++++
.../x/sys/unix/zsyscall_linux_ppc64le.go | 1782 +++++++++++
.../x/sys/unix/zsyscall_netbsd_386.go | 1326 ++++++++
.../x/sys/unix/zsyscall_netbsd_amd64.go | 1326 ++++++++
.../x/sys/unix/zsyscall_netbsd_arm.go | 1326 ++++++++
.../x/sys/unix/zsyscall_openbsd_386.go | 1386 +++++++++
.../x/sys/unix/zsyscall_openbsd_amd64.go | 1386 +++++++++
.../x/sys/unix/zsyscall_solaris_amd64.go | 1559 ++++++++++
.../golang.org/x/sys/unix/zsysctl_openbsd.go | 270 ++
.../x/sys/unix/zsysnum_darwin_386.go | 398 +++
.../x/sys/unix/zsysnum_darwin_amd64.go | 398 +++
.../x/sys/unix/zsysnum_darwin_arm.go | 358 +++
.../x/sys/unix/zsysnum_darwin_arm64.go | 398 +++
.../x/sys/unix/zsysnum_dragonfly_386.go | 304 ++
.../x/sys/unix/zsysnum_dragonfly_amd64.go | 304 ++
.../x/sys/unix/zsysnum_freebsd_386.go | 351 +++
.../x/sys/unix/zsysnum_freebsd_amd64.go | 351 +++
.../x/sys/unix/zsysnum_freebsd_arm.go | 351 +++
.../x/sys/unix/zsysnum_linux_386.go | 355 +++
.../x/sys/unix/zsysnum_linux_amd64.go | 321 ++
.../x/sys/unix/zsysnum_linux_arm.go | 356 +++
.../x/sys/unix/zsysnum_linux_arm64.go | 272 ++
.../x/sys/unix/zsysnum_linux_ppc64.go | 360 +++
.../x/sys/unix/zsysnum_linux_ppc64le.go | 353 +++
.../x/sys/unix/zsysnum_netbsd_386.go | 273 ++
.../x/sys/unix/zsysnum_netbsd_amd64.go | 273 ++
.../x/sys/unix/zsysnum_netbsd_arm.go | 273 ++
.../x/sys/unix/zsysnum_openbsd_386.go | 207 ++
.../x/sys/unix/zsysnum_openbsd_amd64.go | 207 ++
.../x/sys/unix/zsysnum_solaris_amd64.go | 13 +
.../x/sys/unix/ztypes_darwin_386.go | 447 +++
.../x/sys/unix/ztypes_darwin_amd64.go | 462 +++
.../x/sys/unix/ztypes_darwin_arm.go | 449 +++
.../x/sys/unix/ztypes_darwin_arm64.go | 457 +++
.../x/sys/unix/ztypes_dragonfly_386.go | 437 +++
.../x/sys/unix/ztypes_dragonfly_amd64.go | 443 +++
.../x/sys/unix/ztypes_freebsd_386.go | 502 +++
.../x/sys/unix/ztypes_freebsd_amd64.go | 505 +++
.../x/sys/unix/ztypes_freebsd_arm.go | 497 +++
.../golang.org/x/sys/unix/ztypes_linux_386.go | 592 ++++
.../x/sys/unix/ztypes_linux_amd64.go | 610 ++++
.../golang.org/x/sys/unix/ztypes_linux_arm.go | 683 +++++
.../x/sys/unix/ztypes_linux_arm64.go | 597 ++++
.../x/sys/unix/ztypes_linux_ppc64.go | 607 ++++
.../x/sys/unix/ztypes_linux_ppc64le.go | 607 ++++
.../x/sys/unix/ztypes_netbsd_386.go | 396 +++
.../x/sys/unix/ztypes_netbsd_amd64.go | 403 +++
.../x/sys/unix/ztypes_netbsd_arm.go | 401 +++
.../x/sys/unix/ztypes_openbsd_386.go | 441 +++
.../x/sys/unix/ztypes_openbsd_amd64.go | 448 +++
.../x/sys/unix/ztypes_solaris_amd64.go | 422 +++
vendor/gopkg.in/check.v1/.gitignore | 4 +
vendor/gopkg.in/check.v1/LICENSE | 25 +
vendor/gopkg.in/check.v1/README.md | 20 +
vendor/gopkg.in/check.v1/TODO | 2 +
vendor/gopkg.in/check.v1/benchmark.go | 187 ++
vendor/gopkg.in/check.v1/benchmark_test.go | 91 +
vendor/gopkg.in/check.v1/bootstrap_test.go | 82 +
vendor/gopkg.in/check.v1/check.go | 954 ++++++
vendor/gopkg.in/check.v1/check_test.go | 207 ++
vendor/gopkg.in/check.v1/checkers.go | 458 +++
vendor/gopkg.in/check.v1/checkers_test.go | 272 ++
vendor/gopkg.in/check.v1/export_test.go | 9 +
vendor/gopkg.in/check.v1/fixture_test.go | 484 +++
vendor/gopkg.in/check.v1/foundation_test.go | 335 ++
vendor/gopkg.in/check.v1/helpers.go | 231 ++
vendor/gopkg.in/check.v1/helpers_test.go | 519 ++++
vendor/gopkg.in/check.v1/printer.go | 168 +
vendor/gopkg.in/check.v1/printer_test.go | 104 +
vendor/gopkg.in/check.v1/run.go | 175 ++
vendor/gopkg.in/check.v1/run_test.go | 419 +++
vendor/gopkg.in/yaml.v2/LICENSE | 188 ++
vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 +
vendor/gopkg.in/yaml.v2/README.md | 131 +
vendor/gopkg.in/yaml.v2/apic.go | 742 +++++
vendor/gopkg.in/yaml.v2/decode.go | 683 +++++
vendor/gopkg.in/yaml.v2/decode_test.go | 966 ++++++
vendor/gopkg.in/yaml.v2/emitterc.go | 1685 ++++++++++
vendor/gopkg.in/yaml.v2/encode.go | 306 ++
vendor/gopkg.in/yaml.v2/encode_test.go | 501 +++
vendor/gopkg.in/yaml.v2/parserc.go | 1096 +++++++
vendor/gopkg.in/yaml.v2/readerc.go | 391 +++
vendor/gopkg.in/yaml.v2/resolve.go | 203 ++
vendor/gopkg.in/yaml.v2/scannerc.go | 2710 +++++++++++++++++
vendor/gopkg.in/yaml.v2/sorter.go | 104 +
vendor/gopkg.in/yaml.v2/suite_test.go | 12 +
vendor/gopkg.in/yaml.v2/writerc.go | 89 +
vendor/gopkg.in/yaml.v2/yaml.go | 346 +++
vendor/gopkg.in/yaml.v2/yamlh.go | 716 +++++
vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 ++
368 files changed, 137108 insertions(+), 12 deletions(-)
create mode 100644 Godeps/Godeps.json
create mode 100644 Godeps/Readme
create mode 100644 vendor/github.com/cpuguy83/go-md2man/md2man/md2man.go
create mode 100644 vendor/github.com/cpuguy83/go-md2man/md2man/roff.go
create mode 100644 vendor/github.com/davecheney/profile/AUTHORS
create mode 100644 vendor/github.com/davecheney/profile/LICENSE
create mode 100644 vendor/github.com/davecheney/profile/README.md
create mode 100644 vendor/github.com/davecheney/profile/profile.go
create mode 100644 vendor/github.com/davecheney/profile/profile_test.go
create mode 100644 vendor/github.com/inconshreveable/mousetrap/LICENSE
create mode 100644 vendor/github.com/inconshreveable/mousetrap/README.md
create mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_others.go
create mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_windows.go
create mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
create mode 100644 vendor/github.com/peterh/liner/COPYING
create mode 100644 vendor/github.com/peterh/liner/README.md
create mode 100644 vendor/github.com/peterh/liner/bsdinput.go
create mode 100644 vendor/github.com/peterh/liner/common.go
create mode 100644 vendor/github.com/peterh/liner/fallbackinput.go
create mode 100644 vendor/github.com/peterh/liner/input.go
create mode 100644 vendor/github.com/peterh/liner/input_darwin.go
create mode 100644 vendor/github.com/peterh/liner/input_linux.go
create mode 100644 vendor/github.com/peterh/liner/input_test.go
create mode 100644 vendor/github.com/peterh/liner/input_windows.go
create mode 100644 vendor/github.com/peterh/liner/line.go
create mode 100644 vendor/github.com/peterh/liner/line_test.go
create mode 100644 vendor/github.com/peterh/liner/output.go
create mode 100644 vendor/github.com/peterh/liner/output_windows.go
create mode 100644 vendor/github.com/peterh/liner/prefix_test.go
create mode 100644 vendor/github.com/peterh/liner/race_test.go
create mode 100644 vendor/github.com/peterh/liner/signal.go
create mode 100644 vendor/github.com/peterh/liner/signal_legacy.go
create mode 100644 vendor/github.com/peterh/liner/unixmode.go
create mode 100644 vendor/github.com/peterh/liner/width.go
create mode 100644 vendor/github.com/peterh/liner/width_test.go
create mode 100644 vendor/github.com/russross/blackfriday/.gitignore
create mode 100644 vendor/github.com/russross/blackfriday/.travis.yml
create mode 100644 vendor/github.com/russross/blackfriday/README.md
create mode 100644 vendor/github.com/russross/blackfriday/block.go
create mode 100644 vendor/github.com/russross/blackfriday/block_test.go
create mode 100644 vendor/github.com/russross/blackfriday/html.go
create mode 100644 vendor/github.com/russross/blackfriday/inline.go
create mode 100644 vendor/github.com/russross/blackfriday/inline_test.go
create mode 100644 vendor/github.com/russross/blackfriday/latex.go
create mode 100644 vendor/github.com/russross/blackfriday/markdown.go
create mode 100644 vendor/github.com/russross/blackfriday/ref_test.go
create mode 100644 vendor/github.com/russross/blackfriday/smartypants.go
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Amps and angle encoding.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Amps and angle encoding.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Auto links.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Auto links.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Backslash escapes.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Backslash escapes.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Code Blocks.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Code Blocks.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Code Spans.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Code Spans.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Horizontal rules.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Horizontal rules.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Inline HTML (Simple).html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Inline HTML (Simple).text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Inline HTML comments.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Inline HTML comments.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Links, inline style.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Links, inline style.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Links, reference style.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Links, reference style.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Links, shortcut references.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Links, shortcut references.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Literal quotes in titles.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Literal quotes in titles.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Nested blockquotes.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Nested blockquotes.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Ordered and unordered lists.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Ordered and unordered lists.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Strong and em together.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Strong and em together.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Tabs.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Tabs.text
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Tidyness.html
create mode 100644 vendor/github.com/russross/blackfriday/testdata/Tidyness.text
create mode 100644 vendor/github.com/shurcooL/sanitized_anchor_name/.travis.yml
create mode 100644 vendor/github.com/shurcooL/sanitized_anchor_name/README.md
create mode 100644 vendor/github.com/shurcooL/sanitized_anchor_name/main.go
create mode 100644 vendor/github.com/shurcooL/sanitized_anchor_name/main_test.go
create mode 100644 vendor/github.com/spf13/cobra/.gitignore
create mode 100644 vendor/github.com/spf13/cobra/.travis.yml
create mode 100644 vendor/github.com/spf13/cobra/README.md
create mode 100644 vendor/github.com/spf13/cobra/bash_completions.go
create mode 100644 vendor/github.com/spf13/cobra/bash_completions.md
create mode 100644 vendor/github.com/spf13/cobra/bash_completions_test.go
create mode 100644 vendor/github.com/spf13/cobra/cobra.go
create mode 100644 vendor/github.com/spf13/cobra/cobra_test.go
create mode 100644 vendor/github.com/spf13/cobra/command.go
create mode 100644 vendor/github.com/spf13/cobra/command_test.go
create mode 100644 vendor/github.com/spf13/cobra/doc_util.go
create mode 100644 vendor/github.com/spf13/cobra/examples_test.go
create mode 100644 vendor/github.com/spf13/cobra/man_docs.go
create mode 100644 vendor/github.com/spf13/cobra/man_docs.md
create mode 100644 vendor/github.com/spf13/cobra/man_docs_test.go
create mode 100644 vendor/github.com/spf13/cobra/md_docs.go
create mode 100644 vendor/github.com/spf13/cobra/md_docs.md
create mode 100644 vendor/github.com/spf13/cobra/md_docs_test.go
create mode 100644 vendor/github.com/spf13/pflag/.travis.yml
create mode 100644 vendor/github.com/spf13/pflag/LICENSE
create mode 100644 vendor/github.com/spf13/pflag/README.md
create mode 100644 vendor/github.com/spf13/pflag/bool.go
create mode 100644 vendor/github.com/spf13/pflag/bool_test.go
create mode 100644 vendor/github.com/spf13/pflag/count.go
create mode 100644 vendor/github.com/spf13/pflag/count_test.go
create mode 100644 vendor/github.com/spf13/pflag/duration.go
create mode 100644 vendor/github.com/spf13/pflag/example_test.go
create mode 100644 vendor/github.com/spf13/pflag/export_test.go
create mode 100644 vendor/github.com/spf13/pflag/flag.go
create mode 100644 vendor/github.com/spf13/pflag/flag_test.go
create mode 100644 vendor/github.com/spf13/pflag/float32.go
create mode 100644 vendor/github.com/spf13/pflag/float64.go
create mode 100644 vendor/github.com/spf13/pflag/golangflag.go
create mode 100644 vendor/github.com/spf13/pflag/golangflag_test.go
create mode 100644 vendor/github.com/spf13/pflag/int.go
create mode 100644 vendor/github.com/spf13/pflag/int32.go
create mode 100644 vendor/github.com/spf13/pflag/int64.go
create mode 100644 vendor/github.com/spf13/pflag/int8.go
create mode 100644 vendor/github.com/spf13/pflag/int_slice.go
create mode 100644 vendor/github.com/spf13/pflag/int_slice_test.go
create mode 100644 vendor/github.com/spf13/pflag/ip.go
create mode 100644 vendor/github.com/spf13/pflag/ip_test.go
create mode 100644 vendor/github.com/spf13/pflag/ipmask.go
create mode 100644 vendor/github.com/spf13/pflag/ipnet.go
create mode 100644 vendor/github.com/spf13/pflag/ipnet_test.go
create mode 100644 vendor/github.com/spf13/pflag/string.go
create mode 100644 vendor/github.com/spf13/pflag/string_slice.go
create mode 100644 vendor/github.com/spf13/pflag/string_slice_test.go
create mode 100644 vendor/github.com/spf13/pflag/uint.go
create mode 100644 vendor/github.com/spf13/pflag/uint16.go
create mode 100644 vendor/github.com/spf13/pflag/uint32.go
create mode 100644 vendor/github.com/spf13/pflag/uint64.go
create mode 100644 vendor/github.com/spf13/pflag/uint8.go
create mode 100644 vendor/github.com/spf13/pflag/verify/all.sh
create mode 100644 vendor/github.com/spf13/pflag/verify/gofmt.sh
create mode 100644 vendor/github.com/spf13/pflag/verify/golint.sh
create mode 100644 vendor/golang.org/x/sys/unix/.gitignore
create mode 100644 vendor/golang.org/x/sys/unix/asm.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_386.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_arm.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_dragonfly_386.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_386.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_386.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_amd64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_386.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_386.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
create mode 100644 vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
create mode 100644 vendor/golang.org/x/sys/unix/constants.go
create mode 100644 vendor/golang.org/x/sys/unix/creds_test.go
create mode 100644 vendor/golang.org/x/sys/unix/env_unix.go
create mode 100644 vendor/golang.org/x/sys/unix/env_unset.go
create mode 100644 vendor/golang.org/x/sys/unix/export_test.go
create mode 100644 vendor/golang.org/x/sys/unix/flock.go
create mode 100644 vendor/golang.org/x/sys/unix/flock_linux_32bit.go
create mode 100644 vendor/golang.org/x/sys/unix/gccgo.go
create mode 100644 vendor/golang.org/x/sys/unix/gccgo_c.c
create mode 100644 vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/mkall.sh
create mode 100644 vendor/golang.org/x/sys/unix/mkerrors.sh
create mode 100644 vendor/golang.org/x/sys/unix/mksyscall.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksyscall_solaris.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksysnum_darwin.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksysnum_linux.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl
create mode 100644 vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl
create mode 100644 vendor/golang.org/x/sys/unix/mmap_unix_test.go
create mode 100644 vendor/golang.org/x/sys/unix/race.go
create mode 100644 vendor/golang.org/x/sys/unix/race0.go
create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_linux.go
create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix.go
create mode 100644 vendor/golang.org/x/sys/unix/str.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_bsd.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_bsd_test.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_386.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly_386.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_386.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_no_getwd.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_test.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_unix.go
create mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_test.go
create mode 100644 vendor/golang.org/x/sys/unix/types_darwin.go
create mode 100644 vendor/golang.org/x/sys/unix/types_dragonfly.go
create mode 100644 vendor/golang.org/x/sys/unix/types_freebsd.go
create mode 100644 vendor/golang.org/x/sys/unix/types_linux.go
create mode 100644 vendor/golang.org/x/sys/unix/types_netbsd.go
create mode 100644 vendor/golang.org/x/sys/unix/types_openbsd.go
create mode 100644 vendor/golang.org/x/sys/unix/types_solaris.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_dragonfly_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_dragonfly_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_dragonfly_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_386.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_dragonfly_386.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_386.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
create mode 100644 vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go
create mode 100644 vendor/gopkg.in/check.v1/.gitignore
create mode 100644 vendor/gopkg.in/check.v1/LICENSE
create mode 100644 vendor/gopkg.in/check.v1/README.md
create mode 100644 vendor/gopkg.in/check.v1/TODO
create mode 100644 vendor/gopkg.in/check.v1/benchmark.go
create mode 100644 vendor/gopkg.in/check.v1/benchmark_test.go
create mode 100644 vendor/gopkg.in/check.v1/bootstrap_test.go
create mode 100644 vendor/gopkg.in/check.v1/check.go
create mode 100644 vendor/gopkg.in/check.v1/check_test.go
create mode 100644 vendor/gopkg.in/check.v1/checkers.go
create mode 100644 vendor/gopkg.in/check.v1/checkers_test.go
create mode 100644 vendor/gopkg.in/check.v1/export_test.go
create mode 100644 vendor/gopkg.in/check.v1/fixture_test.go
create mode 100644 vendor/gopkg.in/check.v1/foundation_test.go
create mode 100644 vendor/gopkg.in/check.v1/helpers.go
create mode 100644 vendor/gopkg.in/check.v1/helpers_test.go
create mode 100644 vendor/gopkg.in/check.v1/printer.go
create mode 100644 vendor/gopkg.in/check.v1/printer_test.go
create mode 100644 vendor/gopkg.in/check.v1/run.go
create mode 100644 vendor/gopkg.in/check.v1/run_test.go
create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE
create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml
create mode 100644 vendor/gopkg.in/yaml.v2/README.md
create mode 100644 vendor/gopkg.in/yaml.v2/apic.go
create mode 100644 vendor/gopkg.in/yaml.v2/decode.go
create mode 100644 vendor/gopkg.in/yaml.v2/decode_test.go
create mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go
create mode 100644 vendor/gopkg.in/yaml.v2/encode.go
create mode 100644 vendor/gopkg.in/yaml.v2/encode_test.go
create mode 100644 vendor/gopkg.in/yaml.v2/parserc.go
create mode 100644 vendor/gopkg.in/yaml.v2/readerc.go
create mode 100644 vendor/gopkg.in/yaml.v2/resolve.go
create mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go
create mode 100644 vendor/gopkg.in/yaml.v2/sorter.go
create mode 100644 vendor/gopkg.in/yaml.v2/suite_test.go
create mode 100644 vendor/gopkg.in/yaml.v2/writerc.go
create mode 100644 vendor/gopkg.in/yaml.v2/yaml.go
create mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go
create mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go
diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
new file mode 100644
index 00000000..cad6d491
--- /dev/null
+++ b/Godeps/Godeps.json
@@ -0,0 +1,55 @@
+{
+ "ImportPath": "github.com/derekparker/delve",
+ "GoVersion": "go1.5.1",
+ "Packages": [
+ "./..."
+ ],
+ "Deps": [
+ {
+ "ImportPath": "github.com/cpuguy83/go-md2man/md2man",
+ "Comment": "v1.0.4",
+ "Rev": "71acacd42f85e5e82f70a55327789582a5200a90"
+ },
+ {
+ "ImportPath": "github.com/davecheney/profile",
+ "Rev": "c29d1a1565bca9fbeed5eed0e5d52ba78469a16b"
+ },
+ {
+ "ImportPath": "github.com/inconshreveable/mousetrap",
+ "Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
+ },
+ {
+ "ImportPath": "github.com/peterh/liner",
+ "Rev": "941195f85dd7a23971a3d55142972d396278ddcf"
+ },
+ {
+ "ImportPath": "github.com/russross/blackfriday",
+ "Comment": "v1.3",
+ "Rev": "8cec3a854e68dba10faabbe31c089abf4a3e57a6"
+ },
+ {
+ "ImportPath": "github.com/shurcooL/sanitized_anchor_name",
+ "Rev": "244f5ac324cb97e1987ef901a0081a77bfd8e845"
+ },
+ {
+ "ImportPath": "github.com/spf13/cobra",
+ "Rev": "53d96508f5c9311f5dade714e1de7bd6a9d2af4a"
+ },
+ {
+ "ImportPath": "github.com/spf13/pflag",
+ "Rev": "b084184666e02084b8ccb9b704bf0d79c466eb1d"
+ },
+ {
+ "ImportPath": "golang.org/x/sys/unix",
+ "Rev": "342d6a85aa15bcd2ec54803cdffe90d52b6f35a7"
+ },
+ {
+ "ImportPath": "gopkg.in/check.v1",
+ "Rev": "11d3bc7aa68e238947792f30573146a3231fc0f1"
+ },
+ {
+ "ImportPath": "gopkg.in/yaml.v2",
+ "Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
+ }
+ ]
+}
diff --git a/Godeps/Readme b/Godeps/Readme
new file mode 100644
index 00000000..4cdaa53d
--- /dev/null
+++ b/Godeps/Readme
@@ -0,0 +1,5 @@
+This directory tree is generated automatically by godep.
+
+Please do not edit.
+
+See https://github.com/tools/godep for more information.
diff --git a/Makefile b/Makefile
index 5e954b5b..1c530470 100644
--- a/Makefile
+++ b/Makefile
@@ -23,28 +23,19 @@ endif
endif
endif
-deps: check-cert
-ifeq "$(SKIP_DEPS)" ""
- go get -u github.com/peterh/liner
- go get -u github.com/spf13/cobra
- go get -u golang.org/x/sys/unix
- go get -u github.com/davecheney/profile
- go get -u gopkg.in/yaml.v2
-endif
-
-build: deps
+build: check-cert
go build $(FLAGS) github.com/derekparker/delve/cmd/dlv
ifeq "$(UNAME)" "Darwin"
codesign -s $(CERT) ./dlv
endif
-install: deps
+install: check-cert
go install $(FLAGS) github.com/derekparker/delve/cmd/dlv
ifeq "$(UNAME)" "Darwin"
codesign -s $(CERT) $(GOPATH)/bin/dlv
endif
-test: deps
+test: check-cert
ifeq "$(UNAME)" "Darwin"
ifeq "$(TRAVIS)" "true"
sudo -E go test -v ./...
diff --git a/vendor/github.com/cpuguy83/go-md2man/md2man/md2man.go b/vendor/github.com/cpuguy83/go-md2man/md2man/md2man.go
new file mode 100644
index 00000000..8f44fa15
--- /dev/null
+++ b/vendor/github.com/cpuguy83/go-md2man/md2man/md2man.go
@@ -0,0 +1,19 @@
+package md2man
+
+import (
+ "github.com/russross/blackfriday"
+)
+
+func Render(doc []byte) []byte {
+ renderer := RoffRenderer(0)
+ extensions := 0
+ extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
+ extensions |= blackfriday.EXTENSION_TABLES
+ extensions |= blackfriday.EXTENSION_FENCED_CODE
+ extensions |= blackfriday.EXTENSION_AUTOLINK
+ extensions |= blackfriday.EXTENSION_SPACE_HEADERS
+ extensions |= blackfriday.EXTENSION_FOOTNOTES
+ extensions |= blackfriday.EXTENSION_TITLEBLOCK
+
+ return blackfriday.Markdown(doc, renderer, extensions)
+}
diff --git a/vendor/github.com/cpuguy83/go-md2man/md2man/roff.go b/vendor/github.com/cpuguy83/go-md2man/md2man/roff.go
new file mode 100644
index 00000000..4478786b
--- /dev/null
+++ b/vendor/github.com/cpuguy83/go-md2man/md2man/roff.go
@@ -0,0 +1,269 @@
+package md2man
+
+import (
+ "bytes"
+ "fmt"
+ "html"
+ "strings"
+
+ "github.com/russross/blackfriday"
+)
+
+type roffRenderer struct{}
+
+func RoffRenderer(flags int) blackfriday.Renderer {
+ return &roffRenderer{}
+}
+
+func (r *roffRenderer) GetFlags() int {
+ return 0
+}
+
+func (r *roffRenderer) TitleBlock(out *bytes.Buffer, text []byte) {
+ out.WriteString(".TH ")
+
+ splitText := bytes.Split(text, []byte("\n"))
+ for i, line := range splitText {
+ line = bytes.TrimPrefix(line, []byte("% "))
+ if i == 0 {
+ line = bytes.Replace(line, []byte("("), []byte("\" \""), 1)
+ line = bytes.Replace(line, []byte(")"), []byte("\" \""), 1)
+ }
+ line = append([]byte("\""), line...)
+ line = append(line, []byte("\" ")...)
+ out.Write(line)
+ }
+
+ out.WriteString(" \"\"\n")
+}
+
+func (r *roffRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
+ out.WriteString("\n.PP\n.RS\n\n.nf\n")
+ escapeSpecialChars(out, text)
+ out.WriteString("\n.fi\n.RE\n")
+}
+
+func (r *roffRenderer) BlockQuote(out *bytes.Buffer, text []byte) {
+ out.WriteString("\n.PP\n.RS\n")
+ out.Write(text)
+ out.WriteString("\n.RE\n")
+}
+
+func (r *roffRenderer) BlockHtml(out *bytes.Buffer, text []byte) {
+ out.Write(text)
+}
+
+func (r *roffRenderer) Header(out *bytes.Buffer, text func() bool, level int, id string) {
+ marker := out.Len()
+
+ switch {
+ case marker == 0:
+ // This is the doc header
+ out.WriteString(".TH ")
+ case level == 1:
+ out.WriteString("\n\n.SH ")
+ case level == 2:
+ out.WriteString("\n.SH ")
+ default:
+ out.WriteString("\n.SS ")
+ }
+
+ if !text() {
+ out.Truncate(marker)
+ return
+ }
+}
+
+func (r *roffRenderer) HRule(out *bytes.Buffer) {
+ out.WriteString("\n.ti 0\n\\l'\\n(.lu'\n")
+}
+
+func (r *roffRenderer) List(out *bytes.Buffer, text func() bool, flags int) {
+ marker := out.Len()
+ out.WriteString(".IP ")
+ if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
+ out.WriteString("\\(bu 2")
+ } else {
+ out.WriteString("\\n+[step" + string(flags) + "]")
+ }
+ out.WriteString("\n")
+ if !text() {
+ out.Truncate(marker)
+ return
+ }
+
+}
+
+func (r *roffRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
+ out.WriteString("\n\\item ")
+ out.Write(text)
+}
+
+func (r *roffRenderer) Paragraph(out *bytes.Buffer, text func() bool) {
+ marker := out.Len()
+ out.WriteString("\n.PP\n")
+ if !text() {
+ out.Truncate(marker)
+ return
+ }
+ if marker != 0 {
+ out.WriteString("\n")
+ }
+}
+
+// TODO: This might now work
+func (r *roffRenderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
+ out.WriteString(".TS\nallbox;\n")
+
+ out.Write(header)
+ out.Write(body)
+ out.WriteString("\n.TE\n")
+}
+
+func (r *roffRenderer) TableRow(out *bytes.Buffer, text []byte) {
+ if out.Len() > 0 {
+ out.WriteString("\n")
+ }
+ out.Write(text)
+ out.WriteString("\n")
+}
+
+func (r *roffRenderer) TableHeaderCell(out *bytes.Buffer, text []byte, align int) {
+ if out.Len() > 0 {
+ out.WriteString(" ")
+ }
+ out.Write(text)
+ out.WriteString(" ")
+}
+
+// TODO: This is probably broken
+func (r *roffRenderer) TableCell(out *bytes.Buffer, text []byte, align int) {
+ if out.Len() > 0 {
+ out.WriteString("\t")
+ }
+ out.Write(text)
+ out.WriteString("\t")
+}
+
+func (r *roffRenderer) Footnotes(out *bytes.Buffer, text func() bool) {
+
+}
+
+func (r *roffRenderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {
+
+}
+
+func (r *roffRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {
+ out.WriteString("\n\\[la]")
+ out.Write(link)
+ out.WriteString("\\[ra]")
+}
+
+func (r *roffRenderer) CodeSpan(out *bytes.Buffer, text []byte) {
+ out.WriteString("\\fB\\fC")
+ escapeSpecialChars(out, text)
+ out.WriteString("\\fR")
+}
+
+func (r *roffRenderer) DoubleEmphasis(out *bytes.Buffer, text []byte) {
+ out.WriteString("\\fB")
+ out.Write(text)
+ out.WriteString("\\fP")
+}
+
+func (r *roffRenderer) Emphasis(out *bytes.Buffer, text []byte) {
+ out.WriteString("\\fI")
+ out.Write(text)
+ out.WriteString("\\fP")
+}
+
+func (r *roffRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
+}
+
+func (r *roffRenderer) LineBreak(out *bytes.Buffer) {
+ out.WriteString("\n.br\n")
+}
+
+func (r *roffRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
+ r.AutoLink(out, link, 0)
+}
+
+func (r *roffRenderer) RawHtmlTag(out *bytes.Buffer, tag []byte) {
+ out.Write(tag)
+}
+
+func (r *roffRenderer) TripleEmphasis(out *bytes.Buffer, text []byte) {
+ out.WriteString("\\s+2")
+ out.Write(text)
+ out.WriteString("\\s-2")
+}
+
+func (r *roffRenderer) StrikeThrough(out *bytes.Buffer, text []byte) {
+}
+
+func (r *roffRenderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {
+
+}
+
+func (r *roffRenderer) Entity(out *bytes.Buffer, entity []byte) {
+ out.WriteString(html.UnescapeString(string(entity)))
+}
+
+func processFooterText(text []byte) []byte {
+ text = bytes.TrimPrefix(text, []byte("% "))
+ newText := []byte{}
+ textArr := strings.Split(string(text), ") ")
+
+ for i, w := range textArr {
+ if i == 0 {
+ w = strings.Replace(w, "(", "\" \"", 1)
+ w = fmt.Sprintf("\"%s\"", w)
+ } else {
+ w = fmt.Sprintf(" \"%s\"", w)
+ }
+ newText = append(newText, []byte(w)...)
+ }
+ newText = append(newText, []byte(" \"\"")...)
+
+ return newText
+}
+
+func (r *roffRenderer) NormalText(out *bytes.Buffer, text []byte) {
+ escapeSpecialChars(out, text)
+}
+
+func (r *roffRenderer) DocumentHeader(out *bytes.Buffer) {
+}
+
+func (r *roffRenderer) DocumentFooter(out *bytes.Buffer) {
+}
+
+func needsBackslash(c byte) bool {
+ for _, r := range []byte("-_&\\~") {
+ if c == r {
+ return true
+ }
+ }
+ return false
+}
+
+func escapeSpecialChars(out *bytes.Buffer, text []byte) {
+ for i := 0; i < len(text); i++ {
+ // directly copy normal characters
+ org := i
+
+ for i < len(text) && !needsBackslash(text[i]) {
+ i++
+ }
+ if i > org {
+ out.Write(text[org:i])
+ }
+
+ // escape a character
+ if i >= len(text) {
+ break
+ }
+ out.WriteByte('\\')
+ out.WriteByte(text[i])
+ }
+}
diff --git a/vendor/github.com/davecheney/profile/AUTHORS b/vendor/github.com/davecheney/profile/AUTHORS
new file mode 100644
index 00000000..00441d35
--- /dev/null
+++ b/vendor/github.com/davecheney/profile/AUTHORS
@@ -0,0 +1 @@
+Dave Cheney
diff --git a/vendor/github.com/davecheney/profile/LICENSE b/vendor/github.com/davecheney/profile/LICENSE
new file mode 100644
index 00000000..f747a841
--- /dev/null
+++ b/vendor/github.com/davecheney/profile/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2013 Dave Cheney. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/davecheney/profile/README.md b/vendor/github.com/davecheney/profile/README.md
new file mode 100644
index 00000000..fa4bed41
--- /dev/null
+++ b/vendor/github.com/davecheney/profile/README.md
@@ -0,0 +1,50 @@
+profile
+=======
+
+Simple profiling support package for Go
+
+installation
+------------
+
+ go get github.com/davecheney/profile
+
+usage
+-----
+
+Enabling profiling in your application is as simple as one line at the top of your main function
+
+```go
+import "github.com/davecheney/profile"
+
+func main() {
+ defer profile.Start(profile.CPUProfile).Stop()
+ ...
+}
+```
+
+options
+-------
+
+What to profile is controlled by the \*profile.Config value passed to profile.Start. A nil
+Config is the same as choosing all the defaults. By default no profiles are enabled.
+
+```go
+import "github.com/davecheney/profile"
+
+func main() {
+ cfg := profile.Config{
+ MemProfile: true,
+ ProfilePath: ".", // store profiles in current directory
+ NoShutdownHook: true, // do not hook SIGINT
+ }
+
+ // p.Stop() must be called before the program exits to
+ // ensure profiling information is written to disk.
+ p := profile.Start(&cfg)
+ ...
+}
+```
+
+Several convenience package level values are provided for cpu, memory, and block (contention) profiling.
+
+For more complex options, consult the [documentation](http://godoc.org/github.com/davecheney/profile) on the profile.Config type. Enabling more than one profile at once may cause your results to be less reliable as profiling itself is not without overhead.
diff --git a/vendor/github.com/davecheney/profile/profile.go b/vendor/github.com/davecheney/profile/profile.go
new file mode 100644
index 00000000..f8351341
--- /dev/null
+++ b/vendor/github.com/davecheney/profile/profile.go
@@ -0,0 +1,169 @@
+// Package profile provides a simple way to manage runtime/pprof
+// profiling of your Go application.
+package profile
+
+import (
+ "io/ioutil"
+ "log"
+ "os"
+ "os/signal"
+ "path/filepath"
+ "runtime"
+ "runtime/pprof"
+)
+
+// Config controls the operation of the profile package.
+type Config struct {
+ // Quiet suppresses informational messages during profiling.
+ Quiet bool
+
+ // CPUProfile controls if cpu profiling will be enabled.
+ // It defaults to false.
+ CPUProfile bool
+
+ // MemProfile controls if memory profiling will be enabled.
+ // It defaults to false.
+ MemProfile bool
+
+ // BlockProfile controls if block (contention) profiling will
+ // be enabled.
+ // It defaults to false.
+ BlockProfile bool
+
+ // ProfilePath controls the base path where various profiling
+ // files are written. If blank, the base path will be generated
+ // by ioutil.TempDir.
+ ProfilePath string
+
+ // NoShutdownHook controls whether the profiling package should
+ // hook SIGINT to write profiles cleanly.
+ // Programs with more sophisticated signal handling should set
+ // this to true and ensure the Stop() function returned from Start()
+ // is called during shutdown.
+ NoShutdownHook bool
+}
+
+var zeroConfig Config
+
+const memProfileRate = 4096
+
+func defaultConfig() *Config { return &zeroConfig }
+
+var (
+ CPUProfile = &Config{
+ CPUProfile: true,
+ }
+
+ MemProfile = &Config{
+ MemProfile: true,
+ }
+
+ BlockProfile = &Config{
+ BlockProfile: true,
+ }
+)
+
+type profile struct {
+ path string
+ *Config
+ closers []func()
+}
+
+func (p *profile) Stop() {
+ for _, c := range p.closers {
+ c()
+ }
+}
+
+// Start starts a new profiling session configured using *Config.
+// The caller should call the Stop method on the value returned
+// to cleanly stop profiling.
+// Passing a nil *Config is the same as passing a *Config with
+// defaults chosen.
+func Start(cfg *Config) interface {
+ Stop()
+} {
+ if cfg == nil {
+ cfg = defaultConfig()
+ }
+ path := cfg.ProfilePath
+ var err error
+ if path == "" {
+ path, err = ioutil.TempDir("", "profile")
+ } else {
+ err = os.MkdirAll(path, 0777)
+ }
+ if err != nil {
+ log.Fatalf("profile: could not create initial output directory: %v", err)
+ }
+ prof := &profile{
+ path: path,
+ Config: cfg,
+ }
+
+ if prof.CPUProfile {
+ fn := filepath.Join(prof.path, "cpu.pprof")
+ f, err := os.Create(fn)
+ if err != nil {
+ log.Fatalf("profile: could not create cpu profile %q: %v", fn, err)
+ }
+ if !prof.Quiet {
+ log.Printf("profile: cpu profiling enabled, %s", fn)
+ }
+ pprof.StartCPUProfile(f)
+ prof.closers = append(prof.closers, func() {
+ pprof.StopCPUProfile()
+ f.Close()
+ })
+ }
+
+ if prof.MemProfile {
+ fn := filepath.Join(prof.path, "mem.pprof")
+ f, err := os.Create(fn)
+ if err != nil {
+ log.Fatalf("profile: could not create memory profile %q: %v", fn, err)
+ }
+ old := runtime.MemProfileRate
+ runtime.MemProfileRate = memProfileRate
+ if !prof.Quiet {
+ log.Printf("profile: memory profiling enabled, %s", fn)
+ }
+ prof.closers = append(prof.closers, func() {
+ pprof.Lookup("heap").WriteTo(f, 0)
+ f.Close()
+ runtime.MemProfileRate = old
+ })
+ }
+
+ if prof.BlockProfile {
+ fn := filepath.Join(prof.path, "block.pprof")
+ f, err := os.Create(fn)
+ if err != nil {
+ log.Fatalf("profile: could not create block profile %q: %v", fn, err)
+ }
+ runtime.SetBlockProfileRate(1)
+ if !prof.Quiet {
+ log.Printf("profile: block profiling enabled, %s", fn)
+ }
+ prof.closers = append(prof.closers, func() {
+ pprof.Lookup("block").WriteTo(f, 0)
+ f.Close()
+ runtime.SetBlockProfileRate(0)
+ })
+ }
+
+ if !prof.NoShutdownHook {
+ go func() {
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt)
+ <-c
+
+ log.Println("profile: caught interrupt, stopping profiles")
+ prof.Stop()
+
+ os.Exit(0)
+ }()
+ }
+
+ return prof
+}
diff --git a/vendor/github.com/davecheney/profile/profile_test.go b/vendor/github.com/davecheney/profile/profile_test.go
new file mode 100644
index 00000000..1c370263
--- /dev/null
+++ b/vendor/github.com/davecheney/profile/profile_test.go
@@ -0,0 +1,11 @@
+package profile_test
+
+import (
+ "github.com/davecheney/profile"
+)
+
+func ExampleStart() {
+ // start a simple CPU profile and register
+ // a defer to Stop (flush) the profiling data.
+ defer profile.Start(profile.CPUProfile).Stop()
+}
diff --git a/vendor/github.com/inconshreveable/mousetrap/LICENSE b/vendor/github.com/inconshreveable/mousetrap/LICENSE
new file mode 100644
index 00000000..5f0d1fb6
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Alan Shreve
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/github.com/inconshreveable/mousetrap/README.md b/vendor/github.com/inconshreveable/mousetrap/README.md
new file mode 100644
index 00000000..7a950d17
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/README.md
@@ -0,0 +1,23 @@
+# mousetrap
+
+mousetrap is a tiny library that answers a single question.
+
+On a Windows machine, was the process invoked by someone double clicking on
+the executable file while browsing in explorer?
+
+### Motivation
+
+Windows developers unfamiliar with command line tools will often "double-click"
+the executable for a tool. Because most CLI tools print the help and then exit
+when invoked without arguments, this is often very frustrating for those users.
+
+mousetrap provides a way to detect these invocations so that you can provide
+more helpful behavior and instructions on how to run the CLI tool. To see what
+this looks like, both from an organizational and a technical perspective, see
+https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/
+
+### The interface
+
+The library exposes a single interface:
+
+ func StartedByExplorer() (bool)
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/github.com/inconshreveable/mousetrap/trap_others.go
new file mode 100644
index 00000000..9d2d8a4b
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_others.go
@@ -0,0 +1,15 @@
+// +build !windows
+
+package mousetrap
+
+// StartedByExplorer returns true if the program was invoked by the user
+// double-clicking on the executable from explorer.exe
+//
+// It is conservative and returns false if any of the internal calls fail.
+// It does not guarantee that the program was run from a terminal. It only can tell you
+// whether it was launched from explorer.exe
+//
+// On non-Windows platforms, it always returns false.
+func StartedByExplorer() bool {
+ return false
+}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
new file mode 100644
index 00000000..336142a5
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
@@ -0,0 +1,98 @@
+// +build windows
+// +build !go1.4
+
+package mousetrap
+
+import (
+ "fmt"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+const (
+ // defined by the Win32 API
+ th32cs_snapprocess uintptr = 0x2
+)
+
+var (
+ kernel = syscall.MustLoadDLL("kernel32.dll")
+ CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot")
+ Process32First = kernel.MustFindProc("Process32FirstW")
+ Process32Next = kernel.MustFindProc("Process32NextW")
+)
+
+// ProcessEntry32 structure defined by the Win32 API
+type processEntry32 struct {
+ dwSize uint32
+ cntUsage uint32
+ th32ProcessID uint32
+ th32DefaultHeapID int
+ th32ModuleID uint32
+ cntThreads uint32
+ th32ParentProcessID uint32
+ pcPriClassBase int32
+ dwFlags uint32
+ szExeFile [syscall.MAX_PATH]uint16
+}
+
+func getProcessEntry(pid int) (pe *processEntry32, err error) {
+ snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
+ if snapshot == uintptr(syscall.InvalidHandle) {
+ err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
+ return
+ }
+ defer syscall.CloseHandle(syscall.Handle(snapshot))
+
+ var processEntry processEntry32
+ processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
+ ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
+ if ok == 0 {
+ err = fmt.Errorf("Process32First: %v", e1)
+ return
+ }
+
+ for {
+ if processEntry.th32ProcessID == uint32(pid) {
+ pe = &processEntry
+ return
+ }
+
+ ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
+ if ok == 0 {
+ err = fmt.Errorf("Process32Next: %v", e1)
+ return
+ }
+ }
+}
+
+func getppid() (pid int, err error) {
+ pe, err := getProcessEntry(os.Getpid())
+ if err != nil {
+ return
+ }
+
+ pid = int(pe.th32ParentProcessID)
+ return
+}
+
+// StartedByExplorer returns true if the program was invoked by the user double-clicking
+// on the executable from explorer.exe
+//
+// It is conservative and returns false if any of the internal calls fail.
+// It does not guarantee that the program was run from a terminal. It only can tell you
+// whether it was launched from explorer.exe
+func StartedByExplorer() bool {
+ ppid, err := getppid()
+ if err != nil {
+ return false
+ }
+
+ pe, err := getProcessEntry(ppid)
+ if err != nil {
+ return false
+ }
+
+ name := syscall.UTF16ToString(pe.szExeFile[:])
+ return name == "explorer.exe"
+}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
new file mode 100644
index 00000000..9a28e57c
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
@@ -0,0 +1,46 @@
+// +build windows
+// +build go1.4
+
+package mousetrap
+
+import (
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
+ snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CloseHandle(snapshot)
+ var procEntry syscall.ProcessEntry32
+ procEntry.Size = uint32(unsafe.Sizeof(procEntry))
+ if err = syscall.Process32First(snapshot, &procEntry); err != nil {
+ return nil, err
+ }
+ for {
+ if procEntry.ProcessID == uint32(pid) {
+ return &procEntry, nil
+ }
+ err = syscall.Process32Next(snapshot, &procEntry)
+ if err != nil {
+ return nil, err
+ }
+ }
+}
+
+// StartedByExplorer returns true if the program was invoked by the user double-clicking
+// on the executable from explorer.exe
+//
+// It is conservative and returns false if any of the internal calls fail.
+// It does not guarantee that the program was run from a terminal. It only can tell you
+// whether it was launched from explorer.exe
+func StartedByExplorer() bool {
+ pe, err := getProcessEntry(os.Getppid())
+ if err != nil {
+ return false
+ }
+ return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
+}
diff --git a/vendor/github.com/peterh/liner/COPYING b/vendor/github.com/peterh/liner/COPYING
new file mode 100644
index 00000000..9e8c9f20
--- /dev/null
+++ b/vendor/github.com/peterh/liner/COPYING
@@ -0,0 +1,21 @@
+Copyright © 2012 Peter Harris
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
diff --git a/vendor/github.com/peterh/liner/README.md b/vendor/github.com/peterh/liner/README.md
new file mode 100644
index 00000000..615e7645
--- /dev/null
+++ b/vendor/github.com/peterh/liner/README.md
@@ -0,0 +1,99 @@
+Liner
+=====
+
+Liner is a command line editor with history. It was inspired by linenoise;
+everything Unix-like is a VT100 (or is trying very hard to be). If your
+terminal is not pretending to be a VT100, change it. Liner also support
+Windows.
+
+Liner is released under the X11 license (which is similar to the new BSD
+license).
+
+Line Editing
+------------
+
+The following line editing commands are supported on platforms and terminals
+that Liner supports:
+
+Keystroke | Action
+--------- | ------
+Ctrl-A, Home | Move cursor to beginning of line
+Ctrl-E, End | Move cursor to end of line
+Ctrl-B, Left | Move cursor one character left
+Ctrl-F, Right| Move cursor one character right
+Ctrl-Left, Alt-B | Move cursor to previous word
+Ctrl-Right, Alt-F | Move cursor to next word
+Ctrl-D, Del | (if line is *not* empty) Delete character under cursor
+Ctrl-D | (if line *is* empty) End of File - usually quits application
+Ctrl-C | Reset input (create new empty prompt)
+Ctrl-L | Clear screen (line is unmodified)
+Ctrl-T | Transpose previous character with current character
+Ctrl-H, BackSpace | Delete character before cursor
+Ctrl-W | Delete word leading up to cursor
+Ctrl-K | Delete from cursor to end of line
+Ctrl-U | Delete from start of line to cursor
+Ctrl-P, Up | Previous match from history
+Ctrl-N, Down | Next match from history
+Ctrl-R | Reverse Search history (Ctrl-S forward, Ctrl-G cancel)
+Ctrl-Y | Paste from Yank buffer (Alt-Y to paste next yank instead)
+Tab | Next completion
+Shift-Tab | (after Tab) Previous completion
+
+Getting started
+-----------------
+
+```go
+package main
+
+import (
+ "log"
+ "os"
+ "strings"
+
+ "github.com/peterh/liner"
+)
+
+var (
+ history_fn = "/tmp/.liner_history"
+ names = []string{"john", "james", "mary", "nancy"}
+)
+
+func main() {
+ line := liner.NewLiner()
+ defer line.Close()
+
+ line.SetCtrlCAborts(true)
+
+ line.SetCompleter(func(line string) (c []string) {
+ for _, n := range names {
+ if strings.HasPrefix(n, strings.ToLower(line)) {
+ c = append(c, n)
+ }
+ }
+ return
+ })
+
+ if f, err := os.Open(history_fn); err == nil {
+ line.ReadHistory(f)
+ f.Close()
+ }
+
+ if name, err := line.Prompt("What is your name? "); err == nil {
+ log.Print("Got: ", name)
+ line.AppendHistory(name)
+ } else if err == liner.ErrPromptAborted {
+ log.Print("Aborted")
+ } else {
+ log.Print("Error reading line: ", err)
+ }
+
+ if f, err := os.Create(history_fn); err != nil {
+ log.Print("Error writing history file: ", err)
+ } else {
+ line.WriteHistory(f)
+ f.Close()
+ }
+}
+```
+
+For documentation, see http://godoc.org/github.com/peterh/liner
diff --git a/vendor/github.com/peterh/liner/bsdinput.go b/vendor/github.com/peterh/liner/bsdinput.go
new file mode 100644
index 00000000..4b552d44
--- /dev/null
+++ b/vendor/github.com/peterh/liner/bsdinput.go
@@ -0,0 +1,39 @@
+// +build openbsd freebsd netbsd
+
+package liner
+
+import "syscall"
+
+const (
+ getTermios = syscall.TIOCGETA
+ setTermios = syscall.TIOCSETA
+)
+
+const (
+ // Input flags
+ inpck = 0x010
+ istrip = 0x020
+ icrnl = 0x100
+ ixon = 0x200
+
+ // Output flags
+ opost = 0x1
+
+ // Control flags
+ cs8 = 0x300
+
+ // Local flags
+ isig = 0x080
+ icanon = 0x100
+ iexten = 0x400
+)
+
+type termios struct {
+ Iflag uint32
+ Oflag uint32
+ Cflag uint32
+ Lflag uint32
+ Cc [20]byte
+ Ispeed int32
+ Ospeed int32
+}
diff --git a/vendor/github.com/peterh/liner/common.go b/vendor/github.com/peterh/liner/common.go
new file mode 100644
index 00000000..9424abe5
--- /dev/null
+++ b/vendor/github.com/peterh/liner/common.go
@@ -0,0 +1,219 @@
+/*
+Package liner implements a simple command line editor, inspired by linenoise
+(https://github.com/antirez/linenoise/). This package supports WIN32 in
+addition to the xterm codes supported by everything else.
+*/
+package liner
+
+import (
+ "bufio"
+ "bytes"
+ "container/ring"
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+ "sync"
+ "unicode/utf8"
+)
+
+type commonState struct {
+ terminalSupported bool
+ outputRedirected bool
+ inputRedirected bool
+ history []string
+ historyMutex sync.RWMutex
+ completer WordCompleter
+ columns int
+ killRing *ring.Ring
+ ctrlCAborts bool
+ r *bufio.Reader
+ tabStyle TabStyle
+}
+
+// TabStyle is used to select how tab completions are displayed.
+type TabStyle int
+
+// Two tab styles are currently available:
+//
+// TabCircular cycles through each completion item and displays it directly on
+// the prompt
+//
+// TabPrints prints the list of completion items to the screen after a second
+// tab key is pressed. This behaves similar to GNU readline and BASH (which
+// uses readline)
+const (
+ TabCircular TabStyle = iota
+ TabPrints
+)
+
+// ErrPromptAborted is returned from Prompt or PasswordPrompt when the user presses Ctrl-C
+// if SetCtrlCAborts(true) has been called on the State
+var ErrPromptAborted = errors.New("prompt aborted")
+
+// ErrNotTerminalOutput is returned from Prompt or PasswordPrompt if the
+// platform is normally supported, but stdout has been redirected
+var ErrNotTerminalOutput = errors.New("standard output is not a terminal")
+
+// Max elements to save on the killring
+const KillRingMax = 60
+
+// HistoryLimit is the maximum number of entries saved in the scrollback history.
+const HistoryLimit = 1000
+
+// ReadHistory reads scrollback history from r. Returns the number of lines
+// read, and any read error (except io.EOF).
+func (s *State) ReadHistory(r io.Reader) (num int, err error) {
+ s.historyMutex.Lock()
+ defer s.historyMutex.Unlock()
+
+ in := bufio.NewReader(r)
+ num = 0
+ for {
+ line, part, err := in.ReadLine()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return num, err
+ }
+ if part {
+ return num, fmt.Errorf("line %d is too long", num+1)
+ }
+ if !utf8.Valid(line) {
+ return num, fmt.Errorf("invalid string at line %d", num+1)
+ }
+ num++
+ s.history = append(s.history, string(line))
+ if len(s.history) > HistoryLimit {
+ s.history = s.history[1:]
+ }
+ }
+ return num, nil
+}
+
+// WriteHistory writes scrollback history to w. Returns the number of lines
+// successfully written, and any write error.
+//
+// Unlike the rest of liner's API, WriteHistory is safe to call
+// from another goroutine while Prompt is in progress.
+// This exception is to facilitate the saving of the history buffer
+// during an unexpected exit (for example, due to Ctrl-C being invoked)
+func (s *State) WriteHistory(w io.Writer) (num int, err error) {
+ s.historyMutex.RLock()
+ defer s.historyMutex.RUnlock()
+
+ for _, item := range s.history {
+ _, err := fmt.Fprintln(w, item)
+ if err != nil {
+ return num, err
+ }
+ num++
+ }
+ return num, nil
+}
+
+// AppendHistory appends an entry to the scrollback history. AppendHistory
+// should be called iff Prompt returns a valid command.
+func (s *State) AppendHistory(item string) {
+ s.historyMutex.Lock()
+ defer s.historyMutex.Unlock()
+
+ if len(s.history) > 0 {
+ if item == s.history[len(s.history)-1] {
+ return
+ }
+ }
+ s.history = append(s.history, item)
+ if len(s.history) > HistoryLimit {
+ s.history = s.history[1:]
+ }
+}
+
+// Returns the history lines starting with prefix
+func (s *State) getHistoryByPrefix(prefix string) (ph []string) {
+ for _, h := range s.history {
+ if strings.HasPrefix(h, prefix) {
+ ph = append(ph, h)
+ }
+ }
+ return
+}
+
+// Returns the history lines matching the inteligent search
+func (s *State) getHistoryByPattern(pattern string) (ph []string, pos []int) {
+ if pattern == "" {
+ return
+ }
+ for _, h := range s.history {
+ if i := strings.Index(h, pattern); i >= 0 {
+ ph = append(ph, h)
+ pos = append(pos, i)
+ }
+ }
+ return
+}
+
+// Completer takes the currently edited line content at the left of the cursor
+// and returns a list of completion candidates.
+// If the line is "Hello, wo!!!" and the cursor is before the first '!', "Hello, wo" is passed
+// to the completer which may return {"Hello, world", "Hello, Word"} to have "Hello, world!!!".
+type Completer func(line string) []string
+
+// WordCompleter takes the currently edited line with the cursor position and
+// returns the completion candidates for the partial word to be completed.
+// If the line is "Hello, wo!!!" and the cursor is before the first '!', ("Hello, wo!!!", 9) is passed
+// to the completer which may returns ("Hello, ", {"world", "Word"}, "!!!") to have "Hello, world!!!".
+type WordCompleter func(line string, pos int) (head string, completions []string, tail string)
+
+// SetCompleter sets the completion function that Liner will call to
+// fetch completion candidates when the user presses tab.
+func (s *State) SetCompleter(f Completer) {
+ if f == nil {
+ s.completer = nil
+ return
+ }
+ s.completer = func(line string, pos int) (string, []string, string) {
+ return "", f(line[:pos]), line[pos:]
+ }
+}
+
+// SetWordCompleter sets the completion function that Liner will call to
+// fetch completion candidates when the user presses tab.
+func (s *State) SetWordCompleter(f WordCompleter) {
+ s.completer = f
+}
+
+// SetTabCompletionStyle sets the behvavior when the Tab key is pressed
+// for auto-completion. TabCircular is the default behavior and cycles
+// through the list of candidates at the prompt. TabPrints will print
+// the available completion candidates to the screen similar to BASH
+// and GNU Readline
+func (s *State) SetTabCompletionStyle(tabStyle TabStyle) {
+ s.tabStyle = tabStyle
+}
+
+// ModeApplier is the interface that wraps a representation of the terminal
+// mode. ApplyMode sets the terminal to this mode.
+type ModeApplier interface {
+ ApplyMode() error
+}
+
+// SetCtrlCAborts sets whether Prompt on a supported terminal will return an
+// ErrPromptAborted when Ctrl-C is pressed. The default is false (will not
+// return when Ctrl-C is pressed). Unsupported terminals typically raise SIGINT
+// (and Prompt does not return) regardless of the value passed to SetCtrlCAborts.
+func (s *State) SetCtrlCAborts(aborts bool) {
+ s.ctrlCAborts = aborts
+}
+
+func (s *State) promptUnsupported(p string) (string, error) {
+ if !s.inputRedirected || !s.terminalSupported {
+ fmt.Print(p)
+ }
+ linebuf, _, err := s.r.ReadLine()
+ if err != nil {
+ return "", err
+ }
+ return string(bytes.TrimSpace(linebuf)), nil
+}
diff --git a/vendor/github.com/peterh/liner/fallbackinput.go b/vendor/github.com/peterh/liner/fallbackinput.go
new file mode 100644
index 00000000..d9eb79d9
--- /dev/null
+++ b/vendor/github.com/peterh/liner/fallbackinput.go
@@ -0,0 +1,57 @@
+// +build !windows,!linux,!darwin,!openbsd,!freebsd,!netbsd
+
+package liner
+
+import (
+ "bufio"
+ "errors"
+ "os"
+)
+
+// State represents an open terminal
+type State struct {
+ commonState
+}
+
+// Prompt displays p, and then waits for user input. Prompt does not support
+// line editing on this operating system.
+func (s *State) Prompt(p string) (string, error) {
+ return s.promptUnsupported(p)
+}
+
+// PasswordPrompt is not supported in this OS.
+func (s *State) PasswordPrompt(p string) (string, error) {
+ return "", errors.New("liner: function not supported in this terminal")
+}
+
+// NewLiner initializes a new *State
+//
+// Note that this operating system uses a fallback mode without line
+// editing. Patches welcome.
+func NewLiner() *State {
+ var s State
+ s.r = bufio.NewReader(os.Stdin)
+ return &s
+}
+
+// Close returns the terminal to its previous mode
+func (s *State) Close() error {
+ return nil
+}
+
+// TerminalSupported returns false because line editing is not
+// supported on this platform.
+func TerminalSupported() bool {
+ return false
+}
+
+type noopMode struct{}
+
+func (n noopMode) ApplyMode() error {
+ return nil
+}
+
+// TerminalMode returns a noop InputModeSetter on this platform.
+func TerminalMode() (ModeApplier, error) {
+ return noopMode{}, nil
+}
diff --git a/vendor/github.com/peterh/liner/input.go b/vendor/github.com/peterh/liner/input.go
new file mode 100644
index 00000000..c80c85f6
--- /dev/null
+++ b/vendor/github.com/peterh/liner/input.go
@@ -0,0 +1,368 @@
+// +build linux darwin openbsd freebsd netbsd
+
+package liner
+
+import (
+ "bufio"
+ "errors"
+ "os"
+ "os/signal"
+ "strconv"
+ "strings"
+ "syscall"
+ "time"
+)
+
+type nexter struct {
+ r rune
+ err error
+}
+
+// State represents an open terminal
+type State struct {
+ commonState
+ origMode termios
+ defaultMode termios
+ next <-chan nexter
+ winch chan os.Signal
+ pending []rune
+ useCHA bool
+}
+
+// NewLiner initializes a new *State, and sets the terminal into raw mode. To
+// restore the terminal to its previous state, call State.Close().
+//
+// Note if you are still using Go 1.0: NewLiner handles SIGWINCH, so it will
+// leak a channel every time you call it. Therefore, it is recommened that you
+// upgrade to a newer release of Go, or ensure that NewLiner is only called
+// once.
+func NewLiner() *State {
+ var s State
+ s.r = bufio.NewReader(os.Stdin)
+
+ s.terminalSupported = TerminalSupported()
+ if m, err := TerminalMode(); err == nil {
+ s.origMode = *m.(*termios)
+ } else {
+ s.inputRedirected = true
+ }
+ if _, err := getMode(syscall.Stdout); err != 0 {
+ s.outputRedirected = true
+ }
+ if s.inputRedirected && s.outputRedirected {
+ s.terminalSupported = false
+ }
+ if s.terminalSupported && !s.inputRedirected && !s.outputRedirected {
+ mode := s.origMode
+ mode.Iflag &^= icrnl | inpck | istrip | ixon
+ mode.Cflag |= cs8
+ mode.Lflag &^= syscall.ECHO | icanon | iexten
+ mode.ApplyMode()
+
+ winch := make(chan os.Signal, 1)
+ signal.Notify(winch, syscall.SIGWINCH)
+ s.winch = winch
+
+ s.checkOutput()
+ }
+
+ if !s.outputRedirected {
+ s.getColumns()
+ s.outputRedirected = s.columns <= 0
+ }
+
+ return &s
+}
+
+var errTimedOut = errors.New("timeout")
+
+func (s *State) startPrompt() {
+ if s.terminalSupported {
+ if m, err := TerminalMode(); err == nil {
+ s.defaultMode = *m.(*termios)
+ mode := s.defaultMode
+ mode.Lflag &^= isig
+ mode.ApplyMode()
+ }
+ }
+ s.restartPrompt()
+}
+
+func (s *State) restartPrompt() {
+ next := make(chan nexter)
+ go func() {
+ for {
+ var n nexter
+ n.r, _, n.err = s.r.ReadRune()
+ next <- n
+ // Shut down nexter loop when an end condition has been reached
+ if n.err != nil || n.r == '\n' || n.r == '\r' || n.r == ctrlC || n.r == ctrlD {
+ close(next)
+ return
+ }
+ }
+ }()
+ s.next = next
+}
+
+func (s *State) stopPrompt() {
+ if s.terminalSupported {
+ s.defaultMode.ApplyMode()
+ }
+}
+
+func (s *State) nextPending(timeout <-chan time.Time) (rune, error) {
+ select {
+ case thing, ok := <-s.next:
+ if !ok {
+ return 0, errors.New("liner: internal error")
+ }
+ if thing.err != nil {
+ return 0, thing.err
+ }
+ s.pending = append(s.pending, thing.r)
+ return thing.r, nil
+ case <-timeout:
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, errTimedOut
+ }
+ // not reached
+ return 0, nil
+}
+
+func (s *State) readNext() (interface{}, error) {
+ if len(s.pending) > 0 {
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, nil
+ }
+ var r rune
+ select {
+ case thing, ok := <-s.next:
+ if !ok {
+ return 0, errors.New("liner: internal error")
+ }
+ if thing.err != nil {
+ return nil, thing.err
+ }
+ r = thing.r
+ case <-s.winch:
+ s.getColumns()
+ return winch, nil
+ }
+ if r != esc {
+ return r, nil
+ }
+ s.pending = append(s.pending, r)
+
+ // Wait at most 50 ms for the rest of the escape sequence
+ // If nothing else arrives, it was an actual press of the esc key
+ timeout := time.After(50 * time.Millisecond)
+ flag, err := s.nextPending(timeout)
+ if err != nil {
+ if err == errTimedOut {
+ return flag, nil
+ }
+ return unknown, err
+ }
+
+ switch flag {
+ case '[':
+ code, err := s.nextPending(timeout)
+ if err != nil {
+ if err == errTimedOut {
+ return code, nil
+ }
+ return unknown, err
+ }
+ switch code {
+ case 'A':
+ s.pending = s.pending[:0] // escape code complete
+ return up, nil
+ case 'B':
+ s.pending = s.pending[:0] // escape code complete
+ return down, nil
+ case 'C':
+ s.pending = s.pending[:0] // escape code complete
+ return right, nil
+ case 'D':
+ s.pending = s.pending[:0] // escape code complete
+ return left, nil
+ case 'F':
+ s.pending = s.pending[:0] // escape code complete
+ return end, nil
+ case 'H':
+ s.pending = s.pending[:0] // escape code complete
+ return home, nil
+ case 'Z':
+ s.pending = s.pending[:0] // escape code complete
+ return shiftTab, nil
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ num := []rune{code}
+ for {
+ code, err := s.nextPending(timeout)
+ if err != nil {
+ if err == errTimedOut {
+ return code, nil
+ }
+ return nil, err
+ }
+ switch code {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ num = append(num, code)
+ case ';':
+ // Modifier code to follow
+ // This only supports Ctrl-left and Ctrl-right for now
+ x, _ := strconv.ParseInt(string(num), 10, 32)
+ if x != 1 {
+ // Can't be left or right
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, nil
+ }
+ num = num[:0]
+ for {
+ code, err = s.nextPending(timeout)
+ if err != nil {
+ if err == errTimedOut {
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, nil
+ }
+ return nil, err
+ }
+ switch code {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ num = append(num, code)
+ case 'C', 'D':
+ // right, left
+ mod, _ := strconv.ParseInt(string(num), 10, 32)
+ if mod != 5 {
+ // Not bare Ctrl
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, nil
+ }
+ s.pending = s.pending[:0] // escape code complete
+ if code == 'C' {
+ return wordRight, nil
+ }
+ return wordLeft, nil
+ default:
+ // Not left or right
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, nil
+ }
+ }
+ case '~':
+ s.pending = s.pending[:0] // escape code complete
+ x, _ := strconv.ParseInt(string(num), 10, 32)
+ switch x {
+ case 2:
+ return insert, nil
+ case 3:
+ return del, nil
+ case 5:
+ return pageUp, nil
+ case 6:
+ return pageDown, nil
+ case 7:
+ return home, nil
+ case 8:
+ return end, nil
+ case 15:
+ return f5, nil
+ case 17:
+ return f6, nil
+ case 18:
+ return f7, nil
+ case 19:
+ return f8, nil
+ case 20:
+ return f9, nil
+ case 21:
+ return f10, nil
+ case 23:
+ return f11, nil
+ case 24:
+ return f12, nil
+ default:
+ return unknown, nil
+ }
+ default:
+ // unrecognized escape code
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, nil
+ }
+ }
+ }
+
+ case 'O':
+ code, err := s.nextPending(timeout)
+ if err != nil {
+ if err == errTimedOut {
+ return code, nil
+ }
+ return nil, err
+ }
+ s.pending = s.pending[:0] // escape code complete
+ switch code {
+ case 'c':
+ return wordRight, nil
+ case 'd':
+ return wordLeft, nil
+ case 'H':
+ return home, nil
+ case 'F':
+ return end, nil
+ case 'P':
+ return f1, nil
+ case 'Q':
+ return f2, nil
+ case 'R':
+ return f3, nil
+ case 'S':
+ return f4, nil
+ default:
+ return unknown, nil
+ }
+ case 'b':
+ s.pending = s.pending[:0] // escape code complete
+ return altB, nil
+ case 'f':
+ s.pending = s.pending[:0] // escape code complete
+ return altF, nil
+ case 'y':
+ s.pending = s.pending[:0] // escape code complete
+ return altY, nil
+ default:
+ rv := s.pending[0]
+ s.pending = s.pending[1:]
+ return rv, nil
+ }
+
+ // not reached
+ return r, nil
+}
+
+// Close returns the terminal to its previous mode
+func (s *State) Close() error {
+ stopSignal(s.winch)
+ if !s.inputRedirected {
+ s.origMode.ApplyMode()
+ }
+ return nil
+}
+
+// TerminalSupported returns true if the current terminal supports
+// line editing features, and false if liner will use the 'dumb'
+// fallback for input.
+// Note that TerminalSupported does not check all factors that may
+// cause liner to not fully support the terminal (such as stdin redirection)
+func TerminalSupported() bool {
+ bad := map[string]bool{"": true, "dumb": true, "cons25": true}
+ return !bad[strings.ToLower(os.Getenv("TERM"))]
+}
diff --git a/vendor/github.com/peterh/liner/input_darwin.go b/vendor/github.com/peterh/liner/input_darwin.go
new file mode 100644
index 00000000..23c9c5da
--- /dev/null
+++ b/vendor/github.com/peterh/liner/input_darwin.go
@@ -0,0 +1,39 @@
+// +build darwin
+
+package liner
+
+import "syscall"
+
+const (
+ getTermios = syscall.TIOCGETA
+ setTermios = syscall.TIOCSETA
+)
+
+const (
+ // Input flags
+ inpck = 0x010
+ istrip = 0x020
+ icrnl = 0x100
+ ixon = 0x200
+
+ // Output flags
+ opost = 0x1
+
+ // Control flags
+ cs8 = 0x300
+
+ // Local flags
+ isig = 0x080
+ icanon = 0x100
+ iexten = 0x400
+)
+
+type termios struct {
+ Iflag uintptr
+ Oflag uintptr
+ Cflag uintptr
+ Lflag uintptr
+ Cc [20]byte
+ Ispeed uintptr
+ Ospeed uintptr
+}
diff --git a/vendor/github.com/peterh/liner/input_linux.go b/vendor/github.com/peterh/liner/input_linux.go
new file mode 100644
index 00000000..6ca87124
--- /dev/null
+++ b/vendor/github.com/peterh/liner/input_linux.go
@@ -0,0 +1,26 @@
+// +build linux
+
+package liner
+
+import "syscall"
+
+const (
+ getTermios = syscall.TCGETS
+ setTermios = syscall.TCSETS
+)
+
+const (
+ icrnl = syscall.ICRNL
+ inpck = syscall.INPCK
+ istrip = syscall.ISTRIP
+ ixon = syscall.IXON
+ opost = syscall.OPOST
+ cs8 = syscall.CS8
+ isig = syscall.ISIG
+ icanon = syscall.ICANON
+ iexten = syscall.IEXTEN
+)
+
+type termios struct {
+ syscall.Termios
+}
diff --git a/vendor/github.com/peterh/liner/input_test.go b/vendor/github.com/peterh/liner/input_test.go
new file mode 100644
index 00000000..e515a489
--- /dev/null
+++ b/vendor/github.com/peterh/liner/input_test.go
@@ -0,0 +1,61 @@
+// +build !windows
+
+package liner
+
+import (
+ "bufio"
+ "bytes"
+ "testing"
+)
+
+func (s *State) expectRune(t *testing.T, r rune) {
+ item, err := s.readNext()
+ if err != nil {
+ t.Fatalf("Expected rune '%c', got error %s\n", r, err)
+ }
+ if v, ok := item.(rune); !ok {
+ t.Fatalf("Expected rune '%c', got non-rune %v\n", r, v)
+ } else {
+ if v != r {
+ t.Fatalf("Expected rune '%c', got rune '%c'\n", r, v)
+ }
+ }
+}
+
+func (s *State) expectAction(t *testing.T, a action) {
+ item, err := s.readNext()
+ if err != nil {
+ t.Fatalf("Expected Action %d, got error %s\n", a, err)
+ }
+ if v, ok := item.(action); !ok {
+ t.Fatalf("Expected Action %d, got non-Action %v\n", a, v)
+ } else {
+ if v != a {
+ t.Fatalf("Expected Action %d, got Action %d\n", a, v)
+ }
+ }
+}
+
+func TestTypes(t *testing.T) {
+ input := []byte{'A', 27, 'B', 27, 91, 68, 27, '[', '1', ';', '5', 'D', 'e'}
+ var s State
+ s.r = bufio.NewReader(bytes.NewBuffer(input))
+
+ next := make(chan nexter)
+ go func() {
+ for {
+ var n nexter
+ n.r, _, n.err = s.r.ReadRune()
+ next <- n
+ }
+ }()
+ s.next = next
+
+ s.expectRune(t, 'A')
+ s.expectRune(t, 27)
+ s.expectRune(t, 'B')
+ s.expectAction(t, left)
+ s.expectAction(t, wordLeft)
+
+ s.expectRune(t, 'e')
+}
diff --git a/vendor/github.com/peterh/liner/input_windows.go b/vendor/github.com/peterh/liner/input_windows.go
new file mode 100644
index 00000000..9dcc3115
--- /dev/null
+++ b/vendor/github.com/peterh/liner/input_windows.go
@@ -0,0 +1,321 @@
+package liner
+
+import (
+ "bufio"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+var (
+ kernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+ procGetStdHandle = kernel32.NewProc("GetStdHandle")
+ procReadConsoleInput = kernel32.NewProc("ReadConsoleInputW")
+ procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
+ procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
+ procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
+ procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
+ procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
+)
+
+// These names are from the Win32 api, so they use underscores (contrary to
+// what golint suggests)
+const (
+ std_input_handle = uint32(-10 & 0xFFFFFFFF)
+ std_output_handle = uint32(-11 & 0xFFFFFFFF)
+ std_error_handle = uint32(-12 & 0xFFFFFFFF)
+ invalid_handle_value = ^uintptr(0)
+)
+
+type inputMode uint32
+
+// State represents an open terminal
+type State struct {
+ commonState
+ handle syscall.Handle
+ hOut syscall.Handle
+ origMode inputMode
+ defaultMode inputMode
+ key interface{}
+ repeat uint16
+}
+
+const (
+ enableEchoInput = 0x4
+ enableInsertMode = 0x20
+ enableLineInput = 0x2
+ enableMouseInput = 0x10
+ enableProcessedInput = 0x1
+ enableQuickEditMode = 0x40
+ enableWindowInput = 0x8
+)
+
+// NewLiner initializes a new *State, and sets the terminal into raw mode. To
+// restore the terminal to its previous state, call State.Close().
+func NewLiner() *State {
+ var s State
+ hIn, _, _ := procGetStdHandle.Call(uintptr(std_input_handle))
+ s.handle = syscall.Handle(hIn)
+ hOut, _, _ := procGetStdHandle.Call(uintptr(std_output_handle))
+ s.hOut = syscall.Handle(hOut)
+
+ s.terminalSupported = true
+ if m, err := TerminalMode(); err == nil {
+ s.origMode = m.(inputMode)
+ mode := s.origMode
+ mode &^= enableEchoInput
+ mode &^= enableInsertMode
+ mode &^= enableLineInput
+ mode &^= enableMouseInput
+ mode |= enableWindowInput
+ mode.ApplyMode()
+ } else {
+ s.inputRedirected = true
+ s.r = bufio.NewReader(os.Stdin)
+ }
+
+ s.getColumns()
+ s.outputRedirected = s.columns <= 0
+
+ return &s
+}
+
+// These names are from the Win32 api, so they use underscores (contrary to
+// what golint suggests)
+const (
+ focus_event = 0x0010
+ key_event = 0x0001
+ menu_event = 0x0008
+ mouse_event = 0x0002
+ window_buffer_size_event = 0x0004
+)
+
+type input_record struct {
+ eventType uint16
+ pad uint16
+ blob [16]byte
+}
+
+type key_event_record struct {
+ KeyDown int32
+ RepeatCount uint16
+ VirtualKeyCode uint16
+ VirtualScanCode uint16
+ Char int16
+ ControlKeyState uint32
+}
+
+// These names are from the Win32 api, so they use underscores (contrary to
+// what golint suggests)
+const (
+ vk_tab = 0x09
+ vk_prior = 0x21
+ vk_next = 0x22
+ vk_end = 0x23
+ vk_home = 0x24
+ vk_left = 0x25
+ vk_up = 0x26
+ vk_right = 0x27
+ vk_down = 0x28
+ vk_insert = 0x2d
+ vk_delete = 0x2e
+ vk_f1 = 0x70
+ vk_f2 = 0x71
+ vk_f3 = 0x72
+ vk_f4 = 0x73
+ vk_f5 = 0x74
+ vk_f6 = 0x75
+ vk_f7 = 0x76
+ vk_f8 = 0x77
+ vk_f9 = 0x78
+ vk_f10 = 0x79
+ vk_f11 = 0x7a
+ vk_f12 = 0x7b
+ bKey = 0x42
+ fKey = 0x46
+ yKey = 0x59
+)
+
+const (
+ shiftPressed = 0x0010
+ leftAltPressed = 0x0002
+ leftCtrlPressed = 0x0008
+ rightAltPressed = 0x0001
+ rightCtrlPressed = 0x0004
+
+ modKeys = shiftPressed | leftAltPressed | rightAltPressed | leftCtrlPressed | rightCtrlPressed
+)
+
+func (s *State) readNext() (interface{}, error) {
+ if s.repeat > 0 {
+ s.repeat--
+ return s.key, nil
+ }
+
+ var input input_record
+ pbuf := uintptr(unsafe.Pointer(&input))
+ var rv uint32
+ prv := uintptr(unsafe.Pointer(&rv))
+
+ for {
+ ok, _, err := procReadConsoleInput.Call(uintptr(s.handle), pbuf, 1, prv)
+
+ if ok == 0 {
+ return nil, err
+ }
+
+ if input.eventType == window_buffer_size_event {
+ xy := (*coord)(unsafe.Pointer(&input.blob[0]))
+ s.columns = int(xy.x)
+ return winch, nil
+ }
+ if input.eventType != key_event {
+ continue
+ }
+ ke := (*key_event_record)(unsafe.Pointer(&input.blob[0]))
+ if ke.KeyDown == 0 {
+ continue
+ }
+
+ if ke.VirtualKeyCode == vk_tab && ke.ControlKeyState&modKeys == shiftPressed {
+ s.key = shiftTab
+ } else if ke.VirtualKeyCode == bKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
+ ke.ControlKeyState&modKeys == rightAltPressed) {
+ s.key = altB
+ } else if ke.VirtualKeyCode == fKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
+ ke.ControlKeyState&modKeys == rightAltPressed) {
+ s.key = altF
+ } else if ke.VirtualKeyCode == yKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
+ ke.ControlKeyState&modKeys == rightAltPressed) {
+ s.key = altY
+ } else if ke.Char > 0 {
+ s.key = rune(ke.Char)
+ } else {
+ switch ke.VirtualKeyCode {
+ case vk_prior:
+ s.key = pageUp
+ case vk_next:
+ s.key = pageDown
+ case vk_end:
+ s.key = end
+ case vk_home:
+ s.key = home
+ case vk_left:
+ s.key = left
+ if ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) != 0 {
+ if ke.ControlKeyState&modKeys == ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) {
+ s.key = wordLeft
+ }
+ }
+ case vk_right:
+ s.key = right
+ if ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) != 0 {
+ if ke.ControlKeyState&modKeys == ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) {
+ s.key = wordRight
+ }
+ }
+ case vk_up:
+ s.key = up
+ case vk_down:
+ s.key = down
+ case vk_insert:
+ s.key = insert
+ case vk_delete:
+ s.key = del
+ case vk_f1:
+ s.key = f1
+ case vk_f2:
+ s.key = f2
+ case vk_f3:
+ s.key = f3
+ case vk_f4:
+ s.key = f4
+ case vk_f5:
+ s.key = f5
+ case vk_f6:
+ s.key = f6
+ case vk_f7:
+ s.key = f7
+ case vk_f8:
+ s.key = f8
+ case vk_f9:
+ s.key = f9
+ case vk_f10:
+ s.key = f10
+ case vk_f11:
+ s.key = f11
+ case vk_f12:
+ s.key = f12
+ default:
+ // Eat modifier keys
+ // TODO: return Action(Unknown) if the key isn't a
+ // modifier.
+ continue
+ }
+ }
+
+ if ke.RepeatCount > 1 {
+ s.repeat = ke.RepeatCount - 1
+ }
+ return s.key, nil
+ }
+ return unknown, nil
+}
+
+// Close returns the terminal to its previous mode
+func (s *State) Close() error {
+ s.origMode.ApplyMode()
+ return nil
+}
+
+func (s *State) startPrompt() {
+ if m, err := TerminalMode(); err == nil {
+ s.defaultMode = m.(inputMode)
+ mode := s.defaultMode
+ mode &^= enableProcessedInput
+ mode.ApplyMode()
+ }
+}
+
+func (s *State) restartPrompt() {
+}
+
+func (s *State) stopPrompt() {
+ s.defaultMode.ApplyMode()
+}
+
+// TerminalSupported returns true because line editing is always
+// supported on Windows.
+func TerminalSupported() bool {
+ return true
+}
+
+func (mode inputMode) ApplyMode() error {
+ hIn, _, err := procGetStdHandle.Call(uintptr(std_input_handle))
+ if hIn == invalid_handle_value || hIn == 0 {
+ return err
+ }
+ ok, _, err := procSetConsoleMode.Call(hIn, uintptr(mode))
+ if ok != 0 {
+ err = nil
+ }
+ return err
+}
+
+// TerminalMode returns the current terminal input mode as an InputModeSetter.
+//
+// This function is provided for convenience, and should
+// not be necessary for most users of liner.
+func TerminalMode() (ModeApplier, error) {
+ var mode inputMode
+ hIn, _, err := procGetStdHandle.Call(uintptr(std_input_handle))
+ if hIn == invalid_handle_value || hIn == 0 {
+ return nil, err
+ }
+ ok, _, err := procGetConsoleMode.Call(hIn, uintptr(unsafe.Pointer(&mode)))
+ if ok != 0 {
+ err = nil
+ }
+ return mode, err
+}
diff --git a/vendor/github.com/peterh/liner/line.go b/vendor/github.com/peterh/liner/line.go
new file mode 100644
index 00000000..98fa44d9
--- /dev/null
+++ b/vendor/github.com/peterh/liner/line.go
@@ -0,0 +1,884 @@
+// +build windows linux darwin openbsd freebsd netbsd
+
+package liner
+
+import (
+ "container/ring"
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+type action int
+
+const (
+ left action = iota
+ right
+ up
+ down
+ home
+ end
+ insert
+ del
+ pageUp
+ pageDown
+ f1
+ f2
+ f3
+ f4
+ f5
+ f6
+ f7
+ f8
+ f9
+ f10
+ f11
+ f12
+ altB
+ altF
+ altY
+ shiftTab
+ wordLeft
+ wordRight
+ winch
+ unknown
+)
+
+const (
+ ctrlA = 1
+ ctrlB = 2
+ ctrlC = 3
+ ctrlD = 4
+ ctrlE = 5
+ ctrlF = 6
+ ctrlG = 7
+ ctrlH = 8
+ tab = 9
+ lf = 10
+ ctrlK = 11
+ ctrlL = 12
+ cr = 13
+ ctrlN = 14
+ ctrlO = 15
+ ctrlP = 16
+ ctrlQ = 17
+ ctrlR = 18
+ ctrlS = 19
+ ctrlT = 20
+ ctrlU = 21
+ ctrlV = 22
+ ctrlW = 23
+ ctrlX = 24
+ ctrlY = 25
+ ctrlZ = 26
+ esc = 27
+ bs = 127
+)
+
+const (
+ beep = "\a"
+)
+
+type tabDirection int
+
+const (
+ tabForward tabDirection = iota
+ tabReverse
+)
+
+func (s *State) refresh(prompt []rune, buf []rune, pos int) error {
+ s.cursorPos(0)
+ _, err := fmt.Print(string(prompt))
+ if err != nil {
+ return err
+ }
+
+ pLen := countGlyphs(prompt)
+ bLen := countGlyphs(buf)
+ pos = countGlyphs(buf[:pos])
+ if pLen+bLen < s.columns {
+ _, err = fmt.Print(string(buf))
+ s.eraseLine()
+ s.cursorPos(pLen + pos)
+ } else {
+ // Find space available
+ space := s.columns - pLen
+ space-- // space for cursor
+ start := pos - space/2
+ end := start + space
+ if end > bLen {
+ end = bLen
+ start = end - space
+ }
+ if start < 0 {
+ start = 0
+ end = space
+ }
+ pos -= start
+
+ // Leave space for markers
+ if start > 0 {
+ start++
+ }
+ if end < bLen {
+ end--
+ }
+ startRune := len(getPrefixGlyphs(buf, start))
+ line := getPrefixGlyphs(buf[startRune:], end-start)
+
+ // Output
+ if start > 0 {
+ fmt.Print("{")
+ }
+ fmt.Print(string(line))
+ if end < bLen {
+ fmt.Print("}")
+ }
+
+ // Set cursor position
+ s.eraseLine()
+ s.cursorPos(pLen + pos)
+ }
+ return err
+}
+
+func longestCommonPrefix(strs []string) string {
+ if len(strs) == 0 {
+ return ""
+ }
+ longest := strs[0]
+
+ for _, str := range strs[1:] {
+ for !strings.HasPrefix(str, longest) {
+ longest = longest[:len(longest)-1]
+ }
+ }
+ // Remove trailing partial runes
+ longest = strings.TrimRight(longest, "\uFFFD")
+ return longest
+}
+
+func (s *State) circularTabs(items []string) func(tabDirection) (string, error) {
+ item := -1
+ return func(direction tabDirection) (string, error) {
+ if direction == tabForward {
+ if item < len(items)-1 {
+ item++
+ } else {
+ item = 0
+ }
+ } else if direction == tabReverse {
+ if item > 0 {
+ item--
+ } else {
+ item = len(items) - 1
+ }
+ }
+ return items[item], nil
+ }
+}
+
+func (s *State) printedTabs(items []string) func(tabDirection) (string, error) {
+ numTabs := 1
+ prefix := longestCommonPrefix(items)
+ return func(direction tabDirection) (string, error) {
+ if len(items) == 1 {
+ return items[0], nil
+ }
+
+ if numTabs == 2 {
+ if len(items) > 100 {
+ fmt.Printf("\nDisplay all %d possibilities? (y or n) ", len(items))
+ for {
+ next, err := s.readNext()
+ if err != nil {
+ return prefix, err
+ }
+
+ if key, ok := next.(rune); ok {
+ if unicode.ToLower(key) == 'n' {
+ return prefix, nil
+ } else if unicode.ToLower(key) == 'y' {
+ break
+ }
+ }
+ }
+ }
+ fmt.Println("")
+ maxWidth := 0
+ for _, item := range items {
+ if len(item) >= maxWidth {
+ maxWidth = len(item) + 1
+ }
+ }
+
+ numColumns := s.columns / maxWidth
+ numRows := len(items) / numColumns
+ if len(items)%numColumns > 0 {
+ numRows++
+ }
+
+ if len(items) <= numColumns {
+ maxWidth = 0
+ }
+ for i := 0; i < numRows; i++ {
+ for j := 0; j < numColumns*numRows; j += numRows {
+ if i+j < len(items) {
+ if maxWidth > 0 {
+ fmt.Printf("%-*s", maxWidth, items[i+j])
+ } else {
+ fmt.Printf("%v ", items[i+j])
+ }
+ }
+ }
+ fmt.Println("")
+ }
+ } else {
+ numTabs++
+ }
+ return prefix, nil
+ }
+}
+
+func (s *State) tabComplete(p []rune, line []rune, pos int) ([]rune, int, interface{}, error) {
+ if s.completer == nil {
+ return line, pos, rune(esc), nil
+ }
+ head, list, tail := s.completer(string(line), pos)
+ if len(list) <= 0 {
+ return line, pos, rune(esc), nil
+ }
+ hl := utf8.RuneCountInString(head)
+ if len(list) == 1 {
+ s.refresh(p, []rune(head+list[0]+tail), hl+utf8.RuneCountInString(list[0]))
+ return []rune(head + list[0] + tail), hl + utf8.RuneCountInString(list[0]), rune(esc), nil
+ }
+
+ direction := tabForward
+ tabPrinter := s.circularTabs(list)
+ if s.tabStyle == TabPrints {
+ tabPrinter = s.printedTabs(list)
+ }
+
+ for {
+ pick, err := tabPrinter(direction)
+ if err != nil {
+ return line, pos, rune(esc), err
+ }
+ s.refresh(p, []rune(head+pick+tail), hl+utf8.RuneCountInString(pick))
+
+ next, err := s.readNext()
+ if err != nil {
+ return line, pos, rune(esc), err
+ }
+ if key, ok := next.(rune); ok {
+ if key == tab {
+ direction = tabForward
+ continue
+ }
+ if key == esc {
+ return line, pos, rune(esc), nil
+ }
+ }
+ if a, ok := next.(action); ok && a == shiftTab {
+ direction = tabReverse
+ continue
+ }
+ return []rune(head + pick + tail), hl + utf8.RuneCountInString(pick), next, nil
+ }
+ // Not reached
+ return line, pos, rune(esc), nil
+}
+
+// reverse intelligent search, implements a bash-like history search.
+func (s *State) reverseISearch(origLine []rune, origPos int) ([]rune, int, interface{}, error) {
+ p := "(reverse-i-search)`': "
+ s.refresh([]rune(p), origLine, origPos)
+
+ line := []rune{}
+ pos := 0
+ foundLine := string(origLine)
+ foundPos := origPos
+
+ getLine := func() ([]rune, []rune, int) {
+ search := string(line)
+ prompt := "(reverse-i-search)`%s': "
+ return []rune(fmt.Sprintf(prompt, search)), []rune(foundLine), foundPos
+ }
+
+ history, positions := s.getHistoryByPattern(string(line))
+ historyPos := len(history) - 1
+
+ for {
+ next, err := s.readNext()
+ if err != nil {
+ return []rune(foundLine), foundPos, rune(esc), err
+ }
+
+ switch v := next.(type) {
+ case rune:
+ switch v {
+ case ctrlR: // Search backwards
+ if historyPos > 0 && historyPos < len(history) {
+ historyPos--
+ foundLine = history[historyPos]
+ foundPos = positions[historyPos]
+ } else {
+ fmt.Print(beep)
+ }
+ case ctrlS: // Search forward
+ if historyPos < len(history)-1 && historyPos >= 0 {
+ historyPos++
+ foundLine = history[historyPos]
+ foundPos = positions[historyPos]
+ } else {
+ fmt.Print(beep)
+ }
+ case ctrlH, bs: // Backspace
+ if pos <= 0 {
+ fmt.Print(beep)
+ } else {
+ n := len(getSuffixGlyphs(line[:pos], 1))
+ line = append(line[:pos-n], line[pos:]...)
+ pos -= n
+
+ // For each char deleted, display the last matching line of history
+ history, positions := s.getHistoryByPattern(string(line))
+ historyPos = len(history) - 1
+ if len(history) > 0 {
+ foundLine = history[historyPos]
+ foundPos = positions[historyPos]
+ } else {
+ foundLine = ""
+ foundPos = 0
+ }
+ }
+ case ctrlG: // Cancel
+ return origLine, origPos, rune(esc), err
+
+ case tab, cr, lf, ctrlA, ctrlB, ctrlD, ctrlE, ctrlF, ctrlK,
+ ctrlL, ctrlN, ctrlO, ctrlP, ctrlQ, ctrlT, ctrlU, ctrlV, ctrlW, ctrlX, ctrlY, ctrlZ:
+ fallthrough
+ case 0, ctrlC, esc, 28, 29, 30, 31:
+ return []rune(foundLine), foundPos, next, err
+ default:
+ line = append(line[:pos], append([]rune{v}, line[pos:]...)...)
+ pos++
+
+ // For each keystroke typed, display the last matching line of history
+ history, positions = s.getHistoryByPattern(string(line))
+ historyPos = len(history) - 1
+ if len(history) > 0 {
+ foundLine = history[historyPos]
+ foundPos = positions[historyPos]
+ } else {
+ foundLine = ""
+ foundPos = 0
+ }
+ }
+ case action:
+ return []rune(foundLine), foundPos, next, err
+ }
+ s.refresh(getLine())
+ }
+}
+
+// addToKillRing adds some text to the kill ring. If mode is 0 it adds it to a
+// new node in the end of the kill ring, and move the current pointer to the new
+// node. If mode is 1 or 2 it appends or prepends the text to the current entry
+// of the killRing.
+func (s *State) addToKillRing(text []rune, mode int) {
+ // Don't use the same underlying array as text
+ killLine := make([]rune, len(text))
+ copy(killLine, text)
+
+ // Point killRing to a newNode, procedure depends on the killring state and
+ // append mode.
+ if mode == 0 { // Add new node to killRing
+ if s.killRing == nil { // if killring is empty, create a new one
+ s.killRing = ring.New(1)
+ } else if s.killRing.Len() >= KillRingMax { // if killring is "full"
+ s.killRing = s.killRing.Next()
+ } else { // Normal case
+ s.killRing.Link(ring.New(1))
+ s.killRing = s.killRing.Next()
+ }
+ } else {
+ if s.killRing == nil { // if killring is empty, create a new one
+ s.killRing = ring.New(1)
+ s.killRing.Value = []rune{}
+ }
+ if mode == 1 { // Append to last entry
+ killLine = append(s.killRing.Value.([]rune), killLine...)
+ } else if mode == 2 { // Prepend to last entry
+ killLine = append(killLine, s.killRing.Value.([]rune)...)
+ }
+ }
+
+ // Save text in the current killring node
+ s.killRing.Value = killLine
+}
+
+func (s *State) yank(p []rune, text []rune, pos int) ([]rune, int, interface{}, error) {
+ if s.killRing == nil {
+ return text, pos, rune(esc), nil
+ }
+
+ lineStart := text[:pos]
+ lineEnd := text[pos:]
+ var line []rune
+
+ for {
+ value := s.killRing.Value.([]rune)
+ line = make([]rune, 0)
+ line = append(line, lineStart...)
+ line = append(line, value...)
+ line = append(line, lineEnd...)
+
+ pos = len(lineStart) + len(value)
+ s.refresh(p, line, pos)
+
+ next, err := s.readNext()
+ if err != nil {
+ return line, pos, next, err
+ }
+
+ switch v := next.(type) {
+ case rune:
+ return line, pos, next, nil
+ case action:
+ switch v {
+ case altY:
+ s.killRing = s.killRing.Prev()
+ default:
+ return line, pos, next, nil
+ }
+ }
+ }
+
+ return line, pos, esc, nil
+}
+
+// Prompt displays p and returns a line of user input, not including a trailing
+// newline character. An io.EOF error is returned if the user signals end-of-file
+// by pressing Ctrl-D. Prompt allows line editing if the terminal supports it.
+func (s *State) Prompt(prompt string) (string, error) {
+ if s.inputRedirected || !s.terminalSupported {
+ return s.promptUnsupported(prompt)
+ }
+ if s.outputRedirected {
+ return "", ErrNotTerminalOutput
+ }
+
+ s.historyMutex.RLock()
+ defer s.historyMutex.RUnlock()
+
+ s.startPrompt()
+ defer s.stopPrompt()
+ s.getColumns()
+
+ fmt.Print(prompt)
+ p := []rune(prompt)
+ var line []rune
+ pos := 0
+ historyEnd := ""
+ prefixHistory := s.getHistoryByPrefix(string(line))
+ historyPos := len(prefixHistory)
+ historyAction := false // used to mark history related actions
+ killAction := 0 // used to mark kill related actions
+mainLoop:
+ for {
+ next, err := s.readNext()
+ haveNext:
+ if err != nil {
+ return "", err
+ }
+
+ historyAction = false
+ switch v := next.(type) {
+ case rune:
+ switch v {
+ case cr, lf:
+ fmt.Println()
+ break mainLoop
+ case ctrlA: // Start of line
+ pos = 0
+ s.refresh(p, line, pos)
+ case ctrlE: // End of line
+ pos = len(line)
+ s.refresh(p, line, pos)
+ case ctrlB: // left
+ if pos > 0 {
+ pos -= len(getSuffixGlyphs(line[:pos], 1))
+ s.refresh(p, line, pos)
+ } else {
+ fmt.Print(beep)
+ }
+ case ctrlF: // right
+ if pos < len(line) {
+ pos += len(getPrefixGlyphs(line[pos:], 1))
+ s.refresh(p, line, pos)
+ } else {
+ fmt.Print(beep)
+ }
+ case ctrlD: // del
+ if pos == 0 && len(line) == 0 {
+ // exit
+ return "", io.EOF
+ }
+
+ // ctrlD is a potential EOF, so the rune reader shuts down.
+ // Therefore, if it isn't actually an EOF, we must re-startPrompt.
+ s.restartPrompt()
+
+ if pos >= len(line) {
+ fmt.Print(beep)
+ } else {
+ n := len(getPrefixGlyphs(line[pos:], 1))
+ line = append(line[:pos], line[pos+n:]...)
+ s.refresh(p, line, pos)
+ }
+ case ctrlK: // delete remainder of line
+ if pos >= len(line) {
+ fmt.Print(beep)
+ } else {
+ if killAction > 0 {
+ s.addToKillRing(line[pos:], 1) // Add in apend mode
+ } else {
+ s.addToKillRing(line[pos:], 0) // Add in normal mode
+ }
+
+ killAction = 2 // Mark that there was a kill action
+ line = line[:pos]
+ s.refresh(p, line, pos)
+ }
+ case ctrlP: // up
+ historyAction = true
+ if historyPos > 0 {
+ if historyPos == len(prefixHistory) {
+ historyEnd = string(line)
+ }
+ historyPos--
+ line = []rune(prefixHistory[historyPos])
+ pos = len(line)
+ s.refresh(p, line, pos)
+ } else {
+ fmt.Print(beep)
+ }
+ case ctrlN: // down
+ historyAction = true
+ if historyPos < len(prefixHistory) {
+ historyPos++
+ if historyPos == len(prefixHistory) {
+ line = []rune(historyEnd)
+ } else {
+ line = []rune(prefixHistory[historyPos])
+ }
+ pos = len(line)
+ s.refresh(p, line, pos)
+ } else {
+ fmt.Print(beep)
+ }
+ case ctrlT: // transpose prev glyph with glyph under cursor
+ if len(line) < 2 || pos < 1 {
+ fmt.Print(beep)
+ } else {
+ if pos == len(line) {
+ pos -= len(getSuffixGlyphs(line, 1))
+ }
+ prev := getSuffixGlyphs(line[:pos], 1)
+ next := getPrefixGlyphs(line[pos:], 1)
+ scratch := make([]rune, len(prev))
+ copy(scratch, prev)
+ copy(line[pos-len(prev):], next)
+ copy(line[pos-len(prev)+len(next):], scratch)
+ pos += len(next)
+ s.refresh(p, line, pos)
+ }
+ case ctrlL: // clear screen
+ s.eraseScreen()
+ s.refresh(p, line, pos)
+ case ctrlC: // reset
+ fmt.Println("^C")
+ if s.ctrlCAborts {
+ return "", ErrPromptAborted
+ }
+ line = line[:0]
+ pos = 0
+ fmt.Print(prompt)
+ s.restartPrompt()
+ case ctrlH, bs: // Backspace
+ if pos <= 0 {
+ fmt.Print(beep)
+ } else {
+ n := len(getSuffixGlyphs(line[:pos], 1))
+ line = append(line[:pos-n], line[pos:]...)
+ pos -= n
+ s.refresh(p, line, pos)
+ }
+ case ctrlU: // Erase line before cursor
+ if killAction > 0 {
+ s.addToKillRing(line[:pos], 2) // Add in prepend mode
+ } else {
+ s.addToKillRing(line[:pos], 0) // Add in normal mode
+ }
+
+ killAction = 2 // Mark that there was some killing
+ line = line[pos:]
+ pos = 0
+ s.refresh(p, line, pos)
+ case ctrlW: // Erase word
+ if pos == 0 {
+ fmt.Print(beep)
+ break
+ }
+ // Remove whitespace to the left
+ var buf []rune // Store the deleted chars in a buffer
+ for {
+ if pos == 0 || !unicode.IsSpace(line[pos-1]) {
+ break
+ }
+ buf = append(buf, line[pos-1])
+ line = append(line[:pos-1], line[pos:]...)
+ pos--
+ }
+ // Remove non-whitespace to the left
+ for {
+ if pos == 0 || unicode.IsSpace(line[pos-1]) {
+ break
+ }
+ buf = append(buf, line[pos-1])
+ line = append(line[:pos-1], line[pos:]...)
+ pos--
+ }
+ // Invert the buffer and save the result on the killRing
+ var newBuf []rune
+ for i := len(buf) - 1; i >= 0; i-- {
+ newBuf = append(newBuf, buf[i])
+ }
+ if killAction > 0 {
+ s.addToKillRing(newBuf, 2) // Add in prepend mode
+ } else {
+ s.addToKillRing(newBuf, 0) // Add in normal mode
+ }
+ killAction = 2 // Mark that there was some killing
+
+ s.refresh(p, line, pos)
+ case ctrlY: // Paste from Yank buffer
+ line, pos, next, err = s.yank(p, line, pos)
+ goto haveNext
+ case ctrlR: // Reverse Search
+ line, pos, next, err = s.reverseISearch(line, pos)
+ s.refresh(p, line, pos)
+ goto haveNext
+ case tab: // Tab completion
+ line, pos, next, err = s.tabComplete(p, line, pos)
+ goto haveNext
+ // Catch keys that do nothing, but you don't want them to beep
+ case esc:
+ // DO NOTHING
+ // Unused keys
+ case ctrlG, ctrlO, ctrlQ, ctrlS, ctrlV, ctrlX, ctrlZ:
+ fallthrough
+ // Catch unhandled control codes (anything <= 31)
+ case 0, 28, 29, 30, 31:
+ fmt.Print(beep)
+ default:
+ if pos == len(line) && len(p)+len(line) < s.columns-1 {
+ line = append(line, v)
+ fmt.Printf("%c", v)
+ pos++
+ } else {
+ line = append(line[:pos], append([]rune{v}, line[pos:]...)...)
+ pos++
+ s.refresh(p, line, pos)
+ }
+ }
+ case action:
+ switch v {
+ case del:
+ if pos >= len(line) {
+ fmt.Print(beep)
+ } else {
+ n := len(getPrefixGlyphs(line[pos:], 1))
+ line = append(line[:pos], line[pos+n:]...)
+ }
+ case left:
+ if pos > 0 {
+ pos -= len(getSuffixGlyphs(line[:pos], 1))
+ } else {
+ fmt.Print(beep)
+ }
+ case wordLeft, altB:
+ if pos > 0 {
+ var spaceHere, spaceLeft, leftKnown bool
+ for {
+ pos--
+ if pos == 0 {
+ break
+ }
+ if leftKnown {
+ spaceHere = spaceLeft
+ } else {
+ spaceHere = unicode.IsSpace(line[pos])
+ }
+ spaceLeft, leftKnown = unicode.IsSpace(line[pos-1]), true
+ if !spaceHere && spaceLeft {
+ break
+ }
+ }
+ } else {
+ fmt.Print(beep)
+ }
+ case right:
+ if pos < len(line) {
+ pos += len(getPrefixGlyphs(line[pos:], 1))
+ } else {
+ fmt.Print(beep)
+ }
+ case wordRight, altF:
+ if pos < len(line) {
+ var spaceHere, spaceLeft, hereKnown bool
+ for {
+ pos++
+ if pos == len(line) {
+ break
+ }
+ if hereKnown {
+ spaceLeft = spaceHere
+ } else {
+ spaceLeft = unicode.IsSpace(line[pos-1])
+ }
+ spaceHere, hereKnown = unicode.IsSpace(line[pos]), true
+ if spaceHere && !spaceLeft {
+ break
+ }
+ }
+ } else {
+ fmt.Print(beep)
+ }
+ case up:
+ historyAction = true
+ if historyPos > 0 {
+ if historyPos == len(prefixHistory) {
+ historyEnd = string(line)
+ }
+ historyPos--
+ line = []rune(prefixHistory[historyPos])
+ pos = len(line)
+ } else {
+ fmt.Print(beep)
+ }
+ case down:
+ historyAction = true
+ if historyPos < len(prefixHistory) {
+ historyPos++
+ if historyPos == len(prefixHistory) {
+ line = []rune(historyEnd)
+ } else {
+ line = []rune(prefixHistory[historyPos])
+ }
+ pos = len(line)
+ } else {
+ fmt.Print(beep)
+ }
+ case home: // Start of line
+ pos = 0
+ case end: // End of line
+ pos = len(line)
+ }
+ s.refresh(p, line, pos)
+ }
+ if !historyAction {
+ prefixHistory = s.getHistoryByPrefix(string(line))
+ historyPos = len(prefixHistory)
+ }
+ if killAction > 0 {
+ killAction--
+ }
+ }
+ return string(line), nil
+}
+
+// PasswordPrompt displays p, and then waits for user input. The input typed by
+// the user is not displayed in the terminal.
+func (s *State) PasswordPrompt(prompt string) (string, error) {
+ if !s.terminalSupported {
+ return "", errors.New("liner: function not supported in this terminal")
+ }
+ if s.inputRedirected {
+ return s.promptUnsupported(prompt)
+ }
+ if s.outputRedirected {
+ return "", ErrNotTerminalOutput
+ }
+
+ s.startPrompt()
+ defer s.stopPrompt()
+ s.getColumns()
+
+ fmt.Print(prompt)
+ p := []rune(prompt)
+ var line []rune
+ pos := 0
+
+mainLoop:
+ for {
+ next, err := s.readNext()
+ if err != nil {
+ return "", err
+ }
+
+ switch v := next.(type) {
+ case rune:
+ switch v {
+ case cr, lf:
+ fmt.Println()
+ break mainLoop
+ case ctrlD: // del
+ if pos == 0 && len(line) == 0 {
+ // exit
+ return "", io.EOF
+ }
+
+ // ctrlD is a potential EOF, so the rune reader shuts down.
+ // Therefore, if it isn't actually an EOF, we must re-startPrompt.
+ s.restartPrompt()
+ case ctrlL: // clear screen
+ s.eraseScreen()
+ s.refresh(p, []rune{}, 0)
+ case ctrlH, bs: // Backspace
+ if pos <= 0 {
+ fmt.Print(beep)
+ } else {
+ n := len(getSuffixGlyphs(line[:pos], 1))
+ line = append(line[:pos-n], line[pos:]...)
+ pos -= n
+ }
+ case ctrlC:
+ fmt.Println("^C")
+ if s.ctrlCAborts {
+ return "", ErrPromptAborted
+ }
+ line = line[:0]
+ pos = 0
+ fmt.Print(prompt)
+ s.restartPrompt()
+ // Unused keys
+ case esc, tab, ctrlA, ctrlB, ctrlE, ctrlF, ctrlG, ctrlK, ctrlN, ctrlO, ctrlP, ctrlQ, ctrlR, ctrlS,
+ ctrlT, ctrlU, ctrlV, ctrlW, ctrlX, ctrlY, ctrlZ:
+ fallthrough
+ // Catch unhandled control codes (anything <= 31)
+ case 0, 28, 29, 30, 31:
+ fmt.Print(beep)
+ default:
+ line = append(line[:pos], append([]rune{v}, line[pos:]...)...)
+ pos++
+ }
+ }
+ }
+ return string(line), nil
+}
diff --git a/vendor/github.com/peterh/liner/line_test.go b/vendor/github.com/peterh/liner/line_test.go
new file mode 100644
index 00000000..727da6ce
--- /dev/null
+++ b/vendor/github.com/peterh/liner/line_test.go
@@ -0,0 +1,90 @@
+package liner
+
+import (
+ "bytes"
+ "strings"
+ "testing"
+)
+
+func TestAppend(t *testing.T) {
+ var s State
+ s.AppendHistory("foo")
+ s.AppendHistory("bar")
+
+ var out bytes.Buffer
+ num, err := s.WriteHistory(&out)
+ if err != nil {
+ t.Fatal("Unexpected error writing history", err)
+ }
+ if num != 2 {
+ t.Fatalf("Expected 2 history entries, got %d", num)
+ }
+
+ s.AppendHistory("baz")
+ num, err = s.WriteHistory(&out)
+ if err != nil {
+ t.Fatal("Unexpected error writing history", err)
+ }
+ if num != 3 {
+ t.Fatalf("Expected 3 history entries, got %d", num)
+ }
+
+ s.AppendHistory("baz")
+ num, err = s.WriteHistory(&out)
+ if err != nil {
+ t.Fatal("Unexpected error writing history", err)
+ }
+ if num != 3 {
+ t.Fatalf("Expected 3 history entries after duplicate append, got %d", num)
+ }
+
+ s.AppendHistory("baz")
+
+}
+
+func TestHistory(t *testing.T) {
+ input := `foo
+bar
+baz
+quux
+dingle`
+
+ var s State
+ num, err := s.ReadHistory(strings.NewReader(input))
+ if err != nil {
+ t.Fatal("Unexpected error reading history", err)
+ }
+ if num != 5 {
+ t.Fatal("Wrong number of history entries read")
+ }
+
+ var out bytes.Buffer
+ num, err = s.WriteHistory(&out)
+ if err != nil {
+ t.Fatal("Unexpected error writing history", err)
+ }
+ if num != 5 {
+ t.Fatal("Wrong number of history entries written")
+ }
+ if strings.TrimSpace(out.String()) != input {
+ t.Fatal("Round-trip failure")
+ }
+
+ // Test reading with a trailing newline present
+ var s2 State
+ num, err = s2.ReadHistory(&out)
+ if err != nil {
+ t.Fatal("Unexpected error reading history the 2nd time", err)
+ }
+ if num != 5 {
+ t.Fatal("Wrong number of history entries read the 2nd time")
+ }
+
+ num, err = s.ReadHistory(strings.NewReader(input + "\n\xff"))
+ if err == nil {
+ t.Fatal("Unexpected success reading corrupted history", err)
+ }
+ if num != 5 {
+ t.Fatal("Wrong number of history entries read the 3rd time")
+ }
+}
diff --git a/vendor/github.com/peterh/liner/output.go b/vendor/github.com/peterh/liner/output.go
new file mode 100644
index 00000000..e91f4ea8
--- /dev/null
+++ b/vendor/github.com/peterh/liner/output.go
@@ -0,0 +1,63 @@
+// +build linux darwin openbsd freebsd netbsd
+
+package liner
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+func (s *State) cursorPos(x int) {
+ if s.useCHA {
+ // 'G' is "Cursor Character Absolute (CHA)"
+ fmt.Printf("\x1b[%dG", x+1)
+ } else {
+ // 'C' is "Cursor Forward (CUF)"
+ fmt.Print("\r")
+ if x > 0 {
+ fmt.Printf("\x1b[%dC", x)
+ }
+ }
+}
+
+func (s *State) eraseLine() {
+ fmt.Print("\x1b[0K")
+}
+
+func (s *State) eraseScreen() {
+ fmt.Print("\x1b[H\x1b[2J")
+}
+
+type winSize struct {
+ row, col uint16
+ xpixel, ypixel uint16
+}
+
+func (s *State) getColumns() {
+ var ws winSize
+ ok, _, _ := syscall.Syscall(syscall.SYS_IOCTL, uintptr(syscall.Stdout),
+ syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&ws)))
+ if ok < 0 {
+ s.columns = 80
+ }
+ s.columns = int(ws.col)
+}
+
+func (s *State) checkOutput() {
+ // xterm is known to support CHA
+ if strings.Contains(strings.ToLower(os.Getenv("TERM")), "xterm") {
+ s.useCHA = true
+ return
+ }
+
+ // The test for functional ANSI CHA is unreliable (eg the Windows
+ // telnet command does not support reading the cursor position with
+ // an ANSI DSR request, despite setting TERM=ansi)
+
+ // Assume CHA isn't supported (which should be safe, although it
+ // does result in occasional visible cursor jitter)
+ s.useCHA = false
+}
diff --git a/vendor/github.com/peterh/liner/output_windows.go b/vendor/github.com/peterh/liner/output_windows.go
new file mode 100644
index 00000000..27ae55a1
--- /dev/null
+++ b/vendor/github.com/peterh/liner/output_windows.go
@@ -0,0 +1,54 @@
+package liner
+
+import (
+ "unsafe"
+)
+
+type coord struct {
+ x, y int16
+}
+type smallRect struct {
+ left, top, right, bottom int16
+}
+
+type consoleScreenBufferInfo struct {
+ dwSize coord
+ dwCursorPosition coord
+ wAttributes int16
+ srWindow smallRect
+ dwMaximumWindowSize coord
+}
+
+func (s *State) cursorPos(x int) {
+ var sbi consoleScreenBufferInfo
+ procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
+ procSetConsoleCursorPosition.Call(uintptr(s.hOut),
+ uintptr(int(x)&0xFFFF|int(sbi.dwCursorPosition.y)<<16))
+}
+
+func (s *State) eraseLine() {
+ var sbi consoleScreenBufferInfo
+ procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
+ var numWritten uint32
+ procFillConsoleOutputCharacter.Call(uintptr(s.hOut), uintptr(' '),
+ uintptr(sbi.dwSize.x-sbi.dwCursorPosition.x),
+ uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|int(sbi.dwCursorPosition.y)<<16),
+ uintptr(unsafe.Pointer(&numWritten)))
+}
+
+func (s *State) eraseScreen() {
+ var sbi consoleScreenBufferInfo
+ procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
+ var numWritten uint32
+ procFillConsoleOutputCharacter.Call(uintptr(s.hOut), uintptr(' '),
+ uintptr(sbi.dwSize.x)*uintptr(sbi.dwSize.y),
+ 0,
+ uintptr(unsafe.Pointer(&numWritten)))
+ procSetConsoleCursorPosition.Call(uintptr(s.hOut), 0)
+}
+
+func (s *State) getColumns() {
+ var sbi consoleScreenBufferInfo
+ procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
+ s.columns = int(sbi.dwSize.x)
+}
diff --git a/vendor/github.com/peterh/liner/prefix_test.go b/vendor/github.com/peterh/liner/prefix_test.go
new file mode 100644
index 00000000..c826d6c3
--- /dev/null
+++ b/vendor/github.com/peterh/liner/prefix_test.go
@@ -0,0 +1,37 @@
+// +build windows linux darwin openbsd freebsd netbsd
+
+package liner
+
+import "testing"
+
+type testItem struct {
+ list []string
+ prefix string
+}
+
+func TestPrefix(t *testing.T) {
+ list := []testItem{
+ {[]string{"food", "foot"}, "foo"},
+ {[]string{"foo", "foot"}, "foo"},
+ {[]string{"food", "foo"}, "foo"},
+ {[]string{"food", "foe", "foot"}, "fo"},
+ {[]string{"food", "foot", "barbeque"}, ""},
+ {[]string{"cafeteria", "café"}, "caf"},
+ {[]string{"cafe", "café"}, "caf"},
+ {[]string{"cafè", "café"}, "caf"},
+ {[]string{"cafés", "café"}, "café"},
+ {[]string{"áéíóú", "áéíóú"}, "áéíóú"},
+ {[]string{"éclairs", "éclairs"}, "éclairs"},
+ {[]string{"éclairs are the best", "éclairs are great", "éclairs"}, "éclairs"},
+ {[]string{"éclair", "éclairs"}, "éclair"},
+ {[]string{"éclairs", "éclair"}, "éclair"},
+ {[]string{"éclair", "élan"}, "é"},
+ }
+
+ for _, test := range list {
+ lcp := longestCommonPrefix(test.list)
+ if lcp != test.prefix {
+ t.Errorf("%s != %s for %+v", lcp, test.prefix, test.list)
+ }
+ }
+}
diff --git a/vendor/github.com/peterh/liner/race_test.go b/vendor/github.com/peterh/liner/race_test.go
new file mode 100644
index 00000000..e320849c
--- /dev/null
+++ b/vendor/github.com/peterh/liner/race_test.go
@@ -0,0 +1,44 @@
+// +build race
+
+package liner
+
+import (
+ "io/ioutil"
+ "os"
+ "sync"
+ "testing"
+)
+
+func TestWriteHistory(t *testing.T) {
+ oldout := os.Stdout
+ defer func() { os.Stdout = oldout }()
+ oldin := os.Stdout
+ defer func() { os.Stdin = oldin }()
+
+ newinr, newinw, err := os.Pipe()
+ if err != nil {
+ t.Fatal(err)
+ }
+ os.Stdin = newinr
+ newoutr, newoutw, err := os.Pipe()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer newoutr.Close()
+ os.Stdout = newoutw
+
+ var wait sync.WaitGroup
+ wait.Add(1)
+ s := NewLiner()
+ go func() {
+ s.AppendHistory("foo")
+ s.AppendHistory("bar")
+ s.Prompt("")
+ wait.Done()
+ }()
+
+ s.WriteHistory(ioutil.Discard)
+
+ newinw.Close()
+ wait.Wait()
+}
diff --git a/vendor/github.com/peterh/liner/signal.go b/vendor/github.com/peterh/liner/signal.go
new file mode 100644
index 00000000..0cba79e7
--- /dev/null
+++ b/vendor/github.com/peterh/liner/signal.go
@@ -0,0 +1,12 @@
+// +build go1.1,!windows
+
+package liner
+
+import (
+ "os"
+ "os/signal"
+)
+
+func stopSignal(c chan<- os.Signal) {
+ signal.Stop(c)
+}
diff --git a/vendor/github.com/peterh/liner/signal_legacy.go b/vendor/github.com/peterh/liner/signal_legacy.go
new file mode 100644
index 00000000..fa3672da
--- /dev/null
+++ b/vendor/github.com/peterh/liner/signal_legacy.go
@@ -0,0 +1,11 @@
+// +build !go1.1,!windows
+
+package liner
+
+import (
+ "os"
+)
+
+func stopSignal(c chan<- os.Signal) {
+ // signal.Stop does not exist before Go 1.1
+}
diff --git a/vendor/github.com/peterh/liner/unixmode.go b/vendor/github.com/peterh/liner/unixmode.go
new file mode 100644
index 00000000..9838923f
--- /dev/null
+++ b/vendor/github.com/peterh/liner/unixmode.go
@@ -0,0 +1,37 @@
+// +build linux darwin freebsd openbsd netbsd
+
+package liner
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func (mode *termios) ApplyMode() error {
+ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(syscall.Stdin), setTermios, uintptr(unsafe.Pointer(mode)))
+
+ if errno != 0 {
+ return errno
+ }
+ return nil
+}
+
+// TerminalMode returns the current terminal input mode as an InputModeSetter.
+//
+// This function is provided for convenience, and should
+// not be necessary for most users of liner.
+func TerminalMode() (ModeApplier, error) {
+ mode, errno := getMode(syscall.Stdin)
+
+ if errno != 0 {
+ return nil, errno
+ }
+ return mode, nil
+}
+
+func getMode(handle int) (*termios, syscall.Errno) {
+ var mode termios
+ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(handle), getTermios, uintptr(unsafe.Pointer(&mode)))
+
+ return &mode, errno
+}
diff --git a/vendor/github.com/peterh/liner/width.go b/vendor/github.com/peterh/liner/width.go
new file mode 100644
index 00000000..5c6bf685
--- /dev/null
+++ b/vendor/github.com/peterh/liner/width.go
@@ -0,0 +1,60 @@
+package liner
+
+import "unicode"
+
+// These character classes are mostly zero width (when combined).
+// A few might not be, depending on the user's font. Fixing this
+// is non-trivial, given that some terminals don't support
+// ANSI DSR/CPR
+var zeroWidth = []*unicode.RangeTable{
+ unicode.Mn,
+ unicode.Me,
+ unicode.Cc,
+ unicode.Cf,
+}
+
+var doubleWidth = []*unicode.RangeTable{
+ unicode.Han,
+ unicode.Hangul,
+ unicode.Hiragana,
+ unicode.Katakana,
+}
+
+// countGlyphs considers zero-width characters to be zero glyphs wide,
+// and members of Chinese, Japanese, and Korean scripts to be 2 glyphs wide.
+func countGlyphs(s []rune) int {
+ n := 0
+ for _, r := range s {
+ switch {
+ case unicode.IsOneOf(zeroWidth, r):
+ case unicode.IsOneOf(doubleWidth, r):
+ n += 2
+ default:
+ n++
+ }
+ }
+ return n
+}
+
+func getPrefixGlyphs(s []rune, num int) []rune {
+ p := 0
+ for n := 0; n < num && p < len(s); p++ {
+ if !unicode.IsOneOf(zeroWidth, s[p]) {
+ n++
+ }
+ }
+ for p < len(s) && unicode.IsOneOf(zeroWidth, s[p]) {
+ p++
+ }
+ return s[:p]
+}
+
+func getSuffixGlyphs(s []rune, num int) []rune {
+ p := len(s)
+ for n := 0; n < num && p > 0; p-- {
+ if !unicode.IsOneOf(zeroWidth, s[p-1]) {
+ n++
+ }
+ }
+ return s[p:]
+}
diff --git a/vendor/github.com/peterh/liner/width_test.go b/vendor/github.com/peterh/liner/width_test.go
new file mode 100644
index 00000000..add779c8
--- /dev/null
+++ b/vendor/github.com/peterh/liner/width_test.go
@@ -0,0 +1,102 @@
+package liner
+
+import (
+ "strconv"
+ "testing"
+)
+
+func accent(in []rune) []rune {
+ var out []rune
+ for _, r := range in {
+ out = append(out, r)
+ out = append(out, '\u0301')
+ }
+ return out
+}
+
+type testCase struct {
+ s []rune
+ glyphs int
+}
+
+var testCases = []testCase{
+ {[]rune("query"), 5},
+ {[]rune("私"), 2},
+ {[]rune("hello世界"), 9},
+}
+
+func TestCountGlyphs(t *testing.T) {
+ for _, testCase := range testCases {
+ count := countGlyphs(testCase.s)
+ if count != testCase.glyphs {
+ t.Errorf("ASCII count incorrect. %d != %d", count, testCase.glyphs)
+ }
+ count = countGlyphs(accent(testCase.s))
+ if count != testCase.glyphs {
+ t.Errorf("Accent count incorrect. %d != %d", count, testCase.glyphs)
+ }
+ }
+}
+
+func compare(a, b []rune, name string, t *testing.T) {
+ if len(a) != len(b) {
+ t.Errorf(`"%s" != "%s" in %s"`, string(a), string(b), name)
+ return
+ }
+ for i := range a {
+ if a[i] != b[i] {
+ t.Errorf(`"%s" != "%s" in %s"`, string(a), string(b), name)
+ return
+ }
+ }
+}
+
+func TestPrefixGlyphs(t *testing.T) {
+ for _, testCase := range testCases {
+ for i := 0; i <= len(testCase.s); i++ {
+ iter := strconv.Itoa(i)
+ out := getPrefixGlyphs(testCase.s, i)
+ compare(out, testCase.s[:i], "ascii prefix "+iter, t)
+ out = getPrefixGlyphs(accent(testCase.s), i)
+ compare(out, accent(testCase.s[:i]), "accent prefix "+iter, t)
+ }
+ out := getPrefixGlyphs(testCase.s, 999)
+ compare(out, testCase.s, "ascii prefix overflow", t)
+ out = getPrefixGlyphs(accent(testCase.s), 999)
+ compare(out, accent(testCase.s), "accent prefix overflow", t)
+
+ out = getPrefixGlyphs(testCase.s, -3)
+ if len(out) != 0 {
+ t.Error("ascii prefix negative")
+ }
+ out = getPrefixGlyphs(accent(testCase.s), -3)
+ if len(out) != 0 {
+ t.Error("accent prefix negative")
+ }
+ }
+}
+
+func TestSuffixGlyphs(t *testing.T) {
+ for _, testCase := range testCases {
+ for i := 0; i <= len(testCase.s); i++ {
+ iter := strconv.Itoa(i)
+ out := getSuffixGlyphs(testCase.s, i)
+ compare(out, testCase.s[len(testCase.s)-i:], "ascii suffix "+iter, t)
+ out = getSuffixGlyphs(accent(testCase.s), i)
+ compare(out, accent(testCase.s[len(testCase.s)-i:]), "accent suffix "+iter, t)
+ }
+ out := getSuffixGlyphs(testCase.s, 999)
+ compare(out, testCase.s, "ascii suffix overflow", t)
+ out = getSuffixGlyphs(accent(testCase.s), 999)
+ compare(out, accent(testCase.s), "accent suffix overflow", t)
+
+ out = getSuffixGlyphs(testCase.s, -3)
+ if len(out) != 0 {
+ t.Error("ascii suffix negative")
+ }
+ out = getSuffixGlyphs(accent(testCase.s), -3)
+ if len(out) != 0 {
+ t.Error("accent suffix negative")
+ }
+ }
+}
diff --git a/vendor/github.com/russross/blackfriday/.gitignore b/vendor/github.com/russross/blackfriday/.gitignore
new file mode 100644
index 00000000..75623dcc
--- /dev/null
+++ b/vendor/github.com/russross/blackfriday/.gitignore
@@ -0,0 +1,8 @@
+*.out
+*.swp
+*.8
+*.6
+_obj
+_test*
+markdown
+tags
diff --git a/vendor/github.com/russross/blackfriday/.travis.yml b/vendor/github.com/russross/blackfriday/.travis.yml
new file mode 100644
index 00000000..4dd7a1c5
--- /dev/null
+++ b/vendor/github.com/russross/blackfriday/.travis.yml
@@ -0,0 +1,17 @@
+# Travis CI (http://travis-ci.org/) is a continuous integration service for
+# open source projects. This file configures it to run unit tests for
+# blackfriday.
+
+language: go
+
+go:
+ - 1.2
+ - 1.3
+ - 1.4
+
+install:
+ - go get -d -t -v ./...
+ - go build -v ./...
+
+script:
+ - go test -v ./...
diff --git a/vendor/github.com/russross/blackfriday/README.md b/vendor/github.com/russross/blackfriday/README.md
new file mode 100644
index 00000000..52e3b25b
--- /dev/null
+++ b/vendor/github.com/russross/blackfriday/README.md
@@ -0,0 +1,246 @@
+Blackfriday [](https://travis-ci.org/russross/blackfriday)
+===========
+
+Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It
+is paranoid about its input (so you can safely feed it user-supplied
+data), it is fast, it supports common extensions (tables, smart
+punctuation substitutions, etc.), and it is safe for all utf-8
+(unicode) input.
+
+HTML output is currently supported, along with Smartypants
+extensions. An experimental LaTeX output engine is also included.
+
+It started as a translation from C of [Sundown][3].
+
+
+Installation
+------------
+
+Blackfriday is compatible with Go 1. If you are using an older
+release of Go, consider using v1.1 of blackfriday, which was based
+on the last stable release of Go prior to Go 1. You can find it as a
+tagged commit on github.
+
+With Go 1 and git installed:
+
+ go get github.com/russross/blackfriday
+
+will download, compile, and install the package into your `$GOPATH`
+directory hierarchy. Alternatively, you can achieve the same if you
+import it into a project:
+
+ import "github.com/russross/blackfriday"
+
+and `go get` without parameters.
+
+Usage
+-----
+
+For basic usage, it is as simple as getting your input into a byte
+slice and calling:
+
+ output := blackfriday.MarkdownBasic(input)
+
+This renders it with no extensions enabled. To get a more useful
+feature set, use this instead:
+
+ output := blackfriday.MarkdownCommon(input)
+
+### Sanitize untrusted content
+
+Blackfriday itself does nothing to protect against malicious content. If you are
+dealing with user-supplied markdown, we recommend running blackfriday's output
+through HTML sanitizer such as
+[Bluemonday](https://github.com/microcosm-cc/bluemonday).
+
+Here's an example of simple usage of blackfriday together with bluemonday:
+
+``` go
+import (
+ "github.com/microcosm-cc/bluemonday"
+ "github.com/russross/blackfriday"
+)
+
+// ...
+unsafe := blackfriday.MarkdownCommon(input)
+html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
+```
+
+### Custom options
+
+If you want to customize the set of options, first get a renderer
+(currently either the HTML or LaTeX output engines), then use it to
+call the more general `Markdown` function. For examples, see the
+implementations of `MarkdownBasic` and `MarkdownCommon` in
+`markdown.go`.
+
+You can also check out `blackfriday-tool` for a more complete example
+of how to use it. Download and install it using:
+
+ go get github.com/russross/blackfriday-tool
+
+This is a simple command-line tool that allows you to process a
+markdown file using a standalone program. You can also browse the
+source directly on github if you are just looking for some example
+code:
+
+*
+
+Note that if you have not already done so, installing
+`blackfriday-tool` will be sufficient to download and install
+blackfriday in addition to the tool itself. The tool binary will be
+installed in `$GOPATH/bin`. This is a statically-linked binary that
+can be copied to wherever you need it without worrying about
+dependencies and library versions.
+
+
+Features
+--------
+
+All features of Sundown are supported, including:
+
+* **Compatibility**. The Markdown v1.0.3 test suite passes with
+ the `--tidy` option. Without `--tidy`, the differences are
+ mostly in whitespace and entity escaping, where blackfriday is
+ more consistent and cleaner.
+
+* **Common extensions**, including table support, fenced code
+ blocks, autolinks, strikethroughs, non-strict emphasis, etc.
+
+* **Safety**. Blackfriday is paranoid when parsing, making it safe
+ to feed untrusted user input without fear of bad things
+ happening. The test suite stress tests this and there are no
+ known inputs that make it crash. If you find one, please let me
+ know and send me the input that does it.
+
+ NOTE: "safety" in this context means *runtime safety only*. In order to
+ protect yourself agains JavaScript injection in untrusted content, see
+ [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).
+
+* **Fast processing**. It is fast enough to render on-demand in
+ most web applications without having to cache the output.
+
+* **Thread safety**. You can run multiple parsers in different
+ goroutines without ill effect. There is no dependence on global
+ shared state.
+
+* **Minimal dependencies**. Blackfriday only depends on standard
+ library packages in Go. The source code is pretty
+ self-contained, so it is easy to add to any project, including
+ Google App Engine projects.
+
+* **Standards compliant**. Output successfully validates using the
+ W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.
+
+
+Extensions
+----------
+
+In addition to the standard markdown syntax, this package
+implements the following extensions:
+
+* **Intra-word emphasis supression**. The `_` character is
+ commonly used inside words when discussing code, so having
+ markdown interpret it as an emphasis command is usually the
+ wrong thing. Blackfriday lets you treat all emphasis markers as
+ normal characters when they occur inside a word.
+
+* **Tables**. Tables can be created by drawing them in the input
+ using a simple syntax:
+
+ ```
+ Name | Age
+ --------|------
+ Bob | 27
+ Alice | 23
+ ```
+
+* **Fenced code blocks**. In addition to the normal 4-space
+ indentation to mark code blocks, you can explicitly mark them
+ and supply a language (to make syntax highlighting simple). Just
+ mark it like this:
+
+ ``` go
+ func getTrue() bool {
+ return true
+ }
+ ```
+
+ You can use 3 or more backticks to mark the beginning of the
+ block, and the same number to mark the end of the block.
+
+* **Autolinking**. Blackfriday can find URLs that have not been
+ explicitly marked as links and turn them into links.
+
+* **Strikethrough**. Use two tildes (`~~`) to mark text that
+ should be crossed out.
+
+* **Hard line breaks**. With this extension enabled (it is off by
+ default in the `MarkdownBasic` and `MarkdownCommon` convenience
+ functions), newlines in the input translate into line breaks in
+ the output.
+
+* **Smart quotes**. Smartypants-style punctuation substitution is
+ supported, turning normal double- and single-quote marks into
+ curly quotes, etc.
+
+* **LaTeX-style dash parsing** is an additional option, where `--`
+ is translated into `–`, and `---` is translated into
+ `—`. This differs from most smartypants processors, which
+ turn a single hyphen into an ndash and a double hyphen into an
+ mdash.
+
+* **Smart fractions**, where anything that looks like a fraction
+ is translated into suitable HTML (instead of just a few special
+ cases like most smartypant processors). For example, `4/5`
+ becomes `4⁄5`, which renders as
+ 4⁄5.
+
+
+Other renderers
+---------------
+
+Blackfriday is structured to allow alternative rendering engines. Here
+are a few of note:
+
+* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/github_flavored_markdown):
+ provides a GitHub Flavored Markdown renderer with fenced code block
+ highlighting, clickable header anchor links.
+
+ It's not customizable, and its goal is to produce HTML output
+ equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode),
+ except the rendering is performed locally.
+
+* [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,
+ but for markdown.
+
+* LaTeX output: renders output as LaTeX. This is currently part of the
+ main Blackfriday repository, but may be split into its own project
+ in the future. If you are interested in owning and maintaining the
+ LaTeX output component, please be in touch.
+
+ It renders some basic documents, but is only experimental at this
+ point. In particular, it does not do any inline escaping, so input
+ that happens to look like LaTeX code will be passed through without
+ modification.
+
+
+Todo
+----
+
+* More unit testing
+* Improve unicode support. It does not understand all unicode
+ rules (about what constitutes a letter, a punctuation symbol,
+ etc.), so it may fail to detect word boundaries correctly in
+ some instances. It is safe on all utf-8 input.
+
+
+License
+-------
+
+[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt)
+
+
+ [1]: http://daringfireball.net/projects/markdown/ "Markdown"
+ [2]: http://golang.org/ "Go Language"
+ [3]: https://github.com/vmg/sundown "Sundown"
diff --git a/vendor/github.com/russross/blackfriday/block.go b/vendor/github.com/russross/blackfriday/block.go
new file mode 100644
index 00000000..1f300b33
--- /dev/null
+++ b/vendor/github.com/russross/blackfriday/block.go
@@ -0,0 +1,1389 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross .
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+// Functions to parse block-level elements.
+//
+
+package blackfriday
+
+import (
+ "bytes"
+
+ "github.com/shurcooL/sanitized_anchor_name"
+)
+
+// Parse block-level data.
+// Note: this function and many that it calls assume that
+// the input buffer ends with a newline.
+func (p *parser) block(out *bytes.Buffer, data []byte) {
+ if len(data) == 0 || data[len(data)-1] != '\n' {
+ panic("block input is missing terminating newline")
+ }
+
+ // this is called recursively: enforce a maximum depth
+ if p.nesting >= p.maxNesting {
+ return
+ }
+ p.nesting++
+
+ // parse out one block-level construct at a time
+ for len(data) > 0 {
+ // prefixed header:
+ //
+ // # Header 1
+ // ## Header 2
+ // ...
+ // ###### Header 6
+ if p.isPrefixHeader(data) {
+ data = data[p.prefixHeader(out, data):]
+ continue
+ }
+
+ // block of preformatted HTML:
+ //
+ //
+ // ...
+ //
+ if data[0] == '<' {
+ if i := p.html(out, data, true); i > 0 {
+ data = data[i:]
+ continue
+ }
+ }
+
+ // title block
+ //
+ // % stuff
+ // % more stuff
+ // % even more stuff
+ if p.flags&EXTENSION_TITLEBLOCK != 0 {
+ if data[0] == '%' {
+ if i := p.titleBlock(out, data, true); i > 0 {
+ data = data[i:]
+ continue
+ }
+ }
+ }
+
+ // blank lines. note: returns the # of bytes to skip
+ if i := p.isEmpty(data); i > 0 {
+ data = data[i:]
+ continue
+ }
+
+ // indented code block:
+ //
+ // func max(a, b int) int {
+ // if a > b {
+ // return a
+ // }
+ // return b
+ // }
+ if p.codePrefix(data) > 0 {
+ data = data[p.code(out, data):]
+ continue
+ }
+
+ // fenced code block:
+ //
+ // ``` go
+ // func fact(n int) int {
+ // if n <= 1 {
+ // return n
+ // }
+ // return n * fact(n-1)
+ // }
+ // ```
+ if p.flags&EXTENSION_FENCED_CODE != 0 {
+ if i := p.fencedCode(out, data, true); i > 0 {
+ data = data[i:]
+ continue
+ }
+ }
+
+ // horizontal rule:
+ //
+ // ------
+ // or
+ // ******
+ // or
+ // ______
+ if p.isHRule(data) {
+ p.r.HRule(out)
+ var i int
+ for i = 0; data[i] != '\n'; i++ {
+ }
+ data = data[i:]
+ continue
+ }
+
+ // block quote:
+ //
+ // > A big quote I found somewhere
+ // > on the web
+ if p.quotePrefix(data) > 0 {
+ data = data[p.quote(out, data):]
+ continue
+ }
+
+ // table:
+ //
+ // Name | Age | Phone
+ // ------|-----|---------
+ // Bob | 31 | 555-1234
+ // Alice | 27 | 555-4321
+ if p.flags&EXTENSION_TABLES != 0 {
+ if i := p.table(out, data); i > 0 {
+ data = data[i:]
+ continue
+ }
+ }
+
+ // an itemized/unordered list:
+ //
+ // * Item 1
+ // * Item 2
+ //
+ // also works with + or -
+ if p.uliPrefix(data) > 0 {
+ data = data[p.list(out, data, 0):]
+ continue
+ }
+
+ // a numbered/ordered list:
+ //
+ // 1. Item 1
+ // 2. Item 2
+ if p.oliPrefix(data) > 0 {
+ data = data[p.list(out, data, LIST_TYPE_ORDERED):]
+ continue
+ }
+
+ // definition lists:
+ //
+ // Term 1
+ // : Definition a
+ // : Definition b
+ //
+ // Term 2
+ // : Definition c
+ if p.flags&EXTENSION_DEFINITION_LISTS != 0 {
+ if p.dliPrefix(data) > 0 {
+ data = data[p.list(out, data, LIST_TYPE_DEFINITION):]
+ continue
+ }
+ }
+
+ // anything else must look like a normal paragraph
+ // note: this finds underlined headers, too
+ data = data[p.paragraph(out, data):]
+ }
+
+ p.nesting--
+}
+
+func (p *parser) isPrefixHeader(data []byte) bool {
+ if data[0] != '#' {
+ return false
+ }
+
+ if p.flags&EXTENSION_SPACE_HEADERS != 0 {
+ level := 0
+ for level < 6 && data[level] == '#' {
+ level++
+ }
+ if data[level] != ' ' {
+ return false
+ }
+ }
+ return true
+}
+
+func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int {
+ level := 0
+ for level < 6 && data[level] == '#' {
+ level++
+ }
+ i := skipChar(data, level, ' ')
+ end := skipUntilChar(data, i, '\n')
+ skip := end
+ id := ""
+ if p.flags&EXTENSION_HEADER_IDS != 0 {
+ j, k := 0, 0
+ // find start/end of header id
+ for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ {
+ }
+ for k = j + 1; k < end && data[k] != '}'; k++ {
+ }
+ // extract header id iff found
+ if j < end && k < end {
+ id = string(data[j+2 : k])
+ end = j
+ skip = k + 1
+ for end > 0 && data[end-1] == ' ' {
+ end--
+ }
+ }
+ }
+ for end > 0 && data[end-1] == '#' {
+ if isBackslashEscaped(data, end-1) {
+ break
+ }
+ end--
+ }
+ for end > 0 && data[end-1] == ' ' {
+ end--
+ }
+ if end > i {
+ if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 {
+ id = sanitized_anchor_name.Create(string(data[i:end]))
+ }
+ work := func() bool {
+ p.inline(out, data[i:end])
+ return true
+ }
+ p.r.Header(out, work, level, id)
+ }
+ return skip
+}
+
+func (p *parser) isUnderlinedHeader(data []byte) int {
+ // test of level 1 header
+ if data[0] == '=' {
+ i := skipChar(data, 1, '=')
+ i = skipChar(data, i, ' ')
+ if data[i] == '\n' {
+ return 1
+ } else {
+ return 0
+ }
+ }
+
+ // test of level 2 header
+ if data[0] == '-' {
+ i := skipChar(data, 1, '-')
+ i = skipChar(data, i, ' ')
+ if data[i] == '\n' {
+ return 2
+ } else {
+ return 0
+ }
+ }
+
+ return 0
+}
+
+func (p *parser) titleBlock(out *bytes.Buffer, data []byte, doRender bool) int {
+ if data[0] != '%' {
+ return 0
+ }
+ splitData := bytes.Split(data, []byte("\n"))
+ var i int
+ for idx, b := range splitData {
+ if !bytes.HasPrefix(b, []byte("%")) {
+ i = idx // - 1
+ break
+ }
+ }
+
+ data = bytes.Join(splitData[0:i], []byte("\n"))
+ p.r.TitleBlock(out, data)
+
+ return len(data)
+}
+
+func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int {
+ var i, j int
+
+ // identify the opening tag
+ if data[0] != '<' {
+ return 0
+ }
+ curtag, tagfound := p.htmlFindTag(data[1:])
+
+ // handle special cases
+ if !tagfound {
+ // check for an HTML comment
+ if size := p.htmlComment(out, data, doRender); size > 0 {
+ return size
+ }
+
+ // check for an
tag
+ if size := p.htmlHr(out, data, doRender); size > 0 {
+ return size
+ }
+
+ // no special case recognized
+ return 0
+ }
+
+ // look for an unindented matching closing tag
+ // followed by a blank line
+ found := false
+ /*
+ closetag := []byte("\n" + curtag + ">")
+ j = len(curtag) + 1
+ for !found {
+ // scan for a closing tag at the beginning of a line
+ if skip := bytes.Index(data[j:], closetag); skip >= 0 {
+ j += skip + len(closetag)
+ } else {
+ break
+ }
+
+ // see if it is the only thing on the line
+ if skip := p.isEmpty(data[j:]); skip > 0 {
+ // see if it is followed by a blank line/eof
+ j += skip
+ if j >= len(data) {
+ found = true
+ i = j
+ } else {
+ if skip := p.isEmpty(data[j:]); skip > 0 {
+ j += skip
+ found = true
+ i = j
+ }
+ }
+ }
+ }
+ */
+
+ // if not found, try a second pass looking for indented match
+ // but not if tag is "ins" or "del" (following original Markdown.pl)
+ if !found && curtag != "ins" && curtag != "del" {
+ i = 1
+ for i < len(data) {
+ i++
+ for i < len(data) && !(data[i-1] == '<' && data[i] == '/') {
+ i++
+ }
+
+ if i+2+len(curtag) >= len(data) {
+ break
+ }
+
+ j = p.htmlFindEnd(curtag, data[i-1:])
+
+ if j > 0 {
+ i += j - 1
+ found = true
+ break
+ }
+ }
+ }
+
+ if !found {
+ return 0
+ }
+
+ // the end of the block has been found
+ if doRender {
+ // trim newlines
+ end := i
+ for end > 0 && data[end-1] == '\n' {
+ end--
+ }
+ p.r.BlockHtml(out, data[:end])
+ }
+
+ return i
+}
+
+// HTML comment, lax form
+func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int {
+ if data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' {
+ return 0
+ }
+
+ i := 5
+
+ // scan for an end-of-comment marker, across lines if necessary
+ for i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') {
+ i++
+ }
+ i++
+
+ // no end-of-comment marker
+ if i >= len(data) {
+ return 0
+ }
+
+ // needs to end with a blank line
+ if j := p.isEmpty(data[i:]); j > 0 {
+ size := i + j
+ if doRender {
+ // trim trailing newlines
+ end := size
+ for end > 0 && data[end-1] == '\n' {
+ end--
+ }
+ p.r.BlockHtml(out, data[:end])
+ }
+ return size
+ }
+
+ return 0
+}
+
+// HR, which is the only self-closing block tag considered
+func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int {
+ if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') {
+ return 0
+ }
+ if data[3] != ' ' && data[3] != '/' && data[3] != '>' {
+ // not an
tag after all; at least not a valid one
+ return 0
+ }
+
+ i := 3
+ for data[i] != '>' && data[i] != '\n' {
+ i++
+ }
+
+ if data[i] == '>' {
+ i++
+ if j := p.isEmpty(data[i:]); j > 0 {
+ size := i + j
+ if doRender {
+ // trim newlines
+ end := size
+ for end > 0 && data[end-1] == '\n' {
+ end--
+ }
+ p.r.BlockHtml(out, data[:end])
+ }
+ return size
+ }
+ }
+
+ return 0
+}
+
+func (p *parser) htmlFindTag(data []byte) (string, bool) {
+ i := 0
+ for isalnum(data[i]) {
+ i++
+ }
+ key := string(data[:i])
+ if blockTags[key] {
+ return key, true
+ }
+ return "", false
+}
+
+func (p *parser) htmlFindEnd(tag string, data []byte) int {
+ // assume data[0] == '<' && data[1] == '/' already tested
+
+ // check if tag is a match
+ closetag := []byte("" + tag + ">")
+ if !bytes.HasPrefix(data, closetag) {
+ return 0
+ }
+ i := len(closetag)
+
+ // check that the rest of the line is blank
+ skip := 0
+ if skip = p.isEmpty(data[i:]); skip == 0 {
+ return 0
+ }
+ i += skip
+ skip = 0
+
+ if i >= len(data) {
+ return i
+ }
+
+ if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 {
+ return i
+ }
+ if skip = p.isEmpty(data[i:]); skip == 0 {
+ // following line must be blank
+ return 0
+ }
+
+ return i + skip
+}
+
+func (p *parser) isEmpty(data []byte) int {
+ // it is okay to call isEmpty on an empty buffer
+ if len(data) == 0 {
+ return 0
+ }
+
+ var i int
+ for i = 0; i < len(data) && data[i] != '\n'; i++ {
+ if data[i] != ' ' && data[i] != '\t' {
+ return 0
+ }
+ }
+ return i + 1
+}
+
+func (p *parser) isHRule(data []byte) bool {
+ i := 0
+
+ // skip up to three spaces
+ for i < 3 && data[i] == ' ' {
+ i++
+ }
+
+ // look at the hrule char
+ if data[i] != '*' && data[i] != '-' && data[i] != '_' {
+ return false
+ }
+ c := data[i]
+
+ // the whole line must be the char or whitespace
+ n := 0
+ for data[i] != '\n' {
+ switch {
+ case data[i] == c:
+ n++
+ case data[i] != ' ':
+ return false
+ }
+ i++
+ }
+
+ return n >= 3
+}
+
+func (p *parser) isFencedCode(data []byte, syntax **string, oldmarker string) (skip int, marker string) {
+ i, size := 0, 0
+ skip = 0
+
+ // skip up to three spaces
+ for i < len(data) && i < 3 && data[i] == ' ' {
+ i++
+ }
+ if i >= len(data) {
+ return
+ }
+
+ // check for the marker characters: ~ or `
+ if data[i] != '~' && data[i] != '`' {
+ return
+ }
+
+ c := data[i]
+
+ // the whole line must be the same char or whitespace
+ for i < len(data) && data[i] == c {
+ size++
+ i++
+ }
+
+ if i >= len(data) {
+ return
+ }
+
+ // the marker char must occur at least 3 times
+ if size < 3 {
+ return
+ }
+ marker = string(data[i-size : i])
+
+ // if this is the end marker, it must match the beginning marker
+ if oldmarker != "" && marker != oldmarker {
+ return
+ }
+
+ if syntax != nil {
+ syn := 0
+ i = skipChar(data, i, ' ')
+
+ if i >= len(data) {
+ return
+ }
+
+ syntaxStart := i
+
+ if data[i] == '{' {
+ i++
+ syntaxStart++
+
+ for i < len(data) && data[i] != '}' && data[i] != '\n' {
+ syn++
+ i++
+ }
+
+ if i >= len(data) || data[i] != '}' {
+ return
+ }
+
+ // strip all whitespace at the beginning and the end
+ // of the {} block
+ for syn > 0 && isspace(data[syntaxStart]) {
+ syntaxStart++
+ syn--
+ }
+
+ for syn > 0 && isspace(data[syntaxStart+syn-1]) {
+ syn--
+ }
+
+ i++
+ } else {
+ for i < len(data) && !isspace(data[i]) {
+ syn++
+ i++
+ }
+ }
+
+ language := string(data[syntaxStart : syntaxStart+syn])
+ *syntax = &language
+ }
+
+ i = skipChar(data, i, ' ')
+ if i >= len(data) || data[i] != '\n' {
+ return
+ }
+
+ skip = i + 1
+ return
+}
+
+func (p *parser) fencedCode(out *bytes.Buffer, data []byte, doRender bool) int {
+ var lang *string
+ beg, marker := p.isFencedCode(data, &lang, "")
+ if beg == 0 || beg >= len(data) {
+ return 0
+ }
+
+ var work bytes.Buffer
+
+ for {
+ // safe to assume beg < len(data)
+
+ // check for the end of the code block
+ fenceEnd, _ := p.isFencedCode(data[beg:], nil, marker)
+ if fenceEnd != 0 {
+ beg += fenceEnd
+ break
+ }
+
+ // copy the current line
+ end := skipUntilChar(data, beg, '\n') + 1
+
+ // did we reach the end of the buffer without a closing marker?
+ if end >= len(data) {
+ return 0
+ }
+
+ // verbatim copy to the working buffer
+ if doRender {
+ work.Write(data[beg:end])
+ }
+ beg = end
+ }
+
+ syntax := ""
+ if lang != nil {
+ syntax = *lang
+ }
+
+ if doRender {
+ p.r.BlockCode(out, work.Bytes(), syntax)
+ }
+
+ return beg
+}
+
+func (p *parser) table(out *bytes.Buffer, data []byte) int {
+ var header bytes.Buffer
+ i, columns := p.tableHeader(&header, data)
+ if i == 0 {
+ return 0
+ }
+
+ var body bytes.Buffer
+
+ for i < len(data) {
+ pipes, rowStart := 0, i
+ for ; data[i] != '\n'; i++ {
+ if data[i] == '|' {
+ pipes++
+ }
+ }
+
+ if pipes == 0 {
+ i = rowStart
+ break
+ }
+
+ // include the newline in data sent to tableRow
+ i++
+ p.tableRow(&body, data[rowStart:i], columns, false)
+ }
+
+ p.r.Table(out, header.Bytes(), body.Bytes(), columns)
+
+ return i
+}
+
+// check if the specified position is preceded by an odd number of backslashes
+func isBackslashEscaped(data []byte, i int) bool {
+ backslashes := 0
+ for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' {
+ backslashes++
+ }
+ return backslashes&1 == 1
+}
+
+func (p *parser) tableHeader(out *bytes.Buffer, data []byte) (size int, columns []int) {
+ i := 0
+ colCount := 1
+ for i = 0; data[i] != '\n'; i++ {
+ if data[i] == '|' && !isBackslashEscaped(data, i) {
+ colCount++
+ }
+ }
+
+ // doesn't look like a table header
+ if colCount == 1 {
+ return
+ }
+
+ // include the newline in the data sent to tableRow
+ header := data[:i+1]
+
+ // column count ignores pipes at beginning or end of line
+ if data[0] == '|' {
+ colCount--
+ }
+ if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) {
+ colCount--
+ }
+
+ columns = make([]int, colCount)
+
+ // move on to the header underline
+ i++
+ if i >= len(data) {
+ return
+ }
+
+ if data[i] == '|' && !isBackslashEscaped(data, i) {
+ i++
+ }
+ i = skipChar(data, i, ' ')
+
+ // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3
+ // and trailing | optional on last column
+ col := 0
+ for data[i] != '\n' {
+ dashes := 0
+
+ if data[i] == ':' {
+ i++
+ columns[col] |= TABLE_ALIGNMENT_LEFT
+ dashes++
+ }
+ for data[i] == '-' {
+ i++
+ dashes++
+ }
+ if data[i] == ':' {
+ i++
+ columns[col] |= TABLE_ALIGNMENT_RIGHT
+ dashes++
+ }
+ for data[i] == ' ' {
+ i++
+ }
+
+ // end of column test is messy
+ switch {
+ case dashes < 3:
+ // not a valid column
+ return
+
+ case data[i] == '|' && !isBackslashEscaped(data, i):
+ // marker found, now skip past trailing whitespace
+ col++
+ i++
+ for data[i] == ' ' {
+ i++
+ }
+
+ // trailing junk found after last column
+ if col >= colCount && data[i] != '\n' {
+ return
+ }
+
+ case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:
+ // something else found where marker was required
+ return
+
+ case data[i] == '\n':
+ // marker is optional for the last column
+ col++
+
+ default:
+ // trailing junk found after last column
+ return
+ }
+ }
+ if col != colCount {
+ return
+ }
+
+ p.tableRow(out, header, columns, true)
+ size = i + 1
+ return
+}
+
+func (p *parser) tableRow(out *bytes.Buffer, data []byte, columns []int, header bool) {
+ i, col := 0, 0
+ var rowWork bytes.Buffer
+
+ if data[i] == '|' && !isBackslashEscaped(data, i) {
+ i++
+ }
+
+ for col = 0; col < len(columns) && i < len(data); col++ {
+ for data[i] == ' ' {
+ i++
+ }
+
+ cellStart := i
+
+ for (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' {
+ i++
+ }
+
+ cellEnd := i
+
+ // skip the end-of-cell marker, possibly taking us past end of buffer
+ i++
+
+ for cellEnd > cellStart && data[cellEnd-1] == ' ' {
+ cellEnd--
+ }
+
+ var cellWork bytes.Buffer
+ p.inline(&cellWork, data[cellStart:cellEnd])
+
+ if header {
+ p.r.TableHeaderCell(&rowWork, cellWork.Bytes(), columns[col])
+ } else {
+ p.r.TableCell(&rowWork, cellWork.Bytes(), columns[col])
+ }
+ }
+
+ // pad it out with empty columns to get the right number
+ for ; col < len(columns); col++ {
+ if header {
+ p.r.TableHeaderCell(&rowWork, nil, columns[col])
+ } else {
+ p.r.TableCell(&rowWork, nil, columns[col])
+ }
+ }
+
+ // silently ignore rows with too many cells
+
+ p.r.TableRow(out, rowWork.Bytes())
+}
+
+// returns blockquote prefix length
+func (p *parser) quotePrefix(data []byte) int {
+ i := 0
+ for i < 3 && data[i] == ' ' {
+ i++
+ }
+ if data[i] == '>' {
+ if data[i+1] == ' ' {
+ return i + 2
+ }
+ return i + 1
+ }
+ return 0
+}
+
+// parse a blockquote fragment
+func (p *parser) quote(out *bytes.Buffer, data []byte) int {
+ var raw bytes.Buffer
+ beg, end := 0, 0
+ for beg < len(data) {
+ end = beg
+ for data[end] != '\n' {
+ end++
+ }
+ end++
+
+ if pre := p.quotePrefix(data[beg:]); pre > 0 {
+ // skip the prefix
+ beg += pre
+ } else if p.isEmpty(data[beg:]) > 0 &&
+ (end >= len(data) ||
+ (p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0)) {
+ // blockquote ends with at least one blank line
+ // followed by something without a blockquote prefix
+ break
+ }
+
+ // this line is part of the blockquote
+ raw.Write(data[beg:end])
+ beg = end
+ }
+
+ var cooked bytes.Buffer
+ p.block(&cooked, raw.Bytes())
+ p.r.BlockQuote(out, cooked.Bytes())
+ return end
+}
+
+// returns prefix length for block code
+func (p *parser) codePrefix(data []byte) int {
+ if data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' {
+ return 4
+ }
+ return 0
+}
+
+func (p *parser) code(out *bytes.Buffer, data []byte) int {
+ var work bytes.Buffer
+
+ i := 0
+ for i < len(data) {
+ beg := i
+ for data[i] != '\n' {
+ i++
+ }
+ i++
+
+ blankline := p.isEmpty(data[beg:i]) > 0
+ if pre := p.codePrefix(data[beg:i]); pre > 0 {
+ beg += pre
+ } else if !blankline {
+ // non-empty, non-prefixed line breaks the pre
+ i = beg
+ break
+ }
+
+ // verbatim copy to the working buffeu
+ if blankline {
+ work.WriteByte('\n')
+ } else {
+ work.Write(data[beg:i])
+ }
+ }
+
+ // trim all the \n off the end of work
+ workbytes := work.Bytes()
+ eol := len(workbytes)
+ for eol > 0 && workbytes[eol-1] == '\n' {
+ eol--
+ }
+ if eol != len(workbytes) {
+ work.Truncate(eol)
+ }
+
+ work.WriteByte('\n')
+
+ p.r.BlockCode(out, work.Bytes(), "")
+
+ return i
+}
+
+// returns unordered list item prefix
+func (p *parser) uliPrefix(data []byte) int {
+ i := 0
+
+ // start with up to 3 spaces
+ for i < 3 && data[i] == ' ' {
+ i++
+ }
+
+ // need a *, +, or - followed by a space
+ if (data[i] != '*' && data[i] != '+' && data[i] != '-') ||
+ data[i+1] != ' ' {
+ return 0
+ }
+ return i + 2
+}
+
+// returns ordered list item prefix
+func (p *parser) oliPrefix(data []byte) int {
+ i := 0
+
+ // start with up to 3 spaces
+ for i < 3 && data[i] == ' ' {
+ i++
+ }
+
+ // count the digits
+ start := i
+ for data[i] >= '0' && data[i] <= '9' {
+ i++
+ }
+
+ // we need >= 1 digits followed by a dot and a space
+ if start == i || data[i] != '.' || data[i+1] != ' ' {
+ return 0
+ }
+ return i + 2
+}
+
+// returns definition list item prefix
+func (p *parser) dliPrefix(data []byte) int {
+ i := 0
+
+ // need a : followed by a spaces
+ if data[i] != ':' || data[i+1] != ' ' {
+ return 0
+ }
+ for data[i] == ' ' {
+ i++
+ }
+ return i + 2
+}
+
+// parse ordered or unordered list block
+func (p *parser) list(out *bytes.Buffer, data []byte, flags int) int {
+ i := 0
+ flags |= LIST_ITEM_BEGINNING_OF_LIST
+ work := func() bool {
+ for i < len(data) {
+ skip := p.listItem(out, data[i:], &flags)
+ i += skip
+
+ if skip == 0 || flags&LIST_ITEM_END_OF_LIST != 0 {
+ break
+ }
+ flags &= ^LIST_ITEM_BEGINNING_OF_LIST
+ }
+ return true
+ }
+
+ p.r.List(out, work, flags)
+ return i
+}
+
+// Parse a single list item.
+// Assumes initial prefix is already removed if this is a sublist.
+func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int {
+ // keep track of the indentation of the first line
+ itemIndent := 0
+ for itemIndent < 3 && data[itemIndent] == ' ' {
+ itemIndent++
+ }
+
+ i := p.uliPrefix(data)
+ if i == 0 {
+ i = p.oliPrefix(data)
+ }
+ if i == 0 {
+ i = p.dliPrefix(data)
+ // reset definition term flag
+ if i > 0 {
+ *flags &= ^LIST_TYPE_TERM
+ }
+ }
+ if i == 0 {
+ // if in defnition list, set term flag and continue
+ if *flags&LIST_TYPE_DEFINITION != 0 {
+ *flags |= LIST_TYPE_TERM
+ } else {
+ return 0
+ }
+ }
+
+ // skip leading whitespace on first line
+ for data[i] == ' ' {
+ i++
+ }
+
+ // find the end of the line
+ line := i
+ for i > 0 && data[i-1] != '\n' {
+ i++
+ }
+
+ // get working buffer
+ var raw bytes.Buffer
+
+ // put the first line into the working buffer
+ raw.Write(data[line:i])
+ line = i
+
+ // process the following lines
+ containsBlankLine := false
+ sublist := 0
+
+gatherlines:
+ for line < len(data) {
+ i++
+
+ // find the end of this line
+ for data[i-1] != '\n' {
+ i++
+ }
+
+ // if it is an empty line, guess that it is part of this item
+ // and move on to the next line
+ if p.isEmpty(data[line:i]) > 0 {
+ containsBlankLine = true
+ line = i
+ continue
+ }
+
+ // calculate the indentation
+ indent := 0
+ for indent < 4 && line+indent < i && data[line+indent] == ' ' {
+ indent++
+ }
+
+ chunk := data[line+indent : i]
+
+ // evaluate how this line fits in
+ switch {
+ // is this a nested list item?
+ case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) ||
+ p.oliPrefix(chunk) > 0 ||
+ p.dliPrefix(chunk) > 0:
+
+ if containsBlankLine {
+ *flags |= LIST_ITEM_CONTAINS_BLOCK
+ }
+
+ // to be a nested list, it must be indented more
+ // if not, it is the next item in the same list
+ if indent <= itemIndent {
+ break gatherlines
+ }
+
+ // is this the first item in the nested list?
+ if sublist == 0 {
+ sublist = raw.Len()
+ }
+
+ // is this a nested prefix header?
+ case p.isPrefixHeader(chunk):
+ // if the header is not indented, it is not nested in the list
+ // and thus ends the list
+ if containsBlankLine && indent < 4 {
+ *flags |= LIST_ITEM_END_OF_LIST
+ break gatherlines
+ }
+ *flags |= LIST_ITEM_CONTAINS_BLOCK
+
+ // anything following an empty line is only part
+ // of this item if it is indented 4 spaces
+ // (regardless of the indentation of the beginning of the item)
+ case containsBlankLine && indent < 4:
+ if *flags&LIST_TYPE_DEFINITION != 0 && i < len(data)-1 {
+ // is the next item still a part of this list?
+ next := i
+ for data[next] != '\n' {
+ next++
+ }
+ for next < len(data)-1 && data[next] == '\n' {
+ next++
+ }
+ if i < len(data)-1 && data[i] != ':' && data[next] != ':' {
+ *flags |= LIST_ITEM_END_OF_LIST
+ }
+ } else {
+ *flags |= LIST_ITEM_END_OF_LIST
+ }
+ break gatherlines
+
+ // a blank line means this should be parsed as a block
+ case containsBlankLine:
+ raw.WriteByte('\n')
+ *flags |= LIST_ITEM_CONTAINS_BLOCK
+ }
+
+ // if this line was preceeded by one or more blanks,
+ // re-introduce the blank into the buffer
+ if containsBlankLine {
+ containsBlankLine = false
+ raw.WriteByte('\n')
+
+ }
+
+ // add the line into the working buffer without prefix
+ raw.Write(data[line+indent : i])
+
+ line = i
+ }
+
+ rawBytes := raw.Bytes()
+
+ // render the contents of the list item
+ var cooked bytes.Buffer
+ if *flags&LIST_ITEM_CONTAINS_BLOCK != 0 && *flags&LIST_TYPE_TERM == 0 {
+ // intermediate render of block item, except for definition term
+ if sublist > 0 {
+ p.block(&cooked, rawBytes[:sublist])
+ p.block(&cooked, rawBytes[sublist:])
+ } else {
+ p.block(&cooked, rawBytes)
+ }
+ } else {
+ // intermediate render of inline item
+ if sublist > 0 {
+ p.inline(&cooked, rawBytes[:sublist])
+ p.block(&cooked, rawBytes[sublist:])
+ } else {
+ p.inline(&cooked, rawBytes)
+ }
+ }
+
+ // render the actual list item
+ cookedBytes := cooked.Bytes()
+ parsedEnd := len(cookedBytes)
+
+ // strip trailing newlines
+ for parsedEnd > 0 && cookedBytes[parsedEnd-1] == '\n' {
+ parsedEnd--
+ }
+ p.r.ListItem(out, cookedBytes[:parsedEnd], *flags)
+
+ return line
+}
+
+// render a single paragraph that has already been parsed out
+func (p *parser) renderParagraph(out *bytes.Buffer, data []byte) {
+ if len(data) == 0 {
+ return
+ }
+
+ // trim leading spaces
+ beg := 0
+ for data[beg] == ' ' {
+ beg++
+ }
+
+ // trim trailing newline
+ end := len(data) - 1
+
+ // trim trailing spaces
+ for end > beg && data[end-1] == ' ' {
+ end--
+ }
+
+ work := func() bool {
+ p.inline(out, data[beg:end])
+ return true
+ }
+ p.r.Paragraph(out, work)
+}
+
+func (p *parser) paragraph(out *bytes.Buffer, data []byte) int {
+ // prev: index of 1st char of previous line
+ // line: index of 1st char of current line
+ // i: index of cursor/end of current line
+ var prev, line, i int
+
+ // keep going until we find something to mark the end of the paragraph
+ for i < len(data) {
+ // mark the beginning of the current line
+ prev = line
+ current := data[i:]
+ line = i
+
+ // did we find a blank line marking the end of the paragraph?
+ if n := p.isEmpty(current); n > 0 {
+ // did this blank line followed by a definition list item?
+ if p.flags&EXTENSION_DEFINITION_LISTS != 0 {
+ if i < len(data)-1 && data[i+1] == ':' {
+ return p.list(out, data[prev:], LIST_TYPE_DEFINITION)
+ }
+ }
+
+ p.renderParagraph(out, data[:i])
+ return i + n
+ }
+
+ // an underline under some text marks a header, so our paragraph ended on prev line
+ if i > 0 {
+ if level := p.isUnderlinedHeader(current); level > 0 {
+ // render the paragraph
+ p.renderParagraph(out, data[:prev])
+
+ // ignore leading and trailing whitespace
+ eol := i - 1
+ for prev < eol && data[prev] == ' ' {
+ prev++
+ }
+ for eol > prev && data[eol-1] == ' ' {
+ eol--
+ }
+
+ // render the header
+ // this ugly double closure avoids forcing variables onto the heap
+ work := func(o *bytes.Buffer, pp *parser, d []byte) func() bool {
+ return func() bool {
+ pp.inline(o, d)
+ return true
+ }
+ }(out, p, data[prev:eol])
+
+ id := ""
+ if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 {
+ id = sanitized_anchor_name.Create(string(data[prev:eol]))
+ }
+
+ p.r.Header(out, work, level, id)
+
+ // find the end of the underline
+ for data[i] != '\n' {
+ i++
+ }
+ return i
+ }
+ }
+
+ // if the next line starts a block of HTML, then the paragraph ends here
+ if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 {
+ if data[i] == '<' && p.html(out, current, false) > 0 {
+ // rewind to before the HTML block
+ p.renderParagraph(out, data[:i])
+ return i
+ }
+ }
+
+ // if there's a prefixed header or a horizontal rule after this, paragraph is over
+ if p.isPrefixHeader(current) || p.isHRule(current) {
+ p.renderParagraph(out, data[:i])
+ return i
+ }
+
+ // if there's a definition list item, prev line is a definition term
+ if p.flags&EXTENSION_DEFINITION_LISTS != 0 {
+ if p.dliPrefix(current) != 0 {
+ return p.list(out, data[prev:], LIST_TYPE_DEFINITION)
+ }
+ }
+
+ // if there's a list after this, paragraph is over
+ if p.flags&EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK != 0 {
+ if p.uliPrefix(current) != 0 ||
+ p.oliPrefix(current) != 0 ||
+ p.quotePrefix(current) != 0 ||
+ p.codePrefix(current) != 0 {
+ p.renderParagraph(out, data[:i])
+ return i
+ }
+ }
+
+ // otherwise, scan to the beginning of the next line
+ for data[i] != '\n' {
+ i++
+ }
+ i++
+ }
+
+ p.renderParagraph(out, data[:i])
+ return i
+}
diff --git a/vendor/github.com/russross/blackfriday/block_test.go b/vendor/github.com/russross/blackfriday/block_test.go
new file mode 100644
index 00000000..f52506fd
--- /dev/null
+++ b/vendor/github.com/russross/blackfriday/block_test.go
@@ -0,0 +1,1407 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross .
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+// Unit tests for block parsing
+//
+
+package blackfriday
+
+import (
+ "testing"
+)
+
+func runMarkdownBlockWithRenderer(input string, extensions int, renderer Renderer) string {
+ return string(Markdown([]byte(input), renderer, extensions))
+}
+
+func runMarkdownBlock(input string, extensions int) string {
+ htmlFlags := 0
+ htmlFlags |= HTML_USE_XHTML
+
+ renderer := HtmlRenderer(htmlFlags, "", "")
+
+ return runMarkdownBlockWithRenderer(input, extensions, renderer)
+}
+
+func runnerWithRendererParameters(parameters HtmlRendererParameters) func(string, int) string {
+ return func(input string, extensions int) string {
+ htmlFlags := 0
+ htmlFlags |= HTML_USE_XHTML
+
+ renderer := HtmlRendererWithParameters(htmlFlags, "", "", parameters)
+
+ return runMarkdownBlockWithRenderer(input, extensions, renderer)
+ }
+}
+
+func doTestsBlock(t *testing.T, tests []string, extensions int) {
+ doTestsBlockWithRunner(t, tests, extensions, runMarkdownBlock)
+}
+
+func doTestsBlockWithRunner(t *testing.T, tests []string, extensions int, runner func(string, int) string) {
+ // catch and report panics
+ var candidate string
+ defer func() {
+ if err := recover(); err != nil {
+ t.Errorf("\npanic while processing [%#v]: %s\n", candidate, err)
+ }
+ }()
+
+ for i := 0; i+1 < len(tests); i += 2 {
+ input := tests[i]
+ candidate = input
+ expected := tests[i+1]
+ actual := runner(candidate, extensions)
+ if actual != expected {
+ t.Errorf("\nInput [%#v]\nExpected[%#v]\nActual [%#v]",
+ candidate, expected, actual)
+ }
+
+ // now test every substring to stress test bounds checking
+ if !testing.Short() {
+ for start := 0; start < len(input); start++ {
+ for end := start + 1; end <= len(input); end++ {
+ candidate = input[start:end]
+ _ = runMarkdownBlock(candidate, extensions)
+ }
+ }
+ }
+ }
+}
+
+func TestPrefixHeaderNoExtensions(t *testing.T) {
+ var tests = []string{
+ "# Header 1\n",
+ "Header 1
\n",
+
+ "## Header 2\n",
+ "Header 2
\n",
+
+ "### Header 3\n",
+ "Header 3
\n",
+
+ "#### Header 4\n",
+ "Header 4
\n",
+
+ "##### Header 5\n",
+ "Header 5
\n",
+
+ "###### Header 6\n",
+ "Header 6
\n",
+
+ "####### Header 7\n",
+ "# Header 7
\n",
+
+ "#Header 1\n",
+ "Header 1
\n",
+
+ "##Header 2\n",
+ "Header 2
\n",
+
+ "###Header 3\n",
+ "Header 3
\n",
+
+ "####Header 4\n",
+ "Header 4
\n",
+
+ "#####Header 5\n",
+ "Header 5
\n",
+
+ "######Header 6\n",
+ "Header 6
\n",
+
+ "#######Header 7\n",
+ "#Header 7
\n",
+
+ "Hello\n# Header 1\nGoodbye\n",
+ "Hello
\n\nHeader 1
\n\nGoodbye
\n",
+
+ "* List\n# Header\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n#Header\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n * Nested list\n # Nested header\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ "Nested header
\n
\n
\n",
+
+ "#Header 1 \\#\n",
+ "Header 1 #
\n",
+
+ "#Header 1 \\# foo\n",
+ "Header 1 # foo
\n",
+
+ "#Header 1 #\\##\n",
+ "Header 1 ##
\n",
+ }
+ doTestsBlock(t, tests, 0)
+}
+
+func TestPrefixHeaderSpaceExtension(t *testing.T) {
+ var tests = []string{
+ "# Header 1\n",
+ "Header 1
\n",
+
+ "## Header 2\n",
+ "Header 2
\n",
+
+ "### Header 3\n",
+ "Header 3
\n",
+
+ "#### Header 4\n",
+ "Header 4
\n",
+
+ "##### Header 5\n",
+ "Header 5
\n",
+
+ "###### Header 6\n",
+ "Header 6
\n",
+
+ "####### Header 7\n",
+ "####### Header 7
\n",
+
+ "#Header 1\n",
+ "#Header 1
\n",
+
+ "##Header 2\n",
+ "##Header 2
\n",
+
+ "###Header 3\n",
+ "###Header 3
\n",
+
+ "####Header 4\n",
+ "####Header 4
\n",
+
+ "#####Header 5\n",
+ "#####Header 5
\n",
+
+ "######Header 6\n",
+ "######Header 6
\n",
+
+ "#######Header 7\n",
+ "#######Header 7
\n",
+
+ "Hello\n# Header 1\nGoodbye\n",
+ "Hello
\n\nHeader 1
\n\nGoodbye
\n",
+
+ "* List\n# Header\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n#Header\n* List\n",
+ "\n",
+
+ "* List\n * Nested list\n # Nested header\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ "Nested header
\n
\n
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_SPACE_HEADERS)
+}
+
+func TestPrefixHeaderIdExtension(t *testing.T) {
+ var tests = []string{
+ "# Header 1 {#someid}\n",
+ "Header 1
\n",
+
+ "# Header 1 {#someid} \n",
+ "Header 1
\n",
+
+ "# Header 1 {#someid}\n",
+ "Header 1
\n",
+
+ "# Header 1 {#someid\n",
+ "Header 1 {#someid
\n",
+
+ "# Header 1 {#someid\n",
+ "Header 1 {#someid
\n",
+
+ "# Header 1 {#someid}}\n",
+ "Header 1
\n\n}
\n",
+
+ "## Header 2 {#someid}\n",
+ "Header 2
\n",
+
+ "### Header 3 {#someid}\n",
+ "Header 3
\n",
+
+ "#### Header 4 {#someid}\n",
+ "Header 4
\n",
+
+ "##### Header 5 {#someid}\n",
+ "Header 5
\n",
+
+ "###### Header 6 {#someid}\n",
+ "Header 6
\n",
+
+ "####### Header 7 {#someid}\n",
+ "# Header 7
\n",
+
+ "# Header 1 # {#someid}\n",
+ "Header 1
\n",
+
+ "## Header 2 ## {#someid}\n",
+ "Header 2
\n",
+
+ "Hello\n# Header 1\nGoodbye\n",
+ "Hello
\n\nHeader 1
\n\nGoodbye
\n",
+
+ "* List\n# Header {#someid}\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n#Header {#someid}\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n * Nested list\n # Nested header {#someid}\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ "Nested header
\n
\n
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_HEADER_IDS)
+}
+
+func TestPrefixHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
+ var tests = []string{
+ "# header 1 {#someid}\n",
+ "header 1
\n",
+
+ "## header 2 {#someid}\n",
+ "header 2
\n",
+
+ "### header 3 {#someid}\n",
+ "header 3
\n",
+
+ "#### header 4 {#someid}\n",
+ "header 4
\n",
+
+ "##### header 5 {#someid}\n",
+ "header 5
\n",
+
+ "###### header 6 {#someid}\n",
+ "header 6
\n",
+
+ "####### header 7 {#someid}\n",
+ "# header 7
\n",
+
+ "# header 1 # {#someid}\n",
+ "header 1
\n",
+
+ "## header 2 ## {#someid}\n",
+ "header 2
\n",
+
+ "* List\n# Header {#someid}\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n#Header {#someid}\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n * Nested list\n # Nested header {#someid}\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ "Nested header
\n
\n
\n",
+ }
+
+ parameters := HtmlRendererParameters{
+ HeaderIDPrefix: "PRE:",
+ HeaderIDSuffix: ":POST",
+ }
+
+ doTestsBlockWithRunner(t, tests, EXTENSION_HEADER_IDS, runnerWithRendererParameters(parameters))
+}
+
+func TestPrefixAutoHeaderIdExtension(t *testing.T) {
+ var tests = []string{
+ "# Header 1\n",
+ "\n",
+
+ "# Header 1 \n",
+ "\n",
+
+ "## Header 2\n",
+ "\n",
+
+ "### Header 3\n",
+ "\n",
+
+ "#### Header 4\n",
+ "\n",
+
+ "##### Header 5\n",
+ "\n",
+
+ "###### Header 6\n",
+ "\n",
+
+ "####### Header 7\n",
+ "\n",
+
+ "Hello\n# Header 1\nGoodbye\n",
+ "Hello
\n\n\n\nGoodbye
\n",
+
+ "* List\n# Header\n* List\n",
+ "\n",
+
+ "* List\n#Header\n* List\n",
+ "\n",
+
+ "* List\n * Nested list\n # Nested header\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ " \n
\n
\n",
+
+ "# Header\n\n# Header\n",
+ "\n\n\n",
+
+ "# Header 1\n\n# Header 1",
+ "\n\n\n",
+
+ "# Header\n\n# Header 1\n\n# Header\n\n# Header",
+ "\n\n\n\n\n\n\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS)
+}
+
+func TestPrefixAutoHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
+ var tests = []string{
+ "# Header 1\n",
+ "\n",
+
+ "# Header 1 \n",
+ "\n",
+
+ "## Header 2\n",
+ "\n",
+
+ "### Header 3\n",
+ "\n",
+
+ "#### Header 4\n",
+ "\n",
+
+ "##### Header 5\n",
+ "\n",
+
+ "###### Header 6\n",
+ "\n",
+
+ "####### Header 7\n",
+ "\n",
+
+ "Hello\n# Header 1\nGoodbye\n",
+ "Hello
\n\n\n\nGoodbye
\n",
+
+ "* List\n# Header\n* List\n",
+ "\n",
+
+ "* List\n#Header\n* List\n",
+ "\n",
+
+ "* List\n * Nested list\n # Nested header\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ " \n
\n
\n",
+
+ "# Header\n\n# Header\n",
+ "\n\n\n",
+
+ "# Header 1\n\n# Header 1",
+ "\n\n\n",
+
+ "# Header\n\n# Header 1\n\n# Header\n\n# Header",
+ "\n\n\n\n\n\n\n",
+ }
+
+ parameters := HtmlRendererParameters{
+ HeaderIDPrefix: "PRE:",
+ HeaderIDSuffix: ":POST",
+ }
+
+ doTestsBlockWithRunner(t, tests, EXTENSION_AUTO_HEADER_IDS, runnerWithRendererParameters(parameters))
+}
+
+func TestPrefixMultipleHeaderExtensions(t *testing.T) {
+ var tests = []string{
+ "# Header\n\n# Header {#header}\n\n# Header 1",
+ "\n\n\n\n\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS|EXTENSION_HEADER_IDS)
+}
+
+func TestUnderlineHeaders(t *testing.T) {
+ var tests = []string{
+ "Header 1\n========\n",
+ "Header 1
\n",
+
+ "Header 2\n--------\n",
+ "Header 2
\n",
+
+ "A\n=\n",
+ "A
\n",
+
+ "B\n-\n",
+ "B
\n",
+
+ "Paragraph\nHeader\n=\n",
+ "Paragraph
\n\nHeader
\n",
+
+ "Header\n===\nParagraph\n",
+ "Header
\n\nParagraph
\n",
+
+ "Header\n===\nAnother header\n---\n",
+ "Header
\n\nAnother header
\n",
+
+ " Header\n======\n",
+ "Header
\n",
+
+ " Code\n========\n",
+ "Code\n
\n\n========
\n",
+
+ "Header with *inline*\n=====\n",
+ "Header with inline
\n",
+
+ "* List\n * Sublist\n Not a header\n ------\n",
+ "\n- List\n\n
\n- Sublist\nNot a header\n------
\n
\n
\n",
+
+ "Paragraph\n\n\n\n\nHeader\n===\n",
+ "Paragraph
\n\nHeader
\n",
+
+ "Trailing space \n==== \n\n",
+ "Trailing space
\n",
+
+ "Trailing spaces\n==== \n\n",
+ "Trailing spaces
\n",
+
+ "Double underline\n=====\n=====\n",
+ "Double underline
\n\n=====
\n",
+ }
+ doTestsBlock(t, tests, 0)
+}
+
+func TestUnderlineHeadersAutoIDs(t *testing.T) {
+ var tests = []string{
+ "Header 1\n========\n",
+ "\n",
+
+ "Header 2\n--------\n",
+ "\n",
+
+ "A\n=\n",
+ "A
\n",
+
+ "B\n-\n",
+ "B
\n",
+
+ "Paragraph\nHeader\n=\n",
+ "Paragraph
\n\n\n",
+
+ "Header\n===\nParagraph\n",
+ "\n\nParagraph
\n",
+
+ "Header\n===\nAnother header\n---\n",
+ "\n\n\n",
+
+ " Header\n======\n",
+ "\n",
+
+ "Header with *inline*\n=====\n",
+ "\n",
+
+ "Paragraph\n\n\n\n\nHeader\n===\n",
+ "Paragraph
\n\n\n",
+
+ "Trailing space \n==== \n\n",
+ "Trailing space
\n",
+
+ "Trailing spaces\n==== \n\n",
+ "Trailing spaces
\n",
+
+ "Double underline\n=====\n=====\n",
+ "Double underline
\n\n=====
\n",
+
+ "Header\n======\n\nHeader\n======\n",
+ "\n\n\n",
+
+ "Header 1\n========\n\nHeader 1\n========\n",
+ "\n\n\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS)
+}
+
+func TestHorizontalRule(t *testing.T) {
+ var tests = []string{
+ "-\n",
+ "-
\n",
+
+ "--\n",
+ "--
\n",
+
+ "---\n",
+ "
\n",
+
+ "----\n",
+ "
\n",
+
+ "*\n",
+ "*
\n",
+
+ "**\n",
+ "**
\n",
+
+ "***\n",
+ "
\n",
+
+ "****\n",
+ "
\n",
+
+ "_\n",
+ "_
\n",
+
+ "__\n",
+ "__
\n",
+
+ "___\n",
+ "
\n",
+
+ "____\n",
+ "
\n",
+
+ "-*-\n",
+ "-*-
\n",
+
+ "- - -\n",
+ "
\n",
+
+ "* * *\n",
+ "
\n",
+
+ "_ _ _\n",
+ "
\n",
+
+ "-----*\n",
+ "-----*
\n",
+
+ " ------ \n",
+ "
\n",
+
+ "Hello\n***\n",
+ "Hello
\n\n
\n",
+
+ "---\n***\n___\n",
+ "
\n\n
\n\n
\n",
+ }
+ doTestsBlock(t, tests, 0)
+}
+
+func TestUnorderedList(t *testing.T) {
+ var tests = []string{
+ "* Hello\n",
+ "\n",
+
+ "* Yin\n* Yang\n",
+ "\n",
+
+ "* Ting\n* Bong\n* Goo\n",
+ "\n",
+
+ "* Yin\n\n* Yang\n",
+ "\n",
+
+ "* Ting\n\n* Bong\n* Goo\n",
+ "\n",
+
+ "+ Hello\n",
+ "\n",
+
+ "+ Yin\n+ Yang\n",
+ "\n",
+
+ "+ Ting\n+ Bong\n+ Goo\n",
+ "\n",
+
+ "+ Yin\n\n+ Yang\n",
+ "\n",
+
+ "+ Ting\n\n+ Bong\n+ Goo\n",
+ "\n",
+
+ "- Hello\n",
+ "\n",
+
+ "- Yin\n- Yang\n",
+ "\n",
+
+ "- Ting\n- Bong\n- Goo\n",
+ "\n",
+
+ "- Yin\n\n- Yang\n",
+ "\n",
+
+ "- Ting\n\n- Bong\n- Goo\n",
+ "\n",
+
+ "*Hello\n",
+ "*Hello
\n",
+
+ "* Hello \n",
+ "\n",
+
+ "* Hello \n Next line \n",
+ "\n",
+
+ "Paragraph\n* No linebreak\n",
+ "Paragraph\n* No linebreak
\n",
+
+ "Paragraph\n\n* Linebreak\n",
+ "Paragraph
\n\n\n",
+
+ "* List\n * Nested list\n",
+ "\n",
+
+ "* List\n\n * Nested list\n",
+ "\n",
+
+ "* List\n Second line\n\n + Nested\n",
+ "\nList\nSecond line
\n\n \n
\n",
+
+ "* List\n + Nested\n\n Continued\n",
+ "\nList
\n\n\n\nContinued
\n
\n",
+
+ "* List\n * shallow indent\n",
+ "\n",
+
+ "* List\n" +
+ " * shallow indent\n" +
+ " * part of second list\n" +
+ " * still second\n" +
+ " * almost there\n" +
+ " * third level\n",
+ "\n" +
+ "- List\n\n" +
+ "
\n" +
+ "- shallow indent
\n" +
+ "- part of second list
\n" +
+ "- still second
\n" +
+ "- almost there\n\n" +
+ "
\n" +
+ "- third level
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n",
+
+ "* List\n extra indent, same paragraph\n",
+ "\n- List\n extra indent, same paragraph
\n
\n",
+
+ "* List\n\n code block\n",
+ "\n",
+
+ "* List\n\n code block with spaces\n",
+ "\nList
\n\n code block with spaces\n
\n
\n",
+
+ "* List\n\n * sublist\n\n normal text\n\n * another sublist\n",
+ "\nList
\n\n\n\nnormal text
\n\n \n
\n",
+ }
+ doTestsBlock(t, tests, 0)
+}
+
+func TestOrderedList(t *testing.T) {
+ var tests = []string{
+ "1. Hello\n",
+ "\n- Hello
\n
\n",
+
+ "1. Yin\n2. Yang\n",
+ "\n- Yin
\n- Yang
\n
\n",
+
+ "1. Ting\n2. Bong\n3. Goo\n",
+ "\n- Ting
\n- Bong
\n- Goo
\n
\n",
+
+ "1. Yin\n\n2. Yang\n",
+ "\nYin
\n\nYang
\n
\n",
+
+ "1. Ting\n\n2. Bong\n3. Goo\n",
+ "\nTing
\n\nBong
\n\nGoo
\n
\n",
+
+ "1 Hello\n",
+ "1 Hello
\n",
+
+ "1.Hello\n",
+ "1.Hello
\n",
+
+ "1. Hello \n",
+ "\n- Hello
\n
\n",
+
+ "1. Hello \n Next line \n",
+ "\n- Hello\nNext line
\n
\n",
+
+ "Paragraph\n1. No linebreak\n",
+ "Paragraph\n1. No linebreak
\n",
+
+ "Paragraph\n\n1. Linebreak\n",
+ "Paragraph
\n\n\n- Linebreak
\n
\n",
+
+ "1. List\n 1. Nested list\n",
+ "\n- List\n\n
\n- Nested list
\n
\n
\n",
+
+ "1. List\n\n 1. Nested list\n",
+ "\nList
\n\n\n- Nested list
\n
\n
\n",
+
+ "1. List\n Second line\n\n 1. Nested\n",
+ "\nList\nSecond line
\n\n\n- Nested
\n
\n
\n",
+
+ "1. List\n 1. Nested\n\n Continued\n",
+ "\nList
\n\n\n- Nested
\n
\n\nContinued
\n
\n",
+
+ "1. List\n 1. shallow indent\n",
+ "\n- List\n\n
\n- shallow indent
\n
\n
\n",
+
+ "1. List\n" +
+ " 1. shallow indent\n" +
+ " 2. part of second list\n" +
+ " 3. still second\n" +
+ " 4. almost there\n" +
+ " 1. third level\n",
+ "\n" +
+ "- List\n\n" +
+ "
\n" +
+ "- shallow indent
\n" +
+ "- part of second list
\n" +
+ "- still second
\n" +
+ "- almost there\n\n" +
+ "
\n" +
+ "- third level
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n",
+
+ "1. List\n extra indent, same paragraph\n",
+ "\n- List\n extra indent, same paragraph
\n
\n",
+
+ "1. List\n\n code block\n",
+ "\nList
\n\ncode block\n
\n
\n",
+
+ "1. List\n\n code block with spaces\n",
+ "\nList
\n\n code block with spaces\n
\n
\n",
+
+ "1. List\n * Mixted list\n",
+ "\n- List\n\n
\n
\n",
+
+ "1. List\n * Mixed list\n",
+ "\n- List\n\n
\n
\n",
+
+ "* Start with unordered\n 1. Ordered\n",
+ "\n- Start with unordered\n\n
\n- Ordered
\n
\n
\n",
+
+ "* Start with unordered\n 1. Ordered\n",
+ "\n- Start with unordered\n\n
\n- Ordered
\n
\n
\n",
+
+ "1. numbers\n1. are ignored\n",
+ "\n- numbers
\n- are ignored
\n
\n",
+ }
+ doTestsBlock(t, tests, 0)
+}
+
+func TestDefinitionList(t *testing.T) {
+ var tests = []string{
+ "Term 1\n: Definition a\n",
+ "\n- Term 1
\n- Definition a
\n
\n",
+
+ "Term 1\n: Definition a \n",
+ "\n- Term 1
\n- Definition a
\n
\n",
+
+ "Term 1\n: Definition a\n: Definition b\n",
+ "\n- Term 1
\n- Definition a
\n- Definition b
\n
\n",
+
+ "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n",
+ "\n" +
+ "- Term 1
\n" +
+ "- Definition a
\n" +
+ "- Term 2
\n" +
+ "- Definition b
\n" +
+ "
\n",
+
+ "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n\nTerm 3\n: Definition c\n",
+ "\n" +
+ "- Term 1
\n" +
+ "- Definition a
\n" +
+ "- Term 2
\n" +
+ "- Definition b
\n" +
+ "- Term 3
\n" +
+ "- Definition c
\n" +
+ "
\n",
+
+ "Term 1\n: Definition a\n: Definition b\n\nTerm 2\n: Definition c\n",
+ "\n" +
+ "- Term 1
\n" +
+ "- Definition a
\n" +
+ "- Definition b
\n" +
+ "- Term 2
\n" +
+ "- Definition c
\n" +
+ "
\n",
+
+ "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n",
+ "\n" +
+ "- Term 1
\n" +
+ "Definition a
\n" +
+ "- Term 2
\n" +
+ "Definition b
\n" +
+ "
\n",
+
+ "Term 1\n\n: Definition a\n\n: Definition b\n\nTerm 2\n\n: Definition c\n",
+ "\n" +
+ "- Term 1
\n" +
+ "Definition a
\n" +
+ "Definition b
\n" +
+ "- Term 2
\n" +
+ "Definition c
\n" +
+ "
\n",
+
+ "Term 1\n: Definition a\nNext line\n",
+ "\n- Term 1
\n- Definition a\nNext line
\n
\n",
+
+ "Term 1\n: Definition a\n Next line\n",
+ "\n- Term 1
\n- Definition a\nNext line
\n
\n",
+
+ "Term 1\n: Definition a \n Next line \n",
+ "\n- Term 1
\n- Definition a\nNext line
\n
\n",
+
+ "Term 1\n: Definition a\nNext line\n\nTerm 2\n: Definition b",
+ "\n" +
+ "- Term 1
\n" +
+ "- Definition a\nNext line
\n" +
+ "- Term 2
\n" +
+ "- Definition b
\n" +
+ "
\n",
+
+ "Term 1\n: Definition a\n",
+ "\n- Term 1
\n- Definition a
\n
\n",
+
+ "Term 1\n:Definition a\n",
+ "Term 1\n:Definition a
\n",
+
+ "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n\nText 1",
+ "\n" +
+ "- Term 1
\n" +
+ "Definition a
\n" +
+ "- Term 2
\n" +
+ "Definition b
\n" +
+ "
\n" +
+ "\nText 1
\n",
+
+ "Term 1\n\n: Definition a\n\nText 1\n\nTerm 2\n\n: Definition b\n\nText 2",
+ "\n" +
+ "- Term 1
\n" +
+ "Definition a
\n" +
+ "
\n" +
+ "\nText 1
\n" +
+ "\n\n" +
+ "- Term 2
\n" +
+ "Definition b
\n" +
+ "
\n" +
+ "\nText 2
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_DEFINITION_LISTS)
+}
+
+func TestPreformattedHtml(t *testing.T) {
+ var tests = []string{
+ "\n",
+ "\n",
+
+ "\n
\n",
+ "\n
\n",
+
+ "\n
\nParagraph\n",
+ "\n
\nParagraph
\n",
+
+ "\n
\n",
+ "\n
\n",
+
+ "\nAnything here\n
\n",
+ "\nAnything here\n
\n",
+
+ "\n Anything here\n
\n",
+ "\n Anything here\n
\n",
+
+ "\nAnything here\n
\n",
+ "\nAnything here\n
\n",
+
+ "\nThis is *not* &proceessed\n
\n",
+ "\nThis is *not* &proceessed\n
\n",
+
+ "\n Something\n\n",
+ "\n Something\n
\n",
+
+ "\n Something here\n\n",
+ "
\n Something here\n\n",
+
+ "Paragraph\n
\nHere? >&<\n
\n",
+ "
Paragraph\n
\nHere? >&<\n
\n",
+
+ "Paragraph\n\n
\nHow about here? >&<\n
\n",
+ "
Paragraph
\n\n
\nHow about here? >&<\n
\n",
+
+ "Paragraph\n
\nHere? >&<\n
\nAnd here?\n",
+ "
Paragraph\n
\nHere? >&<\n
\nAnd here?\n",
+
+ "Paragraph\n\n
\nHow about here? >&<\n
\nAnd here?\n",
+ "
Paragraph
\n\n
\nHow about here? >&<\n
\nAnd here?\n",
+
+ "Paragraph\n
\nHere? >&<\n
\n\nAnd here?\n",
+ "
Paragraph\n
\nHere? >&<\n
\n\n
And here?
\n",
+
+ "Paragraph\n\n
\nHow about here? >&<\n
\n\nAnd here?\n",
+ "
Paragraph
\n\n
\nHow about here? >&<\n
\n\n
And here?
\n",
+ }
+ doTestsBlock(t, tests, 0)
+}
+
+func TestPreformattedHtmlLax(t *testing.T) {
+ var tests = []string{
+ "Paragraph\n
\nHere? >&<\n
\n",
+ "
Paragraph
\n\n
\nHere? >&<\n
\n",
+
+ "Paragraph\n\n
\nHow about here? >&<\n
\n",
+ "
Paragraph
\n\n
\nHow about here? >&<\n
\n",
+
+ "Paragraph\n
\nHere? >&<\n
\nAnd here?\n",
+ "
Paragraph
\n\n
\nHere? >&<\n
\n\n
And here?
\n",
+
+ "Paragraph\n\n
\nHow about here? >&<\n
\nAnd here?\n",
+ "
Paragraph
\n\n
\nHow about here? >&<\n
\n\n
And here?
\n",
+
+ "Paragraph\n
\nHere? >&<\n
\n\nAnd here?\n",
+ "
Paragraph
\n\n
\nHere? >&<\n
\n\n
And here?
\n",
+
+ "Paragraph\n\n
\nHow about here? >&<\n
\n\nAnd here?\n",
+ "
Paragraph
\n\n
\nHow about here? >&<\n
\n\n
And here?
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_LAX_HTML_BLOCKS)
+}
+
+func TestFencedCodeBlock(t *testing.T) {
+ var tests = []string{
+ "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
+ "
func foo() bool {\n\treturn true;\n}\n
\n",
+
+ "``` c\n/* special & char < > \" escaping */\n```\n",
+ "
/* special & char < > " escaping */\n
\n",
+
+ "``` c\nno *inline* processing ~~of text~~\n```\n",
+ "
no *inline* processing ~~of text~~\n
\n",
+
+ "```\nNo language\n```\n",
+ "
No language\n
\n",
+
+ "``` {ocaml}\nlanguage in braces\n```\n",
+ "
language in braces\n
\n",
+
+ "``` {ocaml} \nwith extra whitespace\n```\n",
+ "
with extra whitespace\n
\n",
+
+ "```{ ocaml }\nwith extra whitespace\n```\n",
+ "
with extra whitespace\n
\n",
+
+ "~ ~~ java\nWith whitespace\n~~~\n",
+ "
~ ~~ java\nWith whitespace\n~~~
\n",
+
+ "~~\nonly two\n~~\n",
+ "
~~\nonly two\n~~
\n",
+
+ "```` python\nextra\n````\n",
+ "
extra\n
\n",
+
+ "~~~ perl\nthree to start, four to end\n~~~~\n",
+ "
~~~ perl\nthree to start, four to end\n~~~~
\n",
+
+ "~~~~ perl\nfour to start, three to end\n~~~\n",
+ "
~~~~ perl\nfour to start, three to end\n~~~
\n",
+
+ "~~~ bash\ntildes\n~~~\n",
+ "
tildes\n
\n",
+
+ "``` lisp\nno ending\n",
+ "
``` lisp\nno ending
\n",
+
+ "~~~ lisp\nend with language\n~~~ lisp\n",
+ "
~~~ lisp\nend with language\n~~~ lisp
\n",
+
+ "```\nmismatched begin and end\n~~~\n",
+ "
```\nmismatched begin and end\n~~~
\n",
+
+ "~~~\nmismatched begin and end\n```\n",
+ "
~~~\nmismatched begin and end\n```
\n",
+
+ " ``` oz\nleading spaces\n```\n",
+ "
leading spaces\n
\n",
+
+ " ``` oz\nleading spaces\n ```\n",
+ "
leading spaces\n
\n",
+
+ " ``` oz\nleading spaces\n ```\n",
+ "
leading spaces\n
\n",
+
+ "``` oz\nleading spaces\n ```\n",
+ "
leading spaces\n
\n",
+
+ " ``` oz\nleading spaces\n ```\n",
+ "
``` oz\n
\n\n
leading spaces\n ```
\n",
+
+ "Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n",
+ "
Bla bla
\n\n
code blocks breakup paragraphs\n
\n\n
Bla Bla
\n",
+
+ "Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nAnd some text after a fenced code block",
+ "
Some text before a fenced code block
\n\n
code blocks breakup paragraphs\n
\n\n
And some text after a fenced code block
\n",
+
+ "`",
+ "
`
\n",
+
+ "Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n\n``` oz\nmultiple code blocks work okay\n```\n\nBla Bla\n",
+ "
Bla bla
\n\n
code blocks breakup paragraphs\n
\n\n
Bla Bla
\n\n
multiple code blocks work okay\n
\n\n
Bla Bla
\n",
+
+ "Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nSome text in between\n``` oz\nmultiple code blocks work okay\n```\nAnd some text after a fenced code block",
+ "
Some text before a fenced code block
\n\n
code blocks breakup paragraphs\n
\n\n
Some text in between
\n\n
multiple code blocks work okay\n
\n\n
And some text after a fenced code block
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_FENCED_CODE)
+}
+
+func TestTable(t *testing.T) {
+ var tests = []string{
+ "a | b\n---|---\nc | d\n",
+ "
\n\n\n| a | \nb | \n
\n\n\n" +
+ "\n\n| c | \nd | \n
\n\n
\n",
+
+ "a | b\n---|--\nc | d\n",
+ "
a | b\n---|--\nc | d
\n",
+
+ "|a|b|c|d|\n|----|----|----|---|\n|e|f|g|h|\n",
+ "
\n\n\n| a | \nb | \nc | \nd | \n
\n\n\n" +
+ "\n\n| e | \nf | \ng | \nh | \n
\n\n
\n",
+
+ "*a*|__b__|[c](C)|d\n---|---|---|---\ne|f|g|h\n",
+ "
\n\n\n| a | \nb | \nc | \nd | \n
\n\n\n" +
+ "\n\n| e | \nf | \ng | \nh | \n
\n\n
\n",
+
+ "a|b|c\n---|---|---\nd|e|f\ng|h\ni|j|k|l|m\nn|o|p\n",
+ "
\n\n\n| a | \nb | \nc | \n
\n\n\n" +
+ "\n\n| d | \ne | \nf | \n
\n\n" +
+ "\n| g | \nh | \n | \n
\n\n" +
+ "\n| i | \nj | \nk | \n
\n\n" +
+ "\n| n | \no | \np | \n
\n\n
\n",
+
+ "a|b|c\n---|---|---\n*d*|__e__|f\n",
+ "
\n\n\n| a | \nb | \nc | \n
\n\n\n" +
+ "\n\n| d | \ne | \nf | \n
\n\n
\n",
+
+ "a|b|c|d\n:--|--:|:-:|---\ne|f|g|h\n",
+ "
\n\n\n| a | \nb | \n" +
+ "c | \nd | \n
\n\n\n" +
+ "\n\n| e | \nf | \n" +
+ "g | \nh | \n
\n\n
\n",
+
+ "a|b|c\n---|---|---\n",
+ "
\n\n\n| a | \nb | \nc | \n
\n\n\n\n\n
\n",
+
+ "a| b|c | d | e\n---|---|---|---|---\nf| g|h | i |j\n",
+ "
\n\n\n| a | \nb | \nc | \nd | \ne | \n
\n\n\n" +
+ "\n\n| f | \ng | \nh | \ni | \nj | \n
\n\n
\n",
+
+ "a|b\\|c|d\n---|---|---\nf|g\\|h|i\n",
+ "
\n\n\n| a | \nb|c | \nd | \n
\n\n\n\n\n| f | \ng|h | \ni | \n
\n\n
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_TABLES)
+}
+
+func TestUnorderedListWith_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
+ var tests = []string{
+ "* Hello\n",
+ "
\n",
+
+ "* Yin\n* Yang\n",
+ "
\n",
+
+ "* Ting\n* Bong\n* Goo\n",
+ "
\n",
+
+ "* Yin\n\n* Yang\n",
+ "
\n",
+
+ "* Ting\n\n* Bong\n* Goo\n",
+ "
\n",
+
+ "+ Hello\n",
+ "
\n",
+
+ "+ Yin\n+ Yang\n",
+ "
\n",
+
+ "+ Ting\n+ Bong\n+ Goo\n",
+ "
\n",
+
+ "+ Yin\n\n+ Yang\n",
+ "
\n",
+
+ "+ Ting\n\n+ Bong\n+ Goo\n",
+ "
\n",
+
+ "- Hello\n",
+ "
\n",
+
+ "- Yin\n- Yang\n",
+ "
\n",
+
+ "- Ting\n- Bong\n- Goo\n",
+ "
\n",
+
+ "- Yin\n\n- Yang\n",
+ "
\n",
+
+ "- Ting\n\n- Bong\n- Goo\n",
+ "
\n",
+
+ "*Hello\n",
+ "
*Hello
\n",
+
+ "* Hello \n",
+ "
\n",
+
+ "* Hello \n Next line \n",
+ "
\n",
+
+ "Paragraph\n* No linebreak\n",
+ "
Paragraph
\n\n
\n",
+
+ "Paragraph\n\n* Linebreak\n",
+ "
Paragraph
\n\n
\n",
+
+ "* List\n * Nested list\n",
+ "
\n",
+
+ "* List\n\n * Nested list\n",
+ "
\n",
+
+ "* List\n Second line\n\n + Nested\n",
+ "
\nList\nSecond line
\n\n \n
\n",
+
+ "* List\n + Nested\n\n Continued\n",
+ "
\nList
\n\n\n\nContinued
\n
\n",
+
+ "* List\n * shallow indent\n",
+ "
\n",
+
+ "* List\n" +
+ " * shallow indent\n" +
+ " * part of second list\n" +
+ " * still second\n" +
+ " * almost there\n" +
+ " * third level\n",
+ "
\n" +
+ "- List\n\n" +
+ "
\n" +
+ "- shallow indent
\n" +
+ "- part of second list
\n" +
+ "- still second
\n" +
+ "- almost there\n\n" +
+ "
\n" +
+ "- third level
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n",
+
+ "* List\n extra indent, same paragraph\n",
+ "
\n- List\n extra indent, same paragraph
\n
\n",
+
+ "* List\n\n code block\n",
+ "
\n",
+
+ "* List\n\n code block with spaces\n",
+ "
\nList
\n\n code block with spaces\n
\n
\n",
+
+ "* List\n\n * sublist\n\n normal text\n\n * another sublist\n",
+ "
\nList
\n\n\n\nnormal text
\n\n \n
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK)
+}
+
+func TestOrderedList_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
+ var tests = []string{
+ "1. Hello\n",
+ "
\n- Hello
\n
\n",
+
+ "1. Yin\n2. Yang\n",
+ "
\n- Yin
\n- Yang
\n
\n",
+
+ "1. Ting\n2. Bong\n3. Goo\n",
+ "
\n- Ting
\n- Bong
\n- Goo
\n
\n",
+
+ "1. Yin\n\n2. Yang\n",
+ "
\nYin
\n\nYang
\n
\n",
+
+ "1. Ting\n\n2. Bong\n3. Goo\n",
+ "
\nTing
\n\nBong
\n\nGoo
\n
\n",
+
+ "1 Hello\n",
+ "
1 Hello
\n",
+
+ "1.Hello\n",
+ "
1.Hello
\n",
+
+ "1. Hello \n",
+ "
\n- Hello
\n
\n",
+
+ "1. Hello \n Next line \n",
+ "
\n- Hello\nNext line
\n
\n",
+
+ "Paragraph\n1. No linebreak\n",
+ "
Paragraph
\n\n
\n- No linebreak
\n
\n",
+
+ "Paragraph\n\n1. Linebreak\n",
+ "
Paragraph
\n\n
\n- Linebreak
\n
\n",
+
+ "1. List\n 1. Nested list\n",
+ "
\n- List\n\n
\n- Nested list
\n
\n
\n",
+
+ "1. List\n\n 1. Nested list\n",
+ "
\nList
\n\n\n- Nested list
\n
\n
\n",
+
+ "1. List\n Second line\n\n 1. Nested\n",
+ "
\nList\nSecond line
\n\n\n- Nested
\n
\n
\n",
+
+ "1. List\n 1. Nested\n\n Continued\n",
+ "
\nList
\n\n\n- Nested
\n
\n\nContinued
\n
\n",
+
+ "1. List\n 1. shallow indent\n",
+ "
\n- List\n\n
\n- shallow indent
\n
\n
\n",
+
+ "1. List\n" +
+ " 1. shallow indent\n" +
+ " 2. part of second list\n" +
+ " 3. still second\n" +
+ " 4. almost there\n" +
+ " 1. third level\n",
+ "
\n" +
+ "- List\n\n" +
+ "
\n" +
+ "- shallow indent
\n" +
+ "- part of second list
\n" +
+ "- still second
\n" +
+ "- almost there\n\n" +
+ "
\n" +
+ "- third level
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n",
+
+ "1. List\n extra indent, same paragraph\n",
+ "
\n- List\n extra indent, same paragraph
\n
\n",
+
+ "1. List\n\n code block\n",
+ "
\nList
\n\ncode block\n
\n
\n",
+
+ "1. List\n\n code block with spaces\n",
+ "
\nList
\n\n code block with spaces\n
\n
\n",
+
+ "1. List\n * Mixted list\n",
+ "
\n- List\n\n
\n
\n",
+
+ "1. List\n * Mixed list\n",
+ "
\n- List\n\n
\n
\n",
+
+ "* Start with unordered\n 1. Ordered\n",
+ "
\n- Start with unordered\n\n
\n- Ordered
\n
\n
\n",
+
+ "* Start with unordered\n 1. Ordered\n",
+ "
\n- Start with unordered\n\n
\n- Ordered
\n
\n
\n",
+
+ "1. numbers\n1. are ignored\n",
+ "
\n- numbers
\n- are ignored
\n
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK)
+}
+
+func TestFencedCodeBlock_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
+ var tests = []string{
+ "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
+ "
func foo() bool {\n\treturn true;\n}\n
\n",
+
+ "``` c\n/* special & char < > \" escaping */\n```\n",
+ "
/* special & char < > " escaping */\n
\n",
+
+ "``` c\nno *inline* processing ~~of text~~\n```\n",
+ "
no *inline* processing ~~of text~~\n
\n",
+
+ "```\nNo language\n```\n",
+ "
No language\n
\n",
+
+ "``` {ocaml}\nlanguage in braces\n```\n",
+ "
language in braces\n
\n",
+
+ "``` {ocaml} \nwith extra whitespace\n```\n",
+ "
with extra whitespace\n
\n",
+
+ "```{ ocaml }\nwith extra whitespace\n```\n",
+ "
with extra whitespace\n
\n",
+
+ "~ ~~ java\nWith whitespace\n~~~\n",
+ "
~ ~~ java\nWith whitespace\n~~~
\n",
+
+ "~~\nonly two\n~~\n",
+ "
~~\nonly two\n~~
\n",
+
+ "```` python\nextra\n````\n",
+ "
extra\n
\n",
+
+ "~~~ perl\nthree to start, four to end\n~~~~\n",
+ "
~~~ perl\nthree to start, four to end\n~~~~
\n",
+
+ "~~~~ perl\nfour to start, three to end\n~~~\n",
+ "
~~~~ perl\nfour to start, three to end\n~~~
\n",
+
+ "~~~ bash\ntildes\n~~~\n",
+ "
tildes\n
\n",
+
+ "``` lisp\nno ending\n",
+ "
``` lisp\nno ending
\n",
+
+ "~~~ lisp\nend with language\n~~~ lisp\n",
+ "
~~~ lisp\nend with language\n~~~ lisp
\n",
+
+ "```\nmismatched begin and end\n~~~\n",
+ "
```\nmismatched begin and end\n~~~
\n",
+
+ "~~~\nmismatched begin and end\n```\n",
+ "
~~~\nmismatched begin and end\n```
\n",
+
+ " ``` oz\nleading spaces\n```\n",
+ "
leading spaces\n
\n",
+
+ " ``` oz\nleading spaces\n ```\n",
+ "
leading spaces\n
\n",
+
+ " ``` oz\nleading spaces\n ```\n",
+ "
leading spaces\n
\n",
+
+ "``` oz\nleading spaces\n ```\n",
+ "
leading spaces\n
\n",
+
+ " ``` oz\nleading spaces\n ```\n",
+ "
``` oz\n
\n\n
leading spaces
\n\n
```\n
\n",
+ }
+ doTestsBlock(t, tests, EXTENSION_FENCED_CODE|EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK)
+}
+
+func TestTitleBlock_EXTENSION_TITLEBLOCK(t *testing.T) {
+ var tests = []string{
+ "% Some title\n" +
+ "% Another title line\n" +
+ "% Yep, more here too\n",
+ "
" +
+ "Some title\n" +
+ "Another title line\n" +
+ "Yep, more here too\n" +
+ "
",
+ }
+
+ doTestsBlock(t, tests, EXTENSION_TITLEBLOCK)
+
+}
diff --git a/vendor/github.com/russross/blackfriday/html.go b/vendor/github.com/russross/blackfriday/html.go
new file mode 100644
index 00000000..264aae58
--- /dev/null
+++ b/vendor/github.com/russross/blackfriday/html.go
@@ -0,0 +1,948 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross
.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+//
+// HTML rendering backend
+//
+//
+
+package blackfriday
+
+import (
+ "bytes"
+ "fmt"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// Html renderer configuration options.
+const (
+ HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks
+ HTML_SKIP_STYLE // skip embedded