%% `file: pmhanguljamo.sty
%%
%% Poorman's Hangul Jamo Input Method.
%%
%% (C) 2020-2025 Kangsoo Kim
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%% 
%% The Current Maintainer of this work is Kangsoo Kim
%%
%% This work consists of the style files --- 
%%    pmhanguljamo.sty, pmhanguljamo-rrk.sty, pmhanguljamo-frkim.sty,
%%    pmhanguljamo-frkim.code.tex
%%
\RequirePackage{xparse}
\ProvidesExplPackage
	{pmhanguljamo}
	{2025/02/10}
	{v1.1.2}
	{Poorman's Hangul Jamo Input Method}

\RequirePackage{l3keys2e}

\bool_new:N \opt_usepmfont_bool
\bool_new:N \opt_rrkopt_bool
\bool_new:N \opt_frkim_bool

\tl_new:N \opt_pmfont_tl
\tl_new:N \opt_pmfontfeature_tl
\tl_new:N \opt_unknown_tl
\tl_clear:N \opt_unknown_tl

\keys_define:nn { pmhanguljamo }
{
	method	.code:n = {
		\str_case:nn { #1 } 
		{
			{ pm }	{ \bool_set_false:N \opt_rrkopt_bool
					  \bool_set_false:N \opt_frkim_bool }
			{ rrk } { \bool_set_true:N \opt_rrkopt_bool
					  \bool_set_false:N \opt_frkim_bool }
			{ frkim } { \bool_set_false:N \opt_rrkopt_bool
					  \bool_set_true:N \opt_frkim_bool }
		}
	},
	compat 	.tl_set:N = \opt_compat_tl,
	rrk	.bool_set:N = \opt_rrkopt_bool,
	RRK	.bool_set:N = \opt_rrkopt_bool,
	pmfont	.code:n = {
		\bool_gset_true:N \opt_usepmfont_bool
		\tl_gset:Nn \opt_pmfont_tl { #1 }
	},
	pmfontfeature	.tl_set:N = \opt_pmfontfeature_tl,
%%% version 0.6+, frkim.
	frkim	.bool_set:N = \opt_frkim_bool,
	zeroisx	.bool_set:N = \opt_zeroisx_bool,
	frcccmds .bool_set:N = \opt_frcccmds_bool,
	hangulfont .tl_set:N = \opt_pmfont_tl,
	hangulfontfeature	.tl_set:N = \opt_pmfontfeature_tl,
	unknown	.code:n = { \tl_put_right:Nn \opt_unknown_tl { #1, } }
}

\ProcessKeysOptions { pmhanguljamo }

%%%% presets

\bool_new:N \g_compat_bool 

\str_if_eq:eeTF { \opt_compat_tl } { 0.5 }
{
	\bool_gset_true:N \g_compat_bool 
}
{
	\bool_gset_false:N \g_compat_bool
}


\NewDocumentCommand \jmcc { m }
{
	\prop_item:Nn \c_compjamo_prop { #1 }
}

\bool_if:NTF \g_compat_bool 
{
	\prop_const_from_keyval:Nn \c_compjamo_prop
	{
		G	= \char"3131,
		GG	= \char"3132,
		GS	= \char"3133,
		N	= \char"3134,
		NJ	= \char"3135,
		NH	= \char"3136,
		D	= \char"3137,
		DD	= \char"3138,
		R	= \char"3139,
		RG	= \char"313A,
		RM	= \char"313B,
		RB	= \char"313C,
		RS	= \char"313D,
		RT	= \char"313E,
		RP	= \char"313F,
		RH	= \char"3140,
		M	= \char"3141,
		B	= \char"3142,
		BB	= \char"3143,
		BS	= \char"3144,
		S	= \char"3145,
		SS	= \char"3146,
		X	= \char"3147,
		J	= \char"3148,
		JJ	= \char"3149,
		C	= \char"314A,
		K	= \char"314B,
		T	= \char"314C,
		P	= \char"314D,
		H	= \char"314E,
		A	= \char"314F,
		AY	= \char"3150,
		AI	= \char"3150,
		YA	= \char"3151,
		YAY	= \char"3152,
		YAI	= \char"3152,
		E	= \char"3153,
		EY	= \char"3154,
		EI	= \char"3154,
		YE	= \char"3155,
		YEY	= \char"3156,
		YEI	= \char"3156,
		O	= \char"3157,
		OA	= \char"3158,
		OAY	= \char"3159,
		OAI	= \char"3159,
		OY	= \char"315A,
		OI	= \char"315A,
		YO	= \char"315B,
		U	= \char"315C,
		UE	= \char"315E,
		UEY	= \char"315E,
		UEI	= \char"315E,
		UY	= \char"315F,
		UI	= \char"315F,
		YU	= \char"3160,
		V	= \char"3161,
		VI	= \char"3162,
		VY	= \char"3162,
		I	= \char"3163,
		NN	= \char"3165,
		ND	= \char"3166,
		NS	= \char"3167,
		NZ	= \char"3168,
		RGS	= \char"3169,
		RD	= \char"316A,
		RBS	= \char"316B,
		RZ	= \char"316C,
		RF	= \char"316D,
		MB	= \char"316E,
		MS	= \char"316F,
		MZ	= \char"3170,
		MX	= \char"3171,
		BG	= \char"3172,
		BD	= \char"3173,
		BSG	= \char"3174,
		BSD	= \char"3175,
		BJ	= \char"3176,
		BT	= \char"3177,
		BX	= \char"3178,
		BBX	= \char"3179,
		SG	= \char"317A,
		SN	= \char"317B,
		SD	= \char"317C,
		SB	= \char"317D,
		SJ	= \char"317E,
		Z	= \char"317F,
		XX	= \char"3180,
		Q	= \char"3181,
		QS	= \char"3182,
		QZ	= \char"3183,
		PX	= \char"3184,
		HH	= \char"3185,
		F	= \char"3186,
		YOYA	= \char"3187,
		YOYAY	= \char"3188,
		YOI	= \char"3189,
		YUYE	= \char"318A,
		YUYEY	= \char"318B,
		YUI	= \char"318C,
		W	= \char"318D,
		WI	= \char"318E,
		@ 	= \char"318D,
		@I	= \char"318E,
		@@	= \double_arae_a,
		WW	= \double_arae_a
	}
}
{
	\prop_const_from_keyval:Nn \c_compjamo_prop
	{
		G	= \char"3131,
		GG	= \char"3132,
		GS	= \char"3133,
		N	= \char"3134,
		NJ	= \char"3135,
		NH	= \char"3136,
		D	= \char"3137,
		DD	= \char"3138,
		R	= \char"3139,
		RG	= \char"313A,
		RM	= \char"313B,
		RB	= \char"313C,
		RS	= \char"313D,
		RT	= \char"313E,
		RP	= \char"313F,
		RH	= \char"3140,
		M	= \char"3141,
		B	= \char"3142,
		BB	= \char"3143,
		BS	= \char"3144,
		S	= \char"3145,
		SS	= \char"3146,
		Q	= \char"3147,
		J	= \char"3148,
		JJ	= \char"3149,
		C	= \char"314A,
		K	= \char"314B,
		T	= \char"314C,
		P	= \char"314D,
		H	= \char"314E,
		A	= \char"314F,
		AY	= \char"3150,
		AI	= \char"3150,
		YA	= \char"3151,
		YAY	= \char"3152,
		YAI	= \char"3152,
		E	= \char"3153,
		EY	= \char"3154,
		EI	= \char"3154,
		YE	= \char"3155,
		YEY	= \char"3156,
		YEI	= \char"3156,
		O	= \char"3157,
		OA	= \char"3158,
		OAY	= \char"3159,
		OAI	= \char"3159,
		OY	= \char"315A,
		OI	= \char"315A,
		YO	= \char"315B,
		U	= \char"315C,
		UE	= \char"315E,
		UEY	= \char"315E,
		UEI	= \char"315E,
		UY	= \char"315F,
		UI	= \char"315F,
		YU	= \char"3160,
		V	= \char"3161,
		VI	= \char"3162,
		VY	= \char"3162,
		I	= \char"3163,
		NN	= \char"3165,
		ND	= \char"3166,
		NS	= \char"3167,
		NZ	= \char"3168,
		RGS	= \char"3169,
		RD	= \char"316A,
		RBS	= \char"316B,
		RZ	= \char"316C,
		RX	= \char"316D,
		MB	= \char"316E,
		MS	= \char"316F,
		MZ	= \char"3170,
		MQ	= \char"3171,
		BG	= \char"3172,
		BD	= \char"3173,
		BSG	= \char"3174,
		BSD	= \char"3175,
		BJ	= \char"3176,
		BT	= \char"3177,
		BQ	= \char"3178,
		BBQ	= \char"3179,
		SG	= \char"317A,
		SN	= \char"317B,
		SD	= \char"317C,
		SB	= \char"317D,
		SJ	= \char"317E,
		Z	= \char"317F,
		QQ	= \char"3180,
		F	= \char"3181,
		FS	= \char"3182,
		FZ	= \char"3183,
		PQ	= \char"3184,
		HH	= \char"3185,
		X	= \char"3186,
		YOYA	= \char"3187,
		YOYAY	= \char"3188,
		YOI	= \char"3189,
		YUYE	= \char"318A,
		YUYEY	= \char"318B,
		YUI	= \char"318C,
		W	= \char"318D,
		AA  = \char"318D,
		WI	= \char"318E,
		AAI = \char"318E,
		@ 	= \char"318D,
		@I	= \char"318E,
		@@	= \double_arae_a,
		WW	= \double_arae_a,
		AAA = \double_arae_a
	}	
}
\newcommand*\double_arae_a{%
	\hbox_set:Nn \l_tmpa_box { \char"318D }
	\dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box + 2pt }
	\makebox[\l_tmpa_dim][c]{ \char"318D\kern-.6em\char"318D }
}

%%%% usepmfont macro

\cs_if_exist:NTF \hangulfontspec
{
	\cs_set_eq:NN \pm_hangulfontspec \hangulfontspec
}
{
	\cs_set_eq:NN \pm_hangulfontspec \fontspec
}

\NewDocumentCommand \usepmfont { }
{
	\bool_gset_true:N \opt_usepmfont_bool
}

\NewDocumentCommand \unusepmfont { }
{
	\bool_gset_false:N \opt_usepmfont_bool
}

\NewDocumentCommand \setpmhangulfont { o m o }
{
	\tl_gset:Nn \opt_pmfont_tl { #2 }
	\IfValueTF { #3 } { \tl_gset:Nn \opt_pmfontfeature_tl { #3, Ligatures=TeX, Script=Hangul, Renderer=OpenType } }
	{
		\IfValueTF { #1 } { \tl_gset:Nn \opt_pmfontfeature_tl { #1, Ligatures=TeX, Script=Hangul, Renderer=OpenType } }
		{ \tl_gset:Nn \opt_pmfontfeature_tl { Ligatures=TeX, Script=Hangul, Renderer=OpenType } }
	}
}

\AtBeginDocument{
	\tl_if_empty:NTF \opt_pmfontfeature_tl
	{
		\tl_gset:Nn \opt_pmfontfeature_tl { Ligatures=TeX, Script=Hangul, Renderer=OpenType }
	}
	{
		\tl_gput_right:Nn \opt_pmfontfeature_tl { , Ligatures=TeX, Script=Hangul, Renderer=OpenType }
	}
}

%%% method=frkim
%%% loads frkim codes and exit
\bool_if:NT \opt_frkim_bool
{
	\bool_new:N \opt_luatexko_loaded
	\@ifpackageloaded{luatexko}{
		\bool_set_true:N \opt_luatexko_loaded
	}{
		\bool_set_false:N \opt_luatexko_loaded
	}

	\tl_set_eq:NN \frkhangulfont \opt_pmfont_tl
	\tl_if_empty:NT \frkhangulfont {
		\tl_set:Nn \frkhangulfont { NotoSerifKR-Regular.otf }
	}
	\tl_set_eq:NN \frkhangulfontfeature \opt_pmfontfeature_tl
	\tl_if_empty:NT \frkhangulfontfeature {
		\tl_set:Nn \frkhangulfontfeature { Ligatures=TeX,Renderer=OpenType,Script=Hangul } }
	
	\input{pmhanguljamo-frkim.code.tex}
	\endinput
}

%%%% if method=rrk, then input pmhanguljamo-rrk.sty
%%%% and stop.

\bool_if:NT \opt_rrkopt_bool
{
	\file_input:n { pmhanguljamo-rrk.sty }
	\endinput
}

%%%%
%%%% pm input method:
%%%%

\NewDocumentCommand \jamotextcmd { m }
{
	\tl_set:Nn \l_tmpa_tl { #1 / }
	\regex_replace_all:nnN { / } { |/ } \l_tmpa_tl
	\regex_replace_all:nnN { ; } { ;/ } \l_tmpa_tl
	\regex_replace_all:nnN { : } { :/ } \l_tmpa_tl
	
	\exp_args:Nno \regex_split:nnN { / } { \l_tmpa_tl } \l_tmpa_seq
	
	\seq_map_indexed_function:NN \l_tmpa_seq \build_syl:nn
}

\tl_new:N \l_cho_tl
\tl_new:N \l_jun_tl
\tl_new:N \l_jon_tl
\bool_new:N \l_jj_bool
\seq_new:N \l_inputword_seq
\seq_new:N \l_inputpar_seq

\NewDocumentEnvironment { jamotext } { +b }
{
	\seq_set_split:Nnn \l_inputpar_seq { \par } { #1 }
	\seq_map_indexed_function:NN \l_inputpar_seq \jamo_word:nn
%	\seq_set_split:Nnn \l_inputword_seq { ~ } { #1 }
%	\seq_map_indexed_inline:Nn \l_inputword_seq
%	{
%		\jamotextcmd { ##2 }
%		\int_compare:nT { ##1 < \seq_count:N \l_inputword_seq }
%		{ \space }
%	}
}{}

\cs_new:Npn \jamo_word:nn #1 #2
{
%	\jamoword { #2 }
	\seq_set_split:Nnn \l_inparpar_seq { ~ } { #2 }
	
	\seq_map_indexed_inline:Nn \l_inparpar_seq
	{
		\regex_match:nnTF { ^\!\{ } { ##2 }
		{
			\tl_set:Nn \l_tmpa_tl { ##2 }
			\regex_match:nnTF { ^\!\{(.+?)\}$ } { ##2 }
			{
				\regex_replace_once:nnN { ^\!\{(.+?)\}$ } { \1 } \l_tmpa_tl
				\l_tmpa_tl 
			}
			{
				\tl_set_eq:NN \l_tmpb_tl \l_tmpa_tl
				\regex_replace_once:nnN { ^\!\{(.+?)\}(.*)$ } { \1 } \l_tmpa_tl
				\l_tmpa_tl 
				\regex_replace_once:nnN { ^\!\{(.+?)\}(.*)$ } { \2 } \l_tmpb_tl
				\exp_args:No \jamoword { \l_tmpb_tl }
			}	
		}
		{
			\jamoword{ ##2 }
		}
		
		\int_compare:nT { ##1 < \seq_count:N \l_inparpar_seq }
		{ \c_space_token }
	}

	\int_compare:nT { #1 < \seq_count:N \l_inputpar_seq }
	{ \par }
}

\NewDocumentCommand \jamoword { m }
{
	\seq_set_split:Nnn \l_inputword_seq { ~ } { #1 }
	\seq_map_indexed_inline:Nn \l_inputword_seq
	{
		\bool_if:NTF \opt_usepmfont_bool
		{
			{
				\pm_hangulfontspec [\opt_pmfontfeature_tl] {\opt_pmfont_tl} 
				\jamotextcmd{ ##2 } 
			} 
		}
		{ \jamotextcmd { ##2 } }
		\int_compare:nT { ##1 < \seq_count:N \l_inputword_seq }
		{ \c_space_token }
	}
}

%%% if xetexko loaded,
\bool_new:N \g_xetexko_bool
\@ifpackageloaded{xetexko-space}{
	\bool_gset_true:N \g_xetexko_bool
}{
	\bool_gset_false:N \g_xetexko_bool
}

\cs_new:Npn \build_syl:nn #1 #2
{
	\bool_set_false:N \l_jj_bool
	\tl_clear:N \l_cho_tl
	\tl_clear:N \l_jun_tl
	\tl_clear:N \l_jon_tl
	\int_set:Nn \l_tmpa_int { #1 }
	\build_syl_fn:n #2 \q_recursion_tail \q_recursion_stop
}

\cs_new:Npn \build_syl_fn:n #1
{	
	\quark_if_recursion_tail_stop_do:nn { #1 }
	{
		\exp_args:Nnx \regex_match:nnTF { [A-Z] } { \l_cho_tl }
		{
			\tl_reverse:N \l_cho_tl
			\tl_set:Nx \l_tmpb_tl { \tl_tail:N \l_cho_tl }
			\tl_reverse:N \l_tmpb_tl %%% remove trailing |
			\exp_args:Nx \jmcc { \l_tmpb_tl }
		}
		{
			\tl_reverse:N \l_jon_tl
			\tl_set:Nx \l_tmpa_tl { \tl_head:N \l_jon_tl }
			\tl_set:Nx \l_tmpb_tl { \tl_tail:N \l_jon_tl }
			\tl_reverse:N \l_tmpb_tl
			
			%%% force allowbreak'ing hangul syllables when xetexko loaded
			%%% luatexko or polyglossia is of no problem.
			%%% --- suppressed version 0.6, xetexko is more smart.
%			\bool_if:NT \g_xetexko_bool {
%				\exp_args:Nnx \regex_match:nnT { [a-z] } { \l_cho_tl }
%				{ 
%					\int_compare:nF { \l_tmpa_int == 1 }
%					{ \allowbreak } 
%				}
%			}
			%%% print out the syllable composed
			\exp_args:NNx \prop_item:Nn \c_cho_prop { \l_cho_tl }
			\exp_args:NNx \prop_item:Nn \c_jung_prop { \l_jun_tl }
			\exp_args:NNx \prop_item:Nn \c_jong_prop { \l_tmpb_tl }
			\exp_args:NNx \prop_item:Nn \c_jong_prop { \l_tmpa_tl } %% tone mark
		}
	}
	
	\regex_match:nnTF { [a-z;:@|*] } { #1 }
	{
		\str_case:nnTF { #1 }
		{
			{ a } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ e } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ o } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ u } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ v } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ i } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ y } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ @ } { \tl_put_right:Nn \l_jun_tl { #1 } }
			{ * } { \tl_put_right:Nn \l_jun_tl { #1 } } %% jungseong filler
		}
		{
			\int_compare:nT { \tl_count:N \l_cho_tl == 0 }  
				{
					\bool_if:NTF \g_compat_bool 
					{ \tl_put_right:Nn \l_cho_tl { x } }
					{ \tl_put_right:Nn \l_cho_tl { q } }
				} 
			\bool_set_true:N \l_jj_bool
		}
		{
			\bool_if:NTF \l_jj_bool
			{
				\tl_put_right:Nn \l_jon_tl { #1 }
			}
			{
				\tl_put_right:Nn \l_cho_tl { #1 }
			}
		}
	}
	{
		\regex_match:nnTF { [A-Z] } { #1 }
		{
			\tl_put_right:Nn \l_cho_tl { #1 }
		}
		{
			#1
		}
	}
	
	\build_syl_fn:n
}

\NewDocumentCommand \ColonMark {} { : }
\NewDocumentCommand \SemiColonMark {} { ; }
\NewDocumentCommand \SlashMark {} { / }
\NewDocumentCommand \CntrdotMark {} { · }

%%%%%%%%% DICTIONARIES
\bool_if:NTF \g_compat_bool 
{
	\prop_const_from_keyval:Nn \c_cho_prop
	{
		g 	= \char"1100,
		gg 	= \char"1101,
		n	= \char"1102,
		d	= \char"1103,
		dd	= \char"1104,
		r	= \char"1105,
		m	= \char"1106,
		b	= \char"1107,
		bb	= \char"1108,
		s	= \char"1109,
		ss	= \char"110A,
		x	= \char"110B,
		j	= \char"110C,
		jj	= \char"110D,
		c	= \char"110E,
		k	= \char"110F,
		t	= \char"1110,
		p	= \char"1111,
		h	= \char"1112,
		ng	= \char"1113,
		nn	= \char"1114,
		nd 	= \char"1115,
		nb	= \char"1116,
		dg	= \char"1117,
		rn	= \char"1118,
		rr	= \char"1119,
		rh	= \char"111A,
		rx	= \char"111B,
		mb	= \char"111C,
		mx	= \char"111D,
		bg	= \char"111E,
		bn	= \char"111F,
		bd	= \char"1120,
		bs	= \char"1121,
		bsg	= \char"1122,
		bsd	= \char"1123,
		bsb	= \char"1124,
		bss	= \char"1125,
		bsj	= \char"1126,
		bj	= \char"1127,
		bc	= \char"1128,
		bt	= \char"1129,
		bp	= \char"112A,
		bx	= \char"112B,
		bbx	= \char"112C,
		sg	= \char"112D,
		sn	= \char"112E,
		sd	= \char"112F,
		sr	= \char"1130,
		sm	= \char"1131,
		sb	= \char"1132,
		sbg	= \char"1133,
		sss	= \char"1134,
		sq	= \char"1135,
		sj	= \char"1136,
		sc	= \char"1137,
		sk	= \char"1138,
		st	= \char"1139,
		sp	= \char"113A,
		sh	= \char"113B,
		sl	= \char"113C,
		ssl	= \char"113D,
		slr	= \char"113E,
		sslr	= \char"113F,
		z	= \char"1140,
		xg	= \char"1141,
		qg  = \char"1141,   %% for compatibility
		xd	= \char"1142,
		xm	= \char"1143,
		xb	= \char"1144,
		xs	= \char"1145,
		xz	= \char"1146,
		xx	= \char"1147,
		xj	= \char"1148,
		xc	= \char"1149,
		xt 	= \char"114A,
		xp	= \char"114B,
		q	= \char"114C,
		jx	= \char"114D,
		jl	= \char"114E,
		jjl	= \char"114F,
		jlr	= \char"1150,
		jjlr	= \char"1151,
		ck	= \char"1152,
		ch	= \char"1153,
		cl	= \char"1154,
		clr	= \char"1155,
		pb	= \char"1156,
		px	= \char"1157,
		hh	= \char"1158,
		f	= \char"1159,
	%%% added version 0.4
		gd	= \char"115A,
		ns	= \char"115B,
		nj	= \char"115C,
		nh	= \char"115D,
		dr	= \char"115E,
	%%% Extended-A
		dm	= \char"A960,
		db	= \char"A961,
		ds	= \char"A962,
		dj	= \char"A963,
		rg	= \char"A964,
		rgg	= \char"A965,
		rd	= \char"A966,
		rdd	= \char"A967,
		rm	= \char"A968,
		rb	= \char"A969,
		rbb	= \char"A96A,
		rbx	= \char"A96B,
		rs	= \char"A96C,
		rj	= \char"A96D,
		rk	= \char"A96E,
		mg	= \char"A96F,
		md	= \char"A970,
		ms	= \char"A971,
		bst	= \char"A972,
		bk	= \char"A973,
		bh	= \char"A974,
		ssb	= \char"A975,
		xr	= \char"A976,
		xh	= \char"A977,
		jjh	= \char"A978,
		tt	= \char"A979,
		ph	= \char"A97A,
		hs	= \char"A97B,
		ff	= \char"A97C,
	%%% Choseong Filler
		w	= \char"115F
	}
}
{
	\prop_const_from_keyval:Nn \c_cho_prop
	{
		g 	= \char"1100,
		gg 	= \char"1101,
		n	= \char"1102,
		d	= \char"1103,
		dd	= \char"1104,
		r	= \char"1105,
		m	= \char"1106,
		b	= \char"1107,
		bb	= \char"1108,
		s	= \char"1109,
		ss	= \char"110A,
		q	= \char"110B,
		j	= \char"110C,
		jj	= \char"110D,
		c	= \char"110E,
		k	= \char"110F,
		t	= \char"1110,
		p	= \char"1111,
		h	= \char"1112,
		ng	= \char"1113,
		nn	= \char"1114,
		nd 	= \char"1115,
		nb	= \char"1116,
		dg	= \char"1117,
		rn	= \char"1118,
		rr	= \char"1119,
		rh	= \char"111A,
		rq	= \char"111B,
		mb	= \char"111C,
		mq 	= \char"111D,
		bg	= \char"111E,
		bn	= \char"111F,
		bd	= \char"1120,
		bs	= \char"1121,
		bsg	= \char"1122,
		bsd	= \char"1123,
		bsb	= \char"1124,
		bss	= \char"1125,
		bsj	= \char"1126,
		bj	= \char"1127,
		bc	= \char"1128,
		bt	= \char"1129,
		bp	= \char"112A,
		bq	= \char"112B,
		bbq	= \char"112C,
		sg	= \char"112D,
		sn	= \char"112E,
		sd	= \char"112F,
		sr	= \char"1130,
		sm	= \char"1131,
		sb	= \char"1132,
		sbg	= \char"1133,
		sss	= \char"1134,
		sf	= \char"1135,
		sj	= \char"1136,
		sc	= \char"1137,
		sk	= \char"1138,
		st	= \char"1139,
		sp	= \char"113A,
		sh	= \char"113B,
		sl	= \char"113C,
		ssl	= \char"113D,
		slr	= \char"113E,
		sslr	= \char"113F,
		z	= \char"1140,
		qg	= \char"1141,
		fg  = \char"1141,   %% for compatibility
		qd	= \char"1142,
		qm	= \char"1143,
		qb	= \char"1144,
		qs	= \char"1145,
		qz	= \char"1146,
		qq	= \char"1147,
		qj	= \char"1148,
		qc	= \char"1149,
		qt 	= \char"114A,
		qp	= \char"114B,
		f	= \char"114C,
		jq	= \char"114D,
		jl	= \char"114E,
		jjl	= \char"114F,
		jlr	= \char"1150,
		jjlr	= \char"1151,
		ck	= \char"1152,
		ch	= \char"1153,
		cl	= \char"1154,
		clr	= \char"1155,
		pb	= \char"1156,
		pq	= \char"1157,
		hh	= \char"1158,
		x	= \char"1159,
	%%% added version 0.4
		gd	= \char"115A,
		ns	= \char"115B,
		nj	= \char"115C,
		nh	= \char"115D,
		dr	= \char"115E,
	%%% Extended-A
		dm	= \char"A960,
		db	= \char"A961,
		ds	= \char"A962,
		dj	= \char"A963,
		rg	= \char"A964,
		rgg	= \char"A965,
		rd	= \char"A966,
		rdd	= \char"A967,
		rm	= \char"A968,
		rb	= \char"A969,
		rbb	= \char"A96A,
		rbq	= \char"A96B,
		rs	= \char"A96C,
		rj	= \char"A96D,
		rk	= \char"A96E,
		mg	= \char"A96F,
		md	= \char"A970,
		ms	= \char"A971,
		bst	= \char"A972,
		bk	= \char"A973,
		bh	= \char"A974,
		ssb	= \char"A975,
		qr	= \char"A976,
		qh	= \char"A977,
		jjh	= \char"A978,
		tt	= \char"A979,
		ph	= \char"A97A,
		hs	= \char"A97B,
		xx	= \char"A97C,
	%%% Choseong Filler
		w	= \char"115F
	}
}

\prop_const_from_keyval:Nn \c_jung_prop
{
	a	= \char"1161,
	ay	= \char"1162,
	ai	= \char"1162,
	ya	= \char"1163,
	yay	= \char"1164,
	yai	= \char"1164,
	e	= \char"1165,
	ey	= \char"1166,
	ei	= \char"1166,
	ye	= \char"1167,
	yey	= \char"1168,
	yei	= \char"1168,
	o	= \char"1169,
	oa	= \char"116A,
	oay	= \char"116B,
	oai	= \char"116B,
	oy	= \char"116C,
	oi	= \char"116C,
	yo	= \char"116D,
	u	= \char"116E,
	ue	= \char"116F,
	uey	= \char"1170,
	uei	= \char"1170,
	uy	= \char"1171,
	ui	= \char"1171,
	yu	= \char"1172,
	v	= \char"1173,
	vy	= \char"1174,
	vi	= \char"1174,
	i	= \char"1175,
	ao	= \char"1176,
	au	= \char"1177,
	yao	= \char"1178,
	yayo	= \char"1179,
	eo	= \char"117A,
	eu	= \char"117B,
	ev	= \char"117C,
	yeo	= \char"117D,
	yeu	= \char"117E,
	oe	= \char"117F,
	oey	= \char"1180,
	oei	= \char"1180,
	oyey	= \char"1181,
	oyei	= \char"1181,
	oo	= \char"1182,
	ou	= \char"1183,
	yoya	= \char"1184,
	yoyay	= \char"1185,
	yoyai	= \char"1185,
	yoye	= \char"1186,
	yoo	= \char"1187,
	yoi	= \char"1188,
	yoy = \char"1188,
	ua	= \char"1189,
	uay	= \char"118A,
	uai	= \char"118A,
	uev	= \char"118B,
	uyey	= \char"118C,
	uyei	= \char"118C,
	uu	= \char"118D,
	yua	= \char"118E,
	yue	= \char"118F,
	yuey	= \char"1190,
	yuei	= \char"1190,
	yuye	= \char"1191,
	yuyey	= \char"1192,
	yuyei	= \char"1192,
	yuu	= \char"1193,
	yui	= \char"1194,
	vu	= \char"1195,
	vv	= \char"1196,
	viu	= \char"1197,
	ia	= \char"1198,
	iya	= \char"1199,
	io	= \char"119A,
	iu	= \char"119B,
	iv	= \char"119C,
	i@	= \char"119D,
	@	= \char"119E,
	@e	= \char"119F,
	@u	= \char"11A0,
	@i	= \char"11A1,
	@@	= \char"11A2,
%% added 0.4
	av	= \char"11A3,
	yau	= \char"11A4,
	yeya = \char"11A5,
	oya	= \char"11A6,
	oyai = \char"11A7,
	oyay = \char"11A7,
%% extended-b
	oye	= \char"D7B0,
	ou	= \char"D7B1,
	yoa	= \char"D7B2,
	yoay	= \char"D7B3,
	yoai	= \char"D7B3,
	yoe	= \char"D7B4,
	uye	= \char"D7B5,
	uii	= \char"D7B6,
	yuay	= \char"D7B7,
	yuai	= \char"D7B7,
	yuo	= \char"D7B8,
	va	= \char"D7B9,
	ve	= \char"D7BA,
	vey	= \char"D7BB,
	vei	= \char"D7BB,
	vo	= \char"D7BC,
	iyao	= \char"D7BD,
	iyay	= \char"D7BE,
	iyai	= \char"D7BE,
	iye	= \char"D7BF,
	iyey	= \char"D7C0,
	iyei	= \char"D7C0,
	@iu	= \char"D7C1,
	iyo	= \char"D7C2,
	iyu	= \char"D7C3,
	ii	= \char"07C4,
	@a	= \char"D7C5,
	@ey	= \char"D7C6,
	@ei	= \char"D7C6,
%%% for avoiding errors,
%	ai	= \char"1162,
%	yai	= \char"1164,
%	ei 	= \char"1166,
%	yei	= \char"1168,
%	oi	= \char"116C,
%	ui	= \char"1171,
%	oai	= \char"116B,
%	uei	= \char"1170,
%	vy	= \char"1174,
%% Jungseong filler
	*	= \char"1160
}

\bool_if:NTF \g_compat_bool 
{
	\prop_const_from_keyval:Nn \c_jong_prop
	{
		g	= \char"11A8,
		gg	= \char"11A9,
		gs	= \char"11AA,
		n	= \char"11AB,
		nj	= \char"11AC,
		nh	= \char"11AD,
		d	= \char"11AE,
		r	= \char"11AF,
		rg	= \char"11B0,
		rm	= \char"11B1,
		rb	= \char"11B2,
		rs	= \char"11B3,
		rt	= \char"11B4,
		rp	= \char"11B5,
		rh	= \char"11B6,
		m	= \char"11B7,
		b	= \char"11B8,
		bs	= \char"11B9,
		s	= \char"11BA,
		ss	= \char"11BB,
		x	= \char"11BC,
		j	= \char"11BD,
		c	= \char"11BE,
		k	= \char"11BF,
		t	= \char"11C0,
		p	= \char"11C1,
		h	= \char"11C2,
		gr	= \char"11C3,
		gsg	= \char"11C4,
		ng	= \char"11C5,
		nd	= \char"11C6,
		ns	= \char"11C7,
		nz	= \char"11C8,
		nt	= \char"11C9,
		dg	= \char"11CA,
		dr	= \char"11CB,
		rgs	= \char"11CC,
		rn	= \char"11CD,
		rd	= \char"11CE,
		rdh	= \char"11CF,
		rr	= \char"11D0,
		rmg	= \char"11D1,
		rms	= \char"11D2,
		rbs	= \char"11D3,
		rbh	= \char"11D4,
		rbx	= \char"11D5,
		rss	= \char"11D6,
		rz	= \char"11D7,
		rk	= \char"11D8,
		rf	= \char"11D9,
		mg	= \char"11DA,
		mr	= \char"11DB,
		mb	= \char"11DC,
		ms	= \char"11DD,
		mss	= \char"11DE,
		mz	= \char"11DF,
		mc	= \char"11E0,
		mh	= \char"11E1,
		mx	= \char"11E2,
		br	= \char"11E3,
		bp	= \char"11E4,
		bh	= \char"11E5,
		bx	= \char"11E6,
		sg	= \char"11E7,
		sd	= \char"11E8,
		sr	= \char"11E9,
		sb	= \char"11EA,
		z	= \char"11EB,
		qg	= \char"11EC,
		qgg	= \char"11ED,
		qq	= \char"11EE,
		qk	= \char"11EF,
		q	= \char"11F0,
		qs	= \char"11F1,
		qz	= \char"11F2,
		pb	= \char"11F3,
		px	= \char"11F4,
		hn	= \char"11F5,
		hr	= \char"11F6,
		hm	= \char"11F7,
		hb	= \char"11F8,
		f	= \char"11F9,
	%% added 0.4
		gn	= \char"11FA,
		gb 	= \char"11FB,
		gc	= \char"11FC,
		gk	= \char"11FD,
		gh	= \char"11FE,
		nn	= \char"11FF,
	%% extended-b
	%% added 0.4
		nr	= \char"D7CB,
		nc	= \char"D7CC,
		dd	= \char"D7CD,
		ddb	= \char"D7CE,
		db	= \char"D7CF,
	%%%
		ds	= \char"D7D0,
		dsg	= \char"D7D1,
		dj	= \char"D7D2,
		dc	= \char"D7D3,
		dt	= \char"D7D4,
		rgg	= \char"D7D5,
		rgh	= \char"D7D6,
		rrz	= \char"D7D7,
		rmh	= \char"D7D8,
		rbd	= \char"D7D9,
		rbp	= \char"D7DA,
		rq	= \char"D7DB,
		rqh	= \char"D7DC,
		rx	= \char"D7DD,
		mn	= \char"D7DE,
		mnn	= \char"D7DF,
		mm	= \char"D7E0,
		mbs	= \char"D7E1,
		mj	= \char"D7E2,
		bd	= \char"D7E3,
		brp	= \char"D7E4,
		bm	= \char"D7E5,
		bb	= \char"D7E6,
		bsd	= \char"D7E7,
		bj	= \char"D7E8,
		bc	= \char"D7E9,
		sm	= \char"D7EA,
		sbx	= \char"D7EB,
		ssg	= \char"D7EC,
		ssd	= \char"D7ED,
		sz	= \char"D7EE,
		sj	= \char"D7EF,
		sc	= \char"D7F0,
		st	= \char"D7F1,
		sh	= \char"D7F2,
		zb	= \char"D7F3,
		zbx	= \char"D7F4,
		qm	= \char"D7F5,
		qh	= \char"D7F6,
		jb	= \char"D7F7,
		jbb	= \char"D7F8,
		jj	= \char"D7F9,
		ps	= \char"D7FA,
		pt	= \char"D7FB,
	%% tone markers
		;	= \char"302E,
		:	= \char"302F,
		|	= {}
	}
}
{
	\prop_const_from_keyval:Nn \c_jong_prop
	{
		g	= \char"11A8,
		gg	= \char"11A9,
		gs	= \char"11AA,
		n	= \char"11AB,
		nj	= \char"11AC,
		nh	= \char"11AD,
		d	= \char"11AE,
		r	= \char"11AF,
		rg	= \char"11B0,
		rm	= \char"11B1,
		rb	= \char"11B2,
		rs	= \char"11B3,
		rt	= \char"11B4,
		rp	= \char"11B5,
		rh	= \char"11B6,
		m	= \char"11B7,
		b	= \char"11B8,
		bs	= \char"11B9,
		s	= \char"11BA,
		ss	= \char"11BB,
		q	= \char"11BC,
		j	= \char"11BD,
		c	= \char"11BE,
		k	= \char"11BF,
		t	= \char"11C0,
		p	= \char"11C1,
		h	= \char"11C2,
		gr	= \char"11C3,
		gsg	= \char"11C4,
		ng	= \char"11C5,
		nd	= \char"11C6,
		ns	= \char"11C7,
		nz	= \char"11C8,
		nt	= \char"11C9,
		dg	= \char"11CA,
		dr	= \char"11CB,
		rgs	= \char"11CC,
		rn	= \char"11CD,
		rd	= \char"11CE,
		rdh	= \char"11CF,
		rr	= \char"11D0,
		rmg	= \char"11D1,
		rms	= \char"11D2,
		rbs	= \char"11D3,
		rbh	= \char"11D4,
		rbq	= \char"11D5,
		rss	= \char"11D6,
		rz	= \char"11D7,
		rk	= \char"11D8,
		rx	= \char"11D9,
		mg	= \char"11DA,
		mr	= \char"11DB,
		mb	= \char"11DC,
		ms	= \char"11DD,
		mss	= \char"11DE,
		mz	= \char"11DF,
		mc	= \char"11E0,
		mh	= \char"11E1,
		mq	= \char"11E2,
		br	= \char"11E3,
		bp	= \char"11E4,
		bh	= \char"11E5,
		bq	= \char"11E6,
		sg	= \char"11E7,
		sd	= \char"11E8,
		sr	= \char"11E9,
		sb	= \char"11EA,
		z	= \char"11EB,
		fg	= \char"11EC,
		fgg	= \char"11ED,
		ff	= \char"11EE,
		fk	= \char"11EF,
		f	= \char"11F0,
		fs	= \char"11F1,
		fz	= \char"11F2,
		pb	= \char"11F3,
		pq	= \char"11F4,
		hn	= \char"11F5,
		hr	= \char"11F6,
		hm	= \char"11F7,
		hb	= \char"11F8,
		x	= \char"11F9,
	%% added 0.4
		gn	= \char"11FA,
		gb 	= \char"11FB,
		gc	= \char"11FC,
		gk	= \char"11FD,
		gh	= \char"11FE,
		nn	= \char"11FF,
	%% extended-b
	%% added 0.4
		nr	= \char"D7CB,
		nc	= \char"D7CC,
		dd	= \char"D7CD,
		ddb	= \char"D7CE,
		db	= \char"D7CF,
	%%%
		ds	= \char"D7D0,
		dsg	= \char"D7D1,
		dj	= \char"D7D2,
		dc	= \char"D7D3,
		dt	= \char"D7D4,
		rgg	= \char"D7D5,
		rgh	= \char"D7D6,
		rrz	= \char"D7D7,
		rmh	= \char"D7D8,
		rbd	= \char"D7D9,
		rbp	= \char"D7DA,
		rf	= \char"D7DB,
		rfh	= \char"D7DC,
		rq	= \char"D7DD,
		mn	= \char"D7DE,
		mnn	= \char"D7DF,
		mm	= \char"D7E0,
		mbs	= \char"D7E1,
		mj	= \char"D7E2,
		bd	= \char"D7E3,
		brp	= \char"D7E4,
		bm	= \char"D7E5,
		bb	= \char"D7E6,
		bsd	= \char"D7E7,
		bj	= \char"D7E8,
		bc	= \char"D7E9,
		sm	= \char"D7EA,
		sbq	= \char"D7EB,
		ssg	= \char"D7EC,
		ssd	= \char"D7ED,
		sz	= \char"D7EE,
		sj	= \char"D7EF,
		sc	= \char"D7F0,
		st	= \char"D7F1,
		sh	= \char"D7F2,
		zb	= \char"D7F3,
		zbq	= \char"D7F4,
		fm	= \char"D7F5,
		fh	= \char"D7F6,
		jb	= \char"D7F7,
		jbb	= \char"D7F8,
		jj	= \char"D7F9,
		ps	= \char"D7FA,
		pt	= \char"D7FB,
	%% tone markers
		;	= \char"302E,
		:	= \char"302F,
		|	= {}
	}
}

%%%% underline
\NewDocumentCommand \jamoul { m m }
{
	\tl_set:Nn \l_pmulcmdnm_tl { #1 }
	\seq_set_split:Nnn \l_pmlli_seq { ~ } { #2 }
	\seq_map_indexed_function:NN \l_pmlli_seq \_tr_ulfn:nn
}

\cs_new:Npn \_tr_ulfn:nn #1 #2
{
	\tl_set:Nn \l_tmpz_tl { #2 }
	\regex_replace_all:nnN { \: } { \:\/ } \l_tmpz_tl
	\regex_replace_all:nnN { \; } { \;\/ } \l_tmpz_tl
	\seq_set_split:NnV \l_pmnni_seq { / } \l_tmpz_tl
	\seq_map_inline:Nn \l_pmnni_seq
	{
		\regex_match:nnT { [a-zA-Z] } { ##1 } 
		{
			\allowbreak
		}
		\exp_args:No \use:c { \l_pmulcmdnm_tl } { \jamoword { ##1 } }
	}
	\int_compare:nT { #1 < \seq_count:N \l_pmlli_seq }
	{
		\exp_args:No \use:c { \l_pmulcmdnm_tl } {~}
	}
}

\endinput

