diff options
-rw-r--r-- | doc/i18n.md | 28 | ||||
-rw-r--r-- | src/i18n/i18n.go | 106 |
2 files changed, 98 insertions, 36 deletions
diff --git a/doc/i18n.md b/doc/i18n.md index b7de2dc..dcb5727 100644 --- a/doc/i18n.md +++ b/doc/i18n.md @@ -92,14 +92,15 @@ follows: The following character codes are available with the following behaviour: -| Code | Mnemonic | Description | -| ---- | ------------------ | ----------------------------------------------------------- | -| `e` | \[e]mail | inserts a link to an email address | -| `E` | \[E]nd | inserts closing-tags for the comma-separated HTML tags | -| `l` | \[l]ink (internal) | links to an internal page | -| `L` | \[L]ink (external) | links to an external page | -| `m` | \[m]onetary | formats the given `int` or `float64` as an amount of Euros. | -| `r` | \[r]aw | inserts the given string verbatim without HTML escaping | +| Code | Mnemonic | Description | +| ---- | ------------------ | ---------------------------------------------------------- | +| `e` | \[e]mail | inserts a link to an email address | +| `E` | \[E]nd | inserts closing-tags for the comma-separated HTML tags | +| `l` | \[l]ink (internal) | links to an internal page | +| `L` | \[L]ink (external) | links to an external page | +| `m` | \[m]onetary | formats the given `int` or `float64` as an amount of Euros | +| `p` | \[p]ercentage | formats the given `int` or `float64` as a percentage | +| `r` | \[r]aw | inserts the given string verbatim without HTML escaping | ```html <!-- <a href="mailto:help@euro-cash.eu">help@euro-cash.eu</a> --> @@ -121,11 +122,16 @@ The following character codes are available with the following behaviour: <!-- Varies per locale --> <!-- €1 and €1.00 --> <p>{{ .Get "{1:m} and {1.00:m}" (map "1" 1 "1.00" 1.00) }}</p> + +<!-- Varies per locale --> +<!-- Ölen har 5 % alkoholhalt, eller egentligen 4,5 % --> +<p>{{ .Get "The beer is {5:p} alcohol, or really {4.5:p}" + (map "5" 5 "4.5" 4.5) }}</p> ``` Some additional notes: - The `-` name is special. `{-:E}` inserts `</a>`. This exists because of how often you need to do this. -- The `m` character code won’t include decimals when the argument is an - integer, and will include the decimals when the argument is a - floating-point number.
\ No newline at end of file +- The `p` and `m` character codes won’t include decimals when the + argument is an integer, and will include the decimals when the argument + is a floating-point number.
\ No newline at end of file diff --git a/src/i18n/i18n.go b/src/i18n/i18n.go index a013c96..ff7b6ce 100644 --- a/src/i18n/i18n.go +++ b/src/i18n/i18n.go @@ -27,7 +27,8 @@ type LocaleInfo struct { DateFormat string GroupSeparator, DecimalSeparator rune MonetaryPre [2]string - MonetaryPost string + MonetarySuf string + PercentPre, PercentSuf string } type number interface { @@ -39,11 +40,12 @@ type sprintfFunc func(LocaleInfo, *strings.Builder, any) error var ( handlers map[rune]sprintfFunc = map[rune]sprintfFunc{ -1: sprintfGeneric, - 'e': sprintfe, 'E': sprintfE, - 'l': sprintfl, 'L': sprintfL, + 'e': sprintfe, + 'l': sprintfl, 'm': sprintfm, + 'p': sprintfp, 'r': sprintfr, } @@ -59,7 +61,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "de", @@ -70,7 +73,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "el", @@ -81,7 +85,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: "%", }, { Bcp: "en", @@ -92,6 +97,7 @@ var ( GroupSeparator: ',', DecimalSeparator: '.', MonetaryPre: [2]string{"€", "-€"}, + PercentSuf: "%", }, { Bcp: "es", @@ -102,7 +108,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "et", @@ -113,7 +120,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: "%", }, { Bcp: "fi", @@ -124,7 +132,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "fr", @@ -135,7 +144,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "ga", @@ -146,6 +156,7 @@ var ( GroupSeparator: ',', DecimalSeparator: '.', MonetaryPre: [2]string{"€", "-€"}, + PercentSuf: "%", }, { Bcp: "hr", @@ -156,7 +167,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "it", @@ -167,7 +179,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: "%", }, { Bcp: "lb", @@ -178,7 +191,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "lt", @@ -189,7 +203,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "lv", @@ -200,7 +215,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: "%", }, { Bcp: "mt", @@ -211,6 +227,7 @@ var ( GroupSeparator: ',', DecimalSeparator: '.', MonetaryPre: [2]string{"€", "-€"}, + PercentSuf: "%", }, { Bcp: "nl", @@ -221,6 +238,7 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"€ ", "€ -"}, + PercentSuf: "%", }, { Bcp: "pt", @@ -231,6 +249,7 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"€ ", "€ -"}, + PercentSuf: "%", }, { Bcp: "sk", @@ -241,7 +260,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "sl", @@ -252,7 +272,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "sv", @@ -263,7 +284,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "tr", @@ -274,6 +296,7 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"€", "-€"}, + PercentPre: "%", }, /* Non-Eurozone locales */ { @@ -285,7 +308,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: "%", }, { Bcp: "ro", @@ -296,7 +320,8 @@ var ( GroupSeparator: '.', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: " %", }, { Bcp: "uk", @@ -307,7 +332,8 @@ var ( GroupSeparator: ' ', DecimalSeparator: ',', MonetaryPre: [2]string{"", "-"}, - MonetaryPost: " €", + MonetarySuf: " €", + PercentSuf: "%", }, } Printers map[string]Printer = make(map[string]Printer, len(locales)) @@ -394,13 +420,25 @@ func (p Printer) Ftoa(n float64) string { return bob.String() } -func (p Printer) Mitoa(n int) string { +func (p Printer) Itop(n int) string { + var bob strings.Builder + sprintfp(p.LocaleInfo, &bob, n) + return bob.String() +} + +func (p Printer) Ftop(n float64) string { + var bob strings.Builder + sprintfp(p.LocaleInfo, &bob, n) + return bob.String() +} + +func (p Printer) Itom(n int) string { var bob strings.Builder sprintfm(p.LocaleInfo, &bob, n) return bob.String() } -func (p Printer) Mftoa(n float64) string { +func (p Printer) Ftom(n float64) string { var bob strings.Builder sprintfm(p.LocaleInfo, &bob, n) return bob.String() @@ -542,12 +580,30 @@ func sprintfm(li LocaleInfo, bob *strings.Builder, v any) error { n := v.(int) htmlesc(bob, li.MonetaryPre[btoi(n >= 0)]) writeInt(bob, abs(n), li) - htmlesc(bob, li.MonetaryPost) + htmlesc(bob, li.MonetarySuf) case float64: n := v.(float64) htmlesc(bob, li.MonetaryPre[btoi(n >= 0)]) writeFloat(bob, abs(n), li) - htmlesc(bob, li.MonetaryPost) + htmlesc(bob, li.MonetarySuf) + default: + return errors.New("TODO") + } + return nil +} + +func sprintfp(li LocaleInfo, bob *strings.Builder, v any) error { + switch v.(type) { + case int: + n := v.(int) + htmlesc(bob, li.PercentPre) + writeInt(bob, n, li) + htmlesc(bob, li.PercentSuf) + case float64: + n := v.(float64) + htmlesc(bob, li.PercentPre) + writeFloat(bob, n, li) + htmlesc(bob, li.PercentSuf) default: return errors.New("TODO") } |