% luatexko.sty
%
% Copyright (c) 2013-2021 Dohyun Kim <nomos at ktug org>
%                         Soojin Nam <jsunam at gmail com>
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% 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.3c or later is part of all distributions of LaTeX
% version 2006/05/20 or later.

\ifdefined\luatexkohangulfontattr \endinput\fi
\ifdefined\selectfont
  \NeedsTeXFormat{LaTeX2e}[2020/10/01]
  \ProvidesPackage{luatexko}[2021/04/20 v3.1 typesetting Korean with LuaTeX]
  \RequirePackage{luatexbase}
  \RequirePackage{fontspec}[2020/02/03]
\else
  \input luatexbase.sty
  \input luaotfload.sty
  \input atbegshi.sty
  \chardef\luatexkoatcatcode=\catcode`\@
  \catcode`\@=11
\fi
\newlanguage\koreanlanguage
\protected\def\pdfliteral{\pdfextension literal}
\newattribute\luatexkohangulfontattr
\newattribute\luatexkohanjafontattr
\newattribute\luatexkofallbackfontattr
\newattribute\luatexkoautojosaattr
\newattribute\luatexkoclassicattr
\newattribute\luatexkodotemphattr
\newattribute\luatexkoulineattr
\newattribute\luatexkorubyattr \chardef\luatexkorubyalloc\allocationnumber
\newattribute\luatexkohangulbyhangulattr
\newattribute\luatexkohanjabyhanjaattr
\directlua{ require"luatexko" }
\ifdefined\AtBegShi@Hook
  \edef\AtBegShi@Hook{% occupy the first position
    \unexpanded{%
      \AtBegShi@Item{%
        \directlua{%
          luatexko.process_atbegshi(tex.getbox(\the\AtBeginShipoutBox))
        }%
      }%
    }%
    \unexpanded\expandafter{\AtBegShi@Hook}%
  }
\else
  \AddToHook{shipout/before}{%
    \directlua{ luatexko.process_atbegshi(tex.getbox(\the\ShipoutBox)) }%
  }
  \DeclareHookRule{shipout/before}{.}{before}{luacolor}
\fi
% classic
\protected\def\typesetclassic{% 0
  \ifnum\luatexkoclassicattr<\z@
    \luatexkoclassicattr\z@
    \parindent1em
  \fi
  }
\protected\def\typesetvertical{% 1
  \ifcase\luatexkoclassicattr
    \luatexkoclassicattr\@ne
    \parindent1em
  \or
  \or
    \luatexkoclassicattr\@ne
  \or
    \luatexkoclassicattr=4\relax
  \or
  \else
    \luatexkoclassicattr\@ne
    \parindent1em
  \fi
  }
\protected\def\typesetmodern{\unsetattribute\luatexkoclassicattr}
\protected\def\inhibitglue{\hskip\z@skip}
\protected\def\Schinese{% 2, 1
  \ifcase\luatexkoclassicattr
    \luatexkoclassicattr\tw@
  \or
  \or
  \or
    \luatexkoclassicattr\tw@
  \or
    \luatexkoclassicattr\@ne
  \else
    \luatexkoclassicattr\tw@
  \fi
  \parindent2em
  }
\protected\def\Tchinese{% 3, 4
  \ifcase\luatexkoclassicattr
    \luatexkoclassicattr\thr@@
  \or
    \luatexkoclassicattr=4\relax
  \or
    \luatexkoclassicattr\thr@@
  \or
  \or
  \else
    \luatexkoclassicattr\thr@@
  \fi
  \parindent2em
  }
\let\korean\typesetmodern \let\japanese\typesetclassic \let\chinese\Schinese
% josa
\count@"AC00
\loop
  \catcode\count@ 12
  \ifnum\count@<"D7A3 \advance\count@\@ne \repeat
\newcount\josaignoreparens
\def\luatexkojosaactivate{%
  \ifx\luatexkojosaactive\relax
  \else
    \directlua{ luatexko.activate("autojosa") }%
    \global\let\luatexkojosaactive\relax
  \fi
  \luatexkoautojosaattr\josaignoreparens }
\protected\def\은{\begingroup\luatexkojosaactivate 은\endgroup}
\let\는\은
\protected\def\을{\begingroup\luatexkojosaactivate 을\endgroup}
\let\를\을
\protected\def\와{\begingroup\luatexkojosaactivate 와\endgroup}
\let\과\와
\protected\def\가{\begingroup\luatexkojosaactivate 가\endgroup}
\protected\def\이{\begingroup\luatexkojosaactivate 이\endgroup}
\protected\def\라{\이라}
\protected\def\으{\begingroup\luatexkojosaactivate 으\endgroup}
\protected\def\로{\으로}
% force hangul font
\def\luatexkotoks@appendchars#1,{%
  \ifx\empty#1\empty
    \expandafter\luatexkotoks@appendchars
  \else
    \ifx*#1\else
      \expandafter\ifx\expandafter\empty\the\toks@\empty
        \etoksapp0{\number#1}%
      \else
        \etoksapp0{,\number#1}%
      \fi
      \expandafter\expandafter\expandafter\luatexkotoks@appendchars
    \fi
  \fi }
\def\luatexkodoluacode#1{\directlua{
  \ifhmode luatexko.updateforcehangul(function() \fi
  #1
  \ifhmode end) \fi }}
