Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
GreenYun committed Oct 23, 2020
1 parent 0f9c1c5 commit 2268443
Show file tree
Hide file tree
Showing 12 changed files with 427 additions and 180 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Package `kansuji`
=================

[![Go Report Card](https://goreportcard.com/badge/github.com/GreenYun/kansuji)](https://goreportcard.com/report/github.com/GreenYun/kansuji)
[![GoDoc](https://godoc.org/github.com/GreenYun/kansuji?status.svg)](https://godoc.org/github.com/GreenYun/kansuji)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/GreenYun/kansuji)](https://pkg.go.dev/github.com/GreenYun/kansuji)

Package kansuji provides kansuji conversion.

The "kansuji" is the romanization form of japanese "漢数字", which has the same meaning of Chinese "中文數字" ("中文数字", means Chinese number). As a matter of fact, these numbers have been used originally by Chinese for thousands of years. The reason to use "kansuji" was just for simple and short.

In the age of Ming dynasty, the Hongwu Emperor (Chu Yuan-chang) has forced the domestic financial system to use the financial style numbers, which are Chinese characters with lots of strokes, that can hardly be modified, compared to the very simple characters originally stand for numbers. This package supports both forms of kansuji.

Reference
---------

1. 中文数字, https://zh.wikipedia.org/wiki/%E4%B8%AD%E6%96%87%E6%95%B0%E5%AD%97
2. 漢数字, https://ja.wikipedia.org/wiki/%E6%BC%A2%E6%95%B0%E5%AD%97
3. 中华人民共和国国家标准 GB/T 15835—2011 出版物上数字用法
4. 大字 (数字), https://ja.wikipedia.org/wiki/%E5%A4%A7%E5%AD%97_(%E6%95%B0%E5%AD%97)
5. 大正十一年大蔵省令第四十三号(会計法規ニ基ク出納計算ノ数字及記載事項ノ訂正ニ関スル件), https://elaws.e-gov.go.jp/search/elawsSearch/elaws_search/lsg0500/detail?lawId=211M10000040043

Status
------

This project is under developing, you may make any [pull requests](https://github.com/GreenYun/kansuji/pulls) to add features or sending ideas by writing [issues](https://github.com/GreenYun/kansuji/issues).
3 changes: 3 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package kansuji

type group [4]rune
6 changes: 6 additions & 0 deletions conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package kansuji

import "strings"

// ToHongKongStandard converts the financial number three into the common form
// found in Hong Kong.
func ToHongKongStandard(in string) string {
return strings.ReplaceAll(in, "參", "叄")
}

// ToCantoneseVariant converts to oral Cantonese form of twenty, thirty and forty.
func ToCantoneseVariant(in string) string {
s := strings.ReplaceAll(in, "貳拾", "廿")
s = strings.ReplaceAll(s, "贰拾", "廿")
Expand All @@ -23,6 +26,9 @@ func ToCantoneseVariant(in string) string {
return s
}

// ToJapaneseLaw converts four financial numbers defined in Japanese laws.
//
// See https://ja.wikipedia.org/wiki/%E5%A4%A7%E5%AD%97_(%E6%95%B0%E5%AD%97)
func ToJapaneseLaw(in string) string {
s := strings.ReplaceAll(in, "一", "壱")
s = strings.ReplaceAll(s, "二", "弐")
Expand Down
67 changes: 0 additions & 67 deletions defines.go

This file was deleted.

14 changes: 14 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Package kansuji provides kansuji conversion.
//
// The "kansuji" is the romanization form of japanese "漢数字", which has the same
// meaning of Chinese "中文數字" ("中文数字", means Chinese number). As a matter of
// fact, these numbers have been used originally by Chinese for thousands of years.
// The reason to use "kansuji" was just for simple and short.
//
// In the age of Ming dynasty, the Hongwu Emperor (Chu Yuan-chang) has forced the
// domestic financial system to use the financial style numbers, which are Chinese
// characters with lots of strokes, that can hardly be modified, compared to the
// very simple characters originally stand for numbers.
//
// This package supports both forms of kansuji.
package kansuji
87 changes: 48 additions & 39 deletions japanese.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,53 @@ import (
"strings"
)

// In Japanese, there are several styles of "ones".
// NoOnes means no "one"s before "ten"s, "hundred"s and "thousand"s.
// CommonOnes puts the optional "one" before every "thousand".
// AllOnes puts every "one" explicitly (usually used in financial situations).
const (
NoOnes int = iota
CommonOnes
AllOnes
)

// JapaneseFloat returns kansuji of a `float64` in Japanese style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
//
// `prec` has the same meaning of `strconv.FormatFloat`.
func JapaneseFloat(in float64, ones, prec int) string {
var sb strings.Builder

isNegative := in < 0
if isNegative {
in = -in
sb.WriteRune(negative()[1])
sb.WriteRune(negative[2])
}

str := strconv.FormatFloat(in, 'f', prec, 64)
str = strings.Trim(str, "0")
strParts := strings.Split(str, ".")

sb.WriteString(japaneseStringInt(strParts[0], ones))

if len(strParts) > 1 && strParts[1] != "" {
sb.WriteRune(point()[2])
sb.WriteRune(point[2])
for i := 0; i < len(strParts[1]); i++ {
sb.WriteRune(chars()[strParts[1][i]])
sb.WriteRune(numbers[strParts[1][i]-'0'])
}
}

return sb.String()
}

// JapaneseInt returns kansuji of a `int64` in Japanese style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
func JapaneseInt(in int64, ones int) string {
var sb strings.Builder

isNegative := in < 0
if isNegative {
in = -in
sb.WriteRune(negative()[0])
sb.WriteRune(negative[2])
}

str := strconv.FormatInt(in, 10)
Expand All @@ -51,6 +60,8 @@ func JapaneseInt(in int64, ones int) string {
return sb.String()
}

// JapaneseUint returns kansuji of a `uint64` in Japanese style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
func JapaneseUint(in uint64, ones int) string {
var sb strings.Builder

Expand All @@ -60,25 +71,37 @@ func JapaneseUint(in uint64, ones int) string {
return sb.String()
}

// JapaneseFinancialFloat returns kansuji of a `float64` in Japanese financial style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
//
// `prec` has the same meaning of `strconv.FormatFloat`.
func JapaneseFinancialFloat(in float64, ones, prec int) string {
return ToJapaneseLaw(JapaneseFloat(in, ones, prec))
}

// JapaneseFinancialInt returns kansuji of a `int64` in Japanese financial style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
func JapaneseFinancialInt(in int64, ones int) string {
return ToJapaneseLaw(JapaneseInt(in, ones))
}

// JapaneseFinancialUint returns kansuji of a `uint64` in Japanese financial style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
func JapaneseFinancialUint(in uint64, ones int) string {
return ToJapaneseLaw(JapaneseUint(in, ones))
}

// JapaneseOldFinancialFloat returns kansuji of a `float64` in Japanese old style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
//
// `prec` has the same meaning of `strconv.FormatFloat`.
func JapaneseOldFinancialFloat(in float64, ones, prec int) string {
var sb strings.Builder

isNegative := in < 0
if isNegative {
in = -in
sb.WriteRune(negative()[1])
sb.WriteRune(negative[2])
}

str := strconv.FormatFloat(in, 'f', prec, 64)
Expand All @@ -88,27 +111,24 @@ func JapaneseOldFinancialFloat(in float64, ones, prec int) string {
sb.WriteString(japaneseStringOldFinancialInt(strParts[0], ones))

if len(strParts) > 1 && strParts[1] != "" {
sb.WriteRune(point()[2])
sb.WriteRune(point[2])
for i := 0; i < len(strParts[1]); i++ {
rs := upperChars()[strParts[1][i]]
if len(rs) >= 3 {
sb.WriteRune(rs[2])
} else {
sb.WriteRune(rs[0])
}
sb.WriteRune(financialNumbers[strParts[1][i]-'0'][2])
}
}

return sb.String()
}

// JapaneseOldFinancialInt returns kansuji of a `int64` in Japanese old style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
func JapaneseOldFinancialInt(in int64, ones int) string {
var sb strings.Builder

isNegative := in < 0
if isNegative {
in = -in
sb.WriteRune(negative()[0])
sb.WriteRune(negative[2])
}

str := strconv.FormatInt(in, 10)
Expand All @@ -117,6 +137,8 @@ func JapaneseOldFinancialInt(in int64, ones int) string {
return sb.String()
}

// JapaneseOldFinancialUint returns kansuji of a `uint64` in Japanese old style.
// `ones` is one of `NoOnes`, `CommonOnes` and `AllOnes`.
func JapaneseOldFinancialUint(in uint64, ones int) string {
var sb strings.Builder

Expand All @@ -134,7 +156,7 @@ func japaneseStringInt(in string, ones int) string {
var integer [12]group
var i, g, b int
for i, g, b = len(in)-1, 0, 0; i >= 0; i-- {
integer[g][b] = chars()[in[i]]
integer[g][b] = numbers[in[i]-'0']
b++
if b == 4 {
g++
Expand All @@ -156,27 +178,23 @@ func japaneseStringInt(in string, ones int) string {
}
for ; g >= 0; g-- {
for ; b >= 0; b-- {
if integer[g][b] == chars()['0'] {
if integer[g][b] == numbers[0] {
continue
}
if !(integer[g][b] == chars()['1'] && b > 0) || ones == AllOnes {
if !(integer[g][b] == numbers[1] && b > 0) || ones == AllOnes {
sb.WriteRune(integer[g][b])
} else {
if ones == CommonOnes && g >= 1 && b >= 3 {
sb.WriteRune(integer[g][b])
}
}
if b > 0 {
sb.WriteRune(multipliers()[b-1])
sb.WriteRune(multipliers[b-1])
}
}
b = 3
if r := multipliersAgain()[g]; r != nil {
if len(r) >= 3 {
sb.WriteRune(r[2])
} else {
sb.WriteRune(r[0])
}
if g > 0 {
sb.WriteRune(multipliers2[g-1][2])
}
}

Expand All @@ -191,12 +209,7 @@ func japaneseStringOldFinancialInt(in string, ones int) string {
var integer [12]group
var i, g, b int
for i, g, b = len(in)-1, 0, 0; i >= 0; i-- {
r := upperChars()[in[i]]
if len(r) >= 3 {
integer[g][b] = r[2]
} else {
integer[g][b] = r[0]
}
integer[g][b] = financialNumbers[in[i]-'0'][2]
b++
if b == 4 {
g++
Expand All @@ -218,27 +231,23 @@ func japaneseStringOldFinancialInt(in string, ones int) string {
}
for ; g >= 0; g-- {
for ; b >= 0; b-- {
if integer[g][b] == chars()['0'] {
if integer[g][b] == numbers[0] {
continue
}
if !(integer[g][b] == upperChars()['1'][2] && b > 0) || ones == AllOnes {
if !(integer[g][b] == financialNumbers[1][2] && b > 0) || ones == AllOnes {
sb.WriteRune(integer[g][b])
} else {
if ones == CommonOnes && g >= 1 && b >= 3 {
sb.WriteRune(integer[g][b])
}
}
if b > 0 {
sb.WriteRune(upperMultipliers()[b-1][2])
sb.WriteRune(financialMultipliers[b-1][2])
}
}
b = 3
if r := multipliersAgain()[g]; r != nil {
if len(r) >= 3 {
sb.WriteRune(r[2])
} else {
sb.WriteRune(r[0])
}
if g > 0 {
sb.WriteRune(multipliers2[g-1][2])
}
}

Expand Down
Loading

0 comments on commit 2268443

Please sign in to comment.