diff --git a/README.md b/README.md index e56ba77..aecc8b0 100644 --- a/README.md +++ b/README.md @@ -16,27 +16,24 @@ Produces [colortest.ansi.svg](cli/testdata/colortest.ansi.svg): ``` $ ansisvg -h -Usage of ansisvg: - -charboxsize value - Character box size (forces pixel units instead of font-relative units) - -colorscheme string - Color scheme (default "Builtin Dark") - -fontfile string - Font file to use and embed - -fontname string - Font name (default "Courier") - -fontref string - External font file to reference - -fontsize int - Font size (default 14) - -grid - Enable grid mode (sets position for each character) - -listcolorschemes - List color schemes - -transparent - Transparent background - -width int - Terminal width (auto) +ansisvg - Convert ANSI to SVG +Usage: ansisvg [FLAGS] + +Example usage: + program | ansisvg > file.svg + +--charboxsize Character box size (use pixel units instead of font units) +--colorscheme Color scheme +--fontfile Font file to use and embed +--fontname Font name +--fontref External font URL to use +--fontsize Font size +--grid Grid mode (sets position for each character) +--help, -h Show help +--listcolorschemes List color schemes +--transparent Transparent background +--version, -v Show version +--width, -w Terminal width (auto if not set) ``` Color themes are the ones from https://github.com/mbadolato/iTerm2-Color-Schemes diff --git a/ansitosvg/ansisvg.go b/ansitosvg/ansisvg.go index 610d898..0f8f496 100644 --- a/ansitosvg/ansisvg.go +++ b/ansitosvg/ansisvg.go @@ -10,23 +10,23 @@ import ( ) type Options struct { - FontName string - FontEmbedded []byte - FontRef string - FontSize int - TerminalWidth int - CharacterBoxSize svgscreen.BoxSize - ColorScheme string - Transparent bool - GridMode bool + FontName string + FontEmbedded []byte + FontRef string + FontSize int + TerminalWidth int + CharBoxSize svgscreen.BoxSize + ColorScheme string + Transparent bool + GridMode bool } var DefaultOptions = Options{ - FontName: "Courier", - FontSize: 14, - CharacterBoxSize: svgscreen.BoxSize{Width: 0, Height: 0}, - ColorScheme: "Builtin Dark", - Transparent: false, + FontName: "Courier", + FontSize: 14, + CharBoxSize: svgscreen.BoxSize{Width: 0, Height: 0}, + ColorScheme: "Builtin Dark", + Transparent: false, } // Convert reads ANSI input from r and writes SVG to w @@ -130,8 +130,8 @@ func Convert(r io.Reader, w io.Writer, opts Options) error { FontSize: opts.FontSize, }, CharacterBoxSize: svgscreen.BoxSize{ - Width: opts.CharacterBoxSize.Width, - Height: opts.CharacterBoxSize.Height, + Width: opts.CharBoxSize.Width, + Height: opts.CharBoxSize.Height, }, TerminalWidth: terminalWidth, Columns: ad.MaxX + 1, diff --git a/cli/cli.go b/cli/cli.go index 0a4e57e..565fc80 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -41,25 +41,77 @@ type Env struct { } func Main(env Env) error { - fs := flag.NewFlagSet("ansisvg", flag.ExitOnError) - var versionFlag = fs.Bool("version", false, "Show version") + fs := flag.NewFlagSet("ansisvg", flag.ContinueOnError) + var versionFlag bool + fs.BoolVar(&versionFlag, "v", false, "") + fs.BoolVar(&versionFlag, "version", false, "Show version") var fontNameFlag = fs.String("fontname", ansitosvg.DefaultOptions.FontName, "Font name") var fontFileFlag = fs.String("fontfile", "", "Font file to use and embed") - var fontRefFlag = fs.String("fontref", "", "External font file to reference") + var fontRefFlag = fs.String("fontref", "", "External font URL to use") var fontSizeFlag = fs.Int("fontsize", ansitosvg.DefaultOptions.FontSize, "Font size") - var terminalWidthFlag = fs.Int("width", 0, "Terminal width (auto)") + var terminalWidthFlag int + fs.IntVar(&terminalWidthFlag, "w", 0, "") + fs.IntVar(&terminalWidthFlag, "width", 0, "Terminal width (auto if not set)") var colorSchemeFlag = fs.String("colorscheme", ansitosvg.DefaultOptions.ColorScheme, "Color scheme") var listColorSchemesFlag = fs.Bool("listcolorschemes", false, "List color schemes") var transparentFlag = fs.Bool("transparent", ansitosvg.DefaultOptions.Transparent, "Transparent background") - var gridModeFlag = fs.Bool("grid", false, "Enable grid mode (sets position for each character)") - var characterBoxSize = boxSize{ - Width: ansitosvg.DefaultOptions.CharacterBoxSize.Width, - Height: ansitosvg.DefaultOptions.CharacterBoxSize.Height, + var gridModeFlag = fs.Bool("grid", false, "Grid mode (sets position for each character)") + var helpFlag bool + fs.BoolVar(&helpFlag, "h", false, "") + fs.BoolVar(&helpFlag, "help", false, "Show help") + var charBoxSize = boxSize{ + Width: ansitosvg.DefaultOptions.CharBoxSize.Width, + Height: ansitosvg.DefaultOptions.CharBoxSize.Height, + } + fs.Var(&charBoxSize, "charboxsize", "Character box size (use pixel units instead of font units)") + // handle error and usage output ourself + fs.Usage = func() {} + fs.SetOutput(io.Discard) + longToShort := map[string]string{ + "help": "h", + "version": "v", + "width": "w", + } + usage := func() { + maxNameLen := 0 + fs.VisitAll(func(f *flag.Flag) { + if len(f.Name) > maxNameLen { + maxNameLen = len(f.Name) + } + }) + + fmt.Fprintf(env.Stdout, ` +%[1]s - Convert ANSI to SVG +Usage: %[1]s [FLAGS] + +Example usage: + program | %[1]s > file.svg + +`[1:], fs.Name()) + fs.VisitAll(func(f *flag.Flag) { + if len(f.Name) == 1 { + return + } + + short := "" + if s, ok := longToShort[f.Name]; ok { + short = ", -" + s + } + + flagNames := f.Name + short + pad := strings.Repeat(" ", maxNameLen-len(flagNames)) + fmt.Fprintf(env.Stdout, "--%s%s%s %s\n", f.Name, short, pad, f.Usage) + }) + } + if err := fs.Parse(env.Args[1:]); err != nil { + return err + } + if helpFlag { + usage() + return nil } - fs.Var(&characterBoxSize, "charboxsize", "Character box size (forces pixel units instead of font-relative units)") - _ = fs.Parse(env.Args[1:]) - if *versionFlag { + if versionFlag { fmt.Fprintln(env.Stdout, env.Version) return nil } @@ -96,10 +148,10 @@ func Main(env Env) error { FontEmbedded: fontEmbedded, FontRef: *fontRefFlag, FontSize: *fontSizeFlag, - TerminalWidth: *terminalWidthFlag, - CharacterBoxSize: svgscreen.BoxSize{ - Width: characterBoxSize.Width, - Height: characterBoxSize.Height, + TerminalWidth: terminalWidthFlag, + CharBoxSize: svgscreen.BoxSize{ + Width: charBoxSize.Width, + Height: charBoxSize.Height, }, ColorScheme: *colorSchemeFlag, Transparent: *transparentFlag, diff --git a/cli/testdata/charboxfontsize.ansi.args b/cli/testdata/charboxfontsize.ansi.args index ad265be..9fe18e4 100644 --- a/cli/testdata/charboxfontsize.ansi.args +++ b/cli/testdata/charboxfontsize.ansi.args @@ -1 +1 @@ --fontsize 40 -fontname Arial -charboxsize 50x50 -grid \ No newline at end of file +--fontsize 40 --fontname Arial --charboxsize 50x50 --grid \ No newline at end of file diff --git a/cli/testdata/colortest_slate.ansi.args b/cli/testdata/colortest_slate.ansi.args index df8fea3..790ba31 100644 --- a/cli/testdata/colortest_slate.ansi.args +++ b/cli/testdata/colortest_slate.ansi.args @@ -1 +1 @@ --colorscheme Slate \ No newline at end of file +--colorscheme Slate \ No newline at end of file diff --git a/cli/testdata/colortest_transparent.ansi.args b/cli/testdata/colortest_transparent.ansi.args index 44c8c07..9c69a35 100644 --- a/cli/testdata/colortest_transparent.ansi.args +++ b/cli/testdata/colortest_transparent.ansi.args @@ -1 +1 @@ --transparent \ No newline at end of file +--transparent \ No newline at end of file diff --git a/cli/testdata/fontembedded.ansi.args b/cli/testdata/fontembedded.ansi.args index 597acbb..e21062c 100644 --- a/cli/testdata/fontembedded.ansi.args +++ b/cli/testdata/fontembedded.ansi.args @@ -1 +1 @@ --fontfile UbuntuMonoNerdFontMono-Regular.woff2 \ No newline at end of file +--fontfile UbuntuMonoNerdFontMono-Regular.woff2 \ No newline at end of file diff --git a/cli/testdata/fontname.ansi.args b/cli/testdata/fontname.ansi.args index b42018c..49da831 100644 --- a/cli/testdata/fontname.ansi.args +++ b/cli/testdata/fontname.ansi.args @@ -1 +1 @@ --fontname Monaco \ No newline at end of file +--fontname Monaco \ No newline at end of file diff --git a/cli/testdata/fontref.ansi.args b/cli/testdata/fontref.ansi.args index 580c13f..30accdd 100644 --- a/cli/testdata/fontref.ansi.args +++ b/cli/testdata/fontref.ansi.args @@ -1 +1 @@ --fontref font.woff2 \ No newline at end of file +--fontref font.woff2 \ No newline at end of file diff --git a/cli/testdata/powerline.ansi.args b/cli/testdata/powerline.ansi.args index 7fc443b..06b40c4 100644 --- a/cli/testdata/powerline.ansi.args +++ b/cli/testdata/powerline.ansi.args @@ -1 +1 @@ --fontfile UbuntuMonoNerdFontMono-Regular.woff2 -grid \ No newline at end of file +--fontfile UbuntuMonoNerdFontMono-Regular.woff2 --grid \ No newline at end of file diff --git a/cli/testdata/terminalwidth4.ansi.args b/cli/testdata/terminalwidth4.ansi.args index ef44f58..058b6b9 100644 --- a/cli/testdata/terminalwidth4.ansi.args +++ b/cli/testdata/terminalwidth4.ansi.args @@ -1 +1 @@ --width 4 \ No newline at end of file +--width 4 \ No newline at end of file diff --git a/cli/testdata/underlinetabs_backgroundcolor.ansi.args b/cli/testdata/underlinetabs_backgroundcolor.ansi.args index 657250a..d14e2b5 100644 --- a/cli/testdata/underlinetabs_backgroundcolor.ansi.args +++ b/cli/testdata/underlinetabs_backgroundcolor.ansi.args @@ -1 +1 @@ --colorscheme "Builtin Solarized Light" \ No newline at end of file +--colorscheme "Builtin Solarized Light" \ No newline at end of file