Skip to content

Commit

Permalink
Work a bit on adding a table layout with -table (still ugly and buggy)
Browse files Browse the repository at this point in the history
  • Loading branch information
arp242 committed May 3, 2022
1 parent 7fb775d commit e63aa48
Show file tree
Hide file tree
Showing 10 changed files with 331 additions and 82 deletions.
18 changes: 14 additions & 4 deletions .readme.gotxt
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ It reads from stdin:
'[' U+005B 91 5b [ LEFT SQUARE BRACKET (Open_Punctuation)
'!' U+0021 33 21 ! EXCLAMATION MARK (Other_Punctuation)

You can use `-quiet` (or `-q`) to suppress the header, and `-format` (of `-f`)
You can use `-compact` (or `-c`) to suppress the header, and `-format` (or `-f`)
to control the output format, for example you may want to generate a codepoint
to X11 keysym mapping:

{{example "i" "-q" "-f" "0x%(hex): \"%(keysym)\", // %(name)" "h€ý"}}
{{example "i" "-c" "-f" "0x%(hex): \"%(keysym)\", // %(name)" "h€ý"}}

See `uni help` for more details on the `-format` flag; this flag can also be
added to other commands.
Expand Down Expand Up @@ -118,8 +118,11 @@ Blocks:

{{trim 5 (example "p" "arrows" "box drawing")}}

### Emoji
Print as table, and with a shorter name:

{{example "p" "-table" "box"}}

### Emoji
The `emoji` command (shortcut: `e`) is is the real reason I wrote this:

{{example "e" "cry"}}
Expand Down Expand Up @@ -170,7 +173,7 @@ both a light and dark skin tone; use `all` to display all skin tones or genders:

Like `print` and `identify`, you can use `-format`:

{{example "e" "g:cat-face" "-q" "-format" "%(name): %(emoji)"}}
{{example "e" "g:cat-face" "-c" "-format" "%(name): %(emoji)"}}

See `uni help` for more details on the `-format` flag.

Expand Down Expand Up @@ -202,8 +205,15 @@ ChangeLog
- Add support for properties; they can be displayed with `%(props)` in
`-format`, and printed with `uni print` (e.g. `uni print dash`).

- Add `-table` / `-t` to show codepoints in a table.

- Add `uni list` command, to list categories, blocks, and properties.

- Change `-q`/`-quiet` to `-c`/`-compact`; `-json` will print as minified if
given, and `-table` will include less padding.

-q is still accepted as a backwards-compatible alias.

- Don't use the Go stdlib `unicode` package; since this is a Unicode 13 database
some operations would fail on codepoints added in Unicode 14.

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright © 2018-2019 Martin Tournoij
Copyright © Martin Tournoij

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
Expand Down
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ It reads from stdin:
'[' U+005B 91 5b [ LEFT SQUARE BRACKET (Open_Punctuation)
'!' U+0021 33 21 ! EXCLAMATION MARK (Other_Punctuation)

You can use `-quiet` (or `-q`) to suppress the header, and `-format` (of `-f`)
You can use `-compact` (or `-c`) to suppress the header, and `-format` (or `-f`)
to control the output format, for example you may want to generate a codepoint
to X11 keysym mapping:

$ uni i -q -f '0x%(hex): "%(keysym)", // %(name)' h€ý
$ uni i -c -f '0x%(hex): "%(keysym)", // %(name)' h€ý
0x68: "h", // LATIN SMALL LETTER H
0x20ac: "EuroSign", // EURO SIGN
0xfd: "yacute", // LATIN SMALL LETTER Y WITH ACUTE
Expand Down Expand Up @@ -169,8 +169,29 @@ Blocks:
'↓' U+2193 8595 e2 86 93 ↓ DOWNWARDS ARROW (Math_Symbol)

### Emoji
Print as table, and with a shorter name:

$ uni p -table box
0 1 2 3 4 5 6 7 8 9 A B C D E F
┌────────────────────────────────────────────────
U+250x │ ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏
U+251x │ ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟
U+252x │ ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯
U+253x │ ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿
U+254x │ ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏
U+255x │ ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟
U+256x │ ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯
U+257x │ ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿

### Emoji
The `emoji` command (shortcut: `e`) is is the real reason I wrote this:

$ uni e cry
Expand Down Expand Up @@ -273,7 +294,7 @@ both a light and dark skin tone; use `all` to display all skin tones or genders:

Like `print` and `identify`, you can use `-format`:

$ uni e g:cat-face -q -format '%(name): %(emoji)'
$ uni e g:cat-face -c -format '%(name): %(emoji)'
grinning cat: 😺
grinning cat with smiling eyes: 😸
cat with tears of joy: 😹
Expand Down Expand Up @@ -412,8 +433,15 @@ ChangeLog
- Add support for properties; they can be displayed with `%(props)` in
`-format`, and printed with `uni print` (e.g. `uni print dash`).

- Add `-table` / `-t` to show codepoints in a table.

- Add `uni list` command, to list categories, blocks, and properties.

- Change `-q`/`-quiet` to `-c`/`-compact`; `-json` will print as minified if
given, and `-table` will include less padding.

-q is still accepted as a backwards-compatible alias.

- Don't use the Go stdlib `unicode` package; since this is a Unicode 13 database
some operations would fail on codepoints added in Unicode 14.

Expand Down
8 changes: 4 additions & 4 deletions dmenu-uni
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ common="-or g:smileys g:hand-fingers-open g:hand-fingers-partial g:hand-single-f
#common="$common -tone mediumdark"

case "${1:-all}" in
all) uni -q p all | $dmenu | grep -o "^'.'" | tr -d "'" | $copy ;;
emoji) uni -q e all | $dmenu | cut -d ' ' -f1 | $copy ;;
emoji-common) uni -q e $common | $dmenu | cut -d ' ' -f1 | $copy ;;
*) uni -q e $@ | $dmenu | cut -d ' ' -f1 | $copy ;;
all) uni -c p all | $dmenu | grep -o "^'.'" | tr -d "'" | $copy ;;
emoji) uni -c e all | $dmenu | cut -d ' ' -f1 | $copy ;;
emoji-common) uni -c e $common | $dmenu | cut -d ' ' -f1 | $copy ;;
*) uni -c e $@ | $dmenu | cut -d ' ' -f1 | $copy ;;
#*) echo >&2 "dmenu-uni: unknown '$1'" ;;
esac
148 changes: 137 additions & 11 deletions format.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"strings"
"unicode/utf8"

