diff options
20 files changed, 2740 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/cartonaugh/README.md b/Master/texmf-dist/doc/latex/cartonaugh/README.md new file mode 100644 index 00000000000..7a271fec759 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/README.md @@ -0,0 +1,39 @@ +# NOTE: THIS FORK IS STILL IN DEVELOPEMENT. +# Cartonaugh +This package is a fork of the [karnaugh-map](https://github.com/2pi/karnaugh-map) package. This fork +is meant to replace some of the functions in this package with Lua internally, and add some +features unto the original package (for example I'm thinking an auto-boolean equation parser). + +## But Why LuaLaTeX? +Personally, it's much easier to write expansion macros in Lua rather than nativally in LaTeX. It's just +a matter of personal preference. It make macros easier to explain, document, and expand upon in the future. +It also allows for some advanced capability, for example the ability to feed in a boolean equation and have it +automatically highlight which cells need to be highlighed (upcomming/todo). + +## Installation + # to get the cartonaugh.sty and cartonaugh.lua file + lualatex cartonaugh.ins + # to get the documentation: cartonaugh.pdf + lualatex cartonaugh.dtx + +## Dependencies +* tikz +* xparse +* xstring + +## Development +This fork is still in development. + +## Tests + ./test.sh +Testing consists of building the pdf output from the test files, and then comparing them to how they are expected to look like. +Comparison is done with help from [diff-pdf](https://github.com/vslavik/diff-pdf). +All of this is done by running the `test.sh` file from the project root folder. +If there is a difference, between the actual and expected output, a diff will be written to the folder `test/result`. + +## License +As karnaugh-map is licensed under [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/), and thus so is this fork. + +## Credit +Credit goes to [2pi](https://github.com/2pi) and [Oscar Gustafsson](https://github.com/oscargus) for writting the orignal package which +this is based upon/forked from. diff --git a/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh-example.pdf b/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh-example.pdf Binary files differnew file mode 100644 index 00000000000..74523a08f63 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh-example.pdf diff --git a/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh-example.tex b/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh-example.tex new file mode 100644 index 00000000000..a9eb12f3461 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh-example.tex @@ -0,0 +1,10 @@ +\documentclass{standalone} +\usepackage{cartonaugh} +\begin{document} + \begin{cartonaugh}[2][2][1][$X_0$][$X_1$] + \minterms{1,2} + \autoterms[0] + \implicant{1}{1} + \implicant{2}{2} + \end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh.pdf b/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh.pdf Binary files differnew file mode 100644 index 00000000000..140c47073ae --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/cartonaugh.pdf diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test.sh b/Master/texmf-dist/doc/latex/cartonaugh/test.sh new file mode 100755 index 00000000000..c2859bd0da6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# color variables +C_RED='\033[0;31m' +C_GREEN='\033[0;32m' +C_RESET='\033[0m' + +# error count variable +ERROR=0 + +# enter test directory +pushd ./test > /dev/null + +# clean actual and result directory and recreate +rm -rf actual result +mkdir actual result + +processTexFile() { + printf "Processing '%s'\n" "${1}"; + lualatex -halt-on-error -interaction=nonstopmode -output-directory actual "${1}" > /dev/null 2>&1 + if [ "$?" == 0 ]; then + printf "Processing of '%s' finished\n" "${1}"; + else + printf "%bProcessing of '%s' failed%b\n" "${C_RED}" "${1}" "${C_RESET}"; + fi +} + +# run lualatex on all files ending with ".tex" and output to folder actual +for file in *.tex; do + (processTexFile "${file}")& # run i parallel +done; + +# wait for all lualatex children +wait + +# if expected folder exist compare to actual +if [ ! -d "./expected" ]; then + printf "%bMissing expected directory, can not compare%b\n" "${C_RED}" "${C_RESET}"; + ERROR=$((ERROR+1)) +else + pushd expected > /dev/null + for file in *.pdf; do + # make sure the actual version exist + if [ ! -f "../actual/${file}" ]; then + printf "%bTest '%s' is missing%b\n" "${C_RED}" "${file}" "${C_RESET}"; + ERROR=$((ERROR+1)) + else + diff-pdf --output-diff="../result/${file}" "${file}" "../actual/${file}"; + # if actual is equal to expected (exit code == 0) rm result file + if [ "$?" == 0 ]; then + rm "../result/${file}"; + printf "%bTest '%s' succeeded%b\n" "${C_GREEN}" "${file}" "${C_RESET}"; + else + printf "%bTest '%s' failed%b\n" "${C_RED}" "${file}" "${C_RESET}"; + ERROR=$((ERROR+1)) + fi + fi + done + popd > /dev/null +fi + +# return from test directory +popd > /dev/null + +# return correct error code +exit $ERROR; diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-bw-color.tex b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-bw-color.tex new file mode 100644 index 00000000000..e45b0215c65 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-bw-color.tex @@ -0,0 +1,16 @@ +\documentclass{standalone} +\usepackage{cartonaugh} +\begin{document} + \begin{cartonaugh}*[4][4][1] + \implicant{0}{0} + \implicant{4}{5} + \implicant{12}{15} + \implicant{8}{10} + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + \implicant{0}{0} + \implicant{4}{5} + \implicant{12}{15} + \implicant{8}{10} + \end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-grid.tex b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-grid.tex new file mode 100644 index 00000000000..61663a86bc7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-grid.tex @@ -0,0 +1,12 @@ +\documentclass{standalone} +\usepackage{cartonaugh} +\begin{document} + \begin{cartonaugh}[2][2][1]\end{cartonaugh} + \begin{cartonaugh}[2][4][1]\end{cartonaugh} + \begin{cartonaugh}[4][2][1]\end{cartonaugh} + \begin{cartonaugh}[4][4][1]\end{cartonaugh} + \begin{cartonaugh}[4][4][2]\end{cartonaugh} + \begin{cartonaugh}[4][4][4]\end{cartonaugh} + \begin{cartonaugh}[4][4][2][$X_1X_0$][$X_3X_2$][$X_5X_4$][1]\end{cartonaugh} + \begin{cartonaugh}[4][4][4][$X_1X_0$][$X_3X_2$][$X_5X_4$][1]\end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicant.tex b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicant.tex new file mode 100644 index 00000000000..2951c8e7dbf --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicant.tex @@ -0,0 +1,248 @@ +\documentclass{standalone} +\usepackage{cartonaugh} +\begin{document} + % draw cell implicants(single, horizontal, vertical, and 2x2 block), default submap + \begin{cartonaugh}[2][2][1] + % single cell + \implicant{0}{0} + % horizontal + \implicant{2}{3} + % vertical + \implicant{1}{3} + % block + \implicant{0}{3} + \end{cartonaugh} + \begin{cartonaugh}[2][4][1] + % single cell + \implicant{0}{0} + \implicant{1}{1} + % horizontal + \implicant{2}{3} + % vertical + \implicant{3}{7} + % block + \implicant{6}{5} + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + % single cell + \implicant{0}{0} + \implicant{1}{1} + % horizontal + \implicant{4}{5} + % vertical + \implicant{1}{5} + % block + \implicant{3}{6} + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + % single cell + \implicant{0}{0} + \implicant{1}{1} + \implicant{2}{2} + \implicant{3}{3} + % horizontal + \implicant{9}{11} + % vertical + \implicant{4}{12} + % block + \implicant{5}{15} + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + % single cell + \implicant{0}{0} + \implicant{1}{1} + \implicant{2}{2} + \implicant{3}{3} + % horizontal + \implicant{9}{11} + % vertical + \implicant{4}{12} + % block + \implicant{5}{15} + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + % single cell + \implicant{0}{0} + \implicant{1}{1} + \implicant{2}{2} + \implicant{3}{3} + % horizontal + \implicant{9}{11} + % vertical + \implicant{4}{12} + % block + \implicant{5}{15} + \end{cartonaugh} + % draw on 0th and 2nd submaps(when possible) + \begin{cartonaugh}[2][2][1] + % single cell + \implicant{0}{0}[0,2] + % horizontal + \implicant{2}{3}[0,2] + % vertical + \implicant{1}{3}[0,2] + % block + \implicant{0}{3}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[2][4][1] + % single cell + \implicant{0}{0}[0,2] + \implicant{1}{1}[0,2] + % horizontal + \implicant{2}{3}[0,2] + % vertical + \implicant{3}{7}[0,2] + % block + \implicant{6}{5}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + % single cell + \implicant{0}{0}[0,2] + \implicant{1}{1}[0,2] + % horizontal + \implicant{4}{5}[0,2] + % vertical + \implicant{1}{5}[0,2] + % block + \implicant{3}{6}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + % single cell + \implicant{0}{0}[0,2] + \implicant{1}{1}[0,2] + \implicant{2}{2}[0,2] + \implicant{3}{3}[0,2] + % horizontal + \implicant{9}{11}[0,2] + % vertical + \implicant{4}{12}[0,2] + % block + \implicant{5}{15}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + % single cell + \implicant{0}{0}[0,2] + \implicant{1}{1}[0,2] + \implicant{2}{2}[0,2] + \implicant{3}{3}[0,2] + % horizontal + \implicant{9}{11}[0,2] + % vertical + \implicant{4}{12}[0,2] + % block + \implicant{5}{15}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + % single cell + \implicant{0}{0}[0,2] + \implicant{1}{1}[0,2] + \implicant{2}{2}[0,2] + \implicant{3}{3}[0,2] + % horizontal + \implicant{9}{11}[0,2] + % vertical + \implicant{4}{12}[0,2] + % block + \implicant{5}{15}[0,2] + \end{cartonaugh} + % draw multiple different implicants + \begin{cartonaugh}[2][2][1] + % single cell + \implicant{0}{0}[0] + % horizontal + \implicant{2}{3}[0] + % vertical + \implicant{1}{3}[0] + % block + \implicant{0}{3}[0] + \end{cartonaugh} + \begin{cartonaugh}[2][4][1] + % single cell + \implicant{0}{0}[0] + \implicant{1}{1}[0] + % horizontal + \implicant{2}{3}[0] + % vertical + \implicant{3}{7}[0] + % block + \implicant{6}{5}[0] + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + % single cell + \implicant{0}{0}[0] + \implicant{1}{1}[0] + % horizontal + \implicant{4}{5}[0] + % vertical + \implicant{1}{5}[0] + % block + \implicant{3}{6}[0] + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + % single cell + \implicant{0}{0}[0] + \implicant{1}{1}[0] + \implicant{2}{2}[0] + \implicant{3}{3}[0] + % horizontal + \implicant{9}{11}[0] + % vertical + \implicant{4}{12}[0] + % block + \implicant{5}{15}[0] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + % single cell + \implicant{0}{0}[0] + \implicant{1}{1}[0] + \implicant{2}{2}[0] + \implicant{3}{3}[0] + \implicant{0}{0}[1] + \implicant{1}{1}[1] + \implicant{2}{2}[1] + \implicant{3}{3}[1] + % horizontal + \implicant{9}{11}[0] + \implicant{9}{11}[1] + % vertical + \implicant{4}{12}[0] + \implicant{4}{12}[1] + % block + \implicant{5}{15}[0] + \implicant{5}{15}[1] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + % single cell + \implicant{0}{0}[0] + \implicant{1}{1}[0] + \implicant{2}{2}[0] + \implicant{3}{3}[0] + \implicant{0}{0}[1] + \implicant{1}{1}[1] + \implicant{2}{2}[1] + \implicant{3}{3}[1] + \implicant{0}{0}[2] + \implicant{1}{1}[2] + \implicant{2}{2}[2] + \implicant{3}{3}[2] + \implicant{0}{0}[3] + \implicant{1}{1}[3] + \implicant{2}{2}[3] + \implicant{3}{3}[3] + % horizontal + \implicant{9}{11}[0] + \implicant{9}{11}[1] + \implicant{9}{11}[2] + \implicant{9}{11}[3] + % vertical + \implicant{4}{12}[0] + \implicant{4}{12}[1] + \implicant{4}{12}[2] + \implicant{4}{12}[3] + % block + \implicant{5}{15}[0] + \implicant{5}{15}[1] + \implicant{5}{15}[2] + \implicant{5}{15}[3] + \end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicantcorner.tex b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicantcorner.tex new file mode 100644 index 00000000000..740e4f263c4 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicantcorner.tex @@ -0,0 +1,38 @@ +\documentclass{standalone} +\usepackage{cartonaugh} +\begin{document} + % test default(should only draw on 0th submap) + \begin{cartonaugh}[4][4][1] + \implicantcorner + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \implicantcorner + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \implicantcorner + \end{cartonaugh} + % draw on 0th and 2nd submaps(when possible) + \begin{cartonaugh}[4][4][1] + \implicantcorner[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \implicantcorner[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \implicantcorner[0,2] + \end{cartonaugh} + % draw multiple different implicants + \begin{cartonaugh}[4][4][1] + \implicantcorner[0] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \implicantcorner[0] + \implicantcorner[1] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \implicantcorner[0] + \implicantcorner[1] + \implicantcorner[2] + \implicantcorner[3] + \end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicantedge.tex b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicantedge.tex new file mode 100644 index 00000000000..b8dd02ec338 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-implicantedge.tex @@ -0,0 +1,69 @@ +\documentclass{standalone} +\usepackage{cartonaugh} +\begin{document} + % vertical and horizontal implicants(when possible), default submap + \begin{cartonaugh}[2][4][1] + \implicantedge{0}{1}{4}{5} + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + \implicantedge{1}{3}{5}{7} + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + \implicantedge{1}{3}{9}{11} + \implicantedge{4}{12}{6}{14} + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \implicantedge{1}{3}{9}{11} + \implicantedge{4}{12}{6}{14} + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \implicantedge{1}{3}{9}{11} + \implicantedge{4}{12}{6}{14} + \end{cartonaugh} + % draw on 0th and 2nd submaps(when possible) + \begin{cartonaugh}[2][4][1] + \implicantedge{0}{1}{4}{5}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + \implicantedge{1}{3}{5}{7}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + \implicantedge{1}{3}{9}{11}[0,2] + \implicantedge{4}{12}{6}{14}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \implicantedge{1}{3}{9}{11}[0,2] + \implicantedge{4}{12}{6}{14}[0,2] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \implicantedge{1}{3}{9}{11}[0,2] + \implicantedge{4}{12}{6}{14}[0,2] + \end{cartonaugh} + % draw multiple different implicants + \begin{cartonaugh}[2][4][1] + \implicantedge{0}{1}{4}{5}[0] + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + \implicantedge{1}{3}{5}{7}[0] + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + \implicantedge{1}{3}{9}{11}[0] + \implicantedge{4}{12}{6}{14}[0] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \implicantedge{1}{3}{9}{11}[0] + \implicantedge{4}{12}{6}{14}[0] + \implicantedge{1}{3}{9}{11}[1] + \implicantedge{4}{12}{6}{14}[1] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \implicantedge{1}{3}{9}{11}[0] + \implicantedge{4}{12}{6}{14}[0] + \implicantedge{1}{3}{9}{11}[1] + \implicantedge{4}{12}{6}{14}[1] + \implicantedge{1}{3}{9}{11}[2] + \implicantedge{4}{12}{6}{14}[2] + \implicantedge{1}{3}{9}{11}[3] + \implicantedge{4}{12}{6}{14}[3] + \end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-options.tex b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-options.tex new file mode 100644 index 00000000000..6fe84ba61bb --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-options.tex @@ -0,0 +1,29 @@ +% Test to test out the different package options +\documentclass[]{standalone} +\usepackage{cartonaugh} +\begin{document} + % Normal stuff + \begin{cartonaugh}[4][4][4] + \autoterms[-] + \end{cartonaugh} + % Test out non-seperated kmap + \begin{cartonaugh}[4][4][4][$BA$][$DC$][$FE$][1] + \autoterms[-] + \end{cartonaugh} + % Test changing color + \begin{cartonaugh}[4][4][4] + \implicant{0}{2}[0] + \implicant{4}{6}[0] + \changecolor{blue} + \implicant{8}{10}[0] + \implicant{12}{14}[0] + \end{cartonaugh} + % Test changing the implicant corner spread + \begin{cartonaugh}[4][4][4] + \implicantcorner[0] + \implicantspread{0.2}{0.7} + \implicantcorner[1] + \resetimplicantspread + \implicantcorner[2] + \end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-terms.tex b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-terms.tex new file mode 100644 index 00000000000..aae274f8be7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cartonaugh/test/cartonaugh-terms.tex @@ -0,0 +1,79 @@ +\documentclass{standalone} +\usepackage{cartonaugh} +\begin{document} + % fill all fields (autoterms) + \begin{cartonaugh}[2][2][1] + \autoterms[-] + \end{cartonaugh} + \begin{cartonaugh}[2][4][1] + \autoterms[-] + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + \autoterms[-] + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + \autoterms[-] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \autoterms[-] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \autoterms[-] + \end{cartonaugh} + % fill remaining after '\indeterminants' '\manualterms' '\maxterms' and '\minterms' + \begin{cartonaugh}[2][2][1] + \manualterms{m} + \indeterminants{1} + \maxterms{2} + \minterms{3} + \autoterms[a] + \end{cartonaugh} + \begin{cartonaugh}[2][2][1] + \manualterms{m} + \terms{1}{T} + \indeterminants{1} + \maxterms{2} + \minterms{3} + \autoterms[a] + \end{cartonaugh} + \begin{cartonaugh}[2][4][1] + \manualterms{m} + \indeterminants{1} + \maxterms{2} + \minterms{3} + \terms{4}{T} + \autoterms[a] + \end{cartonaugh} + \begin{cartonaugh}[4][2][1] + \manualterms{m} + \indeterminants{1} + \maxterms{2} + \minterms{3} + \terms{4}{T} + \autoterms[a] + \end{cartonaugh} + \begin{cartonaugh}[4][4][1] + \manualterms{m,m} + \indeterminants{2,3} + \maxterms{4,5} + \minterms{6,7} + \terms{8,9}{T} + \autoterms[a] + \end{cartonaugh} + \begin{cartonaugh}[4][4][2] + \manualterms{m,m,m,m} + \indeterminants{4,5,6,7} + \maxterms{8,9,10,11} + \minterms{12,13,14,15} + \terms{16,17,18,19}{T} + \autoterms[a] + \end{cartonaugh} + \begin{cartonaugh}[4][4][4] + \manualterms{m,m,m,m} + \indeterminants{4,5,6,7} + \maxterms{8,9,10,11} + \minterms{12,13,14,15} + \terms{16,17,18,19}{T} + \autoterms[a] + \end{cartonaugh} +\end{document} diff --git a/Master/texmf-dist/source/latex/cartonaugh/cartonaugh.dtx b/Master/texmf-dist/source/latex/cartonaugh/cartonaugh.dtx new file mode 100644 index 00000000000..127548da94d --- /dev/null +++ b/Master/texmf-dist/source/latex/cartonaugh/cartonaugh.dtx @@ -0,0 +1,1423 @@ +% \iffalse meta-comment +% Copyright (C) 2021 Jamal Bouajjaj | 2015, 2016, 2017 Mattias Jacobsson and contributors +% This work, cartonaugh, is a fork of Mattias Jacobsson's [karnaugh-map](https://github.com/2pi/karnaugh-map) package with major changes. As the copyright on the base package is under [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/), so is this fork. +% \fi +% +% \iffalse +%<*package> +%<package>%% +%<package>%% Copyright (C) 2021 Jamal Bouajjaj | 2015, 2016, 2017 Mattias Jacobsson and contributors +%<package>%% This work, cartonaugh, is a fork of Mattias Jacobsson's [karnaugh-map](https://github.com/2pi/karnaugh-map) package with major changes. As the copyright on the base package is under [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/), so is this fork. +%<package>%% +%<package> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{cartonaugh}[2021/07/15 v1.0 Draw Karnaugh Maps] +% +%<*driver> + \documentclass{ltxdoc} + \usepackage{cartonaugh} + \usepackage{multicol}% for documentation + \usepackage{tabularx}% for documentation + \usepackage{float}% for documentation + \usepackage{hyperref}% for documentation + \setlength{\parindent}{0pt} + \setlength{\parskip}{0.6em} + \EnableCrossrefs + \CodelineIndex + \RecordChanges + \OnlyDescription + \begin{document} + \DeleteShortVerb{\|} + \DocInput{cartonaugh.dtx} + \PrintChanges + \end{document} +%</driver> +% \fi +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.0}{2021/07/15}{Initial Release} +% +% \GetFileInfo{cartonaugh.sty} +% +% \title{The \textsf{cartonaugh} package} +% \author{Jamal Bouajjaj} +% \date{\textsf{cartonaugh}~\fileversion, \filedate} +% +%\maketitle +% +% \begin{abstract} +% This package, a fork of Mattias Jacobsson/2pi's \href{https://github.com/2pi/karnaugh-map}{karnaugh-map} package, draws karnaugh maps with 2, 3, 4, 5, and 6 variables. +% It also contains commands for filling the karnaugh map with terms semi-automatically or manually. +% Last but not least it contains commands for drawing implicants on top of the map. +% Cartonaugh is a portmanteau of ``cartographer`` and ``karnaugh``. +% Below is an example of a two variable karnaugh map of $X_0 \oplus X_1$. +% \end{abstract} +% \begin{figure}[H] +% \centering +% \begin{cartonaugh}[2][2][1][$X_0$][$X_1$] +% \minterms{1,2} +% \autoterms[0] +% \implicant{1}{1} +% \implicant{2}{2} +% \end{cartonaugh} +% \end{figure} +% \tableofcontents +% \pagebreak +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## + +%% +%% Dependencies +%% + +%% Check if ran under LuaLaTeX. If not, exit +\RequirePackage{iftex} +\RequireLuaTeX + +%% parsing arguments +\RequirePackage{xparse} + +%% working with strings +\RequirePackage{xstring} + +%% drawing +\RequirePackage{tikz} +\usetikzlibrary{calc,matrix} + +%% +%% Helpers +%% +\directlua{require("cartonaugh")} + +%% command raises an error if executed outside the cartonaugh environment +\newcommand{\@cartonaugh@func@bailoutsideenvironment@}[0]{% + \ifnum\@cartonaugh@var@isactive@=0 + \PackageError{cartonaugh}{% + Command can not be used outside cartonaugh environment% + }{% + Do not use this command outside the cartonaugh environment.% + } + \fi +} + +\newcommand{\cartonaughSetColorAtIndex}[2]{\directlua{CARTONAUGH_COLORS[\the\numexpr(#1)\relax] = "\luaescapestring{#2}"}} + +%% store whether a kmap has been created +\newcommand{\@cartonaugh@var@isactive@}{0} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +% \fi +% +% \section{Usage} +% +% \begin{environment}{cartonaugh} +% The |cartonaugh| environment is the base for this package, and everything related to this package happens inside an instances of this environment. +% +% \textbf{Usage:} +% \MakeShortVerb{\|} +% \begin{tabularx}{\textwidth}{l X} +% \small{|\begin{cartonaugh}|} & \\ +% \small{\meta{*}} & \small{One asterisk for black and white implicants, non for colorized implicants} \\ +% \small{\oarg{X size}} & \small{Number of X-axis cells. Default: ''4''} \\ +% \small{\oarg{Y size}} & \small{Number of Y-axis cells. Default: ''4''} \\ +% \small{\oarg{Z size}} & \small{Number of X$\times$Y submaps. Default: ''1''} \\ +% \small{\oarg{X label}} & \small{Label for the X-axis. Default: ''$X_1X_0$''} \\ +% \small{\oarg{Y label}} & \small{Label for the Y-axis. Default: ''$X_3X_2$''} \\ +% \small{\oarg{Z label}} & \small{Label for the submaps. Default: ''$X_5X_4$''} \\ +% \small{\oarg{Submap Seperation Type}} & \small{Whether to seperate the submap by space or by a thick line. Default: 0 (so seperation by space)} \\ +% \end{tabularx} +% \DeleteShortVerb{\|} +% \textbf{Example:} +% +% Four variable karnaugh map, colorized, with X label $X_1X_0$, and Y label $X_3X_2$. +% \begin{verbatim} +%\begin{cartonaugh} +%\end{cartonaugh} +% +%or +% +%\begin{cartonaugh}[4][4][1][$X_1X_0$][$X_3X_2$] +%\end{cartonaugh} +% \end{verbatim} +% Six variable karnaugh map, black and white, with X label $ba$, Y label $dc$, and Z label $fe$. +% \begin{verbatim} +%\begin{cartonaugh}*[4][4][4][$ba$][$dc$][$fe$] +%\end{cartonaugh} +% \end{verbatim} +% +% Six variable karnaugh map, black and white, with X label $ba$, Y label $dc$, and Z label $fe$, and the submaps are seperated by a thick line in between. +% \begin{verbatim} +%\begin{cartonaugh}*[4][4][4][$ba$][$dc$][$fe$][1] +%\end{cartonaugh} +% \end{verbatim} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\NewDocumentEnvironment{cartonaugh}{s O{4} O{4} O{1} O{$X_1X_0$} O{$X_3X_2$} O{$X_5X_4$} O{0}} {% + \begingroup + % store map size {[START] + \renewcommand{\@cartonaugh@var@isactive@}{1}% + % [END]} + % determinate if markings should be color or black and white + % + % [END]} + % test if a matrix template is found or not(aka "\@cartonaugh@local@matrixtemplate@" equals to '0') + \begin{tikzpicture} + \directlua{init_cartonaught_env( + \the\numexpr(#2)\relax, + \the\numexpr(#3)\relax, + \the\numexpr(#4)\relax, + \the\numexpr(#1)\relax, + "\luaescapestring{\detokenize{#5}}", + "\luaescapestring{\detokenize{#6}}", + "\luaescapestring{\detokenize{#7}}", + \the\numexpr(#8)\relax + )} +}{ + \end{tikzpicture} + \endgroup +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +% \fi +% \end{environment} +% +% \newpage +% \MakeShortVerb{\|} +% \subsection{Terms} +% \begin{macro}{\autoterms} +% The |\autoterms| command fills the remaining unfilled cells of the karnaugh map with the contents of the optional argument. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\autoterms|} & \\ +% \small{\oarg{content}} & \small{Content for the remaining unfilled cells. Default: ''-''} +% \end{tabularx} +% +% \textbf{Example:} +% +% Fill all remaining unfilled cells with ''-''. +% \begin{verbatim} +% \DeleteShortVerb{\|} +%\begin{cartonaugh} +% \autoterms[-] +%\end{cartonaugh} +% \end{verbatim} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\autoterms}{O{-}} {% + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + autoterms("\luaescapestring{\detokenize{#1}}", '-') + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +% \fi +% +% \end{macro} +% +% \begin{macro}{\indeterminants} +% The |\indeterminants| command fills the specified cells with ''-'' if they aren't already filled. Order of the cell numbers does not matter. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\indeterminants|} & \\ +% \small{\marg{cells}} & \small{Comma separated list of cells to fill with ''-''} +% \end{tabularx} +% +% \textbf{Example:} +% +% Fill the top left and right cell with ''-''. +% \begin{verbatim} +%\begin{cartonaugh} +% \indeterminants{0,2} +%\end{cartonaugh} +% \end{verbatim} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\indeterminants}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", '-') + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +% \fi +% +% \end{macro} +% +% \begin{macro}{\manualterms} +% The |\manualterms| command fills the 0th cell with the first element in the argument, the 1st cell with the second element in the argument, and so on. If any of the cells already is filled, it is left as it was. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\manualterms|} & \\ +% \small{\marg{content}} & \small{Comma separated list of cell contents} +% \end{tabularx} +% +% \textbf{Example:} +% +% Fill the first four cells with 0, 1, 0, and 1 respectively. +% \begin{verbatim} +%\begin{cartonaugh} +% \manualterms{0,1,0,1} +%\end{cartonaugh} +% \end{verbatim} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\manualterms}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manualterms("\luaescapestring{\detokenize{#1}}") + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +% \fi +% +% \end{macro} +% +% \begin{macro}{\maxterms} +% The |\maxterms| command fills the specified cells with ''0'' if they aren't already filled. Order of the cell numbers does not matter. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\maxterms|} & \\ +% \small{\marg{cells}} & \small{Comma separated list of cells to fill with ''0''} \\ +% \end{tabularx} +% +% \textbf{Example:} +% +% Fill the top left and right cell with ''0''. +% \begin{verbatim} +%\begin{cartonaugh} +% \maxterms{0,2} +%\end{cartonaugh} +% \end{verbatim} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\maxterms}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", '0') + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% +% \begin{macro}{\minterms} +% The |\minterms| command fills the specified cells with ''1'' if they aren't already filled. Order of the cell numbers does not matter. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\minterms|} & \\ +% \small{\marg{cells}} & \small{Comma separated list of cells to fill with ''1''} \\ +% \end{tabularx} +% +% \textbf{Example:} +% +% Fill the top left and right cell with ''1''. +% \begin{verbatim} +%\begin{cartonaugh} +% \minterms{0,2} +%\end{cartonaugh} +% \end{verbatim} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\minterms}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", '1') + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% +% \begin{macro}{\terms} +% The |\terms| command fills the specified cells with the specified content if they aren't already filled. Order of the cell numbers does not matter. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\terms|} & \\ +% \small{\marg{cells}} & \small{Comma separated list of cells to fill with content} \\ +% \small{\marg{content}} & \small{Content to fill the cells with} \\ +% \end{tabularx} +% +% \textbf{Example:} +% +% Fill the top left and right cell with ''X''. +% \begin{verbatim} +%\begin{cartonaugh} +% \terms{0,2}{X} +%\end{cartonaugh} +% \end{verbatim} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\terms}{m m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", + "\luaescapestring{\detokenize{#2}}") + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% +% \newpage +% \MakeShortVerb{\|} +% \subsection{Implicants} +% \begin{macro}{\implicant} +% The |\implicant| command draws quadratic implicants on one or multiple submaps. If the implicant shall be drawn on multiple submaps, \marg{northwest cell} and \marg{southeast cell} must be specified as if the implicant was to be drawn on the 0:th submap. When turned on, colorization is done automatically, following a global sequence of available colors. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\implicant|} & \\ +% \small{\marg{northwest cell}} & \small{The most northwest cell in the implicant} \\ +% \small{\marg{southeast cell}} & \small{The most southeast cell in the implicant} \\ +% \small{\oarg{submaps}} & \small{Comma separated list of submaps the implicant should be drawn on. Default: ''0''} \\ +% \end{tabularx} +% +% \textbf{Example:} +% \DeleteShortVerb{\|} +% \begin{multicols}{2} +% [Implicant around the four most inner cells.] +% \begin{verbatim} +%\begin{cartonaugh} +% \implicant{5}{15} +%\end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh} +% \implicant{5}{15} +% \end{cartonaugh} +% } +% \end{multicols} +% \begin{multicols}{2} +% [Single cell implicant, 0:th cell, on all four submaps.] +% \begin{verbatim} +%\begin{cartonaugh}[4][4][4] +% [$BA$][$DC$][$FE$][1] +% \implicant{0}{0}[0,1,2,3] +%\end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh}[4][4][4][$BA$][$DC$][$FE$][1] +% \implicant{0}{0}[0,1,2,3] +% \end{cartonaugh} +% } +% \end{multicols} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\implicant}{m m O{0}} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manual_draw_implicant( + "\luaescapestring{\detokenize{#1}}", + "\luaescapestring{\detokenize{#2}}", + "\luaescapestring{\detokenize{#3}}" + ) + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% +% \MakeShortVerb{\|} +% \begin{macro}{\implicantedge} +% The |\implicantedge| command draws quadratic implicants with the middle of the implicant facing the edge of a submap either horizontally or vertically. The function is able to draw the same implicant on one or multiple submaps. However if the implicant shall be drawn on multiple submaps, \marg{northwest part - northwest cell}, \marg{northwest part - southeast cell}, \marg{southeast part - northwest cell}, \marg{southeast part - southeast cell} must be specified as if the implicant was to be drawn on the 0:th submap. When turned on, colorization is done automatically, following a global sequence of available colors. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\implicantedge|} & \\ +% \small{\marg{northwest part - northwest cell}} & \small{The most northwest cell in the northwest part of the implicant} \\ +% \small{\marg{northwest part - southeast cell}} & \small{The most southeast cell in the northwest part of the implicant} \\ +% \small{\marg{southeast part - northwest cell}} & \small{The most northwest cell in the southeast part of the implicant} \\ +% \small{\marg{southeast part - southeast cell}} & \small{The most southeast cell in the southeast part of the implicant} \\ +% \small{\oarg{submaps}} & \small{Comma separated list of submaps the implicant should be drawn on. Default: ''0''} \\ +% \end{tabularx} +% +% \textbf{Example:} +% \DeleteShortVerb{\|} +% +% \begin{multicols}{2} +% [Horizontal implicant over the submap edge containing the cells 4, 6, 12, and 14.] +% \begin{verbatim} +%\begin{cartonaugh} +% \implicantedge{4}{12}{6}{14} +%\end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh} +% \implicantedge{4}{12}{6}{14} +% \end{cartonaugh} +% } +% \end{multicols} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\implicantedge}{m m m m O{0}} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manual_draw_edge_implicant( + "\luaescapestring{\detokenize{#1}}", + "\luaescapestring{\detokenize{#2}}", + "\luaescapestring{\detokenize{#3}}", + "\luaescapestring{\detokenize{#4}}", + "\luaescapestring{\detokenize{#5}}" + ) + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% \MakeShortVerb{\|} +% \begin{macro}{\implicantcorner} +% The |\implicantcorner| command draws an implicant around only the four corner pieces on one or multiple four variable karnaugh submaps. When turned on, colorization is done automatically, following a global sequence of available colors. +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\implicantcorner|} & \\ +% \small{\oarg{submaps}} & \small{Comma separated list of submaps the implicant should be drawn on. Default: ''0''} \\ +% \end{tabularx} +% +% \textbf{Example:} +% \DeleteShortVerb{\|} +% +% \begin{multicols}{2} +% [Draw an implicant around all corners on 0th and 2nd submap of a six variable karnaugh map.] +% \begin{verbatim} +%\begin{cartonaugh}[4][4][4] +% \implicantcorner[0,2] +%\end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh}[4][4][4] +% \implicantcorner[0,2] +% \end{cartonaugh} +% } +% \end{multicols} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\implicantcorner}{O{0}} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manual_draw_corner_implicant( + "\luaescapestring{\detokenize{#1}}" + ) + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% +% \newpage +% \MakeShortVerb{\|} +% \subsection{Options} +% \begin{macro}{\implicantspread} +% The |\implicantspread| changed the implicant spread +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\implicantspread|} & \\ +% \small{\marg{innerspread}} & \small{The inner spread's spread, from 0 to 0.5 (as >0.5 will go out of the implicant square)} \\ +% \small{\marg{outerspread}} & \small{The outer spread's spread, from 0.5 and up} \\ +% \end{tabularx} +% +% \textbf{Example:} +% \DeleteShortVerb{\|} +% +% \begin{multicols}{2} +% \begin{verbatim} +% \begin{cartonaugh}[4][4][2] +% \implicantedge{4}{12}{6}{14}[0] +% \implicantspread{0.25}{0.7} +% \implicantedge{4}{12}{6}{14}[1] +% \end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh}[4][4][2] +% \implicantedge{4}{12}{6}{14}[0] +% \implicantspread{0.25}{0.7} +% \implicantedge{4}{12}{6}{14}[1] +% \end{cartonaugh} +% } +% \end{multicols} +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\implicantspread}{m m} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + change_implicant_inner_spread(\luaescapestring{\detokenize{#1}}) + change_implicant_outer_spread(\luaescapestring{\detokenize{#2}}) + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% +% \MakeShortVerb{\|} +% \begin{macro}{\resetimplicantspread} +% The |\resetimplicantspread| resets the implicant spread if set by |\implicantspread| to default values +% \DeleteShortVerb{\|} +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\resetimplicantspread}{} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + change_implicant_inner_spread(0.35) + change_implicant_outer_spread(0.55) + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% \MakeShortVerb{\|} +% \begin{macro}{\changecolor} +% The |\changecolor| changes the color for implicants +% +% \textbf{Usage:} +% +% \begin{tabularx}{\textwidth}{l X} +% \small{|\changecolor|} & \\ +% \small{\marg{color}} & \small{The new color for implicants, in Tikz format} \\ +% \end{tabularx} +% \DeleteShortVerb{\|} +% \textbf{Example:} +% +% \begin{multicols}{2} +% [Change the implicant color to pink, then green] +% \begin{verbatim} +% \begin{cartonaugh} +% \changecolor{pink} +% \implicant{0}{1} +% \changecolor{green} +% \implicant{8}{10} +% \end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh} +% \changecolor{pink} +% \implicant{0}{1} +% \changecolor{green} +% \implicant{8}{10} +% \end{cartonaugh} +% } +% \end{multicols} +% +% +% \iffalse +% \begin{macrocode} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +\DeclareDocumentCommand{\changecolor}{m} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + customColor("\luaescapestring{\detokenize{#1}}") + } +} +% ^^A ########################################################################## +% ^^A ########################################################################## +% ^^A #### /CODE #### +% ^^A ########################################################################## +% ^^A ########################################################################## +% \end{macrocode} +%\fi +% +% \end{macro} +% +% \newpage +% \section{Examples} +% \begin{multicols}{2} +% [Draw a karnaugh map for \small{$f(a,b,c,d,e,f) =$\\$\Sigma(0,1,2,3,8,13,17,20,22,28,33,32,30,19,40,35,49,42,34,10,60,54,62,51,52)$\\$+d(15,45,47)$}.] +% \begin{verbatim} +%\begin{cartonaugh}[4][4][4][$ba$][$dc$][$fe$][1] +% \minterms{0,1,2,3,8,13,17,20,22,28, +% 33,32,30,19,40,35,49,42,34,10,60, +% 54,62,51,52} +% \indeterminants{15,45,47} +% \autoterms[0] +% \implicantcorner[0,2] +% \implicant{1}{3}[0,1,2,3] +% \implicantedge{4}{12}{6}{14}[1,3] +% \implicant{13}{15}[0,2] +%\end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh}[4][4][4][$ba$][$dc$][$fe$][1] +% \minterms{0,1,2,3,8,13,17,20,22,28,33,32,30,19,40,35,49,42,34,10,60,54,62,51,52} +% \indeterminants{15,45,47} +% \autoterms[0] +% \implicantcorner[0,2] +% \implicant{1}{3}[0,1,2,3] +% \implicantedge{4}{12}{6}{14}[1,3] +% \implicant{13}{15}[0,2] +% \end{cartonaugh} +% } +% \end{multicols} +% +% \begin{multicols}{2} +% [Draw a karnaugh map for \small{$f(X_0,X_1) = \Pi(0,2,3)$} in black and white.] +% \begin{verbatim} +%\begin{cartonaugh}*[2][2][1][$X_0$][$X_1$] +% \maxterms{0,2,3} +% \autoterms[1] +% \implicant{1}{1} +%\end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh}*[2][2][1][$X_0$][$X_1$] +% \maxterms{0,2,3} +% \autoterms[1] +% \implicant{1}{1} +% \end{cartonaugh} +% } +% \end{multicols} +% +% \newpage +% \begin{multicols}{2} +% [Draw a variable entered map.] +% \begin{verbatim} +%\begin{cartonaugh}[4][2][1][$ab$][$c$] +% \maxterms{0,2,4,5,6} +% \minterms{3} +% \terms{1}{$d$} +% \terms{7}{$d'$} +% \implicant{1}{3} +% \implicant{3}{7} +%\end{cartonaugh} +% \end{verbatim} +% \columnbreak +% \resizebox{\columnwidth}{!}{ +% \begin{cartonaugh}[4][2][1][$ab$][$c$] +% \maxterms{0,2,4,5,6} +% \minterms{3} +% \terms{1}{$d$} +% \terms{7}{$d'$} +% \implicant{1}{3} +% \implicant{3}{7} +% \end{cartonaugh} +% } +% \end{multicols} +% +% \section{Dependencies} +% \begin{itemize} +% \item tikz +% \item xparse +% \item xstring +% \item lualatex +% \end{itemize} +% +% \newpage +% \section{Miscellaneous} +% \MakeShortVerb{\|} +% \subsection*{Resizing} +% The karnaugh maps produced with this package have a prespecified size which can not be changed. However you can resize the karnaugh map to your desired size. Resizing can be done using the |\resizebox| command from the graphicx package. Scaling the karnaugh map to fill the column width while preserving the aspect ratio can be done as follows. +% \begin{verbatim} +%\resizebox{\columnwidth}{!}{ +% \DeleteShortVerb{\|} +% \begin{cartonaugh} +% \end{cartonaugh} +%} +% \end{verbatim} +% +% \subsection*{Comma separated lists} +% Anywhere in this package where a comma separated list is used data should only be comma separated. Therefore a comma and space separeated list will for example \textit{not} work properly. +% +% An example of errorious usage related to the \small{\marg{cells}} parameter in the terms related commands can result in multiple zeros, ones and other terms overlapping in the same cell in the outputted karnaugh map. +% +%\iffalse +%</package> +%<*luacode> +% +% +% This is the Luacode that is generated and put into cartonaugh.lua +% +% +%\begin{macrocode} +DEBUG_FLAG = 0 + +CARTONAUGH_COLORS = {'red', 'green', 'yellow', 'cyan', 'blue', 'magenta'} +CARTONAUGH_DEFAULT_COLOR = 'cyan' + +cartonaugh_env_settings = {} +used_cells = {} + +-- Function that is used to either print to LaTeX or to the console +-- Used for debugging mode +function localPrint(str) + if DEBUG_FLAG==1 then + print(str) + end + tex.sprint(str) +end + +-- Function that takes a string and splits it be delimiter, then returns it back +-- From https://stackoverflow.com/questions/19262761/lua-need-to-split-at-comma +function split(source, delimiters) + local elements = {} + local pattern = '([^'..delimiters..']+)' + string.gsub(source, pattern, function(value) elements[#elements + 1] = value; end); + return elements +end + +-- Function that converts a decimal number to binary +function decimalToBin(num, numb_bits, return_concat) + if return_concat == nil then return_concat=true end + num = tonumber(num) + numb_bits = tonumber(numb_bits) + local t={} + for b=numb_bits,1,-1 do + rest=math.floor(math.fmod(num,2)) + t[b]=rest + num=(num-rest)/2 + end + if return_concat == true then + return table.concat(t) + else + return t + end +end + +-- Function that converts a decimal number to grey code +function decimalToGreyBin(num, numb_bits) + -- Get the binary array + num = num ~ (num >> 1) + local t = decimalToBin(num, numb_bits, false) + return table.concat(t) +end + +function greyBinToDecimal(num) +-- num = tonumber(num,2) + local mask = num + while mask > 0 do + mask = mask >> 1 + num = num ~ mask + end + return tonumber(num) +end + +-- Function to pad a string by a amount with b string +function padString(str, pad_to, pad_with) + local ret = str + for l=1, (pad_to-string.len(str)) do + ret = pad_with .. ret + end + return ret +end + +function getColor(index) + if index <= 0 then return CARTONAUGH_DEFAULT_COLOR end + if CARTONAUGH_COLORS[index] ~= nil then + return CARTONAUGH_COLORS[index] + else + return CARTONAUGH_DEFAULT_COLOR + end +end + +function customColor(color) + -- Some high number so it's not in the CARTONAUGH_COLORS array + cartonaugh_env_settings.color_index = 100 + CARTONAUGH_DEFAULT_COLOR = color +end + +-- Function to generate a kmap template +function generateKMap(column, row, grid_numb) + local outside_column_bits = 1 + local outside_row_bits = 1 + local outside_grid_numb_bits = 2 + local return_str = '' + if row >= 4 then + outside_row_bits = 2 + end + if column >= 4 then + outside_column_bits = 2 + end + for c=1,column,1 do + for r=1,row,1 do + if r == 0 then + if c == 0 then + -- Do Nothing... + elseif c == (column+1) then + return_str = return_str .. ("\\phantom{" .. decimalToBin(0, outside_column_bits) .. "}") + else + return_str = return_str .. (decimalToGreyBin(c-1, outside_column_bits)) + end + elseif r==(row+1) then + if c==0 then + return_str = return_str .. ("\\phantom{" .. decimalToBin(0, outside_column_bits) .. "}") + end + else + if c == 0 then + return_str = return_str .. (decimalToGreyBin(r-1, outside_row_bits)) + elseif c == (column+1) then + + else + return_str = return_str ..("|(" .. padString((decimalToGreyBin(grid_numb, outside_grid_numb_bits) .. decimalToGreyBin(c-1, outside_column_bits) .. decimalToGreyBin(r-1, outside_row_bits)), 6, 0) .. ")|" .. "\\phantom{0}") + --TODO: Look into why reversing c and r from where they should be makes it work + end + end + + if r == (row) then + return_str = return_str .. ("\\\\") + else + return_str = return_str .. ("\\&") + end + end + end + return return_str +end + +function init_cartonaught_env(numb_cols, numb_row, numb_submaps, is_bw, var12_str, var34_str, var56_str, is_submap_seperated) + -- Change the default texts depending on the number of submaps if not custom name has been given + -- TODO: Get this to actually work + if var12_str == 'X_1X_0' and var34_str == 'X_3X_2' and var56_str == 'X_5X_4' then + if numb_submaps == 1 then + var56_str = 'X_3' + end + if numb_cols == 1 then + var12_str = 'X_0' + end + end + cartonaugh_env_settings = { + cols = numb_cols, + rows = numb_row, + submaps = numb_submaps, + bw = tonumber(is_bw), + var_string = { + v12 = var12_str, + v34 = var34_str, + v56 = var56_str, + }, + color_index = 1, + implicant_settings = { + inner_sep = 0.35, + outer_sep = 0.55, + } + } + used_cells = {} + + if is_submap_seperated == 0 then + is_submap_seperated = false + else + is_submap_seperated = true + end + + draw_pgf_kmap(numb_cols, numb_row, numb_submaps, var12_str, var34_str, var56_str, is_submap_seperated) +end + +function change_implicant_inner_spread(new_amount) + cartonaugh_env_settings.implicant_settings.inner_sep = new_amount +end + +function change_implicant_outer_spread(new_amount) + cartonaugh_env_settings.implicant_settings.outer_sep = new_amount +end + +-- Function to generate the k-maps +-- NOTE: Each variable/cell in the k-map is 1cm. This is so that everything alings with each other just be adding +-- the number of row and column. It's a bit of hack, but for now it will stay this way. Resizing of the matrix +-- will be done with the scale option in the future +function draw_pgf_kmap(column, row, submaps_n, var1, var2, var3, is_submap_seperated) + submaps_n = submaps_n-1 + -- TODO: Transform the following settings variables into arguments + local is_multitable_seperated = is_submap_seperated -- Setting to determine if the graphs are drawn with a sperator line or distanced out + local graph_seperator = 1.5 -- Seperation lenght between kmaps if is_multitable_seperated=false + local kmaplevel_seperator_lenght = 0.1 -- Setting to determine the seperator line's thickness if is_multitable_seperated=true + local line_width = 0.015 -- Set the line thickness of things here + local zero_var_line_lenght = 0.75 -- The lenght of the line at the top-left corner of the kmap where the implacants reside + local column_header_numb_bits = ((column-1) // 2)+1 + local row_header_numb_bits = ((row-1) // 2)+1 + if is_multitable_seperated then graph_seperator = 0 end + for d=0,submaps_n,1 do + -- Find the top-left corner of each grid (seperated by 1 unit) + local grid_x_loc = (d % 2)*(column+graph_seperator) + local grid_y_loc = -(d // 2)*(row+graph_seperator) + -- localPrint(string.format("\\node[above] at (%f,%f) {\\small{%s}};", 0, 0, abimplecant)) + if is_multitable_seperated then + if (d % 2) == 1 then + local add_heigh = 0 + if d >= 2 then add_heigh = kmaplevel_seperator_lenght end + localPrint(string.format("\\fill[black] (%f,%f) rectangle (%f,%f);", grid_x_loc, grid_y_loc, grid_x_loc+kmaplevel_seperator_lenght, grid_y_loc-row-line_width-add_heigh)) + grid_x_loc = grid_x_loc + kmaplevel_seperator_lenght + end + if d >= 2 then + localPrint(string.format("\\fill[black] (%f,%f) rectangle (%f,%f);", grid_x_loc, grid_y_loc, grid_x_loc+column+line_width, grid_y_loc-kmaplevel_seperator_lenght)) + grid_y_loc = grid_y_loc - kmaplevel_seperator_lenght + end + end + -- Print out the top-left line corner with the variables + if (is_multitable_seperated == false) or (d==0) then + localPrint(string.format("\\draw[inner sep=0pt, outer sep=0pt] (%f, %f) -- (%f, %f);", grid_x_loc+line_width, grid_y_loc-line_width, grid_x_loc-zero_var_line_lenght, grid_y_loc+zero_var_line_lenght)) + localPrint(string.format("\\node[left] at (%f,%f) {\\small{%s}};", grid_x_loc-0.3, grid_y_loc+0.3, var2)) + localPrint(string.format("\\node[right] at (%f,%f) {\\small{%s}};", grid_x_loc-0.6, grid_y_loc+0.6, var1)) + end + -- Print out the top boolean column header + if (is_multitable_seperated == false) or (d < 2) then + localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, column sep={1cm,between origins}, nodes={align=center,text width=1cm,inner sep=0pt}, anchor=south west, inner sep=0pt, outer sep=0pt] at (%f, %f) {",grid_x_loc,grid_y_loc+0.05)) + for c=0, column-1, 1 do + localPrint(string.format("%s", decimalToGreyBin(c, column_header_numb_bits))) + if c ~= (column-1) then localPrint("\\&") end + end + localPrint("\\\\};") + end + -- Print out the side boolean row header + if (is_multitable_seperated == false) or (d%2 == 0) then + localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, row sep={1cm,between origins}, nodes={minimum height=1cm,inner sep=0pt, text height=2ex, text depth=0.5ex}, anchor=north east, inner sep=0pt, outer sep=0pt] at (%f, %f) {",grid_x_loc-0.05,grid_y_loc)) + for r=0, row-1, 1 do + localPrint(string.format("%s \\\\", decimalToGreyBin(r, row_header_numb_bits))) + end + localPrint("};") + end + -- Print out the matrix + localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, column sep={1cm,between origins}, row sep={1cm,between origins}, nodes={rectangle,draw,minimum height=1cm,align=center,text width=1cm,inner sep=0pt, text height=2ex, text depth=0.5ex, line width=0.015cm}, anchor=north west, inner sep=0pt, outer sep=0pt] at (%f, %f) {%s};", + grid_x_loc, grid_y_loc, generateKMap(row, column, d) + )) + -- Print out the buttom text saying which matrix is which + if (submaps_n > 0) then + if (is_multitable_seperated == false) then + localPrint(string.format("\\node[below] at (%f, %f) {%s = %s};", grid_x_loc+(column//2),grid_y_loc-row,var3, decimalToBin(d, 2))) + elseif (is_multitable_seperated == true) then + if (d < 2) then + localPrint(string.format("\\node[] at (%f, %f) {%s = %s};", grid_x_loc+(column//2), grid_y_loc+1, var3, decimalToBin(d, 2))) + end + if (d % 2 == 0) and (submaps_n > 2) then + localPrint(string.format("\\node[rotate=90] at (%f, %f) {%s = %s};", grid_x_loc-1, grid_y_loc-(row//2), var3, decimalToBin(d, 2))) + end + end + end + end +end + +-- Function for drawing an implicant manually (meaning to give the start and endpoint, as well as optional +-- submaps for different ones) +function manual_draw_implicant(st, en, submaps_str) + local color_index = cartonaugh_env_settings.color_index + local max_submaps = cartonaugh_env_settings.submaps + local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep + st = tonumber(st) + en = tonumber(en) + local submap_arr = split(submaps_str, ',') + -- Check if the implacent selection + for s=1,table.getn(submap_arr),1 do + current_submap = tonumber(submap_arr[s]) + if current_submap < max_submaps then + local draw_str = string.format("($(%s.center)+(-%s,%s)$) rectangle ($(%s.center)+(%s,-%s)$)", decimalToGreyBin(current_submap, 2) .. decimalToBin(st,4), inner_spread, inner_spread, decimalToGreyBin(current_submap, 2) .. decimalToBin(en,4), inner_spread, inner_spread) + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[rounded corners=3pt,fill=%s,fill opacity=0.25,] {%s};", getColor(color_index) , draw_str)) + end + localPrint(string.format("\\draw[rounded corners=3pt,draw opacity=1.0,] {%s};", draw_str)) + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end + cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1 +end + +-- Handler function for drawing edge implacants, figuring out orientation as well +function manual_draw_edge_implicant(corner1, corner2, corner3, corner4, submaps_str) + corner1 = tonumber(corner1) + corner2 = tonumber(corner2) + corner3 = tonumber(corner3) + corner4 = tonumber(corner4) + + if corner1-corner2 > corner1-corner3 then + manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, 'n') + manual_draw_edge_implicant_orientation(corner3, corner4, submaps_str, 's') + else + manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, 'w') + manual_draw_edge_implicant_orientation(corner3, corner4, submaps_str, 'e') + end + + cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1 + +end + +-- Function to draw out a 1 edge implacant given 2 corners, the submaps, and the orientation (n, s, e, or w) +-- TODO: Perhaps find a way to repeat the code between n/s and e/w +-- TODO: For the mirror variable, have that apply to the lua var directly instead of having LaTeX handle it +-- TODO: Maybe add option for squigly lines for the end instead of nothing +-- TODO: Open up the internal inner_spread and outer_spead settings to the user +function manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, orientation) + local color_index = cartonaugh_env_settings.color_index + local max_submaps = cartonaugh_env_settings.submaps + corner1 = tonumber(corner1) + corner2 = tonumber(corner2) + local submap_arr = split(submaps_str, ',') + local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep + local outer_spead = cartonaugh_env_settings.implicant_settings.outer_sep + -- Check if the implacent selection + for s=1,table.getn(submap_arr),1 do + current_submap = tonumber(submap_arr[s]) + if current_submap < max_submaps then + local draw_string = "" + local mirror = 1 + local corner1_bin = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner1,4) + local corner2_bin = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner2,4) + if orientation == 'n' or orientation == 's' then + -- If the orientation is south, just mirror it + if orientation == 's' then mirror = -1 end + draw_string = string.format("($(%s.center)+(-%f,%f*%s)$)", corner1_bin, inner_spread, outer_spead, mirror) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(-%f,-%f*%s)$)}", corner1_bin, inner_spread, inner_spread, mirror) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f,-%f*%s)$)}", corner2_bin, inner_spread, inner_spread, mirror) + draw_string = draw_string .. string.format("-- ($(%s.center)+(%f,%f*%s)$)", corner2_bin, inner_spread, outer_spead, mirror) + else + if orientation == 'e' then mirror = -1 end + draw_string = string.format("($(%s.center)+(-%f*%s,%f)$)", corner1_bin, outer_spead, mirror, inner_spread) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f*%s,%f)$)}", corner1_bin, inner_spread, mirror, inner_spread) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f*%s,-%f)$)}", corner2_bin, inner_spread, mirror, inner_spread) + draw_string = draw_string .. string.format("-- ($(%s.center)+(-%f*%s,-%f)$)", corner2_bin, outer_spead, mirror, inner_spread) + end + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[fill=%s,fill opacity=0.25,] {%s};", getColor(color_index), draw_string)) + end + localPrint(string.format("\\draw[draw opacity=1.0] {%s};", draw_string)) + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end +end + +-- Function to draw the corner implicants. Only usable on 4x4 matrices +function manual_draw_corner_implicant(submaps_str) + local corner_arr = {0, 2, 8, 10} + local submap_arr = split(submaps_str, ',') + local max_submaps = cartonaugh_env_settings.submaps + local color = cartonaugh_env_settings.color_index + local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep + local outer_spread = cartonaugh_env_settings.implicant_settings.outer_sep + + if cartonaugh_env_settings.cols ~= 4 or cartonaugh_env_settings.rows ~= 4 then + localPrint("\\PackageError{cartonaugh}{Cannot use a corner implicant on anything but a 4x4. Sorry!}") + return + end + + for s=1,table.getn(submap_arr),1 do + current_submap = tonumber(submap_arr[s]) + if current_submap < max_submaps then + for c=0,3,1 do + local x_mirror = 1-(2*(c%2)) + local y_mirror = 1-(2*(c//2)) + local corner = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner_arr[c+1],4) + -- Create the string to draw the corners + local draw_string = string.format("($(%s.center)+(-%f*%d,%f*%d)$)--($(%s.center)+(%f*%d,%f*%d)$)", corner, outer_spread, x_mirror, outer_spread, y_mirror, corner, inner_spread, x_mirror, outer_spread, y_mirror) + draw_string = draw_string .. string.format("{ [rounded corners=3pt] --($(%s.center)+(%f*%d,-%f*%d)$) }", corner, inner_spread, x_mirror, inner_spread, y_mirror) + draw_string = draw_string .. string.format("--($(%s.center)+(-%f*%d,-%f*%d)$) -- cycle", corner, outer_spread, x_mirror, inner_spread, y_mirror) + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[fill=%s,fill opacity=0.25,] {%s};", getColor(color), draw_string)) + end + localPrint(string.format("\\draw[sharp corners, draw opacity=1.0] {%s};", draw_string)) + end + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end + + cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1 + +end + +-- WORK IN PROGRESS/LONG TERM FUNCTION +-- Goals is to eventually give \implicant{1}{x}{0}{x} for example and have it draw it out for you. +-- May give up on this in favor of other things...don't know +function draw_implicant(var_list) +-- local var_list_arr = split(var_list, ',') + local color_index = cartonaugh_env_settings.color_index + local max_submaps = cartonaugh_env_settings.submaps + localPrint("\\PackageWarning{cartonaugh}{This is a UNSTABLE and WIP function. Procede on your own}") + + -- Check argument for submaps greater than 1 + -- TODO: before returning print out a package error + if max_submaps > 1 then + for s=0,max_submaps-1,1 do + if var_list[5+s] == '' then + -- TODO: Fix this + localPrint(string.format("\\PackageError{cartonaugh}{Please feed either 1, 0, or x for sub map number %d's variable boolean}", s+1)) + return + end + end + end + + local low_limit = 0 + local high_limit = 0 + + for b=1,4,1 do + if var_list[b] == 'x' then + print('a',high_limit, greyBinToDecimal(high_limit), decimalToBin(greyBinToDecimal(high_limit), 4)) + print('b',high_limit | (1 << (b-1)), greyBinToDecimal(high_limit | (1 << (b-1))), decimalToBin(greyBinToDecimal(high_limit | (1 << (b-1))), 4)) + if greyBinToDecimal(high_limit) < greyBinToDecimal(high_limit | (1 << (b-1))) then + high_limit = high_limit | (1 << (b-1)) + print(decimalToBin(greyBinToDecimal(high_limit),4), decimalToBin(greyBinToDecimal(high_limit & ~(1 << (b-2))),4)) + if greyBinToDecimal(high_limit) < greyBinToDecimal(high_limit & ~(1 << (b-2))) then + high_limit = high_limit & ~(1 << (b-2)) + end + end + elseif var_list[b] == '1' then + high_limit = high_limit | (1 << (b-1)) + low_limit = low_limit | (1 << (b-1)) + end + print('low_limit=', low_limit, 'high_limit=', high_limit) + end + + local st = decimalToBin(low_limit,4) + local en = decimalToBin(high_limit,4) + + print('low_limit', greyBinToDecimal(low_limit), 'high_limit', greyBinToDecimal(high_limit), 'st=', st, 'en=', en) + + for s=1,1,1 do + current_submap = 0 + if current_submap < max_submaps then + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[rounded corners=3pt,fill=%s,fill opacity=0.25,] {($(%s.center)+(-0.3,0.3)$) rectangle ($(%s.center)+(0.3,-0.3)$)};", getColor(color_index) , decimalToGreyBin(current_submap, 2) .. st, decimalToGreyBin(current_submap, 2) .. en)) + color_index = color_index+1 + end + localPrint(string.format("\\draw[rounded corners=3pt,draw opacity=1.0,] {($(%s.center)+(-0.3,0.3)$)rectangle($(%s.center)+(0.3,-0.3)$)};", decimalToGreyBin(current_submap, 2) .. st, decimalToGreyBin(current_submap, 2) .. en)) + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end + cartonaugh_env_settings.color_index = color_index +end + +function autoterms(what_to_write) + local max_cells = cartonaugh_env_settings.submaps * cartonaugh_env_settings.cols * cartonaugh_env_settings.rows + for cell=0,max_cells-1,1 do + if used_cells[cell] == nil then + used_cells[cell] = true + localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write)) + end + end +end + +function manualterms(what_to_write) + local what_to_write_arr = split(what_to_write, ',') + for cell=0,table.getn(what_to_write_arr)-1,1 do + if used_cells[cell] == nil then + used_cells[cell] = true + localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write_arr[cell+1])) + end + end +end + +function write_to_cell(cells, what_to_write) + local cells_arr = split(cells, ',') + for c=1,table.getn(cells_arr),1 do + local cell = tonumber(cells_arr[c]) + if used_cells[cell] == nil then + used_cells[cell] = true + localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write)) + end + end +end +%\end{macrocode} +%</luacode> +%\fi +% +\endinput diff --git a/Master/texmf-dist/source/latex/cartonaugh/cartonaugh.ins b/Master/texmf-dist/source/latex/cartonaugh/cartonaugh.ins new file mode 100644 index 00000000000..17bd84bcd1d --- /dev/null +++ b/Master/texmf-dist/source/latex/cartonaugh/cartonaugh.ins @@ -0,0 +1,28 @@ +\input docstrip.tex + +\keepsilent + +\usedir{tex/latex/cartonaugh} + +% generate sty file +\generate{ + \file{cartonaugh.sty}{\from{cartonaugh.dtx}{package}} + \usepreamble\empty + \usepostamble\empty + \file{cartonaugh.lua}{\from{cartonaugh.dtx}{luacode}} + } + +\Msg{*********************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the} +\Msg{* following file into a directory searched by TeX:} +\Msg{*} +\Msg{* \space\space cartonaugh.sty} +\Msg{*} +\Msg{* To produce the documentation run the file} +\Msg{* cartonaugh.dtx through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*********************************************************} + +\endbatchfile diff --git a/Master/texmf-dist/tex/latex/cartonaugh/cartonaugh.lua b/Master/texmf-dist/tex/latex/cartonaugh/cartonaugh.lua new file mode 100644 index 00000000000..d0f44debfde --- /dev/null +++ b/Master/texmf-dist/tex/latex/cartonaugh/cartonaugh.lua @@ -0,0 +1,474 @@ +DEBUG_FLAG = 0 + +CARTONAUGH_COLORS = {'red', 'green', 'yellow', 'cyan', 'blue', 'magenta'} +CARTONAUGH_DEFAULT_COLOR = 'cyan' + +cartonaugh_env_settings = {} +used_cells = {} + +-- Function that is used to either print to LaTeX or to the console +-- Used for debugging mode +function localPrint(str) + if DEBUG_FLAG==1 then + print(str) + end + tex.sprint(str) +end + +-- Function that takes a string and splits it be delimiter, then returns it back +-- From https://stackoverflow.com/questions/19262761/lua-need-to-split-at-comma +function split(source, delimiters) + local elements = {} + local pattern = '([^'..delimiters..']+)' + string.gsub(source, pattern, function(value) elements[#elements + 1] = value; end); + return elements +end + +-- Function that converts a decimal number to binary +function decimalToBin(num, numb_bits, return_concat) + if return_concat == nil then return_concat=true end + num = tonumber(num) + numb_bits = tonumber(numb_bits) + local t={} + for b=numb_bits,1,-1 do + rest=math.floor(math.fmod(num,2)) + t[b]=rest + num=(num-rest)/2 + end + if return_concat == true then + return table.concat(t) + else + return t + end +end + +-- Function that converts a decimal number to grey code +function decimalToGreyBin(num, numb_bits) + -- Get the binary array + num = num ~ (num >> 1) + local t = decimalToBin(num, numb_bits, false) + return table.concat(t) +end + +function greyBinToDecimal(num) +-- num = tonumber(num,2) + local mask = num + while mask > 0 do + mask = mask >> 1 + num = num ~ mask + end + return tonumber(num) +end + +-- Function to pad a string by a amount with b string +function padString(str, pad_to, pad_with) + local ret = str + for l=1, (pad_to-string.len(str)) do + ret = pad_with .. ret + end + return ret +end + +function getColor(index) + if index <= 0 then return CARTONAUGH_DEFAULT_COLOR end + if CARTONAUGH_COLORS[index] ~= nil then + return CARTONAUGH_COLORS[index] + else + return CARTONAUGH_DEFAULT_COLOR + end +end + +function customColor(color) + -- Some high number so it's not in the CARTONAUGH_COLORS array + cartonaugh_env_settings.color_index = 100 + CARTONAUGH_DEFAULT_COLOR = color +end + +-- Function to generate a kmap template +function generateKMap(column, row, grid_numb) + local outside_column_bits = 1 + local outside_row_bits = 1 + local outside_grid_numb_bits = 2 + local return_str = '' + if row >= 4 then + outside_row_bits = 2 + end + if column >= 4 then + outside_column_bits = 2 + end + for c=1,column,1 do + for r=1,row,1 do + if r == 0 then + if c == 0 then + -- Do Nothing... + elseif c == (column+1) then + return_str = return_str .. ("\\phantom{" .. decimalToBin(0, outside_column_bits) .. "}") + else + return_str = return_str .. (decimalToGreyBin(c-1, outside_column_bits)) + end + elseif r==(row+1) then + if c==0 then + return_str = return_str .. ("\\phantom{" .. decimalToBin(0, outside_column_bits) .. "}") + end + else + if c == 0 then + return_str = return_str .. (decimalToGreyBin(r-1, outside_row_bits)) + elseif c == (column+1) then + + else + return_str = return_str ..("|(" .. padString((decimalToGreyBin(grid_numb, outside_grid_numb_bits) .. decimalToGreyBin(c-1, outside_column_bits) .. decimalToGreyBin(r-1, outside_row_bits)), 6, 0) .. ")|" .. "\\phantom{0}") + --TODO: Look into why reversing c and r from where they should be makes it work + end + end + + if r == (row) then + return_str = return_str .. ("\\\\") + else + return_str = return_str .. ("\\&") + end + end + end + return return_str +end + +function init_cartonaught_env(numb_cols, numb_row, numb_submaps, is_bw, var12_str, var34_str, var56_str, is_submap_seperated) + -- Change the default texts depending on the number of submaps if not custom name has been given + -- TODO: Get this to actually work + if var12_str == 'X_1X_0' and var34_str == 'X_3X_2' and var56_str == 'X_5X_4' then + if numb_submaps == 1 then + var56_str = 'X_3' + end + if numb_cols == 1 then + var12_str = 'X_0' + end + end + cartonaugh_env_settings = { + cols = numb_cols, + rows = numb_row, + submaps = numb_submaps, + bw = tonumber(is_bw), + var_string = { + v12 = var12_str, + v34 = var34_str, + v56 = var56_str, + }, + color_index = 1, + implicant_settings = { + inner_sep = 0.35, + outer_sep = 0.55, + } + } + used_cells = {} + + if is_submap_seperated == 0 then + is_submap_seperated = false + else + is_submap_seperated = true + end + + draw_pgf_kmap(numb_cols, numb_row, numb_submaps, var12_str, var34_str, var56_str, is_submap_seperated) +end + +function change_implicant_inner_spread(new_amount) + cartonaugh_env_settings.implicant_settings.inner_sep = new_amount +end + +function change_implicant_outer_spread(new_amount) + cartonaugh_env_settings.implicant_settings.outer_sep = new_amount +end + +-- Function to generate the k-maps +-- NOTE: Each variable/cell in the k-map is 1cm. This is so that everything alings with each other just be adding +-- the number of row and column. It's a bit of hack, but for now it will stay this way. Resizing of the matrix +-- will be done with the scale option in the future +function draw_pgf_kmap(column, row, submaps_n, var1, var2, var3, is_submap_seperated) + submaps_n = submaps_n-1 + -- TODO: Transform the following settings variables into arguments + local is_multitable_seperated = is_submap_seperated -- Setting to determine if the graphs are drawn with a sperator line or distanced out + local graph_seperator = 1.5 -- Seperation lenght between kmaps if is_multitable_seperated=false + local kmaplevel_seperator_lenght = 0.1 -- Setting to determine the seperator line's thickness if is_multitable_seperated=true + local line_width = 0.015 -- Set the line thickness of things here + local zero_var_line_lenght = 0.75 -- The lenght of the line at the top-left corner of the kmap where the implacants reside + local column_header_numb_bits = ((column-1) // 2)+1 + local row_header_numb_bits = ((row-1) // 2)+1 + if is_multitable_seperated then graph_seperator = 0 end + for d=0,submaps_n,1 do + -- Find the top-left corner of each grid (seperated by 1 unit) + local grid_x_loc = (d % 2)*(column+graph_seperator) + local grid_y_loc = -(d // 2)*(row+graph_seperator) + -- localPrint(string.format("\\node[above] at (%f,%f) {\\small{%s}};", 0, 0, abimplecant)) + if is_multitable_seperated then + if (d % 2) == 1 then + local add_heigh = 0 + if d >= 2 then add_heigh = kmaplevel_seperator_lenght end + localPrint(string.format("\\fill[black] (%f,%f) rectangle (%f,%f);", grid_x_loc, grid_y_loc, grid_x_loc+kmaplevel_seperator_lenght, grid_y_loc-row-line_width-add_heigh)) + grid_x_loc = grid_x_loc + kmaplevel_seperator_lenght + end + if d >= 2 then + localPrint(string.format("\\fill[black] (%f,%f) rectangle (%f,%f);", grid_x_loc, grid_y_loc, grid_x_loc+column+line_width, grid_y_loc-kmaplevel_seperator_lenght)) + grid_y_loc = grid_y_loc - kmaplevel_seperator_lenght + end + end + -- Print out the top-left line corner with the variables + if (is_multitable_seperated == false) or (d==0) then + localPrint(string.format("\\draw[inner sep=0pt, outer sep=0pt] (%f, %f) -- (%f, %f);", grid_x_loc+line_width, grid_y_loc-line_width, grid_x_loc-zero_var_line_lenght, grid_y_loc+zero_var_line_lenght)) + localPrint(string.format("\\node[left] at (%f,%f) {\\small{%s}};", grid_x_loc-0.3, grid_y_loc+0.3, var2)) + localPrint(string.format("\\node[right] at (%f,%f) {\\small{%s}};", grid_x_loc-0.6, grid_y_loc+0.6, var1)) + end + -- Print out the top boolean column header + if (is_multitable_seperated == false) or (d < 2) then + localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, column sep={1cm,between origins}, nodes={align=center,text width=1cm,inner sep=0pt}, anchor=south west, inner sep=0pt, outer sep=0pt] at (%f, %f) {",grid_x_loc,grid_y_loc+0.05)) + for c=0, column-1, 1 do + localPrint(string.format("%s", decimalToGreyBin(c, column_header_numb_bits))) + if c ~= (column-1) then localPrint("\\&") end + end + localPrint("\\\\};") + end + -- Print out the side boolean row header + if (is_multitable_seperated == false) or (d%2 == 0) then + localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, row sep={1cm,between origins}, nodes={minimum height=1cm,inner sep=0pt, text height=2ex, text depth=0.5ex}, anchor=north east, inner sep=0pt, outer sep=0pt] at (%f, %f) {",grid_x_loc-0.05,grid_y_loc)) + for r=0, row-1, 1 do + localPrint(string.format("%s \\\\", decimalToGreyBin(r, row_header_numb_bits))) + end + localPrint("};") + end + -- Print out the matrix + localPrint(string.format("\\matrix[matrix of nodes, ampersand replacement=\\&, column sep={1cm,between origins}, row sep={1cm,between origins}, nodes={rectangle,draw,minimum height=1cm,align=center,text width=1cm,inner sep=0pt, text height=2ex, text depth=0.5ex, line width=0.015cm}, anchor=north west, inner sep=0pt, outer sep=0pt] at (%f, %f) {%s};", + grid_x_loc, grid_y_loc, generateKMap(row, column, d) + )) + -- Print out the buttom text saying which matrix is which + if (submaps_n > 0) then + if (is_multitable_seperated == false) then + localPrint(string.format("\\node[below] at (%f, %f) {%s = %s};", grid_x_loc+(column//2),grid_y_loc-row,var3, decimalToBin(d, 2))) + elseif (is_multitable_seperated == true) then + if (d < 2) then + localPrint(string.format("\\node[] at (%f, %f) {%s = %s};", grid_x_loc+(column//2), grid_y_loc+1, var3, decimalToBin(d, 2))) + end + if (d % 2 == 0) and (submaps_n > 2) then + localPrint(string.format("\\node[rotate=90] at (%f, %f) {%s = %s};", grid_x_loc-1, grid_y_loc-(row//2), var3, decimalToBin(d, 2))) + end + end + end + end +end + +-- Function for drawing an implicant manually (meaning to give the start and endpoint, as well as optional +-- submaps for different ones) +function manual_draw_implicant(st, en, submaps_str) + local color_index = cartonaugh_env_settings.color_index + local max_submaps = cartonaugh_env_settings.submaps + local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep + st = tonumber(st) + en = tonumber(en) + local submap_arr = split(submaps_str, ',') + -- Check if the implacent selection + for s=1,table.getn(submap_arr),1 do + current_submap = tonumber(submap_arr[s]) + if current_submap < max_submaps then + local draw_str = string.format("($(%s.center)+(-%s,%s)$) rectangle ($(%s.center)+(%s,-%s)$)", decimalToGreyBin(current_submap, 2) .. decimalToBin(st,4), inner_spread, inner_spread, decimalToGreyBin(current_submap, 2) .. decimalToBin(en,4), inner_spread, inner_spread) + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[rounded corners=3pt,fill=%s,fill opacity=0.25,] {%s};", getColor(color_index) , draw_str)) + end + localPrint(string.format("\\draw[rounded corners=3pt,draw opacity=1.0,] {%s};", draw_str)) + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end + cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1 +end + +-- Handler function for drawing edge implacants, figuring out orientation as well +function manual_draw_edge_implicant(corner1, corner2, corner3, corner4, submaps_str) + corner1 = tonumber(corner1) + corner2 = tonumber(corner2) + corner3 = tonumber(corner3) + corner4 = tonumber(corner4) + + if corner1-corner2 > corner1-corner3 then + manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, 'n') + manual_draw_edge_implicant_orientation(corner3, corner4, submaps_str, 's') + else + manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, 'w') + manual_draw_edge_implicant_orientation(corner3, corner4, submaps_str, 'e') + end + + cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1 + +end + +-- Function to draw out a 1 edge implacant given 2 corners, the submaps, and the orientation (n, s, e, or w) +-- TODO: Perhaps find a way to repeat the code between n/s and e/w +-- TODO: For the mirror variable, have that apply to the lua var directly instead of having LaTeX handle it +-- TODO: Maybe add option for squigly lines for the end instead of nothing +-- TODO: Open up the internal inner_spread and outer_spead settings to the user +function manual_draw_edge_implicant_orientation(corner1, corner2, submaps_str, orientation) + local color_index = cartonaugh_env_settings.color_index + local max_submaps = cartonaugh_env_settings.submaps + corner1 = tonumber(corner1) + corner2 = tonumber(corner2) + local submap_arr = split(submaps_str, ',') + local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep + local outer_spead = cartonaugh_env_settings.implicant_settings.outer_sep + -- Check if the implacent selection + for s=1,table.getn(submap_arr),1 do + current_submap = tonumber(submap_arr[s]) + if current_submap < max_submaps then + local draw_string = "" + local mirror = 1 + local corner1_bin = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner1,4) + local corner2_bin = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner2,4) + if orientation == 'n' or orientation == 's' then + -- If the orientation is south, just mirror it + if orientation == 's' then mirror = -1 end + draw_string = string.format("($(%s.center)+(-%f,%f*%s)$)", corner1_bin, inner_spread, outer_spead, mirror) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(-%f,-%f*%s)$)}", corner1_bin, inner_spread, inner_spread, mirror) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f,-%f*%s)$)}", corner2_bin, inner_spread, inner_spread, mirror) + draw_string = draw_string .. string.format("-- ($(%s.center)+(%f,%f*%s)$)", corner2_bin, inner_spread, outer_spead, mirror) + else + if orientation == 'e' then mirror = -1 end + draw_string = string.format("($(%s.center)+(-%f*%s,%f)$)", corner1_bin, outer_spead, mirror, inner_spread) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f*%s,%f)$)}", corner1_bin, inner_spread, mirror, inner_spread) + draw_string = draw_string .. string.format("{[rounded corners=3pt] -- ($(%s.center)+(%f*%s,-%f)$)}", corner2_bin, inner_spread, mirror, inner_spread) + draw_string = draw_string .. string.format("-- ($(%s.center)+(-%f*%s,-%f)$)", corner2_bin, outer_spead, mirror, inner_spread) + end + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[fill=%s,fill opacity=0.25,] {%s};", getColor(color_index), draw_string)) + end + localPrint(string.format("\\draw[draw opacity=1.0] {%s};", draw_string)) + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end +end + +-- Function to draw the corner implicants. Only usable on 4x4 matrices +function manual_draw_corner_implicant(submaps_str) + local corner_arr = {0, 2, 8, 10} + local submap_arr = split(submaps_str, ',') + local max_submaps = cartonaugh_env_settings.submaps + local color = cartonaugh_env_settings.color_index + local inner_spread = cartonaugh_env_settings.implicant_settings.inner_sep + local outer_spread = cartonaugh_env_settings.implicant_settings.outer_sep + + if cartonaugh_env_settings.cols ~= 4 or cartonaugh_env_settings.rows ~= 4 then + localPrint("\\PackageError{cartonaugh}{Cannot use a corner implicant on anything but a 4x4. Sorry!}") + return + end + + for s=1,table.getn(submap_arr),1 do + current_submap = tonumber(submap_arr[s]) + if current_submap < max_submaps then + for c=0,3,1 do + local x_mirror = 1-(2*(c%2)) + local y_mirror = 1-(2*(c//2)) + local corner = decimalToGreyBin(current_submap, 2) .. decimalToBin(corner_arr[c+1],4) + -- Create the string to draw the corners + local draw_string = string.format("($(%s.center)+(-%f*%d,%f*%d)$)--($(%s.center)+(%f*%d,%f*%d)$)", corner, outer_spread, x_mirror, outer_spread, y_mirror, corner, inner_spread, x_mirror, outer_spread, y_mirror) + draw_string = draw_string .. string.format("{ [rounded corners=3pt] --($(%s.center)+(%f*%d,-%f*%d)$) }", corner, inner_spread, x_mirror, inner_spread, y_mirror) + draw_string = draw_string .. string.format("--($(%s.center)+(-%f*%d,-%f*%d)$) -- cycle", corner, outer_spread, x_mirror, inner_spread, y_mirror) + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[fill=%s,fill opacity=0.25,] {%s};", getColor(color), draw_string)) + end + localPrint(string.format("\\draw[sharp corners, draw opacity=1.0] {%s};", draw_string)) + end + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end + + cartonaugh_env_settings.color_index = cartonaugh_env_settings.color_index+1 + +end + +-- WORK IN PROGRESS/LONG TERM FUNCTION +-- Goals is to eventually give \implicant{1}{x}{0}{x} for example and have it draw it out for you. +-- May give up on this in favor of other things...don't know +function draw_implicant(var_list) +-- local var_list_arr = split(var_list, ',') + local color_index = cartonaugh_env_settings.color_index + local max_submaps = cartonaugh_env_settings.submaps + localPrint("\\PackageWarning{cartonaugh}{This is a UNSTABLE and WIP function. Procede on your own}") + + -- Check argument for submaps greater than 1 + -- TODO: before returning print out a package error + if max_submaps > 1 then + for s=0,max_submaps-1,1 do + if var_list[5+s] == '' then + -- TODO: Fix this + localPrint(string.format("\\PackageError{cartonaugh}{Please feed either 1, 0, or x for sub map number %d's variable boolean}", s+1)) + return + end + end + end + + local low_limit = 0 + local high_limit = 0 + + for b=1,4,1 do + if var_list[b] == 'x' then + print('a',high_limit, greyBinToDecimal(high_limit), decimalToBin(greyBinToDecimal(high_limit), 4)) + print('b',high_limit | (1 << (b-1)), greyBinToDecimal(high_limit | (1 << (b-1))), decimalToBin(greyBinToDecimal(high_limit | (1 << (b-1))), 4)) + if greyBinToDecimal(high_limit) < greyBinToDecimal(high_limit | (1 << (b-1))) then + high_limit = high_limit | (1 << (b-1)) + print(decimalToBin(greyBinToDecimal(high_limit),4), decimalToBin(greyBinToDecimal(high_limit & ~(1 << (b-2))),4)) + if greyBinToDecimal(high_limit) < greyBinToDecimal(high_limit & ~(1 << (b-2))) then + high_limit = high_limit & ~(1 << (b-2)) + end + end + elseif var_list[b] == '1' then + high_limit = high_limit | (1 << (b-1)) + low_limit = low_limit | (1 << (b-1)) + end + print('low_limit=', low_limit, 'high_limit=', high_limit) + end + + local st = decimalToBin(low_limit,4) + local en = decimalToBin(high_limit,4) + + print('low_limit', greyBinToDecimal(low_limit), 'high_limit', greyBinToDecimal(high_limit), 'st=', st, 'en=', en) + + for s=1,1,1 do + current_submap = 0 + if current_submap < max_submaps then + if cartonaugh_env_settings.bw == 0 then + localPrint(string.format("\\fill[rounded corners=3pt,fill=%s,fill opacity=0.25,] {($(%s.center)+(-0.3,0.3)$) rectangle ($(%s.center)+(0.3,-0.3)$)};", getColor(color_index) , decimalToGreyBin(current_submap, 2) .. st, decimalToGreyBin(current_submap, 2) .. en)) + color_index = color_index+1 + end + localPrint(string.format("\\draw[rounded corners=3pt,draw opacity=1.0,] {($(%s.center)+(-0.3,0.3)$)rectangle($(%s.center)+(0.3,-0.3)$)};", decimalToGreyBin(current_submap, 2) .. st, decimalToGreyBin(current_submap, 2) .. en)) + else + localPrint(string.format("\\PackageWarning{cartonaugh}{You can only draw on existing sub maps. Ignoring instruction to draw on non existing sub map number %d}", s)) + end + end + cartonaugh_env_settings.color_index = color_index +end + +function autoterms(what_to_write) + local max_cells = cartonaugh_env_settings.submaps * cartonaugh_env_settings.cols * cartonaugh_env_settings.rows + for cell=0,max_cells-1,1 do + if used_cells[cell] == nil then + used_cells[cell] = true + localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write)) + end + end +end + +function manualterms(what_to_write) + local what_to_write_arr = split(what_to_write, ',') + for cell=0,table.getn(what_to_write_arr)-1,1 do + if used_cells[cell] == nil then + used_cells[cell] = true + localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write_arr[cell+1])) + end + end +end + +function write_to_cell(cells, what_to_write) + local cells_arr = split(cells, ',') + for c=1,table.getn(cells_arr),1 do + local cell = tonumber(cells_arr[c]) + if used_cells[cell] == nil then + used_cells[cell] = true + localPrint(string.format("\\path (%s) node {%s};", decimalToBin(cell, 6), what_to_write)) + end + end +end diff --git a/Master/texmf-dist/tex/latex/cartonaugh/cartonaugh.sty b/Master/texmf-dist/tex/latex/cartonaugh/cartonaugh.sty new file mode 100644 index 00000000000..c63cec1d88f --- /dev/null +++ b/Master/texmf-dist/tex/latex/cartonaugh/cartonaugh.sty @@ -0,0 +1,205 @@ +%% +%% This is file `cartonaugh.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% cartonaugh.dtx (with options: `package') +%% +%% IMPORTANT NOTICE: +%% +%% For the copyright see the source file. +%% +%% Any modified versions of this file must be renamed +%% with new filenames distinct from cartonaugh.sty. +%% +%% For distribution of the original source see the terms +%% for copying and modification in the file cartonaugh.dtx. +%% +%% This generated file may be distributed as long as the +%% original source files, as listed above, are part of the +%% same distribution. (The sources need not necessarily be +%% in the same archive or directory.) +%% +%% Copyright (C) 2021 Jamal Bouajjaj | 2015, 2016, 2017 Mattias Jacobsson and contributors +%% This work, cartonaugh, is a fork of Mattias Jacobsson's [karnaugh-map](https://github.com/2pi/karnaugh-map) package with major changes. As the copyright on the base package is under [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/), so is this fork. +%% + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{cartonaugh}[2021/07/15 v1.0 Draw Karnaugh Maps] + +%% +%% Dependencies +%% + +%% Check if ran under LuaLaTeX. If not, exit +\RequirePackage{iftex} +\RequireLuaTeX + +%% parsing arguments +\RequirePackage{xparse} + +%% working with strings +\RequirePackage{xstring} + +%% drawing +\RequirePackage{tikz} +\usetikzlibrary{calc,matrix} + +%% +%% Helpers +%% +\directlua{require("cartonaugh")} + +%% command raises an error if executed outside the cartonaugh environment +\newcommand{\@cartonaugh@func@bailoutsideenvironment@}[0]{% + \ifnum\@cartonaugh@var@isactive@=0 + \PackageError{cartonaugh}{% + Command can not be used outside cartonaugh environment% + }{% + Do not use this command outside the cartonaugh environment.% + } + \fi +} + +\newcommand{\cartonaughSetColorAtIndex}[2]{\directlua{CARTONAUGH_COLORS[\the\numexpr(#1)\relax] = "\luaescapestring{#2}"}} + +%% store whether a kmap has been created +\newcommand{\@cartonaugh@var@isactive@}{0} +\NewDocumentEnvironment{cartonaugh}{s O{4} O{4} O{1} O{$X_1X_0$} O{$X_3X_2$} O{$X_5X_4$} O{0}} {% + \begingroup + % store map size {[START] + \renewcommand{\@cartonaugh@var@isactive@}{1}% + % [END]} + % determinate if markings should be color or black and white + % + % [END]} + % test if a matrix template is found or not(aka "\@cartonaugh@local@matrixtemplate@" equals to '0') + \begin{tikzpicture} + \directlua{init_cartonaught_env( + \the\numexpr(#2)\relax, + \the\numexpr(#3)\relax, + \the\numexpr(#4)\relax, + \the\numexpr(#1)\relax, + "\luaescapestring{\detokenize{#5}}", + "\luaescapestring{\detokenize{#6}}", + "\luaescapestring{\detokenize{#7}}", + \the\numexpr(#8)\relax + )} +}{ + \end{tikzpicture} + \endgroup +} +\DeclareDocumentCommand{\autoterms}{O{-}} {% + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + autoterms("\luaescapestring{\detokenize{#1}}", '-') + } +} +\DeclareDocumentCommand{\indeterminants}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", '-') + } +} +\DeclareDocumentCommand{\manualterms}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manualterms("\luaescapestring{\detokenize{#1}}") + } +} +\DeclareDocumentCommand{\maxterms}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", '0') + } +} +\DeclareDocumentCommand{\minterms}{m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", '1') + } +} +\DeclareDocumentCommand{\terms}{m m} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + write_to_cell("\luaescapestring{\detokenize{#1}}", + "\luaescapestring{\detokenize{#2}}") + } +} +\DeclareDocumentCommand{\implicant}{m m O{0}} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manual_draw_implicant( + "\luaescapestring{\detokenize{#1}}", + "\luaescapestring{\detokenize{#2}}", + "\luaescapestring{\detokenize{#3}}" + ) + } +} +\DeclareDocumentCommand{\implicantedge}{m m m m O{0}} {% + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manual_draw_edge_implicant( + "\luaescapestring{\detokenize{#1}}", + "\luaescapestring{\detokenize{#2}}", + "\luaescapestring{\detokenize{#3}}", + "\luaescapestring{\detokenize{#4}}", + "\luaescapestring{\detokenize{#5}}" + ) + } +} +\DeclareDocumentCommand{\implicantcorner}{O{0}} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + manual_draw_corner_implicant( + "\luaescapestring{\detokenize{#1}}" + ) + } +} +\DeclareDocumentCommand{\implicantspread}{m m} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + change_implicant_inner_spread(\luaescapestring{\detokenize{#1}}) + change_implicant_outer_spread(\luaescapestring{\detokenize{#2}}) + } +} +\DeclareDocumentCommand{\resetimplicantspread}{} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + change_implicant_inner_spread(0.35) + change_implicant_outer_spread(0.55) + } +} +\DeclareDocumentCommand{\changecolor}{m} { + % bail if outside environment cartonaugh + \@cartonaugh@func@bailoutsideenvironment@{} + % + \directlua{ + customColor("\luaescapestring{\detokenize{#1}}") + } +} +\endinput +%% +%% End of file `cartonaugh.sty'. diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 331a8138060..edcd605c1fe 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -153,7 +153,8 @@ my @TLP_working = qw( c90 c-pascal cabin cachepic caladea calcage calctab calculation calculator calligra calligra-type1 callouts calrsfs cals calxxxx-yyyy cancel canoniclayout cantarell - capt-of captcont captdef caption carbohydrates carlisle carlito carolmin-ps + capt-of captcont captdef caption + carbohydrates carlisle carlito carolmin-ps cartonaugh cascade cascadia-code cascadilla cases casyl catchfile catchfilebetweentags catcodes catechis catoptions causets cbcoptic cbfonts cbfonts-fd diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index a85019a43bf..a9e90e7fc46 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -1889,6 +1889,7 @@ $standardtex 'captcont', '\.sty|[^c]\.cfg', # omit ltxdoc.cfg, would be system-wide 'captdef', '^..[^s].*\.sty', # not miscdoc.sty 'carlisle', '\.sty|\.ltx', + 'cartonaugh', '\.lua|' . $standardtex, 'chemfig', '(t-)?chemfig(-lewis)?.tex|' . $standardtex, 'chemformula', '\.sty$', # not chemformula-manual.cls 'chemstyle', '\.jdf|' . $standardtex, diff --git a/Master/tlpkg/tlpsrc/cartonaugh.tlpsrc b/Master/tlpkg/tlpsrc/cartonaugh.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/cartonaugh.tlpsrc diff --git a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc index 6a69de7dfa4..b551069e627 100644 --- a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc @@ -33,6 +33,7 @@ depend bussproofs depend bussproofs-extra depend bytefield depend calculation +depend cartonaugh depend cascade depend causets depend ccfonts |