\protected\def\registerpunctuations#1{%
  \toks@{}\luatexkotoks@appendchars#1,*,\luatexkodoluacode{
    local t = luatexko.forcehangulchars
    for _,v in ipairs{\the\toks@} do t[v]=true end }}
\let\registerhangulpunctuations\registerpunctuations
\protected\def\unregisterpunctuations#1{%
  \toks@{}\luatexkotoks@appendchars#1,*,\luatexkodoluacode{
    local t = luatexko.forcehangulchars
    for _,v in ipairs{\the\toks@} do t[v]=nil end }}
\let\unregisterhangulpunctuations\unregisterpunctuations
\protected\def\hangulpunctuations{%
  \afterassignment\luatexkohangulpunctuations\count@ }
\def\luatexkohangulpunctuations{\luatexkodoluacode{
  local t = luatexko.forcehangulchars
  for i in pairs(t) do t[i]=\ifcase\count@ false \else true \fi end }}
% breakable before/after (affects entire paragraph and all after)
\protected\def\registerbreakableafter#1{%
  \toks@{}\luatexkotoks@appendchars#1,*,\directlua{
    local t = luatexko.breakableafter
    for _,v in ipairs{\the\toks@} do t[v]=true end }}
\protected\def\registerbreakablebefore#1{%
  \toks@{}\luatexkotoks@appendchars#1,*,\directlua{
    local t = luatexko.breakablebefore
    for _,v in ipairs{\the\toks@} do t[v]=true end }}
% hangulbyhangul/hanjabyhanja font
\protected\def\hangulbyhangulfont{%
  \afterassignment\luatexkohangulbyhangulfont\count@ }
\def\luatexkohangulbyhangulfont{%
  \ifcase\count@ \unsetattribute\luatexkohangulbyhangulattr
  \else \luatexkohangulbyhangulattr\count@
  \fi }
\protected\def\hanjabyhanjafont{%
  \afterassignment\luatexkohanjabyhanjafont\count@ }
\def\luatexkohanjabyhanjafont{%
  \ifcase\count@ \unsetattribute\luatexkohanjabyhanjaattr
  \else \luatexkohanjabyhanjaattr\count@
  \fi }
% dotemph
\newcount\luatexkodotemphcount
\def\dotemphraise{1ex }
\unless\ifdefined\bfseries\let\bfseries\bf\fi
\def\dotemphchar{\bfseries\char"02D9 }
\protected\def\dotemph#1{%
  \global\advance\luatexkodotemphcount\@ne
  \begingroup
  \setbox\z@\hbox{\raise\dotemphraise\hbox{\dotemphchar}}%
  \directlua{
    if \the\luatexkodotemphcount == 1 then luatexko.activate("dotemph") end
    luatexko.dotemphbox[\the\luatexkodotemphcount] = node.copy(tex.box[0])
  }\luatexkodotemphattr\luatexkodotemphcount #1%
  \directlua{
    luatexko.dotemphboundary(\the\luatexkodotemphattr)
  }%
  \endgroup }
% uline
\newcount\luatexkoulinecount
\def\ulinedown{0.5ex }\def\ulinewidth{0.04em }
\protected\def\markoverwith#1#{%
  \ifx\empty#1\empty
    \def\luatexkoleaderstype{101}% cleaders
  \else
    \def\luatexkoleaderstype{102}% xleaders
  \fi
  \luatexkomarkoverwith }
\def\luatexkomarkoverwith#1#2{%
  \global\advance\luatexkoulinecount\@ne
  \begingroup
  \leavevmode
  \setbox\z@\hbox{#1}%
  \directlua{
    if \the\luatexkoulinecount == 1 then luatexko.activate("uline") end
    luatexko.ulboundary(\the\luatexkoulinecount,
                        tex.box[0].list,
                        \luatexkoleaderstype)
  }%
  \luatexkoulineattr\luatexkoulinecount #2\relax
  \directlua{
    luatexko.ulboundary(\the\luatexkoulineattr)
  }\endgroup }
\protected\def\uline{\markoverwith{%
  \vrule width\z@ height-\ulinedown depth\dimexpr\ulinedown+\ulinewidth\relax }}
\protected\def\dashuline{\markoverwith*{%
  \hbox{\kern.125em
    \vrule width.3em height-\ulinedown depth\dimexpr\ulinedown+\ulinewidth\relax
    \kern.125em }}}
