kalendarium.sty 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. %%
  2. %% This is file `kalendarium.sty',
  3. %% generated with the docstrip utility.
  4. %%
  5. %% The original source files were:
  6. %%
  7. %% kalendarium.dtx (with options: `package')
  8. %% ----------------------------------------------------------------
  9. %% kalendarium --- Format dates according to the Roman calendar
  10. %% E-mail: aws@awsmith.us
  11. %% Released under the LaTeX Project Public License v1.3c or later
  12. %% See http://www.latex-project.org/lppl.txt
  13. %% ----------------------------------------------------------------
  14. %%
  15. \NeedsTeXFormat{LaTeX2e}
  16. \ProvidesPackage{kalendarium}[2018/06/14 1.0 Format dates using the Roman calendar]
  17. \RequirePackage{xparse}
  18. \RequirePackage{l3keys2e}
  19. \ProvidesExplPackage
  20. {kalendarium}
  21. {2018-06-17}{1.0}
  22. {A package to display dates in the classical Roman style}
  23. \ExplSyntaxOn
  24. \keys_define:nn {kalendarium}{
  25. abbreviate .bool_set:N = \l_kal_abbreviate_bool,
  26. abbreviate .initial:n = { false },
  27. periods .bool_set:N = \l_kal_periods_bool,
  28. periods .initial:n = { true },
  29. era .tl_set:N = \l_kal_era_tl,
  30. era .initial:n = { ad },
  31. julian .bool_set:N = \l_kal_julian_bool,
  32. julian .initial:n = { false },
  33. dayfmt .tl_set:N = \l_kal_dayfmt_tl,
  34. dayfmt .initial:n = { roman },
  35. yearfmt .tl_set:N = \l_kal_yearfmt_tl,
  36. yearfmt .initial:n = { roman },
  37. antediem .bool_set:N = \l_kal_antediem_bool,
  38. antediem .initial:n = { true },
  39. bissextum .bool_set:N = \l_kal_bissextum_bool,
  40. bissextum .initial:n = { true },
  41. oldmonths .bool_set:N = \l_kal_oldmonths_bool,
  42. oldmonths .initial:n = { false }
  43. }
  44. \ProcessKeysOptions {kalendarium}
  45. \clist_new:N \c_kal_day_acc_clist
  46. \clist_set:Nn \c_kal_day_acc_clist {
  47. primum,secundum,tertium,quartum,quintum,sextum,septimum,octavum,nonum,decimum,
  48. undecimum,duodecimum,tertium\ decimum,quartum\ decimum,quintum\ decimum,
  49. sextum\ decimum,septimum\ decimum,duodevicesimum,undevicesimum,bissextum
  50. }
  51. \clist_new:N \c_kal_day_abl_clist
  52. \clist_set:Nn \c_kal_day_abl_clist {
  53. primo,secundo,tertio,quarto,quinto,sexto,septimo,octavo,nono,decimo,
  54. undecimo,duodecimo,tertio\ decimo,quarto\ decimo,quinto\ decimo,
  55. sexto\ decimo,septimo\ decimo,duodevicesimo,undevicesimo,bissexto
  56. }
  57. \clist_new:N \c_kal_weekday_gen_clist
  58. \clist_set:Nn \c_kal_weekday_gen_clist {
  59. Saturni,Solis,Lunae,Martis,Mercurii,Iovis,Veneris
  60. }
  61. \clist_new:N \c_kal_weekday_abbr_clist
  62. \clist_set:Nn \c_kal_weekday_abbr_clist {
  63. Sat,Sol,Lun,Mart,Merc,Iov,Ven
  64. }
  65. \clist_new:N \c_kal_month_acc_clist
  66. \clist_set:Nn \c_kal_month_acc_clist {
  67. Ianuarias,Februarias,Martias,Apriles,Maias,Iunias,Iulias,Augustas,
  68. Septembres,Octobres,Novembres,Decembres,Quintiles,Sextiles,Augustas
  69. }
  70. \clist_new:N \c_kal_month_abl_clist
  71. \clist_set:Nn \c_kal_month_abl_clist {
  72. Ianuariis,Februariis,Martiis,Aprilibus,Maiis,Iuniis,Iuliis,
  73. Augustis,Septembribus,Octobribus,Novembribus,Decembribus,
  74. Quintilibus,Sextilibus,Augustis
  75. }
  76. \clist_new:N \c_kal_month_abbr_clist
  77. \clist_set:Nn \c_kal_month_abbr_clist {
  78. Ian,Feb,Mar,Apr,Mai,Iun,Iul,Aug,Sept,Oct,Nov,Dec,Quin,Sex,Aug
  79. }
  80. \clist_new:N \c_kal_month_lengths_clist
  81. \clist_set:Nn \c_kal_month_lengths_clist {
  82. 31,28,31,30,31,30,31,31,30,31,30,31,31,31
  83. }
  84. \clist_new:N \c_kal_month_ides_clist
  85. \clist_set:Nn \c_kal_month_ides_clist {
  86. 13,13,15,13,15,13,15,13,13,15,13,13,15,13
  87. }
  88. \cs_new:Nn \kal_period:n {
  89. \bool_if:NT \l_kal_periods_bool {.}
  90. }
  91. \cs_new:Npn \kal_abbr:nn #1#2 {
  92. \bool_if:NTF \l_kal_abbreviate_bool {#2 \kal_period:n{}} {#1}
  93. }
  94. \cs_new:Npn \kal_month:nn #1#2 {
  95. \kal_abbr:nn
  96. { \clist_item:Nn {#1} {#2} }
  97. { \clist_item:Nn \c_kal_month_abbr_clist {#2} }
  98. }
  99. \cs_new:Npn \kal_ante_diem:nn #1#2 {
  100. \bool_if:nTF {\l_kal_antediem_bool}
  101. {
  102. \kal_abbr:nn {ante\ diem} {\KalAbbrFormat{a \kal_period:n{} d}}
  103. \ \int_compare:nNnTF {#2} = {1}
  104. { \clist_item:Nn \c_kal_day_acc_clist {#1} }
  105. { #1 }
  106. }
  107. {
  108. \int_compare:nNnTF {#2} = {1}
  109. { \clist_item:Nn \c_kal_day_abl_clist {#1} }
  110. { #1 }
  111. }
  112. }
  113. \cs_new:Npn \kal_day:n #1 {
  114. \int_compare:nNnTF {#1} = {2}
  115. { \kal_abbr:nn {pridie} {prid} }
  116. {
  117. \str_case_e:nnF { \l_kal_dayfmt_tl }
  118. {
  119. { latin } { \kal_ante_diem:nn {#1} {1} }
  120. { roman } { \kal_ante_diem:nn {\KalDayFormat{
  121. \int_to_roman:n {#1}}} {0} }
  122. { arabic } { \kal_ante_diem:nn {\int_eval:n {#1}} {0} }
  123. }
  124. { \kal_ante_diem:nn {\KalDayFormat{\int_to_roman:n {#1}}} {0} }
  125. }
  126. }
  127. \cs_new:Npn \kal_bissextum_day:n #1 {
  128. \int_compare:nNnTF {#1} < {24}
  129. { \kal_day:n { \l_kal_month_length_int - #1 + 1 } }
  130. {
  131. \int_compare:nNnTF {#1} > {24}
  132. { \kal_day:n { \l_kal_month_length_int - #1 + 2 } }
  133. {
  134. \str_case_e:nnF { \l_kal_dayfmt_tl }
  135. {
  136. { latin } { \kal_ante_diem:nn {20} {1} }
  137. { roman } { \kal_ante_diem:nn {bis\ \KalDayFormat{vi} } {0} }
  138. { arabic } { \kal_ante_diem:nn {bis\ \KalDayFormat{6} } {0} }
  139. }
  140. { \kal_ante_diem:nn {bis\ \KalDayFormat{vi} } {0} }
  141. }
  142. }
  143. }
  144. \cs_new:Npn \kal_year:n #1 {
  145. \KalYearFormat{
  146. \str_case_e:nnF { \l_kal_yearfmt_tl }
  147. {
  148. { roman } { \int_to_roman:n {#1} }
  149. { arabic } { \int_eval:n {#1} }
  150. }
  151. { \int_to_roman:n {#1} }
  152. }
  153. }
  154. \int_new:N \l_kal_month_idx_int
  155. \int_new:N \l_kal_month_length_int
  156. \int_new:N \l_kal_month_ides_int
  157. \cs_new:Npn \kal_date:nnn #1#2#3 {
  158. \bool_if:nTF {\l_kal_oldmonths_bool}
  159. {
  160. \int_case:nnF {#2}
  161. {
  162. {7} { \int_set:Nn \l_kal_month_idx_int {13} }
  163. {8} { \int_set:Nn \l_kal_month_idx_int {14} }
  164. }
  165. { \int_set:Nn \l_kal_month_idx_int {#2} }
  166. }
  167. { \int_set:Nn \l_kal_month_idx_int {#2} }
  168. \int_compare:nNnTF {\l_kal_month_idx_int} = {2}
  169. {
  170. \int_compare:nNnTF { \int_mod:nn {#1} {4} } = {0}
  171. {
  172. \bool_if:nTF
  173. {
  174. \l_kal_julian_bool ||
  175. \int_compare_p:n { \int_mod:nn {#1} {100} != 0 }
  176. }
  177. { \int_set:Nn \l_kal_month_length_int {29} }
  178. {
  179. \int_compare:nNnTF { \int_mod:nn {#1} {400} } = {0}
  180. { \int_set:Nn \l_kal_month_length_int {29} }
  181. { \int_set:Nn \l_kal_month_length_int {28} }
  182. }
  183. }
  184. { \int_set:Nn \l_kal_month_length_int {28} }
  185. }
  186. {
  187. \int_set:Nn \l_kal_month_length_int
  188. { \clist_item:Nn \c_kal_month_lengths_clist {\l_kal_month_idx_int} }
  189. }
  190. \int_set:Nn \l_kal_month_ides_int
  191. { \clist_item:Nn \c_kal_month_ides_clist {\l_kal_month_idx_int} }
  192. \int_case:nnTF {#3}
  193. {
  194. { 1 } { \kal_abbr:nn {Kalendis} {Kal} }
  195. { \l_kal_month_ides_int - 8 } { \kal_abbr:nn {Nonis} {Non} }
  196. { \l_kal_month_ides_int } { \kal_abbr:nn {Idibus} {Id} }
  197. }
  198. { \ \kal_month:nn {\c_kal_month_abl_clist} {\l_kal_month_idx_int} }
  199. {
  200. \int_compare:nNnTF {#3} < { \l_kal_month_ides_int - 8 }
  201. {
  202. \kal_day:n { \l_kal_month_ides_int - #3 - 7 }
  203. \ \kal_abbr:nn {Nonas} {Non}
  204. \ \kal_month:nn {\c_kal_month_acc_clist} {\l_kal_month_idx_int}
  205. }
  206. {
  207. \int_compare:nNnTF {#3} < {\l_kal_month_ides_int}
  208. {
  209. \kal_day:n { \l_kal_month_ides_int - #3 + 1 }
  210. \ \kal_abbr:nn {Idus} {Id}
  211. \ \kal_month:nn {\c_kal_month_acc_clist} {\l_kal_month_idx_int}
  212. }
  213. {
  214. \bool_if:nTF
  215. {
  216. \int_compare_p:nNn {\l_kal_month_idx_int} = {2} &&
  217. \l_kal_bissextum_bool
  218. }
  219. { \kal_bissextum_day:n {#3} }
  220. {
  221. \kal_day:n { \l_kal_month_length_int - #3 + 2 }
  222. }
  223. \ \kal_abbr:nn {Kalendas} {Kal}
  224. \ \int_compare:nNnTF {\l_kal_month_idx_int} = {12}
  225. { \kal_month:nn {\c_kal_month_acc_clist} {1} }
  226. {
  227. \kal_month:nn {\c_kal_month_acc_clist}
  228. {\l_kal_month_idx_int + 1}
  229. }
  230. }
  231. }
  232. }
  233. \str_case_e:nn { \l_kal_era_tl }
  234. {
  235. { auc } {
  236. \ \KalYearFormat{
  237. \int_compare:nNnTF {#1} < {0}
  238. { \kal_year:n { #1 + 754 } }
  239. { \kal_year:n { #1 + 753 } }
  240. }
  241. \ \kal_abbr:nn {ab\ urbe\ condita}
  242. {\KalAbbrFormat{a \kal_period:n{} u \kal_period:n{} c}}
  243. }
  244. { ad } {
  245. \int_compare:nNnTF {#1} < {0}
  246. {
  247. \ \KalYearFormat{\kal_year:n {\int_abs:n {#1}}}
  248. \ \kal_abbr:nn {ante\ Christum}
  249. {\KalAbbrFormat{a \kal_period:n{} c}}
  250. }
  251. {
  252. \ \kal_abbr:nn {anno\ Domini}
  253. {\KalAbbrFormat{a \kal_period:n{} d}}
  254. \ \KalYearFormat{\kal_year:n {#1}}
  255. }
  256. }
  257. { adshort } {
  258. \int_compare:nNnTF {#1} < {0}
  259. {
  260. \ \KalYearFormat{\kal_year:n {\int_abs:n {#1}}}
  261. \ \kal_abbr:nn {ante\ Christum}
  262. {\KalAbbrFormat{a \kal_period:n{} c}}
  263. }
  264. {
  265. \ \kal_abbr:nn {anno} {\KalAbbrFormat{a}}
  266. \ \KalYearFormat{\kal_year:n {#1}}
  267. }
  268. }
  269. { secular } {
  270. \int_compare:nNnTF {#1} < {0}
  271. {
  272. \ \KalYearFormat{\kal_year:n {\int_abs:n {#1}}}
  273. \ \kal_abbr:nn {ante\ saeculum\ commune}
  274. {\KalAbbrFormat{a \kal_period:n{} s \kal_period:n{} c}}
  275. }
  276. {
  277. \ \kal_abbr:nn {saeculo\ communi}
  278. {\KalAbbrFormat{s \kal_period:n{} c}}
  279. \ \KalYearFormat{\kal_year:n {#1}}
  280. }
  281. }
  282. }
  283. }
  284. \int_new:N \l_kal_date_year_int
  285. \int_new:N \l_kal_date_month_int
  286. \int_new:N \l_kal_date_day_int
  287. \seq_new:N \l_kal_date_split_seq
  288. \int_new:N \l_kal_date_idx_int
  289. \cs_new:Npn \kal_date_string:nnn #1#2#3 {
  290. \seq_set_split:Nnn \l_kal_date_split_seq {#2} {#3}
  291. \int_set:Nn \l_kal_date_idx_int {1}
  292. \int_do_until:nNnn {\l_kal_date_idx_int} = {4}
  293. {
  294. \str_case_e:nn {\tl_item:nn {#1} {\l_kal_date_idx_int}}
  295. {
  296. { Y } { \int_gset:Nn \l_kal_date_year_int
  297. { \seq_item:Nn \l_kal_date_split_seq {\l_kal_date_idx_int} } }
  298. { M } { \int_gset:Nn \l_kal_date_month_int
  299. { \seq_item:Nn \l_kal_date_split_seq {\l_kal_date_idx_int} } }
  300. { D } { \int_gset:Nn \l_kal_date_day_int
  301. { \seq_item:Nn \l_kal_date_split_seq {\l_kal_date_idx_int} } }
  302. }
  303. \int_incr:N \l_kal_date_idx_int
  304. }
  305. \kal_date:nnn {\l_kal_date_year_int}
  306. {\l_kal_date_month_int}
  307. {\l_kal_date_day_int}
  308. }
  309. \cs_generate_variant:Nn \kal_date_string:nnn { nno }
  310. \int_new:N \l_kal_weekday_idx_int
  311. \int_new:N \l_kal_weekday_month_int
  312. \int_new:N \l_kal_weekday_year_int
  313. \int_new:N \l_kal_weekday_century_int
  314. \cs_new:Npn \kal_weekday:nnn #1#2#3 {
  315. \int_compare:nNnTF {#2} < {3}
  316. { \int_set:Nn \l_kal_weekday_month_int { #2 + 13 } }
  317. { \int_set:Nn \l_kal_weekday_month_int { #2 + 1 } }
  318. \int_set:Nn \l_kal_weekday_year_int { \int_mod:nn {#1} {100} }
  319. \int_set:Nn \l_kal_weekday_century_int { \fp_eval:n { floor(#1 / 100) } }
  320. \int_set:Nn \l_kal_weekday_idx_int {#3}
  321. \int_add:Nn \l_kal_weekday_idx_int
  322. { \fp_eval:n { floor(13 * \l_kal_weekday_month_int / 5) } }
  323. \int_add:Nn \l_kal_weekday_idx_int { \l_kal_weekday_year_int }
  324. \int_add:Nn \l_kal_weekday_idx_int
  325. { \fp_eval:n { floor(\l_kal_weekday_year_int / 4) } }
  326. \bool_if:nTF {\l_kal_julian_bool}
  327. { \int_add:Nn \l_kal_weekday_idx_int { 5 + 6 * \l_kal_weekday_century_int } }
  328. {
  329. \int_add:Nn \l_kal_weekday_idx_int { \fp_eval:n
  330. { 5 * \l_kal_weekday_century_int + floor(\l_kal_weekday_century_int / 4) }
  331. }
  332. }
  333. \int_set:Nn \l_kal_weekday_idx_int { \int_mod:nn {\l_kal_weekday_idx_int} {7} }
  334. \int_incr:N \l_kal_weekday_idx_int
  335. \kal_abbr:nn
  336. { \clist_item:Nn \c_kal_weekday_gen_clist { \l_kal_weekday_idx_int } }
  337. { \clist_item:Nn \c_kal_weekday_abbr_clist { \l_kal_weekday_idx_int } }
  338. }
  339. \DeclareDocumentCommand{\KalDate}{o m m m}
  340. {
  341. \IfValueTF{#1}
  342. {
  343. \group_begin:
  344. \keys_set:nn {kalendarium} {#1}
  345. \kal_date:nnn {#2} {#3} {#4}
  346. \group_end:
  347. }
  348. { \kal_date:nnn {#2} {#3} {#4} }
  349. }
  350. \DeclareDocumentCommand{\KalDateStr}{o m m m}
  351. {
  352. \IfValueTF{#1}
  353. {
  354. \group_begin:
  355. \keys_set:nn {kalendarium} {#1}
  356. \kal_date_string:nno {#2} {#3} {#4}
  357. \group_end:
  358. }
  359. { \kal_date_string:nno {#2} {#3} {#4} }
  360. }
  361. \DeclareDocumentCommand{\KalToday}{o}
  362. {
  363. \IfValueTF{#1}
  364. {
  365. \group_begin:
  366. \keys_set:nn {kalendarium} {#1}
  367. \kal_date:nnn {\the\year} {\the\month} {\the\day}
  368. \group_end:
  369. }
  370. { \kal_date:nnn {\the\year} {\the\month} {\the\day} }
  371. }
  372. \DeclareDocumentCommand{\KalWeekday}{o m m m}
  373. {
  374. \IfValueTF{#1}
  375. {
  376. \group_begin:
  377. \keys_set:nn {kalendarium} {#1}
  378. \kal_weekday:nnn {#2} {#3} {#4}
  379. \group_end:
  380. }
  381. { \kal_weekday:nnn {#2} {#3} {#4} }
  382. }
  383. \ExplSyntaxOff
  384. \newcommand{\KalAbbrFormat}[1]{\textsc{#1}}
  385. \newcommand{\KalDayFormat}[1]{\MakeUppercase{#1}}
  386. \newcommand{\KalYearFormat}[1]{\MakeUppercase{#1}}
  387. %%
  388. %% Copyright (C) 2018 by Andrew Smith <aws@awsmith.us>
  389. %%
  390. %% This work may be distributed and/or modified under the
  391. %% conditions of the LaTeX Project Public License (LPPL), either
  392. %% version 1.3c of this license or (at your option) any later
  393. %% version. The latest version of this license is in the file:
  394. %%
  395. %% http://www.latex-project.org/lppl.txt
  396. %%
  397. %% This work is "maintained" (as per LPPL maintenance status) by
  398. %% Andrew Smith.
  399. %%
  400. %% This work consists of the file kalendarium.dtx
  401. %% and the derived files kalendarium.ins,
  402. %% kalendarium.pdf and
  403. %% kalendarium.sty.
  404. %%
  405. %%
  406. %% End of file `kalendarium.sty'.