"github.com/mattn/go-runewidth"
"zgo.at/termtext"
"zgo.at/uni/v2/unidata"
"zgo.at/zli"
Expand Down Expand Up @@ -49,23 +50,38 @@ type column struct {

type Format struct {
format string // Format string: %(..)
as printAs // How to print (list, table, json)
re *regexp.Regexp // Cached regexp for format.
cols []column // Columns we know about.
colNames []string
lines [][]string // Processed lines, to be printed.
autoalign []int // Max line lengths for autoalign.
ntrim int // Number of columns with "trim"
json bool // Print as JSON.

printHeader bool
tblData []map[string]string
}

var (
reFindCols = regexp.MustCompile(`%\((.*?)(?: .+?)?\)`)
var reFindCols = regexp.MustCompile(`%\((.*?)(?: .+?)?\)`)

type printAs uint8

const (
printAsList = printAs(iota)
printAsJSON
printAsTable
printAsListCompact
printAsJSONCompact
printAsTableCompact
)

func NewFormat(format string, asJSON, printHeader bool, knownCols ...string) (*Format, error) {
f := Format{format: format, printHeader: printHeader, json: asJSON}
func NewFormat(format string, as printAs, knownCols ...string) (*Format, error) {
f := Format{format: format, as: as}

if as == printAsTable || as == printAsTableCompact {
// Don't need all the rest of the logic.
return &f, nil
}

for _, m := range reFindCols.FindAllString(format, -1) {
err := f.processColumn(m)
if err != nil {
Expand All @@ -90,7 +106,7 @@ func NewFormat(format string, asJSON, printHeader bool, knownCols ...string) (*F
h["tab"] = tabOrSpace()
h["wide_padding"] = " "

if printHeader && !asJSON {
if as == printAsList {
f.Line(h)
}

Expand All @@ -100,6 +116,9 @@ func NewFormat(format string, asJSON, printHeader bool, knownCols ...string) (*F
return &f, nil
}

func (f *Format) tbl() bool { return f.as == printAsTable || f.as == printAsTableCompact }
func (f *Format) json() bool { return f.as == printAsJSON || f.as == printAsJSONCompact }

func (f *Format) processColumn(line string) error {
s := zstring.Fields(line[2:len(line)-1], " ") // name, flags
name := s[0]
Expand Down Expand Up @@ -159,6 +178,11 @@ func (f *Format) processColumn(line string) error {

// Add a new line.
func (f *Format) Line(columns map[string]string) error {
if f.tbl() {
f.tblData = append(f.tblData, columns)
return nil
}

line := make([]string, len(f.cols))
for i, c := range f.cols {
line[i] = columns[c.name]
Expand Down Expand Up @@ -209,7 +233,9 @@ func (f *Format) printJSON(out io.Writer) {
buf := new(bytes.Buffer)
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
enc.SetIndent("", "\t")
if f.as != printAsJSONCompact {
enc.SetIndent("", "\t")
}

out.Write([]byte("["))
for i, l := range f.lines {
Expand All @@ -234,11 +260,103 @@ func (f *Format) printJSON(out io.Writer) {
out.Write([]byte("]\n"))
}

// -table
// -table compact
//
// TODO: fails; uni search euro -t
// Doesn't start at 0
//
//func (f *Format) printTbl(codepoints ...unidata.Codepoint) {
func (f *Format) printTbl(out io.Writer) {
sort.Slice(f.tblData, func(i, j int) bool {
return f.tblData[i]["cpoint"] < f.tblData[j]["cpoint"]
})

var (
wide = false
tblMap = make(map[string]string)
head = 4
)
for _, r := range f.tblData {
if r["width"] == "wide" {
wide = true
}
tblMap[r["cpoint"]] = r["char"]
if []rune(r["char"])[0] > 0xffff {
head = 5
}
}

h := strings.Repeat(" ", head)
if wide {
fmt.Println(h + " 0 1 2 3 4 5 6 7 8 9 A B C D E F")
fmt.Println(h + " ┌" + strings.Repeat("─", 64))
} else {
fmt.Println(h + " 0 1 2 3 4 5 6 7 8 9 A B C D E F")
fmt.Println(h + " ┌" + strings.Repeat("─", 48))
}

start, err := strconv.ParseInt(f.tblData[0]["cpoint"][2:], 16, 32)
zli.F(err)
end, err := strconv.ParseInt(f.tblData[len(f.tblData)-1]["cpoint"][2:], 16, 32)
zli.F(err)

var (
row = ""
blank = 0
didel = false
)
// TODO: color cells that weren't in the selection, or maybe use some
// codepoints for that. Also color unassigned cells.
// TODO: output block name to the right.
for i := start; i <= end; i++ {
cp := fmt.Sprintf("U+%0"+strconv.Itoa(head)+"X", i)

cp1 := fmt.Sprintf("U+%04X", i)
char, ok := tblMap[cp1]
if !ok {
blank++
char = " "
}

if strings.HasSuffix(cp, "0") {
row += fmt.Sprintf("%sx │", strings.TrimSuffix(cp, "0"))
}

// If some chars are wide bit this one isn't, need to add space here.
row += fmt.Sprintf(" %s ", char)
if wide && runewidth.RuneWidth([]rune(char)[0]) == 1 {
row += " "
}
if strings.HasSuffix(cp, "F") || i == end {
if blank < 16 {
fmt.Print(row)
fmt.Print("\n")
if f.as != printAsTableCompact {
fmt.Println(h + " │")
}
didel = false
} else if !didel {
//fmt.Println(h + " │ …")
fmt.Println(h + " … │")
didel = true
}

row = ""
blank = 0
}
}
}

func (f *Format) Print(out io.Writer) {
if f.json {
if f.json() {
f.printJSON(out)
return
}
if f.tbl() {
f.printTbl(out)
return
}

for lineno, l := range f.lines {
line := f.format
Expand Down Expand Up @@ -299,7 +417,7 @@ func (f *Format) fmtPlaceholder(i, lineno int, text string, applyTrim int) strin
c := f.cols[i]

if c.quote {
if f.printHeader && lineno == 0 {
if f.as != printAsListCompact && lineno == 0 {
text = " " + text + " " // TODO: why two spaces?
} else {
text = "'" + text + "'"
Expand All @@ -317,7 +435,7 @@ func (f *Format) fmtPlaceholder(i, lineno int, text string, applyTrim int) strin
text = zstring.AlignRight(text, w)
}
if c.fill > 0 {
if !f.printHeader || lineno > 0 {
if f.as == printAsListCompact || lineno > 0 {
text = strings.ReplaceAll(text, " ", string(c.fill))
}
}
Expand All @@ -340,6 +458,14 @@ var knownColumns = []string{"char", "wide_padding", "cpoint", "dec", "hex",
"digraph", "name", "cat", "block", "plane", "width", "props"}

func (f *Format) toLine(info unidata.Codepoint, raw bool) map[string]string {
if f.tbl() {
return map[string]string{
"char": map[bool]string{false: info.Display(), true: string(info.Codepoint)}[raw],
"width": info.Width().String(),
"cpoint": info.FormatCodepoint(),
}
}

if len(f.cols) == len(knownColumns) { // Optimize printing all columns.
return map[string]string{
"char": map[bool]string{false: info.Display(), true: string(info.Codepoint)}[raw],
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ module zgo.at/uni/v2
go 1.17

require (
github.com/mattn/go-runewidth v0.0.13
zgo.at/termtext v1.0.0
zgo.at/zli v0.0.0-20220501195129-6f455d326bf8
zgo.at/zli v0.0.0-20220503115514-715dad1d8932
zgo.at/zstd v0.0.0-20220413140508-6078fed48e39
)

require (
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 // indirect
Expand Down
Loading

0 comments on commit e63aa48

Please sign in to comment.