\protected\def\dotuline{\markoverwith*{%
  \lower\dimexpr\ulinedown+.2ex\relax\hbox{\kern.07em .\kern.07em }}}
\protected\def\uuline{\markoverwith{%
    \lower\ulinedown\vtop{%
      \hrule width .2em height\z@ depth\ulinewidth
      \kern .15ex
      \hrule width .2em height\z@ depth\ulinewidth
    }%
}}
\protected\def\sout#1{%
  \begingroup
  \setbox\z@\hbox{#1}%
  \edef\soutdown{%
    \the\dimexpr
    \directlua{ tex.sprint(luatexko.get_strike_out_down(tex.box[0])) }sp
    -.5\dimexpr\ulinewidth\relax \relax
  }%
  \markoverwith{%
    \vrule width  \z@
    height-\soutdown
    depth  \dimexpr\soutdown+\ulinewidth\relax
  }%
  {#1}%
  \endgroup
}
\protected\def\xout{\markoverwith{\hbox to.4em{\hss/\hss}}}
\protected\def\uwave{\font\luatexkofontsixly=lasy6\relax
  \markoverwith{\lower4\p@\hbox{\luatexkofontsixly\char58}}}
% ruby
\def\rubysize{0.6}  % size of ruby compared to base chars
\def\rubysep{0.1ex} % distance between base chars and ruby
\def\luatexkostretchfactor{.0125} % .5em/20/2 is hard coded.
\newif\ifruby@overlap
\let\rubyoverlap\ruby@overlaptrue
\let\rubynooverlap\ruby@overlapfalse
\rubyoverlap % ruby may hangover neighboring chars
\newcount\luatexkorubycount
\def\luatexkorubybasehbox{\hbox attr\luatexkorubyalloc=\luatexkorubycount}
\protected\def\ruby#1#2{%
  \global\advance\luatexkorubycount\@ne
  \begingroup
  \leavevmode
  \setbox\z@\luatexkorubybasehbox{#1}% base
  \setbox\tw@\hbox{% ruby
    \ifdefined\rubyfont \rubyfont \fi
    \ifdefined\selectfont % <- latex
      \dimen@\dimexpr\rubysize em\relax
      \fontsize\dimen@\dimen@\selectfont
    \fi
    #2}%
  \hbadness\@M % supress underfull warning
  \dimen@ii\dimexpr\rubysize em\relax % ruby font size
  \directlua{ luatexko.getrubystretchfactor(tex.box[2]) }% for intercharstretch
  \ifdim\wd\z@ < \wd\tw@ % ruby is wider
    \ifruby@overlap
      \dimen@\dimexpr\wd\tw@-\wd\z@-\dimen@ii\relax % overhang .5 rubysize
      \ifdim\dimen@ > \z@
        \setbox\z@\luatexkorubybasehbox spread\dimen@{%
          \hskip\z@ plus \luatexkostretchfactor em\relax
          \unhbox\z@
          \hskip\z@ plus \luatexkostretchfactor em\relax }%
      \fi
    \else
      \setbox\z@\luatexkorubybasehbox to\wd\tw@{%
        \hskip\z@ plus \luatexkostretchfactor em\relax
        \unhbox\z@
        \hskip\z@ plus \luatexkostretchfactor em\relax }%
    \fi
  \else
    \ifdim\rubysize\wd\z@ > 2\wd\tw@ % ruby is far shorter
      \setbox\tw@\hbox to\wd\z@{%
        \hskip\dimen@ii plus 1sp\relax
        \unhbox\tw@
        \hskip\dimen@ii plus 1sp\relax }%
    \else
      \setbox\tw@\hbox to\wd\z@{%
        \hskip\z@ plus \luatexkostretchfactor \dimen@ii\relax
        \unhbox\tw@
        \hskip\z@ plus \luatexkostretchfactor \dimen@ii\relax }%
    \fi
  \fi
  \directlua{
    if \the\luatexkorubycount == 1 then luatexko.activate("ruby") end
    luatexko.rubybox[\the\luatexkorubycount] = {
      node.copy(tex.box[2]),
      \number\numexpr\dimexpr\rubysep\relax\relax,
      \ifruby@overlap true\else false\fi, }}%
  \box\z@
  \endgroup }
\protected\def\xxruby#1#2{%
  \begingroup\def\basestr{#1}\def\rubystr{#2}\luatexkoxxruby\endgroup }
\def\luatexkoxxruby{%
  \ifx\empty\basestr\else
    \expandafter\luatexkogetrubybasechar\basestr\end
    \expandafter\luatexkogetrubyrubychar\rubystr\end
    \ruby\basechar\rubychar
    \expandafter\luatexkoxxruby
  \fi }
\def\luatexkogetrubybasechar#1#2\end{\def\basechar{#1}\def\basestr{#2}}
\def\luatexkogetrubyrubychar#1#2\end{\def\rubychar{#1}\def\rubystr{#2}}
% vertical writing
\protected\def\vertical#1{%
  \leavevmode
  \setbox\z@\vbox\bgroup
    \hsize#1\relax
    \typesetvertical }
\protected\def\endvertical{%
  \egroup
  \luatexkorotatebox\z@
  \box\z@ }
\protected\def\luatexkorotatebox#1{%
  \setbox#1\hbox to\dimexpr\ht#1+\dp#1{%
    \hfil
    \vbox to\wd#1{%
      \wd#1\z@ \ht#1\z@ \dp#1\z@
      \pdfliteral{q 0 -1 1 0 0 0 cm}\box#1\pdfliteral{Q}%
      \vfil }}}
