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.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
package mop
@ -10,39 +10,65 @@ import (
`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 {
tags map[string]termbox.Attribute
Foreground termbox.Attribute
Background termbox.Attribute
RightAligned bool
Foreground termbox.Attribute // Foreground color.
Background termbox.Attribute // Background color (so far always termbox.ColorDefault).
RightAligned bool // True when the string is right aligned.
tags map[string]termbox.Attribute // Tags to Termbox translation hash.
regex *regexp.Regexp // Regex to identify the supported tag names.
}
//-----------------------------------------------------------------------------
func (self *Markup) Initialize() *Markup {
self.tags = make(map[string]termbox.Attribute)
self.tags[`/`] = termbox.ColorDefault
self.tags[`black`] = termbox.ColorBlack
self.tags[`red`] = termbox.ColorRed
self.tags[`green`] = termbox.ColorGreen
self.tags[`yellow`] = termbox.ColorYellow
self.tags[`blue`] = termbox.ColorBlue
self.tags[`magenta`] = termbox.ColorMagenta
self.tags[`cyan`] = termbox.ColorCyan
self.tags[`white`] = termbox.ColorWhite
self.tags[`right`] = termbox.ColorDefault // Termbox can combine attributes and a single color using bitwise OR.
self.tags[`b`] = termbox.AttrBold // Attribute = 1 << (iota + 4)
self.tags[`u`] = termbox.AttrUnderline
self.tags[`r`] = termbox.AttrReverse
self.Foreground = termbox.ColorDefault
self.Background = termbox.ColorDefault
self.RightAligned = false
return self
// Initialize creates tags to Termbox translation hash and sets default
// colors and string alignment.
func (markup *Markup) Initialize() *Markup {
markup.Foreground = termbox.ColorDefault
markup.Background = termbox.ColorDefault
markup.RightAligned = false
markup.tags = make(map[string]termbox.Attribute)
markup.tags[`/`] = termbox.ColorDefault
markup.tags[`black`] = termbox.ColorBlack
markup.tags[`red`] = termbox.ColorRed
markup.tags[`green`] = termbox.ColorGreen
markup.tags[`yellow`] = termbox.ColorYellow
markup.tags[`blue`] = termbox.ColorBlue
markup.tags[`magenta`] = termbox.ColorMagenta
markup.tags[`cyan`] = termbox.ColorCyan
markup.tags[`white`] = termbox.ColorWhite
markup.tags[`right`] = termbox.ColorDefault // Termbox can combine attributes and a single color using bitwise OR.
markup.tags[`b`] = termbox.AttrBold // Attribute = 1 << (iota + 4)
markup.tags[`u`] = termbox.AttrUnderline
markup.tags[`r`] = termbox.AttrReverse
markup.regex = markup.supportedTags() // Once we have the hash we could build the regex.
return markup
}
//-----------------------------------------------------------------------------
func (self *Markup) Tokenize(str string) []string {
matches := self.supported_tags().FindAllStringIndex(str, -1)
// Tokenize works just like strings.Split() except the resulting array includes
// the delimiters. For example, the "<green>Hello, <red>world!</>" string when
// 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))
head, tail := 0, 0
@ -50,9 +76,11 @@ func (self *Markup) Tokenize(str string) []string {
tail = match[0]
if match[1] != 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]
}
@ -64,35 +92,37 @@ func (self *Markup) Tokenize(str string) []string {
return strings
}
//-----------------------------------------------------------------------------
func (self *Markup) IsTag(str string) bool {
tag, open := probe_tag(str)
// IsTag returns true when the given string looks like markup tag. When the
// tag name matches one of the markup-supported tags it gets translated to
// relevant Termbox attributes and colors.
func (markup *Markup) IsTag(str string) bool {
tag, open := probeForTag(str)
if tag == `` {
return false
}
return self.process(tag, open)
return markup.process(tag, open)
}
//-----------------------------------------------------------------------------
func (self *Markup) process(tag string, open bool) bool {
if attribute, ok := self.tags[tag]; ok {
func (markup *Markup) process(tag string, open bool) bool {
if attribute, ok := markup.tags[tag]; ok {
switch tag {
case `right`:
self.RightAligned = open
markup.RightAligned = open // On for <right>, off for </right>.
default:
if open {
if attribute >= termbox.AttrBold {
self.Foreground |= attribute
markup.Foreground |= attribute // Set the Termbox attribute.
} else {
self.Foreground = attribute
markup.Foreground = attribute // Set the Termbox color.
}
} else {
if attribute >= termbox.AttrBold {
self.Foreground &= ^attribute
markup.Foreground &= ^attribute // Clear the Termbox attribute.
} 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 regular expression that matches all possible tags, i.e.
// </?black>|</?red>| ... |</?white>
//-----------------------------------------------------------------------------
func (self *Markup) supported_tags() *regexp.Regexp {
// supportedTags returns regular expression that matches all possible tags
// supported by the markup, i.e. </?black>|</?red>| ... |<?b>| ... |</?right>
func (markup *Markup) supportedTags() *regexp.Regexp {
arr := []string{}
for tag, _ := range self.tags {
for tag := range markup.tags {
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:] == `>` {
return extract_tag_name(str), str[1:2] != `/`
return extractTagName(str), str[1:2] != `/`
}
return ``, false
}
//
// Extract tag name from the given tag, i.e. `<hello>` => `hello`
//-----------------------------------------------------------------------------
func extract_tag_name(str string) string {
// Extract tag name from the given tag, i.e. `<hello>` => `hello`.
func extractTagName(str string) string {
if len(str) < 3 {
return ``
} else if str[1:2] != `/` {

Loading…
Cancel
Save