%%
%% This style can be used with memoir or oblivoir class.
%%
\ProvidesExplPackage{srcandtext}
	{2025/07/20}
	{v0.9.6}
	{source and text class}

%\RequirePackage{xparse}
\RequirePackage{l3keys2e}
\RequirePackage{etoolbox}
\RequirePackage{xcolor}

\AtEndPreamble{
	\@ifpackageloaded{hyperref}{}{\RequirePackage{hyperref}}
}

\keys_define:nn { srcandtextstyle }
{
	tcolorbox	.bool_set:N = \opt_tcolorbox_bool,
	listings	.bool_set_inverse:N = \opt_tcolorbox_bool,
	expl	.bool_set:N = \opt_expl_bool,
	bvlskip	.tl_set:N = \opt_bvlskip_tl,
	exampleenv	.tl_set:N = \opt_exampleenv_tl,
	framecolor	.tl_set:N = \sntcolframecolor,
	backcolor	.tl_set:N = \sntcolbackcolor,
	private	.bool_set:N = \opt_private_bool,
	other	.tl_set:N = \opt_other_tl,
	righthand	.dim_set:N = \opt_righthand_dim,
	shortverb	.bool_set:N = \opt_shortverb_bool,
}

\keys_set:nn { srcandtextstyle }
{
	tcolorbox = true,
	expl = false,
	bvlskip = 1.2,
	exampleenv = exampleonly,
	framecolor = cyan,
	backcolor = cyan!10,
	private	= false,
	righthand = 0.35\textwidth,
	shortverb = true,
}

\ProcessKeysOptions { srcandtextstyle }

\bool_if:NT \opt_private_bool { \bool_set_true:N \opt_tcolorbox_bool }

