% ksvqt
% written by Nova de Hi, 2025
%
\ProvidesExplPackage{ksvqt}
	{2025/07/20}
	{version 0.9.1}
	{yet another way to typeset CJK brackets for ko.TeX}

\RequirePackage{xparse}
\RequirePackage{iftex}

\tl_set:Nn \l_defaultsym_tl { 0 }

\bool_new:N \g_naturalwidth_bool
\bool_set_false:N \g_naturalwidth_bool

\dim_new:N  \l_open_ksvqtbox_dim
\dim_new:N  \l_close_ksvqtbox_dim
\dim_set:Nn \l_open_ksvqtbox_dim { 0.5em }
\dim_set:Nn \l_close_ksvqtbox_dim { 0.5em }
\dim_new:N  \l_open_ksvqtbox_eight_dim
\dim_new:N  \l_close_ksvqtbox_eight_dim
\dim_set:Nn \l_open_ksvqtbox_eight_dim { 0.5em }
\dim_set:Nn \l_close_ksvqtbox_eight_dim { 0.5em }
\dim_new:N  \l_open_ksvqtbox_nine_dim
\dim_new:N  \l_close_ksvqtbox_nine_dim
\dim_set:Nn \l_open_ksvqtbox_nine_dim { 0.5em }
\dim_set:Nn \l_close_ksvqtbox_nine_dim { 0.5em }

\tl_set:Nn \_ksvqt_innermacro_before {  }
\tl_set:Nn \_ksvqt_innermacro_after  {  }
\tl_set:Nn \_ksvqt_outermacro_before {  }
\tl_set:Nn \_ksvqt_outermacro_after  {  }

\tl_new:N \ksvqt_spec_mac_six
\tl_new:N \ksvqt_spec_mac_seven
\tl_new:N \ksvqt_spec_mac_eight
\tl_new:N \ksvqt_spec_mac_nine
\tl_new:N \ksvqtspecmac_cur

\bool_new:N \g_userwidth_bool

\tl_set:Nn \_original_open_brk { \< }

\NewDocumentCommand \< { }
{
	\mode_if_math:TF 
	{ \tl_use:N \_original_open_brk }
	{ \_start_vqtmain:n }
}

\let\ksvqtstop\relax

\fp_new:N \l_cur_emsize_fp

\cs_new:Nn \__check_emsize:
{
	\fp_set:Nn \l_cur_emsize_fp { 0.5 * \f@size }
    \exp_args:NNf \dim_set:Nn \l_open_ksvqtbox_dim { \fp_use:N \l_cur_emsize_fp pt }
    \exp_args:NNf \dim_set:Nn \l_close_ksvqtbox_dim { \fp_use:N \l_cur_emsize_fp pt }
    \exp_args:NNf \dim_set:Nn \l_open_ksvqtbox_eight_dim { \fp_use:N \l_cur_emsize_fp pt }
    \exp_args:NNf \dim_set:Nn \l_close_ksvqtbox_eight_dim { \fp_use:N \l_cur_emsize_fp pt }
    \exp_args:NNf \dim_set:Nn \l_open_ksvqtbox_nine_dim { \fp_use:N \l_cur_emsize_fp pt }
    \exp_args:NNf \dim_set:Nn \l_close_ksvqtbox_nine_dim { \fp_use:N \l_cur_emsize_fp pt }
}

\fp_new:N \ksvqtemsizefp

