% luatexko.sty
%
% Copyright (c) 2013-2025 Dohyun Kim <nomosnomos at gmail com>
%                         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\ProvidesPackage
  \NeedsTeXFormat{LaTeX2e}[2021/11/15]
  \ProvidesPackage{luatexko}[2025/02/28 v3.8 typesetting Korean with LuaTeX]
  \RequirePackage{luatexbase}
  \RequirePackage{fontspec}[2020/02/03]
  \let\luatexkoselectfont\selectfont
\else
  \input luatexbase.sty
  \input luaotfload.sty
  \input atbegshi.sty
  \chardef\luatexkoatcatcode=\catcode`\@
  \catcode`\@=11
\fi
\newlanguage\koreanlanguage
\newattribute\luatexkohangulfontattr
\newattribute\luatexkohanjafontattr
\newattribute\luatexkofallbackfontattr
\newattribute\luatexkoautojosaattr
\newattribute\luatexkoclassicattr
\newattribute\luatexkodotemphattr
\newattribute\luatexkorubyattr \chardef\luatexkorubyalloc\allocationnumber
\newattribute\luatexkohangulbyhangulattr
\newattribute\luatexkohanjabyhanjaattr
\directlua{ require"luatexko" }
% classics
% 0: horizontal KO, JP
% 1: vertical   KO, SC
% 2: horizontal SC
% 3: horizontal TC
% 4: vertical   TC
% 5: vertical   JP
\chardef\luatexkolangCJK=\z@ % 0:KO, 1:JP, 2:SC, 3:TC
\protected\def\typesetclassic{%
  \ifnum\luatexkoclassicattr<\z@
    \luatexkoclassicattr\z@
    \parindent1em
  \fi
  }
\protected\def\typesetvertical{% 1, 4, 5
  \ifcase\luatexkolangCJK
    \luatexkoclassicattr\@ne
    \parindent1em
  \or
    \luatexkoclassicattr=5\relax
    \parindent1em
  \or
    \luatexkoclassicattr\@ne
    \parindent2em
  \or
    \luatexkoclassicattr=4\relax
    \parindent2em
  \else
    \luatexkoclassicattr\@ne
    \parindent1em
  \fi
  }
\protected\def\typesetmodern{\unsetattribute\luatexkoclassicattr}
\protected\def\inhibitglue{\hskip\z@skip}
\protected\def\japanese{% 0, 5
  \chardef\luatexkolangCJK=\@ne
  \ifcase\luatexkoclassicattr
  \or
    \luatexkoclassicattr=5\relax
  \or
    \luatexkoclassicattr\z@
  \or
    \luatexkoclassicattr\z@
  \or
    \luatexkoclassicattr=5\relax
  \or
  \else
    \luatexkoclassicattr\z@
  \fi
  \parindent1em
  }
\protected\def\Schinese{% 2, 1
  \chardef\luatexkolangCJK=\tw@
  \ifcase\luatexkoclassicattr
    \luatexkoclassicattr\tw@
  \or
  \or
  \or
    \luatexkoclassicattr\tw@
  \or
    \luatexkoclassicattr\@ne
  \or
    \luatexkoclassicattr\@ne
  \else
    \luatexkoclassicattr\tw@
  \fi
  \parindent2em
  }
\protected\def\Tchinese{% 3, 4
  \chardef\luatexkolangCJK=\thr@@
  \ifcase\luatexkoclassicattr
    \luatexkoclassicattr\thr@@
  \or
    \luatexkoclassicattr=4\relax
  \or
    \luatexkoclassicattr\thr@@
  \or
  \or
  \or
    \luatexkoclassicattr=4\relax
  \else
    \luatexkoclassicattr\thr@@
  \fi
  \parindent2em
  }
