diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/mahjong/mahjong.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/mahjong/mahjong.sty | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/mahjong/mahjong.sty b/Master/texmf-dist/tex/latex/mahjong/mahjong.sty new file mode 100644 index 00000000000..b0b58e439ec --- /dev/null +++ b/Master/texmf-dist/tex/latex/mahjong/mahjong.sty @@ -0,0 +1,204 @@ +%% +%% This is file `mahjong.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% mahjong.dtx (with options: `pkg') +%% Copyright (c) 2021 Daniel Schmitz +%% +%% Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +%% associated documentation files (the "Software"), to deal in the Software without restriction, +%% including without limitation the rights to use, copy, modify, merge, publish, distribute, +%% sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +%% furnished to do so, subject to the following conditions: +%% +%% The above copyright notice and this permission notice shall be included in all copies or substantial +%% portions of the Software. +%% +%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +%% NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +%% DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +%% OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + + + +\NeedsTeXFormat{LaTeX2e}[2019/10/01] +\RequirePackage{expl3} +\ProvidesExplPackage{mahjong}{2021/04/16}{1.0.1}{Typeset Mahjong Hands} +\RequirePackage{xparse} +\RequirePackage{l3keys2e} +\RequirePackage{graphicx} +\RequirePackage{stackengine} + +\msg_new:nnnn {mahjong} {invalid_token} +{Token ~ #1 ~ is ~ not ~ valid ~ in ~ MPSZ ~ notation} +{Valid ~ tokens ~ are ~ digits ~ 0-9, ~ m, ~ p, ~ s, ~ z, ~ x, ~ -, ~ ?, ~ ', ~ and ~ " } +\msg_new:nnnn {mahjong} {unknown_tile} +{I~don't~know~tile~#1.} +{Please~check~the~documentation~for~recognized~tiles.} +\msg_new:nnnn {mahjong} {unknown_orientation} +{Orientation ~ #1 ~ is ~ unknown} +{This ~ should ~ not ~ happen.~ Please ~ create ~ a ~ bug ~ report.} + +\keys_define:nn {mahjong} { + height .dim_gset:N = \g_mahjong_default_height +} + +\cs_new:Npn \c__mahjong_suits_tl {mpsz} +\cs_new:Npn \c__mahjong_allowed_tokens_tl {0123456789mpsz-?x'"} + +\tl_new:N \l__mahjong_suit_tl +\tl_new:N \l__mahjong_tiles_tl +\tl_new:N \l__mahjong_reversed_tl +\tl_new:N \l__mahjong_hand_tl +\tl_new:N \l__mahjong_current_suit_tl +\tl_new:N \l__mahjong_current_group_tl +\tl_new:N \l__mahjong_current_char + +\dim_set:Nn \g_mahjong_default_height {\baselineskip} +\dim_new:N \l_mahjong_tile_height + +\int_new:N \l__mahjong_tile_orientation_int +\seq_new:N \l__mahjong_tile_maps_seq +\str_new:N \l__mahjong_file_path_str + +\ProcessKeysPackageOptions{mahjong} + +\cs_set:Npn \__mahjong_make_tile:nn #1#2 { + \file_if_exist:nTF {#1} { + \int_case:nnF {#2} { + {0} { + \stackinset{c}{0pt}{c}{0pt}{ + \includegraphics[ + angle=0, + height=.85\l_mahjong_tile_height] + {#1} + }{ + \includegraphics[ + angle=0, + height=\l_mahjong_tile_height] + {tiles/mahjong-Front.pdf} + } + } {1} { + \stackinset{c}{0pt}{c}{0pt}{ + \includegraphics[ + angle=90, + width=.85\l_mahjong_tile_height] + {#1} + }{ + \includegraphics[ + angle=90, + width=\l_mahjong_tile_height] + {tiles/mahjong-Front.pdf} + } + } {2} { + % Stack 2 rotated tiles on top of each other. + \stackon [0pt] { + \__mahjong_make_tile:nn {#1} {1} + } { + \__mahjong_make_tile:nn {#1} {1} + } + } + } { + \msg_fatal:nnx {mahjong} {unknown_orientation} {#2} + } + } { + \msg_error:nnx {mahjong} {unknown_tile} {#1} + } +} + +\cs_generate_variant:Nn \__mahjong_make_tile:nn {VV, xV, nV} +\cs_set:Npn \mahjong_typeset_hand:n #1 { + \tl_set:Nx \l__mahjong_hand_tl {\text_lowercase:n {#1}} + % MPSZ notation is easier to parse right-to-left, so reverse string + % There is no string reversal function but we can reverse token lists + % Token lists and strings are freely convertible between each other + \tl_set:Nx \l__mahjong_reversed_tl {\tl_reverse:V \l__mahjong_hand_tl} + \tl_map_variable:NNn \l__mahjong_reversed_tl \l__mahjong_current_char { + % Check if we recognize the current token + \exp_args:NVV \tl_if_in:nnF \c__mahjong_allowed_tokens_tl \l__mahjong_current_char { + \msg_error:nnx {mahjong} {invalid_token} {\l__mahjong_current_char} + } + \exp_args:NVV \tl_if_in:nnTF \c__mahjong_suits_tl \l__mahjong_current_char { + % If we've found a suit identifier, change the current suit + \tl_set:NV \l__mahjong_current_suit_tl \l__mahjong_current_char + } { + \str_case:VnF \l__mahjong_current_char { + {'} { + % An apostrophe indicates that the next tile is rotated + \int_set:Nn \l__mahjong_tile_orientation_int {1} + } + {"} { + % Quotes mean the next tile is actually 2 rotated tiles stacked on top of each other + \int_set:Nn \l__mahjong_tile_orientation_int {2} + } + } { + % Default case: We've got a complete tile identifier + % Turn it into a property list + \prop_clear:N \l_tmpa_prop + \prop_put:NnV \l_tmpa_prop {suit} \l__mahjong_current_suit_tl + \prop_put:NnV \l_tmpa_prop {face} \l__mahjong_current_char + \prop_put:NnV \l_tmpa_prop {orientation} \l__mahjong_tile_orientation_int + % Add it to the beginning of the sequence (we are parsing in reverse) + \seq_put_left:NV \l__mahjong_tile_maps_seq \l_tmpa_prop + \int_set:Nn \l__mahjong_tile_orientation_int {0} + } + } + } + % Typesetting begins here. Sequence is in correct order + \seq_map_variable:NNn \l__mahjong_tile_maps_seq \l_tmpa_prop { + \prop_get:NnN \l_tmpa_prop {face} \l_tmpa_tl + \prop_get:NnN \l_tmpa_prop {orientation} \l_tmpa_int + \str_case:VnF \l_tmpa_tl { + {-} { + % If the current face is a dash, insert a space + \includegraphics[height=\l_mahjong_tile_height]{tiles/mahjong-Space.pdf} + } {x} { + % Insert a flipped tile + \int_case:nn {\l_tmpa_int} { + {0} { % Upright + \includegraphics[ + angle=0, + height=\l_mahjong_tile_height] + {tiles/mahjong-Back.pdf} + } {1} { % Rotated + \includegraphics[ + angle=90, + width=\l_mahjong_tile_height] + {tiles/mahjong-Back.pdf} + } {2} { % Rotated and stacked + \stackon [0pt] { + \includegraphics[ + angle=90, + width=\l_mahjong_tile_height] + {tiles/mahjong-Back.pdf} + } { + \includegraphics[angle=90, + width=\l_mahjong_tile_height] + {tiles/mahjong-Back.pdf} + } + } + } + } {?} { % Blank tile + \__mahjong_make_tile:nV {tiles/mahjong-Blank.pdf} \l_tmpa_int + } + } { % Any other tile identified by a code. + \__mahjong_make_tile:xV {tiles/mahjong-\l_tmpa_tl\prop_item:Nn \l_tmpa_prop {suit}.pdf} \l_tmpa_int + } + } + % Clear the list for the next invocation + \seq_clear:N \l__mahjong_tile_maps_seq +} + +\cs_generate_variant:Nn \__mahjong_typeset_hand:n {x} +\NewDocumentCommand{\mahjong}{O{\g_mahjong_default_height} m}{ + \dim_set:Nn \l_mahjong_tile_height {#1} + \mahjong_typeset_hand:n {#2} +} +\endinput +%% +%% End of file `mahjong.sty'. |