feat: add `--no-color` and enable color in the text merit profile

master
Dominique Merle 2 years ago
parent e895131afc
commit a8d93febba

@ -234,8 +234,8 @@ The --width parameter only applies to the default format (text).
os.Exit(errorBalancing)
}
deliberator := &judgment.MajorityJudgment{}
result, deliberationErr := deliberator.Deliberate(poll)
mj := &judgment.MajorityJudgment{}
result, deliberationErr := mj.Deliberate(poll)
if deliberationErr != nil {
fmt.Println("Deliberation Error:", deliberationErr)
os.Exit(errorDeliberating)
@ -246,9 +246,10 @@ The --width parameter only applies to the default format (text).
desiredWidth = 79
}
options := &formatter.Options{
Sorted: cmd.Flags().Lookup("sort").Changed,
Width: desiredWidth,
Scale: precisionScale,
Colorized: !cmd.Flags().Lookup("no-color").Changed,
Scale: precisionScale,
Sorted: cmd.Flags().Lookup("sort").Changed,
Width: desiredWidth,
}
out, formatterErr := outputFormatter.Format(
@ -290,6 +291,7 @@ func init() {
//rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration")
rootCmd.Flags().BoolP("sort", "s", false, "sort proposals by their rank")
rootCmd.Flags().BoolP("normalize", "n", false, "normalize input to balance proposal participation")
rootCmd.Flags().Bool("no-color", false, "do not use colors in the text outputs")
rootCmd.SetVersionTemplate("{{.Version}}\n" + version.BuildDate + "\n")
}

@ -5,9 +5,10 @@ import "github.com/mieuxvoter/majority-judgment-library-go/judgment"
// Options are shared between all formatters.
// Some formatters may ignore some options.
type Options struct {
Sorted bool
Width int
Scale float64 // so we can use integers internally, and display floats
Colorized bool
Scale float64 // so we can use integers internally, and display floats
Sorted bool
Width int
}
const defaultWidth = 79

@ -2,8 +2,10 @@ package formatter
import (
"fmt"
"github.com/acarl005/stripansi"
"github.com/mieuxvoter/majority-judgment-library-go/judgment"
"math"
"github.com/muesli/termenv"
"strconv"
"strings"
)
@ -31,6 +33,10 @@ func (t *TextFormatter) Format(
expectedWidth = defaultWidth
}
colorized := options.Colorized
palette := judgment.CreateDefaultPalette(len(grades))
colorProfile := termenv.ColorProfile()
proposalsResults := result.Proposals
if options.Sorted {
proposalsResults = result.ProposalsSorted
@ -80,6 +86,7 @@ func (t *TextFormatter) Format(
line += makeAsciiMeritProfile(
pollTally.Proposals[proposalResult.Index],
chartWidth,
colorized,
)
out += line + "\n"
@ -91,11 +98,19 @@ func (t *TextFormatter) Format(
if maximumDefinitionLength < minimumDefinitionLength {
maximumDefinitionLength = minimumDefinitionLength
}
gradeChar := getCharForIndex(gradeIndex)
if colorized {
color := colorProfile.FromColor(palette[gradeIndex])
s := termenv.String(gradeChar)
s = s.Background(color)
s = s.Foreground(color)
gradeChar = s.String()
}
legendDefinitions = append(
legendDefinitions,
fmt.Sprintf(
"%s=%s",
getCharForIndex(gradeIndex),
gradeChar,
truncateString(gradeName, maximumDefinitionLength, '…'),
),
)
@ -127,7 +142,12 @@ func countDigits(i int) (count int) {
// makeTextLegend makes a legend for an ASCII chart
// `title` should be shorter than `indentation` characters
func makeTextLegend(title string, definitions []string, indentation int, maxWidth int) (legend string) {
func makeTextLegend(
title string,
definitions []string,
indentation int,
maxWidth int,
) (legend string) {
line := ""
leftOnLine := maxWidth
for i, def := range definitions {
@ -135,7 +155,7 @@ func makeTextLegend(title string, definitions []string, indentation int, maxWidt
line += fmt.Sprintf("%*s", indentation-1, title)
leftOnLine -= indentation - 1
}
needed := measureStringLength(def) + 1
needed := measureStringLength(stripansi.Strip(def)) + 1
if needed > leftOnLine && i > 0 {
legend += line + "\n"
line = ""
@ -154,31 +174,58 @@ func makeTextLegend(title string, definitions []string, indentation int, maxWidt
func makeAsciiMeritProfile(
tally *judgment.ProposalTally,
width int,
colorized bool,
) (ascii string) {
if width < 3 {
width = 3
}
amountOfJudges := float64(tally.CountJudgments())
for gradeIndex, gradeTallyInt := range tally.Tally {
gradeTally := float64(gradeTallyInt)
palette := judgment.CreateDefaultPalette(int(tally.CountAvailableGrades()))
colorProfile := termenv.ColorProfile()
for cursor := 0; cursor < width; cursor++ {
ratio := float64(cursor) / float64(width)
gradeIndex, _ := getGradeAtRatio(tally, ratio)
gradeChar := getCharForIndex(gradeIndex)
ascii += strings.Repeat(
gradeChar,
int(math.Round(float64(width)*gradeTally/amountOfJudges)),
)
}
isMedian := (width)/2 == cursor
if isMedian {
gradeChar = "|"
}
for len(ascii) < width {
ascii += ascii[len(ascii)-1:]
if colorized {
color := colorProfile.FromColor(palette[gradeIndex])
s := termenv.String(gradeChar)
s = s.Background(color)
if !isMedian {
s = s.Foreground(color)
}
gradeChar = s.String()
}
ascii += gradeChar
}
for len(ascii) > width {
ascii = ascii[0 : len(ascii)-1]
}
return
}
func getGradeAtRatio(
tally *judgment.ProposalTally,
ratio float64,
) (int, error) {
targetIndex := int(ratio * float64(tally.CountJudgments()))
cursorStart := 0
cursor := 0
for gradeIndex, gradeTallyInt := range tally.Tally {
if 0 == gradeTallyInt {
continue
}
cursorStart = cursor
cursor = cursor + int(gradeTallyInt)
ascii = replaceAtIndex(ascii, '|', width/2)
if cursorStart <= targetIndex && targetIndex < cursor {
return gradeIndex, nil
}
}
return
return 0, fmt.Errorf("")
}
func getCharForIndex(gradeIndex int) string {

@ -3,8 +3,10 @@ module github.com/MieuxVoter/majority-judgment-cli
go 1.17
require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/csimplestring/go-csv v0.0.0-20180328183906-5b8b3cd94f2c
github.com/mieuxvoter/majority-judgment-library-go v0.3.1
github.com/muesli/termenv v0.9.0
github.com/spf13/cobra v1.2.1
github.com/spf13/viper v1.9.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
@ -16,8 +18,11 @@ require (
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect

Loading…
Cancel
Save