\let\korean\typesetmodern \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 }
\edef\dotemphchar{\expandafter\noexpand\ifdefined\bfseries\bfseries\else\bf\fi ^^^^02d9}
\protected\def\dotemph#1{%
  \global\advance\luatexkodotemphcount\@ne
  \ifnum\luatexkodotemphcount=\@ne \directlua{ luatexko.activate"dotemph" }\fi
  \begingroup
  \count@=\luatexkodotemphcount
  \setbox\z@\hbox{\raise\dotemphraise\hbox{\dotemphchar}}%
  \directlua{ luatexko.dotemphbox[\number\count@] = node.copy(tex.box[0]) }%
  \luatexkodotemphattr\count@ #1\relax
  \directlua{ luatexko.dotemphboundary(\number\count@) }%
  \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
  \ifnum\luatexkoulinecount=\@ne \directlua{ luatexko.activate"uline" }\fi
  \begingroup
  \ifx\luatexko@prev@ulinedown\ulinedown
    \edef\ulinedown{\dimexpr\ulinedown+\ulinewidth+.15ex\relax}\fi
  \let\luatexko@prev@ulinedown\ulinedown
  \count@=\luatexkoulinecount
  \leavevmode
  \setbox\z@\hbox{#1}%
  \directlua{ luatexko.ulboundary(\number\count@, tex.box[0].list, \luatexkoleaderstype) }%
  #2\relax
  \directlua{ luatexko.ulboundary(\number\count@) }%
  \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
\protected\def\ruby#1#2{%
  \global\advance\luatexkorubycount\@ne
  \ifnum\luatexkorubycount=\@ne \directlua{ luatexko.activate"ruby" }\fi
  \begingroup
  \count@=\luatexkorubycount
  \leavevmode
  \setbox\z@\hbox attr\luatexkorubyalloc=\count@{#1}% base
  \setbox\tw@\hbox{% ruby
    \ifdefined\rubyfont \rubyfont \fi
    \ifcsname ver@luatexko.sty\endcsname % <- latex
      \dimen@\dimexpr\rubysize em\relax
      \fontsize\dimen@\dimen@\luatexkoselectfont
    \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@\hbox attr\luatexkorubyalloc=\count@ spread\dimen@{%
          \hskip\z@ plus \luatexkostretchfactor em\relax
          \unhbox\z@
          \hskip\z@ plus \luatexkostretchfactor em\relax }%
      \fi
    \else
      \setbox\z@\hbox attr\luatexkorubyalloc=\count@ 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{
    luatexko.rubybox[\number\count@] = {
      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
  \ifx\empty#1\empty
    \setbox\z@\hbox\bgroup
  \else
    \setbox\z@\vbox\bgroup \hsize#1\relax
  \fi
  \typesetvertical }
\protected\def\endvertical{%
  \ifinner\else \par\fi
  \egroup
  \luatexkorotatebox\z@
  \box\z@ }
\protected\def\luatexkorotatebox#1{%
  \dimen@\dimexpr\ht#1+\dp#1\relax
  \setbox#1\hbox to\dimen@\bgroup
    \hfil
    \vbox to\wd#1\bgroup
      \wd#1\z@
      \ifnum\outputmode > 0
        \pdfextension save\relax
        \pdfextension setmatrix{0 -1 1 0}\relax
      \else
        \special{pdf:btrans rotate -90}\relax
      \fi
      \box#1\relax
      \kern-\dimen@
      \ifnum\outputmode > 0
        \pdfextension restore\relax
      \else
        \special{pdf:etrans}\relax
      \fi
      \vfil
    \egroup
  \egroup
}
% horizontal box inside vertical writing
\def\luatexkohorizboxmoveright{0.5ex}
\protected\def\horizontal#1{%
  \directlua{ luatexko.gethorizboxmoveright() }%
  \leavevmode
  \ifx\empty#1\empty
    \setbox\z@\hbox\bgroup
  \else
    \setbox\z@\vbox\bgroup \hsize#1\relax
  \fi
  \typesetmodern }
\protected\def\endhorizontal{%
  \ifinner\else \par\fi
  \egroup
  \luatexkounrotatebox\z@
  \raise\luatexkohorizboxmoveright
  \box\z@ }
\protected\def\luatexkounrotatebox#1{%
  \dimen@\dimexpr\ht#1+\dp#1\relax
  \setbox#1\hbox to\dimen@\bgroup
    \lower.5\wd#1\vbox to\wd#1\bgroup
      \vfil
      \wd#1\z@
      \ifnum\outputmode > 0
        \pdfextension save\relax
        \pdfextension setmatrix{0 1 -1 0}\relax
      \else
        \special{pdf:btrans rotate 90}\relax
      \fi
      \box#1\relax
      \kern-\dimen@
      \ifnum\outputmode > 0
        \pdfextension restore\relax
      \else
        \special{pdf:etrans}\relax
      \fi
    \egroup
    \hfil
  \egroup
}
% 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\ifluatexkorunningselectfont
\def\luatexkohangulselectfont{%
  \ifluatexkorunningselectfont \else
    \ifdefined\luatexkohangulfont
      \begingroup
      \luatexkorunningselectfonttrue
      \luatexkohangulfont
      \expandafter\expandafter\expandafter\endgroup
      \expandafter\luatexkohangulfontattr\fontid\font\relax
    \fi
  \fi }
\def\luatexkohanjaselectfont{%
  \ifluatexkorunningselectfont \else
    \ifdefined\luatexkohanjafont
      \begingroup
      \luatexkorunningselectfonttrue
      \luatexkohanjafont
      \expandafter\expandafter\expandafter\endgroup
      \expandafter\luatexkohanjafontattr\fontid\font\relax
    \fi
  \fi }
\def\luatexkofallbackselectfont{%
  \ifluatexkorunningselectfont \else
    \ifdefined\luatexkofallbackfont
      \begingroup
      \luatexkorunningselectfonttrue
      \luatexkofallbackfont
      \expandafter\expandafter\expandafter\endgroup
      \expandafter\luatexkofallbackfontattr\fontid\font\relax
    \fi
  \fi }
% plain
\ifcsname ver@luatexko.sty\endcsname\else
  % do not verticalize headline/footline.
  \def\verticaltypesetting{%
    \dimen@\hsize \hsize\vsize \vsize\dimen@
    \edef\plainoutput{\dimen@\hsize \hsize\vsize \vsize\dimen@
      \unexpanded\expandafter{\plainoutput}}%
    \def\pagebody{\setbox\z@\vbox to\hsize{\boxmaxdepth=\maxdepth \pagecontents}%
      \luatexkorotatebox\z@\box\z@}%
    \typesetvertical
    \let\verticaltypesetting\relax % prevent multiple running
  }
  \def\beginverticaltypesetting{\vfill\supereject \begingroup \verticaltypesetting}
  \def\endverticaltypesetting{\vfill\supereject \endgroup}
  % hangul fonts
  \protected\def\hangulfont{%
    \afterassignment\luatexkohangulselectfont\font\luatexkohangulfont}
  \protected\def\hanjafont{%
    \afterassignment\luatexkohanjaselectfont\font\luatexkohanjafont}
  \protected\def\fallbackfont{%
    \afterassignment\luatexkofallbackselectfont\font\luatexkofallbackfont}
  \def\sethangulfont#1{%
    \def\@tempa{#1}\edef\@tempb{\csstring#1}%
    \expandafter\afterassignment\expandafter\luatexko@sethangulfont
    \expandafter\font\csname luatexko.hangulfont.\@tempb\endcsname }
  \def\luatexko@sethangulfont{%
    \expandafter\protected\expandafter\edef\@tempa{%
      \luatexkohangulfontattr\fontid\csname luatexko.hangulfont.\@tempb\endcsname\relax }}
  \def\sethanjafont#1{%
    \def\@tempa{#1}\edef\@tempb{\csstring#1}%
    \expandafter\afterassignment\expandafter\luatexko@sethanjafont
    \expandafter\font\csname luatexko.hanjafont.\@tempb\endcsname }
  \def\luatexko@sethanjafont{%
    \expandafter\protected\expandafter\edef\@tempa{%
      \luatexkohanjafontattr\fontid\csname luatexko.hanjafont.\@tempb\endcsname\relax }}
  \def\setfallbackfont#1{%
    \def\@tempa{#1}\edef\@tempb{\csstring#1}%
    \expandafter\afterassignment\expandafter\luatexko@setfallbackfont
    \expandafter\font\csname luatexko.fallbackfont.\@tempb\endcsname }
  \def\luatexko@setfallbackfont{%
    \expandafter\protected\expandafter\edef\@tempa{%
      \luatexkofallbackfontattr\fontid\csname luatexko.fallbackfont.\@tempb\endcsname\relax }}
  \hangulfont={UnBatang:mode=node;script=hang;+tlig} at 10pt % default: unbatang
  \protected\def\setmathhangulfonts#1#2#3{% font identifiers
    \ifnum\Umathcodenum"AC00="AC00\relax
      \csname newfam\endcsname\symmathhangul
      \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
% do not verticalize headline/footline
\def\verticaltypesetting{%
  \ifx\@nodocument\relax % not in the preamble
    \clearpage
    \begingroup
  \fi
  \hsize\textheight \vsize\textwidth
  \textwidth\hsize  \textheight\vsize
  \@colroom\vsize   \@colht\vsize
  \if@twocolumn
    \columnwidth=.5\dimexpr\textwidth-\columnsep\relax
    \linewidth\columnwidth \hsize\columnwidth
  \else
    \linewidth\hsize \columnwidth\hsize
  \fi
  \IfFormatAtLeastTF{2025-06-01}{%
    \AddToHook{build/page/before}[luatexko/beforeOR]{%
      \luatexkorotatebox\@outputbox
      \textwidth\textheight
    }%
  }{%
    \expandafter\def\expandafter\@outputpage\expandafter{%
      \expandafter\luatexkorotatebox\expandafter\@outputbox
      \expandafter\textwidth\expandafter\textheight
      \@outputpage
    }%
  }%
  \typesetvertical
  \let\verticaltypesetting\relax % prevent multiple running
}
\def\endverticaltypesetting{%
  \clearpage
  \IfFormatAtLeastTF{2025-06-01}{\RemoveFromHook{build/page/before}[luatexko/beforeOR]}{}%
  \endgroup
  \global\@colroom\textheight
  \global\@colht\textheight
  \global\vsize\textheight
}
% hangul fonts
\AddToHook{selectfont}{%
  \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
\DeclareDocumentCommand \setmainhangulfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomainhangulfamily { Ligatures=TeX, #1, #3 } { #2 }
  \cs_set_protected_nopar:Npn \luatexkomainhangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomainhangulfamily \luatexkoselectfont
  }
  \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 }
  \cs_set_protected_nopar:Npn \luatexkosanshangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkosanshangulfamily \luatexkoselectfont
  }
  \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 }
  \cs_set_protected_nopar:Npn \luatexkomonohangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomonohangulfamily \luatexkoselectfont
  }
  \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 }
  \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 } \luatexkoselectfont
    }
    \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 }
  \cs_set_nopar:Npn \luatexkohangulfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkohangulfontfamily \luatexkoselectfont
  }
  \luatexkohangulselectfont
  \ignorespaces
}
\DeclareDocumentCommand \setmainhanjafont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomainhanjafamily { Ligatures=TeX, #1, #3 } { #2 }
  \cs_set_protected_nopar:Npn \luatexkomainhanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomainhanjafamily \luatexkoselectfont
  }
  \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 }
  \cs_set_protected_nopar:Npn \luatexkosanshanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkosanshanjafamily \luatexkoselectfont
  }
  \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 }
  \cs_set_protected_nopar:Npn \luatexkomonohanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomonohanjafamily \luatexkoselectfont
  }
  \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 }
  \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 } \luatexkoselectfont
    }
    \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 }
  \cs_set_nopar:Npn \luatexkohanjafont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkohanjafontfamily \luatexkoselectfont
  }
  \luatexkohanjaselectfont
  \ignorespaces
}

