This closes #1819, formula calculation engine support array formulas

- Improve the defined name and table name validation rules
- Rename internal variable names to avoid the same with Go 1.21's built-in min and max functions
- Simplify data type conversion in internal code
- Update GitHub Actions workflow configuration, test on Go 1.22.x, and disable Go module cache
- Update dependencies module
This commit is contained in:
xuri 2024-02-26 02:22:51 +08:00
parent 02b84a906c
commit 688808b2b4
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
14 changed files with 443 additions and 260 deletions

View File

@ -5,7 +5,7 @@ jobs:
test: test:
strategy: strategy:
matrix: matrix:
go-version: [1.18.x, 1.19.x, 1.20.x, '>=1.21.1'] go-version: [1.18.x, 1.19.x, 1.20.x, '>=1.21.1', 1.22.x]
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
targetplatform: [x86, x64] targetplatform: [x86, x64]
@ -17,6 +17,7 @@ jobs:
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
cache: false
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4

220
calc.go
View File

@ -281,6 +281,10 @@ func (fa formulaArg) Value() (value string) {
return fmt.Sprintf("%g", fa.Number) return fmt.Sprintf("%g", fa.Number)
case ArgString: case ArgString:
return fa.String return fa.String
case ArgMatrix:
if args := fa.ToList(); len(args) > 0 {
return args[0].Value()
}
case ArgError: case ArgError:
return fa.Error return fa.Error
} }
@ -299,6 +303,10 @@ func (fa formulaArg) ToNumber() formulaArg {
} }
case ArgNumber: case ArgNumber:
n = fa.Number n = fa.Number
case ArgMatrix:
if args := fa.ToList(); len(args) > 0 {
return args[0].ToNumber()
}
} }
return newNumberFormulaArg(n) return newNumberFormulaArg(n)
} }
@ -920,9 +928,14 @@ func newEmptyFormulaArg() formulaArg {
// //
// TODO: handle subtypes: Nothing, Text, Logical, Error, Concatenation, Intersection, Union // TODO: handle subtypes: Nothing, Text, Logical, Error, Concatenation, Intersection, Union
func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.Token) (formulaArg, error) { func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.Token) (formulaArg, error) {
var err error var (
opdStack, optStack, opfStack, opfdStack, opftStack, argsStack := NewStack(), NewStack(), NewStack(), NewStack(), NewStack(), NewStack() err error
var inArray, inArrayRow bool inArray, inArrayRow bool
formulaArray [][]formulaArg
formulaArrayRow []formulaArg
opdStack, optStack, opfStack = NewStack(), NewStack(), NewStack()
opfdStack, opftStack, argsStack = NewStack(), NewStack(), NewStack()
)
for i := 0; i < len(tokens); i++ { for i := 0; i < len(tokens); i++ {
token := tokens[i] token := tokens[i]
@ -936,11 +949,11 @@ func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.T
// function start // function start
if isFunctionStartToken(token) { if isFunctionStartToken(token) {
if token.TValue == "ARRAY" { if token.TValue == "ARRAY" {
inArray = true inArray, formulaArray = true, [][]formulaArg{}
continue continue
} }
if token.TValue == "ARRAYROW" { if token.TValue == "ARRAYROW" {
inArrayRow = true inArrayRow, formulaArrayRow = true, []formulaArg{}
continue continue
} }
opfStack.Push(token) opfStack.Push(token)
@ -1021,14 +1034,16 @@ func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.T
} }
if inArrayRow && isOperand(token) { if inArrayRow && isOperand(token) {
formulaArrayRow = append(formulaArrayRow, opfdStack.Pop().(formulaArg))
continue continue
} }
if inArrayRow && isFunctionStopToken(token) { if inArrayRow && isFunctionStopToken(token) {
formulaArray = append(formulaArray, formulaArrayRow)
inArrayRow = false inArrayRow = false
continue continue
} }
if inArray && isFunctionStopToken(token) { if inArray && isFunctionStopToken(token) {
argsStack.Peek().(*list.List).PushBack(opfdStack.Pop()) argsStack.Peek().(*list.List).PushBack(newMatrixFormulaArg(formulaArray))
inArray = false inArray = false
continue continue
} }
@ -1825,13 +1840,13 @@ func (fn *formulaFuncs) bassel(argsList *list.List, modfied bool) formulaArg {
if n.Type != ArgNumber { if n.Type != ArgNumber {
return n return n
} }
max, x1 := 100, x.Number*0.5 maxVal, x1 := 100, x.Number*0.5
x2 := x1 * x1 x2 := x1 * x1
x1 = math.Pow(x1, n.Number) x1 = math.Pow(x1, n.Number)
n1, n2, n3, n4, add := fact(n.Number), 1.0, 0.0, n.Number, false n1, n2, n3, n4, add := fact(n.Number), 1.0, 0.0, n.Number, false
result := x1 / n1 result := x1 / n1
t := result * 0.9 t := result * 0.9
for result != t && max != 0 { for result != t && maxVal != 0 {
x1 *= x2 x1 *= x2
n3++ n3++
n1 *= n3 n1 *= n3
@ -1844,7 +1859,7 @@ func (fn *formulaFuncs) bassel(argsList *list.List, modfied bool) formulaArg {
} else { } else {
result -= r result -= r
} }
max-- maxVal--
add = !add add = !add
} }
return newNumberFormulaArg(result) return newNumberFormulaArg(result)
@ -2151,8 +2166,8 @@ func (fn *formulaFuncs) bitwise(name string, argsList *list.List) formulaArg {
if num1.Type != ArgNumber || num2.Type != ArgNumber { if num1.Type != ArgNumber || num2.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
} }
max := math.Pow(2, 48) - 1 maxVal := math.Pow(2, 48) - 1
if num1.Number < 0 || num1.Number > max || num2.Number < 0 || num2.Number > max { if num1.Number < 0 || num1.Number > maxVal || num2.Number < 0 || num2.Number > maxVal {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
} }
bitwiseFuncMap := map[string]func(a, b int) int{ bitwiseFuncMap := map[string]func(a, b int) int{
@ -6958,9 +6973,9 @@ func (fn *formulaFuncs) BETAdotINV(argsList *list.List) formulaArg {
// incompleteGamma is an implementation of the incomplete gamma function. // incompleteGamma is an implementation of the incomplete gamma function.
func incompleteGamma(a, x float64) float64 { func incompleteGamma(a, x float64) float64 {
max := 32 maxVal := 32
summer := 0.0 summer := 0.0
for n := 0; n <= max; n++ { for n := 0; n <= maxVal; n++ {
divisor := a divisor := a
for i := 1; i <= n; i++ { for i := 1; i <= n; i++ {
divisor *= a + float64(i) divisor *= a + float64(i)
@ -7079,7 +7094,7 @@ func (fn *formulaFuncs) BINOMdotDISTdotRANGE(argsList *list.List) formulaArg {
// binominv implement inverse of the binomial distribution calculation. // binominv implement inverse of the binomial distribution calculation.
func binominv(n, p, alpha float64) float64 { func binominv(n, p, alpha float64) float64 {
q, i, sum, max := 1-p, 0.0, 0.0, 0.0 q, i, sum, maxVal := 1-p, 0.0, 0.0, 0.0
n = math.Floor(n) n = math.Floor(n)
if q > p { if q > p {
factor := math.Pow(q, n) factor := math.Pow(q, n)
@ -7091,8 +7106,8 @@ func binominv(n, p, alpha float64) float64 {
return i return i
} }
factor := math.Pow(p, n) factor := math.Pow(p, n)
sum, max = 1-factor, n sum, maxVal = 1-factor, n
for i = 0; i < max && sum >= alpha; i++ { for i = 0; i < maxVal && sum >= alpha; i++ {
factor *= (n - i) / (i + 1) * q / p factor *= (n - i) / (i + 1) * q / p
sum -= factor sum -= factor
} }
@ -8078,10 +8093,13 @@ func (fn *formulaFuncs) FORECASTdotLINEAR(argsList *list.List) formulaArg {
return fn.pearsonProduct("FORECAST.LINEAR", 3, argsList) return fn.pearsonProduct("FORECAST.LINEAR", 3, argsList)
} }
// maritxToSortedColumnList convert matrix formula arguments to a ascending // matrixToSortedColumnList convert matrix formula arguments to a ascending
// order list by column. // order list by column.
func maritxToSortedColumnList(arg formulaArg) formulaArg { func matrixToSortedColumnList(arg formulaArg) formulaArg {
mtx, cols := []formulaArg{}, len(arg.Matrix[0]) var (
mtx []formulaArg
cols = len(arg.Matrix[0])
)
for colIdx := 0; colIdx < cols; colIdx++ { for colIdx := 0; colIdx < cols; colIdx++ {
for _, row := range arg.Matrix { for _, row := range arg.Matrix {
cell := row[colIdx] cell := row[colIdx]
@ -8120,14 +8138,14 @@ func (fn *formulaFuncs) FREQUENCY(argsList *list.List) formulaArg {
c [][]formulaArg c [][]formulaArg
i, j int i, j int
) )
if dataMtx = maritxToSortedColumnList(data); dataMtx.Type != ArgList { if dataMtx = matrixToSortedColumnList(data); dataMtx.Type != ArgList {
return dataMtx return dataMtx
} }
if binsMtx = maritxToSortedColumnList(bins); binsMtx.Type != ArgList { if binsMtx = matrixToSortedColumnList(bins); binsMtx.Type != ArgList {
return binsMtx return binsMtx
} }
for row := 0; row < len(binsMtx.List)+1; row++ { for row := 0; row < len(binsMtx.List)+1; row++ {
rows := []formulaArg{} var rows []formulaArg
for col := 0; col < 1; col++ { for col := 0; col < 1; col++ {
rows = append(rows, newNumberFormulaArg(0)) rows = append(rows, newNumberFormulaArg(0))
} }
@ -8349,8 +8367,8 @@ func (fn *formulaFuncs) GEOMEAN(argsList *list.List) formulaArg {
return product return product
} }
count := fn.COUNT(argsList) count := fn.COUNT(argsList)
min := fn.MIN(argsList) minVal := fn.MIN(argsList)
if product.Number > 0 && min.Number > 0 { if product.Number > 0 && minVal.Number > 0 {
return newNumberFormulaArg(math.Pow(product.Number, 1/count.Number)) return newNumberFormulaArg(math.Pow(product.Number, 1/count.Number))
} }
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
@ -9055,7 +9073,7 @@ func (fn *formulaFuncs) HARMEAN(argsList *list.List) formulaArg {
if argsList.Len() < 1 { if argsList.Len() < 1 {
return newErrorFormulaArg(formulaErrorVALUE, "HARMEAN requires at least 1 argument") return newErrorFormulaArg(formulaErrorVALUE, "HARMEAN requires at least 1 argument")
} }
if min := fn.MIN(argsList); min.Number < 0 { if minVal := fn.MIN(argsList); minVal.Number < 0 {
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA) return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
} }
number, val, cnt := 0.0, 0.0, 0.0 number, val, cnt := 0.0, 0.0, 0.0
@ -10002,7 +10020,7 @@ func (fn *formulaFuncs) MAX(argsList *list.List) formulaArg {
if argsList.Len() == 0 { if argsList.Len() == 0 {
return newErrorFormulaArg(formulaErrorVALUE, "MAX requires at least 1 argument") return newErrorFormulaArg(formulaErrorVALUE, "MAX requires at least 1 argument")
} }
return fn.max(false, argsList) return fn.maxValue(false, argsList)
} }
// MAXA function returns the largest value from a supplied set of numeric // MAXA function returns the largest value from a supplied set of numeric
@ -10015,7 +10033,7 @@ func (fn *formulaFuncs) MAXA(argsList *list.List) formulaArg {
if argsList.Len() == 0 { if argsList.Len() == 0 {
return newErrorFormulaArg(formulaErrorVALUE, "MAXA requires at least 1 argument") return newErrorFormulaArg(formulaErrorVALUE, "MAXA requires at least 1 argument")
} }
return fn.max(true, argsList) return fn.maxValue(true, argsList)
} }
// MAXIFS function returns the maximum value from a subset of values that are // MAXIFS function returns the maximum value from a subset of values that are
@ -10031,36 +10049,36 @@ func (fn *formulaFuncs) MAXIFS(argsList *list.List) formulaArg {
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA) return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
} }
var args []formulaArg var args []formulaArg
max, maxRange := -math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix maxVal, maxRange := -math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix
for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() { for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
args = append(args, arg.Value.(formulaArg)) args = append(args, arg.Value.(formulaArg))
} }
for _, ref := range formulaIfsMatch(args) { for _, ref := range formulaIfsMatch(args) {
if num := maxRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && max < num.Number { if num := maxRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && maxVal < num.Number {
max = num.Number maxVal = num.Number
} }
} }
if max == -math.MaxFloat64 { if maxVal == -math.MaxFloat64 {
max = 0 maxVal = 0
} }
return newNumberFormulaArg(max) return newNumberFormulaArg(maxVal)
} }
// calcListMatrixMax is part of the implementation max. // calcListMatrixMax is part of the implementation max.
func calcListMatrixMax(maxa bool, max float64, arg formulaArg) float64 { func calcListMatrixMax(maxa bool, maxVal float64, arg formulaArg) float64 {
for _, cell := range arg.ToList() { for _, cell := range arg.ToList() {
if cell.Type == ArgNumber && cell.Number > max { if cell.Type == ArgNumber && cell.Number > maxVal {
if maxa && cell.Boolean || !cell.Boolean { if maxa && cell.Boolean || !cell.Boolean {
max = cell.Number maxVal = cell.Number
} }
} }
} }
return max return maxVal
} }
// max is an implementation of the formula functions MAX and MAXA. // maxValue is an implementation of the formula functions MAX and MAXA.
func (fn *formulaFuncs) max(maxa bool, argsList *list.List) formulaArg { func (fn *formulaFuncs) maxValue(maxa bool, argsList *list.List) formulaArg {
max := -math.MaxFloat64 maxVal := -math.MaxFloat64
for token := argsList.Front(); token != nil; token = token.Next() { for token := argsList.Front(); token != nil; token = token.Next() {
arg := token.Value.(formulaArg) arg := token.Value.(formulaArg)
switch arg.Type { switch arg.Type {
@ -10069,29 +10087,29 @@ func (fn *formulaFuncs) max(maxa bool, argsList *list.List) formulaArg {
continue continue
} else { } else {
num := arg.ToBool() num := arg.ToBool()
if num.Type == ArgNumber && num.Number > max { if num.Type == ArgNumber && num.Number > maxVal {
max = num.Number maxVal = num.Number
continue continue
} }
} }
num := arg.ToNumber() num := arg.ToNumber()
if num.Type != ArgError && num.Number > max { if num.Type != ArgError && num.Number > maxVal {
max = num.Number maxVal = num.Number
} }
case ArgNumber: case ArgNumber:
if arg.Number > max { if arg.Number > maxVal {
max = arg.Number maxVal = arg.Number
} }
case ArgList, ArgMatrix: case ArgList, ArgMatrix:
max = calcListMatrixMax(maxa, max, arg) maxVal = calcListMatrixMax(maxa, maxVal, arg)
case ArgError: case ArgError:
return arg return arg
} }
} }
if max == -math.MaxFloat64 { if maxVal == -math.MaxFloat64 {
max = 0 maxVal = 0
} }
return newNumberFormulaArg(max) return newNumberFormulaArg(maxVal)
} }
// MEDIAN function returns the statistical median (the middle value) of a list // MEDIAN function returns the statistical median (the middle value) of a list
@ -10145,7 +10163,7 @@ func (fn *formulaFuncs) MIN(argsList *list.List) formulaArg {
if argsList.Len() == 0 { if argsList.Len() == 0 {
return newErrorFormulaArg(formulaErrorVALUE, "MIN requires at least 1 argument") return newErrorFormulaArg(formulaErrorVALUE, "MIN requires at least 1 argument")
} }
return fn.min(false, argsList) return fn.minValue(false, argsList)
} }
// MINA function returns the smallest value from a supplied set of numeric // MINA function returns the smallest value from a supplied set of numeric
@ -10158,7 +10176,7 @@ func (fn *formulaFuncs) MINA(argsList *list.List) formulaArg {
if argsList.Len() == 0 { if argsList.Len() == 0 {
return newErrorFormulaArg(formulaErrorVALUE, "MINA requires at least 1 argument") return newErrorFormulaArg(formulaErrorVALUE, "MINA requires at least 1 argument")
} }
return fn.min(true, argsList) return fn.minValue(true, argsList)
} }
// MINIFS function returns the minimum value from a subset of values that are // MINIFS function returns the minimum value from a subset of values that are
@ -10174,36 +10192,36 @@ func (fn *formulaFuncs) MINIFS(argsList *list.List) formulaArg {
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA) return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
} }
var args []formulaArg var args []formulaArg
min, minRange := math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix minVal, minRange := math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix
for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() { for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() {
args = append(args, arg.Value.(formulaArg)) args = append(args, arg.Value.(formulaArg))
} }
for _, ref := range formulaIfsMatch(args) { for _, ref := range formulaIfsMatch(args) {
if num := minRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && min > num.Number { if num := minRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && minVal > num.Number {
min = num.Number minVal = num.Number
} }
} }
if min == math.MaxFloat64 { if minVal == math.MaxFloat64 {
min = 0 minVal = 0
} }
return newNumberFormulaArg(min) return newNumberFormulaArg(minVal)
} }
// calcListMatrixMin is part of the implementation min. // calcListMatrixMin is part of the implementation min.
func calcListMatrixMin(mina bool, min float64, arg formulaArg) float64 { func calcListMatrixMin(mina bool, minVal float64, arg formulaArg) float64 {
for _, cell := range arg.ToList() { for _, cell := range arg.ToList() {
if cell.Type == ArgNumber && cell.Number < min { if cell.Type == ArgNumber && cell.Number < minVal {
if mina && cell.Boolean || !cell.Boolean { if mina && cell.Boolean || !cell.Boolean {
min = cell.Number minVal = cell.Number
} }
} }
} }
return min return minVal
} }
// min is an implementation of the formula functions MIN and MINA. // minValue is an implementation of the formula functions MIN and MINA.
func (fn *formulaFuncs) min(mina bool, argsList *list.List) formulaArg { func (fn *formulaFuncs) minValue(mina bool, argsList *list.List) formulaArg {
min := math.MaxFloat64 minVal := math.MaxFloat64
for token := argsList.Front(); token != nil; token = token.Next() { for token := argsList.Front(); token != nil; token = token.Next() {
arg := token.Value.(formulaArg) arg := token.Value.(formulaArg)
switch arg.Type { switch arg.Type {
@ -10212,29 +10230,29 @@ func (fn *formulaFuncs) min(mina bool, argsList *list.List) formulaArg {
continue continue
} else { } else {
num := arg.ToBool() num := arg.ToBool()
if num.Type == ArgNumber && num.Number < min { if num.Type == ArgNumber && num.Number < minVal {
min = num.Number minVal = num.Number
continue continue
} }
} }
num := arg.ToNumber() num := arg.ToNumber()
if num.Type != ArgError && num.Number < min { if num.Type != ArgError && num.Number < minVal {
min = num.Number minVal = num.Number
} }
case ArgNumber: case ArgNumber:
if arg.Number < min { if arg.Number < minVal {
min = arg.Number minVal = arg.Number
} }
case ArgList, ArgMatrix: case ArgList, ArgMatrix:
min = calcListMatrixMin(mina, min, arg) minVal = calcListMatrixMin(mina, minVal, arg)
case ArgError: case ArgError:
return arg return arg
} }
} }
if min == math.MaxFloat64 { if minVal == math.MaxFloat64 {
min = 0 minVal = 0
} }
return newNumberFormulaArg(min) return newNumberFormulaArg(minVal)
} }
// pearsonProduct is an implementation of the formula functions FORECAST, // pearsonProduct is an implementation of the formula functions FORECAST,
@ -13554,7 +13572,7 @@ func (fn *formulaFuncs) code(name string, argsList *list.List) formulaArg {
// //
// CONCAT(text1,[text2],...) // CONCAT(text1,[text2],...)
func (fn *formulaFuncs) CONCAT(argsList *list.List) formulaArg { func (fn *formulaFuncs) CONCAT(argsList *list.List) formulaArg {
return fn.concat("CONCAT", argsList) return fn.concat(argsList)
} }
// CONCATENATE function joins together a series of supplied text strings into // CONCATENATE function joins together a series of supplied text strings into
@ -13562,12 +13580,12 @@ func (fn *formulaFuncs) CONCAT(argsList *list.List) formulaArg {
// //
// CONCATENATE(text1,[text2],...) // CONCATENATE(text1,[text2],...)
func (fn *formulaFuncs) CONCATENATE(argsList *list.List) formulaArg { func (fn *formulaFuncs) CONCATENATE(argsList *list.List) formulaArg {
return fn.concat("CONCATENATE", argsList) return fn.concat(argsList)
} }
// concat is an implementation of the formula functions CONCAT and // concat is an implementation of the formula functions CONCAT and
// CONCATENATE. // CONCATENATE.
func (fn *formulaFuncs) concat(name string, argsList *list.List) formulaArg { func (fn *formulaFuncs) concat(argsList *list.List) formulaArg {
var buf bytes.Buffer var buf bytes.Buffer
for arg := argsList.Front(); arg != nil; arg = arg.Next() { for arg := argsList.Front(); arg != nil; arg = arg.Next() {
for _, cell := range arg.Value.(formulaArg).ToList() { for _, cell := range arg.Value.(formulaArg).ToList() {
@ -13831,16 +13849,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")
} }
bytes := 0 result := 0
for _, r := range argsList.Front().Value.(formulaArg).Value() { for _, r := range argsList.Front().Value.(formulaArg).Value() {
b := utf8.RuneLen(r) b := utf8.RuneLen(r)
if b == 1 { if b == 1 {
bytes++ result++
} else if b > 1 { } else if b > 1 {
bytes += 2 result += 2
} }
} }
return newNumberFormulaArg(float64(bytes)) return newNumberFormulaArg(float64(result))
} }
// 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
@ -14774,7 +14792,7 @@ func (fn *formulaFuncs) COLUMN(argsList *list.List) formulaArg {
// calcColsRowsMinMax calculation min and max value for given formula arguments // calcColsRowsMinMax calculation min and max value for given formula arguments
// sequence of the formula functions COLUMNS and ROWS. // sequence of the formula functions COLUMNS and ROWS.
func calcColsRowsMinMax(cols bool, argsList *list.List) (min, max int) { func calcColsRowsMinMax(cols bool, argsList *list.List) (minVal, maxVal int) {
getVal := func(cols bool, cell cellRef) int { getVal := func(cols bool, cell cellRef) int {
if cols { if cols {
return cell.Col return cell.Col
@ -14784,22 +14802,22 @@ func calcColsRowsMinMax(cols bool, argsList *list.List) (min, max int) {
if argsList.Front().Value.(formulaArg).cellRanges != nil && argsList.Front().Value.(formulaArg).cellRanges.Len() > 0 { if argsList.Front().Value.(formulaArg).cellRanges != nil && argsList.Front().Value.(formulaArg).cellRanges.Len() > 0 {
crs := argsList.Front().Value.(formulaArg).cellRanges crs := argsList.Front().Value.(formulaArg).cellRanges
for cr := crs.Front(); cr != nil; cr = cr.Next() { for cr := crs.Front(); cr != nil; cr = cr.Next() {
if min == 0 { if minVal == 0 {
min = getVal(cols, cr.Value.(cellRange).From) minVal = getVal(cols, cr.Value.(cellRange).From)
} }
if max < getVal(cols, cr.Value.(cellRange).To) { if maxVal < getVal(cols, cr.Value.(cellRange).To) {
max = getVal(cols, cr.Value.(cellRange).To) maxVal = getVal(cols, cr.Value.(cellRange).To)
} }
} }
} }
if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 { if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
cr := argsList.Front().Value.(formulaArg).cellRefs cr := argsList.Front().Value.(formulaArg).cellRefs
for refs := cr.Front(); refs != nil; refs = refs.Next() { for refs := cr.Front(); refs != nil; refs = refs.Next() {
if min == 0 { if minVal == 0 {
min = getVal(cols, refs.Value.(cellRef)) minVal = getVal(cols, refs.Value.(cellRef))
} }
if max < getVal(cols, refs.Value.(cellRef)) { if maxVal < getVal(cols, refs.Value.(cellRef)) {
max = getVal(cols, refs.Value.(cellRef)) maxVal = getVal(cols, refs.Value.(cellRef))
} }
} }
} }
@ -14814,13 +14832,13 @@ func (fn *formulaFuncs) COLUMNS(argsList *list.List) formulaArg {
if argsList.Len() != 1 { if argsList.Len() != 1 {
return newErrorFormulaArg(formulaErrorVALUE, "COLUMNS requires 1 argument") return newErrorFormulaArg(formulaErrorVALUE, "COLUMNS requires 1 argument")
} }
min, max := calcColsRowsMinMax(true, argsList) minVal, maxVal := calcColsRowsMinMax(true, argsList)
if max == MaxColumns { if maxVal == MaxColumns {
return newNumberFormulaArg(float64(MaxColumns)) return newNumberFormulaArg(float64(MaxColumns))
} }
result := max - min + 1 result := maxVal - minVal + 1
if max == min { if maxVal == minVal {
if min == 0 { if minVal == 0 {
return newErrorFormulaArg(formulaErrorVALUE, "invalid reference") return newErrorFormulaArg(formulaErrorVALUE, "invalid reference")
} }
return newNumberFormulaArg(float64(1)) return newNumberFormulaArg(float64(1))
@ -15555,13 +15573,13 @@ func (fn *formulaFuncs) ROWS(argsList *list.List) formulaArg {
if argsList.Len() != 1 { if argsList.Len() != 1 {
return newErrorFormulaArg(formulaErrorVALUE, "ROWS requires 1 argument") return newErrorFormulaArg(formulaErrorVALUE, "ROWS requires 1 argument")
} }
min, max := calcColsRowsMinMax(false, argsList) minVal, maxVal := calcColsRowsMinMax(false, argsList)
if max == TotalRows { if maxVal == TotalRows {
return newNumberFormulaArg(TotalRows) return newNumberFormulaArg(TotalRows)
} }
result := max - min + 1 result := maxVal - minVal + 1
if max == min { if maxVal == minVal {
if min == 0 { if minVal == 0 {
return newErrorFormulaArg(formulaErrorVALUE, "invalid reference") return newErrorFormulaArg(formulaErrorVALUE, "invalid reference")
} }
return newNumberFormulaArg(float64(1)) return newNumberFormulaArg(float64(1))

12
col.go
View File

@ -354,20 +354,20 @@ func (f *File) GetColOutlineLevel(sheet, col string) (uint8, error) {
} }
// parseColRange parse and convert column range with column name to the column number. // parseColRange parse and convert column range with column name to the column number.
func (f *File) parseColRange(columns string) (min, max int, err error) { func (f *File) parseColRange(columns string) (minVal, maxVal int, err error) {
colsTab := strings.Split(columns, ":") colsTab := strings.Split(columns, ":")
min, err = ColumnNameToNumber(colsTab[0]) minVal, err = ColumnNameToNumber(colsTab[0])
if err != nil { if err != nil {
return return
} }
max = min maxVal = minVal
if len(colsTab) == 2 { if len(colsTab) == 2 {
if max, err = ColumnNameToNumber(colsTab[1]); err != nil { if maxVal, err = ColumnNameToNumber(colsTab[1]); err != nil {
return return
} }
} }
if max < min { if maxVal < minVal {
min, max = max, min minVal, maxVal = maxVal, minVal
} }
return return
} }

View File

@ -68,22 +68,22 @@ func TestTimeFromExcelTime(t *testing.T) {
}) })
} }
for hour := 0; hour < 24; hour++ { for hour := 0; hour < 24; hour++ {
for min := 0; min < 60; min++ { for minVal := 0; minVal < 60; minVal++ {
for sec := 0; sec < 60; sec++ { for sec := 0; sec < 60; sec++ {
date := time.Date(2021, time.December, 30, hour, min, sec, 0, time.UTC) date := time.Date(2021, time.December, 30, hour, minVal, sec, 0, time.UTC)
// Test use 1900 date system // Test use 1900 date system
excel1900Time, err := timeToExcelTime(date, false) excel1900Time, err := timeToExcelTime(date, false)
assert.NoError(t, err) assert.NoError(t, err)
date1900Out := timeFromExcelTime(excel1900Time, false) date1900Out := timeFromExcelTime(excel1900Time, false)
assert.EqualValues(t, hour, date1900Out.Hour()) assert.EqualValues(t, hour, date1900Out.Hour())
assert.EqualValues(t, min, date1900Out.Minute()) assert.EqualValues(t, minVal, date1900Out.Minute())
assert.EqualValues(t, sec, date1900Out.Second()) assert.EqualValues(t, sec, date1900Out.Second())
// Test use 1904 date system // Test use 1904 date system
excel1904Time, err := timeToExcelTime(date, true) excel1904Time, err := timeToExcelTime(date, true)
assert.NoError(t, err) assert.NoError(t, err)
date1904Out := timeFromExcelTime(excel1904Time, true) date1904Out := timeFromExcelTime(excel1904Time, true)
assert.EqualValues(t, hour, date1904Out.Hour()) assert.EqualValues(t, hour, date1904Out.Hour())
assert.EqualValues(t, min, date1904Out.Minute()) assert.EqualValues(t, minVal, date1904Out.Minute())
assert.EqualValues(t, sec, date1904Out.Second()) assert.EqualValues(t, sec, date1904Out.Second())
} }
} }

View File

@ -980,21 +980,21 @@ func (f *File) drawChartSeriesDLbls(i int, opts *Chart) *cDLbls {
// drawPlotAreaCatAx provides a function to draw the c:catAx element. // drawPlotAreaCatAx provides a function to draw the c:catAx element.
func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs { func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs {
max := &attrValFloat{Val: opts.XAxis.Maximum} maxVal := &attrValFloat{Val: opts.XAxis.Maximum}
min := &attrValFloat{Val: opts.XAxis.Minimum} minVal := &attrValFloat{Val: opts.XAxis.Minimum}
if opts.XAxis.Maximum == nil { if opts.XAxis.Maximum == nil {
max = nil maxVal = nil
} }
if opts.XAxis.Minimum == nil { if opts.XAxis.Minimum == nil {
min = nil minVal = nil
} }
axs := []*cAxs{ axs := []*cAxs{
{ {
AxID: &attrValInt{Val: intPtr(100000000)}, AxID: &attrValInt{Val: intPtr(100000000)},
Scaling: &cScaling{ Scaling: &cScaling{
Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])}, Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])},
Max: max, Max: maxVal,
Min: min, Min: minVal,
}, },
Delete: &attrValBool{Val: boolPtr(opts.XAxis.None)}, Delete: &attrValBool{Val: boolPtr(opts.XAxis.None)},
AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])}, AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])},
@ -1030,8 +1030,8 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs {
AxID: &attrValInt{Val: intPtr(opts.XAxis.axID)}, AxID: &attrValInt{Val: intPtr(opts.XAxis.axID)},
Scaling: &cScaling{ Scaling: &cScaling{
Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])}, Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])},
Max: max, Max: maxVal,
Min: min, Min: minVal,
}, },
Delete: &attrValBool{Val: boolPtr(true)}, Delete: &attrValBool{Val: boolPtr(true)},
AxPos: &attrValString{Val: stringPtr("b")}, AxPos: &attrValString{Val: stringPtr("b")},
@ -1052,13 +1052,13 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs {
// drawPlotAreaValAx provides a function to draw the c:valAx element. // drawPlotAreaValAx provides a function to draw the c:valAx element.
func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs { func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
max := &attrValFloat{Val: opts.YAxis.Maximum} maxVal := &attrValFloat{Val: opts.YAxis.Maximum}
min := &attrValFloat{Val: opts.YAxis.Minimum} minVal := &attrValFloat{Val: opts.YAxis.Minimum}
if opts.YAxis.Maximum == nil { if opts.YAxis.Maximum == nil {
max = nil maxVal = nil
} }
if opts.YAxis.Minimum == nil { if opts.YAxis.Minimum == nil {
min = nil minVal = nil
} }
var logBase *attrValFloat var logBase *attrValFloat
if opts.YAxis.LogBase >= 2 && opts.YAxis.LogBase <= 1000 { if opts.YAxis.LogBase >= 2 && opts.YAxis.LogBase <= 1000 {
@ -1070,8 +1070,8 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
Scaling: &cScaling{ Scaling: &cScaling{
LogBase: logBase, LogBase: logBase,
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])}, Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
Max: max, Max: maxVal,
Min: min, Min: minVal,
}, },
Delete: &attrValBool{Val: boolPtr(opts.YAxis.None)}, Delete: &attrValBool{Val: boolPtr(opts.YAxis.None)},
AxPos: &attrValString{Val: stringPtr(valAxPos[opts.YAxis.ReverseOrder])}, AxPos: &attrValString{Val: stringPtr(valAxPos[opts.YAxis.ReverseOrder])},
@ -1109,8 +1109,8 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
AxID: &attrValInt{Val: intPtr(opts.YAxis.axID)}, AxID: &attrValInt{Val: intPtr(opts.YAxis.axID)},
Scaling: &cScaling{ Scaling: &cScaling{
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])}, Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
Max: max, Max: maxVal,
Min: min, Min: minVal,
}, },
Delete: &attrValBool{Val: boolPtr(false)}, Delete: &attrValBool{Val: boolPtr(false)},
AxPos: &attrValString{Val: stringPtr("r")}, AxPos: &attrValString{Val: stringPtr("r")},
@ -1129,21 +1129,21 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
// drawPlotAreaSerAx provides a function to draw the c:serAx element. // drawPlotAreaSerAx provides a function to draw the c:serAx element.
func (f *File) drawPlotAreaSerAx(opts *Chart) []*cAxs { func (f *File) drawPlotAreaSerAx(opts *Chart) []*cAxs {
max := &attrValFloat{Val: opts.YAxis.Maximum} maxVal := &attrValFloat{Val: opts.YAxis.Maximum}
min := &attrValFloat{Val: opts.YAxis.Minimum} minVal := &attrValFloat{Val: opts.YAxis.Minimum}
if opts.YAxis.Maximum == nil { if opts.YAxis.Maximum == nil {
max = nil maxVal = nil
} }
if opts.YAxis.Minimum == nil { if opts.YAxis.Minimum == nil {
min = nil minVal = nil
} }
return []*cAxs{ return []*cAxs{
{ {
AxID: &attrValInt{Val: intPtr(100000005)}, AxID: &attrValInt{Val: intPtr(100000005)},
Scaling: &cScaling{ Scaling: &cScaling{
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])}, Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
Max: max, Max: maxVal,
Min: min, Min: minVal,
}, },
Delete: &attrValBool{Val: boolPtr(opts.YAxis.None)}, Delete: &attrValBool{Val: boolPtr(opts.YAxis.None)},
AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])}, AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])},

View File

@ -334,7 +334,7 @@ func (ws *xlsxWorksheet) checkSheet() {
// with r="0" attribute. // with r="0" attribute.
func (ws *xlsxWorksheet) checkSheetRows() (int, []xlsxRow) { func (ws *xlsxWorksheet) checkSheetRows() (int, []xlsxRow) {
var ( var (
row, max int row, maxVal int
r0 []xlsxRow r0 []xlsxRow
maxRowNum = func(num int, c []xlsxC) int { maxRowNum = func(num int, c []xlsxC) int {
for _, cell := range c { for _, cell := range c {
@ -351,8 +351,8 @@ func (ws *xlsxWorksheet) checkSheetRows() (int, []xlsxRow) {
continue continue
} }
if i == 0 && *r.R == 0 { if i == 0 && *r.R == 0 {
if num := maxRowNum(row, r.C); num > max { if num := maxRowNum(row, r.C); num > maxVal {
max = num maxVal = num
} }
r0 = append(r0, r) r0 = append(r0, r)
continue continue
@ -361,8 +361,8 @@ func (ws *xlsxWorksheet) checkSheetRows() (int, []xlsxRow) {
row = *r.R row = *r.R
} }
} }
if max > row { if maxVal > row {
row = max row = maxVal
} }
return row, r0 return row, r0
} }

4
go.mod
View File

@ -8,9 +8,9 @@ require (
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05
golang.org/x/crypto v0.18.0 golang.org/x/crypto v0.19.0
golang.org/x/image v0.14.0 golang.org/x/image v0.14.0
golang.org/x/net v0.20.0 golang.org/x/net v0.21.0
golang.org/x/text v0.14.0 golang.org/x/text v0.14.0
) )

8
go.sum
View File

@ -15,12 +15,12 @@ github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

16
hsl.go
View File

@ -65,21 +65,21 @@ func RGBToHSL(r, g, b uint8) (h, s, l float64) {
fR := float64(r) / 255 fR := float64(r) / 255
fG := float64(g) / 255 fG := float64(g) / 255
fB := float64(b) / 255 fB := float64(b) / 255
max := math.Max(math.Max(fR, fG), fB) maxVal := math.Max(math.Max(fR, fG), fB)
min := math.Min(math.Min(fR, fG), fB) minVal := math.Min(math.Min(fR, fG), fB)
l = (max + min) / 2 l = (maxVal + minVal) / 2
if max == min { if maxVal == minVal {
// Achromatic. // Achromatic.
h, s = 0, 0 h, s = 0, 0
} else { } else {
// Chromatic. // Chromatic.
d := max - min d := maxVal - minVal
if l > 0.5 { if l > 0.5 {
s = d / (2.0 - max - min) s = d / (2.0 - maxVal - minVal)
} else { } else {
s = d / (max + min) s = d / (maxVal + minVal)
} }
switch max { switch maxVal {
case fR: case fR:
h = (fG - fB) / d h = (fG - fB) / d
if fG < fB { if fG < fB {

176
numfmt.go
View File

@ -5776,7 +5776,7 @@ func localMonthsNameKiche(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesKiche[int(t.Month())-1] return monthNamesKiche[int(t.Month())-1]
} }
return string([]rune(monthNamesKicheAbbr[int(t.Month()-1)])[:1]) return string([]rune(monthNamesKicheAbbr[(t.Month() - 1)])[:1])
} }
// localMonthsNameKinyarwanda returns the Kinyarwanda name of the month. // localMonthsNameKinyarwanda returns the Kinyarwanda name of the month.
@ -5787,7 +5787,7 @@ func localMonthsNameKinyarwanda(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesKinyarwanda[int(t.Month())-1] return monthNamesKinyarwanda[int(t.Month())-1]
} }
return string([]rune(monthNamesKinyarwanda[int(t.Month()-1)])[:1]) return string([]rune(monthNamesKinyarwanda[(t.Month() - 1)])[:1])
} }
// localMonthsNameKiswahili returns the Kiswahili name of the month. // localMonthsNameKiswahili returns the Kiswahili name of the month.
@ -5798,7 +5798,7 @@ func localMonthsNameKiswahili(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesKiswahili[int(t.Month())-1] return monthNamesKiswahili[int(t.Month())-1]
} }
return string([]rune(monthNamesKiswahili[int(t.Month()-1)])[:1]) return string([]rune(monthNamesKiswahili[(t.Month() - 1)])[:1])
} }
// localMonthsNameKonkani returns the Konkani name of the month. // localMonthsNameKonkani returns the Konkani name of the month.
@ -5809,7 +5809,7 @@ func localMonthsNameKonkani(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesKonkani[int(t.Month())-1] return monthNamesKonkani[int(t.Month())-1]
} }
return string([]rune(monthNamesKonkani[int(t.Month()-1)])[:1]) return string([]rune(monthNamesKonkani[(t.Month() - 1)])[:1])
} }
// localMonthsNameKorean returns the Korean name of the month. // localMonthsNameKorean returns the Korean name of the month.
@ -5828,7 +5828,7 @@ func localMonthsNameKyrgyz(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesKyrgyz[int(t.Month())-1] return monthNamesKyrgyz[int(t.Month())-1]
} }
return string([]rune(monthNamesKyrgyz[int(t.Month()-1)])[:1]) return string([]rune(monthNamesKyrgyz[(t.Month() - 1)])[:1])
} }
// localMonthsNameLao returns the Lao name of the month. // localMonthsNameLao returns the Lao name of the month.
@ -5839,7 +5839,7 @@ func localMonthsNameLao(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesLao[int(t.Month())-1] return monthNamesLao[int(t.Month())-1]
} }
return string([]rune(monthNamesLao[int(t.Month()-1)])[:1]) return string([]rune(monthNamesLao[(t.Month() - 1)])[:1])
} }
// localMonthsNameLatin returns the Latin name of the month. // localMonthsNameLatin returns the Latin name of the month.
@ -5850,7 +5850,7 @@ func localMonthsNameLatin(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesLatin[int(t.Month())-1] return monthNamesLatin[int(t.Month())-1]
} }
return string([]rune(monthNamesLatin[int(t.Month()-1)])[:1]) return string([]rune(monthNamesLatin[(t.Month() - 1)])[:1])
} }
// localMonthsNameLatvian returns the Latvian name of the month. // localMonthsNameLatvian returns the Latvian name of the month.
@ -5861,7 +5861,7 @@ func localMonthsNameLatvian(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesLatvian[int(t.Month())-1] return monthNamesLatvian[int(t.Month())-1]
} }
return string([]rune(monthNamesLatvian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesLatvian[(t.Month() - 1)])[:1])
} }
// localMonthsNameLithuanian returns the Lithuanian name of the month. // localMonthsNameLithuanian returns the Lithuanian name of the month.
@ -5872,7 +5872,7 @@ func localMonthsNameLithuanian(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesLithuanian[int(t.Month())-1] return monthNamesLithuanian[int(t.Month())-1]
} }
return string([]rune(monthNamesLithuanian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesLithuanian[(t.Month() - 1)])[:1])
} }
// localMonthsNameLowerSorbian returns the LowerSorbian name of the month. // localMonthsNameLowerSorbian returns the LowerSorbian name of the month.
@ -5883,7 +5883,7 @@ func localMonthsNameLowerSorbian(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesLowerSorbian[int(t.Month())-1] return monthNamesLowerSorbian[int(t.Month())-1]
} }
return string([]rune(monthNamesLowerSorbian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesLowerSorbian[(t.Month() - 1)])[:1])
} }
// localMonthsNameLuxembourgish returns the Luxembourgish name of the month. // localMonthsNameLuxembourgish returns the Luxembourgish name of the month.
@ -5894,7 +5894,7 @@ func localMonthsNameLuxembourgish(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesLuxembourgish[int(t.Month())-1] return monthNamesLuxembourgish[int(t.Month())-1]
} }
return string([]rune(monthNamesLuxembourgish[int(t.Month()-1)])[:1]) return string([]rune(monthNamesLuxembourgish[(t.Month() - 1)])[:1])
} }
// localMonthsNameMacedonian returns the Macedonian name of the month. // localMonthsNameMacedonian returns the Macedonian name of the month.
@ -5905,7 +5905,7 @@ func localMonthsNameMacedonian(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMacedonian[int(t.Month())-1] return monthNamesMacedonian[int(t.Month())-1]
} }
return string([]rune(monthNamesMacedonian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMacedonian[(t.Month() - 1)])[:1])
} }
// localMonthsNameMalay returns the Malay name of the month. // localMonthsNameMalay returns the Malay name of the month.
@ -5916,7 +5916,7 @@ func localMonthsNameMalay(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMalay[int(t.Month())-1] return monthNamesMalay[int(t.Month())-1]
} }
return string([]rune(monthNamesMalay[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMalay[(t.Month() - 1)])[:1])
} }
// localMonthsNameMalayalam returns the Malayalam name of the month. // localMonthsNameMalayalam returns the Malayalam name of the month.
@ -5927,7 +5927,7 @@ func localMonthsNameMalayalam(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMalayalam[int(t.Month())-1] return monthNamesMalayalam[int(t.Month())-1]
} }
return string([]rune(monthNamesMalayalam[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMalayalam[(t.Month() - 1)])[:1])
} }
// localMonthsNameMaltese returns the Maltese name of the month. // localMonthsNameMaltese returns the Maltese name of the month.
@ -5938,7 +5938,7 @@ func localMonthsNameMaltese(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMaltese[int(t.Month())-1] return monthNamesMaltese[int(t.Month())-1]
} }
return string([]rune(monthNamesMaltese[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMaltese[(t.Month() - 1)])[:1])
} }
// localMonthsNameMaori returns the Maori name of the month. // localMonthsNameMaori returns the Maori name of the month.
@ -5949,13 +5949,13 @@ func localMonthsNameMaori(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMaori[int(t.Month())-1] return monthNamesMaori[int(t.Month())-1]
} }
return string([]rune(monthNamesMaori[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMaori[(t.Month() - 1)])[:1])
} }
// localMonthsNameMapudungun returns the Mapudungun name of the month. // localMonthsNameMapudungun returns the Mapudungun name of the month.
func localMonthsNameMapudungun(t time.Time, abbr int) string { func localMonthsNameMapudungun(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesMapudungun[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMapudungun[(t.Month() - 1)])[:1])
} }
return monthNamesMapudungun[int(t.Month())-1] return monthNamesMapudungun[int(t.Month())-1]
} }
@ -5968,7 +5968,7 @@ func localMonthsNameMarathi(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMarathi[int(t.Month())-1] return monthNamesMarathi[int(t.Month())-1]
} }
return string([]rune(monthNamesMarathi[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMarathi[(t.Month() - 1)])[:1])
} }
// localMonthsNameMohawk returns the Mohawk name of the month. // localMonthsNameMohawk returns the Mohawk name of the month.
@ -5979,7 +5979,7 @@ func localMonthsNameMohawk(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMohawk[int(t.Month())-1] return monthNamesMohawk[int(t.Month())-1]
} }
return string([]rune(monthNamesMohawk[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMohawk[(t.Month() - 1)])[:1])
} }
// localMonthsNameMongolian returns the Mongolian name of the month. // localMonthsNameMongolian returns the Mongolian name of the month.
@ -5990,7 +5990,7 @@ func localMonthsNameMongolian(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesMongolian[int(t.Month())-1] return monthNamesMongolian[int(t.Month())-1]
} }
return string([]rune(monthNamesMongolian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesMongolian[(t.Month() - 1)])[:1])
} }
// localMonthsNameMorocco returns the Morocco name of the month. // localMonthsNameMorocco returns the Morocco name of the month.
@ -6012,7 +6012,7 @@ func localMonthsNameNepali(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesNepali[int(t.Month())-1] return monthNamesNepali[int(t.Month())-1]
} }
return string([]rune(monthNamesNepali[int(t.Month()-1)])[:1]) return string([]rune(monthNamesNepali[(t.Month() - 1)])[:1])
} }
// localMonthsNameNepaliIN returns the India Nepali name of the month. // localMonthsNameNepaliIN returns the India Nepali name of the month.
@ -6023,7 +6023,7 @@ func localMonthsNameNepaliIN(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesNepaliIN[int(t.Month())-1] return monthNamesNepaliIN[int(t.Month())-1]
} }
return string([]rune(monthNamesNepaliIN[int(t.Month()-1)])[:1]) return string([]rune(monthNamesNepaliIN[(t.Month() - 1)])[:1])
} }
// localMonthsNameNigeria returns the Nigeria name of the month. // localMonthsNameNigeria returns the Nigeria name of the month.
@ -6045,7 +6045,7 @@ func localMonthsNameNorwegian(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesNorwegian[int(t.Month())-1] return monthNamesNorwegian[int(t.Month())-1]
} }
return string([]rune(monthNamesNorwegian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesNorwegian[(t.Month() - 1)])[:1])
} }
// localMonthsNameOccitan returns the Occitan name of the month. // localMonthsNameOccitan returns the Occitan name of the month.
@ -6056,13 +6056,13 @@ func localMonthsNameOccitan(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesOccitan[int(t.Month())-1] return monthNamesOccitan[int(t.Month())-1]
} }
return string([]rune(monthNamesOccitan[int(t.Month()-1)])[:1]) return string([]rune(monthNamesOccitan[(t.Month() - 1)])[:1])
} }
// localMonthsNameOdia returns the Odia name of the month. // localMonthsNameOdia returns the Odia name of the month.
func localMonthsNameOdia(t time.Time, abbr int) string { func localMonthsNameOdia(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesOdia[int(t.Month()-1)])[:1]) return string([]rune(monthNamesOdia[(t.Month() - 1)])[:1])
} }
return monthNamesOdia[int(t.Month())-1] return monthNamesOdia[int(t.Month())-1]
} }
@ -6075,7 +6075,7 @@ func localMonthsNameOromo(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesOromo[int(t.Month())-1] return monthNamesOromo[int(t.Month())-1]
} }
return string([]rune(monthNamesOromo[int(t.Month()-1)])[:1]) return string([]rune(monthNamesOromo[(t.Month() - 1)])[:1])
} }
// localMonthsNamePashto returns the Pashto name of the month. // localMonthsNamePashto returns the Pashto name of the month.
@ -6094,7 +6094,7 @@ func localMonthsNamePashto(t time.Time, abbr int) string {
// localMonthsNamePersian returns the Persian name of the month. // localMonthsNamePersian returns the Persian name of the month.
func localMonthsNamePersian(t time.Time, abbr int) string { func localMonthsNamePersian(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesPersian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesPersian[(t.Month() - 1)])[:1])
} }
return monthNamesPersian[int(t.Month())-1] return monthNamesPersian[int(t.Month())-1]
} }
@ -6102,29 +6102,29 @@ func localMonthsNamePersian(t time.Time, abbr int) string {
// localMonthsNamePolish returns the Polish name of the month. // localMonthsNamePolish returns the Polish name of the month.
func localMonthsNamePolish(t time.Time, abbr int) string { func localMonthsNamePolish(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return string([]rune(monthNamesPolish[int(t.Month()-1)])[:3]) return string([]rune(monthNamesPolish[(t.Month() - 1)])[:3])
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesPolish[int(t.Month())-1] return monthNamesPolish[int(t.Month())-1]
} }
return string([]rune(monthNamesPolish[int(t.Month()-1)])[:1]) return string([]rune(monthNamesPolish[(t.Month() - 1)])[:1])
} }
// localMonthsNamePortuguese returns the Portuguese name of the month. // localMonthsNamePortuguese returns the Portuguese name of the month.
func localMonthsNamePortuguese(t time.Time, abbr int) string { func localMonthsNamePortuguese(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return string([]rune(monthNamesPortuguese[int(t.Month()-1)])[:3]) return string([]rune(monthNamesPortuguese[(t.Month() - 1)])[:3])
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesPortuguese[int(t.Month())-1] return monthNamesPortuguese[int(t.Month())-1]
} }
return string([]rune(monthNamesPortuguese[int(t.Month()-1)])[:1]) return string([]rune(monthNamesPortuguese[(t.Month() - 1)])[:1])
} }
// localMonthsNamePunjabi returns the Punjabi name of the month. // localMonthsNamePunjabi returns the Punjabi name of the month.
func localMonthsNamePunjabi(t time.Time, abbr int) string { func localMonthsNamePunjabi(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesPunjabi[int(t.Month()-1)])[:1]) return string([]rune(monthNamesPunjabi[(t.Month() - 1)])[:1])
} }
return monthNamesPunjabi[int(t.Month())-1] return monthNamesPunjabi[int(t.Month())-1]
} }
@ -6132,7 +6132,7 @@ func localMonthsNamePunjabi(t time.Time, abbr int) string {
// localMonthsNamePunjabiArab returns the Punjabi Arab name of the month. // localMonthsNamePunjabiArab returns the Punjabi Arab name of the month.
func localMonthsNamePunjabiArab(t time.Time, abbr int) string { func localMonthsNamePunjabiArab(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesPunjabiArab[int(t.Month()-1)])[:1]) return string([]rune(monthNamesPunjabiArab[(t.Month() - 1)])[:1])
} }
return monthNamesPunjabiArab[int(t.Month())-1] return monthNamesPunjabiArab[int(t.Month())-1]
} }
@ -6140,26 +6140,26 @@ func localMonthsNamePunjabiArab(t time.Time, abbr int) string {
// localMonthsNameQuechua returns the Quechua name of the month. // localMonthsNameQuechua returns the Quechua name of the month.
func localMonthsNameQuechua(t time.Time, abbr int) string { func localMonthsNameQuechua(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return string([]rune(monthNamesQuechua[int(t.Month()-1)])[:3]) return string([]rune(monthNamesQuechua[(t.Month() - 1)])[:3])
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesQuechua[int(t.Month())-1] return monthNamesQuechua[int(t.Month())-1]
} }
return string([]rune(monthNamesQuechua[int(t.Month()-1)])[:1]) return string([]rune(monthNamesQuechua[(t.Month() - 1)])[:1])
} }
// localMonthsNameQuechuaEcuador returns the QuechuaEcuador name of the month. // localMonthsNameQuechuaEcuador returns the QuechuaEcuador name of the month.
func localMonthsNameQuechuaEcuador(t time.Time, abbr int) string { func localMonthsNameQuechuaEcuador(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
if int(t.Month()) == 1 { if int(t.Month()) == 1 {
return string([]rune(monthNamesQuechuaEcuador[int(t.Month()-1)])[:4]) return string([]rune(monthNamesQuechuaEcuador[(t.Month() - 1)])[:4])
} }
return string([]rune(monthNamesQuechuaEcuador[int(t.Month()-1)])[:3]) return string([]rune(monthNamesQuechuaEcuador[(t.Month() - 1)])[:3])
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesQuechuaEcuador[int(t.Month())-1] return monthNamesQuechuaEcuador[int(t.Month())-1]
} }
return string([]rune(monthNamesQuechuaEcuador[int(t.Month()-1)])[:1]) return string([]rune(monthNamesQuechuaEcuador[(t.Month() - 1)])[:1])
} }
// localMonthsNameRomanian returns the Romanian name of the month. // localMonthsNameRomanian returns the Romanian name of the month.
@ -6170,7 +6170,7 @@ func localMonthsNameRomanian(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesRomanian[int(t.Month())-1] return monthNamesRomanian[int(t.Month())-1]
} }
return string([]rune(monthNamesRomanian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesRomanian[(t.Month() - 1)])[:1])
} }
// localMonthsNameRomansh returns the Romansh name of the month. // localMonthsNameRomansh returns the Romansh name of the month.
@ -6181,7 +6181,7 @@ func localMonthsNameRomansh(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesRomansh[int(t.Month())-1] return monthNamesRomansh[int(t.Month())-1]
} }
return string([]rune(monthNamesRomansh[int(t.Month()-1)])[:1]) return string([]rune(monthNamesRomansh[(t.Month() - 1)])[:1])
} }
// localMonthsNameRussian returns the Russian name of the month. // localMonthsNameRussian returns the Russian name of the month.
@ -6207,7 +6207,7 @@ func localMonthsNameSakha(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSakha[int(t.Month())-1] return monthNamesSakha[int(t.Month())-1]
} }
return string([]rune(monthNamesSakha[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSakha[(t.Month() - 1)])[:1])
} }
// localMonthsNameSami returns the Sami name of the month. // localMonthsNameSami returns the Sami name of the month.
@ -6218,7 +6218,7 @@ func localMonthsNameSami(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSami[int(t.Month())-1] return monthNamesSami[int(t.Month())-1]
} }
return string([]rune(monthNamesSami[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSami[(t.Month() - 1)])[:1])
} }
// localMonthsNameSamiLule returns the Sami (Lule) name of the month. // localMonthsNameSamiLule returns the Sami (Lule) name of the month.
@ -6229,25 +6229,25 @@ func localMonthsNameSamiLule(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSamiLule[int(t.Month())-1] return monthNamesSamiLule[int(t.Month())-1]
} }
return string([]rune(monthNamesSamiLule[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSamiLule[(t.Month() - 1)])[:1])
} }
// localMonthsNameSamiNorthern returns the Sami (Northern) name of the month. // localMonthsNameSamiNorthern returns the Sami (Northern) name of the month.
func localMonthsNameSamiNorthern(t time.Time, abbr int) string { func localMonthsNameSamiNorthern(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSamiNorthernAbbr[int(t.Month()-1)] return monthNamesSamiNorthernAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSamiNorthern[int(t.Month())-1] return monthNamesSamiNorthern[int(t.Month())-1]
} }
return string([]rune(monthNamesSamiNorthern[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSamiNorthern[(t.Month() - 1)])[:1])
} }
// localMonthsNameSamiNorthernFI returns the Sami (Northern) Finland name of the // localMonthsNameSamiNorthernFI returns the Sami (Northern) Finland name of the
// month. // month.
func localMonthsNameSamiNorthernFI(t time.Time, abbr int) string { func localMonthsNameSamiNorthernFI(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSamiNorthernAbbr[int(t.Month()-1)] return monthNamesSamiNorthernAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
if int(t.Month()) == 1 { if int(t.Month()) == 1 {
@ -6255,13 +6255,13 @@ func localMonthsNameSamiNorthernFI(t time.Time, abbr int) string {
} }
return monthNamesSamiNorthern[int(t.Month())-1] return monthNamesSamiNorthern[int(t.Month())-1]
} }
return string([]rune(monthNamesSamiNorthern[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSamiNorthern[(t.Month() - 1)])[:1])
} }
// localMonthsNameSamiSkolt returns the Sami (Skolt) name of the month. // localMonthsNameSamiSkolt returns the Sami (Skolt) name of the month.
func localMonthsNameSamiSkolt(t time.Time, abbr int) string { func localMonthsNameSamiSkolt(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesSamiSkolt[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSamiSkolt[(t.Month() - 1)])[:1])
} }
return monthNamesSamiSkolt[int(t.Month())-1] return monthNamesSamiSkolt[int(t.Month())-1]
} }
@ -6269,18 +6269,18 @@ func localMonthsNameSamiSkolt(t time.Time, abbr int) string {
// localMonthsNameSamiSouthern returns the Sami (Southern) name of the month. // localMonthsNameSamiSouthern returns the Sami (Southern) name of the month.
func localMonthsNameSamiSouthern(t time.Time, abbr int) string { func localMonthsNameSamiSouthern(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSamiSouthernAbbr[int(t.Month()-1)] return monthNamesSamiSouthernAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSamiSouthern[int(t.Month())-1] return monthNamesSamiSouthern[int(t.Month())-1]
} }
return string([]rune(monthNamesSamiSouthern[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSamiSouthern[(t.Month() - 1)])[:1])
} }
// localMonthsNameSanskrit returns the Sanskrit name of the month. // localMonthsNameSanskrit returns the Sanskrit name of the month.
func localMonthsNameSanskrit(t time.Time, abbr int) string { func localMonthsNameSanskrit(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesSanskrit[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSanskrit[(t.Month() - 1)])[:1])
} }
return monthNamesSanskrit[int(t.Month())-1] return monthNamesSanskrit[int(t.Month())-1]
} }
@ -6288,85 +6288,85 @@ func localMonthsNameSanskrit(t time.Time, abbr int) string {
// localMonthsNameScottishGaelic returns the Scottish Gaelic name of the month. // localMonthsNameScottishGaelic returns the Scottish Gaelic name of the month.
func localMonthsNameScottishGaelic(t time.Time, abbr int) string { func localMonthsNameScottishGaelic(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesScottishGaelicAbbr[int(t.Month()-1)] return monthNamesScottishGaelicAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesScottishGaelic[int(t.Month())-1] return monthNamesScottishGaelic[int(t.Month())-1]
} }
return string([]rune(monthNamesScottishGaelic[int(t.Month()-1)])[:1]) return string([]rune(monthNamesScottishGaelic[(t.Month() - 1)])[:1])
} }
// localMonthsNameSerbian returns the Serbian (Cyrillic) name of the month. // localMonthsNameSerbian returns the Serbian (Cyrillic) name of the month.
func localMonthsNameSerbian(t time.Time, abbr int) string { func localMonthsNameSerbian(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSerbianAbbr[int(t.Month()-1)] return monthNamesSerbianAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSerbian[int(t.Month())-1] return monthNamesSerbian[int(t.Month())-1]
} }
return string([]rune(monthNamesSerbian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSerbian[(t.Month() - 1)])[:1])
} }
// localMonthsNameSerbianBA returns the Serbian (Cyrillic) Bosnia and // localMonthsNameSerbianBA returns the Serbian (Cyrillic) Bosnia and
// Herzegovina name of the month. // Herzegovina name of the month.
func localMonthsNameSerbianBA(t time.Time, abbr int) string { func localMonthsNameSerbianBA(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSerbianBAAbbr[int(t.Month()-1)] return monthNamesSerbianBAAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSerbianBA[int(t.Month())-1] return monthNamesSerbianBA[int(t.Month())-1]
} }
return string([]rune(monthNamesSerbianBA[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSerbianBA[(t.Month() - 1)])[:1])
} }
// localMonthsNameSerbianLatin returns the Serbian (Latin) name of the month. // localMonthsNameSerbianLatin returns the Serbian (Latin) name of the month.
func localMonthsNameSerbianLatin(t time.Time, abbr int) string { func localMonthsNameSerbianLatin(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return string([]rune(monthNamesSerbianLatin[int(t.Month()-1)])[:3]) return string([]rune(monthNamesSerbianLatin[(t.Month() - 1)])[:3])
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSerbianLatin[int(t.Month())-1] return monthNamesSerbianLatin[int(t.Month())-1]
} }
return string([]rune(monthNamesSerbianLatin[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSerbianLatin[(t.Month() - 1)])[:1])
} }
// localMonthsNameSerbianLatinCS returns the Serbian (Latin) name of the month. // localMonthsNameSerbianLatinCS returns the Serbian (Latin) name of the month.
func localMonthsNameSerbianLatinCS(t time.Time, abbr int) string { func localMonthsNameSerbianLatinCS(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSerbianLatinAbbr[int(t.Month()-1)] return monthNamesSerbianLatinAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSerbianLatin[int(t.Month())-1] return monthNamesSerbianLatin[int(t.Month())-1]
} }
return string([]rune(monthNamesSerbianLatin[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSerbianLatin[(t.Month() - 1)])[:1])
} }
// localMonthsNameSesothoSaLeboa returns the Sesotho sa Leboa name of the month. // localMonthsNameSesothoSaLeboa returns the Sesotho sa Leboa name of the month.
func localMonthsNameSesothoSaLeboa(t time.Time, abbr int) string { func localMonthsNameSesothoSaLeboa(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSesothoSaLeboaAbbr[int(t.Month()-1)] return monthNamesSesothoSaLeboaAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSesothoSaLeboa[int(t.Month())-1] return monthNamesSesothoSaLeboa[int(t.Month())-1]
} }
return string([]rune(monthNamesSesothoSaLeboa[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSesothoSaLeboa[(t.Month() - 1)])[:1])
} }
// localMonthsNameSetswana returns the Setswana name of the month. // localMonthsNameSetswana returns the Setswana name of the month.
func localMonthsNameSetswana(t time.Time, abbr int) string { func localMonthsNameSetswana(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSetswanaAbbr[int(t.Month()-1)] return monthNamesSetswanaAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSetswana[int(t.Month())-1] return monthNamesSetswana[int(t.Month())-1]
} }
return string([]rune(monthNamesSetswana[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSetswana[(t.Month() - 1)])[:1])
} }
// localMonthsNameSindhi returns the Sindhi name of the month. // localMonthsNameSindhi returns the Sindhi name of the month.
func localMonthsNameSindhi(t time.Time, abbr int) string { func localMonthsNameSindhi(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesSindhi[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSindhi[(t.Month() - 1)])[:1])
} }
return monthNamesSindhi[int(t.Month())-1] return monthNamesSindhi[int(t.Month())-1]
} }
@ -6374,12 +6374,12 @@ func localMonthsNameSindhi(t time.Time, abbr int) string {
// localMonthsNameSinhala returns the Sinhala name of the month. // localMonthsNameSinhala returns the Sinhala name of the month.
func localMonthsNameSinhala(t time.Time, abbr int) string { func localMonthsNameSinhala(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSinhalaAbbr[int(t.Month()-1)] return monthNamesSinhalaAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSinhala[int(t.Month())-1] return monthNamesSinhala[int(t.Month())-1]
} }
return string([]rune(monthNamesSinhala[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSinhala[(t.Month() - 1)])[:1])
} }
// localMonthsNameSlovak returns the Slovak name of the month. // localMonthsNameSlovak returns the Slovak name of the month.
@ -6390,40 +6390,40 @@ func localMonthsNameSlovak(t time.Time, abbr int) string {
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSlovak[int(t.Month())-1] return monthNamesSlovak[int(t.Month())-1]
} }
return string([]rune(monthNamesSlovak[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSlovak[(t.Month() - 1)])[:1])
} }
// localMonthsNameSlovenian returns the Slovenian name of the month. // localMonthsNameSlovenian returns the Slovenian name of the month.
func localMonthsNameSlovenian(t time.Time, abbr int) string { func localMonthsNameSlovenian(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSlovenianAbbr[int(t.Month()-1)] return monthNamesSlovenianAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSlovenian[int(t.Month())-1] return monthNamesSlovenian[int(t.Month())-1]
} }
return string([]rune(monthNamesSlovenian[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSlovenian[(t.Month() - 1)])[:1])
} }
// localMonthsNameSomali returns the Somali name of the month. // localMonthsNameSomali returns the Somali name of the month.
func localMonthsNameSomali(t time.Time, abbr int) string { func localMonthsNameSomali(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSomaliAbbr[int(t.Month()-1)] return monthNamesSomaliAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSomali[int(t.Month())-1] return monthNamesSomali[int(t.Month())-1]
} }
return string([]rune(monthNamesSomali[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSomali[(t.Month() - 1)])[:1])
} }
// localMonthsNameSotho returns the Sotho name of the month. // localMonthsNameSotho returns the Sotho name of the month.
func localMonthsNameSotho(t time.Time, abbr int) string { func localMonthsNameSotho(t time.Time, abbr int) string {
if abbr == 3 { if abbr == 3 {
return monthNamesSothoAbbr[int(t.Month()-1)] return monthNamesSothoAbbr[(t.Month() - 1)]
} }
if abbr == 4 || abbr > 6 { if abbr == 4 || abbr > 6 {
return monthNamesSotho[int(t.Month())-1] return monthNamesSotho[int(t.Month())-1]
} }
return string([]rune(monthNamesSotho[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSotho[(t.Month() - 1)])[:1])
} }
// localMonthsNameSpanish returns the Spanish name of the month. // localMonthsNameSpanish returns the Spanish name of the month.
@ -6478,7 +6478,7 @@ func localMonthsNameSyriac(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesSyriac[int(t.Month())-1] return monthNamesSyriac[int(t.Month())-1]
} }
return string([]rune(monthNamesSyriac[int(t.Month()-1)])[:1]) return string([]rune(monthNamesSyriac[(t.Month() - 1)])[:1])
} }
// localMonthsNameTajik returns the Tajik name of the month. // localMonthsNameTajik returns the Tajik name of the month.
@ -6489,7 +6489,7 @@ func localMonthsNameTajik(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesTajik[int(t.Month())-1] return monthNamesTajik[int(t.Month())-1]
} }
return string([]rune(monthNamesTajik[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTajik[(t.Month() - 1)])[:1])
} }
// localMonthsNameTamazight returns the Tamazight name of the month. // localMonthsNameTamazight returns the Tamazight name of the month.
@ -6500,13 +6500,13 @@ func localMonthsNameTamazight(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesTamazight[int(t.Month())-1] return monthNamesTamazight[int(t.Month())-1]
} }
return string([]rune(monthNamesTamazight[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTamazight[(t.Month() - 1)])[:1])
} }
// localMonthsNameTamil returns the Tamil name of the month. // localMonthsNameTamil returns the Tamil name of the month.
func localMonthsNameTamil(t time.Time, abbr int) string { func localMonthsNameTamil(t time.Time, abbr int) string {
if abbr == 5 { if abbr == 5 {
return string([]rune(monthNamesTamil[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTamil[(t.Month() - 1)])[:1])
} }
return monthNamesTamil[int(t.Month())-1] return monthNamesTamil[int(t.Month())-1]
} }
@ -6519,7 +6519,7 @@ func localMonthsNameTamilLK(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesTamil[int(t.Month())-1] return monthNamesTamil[int(t.Month())-1]
} }
return string([]rune(monthNamesTamil[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTamil[(t.Month() - 1)])[:1])
} }
// localMonthsNameTatar returns the Tatar name of the month. // localMonthsNameTatar returns the Tatar name of the month.
@ -6530,7 +6530,7 @@ func localMonthsNameTatar(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesTatar[int(t.Month())-1] return monthNamesTatar[int(t.Month())-1]
} }
return string([]rune(monthNamesTatar[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTatar[(t.Month() - 1)])[:1])
} }
// localMonthsNameTelugu returns the Telugu name of the month. // localMonthsNameTelugu returns the Telugu name of the month.
@ -6541,7 +6541,7 @@ func localMonthsNameTelugu(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesTelugu[int(t.Month())-1] return monthNamesTelugu[int(t.Month())-1]
} }
return string([]rune(monthNamesTelugu[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTelugu[(t.Month() - 1)])[:1])
} }
// localMonthsNameSyllabics returns the Syllabics name of the month. // localMonthsNameSyllabics returns the Syllabics name of the month.
@ -6589,7 +6589,7 @@ func localMonthsNameTigrinya(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesTigrinya[int(t.Month())-1] return monthNamesTigrinya[int(t.Month())-1]
} }
return string([]rune(monthNamesTigrinya[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTigrinya[(t.Month() - 1)])[:1])
} }
// localMonthsNameTsonga returns the Tsonga name of the month. // localMonthsNameTsonga returns the Tsonga name of the month.
@ -6600,7 +6600,7 @@ func localMonthsNameTsonga(t time.Time, abbr int) string {
if abbr == 4 { if abbr == 4 {
return monthNamesTsonga[int(t.Month())-1] return monthNamesTsonga[int(t.Month())-1]
} }
return string([]rune(monthNamesTsonga[int(t.Month()-1)])[:1]) return string([]rune(monthNamesTsonga[(t.Month() - 1)])[:1])
} }
// localMonthsNameTraditionalMongolian returns the Traditional Mongolian name of // localMonthsNameTraditionalMongolian returns the Traditional Mongolian name of
@ -6922,10 +6922,10 @@ func (nf *numberFormat) daysHandler(token nfp.Token) {
} }
if strings.Contains(strings.ToUpper(token.TValue), "A") { if strings.Contains(strings.ToUpper(token.TValue), "A") {
if l == 3 { if l == 3 {
nf.result += weekdayNamesAbbr[int(nf.t.Weekday())] nf.result += weekdayNamesAbbr[nf.t.Weekday()]
} }
if l > 3 { if l > 3 {
nf.result += weekdayNames[int(nf.t.Weekday())] nf.result += weekdayNames[nf.t.Weekday()]
} }
return return
} }
@ -6936,9 +6936,9 @@ func (nf *numberFormat) daysHandler(token nfp.Token) {
case 2: case 2:
nf.result += fmt.Sprintf("%02d", nf.t.Day()) nf.result += fmt.Sprintf("%02d", nf.t.Day())
case 3: case 3:
nf.result += weekdayNamesAbbr[int(nf.t.Weekday())] nf.result += weekdayNamesAbbr[nf.t.Weekday()]
default: default:
nf.result += weekdayNames[int(nf.t.Weekday())] nf.result += weekdayNames[nf.t.Weekday()]
} }
} }
} }