\NewDocumentCommand \ksvqtcalcemsize { m }
{
	\fp_set:Nn \ksvqtemsizefp { #1 * \f@size }
}

\NewDocumentCommand \ksvqtemsize {}
{
	\fp_use:N \ksvqtemsizefp
}

\NewDocumentCommand \ksvqtBrackets { t< m }
{
	\IfBooleanT { #1 }
	{
		\_start_vqtmain:n #2
	}
}

\cs_new:Npn \_start_vqtmain:n #1
{
	\bool_if:NF \g_userwidth_bool 
	{
		\__check_emsize:
	}

	\regex_match:nnTF { [0-9] } { #1 }
	{
		\_ksvqt_fn:n #1
	}
	{
		\str_if_eq:nnTF { #1 } { ! }
		{
			\exp_last_unbraced:No
			\_ksvqt_fn:n \l_defaultsym_tl 
		}
		{
			\exp_last_unbraced:No 
			\_ksvqt_fn:n \l_defaultsym_tl #1
		}
	}
}

\tl_set:Nn \ksvqt_open_tl { {「} }
\tl_set:Nn \ksvqt_close_tl { {」} }

\sys_if_engine_pdftex:TF 
{
	\tl_set:Nn \_ksvqt_usermark_six {{【}{】}}
	\tl_set:Nn \_ksvqt_usermark_seven {{「}{」}}
	\tl_set:Nn \_ksvqt_usermark_eight {{「}{」}}
	\tl_set:Nn \_ksvqt_usermark_nine  {{「}{」}}
}
{
	\tl_set:Nn \_ksvqt_usermark_six {{〖}{〗}} % 3016, 3017: white lenticular brk
	\tl_set:Nn \_ksvqt_usermark_seven {{〘}{〙}} % 3014, 3015: tortoise shell brk
	\tl_set:Nn \_ksvqt_usermark_eight {{〚}{〛}} % 301a, 301b: square brk.
	\tl_set:Nn \_ksvqt_usermark_nine  {{｟}{｠}} % ff5f, ff60, full width white parenthesis
}

\cs_new:Npn \_ksvqt_fn:n #1
{
	\str_case:nnTF { #1 }
	{
		{ 0 } { \tl_set:Nn \_ksvqt_mark { {「}{」} } }
		{ 1 } { \tl_set:Nn \_ksvqt_mark { {『}{』} } }
		{ 2 } { \tl_set:Nn \_ksvqt_mark { {〈}{〉} } }
		{ 3 } { \tl_set:Nn \_ksvqt_mark { {《}{》} } }
		{ 4 } { \tl_set:Nn \_ksvqt_mark { {〔}{〕} } }
		{ 5 } { \tl_set:Nn \_ksvqt_mark { {【}{】} } }
		{ 6 } {
				\tl_set:No \_ksvqt_mark { \_ksvqt_usermark_six } 
				\tl_set_eq:NN \ksvqtspecmac_cur \ksvqt_spec_mac_six
			  }
		{ 7 } {
				\tl_set:No \_ksvqt_mark { \_ksvqt_usermark_seven } 
				\tl_set_eq:NN \ksvqtspecmac_cur \ksvqt_spec_mac_seven
			  }
%		{ 8 } { \tl_set:No \_ksvqt_mark { \_ksvqt_usermark_eight } }
	}
	{
		\ksvqt_command_main
	}
	{
		\str_case:nnTF { #1 }
		{
			{ 8 } {
				\tl_set:No \_ksvqt_mark { \_ksvqt_usermark_eight }
				\tl_set_eq:NN \ksvqtspecmac_cur \ksvqt_spec_mac_eight
			}
			{ 9 } {
				\tl_set:No \_ksvqt_mark { \_ksvqt_usermark_nine }
				\tl_set_eq:NN \ksvqtspecmac_cur \ksvqt_spec_mac_nine
			}
		}
		{
			\ksvqt_command_main_spec { #1 } 
		}
		{
    		\tl_set:Nn \_ksvqt_mark { \ksvqt_open_tl \ksvqt_close_tl }
    		\ksvqt_command_main
		}
	}
}

\cs_new:Npn \_print_with_natural:n #1
{
	\tl_use:N \_ksvqt_outermacro_before 
	{ \exp_args:Nf \ksvqtspecmac_cur { \tl_head:N \_ksvqt_mark }\_ksvqt_innermacro_before }
	\nobreak 
	\ksvqtspecmac_cur #1
	\nobreak
	{ \_ksvqt_innermacro_after \exp_args:Nf \ksvqtspecmac_cur { \tl_item:Nn \_ksvqt_mark { 2 } } }
	\tl_use:N \_ksvqt_outermacro_after
}

\NewDocumentCommand \ksvqt_command_main_spec { m u> }
{
	\str_case:nnF { #1 }
	{
		{ 8 } { \tl_set:Nn \l_tmpa_tl { eight } }
		{ 9 } { \tl_set:Nn \l_tmpa_tl { nine  } }
	}
	{
		\tl_set:Nn \l_tmpa_tl { nine }
	}
	\mode_if_vertical:TF { \mode_leave_vertical: } { \allowbreak }
	\group_begin:
	\bool_if:NTF \g_naturalwidth_bool
	{
		\_print_with_natural:n { #2 }
	}
	{
    	\tl_use:N \_ksvqt_outermacro_before
    	\makebox [ \dim_use:c { l_open_ksvqtbox_\l_tmpa_tl _dim } ] [ r ] { \exp_args:Nf \ksvqtspecmac_cur { \tl_head:N \_ksvqt_mark } \_ksvqt_innermacro_before  }
    	\nobreak 
    	#2
    	\nobreak
    	\makebox [ \dim_use:c { l_close_ksvqtbox_\l_tmpa_tl _dim } ] [ l ] { \_ksvqt_innermacro_after \exp_args:Nf \ksvqtspecmac_cur { \tl_item:Nn \_ksvqt_mark { 2 } } }
    	\tl_use:N \_ksvqt_outermacro_after
	}
	\group_end:
	\allowbreak
}

\NewDocumentCommand \ksvqt_command_main { u> }
{
%	\mode_if_vertical:TF { \mode_leave_vertical: } { \allowbreak }
	\group_begin:
	\bool_if:NTF \g_naturalwidth_bool
	{
		\_print_with_natural:n { #1 }
	}
	{
    	\tl_use:N \_ksvqt_outermacro_before 
    	\makebox [ \l_open_ksvqtbox_dim ] [ r ] { \exp_args:Nf \ksvqtspecmac_cur { \tl_head:N \_ksvqt_mark } \_ksvqt_innermacro_before } 
    	\nobreak 
    	#1
    	\nobreak
    	\makebox [ \l_close_ksvqtbox_dim ] [ l ] { \_ksvqt_innermacro_after \exp_args:Nf \ksvqtspecmac_cur { \tl_item:Nn \_ksvqt_mark { 2 } } }
    	\tl_use:N \_ksvqt_outermacro_after
	}
	\group_end:
	\mode_if_vertical:F { \allowbreak }
}

\NewDocumentCommand \ksvqtuserdef { O{7} m }
{
	\str_case:nn { #1 }
	{
		{ 6 } { \tl_set:Nn \_ksvqt_usermark_six   { #2 } }
		{ 7 } { \tl_set:Nn \_ksvqt_usermark_seven { #2 } }
		{ 8 } { \tl_set:Nn \_ksvqt_usermark_eight { #2 } }
		{ 9 } { \tl_set:Nn \_ksvqt_usermark_nine  { #2 } }
	}
}

\NewDocumentCommand \ksvqtwidthdef { somo }
{
	\bool_gset_true:N \g_userwidth_bool 

	\IfBooleanTF { #1 }
	{
		\IfValueTF {#2 }
		{
			\str_case:nnF { #2 }
			{
				{ 8 } { \tl_set:Nn \l_tmpa_tl { eight } }
				{ 9 } { \tl_set:Nn \l_tmpa_tl { nine  } }
			}
			{
				\tl_set:Nn \l_tmpa_tl { nine }
			}
		}
		{
			\tl_set:Nn \l_tmpa_tl { nine }
		}
    	\IfValueTF { #4 }
    	{
    		\dim_set:cn { l_open_ksvqtbox_\l_tmpa_tl _dim } { #3 }
    		\dim_set:cn { l_close_ksvqtbox_\l_tmpa_tl _dim } { #4 }
    	}
    	{
    		\dim_set:cn { l_open_ksvqtbox_\l_tmpa_tl _dim } { #3 }
    		\dim_set:cn { l_close_ksvqtbox_\l_tmpa_tl _dim } { #3 }
    	}
	}
	{
    	\IfValueTF { #4 }
    	{
    		\dim_set:Nn \l_open_ksvqtbox_dim { #3 }
    		\dim_set:Nn \l_close_ksvqtbox_dim { #4 }
    	}
    	{
    		\dim_set:Nn \l_open_ksvqtbox_dim { #3 }
    		\dim_set:Nn \l_close_ksvqtbox_dim { #3 }
    	}
	}
}

\NewDocumentCommand \ksvqtwidthdefault { }
{
	\bool_gset_false:N \g_userwidth_bool
}

\NewDocumentCommand \ksvqtinnermacro { s O{both} m }
{
	\str_if_eq:nnTF { #2 } { both }
	{
		\tl_set:Nn \_ksvqt_innermacro_before { #3 }
		\tl_set:Nn \_ksvqt_innermacro_after  { #3 }
	}
	{
		\IfBooleanF { #1 }
		{
			\tl_clear:N \_ksvqt_innermacro_before
			\tl_clear:N \_ksvqt_innermacro_after
		}
		\tl_set:cn { _ksvqt_innermacro_ #2 } { #3 }
	}
}

\NewDocumentCommand \ksvqtoutermacro { s O{both} m }
{
	\str_if_eq:nnTF { #2 } { both }
	{
		\tl_set:Nn \_ksvqt_outermacro_before { #3 }
		\tl_set:Nn \_ksvqt_outermacro_after { #3 }
	}
	{
		\IfBooleanF { #1 }
		{
			\tl_clear:N \_ksvqt_outermacro_before
			\tl_clear:N \_ksvqt_outermacro_after
		}
		\tl_set:cn { _ksvqt_outermacro_ #2 } { #3 }
	}
}

\NewDocumentCommand \ksvqtdefaultsym { m }
{
	\tl_set:Nn \l_defaultsym_tl { #1 }
}

\NewDocumentCommand \ksvqtwidthnatural { O{true} }
{
	\str_case:nnF { #1 }
	{
		{ true  } { \bool_set_true:N \g_naturalwidth_bool }
		{ false } { \bool_set_false:N \g_naturalwidth_bool }
	}
	{
		\bool_set_false:N \g_naturalwidth_bool 
	}
}

\NewDocumentCommand \ksvqtwidthforce { O{true} }
{
	\str_case:nnF { #1 }
	{
		{ false } { \bool_set_true:N \g_naturalwidth_bool }
		{ true  } { \bool_set_false:N \g_naturalwidth_bool }
	}
	{
		\bool_set_true:N \g_naturalwidth_bool 
	}
}

\NewDocumentCommand \ksvqtuserdefrestore { O{6,7,8,9} }
{
	\sys_if_engine_pdftex:F 
	{
    	\clist_set:Nn \l_tmpb_clist { #1 }
    	\clist_map_inline:Nn \l_tmpb_clist
    	{
    		\str_case:nn { ##1 } 
    		{
    			{ 6 } { \tl_set:Nn \_ksvqt_usermark_six   {{〖}{〗}} }
    			{ 7 } { \tl_set:Nn \_ksvqt_usermark_seven {{〘}{〙} } }
    			{ 8 } { \tl_set:Nn \_ksvqt_usermark_eight {{〚}{〛}} }
    			{ 9 } { \tl_set:Nn \_ksvqt_usermark_nine  {{｟}{｠}} }
    		}
    	}
	}
}

\NewDocumentCommand \ksvqtspecmac { O{6} m }
{
	\str_case:nnF { #1 }
	{
		{ 6 } { \tl_set:Nn \ksvqt_spec_mac_six { #2 } }
		{ 7 } { \tl_set:Nn \ksvqt_spec_mac_seven { #2 } }
		{ 8 } { \tl_set:Nn \ksvqt_spec_mac_eight { #2 } }
		{ 9 } { \tl_set:Nn \ksvqt_spec_mac_nine { #2 } }
	}
	{
		\tl_clear:N \ksvqt_spec_mac_six
		\tl_clear:N \ksvqt_spec_mac_seven
		\tl_clear:N \ksvqt_spec_mac_eight
		\tl_clear:N \ksvqt_spec_mac_nine
	}
}