\DeclareDocumentCommand \setmainfallbackfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomainfallbackfamily { Ligatures=TeX, #1, #3 } { #2 }
  \cs_set_protected_nopar:Npn \luatexkomainfallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomainfallbackfamily \luatexkoselectfont
  }
  \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 }
  \cs_set_protected_nopar:Npn \luatexkosansfallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkosansfallbackfamily \luatexkoselectfont
  }
  \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 }
  \cs_set_protected_nopar:Npn \luatexkomonofallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkomonofallbackfamily \luatexkoselectfont
  }
  \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 }
  \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 } \luatexkoselectfont
    }
    \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 }
  \cs_set_nopar:Npn \luatexkofallbackfont
  {
    \fontencoding \g_fontspec_encoding_tl
    \fontfamily \luatexkofallbackfontfamily \luatexkoselectfont
  }
  \luatexkofallbackselectfont
  \ignorespaces
}
\DeclareDocumentCommand \setmathhangulfont { O{} m O{} }
{
  \fontspec_set_family:Nnn \luatexkomathhangulfamily { #1, #3 } { #2 }
  \DeclareSymbolFont { mathhangul }
    \g_fontspec_encoding_tl \luatexkomathhangulfamily \seriesdefault \shapedefault
  \int_compare:nNnF { \Umathcharfam"AC00 } = { \symmathhangul }
  {
    \setmathhangulblock{AC00}{D7A3}
  }
  \ignorespaces
}
\ExplSyntaxOff
\let\adhochangulfont\hangulfontspec
\let\adhochanjafont\hanjafontspec
\let\adhocfallbackfont\fallbackfontspec
% interhangul, interlatincjk, charraise
\protected\def\addhangulfontfeature#1{%
  \begingroup
  \ifdefined\luatexkohangulfont
    \fontseries\seriesdefault\fontshape\shapedefault \luatexkohangulfont \fi
  \addfontfeature{#1}%
  \edef\x{\endgroup
    \def\noexpand\luatexkohangulfont{%
      \noexpand\fontencoding{\UTFencname}%
      \noexpand\fontfamily{\f@family}\noexpand\luatexkoselectfont}}\x
  \luatexkohangulselectfont
  \ignorespaces}
\let\addhangulfontfeatures\addhangulfontfeature
\protected\def\addhanjafontfeature#1{%
  \begingroup
  \ifdefined\luatexkohanjafont
    \fontseries\seriesdefault\fontshape\shapedefault \luatexkohanjafont \fi
  \addfontfeature{#1}%
  \edef\x{\endgroup
    \def\noexpand\luatexkohanjafont{%
      \noexpand\fontencoding{\UTFencname}%
      \noexpand\fontfamily{\f@family}\noexpand\luatexkoselectfont}}\x
  \luatexkohanjaselectfont
  \ignorespaces}
\let\addhanjafontfeatures\addhanjafontfeature
\protected\def\addfallbackfontfeature#1{%
  \begingroup
  \ifdefined\luatexkofallbackfont
    \fontseries\seriesdefault\fontshape\shapedefault \luatexkofallbackfont \fi
  \addfontfeature{#1}%
  \edef\x{\endgroup
    \def\noexpand\luatexkofallbackfont{%
      \noexpand\fontencoding{\UTFencname}%
      \noexpand\fontfamily{\f@family}\noexpand\luatexkoselectfont}}\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\expandafter\endgroup
    \iffontchar\font"AC00 \else
      \IfFontExistsTF{UnBatang.ttf}
        {\setmainhangulfont{UnBatang}[Script=Hangul,Language=Korean]}
        {}
    \fi
  \fi
  \ifdefined\luatexkosanshangulfont\else
    \begingroup\sffamily\expandafter\endgroup
    \iffontchar\font"AC00 \else
      \IfFontExistsTF{UnDotum.ttf}{\setsanshangulfont{UnDotum}}{}
    \fi
  \fi
  \ifdefined\luatexkomonohangulfont\else
    \begingroup\ttfamily\expandafter\endgroup
    \iffontchar\font"AC00 \else
      \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
\AddToHook{package/hyperref/after}{\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{...}}}
\AddToHook{package/pxrubrica/after}{\let\ruby\jruby}
% misc
\RequirePackage{kolabels-utf}
\protected\def\hellipsis{\char"2026\char"2026 }
\if@hangul
  \RequirePackage{konames-utf}
  \linespread{1.3888}
  \footnotesep=1.3888\footnotesep
  \skip\footins=\glueexpr\skip\footins/72*100\relax
  \frenchspacing
\fi
\endinput