diff --git a/libs/blackterm/.gitrepo b/libs/blackterm/.gitrepo new file mode 100644 index 0000000..ceb59ff --- /dev/null +++ b/libs/blackterm/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://github.com/capitancambio/blackterm.git + branch = master + commit = 8446c9dfde022a8fe07dc6e5c56f12799f39e8cc + parent = 452de887964a3f6ab91d2d03605106e29638604f + cmdver = 0.3.1 diff --git a/libs/blackterm/README.md b/libs/blackterm/README.md new file mode 100644 index 0000000..db3efe8 --- /dev/null +++ b/libs/blackterm/README.md @@ -0,0 +1,3 @@ +#blackterm + +A simple blackfriday renderer to print a subset of markdown in the terminal with flying colours. Not really advanced, just to give support to [dp2](https://github.com/daisy/pipeline-cli-go) diff --git a/libs/blackterm/render.go b/libs/blackterm/render.go new file mode 100644 index 0000000..42a42fa --- /dev/null +++ b/libs/blackterm/render.go @@ -0,0 +1,143 @@ +package blackterm + +import ( + "bytes" + "fmt" + + "github.com/capitancambio/chalk" + "github.com/russross/blackfriday" +) + +/* +Process a subset of markdown elements and prints them with flying colours! +*/ +func Markdown(input []byte) []byte { + tr := NewTerminalRenderer() + ret := blackfriday.Markdown(input, tr, blackfriday.EXTENSION_STRIKETHROUGH) + //get rid of \n at the end of the text + for len(ret) > 0 && ret[len(ret)-1] == '\n' { + ret = ret[:len(ret)-1] + } + return ret +} + +func MarkdownString(input string) string { + return string(Markdown([]byte(input))) +} + +type TerminalRenderer struct { + Headers map[int]chalk.Style + DefHeader chalk.Style + Bullet string +} + +func NewTerminalRenderer() TerminalRenderer { + return TerminalRenderer{ + Headers: map[int]chalk.Style{ + 1: chalk.Underline.NewStyle().WithForeground(chalk.Magenta), + }, + DefHeader: chalk.Bold.NewStyle().WithForeground(chalk.Magenta), + Bullet: " • ", + } +} + +func (tr TerminalRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) { + +} +func (tr TerminalRenderer) BlockQuote(out *bytes.Buffer, text []byte) {} +func (tr TerminalRenderer) BlockHtml(out *bytes.Buffer, text []byte) {} +func (tr TerminalRenderer) Header(out *bytes.Buffer, text func() bool, level int, id string) { + style, ok := tr.Headers[level] + if !ok { + style = tr.DefHeader + } + + out.WriteString(style.Prefix()) + if text() { + out.WriteByte('\n') + out.WriteByte('\n') + } + + out.WriteString(style.Suffix()) + +} +func (tr TerminalRenderer) HRule(out *bytes.Buffer) {} +func (tr TerminalRenderer) List(out *bytes.Buffer, text func() bool, flags int) { + text() + out.WriteByte('\n') + +} +func (tr TerminalRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) { + + out.WriteString(tr.Bullet) + out.Write(text) + out.WriteByte('\n') + +} +func (tr TerminalRenderer) Paragraph(out *bytes.Buffer, text func() bool) { + if text() { + out.WriteString("\n") + } + +} +func (tr TerminalRenderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {} +func (tr TerminalRenderer) TableRow(out *bytes.Buffer, text []byte) {} +func (tr TerminalRenderer) TableHeaderCell(out *bytes.Buffer, text []byte, flags int) {} +func (tr TerminalRenderer) TableCell(out *bytes.Buffer, text []byte, flags int) {} +func (tr TerminalRenderer) Footnotes(out *bytes.Buffer, text func() bool) {} +func (tr TerminalRenderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {} +func (tr TerminalRenderer) TitleBlock(out *bytes.Buffer, text []byte) { + +} + +// Span-level callbacks{} +func (tr TerminalRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {} +func (tr TerminalRenderer) CodeSpan(out *bytes.Buffer, text []byte) { + style := chalk.Green.NewStyle().WithBackground(chalk.Black).WithTextStyle(chalk.Bold) + out.WriteString(style.Prefix()) + out.Write(text) + out.WriteString(style.Suffix()) +} +func (tr TerminalRenderer) DoubleEmphasis(out *bytes.Buffer, text []byte) { + out.WriteString(chalk.Inverse.TextStyle(string(text))) +} +func (tr TerminalRenderer) Emphasis(out *bytes.Buffer, text []byte) { + out.WriteString(chalk.Bold.TextStyle(string(text))) + +} +func (tr TerminalRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) { + out.WriteString(fmt.Sprintf("[IMAGE: %s (%s)]", string(alt), string(link))) +} + +func (tr TerminalRenderer) LineBreak(out *bytes.Buffer) { + out.WriteString("\n") +} +func (tr TerminalRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) { + out.WriteString(fmt.Sprintf("%s (%s)", string(content), string(link))) +} +func (tr TerminalRenderer) RawHtmlTag(out *bytes.Buffer, tag []byte) {} +func (tr TerminalRenderer) TripleEmphasis(out *bytes.Buffer, text []byte) { + style := chalk.Inverse.NewStyle().WithForeground(chalk.Red) + out.WriteString(style.Prefix()) + out.Write(text) + out.WriteString(style.Suffix()) + +} +func (tr TerminalRenderer) StrikeThrough(out *bytes.Buffer, text []byte) { + out.WriteString(chalk.Strikethrough.TextStyle(string(text))) +} +func (tr TerminalRenderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {} + +// Low-level callbacks{} +func (tr TerminalRenderer) Entity(out *bytes.Buffer, entity []byte) { + out.Write(entity) +} + +func (tr TerminalRenderer) NormalText(out *bytes.Buffer, text []byte) { + out.Write(text) +} + +// Header and footer{} +func (tr TerminalRenderer) DocumentHeader(out *bytes.Buffer) {} +func (tr TerminalRenderer) DocumentFooter(out *bytes.Buffer) {} +func (tr TerminalRenderer) GetFlags() int { return 0 } diff --git a/libs/blackterm/test/main.go b/libs/blackterm/test/main.go new file mode 100644 index 0000000..3092492 --- /dev/null +++ b/libs/blackterm/test/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "fmt" + + "github.com/capitancambio/blackterm" +) + +func main() { + input := `#Markdown header +## Level 2 header +Normal text + +This is a list: + +* The first item +* The second item + +Just saying, *this is quite important* so you pay attention. +But this is even **more important!** +And I'm sorry to break this to you but .... ***THIS IS THE MOST IMPORTANT THING EVER WRITTEN!!*** + +On the other hand you shouldn't ~~pay attention to this~~ + +[I'm a link](http://thisshouldbedisplayed.com) +![This is an image](http://actualurltotheimage.com/img.png) + +This is how the source code span is generated +` + "```" + ` +func (tr TerminalRenderer) CodeSpan(out *bytes.Buffer, text []byte) { +style := chalk.Green.NewStyle().WithBackground(chalk.Black).WithTextStyle(chalk.Bold) +out.WriteString(style.Prefix()) +out.WriteString("\n[[[\n") +out.Write(text) +out.WriteString("\n"]]]\n") +out.WriteString(style.Suffix()) +} +` + "```" + ` + +Inline code span ` + "`2+2`" + ` looks like this + + + + +` + + //input := "HEY!" + //renderer := blackterm.NewTerminalRenderer() + //out := blackfriday.Markdown([]byte(input), renderer, blackfriday.EXTENSION_STRIKETHROUGH) + out := blackterm.Markdown([]byte(input)) + fmt.Printf("%s", out) + +}