Improve compatibility with zenity.
This commit is contained in:
parent
9816e864ae
commit
6c17f894e1
10 changed files with 143 additions and 17 deletions
|
@ -520,9 +520,13 @@ func loadFlags() []zenity.Option {
|
|||
if ellipsize {
|
||||
opts = append(opts, zenity.Ellipsize())
|
||||
}
|
||||
if !noMarkup {
|
||||
switch {
|
||||
case entryDlg:
|
||||
text = zencmd.StripMnemonic(text)
|
||||
case calendarDlg, progressDlg:
|
||||
text = zencmd.StripMarkup(text)
|
||||
case errorDlg, infoDlg, warningDlg, questionDlg:
|
||||
if !noMarkup {
|
||||
text = zencmd.StripMarkup(text)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
func calendar(text string, opts options) (time.Time, error) {
|
||||
args := []string{"--calendar", "--text", text, "--date-format", zenutil.DateFormat}
|
||||
args := []string{"--calendar", "--text", quoteMarkup(text), "--date-format", zenutil.DateFormat}
|
||||
args = appendGeneral(args, opts)
|
||||
args = appendButtons(args, opts)
|
||||
args = appendWidthHeight(args, opts)
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
package zenity
|
||||
|
||||
import (
|
||||
"github.com/ncruces/zenity/internal/zenutil"
|
||||
)
|
||||
import "github.com/ncruces/zenity/internal/zenutil"
|
||||
|
||||
func entry(text string, opts options) (string, error) {
|
||||
args := []string{"--entry", "--text", text}
|
||||
args := []string{"--entry", "--text", quoteMnemonics(text)}
|
||||
args = appendGeneral(args, opts)
|
||||
args = appendButtons(args, opts)
|
||||
args = appendWidthHeight(args, opts)
|
||||
|
|
|
@ -12,18 +12,18 @@ func StripMarkup(s string) string {
|
|||
// https://docs.gtk.org/Pango/pango_markup.html
|
||||
|
||||
dec := xml.NewDecoder(strings.NewReader(s))
|
||||
var buf strings.Builder
|
||||
var res strings.Builder
|
||||
|
||||
for {
|
||||
t, err := dec.Token()
|
||||
if err == io.EOF {
|
||||
return buf.String()
|
||||
return res.String()
|
||||
}
|
||||
if err != nil {
|
||||
return s
|
||||
}
|
||||
if t, ok := t.(xml.CharData); ok {
|
||||
buf.Write(t)
|
||||
res.Write(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package zencmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
import "testing"
|
||||
|
||||
var markupTests = []struct {
|
||||
data string
|
||||
|
|
25
internal/zencmd/mnemonic.go
Normal file
25
internal/zencmd/mnemonic.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package zencmd
|
||||
|
||||
import "strings"
|
||||
|
||||
// StripMnemonic is internal.
|
||||
func StripMnemonic(s string) string {
|
||||
// Strips mnemonics described in:
|
||||
// https: //docs.gtk.org/gtk4/class.Label.html#mnemonics
|
||||
|
||||
var res strings.Builder
|
||||
|
||||
underscore := false
|
||||
for _, b := range []byte(s) {
|
||||
switch {
|
||||
case underscore:
|
||||
underscore = false
|
||||
case b == '_':
|
||||
underscore = true
|
||||
continue
|
||||
}
|
||||
res.WriteByte(b)
|
||||
}
|
||||
|
||||
return res.String()
|
||||
}
|
46
internal/zencmd/mnemonic_test.go
Normal file
46
internal/zencmd/mnemonic_test.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package zencmd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var mnemonicTests = []struct {
|
||||
data string
|
||||
want string
|
||||
}{
|
||||
{"", ""},
|
||||
{"abc", "abc"},
|
||||
{"_abc", `abc`},
|
||||
{"_a_b_c_", "abc"},
|
||||
{"a__c", `a_c`},
|
||||
{"a___c", `a_c`},
|
||||
{"a____c", `a__c`},
|
||||
}
|
||||
|
||||
func TestStripMnemonic(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, test := range mnemonicTests {
|
||||
if got := StripMnemonic(test.data); got != test.want {
|
||||
t.Errorf("StripMnemonic(%q) = %q; want %q", test.data, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func FuzzStripMnemonic(f *testing.F) {
|
||||
for _, test := range mnemonicTests {
|
||||
f.Add(test.data)
|
||||
}
|
||||
|
||||
f.Fuzz(func(t *testing.T, s string) {
|
||||
q := quoteMnemonic(s)
|
||||
u := StripMnemonic(q)
|
||||
if s != u {
|
||||
t.Errorf("strip(quote(%q)) = strip(%q) = %q", s, q, u)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func quoteMnemonic(s string) string {
|
||||
return strings.ReplaceAll(s, "_", "__")
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package zencmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
import "testing"
|
||||
|
||||
var unescapeTests = []struct {
|
||||
data string
|
||||
|
|
14
util.go
14
util.go
|
@ -2,6 +2,7 @@ package zenity
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
|
@ -14,6 +15,19 @@ func quoteAccelerators(text string) string {
|
|||
return strings.ReplaceAll(text, "&", "&&")
|
||||
}
|
||||
|
||||
func quoteMnemonics(text string) string {
|
||||
return strings.ReplaceAll(text, "_", "__")
|
||||
}
|
||||
|
||||
func quoteMarkup(text string) string {
|
||||
var res strings.Builder
|
||||
err := xml.EscapeText(&res, []byte(text))
|
||||
if err != nil {
|
||||
return text
|
||||
}
|
||||
return res.String()
|
||||
}
|
||||
|
||||
func appendGeneral(args []string, opts options) []string {
|
||||
if opts.title != nil {
|
||||
args = append(args, "--title", *opts.title)
|
||||
|
|
43
util_test.go
43
util_test.go
|
@ -31,6 +31,49 @@ func Test_quoteAccelerators(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_quoteMnemonics(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
text string
|
||||
want string
|
||||
}{
|
||||
{name: "None", text: "abc", want: "abc"},
|
||||
{name: "One", text: "_abc", want: "__abc"},
|
||||
{name: "Two", text: "_a_bc", want: "__a__bc"},
|
||||
{name: "Three", text: "ab__c", want: "ab____c"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := quoteMnemonics(tt.text); got != tt.want {
|
||||
t.Errorf("quoteMnemonics(%q) = %q; want %q", tt.text, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_quoteMarkup(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
text string
|
||||
want string
|
||||
}{
|
||||
{name: "None", text: `abc`, want: "abc"},
|
||||
{name: "LT", text: `<`, want: "<"},
|
||||
{name: "Amp", text: `&`, want: "&"},
|
||||
{name: "Quot", text: `"`, want: """},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := quoteMarkup(tt.text); got != tt.want {
|
||||
t.Errorf("quoteMarkup(%q) = %q; want %q", tt.text, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_appendGeneral(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := appendGeneral(nil, options{
|
||||
|
|
Loading…
Reference in a new issue