View File

@ -63,7 +63,7 @@ func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error) {
return nil, err return nil, err
} }
rows, _ := f.Rows(sheet) rows, _ := f.Rows(sheet)
results, cur, max := make([][]string, 0, 64), 0, 0 results, cur, maxVal := make([][]string, 0, 64), 0, 0
for rows.Next() { for rows.Next() {
cur++ cur++
row, err := rows.Columns(opts...) row, err := rows.Columns(opts...)
@ -72,10 +72,10 @@ func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error) {
} }
results = append(results, row) results = append(results, row)
if len(row) > 0 { if len(row) > 0 {
max = cur maxVal = cur
} }
} }
return results[:max], rows.Close() return results[:maxVal], rows.Close()
} }
// Rows defines an iterator to a sheet. // Rows defines an iterator to a sheet.

View File

@ -439,24 +439,24 @@ func (sw *StreamWriter) SetRow(cell string, values []interface{}, opts ...RowOpt
// the width column B:C as 20: // the width column B:C as 20:
// //
// err := sw.SetColWidth(2, 3, 20) // err := sw.SetColWidth(2, 3, 20)
func (sw *StreamWriter) SetColWidth(min, max int, width float64) error { func (sw *StreamWriter) SetColWidth(minVal, maxVal int, width float64) error {
if sw.sheetWritten { if sw.sheetWritten {
return ErrStreamSetColWidth return ErrStreamSetColWidth
} }
if min < MinColumns || min > MaxColumns || max < MinColumns || max > MaxColumns { if minVal < MinColumns || minVal > MaxColumns || maxVal < MinColumns || maxVal > MaxColumns {
return ErrColumnNumber return ErrColumnNumber
} }
if width > MaxColumnWidth { if width > MaxColumnWidth {
return ErrColumnWidth return ErrColumnWidth
} }
if min > max { if minVal > maxVal {
min, max = max, min minVal, maxVal = maxVal, minVal
} }
sw.cols.WriteString(`<col min="`) sw.cols.WriteString(`<col min="`)
sw.cols.WriteString(strconv.Itoa(min)) sw.cols.WriteString(strconv.Itoa(minVal))
sw.cols.WriteString(`" max="`) sw.cols.WriteString(`" max="`)
sw.cols.WriteString(strconv.Itoa(max)) sw.cols.WriteString(strconv.Itoa(maxVal))
sw.cols.WriteString(`" width="`) sw.cols.WriteString(`" width="`)
sw.cols.WriteString(strconv.FormatFloat(width, 'f', -1, 64)) sw.cols.WriteString(strconv.FormatFloat(width, 'f', -1, 64))
sw.cols.WriteString(`" customWidth="1"/>`) sw.cols.WriteString(`" customWidth="1"/>`)

View File

@ -19,7 +19,6 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"unicode"
"unicode/utf8" "unicode/utf8"
) )
@ -316,14 +315,22 @@ func checkDefinedName(name string) error {
if utf8.RuneCountInString(name) > MaxFieldLength { if utf8.RuneCountInString(name) > MaxFieldLength {
return ErrNameLength return ErrNameLength
} }
inCodeRange := func(code int, tbl []int) bool {
for i := 0; i < len(tbl); i += 2 {
if tbl[i] <= code && code <= tbl[i+1] {
return true
}
}
return false
}
for i, c := range name { for i, c := range name {
if string(c) == "_" { if i == 0 {
if inCodeRange(int(c), supportedDefinedNameAtStartCharCodeRange) {
continue continue
} }
if unicode.IsLetter(c) { return newInvalidNameError(name)
continue
} }
if i > 0 && (unicode.IsDigit(c) || c == '.') { if inCodeRange(int(c), supportedDefinedNameAfterStartCharCodeRange) {
continue continue
} }
return newInvalidNameError(name) return newInvalidNameError(name)

View File

@ -302,6 +302,163 @@ var IndexedColorMapping = []string{
"000000", "FFFFFF", "000000", "FFFFFF",
} }
// supportedDefinedNameAtStartCharCodeRange list the valid first character of a
// defined name ASCII letters.
var supportedDefinedNameAtStartCharCodeRange = []int{
65, 90, 92, 92, 95, 95, 97, 122, 161, 161, 164, 164,
167, 168, 170, 170, 173, 173, 175, 186, 188, 696, 699, 705,
711, 711, 713, 715, 717, 717, 720, 721, 728, 731, 733, 733,
736, 740, 750, 750, 880, 883, 886, 887, 890, 893, 902, 902,
904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1315,
1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1610,
1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788,
1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026,
2036, 2037, 2042, 2042, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401,
2417, 2418, 2427, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480,
2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529,
2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611,
2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701,
2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749,
2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864,
2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929,
2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972,
2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084,
3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161,
3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257,
3261, 3261, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368,
3370, 3385, 3389, 3389, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505,
3507, 3515, 3517, 3517, 3520, 3526, 3585, 3642, 3648, 3662, 3713, 3714,
3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743,
3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763,
3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911,
3913, 3948, 3976, 3979, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189,
4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293,
4304, 4346, 4348, 4348, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4680,
4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749,
4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822,
4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740,
5743, 5750, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905,
5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103,
6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6400, 6428, 6480, 6509,
6512, 6516, 6528, 6569, 6593, 6599, 6656, 6678, 6917, 6963, 6981, 6987,
7043, 7072, 7086, 7087, 7168, 7203, 7245, 7247, 7258, 7293, 7424, 7615,
7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025,
8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126,
8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180,
8182, 8188, 8208, 8208, 8211, 8214, 8216, 8216, 8220, 8221, 8224, 8225,
8229, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8305, 8305,
8308, 8308, 8319, 8319, 8321, 8324, 8336, 8340, 8450, 8451, 8453, 8453,
8455, 8455, 8457, 8467, 8469, 8470, 8473, 8477, 8481, 8482, 8484, 8484,
8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521,
8526, 8526, 8531, 8532, 8539, 8542, 8544, 8584, 8592, 8601, 8658, 8658,
8660, 8660, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719,
8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741,
8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780,
8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835,
8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978,
9312, 9397, 9424, 9449, 9472, 9547, 9552, 9588, 9601, 9615, 9618, 9621,
9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665,
9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734,
9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794,
9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 11264, 11310,
11312, 11358, 11360, 11375, 11377, 11389, 11392, 11492, 11520, 11557, 11568, 11621,
11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710,
11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12288, 12291, 12293, 12311,
12317, 12319, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447,
12449, 12543, 12549, 12589, 12593, 12686, 12704, 12727, 12784, 12828, 12832, 12841,
12849, 12850, 12857, 12857, 12896, 12923, 12927, 12927, 12963, 12968, 13059, 13059,
13069, 13069, 13076, 13076, 13080, 13080, 13090, 13091, 13094, 13095, 13099, 13099,
13110, 13110, 13115, 13115, 13129, 13130, 13133, 13133, 13137, 13137, 13143, 13143,
13179, 13182, 13184, 13188, 13192, 13258, 13261, 13267, 13269, 13270, 13272, 13272,
13275, 13277, 13312, 19893, 19968, 40899, 40960, 42124, 42240, 42508, 42512, 42527,
42538, 42539, 42560, 42591, 42594, 42606, 42624, 42647, 42786, 42887, 42891, 42892,
43003, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187,
43274, 43301, 43312, 43334, 43520, 43560, 43584, 43586, 43588, 43595, 44032, 55203,
57344, 63560, 63744, 64045, 64048, 64106, 64112, 64217, 64256, 64262, 64275, 64279,
64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321,
64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019,
65072, 65073, 65075, 65092, 65097, 65106, 65108, 65111, 65113, 65126, 65128, 65131,
65136, 65140, 65142, 65276, 65281, 65374, 65377, 65470, 65474, 65479, 65482, 65487,
65490, 65495, 65498, 65500, 65504, 65510,
}
// supportedDefinedNameAfterStartCharCodeRange list the valid after first
// character of a defined name ASCII letters.
var supportedDefinedNameAfterStartCharCodeRange = []int{
46, 46, 48, 57, 63, 63, 65, 90, 92, 92, 95, 95,
97, 122, 161, 161, 164, 164, 167, 168, 170, 170, 173, 173,
175, 186, 188, 887, 890, 893, 900, 902, 904, 906, 908, 908,
910, 929, 931, 1315, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469,
1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522,
1536, 1539, 1542, 1544, 1547, 1547, 1550, 1562, 1567, 1567, 1569, 1630,
1632, 1641, 1646, 1747, 1749, 1791, 1807, 1866, 1869, 1969, 1984, 2038,
2042, 2042, 2305, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415,
2417, 2418, 2427, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472,
2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510,
2519, 2519, 2524, 2525, 2527, 2531, 2534, 2554, 2561, 2563, 2565, 2570,
2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617,
2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652,
2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728,
2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765,
2768, 2768, 2784, 2787, 2790, 2799, 2801, 2801, 2817, 2819, 2821, 2828,
2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884,
2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2929,
2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972,
2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016,
3018, 3021, 3024, 3024, 3031, 3031, 3046, 3066, 3073, 3075, 3077, 3084,
3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144,
3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3192, 3199,
3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257,
3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299,
3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368,
3370, 3385, 3389, 3396, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3427,
3430, 3445, 3449, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515,
3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551,
3570, 3571, 3585, 3642, 3647, 3662, 3664, 3673, 3713, 3714, 3716, 3716,
3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747,
3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780,
3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3843, 3859, 3897,
3902, 3911, 3913, 3948, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028,
4030, 4044, 4046, 4047, 4096, 4169, 4176, 4249, 4254, 4293, 4304, 4346,
4348, 4348, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4680, 4682, 4685,
4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784,
4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880,
4882, 4885, 4888, 4954, 4959, 4960, 4969, 4988, 4992, 5017, 5024, 5108,
5121, 5740, 5743, 5750, 5760, 5786, 5792, 5866, 5870, 5872, 5888, 5900,
5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003,
6016, 6099, 6103, 6103, 6107, 6109, 6112, 6121, 6128, 6137, 6155, 6158,
6160, 6169, 6176, 6263, 6272, 6314, 6400, 6428, 6432, 6443, 6448, 6459,
6464, 6464, 6470, 6509, 6512, 6516, 6528, 6569, 6576, 6601, 6608, 6617,
6624, 6683, 6912, 6987, 6992, 7001, 7009, 7036, 7040, 7082, 7086, 7097,
7168, 7223, 7232, 7241, 7245, 7293, 7424, 7654, 7678, 7957, 7960, 7965,
7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029,
8031, 8061, 8064, 8116, 8118, 8132, 8134, 8147, 8150, 8155, 8157, 8175,
8178, 8180, 8182, 8190, 8192, 8208, 8211, 8214, 8216, 8216, 8220, 8221,
8224, 8225, 8229, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8260, 8260,
8274, 8274, 8287, 8292, 8298, 8305, 8308, 8316, 8319, 8332, 8336, 8340,
8352, 8373, 8400, 8432, 8448, 8527, 8531, 8584, 8592, 9000, 9003, 9191,
9216, 9254, 9280, 9290, 9312, 9885, 9888, 9916, 9920, 9923, 9985, 9988,
9990, 9993, 9996, 10023, 10025, 10059, 10061, 10061, 10063, 10066, 10070, 10070,
10072, 10078, 10081, 10087, 10102, 10132, 10136, 10159, 10161, 10174, 10176, 10180,
10183, 10186, 10188, 10188, 10192, 10213, 10224, 10626, 10649, 10711, 10716, 10747,
10750, 11084, 11088, 11092, 11264, 11310, 11312, 11358, 11360, 11375, 11377, 11389,
11392, 11498, 11517, 11517, 11520, 11557, 11568, 11621, 11631, 11631, 11648, 11670,
11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726,
11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 11904, 11929, 11931, 12019,
12032, 12245, 12272, 12283, 12288, 12311, 12317, 12335, 12337, 12348, 12350, 12351,
12353, 12438, 12441, 12447, 12449, 12543, 12549, 12589, 12593, 12686, 12688, 12727,
12736, 12771, 12784, 12830, 12832, 12867, 12880, 13054, 13056, 19893, 19904, 40899,
40960, 42124, 42128, 42182, 42240, 42508, 42512, 42539, 42560, 42591, 42594, 42610,
42620, 42621, 42623, 42647, 42752, 42892, 43003, 43051, 43072, 43123, 43136, 43204,
43216, 43225, 43264, 43310, 43312, 43347, 43520, 43574, 43584, 43597, 43600, 43609,
44032, 55203, 55296, 64045, 64048, 64106, 64112, 64217, 64256, 64262, 64275, 64279,
64285, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433,
64467, 64829, 64848, 64911, 64914, 64967, 65008, 65021, 65024, 65039, 65056, 65062,
65072, 65073, 65075, 65092, 65097, 65106, 65108, 65111, 65113, 65126, 65128, 65131,
65136, 65140, 65142, 65276, 65279, 65279, 65281, 65374, 65377, 65470, 65474, 65479,
65482, 65487, 65490, 65495, 65498, 65500, 65504, 65510, 65512, 65518, 65529, 65533,
}
// supportedImageTypes defined supported image types. // supportedImageTypes defined supported image types.
var supportedImageTypes = map[string]string{ var supportedImageTypes = map[string]string{
".bmp": ".bmp", ".emf": ".emf", ".emz": ".emz", ".gif": ".gif", ".bmp": ".bmp", ".emf": ".emf", ".emz": ".emz", ".gif": ".gif",
@ -332,7 +489,7 @@ var supportedDrawingUnderlineTypes = []string{
var supportedPositioning = []string{"absolute", "oneCell", "twoCell"} var supportedPositioning = []string{"absolute", "oneCell", "twoCell"}
// builtInDefinedNames defined built-in defined names are built with a _xlnm prefix. // builtInDefinedNames defined built-in defined names are built with a _xlnm prefix.
var builtInDefinedNames = []string{"_xlnm.Print_Area", "_xlnm.Print_Titles", "_xlnm._FilterDatabase"} var builtInDefinedNames = []string{"_xlnm.Print_Area", "_xlnm.Print_Titles", "_xlnm.Criteria", "_xlnm._FilterDatabase", "_xlnm.Extract", "_xlnm.Consolidate_Area", "_xlnm.Database", "_xlnm.Sheet_Title"}
const templateDocpropsApp = `<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>0</TotalTime><Application>Go Excelize</Application></Properties>` const templateDocpropsApp = `<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>0</TotalTime><Application>Go Excelize</Application></Properties>`