github.com/haraldrudell/parl@v0.4.176/pstrings/fit.go (about)

     1  /*
     2  © 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package pstrings
     7  
     8  import (
     9  	"strings"
    10  )
    11  
    12  var epsilonRune = []rune("…")[0]
    13  
    14  // Fit return a string fitted to certain column width
    15  //   - if width < 1, no change
    16  //   - if s’ length equals width, no change
    17  //   - if s’ length less than width, pad with spaces if pad true, otherwise no change
    18  //   - otherwise cut s in the center and replace with single epsilon "…" character
    19  func Fit(s string, width int, pad bool) (s2 string) {
    20  	length := len([]rune(s)) // length in unicode code points
    21  
    22  	// width < 1 or equal length or less but no pad: nothing to do
    23  	if width < 1 || length == width || length < width && !pad {
    24  		s2 = s
    25  		return // no change return
    26  	}
    27  
    28  	if length < width {
    29  		s2 = s + strings.Repeat("\x20", width-length)
    30  		return
    31  	}
    32  
    33  	// length > width:
    34  	// "abcdef" width:4: center:3, cut:3 right:2, left:1: "ab…ef"
    35  	center := length / 2      // center of string, rounded down
    36  	cut := length - width + 1 // number of characters to delete, add 1 for "…"
    37  	right := cut/2 + 1        // characters to delete after center
    38  	left := cut - right       // characters to delete before center
    39  	runes := []rune(s)
    40  	runes[center-left] = epsilonRune
    41  	copy(runes[center-left+1:], runes[center+right:])
    42  	runes = runes[:width]
    43  	s2 = string(runes)
    44  	return
    45  }