%% %% This is file `kvmap.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% kvmap.dtx (with options: `pkg,cfg') %% Copyright (C) 2020 Ben Frank %% %% It may be distributed and/or modified under the conditions of %% the LaTeX Project Public License (LPPL), either version 1.3c of %% this license or (at your option) any later version. The latest %% version of this license is in the file: %% %% http://www.latex-project.org/lppl.txt %% \RequirePackage{expl3} \ProvidesExplPackage{kvmap}{2020/03/27}{0.3.3}{Drawing karnaugh maps with LaTeX} \RequirePackage{xparse} \RequirePackage{tikz} \RequirePackage{environ} \cs_generate_variant:Nn \seq_set_split:Nnn { Nno, Nnx } \cs_generate_variant:Nn \int_mod:nn { VV } \cs_generate_variant:Nn \int_div_truncate:nn { VV } \cs_new:Npn \__kvmap_graycode_xor_bits:nn #1#2 { \int_compare:nTF { #1 = #2 } { 0 } { 1 } } \cs_new:Npn \__kvmap_graycode_xor:w #1#2\q_stop#3#4\q_stop { \__kvmap_graycode_xor_bits:nn { #1 } { #3 } \tl_if_empty:nF { #2 } { \__kvmap_graycode_xor:w #2\q_stop#4\q_stop } } \cs_new:Npn \__kvmap_graycode_xor:nn #1#2 { \__kvmap_graycode_xor:w #1\q_stop#2\q_stop } \cs_generate_variant:Nn \__kvmap_graycode_xor:nn { xx } \cs_new:Npn \kvmap_graycode_at:nn #1#2 { \__kvmap_graycode_xor:xx { \tl_tail:f { \int_to_bin:n { #1 - 1 + #2 } } } { \tl_tail:f { \int_to_bin:n { \fp_eval:n { floor((#1-1)/2) + #2 } } } } } \cs_generate_variant:Nn \kvmap_graycode_at:nn { nV } \bool_new:N \l__kvmap_matrix_isintikz_bool \int_new:N \l__kvmap_matrix_height_int \int_new:N \l__kvmap_matrix_width_int \cs_new:Nn \__kvmap_outputgraycode: { \int_step_inline:nnnn { 1 } { 1 } { \l__kvmap_matrix_width_int } { \node ~ at ~ (\fp_eval:n { 0.5 + (##1-1) }, .3) { \kvmap_graycode_at:nV { ##1 } \l__kvmap_matrix_width_int }; } \int_step_inline:nnnn { 1 } { 1 } { \l__kvmap_matrix_height_int } { \node[anchor = east] ~ at ~ (0, \fp_eval:n { -0.5 - (##1-1) }) { \kvmap_graycode_at:nV { ##1 } \l__kvmap_matrix_height_int }; } } \tikzset{kvnode/.style = { inner ~ sep = 8pt }} \cs_new:Npn \__kvmap_outputmatrix:n #1 { \int_zero:N \l_tmpa_int \seq_set_split:Nnn \l_tmpa_seq { , } { #1 } \seq_map_inline:Nn \l_tmpa_seq { \node[kvnode] ~ (\int_mod:VV \l_tmpa_int \l__kvmap_matrix_width_int \int_div_truncate:VV \l_tmpa_int \l__kvmap_matrix_width_int ) ~ at ~ (.5+\int_mod:VV \l_tmpa_int \l__kvmap_matrix_width_int, -.5-\int_div_truncate:nn \l_tmpa_int \l__kvmap_matrix_width_int ) ~ {$##1$}; \int_incr:N \l_tmpa_int } } \keys_define:nn { kvmap/bundle } { reducespace .dim_set:N = \l__kvmap_bundle_reducespace_dim, reducespace .initial:n = { 0pt }, color .tl_set:N = \l__kvmap_bundle_color_tl, color .initial:n = { black }, invert .bool_set:N = \l__kvmap_bundle_invert_bool, invert .default:n = true, invert .initial:n = false, vinvert .bool_set:N = \l__kvmap_bundle_vinvert_bool, vinvert .default:n = true, vinvert .initial:n = true, hinvert .bool_set:N = \l__kvmap_bundle_hinvert_bool, hinvert .default:n = true, hinvert .initial:n = true, overlapmargins .dim_set:N = \l__kvmap_bundle_overlapmargins_dim, overlapmargins .initial:n = { 0pt }, } \tikzset{kvbundle/.style = { rounded ~ corners = 5pt }} \int_new:N \l__kvmap_bundle_minx_int \int_new:N \l__kvmap_bundle_miny_int \int_new:N \l__kvmap_bundle_maxx_int \int_new:N \l__kvmap_bundle_maxy_int \NewDocumentCommand { \bundle } { O{} m m m m } { \group_begin: \keys_set:nn { kvmap/bundle } { #1 } \int_set:Nn \l__kvmap_bundle_minx_int { \int_min:nn { #2 } { #4 } } \int_set:Nn \l__kvmap_bundle_miny_int { \int_min:nn { #3 } { #5 } } \int_set:Nn \l__kvmap_bundle_maxx_int { \int_max:nn { #2 } { #4 } } \int_set:Nn \l__kvmap_bundle_maxy_int { \int_max:nn { #3 } { #5 } } \bool_if:NTF \l__kvmap_bundle_invert_bool { \bool_if:nT { \int_compare_p:n { \l__kvmap_matrix_height_int - 1 = \l__kvmap_bundle_maxy_int } && \int_compare_p:n { 0 = \l__kvmap_bundle_miny_int } && \l__kvmap_bundle_vinvert_bool } { \draw[draw=\l__kvmap_bundle_color_tl,kvbundle] ~ ([xshift=\l__kvmap_bundle_reducespace_dim, yshift=\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_miny_int . north ~ west) -- ([xshift=\l__kvmap_bundle_reducespace_dim, yshift=\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_miny_int . south ~ west) -- ([xshift=-\l__kvmap_bundle_reducespace_dim, yshift=\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_miny_int . south ~ east) -- ([xshift=-\l__kvmap_bundle_reducespace_dim, yshift=\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_miny_int . north ~ east); \draw[draw=\l__kvmap_bundle_color_tl,kvbundle] ~ ([xshift=\l__kvmap_bundle_reducespace_dim, yshift=-\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_maxy_int . south ~ west) -- ([xshift=\l__kvmap_bundle_reducespace_dim, yshift=-\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_maxy_int . north ~ west) -- ([xshift=-\l__kvmap_bundle_reducespace_dim, yshift=-\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_maxy_int . north ~ east) -- ([xshift=-\l__kvmap_bundle_reducespace_dim, yshift=-\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_maxy_int . south ~ east); } \bool_if:nT { \int_compare_p:n { \l__kvmap_matrix_width_int - 1 = \l__kvmap_bundle_maxx_int } && \int_compare_p:n { 0 = \l__kvmap_bundle_minx_int } && \l__kvmap_bundle_hinvert_bool } { \draw[draw=\l__kvmap_bundle_color_tl,kvbundle] ~ ([yshift=-\l__kvmap_bundle_reducespace_dim, xshift=-\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_miny_int . north ~ west) -- ([yshift=-\l__kvmap_bundle_reducespace_dim, xshift=-\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_miny_int . north ~ east) -- ([yshift=\l__kvmap_bundle_reducespace_dim, xshift=-\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_maxy_int . south ~ east) -- ([yshift=\l__kvmap_bundle_reducespace_dim, xshift=-\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_maxy_int . south ~ west); \draw[draw=\l__kvmap_bundle_color_tl,kvbundle] ~ ([yshift=-\l__kvmap_bundle_reducespace_dim, xshift=\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_miny_int . north ~ east) -- ([yshift=-\l__kvmap_bundle_reducespace_dim, xshift=\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_miny_int . north ~ west) -- ([yshift=\l__kvmap_bundle_reducespace_dim, xshift=\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_maxy_int . south ~ west) -- ([yshift=\l__kvmap_bundle_reducespace_dim, xshift=\l__kvmap_bundle_overlapmargins_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_maxy_int . south ~ east); } } { \draw[draw=\l__kvmap_bundle_color_tl, kvbundle] ~ ([xshift=\l__kvmap_bundle_reducespace_dim, yshift=-\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_minx_int \int_use:N \l__kvmap_bundle_miny_int . north ~ west) ~ rectangle ~ ([xshift=-\l__kvmap_bundle_reducespace_dim, yshift=\l__kvmap_bundle_reducespace_dim] \int_use:N \l__kvmap_bundle_maxx_int \int_use:N \l__kvmap_bundle_maxy_int . south ~ east); } \group_end: } \cs_new:Npn \kvmap_map:nn #1#2 { \draw ~ (0,0) ~ grid ~ (\int_use:N \l__kvmap_matrix_width_int, -\int_use:N \l__kvmap_matrix_height_int); \__kvmap_outputmatrix:n { #1 } \__kvmap_outputgraycode: \draw ~ (0,0) ~ -- ~ (-.7,.7); \int_set:Nn \l_tmpa_int { \fp_eval:n { floor(ln(\l__kvmap_matrix_width_int)/ln(2)) } } \tl_clear:N \l_tmpa_tl \int_step_inline:nnnn { 1 } { 1 } { \l_tmpa_int } { \tl_put_right:Nn \l_tmpa_tl { \clist_item:nn { #2 } { ##1 } } } \node[anchor = west] ~ at ~ (-.5, .7) ~ { $\tl_use:N \l_tmpa_tl$ }; \tl_clear:N \l_tmpa_tl \int_step_inline:nnnn { \l_tmpa_int + 1 } { 1 } { \l_tmpa_int + \fp_eval:n { floor(ln(\l__kvmap_matrix_height_int)/ln(2)) } } { \tl_put_right:Nn \l_tmpa_tl { \clist_item:nn { #2 } { ##1 } } } \node[anchor = east] ~ at ~ (-.4, .2) ~ { $\tl_use:N \l_tmpa_tl$ }; } \cs_generate_variant:Nn \kvmap_map:nn { xn } \NewDocumentEnvironment { kvmap } { O{} } { \group_begin: \keys_set:nn { kvmap } { #1 } \int_gzero:N \l__kvmap_matrix_height_int \int_gzero:N \l__kvmap_matrix_width_int \begin{tikzpicture} } { \end{tikzpicture} \group_end: } \NewDocumentCommand { \kvlist } { m m m m } { \tikzifinpicture { \bool_set_true:N \l__kvmap_matrix_isintikz_bool } { \bool_set_false:N \l__kvmap_matrix_isintikz_bool } \bool_if:NF \l__kvmap_matrix_isintikz_bool { \begin{tikzpicture} } \int_gset:Nn \l__kvmap_matrix_width_int { #1 } \int_gset:Nn \l__kvmap_matrix_height_int { #2 } \kvmap_map:nn { #3 } { #4 } \bool_if:NF \l__kvmap_matrix_isintikz_bool { \end{tikzpicture} } } \seq_new:N \l__kvmap_tmp_seq \NewEnviron { kvmatrix } [ 1 ] { \seq_set_split:Nno \l_tmpa_seq { \\ } { \BODY } \seq_remove_all:Nn \l_tmpa_seq { } \seq_set_split:Nnx \l_tmpb_seq { & } { \seq_item:Nn \l_tmpa_seq { 1 } } \int_gset:Nn \l__kvmap_matrix_width_int { \seq_count:N \l_tmpb_seq } \int_gset:Nn \l__kvmap_matrix_height_int { \seq_count:N \l_tmpa_seq } \seq_clear:N \l__kvmap_tmp_seq \seq_map_inline:Nn \l_tmpa_seq { \seq_clear:N \l_tmpb_seq \seq_set_split:Nnn \l_tmpb_seq { & } { ##1 } \seq_concat:NNN \l__kvmap_tmp_seq \l__kvmap_tmp_seq \l_tmpb_seq } \tikzifinpicture { \bool_set_true:N \l__kvmap_matrix_isintikz_bool } { \bool_set_false:N \l__kvmap_matrix_isintikz_bool } \bool_if:NF \l__kvmap_matrix_isintikz_bool { \begin{tikzpicture} } \kvmap_map:xn { \seq_use:Nnnn \l__kvmap_tmp_seq { , } { , } { , } } { #1 } \bool_if:NF \l__kvmap_matrix_isintikz_bool { \end{tikzpicture} } } \NewDocumentCommand { \kvmapsetup } { m } { \keys_set:nn { kvmap } { #1 } } %% %% %% End of file `kvmap.sty'.