number_formatter.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. // Copyright (c) 2014-2021 Thomas Fussell
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE
  20. //
  21. // @license: http://www.opensource.org/licenses/mit-license.php
  22. // @author: see AUTHORS file
  23. #pragma once
  24. #include <string>
  25. #include <unordered_map>
  26. #include <vector>
  27. #include <xlnt/utils/datetime.hpp>
  28. #include <xlnt/utils/numeric.hpp>
  29. namespace xlnt {
  30. namespace detail {
  31. enum class format_color
  32. {
  33. black,
  34. blue,
  35. cyan,
  36. green,
  37. magenta,
  38. red,
  39. white,
  40. yellow,
  41. color1,
  42. color2,
  43. color3,
  44. color4,
  45. color5,
  46. color6,
  47. color7,
  48. color8,
  49. color9,
  50. color10,
  51. color11,
  52. color12,
  53. color13,
  54. color14,
  55. color15,
  56. color16,
  57. color17,
  58. color18,
  59. color19,
  60. color20,
  61. color21,
  62. color22,
  63. color23,
  64. color24,
  65. color25,
  66. color26,
  67. color27,
  68. color28,
  69. color29,
  70. color30,
  71. color31,
  72. color32,
  73. color33,
  74. color34,
  75. color35,
  76. color36,
  77. color37,
  78. color38,
  79. color39,
  80. color40,
  81. color41,
  82. color42,
  83. color43,
  84. color44,
  85. color45,
  86. color46,
  87. color47,
  88. color48,
  89. color49,
  90. color50,
  91. color51,
  92. color52,
  93. color53,
  94. color54,
  95. color55,
  96. color56
  97. };
  98. enum class format_locale
  99. {
  100. arabic = 0x1,
  101. bulgarian = 0x2,
  102. catalan = 0x3,
  103. chinese_simplified = 0x4,
  104. chinese_simplified_legacy = 0x4,
  105. czech = 0x5,
  106. danish = 0x6,
  107. german = 0x7,
  108. greek = 0x8,
  109. english = 0x9,
  110. spanish = 0xA,
  111. finnish = 0xB,
  112. french = 0xC,
  113. hebrew = 0xD,
  114. hungarian = 0xE,
  115. icelandic = 0xF,
  116. italian = 0x10,
  117. japanese = 0x11,
  118. korean = 0x12,
  119. dutch = 0x13,
  120. norwegian = 0x14,
  121. polish = 0x15,
  122. portuguese = 0x16,
  123. romansh = 0x17,
  124. romanian = 0x18,
  125. russian = 0x19,
  126. croatian = 0x1A,
  127. slovak = 0x1B,
  128. albanian = 0x1C,
  129. swedish = 0x1D,
  130. thai = 0x1E,
  131. turkish = 0x1F,
  132. urdu = 0x20,
  133. indonesian = 0x21,
  134. ukrainian = 0x22,
  135. belarusian = 0x23,
  136. slovenian = 0x24,
  137. estonian = 0x25,
  138. latvian = 0x26,
  139. lithuanian = 0x27,
  140. tajik = 0x28,
  141. persian = 0x29,
  142. vietnamese = 0x2A,
  143. armenian = 0x2B,
  144. azerbaijani = 0x2C,
  145. basque = 0x2D,
  146. upper_sorbian = 0x2E,
  147. macedonian_fyrom = 0x2F,
  148. southern_sotho = 0x30,
  149. tsonga = 0x31,
  150. setswana = 0x32,
  151. venda = 0x33,
  152. isixhosa = 0x34,
  153. isizulu = 0x35,
  154. afrikaans = 0x36,
  155. georgian = 0x37,
  156. faroese = 0x38,
  157. hindi = 0x39,
  158. maltese = 0x3A,
  159. sami_northern = 0x3B,
  160. irish = 0x3C,
  161. yiddish = 0x3D,
  162. malay = 0x3E,
  163. kazakh = 0x3F,
  164. kyrgyz = 0x40,
  165. kiswahili = 0x41,
  166. turkmen = 0x42,
  167. uzbek = 0x43,
  168. tatar = 0x44,
  169. bangla = 0x45,
  170. punjabi = 0x46,
  171. gujarati = 0x47,
  172. odia = 0x48,
  173. tamil = 0x49,
  174. telugu = 0x4A,
  175. kannada = 0x4B,
  176. malayalam = 0x4C,
  177. assamese = 0x4D,
  178. marathi = 0x4E,
  179. sanskrit = 0x4F,
  180. mongolian = 0x50,
  181. tibetan = 0x51,
  182. welsh = 0x52,
  183. khmer = 0x53,
  184. lao = 0x54,
  185. burmese = 0x55,
  186. galician = 0x56,
  187. konkani = 0x57,
  188. manipuri = 0x58,
  189. sindhi = 0x59,
  190. syriac = 0x5A,
  191. sinhala = 0x5B,
  192. cherokee = 0x5C,
  193. inuktitut = 0x5D,
  194. amharic = 0x5E,
  195. tamazight = 0x5F,
  196. kashmiri = 0x60,
  197. nepali = 0x61,
  198. frisian = 0x62,
  199. pashto = 0x63,
  200. filipino = 0x64,
  201. divehi = 0x65,
  202. edo = 0x66,
  203. fulah = 0x67,
  204. hausa = 0x68,
  205. ibibio = 0x69,
  206. yoruba = 0x6A,
  207. quechua = 0x6B,
  208. sesotho_sa_leboa = 0x6C,
  209. bashkir = 0x6D,
  210. luxembourgish = 0x6E,
  211. greenlandic = 0x6F,
  212. igbo = 0x70,
  213. kanuri = 0x71,
  214. oromo = 0x72,
  215. tigrinya = 0x73,
  216. guarani = 0x74,
  217. hawaiian = 0x75,
  218. latin = 0x76,
  219. somali = 0x77,
  220. yi = 0x78,
  221. papiamento = 0x79,
  222. mapudungun = 0x7A,
  223. mohawk = 0x7C,
  224. breton = 0x7E,
  225. invariant_language_invariant_country = 0x7F,
  226. uyghur = 0x80,
  227. maori = 0x81,
  228. occitan = 0x82,
  229. corsican = 0x83,
  230. alsatian = 0x84,
  231. sakha = 0x85,
  232. kiche = 0x86,
  233. kinyarwanda = 0x87,
  234. wolof = 0x88,
  235. dari = 0x8C,
  236. scottish_gaelic = 0x91,
  237. central_kurdish = 0x92,
  238. arabic_saudi_arabia = 0x401,
  239. bulgarian_bulgaria = 0x402,
  240. catalan_catalan = 0x403,
  241. chinese_traditional_taiwan = 0x404,
  242. czech_czech_republic = 0x405,
  243. danish_denmark = 0x406,
  244. german_germany = 0x407,
  245. greek_greece = 0x408,
  246. english_united_states = 0x409,
  247. finnish_finland = 0x40B,
  248. french_france = 0x40C,
  249. hebrew_israel = 0x40D,
  250. hungarian_hungary = 0x40E,
  251. icelandic_iceland = 0x40F,
  252. italian_italy = 0x410,
  253. japanese_japan = 0x411,
  254. korean_korea = 0x412,
  255. dutch_netherlands = 0x413,
  256. norwegian_bokml_norway = 0x414,
  257. polish_poland = 0x415,
  258. portuguese_brazil = 0x416,
  259. romansh_switzerland = 0x417,
  260. romanian_romania = 0x418,
  261. russian_russia = 0x419,
  262. croatian_croatia = 0x41A,
  263. slovak_slovakia = 0x41B,
  264. albanian_albania = 0x41C,
  265. swedish_sweden = 0x41D,
  266. thai_thailand = 0x41E,
  267. turkish_turkey = 0x41F,
  268. urdu_islamic_republic_of_pakistan = 0x420,
  269. indonesian_indonesia = 0x421,
  270. ukrainian_ukraine = 0x422,
  271. belarusian_belarus = 0x423,
  272. slovenian_slovenia = 0x424,
  273. estonian_estonia = 0x425,
  274. latvian_latvia = 0x426,
  275. lithuanian_lithuania = 0x427,
  276. tajik_cyrillic_tajikistan = 0x428,
  277. persian_iran = 0x429,
  278. vietnamese_vietnam = 0x42A,
  279. armenian_armenia = 0x42B,
  280. azerbaijani_latin_azerbaijan = 0x42C,
  281. basque_basque = 0x42D,
  282. upper_sorbian_germany = 0x42E,
  283. macedonian_former_yugoslav_republic_of_macedonia = 0x42F,
  284. southern_sotho_south_africa = 0x430,
  285. tsonga_south_africa = 0x431,
  286. setswana_south_africa = 0x432,
  287. venda_south_africa = 0x433,
  288. isixhosa_south_africa = 0x434,
  289. isizulu_south_africa = 0x435,
  290. afrikaans_south_africa = 0x436,
  291. georgian_georgia = 0x437,
  292. faroese_faroe_islands = 0x438,
  293. hindi_india = 0x439,
  294. maltese_malta = 0x43A,
  295. sami_northern_norway = 0x43B,
  296. yiddish_world = 0x43D,
  297. malay_malaysia = 0x43E,
  298. kazakh_kazakhstan = 0x43F,
  299. kyrgyz_kyrgyzstan = 0x440,
  300. kiswahili_kenya = 0x441,
  301. turkmen_turkmenistan = 0x442,
  302. uzbek_latin_uzbekistan = 0x443,
  303. tatar_russia = 0x444,
  304. bangla_india = 0x445,
  305. punjabi_india = 0x446,
  306. gujarati_india = 0x447,
  307. odia_india = 0x448,
  308. tamil_india = 0x449,
  309. telugu_india = 0x44A,
  310. kannada_india = 0x44B,
  311. malayalam_india = 0x44C,
  312. assamese_india = 0x44D,
  313. marathi_india = 0x44E,
  314. sanskrit_india = 0x44F,
  315. mongolian_cyrillic_mongolia = 0x450,
  316. tibetan_prc = 0x451,
  317. welsh_united_kingdom = 0x452,
  318. khmer_cambodia = 0x453,
  319. lao_lao_p_d_r = 0x454,
  320. burmese_myanmar = 0x455,
  321. galician_galician = 0x456,
  322. konkani_india = 0x457,
  323. manipuri_india = 0x458,
  324. sindhi_devanagari_india = 0x459,
  325. syriac_syria = 0x45A,
  326. sinhala_sri_lanka = 0x45B,
  327. cherokee_cherokee = 0x45C,
  328. inuktitut_syllabics_canada = 0x45D,
  329. amharic_ethiopia = 0x45E,
  330. central_atlas_tamazight_arabic_morocco = 0x45F,
  331. kashmiri_perso_arabic = 0x460,
  332. nepali_nepal = 0x461,
  333. frisian_netherlands = 0x462,
  334. pashto_afghanistan = 0x463,
  335. filipino_philippines = 0x464,
  336. divehi_maldives = 0x465,
  337. edo_nigeria = 0x466,
  338. fulah_nigeria = 0x467,
  339. hausa_latin_nigeria = 0x468,
  340. ibibio_nigeria = 0x469,
  341. yoruba_nigeria = 0x46A,
  342. quechua_bolivia = 0x46B,
  343. sesotho_sa_leboa_south_africa = 0x46C,
  344. bashkir_russia = 0x46D,
  345. luxembourgish_luxembourg = 0x46E,
  346. greenlandic_greenland = 0x46F,
  347. igbo_nigeria = 0x470,
  348. kanuri_nigeria = 0x471,
  349. oromo_ethiopia = 0x472,
  350. tigrinya_ethiopia = 0x473,
  351. guarani_paraguay = 0x474,
  352. hawaiian_united_states = 0x475,
  353. latin_world = 0x476,
  354. somali_somalia = 0x477,
  355. yi_prc = 0x478,
  356. papiamento_caribbean = 0x479,
  357. mapudungun_chile = 0x47A,
  358. mohawk_mohawk = 0x47C,
  359. breton_france = 0x47E,
  360. uyghur_prc = 0x480,
  361. maori_new_zealand = 0x481,
  362. occitan_france = 0x482,
  363. corsican_france = 0x483,
  364. alsatian_france = 0x484,
  365. sakha_russia = 0x485,
  366. kiche_guatemala = 0x486,
  367. kinyarwanda_rwanda = 0x487,
  368. wolof_senegal = 0x488,
  369. dari_afghanistan = 0x48C,
  370. scottish_gaelic_united_kingdom = 0x491,
  371. central_kurdish_iraq = 0x492,
  372. arabic_iraq = 0x801,
  373. valencian_spain = 0x803,
  374. chinese_simplified_prc = 0x804,
  375. german_switzerland = 0x807,
  376. english_united_kingdom = 0x809,
  377. spanish_mexico = 0x80A,
  378. french_belgium = 0x80C,
  379. italian_switzerland = 0x810,
  380. dutch_belgium = 0x813,
  381. norwegian_nynorsk_norway = 0x814,
  382. portuguese_portugal = 0x816,
  383. romanian_moldova = 0x818,
  384. russian_moldova = 0x819,
  385. swedish_finland = 0x81D,
  386. urdu_india = 0x820,
  387. azerbaijani_cyrillic_azerbaijan = 0x82C,
  388. lower_sorbian_germany = 0x82E,
  389. setswana_botswana = 0x832,
  390. sami_northern_sweden = 0x83B,
  391. irish_ireland = 0x83C,
  392. malay_brunei_darussalam = 0x83E,
  393. uzbek_cyrillic_uzbekistan = 0x843,
  394. bangla_bangladesh = 0x845,
  395. punjabi_islamic_republic_of_pakistan = 0x846,
  396. tamil_sri_lanka = 0x849,
  397. mongolian_traditional_mongolian_prc = 0x850,
  398. sindhi_islamic_republic_of_pakistan = 0x859,
  399. inuktitut_latin_canada = 0x85D,
  400. tamazight_latin_algeria = 0x85F,
  401. kashmiri_devanagari_india = 0x860,
  402. nepali_india = 0x861,
  403. fulah_latin_senegal = 0x867,
  404. quechua_ecuador = 0x86B,
  405. tigrinya_eritrea = 0x873,
  406. arabic_egypt = 0xC01,
  407. chinese_traditional_hong_kong_s_a_r = 0xC04,
  408. german_austria = 0xC07,
  409. english_australia = 0xC09,
  410. spanish_spain = 0xC0A,
  411. french_canada = 0xC0C,
  412. sami_northern_finland = 0xC3B,
  413. mongolian_traditional_mongolian_mongolia = 0xC50,
  414. dzongkha_bhutan = 0xC51,
  415. quechua_peru = 0xC6B,
  416. arabic_libya = 0x1001,
  417. chinese_simplified_singapore = 0x1004,
  418. german_luxembourg = 0x1007,
  419. english_canada = 0x1009,
  420. spanish_guatemala = 0x100A,
  421. french_switzerland = 0x100C,
  422. croatian_latin_bosnia_and_herzegovina = 0x101A,
  423. sami_lule_norway = 0x103B,
  424. central_atlas_tamazight_tifinagh_morocco = 0x105F,
  425. arabic_algeria = 0x1401,
  426. chinese_traditional_macao_s_a_r = 0x1404,
  427. german_liechtenstein = 0x1407,
  428. english_new_zealand = 0x1409,
  429. spanish_costa_rica = 0x140A,
  430. french_luxembourg = 0x140C,
  431. bosnian_latin_bosnia_and_herzegovina = 0x141A,
  432. sami_lule_sweden = 0x143B,
  433. arabic_morocco = 0x1801,
  434. english_ireland = 0x1809,
  435. spanish_panama = 0x180A,
  436. french_monaco = 0x180C,
  437. serbian_latin_bosnia_and_herzegovina = 0x181A,
  438. sami_southern_norway = 0x183B,
  439. arabic_tunisia = 0x1C01,
  440. english_south_africa = 0x1C09,
  441. spanish_dominican_republic = 0x1C0A,
  442. french_caribbean = 0x1C0C,
  443. serbian_cyrillic_bosnia_and_herzegovina = 0x1C1A,
  444. sami_southern_sweden = 0x1C3B,
  445. arabic_oman = 0x2001,
  446. english_jamaica = 0x2009,
  447. spanish_venezuela = 0x200A,
  448. french_reunion = 0x200C,
  449. bosnian_cyrillic_bosnia_and_herzegovina = 0x201A,
  450. sami_skolt_finland = 0x203B,
  451. arabic_yemen = 0x2401,
  452. english_caribbean = 0x2409,
  453. spanish_colombia = 0x240A,
  454. french_congo_drc = 0x240C,
  455. serbian_latin_serbia = 0x241A,
  456. sami_inari_finland = 0x243B,
  457. arabic_syria = 0x2801,
  458. english_belize = 0x2809,
  459. spanish_peru = 0x280A,
  460. french_senegal = 0x280C,
  461. serbian_cyrillic_serbia = 0x281A,
  462. arabic_jordan = 0x2C01,
  463. english_trinidad_and_tobago = 0x2C09,
  464. spanish_argentina = 0x2C0A,
  465. french_cameroon = 0x2C0C,
  466. serbian_latin_montenegro = 0x2C1A,
  467. arabic_lebanon = 0x3001,
  468. english_zimbabwe = 0x3009,
  469. spanish_ecuador = 0x300A,
  470. french_cote_divoire = 0x300C,
  471. serbian_cyrillic_montenegro = 0x301A,
  472. arabic_kuwait = 0x3401,
  473. english_philippines = 0x3409,
  474. spanish_chile = 0x340A,
  475. french_mali = 0x340C,
  476. arabic_u_a_e = 0x3801,
  477. english_indonesia = 0x3809,
  478. spanish_uruguay = 0x380A,
  479. french_morocco = 0x380C,
  480. arabic_bahrain = 0x3C01,
  481. english_hong_kong_sar = 0x3C09,
  482. spanish_paraguay = 0x3C0A,
  483. french_haiti = 0x3C0C,
  484. arabic_qatar = 0x4001,
  485. english_india = 0x4009,
  486. spanish_bolivia = 0x400A,
  487. english_malaysia = 0x4409,
  488. spanish_el_salvador = 0x440A,
  489. english_singapore = 0x4809,
  490. spanish_honduras = 0x480A,
  491. spanish_nicaragua = 0x4C0A,
  492. spanish_puerto_rico = 0x500A,
  493. spanish_united_states = 0x540A,
  494. spanish_latin_america = 0x580A,
  495. spanish_cuba = 0x5C0A,
  496. bosnian_cyrillic = 0x641A,
  497. bosnian_latin = 0x681A,
  498. serbian_cyrillic = 0x6C1A,
  499. serbian_latin = 0x701A,
  500. sami_inari = 0x703B,
  501. azerbaijani_cyrillic = 0x742C,
  502. sami_skolt = 0x743B,
  503. chinese = 0x7804,
  504. norwegian_nynorsk = 0x7814,
  505. bosnian = 0x781A,
  506. azerbaijani_latin = 0x782C,
  507. sami_southern = 0x783B,
  508. uzbek_cyrillic = 0x7843,
  509. mongolian_cyrillic = 0x7850,
  510. inuktitut_syllabics = 0x785D,
  511. tamazight_tifinagh = 0x785F,
  512. chinese_traditional = 0x7C04,
  513. chinese_traditional_legacy = 0x7C04,
  514. norwegian_bokml = 0x7C14,
  515. serbian = 0x7C1A,
  516. tajik_cyrillic = 0x7C28,
  517. lower_sorbian = 0x7C2E,
  518. sami_lule = 0x7C3B,
  519. uzbek_latin = 0x7C43,
  520. punjabi_arabic = 0x7C46,
  521. mongolian_traditional_mongolian = 0x7C50,
  522. sindhi_arabic = 0x7C59,
  523. inuktitut_latin = 0x7C5D,
  524. tamazight_latin = 0x7C5F,
  525. fulah_latin = 0x7C67,
  526. hausa_latin = 0x7C68,
  527. central_kurdish_arabic = 0x7C92,
  528. system_default_time = 0xF400,
  529. system_default_long_date = 0xF800
  530. };
  531. // TODO this really shouldn't be exported...
  532. struct XLNT_API format_condition
  533. {
  534. enum class condition_type
  535. {
  536. less_than,
  537. less_or_equal,
  538. equal,
  539. not_equal,
  540. greater_than,
  541. greater_or_equal
  542. } type = condition_type::not_equal;
  543. double value = 0.0;
  544. bool satisfied_by(double number) const;
  545. };
  546. struct format_placeholders
  547. {
  548. enum class placeholders_type
  549. {
  550. general,
  551. text,
  552. integer_only,
  553. integer_part,
  554. fractional_part,
  555. fraction_integer,
  556. fraction_numerator,
  557. fraction_denominator,
  558. scientific_significand,
  559. scientific_exponent_plus,
  560. scientific_exponent_minus
  561. } type = placeholders_type::general;
  562. bool use_comma_separator = false;
  563. bool percentage = false;
  564. bool scientific = false;
  565. std::size_t num_zeros = 0; // 0
  566. std::size_t num_optionals = 0; // #
  567. std::size_t num_spaces = 0; // ?
  568. std::size_t thousands_scale = 0;
  569. };
  570. struct number_format_token
  571. {
  572. enum class token_type
  573. {
  574. color,
  575. locale,
  576. condition,
  577. text,
  578. fill,
  579. space,
  580. number,
  581. datetime,
  582. end_section,
  583. end
  584. } type = token_type::end;
  585. std::string string;
  586. };
  587. struct template_part
  588. {
  589. enum class template_type
  590. {
  591. text,
  592. fill,
  593. space,
  594. general,
  595. month_number,
  596. month_number_leading_zero,
  597. month_abbreviation,
  598. month_name,
  599. month_letter,
  600. day_number,
  601. day_number_leading_zero,
  602. day_abbreviation,
  603. day_name,
  604. year_short,
  605. year_long,
  606. hour,
  607. hour_leading_zero,
  608. minute,
  609. minute_leading_zero,
  610. second,
  611. second_fractional,
  612. second_leading_zero,
  613. second_leading_zero_fractional,
  614. am_pm,
  615. a_p,
  616. elapsed_hours,
  617. elapsed_minutes,
  618. elapsed_seconds
  619. } type = template_type::general;
  620. std::string string;
  621. format_placeholders placeholders;
  622. };
  623. struct format_code
  624. {
  625. bool has_color = false;
  626. format_color color = format_color::black;
  627. bool has_locale = false;
  628. format_locale locale = format_locale::english_united_states;
  629. bool has_condition = false;
  630. format_condition condition;
  631. bool is_datetime = false;
  632. bool is_timedelta = false;
  633. bool twelve_hour = false;
  634. std::vector<template_part> parts;
  635. };
  636. class number_format_parser
  637. {
  638. public:
  639. number_format_parser(const std::string &format_string);
  640. const std::vector<format_code> &result() const;
  641. void reset(const std::string &format_string);
  642. void parse();
  643. private:
  644. void finalize();
  645. void validate();
  646. number_format_token parse_next_token();
  647. format_placeholders parse_placeholders(const std::string &placeholders_string);
  648. format_color color_from_string(const std::string &color);
  649. std::pair<format_locale, std::string> locale_from_string(const std::string &locale_string);
  650. std::size_t position_ = 0;
  651. std::string format_string_;
  652. std::vector<format_code> codes_;
  653. };
  654. class XLNT_API number_formatter
  655. {
  656. public:
  657. number_formatter(const std::string &format_string, xlnt::calendar calendar);
  658. std::string format_number(double number);
  659. std::string format_text(const std::string &text);
  660. private:
  661. std::string fill_placeholders(const format_placeholders &p, double number);
  662. std::string fill_fraction_placeholders(const format_placeholders &numerator,
  663. const format_placeholders &denominator, double number, bool improper);
  664. std::string fill_scientific_placeholders(const format_placeholders &integer_part,
  665. const format_placeholders &fractional_part, const format_placeholders &exponent_part,
  666. double number);
  667. std::string format_number(const format_code &format, double number);
  668. std::string format_text(const format_code &format, const std::string &text);
  669. number_format_parser parser_;
  670. std::vector<format_code> format_;
  671. xlnt::calendar calendar_;
  672. xlnt::detail::number_serialiser serialiser_;
  673. };
  674. } // namespace detail
  675. } // namespace xlnt