Support double-byte chars for formula functions LENB, RIGHTB and MIDB (#1478)
This commit is contained in:
parent
983cd76485
commit
f143dd5c34
46
calc.go
46
calc.go
|
@ -13426,9 +13426,7 @@ func (fn *formulaFuncs) LEFTB(argsList *list.List) formulaArg {
|
||||||
return fn.leftRight("LEFTB", argsList)
|
return fn.leftRight("LEFTB", argsList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// leftRight is an implementation of the formula functions LEFT, LEFTB, RIGHT,
|
// leftRight is an implementation of the formula functions LEFT, LEFTB, RIGHT, RIGHTB.
|
||||||
// RIGHTB. TODO: support DBCS include Japanese, Chinese (Simplified), Chinese
|
|
||||||
// (Traditional), and Korean.
|
|
||||||
func (fn *formulaFuncs) leftRight(name string, argsList *list.List) formulaArg {
|
func (fn *formulaFuncs) leftRight(name string, argsList *list.List) formulaArg {
|
||||||
if argsList.Len() < 1 {
|
if argsList.Len() < 1 {
|
||||||
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
|
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
|
||||||
|
@ -13447,10 +13445,22 @@ func (fn *formulaFuncs) leftRight(name string, argsList *list.List) formulaArg {
|
||||||
}
|
}
|
||||||
numChars = int(numArg.Number)
|
numChars = int(numArg.Number)
|
||||||
}
|
}
|
||||||
|
if name == "LEFTB" || name == "RIGHTB" {
|
||||||
|
if len(text) > numChars {
|
||||||
|
if name == "LEFTB" {
|
||||||
|
return newStringFormulaArg(text[:numChars])
|
||||||
|
}
|
||||||
|
// RIGHTB
|
||||||
|
return newStringFormulaArg(text[len(text)-numChars:])
|
||||||
|
}
|
||||||
|
return newStringFormulaArg(text)
|
||||||
|
}
|
||||||
|
// LEFT/RIGHT
|
||||||
if utf8.RuneCountInString(text) > numChars {
|
if utf8.RuneCountInString(text) > numChars {
|
||||||
if name == "LEFT" || name == "LEFTB" {
|
if name == "LEFT" {
|
||||||
return newStringFormulaArg(string([]rune(text)[:numChars]))
|
return newStringFormulaArg(string([]rune(text)[:numChars]))
|
||||||
}
|
}
|
||||||
|
// RIGHT
|
||||||
return newStringFormulaArg(string([]rune(text)[utf8.RuneCountInString(text)-numChars:]))
|
return newStringFormulaArg(string([]rune(text)[utf8.RuneCountInString(text)-numChars:]))
|
||||||
}
|
}
|
||||||
return newStringFormulaArg(text)
|
return newStringFormulaArg(text)
|
||||||
|
@ -13480,7 +13490,16 @@ func (fn *formulaFuncs) LENB(argsList *list.List) formulaArg {
|
||||||
if argsList.Len() != 1 {
|
if argsList.Len() != 1 {
|
||||||
return newErrorFormulaArg(formulaErrorVALUE, "LENB requires 1 string argument")
|
return newErrorFormulaArg(formulaErrorVALUE, "LENB requires 1 string argument")
|
||||||
}
|
}
|
||||||
return newStringFormulaArg(strconv.Itoa(len(argsList.Front().Value.(formulaArg).String)))
|
bytes := 0
|
||||||
|
for _, r := range []rune(argsList.Front().Value.(formulaArg).String) {
|
||||||
|
b := utf8.RuneLen(r)
|
||||||
|
if b == 1 {
|
||||||
|
bytes++
|
||||||
|
} else if b > 1 {
|
||||||
|
bytes += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newStringFormulaArg(strconv.Itoa(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOWER converts all characters in a supplied text string to lower case. The
|
// LOWER converts all characters in a supplied text string to lower case. The
|
||||||
|
@ -13528,6 +13547,19 @@ func (fn *formulaFuncs) mid(name string, argsList *list.List) formulaArg {
|
||||||
if startNum < 0 {
|
if startNum < 0 {
|
||||||
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
|
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
|
||||||
}
|
}
|
||||||
|
if name == "MIDB" {
|
||||||
|
textLen := len(text)
|
||||||
|
if startNum > textLen {
|
||||||
|
return newStringFormulaArg("")
|
||||||
|
}
|
||||||
|
startNum--
|
||||||
|
endNum := startNum + int(numCharsArg.Number)
|
||||||
|
if endNum > textLen+1 {
|
||||||
|
return newStringFormulaArg(text[startNum:])
|
||||||
|
}
|
||||||
|
return newStringFormulaArg(text[startNum:endNum])
|
||||||
|
}
|
||||||
|
// MID
|
||||||
textLen := utf8.RuneCountInString(text)
|
textLen := utf8.RuneCountInString(text)
|
||||||
if startNum > textLen {
|
if startNum > textLen {
|
||||||
return newStringFormulaArg("")
|
return newStringFormulaArg("")
|
||||||
|
@ -13535,9 +13567,9 @@ func (fn *formulaFuncs) mid(name string, argsList *list.List) formulaArg {
|
||||||
startNum--
|
startNum--
|
||||||
endNum := startNum + int(numCharsArg.Number)
|
endNum := startNum + int(numCharsArg.Number)
|
||||||
if endNum > textLen+1 {
|
if endNum > textLen+1 {
|
||||||
return newStringFormulaArg(text[startNum:])
|
return newStringFormulaArg(string([]rune(text)[startNum:]))
|
||||||
}
|
}
|
||||||
return newStringFormulaArg(text[startNum:endNum])
|
return newStringFormulaArg(string([]rune(text)[startNum:endNum]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROPER converts all characters in a supplied text string to proper case
|
// PROPER converts all characters in a supplied text string to proper case
|
||||||
|
|
14
calc_test.go
14
calc_test.go
|
@ -1709,11 +1709,15 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
"=LEFTB(\"Original Text\",13)": "Original Text",
|
"=LEFTB(\"Original Text\",13)": "Original Text",
|
||||||
"=LEFTB(\"Original Text\",20)": "Original Text",
|
"=LEFTB(\"Original Text\",20)": "Original Text",
|
||||||
// LEN
|
// LEN
|
||||||
"=LEN(\"\")": "0",
|
"=LEN(\"\")": "0",
|
||||||
"=LEN(D1)": "5",
|
"=LEN(D1)": "5",
|
||||||
|
"=LEN(\"テキスト\")": "4",
|
||||||
|
"=LEN(\"オリジナルテキスト\")": "9",
|
||||||
// LENB
|
// LENB
|
||||||
"=LENB(\"\")": "0",
|
"=LENB(\"\")": "0",
|
||||||
"=LENB(D1)": "5",
|
"=LENB(D1)": "5",
|
||||||
|
"=LENB(\"テキスト\")": "8",
|
||||||
|
"=LENB(\"オリジナルテキスト\")": "18",
|
||||||
// LOWER
|
// LOWER
|
||||||
"=LOWER(\"test\")": "test",
|
"=LOWER(\"test\")": "test",
|
||||||
"=LOWER(\"TEST\")": "test",
|
"=LOWER(\"TEST\")": "test",
|
||||||
|
@ -1725,6 +1729,8 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
"=MID(\"255 years\",3,1)": "5",
|
"=MID(\"255 years\",3,1)": "5",
|
||||||
"=MID(\"text\",3,6)": "xt",
|
"=MID(\"text\",3,6)": "xt",
|
||||||
"=MID(\"text\",6,0)": "",
|
"=MID(\"text\",6,0)": "",
|
||||||
|
"=MID(\"オリジナルテキスト\",6,4)": "テキスト",
|
||||||
|
"=MID(\"オリジナルテキスト\",3,5)": "ジナルテキ",
|
||||||
// MIDB
|
// MIDB
|
||||||
"=MIDB(\"Original Text\",7,1)": "a",
|
"=MIDB(\"Original Text\",7,1)": "a",
|
||||||
"=MIDB(\"Original Text\",4,7)": "ginal T",
|
"=MIDB(\"Original Text\",4,7)": "ginal T",
|
||||||
|
|
Loading…
Reference in New Issue