You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

121 lines
2.9 KiB

package ui
import (
"io"
"fmt"
"strings"
"golang.org/x/net/html"
)
type mockerBuilder struct {
strings.Builder
}
func (m* mockerBuilder) Write(p []byte) (n int, err error) {
m.append ( string(p) )
return 0,nil
}
func (m* mockerBuilder) append ( args... string) {
for _, str := range args {
m.WriteString ( str );
}
}
type htmlConfig struct {
invis bool
spanDepth int
}
func htmlAttr ( z *html.Tokenizer, attr string ) string {
var more bool = true
var key, val []byte
var stringkey string
for more {
key, val, more = z.TagAttr ()
stringkey = string( key )
if stringkey == attr {
fmt.Println ( " >> attr: ", attr, " == ", string(val) );
return string(val)
}
}
return "";
}
func spanToPango ( z *html.Tokenizer, tt html.TokenType, buf *mockerBuilder, cfg *htmlConfig ) {
if tt == html.StartTagToken {
class := htmlAttr ( z, "class" )
if class == "invisible" {
cfg.invis = true;
}
if cfg.invis == true {
cfg.spanDepth++;
}
} else {
cfg.spanDepth--;
if cfg.spanDepth == 0 {
cfg.invis = false;
}
}
}
func brToPango ( z *html.Tokenizer, tt html.TokenType, buf *mockerBuilder, cfg *htmlConfig ) {
if tt == html.StartTagToken {
buf.append ( "\n\n" );
}
}
func pToPango ( z *html.Tokenizer, tt html.TokenType, buf *mockerBuilder, cfg *htmlConfig ) {
// pass
}
func aToPango ( z *html.Tokenizer, tt html.TokenType, buf *mockerBuilder, cfg *htmlConfig ) {
if tt == html.StartTagToken {
href := htmlAttr ( z, "href" )
buf.append ( "<a href=\"", href, "\">" );
} else {
buf.append ( "</a>" )
}
}
func htmlToPango ( content string ) (string, error) {
fmt.Println ("IN: ", content );
r := strings.NewReader ( content )
var buf mockerBuilder;
var cfg htmlConfig
cfg.invis = false
cfg.spanDepth = 0
z := html.NewTokenizer ( r );
for {
tt := z.Next()
switch tt {
case html.ErrorToken :
if z.Err() == io.EOF {
var str string = buf.String()
fmt.Println ("out: ", str );
return str, nil
}
return buf.String(), z.Err()
case html.TextToken :
if cfg.invis == false {
buf.append ( html.EscapeString(string(z.Text())) )
}
case html.StartTagToken, html.EndTagToken:
nm, _ := z.TagName()
name := string(nm)
if name == "p" {
pToPango ( z, tt, &buf, &cfg );
} else if name == "br" {
brToPango ( z, tt, &buf, &cfg );
} else if name == "span" {
spanToPango ( z, tt, &buf, &cfg );
} else if name == "a" {
aToPango ( z, tt, &buf, &cfg );
}
}
}
return "", nil;
}