diff --git a/chars.go b/chars.go
index 02f0041..476727f 100644
--- a/chars.go
+++ b/chars.go
@@ -3,7 +3,7 @@ package main
import emoji "github.com/tmdvs/Go-Emoji-Utils"
var charWidths = map[string]float64{
- " ": 4.9,
+ " ": 6,
"0": 14.333328247070312,
"1": 10.583328247070312,
"2": 13.433334350585938,
@@ -74,8 +74,8 @@ var charWidths = map[string]float64{
"%": 18.416671752929688,
"^": 9.683334350585938,
"*": 9.683334350585938,
- "(": 7.883331298828125,
- ")": 7.883331298828125,
+ "(": 7,
+ ")": 7,
"-": 10.300003051757812,
"_": 9.73333740234375,
"=": 14.333328247070312,
@@ -89,10 +89,11 @@ var charWidths = map[string]float64{
"'": 5.26666259765625,
"\"": 9.5,
",": 6.26666259765625,
- ".": 6.26666259765625,
+ ".": 5,
"/": 7.76666259765625,
"?": 11.649993896484375,
"`": 11.833328247070312,
+ "”": 9,
}
func getCharWidth(char string) float64 {
diff --git a/go.mod b/go.mod
index a876fac..41cf4f3 100644
--- a/go.mod
+++ b/go.mod
@@ -11,6 +11,7 @@ require (
github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 // indirect
github.com/grokify/html-strip-tags-go v0.0.1
github.com/joho/godotenv v1.3.0
+ github.com/rivo/uniseg v0.2.0
github.com/tmdvs/Go-Emoji-Utils v1.1.0
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
)
diff --git a/go.sum b/go.sum
index 3617f5d..59ca837 100644
--- a/go.sum
+++ b/go.sum
@@ -14,6 +14,8 @@ github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/tmdvs/Go-Emoji-Utils v1.1.0 h1:gtPix7HZPrd49+MNDcuRLvv4xVNxCE5wgjqyuvmbyYg=
github.com/tmdvs/Go-Emoji-Utils v1.1.0/go.mod h1:J82i2WeGn+Kz+T3s5v9+i/OJlvevIVfGZ6qXgqiNWBc=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
diff --git a/main.go b/main.go
index ff8ea68..933a0ef 100644
--- a/main.go
+++ b/main.go
@@ -7,6 +7,7 @@ import (
"fmt"
"html/template"
"log"
+ "math"
"net/http"
"os"
"regexp"
@@ -17,6 +18,8 @@ import (
"github.com/ChimeraCoder/anaconda"
strip "github.com/grokify/html-strip-tags-go"
"github.com/joho/godotenv"
+ "github.com/rivo/uniseg"
+ emoji "github.com/tmdvs/Go-Emoji-Utils"
)
//go:embed index.html tweet.svg.tmpl suspendedTweet.svg
@@ -86,18 +89,21 @@ func getTweet(w http.ResponseWriter, r *http.Request) {
return
}
}
+ fmt.Println(err)
w.WriteHeader(404)
return
}
- re := regexp.MustCompile(`[\x{1F300}-\x{1F6FF}]`)
- emojis := re.FindAllString(tweet.FullText, -1)
-
- emojiCount := 0
- for _, emoji := range emojis {
- emojiCount += len([]byte(emoji)) - 1
+ gr := uniseg.NewGraphemes(tweet.FullText)
+ count := 0
+ displayText := ""
+ for gr.Next() {
+ if count >= tweet.DisplayTextRange[0] && count < tweet.DisplayTextRange[1] {
+ displayText += gr.Str()
+ }
+ count += 1
}
- tweet.FullText = tweet.FullText[tweet.DisplayTextRange[0] : tweet.DisplayTextRange[1]+emojiCount]
+ tweet.FullText = displayText
for _, user := range tweet.Entities.User_mentions {
tweet.FullText = strings.ReplaceAll(tweet.FullText, "@"+user.Screen_name, fmt.Sprintf("@%s", user.Screen_name, user.Screen_name))
@@ -133,15 +139,21 @@ func getTweet(w http.ResponseWriter, r *http.Request) {
return template.HTML(in)
},
"calculateHeight": func(tweet anaconda.Tweet) string {
- height := 64.0 /* Avatar */ + 20 /* footer */ + 46 /* test margin */ + 32 /* margin */
+ height := 64.0 /* Avatar */ + 20 /* footer */ + 46 /* text margin */ + 22 /* margin */
lineWidth := 0.0
- tweetText := strings.ReplaceAll(tweet.FullText, "
", " \n ")
+ lineHeight := 28.0
+ tweetText := strings.ReplaceAll(tweet.FullText, "
", " \n")
tweetText = strip.StripTags(tweetText)
- words := strings.Split(tweetText, " ")
+ words := regexp.MustCompile(`[ |-]`).Split(tweetText, -1)
for _, word := range words {
+ if len(emoji.FindAll(word)) > 0 {
+ lineHeight = 32.0
+ }
+
if strings.Contains(word, "\n") {
- height += 28
+ height += lineHeight
+ lineHeight = 28.0
lineWidth = 0
continue
}
@@ -152,38 +164,53 @@ func getTweet(w http.ResponseWriter, r *http.Request) {
wordWidth += getCharWidth(char)
}
- if lineWidth+wordWidth > 443 {
- height += 28
+ if wordWidth > 435 {
+ height += (lineHeight * (math.Ceil(wordWidth/435) + 1))
+ lineHeight = 28.0
+ lineWidth = 0
+ } else if lineWidth+getCharWidth(" ")+wordWidth > 435 {
+ height += lineHeight
+ lineHeight = 28.0
lineWidth = wordWidth
} else {
lineWidth += wordWidth
}
}
if lineWidth > 0 {
- height += 28
+ height += lineHeight
}
if tweet.InReplyToScreenName != "" {
- height += 34
+ height += 42
}
- height += float64(strings.Count(tweet.FullText, "
") * 28)
-
- if len(tweet.ExtendedEntities.Media) >= 1 {
- ratio := float64(tweet.ExtendedEntities.Media[0].Sizes.Small.W) / 464
- if len(tweet.ExtendedEntities.Media) == 2 {
- height += ((float64(tweet.ExtendedEntities.Media[0].Sizes.Small.H) / ratio) + 5) / 2
- } else {
- height += (float64(tweet.ExtendedEntities.Media[0].Sizes.Small.H) / ratio) + 5
- }
+ for i, img := range tweet.ExtendedEntities.Media {
+ ratio := float64(img.Sizes.Small.W) / 468
+ tweet.ExtendedEntities.Media[i].Sizes.Small.W = 468
+ tweet.ExtendedEntities.Media[i].Sizes.Small.H = int((float64(img.Sizes.Small.H) / ratio) + 5.0)
}
if len(tweet.ExtendedEntities.Media) > 1 {
- for i := range tweet.ExtendedEntities.Media {
- tweet.ExtendedEntities.Media[i].Sizes.Small.W = 225
+ for i, img := range tweet.ExtendedEntities.Media {
+ tweet.ExtendedEntities.Media[i].Sizes.Small.W = (img.Sizes.Small.W / 2) - 20
+ tweet.ExtendedEntities.Media[i].Sizes.Small.H = (img.Sizes.Small.H / 2) - 20
}
}
+ switch len(tweet.ExtendedEntities.Media) {
+ case 1:
+ height += float64(tweet.ExtendedEntities.Media[0].Sizes.Small.H)
+ case 2:
+ height += math.Max(float64(tweet.ExtendedEntities.Media[0].Sizes.Small.H), float64(tweet.ExtendedEntities.Media[1].Sizes.Small.H)) + 5
+ case 3:
+ height += math.Max(float64(tweet.ExtendedEntities.Media[0].Sizes.Small.H), float64(tweet.ExtendedEntities.Media[1].Sizes.Small.H)) + 5
+ height += float64(tweet.ExtendedEntities.Media[2].Sizes.Small.H) + 35
+ case 4:
+ height += math.Max(float64(tweet.ExtendedEntities.Media[0].Sizes.Small.H), float64(tweet.ExtendedEntities.Media[1].Sizes.Small.H)) + 10
+ height += math.Max(float64(tweet.ExtendedEntities.Media[2].Sizes.Small.H), float64(tweet.ExtendedEntities.Media[3].Sizes.Small.H)) + 10
+ height += 7
+ }
+
return fmt.Sprintf("%dpx", int64(height))
},
}