\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{PrimeTeX/packages/Boxout}{2025-09-03}{1.0}{
	Commands for typesetting boxouts.
}

\ProvideLength{\boxoutpadding}[1em]
\ProvideLength{\boxoutrule}[1pt]

\NewTblrEnviron{tblrBoxout}
\SetTblrInner[tblrBoxout]{
	cells		= {boxoutBGColor},
	hborder{1}	= {belowspace=\boxoutpadding},
	hborder{Z}	= {abovespace=\boxoutpadding},
	hlines		= {0pt,boxoutBGColor},
	hline{1,Z}	= {\boxoutrule,boxoutFGColor},
	vborder{1}	= {rightspace=\boxoutpadding},
	vborder{Z}	= {leftspace=\boxoutpadding},
	vlines		= {0pt,boxoutBGColor},
	vline{1,Z}	= {\boxoutrule,boxoutFGColor},
}

\tl_const:Nn \c_Boxout_innerspec_tl {colspec={X[l,h]}}
\bool_const:Nn \c_Boxout_warning_bool {\c_false_bool}

\tl_new:N \l_Boxout_title_tl

\cs_new:Nn \__Boxout_default_format: {
	\justifying
	\setlength{\parindent}{0pt}
	\setlength{\parskip}{\medskipamount}
}

\keys_define:nn {Boxout} {
	innerspec	.tl_set_e:N= \l_Boxout_innerspec_tl,
	innerspec	.initial:e	= {\c_Boxout_innerspec_tl},

	danger		.code:n		= {\int_set:Nn \l_Boxout_severity_int {4}},

	warning		.code:n		= {\int_set:Nn \l_Boxout_severity_int {3}},

	info		.code:n		= {\int_set:Nn \l_Boxout_severity_int {2}},

	tip			.code:n		= {\int_set:Nn \l_Boxout_severity_int {1}},

	severity	.int_set:N	= {\l_Boxout_severity_int},
	severity	.initial:n	= {0},

	format		.cs_set:Np	= \__Boxout_format:,
	format		.initial:n	= {},
}

