Przeglądaj źródła

Print descriptions of news

Print the full descriptions of each news item.

The description is formatted as html, basic parsing is done to display
it properly. -q/--quiet can be used to diplay title only.
morganamilo 7 lat temu
rodzic
commit
a10241f7ab
2 zmienionych plików z 103 dodań i 1 usunięć
  1. 96 0
      parser.go
  2. 7 1
      print.go

+ 96 - 0
parser.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"bytes"
 	"fmt"
 	"io"
 	"os"
@@ -8,6 +9,15 @@ import (
 	"strings"
 )
 
+var htmlEscapeSequences = map[string]rune{
+	"quot": '"',
+	"apos": '\'',
+	"amp":  '&',
+	"lt":   '<',
+	"gt":   '>',
+	"nbsp": '\u008a',
+}
+
 // A basic set implementation for strings.
 // This is used a lot so it deserves its own type.
 // Other types of sets are used throughout the code but do not have
@@ -673,3 +683,89 @@ func parseNumberMenu(input string) (intRanges, intRanges, stringSet, stringSet)
 
 	return include, exclude, otherInclude, otherExclude
 }
+
+func unescapeHtmlChar(str string) rune {
+	var first string
+	var rest string
+	for i := range str {
+		first = str[0:i]
+		rest = str[i:]
+	}
+
+	if first == "#" {
+		num, err := strconv.Atoi(rest)
+		if err != nil {
+			return '?'
+		}
+
+		return rune(num)
+	}
+
+	char, ok := htmlEscapeSequences[str]
+	if !ok {
+		return '?'
+	}
+
+	return char
+}
+
+// Crude html parsing, good enough for the arch news
+// This is only displayed in the terminal so there should be no security
+// concerns
+func parseNews(str string) string {
+	var buffer bytes.Buffer
+	var tagBuffer bytes.Buffer
+	var escapeBuffer bytes.Buffer
+	inTag := false
+	inEscape := false
+
+	for _, char := range str {
+		if inTag {
+			if char == '>' {
+				inTag = false
+				switch tagBuffer.String() {
+				case "code":
+					buffer.WriteString(cyanCode)
+				case "/code":
+					buffer.WriteString(resetCode)
+				case "/p":
+					buffer.WriteRune('\n')
+				}
+
+				continue
+			}
+
+			tagBuffer.WriteRune(char)
+			continue
+		}
+
+		if inEscape {
+			if char == ';' {
+				inEscape = false
+				char := unescapeHtmlChar(escapeBuffer.String())
+				buffer.WriteRune(char)
+				continue
+			}
+
+			escapeBuffer.WriteRune(char)
+			continue
+		}
+
+		if char == '<' {
+			inTag = true
+			tagBuffer.Reset()
+			continue
+		}
+
+		if char == '&' {
+			inEscape = true
+			escapeBuffer.Reset()
+			continue
+		}
+
+		buffer.WriteRune(char)
+	}
+
+	buffer.WriteString(resetCode)
+	return buffer.String()
+}

+ 7 - 1
print.go

@@ -419,7 +419,13 @@ func (item Item) Print() error {
 
 	fd := formatTime(int(date.Unix()))
 
-	fmt.Println(magenta(fd), strings.TrimSpace(item.Title))
+	fmt.Println(bold(magenta(fd)), bold(strings.TrimSpace(item.Title)))
+	//fmt.Println(strings.TrimSpace(item.Link))
+
+	if !cmdArgs.existsArg("q", "quiet") {
+		desc := strings.TrimSpace(parseNews(item.Description))
+		fmt.Println(desc)
+	}
 
 	return nil
 }