generate_resources.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "go/format"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "sync"
  11. "text/template"
  12. "time"
  13. "gopkg.in/yaml.v2"
  14. "golang.org/x/text/unicode/cldr"
  15. i18n "github.com/go-playground/universal-translator"
  16. )
  17. // numbers:
  18. // symbols:
  19. // decimal: .
  20. // group: ','
  21. // negative: '-'
  22. // percent: '%'
  23. // permille: "\u2030"
  24. // formats:
  25. // decimal: '#,##0.###'
  26. // currency: "\xA4#,##0.00;(\xA4#,##0.00)"
  27. // percent: '#,##0%'
  28. // currencies:
  29. // JPY:
  30. // symbol: "\xA5"
  31. // USD:
  32. // symbol: $
  33. type pluralInfo struct {
  34. path string
  35. locale string
  36. plural string
  37. }
  38. func main() {
  39. //plurals
  40. rules := "data/rules"
  41. plurals := map[string]*pluralInfo{}
  42. basePlurals := map[string]string{}
  43. err := filepath.Walk(rules, func(path string, info os.FileInfo, err error) error {
  44. if err != nil {
  45. panic(err)
  46. }
  47. if info.IsDir() {
  48. return nil
  49. }
  50. in, err := ioutil.ReadFile(path)
  51. if err != nil {
  52. panic(err)
  53. }
  54. var out yaml.MapSlice
  55. if err = yaml.Unmarshal(in, &out); err != nil {
  56. panic(err)
  57. }
  58. var plural string
  59. for _, item := range out {
  60. if item.Key == "plural" {
  61. plural = item.Value.(string)
  62. }
  63. }
  64. locale := strings.Replace(info.Name(), filepath.Ext(info.Name()), "", 1)
  65. locale = strings.ToLower(strings.Replace(locale, "-", "_", -1))
  66. plurals[locale] = &pluralInfo{
  67. path: path,
  68. locale: locale,
  69. plural: plural,
  70. }
  71. if plural == "" {
  72. return nil
  73. }
  74. basePlurals[locale] = plural
  75. return nil
  76. })
  77. if err != nil {
  78. panic(err)
  79. }
  80. for _, p := range plurals {
  81. if p.plural == "" {
  82. var ok bool
  83. fmt.Print("can't find plurals in ", p.path, " attempting to locate base language plural rules...")
  84. base := strings.SplitN(p.locale, "_", 2)
  85. p.plural, ok = basePlurals[base[0]]
  86. if !ok {
  87. fmt.Println("Not Found")
  88. continue
  89. }
  90. fmt.Println("Found")
  91. }
  92. }
  93. // cldr
  94. var decoder cldr.Decoder
  95. cldr, err := decoder.DecodePath("data/core")
  96. if err != nil {
  97. panic(err)
  98. }
  99. locs := map[string]string{}
  100. numbers := map[string]i18n.Number{}
  101. calendars := map[string]i18n.Calendar{}
  102. locales := cldr.Locales()
  103. for _, loc := range locales {
  104. ldml := cldr.RawLDML(loc)
  105. if ldml.Numbers == nil {
  106. continue
  107. }
  108. var number i18n.Number
  109. number.Currencies = make(i18n.CurrencyFormatValue)
  110. if len(ldml.Numbers.Symbols) > 0 {
  111. symbol := ldml.Numbers.Symbols[0]
  112. if len(symbol.Decimal) > 0 {
  113. number.Symbols.Decimal = symbol.Decimal[0].Data()
  114. }
  115. if len(symbol.Group) > 0 {
  116. number.Symbols.Group = symbol.Group[0].Data()
  117. }
  118. if len(symbol.MinusSign) > 0 {
  119. number.Symbols.Negative = symbol.MinusSign[0].Data()
  120. }
  121. if len(symbol.PercentSign) > 0 {
  122. number.Symbols.Percent = symbol.PercentSign[0].Data()
  123. }
  124. if len(symbol.PerMille) > 0 {
  125. number.Symbols.PerMille = symbol.PerMille[0].Data()
  126. }
  127. }
  128. if len(ldml.Numbers.DecimalFormats) > 0 && len(ldml.Numbers.DecimalFormats[0].DecimalFormatLength) > 0 {
  129. number.Formats.Decimal = ldml.Numbers.DecimalFormats[0].DecimalFormatLength[0].DecimalFormat[0].Pattern[0].Data()
  130. }
  131. if len(ldml.Numbers.CurrencyFormats) > 0 && len(ldml.Numbers.CurrencyFormats[0].CurrencyFormatLength) > 0 {
  132. number.Formats.Currency = ldml.Numbers.CurrencyFormats[0].CurrencyFormatLength[0].CurrencyFormat[0].Pattern[0].Data()
  133. number.Formats.CurrencyAccounting = number.Formats.Currency
  134. if len(ldml.Numbers.CurrencyFormats[0].CurrencyFormatLength[0].CurrencyFormat) > 1 {
  135. number.Formats.CurrencyAccounting = ldml.Numbers.CurrencyFormats[0].CurrencyFormatLength[0].CurrencyFormat[1].Pattern[0].Data()
  136. }
  137. }
  138. if len(ldml.Numbers.PercentFormats) > 0 && len(ldml.Numbers.PercentFormats[0].PercentFormatLength) > 0 {
  139. number.Formats.Percent = ldml.Numbers.PercentFormats[0].PercentFormatLength[0].PercentFormat[0].Pattern[0].Data()
  140. }
  141. if ldml.Numbers.Currencies != nil {
  142. for _, currency := range ldml.Numbers.Currencies.Currency {
  143. var c i18n.Currency
  144. c.Currency = currency.Type
  145. if len(currency.DisplayName) > 0 {
  146. c.DisplayName = currency.DisplayName[0].Data()
  147. }
  148. if len(currency.Symbol) > 0 {
  149. c.Symbol = currency.Symbol[0].Data()
  150. }
  151. number.Currencies[c.Currency] = c
  152. }
  153. }
  154. numbers[loc] = number
  155. locs[loc] = strings.ToLower(strings.Replace(loc, "_", "", -1))
  156. if ldml.Dates != nil && ldml.Dates.Calendars != nil {
  157. var calendar i18n.Calendar
  158. ldmlCar := ldml.Dates.Calendars.Calendar[0]
  159. for _, cal := range ldml.Dates.Calendars.Calendar {
  160. if cal.Type == "gregorian" {
  161. ldmlCar = cal
  162. }
  163. }
  164. if ldmlCar.DateFormats != nil {
  165. for _, datefmt := range ldmlCar.DateFormats.DateFormatLength {
  166. switch datefmt.Type {
  167. case "full":
  168. calendar.Formats.DateEra.BC.Full = datefmt.DateFormat[0].Pattern[0].Data()
  169. calendar.Formats.DateEra.AD.Full = calendar.Formats.DateEra.BC.Full
  170. case "long":
  171. calendar.Formats.DateEra.BC.Long = datefmt.DateFormat[0].Pattern[0].Data()
  172. calendar.Formats.DateEra.AD.Long = calendar.Formats.DateEra.BC.Long
  173. // Overrides TODO: Split Each Section into separate function, getting to big to maintain
  174. case "medium":
  175. calendar.Formats.DateEra.BC.Medium = datefmt.DateFormat[0].Pattern[0].Data()
  176. calendar.Formats.DateEra.AD.Medium = calendar.Formats.DateEra.BC.Medium
  177. case "short":
  178. calendar.Formats.DateEra.BC.Short = datefmt.DateFormat[0].Pattern[0].Data()
  179. calendar.Formats.DateEra.AD.Short = calendar.Formats.DateEra.BC.Short
  180. }
  181. }
  182. // Overrides TODO: Split Each Section into separate function, getting to big to maintain
  183. switch loc {
  184. case "th":
  185. calendar.Formats.DateEra.BC.Full = "EEEEที่ d MMMM GGGG y"
  186. calendar.Formats.DateEra.AD.Full = "EEEEที่ d MMMM y GGGG"
  187. calendar.Formats.DateEra.BC.Long = "d MMMM GG y"
  188. calendar.Formats.DateEra.AD.Long = "d MMMM y GG"
  189. case "en":
  190. calendar.Formats.DateEra.BC.Full = "EEEE, MMMM d, y GGGG"
  191. calendar.Formats.DateEra.BC.Long = "MMMM d, y GG"
  192. // calendar.Formats.DateEra.BC.Medium = "MMM d, y GG"
  193. // calendar.Formats.DateEra.BC.Short = "M/d/yy G"
  194. }
  195. }
  196. if ldmlCar.TimeFormats != nil {
  197. for _, datefmt := range ldmlCar.TimeFormats.TimeFormatLength {
  198. switch datefmt.Type {
  199. case "full":
  200. calendar.Formats.Time.Full = datefmt.TimeFormat[0].Pattern[0].Data()
  201. case "long":
  202. calendar.Formats.Time.Long = datefmt.TimeFormat[0].Pattern[0].Data()
  203. case "medium":
  204. calendar.Formats.Time.Medium = datefmt.TimeFormat[0].Pattern[0].Data()
  205. case "short":
  206. calendar.Formats.Time.Short = datefmt.TimeFormat[0].Pattern[0].Data()
  207. }
  208. }
  209. }
  210. if ldmlCar.DateTimeFormats != nil {
  211. for _, datefmt := range ldmlCar.DateTimeFormats.DateTimeFormatLength {
  212. switch datefmt.Type {
  213. case "full":
  214. calendar.Formats.DateTime.Full = datefmt.DateTimeFormat[0].Pattern[0].Data()
  215. case "long":
  216. calendar.Formats.DateTime.Long = datefmt.DateTimeFormat[0].Pattern[0].Data()
  217. case "medium":
  218. calendar.Formats.DateTime.Medium = datefmt.DateTimeFormat[0].Pattern[0].Data()
  219. case "short":
  220. calendar.Formats.DateTime.Short = datefmt.DateTimeFormat[0].Pattern[0].Data()
  221. }
  222. }
  223. }
  224. if ldmlCar.Months != nil {
  225. for _, monthctx := range ldmlCar.Months.MonthContext {
  226. for _, months := range monthctx.MonthWidth {
  227. i18nMonth := make(i18n.CalendarMonthFormatNameValue)
  228. for _, m := range months.Month {
  229. switch m.Type {
  230. case "1":
  231. i18nMonth[time.January] = m.Data()
  232. case "2":
  233. i18nMonth[time.February] = m.Data()
  234. case "3":
  235. i18nMonth[time.March] = m.Data()
  236. case "4":
  237. i18nMonth[time.April] = m.Data()
  238. case "5":
  239. i18nMonth[time.May] = m.Data()
  240. case "6":
  241. i18nMonth[time.June] = m.Data()
  242. case "7":
  243. i18nMonth[time.July] = m.Data()
  244. case "8":
  245. i18nMonth[time.August] = m.Data()
  246. case "9":
  247. i18nMonth[time.September] = m.Data()
  248. case "10":
  249. i18nMonth[time.October] = m.Data()
  250. case "11":
  251. i18nMonth[time.November] = m.Data()
  252. case "12":
  253. i18nMonth[time.December] = m.Data()
  254. }
  255. }
  256. switch months.Type {
  257. case "abbreviated":
  258. calendar.FormatNames.Months.Abbreviated = i18nMonth
  259. case "narrow":
  260. calendar.FormatNames.Months.Narrow = i18nMonth
  261. case "short":
  262. calendar.FormatNames.Months.Short = i18nMonth
  263. case "wide":
  264. calendar.FormatNames.Months.Wide = i18nMonth
  265. }
  266. }
  267. }
  268. }
  269. if ldmlCar.Days != nil {
  270. for _, dayctx := range ldmlCar.Days.DayContext {
  271. for _, days := range dayctx.DayWidth {
  272. i18nDay := make(i18n.CalendarDayFormatNameValue)
  273. for _, d := range days.Day {
  274. switch d.Type {
  275. case "sun":
  276. i18nDay[time.Sunday] = d.Data()
  277. case "mon":
  278. i18nDay[time.Monday] = d.Data()
  279. case "tue":
  280. i18nDay[time.Tuesday] = d.Data()
  281. case "wed":
  282. i18nDay[time.Wednesday] = d.Data()
  283. case "thu":
  284. i18nDay[time.Thursday] = d.Data()
  285. case "fri":
  286. i18nDay[time.Friday] = d.Data()
  287. case "sat":
  288. i18nDay[time.Saturday] = d.Data()
  289. }
  290. }
  291. switch days.Type {
  292. case "abbreviated":
  293. calendar.FormatNames.Days.Abbreviated = i18nDay
  294. case "narrow":
  295. calendar.FormatNames.Days.Narrow = i18nDay
  296. case "short":
  297. calendar.FormatNames.Days.Short = i18nDay
  298. case "wide":
  299. calendar.FormatNames.Days.Wide = i18nDay
  300. }
  301. }
  302. }
  303. }
  304. if ldmlCar.DayPeriods != nil {
  305. for _, ctx := range ldmlCar.DayPeriods.DayPeriodContext {
  306. for _, width := range ctx.DayPeriodWidth {
  307. // var i18nPeriod i18n.CalendarPeriodFormatNameValue
  308. i18nPeriod := make(i18n.CalendarPeriodFormatNameValue)
  309. for _, d := range width.DayPeriod {
  310. if _, ok := i18nPeriod[d.Type]; !ok {
  311. i18nPeriod[d.Type] = d.Data()
  312. }
  313. }
  314. switch width.Type {
  315. case "abbreviated":
  316. calendar.FormatNames.Periods.Abbreviated = i18nPeriod
  317. case "narrow":
  318. calendar.FormatNames.Periods.Narrow = i18nPeriod
  319. case "short":
  320. calendar.FormatNames.Periods.Short = i18nPeriod
  321. case "wide":
  322. calendar.FormatNames.Periods.Wide = i18nPeriod
  323. }
  324. }
  325. }
  326. // var empty i18n.CalendarPeriodFormatNameValue
  327. // if calendar.FormatNames.Periods.Abbreviated == empty {
  328. // calendar.FormatNames.Periods.Abbreviated = calendar.FormatNames.Periods.Wide
  329. // }
  330. }
  331. if ldmlCar.Eras != nil {
  332. var eras i18n.Eras
  333. if ldmlCar.Eras.EraNames != nil && len(ldmlCar.Eras.EraNames.Era) > 0 {
  334. eras.BC.Full = ldmlCar.Eras.EraNames.Era[0].Data()
  335. }
  336. if ldmlCar.Eras.EraAbbr != nil && len(ldmlCar.Eras.EraAbbr.Era) > 0 {
  337. eras.BC.Abbrev = ldmlCar.Eras.EraAbbr.Era[0].Data()
  338. }
  339. if ldmlCar.Eras.EraNarrow != nil && len(ldmlCar.Eras.EraNarrow.Era) > 0 {
  340. eras.BC.Narrow = ldmlCar.Eras.EraNarrow.Era[0].Data()
  341. }
  342. if ldmlCar.Eras.EraNames != nil && len(ldmlCar.Eras.EraNames.Era) > 2 {
  343. eras.AD.Full = ldmlCar.Eras.EraNames.Era[2].Data()
  344. }
  345. if ldmlCar.Eras.EraAbbr != nil && len(ldmlCar.Eras.EraAbbr.Era) > 2 {
  346. eras.AD.Abbrev = ldmlCar.Eras.EraAbbr.Era[2].Data()
  347. }
  348. if ldmlCar.Eras.EraNarrow != nil && len(ldmlCar.Eras.EraNarrow.Era) > 2 {
  349. eras.AD.Narrow = ldmlCar.Eras.EraNarrow.Era[2].Data()
  350. }
  351. calendar.FormatNames.Eras = eras
  352. }
  353. calendars[loc] = calendar
  354. }
  355. }
  356. for locale := range locs {
  357. if !strings.Contains(locale, "_") {
  358. continue
  359. }
  360. calendar := calendars[locale]
  361. bString := strings.SplitN(locale, "_", 2)
  362. base := bString[0]
  363. baseCal := calendars[base]
  364. // copy base calendar objects
  365. // Dates
  366. if calendar.Formats.DateEra.AD.Full == "" {
  367. calendar.Formats.DateEra.BC.Full = baseCal.Formats.DateEra.BC.Full
  368. calendar.Formats.DateEra.AD.Full = baseCal.Formats.DateEra.AD.Full
  369. }
  370. if calendar.Formats.DateEra.AD.Long == "" {
  371. calendar.Formats.DateEra.BC.Long = baseCal.Formats.DateEra.BC.Long
  372. calendar.Formats.DateEra.AD.Long = baseCal.Formats.DateEra.AD.Long
  373. }
  374. if calendar.Formats.DateEra.AD.Medium == "" {
  375. calendar.Formats.DateEra.BC.Medium = baseCal.Formats.DateEra.BC.Medium
  376. calendar.Formats.DateEra.AD.Medium = baseCal.Formats.DateEra.AD.Medium
  377. }
  378. if calendar.Formats.DateEra.AD.Short == "" {
  379. calendar.Formats.DateEra.BC.Short = baseCal.Formats.DateEra.BC.Short
  380. calendar.Formats.DateEra.AD.Short = baseCal.Formats.DateEra.AD.Short
  381. }
  382. // times
  383. if calendar.Formats.Time.Full == "" {
  384. calendar.Formats.Time.Full = baseCal.Formats.Time.Full
  385. }
  386. if calendar.Formats.Time.Long == "" {
  387. calendar.Formats.Time.Long = baseCal.Formats.Time.Long
  388. }
  389. if calendar.Formats.Time.Medium == "" {
  390. calendar.Formats.Time.Medium = baseCal.Formats.Time.Medium
  391. }
  392. if calendar.Formats.Time.Short == "" {
  393. calendar.Formats.Time.Short = baseCal.Formats.Time.Short
  394. }
  395. // date & times
  396. if calendar.Formats.DateTime.Full == "" {
  397. calendar.Formats.DateTime.Full = baseCal.Formats.DateTime.Full
  398. }
  399. if calendar.Formats.DateTime.Long == "" {
  400. calendar.Formats.DateTime.Long = baseCal.Formats.DateTime.Long
  401. }
  402. if calendar.Formats.DateTime.Medium == "" {
  403. calendar.Formats.DateTime.Medium = baseCal.Formats.DateTime.Medium
  404. }
  405. if calendar.Formats.DateTime.Short == "" {
  406. calendar.Formats.DateTime.Short = baseCal.Formats.DateTime.Short
  407. }
  408. // months
  409. if calendar.FormatNames.Months.Abbreviated == nil {
  410. calendar.FormatNames.Months.Abbreviated = make(i18n.CalendarMonthFormatNameValue)
  411. }
  412. if calendar.FormatNames.Months.Narrow == nil {
  413. calendar.FormatNames.Months.Narrow = make(i18n.CalendarMonthFormatNameValue)
  414. }
  415. if calendar.FormatNames.Months.Short == nil {
  416. calendar.FormatNames.Months.Short = make(i18n.CalendarMonthFormatNameValue)
  417. }
  418. if calendar.FormatNames.Months.Wide == nil {
  419. calendar.FormatNames.Months.Wide = make(i18n.CalendarMonthFormatNameValue)
  420. }
  421. for k, v := range baseCal.FormatNames.Months.Abbreviated {
  422. val, ok := calendar.FormatNames.Months.Abbreviated[k]
  423. if !ok {
  424. calendar.FormatNames.Months.Abbreviated[k] = v
  425. continue
  426. }
  427. if val == "" {
  428. calendar.FormatNames.Months.Abbreviated[k] = v
  429. }
  430. }
  431. for k, v := range baseCal.FormatNames.Months.Narrow {
  432. val, ok := calendar.FormatNames.Months.Narrow[k]
  433. if !ok {
  434. calendar.FormatNames.Months.Narrow[k] = v
  435. continue
  436. }
  437. if val == "" {
  438. calendar.FormatNames.Months.Narrow[k] = v
  439. }
  440. }
  441. for k, v := range baseCal.FormatNames.Months.Short {
  442. val, ok := calendar.FormatNames.Months.Short[k]
  443. if !ok {
  444. calendar.FormatNames.Months.Short[k] = v
  445. continue
  446. }
  447. if val == "" {
  448. calendar.FormatNames.Months.Short[k] = v
  449. }
  450. }
  451. for k, v := range baseCal.FormatNames.Months.Wide {
  452. val, ok := calendar.FormatNames.Months.Wide[k]
  453. if !ok {
  454. calendar.FormatNames.Months.Wide[k] = v
  455. continue
  456. }
  457. if val == "" {
  458. calendar.FormatNames.Months.Wide[k] = v
  459. }
  460. }
  461. // days
  462. if calendar.FormatNames.Days.Abbreviated == nil {
  463. calendar.FormatNames.Days.Abbreviated = make(i18n.CalendarDayFormatNameValue)
  464. }
  465. if calendar.FormatNames.Days.Narrow == nil {
  466. calendar.FormatNames.Days.Narrow = make(i18n.CalendarDayFormatNameValue)
  467. }
  468. if calendar.FormatNames.Days.Short == nil {
  469. calendar.FormatNames.Days.Short = make(i18n.CalendarDayFormatNameValue)
  470. }
  471. if calendar.FormatNames.Days.Wide == nil {
  472. calendar.FormatNames.Days.Wide = make(i18n.CalendarDayFormatNameValue)
  473. }
  474. for k, v := range baseCal.FormatNames.Days.Abbreviated {
  475. val, ok := calendar.FormatNames.Days.Abbreviated[k]
  476. if !ok {
  477. calendar.FormatNames.Days.Abbreviated[k] = v
  478. continue
  479. }
  480. if val == "" {
  481. calendar.FormatNames.Days.Abbreviated[k] = v
  482. }
  483. }
  484. for k, v := range baseCal.FormatNames.Days.Narrow {
  485. val, ok := calendar.FormatNames.Days.Narrow[k]
  486. if !ok {
  487. calendar.FormatNames.Days.Narrow[k] = v
  488. continue
  489. }
  490. if val == "" {
  491. calendar.FormatNames.Days.Narrow[k] = v
  492. }
  493. }
  494. for k, v := range baseCal.FormatNames.Days.Short {
  495. val, ok := calendar.FormatNames.Days.Short[k]
  496. if !ok {
  497. calendar.FormatNames.Days.Short[k] = v
  498. continue
  499. }
  500. if val == "" {
  501. calendar.FormatNames.Days.Short[k] = v
  502. }
  503. }
  504. for k, v := range baseCal.FormatNames.Days.Wide {
  505. val, ok := calendar.FormatNames.Days.Wide[k]
  506. if !ok {
  507. calendar.FormatNames.Days.Wide[k] = v
  508. continue
  509. }
  510. if val == "" {
  511. calendar.FormatNames.Days.Wide[k] = v
  512. }
  513. }
  514. // periods
  515. if calendar.FormatNames.Periods.Abbreviated == nil {
  516. calendar.FormatNames.Periods.Abbreviated = make(i18n.CalendarPeriodFormatNameValue)
  517. }
  518. if calendar.FormatNames.Periods.Narrow == nil {
  519. calendar.FormatNames.Periods.Narrow = make(i18n.CalendarPeriodFormatNameValue)
  520. }
  521. if calendar.FormatNames.Periods.Short == nil {
  522. calendar.FormatNames.Periods.Short = make(i18n.CalendarPeriodFormatNameValue)
  523. }
  524. if calendar.FormatNames.Periods.Wide == nil {
  525. calendar.FormatNames.Periods.Wide = make(i18n.CalendarPeriodFormatNameValue)
  526. }
  527. for k, v := range baseCal.FormatNames.Periods.Abbreviated {
  528. val, ok := calendar.FormatNames.Periods.Abbreviated[k]
  529. if !ok {
  530. calendar.FormatNames.Periods.Abbreviated[k] = v
  531. continue
  532. }
  533. if val == "" {
  534. calendar.FormatNames.Periods.Abbreviated[k] = v
  535. }
  536. }
  537. for k, v := range baseCal.FormatNames.Periods.Narrow {
  538. val, ok := calendar.FormatNames.Periods.Narrow[k]
  539. if !ok {
  540. calendar.FormatNames.Periods.Narrow[k] = v
  541. continue
  542. }
  543. if val == "" {
  544. calendar.FormatNames.Periods.Narrow[k] = v
  545. }
  546. }
  547. for k, v := range baseCal.FormatNames.Periods.Short {
  548. val, ok := calendar.FormatNames.Periods.Short[k]
  549. if !ok {
  550. calendar.FormatNames.Periods.Short[k] = v
  551. continue
  552. }
  553. if val == "" {
  554. calendar.FormatNames.Periods.Short[k] = v
  555. }
  556. }
  557. for k, v := range baseCal.FormatNames.Periods.Wide {
  558. val, ok := calendar.FormatNames.Periods.Wide[k]
  559. if !ok {
  560. calendar.FormatNames.Periods.Wide[k] = v
  561. continue
  562. }
  563. if val == "" {
  564. calendar.FormatNames.Periods.Wide[k] = v
  565. }
  566. }
  567. calendars[locale] = calendar
  568. number := numbers[locale]
  569. baseNum := numbers[base]
  570. // symbols
  571. if number.Symbols.Decimal == "" {
  572. number.Symbols.Decimal = baseNum.Symbols.Decimal
  573. }
  574. if number.Symbols.Group == "" {
  575. number.Symbols.Group = baseNum.Symbols.Group
  576. }
  577. if number.Symbols.Negative == "" {
  578. number.Symbols.Negative = baseNum.Symbols.Negative
  579. }
  580. if number.Symbols.Percent == "" {
  581. number.Symbols.Percent = baseNum.Symbols.Percent
  582. }
  583. if number.Symbols.PerMille == "" {
  584. number.Symbols.PerMille = baseNum.Symbols.PerMille
  585. }
  586. // formats
  587. if number.Formats.Decimal == "" {
  588. number.Formats.Decimal = baseNum.Formats.Decimal
  589. }
  590. if number.Formats.Currency == "" {
  591. number.Formats.Currency = baseNum.Formats.Currency
  592. }
  593. if number.Formats.CurrencyAccounting == "" {
  594. number.Formats.CurrencyAccounting = baseNum.Formats.CurrencyAccounting
  595. }
  596. if number.Formats.Percent == "" {
  597. number.Formats.Percent = baseNum.Formats.Percent
  598. }
  599. // currency
  600. for k, v := range baseNum.Currencies {
  601. val, ok := number.Currencies[k]
  602. if !ok {
  603. // number.Currencies[k] = v
  604. continue
  605. }
  606. if val.Currency == "" {
  607. val.Currency = v.Currency
  608. }
  609. if val.DisplayName == "" {
  610. val.DisplayName = v.DisplayName
  611. }
  612. if val.Symbol == "" {
  613. val.Symbol = v.Symbol
  614. }
  615. number.Currencies[k] = val
  616. }
  617. numbers[locale] = number
  618. }
  619. var wg sync.WaitGroup
  620. wg.Add(len(numbers))
  621. for locale, number := range numbers {
  622. go func(locale string, number i18n.Number) {
  623. localeLowercase := strings.ToLower(locale)
  624. defer func() { wg.Done() }()
  625. path := "../../resources/locales/" + locale
  626. if _, err := os.Stat(path); err != nil {
  627. if err = os.MkdirAll(path, 0777); err != nil {
  628. panic(err)
  629. }
  630. }
  631. path += "/"
  632. mainFile, err := os.Create(path + "main.go")
  633. if err != nil {
  634. panic(err)
  635. }
  636. defer mainFile.Close()
  637. calendar := calendars[locale]
  638. mainCodes, err := format.Source([]byte(fmt.Sprintf(`package %s
  639. import "github.com/go-playground/universal-translator"
  640. var locale = &ut.Locale{
  641. Locale: %q,
  642. Number: ut.Number{
  643. Symbols: symbols,
  644. Formats: formats,
  645. Currencies: currencies,
  646. },
  647. Calendar: calendar,
  648. PluralRule: pluralRule,
  649. }
  650. func init() {
  651. ut.RegisterLocale(locale)
  652. }
  653. `, locale, locale)))
  654. if err != nil {
  655. panic(err)
  656. }
  657. fmt.Fprintf(mainFile, "%s", mainCodes)
  658. numberFile, err := os.Create(path + "number.go")
  659. if err != nil {
  660. panic(err)
  661. }
  662. defer numberFile.Close()
  663. numberCodes, err := format.Source([]byte(fmt.Sprintf(`package %s
  664. import "github.com/go-playground/universal-translator"
  665. var (
  666. symbols = %#v
  667. formats = %#v
  668. )
  669. `, locale, number.Symbols, number.Formats)))
  670. if err != nil {
  671. panic(err)
  672. }
  673. fmt.Fprintf(numberFile, "%s", numberCodes)
  674. currencyFile, err := os.Create(path + "currency.go")
  675. if err != nil {
  676. panic(err)
  677. }
  678. defer currencyFile.Close()
  679. currencyCodes, err := format.Source([]byte(fmt.Sprintf(`package %s
  680. import "github.com/go-playground/universal-translator"
  681. var currencies = %# v
  682. `, locale, number.Currencies)))
  683. if err != nil {
  684. panic(err)
  685. }
  686. fmt.Fprintf(currencyFile, "%s", currencyCodes)
  687. calendarFile, err := os.Create(path + "calendar.go")
  688. if err != nil {
  689. panic(err)
  690. }
  691. defer calendarFile.Close()
  692. calendarCodes, err := format.Source([]byte(fmt.Sprintf(`package %s
  693. import "github.com/go-playground/universal-translator"
  694. var calendar = %#v
  695. `, locale, calendar)))
  696. if err != nil {
  697. panic(err)
  698. }
  699. fmt.Fprintf(calendarFile, "%s", calendarCodes)
  700. var ok bool
  701. pluralCode := "1"
  702. pInfo, ok := plurals[localeLowercase]
  703. if ok && pInfo.plural != "" {
  704. pluralCode = pInfo.plural
  705. }
  706. pluralFile, err := os.Create(path + "plural.go")
  707. if err != nil {
  708. panic(err)
  709. }
  710. defer pluralFile.Close()
  711. pluralCodes, err := format.Source([]byte(fmt.Sprintf(`package %s
  712. var pluralRule = %q
  713. `, locale, pluralCode)))
  714. if err != nil {
  715. panic(err)
  716. }
  717. fmt.Fprintf(pluralFile, "%s", pluralCodes)
  718. }(locale, number)
  719. }
  720. wg.Wait()
  721. // TODO: make switch with all of the locales + function to return new!
  722. localesFile, err := os.Create("../../resources/locales/all.go")
  723. if err != nil {
  724. panic(err)
  725. }
  726. defer localesFile.Close()
  727. tmpl, err := template.New("").Parse(`package locales
  728. // Imports for all locales
  729. import (
  730. {{range $locale, $_ := .}}// Locale "{{$locale}}" import that automatically registers itslef with the universal-translator package
  731. _ "github.com/go-playground/universal-translator/resources/locales/{{$locale}}"
  732. {{end}})
  733. `)
  734. if err != nil {
  735. panic(err)
  736. }
  737. var buf bytes.Buffer
  738. if err := tmpl.Execute(&buf, locs); err != nil {
  739. panic(err)
  740. }
  741. allCodes, err := format.Source(buf.Bytes())
  742. if err != nil {
  743. panic(err)
  744. }
  745. _, err = localesFile.Write(allCodes)
  746. if err != nil {
  747. panic(err)
  748. }
  749. }