Documentation and golint cleanup for markup

master
Michael Dvorkin 11 years ago
parent 7231d8f29c
commit ffc491b20f
  1. 136
      markup.go

@ -1,6 +1,6 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. // Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style license that can
// license that can be found in the LICENSE file. // be found in the LICENSE file.
package mop package mop
@ -10,39 +10,65 @@ import (
`strings` `strings`
) )
// Markup implements some minimalistic text formatting conventions that
// get translated to Termbox colors and attributes. To colorize a string
// wrap it in <color-name>...</> tags. Unlike HTML each tag sets a new
// color whereas the </> tag changes color back to default. For example:
//
// <green>Hello, <red>world!</>
//
// The color tags could be combined with the attributes: <b>...</b> for
// bold, <u>...</u> for underline, and <r>...</r> for reverse. Unlike
// colors the attributes require matching closing tag.
//
// The <right>...</right> tag is used to right align the enclosed string
// (ex. when displaying current time in the upper right corner).
type Markup struct { type Markup struct {
tags map[string]termbox.Attribute Foreground termbox.Attribute // Foreground color.
Foreground termbox.Attribute Background termbox.Attribute // Background color (so far always termbox.ColorDefault).
Background termbox.Attribute RightAligned bool // True when the string is right aligned.
RightAligned bool tags map[string]termbox.Attribute // Tags to Termbox translation hash.
regex *regexp.Regexp // Regex to identify the supported tag names.
} }
//----------------------------------------------------------------------------- // Initialize creates tags to Termbox translation hash and sets default
func (self *Markup) Initialize() *Markup { // colors and string alignment.
self.tags = make(map[string]termbox.Attribute) func (markup *Markup) Initialize() *Markup {
self.tags[`/`] = termbox.ColorDefault markup.Foreground = termbox.ColorDefault
self.tags[`black`] = termbox.ColorBlack markup.Background = termbox.ColorDefault
self.tags[`red`] = termbox.ColorRed markup.RightAligned = false
self.tags[`green`] = termbox.ColorGreen
self.tags[`yellow`] = termbox.ColorYellow markup.tags = make(map[string]termbox.Attribute)
self.tags[`blue`] = termbox.ColorBlue markup.tags[`/`] = termbox.ColorDefault
self.tags[`magenta`] = termbox.ColorMagenta markup.tags[`black`] = termbox.ColorBlack
self.tags[`cyan`] = termbox.ColorCyan markup.tags[`red`] = termbox.ColorRed
self.tags[`white`] = termbox.ColorWhite markup.tags[`green`] = termbox.ColorGreen
self.tags[`right`] = termbox.ColorDefault // Termbox can combine attributes and a single color using bitwise OR. markup.tags[`yellow`] = termbox.ColorYellow
self.tags[`b`] = termbox.AttrBold // Attribute = 1 << (iota + 4) markup.tags[`blue`] = termbox.ColorBlue
self.tags[`u`] = termbox.AttrUnderline markup.tags[`magenta`] = termbox.ColorMagenta
self.tags[`r`] = termbox.AttrReverse markup.tags[`cyan`] = termbox.ColorCyan
self.Foreground = termbox.ColorDefault markup.tags[`white`] = termbox.ColorWhite
self.Background = termbox.ColorDefault markup.tags[`right`] = termbox.ColorDefault // Termbox can combine attributes and a single color using bitwise OR.
self.RightAligned = false markup.tags[`b`] = termbox.AttrBold // Attribute = 1 << (iota + 4)
markup.tags[`u`] = termbox.AttrUnderline
return self markup.tags[`r`] = termbox.AttrReverse
markup.regex = markup.supportedTags() // Once we have the hash we could build the regex.
return markup
} }
//----------------------------------------------------------------------------- // Tokenize works just like strings.Split() except the resulting array includes
func (self *Markup) Tokenize(str string) []string { // the delimiters. For example, the "<green>Hello, <red>world!</>" string when
matches := self.supported_tags().FindAllStringIndex(str, -1) // tokenized by tags produces the following:
//
// [0] "<green>"
// [1] "Hello, "
// [2] "<red>"
// [3] "world!"
// [4] "</>"
//
func (markup *Markup) Tokenize(str string) []string {
matches := markup.regex.FindAllStringIndex(str, -1)
strings := make([]string, 0, len(matches)) strings := make([]string, 0, len(matches))
head, tail := 0, 0 head, tail := 0, 0
@ -50,9 +76,11 @@ func (self *Markup) Tokenize(str string) []string {
tail = match[0] tail = match[0]
if match[1] != 0 { if match[1] != 0 {
if head != 0 || tail != 0 { if head != 0 || tail != 0 {
strings = append(strings, str[head:tail]) // Apend text between tags. // Apend the text between tags.
strings = append(strings, str[head:tail])
} }
strings = append(strings, str[match[0]:match[1]]) // Append tag. // Append the tag itmarkup.
strings = append(strings, str[match[0]:match[1]])
} }
head = match[1] head = match[1]
} }
@ -64,35 +92,37 @@ func (self *Markup) Tokenize(str string) []string {
return strings return strings
} }
//----------------------------------------------------------------------------- // IsTag returns true when the given string looks like markup tag. When the
func (self *Markup) IsTag(str string) bool { // tag name matches one of the markup-supported tags it gets translated to
tag, open := probe_tag(str) // relevant Termbox attributes and colors.
func (markup *Markup) IsTag(str string) bool {
tag, open := probeForTag(str)
if tag == `` { if tag == `` {
return false return false
} }
return self.process(tag, open) return markup.process(tag, open)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func (self *Markup) process(tag string, open bool) bool { func (markup *Markup) process(tag string, open bool) bool {
if attribute, ok := self.tags[tag]; ok { if attribute, ok := markup.tags[tag]; ok {
switch tag { switch tag {
case `right`: case `right`:
self.RightAligned = open markup.RightAligned = open // On for <right>, off for </right>.
default: default:
if open { if open {
if attribute >= termbox.AttrBold { if attribute >= termbox.AttrBold {
self.Foreground |= attribute markup.Foreground |= attribute // Set the Termbox attribute.
} else { } else {
self.Foreground = attribute markup.Foreground = attribute // Set the Termbox color.
} }
} else { } else {
if attribute >= termbox.AttrBold { if attribute >= termbox.AttrBold {
self.Foreground &= ^attribute markup.Foreground &= ^attribute // Clear the Termbox attribute.
} else { } else {
self.Foreground = termbox.ColorDefault markup.Foreground = termbox.ColorDefault
} }
} }
} }
@ -101,14 +131,12 @@ func (self *Markup) process(tag string, open bool) bool {
return true return true
} }
// // supportedTags returns regular expression that matches all possible tags
// Return regular expression that matches all possible tags, i.e. // supported by the markup, i.e. </?black>|</?red>| ... |<?b>| ... |</?right>
// </?black>|</?red>| ... |</?white> func (markup *Markup) supportedTags() *regexp.Regexp {
//-----------------------------------------------------------------------------
func (self *Markup) supported_tags() *regexp.Regexp {
arr := []string{} arr := []string{}
for tag, _ := range self.tags { for tag := range markup.tags {
arr = append(arr, `</?` + tag + `>`) arr = append(arr, `</?` + tag + `>`)
} }
@ -116,18 +144,16 @@ func (self *Markup) supported_tags() *regexp.Regexp {
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func probe_tag(str string) (string, bool) { func probeForTag(str string) (string, bool) {
if len(str) > 2 && str[0:1] == `<` && str[len(str)-1:] == `>` { if len(str) > 2 && str[0:1] == `<` && str[len(str)-1:] == `>` {
return extract_tag_name(str), str[1:2] != `/` return extractTagName(str), str[1:2] != `/`
} }
return ``, false return ``, false
} }
// // Extract tag name from the given tag, i.e. `<hello>` => `hello`.
// Extract tag name from the given tag, i.e. `<hello>` => `hello` func extractTagName(str string) string {
//-----------------------------------------------------------------------------
func extract_tag_name(str string) string {
if len(str) < 3 { if len(str) < 3 {
return `` return ``
} else if str[1:2] != `/` { } else if str[1:2] != `/` {

Loading…
Cancel
Save