\NewDocumentEnvironment{Boxout}{
	% #1: Key-value options.
	O{}
	% #2: Label.
	>{\TrimSpaces}m
	% #3: Caption.
	O{}
	% #4: Body.
	+b
}{ \group_begin:
	\keys_set:nn{Boxout}{#1}
	\int_case:nn \l_Boxout_severity_int {
		{1} {
			\colorlet{boxoutBGColor}{tipBGColor}
			\colorlet{boxoutFGColor}{tipFGColor}
		}
		{2} {
			\colorlet{boxoutBGColor}{infoBGColor}
			\colorlet{boxoutFGColor}{infoFGColor}
		}
		{3} {
			\colorlet{boxoutBGColor}{warningBGColor}
			\colorlet{boxoutFGColor}{warningFGColor}
		}
		{4} {
			\colorlet{boxoutBGColor}{dangerBGColor}
			\colorlet{boxoutFGColor}{dangerFGColor}
		}
	}
	\color{textColor}
	\label{box:#2}
	\tl_if_empty:nTF {#3} {
		% No header
		\expanded{\noexpand\begin{tblrBoxout}{\l_Boxout_innerspec_tl}}
			\__Boxout_default_format:\__Boxout_format:\ignorespaces#4\\
		\end{tblrBoxout}
	}{
		% Yes header
		\expanded{\noexpand\begin{tblrBoxout}{\l_Boxout_innerspec_tl}}
			\SetCell{halign=c, font={\sbfamily\bfseries}}{#3}\\
			\__Boxout_default_format:\__Boxout_format:\ignorespaces#4\\
		\end{tblrBoxout}
	}
\group_end: }{}

\keys_define:nn{}{
	BigBoxout	.inherit:n	= {BigFloat, Boxout},
}

\NewDocumentEnvironment{BigBoxout}{
	s
	% #2: Key-value options.
	O{}
	% #3: Label, passed to Boxout argument #1.
	>{\TrimSpaces}m
	% #4: Caption, passed to Boxout argument #3.
	O{}
	% #5: Body, passed to Boxout.
	+b
}{ \group_begin:
	\keys_set:nn{BigBoxout}{#2}
	\bool_if:nT {#1} {\dim_set:Nn \l_BigFloat_overhang_dim {0pt}}
	\begin{BigFloat}[
		type		= generic,
		overhang	= \l_BigFloat_overhang_dim,
		placement:V	= \l_Float_placement_clist,
		offset		= \l_BigFloat_offset_fp,
	]
		\begin{Boxout}[
			innerspec:V	= \l_Boxout_innerspec_tl,
			severity:V	= \l_Boxout_severity_int,
		]{#3}[#4]
			#5
		\end{Boxout}
	\end{BigFloat}
\group_end: }{}

\str_const:Nn \c_MarginBoxout_position_str {auto}
\dim_const:Nn \c_MarginBoxout_width_dim {\marginparwidth}

\keys_define:nn{}{
	MarginBoxout	.inherit:n	= Boxout,
}

\keys_define:nn{MarginBoxout}{
	position	.choices:nn	= {auto,reverse,left,right,nearest}{
		\str_set:Ne \l_MarginBoxout_position_str {\l_keys_choice_tl}
	},
	position	.initial:e	= {\c_MarginBoxout_position_str},

	width		.dim_set:N	= \l_MarginBoxout_width_dim,
	width		.initial:e	= {\c_MarginBoxout_width_dim},
}

\NewDocumentCommand{\MarginBoxout}{
	% #1: Key-value options.
	O{}
	% #2: Label.
	>{\TrimSpaces}m
	% #3: Caption
	O{}
	% #4: Content.
	+m
}{ \group_begin:
	\keys_set:nn {MarginBoxout} {#1}
	\marginalia[
		width	= \l_MarginBoxout_width_dim,
	]{
		\begin{Boxout}[
			innerspec:V	= \l_Boxout_innerspec_tl,
			severity:V	= \l_Boxout_severity_int,
			format		= {\RaggedOutside},
		]{#2}[#3]
			#4
		\end{Boxout}
	}
\group_end: }

\dim_const:Nn \c_WrapBoxout_width_dim {3in}
\dim_const:Nn \c_WrapBoxout_justifywidth_dim {18em}

\str_new:N \l_WrapBoxout_passed_keys_str

\keys_define:nn{}{
	WrapBoxout	.inherit:n	= {WrapFig, Boxout},
}
\keys_define:nn{WrapBoxout}{
	justifywidth.dim_set:N	= \l_WrapBoxout_justifywidth_dim,
	justifywidth.initial:e	= {\c_WrapBoxout_justifywidth_dim},

	width		.dim_set:N	= \l_WrapBoxout_width_dim,
	width		.initial:e	= {\c_WrapBoxout_width_dim},

	unknown.code:n		= {
		\str_put_right:Ne \l_WrapBoxout_passed_keys_str {\l_keys_key_str=\l_keys_value_tl,}
	}
}

\cs_new:Npn \__WrapBoxout_format: {}

\NewDocumentEnvironment{WrapBoxout}{
	% #1: Key-value options.
	O{}
	% #2: Label.
	>{\TrimSpaces}m
	% #3: Caption
	O{}
	% #4: Body.
	+b
}{ \group_begin:
	\keys_set:nn{WrapBoxout}{#1}
	\__WrapFig_process_options:
	\message{WrapBoxout:~\l_WrapFig_passed_keys_str}
	\dim_compare:nNnTF {\l_WrapBoxout_width_dim} > {\l_WrapBoxout_justifywidth_dim} {
		\cs_set:Nn \__WrapBoxout_format: {\justifying}
	} {
		\cs_set:Nn \__WrapBoxout_format: {\l_WrapFig_format_tl}
	}
	\expanded{\noexpand\begin{wrapstuff}[
		\l_WrapFig_placement_str,
		hoffset	= {\dim_use:N \l_WrapFig_hoffset_dim},
		\l_WrapBoxout_passed_keys_str,
	]}
		\begin{Boxout}[
			innerspec:e	= {
				\l_Boxout_innerspec_tl,
				columns={\dim_use:N \l_WrapBoxout_width_dim}
			},
			severity:V	= \l_Boxout_severity_int,
			format		= \__WrapBoxout_format:,
		]{#2}[#3]
			#4
		\end{Boxout}
	\end{wrapstuff}
\group_end: }{}