\msg_new:nnn { srcandtext } { sntsavestar } 
{ The~starred~version~of~`sntsave'~ is~allowd~only~in~preamble. }

%%% if memoir.cls is not loaded
\bool_new:N \opt_memoir_bool
\dim_new:N \opt_baseline_dim
\@ifclassloaded{memoir}{
	\bool_gset_true:N \opt_memoir_bool
	\dim_set_eq:NN \opt_baseline_dim \onelineskip
}{
	\bool_gset_false:N \opt_memoir_bool
	\dim_set_eq:NN \opt_baseline_dim \baselineskip
}

\bool_if:NF \opt_memoir_bool
{
	\RequirePackage{sntmemstrmfuncs}
}

\skip_new:N \g_preexample_skip
\skip_set:Nn \g_preexample_skip { 
	\dim_eval:n { -\opt_baseline_dim + .67\opt_baseline_dim }
	plus 3pt
	minus 1pt
}

\RequirePackage{tcolorbox}
%\newcommand*\sntcolframecolor{cyan}
%\newcommand*\sntcolbackcolor{cyan!10}

\bool_if:NTF \opt_tcolorbox_bool
{
%	\RequirePackage { tcolorbox }
	\tcbuselibrary{minted,breakable}
	\tcbset{
		listing~engine=minted,
		colframe=\sntcolframecolor,
		colback=\sntcolbackcolor,
		minted~options={tabsize=4,fontsize=\normalsize,breaklines},
		\opt_other_tl
	}
	
	\NewDocumentEnvironment { exampleonly } {}
    {
        \par
        \vspace { \g_preexample_skip }
        \renewcommand\baselinestretch{ \opt_bvlskip_tl }
        \tcblisting {listing~only,breakable,after={\allowbreak\normalcolor}}
    }{
        \endtcblisting
        \relax
    }

    \NewDocumentEnvironment {exampleside} {}
    {%
        \par
        \vspace { \g_preexample_skip }
        \renewcommand\baselinestretch{ \opt_bvlskip_tl }
        \tcblisting{listing~side~text,
        	righthand~width=\opt_righthand_dim,after={\allowbreak\normalcolor}}
    }{%
        \endtcblisting
    }

    \NewDocumentEnvironment {examplebelow} {}
    {%
        \par
        \vspace { \g_preexample_skip }
        \renewcommand\baselinestretch{ \opt_bvlskip_tl }
	    \tcblisting{breakable,after={\allowbreak\normalcolor}}
    }{%
        \endtcblisting
    }
}
{
%	\RequirePackage { tcolorbox }
	\tcbuselibrary{listings,breakable}
	\tcbset{
		size=normal,
		listing~engine=listings,
		colframe=\sntcolframecolor,
		colback=\sntcolbackcolor,
	}

	\NewDocumentEnvironment { exampleonly } {}
	{
		\expandafter\boxedverbatim
	}
	{
		\endboxedverbatim
	}

    \NewDocumentEnvironment {exampleside} {}
    {%
        \par
        \vspace { \g_preexample_skip }
        \renewcommand\baselinestretch{\opt_bvlskip_tl}
        \tcblisting{listing~side~text,righthand~width=\opt_righthand_dim,after={\allowbreak\normalcolor}}
    }{%
        \endtcblisting
    }

    \NewDocumentEnvironment {examplebelow} {}
    {%
        \par
        \vspace { \g_preexample_skip }
        \renewcommand\baselinestretch{\opt_bvlskip_tl}
	    \tcblisting{breakable,after={\allowbreak\normalcolor}}
    }{%
        \endtcblisting
    }
}

\def\sntInPreamble{true}
\AtBeginDocument{\let\sntInPreamble\relax}

\ior_new:N \l_snt_ior
\iow_new:N \l_out_iow
\newoutputstream { sntfile }

\bool_new:N \l_expl_bool
\bool_set_eq:NN \l_expl_bool \opt_expl_bool

\RequirePackage{etoolbox}

\NewDocumentCommand \autoexplon { }
{
	\AtBeginEnvironment { sntsave } { \bool_set_true:N \l_expl_bool }
	\AtBeginEnvironment { sntsave* } { \bool_set_true:N \l_expl_bool }
}

\NewDocumentCommand \autoexploff { }
{
	\AtBeginEnvironment { sntsave } { \bool_set_false:N \l_expl_bool }
	\AtBeginEnvironment { sntsave* } { \bool_set_false:N \l_expl_bool }
}

\NewDocumentEnvironment { sntsave } { }
{
	\openoutputfile { \jobname.code.snt } { sntfile }
	
	\bool_if:NT \l_expl_bool
	{
    	\addtostream { sntfile } { 
    		\iow_char:N \\ ExplSyntaxOn ~ \iow_char:N \% snt**
    	}
	}
	
	\writeverbatim { sntfile }
}
{
	\endwriteverbatim
	
	\bool_if:NT \l_expl_bool
	{
    	\addtostream { sntfile } {
    		\iow_char:N \\ ExplSyntaxOff ~ \iow_char:N \% snt**
    	}
	}
	
	\closeoutputstream { sntfile }
}

\NewDocumentEnvironment { sntsave* } { }
{
	\openoutputfile { \jobname.code.snt } { sntfile }
	
	\bool_if:NT \l_expl_bool
	{
    	\addtostream { sntfile } { 
    		\iow_char:N \\ ExplSyntaxOn ~ \iow_char:N \% snt**
    	}
	}
	
	\writeverbatim { sntfile }
}
{
	\endwriteverbatim
	
	\bool_if:NT \l_expl_bool
	{
    	\addtostream { sntfile } {
    		\iow_char:N \\ ExplSyntaxOff ~ \iow_char:N \% snt**
    	}
	}
	
	\closeoutputstream { sntfile }

	\cs_if_free:NTF \sntInPreamble
	{
		\msg_error:nn { srcandtext } { sntsavestar }
	}
	{
		\AtEndPreamble { 
			\makeatletter
			\input { \jobname.code.snt }
			\makeatother
		}
	}
}

\NewDocumentCommand \loadsntcode { }
{
	\exp_args:No \file_input:n  { \jobname.code.snt }
}

\NewDocumentCommand \loadsnttext { s }
{
    \ior_open:Nn \l_snt_ior { \jobname.code.snt }
    \iow_open:Nn \l_out_iow { \jobname.text.snt }

    \ior_str_map_inline:Nn \l_snt_ior 
    {
    	\str_if_in:nnTF { ##1 } { snt** }
		{				
		}
		{
            \str_if_in:nnTF { ##1 } { <Code> }
            {
                \iow_now:Nx \l_out_iow { \exp_not:N \begin { \opt_exampleenv_tl } }
            }
            {
                \str_if_in:nnTF { ##1 } { </Code> }
                {
                    \iow_now:Nx \l_out_iow { \exp_not:N \end { \opt_exampleenv_tl } }
                }
                {
                    \tl_set:Nn \l_tmpa_tl { ##1 }
                    \regex_replace_once:nnN { ^\%\% } { } \l_tmpa_tl 
                    \iow_now:Nx \l_out_iow { \l_tmpa_tl }
                }
            }
        }
    }
    
    \ior_close:N \l_snt_ior
    \iow_close:N \l_out_iow

    \input {\jobname.text.snt }

    \IfBooleanT { #1 }
    {
		\input { \jobname.code.snt }
	}
}

\newcounter{numpar}
\counterwithin*{numpar}{section}

\NewDocumentCommand \numpar { }
{
	\par
	\refstepcounter{numpar}
	\noindent
	\ifxetex
	\XeTeXLinkBox {
		\llap{\textbf{\sffamily\thenumpar .}\hspace{.8em} }
	}
	\else
		\llap{\textbf{\sffamily\thenumpar .}\ }
	\fi	
}

%%% st commands
\NewDocumentCommand \stm { s m }
{
	\tl_set:Nn \l_tmpa_tl { #2 }
	\regex_replace_all:nnN { \_ } { \c{textunderscore} } \l_tmpa_tl
	\texttt{\textbackslash \l_tmpa_tl}
	\IfBooleanT { #1 } { \allowbreak }
	\index{\l_tmpa_tl @\string\texttt{\textbackslash \l_tmpa_tl}}
	\index{매크로!\string\texttt{\textbackslash \l_tmpa_tl } }
}

\NewDocumentCommand \ste { s m }
{
	\tl_set:Nn \l_tmpa_tl { #2 }
	\regex_replace_all:nnN { \_ } { \c{textunderscore } } \l_tmpa_tl
	\cnm{\textit{#2}}
	\IfBooleanT { #1 } { \allowbreak }
	\index{\l_tmpa_tl @\string\textit{\l_tmpa_tl}}
	\index{환경!\string\textit{\l_tmpa_tl}}
}

\NewDocumentCommand \stp { s m }
{
	\textsf{#2}
	\IfBooleanT { #1 } { \allowbreak }
	\index{#2@\string\textsf{#2}}
	\index{패키지!\string\textsf{#2}}
}

\NewDocumentCommand \stopt { s m }
{
	\texttt{#2}
	\IfBooleanT { #1 } { \allowbreak }
	\index{#2@\string\texttt{#2}}
	\index{옵션!\string\texttt{#2}}
}

\NewDocumentCommand \wi { m }
{
	#1\index{#1}
}

\AtEndPreamble{
	\@ifpackageloaded{minted} {
		\providecommand \minted@inputlineno {}  %% avoid empty bug
	}{}{}
	\bool_if:NT \opt_shortverb_bool
	{
		\MakeShortVerb{\|}
	}
}
\bool_if:NT \opt_memoir_bool
{
	\firmlists
}

\NewDocumentCommand \sntcolorset { m }
{
	\clist_set:Nn \l_tmpa_clist { #1 }
	\undef\sntcolframecolor \undef\sntcolbackcolor
	\clist_pop:NN \l_tmpa_clist \l_tmpa_tl
	\tl_set_eq:NN \sntcolframecolor \l_tmpa_tl
	\clist_pop:NN \l_tmpa_clist \l_tmpa_tl
	\tl_set_eq:NN \sntcolbackcolor \l_tmpa_tl
	
	\tcbset{
		colframe=\sntcolframecolor,
		colback=\sntcolbackcolor,
	}
}

%%%% private option
\newcommand\PrivateSpacing{\setstretch{1.1}}

\bool_if:NT \opt_private_bool
{
	\tcbuselibrary{skins}

    \cs_if_exist:NT \cmd {
        \RenewDocumentCommand \cmd { m }
        {
        	\str_set:Nn \l_tmpa_str { #1 }
        	\regex_replace_once:nnN { \ $ } { } \l_tmpa_str
        	\texttt{\textbackslash \str_tail:N \l_tmpa_str }
        }
    }
    
    \RenewDocumentEnvironment {exampleside} {}
    {%
        \par
        \vspace { \g_preexample_skip }
    %        \renewcommand\baselinestretch{ \opt_bvlskip_tl }
    		\PrivateSpacing
        \tcblisting{listing~side~text,
        	sharp~corners,
    			top=2pt,bottom=2pt, 
    			leftrule=1pt,rightrule=2pt, toprule=1pt,bottomrule=2pt,
            bicolor,colbacklower=white,
        	righthand~width=\opt_righthand_dim,after={\allowbreak\normalcolor}}
    }{%
        \endtcblisting
    }
    
    \RenewDocumentEnvironment {examplebelow} {}
    {%
        \par
        \vspace { \g_preexample_skip }
    %        \renewcommand\baselinestretch{ \opt_bvlskip_tl }
    		\PrivateSpacing
    	    \tcblisting{breakable,
        	sharp~corners,
    			top=2pt,bottom=2pt,
    			leftrule=1pt,rightrule=2pt, toprule=1pt,bottomrule=2pt,
            bicolor,colbacklower=white,
            after={\allowbreak\normalcolor}}
    }{%
        \endtcblisting
    }
}

\NewDocumentCommand \setrighthandwidth { m }
{
	\dim_set:Nn \opt_righthand_dim { #1 }
}

\endinput
