diff --git a/go.mod b/go.mod index f97e9caeb..df49a1664 100644 --- a/go.mod +++ b/go.mod @@ -4,23 +4,17 @@ go 1.13 require ( github.com/AlecAivazis/survey/v2 v2.0.4 - github.com/alecthomas/chroma v0.6.8 - github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/go-version v1.2.0 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/kr/text v0.1.0 github.com/mattn/go-colorable v0.1.2 github.com/mattn/go-isatty v0.0.9 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b github.com/mitchellh/go-homedir v1.1.0 - github.com/mitchellh/go-wordwrap v1.0.0 github.com/pkg/errors v0.8.1 - github.com/russross/blackfriday/v2 v2.0.1 - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.5 - github.com/tj/go-css v0.0.0-20191108133013-220a796d1705 + github.com/vilmibm/go-termd v0.0.4 golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 gopkg.in/yaml.v3 v3.0.0-20191010095647-fc94e3f71652 ) diff --git a/go.sum b/go.sum index 4164f7646..79806902b 100644 --- a/go.sum +++ b/go.sum @@ -110,6 +110,8 @@ github.com/tj/go-css v0.0.0-20191108133013-220a796d1705/go.mod h1:e+JPLQ9wyQCgRn github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/vilmibm/go-termd v0.0.4 h1:uCmDUZ3qZUblTN/D5Hvl+g1rTJj/HW746JQFWidqAyk= +github.com/vilmibm/go-termd v0.0.4/go.mod h1:ys+dRO6wlM3el0vPJmYBkhOPPozViBgDXHOEn1x5Vsc= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/markdown/highlight.go b/markdown/highlight.go deleted file mode 100644 index 5d44744ed..000000000 --- a/markdown/highlight.go +++ /dev/null @@ -1,36 +0,0 @@ -// This package is sourced from https://github.com/tj/go-termd under the terms of the MIT license. -// It was inlined to work around some dependency issues. -package markdown - -import ( - "strings" - - "github.com/alecthomas/chroma" - "github.com/alecthomas/chroma/lexers" -) - -// SyntaxHighlighter is the interface used to highlight blocks of code. -type SyntaxHighlighter interface { - Token(chroma.Token) string -} - -// highlight returns highlighted code, or the input text on error. -func highlight(source, lang string, highlight SyntaxHighlighter) string { - l := lexers.Get(lang) - if l == nil { - return source - } - - l = chroma.Coalesce(l) - - it, err := l.Tokenise(nil, source) - if err != nil { - return source - } - - var w strings.Builder - for _, t := range it.Tokens() { - w.WriteString(highlight.Token(t)) - } - return w.String() -} diff --git a/markdown/markdown.go b/markdown/markdown.go deleted file mode 100644 index 68e3a7c8c..000000000 --- a/markdown/markdown.go +++ /dev/null @@ -1,122 +0,0 @@ -// Package markdown provides terminal markdown rendering, -// with code block syntax highlighting support. -// This package is sourced from https://github.com/tj/go-termd under the terms of the MIT license. -// It was inlined to work around some dependency issues. -package markdown - -import ( - "fmt" - "strings" - - "github.com/kr/text" - "github.com/mitchellh/go-wordwrap" - blackfriday "github.com/russross/blackfriday/v2" -) - -// Compiler is the markdown to text compiler. The zero value can be used. -type Compiler struct { - // Columns is the number of columns to wrap text, defaulting to 90. - Columns int - - // Markdown is an optional instance of a blackfriday markdown parser, - // defaulting to one with CommonExtensions enabled. - Markdown *blackfriday.Markdown - - // SyntaxHighlighter is an optional syntax highlighter for code blocks, - // using the low-level SyntaxHighlighter interface, or SyntaxTheme map. - SyntaxHighlighter - - inBlockQuote bool - inList bool -} - -// Compile returns a terminal-styled plain text representation of a markdown string. -func (c *Compiler) Compile(s string) string { - if c.Markdown == nil { - c.Markdown = blackfriday.New(blackfriday.WithExtensions(blackfriday.CommonExtensions)) - } - - if c.Columns == 0 { - c.Columns = 90 - } - - if c.SyntaxHighlighter == nil { - c.SyntaxHighlighter = SyntaxTheme{} - } - - n := c.Markdown.Parse([]byte(s)) - return c.visit(n) -} - -// visit returns a compiled node string. -func (c *Compiler) visit(n *blackfriday.Node) (s string) { - switch n.Type { - case blackfriday.Document: - s = c.visit(n.FirstChild) - case blackfriday.BlockQuote: - prev := c.inBlockQuote - c.inBlockQuote = true - s = c.visit(n.FirstChild) - s = fmt.Sprintf("\033[38;5;102m%s\033[m", s) - c.inBlockQuote = prev - case blackfriday.List: - prev := c.inList - c.inList = true - s = fmt.Sprintf("%s\n", c.visit(n.FirstChild)) - c.inList = prev - case blackfriday.Item: - s = fmt.Sprintf(" - %s", c.visit(n.FirstChild)) - case blackfriday.Paragraph: - s = c.visit(n.FirstChild) - if c.inList { - s += "\n" - } else { - s = wordwrap.WrapString(s, uint(c.Columns)) - s = text.Indent(s, " ") - s += "\n\n" - } - case blackfriday.Heading: - h := strings.Repeat("#", n.HeadingData.Level) - t := c.visit(n.FirstChild) - s = fmt.Sprintf("\033[1m%s %s\033[m\n\n", h, t) - case blackfriday.HorizontalRule: - s = fmt.Sprintf(" %s\n\n", strings.Repeat("─", c.Columns)) - case blackfriday.Emph: - s = c.visit(n.FirstChild) - if !c.inBlockQuote { - s = fmt.Sprintf("\033[3m%s\033[m", s) - } - case blackfriday.Strong: - s = c.visit(n.FirstChild) - if !c.inBlockQuote { - s = fmt.Sprintf("\033[1m%s\033[m", s) - } - case blackfriday.Link: - s = c.visit(n.FirstChild) - d := string(n.LinkData.Destination) - if s != d { - s = fmt.Sprintf("%s (%s)", s, d) - } - case blackfriday.Image: - s = string(n.LinkData.Destination) - case blackfriday.Text: - s = string(n.Literal) - case blackfriday.CodeBlock: - lang := string(n.CodeBlockData.Info) - s = string(n.Literal) - s = highlight(s, lang, c.SyntaxHighlighter) - s = fmt.Sprintf("%s\n", text.Indent(s, " ")) - case blackfriday.Code: - s = fmt.Sprintf("\033[38;5;102m`%s`\033[m", string(n.Literal)) - case blackfriday.HTMLSpan: - // ignore - default: - s = fmt.Sprintf("", n) - } - - if n.Next != nil { - s += c.visit(n.Next) - } - - return -} diff --git a/markdown/theme.go b/markdown/theme.go deleted file mode 100644 index 84086c924..000000000 --- a/markdown/theme.go +++ /dev/null @@ -1,202 +0,0 @@ -// This package is sourced from https://github.com/tj/go-termd under the terms of the MIT license. -// It was inlined to work around some dependency issues. -package markdown - -import ( - "fmt" - - "github.com/alecthomas/chroma" - "github.com/aybabtme/rgbterm" - "github.com/tj/go-css/csshex" -) - -// Style is the configuration used to style a particular token. -type Style struct { - Color string `json:"color"` - Background string `json:"background"` - Bold bool `json:"bold"` - Faint bool `json:"faint"` - Italic bool `json:"italic"` - Underline bool `json:"underline"` -} - -// apply returns a string with the style applied. -func (s Style) apply(v string) string { - if s.Bold { - v = escape(1, v) - } - - if s.Faint { - v = escape(2, v) - } - - if s.Italic { - v = escape(3, v) - } - - if s.Underline { - v = escape(4, v) - } - - if s.Color != "" { - v = foreground(v, s.Color) - } - - if s.Background != "" { - v = background(v, s.Background) - } - - return v -} - -// SyntaxTheme is a map of token names to style configurations. -type SyntaxTheme map[string]Style - -// Token implementation. -func (c SyntaxTheme) Token(t chroma.Token) string { - // specific - if s, ok := c.mapped(t.Type, t.Value); ok { - return s - } - - // sub-category - if s, ok := c.mapped(t.Type.SubCategory(), t.Value); ok { - return s - } - - // category - if s, ok := c.mapped(t.Type.Category(), t.Value); ok { - return s - } - - return t.Value -} - -// mapped returns a string mapped to its style, or returns the input string as-is. -func (c SyntaxTheme) mapped(t chroma.TokenType, v string) (string, bool) { - // check if the key is valid - k, ok := themeKeys[t] - if !ok { - return v, false - } - - // check if the style is mapped - s, ok := c[k] - if !ok { - return v, false - } - - return s.apply(v), true -} - -// escape returns an ansi escape sequence with the given code. -func escape(code int, s string) string { - return fmt.Sprintf("\033[%dm%s\033[m", code, s) -} - -// foreground color. -func foreground(s, color string) string { - r, g, b, ok := csshex.Parse(color) - if !ok { - return s - } - return rgbterm.FgString(s, r, g, b) -} - -// background color. -func background(s, color string) string { - r, g, b, ok := csshex.Parse(color) - if !ok { - return s - } - return rgbterm.BgString(s, r, g, b) -} - -// themeKeys is the map of token types to names. -var themeKeys = map[chroma.TokenType]string{ - chroma.Keyword: "keyword", - chroma.KeywordConstant: "keyword.constant", - chroma.KeywordDeclaration: "keyword.declaration", - chroma.KeywordNamespace: "keyword.namespace", - chroma.KeywordPseudo: "keyword.pseudo", - chroma.KeywordReserved: "keyword.reserved", - chroma.KeywordType: "keyword.type", - chroma.Name: "name", - chroma.NameAttribute: "name.attribute", - chroma.NameBuiltin: "name.builtin", - chroma.NameBuiltinPseudo: "name.builtin.pseudo", - chroma.NameClass: "name.class", - chroma.NameConstant: "name.constant", - chroma.NameDecorator: "name.decorator", - chroma.NameEntity: "name.entity", - chroma.NameException: "name.exception", - chroma.NameFunction: "name.function", - chroma.NameFunctionMagic: "name.function.magic", - chroma.NameKeyword: "name.keyword", - chroma.NameLabel: "name.label", - chroma.NameNamespace: "name.namespace", - chroma.NameOperator: "name.operator", - chroma.NameOther: "name.other", - chroma.NamePseudo: "name.pseudo", - chroma.NameProperty: "name.property", - chroma.NameTag: "name.tag", - chroma.NameVariable: "name.variable", - chroma.NameVariableAnonymous: "name.variable.anonymous", - chroma.NameVariableClass: "name.variable.class", - chroma.NameVariableGlobal: "name.variable.global", - chroma.NameVariableInstance: "name.variable.instance", - chroma.NameVariableMagic: "name.variable.magic", - chroma.Literal: "literal", - chroma.LiteralDate: "literal.date", - chroma.LiteralOther: "literal.other", - chroma.LiteralString: "literal.string", - chroma.LiteralStringAffix: "literal.string.affix", - chroma.LiteralStringAtom: "literal.string.atom", - chroma.LiteralStringBacktick: "literal.string.backtick", - chroma.LiteralStringBoolean: "literal.string.boolean", - chroma.LiteralStringChar: "literal.string.char", - chroma.LiteralStringDelimiter: "literal.string.delimiter", - chroma.LiteralStringDoc: "literal.string.doc", - chroma.LiteralStringDouble: "literal.string.double", - chroma.LiteralStringEscape: "literal.string.escape", - chroma.LiteralStringHeredoc: "literal.string.heredoc", - chroma.LiteralStringInterpol: "literal.string.interpol", - chroma.LiteralStringName: "literal.string.name", - chroma.LiteralStringOther: "literal.string.other", - chroma.LiteralStringRegex: "literal.string.regex", - chroma.LiteralStringSingle: "literal.string.single", - chroma.LiteralStringSymbol: "literal.string.symbol", - chroma.LiteralNumber: "literal.number", - chroma.LiteralNumberBin: "literal.number.bin", - chroma.LiteralNumberFloat: "literal.number.float", - chroma.LiteralNumberHex: "literal.number.hex", - chroma.LiteralNumberInteger: "literal.number.integer", - chroma.LiteralNumberIntegerLong: "literal.number.integer.long", - chroma.LiteralNumberOct: "literal.number.oct", - chroma.Operator: "operator", - chroma.OperatorWord: "operator.word", - chroma.Punctuation: "punctuation", - chroma.Comment: "comment", - chroma.CommentHashbang: "comment.hashbang", - chroma.CommentMultiline: "comment.multiline", - chroma.CommentSingle: "comment.single", - chroma.CommentSpecial: "comment.special", - chroma.CommentPreproc: "comment.preproc", - chroma.CommentPreprocFile: "comment.preproc.file", - chroma.Generic: "generic", - chroma.GenericDeleted: "generic.deleted", - chroma.GenericEmph: "generic.emph", - chroma.GenericError: "generic.error", - chroma.GenericHeading: "generic.heading", - chroma.GenericInserted: "generic.inserted", - chroma.GenericOutput: "generic.output", - chroma.GenericPrompt: "generic.prompt", - chroma.GenericStrong: "generic.strong", - chroma.GenericSubheading: "generic.subheading", - chroma.GenericTraceback: "generic.traceback", - chroma.GenericUnderline: "generic.underline", - chroma.Text: "text", - chroma.TextWhitespace: "text.whitespace", - chroma.TextSymbol: "text.symbol", - chroma.TextPunctuation: "text.punctuation", -} diff --git a/utils/utils.go b/utils/utils.go index 2fc878469..2c8c5ac0a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -8,8 +8,8 @@ import ( "os/exec" "runtime" - md "github.com/github/gh-cli/markdown" "github.com/kballard/go-shellquote" + md "github.com/vilmibm/go-termd" ) func OpenInBrowser(url string) error {