% horizontal box inside vertical writing
\def\luatexkohorizboxmoveright{0.5ex}
\protected\def\horizontal#1{%
  \directlua{ luatexko.gethorizboxmoveright() }%
  \leavevmode
  \setbox\z@\vbox\bgroup
    \hsize#1\relax
    \typesetmodern }
\protected\def\endhorizontal{%
  \egroup
  \dimen@=\dimexpr.5\wd\z@-\luatexkohorizboxmoveright\relax
  \luatexkounrotatebox\z@
  \lower\dimen@\box\z@ }
\protected\def\luatexkounrotatebox#1{%
  \setbox#1\hbox to\dimexpr\ht#1+\dp#1{%
    \vbox to\wd#1{%
      \vfil
      \wd#1\z@ \ht#1\z@ \dp#1\z@
      \pdfliteral{q 0 1 -1 0 0 0 cm}\box#1\pdfliteral{Q}}%
    \hfil }}
% do not veticalize headline/footline
\ifdefined\selectfont
  \def\verticaltypesetting{%
    \maxdepth\z@ \typesetvertical
    \dimen@\textwidth \textwidth\textheight \textheight\dimen@
    \edef\@outputpage{\unexpanded{\luatexkorotatebox\@outputbox
    \textwidth\textheight}\unexpanded\expandafter{\@outputpage}}}
\else
  \def\verticaltypesetting{%
    \dimen@\hsize \hsize\vsize \vsize\dimen@
    \edef\plainoutput{\unexpanded{\dimen@\hsize \hsize\vsize \vsize\dimen@}%
      \unexpanded\expandafter{\plainoutput}}%
    \def\pagebody{\setbox\z@\vbox to\hsize{\boxmaxdepth=\maxdepth
      \pagecontents}\luatexkorotatebox\z@\box\z@}%
    \maxdepth\z@ \typesetvertical }
\fi
% hangul normalize
\def\luatexhangulnormalize{%
  \directlua{require"luatexko-normalize"}%
  \afterassignment\luatexkohangulnormalize\count@}
\def\luatexkohangulnormalize{%
  \ifcase\count@ \directlua{ luatexko.normalize.unload() }% 0: none
  \or \directlua{ luatexko.normalize.compose() }% 1: nfc
  \else \directlua{ luatexko.normalize.decompose() }% 2: nfd
  \fi }
% convert uhc to utf8
\def\luatexuhcinputencoding{%
  \directlua{require"luatexko-uhc2utf8"}%
  \afterassignment\luatexkouhcinputencoding\count@}
\def\luatexkouhcinputencoding{%
  \ifcase\count@ \directlua{ luatexko.uhc2utf8.stopconvert() }%
  \else \directlua{ luatexko.uhc2utf8.startconvert() }%
  \fi}
% math hangul
\def\setmathhangulblock#1#2{%
  \count@="#1
  \loop
    \Umathcode\count@ = 7 \symmathhangul\count@
    \ifnum\count@<"#2 \advance\count@\@ne \repeat}
% font fallback
\newif\ifluatexkoselectfontrunning
\def\luatexkohangulselectfont{%
  \ifluatexkoselectfontrunning \else
    \ifdefined\luatexkohangulfont
      \begingroup
      \luatexkoselectfontrunningtrue
      \luatexkohangulfont
      \expandafter\expandafter\expandafter\endgroup
      \expandafter\luatexkohangulfontattr\fontid\font\relax
    \fi
  \fi }
\def\luatexkohanjaselectfont{%
  \ifluatexkoselectfontrunning \else
    \ifdefined\luatexkohanjafont
      \begingroup
      \luatexkoselectfontrunningtrue
      \luatexkohanjafont
      \expandafter\expandafter\expandafter\endgroup
      \expandafter\luatexkohanjafontattr\fontid\font\relax
    \fi
  \fi }
\def\luatexkofallbackselectfont{%
  \ifluatexkoselectfontrunning \else
    \ifdefined\luatexkofallbackfont
      \begingroup
      \luatexkoselectfontrunningtrue
      \luatexkofallbackfont
      \expandafter\expandafter\expandafter\endgroup
      \expandafter\luatexkofallbackfontattr\fontid\font\relax
    \fi
  \fi }
