shithub: hell

ref: 42ce929bb7bf1b60aaa42996954361c948505573
dir: /format.go/

View raw version
package main

import (
	"strings"

	"golang.org/x/term"
)

func hyphenate(input string) (string, bool) {
	width, _, err := term.GetSize(int(0))
	if err != nil {
		//Use generic width
		//Maybe make this a config later
		width = 80
	}
	return hyphenateWithWidth(input, width)
}

func hyphenateWithWidth(input string, width int) (string, bool) {
	var remainder = []rune(input)
	var result []rune

	if width < 2 {
		return input, false
	}

	longline := false

	for len(remainder) > width {
		if strings.HasPrefix(string(remainder), "\n") {
			result = append(result, '\n')
			longline = true
			remainder = remainder[1:]
			continue
		}

		index := strings.Index(string(remainder), "\n")
		// If a newline is found at or before the wrap position, break there.
		if index != -1 && index <= width-1 {
			result = append(result, remainder[:index]...)
			remainder = remainder[index:]
			continue
		}

		var breakPos = -1
		for i := width - 1; i >= 0; i-- {
			if remainder[i] == ' ' {
				breakPos = i
				break
			}
		}

		if breakPos > 0 {
			result = append(result, remainder[:breakPos]...)
			result = append(result, '\n')
			longline = true
			remainder = remainder[breakPos+1:]
			continue
		}

		if remainder[width-1] == ' ' {
			result = append(result, remainder[:width-1]...)
			result = append(result, '\n')
			longline = true
			remainder = remainder[width:] // Consume the space
		} else if remainder[width-1] == '-' {
			result = append(result, remainder[:width]...)
			result = append(result, '\n')
			longline = true
			remainder = remainder[width:] // Consume the hyphen
		} else if remainder[width-1] != ' ' {
			result = append(result, remainder[:width-1]...)
			result = append(result, '-')
			remainder = remainder[width-1:]
		}
	}

	result = append(result, remainder...)
	//Sometimes posts come from mastodon with a newline/space at the end
	//you can actually see it in the web interface
	if strings.HasSuffix(string(result), " ") {
		result = result[:len(result)-1]
	}
	if strings.HasSuffix(string(result), "\n") {
		result = result[:len(result)-1]
	}
	//Put an extra newline at the end if status takes multiple lines
	return string(result), longline
}

func countEmoji(runes []rune) int {
	count := 0
	for _, r := range runes {
		if isEmoji(r) {
			count++
		}
	}
	return count
}

func isEmoji(r rune) bool {
	return r >= 0x1F600 && r <= 0x1F64F // Emoticons
}