de-inline go-termd

This commit is contained in:
vilmibm 2020-01-13 16:10:22 -06:00
parent 4592aaf63d
commit daf02ff3ec
6 changed files with 4 additions and 368 deletions

8
go.mod
View file

@ -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
)

2
go.sum
View file

@ -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=

View file

@ -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()
}

View file

@ -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("<unhandled: %v>", n)
}
if n.Next != nil {
s += c.visit(n.Next)
}
return
}

View file

@ -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",
}

View file

@ -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 {