% plain
\ifdefined\selectfont\else
  \protected\def\hangulfont{%
    \afterassignment\luatexkohangulselectfont\font\luatexkohangulfont}
  \protected\def\hanjafont{%
    \afterassignment\luatexkohanjaselectfont\font\luatexkohanjafont}
  \protected\def\fallbackfont{%
    \afterassignment\luatexkofallbackselectfont\font\luatexkofallbackfont}
  \newfam\symmathhangul
  \protected\def\setmathhangulfonts#1#2#3{% font identifiers
    \ifnum\Umathcharfam"AC00=\symmathhangul\else
      \setmathhangulblock{AC00}{D7A3}%
    \fi
    \textfont\symmathhangul=#1\relax
    \scriptfont\symmathhangul=#2\relax
    \scriptscriptfont\symmathhangul=#3\relax }
  \protected\def\mathhangulfont{%
    \afterassignment\luatexkosetmathhangulfonts\font\textmathhangul}
  \def\luatexkosetmathhangulfonts{%
    \toks@\expandafter{\directlua{
      local n = tex.fontname(font.id"textmathhangul"):gsub(" at .+", "")
      tex.sprint(string.unquoted(n)) }}%
    \dimen@\fontdimen 6 \textmathhangul
    \font\scriptmathhangul= {\the\toks@} at .7\dimen@
    \font\scriptscriptmathhangul = {\the\toks@} at .5\dimen@
    \setmathhangulfonts\textmathhangul\scriptmathhangul\scriptscriptmathhangul}
  \catcode`\@=\luatexkoatcatcode
\endinput\fi
% latex
\IfHookExistsTF{selectfont}{
  \AddToHook{selectfont}{%
    \luatexkohangulselectfont
    \luatexkohanjaselectfont
    \luatexkofallbackselectfont }
}{
  \RequirePackage{everysel}
  \EverySelectfont{%
    \luatexkohangulselectfont
    \luatexkohanjaselectfont
    \luatexkofallbackselectfont }
}
\AddToHook{rmfamily}{%
  \let\luatexkohangulfont  \luatexkomainhangulfont
  \let\luatexkohanjafont   \luatexkomainhanjafont
  \let\luatexkofallbackfont\luatexkomainfallbackfont
}
\AddToHook{sffamily}{%
  \let\luatexkohangulfont  \luatexkosanshangulfont
  \let\luatexkohanjafont   \luatexkosanshanjafont
  \let\luatexkofallbackfont\luatexkosansfallbackfont
}
\AddToHook{ttfamily}{%
  \let\luatexkohangulfont  \luatexkomonohangulfont
  \let\luatexkohanjafont   \luatexkomonohanjafont
  \let\luatexkofallbackfont\luatexkomonofallbackfont
}
\AddToHook{normalfont}{%
  \let\luatexkohangulfont  \luatexkodefaulthangulfont
  \let\luatexkohanjafont   \luatexkodefaulthanjafont
  \let\luatexkofallbackfont\luatexkodefaultfallbackfont
}
% fontspec-like
\ExplSyntaxOn
\cs_new_nopar:Npn \l_luatexko_silent_upshape {
  \tl_map_inline:nn { \mddefault \bfdefault }
  {
    \cs_if_exist:cF
    { \g_fontspec_encoding_tl/\l_fontspec_family_tl/##1/\updefault }
    {
      \cs_if_exist:cT
      { \g_fontspec_encoding_tl/\l_fontspec_family_tl/##1/\shapedefault }
      {
        \cs_set_eq:cc
        { \g_fontspec_encoding_tl/\l_fontspec_family_tl/##1/\updefault }
        { \g_fontspec_encoding_tl/\l_fontspec_family_tl/##1/\shapedefault }
      }
    }
  }
}
\DeclareDocumentCommand \setmainhangulfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomainhangulfamily { Ligatures=TeX, #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkomainhangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomainhangulfamily \selectfont
  }
  \str_if_eq:eeT \familydefault \rmdefault
  {
    \cs_set_eq:NN \luatexkodefaulthangulfont \luatexkomainhangulfont
    \cs_set_eq:NN \luatexkohangulfont \luatexkomainhangulfont
    \luatexkohangulselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \setsanshangulfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkosanshangulfamily { Ligatures=TeX, #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkosanshangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkosanshangulfamily \selectfont
  }
  \str_if_eq:eeT \familydefault \sfdefault
  {
    \cs_set_eq:NN \luatexkodefaulthangulfont \luatexkosanshangulfont
    \cs_set_eq:NN \luatexkohangulfont \luatexkosanshangulfont
    \luatexkohangulselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \setmonohangulfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomonohangulfamily { #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkomonohangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomonohangulfamily \selectfont
  }
  \str_if_eq:eeT \familydefault \ttdefault
  {
    \cs_set_eq:NN \luatexkodefaulthangulfont \luatexkomonohangulfont
    \cs_set_eq:NN \luatexkohangulfont \luatexkomonohangulfont
    \luatexkohangulselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \newhangulfontfamily { m O{} m O{} }
{
  \fontspec_set_family:cnn { luatexko_user_family_ \cs_to_str:N #1 } { #2, #4 } { #3 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn #1
  {
    \cs_set_nopar:Npn \luatexkohangulfont
    {
      \fontencoding \g_fontspec_encoding_tl
      \exp_args:Nc \fontfamily { luatexko_user_family_ \cs_to_str:N #1 } \selectfont
    }
    \luatexkohangulselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \newhangulfontface { m O{} m O{} }
{
  \newhangulfontfamily #1 { #3 } [ BoldFont={}, ItalicFont={}, SmallCapsFont={}, #2, #4 ]
}
\DeclareDocumentCommand \hangulfontspec { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkohangulfontfamily { #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_nopar:Npn \luatexkohangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkohangulfontfamily \selectfont
  }
  \luatexkohangulselectfont
  \ignorespaces
}
\DeclareDocumentCommand \setmainhanjafont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomainhanjafamily { Ligatures=TeX, #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkomainhanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomainhanjafamily \selectfont
  }
  \str_if_eq:eeT \familydefault \rmdefault
  {
    \cs_set_eq:NN \luatexkodefaulthanjafont \luatexkomainhanjafont
    \cs_set_eq:NN \luatexkohanjafont \luatexkomainhanjafont
    \luatexkohanjaselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \setsanshanjafont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkosanshanjafamily { Ligatures=TeX, #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkosanshanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkosanshanjafamily \selectfont
  }
  \str_if_eq:eeT \familydefault \sfdefault
  {
    \cs_set_eq:NN \luatexkodefaulthanjafont \luatexkosanshanjafont
    \cs_set_eq:NN \luatexkohanjafont \luatexkosanshanjafont
    \luatexkohanjaselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \setmonohanjafont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomonohanjafamily { #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkomonohanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomonohanjafamily \selectfont
  }
  \str_if_eq:eeT \familydefault \ttdefault
  {
    \cs_set_eq:NN \luatexkodefaulthanjafont \luatexkomonohanjafont
    \cs_set_eq:NN \luatexkohanjafont \luatexkomonohanjafont
    \luatexkohanjaselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \newhanjafontfamily { m O{} m O{} }
{
  \fontspec_set_family:cnn { luatexko_user_family_ \cs_to_str:N #1 } { #2, #4 } { #3 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn #1
  {
    \cs_set_nopar:Npn \luatexkohanjafont
    {
      \fontencoding \g_fontspec_encoding_tl
      \exp_args:Nc \fontfamily { luatexko_user_family_ \cs_to_str:N #1 } \selectfont
    }
    \luatexkohanjaselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \newhanjafontface { m O{} m O{} }
{
  \newhanjafontfamily #1 { #3 } [ BoldFont={}, ItalicFont={}, SmallCapsFont={}, #2, #4 ]
}
\DeclareDocumentCommand \hanjafontspec { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkohanjafontfamily { #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_nopar:Npn \luatexkohanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkohanjafontfamily \selectfont
  }
  \luatexkohanjaselectfont
  \ignorespaces
}

\DeclareDocumentCommand \setmainfallbackfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomainfallbackfamily { Ligatures=TeX, #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkomainfallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomainfallbackfamily \selectfont
  }
  \str_if_eq:eeT \familydefault \rmdefault
  {
    \cs_set_eq:NN \luatexkodefaultfallbackfont \luatexkomainfallbackfont
    \cs_set_eq:NN \luatexkofallbackfont \luatexkomainfallbackfont
    \luatexkofallbackselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \setsansfallbackfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkosansfallbackfamily { Ligatures=TeX, #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkosansfallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkosansfallbackfamily \selectfont
  }
  \str_if_eq:eeT \familydefault \sfdefault
  {
    \cs_set_eq:NN \luatexkodefaultfallbackfont \luatexkosansfallbackfont
    \cs_set_eq:NN \luatexkofallbackfont \luatexkosansfallbackfont
    \luatexkofallbackselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \setmonofallbackfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomonofallbackfamily { #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn \luatexkomonofallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomonofallbackfamily \selectfont
  }
  \str_if_eq:eeT \familydefault \ttdefault
  {
    \cs_set_eq:NN \luatexkodefaultfallbackfont \luatexkomonofallbackfont
    \cs_set_eq:NN \luatexkofallbackfont \luatexkomonofallbackfont
    \luatexkofallbackselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \newfallbackfontfamily { m O{} m O{} }
{
  \fontspec_set_family:cnn { luatexko_user_family_ \cs_to_str:N #1 } { #2, #4 } { #3 }
  \l_luatexko_silent_upshape
  \cs_set_protected_nopar:Npn #1
  {
    \cs_set_nopar:Npn \luatexkofallbackfont
    {
      \fontencoding \g_fontspec_encoding_tl
      \exp_args:Nc \fontfamily { luatexko_user_family_ \cs_to_str:N #1 } \selectfont
    }
    \luatexkofallbackselectfont
  }
  \ignorespaces
}
\DeclareDocumentCommand \newfallbackfontface { m O{} m O{} }
{
  \newfallbackfontfamily #1 { #3 } [ BoldFont={}, ItalicFont={}, SmallCapsFont={}, #2, #4 ]
}
\DeclareDocumentCommand \fallbackfontspec { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkofallbackfontfamily { #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \cs_set_nopar:Npn \luatexkofallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkofallbackfontfamily \selectfont
  }
  \luatexkofallbackselectfont
  \ignorespaces
}
\DeclareDocumentCommand \setmathhangulfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomathhangulfamily { #1, #3 } { #2 }
  \l_luatexko_silent_upshape
  \DeclareSymbolFont { mathhangul }
    \g_fontspec_encoding_tl \luatexkomathhangulfamily \mddefault \updefault
  \int_compare:nNnF { \Umathcharfam"AC00 } = { \symmathhangul }
  {
    \setmathhangulblock{AC00}{D7A3}
  }
  \ignorespaces
}
\ExplSyntaxOff
\let\adhochangulfont\hangulfontspec
\let\adhochanjafont\hanjafontspec
\let\adhocfallbackfont\fallbackfontspec
% interhangul, interlatincjk, charraise
\def\luatexkosilentupshape{%
  \@tfor \@tempa := \mddefault \bfdefault \do {%
    \ifcsname \f@encoding/\f@family/\@tempa/\updefault\endcsname \else
    \ifcsname \f@encoding/\f@family/\@tempa/\shapedefault\endcsname
      \global \expandafter\let
        \csname \f@encoding/\f@family/\@tempa/\updefault \expandafter\endcsname
        \csname \f@encoding/\f@family/\@tempa/\shapedefault\endcsname
    \fi\fi
  }%
}
\protected\def\addhangulfontfeature#1{%
  \begingroup
  \ifdefined\luatexkohangulfont
    \fontseries\mddefault\fontshape\shapedefault \luatexkohangulfont \fi
  \addfontfeature{#1}%
  \luatexkosilentupshape
  \edef\x{\endgroup
    \def\noexpand\luatexkohangulfont{%
      \noexpand\fontencoding{\UTFencname}%
      \noexpand\fontfamily{\f@family}\noexpand\selectfont}}\x
  \luatexkohangulselectfont
  \ignorespaces}
\let\addhangulfontfeatures\addhangulfontfeature
\protected\def\addhanjafontfeature#1{%
  \begingroup
  \ifdefined\luatexkohanjafont
    \fontseries\mddefault\fontshape\shapedefault \luatexkohanjafont \fi
  \addfontfeature{#1}%
  \luatexkosilentupshape
  \edef\x{\endgroup
    \def\noexpand\luatexkohanjafont{%
      \noexpand\fontencoding{\UTFencname}%
      \noexpand\fontfamily{\f@family}\noexpand\selectfont}}\x
  \luatexkohanjaselectfont
  \ignorespaces}
\let\addhanjafontfeatures\addhanjafontfeature
\protected\def\addfallbackfontfeature#1{%
  \begingroup
  \ifdefined\luatexkofallbackfont
    \fontseries\mddefault\fontshape\shapedefault \luatexkofallbackfont \fi
  \addfontfeature{#1}%
  \luatexkosilentupshape
  \edef\x{\endgroup
    \def\noexpand\luatexkofallbackfont{%
      \noexpand\fontencoding{\UTFencname}%
      \noexpand\fontfamily{\f@family}\noexpand\selectfont}}\x
  \luatexkofallbackselectfont
  \ignorespaces}
\let\addfallbackfontfeatures\addfallbackfontfeature
\newfontfeature{InterHangul}{interhangul=#1}
\newfontfeature{InterLatinCJK}{interlatincjk=#1}
\newfontfeature{CharRaise}{charraise=#1}
\newfontfeature{RemoveClassicSpaces}{+removeclassicspaces}
\newfontfeature{CompressPunctuations}{+compresspunctuations}
\newfontfeature{Expansion}{expansion=\ifx\empty#1\empty default\else #1\fi }
\newfontfeature{Protrusion}{protrusion=\ifx\empty#1\empty default\else #1\fi }
\newfontfeature{InterCharacter}{intercharacter=#1}
\newfontfeature{InterCharStretch}{intercharstretch=#1}
% italic correction
\def\nocorrlist{,.^^^^3001^^^^3002^^^^ff0c^^^^ff0e^^^^ff61^^^^ff64}
% package options
\newif\if@hangul
\newif\if@hanja
\DeclareOption{hangul}{\@hangultrue}
\DeclareOption{hanja}{\@hangultrue\@hanjatrue}
\ProcessOptions\relax
\AtBeginDocument{
  % default hangul fonts
  \ifdefined\luatexkomainhangulfont\else
    \begingroup\rmfamily
    \directlua{ luatexko.currenthashangulchars(255) }\expandafter\endgroup
    \ifnum\count@=\z@
      \IfFontExistsTF{UnBatang.ttf}
        {\setmainhangulfont{UnBatang}[Script=Hangul,Language=Korean]}
        {}
    \fi
  \fi
  \ifdefined\luatexkosanshangulfont\else
    \begingroup\sffamily
    \directlua{ luatexko.currenthashangulchars(255) }\expandafter\endgroup
    \ifnum\count@=\z@
      \IfFontExistsTF{UnDotum.ttf}{\setsanshangulfont{UnDotum}}{}
    \fi
  \fi
  \ifdefined\luatexkomonohangulfont\else
    \begingroup\ttfamily
    \directlua{ luatexko.currenthashangulchars(255) }\expandafter\endgroup
    \ifnum\count@=\z@
      \def\@tempa{lmtt}\def\@tempb{LatinModernMono(0)}
      \ifnum 0\ifx\ttdefault\@tempa 1\else\ifx\ttdefault\@tempb 1\fi\fi >\z@
        \IfFontExistsTF{UnDotum.ttf}
          {\setmonohangulfont{UnDotum}[
            UprightFeatures={SizeFeatures={
              {Size={-8.5},   FakeStretch=1.062},
              {Size={8.5-11}, FakeStretch=1.05 },
              {Size={11-},    FakeStretch=1.03 }}},
            BoldFeatures={SizeFeatures={
              {Size={-},      FakeStretch=1.05}}},
            WordSpace={1.66667,0,0}]
          }
          {\let\luatexkomonohangulfont\luatexkosanshangulfont }
      \else
        \let\luatexkomonohangulfont\luatexkosanshangulfont
      \fi
    \fi
  \fi
  % just in case, reset luatexkodefault...font
  \edef\famdef@ult{\familydefault}
  \ifx\famdef@ult\sfdefault
    \let\luatexkodefaulthangulfont  \luatexkosanshangulfont
    \let\luatexkodefaulthanjafont   \luatexkosanshanjafont
    \let\luatexkodefaultfallbackfont\luatexkosansfallbackfont
  \else\ifx\famdef@ult\ttdefault
    \let\luatexkodefaulthangulfont  \luatexkomonohangulfont
    \let\luatexkodefaulthanjafont   \luatexkomonohanjafont
    \let\luatexkodefaultfallbackfont\luatexkomonofallbackfont
  \else
    \let\luatexkodefaulthangulfont  \luatexkomainhangulfont
    \let\luatexkodefaulthanjafont   \luatexkomainhanjafont
    \let\luatexkodefaultfallbackfont\luatexkomainfallbackfont
  \fi\fi
  % hyperref
  \@ifpackageloaded{hyperref}{\pdfstringdefDisableCommands{%
    \let\ruby\@firstoftwo
    \let\xxruby\@firstoftwo
    \let\dotemph\@firstofone
    \let\markoverwith\@secondoftwo
    \let\uline\@firstofone
    \let\sout\@firstofone
    \let\uuline\@firstofone
    \let\xout\@firstofone
    \let\uwave\@firstofone
    \let\dashuline\@firstofone
    \let\dotuline\@firstofone
    \let\typesetclassic\empty
    \let\typesetmodern\empty
    \let\inhibitglue\empty
    \let\hangulpunctuations\count@
    \let\registerpunctuations\@gobble
    \let\unregisterpunctuations\@gobble
    \let\registerhangulpunctuations\@gobble
    \let\unregisterhangulpunctuations\@gobble
    \let\registerbreakableafter\@gobble
    \let\registerbreakablebefore\@gobble
    \let\hangulbyhangulfont\count@
    \let\hanjabyhanjafont\count@
    \let\addhangulfontfeature\@gobble
    \let\addhangulfontfeatures\@gobble
    \let\addhanjafontfeature\@gobble
    \let\addhanjafontfeatures\@gobble
    \let\addfallbackfontfeature\@gobble
    \let\addfallbackfontfeatures\@gobble
    \def\는{는}\def\은{은}\def\을{을}\def\를{를}\def\와{와}\def\과{과}%
    \def\가{가}\def\이{이}\def\라{라}\def\으{으}\def\로{로}%
    \def\hellipsis{...}}}{}
  \if@hangul \RequirePackage{konames-utf}\fi
}
% misc
\RequirePackage{kolabels-utf}
\protected\def\hellipsis{\char"2026\char"2026 }
\if@hangul
  \linespread{1.3888}
  \footnotesep=1.3888\footnotesep
  \skip\footins=\glueexpr\skip\footins/72*100\relax
  \frenchspacing
\fi
\endinput
