% ddphonism % % (c) Celia Rubio Madrigal % %% This program can be redistributed and/or modified under the terms %% of the LaTeX Project Public License Distributed from CTAN archives %% in directory macros/latex/base/lppl.txt. \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{ddphonism} [2019/09/01 v0.2 Dodecaphonic diagrams: twelve-tone matrices, clock diagrams, etc.] \RequirePackage{etoolbox} \RequirePackage{xparse} \RequirePackage{tikz} \RequirePackage{xstring} \RequirePackage{pgfkeys} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Matrices \usetikzlibrary{matrix} \ExplSyntaxOn \DeclareExpandableDocumentCommand{\Evaluation}{m}{\int_eval:n {#1}} \ExplSyntaxOff \newcounter{Dsize} \newcommand{\DsizeMake}[1]{% \setcounter{Dsize}{0}% \foreach \n in {#1}{% \stepcounter{Dsize}% }% } % Only with numbers. \newcounter{Dfirst} \newcommand{\DheadMake}[1]{% \setcounter{Dfirst}{-1}% \foreach \n in {#1}{% \ifnum\theDfirst=-1% \setcounter{Dfirst}{\n}% \fi% }% } % Only when DsizeMake is already done. \newcounter{Dmod} \newcommand{\Modulo}[1]{% \setcounter{Dmod}{#1}% \loop% \ifnum\theDmod>\Evaluation{\theDsize-1}% \setcounter{Dmod}{\Evaluation{\theDmod-\theDsize}}% \repeat% \ifnum\theDmod<0% \setcounter{Dmod}{\Evaluation{\theDmod+\theDsize}}% \repeat% \theDmod% } \newif\ifdmatrixLines \newif\ifdmatrixOutside \newif\ifdmatrixInside \newif\ifdmatrixV \newif\ifdmatrixH \newif\ifdmatrixTikz \pgfkeys{ /dmatrix/.is family , /dmatrix , default/.style = { lines = false , outside lines = false , inside lines = false , sep = 1 , vsep = 1 , hsep = 1 , no tikz = false } , no tikz/.is if=dmatrixTikz , lines/.is if=dmatrixLines , outside lines/.is if=dmatrixOutside , inside lines/.is if=dmatrixInside , vlines/.is if=dmatrixV , hlines/.is if=dmatrixH , sep/.estore in=\dmatrixSep , vsep/.estore in=\dmatrixVsep , hsep/.estore in=\dmatrixHsep } \newcommand{\DLOH}{% \draw (0.05*\dmatrixSep*\dmatrixHsep,0) --% (\theDsize*\dmatrixSep*\dmatrixHsep+0.05*\dmatrixSep*\dmatrixHsep,0);% \draw (0.05*\dmatrixSep*\dmatrixHsep,-\theDsize*0.5*\dmatrixSep*\dmatrixVsep) -- % (\theDsize*\dmatrixSep*\dmatrixHsep+0.05*\dmatrixSep*\dmatrixHsep,-\theDsize*0.5*\dmatrixSep*\dmatrixVsep);% } \newcommand{\DLOV}{% \draw (0.05*\dmatrixSep*\dmatrixHsep,0) -- % (0.05*\dmatrixSep*\dmatrixHsep,-\theDsize*0.5*\dmatrixSep*\dmatrixVsep);% \draw (\theDsize*\dmatrixSep*\dmatrixHsep+0.05*\dmatrixSep*\dmatrixHsep,0) -- % (\theDsize*\dmatrixSep*\dmatrixHsep+0.05*\dmatrixSep*\dmatrixHsep,-\theDsize*0.5*\dmatrixSep*\dmatrixVsep); } \newcommand{\DLIH}{% \draw (0.05*\dmatrixSep*\dmatrixHsep,-\xD*0.5*\dmatrixSep*\dmatrixVsep) -- % (\theDsize*\dmatrixSep*\dmatrixHsep+0.05*\dmatrixSep*\dmatrixHsep,-\xD*0.5*\dmatrixSep*\dmatrixVsep);% } \newcommand{\DLIV}{% \draw (\xD*\dmatrixSep*\dmatrixHsep+0.05*\dmatrixSep*\dmatrixHsep,0) -- % (\xD*\dmatrixSep*\dmatrixHsep+0.05*\dmatrixSep*\dmatrixHsep,-\theDsize*0.5*\dmatrixSep*\dmatrixVsep);% } \newcommand{\dmatrix}[2][]{% \DsizeMake{#2}% \DheadMake{#2}% % \pgfkeys{/dmatrix, default, #1}% % \ifdmatrixTikz\else% \begin{tikzpicture}% \fi% \foreach [count=\nj] \j in {#2} {% \foreach [count=\ni] \i in {#2} {% \draw node at ( \ni*\dmatrixSep*\dmatrixHsep-0.5*\dmatrixSep*\dmatrixHsep , -\nj*\dmatrixSep*\dmatrixVsep/2+0.25*\dmatrixSep*\dmatrixVsep) {% \Modulo{\Evaluation{\i-\j+\theDfirst}}% };% }% }% \foreach \xD in {1,...,\Evaluation{\theDsize-1}} {% \ifdmatrixLines \DLOH\DLOV\DLIH\DLIV \fi \ifdmatrixOutside \DLOH\DLOV \fi \ifdmatrixInside \DLIH\DLIV \fi \ifdmatrixH \DLOH\DLIH \fi \ifdmatrixV \DLOV\DLIV \fi }% % \ifdmatrixTikz\else% \end{tikzpicture}% \fi% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Diagrams \usetikzlibrary{shapes,arrows,decorations.markings,shapes.misc} \tikzstyle{ddiagram}=[minimum height=0pt,inner sep=0pt,outer sep=0pt,scale=0.65] \newif\ifddiagramTikz \newif\ifddiagramNoNum \newif\ifddiagramNoArr \pgfkeys{ /ddiagram/.is family , /ddiagram , default/.style = { name =\empty% , up =\empty% , no tikz = false , no numbers = false , no arrow = false , xshift = 0 , yshift = 0 , arrow shift = 2.5 } , no tikz/.is if=ddiagramTikz , no numbers/.is if=ddiagramNoNum , no arrow/.is if=ddiagramNoArr , name/.estore in=\ddiagramName , up/.estore in=\ddiagramUp , xshift/.estore in=\ddiagramX , yshift/.estore in=\ddiagramY , arrow shift/.estore in=\ddiagramArrS } \newcounter{Dprev} \newcommand{\Dvar}{} \newcommand{\ddiagram}[2][]{% \DsizeMake{#2}% \DheadMake{#2}% % \pgfkeys{/ddiagram, default, #1}% % \ifdefequal{\ddiagramUp}{\empty}% {\renewcommand{\Dvar}{\theDfirst}}% if empty {\renewcommand{\Dvar}{\ddiagramUp}}% if not empty % \ifddiagramTikz\else% \begin{tikzpicture}[ddiagram,rotate=360*\Dvar/\theDsize]% \fi% \foreach \x in {0,...,\Evaluation{\theDsize-1}} {% \ifddiagramNoNum\else \node [xshift=\ddiagramX,yshift=\ddiagramY] at (90-360*\x/\theDsize:2) {\x};% \fi \node [xshift=\ddiagramX,yshift=\ddiagramY] (\x) at (90-360*\x/\theDsize:1.6) {};% };% % \setcounter{Dprev}{-1}% \foreach \x in {#2}{% \ifnum \theDprev=\theDfirst% \ifddiagramNoArr \draw [xshift=\ddiagramX,yshift=\ddiagramY] (\theDprev) -- (\x);% \else \draw [xshift=\ddiagramX,yshift=\ddiagramY, decoration= {markings,mark=at position 0.099*\ddiagramArrS with {\arrow[scale=1.25,>=triangle 45]{>}}}, postaction={decorate} ] (\theDprev) -- (\x);% \fi \else \ifnum \theDprev=-1 \else% \draw [xshift=\ddiagramX,yshift=\ddiagramY] (\theDprev) -- (\x);% \fi\fi% \setcounter{Dprev}{\x}% };% \draw [xshift=\ddiagramX,yshift=\ddiagramY] (\theDprev) -- (\theDfirst);% % \ifdefequal{\ddiagramName}{\empty}% {}% if empty {\node [xshift=\ddiagramX,yshift=\ddiagramY] at (0,0) [circle,fill=white] {\ddiagramName};}% if not empty \ifddiagramTikz\else% \end{tikzpicture}% \fi% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Dihedral diagrams \tikzstyle ddihedralArrow=[decoration= {markings,mark=at position 1 with {\arrow[scale=1.5,>=angle 60]{>}}}, postaction={decorate}] \tikzstyle{ddihedral}=[inner sep=0,minimum height=18pt] \newif\ifddihedralTikz \newif\ifddihedralItalics \pgfkeys{ /ddihedral/.is family, /ddihedral, default/.style = { t = 0, c = 0, s = 0, v = 0 , no tikz=false , new t = T, new c = C, new s = S, new v = V , no italics = false }, no tikz/.is if=ddihedralTikz, t/.estore in = \ddihedralT, c/.estore in = \ddihedralC, s/.estore in = \ddihedralS, v/.estore in = \ddihedralV, no italics/.is if=ddihedralItalics, new t/.estore in = \ddihedralNewT, new c/.estore in = \ddihedralNewC, new s/.estore in = \ddihedralNewS, new v/.estore in = \ddihedralNewV, } \newif\ifdarrowsTikz \pgfkeys{ /darrows/.is family, /darrows, default/.style = {no tikz=false}, no tikz/.is if=darrowsTikz, } \newcommand{\darrows}[2][]{% \DsizeMake{#2}% % \pgfkeys{/darrows, default, #1}% % \ifdarrowsTikz\else% \begin{tikzpicture}% \fi% \draw foreach \x in {0,...,\Evaluation{\theDsize-1}} {% (90-360*\x/\theDsize:2.5) node[circle] (\x) {}% };% \foreach \x [count=\y] in {#2} {% \draw [style=ddihedralArrow] (90-360*\Evaluation{\y-1}/\theDsize:1.25) -- (\x);% };% \ifdarrowsTikz\else% \end{tikzpicture}% \fi% } \newcommand\ddihedral[2][]{% \DsizeMake{#2}% % \pgfkeys{/ddihedral, default, #1}% % \ifddihedralTikz\else% \begin{tikzpicture}[ddihedral]% \fi% \draw foreach \x in {0,...,\Evaluation{\theDsize-1}} {% (\Evaluation{(90+\ddihedralT*360/\theDsize)+(2*\ddihedralS-1)*\x*360/\theDsize}:2.5)% node[very thin,circle,draw] (\x) {\x}% };% % \draw foreach \x in {0,...,\Evaluation{\theDsize-1}} {% (\Evaluation{(90-\ddihedralC*360/\theDsize)+(2*\ddihedralV-1)*\x*360/\theDsize}:1.25)% node[very thin,circle,draw] {\x}% };% % \darrows[no tikz]{#2}% % \node at (0,0) [very thin,draw,circle, fill=white] {% {\ifddihedralItalics\else\it\fi% \ifodd\ddihedralV% \ddihedralNewV\else% \ifnum\ddihedralC=0% \ifodd\ddihedralS\else% \ifnum\ddihedralT=0% \ddihedralNewT$^0$% \fi\fi\fi\fi% \ifnum\ddihedralC=0% \else \ddihedralNewC$^{\ddihedralC}$\fi% \ifodd\ddihedralS% \ddihedralNewS\fi% \ifnum\ddihedralT=0% \else \ddihedralNewT$^{\ddihedralT}$\fi}% };% \ifddihedralTikz\else% \end{tikzpicture}% \fi% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Rows \pgfkeys{ /drow/.is family, /drow, default/.style = {sep=\arraycolsep}, sep/.estore in = \drowSep, } \long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} \newcounter{myDDcntr} \newlength{\Dvarr} \newcommand{\drow}[2][]{% \DsizeMake{#2}% % \pgfkeys{/drow, default, #1}% \setlength{\Dvarr}{\arraycolsep} \setlength{\arraycolsep}{\drowSep} % \ifnum\theDsize=0% \ensuremath{\left(\right)}% \else\ifnum\theDsize=1% \ensuremath{% \left(\begin{array}{*{\theDsize}c}% 0\\% #2\\% \end{array}\right)% }% \else% \def\TableDDdata{}% \setcounter{myDDcntr}{0}% \loop% \addto\TableDDdata{\themyDDcntr\stepcounter{myDDcntr} &}% \stepcounter{myDDcntr}% \ifnum\themyDDcntr<\Evaluation{\theDsize-1}% \repeat% \addto\TableDDdata{\themyDDcntr \\}% \setcounter{myDDcntr}{0}% % \ensuremath{% \left(\begin{array}{*{\theDsize}c}% \TableDDdata% \StrSubstitute{#2}{,}{&}\\% \end{array}\right)% }% \fi\fi% \setlength{\arraycolsep}{\Dvarr} } \endinput %% End of file `ddphonism.sty'.