package cjlookup import ( "bufio" "encoding/csv" utils "github.com/tgckpg/golifehk/utils" "io" "log" "os" "path/filepath" "strconv" "strings" ) var TXT_CANGJIE_KEYS string = filepath.Join(utils.STATIC_DIR, "cangjie.keys.txt") var YAML_CANGJIE5_DICT string = filepath.Join(utils.STATIC_DIR, "cangjie5.dict.yaml") var YAML_JYUTPING_CHARS string = filepath.Join(utils.STATIC_DIR, "jyut6ping3.chars.dict.yaml") func ReadCangJieKeys() (*strings.Replacer, error) { f, err := os.Open(TXT_CANGJIE_KEYS) if err != nil { log.Fatal(err) } defer f.Close() r := csv.NewReader(f) r.Comma = '\t' r.FieldsPerRecord = -1 cjKeymap := []string{} for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } cjKeymap = append(cjKeymap, record[0]) cjKeymap = append(cjKeymap, record[1]) } return strings.NewReplacer(cjKeymap...), nil } func ReadCangJieTable(charMap map[string]*CChar, repl *strings.Replacer) error { f, err := os.Open(YAML_CANGJIE5_DICT) if err != nil { log.Fatal(err) } defer f.Close() br := bufio.NewReader(f) // Skip until YAML document end for { line, err := br.ReadString('\n') if err != nil { return err } if strings.TrimSpace(line) == "..." { break } } r := csv.NewReader(br) r.Comma = '\t' r.FieldsPerRecord = -1 for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } face := record[0] if c, ok := charMap[face]; ok { c.Face = face c.CangJie = repl.Replace(record[1]) } else { c := CChar{} c.Face = face c.Key = &c.Face c.CangJie = repl.Replace(record[1]) charMap[face] = &c } } return nil } func ReadJyutPingTable(charMap map[string]*CChar) (map[string]*CJyutPing, error) { f, err := os.Open(YAML_JYUTPING_CHARS) if err != nil { log.Fatal(err) } defer f.Close() br := bufio.NewReader(f) // Skip until YAML document end for { line, err := br.ReadString('\n') if err != nil { return nil, err } if strings.TrimSpace(line) == "..." { break } } r := csv.NewReader(br) r.Comma = '\t' r.FieldsPerRecord = -1 JyutPingMap := map[string]*CJyutPing{} for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } face := record[0] jyutping := record[1] var tjz *[]*CChar cjp, ok := JyutPingMap[jyutping] if ok { tjz = cjp.TungJamZi } else { cjp = &CJyutPing{} cjp.Roman = jyutping cjp.SearchKey = strings.ToUpper(jyutping) cjp.Key = &cjp.SearchKey tjz = &[]*CChar{} cjp.TungJamZi = tjz JyutPingMap[jyutping] = cjp } var c *CChar c, ok = charMap[face] if !ok { c = &CChar{} c.Face = face c.Key = &c.Face charMap[face] = c } *tjz = append(*tjz, c) var dj *DukJam if len(record) == 2 { c.JyutPing = cjp dj = &DukJam{} dj.Weight = 100 dj.JyutPing = cjp } else if len(record) == 3 { s := record[2] var w int if strings.HasSuffix(s, "%") { w, err = strconv.Atoi(s[:len(s)-1]) if err != nil { return nil, err } } dj = &DukJam{} dj.Weight = w dj.JyutPing = cjp } if dj != nil { if c.DukJam == nil { c.DukJam = &[]*DukJam{} } *c.DukJam = append(*c.DukJam, dj) } } for _, c := range charMap { if c.JyutPing == nil && c.DukJam != nil { _max := -1 for _, dj := range *c.DukJam { if _max < dj.Weight { _max = dj.Weight c.JyutPing = dj.JyutPing } } } } return JyutPingMap, nil }