\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{argumentation}[2026/06/20 Argumentation] % Author: Lars Bengel % E-Mail: lars.bengel@fernuni-hagen.de % Version: 1.7 % Date: 2026/06/20 % License: LaTeX Project Public License 1.3c %%%%%%%%%%% Package Requirements %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{amsbsy,amsmath} % Proper bold letters in math mode \RequirePackage{pgfopts} % Managing package options \RequirePackage{xspace} % Dynamic spaces after math commands \RequirePackage{xcolor} % Defining colors \RequirePackage{tikz} % Drawing the argumentation frameworks \usetikzlibrary{positioning} % Relative node positioning \usetikzlibrary{arrows.meta} % Directed edges / attack arrows \usetikzlibrary{arrows} % Directed edges / attack arrows \usetikzlibrary{decorations.markings} % Creating the support edge markings \usetikzlibrary{calc} % Coordinate arithmetic for setattack %%%%%%%%%%% Package Style Definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Color definitions \definecolor{aigyellow}{RGB}{210,149,81} % Highlight color \definecolor{aigblue}{RGB}{0,76,151} % Node color %%% Argument Style Definitions \tikzset{ argument size/.style={}, % Size of argument nodes argument/.style={}, % Base style for argument nodes argument standard/.style={circle,draw=black,inner sep=0,outer sep=0}, % Standard argument style argument large/.style={circle,draw=black,inner sep=0,outer sep=0, font=\large}, % Large argument style argument thick/.style={circle,draw=black,inner sep=0,outer sep=0, line width=0.1em}, % Thick outline argument style argument gray/.style={argument thick,fill=gray!30,draw=gray!65,text=black!80}, % Gray argument style argument colored/.style={argument thick,fill=aigblue!40,draw=aigblue!80}, % Colored argument style } %%% Attack/Support Edge Definitions \tikzset{ attack width/.style={}, % Width of attack arrows attack/.style={}, % Base style for attack arrow attack standard/.style={-{stealth'}}, % Standard attack arrow attack large/.style={-{Stealth[scale=1.25]}}, % Larger arrow tip attack modern/.style={-{To[sharp,length=0.65ex,line width=0.05em]}}, % Modern rightarrow style tip support/.style={}, % Base style for support support marked/.style = {attack, postaction = {decorate,decoration={markings,mark=at position 0.36 with {\draw[-] (0,-0.1) -- (0.1,0.1);}}}}, % Marked support arrow support dashed/.style={attack,densely dashed}, % Dashed Support arrow support double/.style={-{Classical TikZ Rightarrow},double}, % double-line support arrow } %%% Additional Style Parameters \tikzset{ selfattack/.style={loop,min distance=0.4em,in=0,out=60,looseness=4.5}, % Self-attack inactive/.style={fill=none,draw=gray!50,text=gray!60}, % Inactive argument or edge (reduct) incomplete/.style={densely dashed}, % incomplete argument or edge accepted/.style={fill=green!40}, % Accepted argument (in) rejected/.style={fill=red!40}, % Rejected argument (out) undecided/.style={fill=cyan!40}, % Undecided Argument (undec) highlight/.style={fill=aigyellow!60}, % Highlighted argument caption/.style={draw=none}, % Caption or text invisible/.style={draw=none,fill=none,opacity=0.0}, % Invisible argument or edge annotation/.style={font=\scriptsize,node distance=4ex}, % Argument annotation argin/.style={accepted}, argout/.style={rejected}, argundec/.style={undecided}, } %%% Style-Options for af environment \pgfkeys{/tikz/.cd, af/.style={}, % Base style for af standard/.style={node distance=6.6ex,argument size/.style={minimum size=4.5ex},attack width/.style={line width=0.05em}}, % Standard size style for af small/.style={node distance=3.5ex,argument size/.style={minimum size=3.4ex},attack width/.style={line width=0.045em},caption/.append style={font=\small}}, % Small size style for af tiny/.style={node distance=2.3ex,argument size/.style={minimum size=2.6ex,font=\small},attack width/.style={line width=0.03em},caption/.append style={font=\small}}, % Tiny size style for af } %%% Option for switching beamer cover type in af \makeatletter \newif\if@afoverlay \pgfkeys{/tikz/.cd, covered/.is choice, covered/transparent/.code={\@afoverlaytrue}, covered/invisible/.code={\@afoverlayfalse}, covered/.default=transparent, covered=transparent, } \makeatother %%%%%%%%%% Internal Utility Functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \makeatletter \newif\ifmacros \newif\if@numericidx \newif\if@alphaidx \newif\if@insideaf %%% Defines the font style in which argument names are displayed \newcommand{\@arg@style}[1]{#1} % Dummy command in case the beamer documentclass is not loaded \ProvideDocumentCommand{ \alt } {r<> m m} {#2} \makeatother %%%%%%%%%% Package Options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Options for style of the argument node itself \pgfkeys{/argumentation/.cd, .unknown/.code={}, argumentstyle/.is choice, argumentstyle/standard/.code={\tikzset{argument/.style={argument standard,argument size}}}, argumentstyle/large/.code={\tikzset{argument/.style={argument large,argument size}}}, argumentstyle/thick/.code={\tikzset{argument/.style={argument thick,argument size}}}, argumentstyle/gray/.code={\tikzset{argument/.style={argument gray,argument size}}}, argumentstyle/colored/.code={\tikzset{argument/.style={argument colored,argument size}}}, argumentstyle=standard, } %%% Options for the style of the attack edges \pgfkeys{/argumentation/.cd, attackstyle/.is choice, attackstyle/standard/.code={\tikzset{attack/.style={attack width,attack standard}}}, attackstyle/large/.code={\tikzset{attack/.style={attack width,attack large}}}, attackstyle/modern/.code={\tikzset{attack/.style={attack width,attack modern}}}, attackstyle=standard, } %%% Option for hyperedge junction placement: minimum clearance beyond target node border \pgfkeys{/argumentation/.cd, junction dist/.initial=1ex, } %%% Options for the style of the support edges \pgfkeys{/argumentation/.cd, supportstyle/.is choice, supportstyle/marked/.code={\tikzset{support/.style={support marked}}}, supportstyle/dashed/.code={\tikzset{support/.style={support dashed}}}, supportstyle/double/.code={\tikzset{support/.style={support double}}}, supportstyle=double, } %%% Options for the automatic text formatting for the argument names \makeatletter \pgfkeys{/argumentation/.cd, namestyle/.is choice, namestyle/none/.code={\renewcommand{\@arg@style}[1]{##1}}, namestyle/math/.code={\renewcommand{\@arg@style}[1]{\ensuremath{##1}}}, namestyle/bold/.code={\renewcommand{\@arg@style}[1]{\ensuremath{\boldsymbol{##1}}}}, namestyle/monospace/.code={\renewcommand{\@arg@style}[1]{{\ttfamily##1}}}, namestyle/monoemph/.code={\renewcommand{\@arg@style}[1]{{\ttfamily\itshape##1}}}, namestyle=none, } %%% Option for automatic indexing of arguments \pgfkeys{/argumentation/.cd, indexing/.is choice, indexing/numeric/.code={\@numericidxtrue}, indexing/alphabetic/.code={\@alphaidxtrue}, indexing/none/.code={\@numericidxfalse\@alphaidxfalse}, indexing/.default=numeric, indexing=numeric, } \makeatother %%% Forward argumentation-specific keys from /tikz namespace to /argumentation \pgfkeys{/tikz/.cd, argumentstyle/.code={\pgfkeys{/argumentation/.cd,argumentstyle=#1}}, attackstyle/.code={\pgfkeys{/argumentation/.cd,attackstyle=#1}}, supportstyle/.code={\pgfkeys{/argumentation/.cd,supportstyle=#1}}, namestyle/.code={\pgfkeys{/argumentation/.cd,namestyle=#1}}, junction dist/.code={\pgfkeys{/argumentation/.cd,junction dist=#1}}, } %%% Option for enabling additional macros \pgfkeys{/argumentation/.cd, macros/.is choice, macros/true/.code={\macrostrue}, macros/false/.code={\macrosfalse}, macros/.default=true, macros=false, } \ProcessPgfPackageOptions{/argumentation} %%%%%%%%%%%%%%% Arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \makeatletter % Internal counter for argument IDs \newcounter{@argument} %%% Command for creating arguments % #1 beamer overlay specification (optional) % #2 TikZ parameters (optional) % #3 unique argument ID (optional) % #4 argument display name % #5 ignored % #6 absolute positioning values (optional) \NewDocumentCommand { \argument } {D<>{.-} O{} d() m dat d()} {% \stepcounter{@argument} \IfNoValueTF {#3}{% \if@alphaidx \edef\@argid{\alph{@argument}} \else\if@numericidx \edef\@argid{a\arabic{@argument}} \else \PackageError{argumentation}{Missing argument ID}{Must either provide argument ID inside () or activate auto-indexing} \fi\fi }{% \edef\@argid{#3} } \@create@argument{#1}{#2}{}{\@argid}{#4}{#6} } %%% Auxiliary command for creating arguments % #1 beamer overlay specification (optional) % #2 TikZ parameters (optional) % #3 TikZ parameters (optional) % #4 unique argument ID (optional) % #5 argument display name % #6 absolute positioning value (optional) \NewDocumentCommand { \@create@argument } {mmmmmm} {% \alt<#1>{ \IfNoValueTF {#6}{% \node[argument size,argument,#2,#3](#4) {\@arg@style{#5}}; }{% \node[argument size,argument,#2,#3](#4) at (#6) {\@arg@style{#5}}; } }{% \if@afoverlay \IfNoValueTF {#6}{% \node[argument size,argument,inactive,#2,#3](#4) {\@arg@style{#5}}; }{% \node[argument size,argument,inactive,#2,#3](#4) at (#6) {\@arg@style{#5}}; } \else \IfNoValueTF {#6}{% \node[argument size,argument,invisible,#2,#3](#4) {\@arg@style{#5}}; }{% \node[argument size,argument,invisible,#2,#3](#4) at (#6) {\@arg@style{#5}}; } \fi } } \makeatother %%%%%%%%%%%%%%% Attacks & Support %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \makeatletter %%% Command for creating attacks % #1 beamer overlay specification (optional) % #2 TikZ parameters (optional) % #3 attacking argument ID % #4 attacked argument ID % #5 annotation text (optional) \NewDocumentCommand { \attack } {D<>{.-} O{} m m d()} {% \@create@attack{#1}{#2}{}{#3}{#4}{#5} } %%% Internal command for creating the attack in TikZ % #1 beamer overlay specification (optional) % #2 TikZ parameters (optional) % #3 TikZ parameters (optional) % #4 attacking argument ID % #5 attacked argument ID % #6 annotation text \NewDocumentCommand { \@create@attack } {mmmmmm} {% \alt<#1>{ \IfNoValueTF{#6}{% \path(#4) edge [attack,#2,#3] (#5); }{% \path(#4) edge [attack,#2,#3] node[annotation](p_#4_#5){#6} (#5); } }{% \if@afoverlay \IfNoValueTF{#6}{% \path(#4) edge [attack,inactive,#2,#3] (#5); }{% \path(#4) edge [attack,inactive,#2,#3] node[annotation](p_#4_#5){#6} (#5); } \else \IfNoValueTF{#6}{% \path(#4) edge [attack,invisible,#2,#3] (#5); }{% \path(#4) edge [attack,invisible,#2,#3] node[annotation](p_#4_#5){#6} (#5); } \fi } } %%% Self-attack edge % #1 TikZ parameters (optional) % #2 argument ID \NewDocumentCommand { \selfattack } {D<>{.-} O{} m} {% \attack<#1>[selfattack,#2]{#3}{#3} } %%% Symmetric attack edges between two arguments % #1 TikZ parameters (optional) % #2 first argument ID % #3 second argument ID \NewDocumentCommand { \dualattack } {D<>{.-} O{} m m} {% \attack<#1>[bend right,#2]{#3}{#4} \attack<#1>[bend right,#2]{#4}{#3} } %%% Hyperedge attack from a set of arguments to one argument % #1 beamer overlay specification (optional) % #2 TikZ parameters (optional) % #3 comma-separated list of attacking argument IDs % #4 attacked argument ID % #5 annotation text (optional) \NewDocumentCommand { \setattack } {D<>{.-} O{} m m d()} {% \@create@sehyperedge{#1}{#2}{}{#3}{#4}{#5}{attack}% } %%% Create attack edge with value (DEPRECATED as of v1.4) % #1 TikZ parameters (optional) % #2 attacking argument ID % #3 attacked argument ID % #4 annotation text \NewDocumentCommand{ \annotatedattack } {D<>{.-} O{} m m m} {% \attack<#1>[#2]{#3}{#4}(#5) } %%% Support edge % #1 overlay specification (optional) % #2 TikZ parameters (optional) % #3 supporting argument ID % #4 supported argument ID % #5 annotation text (optional) \NewDocumentCommand { \support } {D<>{.-} O{} m m d()} {% \alt<#1>{% \IfNoValueTF{#5}{% \path(#3) edge [support=0.35,#2] (#4); }{% \path(#3) edge [support=0.35,#2] node[annotation](p_#3_#4){#5} (#4); } }{% \if@afoverlay \IfNoValueTF{#5}{% \path(#3) edge [support=0.35,inactive,#2] (#4); }{% \path(#3) edge [support=0.35,inactive,#2] node[annotation](p_#3_#4){#5} (#4); } \else \IfNoValueTF{#5}{% \path(#3) edge [support=0.35,invisible,#2] (#4); }{% \path(#3) edge [support=0.35,invisible,#2] node[annotation](p_#3_#4){#5} (#4); } \fi } } %%% Hyperedge support from a set of arguments to one argument % #1 beamer overlay specification (optional) % #2 TikZ parameters (optional) % #3 comma-separated list of supporting argument IDs % #4 supported argument ID % #5 annotation text (optional) \NewDocumentCommand { \setsupport } {D<>{.-} O{} m m d()} {% \@create@sehyperedge{#1}{#2}{}{#3}{#4}{#5}{support=0.35}% } %%% Shared internal command for set-attack and set-support % #1 beamer overlay specification % #2 TikZ parameters (optional) % #3 TikZ parameters (optional) % #4 comma-separated list of source argument IDs % #5 target argument ID % #6 annotation text % #7 junction-to-target edge style (attack / support=0.35) \newcounter{@sehyperedge@count} \newif\if@sehyperedge@first \NewDocumentCommand { \@create@sehyperedge } {mmmmmmm} {% \stepcounter{@sehyperedge@count}% \edef\@shcent{sehyperedge@cent@\the@sehyperedge@count}% \edef\@shjunc{sehyperedge@junc@\the@sehyperedge@count}% \edef\@shann{sehyperedge@ann@\the@sehyperedge@count}% % Build "node=1,node=1,..." string for barycentric cs from source clist \global\let\@sehyperedge@bary\@empty \@sehyperedge@firsttrue \@for\@she@item:=#4\do{% \if@sehyperedge@first \@sehyperedge@firstfalse \xdef\@sehyperedge@bary{\@she@item=1}% \else \xdef\@sehyperedge@bary{\@sehyperedge@bary,\@she@item=1}% \fi }% \edef\@shcmd{\noexpand\coordinate(\@shcent) at (barycentric cs:\@sehyperedge@bary);}% \alt<#1>{% \@@draw@sehyperedge{}{#2}{#3}{#4}{#5}{#6}{#7}% }{% \if@afoverlay \@@draw@sehyperedge{inactive}{#2}{#3}{#4}{#5}{#6}{#7}% \else \@@draw@sehyperedge{invisible}{#2}{#3}{#4}{#5}{#6}{#7}% \fi }% } %%% Shared internal drawing helper for set-attack and set-support % #1 style modifier (empty / inactive / invisible) % #2 TikZ parameters % #3 TikZ parameters % #4 source IDs (comma-separated) % #5 target ID % #6 annotation text % #7 junction-to-target edge style \NewDocumentCommand { \@@draw@sehyperedge } {mmmmmmm} {% \begingroup \pgfkeys{/tikz/.cd,#2,#3}% \@shcmd \path let \p{@c} = (\@shcent), \p{@t} = (#5.center), \p{@te} = (#5.east), \n{@d} = {veclen(\x{@t}-\x{@c}, \y{@t}-\y{@c})}, \n{@r} = {\x{@te} - \x{@t}}, \n{@jd} = {max(0.25*\n{@d}, \n{@r} + \pgfkeysvalueof{/argumentation/junction dist})} in ($(#5.center)!\n{@jd}!(\@shcent)$) node[coordinate](\@shjunc){};% \edef\@shtgt{#5}% \foreach \@she@src in {#4} {% \ifx\@she@src\@shtgt % Source = target: detour arc bowing 45° off the junction direction \draw[attack width,#7,-,#1,#2,#3] let \p{src} = (\@she@src), \p{src_e} = (\@she@src.east), \p{jnc} = (\@shjunc), \n{r} = {\x{src_e} - \x{src}}, \n{ja} = {atan2(\y{jnc}-\y{src}, \x{jnc}-\x{src})}, \n{sbx} = {\x{src} + \n{r}*cos(\n{ja}+45)}, \n{sby} = {\y{src} + \n{r}*sin(\n{ja}+45)}, \n{cp1x} = {\n{sbx} + 1.25*\n{r}*cos(\n{ja}+45)}, \n{cp1y} = {\n{sby} + 1.25*\n{r}*sin(\n{ja}+45)}, \n{cp2x} = {\x{jnc} + \n{r}*cos(\n{ja})}, \n{cp2y} = {\y{jnc} + \n{r}*sin(\n{ja})} in (\n{sbx}, \n{sby}) .. controls (\n{cp1x}, \n{cp1y}) and (\n{cp2x}, \n{cp2y}) .. (\@shjunc);% \else \draw[attack width,#7,-,#1,#2,#3] let \p{src} = (\@she@src), \p{src_e} = (\@she@src.east), \p{jnc} = (\@shjunc), \p{tgt} = (#5), \n{r} = {\x{src_e} - \x{src}}, \n{dx} = {\x{jnc} - \x{src}}, \n{dy} = {\y{jnc} - \y{src}}, \n{h} = {veclen(\n{dx}, \n{dy})}, \n{ux} = {\n{dx} / \n{h}}, \n{uy} = {\n{dy} / \n{h}}, \n{bx} = {\x{src} + \n{r} * \n{ux}}, \n{by} = {\y{src} + \n{r} * \n{uy}}, \n{cp1x} = {\n{bx} + \n{h}/3 * \n{ux}}, \n{cp1y} = {\n{by} + \n{h}/3 * \n{uy}}, \n{j2tx} = {\x{tgt} - \x{jnc}}, \n{j2ty} = {\y{tgt} - \y{jnc}}, \n{j2td} = {veclen(\n{j2tx}, \n{j2ty})}, \n{j2tux} = {\n{j2tx} / \n{j2td}}, \n{j2tuy} = {\n{j2ty} / \n{j2td}}, \n{cp2x} = {\x{jnc} - 0.35 * \n{h} * \n{j2tux}}, \n{cp2y} = {\y{jnc} - 0.35 * \n{h} * \n{j2tuy}} in (\n{bx}, \n{by}) .. controls (\n{cp1x}, \n{cp1y}) and (\n{cp2x}, \n{cp2y}) .. (\@shjunc);% \fi }% \IfNoValueTF{#6}{% \path(\@shjunc) edge[#7,#1,#2,#3] (#5);% }{% \path(\@shjunc) edge[#7,#1,#2,#3] node[annotation](\@shann){#6} (#5);% }% \endgroup } \makeatother %%%%%%%%%%%%%%% AF Environment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Uncounted version of the environment \makeatletter \NewDocumentEnvironment {af*} {O{}} {% \setcounter{@argument}{0} \pgfkeys{/argumentation/.cd, #1} \tikzpicture[standard,af,#1] }{% \endtikzpicture } \NewDocumentCommand{\newafenvironment}{mm}{ \newcounter{#1} \NewDocumentEnvironment{#1}{O{}}{ \refstepcounter{#1} \@insideaftrue \begin{af*}[##1] }{ \end{af*} \@insideaffalse } \ifmacros \@ifpackageloaded{hyperref}{ \global\expandafter\def\csname #1ref\endcsname##1{\ensuremath{\hyperref[##1]{#2_{\ref*{##1}}}}\xspace} }{ \global\expandafter\def\csname #1ref\endcsname##1{\ensuremath{#2_{\ref{##1}}}\xspace} } \fi } \newafenvironment{af}{\AF} \makeatother %%%%%%%%%%%%%%%% Additional Commands %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Definitions for referencing \ifmacros \providecommand{\AF}{\ensuremath{F}\xspace} % AF abbreviation \providecommand{\arguments}{\ensuremath{A}\xspace} % Set of arguments \providecommand{\attacks}{\ensuremath{R}\xspace} % Set of attacks \providecommand{\AFcomplete}{\ensuremath{\AF = (\arguments, \attacks)}\xspace} % Full AF \newcommand{\fullafref}[1]{\ensuremath{\afref{#1} = (\arguments_{\ref*{#1}}, \attacks_{\ref*{#1}})}\xspace} % Full AF with reference \fi %%% Creates a node displaying the name of the AF % #1 overlay specification (optional) % #2 TikZ-parameters (optional) % #3 node identifier (optional) % #4 node name % #5 ignored % #6 node position \NewDocumentCommand { \afname } { D<>{.-} O{} D(){caption} m dat d()} {% \alt<#1>{ \IfNoValueTF {#6}{% \node[caption,#2](#3){#4}; }{% \node[caption,#2](#3) at (#6) {#4}; } }{% \IfNoValueTF {#6}{% \node[caption,invisible,#2](#3){#4}; }{% \node[caption,invisible,#2](#3) at (#6) {#4}; } } } %%% Create a text annotation next to another node \NewDocumentCommand { \annotation } {D<>{.-} O{} m m} {% \alt<#1>{% \node[annotation,above of=#3,#2](an_#3){#4}; }{% \node[annotation,above of=#3,invisible,#2](an_#3){#4}; } } %%% Commands for setting custom tikz-style parameters \newcommand{\setafstyle}[1]{\tikzset{af/.style={#1}}} \newcommand{\setargumentcolorscheme}[2]{\tikzset{argument colored/.style={argument thick,fill=#2,draw=#1}}} \newcommand{\setargumentstyle}[1]{\tikzset{argument/.style={argument size,#1}}} \newcommand{\setattackstyle}[1]{\tikzset{attack/.style={attack width,#1}}} \newcommand{\setsupportstyle}[1]{\tikzset{support/.style={#1}}} \newcommand{\setannotationstyle}[1]{\tikzset{annotation/.style={#1}}}