From 8662faa0973b19c486f94af9cd83ce2fef86c300 Mon Sep 17 00:00:00 2001 From: Kenneth Shaw Date: Sat, 6 Apr 2024 06:03:12 +0700 Subject: [PATCH] Updating dependencies and adding shell completion support --- go.mod | 14 ++-- go.sum | 28 ++++---- main.go | 193 +++++++++++++++++++++++++++++++++----------------------- 3 files changed, 136 insertions(+), 99 deletions(-) diff --git a/go.mod b/go.mod index 61eb2c8..6af63d2 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,9 @@ require ( github.com/kenshaw/rasterm v0.1.10 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - github.com/tdewolff/canvas v0.0.0-20240313223806-c16dea836d4e - github.com/tdewolff/font v0.0.0-20240307164724-5999bab46d7d - golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 + github.com/tdewolff/canvas v0.0.0-20240404204646-eb921826d23b + github.com/tdewolff/font v0.0.0-20240404204409-be214eafe484 + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 ) require ( @@ -20,7 +20,7 @@ require ( github.com/benoitkugler/textlayout v0.3.0 // indirect github.com/benoitkugler/textprocessing v0.0.3 // indirect github.com/go-fonts/latin-modern v0.3.2 // indirect - github.com/go-text/typesetting v0.1.0 // indirect + github.com/go-text/typesetting v0.1.1 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kenshaw/snaker v0.2.0 // indirect @@ -29,9 +29,9 @@ require ( github.com/tdewolff/minify/v2 v2.20.19 // indirect github.com/tdewolff/parse/v2 v2.7.12 // indirect golang.org/x/image v0.15.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect star-tex.org/x/tex v0.4.0 // indirect ) diff --git a/go.sum b/go.sum index 62d0f07..a664ae1 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ github.com/go-latex/latex v0.0.0-20230307184459-12ec69307ad9 h1:NxXI5pTAtpEaU49b github.com/go-latex/latex v0.0.0-20230307184459-12ec69307ad9/go.mod h1:gWuR/CrFDDeVRFQwHPvsv9soJVB/iqymhuZQuJ3a9OM= github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= -github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKwVvHw= -github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI= +github.com/go-text/typesetting v0.1.1 h1:bGAesCuo85nXnEN5LmFMVGAGpGkCPtHrZLi//qD7EJo= +github.com/go-text/typesetting v0.1.1/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI= github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY= github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= @@ -48,10 +48,10 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/tdewolff/canvas v0.0.0-20240313223806-c16dea836d4e h1:I2Rk8cgejhQBt4R5H6msc2J+I5H3huMWTqyLvtg9sT0= -github.com/tdewolff/canvas v0.0.0-20240313223806-c16dea836d4e/go.mod h1:b4lDs85I0Ine/lQglBErYWtTEKUBw3zjMx3P6ZKPNXw= -github.com/tdewolff/font v0.0.0-20240307164724-5999bab46d7d h1:EiCcVUobr7kO6XJIhgPbWuaKLL3WZML73osBHJjOAMY= -github.com/tdewolff/font v0.0.0-20240307164724-5999bab46d7d/go.mod h1:S1ByajP+rzLFlhudtNTELNuhxoSZ19Coif+JE4kivAo= +github.com/tdewolff/canvas v0.0.0-20240404204646-eb921826d23b h1:8wPwQtX2ulzB611fk+tPxLACiqb9VoJ9vwn8occWHD0= +github.com/tdewolff/canvas v0.0.0-20240404204646-eb921826d23b/go.mod h1:dFEWjsGVQGviBNKYPqDbDhjfRg5QQjmEgoR6jo057bU= +github.com/tdewolff/font v0.0.0-20240404204409-be214eafe484 h1:pS1QrGQdj4Qrwc26uU8wDHlGq1oe/64mFjwWhCuGdvo= +github.com/tdewolff/font v0.0.0-20240404204409-be214eafe484/go.mod h1:S1ByajP+rzLFlhudtNTELNuhxoSZ19Coif+JE4kivAo= github.com/tdewolff/minify/v2 v2.20.19 h1:tX0SR0LUrIqGoLjXnkIzRSIbKJ7PaNnSENLD4CyH6Xo= github.com/tdewolff/minify/v2 v2.20.19/go.mod h1:ulkFoeAVWMLEyjuDz1ZIWOA31g5aWOawCFRp9R/MudM= github.com/tdewolff/parse/v2 v2.7.12 h1:tgavkHc2ZDEQVKy1oWxwIyh5bP4F5fEh/JmBwPP/3LQ= @@ -59,21 +59,21 @@ github.com/tdewolff/parse/v2 v2.7.12/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/image v0.0.0-20210504121937-7319ad40d33e/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= diff --git a/main.go b/main.go index 92d9743..4c47e5b 100644 --- a/main.go +++ b/main.go @@ -43,16 +43,25 @@ func main() { } } -func run(ctx context.Context, appName, appVersion string, cliargs []string) error { +func run(ctx context.Context, name, version string, cliargs []string) error { var all, list, match bool fg, bg := colors.FromColor(color.Black), colors.FromColor(color.White) var size, margin, dpi int style, variant := canvas.FontRegular, canvas.FontNormal var text string + var ( + bashCompletion bool + zshCompletion bool + fishCompletion bool + powershellCompletion bool + noDescriptions bool + ) c := &cobra.Command{ - Use: appName + " [flags] [font2, ..., fontN]", - Short: appName + ", a command-line font viewer using terminal graphics", - Version: appVersion, + Use: name + " [flags] [font2, ..., fontN]", + Short: name + ", a command-line font viewer using terminal graphics", + Version: version, + SilenceErrors: true, + SilenceUsage: false, Args: func(_ *cobra.Command, args []string) error { switch hasArgs := len(args) != 0; { case all && hasArgs: @@ -61,8 +70,6 @@ func run(ctx context.Context, appName, appVersion string, cliargs []string) erro return errors.New("--list does not take any args") case match && !hasArgs: return errors.New("--match requires one or more args") - case !all && !list && !match && !hasArgs: - return errors.New("requires one or more args") case all && list, all && match, match && list: @@ -71,6 +78,23 @@ func run(ctx context.Context, appName, appVersion string, cliargs []string) erro return nil }, RunE: func(cmd *cobra.Command, args []string) error { + // completions and short circuits + switch { + case bashCompletion: + return cmd.GenBashCompletionV2(os.Stdout, !noDescriptions) + case zshCompletion: + if noDescriptions { + return cmd.GenZshCompletionNoDesc(os.Stdout) + } + return cmd.GenZshCompletion(os.Stdout) + case fishCompletion: + return cmd.GenFishCompletion(os.Stdout, !noDescriptions) + case powershellCompletion: + if noDescriptions { + return cmd.GenPowerShellCompletion(os.Stdout) + } + return cmd.GenPowerShellCompletionWithDesc(os.Stdout) + } sysfonts, err := fontpkg.FindSystemFonts(fontpkg.DefaultFontDirs()) if err != nil { return err @@ -84,7 +108,7 @@ func run(ctx context.Context, appName, appVersion string, cliargs []string) erro case match: f = doMatch } - return f(os.Stdout, sysfonts, &Params{ + return f(os.Stdout, sysfonts, &Args{ FG: fg, BG: bg, Size: size, @@ -97,25 +121,38 @@ func run(ctx context.Context, appName, appVersion string, cliargs []string) erro }) }, } - c.Flags().BoolVar(&all, "all", false, "show all system fonts") - c.Flags().BoolVar(&list, "list", false, "list system fonts") - c.Flags().BoolVar(&match, "match", false, "match system fonts") - c.Flags().Var(fg.Pflag(), "fg", "foreground color") - c.Flags().Var(bg.Pflag(), "bg", "background color") - c.Flags().IntVar(&size, "size", 48, "font size") - c.Flags().IntVar(&margin, "margin", 5, "margin") - c.Flags().IntVar(&dpi, "dpi", 100, "dpi") - c.Flags().Var(NewStyle(&style), "style", "font style") - c.Flags().Var(NewVariant(&variant), "variant", "font variant") - c.Flags().StringVar(&text, "text", "", "display text") c.SetVersionTemplate("{{ .Name }} {{ .Version }}\n") c.InitDefaultHelpCmd() c.SetArgs(cliargs[1:]) - c.SilenceErrors, c.SilenceUsage = true, false + flags := c.Flags() + flags.BoolVar(&all, "all", false, "show all system fonts") + flags.BoolVar(&list, "list", false, "list system fonts") + flags.BoolVar(&match, "match", false, "match system fonts") + flags.Var(fg.Pflag(), "fg", "foreground color") + flags.Var(bg.Pflag(), "bg", "background color") + flags.IntVar(&size, "size", 48, "font size") + flags.IntVar(&margin, "margin", 5, "margin") + flags.IntVar(&dpi, "dpi", 100, "dpi") + flags.Var(NewStyle(&style), "style", "font style") + flags.Var(NewVariant(&variant), "variant", "font variant") + flags.StringVar(&text, "text", "", "display text") + // completions + flags.BoolVar(&bashCompletion, "completion-script-bash", false, "output bash completion script and exit") + flags.BoolVar(&zshCompletion, "completion-script-zsh", false, "output zsh completion script and exit") + flags.BoolVar(&fishCompletion, "completion-script-fish", false, "output fish completion script and exit") + flags.BoolVar(&powershellCompletion, "completion-script-powershell", false, "output powershell completion script and exit") + flags.BoolVar(&noDescriptions, "no-descriptions", false, "disable descriptions in completion scripts") + // mark hidden + for _, name := range []string{ + "completion-script-bash", "completion-script-zsh", "completion-script-fish", + "completion-script-powershell", "no-descriptions", + } { + flags.Lookup(name).Hidden = true + } return c.ExecuteContext(ctx) } -type Params struct { +type Args struct { FG color.Color BG color.Color Size int @@ -129,14 +166,14 @@ type Params struct { tpl *template.Template } -func (v *Params) Template() (*template.Template, error) { +func (args *Args) Template() (*template.Template, error) { var err error - v.once.Do(func() { - s := v.Text + args.once.Do(func() { + s := args.Text if s == "" { s = string(textTpl) } - v.tpl, err = template.New("").Funcs(map[string]interface{}{ + args.tpl, err = template.New("").Funcs(map[string]interface{}{ "size": func(size int) string { return fmt.Sprintf("\x00%d\x00", size) }, @@ -148,31 +185,31 @@ func (v *Params) Template() (*template.Template, error) { switch { case err != nil: return nil, err - case v.tpl == nil: + case args.tpl == nil: return nil, errors.New("invalid template state") } - return v.tpl, nil + return args.tpl, nil } // do renders the specified font queries to w. -func do(w io.Writer, sysfonts *fontpkg.SystemFonts, v *Params) error { +func do(w io.Writer, sysfonts *fontpkg.SystemFonts, args *Args) error { if !rasterm.Available() { return rasterm.ErrTermGraphicsNotAvailable } var fonts []*Font // collect fonts - for i := 0; i < len(v.Args); i++ { - v, err := Open(sysfonts, v.Args[i], v.Style) + for i := 0; i < len(args.Args); i++ { + v, err := Open(sysfonts, args.Args[i], args.Style) if err != nil { fmt.Fprintf(w, "error: unable to open arg %d: %v\n", i, err) } fonts = append(fonts, v...) } - return render(w, fonts, v) + return render(w, fonts, args) } // doAll renders all system fonts to w. -func doAll(w io.Writer, sysfonts *fontpkg.SystemFonts, v *Params) error { +func doAll(w io.Writer, sysfonts *fontpkg.SystemFonts, args *Args) error { if !rasterm.Available() { return rasterm.ErrTermGraphicsNotAvailable } @@ -187,10 +224,10 @@ func doAll(w io.Writer, sysfonts *fontpkg.SystemFonts, v *Params) error { fonts = append(fonts, NewFont(sysfonts.Fonts[family][style])) } } - return render(w, fonts, v) + return render(w, fonts, args) } -func doList(w io.Writer, sysfonts *fontpkg.SystemFonts, _ *Params) error { +func doList(w io.Writer, sysfonts *fontpkg.SystemFonts, _ *Args) error { families := maps.Keys(sysfonts.Fonts) slices.Sort(families) for i := 0; i < len(families); i++ { @@ -206,22 +243,22 @@ func doList(w io.Writer, sysfonts *fontpkg.SystemFonts, _ *Params) error { return nil } -func doMatch(w io.Writer, sysfonts *fontpkg.SystemFonts, v *Params) error { - for _, name := range v.Args { - if font := Match(sysfonts, name, v.Style); font != nil { +func doMatch(w io.Writer, sysfonts *fontpkg.SystemFonts, args *Args) error { + for _, name := range args.Args { + if font := Match(sysfonts, name, args.Style); font != nil { font.WriteYAML(w) } } return nil } -func render(w io.Writer, fonts []*Font, v *Params) error { - tpl, err := v.Template() +func render(w io.Writer, fonts []*Font, args *Args) error { + tpl, err := args.Template() if err != nil { return err } for i := 0; i < len(fonts); i++ { - if err := fonts[i].Render(w, tpl, v); err != nil { + if err := fonts[i].Render(w, tpl, args); err != nil { fmt.Fprintf(os.Stdout, "%s -- error: %v\n", fonts[i], err) } if i != len(fonts)-1 { @@ -348,9 +385,9 @@ func (font *Font) Load(style canvas.FontStyle) (*canvas.FontFamily, error) { return ff, nil } -func (font *Font) Render(w io.Writer, tpl *template.Template, v *Params) error { +func (font *Font) Render(w io.Writer, tpl *template.Template, args *Args) error { // load font family - ff, err := font.Load(v.Style) + ff, err := font.Load(args.Style) if err != nil { return err } @@ -358,7 +395,7 @@ func (font *Font) Render(w io.Writer, tpl *template.Template, v *Params) error { // generate text buf := new(bytes.Buffer) if err := tpl.Execute(buf, TemplateData{ - Size: v.Size, + Size: args.Size, Name: font.BestName(), Style: font.Style, SampleText: font.SampleText, @@ -373,12 +410,12 @@ func (font *Font) Render(w io.Writer, tpl *template.Template, v *Params) error { ctx := canvas.NewContext(c) ctx.SetZIndex(1) - ctx.SetFillColor(v.FG) + ctx.SetFillColor(args.FG) // draw text - lines, sizes := breakLines(buf.Bytes(), v.Size) + lines, sizes := breakLines(buf.Bytes(), args.Size) for i, y := 0, float64(0); i < len(lines); i++ { - face := ff.Face(float64(sizes[i]), v.FG, v.Style, v.Variant) + face := ff.Face(float64(sizes[i]), args.FG, args.Style, args.Variant) txt := canvas.NewTextBox(face, strings.TrimSpace(lines[i]), 0, 0, canvas.Left, canvas.Top, 0, 0) b := txt.Bounds() ctx.DrawText(0, y, txt) @@ -386,11 +423,11 @@ func (font *Font) Render(w io.Writer, tpl *template.Template, v *Params) error { } // fit canvas to context - c.Fit(float64(v.Margin)) + c.Fit(float64(args.Margin)) // draw background ctx.SetZIndex(-1) - ctx.SetFillColor(v.BG) + ctx.SetFillColor(args.BG) width, height := ctx.Size() ctx.DrawPath(0, 0, canvas.Rectangle(width, height)) @@ -399,9 +436,9 @@ func (font *Font) Render(w io.Writer, tpl *template.Template, v *Params) error { // encode return rasterm.Encode(w, rasterizer.Draw( c, - canvas.DPI(float64(v.DPI)), - canvas.DefaultColorSpace), - ) + canvas.DPI(float64(args.DPI)), + canvas.DefaultColorSpace, + )) } func breakLines(buf []byte, size int) ([]string, []int) { @@ -452,89 +489,89 @@ func peek(r []rune, i int) rune { } type Style struct { - v *canvas.FontStyle + fontStyle *canvas.FontStyle } -func NewStyle(v *canvas.FontStyle) pflag.Value { +func NewStyle(fontStyle *canvas.FontStyle) pflag.Value { return Style{ - v: v, + fontStyle: fontStyle, } } -func (v Style) String() string { - return strings.ToLower(v.v.String()) +func (style Style) String() string { + return strings.ToLower(style.fontStyle.String()) } -func (v Style) Set(s string) error { +func (style Style) Set(s string) error { italic, str := false, strings.ToLower(s) if italicRE.MatchString(str) { italic, str = true, italicRE.ReplaceAllString(str, "") } switch strings.TrimSpace(str) { case "regular", "", "400", "0": - *v.v = canvas.FontRegular + *style.fontStyle = canvas.FontRegular case "thin", "100": - *v.v = canvas.FontThin + *style.fontStyle = canvas.FontThin case "extra-light", "extralight", "200": - *v.v = canvas.FontExtraLight + *style.fontStyle = canvas.FontExtraLight case "light", "300": - *v.v = canvas.FontLight + *style.fontStyle = canvas.FontLight case "medium", "500": - *v.v = canvas.FontMedium + *style.fontStyle = canvas.FontMedium case "semi-bold", "semibold", "600": - *v.v = canvas.FontSemiBold + *style.fontStyle = canvas.FontSemiBold case "bold", "700": - *v.v = canvas.FontBold + *style.fontStyle = canvas.FontBold case "extra-bold", "extrabold", "800": - *v.v = canvas.FontExtraBold + *style.fontStyle = canvas.FontExtraBold case "black", "900": - *v.v = canvas.FontBlack + *style.fontStyle = canvas.FontBlack default: return fmt.Errorf("invalid font style %q", s) } if italic { - *v.v |= canvas.FontItalic + *style.fontStyle |= canvas.FontItalic } return nil } var italicRE = regexp.MustCompile(`(?i)\s*italic\s*`) -func (v Style) Type() string { +func (style Style) Type() string { return "font-style" } type Variant struct { - v *canvas.FontVariant + fontVariant *canvas.FontVariant } -func NewVariant(v *canvas.FontVariant) pflag.Value { +func NewVariant(fontVariant *canvas.FontVariant) pflag.Value { return Variant{ - v: v, + fontVariant: fontVariant, } } -func (v Variant) String() string { - return strings.ToLower(v.v.String()) +func (variant Variant) String() string { + return strings.ToLower(variant.fontVariant.String()) } -func (v Variant) Set(s string) error { +func (variant Variant) Set(s string) error { switch strings.ToLower(s) { case "normal": - *v.v = canvas.FontNormal + *variant.fontVariant = canvas.FontNormal case "subscript": - *v.v = canvas.FontSubscript + *variant.fontVariant = canvas.FontSubscript case "superscript": - *v.v = canvas.FontSuperscript + *variant.fontVariant = canvas.FontSuperscript case "smallcaps": - *v.v = canvas.FontSmallcaps + *variant.fontVariant = canvas.FontSmallcaps default: return fmt.Errorf("invalid font variant %q", s) } return nil } -func (v Variant) Type() string { +func (variant Variant) Type() string { return "font-variant" }