summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-05-17 22:32:58 +0000
committerKarl Berry <karl@freefriends.org>2013-05-17 22:32:58 +0000
commit5e514c20c590569dee9a6ae13ab7ac8ed0878822 (patch)
tree181c94317f4c68bc0734d51b48742bc39893d6fa
parent92ef8eb9450138c18ff43262f6251d8e23d722ce (diff)
luatexko (17may13)
git-svn-id: svn://tug.org/texlive/trunk@30533 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/luatex/luatexko/README138
-rw-r--r--Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdfbin0 -> 465585 bytes
-rw-r--r--Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex392
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty355
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua486
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua130
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko.lua1720
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko.sty248
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds1
-rw-r--r--Master/tlpkg/tlpsrc/collection-luatex.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/luatexko.tlpsrc0
12 files changed, 3472 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/luatex/luatexko/README b/Master/texmf-dist/doc/luatex/luatexko/README
new file mode 100644
index 00000000000..ed9cbeac029
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/luatexko/README
@@ -0,0 +1,138 @@
+=========================================
+LuaTeX-ko Package version 1.0 (2013/05/10)
+=========================================
+
+This is a Lua(La)TeX macro package that supports typesetting Korean
+documents including Old Hangul texts. As LuaTeX has opened up access to
+almost all the hidden routines of TeX engine, users can obtain more
+beautiful outcome using this package rather than other Hangul macros
+operating on other engines.
+
+Due to the backward-incompatible update of LuaTeX in early 2013, LuaTeX
+version 0.76+ and luaotfload package version 2.2+ are required for this
+package to run.
+
+This package also requires both cjk-ko and xetexko packages for its full
+functionality.
+
+
+License
+=======
+This package is licensed under LPPL (LaTeX Project Public License).
+
+See each file for details.
+
+
+Author
+======
+Please report any errors or suggestions to Dohyun Kim <nomos at ktug org>.
+
+
+Files
+=====
+
+TeXinputs
+---------
+ luatexko.sty -> tex/luatex/luatexko/
+ luatexko-core.sty -> tex/luatex/luatexko/
+ luatexko.lua -> tex/luatex/luatexko/
+ luatexko-normalize.lua -> tex/luatex/luatexko/
+ luatexko-uhc2utf8.lua -> tex/luatex/luatexko/
+
+Documents
+---------
+ luatexko-doc.pdf -> doc/luatex/luatexko/
+ luatexko-doc.tex -> doc/luatex/luatexko/
+ README (this file) -> doc/luatex/luatexko/
+
+
+Loading
+=======
+For a LaTeX user, declaring
+ \usepackage{luatexko}
+or
+ \usepackage{kotex}
+is sufficient to load the package, which will load fontspec as well.
+Notice that kotex.sty is a file provided by cjk-ko package.
+
+Under plain TeX: \input luatexko.sty
+
+
+Package Options
+===============
+ [hangul]
+Load Hangul captions. Besides, this option adjusts interword and
+interline spacing.
+
+ [hanja]
+Load Hanja captions. Also adjusts spacing as [hangul] option does.
+
+ [unfonts]
+Load font setting predefined for Un TrueType fonts available at
+http://kldp.net/projects/unfonts/.
+
+
+Hangul Font Commands
+====================
+ \setmainhangulfont
+ \setsanshangulfont
+ \setmonohangulfont
+Equivalent to \setmainfont et. al. of fontspec package. These fonts are
+used when the font loaded by \setmainfont et. al. does not have Hangul
+glyphs.
+
+ \setmainhanjafont
+ \setsanshanjafont
+ \setmonohanjafont
+These fonts are used when the font loaded by \setmainfont or
+\setmainhangulfont et. al. does not have Hanja glyphs.
+
+In like manner, these commands are available as well:
+ \hangulfontspec
+ \hanjafontspec
+ \newhangulfontfamily
+ \newhanjafontfamily
+ \addhangulfontfeature
+ \addhanjafontfeature
+
+
+Hangul Font Options
+===================
+ [InterHangul=<dimen>]
+Set spacing between Hangul characters.
+
+ [InterLatinCJK=<dimen>]
+Set spacing between CJK and Latin characters.
+
+ [PunctRaise=<dimen>]
+Raise Latin fullstop and comma after CJK character.
+
+ [QuoteRaise=<dimen>]
+Raise Latin quotation marks and parentheses around CJK text.
+
+ [CharRaise=<dimen>]
+Raise CJK characters by <dimen>.
+
+
+Other User Commands
+===================
+ \luatexuhcinputencoding=<number>
+When <number> is 1 or greater, UHC (aka. Windows CP949) input encoding
+is allowed. <number> 0 restores UTF-8, the default input encoding.
+
+ \dotemph{...}
+Emphasise Hangul or Hanja by putting dot above.
+
+ \ruby{<base text>}{<ruby text>}
+Typeset ruby annotations.
+
+ \uline{...}
+ \sout{...}
+ \uuline{...}
+ \xout{...}
+ \uwave{...}
+ \dashuline{...}
+ \dotuline{...}
+Same functionality as ulem package provides.
+
+--END of README--
diff --git a/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf
new file mode 100644
index 00000000000..40d160d2280
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex
new file mode 100644
index 00000000000..58bd4200516
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex
@@ -0,0 +1,392 @@
+%% !TEX program = lualatex
+%% !TEX encoding = UTF-8
+%%
+%% written by Dohyun Kim <nomos at ktug org>
+%% public domain
+%%
+%% $Id: luatexko-doc.tex,v 1.67 2011/07/20 09:56:06 nomos Exp $
+
+\documentclass[a4paper]{article}
+\usepackage{typearea}
+\usepackage[hangul]{luatexko}
+\usepackage{luamplib}
+\setmainhangulfont[
+ AutoFakeSlant,
+ InterLatinCJK=.125em,
+ QuoteRaise=.1em,
+ Expansion,
+ ]{NanumMyeongjo}
+\setmainhanjafont[AutoFakeSlant]{UnBatang}
+\setsanshangulfont[
+ AutoFakeSlant,
+ InterLatinCJK=.125em,
+ ]{NanumGothic}
+\usepackage[svgnames]{xcolor}
+\usepackage{mflogo}
+\usepackage{metalogo}
+\usepackage[unicode,bookmarksnumbered]{hyperref}
+
+\edef\verbatim{\unexpanded\expandafter{\verbatim
+ \linespread{1.1}\selectfont\color{MidnightBlue}}}
+\edef\itemize{\unexpanded\expandafter{\itemize\small}}
+\catcode`|=13 \def|{\verb|\color{MidnightBlue}} %|
+\let\luatex\LuaTeX
+\def\luatexko{\luatex-k$o$}
+\def\texlive{\TeX\ Live}
+\def\kotex{\textsf{k}\kern-.1em \textit{o}\kern-.1ex .\kern-.1667em \TeX}
+\edef\section#1{\unexpanded\expandafter{\section{\empty}\vskip-5pt\hrule\nobreak\vskip5pt}}
+\def\hemph#1{\textsf{\bfseries #1}}
+
+\begin{document}
+\title{\luatexko\ 간단 매뉴얼}
+\author{Dohyun Kim <|nomos at ktug org|>}
+\maketitle
+
+\begin{quote}\small
+ For summary introduction in English, please see |README| file in this package.
+
+ 주요 변경 사항:
+ \begin{itemize}\itemsep=0pt
+ \item 플레인텍에서도 luatexko.sty을 불러야 한다.
+ \item 패키지 옵션 |unfonts|가 선언되지 않으면 은글꼴을 자동으로
+ 부르지 않는다.
+ \item 글꼴 옵션에 |QuoteRaise|가 추가되었다.
+ \item 세로쓰기를 더 이상 공식적으로 지원하지 않는다.
+ \item \MP\ 코드를 넣으려면 luamplib 패키지를 불러야 한다.
+ \end{itemize}
+\end{quote}
+
+\section{}
+\texlive\ 2013 이상을 사용해야 한다. 실행 명령은 레이텍의 경우
+|lualatex|, 플레인텍은 |luatex|이다. 아직 \luatex은 베타 상태로 개발
+중에 있으므로 안정적인 동작을 보장하지 않는다.
+
+\section{}
+\luatexko\ 로드하기: |\usepackage{luatexko}|. 플레인텍은
+|\input luatexko.sty|. 입력은 원칙적으로 UTF-8으로 한다.
+BOM (Byte Order Mark)은 있어도 좋고 없어도 좋다.
+CP949 인코딩에 관해서는 제\ref{sec:uhcencoding}절 참조.
+
+\section{}
+패키지 옵션으로 |[hangul]|과 |[hanja]|가 제공된다. 장 제목이나
+표·그림 캡션 따위가 한글 또는 한자 방식으로 표시된다. 다만
+장(chapter) 제목과 편(part) 제목에만 “제(第)”가 붙어 ``제~1 편''
+“제~3 장”과 같은 방식으로 표시되며 절 제목 이하에는 붙지 않는다.
+
+또한 |[unfonts]|는 은글꼴을 불러오는 패키지 옵션이다.
+이전 버전과 달리 \hemph{은글꼴이 기본으로 로드되지 않음}에 유의할 것.
+
+\section{}
+\luatexko를 로드하면 fontspec 패키지를 자동으로 불러온다. 글꼴 설정에
+대해서는 fontspec 문서를 참조하라.
+
+한국어 글꼴을 위해 새로 마련한 명령은 다음과 같다.
+\begin{verbatim}
+ \setmainhangulfont \setmainhanjafont
+ \setsanshangulfont \setsanshanjafont
+ \setmonohangulfont \setmonohanjafont
+ \newhangulfontfamily \newhanjafontfamily
+ \addhangulfontfeature \addhanjafontfeature
+ \hangulfontspec \hanjafontspec
+\end{verbatim}
+|\adhochangulfont| |\adhochanjafont|는 각각 |\hangulfontspec|
+|\hanjafontspec|의 다른 이름이다.
+\begin{itemize}\item[]
+플레인텍에서 한글 글꼴 설정은 영문 글꼴 지정하는 방식과 거의 같다.
+\begin{verbatim}
+ \hangulfont=UnDotum\relax
+ \hanjafont=UnDotum at 14pt
+ \hangulfont=UnDotum scaled 2000
+ \hanjafont{HCR Batang LVT}\relax
+ \hangulfont={HCR Batang LVT:script=hang;+dlig} at 12pt
+\end{verbatim}
+\end{itemize}
+
+\section{}
+원칙적으로 \luatexko에서는 영문폰트에 지정한 글자가 없으면 한글폰트에서,
+한글폰트에도 없으면 한자폰트에서 글자를 찾아 찍는다. 기존 \kotex과는
+글꼴 대체 방식이 다르므로 주의해야 한다.
+
+하지만 |\hanjabyhanjafont=1|을 선언하면 한자는 우선 한자글꼴로
+식자한다. |0|을 선언하면 원래 방식으로 되돌아간다. 이 명령은 문단
+중간에서 사용하지 않도록 주의해야 한다. 문단 중에 사용되었다면
+그 문단의 처음부터 효력이 발생한다.
+
+\section{}
+fontspec의 글꼴 옵션 외에 \luatexko가 따로 제공하는 것들이
+있다. \footnote{ 옛한글 식자를 위해서는
+ |[Script=Hangul]| 옵션을 사용하는 것으로 충분하다. 그러나
+ |[YetHangul]| 옵션을 써도 무해하다.}
+
+\begin{figure}
+ \fboxsep=1em
+ \fbox{\vbox{\hsize\dimexpr\linewidth-2.1em\relax
+% \fontspec[Script=Hangul]{malgungothic}
+ \fontspec[Script=Hangul]{HCR Dotum LVT}
+ \centering
+뎨 가ᄂᆞᆫ 뎌 각시 본 듯도 ᄒᆞᆫ뎌이고.\\
+天텬上상白ᄇᆡᆨ玉옥京경을 엇디ᄒᆞ야 離니別별ᄒᆞ고\\
+ᄒᆡ 다 져믄 날의 눌을 보라 가시ᄂᆞᆫ고
+
+\medskip
+
+어와 네여이고 내 ᄉᆞ셜 드러보오.\\
+내 얼굴 이 거동이 님 괴얌즉 ᄒᆞᆫ가마ᄂᆞᆫ\\
+엇딘디 날 보시고 네로다 녀기실ᄉᆡ\\
+나도 님을 미더 군 ᄠᅥ디 전혀 업서\\
+이ᄅᆡ야 교ᄐᆡ야 어ᄌᆞ러이 구돗ᄯᅥᆫ디\\
+반기시ᄂᆞᆫ ᄂᆞᆺ비치 녜와 엇디 다ᄅᆞ신고.\\
+%누어 ᄉᆡᆼ각ᄒᆞ고 니러 안자 혜여ᄒᆞ니\\
+%내 몸의 지은 죄 뫼ᄀᆞ티 ᄡᅡ혀시니\\
+%하ᄂᆞᆯ히라 원망ᄒᆞ고 사ᄅᆞᆷ이라 허믈ᄒᆞ랴\\
+%셜워 플텨 혜니 造조物믈의 타시로다.
+}}
+\caption{옛한글 조판 보기}\label{fig:yethangul}
+\end{figure}
+
+\begin{description}
+\item[InterHangul] 한글 글자 사이의 자간. 아래는 $-0.04$em 만큼 한글
+ 자간을 지시한다.
+\begin{verbatim}
+ [InterHangul=-0.04em]
+\end{verbatim}
+
+\item[InterLatinCJK] 한글 또는 한자와 라틴 문자 사이의 자간을
+ 설정한다.
+\begin{verbatim}
+ [InterLatinCJK=0.125em]
+\end{verbatim}
+
+\item[PunctRaise] 한글 또는 한자 다음에 라틴 구두점이 왔을 때 그 세로
+ 위치를 조절할 수 있다.
+\begin{verbatim}
+ [PunctRaise=-0.125em]
+\end{verbatim}
+
+\item[QuoteRaise] 한글 또는 한자 주변에 라틴 인용부호나 \hemph{괄호}가 왔을 때
+ 그 세로 위치를 조절할 수 있다.
+\begin{verbatim}
+ [QuoteRaise=0.125em]
+\end{verbatim}
+
+\item[CharRaise] 글자의 세로 위치를
+ {\addhangulfontfeature{CharRaise=.3em} 조절}할 수 있는 기능이다.
+ 이로써 주변에 식자되는 다른 글꼴과 조화를 이루게 한다.
+\begin{verbatim}
+ [CharRaise=0.1em]
+\end{verbatim}
+
+\item[Protrusion] 특정 글자가 행 끌에 왔을 때 판면 바깥으로 끌어내는
+ 기능이다. Lua\LaTeX의 기본값은 구두점들만 완전히 글자내밀기 한다. 즉
+ hanging punctuation이 작동한다.
+\begin{verbatim}
+ [Protrusion]
+\end{verbatim}
+ 이는 |Protrusion=default|와 마찬가지 뜻이다. 마이크로타입에 관심
+ 있으면 자신만의 설정을 만들어 지정할 수 있다.
+
+\item[Expansion] 판면의 균일한 조판을 위해 글자들을 미세하게 늘이거나
+ 줄이는 기능이다.
+\begin{verbatim}
+ [Expansion]
+\end{verbatim}
+ 이는 |Expansion=default|와 마찬가지 뜻이다.
+
+\end{description}
+
+\section{}
+\begin{figure}\linespread{1.388}\selectfont\hfil
+\fbox{\vbox{\hsize=36em \begin{chinese} \setmainfont{STFangsong}
+子曰:「學而時習之,不亦說乎?有朋自遠方來,不亦樂乎?人不知而不慍,不亦君子乎?」
+
+有子曰:「其為人也孝弟,而好犯上者,鮮矣!不好犯上,而好作亂者,未之有也!君子務本,本立而道生;孝弟也者,其為仁之本歟?」
+
+子曰:「巧言令色,鮮矣仁!」
+
+曾子曰:「吾日三省吾身:為人謀,而不忠乎?與朋友交,而不信乎?傳,不習乎?」
+
+子曰:「道千乘之國,敬事而信,節用而愛人,使民以時。」
+\end{chinese}}}\hfil
+\caption{고문헌 조판 보기}\label{fig:ancientdoc}
+\end{figure}
+
+고문헌·일본어·중국어 조판을 위해 japanese, Schinese, Tchinese 환경을
+제공한다. chinese는 Schinese의 다른 이름이다. korean 환경도
+마련했는데 이들 환경 안에서 잠깐 한국어를 조판하는 데
+사용한다. 일본어·중국어라도 글꼴 설정은 |\newhangulfontfamily|
+|\newhanjafontfamily| 따위를 이용한다. 그림~\ref{fig:ancientdoc} 참조.
+
+\section{}
+\luatexko가 글자 사이에 삽입하는 미세간격을 사용자가 영(zero)으로
+강제하기 위해선 |\inhibitglue| 명령을 이용한다.
+대체로 일본어·중국어 환경에서만 문제된다.
+
+\section{}
+\begin{quote}
+ |$가^{나^다}$|\quad$\Rightarrow\quad가^{나^다}$
+\end{quote}
+수식 모드에서도 한글을 {\small(hbox로 감싸지 않고)} 직접 입력할 수
+있다. 문서의 기본 한글 글꼴이 자동으로 수식 한글에도 적용되므로 따로
+설정할 것이 없지만 굳이 한다면 다음처럼 지시한다.
+\begin{verbatim}
+ \setmathhangulfont{HCRBatang}
+\end{verbatim}
+현재 한글만 쓸 수 있게 설정되어 있다.
+
+\section{}
+\luatex 에서는 아직 \hemph{세로쓰기를 지원하지 않는다}.%
+\footnote{굳이 세로쓰기를 실험해보고자 한다면 |ttx -t vmtx <폰트>.ttf|
+ 명령의 결과물인 |<폰트>.ttx| 파일을 현재 디렉토리에 두어야 한다. 그런 다음
+ |\string\begin\string{vertical\string}\string{<dimen>\string}
+ ...\string\end\string{vertical\string}| 환경을 이용하라. ttx에 대해선
+ \url{http://sourceforge.net/projects/fonttools/} 참조.
+ 문서 전체에 대해 세로쓰기를 하려면 이 환경을 쓰는 대신
+ |\string\verticaltypesetting| 명령을 전처리부에 선언한다.}
+
+%\begin{figure}
+%\hfil\framebox[\linewidth]{\begin{vertical}{16em}
+%\fontspec[Vertical=RotatedGlyphs]{Adobe Myungjo Std Medium}
+%\parindent-1em\leftskip1em \linespread{1.5}\selectfont
+%\noindent 님의 침묵{\small(The Silent Beloved)}
+%\smallbreak
+%\hfil\hfil 한 용 운\hfil
+%\bigbreak
+%님은 갓슴니다 아아 사랑하는나의님은 갓슴니다\par
+%푸른산빗을깨치고 단풍나무숩을향하야난 적은길을 거러서 참어떨치고
+%갓슴니다\par
+%黃金의꽃가티 굿고빗나든 옛盟誓는 차듸찬띠끌이되야서 한숨의 微風에
+%나러갓슴니다\par
+%날카로은 첫〈키쓰〉의追憶은 나의運命의指針을 돌너노코 뒷거름처서 사러젓슴니다\\
+%%…… \par
+%\hellipsis\par
+%아아 님은갓지마는 나는 님을보내지 아니하얏슴니다\par
+%제곡조를못이기는 사랑의노래는 님의沈默을 휩싸고돔니다\par
+%\end{vertical}}
+%\caption{세로쓰기의 예}\label{fig:vertical}
+%\end{figure}
+
+\section{}
+전처리부에서 |\usepackage{luamplib}|을 선언하면 \MP\ 코드를 문서 중간에 삽입할 수 있다.
+한글이나 수식은 |btex| ... |etex| 안에 넣어야 한다. 그림~\ref{fig:mplib} 참조.
+
+\begin{figure}
+\setbox0\hbox{%
+\begin{mplibcode}
+beginfig(1);
+ draw fullcircle scaled 2cm;
+ dotlabel.bot(btex\TeX etex, origin);
+ dotlabel.rt(btex 루아 etex, dir 45*1cm);
+endfig;
+\end{mplibcode}
+}%
+\setbox2\vbox{\bigskip
+\begin{verbatim}
+ \usepackage{luamplib}
+ ...
+ \begin{mplibcode}
+ beginfig(1);
+ draw fullcircle scaled 2cm;
+ dotlabel.bot(btex \TeX etex, origin);
+ dotlabel.rt(btex 루아 etex, dir 45*1cm);
+ endfig;
+ \end{mplibcode}
+\end{verbatim}}\wd2=.7\linewidth
+\framebox[\linewidth]{\box2 \raise.8cm\box0 }
+\caption{mplib 용례}\label{fig:mplib}
+\end{figure}
+
+\section{}
+|\dotemph| 명령으로 \dotemph{드러냄표}%
+를 이용한 강조를 할 수 있다. 기본은 글자 위에 점을 찍는 형태이나
+다음과 같이 명령을 주어 개인적으로 선호하는 기호를 드러냄표로 쓸 수
+있다.
+\begin{verbatim}
+ \def\dotemphraise{0.4em }
+ \def\dotemphchar{\bfseries ^^^^02d9}
+\end{verbatim}
+전자는 드러냄표를 피강조 글자 위로 끌어올리는 길이를, 후자는 드러냄표
+기호 자체를 정의한다. |^^^^02d9|는 유니코드 코드포인트를 뜻하는
+16진수이고 소문자로만 써야 한다. 숫자 대신 직접 문자를 입력해도 된다.
+플레인텍에서도 쓸 수 있다.
+
+\section{}
+루비를 달 수 있다. ruby 패키지가 이미 존재하지만 \luatexko와 궁합이 잘
+맞지 않아 새로 매크로를 제공한다. 플레인텍도 지원한다.
+\begin{quote}
+|\ruby{漢字}{한자}|\quad$\Rightarrow$\quad\ruby{漢字}{한자}
+\end{quote}
+이처럼 글자별로 따로 루비를 달 필요가 없다. 관련 설정은 다음처럼
+한다.
+
+①~|\rubyfont|: 루비를 식자할 폰트를 지시해 둔다.
+
+②~|\def\rubysize{0.6}|: 루비 글자 크기를 본문 글자 크기에 대한 비율로
+지정
+
+③~|\def\rubysep{0.2ex}|: 루비와 본문 글자 사이의 간격을 지정
+
+④~|\rubynooverlap|: 루비의 폭이 본문 글자의 폭보다 클 때 루비가 이웃
+글자들 위로 삐져나가지 못하게 한다. 본문 글자의 흐름을 중시하여
+|\rubyoverlap|을 기본값으로 하였으므로 이는 따로 선언할 필요가 없다.
+
+\section{}
+ulem 패키지가 \luatexko와 궁합이 잘 맞지 않아{\small (줄바꿈에 문제가 있음)}
+명령을 따로 제공한다. 플레인텍에서도 쓸 수 있다.
+
+\bigskip
+\halign{\qquad#\hfil&\quad$\Rightarrow$\quad#\hfil\cr
+|\uline{밑줄을 그을 수 있다}|&\uline{밑줄을 그을 수 있다}\cr
+|\sout{취소선을 그을 수 있다}|&\sout{취소선을 그을 수 있다}\cr
+|\uuline{밑줄을 두 줄 긋는다}|&\uuline{밑줄을 두 줄 긋는다}\cr
+|\xout{빗금으로 취소할 수 있다}|&\xout{빗금으로 취소할 수 있다}\cr
+|\uwave{물결표로 밑줄을 삼는다}|&\uwave{물결표로 밑줄을 삼는다}\cr
+|\dashuline{대시로 밑줄을 삼는다}|&\dashuline{대시로 밑줄을 삼는다}\cr
+|\dotuline{밑줄을 점선으로 긋는다}|&\dotuline{밑줄을 점선으로 긋는다}\cr
+}
+\bigskip
+
+관련하여 다음 설정을 할 수 있다.
+
+①~|\def\ulinedown{0.25em}|: 밑줄을 베이스라인 아래로 끌어내리는 정도
+
+②~|\def\ulinewidth{0.04em}|: 밑줄의 굵기
+
+\section{}
+자동조사는 \kotex 과 동일하게 |\은| |\는| |\이| |\가| |\을| |\를|
+|\와| |\과| |\로| |\으로| |\라| |\이라| 따위를 사용한다. 문장 중에서도
+작동할 뿐만 아니라 플레인텍도 지원한다.
+
+\section{}
+항목 번호를 한국어 기호로 붙일 수 있다. \kotex과 동일하게 |\jaso|
+|\gana| |\ojaso| |\ogana| |\pjaso| |\pgana| |\onum| |\pnum| |\oeng|
+|\peng| |\hnum| |\Hnum| |\hroman| |\hRoman| |\hNum| |\hanjanum| 따위를
+사용한다.
+
+\section{}
+hyperref 패키지는 |[unicode]| 옵션을 주어야 한다.
+
+\section{}
+|\luatexhangulnormalize=1|이라 지시하면 첫가끝 자모를 완성형 음절로,
+|2|라면 완성형 음절을 첫가끝 자모로 인코딩 변환한다. |0|이 할당되면
+인코딩 변환 기능이 꺼진다. \XeTeX의 |\XeTeXinputnormalization| 명령과
+유사하나 오직 한글과 일부 한자에 대해서만 정규화가 작동하는 점에서
+\XeTeX의 그것에 비해 기능이 한참 모자란다.
+
+\section{}\label{sec:uhcencoding}
+권장하지 않지만 불가피하게 입력 인코딩이 UHC {\small(CP949라고도 하며
+EUC-KR을 포함한다)}인 파일을 처리할 때는 |\luatexuhcinputencoding=1|을
+선언한다. |0|을 할당하면 다시 UTF-8 입력으로 간주한다.
+\XeTeX의 |\XeTeXinputencoding| 명령과 유사하나 오직 한글만 처리할 수
+있어 \XeTeX의 그것에 비해 기능이 한참 모자란다.
+
+\section{}
+마찬가지로 바람직하지는 않지만 불가피하게 파일 이름이 UHC로 인코딩되어
+있다면 |\luatexuhcfilenames=1|을 선언한다. |0|을 할당하면 다시 UTF-8
+이름으로 간주한다. 윈도 계열 운영체제에서만 문제될 것이다.
+
+\begin{flushright}
+ \fboxsep=-\fboxrule
+ \fbox{\vbox to 1em{\hbox to 1em{\hss}\vss}}
+\end{flushright}
+
+\end{document}
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty
new file mode 100644
index 00000000000..2a837045d5a
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty
@@ -0,0 +1,355 @@
+% $Id: luatexko-core.sty,v 1.22 2012/11/23 05:06:02 nomos Exp $
+%
+% Copyright (c) 2013 Dohyun Kim <nomos at ktug org>
+%
+% 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.
+
+\ifx\ProvidesPackage\undefined
+ \input luaotfload.sty
+ \catcode`@ = 11
+\else
+ \ProvidesPackage{luatexko-core}[2013/05/10 v1.0 Typesetting Korean with LuaTeX]
+ \RequirePackage{luaotfload}
+\fi
+
+%% attributes
+\newluatexattribute\finemathattr \finemathattr\@ne % finemath on by default
+\newluatexattribute\cjtypesetattr
+\newluatexattribute\dotemphattr
+\newluatexattribute\autojosaattr
+\newluatexattribute\luakorubyattr \chardef\luakorubyattrnum\the\allocationnumber
+\newluatexattribute\hangfntattr
+\newluatexattribute\hanjfntattr
+
+%% load lua modules
+\RequireLuaModule{luatexko}
+
+%% japanese/chinese/pre-modern
+\protected\def\japanese{\frenchspacing\cjtypesetattr\@ne
+ \luatexkolatinspaceskip\parindent1em }
+\protected\def\Schinese{\frenchspacing\cjtypesetattr\tw@
+ \luatexkolatinspaceskip\parindent2em }
+\protected\def\Tchinese{\frenchspacing\cjtypesetattr\thr@@
+ \luatexkolatinspaceskip\parindent2em }
+\let\chinese\Schinese
+% korean in japanese/chinese env.
+\protected\def\korean{\unsetluatexattribute\cjtypesetattr}
+
+% inhibitglue
+\protected\def\inhibitglue{{\unsetluatexattribute\cjtypesetattr\hskip\z@skip}}
+
+\def\luatexkolatinspaceskip{\spaceskip\fontdimen\tw@\the\font
+ plus \fontdimen\thr@@\the\font minus \fontdimen4\the\font}
+
+%% auto josa
+\protected\def\은{{\autojosaattr\@ne 은}}
+\let\는\은
+
+\protected\def\을{{\autojosaattr\@ne 을}}
+\let\를\을
+
+\protected\def\와{{\autojosaattr\@ne 와}}
+\let\과\와
+
+\protected\def\가{{\autojosaattr\@ne 가}}
+\protected\def\이{{\autojosaattr\@ne 이}}
+\protected\def\라{\이라}
+
+\protected\def\으{{\autojosaattr\@ne 으}}
+\protected\def\로{\으로}
+
+%% dot-emphasis
+\def\dotemphraise{0.4em }
+\unless\ifdefined\bfseries\let\bfseries\bf\fi
+\def\dotemphchar{\bfseries ^^^^02d9}
+\newcount\dotemph@cnt \dotemph@cnt\z@
+\protected\def\dotemph#1{{%
+ \ifnum\dotemph@cnt > 100 \global\dotemph@cnt\z@ \fi
+ \global\advance\dotemph@cnt\@ne
+ \setbox\z@\hbox{\raise\dotemphraise\hbox{\dotemphchar}}\ht\z@\z@\dp\z@\z@
+ \directlua{luatexko.dotemphnode[\the\dotemph@cnt] = node.copy_list(tex.box[0])}%
+ \dotemphattr\dotemph@cnt #1}}
+
+%% ruby : ruby.sty by Lemberg is excellent; but
+%% it doesn't match well with luatexko, so implemented anew
+%% with plain tex support and enhanced features.
+\def\rubysize{0.6} % size of ruby compared to base character
+\def\rubysep{0.1ex} % distance between base character and ruby
+% users can define \rubyfont : eg. \font\rubyfont={foo:+ruby}
+\newif\ifruby@overlap
+\let\rubyoverlap\ruby@overlaptrue
+\let\rubynooverlap\ruby@overlapfalse
+\rubyoverlap % ruby may protrude over adjacent chars
+\newcount\luakorubyattr@cnt\luakorubyattr@cnt\z@
+\protected\def\ruby#1#2{%
+ \ifnum\luakorubyattr@cnt > 1000 \global\luakorubyattr@cnt\z@ \fi
+ \global\advance\luakorubyattr@cnt\@ne
+ \begingroup
+ \setbox\z@\hbox attr\luakorubyattrnum\luakorubyattr@cnt{% base character
+ \vrule width\z@ height.88em depth\z@\relax #1}%
+ \setbox\tw@\hbox{% ruby
+ \ifdefined\rubyfont \rubyfont \fi
+ \expandafter\dimen@\pdffontsize\the\font
+ \dimen@\rubysize\dimen@
+ \ifcsname selectfont\endcsname
+ \fontsize\dimen@\dimen@\selectfont
+ \else
+ \ifdefined\rubyfont \else
+ \resizecurrentfont{\the\dimen@}%
+ \fi
+ \fi #2}\ht\tw@\z@\dp\tw@\z@
+ \directlua{%
+ luatexko.rubynode[\the\luakorubyattr@cnt] = {
+ node.copy_list(tex.box[2]),
+ \number\numexpr\dimexpr\rubysep\relax\relax,
+ \ifruby@overlap true\else false\fi}}%
+ \leavevmode\box\z@
+ \endgroup}
+
+\ifcsname selectfont\endcsname\else
+ % font resize under plain tex
+ % ex: \resizecurrentfont{9pt}
+ \def\resizecurrentfont#1{%
+ \edef\curr@font@name{\directlua{
+ local f = font.current()
+ f = f and fonts.hashes.identifiers[f]
+ f = f and f.properties and f.properties.name
+ if not f then
+ f = "\fontname\font"
+ f = string.gsub(f," at .+","")
+ end
+ if f then
+ tex.sprint(f)
+ else
+ error("cannot get current font name")
+ end
+ }}%
+ \font\resized@font={\curr@font@name} at #1\resized@font}
+\fi
+
+%% vertical typesetting
+%% EXPERIMENTAL code: don't use this
+\def\luatexko@vertical{%
+ \ifnum\cjtypesetattr<\@ne
+ \cjtypesetattr\z@ % korean-vertical
+ \spaceskip 0.5em plus 0.15em minus 0.06em
+ \parindent 1em
+ \fi
+}
+\protected\def\vertical#1{%
+ \leavevmode
+ \setbox\z@\vbox\bgroup
+ \hsize#1\relax
+ \luatexko@vertical
+ \parindent\z@
+ \everypar{}%
+ \leftskip\z@
+ \rightskip\z@ }
+\protected\def\endvertical{\egroup\luatexkorotatebox\z@\box\z@}
+\protected\def\luatexkorotatebox#1{%
+ \ifvbox#1\count@\@ne\else\count@\z@\fi
+ \dimen@\wd#1\dimen@ii\dimexpr\ht#1+\dp#1\relax
+ \setbox#1\ifnum\count@=\@ne
+ \vbox to\dimen@\bgroup\hbox to\dimen@ii\bgroup\hfil\else
+ \hbox to\dimen@ii\bgroup\vbox to\dimen@\bgroup\fi
+ \wd#1\z@ \ht#1\z@ \dp#1\z@
+ \pdfliteral{ q 0 -1 1 0 0 0 cm}\box#1\pdfliteral{ Q}%
+ \ifnum\count@=\@ne\egroup\vfil\else\vfil\egroup\hfil\fi\egroup}
+
+% do not veticalize headline/footline
+\ifdefined\ProvidesPackage % for latex
+ \def\verticaltypesetting{%
+ \maxdepth\z@ \luatexko@vertical
+ \dimen@\textwidth \textwidth\textheight \textheight\dimen@
+ \edef\@outputpage{\unexpanded{\luatexkorotatebox\@outputbox
+ \textwidth\textheight}\unexpanded\expandafter{\@outputpage}}}
+\else % for plain
+ \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@ \luatexko@vertical}
+\fi
+
+%% underline using post_linebreak_filter
+%% ulem doesn't work well with luatexko;
+%% especially linebreak does not occur inside cjk words.
+\def\ulinewidth{0.04em }
+\def\ulinedown {0.25em }
+\newcount\ulinebox@cnt\ulinebox@cnt\z@
+\protected\def\uline#1{%
+ \ifnum\ulinebox@cnt > 100 \global\ulinebox@cnt\z@ \fi
+ \global\advance\ulinebox@cnt\@ne
+ \dimen@\dimexpr\ulinedown+\ulinewidth\relax
+ \dimen@ii-\dimexpr\ulinedown\relax
+ \setbox\z@\hbox{\vrule width\z@ height\dimen@ii depth\dimen@}%
+ \directlua{luatexko.ulinebox[\the\ulinebox@cnt]=node.copy_list(tex.box[0].head)}%
+ \leavevmode\special{luako:ulinebegin=\the\ulinebox@cnt}%
+ #1\special{luako:ulineend}}
+% strike-out
+\protected\def\sout#1{{\def\ulinedown{-0.5ex-\ulinewidth/2}\uline{#1}}}
+% ulem with arbitray box
+\protected\def\markoverwidth#1#2{%
+ \ifnum\ulinebox@cnt > 100 \global\ulinebox@cnt\z@ \fi
+ \global\advance\ulinebox@cnt\@ne
+ \setbox\z@\hbox{#1}%
+ \directlua{luatexko.ulinebox[\the\ulinebox@cnt]=node.copy_list(tex.box[0])}%
+ \leavevmode\special{luako:ulinebegin=\the\ulinebox@cnt}%
+ #2\special{luako:ulineend}}
+\protected\def\uuline{\dimen@ii-\dimexpr\ulinedown\relax
+ \dimen@\dimexpr\ulinedown+\ulinewidth\relax
+ \markoverwidth{\vtop{\hrule width.2em height\dimen@ii depth\dimen@
+ \kern.1em\hrule height\dimen@ii depth\dimen@}}}
+\protected\def\uwave {\ifx\ltxko@sixly\undefined \font\ltxko@sixly=lasy6 \fi
+ \markoverwidth{\lower4\p@\hbox{\ltxko@sixly\char58}}}
+\protected\def\xout {\markoverwidth{\hbox to.35em{/\hss}}}
+\protected\def\dashuline{\markoverwidth{\kern.125em\vtop{\kern\ulinedown
+ \hrule width.3em height\z@ depth\ulinewidth}\kern.125em}}
+\protected\def\dotuline{\dimen@\dimexpr\ulinedown+0.1ex\relax
+ \markoverwidth{\lower\dimen@\hbox{\kern.1em .\kern.04em}}}
+
+%% hangul font -- core
+\def\luatexko@hangul@selectfont{%
+ \begingroup
+ \let\luatexko@hangul@selectfont\relax
+ \let\luatexko@hanja@selectfont\relax
+ \check@hangul@family
+ \ifdefined\hangul@font \hangul@font \fi
+ \expandafter\endgroup
+ \directlua{
+ local i = font.current()
+ local name = fonts.hashes.identifiers[i]
+ name = name and name.properties and name.properties.name
+ luatexko.tmpfntname = name or "luatexkodefault"
+ }%
+ \directlua{
+ local name = luatexko.tmpfntname
+ local hang = luatexko.hangulfont[name]
+ if hang then
+ tex.setattribute("hangfntattr", hang)
+ else
+ local c = luatexko.hangulcount
+ c = c + 1
+ luatexko.hangulcount = c
+ tex.setattribute("hangfntattr",c)
+ luatexko.hangulfont[name] = c
+ luatexko.hangulfont[c] = name
+ end }%
+}
+\def\luatexko@hanja@selectfont{%
+ \begingroup
+ \let\luatexko@hangul@selectfont\relax
+ \let\luatexko@hanja@selectfont\relax
+ \check@hanja@family
+ \ifdefined\hanja@font \hanja@font \fi
+ \expandafter\endgroup
+ \directlua{
+ local i = font.current()
+ local name = fonts.hashes.identifiers[i]
+ name = name and name.properties and name.properties.name
+ luatexko.tmpfntname = name or "luatexkodefault"
+ }%
+ \directlua{
+ local name = luatexko.tmpfntname
+ local hanj = luatexko.hangulfont[name]
+ if hanj then
+ tex.setattribute("hanjfntattr", hanj)
+ else
+ local c = luatexko.hangulcount
+ c = c + 1
+ luatexko.hangulcount = c
+ tex.setattribute("hanjfntattr",c)
+ luatexko.hangulfont[name] = c
+ luatexko.hangulfont[c] = name
+ end }%
+ \ifnum\cjtypesetattr>\z@\luatexkolatinspaceskip\fi
+}
+\let\check@hangul@family\relax
+\let\check@hanja@family \relax
+% user interface for plain tex
+\protected\def\hangulfont
+ {\afterassignment\luatexko@hangul@selectfont\font\hangul@font}
+\protected\def\hanjafont
+ {\afterassignment\luatexko@hanja@selectfont \font\hanja@font }
+
+%% hangul in math mode -- general
+\def\setmathhangulblock#1#2{%
+ \count@="#1
+ \loop
+ \luatexUmathcode\count@ = 7 \symmathhangul \count@
+ \ifnum\count@<"#2
+ \advance\count@\@ne
+ \repeat}
+\ifdefined\ProvidesPackage
+ \let\setmathhangulfont\@gobble
+\else
+ % for plain; see luatexko.sty for latex
+ \newfam\symmathhangul
+ \def\setmathhangulfont#1#{\setmathhangulfont@}
+ \def\setmathhangulfont@#1{%
+ \font\tenhangul = "#1" at 10pt
+ \font\sevenhangul = "#1" at 7pt
+ \font\fivehangul = "#1" at 5pt
+ \textfont\symmathhangul = \tenhangul
+ \scriptfont\symmathhangul = \sevenhangul
+ \scriptscriptfont\symmathhangul = \fivehangul}
+ \setmathhangulblock{AC00}{D7A3}
+\fi
+
+%% hangul normalization
+\def\luatexhangulnormalize{\RequireLuaModule{luatexko-normalize}%
+ \afterassignment\luatexh@ngulnorm@lize\count@}
+\def\luatexh@ngulnorm@lize{%
+ \ifnum\count@=\z@
+ \directlua{ luatexkonormalize.unload() }%
+ \else\ifnum\count@=\@ne % nfc
+ \directlua{ luatexkonormalize.compose() }%
+ \else\ifnum\count@=\tw@ % nfd
+ \directlua{ luatexkonormalize.decompose() }%
+ \fi\fi\fi}
+
+%% uhc to utf8
+\def\luatexuhcinputencoding{\RequireLuaModule{luatexko-uhc2utf8}%
+ \afterassignment\luatexuhcinput@ncoding\count@}
+\def\luatexuhcinput@ncoding{%
+ \ifnum\count@>\z@
+ \directlua{ luatexkouhc2utf8.startconvert() }%
+ \else
+ \directlua{ luatexkouhc2utf8.stopconvert() }%
+ \fi}
+
+%% uhc file names
+\def\luatexuhcfilenames{\RequireLuaModule{luatexko-uhc2utf8}%
+ \afterassignment\luatexuhcfilen@mes\count@}
+\def\luatexuhcfilen@mes{%
+ \ifnum\count@>\z@
+ \directlua{ luatexkouhc2utf8.start_uhc_filename() }%
+ \else
+ \directlua{ luatexkouhc2utf8.stop_uhc_filename() }%
+ \fi}
+
+%% use hanja font for hanja chars
+\def\hanjafontforhanja{\afterassignment\h@nj@fontforh@nj@\count@}
+\let\hanjabyhanjafont\hanjafontforhanja
+\def\h@nj@fontforh@nj@{%
+ \ifnum\count@>\z@
+ \directlua{ luatexko.hanjafontforhanja = true }%
+ \else
+ \directlua{ luatexko.hanjafontforhanja = false }%
+ \fi}
+
+%% frenchspacing is default
+\frenchspacing
+
+%% 말줄임표
+\def\hellipsis{^^^^2026\kern-.1em ^^^^2026}
+
+\endinput
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua
new file mode 100644
index 00000000000..85533605571
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua
@@ -0,0 +1,486 @@
+-- $Id: luatexko-normalize.lua,v 1.5 2012/06/01 08:31:05 nomos Exp $
+--
+-- Copyright (c) 2013 Dohyun Kim <nomos at ktug org>
+--
+-- 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.
+
+module('luatexkonormalize', package.seeall)
+
+luatexbase.provides_module({
+ name = "luatexko-normalize",
+ version = 1.0,
+ date = "2013/05/10",
+ author = "Dohyun Kim",
+ description = "Hangul normalization",
+ license = "LPPL v1.3+",
+})
+
+local cho = "[\225\132\128-\225\132\146]"
+local jung = "[\225\133\161-\225\133\181]"
+local jong = "[\225\134\168-\225\135\130]"
+local ojong = "[\225\135\131-\225\135\191\237\159\139-\237\159\187]"
+local compathanja = "[\239\164\128-\239\168\139]"
+local chanjatohanja = {
+ [0xF900] = 0x8C48,
+ [0xF901] = 0x66F4,
+ [0xF902] = 0x8ECA,
+ [0xF903] = 0x8CC8,
+ [0xF904] = 0x6ED1,
+ [0xF905] = 0x4E32,
+ [0xF906] = 0x53E5,
+ [0xF907] = 0x9F9C,
+ [0xF908] = 0x9F9C,
+ [0xF909] = 0x5951,
+ [0xF90A] = 0x91D1,
+ [0xF90B] = 0x5587,
+ [0xF90C] = 0x5948,
+ [0xF90D] = 0x61F6,
+ [0xF90E] = 0x7669,
+ [0xF90F] = 0x7F85,
+ [0xF910] = 0x863F,
+ [0xF911] = 0x87BA,
+ [0xF912] = 0x88F8,
+ [0xF913] = 0x908F,
+ [0xF914] = 0x6A02,
+ [0xF915] = 0x6D1B,
+ [0xF916] = 0x70D9,
+ [0xF917] = 0x73DE,
+ [0xF918] = 0x843D,
+ [0xF919] = 0x916A,
+ [0xF91A] = 0x99F1,
+ [0xF91B] = 0x4E82,
+ [0xF91C] = 0x5375,
+ [0xF91D] = 0x6B04,
+ [0xF91E] = 0x721B,
+ [0xF91F] = 0x862D,
+ [0xF920] = 0x9E1E,
+ [0xF921] = 0x5D50,
+ [0xF922] = 0x6FEB,
+ [0xF923] = 0x85CD,
+ [0xF924] = 0x8964,
+ [0xF925] = 0x62C9,
+ [0xF926] = 0x81D8,
+ [0xF927] = 0x881F,
+ [0xF928] = 0x5ECA,
+ [0xF929] = 0x6717,
+ [0xF92A] = 0x6D6A,
+ [0xF92B] = 0x72FC,
+ [0xF92C] = 0x90DE,
+ [0xF92D] = 0x4F86,
+ [0xF92E] = 0x51B7,
+ [0xF92F] = 0x52DE,
+ [0xF930] = 0x64C4,
+ [0xF931] = 0x6AD3,
+ [0xF932] = 0x7210,
+ [0xF933] = 0x76E7,
+ [0xF934] = 0x8001,
+ [0xF935] = 0x8606,
+ [0xF936] = 0x865C,
+ [0xF937] = 0x8DEF,
+ [0xF938] = 0x9732,
+ [0xF939] = 0x9B6F,
+ [0xF93A] = 0x9DFA,
+ [0xF93B] = 0x788C,
+ [0xF93C] = 0x797F,
+ [0xF93D] = 0x7DA0,
+ [0xF93E] = 0x83C9,
+ [0xF93F] = 0x9304,
+ [0xF940] = 0x9E7F,
+ [0xF941] = 0x8AD6,
+ [0xF942] = 0x58DF,
+ [0xF943] = 0x5F04,
+ [0xF944] = 0x7C60,
+ [0xF945] = 0x807E,
+ [0xF946] = 0x7262,
+ [0xF947] = 0x78CA,
+ [0xF948] = 0x8CC2,
+ [0xF949] = 0x96F7,
+ [0xF94A] = 0x58D8,
+ [0xF94B] = 0x5C62,
+ [0xF94C] = 0x6A13,
+ [0xF94D] = 0x6DDA,
+ [0xF94E] = 0x6F0F,
+ [0xF94F] = 0x7D2F,
+ [0xF950] = 0x7E37,
+ [0xF951] = 0x964B,
+ [0xF952] = 0x52D2,
+ [0xF953] = 0x808B,
+ [0xF954] = 0x51DC,
+ [0xF955] = 0x51CC,
+ [0xF956] = 0x7A1C,
+ [0xF957] = 0x7DBE,
+ [0xF958] = 0x83F1,
+ [0xF959] = 0x9675,
+ [0xF95A] = 0x8B80,
+ [0xF95B] = 0x62CF,
+ [0xF95C] = 0x6A02,
+ [0xF95D] = 0x8AFE,
+ [0xF95E] = 0x4E39,
+ [0xF95F] = 0x5BE7,
+ [0xF960] = 0x6012,
+ [0xF961] = 0x7387,
+ [0xF962] = 0x7570,
+ [0xF963] = 0x5317,
+ [0xF964] = 0x78FB,
+ [0xF965] = 0x4FBF,
+ [0xF966] = 0x5FA9,
+ [0xF967] = 0x4E0D,
+ [0xF968] = 0x6CCC,
+ [0xF969] = 0x6578,
+ [0xF96A] = 0x7D22,
+ [0xF96B] = 0x53C3,
+ [0xF96C] = 0x585E,
+ [0xF96D] = 0x7701,
+ [0xF96E] = 0x8449,
+ [0xF96F] = 0x8AAA,
+ [0xF970] = 0x6BBA,
+ [0xF971] = 0x8FB0,
+ [0xF972] = 0x6C88,
+ [0xF973] = 0x62FE,
+ [0xF974] = 0x82E5,
+ [0xF975] = 0x63A0,
+ [0xF976] = 0x7565,
+ [0xF977] = 0x4EAE,
+ [0xF978] = 0x5169,
+ [0xF979] = 0x51C9,
+ [0xF97A] = 0x6881,
+ [0xF97B] = 0x7CE7,
+ [0xF97C] = 0x826F,
+ [0xF97D] = 0x8AD2,
+ [0xF97E] = 0x91CF,
+ [0xF97F] = 0x52F5,
+ [0xF980] = 0x5442,
+ [0xF981] = 0x5973,
+ [0xF982] = 0x5EEC,
+ [0xF983] = 0x65C5,
+ [0xF984] = 0x6FFE,
+ [0xF985] = 0x792A,
+ [0xF986] = 0x95AD,
+ [0xF987] = 0x9A6A,
+ [0xF988] = 0x9E97,
+ [0xF989] = 0x9ECE,
+ [0xF98A] = 0x529B,
+ [0xF98B] = 0x66C6,
+ [0xF98C] = 0x6B77,
+ [0xF98D] = 0x8F62,
+ [0xF98E] = 0x5E74,
+ [0xF98F] = 0x6190,
+ [0xF990] = 0x6200,
+ [0xF991] = 0x649A,
+ [0xF992] = 0x6F23,
+ [0xF993] = 0x7149,
+ [0xF994] = 0x7489,
+ [0xF995] = 0x79CA,
+ [0xF996] = 0x7DF4,
+ [0xF997] = 0x806F,
+ [0xF998] = 0x8F26,
+ [0xF999] = 0x84EE,
+ [0xF99A] = 0x9023,
+ [0xF99B] = 0x934A,
+ [0xF99C] = 0x5217,
+ [0xF99D] = 0x52A3,
+ [0xF99E] = 0x54BD,
+ [0xF99F] = 0x70C8,
+ [0xF9A0] = 0x88C2,
+ [0xF9A1] = 0x8AAA,
+ [0xF9A2] = 0x5EC9,
+ [0xF9A3] = 0x5FF5,
+ [0xF9A4] = 0x637B,
+ [0xF9A5] = 0x6BAE,
+ [0xF9A6] = 0x7C3E,
+ [0xF9A7] = 0x7375,
+ [0xF9A8] = 0x4EE4,
+ [0xF9A9] = 0x56F9,
+ [0xF9AA] = 0x5BE7,
+ [0xF9AB] = 0x5DBA,
+ [0xF9AC] = 0x601C,
+ [0xF9AD] = 0x73B2,
+ [0xF9AE] = 0x7469,
+ [0xF9AF] = 0x7F9A,
+ [0xF9B0] = 0x8046,
+ [0xF9B1] = 0x9234,
+ [0xF9B2] = 0x96F6,
+ [0xF9B3] = 0x9748,
+ [0xF9B4] = 0x9818,
+ [0xF9B5] = 0x4F8B,
+ [0xF9B6] = 0x79AE,
+ [0xF9B7] = 0x91B4,
+ [0xF9B8] = 0x96B7,
+ [0xF9B9] = 0x60E1,
+ [0xF9BA] = 0x4E86,
+ [0xF9BB] = 0x50DA,
+ [0xF9BC] = 0x5BEE,
+ [0xF9BD] = 0x5C3F,
+ [0xF9BE] = 0x6599,
+ [0xF9BF] = 0x6A02,
+ [0xF9C0] = 0x71CE,
+ [0xF9C1] = 0x7642,
+ [0xF9C2] = 0x84FC,
+ [0xF9C3] = 0x907C,
+ [0xF9C4] = 0x9F8D,
+ [0xF9C5] = 0x6688,
+ [0xF9C6] = 0x962E,
+ [0xF9C7] = 0x5289,
+ [0xF9C8] = 0x677B,
+ [0xF9C9] = 0x67F3,
+ [0xF9CA] = 0x6D41,
+ [0xF9CB] = 0x6E9C,
+ [0xF9CC] = 0x7409,
+ [0xF9CD] = 0x7559,
+ [0xF9CE] = 0x786B,
+ [0xF9CF] = 0x7D10,
+ [0xF9D0] = 0x985E,
+ [0xF9D1] = 0x516D,
+ [0xF9D2] = 0x622E,
+ [0xF9D3] = 0x9678,
+ [0xF9D4] = 0x502B,
+ [0xF9D5] = 0x5D19,
+ [0xF9D6] = 0x6DEA,
+ [0xF9D7] = 0x8F2A,
+ [0xF9D8] = 0x5F8B,
+ [0xF9D9] = 0x6144,
+ [0xF9DA] = 0x6817,
+ [0xF9DB] = 0x7387,
+ [0xF9DC] = 0x9686,
+ [0xF9DD] = 0x5229,
+ [0xF9DE] = 0x540F,
+ [0xF9DF] = 0x5C65,
+ [0xF9E0] = 0x6613,
+ [0xF9E1] = 0x674E,
+ [0xF9E2] = 0x68A8,
+ [0xF9E3] = 0x6CE5,
+ [0xF9E4] = 0x7406,
+ [0xF9E5] = 0x75E2,
+ [0xF9E6] = 0x7F79,
+ [0xF9E7] = 0x88CF,
+ [0xF9E8] = 0x88E1,
+ [0xF9E9] = 0x91CC,
+ [0xF9EA] = 0x96E2,
+ [0xF9EB] = 0x533F,
+ [0xF9EC] = 0x6EBA,
+ [0xF9ED] = 0x541D,
+ [0xF9EE] = 0x71D0,
+ [0xF9EF] = 0x7498,
+ [0xF9F0] = 0x85FA,
+ [0xF9F1] = 0x96A3,
+ [0xF9F2] = 0x9C57,
+ [0xF9F3] = 0x9E9F,
+ [0xF9F4] = 0x6797,
+ [0xF9F5] = 0x6DCB,
+ [0xF9F6] = 0x81E8,
+ [0xF9F7] = 0x7ACB,
+ [0xF9F8] = 0x7B20,
+ [0xF9F9] = 0x7C92,
+ [0xF9FA] = 0x72C0,
+ [0xF9FB] = 0x7099,
+ [0xF9FC] = 0x8B58,
+ [0xF9FD] = 0x4EC0,
+ [0xF9FE] = 0x8336,
+ [0xF9FF] = 0x523A,
+ [0xFA00] = 0x5207,
+ [0xFA01] = 0x5EA6,
+ [0xFA02] = 0x62D3,
+ [0xFA03] = 0x7CD6,
+ [0xFA04] = 0x5B85,
+ [0xFA05] = 0x6D1E,
+ [0xFA06] = 0x66B4,
+ [0xFA07] = 0x8F3B,
+ [0xFA08] = 0x884C,
+ [0xFA09] = 0x964D,
+ [0xFA0A] = 0x898B,
+ [0xFA0B] = 0x5ED3,
+}
+local jamotocjamo = {
+ ccho = {
+ [0x1100] = 0x3131,
+ [0x1101] = 0x3132,
+ -- [0x11AA] = 0x3133,
+ [0x1102] = 0x3134,
+ -- [0x11AC] = 0x3135,
+ -- [0x11AD] = 0x3136,
+ [0x1103] = 0x3137,
+ [0x1104] = 0x3138,
+ [0x1105] = 0x3139,
+ -- [0x11B0] = 0x313A,
+ -- [0x11B1] = 0x313B,
+ -- [0x11B2] = 0x313C,
+ -- [0x11B3] = 0x313D,
+ -- [0x11B4] = 0x313E,
+ -- [0x11B5] = 0x313F,
+ [0x111A] = 0x3140,
+ [0x1106] = 0x3141,
+ [0x1107] = 0x3142,
+ [0x1108] = 0x3143,
+ [0x1121] = 0x3144,
+ [0x1109] = 0x3145,
+ [0x110A] = 0x3146,
+ [0x110B] = 0x3147,
+ [0x110C] = 0x3148,
+ [0x110D] = 0x3149,
+ [0x110E] = 0x314A,
+ [0x110F] = 0x314B,
+ [0x1110] = 0x314C,
+ [0x1111] = 0x314D,
+ [0x1112] = 0x314E,
+ [0x1114] = 0x3165,
+ [0x1115] = 0x3166,
+ -- [0x11C7] = 0x3167,
+ -- [0x11C8] = 0x3168,
+ -- [0x11CC] = 0x3169,
+ -- [0x11CE] = 0x316A,
+ -- [0x11D3] = 0x316B,
+ -- [0x11D7] = 0x316C,
+ -- [0x11D9] = 0x316D,
+ [0x111C] = 0x316E,
+ -- [0x11DD] = 0x316F,
+ -- [0x11DF] = 0x3170,
+ [0x111D] = 0x3171,
+ [0x111E] = 0x3172,
+ [0x1120] = 0x3173,
+ [0x1122] = 0x3174,
+ [0x1123] = 0x3175,
+ [0x1127] = 0x3176,
+ [0x1129] = 0x3177,
+ [0x112B] = 0x3178,
+ [0x112C] = 0x3179,
+ [0x112D] = 0x317A,
+ [0x112E] = 0x317B,
+ [0x112F] = 0x317C,
+ [0x1132] = 0x317D,
+ [0x1136] = 0x317E,
+ [0x1140] = 0x317F,
+ [0x1147] = 0x3180,
+ [0x114C] = 0x3181,
+ -- [0x11F1] = 0x3182,
+ -- [0x11F2] = 0x3183,
+ [0x1157] = 0x3184,
+ [0x1158] = 0x3185,
+ [0x1159] = 0x3186,
+ },
+ cjung = {
+ [0x1161] = 0x314F,
+ [0x1162] = 0x3150,
+ [0x1163] = 0x3151,
+ [0x1164] = 0x3152,
+ [0x1165] = 0x3153,
+ [0x1166] = 0x3154,
+ [0x1167] = 0x3155,
+ [0x1168] = 0x3156,
+ [0x1169] = 0x3157,
+ [0x116A] = 0x3158,
+ [0x116B] = 0x3159,
+ [0x116C] = 0x315A,
+ [0x116D] = 0x315B,
+ [0x116E] = 0x315C,
+ [0x116F] = 0x315D,
+ [0x1170] = 0x315E,
+ [0x1171] = 0x315F,
+ [0x1172] = 0x3160,
+ [0x1173] = 0x3161,
+ [0x1174] = 0x3162,
+ [0x1175] = 0x3163,
+ -- [0x1160] = 0x3164,
+ [0x1184] = 0x3187,
+ [0x1185] = 0x3188,
+ [0x1188] = 0x3189,
+ [0x1191] = 0x318A,
+ [0x1192] = 0x318B,
+ [0x1194] = 0x318C,
+ [0x119E] = 0x318D,
+ [0x11A1] = 0x318E,
+ }
+}
+
+local gsub = unicode.utf8.gsub
+local byte = unicode.utf8.byte
+local char = unicode.utf8.char
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+
+local syllable2jamo = function(l,v,t)
+ l, v = byte(l), byte(v)
+ local s = (l - 0x1100) * 21
+ s = (s + v - 0x1161) * 28
+ if t then
+ t = byte(t)
+ s = s + t - 0x11a7
+ end
+ s = s + 0xac00
+ return char(s)
+end
+
+local hanguldecompose = function(buffer)
+ buffer = gsub(buffer, "[가-힣]", function(s)
+ s = byte(s) - 0xac00
+ local cho = s / (21 * 28) + 0x1100
+ local jung = (s % (21 * 28)) / 28 + 0x1161
+ local jong = s % 28 + 0x11a7
+ if jong > 0x11a7 then
+ return char(cho)..char(jung)..char(jong)
+ end
+ return char(cho)..char(jung)
+ end)
+ return buffer
+end
+
+local function hanjanormalize(c)
+ local hanja = chanjatohanja[byte(c)]
+ hanja = hanja and char(hanja)
+ return hanja
+end
+
+local function jamo2cjamocho(c)
+ local jamo = jamotocjamo.ccho[byte(c)]
+ jamo = jamo and char(jamo)
+ return jamo
+end
+
+local function jamo2cjamojung(c)
+ local jamo = jamotocjamo.cjung[byte(c)]
+ jamo = jamo and char(jamo)
+ return jamo
+end
+
+local hangulcompose = function(buffer)
+ buffer = hanguldecompose(buffer)
+ buffer = gsub(buffer, "("..cho..")("..jung..")("..jong..")", syllable2jamo)
+ buffer = gsub(buffer, "("..cho..")("..jung..ojong..")", "%1\1%2")
+ buffer = gsub(buffer, "("..cho..")("..jung..")", syllable2jamo)
+ buffer = gsub(buffer, "([\225\132\128-\225\133\153])\225\133\160", jamo2cjamocho)
+ buffer = gsub(buffer, "\225\133\159([\225\133\161-\225\134\161])", jamo2cjamojung)
+ buffer = gsub(buffer, "\1", "")
+ buffer = gsub(buffer, "("..compathanja..")", hanjanormalize)
+ return buffer
+end
+
+local loaded = false
+
+function compose()
+ if loaded then
+ remove_from_callback('process_input_buffer', 'luatexko-hangul-normalize')
+ end
+ loaded = true
+ add_to_callback('process_input_buffer', hangulcompose, 'luatexko-hangul-normalize')
+end
+
+function decompose()
+ if loaded then
+ remove_from_callback('process_input_buffer', 'luatexko-hangul-normalize')
+ end
+ loaded = true
+ add_to_callback('process_input_buffer', hanguldecompose, 'luatexko-hangul-normalize')
+end
+
+function unload()
+ if loaded then
+ remove_from_callback('process_input_buffer', 'luatexko-hangul-normalize')
+ end
+ loaded = false
+end
+
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua
new file mode 100644
index 00000000000..9f792d0397d
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua
@@ -0,0 +1,130 @@
+-- $Id: luatexko-uhc2utf8.lua,v 1.4 2011/07/08 15:23:52 nomos Exp $
+--
+-- Copyright (c) 2013 Dohyun Kim <nomos at ktug org>
+--
+-- 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.
+
+module('luatexkouhc2utf8', package.seeall)
+
+luatexbase.provides_module({
+ name = "luatexko-uhc2utf8",
+ version = 1.0,
+ date = "2013/05/10",
+ author = "Dohyun Kim",
+ description = "UHC (CP949) input encoding",
+ license = "LPPL v1.3+",
+})
+
+local find = string.find
+local gsub = string.gsub
+local byte = string.byte
+local len = string.len
+local format = string.format
+local ugsub = unicode.utf8.gsub
+local ubyte = unicode.utf8.byte
+local uchar = unicode.utf8.char
+local floor = math.floor
+local isfile = lfs.isfile
+local kpse_find_file = kpse.find_file
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+
+local function get_uhc_uni_table()
+ local t_uhc2ucs = {}
+ local file = kpse_find_file("KSCms-UHC-UCS2","cmap files")
+ if file then
+ file = io.open(file, "r")
+ while true do
+ local line = file:read("*line")
+ if not line then break end
+ local _,_,ea,eb,uni = find(line,"<(%x+)>%s+<(%x+)>%s+<(%x+)>")
+ if ea and eb and uni then
+ ea, eb, uni = tonumber(ea,16),tonumber(eb,16),tonumber(uni,16)
+ for i=ea,eb do
+ t_uhc2ucs[i] = uni
+ uni = uni + 1
+ end
+ end
+ end
+ file:close()
+ end
+ return t_uhc2ucs
+end
+
+local t_uhc2ucs = t_uhc2ucs or get_uhc_uni_table()
+
+local uhc_to_utf8 = function(buffer)
+ if not buffer then return end
+ -- check if buffer is already utf-8; better solution?
+ local t = gsub(buffer,"[\0-\127]","")
+ t = gsub(t,"[\194-\223][\128-\191]","")
+ t = gsub(t,"[\224-\239][\128-\191][\128-\191]","")
+ t = gsub(t,"[\240-\244][\128-\191][\128-\191][\128-\191]","")
+ if len(t) == 0 then return buffer end
+ -- now convert to utf8
+ buffer = gsub(buffer, "([\129-\253])([\65-\254])",
+ function(a, b)
+ a, b = byte(a), byte(b)
+ local utf = t_uhc2ucs[a * 256 + b]
+ if utf then return uchar(utf) end
+ end)
+ return buffer
+end
+
+function startconvert ()
+ add_to_callback('process_input_buffer', uhc_to_utf8, 'luatexko-uhctoutf8', 1)
+end
+
+function stopconvert ()
+ remove_from_callback('process_input_buffer', 'luatexko-uhctoutf8')
+end
+
+-----------------------------------------
+-- Hangul Windows OS uses CP949 filenames
+-----------------------------------------
+local function get_uni_uhc_table()
+ local t_ucs2uhc = {}
+ for i,v in pairs(t_uhc2ucs) do
+ t_ucs2uhc[v] = i
+ end
+ return t_ucs2uhc
+end
+
+local t_ucs2uhc = t_ucs2uhc or get_uni_uhc_table()
+
+local function utf8_to_uhc (name)
+ if not name then return end
+ name = ugsub(name, "[\161-\239\191\166]", -- 00A1..FFE6
+ function(u)
+ local c = t_ucs2uhc[ubyte(u)]
+ if not c then return u end
+ return format("%c%c", floor(c/256), c%256)
+ end)
+ return name
+end
+
+local function uhc_find_file (file, ...)
+ local f = kpse_find_file(file, ...)
+ if f then return f end
+ f = utf8_to_uhc(file)
+ f = f and kpse_find_file(f, ...)
+ return f
+end
+
+function start_uhc_filename ()
+ add_to_callback('find_read_file', function(id, name) return uhc_find_file(name) end, 'luatexko-touhc-findreadfile')
+ add_to_callback('find_image_file', uhc_find_file, 'luatexko-touhc-findimagefile')
+ kpse.find_file = uhc_find_file
+end
+
+function stop_uhc_filename ()
+ remove_from_callback('find_read_file', 'luatexko-touhc-findreadfile')
+ remove_from_callback('find_image_file', 'luatexko-touhc-findimagefile')
+ kpse.find_file = kpse_find_file
+end
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
new file mode 100644
index 00000000000..98000fc1a98
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
@@ -0,0 +1,1720 @@
+-- $Id: luatexko.lua,v 1.29 2012/12/13 09:13:22 nomos Exp $
+--
+-- Copyright (c) 2013 Dohyun Kim <nomos at ktug org>
+--
+-- 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.
+
+module('luatexko', package.seeall)
+
+local err,warn,info,log = luatexbase.provides_module({
+ name = 'luatexko',
+ date = '2013/05/10',
+ version = 1.0,
+ description = 'Korean linebreaking and font-switching',
+ author = 'Dohyun Kim',
+ license = 'LPPL v1.3+',
+})
+
+local stringbyte = string.byte
+local stringgsub = string.gsub
+local stringchar = string.char
+local stringfind = string.find
+local stringmatch = string.match
+local stringgmatch = string.gmatch
+local stringformat = string.format
+local mathfloor = math.floor
+local tex_round = tex.round
+local tex_sp = tex.sp
+local fontdefine = font.define
+
+local fontdata = fonts.hashes.identifiers
+local font_define_func = callback.find("define_font")
+local utf8char = unicode.utf8.char
+
+local remove_node = node.remove
+local insert_before = node.insert_before
+local insert_after = node.insert_after
+local copy_node = node.copy
+local traverse_id = node.traverse_id
+local traverse = node.traverse
+local has_attribute = node.has_attribute
+local unset_attribute = node.unset_attribute
+local set_attribute = node.set_attribute
+local nodecount = node.count
+local nodeslide = node.slide
+local nodedimensions = node.dimensions
+local nodetail = node.tail
+
+local finemathattr = luatexbase.attributes.finemathattr
+local cjtypesetattr = luatexbase.attributes.cjtypesetattr
+local dotemphattr = luatexbase.attributes.dotemphattr
+local autojosaattr = luatexbase.attributes.autojosaattr
+local luakorubyattr = luatexbase.attributes.luakorubyattr
+local hangfntattr = luatexbase.attributes.hangfntattr
+local hanjfntattr = luatexbase.attributes.hanjfntattr
+local luakoglueattr = luatexbase.new_attribute("luakoglueattr")
+local luakounicodeattr = luatexbase.new_attribute("luakounicodeattr")
+local quoteraiseattr = luatexbase.new_attribute("quoteraiseattr")
+
+local add_to_callback = luatexbase.add_to_callback
+
+local gluenode = node.id("glue")
+local gluespecnode = node.id("glue_spec")
+local glyphnode = node.id("glyph")
+local discnode = node.id("disc")
+local mathnode = node.id("math")
+local hlistnode = node.id("hlist")
+local vlistnode = node.id("vlist")
+local kernnode = node.id("kern")
+local penaltynode = node.id("penalty")
+local rulenode = node.id("rule")
+local whatsitnode = node.id("whatsit")
+local whatsitspecial = node.subtype("special")
+
+local new_glue = node.new(gluenode)
+local new_glue_spec = node.new(gluespecnode)
+local new_penalty = node.new(penaltynode)
+local new_kern = node.new(kernnode,1)
+local new_rule = node.new(rulenode)
+
+local emsize = 655360
+
+dotemphnode = {}
+rubynode = {}
+ulinebox = {}
+hangulfont = {}
+hangulcount = 0
+hanjafontforhanja = false
+
+local cjkclass = {
+ [0x2018] = 1, -- ‘
+ [0x201C] = 1, -- “
+ [0xFF08] = 1, -- (
+ [0xFE35] = 1, -- ( vert
+ [0x3014] = 1, -- 〔
+ [0xFE39] = 1, -- 〔 vert
+ [0xFF3B] = 1, -- [
+ [0xFE47] = 1, -- [ vert
+ [0xFF5B] = 1, -- {
+ [0xFE37] = 1, -- { vert
+ [0x3008] = 1, -- 〈
+ [0xFE3F] = 1, -- 〈 vert
+ [0x300A] = 1, -- 《
+ [0xFE3D] = 1, -- 《 vert
+ [0x300C] = 1, -- 「
+ [0xFE41] = 1, -- 「 vert
+ [0x300E] = 1, -- 『
+ [0xFE43] = 1, -- 『 vert
+ [0x3010] = 1, -- 【
+ [0xFE3B] = 1, -- 【 vert
+ [0x3001] = 2, -- 、
+ [0xFE11] = 2, -- 、 vert
+ [0xFF0C] = 2, -- ,
+ [0xFE10] = 2, -- , vert
+ [0x2019] = 2, -- ’
+ [0x201D] = 2, -- ”
+ [0xFF09] = 2, -- )
+ [0xFE36] = 2, -- ) vert
+ [0x3015] = 2, -- 〕
+ [0xFE3A] = 2, -- 〕 vert
+ [0xFF3D] = 2, -- ]
+ [0xFE48] = 2, -- ] vert
+ [0xFF5D] = 2, -- }
+ [0xFE38] = 2, -- } vert
+ [0x3009] = 2, -- 〉
+ [0xFE40] = 2, -- 〉 vert
+ [0x300B] = 2, -- 》
+ [0xFE3E] = 2, -- 》 vert
+ [0x300D] = 2, -- 」
+ [0xFE42] = 2, -- 」 vert
+ [0x300F] = 2, -- 』
+ [0xFE44] = 2, -- 』 vert
+ [0x3011] = 2, -- 】
+ [0xFE3C] = 2, -- 】 vert
+ [0x00B7] = 3, -- ·
+ [0x30FB] = 3, -- ・
+ [0xFF1A] = 3, -- :
+ [0xFE13] = 3, -- : vert
+ [0xFF1B] = 3, -- ;
+ [0xFE14] = 3, -- ; vert
+ [0x3002] = 4, -- 。
+ [0xFE12] = 4, -- 。 vert
+ [0xFF0E] = 4, -- .
+ [0x2015] = 5, -- ―
+ [0x2026] = 5, -- …
+ [0xFE19] = 5, -- … vert
+ [0x2025] = 5, -- ‥
+ [0xFE30] = 5, -- ‥ vert
+ [0xFF1F] = 6, -- ?
+ [0xFF01] = 6, -- !
+}
+
+local inhibitxspcode = {
+ [0x002D] = 0, -- - hyphen minus
+ [0x003C] = 0, -- <
+ [0x003E] = 1, -- >
+ [0x00B0] = 1,
+ [0x2015] = 0,
+ [0x2018] = 2,
+ [0x2019] = 1,
+ [0x201C] = 2,
+ [0x201D] = 1,
+ [0x2026] = 0,
+ [0xFE19] = 0,
+ [0x2032] = 1,
+ [0x2033] = 1,
+ [0x3001] = 1,
+ [0xFE11] = 1,
+ [0x3002] = 1,
+ [0xFE12] = 1,
+ [0x3008] = 2,
+ [0xFE3F] = 2,
+ [0x3009] = 1,
+ [0xFE40] = 1,
+ [0x300A] = 2,
+ [0xFE3D] = 2,
+ [0x300B] = 1,
+ [0xFE3E] = 1,
+ [0x300C] = 2,
+ [0xFE41] = 2,
+ [0x300D] = 1,
+ [0xFE42] = 1,
+ [0x300E] = 2,
+ [0xFE43] = 2,
+ [0x300F] = 1,
+ [0xFE44] = 1,
+ [0x3010] = 2,
+ [0xFE3B] = 2,
+ [0x3011] = 1,
+ [0xFE3C] = 1,
+ [0x3012] = 2, -- 〒
+ [0x3014] = 2,
+ [0xFE39] = 2,
+ [0x3015] = 1,
+ [0xFE3A] = 1,
+ [0x301C] = 0,
+ [0xFF08] = 2,
+ [0xFE35] = 2,
+ [0xFF09] = 1,
+ [0xFE36] = 1,
+ [0xFF0C] = 1,
+ [0xFE10] = 1,
+ [0xFF0E] = 1,
+ [0xFF1B] = 1,
+ [0xFE14] = 1,
+ [0xFF1F] = 1,
+ [0xFF3B] = 2,
+ [0xFE47] = 2,
+ [0xFF3D] = 1,
+ [0xFE48] = 1,
+ [0xFF5B] = 2,
+ [0xFE37] = 2,
+ [0xFF5D] = 1,
+ [0xFE38] = 1,
+ [0xFFE5] = 0,
+}
+
+local postbreakpenalty = {
+ [0x0023] = 500,
+ [0x0024] = 500,
+ [0x0025] = 500,
+ [0x0026] = 500,
+ [0x0028] = 10000,
+ [0x003C] = 10000, -- <
+ [0x005B] = 10000,
+ [0x0060] = 10000,
+ [0x2013] = 50, -- en-dash
+ [0x2014] = 50, -- em-dash
+ [0x2018] = 10000,
+ [0x201C] = 10000,
+ [0x3008] = 10000,
+ [0xFE3F] = 10000,
+ [0x300A] = 10000,
+ [0xFE3D] = 10000,
+ [0x300C] = 10000,
+ [0xFE41] = 10000,
+ [0x300E] = 10000,
+ [0xFE43] = 10000,
+ [0x3010] = 10000,
+ [0xFE3B] = 10000,
+ [0x3014] = 10000,
+ [0xFE39] = 10000,
+ [0xFF03] = 200,
+ [0xFF04] = 200,
+ [0xFF05] = 200,
+ [0xFF06] = 200,
+ [0xFF08] = 10000,
+ [0xFE35] = 10000,
+ [0xFF3B] = 10000,
+ [0xFE47] = 10000,
+ [0xFF40] = 10000,
+ [0xFF5B] = 10000,
+ [0xFE37] = 10000,
+}
+
+local prebreakpenalty = {
+ [0x0021] = 10000,
+ [0x0022] = 10000,
+ [0x0027] = 10000,
+ [0x0029] = 10000,
+ [0x002A] = 500,
+ [0x002B] = 500,
+ [0x002C] = 10000,
+ [0x002D] = 10000,
+ [0x002E] = 10000,
+ [0x002F] = 500,
+ [0x003A] = 10000,
+ [0x003B] = 10000,
+ [0x003E] = 10000, -- >
+ [0x003F] = 10000,
+ [0x005D] = 10000,
+ [0x00B4] = 10000,
+ [0x00B7] = 10000, -- ·
+ [0x2013] = 10000, -- –
+ [0x2014] = 10000, -- —
+ [0x2015] = 10000,
+ [0x2019] = 10000,
+ [0x201D] = 10000,
+ [0x2025] = 250,
+ [0xFE30] = 250,
+ [0x2026] = 250,
+ [0xFE19] = 250,
+ [0x2212] = 200,
+ [0x3001] = 10000,
+ [0xFE11] = 10000,
+ [0x3002] = 10000,
+ [0xFE12] = 10000,
+ [0x3005] = 10000,
+ [0x3009] = 10000,
+ [0xFE40] = 10000,
+ [0x300B] = 10000,
+ [0xFE3E] = 10000,
+ [0x300D] = 10000,
+ [0xFE42] = 10000,
+ [0x300F] = 10000,
+ [0xFE44] = 10000,
+ [0x3011] = 10000,
+ [0xFE3C] = 10000,
+ [0x3015] = 10000,
+ [0xFE3A] = 10000,
+ [0x3041] = 150,
+ [0x3043] = 150,
+ [0x3045] = 150,
+ [0x3047] = 150,
+ [0x3049] = 150,
+ [0x3063] = 150,
+ [0x3083] = 150,
+ [0x3085] = 150,
+ [0x3087] = 150,
+ [0x308E] = 150,
+ [0x309B] = 10000,
+ [0x309C] = 10000,
+ [0x30A1] = 150,
+ [0x30A3] = 150,
+ [0x30A5] = 150,
+ [0x30A7] = 150,
+ [0x30A9] = 150,
+ [0x30C3] = 150,
+ [0x30E3] = 150,
+ [0x30E5] = 150,
+ [0x30E7] = 150,
+ [0x30EE] = 150,
+ [0x30F5] = 150,
+ [0x30F6] = 150,
+ [0x30FB] = 10000,
+ [0x30FC] = 10000,
+ [0xFF01] = 10000,
+ [0xFF09] = 10000,
+ [0xFE36] = 10000,
+ [0xFF0B] = 200,
+ [0xFF0C] = 10000,
+ [0xFE10] = 10000,
+ [0xFF0E] = 10000,
+ [0xFF1A] = 10000,
+ [0xFE13] = 10000,
+ [0xFF1B] = 10000,
+ [0xFE14] = 10000,
+ [0xFF1D] = 200,
+ [0xFF1F] = 10000,
+ [0xFF3D] = 10000,
+ [0xFE48] = 10000,
+ [0xFF5D] = 10000,
+ [0xFE38] = 10000,
+}
+
+local xspcode = {
+ [0x0027] = 2,
+ [0x0028] = 1,
+ [0x0029] = 2,
+ [0x002C] = 2,
+ [0x002E] = 2,
+ [0x003B] = 2,
+ [0x005B] = 1,
+ [0x005D] = 2,
+ [0x0060] = 1,
+}
+
+local cjk_glue_spec = { [0] =
+-- 한자 ( ) · . — ? 한글 초성 중종성 latin
+{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --한자
+{[0] = nil, nil, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, -- (
+{[0] = {.5,.5}, {.5,.5}, nil, {.25,.25},nil, {.5,.5}, {.5,.5}, {.25,.25},{.25,.25},{.25,.25},{.5,.5}, }, -- )
+{[0] = {.25,.25},{.25,.25},{.25,.25},{.5,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},}, -- ·
+{[0] = {.5,0}, {.5,0}, nil, {.75,.25},nil, {.5,0}, {.5,0}, {.5,0}, {.5,0}, {.5,0}, {.5,0}, }, -- .
+{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, -- —
+{[0] = {.5,.5}, {.5,.5}, nil, {.25,.25},nil, nil, nil, {.5,.5}, {.5,.5}, {.5,.5}, {.5,.5}, }, -- ?
+--
+{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --한글
+{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --초성
+{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --중종성
+{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --latin
+}
+
+local latin_fullstop = {
+ [0x2e] = 1,
+ [0x21] = 2,
+ [0x3f] = 2,
+ [0x2026] = 1, -- \ldots
+}
+
+local latin_quotes = {
+ [0x0028] = 0x0029, -- ( )
+ [0x2018] = 0x2019, -- ‘ ’
+ [0x201C] = 0x201D, -- “ ”
+}
+
+local josa_list = { -- automatic josa selection
+ -- 리을, 중성, 종성
+ [0xAC00] = {0xC774, 0xAC00, 0xC774}, -- 가 = 이, 가, 이
+ [0xC740] = {0xC740, 0xB294, 0xC740}, -- 은 = 은, 는, 은
+ [0xC744] = {0xC744, 0xB97C, 0xC744}, -- 을 = 을, 를, 을
+ [0xC640] = {0xACFC, 0xC640, 0xACFC}, -- 와 = 과, 와, 과
+ [0xC73C] = {-1, -1, 0xC73C}, -- 으(로) = , , 으
+ [0xC774] = {0xC774, -1, 0xC774}, -- 이(라) = 이, , 이
+}
+
+local josa_code = {
+ [0x30] = 3, -- 0
+ [0x31] = 1, -- 1
+ [0x33] = 3, -- 3
+ [0x36] = 3, -- 6
+ [0x37] = 1, -- 7
+ [0x38] = 1, -- 8
+ [0x4C] = 1, -- L
+ [0x4D] = 3, -- M
+ [0x4E] = 3, -- N
+ [0x6C] = 1, -- l
+ [0x6D] = 3, -- m
+ [0x6E] = 3, -- n
+ [0xFB02] = 1, -- fl
+ [0xFB04] = 1, -- ffl
+ ng = 3,
+ ap = 3,
+ up = 3,
+ at = 3,
+ et = 3,
+ it = 3,
+ ot = 3,
+ ut = 3,
+ ok = 3,
+ ic = 3,
+ le = 1,
+ ime = 3,
+ ine = 3,
+ ack = 3,
+ ick = 3,
+ oat = 2,
+ TEX = 3,
+ -- else 2
+}
+
+local function get_gluenode (w,st,sh)
+ local g = copy_node(new_glue)
+ local s = copy_node(new_glue_spec)
+ s.width, s.stretch, s.shrink = w or 0, st or 0, sh or 0
+ g.spec = s
+ return g
+end
+
+local function get_penaltynode (n)
+ local p = copy_node(new_penalty)
+ p.penalty = n or 0
+ return p
+end
+
+local function get_kernnode (n)
+ local k = copy_node(new_kern)
+ k.kern = n or 0
+ return k
+end
+
+local function get_rulenode (w,h,d)
+ local r = copy_node(new_rule)
+ r.width, r.height, r.depth = w or 0, h or 0, d or 0
+ return r
+end
+
+local function make_luako_glue(...)
+ local glue = get_gluenode(...)
+ set_attribute(glue,luakoglueattr,1)
+ return glue
+end
+
+local function is_cjk_k (c)
+ return (c >= 0x2E80 and c <= 0x9FFF )
+ or (c >= 0xF900 and c <= 0xFAFF )
+ or (c >= 0xFE10 and c <= 0xFE1F )
+ or (c >= 0xFE30 and c <= 0xFE4F )
+ or (c >= 0xFF00 and c <= 0xFFEF )
+ or (c >= 0x20000 and c <= 0x2A6DF)
+ or (c >= 0x2F800 and c <= 0x2FA1F)
+ or c == 0x00B0 or c == 0x2015
+ -- or c == 0x2018 or c == 0x2019
+ -- or c == 0x201C or c == 0x201D
+ or c == 0x2026 or c == 0x2032
+ or c == 0x2033
+end
+
+local function is_hanja (c)
+ return (c >= 0x3400 and c <= 0x9FFF )
+ or (c >= 0xF900 and c <= 0xFAFF )
+ or (c >= 0x20000 and c <= 0x2A6DF)
+ or (c >= 0x2F800 and c <= 0x2FA1F)
+end
+
+local function is_hangul (c)
+ return (c >= 0xAC00 and c <= 0xD7A3)
+end
+
+local function is_chosong (c)
+ return (c >= 0x1100 and c <= 0x115F)
+ or (c >= 0xA960 and c <= 0xA97C)
+end
+
+local function is_jungjongsong (c)
+ return (c >= 0x1160 and c <= 0x11FF)
+ or (c >= 0xD7B0 and c <= 0xD7Fb)
+ or c == 0x302E or c == 0x302F -- tone marks
+end
+
+local function get_cjk_class (ch, cjtype)
+ if ch then
+ if is_hangul(ch) then return 7 end -- hangul = 7
+ if is_chosong(ch) then return 8 end -- jamo LC = 8
+ if is_jungjongsong(ch) then return 9 end -- jamo VL, TC, TM = 9
+ local c = is_cjk_k(ch) and 0 or 10 -- hanja = 0; latin = 10
+ if cjkclass[ch] then c = cjkclass[ch] end -- cjkclass 1 .. 6
+ if cjtype then
+ if cjtype == 2 and
+ (ch == 0xFF1F or ch == 0xFF01 or ch == 0xFF1A or ch == 0xFF1B) then
+ c = 4 -- simplified chinese ? !
+ end
+ else
+ if ch == 0x2018 or ch == 0x2019 or ch == 0x201C or ch == 0x201D then
+ c = 10 -- korean “ ” ‘ ’
+ end
+ end
+ return c
+ end
+ return nil
+end
+
+local function get_font_table (fid)
+ if fid then
+ if fontdata[fid] then
+ return fontdata[fid]
+ else
+ return font.getfont(fid)
+ end
+ end
+end
+
+local function get_font_char (fid, chr)
+ local f = get_font_table(fid)
+ return chr and f and f.characters and f.characters[chr]
+end
+
+local function get_font_emsize(fid)
+ local f = get_font_table(fid)
+ return (f and f.parameters and f.parameters.quad) or emsize
+end
+
+local function get_font_feature (fid, name)
+ local f = get_font_table(fid)
+ return f and f.shared and f.shared.features and f.shared.features[name]
+end
+
+local function get_char_boundingbox(fid, chr)
+ local f = get_font_table(fid)
+ local glbox = f and f.shared
+ glbox = glbox and glbox.rawdata
+ glbox = glbox and glbox.descriptions
+ glbox = glbox and glbox[chr] and glbox[chr].boundingbox
+ if glbox then
+ local factor, bbox = f.parameters and f.parameters.factor or 655.36, {}
+ for i,v in ipairs(glbox) do
+ bbox[i] = v * factor
+ end
+ return bbox
+ end
+end
+
+local function get_unicode_char(curr)
+ if curr.char > 0 and curr.char < 0xF0000 then return curr.char end
+ local uni = has_attribute(curr, luakounicodeattr)
+ if uni then return uni end
+ return curr.char
+end
+
+----------------------------
+-- cjk linebreak and spacing
+----------------------------
+local function get_hlist_class_first (hlist)
+ local curr = hlist.head
+ while curr do
+ if curr.id == glyphnode then
+ local c,f = get_unicode_char(curr), curr.font
+ if c then return c,f end
+ elseif curr.id == hlistnode or curr.id == vlistnode then
+ local c,f = get_hlist_class_first(curr)
+ if c then return c,f end
+ elseif curr.id == gluenode then
+ if curr.spec and curr.spec.width ~= 0 then return end
+ end
+ curr = curr.next
+ end
+end
+
+local function get_hlist_class_last (hlist,prevchar,prevfont)
+ local curr = nodeslide(hlist.head)
+ while curr do
+ if curr.id == glyphnode then
+ local c,f = get_unicode_char(curr), curr.font
+ if c then return c,f end
+ elseif curr.id == hlistnode or curr.id == vlistnode then
+ local c,f = get_hlist_class_last(curr)
+ if c then return c,f end
+ elseif curr.id == gluenode then
+ if curr.spec and curr.spec.width ~= 0 then return end
+ end
+ curr = curr.prev
+ end
+ return prevchar, prevfont
+end
+
+local function kanjiskip (head,curr)
+ insert_before(head,curr,make_luako_glue(0, emsize*0.1, emsize*0.02))
+end
+
+local function xkanjiskip (head,curr)
+ if has_attribute(curr,finemathattr) == 0 then -- ttfamily
+ kanjiskip(head,curr)
+ else
+ insert_before(head,curr,make_luako_glue(0.25*emsize, emsize*0.15, emsize*0.06))
+ end
+end
+
+local function interhangulskip (head,curr,currfont,prevfont,was_penalty)
+ local width = 0
+ local interhangul = get_font_feature(currfont, "interhangul")
+ if interhangul and currfont == prevfont then
+ width = tex_sp(interhangul)
+ end
+ if not was_penalty then
+ insert_before(head,curr,get_penaltynode(50))
+ end
+ insert_before(head,curr,make_luako_glue(width, emsize*0.04, emsize*0.02))
+end
+
+local function interhanjaskip (head,curr,was_penalty)
+ if not was_penalty then
+ insert_before(head,curr,get_penaltynode(50))
+ end
+ insert_before(head,curr,make_luako_glue(0, emsize*0.04, emsize*0.02))
+end
+
+local function koreanlatinskip (head,curr,currfont,prevfont,was_penalty)
+ local width = 0 -- default: 0em
+ if has_attribute(curr,finemathattr) == 1 then -- not ttfamily
+ local latincjk = get_font_feature(currfont, "interlatincjk")
+ if not latincjk then
+ latincjk = get_font_feature(prevfont, "interlatincjk")
+ end
+ if latincjk then
+ width = tex_sp(latincjk)
+ end
+ end
+ if not was_penalty then
+ insert_before(head,curr,get_penaltynode(50))
+ end
+ insert_before(head,curr,make_luako_glue(width, emsize*0.04, emsize*0.02))
+end
+
+local function cjk_insert_nodes(head,curr,currchar,currfont,prevchar,prevfont)
+ local was_penalty = false
+ local currentcjtype = has_attribute(curr,cjtypesetattr)
+ local p = get_cjk_class(prevchar, currentcjtype)
+ local c = get_cjk_class(currchar, currentcjtype)
+ ---[[raise latin puncts
+ if curr.id == glyphnode and has_attribute(curr,finemathattr) == 1 then -- not ttfamily
+ if c < 10 then -- not ttfamily
+ local nn, raise = curr.next, nil
+ while nn do
+ if nn.id == glyphnode and currfont ~= nn.font and latin_fullstop[nn.char] then
+ if not raise then
+ raise = get_font_feature(currfont, "punctraise")
+ raise = raise and tex_sp(raise)
+ end
+ if raise then
+ nn.yoffset = nn.yoffset or 0
+ nn.yoffset = nn.yoffset + raise
+ end
+ nn = nn.next
+ elseif nn.id == kernnode then
+ nn = nn.next
+ else
+ break
+ end
+ end
+ elseif latin_quotes[currchar] and not has_attribute(curr,quoteraiseattr) then
+ local nn, raise, cjkfont, depth, todotbl = curr.next, nil, nil, 1, {curr}
+ while nn do
+ if nn.id == glyphnode then
+ if latin_quotes[nn.char] == latin_quotes[currchar] then
+ depth = depth + 1
+ todotbl[#todotbl + 1] = nn
+ elseif nn.char == latin_quotes[currchar] then
+ depth = depth - 1
+ todotbl[#todotbl + 1] = nn
+ if depth == 0 then
+ if raise and nn.font == currfont and cjkfont ~= currfont then
+ for _,n in ipairs(todotbl) do
+ n.yoffset = n.yoffset or 0
+ n.yoffset = n.yoffset + raise
+ end
+ end
+ for _,n in ipairs(todotbl) do
+ set_attribute(n, quoteraiseattr, 1)
+ end
+ break
+ end
+ elseif not raise then
+ if get_cjk_class(get_unicode_char(nn)) < 10 then
+ raise = get_font_feature(nn.font, "quoteraise")
+ raise = raise and tex_sp(raise)
+ if raise then cjkfont = nn.font end
+ end
+ end
+ end
+ nn = nn.next
+ end
+ end
+ end
+ --raise latin puncts]]
+ if prebreakpenalty[currchar] then
+ was_penalty = true
+ insert_before(head,curr,get_penaltynode(prebreakpenalty[currchar]))
+ elseif postbreakpenalty[prevchar] then
+ was_penalty = true
+ insert_before(head,curr,get_penaltynode(postbreakpenalty[prevchar]))
+ end
+ ---[[ kern is a breakpoint if followed by a glue: protrusion and compress_fullwidth_punctuations
+ if (c and c == 1) or (p and p >= 2 and p <= 6) then was_penalty = true end
+ --]]
+ if p and c then
+ if currentcjtype then
+ if cjk_glue_spec[p] and cjk_glue_spec[p][c] then
+ local width = emsize * cjk_glue_spec[p][c][1]
+ local stretch = 0
+ local shrink = emsize * cjk_glue_spec[p][c][2]
+ insert_before(head,curr,make_luako_glue(width, stretch, shrink))
+ elseif p < 10 and c < 10 and p ~= 8 and c ~= 9 then
+ kanjiskip(head,curr)
+ elseif (p < 10 and c == 10) or (p == 10 and c < 10) then
+ if xspcode[currchar] then
+ if xspcode[currchar] % 2 == 1 then
+ xkanjiskip(head,curr)
+ end
+ elseif xspcode[prevchar] then
+ if xspcode[prevchar] > 1 then
+ xkanjiskip(head,curr)
+ end
+ elseif inhibitxspcode[currchar] then -- 3, 2
+ if inhibitxspcode[currchar] > 1 then
+ xkanjiskip(head,curr)
+ end
+ elseif inhibitxspcode[prevchar] then -- 3, 1
+ if inhibitxspcode[prevchar] % 2 == 1 then
+ xkanjiskip(head,curr)
+ end
+ else
+ xkanjiskip(head,curr)
+ end
+ end
+ else
+ if (p < 10 and c == 10) or (p == 10 and c < 10) then
+ if xspcode[currchar] then
+ if xspcode[currchar] % 2 == 1 then
+ koreanlatinskip(head,curr,currfont,prevfont,was_penalty)
+ end
+ elseif xspcode[prevchar] then
+ if xspcode[prevchar] > 1 then
+ koreanlatinskip(head,curr,currfont,prevfont,was_penalty)
+ end
+ elseif inhibitxspcode[currchar] then -- 3, 2
+ if inhibitxspcode[currchar] > 1 then
+ koreanlatinskip(head,curr,currfont,prevfont,was_penalty)
+ end
+ elseif inhibitxspcode[prevchar] then -- 3, 1
+ if inhibitxspcode[prevchar] % 2 == 1 then
+ koreanlatinskip(head,curr,currfont,prevfont,was_penalty)
+ end
+ else
+ koreanlatinskip(head,curr,currfont,prevfont,was_penalty)
+ end
+ elseif cjk_glue_spec[p] and cjk_glue_spec[p][c] then
+ koreanlatinskip(head,curr,currfont,prevfont,was_penalty)
+ elseif p == 7 and c == 7 then
+ interhangulskip(head,curr,currfont,prevfont,was_penalty)
+ elseif p < 10 and c < 10 and p ~= 8 and c ~= 9 then
+ interhanjaskip(head,curr,was_penalty)
+ end
+ end
+ end
+ -- for dot emphasis
+ if has_attribute(curr,dotemphattr)
+ and c ~= 0
+ and c ~= 7
+ and p ~= 8
+ and c ~= 8 then
+ unset_attribute(curr,dotemphattr)
+ end
+
+ return currchar,currfont
+end
+
+local function cjk_spacing_linebreak (head)
+ local prevchar,prevfont = nil,nil
+ for curr in traverse(head) do
+ if has_attribute(curr,finemathattr) then
+ if curr.id == gluenode then
+ prevchar,prevfont = nil,nil
+ unset_attribute(curr,finemathattr)
+ elseif curr.id == glyphnode then
+ emsize = get_font_emsize(curr.font)
+ local uni = get_unicode_char(curr)
+ if uni then
+ prevchar,prevfont = cjk_insert_nodes(head,curr,uni,curr.font,prevchar,prevfont)
+ end
+ unset_attribute(curr,finemathattr)
+ elseif curr.id == mathnode then
+ local currchar = 0
+ if curr.surround and curr.surround > 0 then
+ currchar = 0x4E00
+ end
+ if curr.subtype == 0 then
+ cjk_insert_nodes(head,curr,currchar,nil,prevchar,prevfont)
+ prevchar,prevfont = nil,nil
+ else
+ prevchar,prevfont = currchar,nil
+ end
+ unset_attribute(curr,finemathattr)
+ elseif curr.id == hlistnode or curr.id == vlistnode then
+ local firstchr, firstfid = get_hlist_class_first(curr)
+ if firstchr then
+ cjk_insert_nodes(head,curr,firstchr,firstfid,prevchar,prevfont)
+ end
+ prevchar,prevfont = get_hlist_class_last(curr,prevchar,prevfont)
+ unset_attribute(curr,finemathattr)
+ end
+ else
+ prevchar,prevfont = 0,nil -- treat \verb as latin character.
+ end
+ end
+end
+
+------------------------------------
+-- remove japanese/chinese spaceskip
+------------------------------------
+local function remove_cj_spaceskip (head)
+ for curr in traverse_id(gluenode,head) do
+ local cjattr = has_attribute(curr,cjtypesetattr)
+ local prv, nxt = curr.prev, curr.next
+ if cjattr and cjattr > 0 and prv and nxt then
+ local prevclass, prevchar, prevfont, nextclass
+ if prv.id == hlistnode or prv.id == vlistnode then
+ prevclass = get_hlist_class_last(prv)
+ else
+ -- what is this strange kern before \text??
+ if prv.id == kernnode and prv.kern == 0 then
+ prv = prv.prev
+ end
+ if prv.id == glyphnode then
+ prevclass = get_cjk_class(get_unicode_char(prv), cjattr)
+ prevchar, prevfont = prv.char, prv.font
+ end
+ end
+ if nxt.id == glyphnode then
+ nextclass = get_cjk_class(get_unicode_char(nxt), cjattr)
+ elseif nxt.id == hlistnode or nxt.id == vlistnode then
+ nextclass = get_hlist_class_first(nxt)
+ end
+ if (prevclass and prevclass < 10) or (nextclass and nextclass < 10) then
+ local subtype = curr.subtype
+ if subtype == 13 then -- do not touch on xspaceskip for now
+ remove_node(head,curr)
+ else -- before \text?? spaceskip is replaced by glue type 0
+ local spec = curr.spec
+ local csp = spec and spec.width
+ local cst = spec and spec.stretch
+ local csh = spec and spec.shrink
+ local fp = get_font_table(prevfont)
+ fp = fp and fp.parameters
+ local sp = fp and fp.space
+ local st = fp and fp.space_stretch
+ local sh = fp and fp.space_shrink
+ sp = sp and tex_round(sp)
+ st = st and tex_round(st)
+ sh = sh and tex_round(sh)
+ if prevchar and prevchar >= 65 and prevchar <= 90 then
+ st = st and mathfloor(st*(999/1000))
+ sh = sh and mathfloor(sh*(1001/1000))
+ end
+ if sp == csp and st == cst and sh == csh then
+ remove_node(head,curr)
+ end
+ end
+ end
+ end
+ end
+end
+
+----------------------------------
+-- compress fullwidth punctuations
+----------------------------------
+local function compress_fullwidth_punctuations (head)
+ for curr in traverse_id(glyphnode,head) do
+ local uni = get_unicode_char(curr)
+ local class = uni and get_cjk_class(uni, has_attribute(curr, cjtypesetattr))
+ local chr = get_font_char(curr.font, curr.char)
+ if chr and class and class >= 1 and class <= 4 then
+ local width = curr.width or 655360
+ emsize = get_font_emsize(curr.font)
+ local ensize = emsize/2
+ local oneoften = emsize/10
+ local bbox = get_char_boundingbox(curr.font, curr.char)
+ if not bbox then return head end --
+ if class == 2 or class == 4 then
+ local wd
+ if get_font_feature(curr.font,'vertical') then
+ wd = ensize<width and ensize-width or 0
+ else
+ wd = (bbox[3] < ensize) and ensize-width or bbox[3]-width+oneoften
+ end
+ if chr.right_protruding then
+ -- kern is a breakpoint if followed by a glue
+ insert_after(head, curr, get_kernnode(wd))
+ else
+ insert_after(head, curr, get_rulenode(wd))
+ end
+ elseif class == 1 then
+ local wd
+ if get_font_feature(curr.font,'vertical') then
+ wd = ensize<width and ensize-width or 0
+ else
+ wd = (width-bbox[1] < ensize) and ensize-width or -bbox[1]+oneoften
+ end
+ if chr.left_protruding then
+ head = insert_before(head, curr, get_kernnode(wd))
+ else
+ head = insert_before(head, curr, get_rulenode(wd))
+ end
+ elseif class == 3 then
+ local lwd, rwd
+ local quarter, thirdquarter, halfwd = ensize/2, ensize*1.5, width/2
+ if get_font_feature(curr.font,'vertical') then
+ rwd = quarter<halfwd and quarter-halfwd or 0
+ lwd = rwd
+ else
+ rwd = (bbox[3] < thirdquarter) and quarter-halfwd or bbox[3]-width
+ lwd = (width-bbox[1] < thirdquarter) and quarter-halfwd or -bbox[1]
+ end
+ if chr.left_protruding then
+ head = insert_before(head, curr, get_kernnode(lwd))
+ else
+ head = insert_before(head, curr, get_rulenode(lwd))
+ end
+ if chr.right_protruding then
+ insert_after (head, curr, get_kernnode(rwd))
+ else
+ insert_after (head, curr, get_rulenode(rwd))
+ end
+ end
+ end
+ end
+ return head -- should be returned!
+end
+
+------------------------------
+-- ruby: pre-linebreak routine
+------------------------------
+local function spread_ruby_box(head,extrawidth)
+ for curr in traverse_id(gluenode,head) do
+ if curr.spec then
+ if has_attribute(curr,luakoglueattr) then
+ curr.spec.width = curr.spec.width + extrawidth
+ else
+ head = insert_before(head,curr,get_kernnode(curr.spec.width+extrawidth))
+ head = remove_node(head,curr)
+ end
+ end
+ end
+ return head
+end
+
+local function spread_ruby_base_box (head)
+ for curr in traverse_id(hlistnode,head) do
+ local attr = has_attribute(curr,luakorubyattr)
+ local rubyoverlap = attr and rubynode[attr][3]
+ if attr and not rubyoverlap then
+ local ruby = rubynode[attr][1]
+ if ruby and ruby.width > curr.width then
+ local basehead = curr.head
+ local numofglues = nodecount(gluenode,basehead)
+ local extrawidth = (ruby.width - curr.width)/(numofglues + 1)
+ if numofglues > 0 then
+ basehead = spread_ruby_box(basehead,extrawidth)
+ end
+ local leading = get_kernnode(extrawidth/2)
+ curr.width = ruby.width
+ leading.next = basehead
+ curr.head = leading
+ end
+ end
+ end
+end
+
+local function get_ruby_side_width (basewidth,rubywidth,adjacent)
+ local width,margin = (rubywidth-basewidth)/2, 0
+ if adjacent then
+ if adjacent.id == glyphnode then
+ if not is_hanja(get_unicode_char(adjacent)) then
+ width = (rubywidth-basewidth-emsize)/2
+ if width > 0 then
+ margin = emsize/2
+ else
+ width,margin = 0,(rubywidth-basewidth)/2
+ end
+ end
+ end
+ end
+ return width,margin
+end
+
+local function get_ruby_side_kern (head)
+ for curr in traverse_id(hlistnode,head) do
+ local attr = has_attribute(curr,luakorubyattr)
+ local rubyoverlap = attr and rubynode[attr][3]
+ if rubyoverlap then
+ local basewidth = curr.width
+ local rubywidth = rubynode[attr][1].width
+ if curr.width < rubywidth then
+ local _,fid = get_hlist_class_first(curr)
+ emsize = get_font_emsize(fid)
+ local leftwidth,leftmargin = get_ruby_side_width(basewidth,rubywidth,curr.prev)
+ if leftwidth > 0 then
+ curr.width = curr.width + leftwidth
+ end
+ if leftmargin > 0 then
+ rubynode[attr].leftmargin = leftmargin
+ end
+ local rightwidth,rightmargin = get_ruby_side_width(basewidth,rubywidth,curr.next)
+ if rightwidth > 0 then
+ curr.width = curr.width + rightwidth
+ end
+ if rightmargin > 0 then
+ rubynode[attr].rightmargin = rightmargin
+ end
+ rubynode[attr].rightshift = rightwidth - leftwidth
+ local totalspace = leftwidth+rightwidth
+ if totalspace > 0 then
+ local numofglues = nodecount(gluenode,curr.head)
+ local extrawidth = totalspace/(numofglues + 1)
+ if numofglues > 0 then
+ curr.head = spread_ruby_box(curr.head,extrawidth)
+ end
+ local leading = get_kernnode(extrawidth*(leftwidth/totalspace))
+ leading.next = curr.head
+ curr.head = leading
+ end
+ end
+ end
+ end
+end
+
+local function zero_width_rule_with_dir (head,curr,before)
+ local rule = get_rulenode(0)
+ rule.dir = curr.dir
+ if before then
+ head = insert_before(head,curr,rule)
+ else
+ insert_after(head,curr,rule)
+ end
+ return head
+end
+
+local function no_ruby_at_margin(head)
+ for curr in traverse_id(hlistnode,head) do
+ local attr = has_attribute(curr,luakorubyattr)
+ if attr then
+ local margin = rubynode[attr].leftmargin
+ if margin then
+ head = insert_before(head,curr,get_kernnode(-margin))
+ head = zero_width_rule_with_dir(head,curr,true) -- before
+ head = insert_before(head,curr,get_kernnode(margin))
+ end
+ margin = rubynode[attr].rightmargin
+ if margin then
+ if curr.next then
+ if curr.next.id == gluenode then
+ insert_after(head,curr,get_kernnode(-margin))
+ head = zero_width_rule_with_dir(head,curr)
+ insert_after(head,curr,get_kernnode(margin))
+ elseif curr.next.id == penaltynode and curr.next.penalty < 10000 then
+ insert_after(head,curr.next,get_kernnode(-margin))
+ head = zero_width_rule_with_dir(head,curr)
+ insert_after(head,curr,get_kernnode(margin))
+ end
+ end
+ end
+ end
+ end
+ return head
+end
+
+------------------------------
+-- discourage character orphan
+------------------------------
+local function inject_char_widow_penalty (head,curr,uni,pv,cjattr)
+ if uni and prebreakpenalty[uni] ~= 10000 then
+ local class = get_cjk_class(uni, cjattr)
+ if class and class < 9 then
+ if curr.prev and curr.prev.id == rulenode then
+ curr = curr.prev
+ end
+ if curr.prev and curr.prev.id == gluenode then
+ curr = curr.prev
+ end
+ if curr.prev and curr.prev.id == penaltynode then
+ if curr.prev.penalty < pv then
+ curr.prev.penalty = pv
+ end
+ else
+ insert_before(head,curr,get_penaltynode(pv))
+ end
+ return true
+ end
+ end
+end
+
+local function discourage_char_widow (head,curr)
+ while curr do
+ local cjattr = has_attribute(curr,cjtypesetattr)
+ local pv = cjattr and 500 or 5000
+ if curr.id == glyphnode then
+ emsize = get_font_emsize(curr.font)
+ local width = curr.width or 0
+ if width >= 2*emsize then return end
+ local uni = get_unicode_char(curr)
+ if inject_char_widow_penalty(head,curr,uni,pv,cjattr) then
+ return true
+ end
+ elseif curr.id == hlistnode and curr.id == vlistnode then
+ local width = curr.width or 0
+ local uni,fid = get_hlist_class_first(curr)
+ emsize = get_font_emsize(fid)
+ if width >= 2*emsize then return end
+ if inject_char_widow_penalty(head,curr,uni,pv,cjattr) then
+ return true
+ end
+ end
+ if not curr.prev then return end
+ curr = curr.prev
+ end
+end
+
+---------------------------
+-- automatic josa selection
+---------------------------
+local function syllable2jamo (code)
+ local code = code - 0xAC00
+ local L = 0x1100 + mathfloor(code / 588)
+ local V = 0x1161 + mathfloor((code % 588) / 28)
+ local T = 0x11A7 + code % 28
+ if T == 0x11A7 then T = nil end
+ return L, V, T
+end
+
+local function number2josacode (n)
+ n = n % 10 + stringbyte("0")
+ if josa_code[n] then return josa_code[n] end
+ return nil -- 2
+end
+
+local function latin2josacode (n)
+ n = n + stringbyte("a")
+ if josa_code[n] then return josa_code[n] end
+ return nil -- 2
+end
+
+for c = 0x2160, 0x216B do -- Ⅰ
+ josa_code[c] = number2josacode(c - 0x215F)
+end
+for c = 0x2170, 0x217B do -- ⅰ
+ josa_code[c] = number2josacode(c - 0x216F)
+end
+for c = 0x2460, 0x2473 do -- ①
+ josa_code[c] = number2josacode(c - 0x245F)
+end
+for c = 0x2474, 0x2487 do -- ⑴
+ josa_code[c] = number2josacode(c - 0x2473)
+end
+for c = 0x2488, 0x249B do -- ⒈
+ josa_code[c] = number2josacode(c - 0x2487)
+end
+for c = 0x249C, 0x24B5 do -- ⒜
+ josa_code[c] = latin2josacode(c - 0x249C)
+end
+for c = 0x24B6, 0x24CF do -- Ⓐ
+ josa_code[c] = latin2josacode(c - 0x24B6)
+end
+for c = 0x24D0, 0x24E9 do -- ⓐ
+ josa_code[c] = latin2josacode(c - 0x24D0)
+end
+for c = 0x3131, 0x314E do -- ㄱ
+ josa_code[c] = 3
+end
+josa_code[0x3139] = 1 -- ㄹ
+for c = 0x3165, 0x3186 do
+ josa_code[c] = 3
+end
+for c = 0x3200, 0x320D do -- ㈀
+ josa_code[c] = 3
+end
+josa_code[0x3203] = 1 -- ㈃
+for c = 0x3260, 0x327F do -- ㉠
+ josa_code[c] = 3
+end
+josa_code[0x3263] = 1 -- ㉣
+for c = 0xFF10, 0xFF19 do -- 0
+ josa_code[c] = number2josacode(c - 0xFF10)
+end
+for c = 0xFF21, 0xFF3A do -- A
+ josa_code[c] = latin2josacode(c - 0xFF21)
+end
+for c = 0xFF41, 0xFF5A do -- a
+ josa_code[c] = latin2josacode(c - 0xFF41)
+end
+
+local function jamo2josacode(code)
+ if code and code > 0x11A7 then
+ if code == 0x11AF then return 1 end
+ return 3
+ end
+ return 2
+end
+
+local function get_hanja_hangul_table (table,file,init)
+ local i = 0
+ local file = kpse.find_file(file)
+ if not file then return table end
+ file = io.open(file, "r")
+ if not file then return table end
+ while true do
+ local d = file:read("*number")
+ if not d then break end
+ table[init + i] = d
+ i = i + 1
+ end
+ file:close()
+ return table
+end
+
+local hanja2hangul = { }
+hanja2hangul = get_hanja_hangul_table(hanja2hangul,"hanja_hangul.tab",0x4E00)
+hanja2hangul = get_hanja_hangul_table(hanja2hangul,"hanjaexa_hangul.tab",0x3400)
+hanja2hangul = get_hanja_hangul_table(hanja2hangul,"hanjacom_hangul.tab",0xF900)
+
+-- 1 : 리을, 2 : 중성, 3 : 종성
+local function get_josacode (prevs)
+ local code = prevs[1] -- last char
+ if not code then return 2 end
+ if is_hangul(code) then -- hangul syllable
+ local _, _, T = syllable2jamo(code)
+ return jamo2josacode(T)
+ end
+ if is_jungjongsong(code) then return jamo2josacode(code) end
+ if (code >= 0x3400 and code <= 0x9FA5)
+ or (code >= 0xF900 and code <= 0xFA2D) then
+ local _, _, T = syllable2jamo(hanja2hangul[code])
+ return jamo2josacode(T)
+ end
+ -- latin
+ if prevs[1] < 0x80
+ and prevs[2] and prevs[2] < 0x80
+ and prevs[3] and prevs[3] < 0x80 then
+ local liii = stringchar(prevs[3], prevs[2], prevs[1])
+ if josa_code[liii] then return josa_code[liii] end
+ end
+ if prevs[1] < 0x80
+ and prevs[2] and prevs[2] < 0x80 then
+ local lii = stringchar(prevs[2], prevs[1])
+ if josa_code[lii] then return josa_code[lii] end
+ end
+ if josa_code[code] then return josa_code[code] end
+ return 2
+end
+
+local function get_josaprevs(curr,josaprev)
+ while curr do
+ if curr.id == glyphnode then
+ local chr = get_unicode_char(curr)
+ if xspcode[chr]
+ or inhibitxspcode[chr]
+ or prebreakpenalty[chr]
+ or postbreakpenalty[chr]
+ or chr == 0x302E -- tone mark
+ or chr == 0x302F then -- tone mark
+ --skip
+ else
+ josaprev[#josaprev + 1] = chr
+ end
+ elseif curr.id == hlistnode or curr.id == vlistnode then
+ josaprev = get_josaprevs(nodeslide(curr.head),josaprev)
+ end
+ if #josaprev == 3 then break end
+ curr = curr.prev
+ end
+ return josaprev
+end
+
+local function korean_autojosa (head)
+ for curr in traverse_id(glyphnode,head) do
+ if has_attribute(curr,autojosaattr) and has_attribute(curr,finemathattr) then
+ local josaprev = {}
+ josaprev = get_josaprevs(curr.prev,josaprev)
+ local josacode = get_josacode(josaprev)
+ local thischar = get_unicode_char(curr)
+ if thischar == 0xC774 then
+ if curr.next
+ and curr.next.id == glyphnode
+ and get_unicode_char(curr.next) == 0xB77C then
+ curr.char = josa_list[0xC774][josacode]
+ else
+ curr.char = josa_list[0xAC00][josacode]
+ end
+ elseif thischar and josa_list[thischar] then
+ curr.char = josa_list[thischar][josacode]
+ end
+ end
+ if curr.char < 0 then remove_node(head,curr) end
+ end
+end
+
+------------------------------
+-- switch to hangul/hanja font
+------------------------------
+local function hangulspaceskip (engfont, hfontid, nglue)
+ local eng = engfont.parameters
+ if not eng then return end
+ local spec = nglue.spec
+ if not spec then return end
+ local gsp, gst, gsh = spec.width, spec.stretch, spec.shrink
+ local esp, est, esh = eng.space, eng.space_stretch, eng.space_shrink
+ esp = esp and tex_round(esp)
+ est = est and tex_round(est)
+ esh = esh and tex_round(esh)
+ if esp == gsp and est == gst and esh == gsh then else return end
+ local hf = get_font_table(hfontid)
+ if not hf then return end
+ local hp = hf.parameters
+ if not hp then return end
+ local hsp,hst,hsh = hp.space,hp.space_stretch,hp.space_shrink
+ if hsp and hst and hsh then else return end
+ return tex_round(hsp), tex_round(hst), tex_round(hsh)
+end
+
+local hangulfontlist = {}
+
+local function font_substitute(head)
+ for curr in traverse_id(glyphnode, head) do
+ local eng = get_font_table(curr.font)
+ local engsize = eng and eng.size
+ local engfontchar = get_font_char(curr.font, curr.char)
+ if not engsize then -- no font table of plain tex cm font
+ engsize = tex_sp(tex.pdffontsize(font.current()))
+ engfontchar = get_cjk_class(curr.char) == 10
+ end
+ if curr.char and not engfontchar then
+ local korid = false
+ local hangul = has_attribute(curr, hangfntattr)
+ local hanja = has_attribute(curr, hanjfntattr)
+ local ftable = {hangul, hanja}
+
+ if hanjafontforhanja then
+ local uni = get_unicode_char(curr)
+ uni = uni and get_cjk_class(uni)
+ if uni and uni < 7 then ftable = {hanja, hangul} end
+ end
+ for _,fallback in ipairs(ftable) do
+ local fkey = fallback and hangulfont[fallback]
+ if fkey then
+ local fname, fsize = stringmatch(fkey, "(.+) at (.+)")
+ if not fname then fname = fkey end
+ if fsize then
+ fsize = tex_sp(fsize)
+ else
+ fsize = engsize
+ end
+ fkey = fname .. "@" .. fsize
+ local fid = hangulfontlist[fkey]
+ if not fid then
+ fid = font_define_func(fname, fsize, font.nextid())
+ if type(fid) == "table" then fid = fontdefine(fid) end
+ hangulfontlist[fkey] = fid
+ end
+ local c = get_font_char(fid, curr.char)
+ if c then
+ korid = true
+ curr.font = fid
+ -- adjust next glue by hangul font space
+ local nxt = curr.next
+ if hangulmain and nxt and nxt.id == gluenode and nxt.subtype and nxt.subtype == 0 then
+ local sp,st,sh = hangulspaceskip(eng, fid, nxt)
+ if sp and st and sh then
+ nxt.spec.width = sp
+ nxt.spec.stretch = st
+ nxt.spec.shrink = sh
+ end
+ end
+ --- charraise option charraise
+ local charraise = get_font_feature(fid, "charraise")
+ if charraise then
+ charraise = tex_sp(charraise)
+ curr.yoffset = curr.yoffset and (curr.yoffset + charraise) or charraise
+ end
+ ---
+ break
+ end
+ end
+ end
+ if not korid then
+ warn("!Missing character: %s U+%04X", utf8char(curr.char),curr.char)
+ end
+ end
+ end
+ return head
+end
+
+-----------------------------
+-- reserve unicode code point
+-----------------------------
+local function assign_unicode_codevalue (head)
+ for curr in traverse_id(glyphnode, head) do
+ set_attribute(curr, luakounicodeattr, curr.char)
+ end
+ return head
+end
+
+
+------------------------------------
+-- vetical typesetting: EXPERIMENTAL -- don't use this
+------------------------------------
+---[[no vwidth in luaotfload v2
+local tsbtable = {}
+
+local function read_tsb_table(filename)-- for ttx-generated vmtx table
+ if tsbtable[filename] then
+ return tsbtable[filename]
+ end
+ local filepath = kpse.find_file(filename)
+ if not filepath then return end
+ local file = io.open(filepath, "r")
+ if not file then return end
+ local tsbtb = {}
+ local patt = 'name="(.-)" height="(.-)" tsb="(.-)"'
+ while true do
+ local l = file:read("*line")
+ if not l then break end
+ for name, height, tsb in stringgmatch(l,patt) do
+ tsbtb[name] = {}
+ tsbtb[name].height = height
+ tsbtb[name].tsb = tsb
+ end
+ end
+ file:close()
+ tsbtable[filename] = tsbtb
+ return tsbtb
+end
+
+local function cjk_vertical_font (vf)
+ if not vf.shared then return end
+ if not vf.shared.features then return end
+ if not vf.shared.features["vertical"] then return end
+ if vf.type == "virtual" then return end
+
+ --- for read-ttx
+ local filename = vf.filename
+ filename = stringgsub(filename,".*/","")
+ filename = stringgsub(filename,"[tToO][tT][fF]$","ttx")
+ local tsbtable = read_tsb_table(filename)
+ if not tsbtable then
+ warn("Cannot read %s. Aborting vertical typesetting.",filename)
+ return
+ end
+ ---
+
+ local tmp = table.copy(vf) -- fastcopy takes time too long.
+ local id = fontdefine(tmp)
+
+ local hash = vf.properties and vf.properties.hash and vf.properties.hash..' @ vertical'
+ hash = hash or (vf.name and vf.size and vf.name..' @ '..vf.size..' @ vertical')
+
+ vf.properties = vf.properties or {}
+ vf.properties.hash = vf.properties.hash or ""
+ vf.properties.hash = hash
+ vf.type = 'virtual'
+ vf.fonts = {{ id = id }}
+ local quad = vf.parameters and vf.parameters.quad or 655360
+ local descriptions = vf.shared and vf.shared.rawdata and vf.shared.rawdata.descriptions
+ local ascender = vf.parameters and vf.parameters.ascender
+ local factor = vf.parameters and vf.parameters.factor
+ local halfxht = (vf.parameters and vf.parameters.x_height and vf.parameters.x_height/2) or quad/4
+ for i,v in pairs(vf.characters) do
+ local dsc = descriptions[i]
+ local gname = dsc.name
+ -- local vw = dsc and dsc.vwidth
+ --- for read-ttx
+ local vw = tsbtable and tsbtable[gname] and tsbtable[gname].height
+ local tsb = tsbtable and tsbtable[gname] and tsbtable[gname].tsb
+ if not vw and dsc.index then
+ local cid = stringformat("cid%05d", dsc.index)
+ vw = tsbtable and tsbtable[cid] and tsbtable[cid].height
+ tsb = tsbtable and tsbtable[cid] and tsbtable[cid].tsb
+ end
+ tsb = tsb and factor and tsb*factor
+ ---
+ vw = vw and factor and vw * factor
+ vw = vw or quad
+ local vh = dsc and dsc.boundingbox and dsc.boundingbox[3]
+ vh = vh and factor and vh * factor
+ vh = vh and vh - quad/2 or quad/2
+ vh = vh + halfxht
+ vh = vh > 0 and vh or nil
+ local vd = dsc and dsc.boundingbox and dsc.boundingbox[1]
+ vd = vd and factor and vd * factor
+ vd = vd and quad/2 - vd or quad/2
+ vd = vd - halfxht
+ vd = vd > 0 and vd or nil
+ local bb4 = dsc and dsc.boundingbox and dsc.boundingbox[4]
+ bb4 = bb4 and factor and bb4*factor
+ local asc = bb4 and tsb and bb4 + tsb
+ asc = asc or ascender
+ v.commands = {
+ {'right', asc}, -- bbox4 + top_side_bearing! But, tsb not available!
+ {'down', halfxht},
+ {'special', 'pdf: q 0 1 -1 0 0 0 cm'},
+ {'push'},
+ {'char', i},
+ {'pop'},
+ {'special', 'pdf: Q'},
+ }
+ v.width = vw
+ v.height = vh
+ v.depth = vd
+ end
+ return vf
+end
+
+local function activate_vertical_virtual (tfmdata,value)
+ if value then
+ add_to_callback("luaotfload.patch_font",
+ cjk_vertical_font,
+ "luatexko.vetical_virtual_font")
+ end
+end
+
+local otffeatures = fonts.constructors.newfeatures("otf")
+otffeatures.register {
+ name = "vertical",
+ description = "vertical typesetting",
+ initializers = {
+ node = activate_vertical_virtual,
+ }
+}
+--no vwidth in luaotfload v2]]
+
+----------------------------------
+-- add to callback : pre-linebreak
+----------------------------------
+add_to_callback('hpack_filter', function(head)
+ assign_unicode_codevalue(head)
+ korean_autojosa(head)
+ remove_cj_spaceskip(head)
+ font_substitute(head)
+ return head
+end, 'luatexko.hpack_filter_first',1)
+
+add_to_callback('hpack_filter', function(head)
+ get_ruby_side_kern(head)
+ cjk_spacing_linebreak(head)
+ spread_ruby_base_box(head)
+ head = compress_fullwidth_punctuations(head)
+ -- head = no_ruby_at_margin(head)
+ return head
+end, 'luatexko.hpack_filter')
+
+add_to_callback('pre_linebreak_filter', function(head)
+ assign_unicode_codevalue(head)
+ korean_autojosa(head)
+ remove_cj_spaceskip(head)
+ font_substitute(head)
+ return head
+end, 'luatexko.pre_linebreak_filter_first',1)
+
+add_to_callback('pre_linebreak_filter', function(head)
+ get_ruby_side_kern(head)
+ cjk_spacing_linebreak(head)
+ spread_ruby_base_box(head)
+ head = compress_fullwidth_punctuations(head)
+ discourage_char_widow(head, nodeslide(head))
+ head = no_ruby_at_margin(head)
+ return head
+end, 'luatexko.pre_linebreak_filter')
+
+
+--------------------------
+-- dot emphasis (드러냄표)
+--------------------------
+local function after_linebreak_dotemph (head)
+ for curr in traverse(head) do
+ if curr.id == hlistnode then -- hlist may be nested!!!
+ after_linebreak_dotemph(curr.head)
+ elseif curr.id == glyphnode then
+ local attr = has_attribute(curr,dotemphattr)
+ if attr and attr > 0 then
+ local d = copy_node(dotemphnode[attr])
+ local dot = d.head
+ d.head = get_kernnode(-curr.width/2-d.width/2)
+ d.head.next = dot
+ d.width = 0
+ insert_after(head,curr,d)
+ unset_attribute(curr,dotemphattr)
+ end
+ end
+ end
+end
+
+-------------------------------
+-- ruby: post-linebreak routine
+-------------------------------
+local function after_linebreak_ruby (head)
+ for curr in traverse_id(hlistnode,head) do
+ after_linebreak_ruby(curr.head) -- hlist may be nested!!!
+ local attr = has_attribute(curr,luakorubyattr)
+ if attr then
+ local ruby = rubynode[attr][1]
+ if ruby then
+ if ruby.width < curr.width then
+ local rubyhead = ruby.head
+ local numofglues = nodecount(gluenode,rubyhead)
+ local extrawidth = (curr.width - ruby.width)/(numofglues + 1)
+ ruby.width = curr.width - extrawidth/2
+ if numofglues > 0 then
+ ruby.head = spread_ruby_box(rubyhead,extrawidth)
+ end
+ else
+ local right = rubynode[attr].rightshift or 0
+ ruby.width = curr.width + (ruby.width-curr.width+right)/2
+ end
+ ruby.shift = -curr.height-rubynode[attr][2]
+ insert_after(head,curr,ruby)
+ insert_after(head,curr,get_kernnode(-ruby.width))
+ end
+ rubynode[attr] = nil
+ unset_attribute(curr,luakorubyattr)
+ end
+ end
+end
+
+---------------------
+-- underline emphasis
+---------------------
+local function draw_underline(head,curr,width,ulinenum,ulstart)
+ if width and width > 0 then
+ local glue = get_gluenode(width)
+ glue.subtype = 101 -- cleaders
+ glue.leader = copy_node(ulinebox[ulinenum])
+ insert_before(head, curr, get_kernnode(-width))
+ insert_before(head, curr, glue)
+ end
+ for _,nd in ipairs({ulstart,curr}) do
+ if nd.id == whatsitnode
+ and nd.subtype == whatsitspecial
+ and nd.data
+ and stringfind(nd.data,"luako:uline") then
+ remove_node(head,nd)
+ end
+ end
+end
+
+local function after_linebreak_underline(head,glueorder,glueset,gluesign,ulinenum)
+ local ulstart = ulinenum and head or false
+ if ulstart and ulstart.id == gluenode then ulstart = ulstart.next end
+ for curr in traverse(head) do
+ if curr.id == hlistnode then
+ ulinenum = after_linebreak_underline(curr.head,curr.glue_order,curr.glue_set,curr.glue_sign,ulinenum)
+ elseif curr.id == whatsitnode and curr.subtype == whatsitspecial
+ and curr.data then
+ if stringfind(curr.data,"luako:ulinebegin=") then
+ ulinenum = tonumber(stringmatch(curr.data,"(%d+)"))
+ ulstart = curr
+ elseif ulstart and ulinenum
+ and stringfind(curr.data,'luako:ulineend') then
+ local wd = nodedimensions(glueset,gluesign,glueorder,ulstart,curr)
+ draw_underline(head,curr,wd,ulinenum,ulstart)
+ ulinebox[ulinenum] = nil
+ ulinenum = nil
+ end
+ end
+ if ulstart and ulinenum and curr == nodetail(head) then
+ local wd = nodedimensions(glueset,gluesign,glueorder,ulstart,curr)
+ draw_underline(head,curr,wd,ulinenum,ulstart)
+ end
+ end
+ return ulinenum
+end
+
+-----------------------------------
+-- add to callback : post-linebreak
+-----------------------------------
+add_to_callback('vpack_filter', function(head)
+ after_linebreak_dotemph(head)
+ after_linebreak_ruby(head)
+ after_linebreak_underline(head)
+ return true
+end, 'luatexko.vpack_filter')
+
+add_to_callback("post_linebreak_filter", function(head)
+ after_linebreak_dotemph(head)
+ after_linebreak_ruby(head)
+ after_linebreak_underline(head)
+ return true
+end, 'luatexko.post_linebreak_filter')
+
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty
new file mode 100644
index 00000000000..25ca8590bdd
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty
@@ -0,0 +1,248 @@
+% $Id: luatexko.sty,v 1.39 2012/11/23 05:06:02 nomos Exp $
+%
+% Copyright (c) 2013 Dohyun Kim <nomos at ktug org>
+%
+% 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.
+
+\ifx\luatexkocatcodeofatchar\undefined\else
+ \expandafter\endinput\fi % no multiple loading
+\ifx\ProvidesPackage\relax \let\ProvidesPackage\undefined \fi
+\ifx\ProvidesPackage\undefined % plain tex
+ \edef\luatexkocatcodeofatchar{\catcode`@=\the\catcode`@}
+ \input luatexko-core.sty
+ %\hangulfont{name:NanumGothic:interlatincjk=0.125em} at 10pt
+ %\setmathhangulfont{NanumGothic}
+ \luatexkocatcodeofatchar
+ \expandafter\endinput
+\fi
+
+\ProvidesPackage{luatexko}[2013/05/10 v1.0 Typesetting Korean with LuaLaTeX]
+\RequirePackage{fontspec}
+\RequirePackage{luatexko-core}
+
+%% fontspec Korean options
+\ExplSyntaxOn
+
+\DeclareDocumentCommand \newhangulfontfeature {mmmm}
+ {
+ \fontspec_define_font_feature:n {#1}
+ \keys_define:nn {fontspec}
+ {
+ #1 .default:n = {#3} ,
+ #1 / unknown .code:n = {
+ \fontspec_update_fontid:n {#2:##1}
+ \fontspec_update_featstr:n {#2=##1}#4
+ }
+ }
+ }
+
+\fontspec_define_font_feature:n {YetHangul}
+\keys_define:nn {fontspec}
+ {
+ YetHangul .default:n = {On} ,
+ YetHangul / On .code:n = {
+ \fontspec_update_fontid:n {yethangul:on}
+ \fontspec_update_featstr:n {script=hang;+ccmp;+ljmo;+vjmo;+tjmo}
+ } ,
+ YetHangul / Off .code:n = {
+ \fontspec_update_fontid:n {yethangul:off}
+ \fontspec_update_featstr:n {-ljmo;-vjmo;-tjmo}
+ }
+ }
+
+\ExplSyntaxOff
+
+\newhangulfontfeature{InterHangul}{interhangul}{0}{}
+\newhangulfontfeature{InterLatinCJK}{interlatincjk}{0}{}
+\newhangulfontfeature{PunctRaise}{punctraise}{0}{}
+\newhangulfontfeature{QuoteRaise}{quoteraise}{0}{}
+\newhangulfontfeature{CharRaise}{charraise}{0}{}
+\newhangulfontfeature{Protrusion}{protrusion}{default}{\aftergroup\pdfprotrudechars\aftergroup\tw@}
+\newhangulfontfeature{Expansion}{expansion}{default}{\aftergroup\pdfadjustspacing\aftergroup\tw@}
+
+%% macros for Korean fonts
+\protected\def\setmainhangulfont{\newfontfamily\serifhangul@font}
+\protected\def\setmainhanjafont {\newfontfamily\serifhanja@font}
+\protected\def\setsanshangulfont{\newfontfamily\sanshangul@font}
+\protected\def\setsanshanjafont {\newfontfamily\sanshanja@font}
+\protected\def\setmonohangulfont{\newfontfamily\monohangul@font}
+\protected\def\setmonohanjafont {\newfontfamily\monohanja@font}
+
+\protected\def\newhangulfontfamily#1{%
+ \protected\def#1{\expandafter\let\expandafter\hangul@font
+ \csname luatexko@\string#1\endcsname
+ \luatexko@hangul@selectfont}\expandafter\newfontfamily
+ \csname luatexko@\string#1\endcsname}
+\protected\def\newhanjafontfamily#1{%
+ \protected\def#1{\expandafter\let\expandafter\hanja@font
+ \csname luatexko@\string#1\endcsname
+ \luatexko@hanja@selectfont}\expandafter\newfontfamily
+ \csname luatexko@\string#1\endcsname}
+
+\protected\def\newhangulfontface#1{%
+ \protected\def#1{\expandafter\let\expandafter\hangul@font
+ \csname luatexko@\string#1\endcsname
+ \luatexko@hangul@selectfont}\expandafter\newfontface
+ \csname luatexko@\string#1\endcsname}
+\protected\def\newhanjafontface#1{%
+ \protected\def#1{\expandafter\let\expandafter\hanja@font
+ \csname luatexko@\string#1\endcsname
+ \luatexko@hanja@selectfont}\expandafter\newfontface
+ \csname luatexko@\string#1\endcsname}
+
+\protected\def\hangulfontspec#1#{%
+ \def\luatexko@fontspec@temp{#1}\hangulfontspec@}
+\def\hangulfontspec@#1{%
+ \expandafter\newfontfamily\expandafter\hangul@font\luatexko@fontspec@temp{#1}%
+ \luatexko@hangul@selectfont\ignorespaces}
+\let\adhochangulfont\hangulfontspec
+\protected\def\hanjafontspec#1#{%
+ \def\luatexko@fontspec@temp{#1}\hanjafontspec@}
+\def\hanjafontspec@#1{%
+ \expandafter\newfontfamily\expandafter\hanja@font\luatexko@fontspec@temp{#1}%
+ \luatexko@hanja@selectfont\ignorespaces}
+\let\adhochanjafont\hanjafontspec
+
+% add{hangul/hanja}fontfeature
+\protected\def\addhangulfontfeature#1{%
+ \begingroup
+ \check@hangul@family
+ \hangul@font\addfontfeature{#1}\global
+ \let\luatexko@fontspec@temp\f@family
+ \endgroup
+ \def\hangul@font{\fontfamily\luatexko@fontspec@temp
+ \luatexko@orig@selectfont}\luatexko@hangul@selectfont \ignorespaces}
+\let\addhangulfontfeatures\addhangulfontfeature
+\protected\def\addhanjafontfeature#1{%
+ \begingroup
+ \check@hanja@family
+ \hanja@font\addfontfeature{#1}\global
+ \let\luatexko@fontspec@temp\f@family
+ \endgroup
+ \def\hanja@font{\fontfamily\luatexko@fontspec@temp
+ \luatexko@orig@selectfont}\luatexko@hanja@selectfont \ignorespaces}
+\let\addhanjafontfeatures\addhanjafontfeature
+
+% check hangul/hanja family
+\def\check@hangul@family{%
+ \unless\ifdefined\hangul@font
+ \ifx\f@family\sfdefault \let\hangul@font\sanshangul@font
+ \else\ifx\f@family\ttdefault \let\hangul@font\monohangul@font
+ \else \let\hangul@font\serifhangul@font
+ \fi\fi\fi
+}
+\def\check@hanja@family{%
+ \unless\ifdefined\hanja@font
+ \ifx\f@family\sfdefault \let\hanja@font\sanshanja@font
+ \else\ifx\f@family\ttdefault \let\hanja@font\monohanja@font
+ \else \let\hanja@font\serifhanja@font
+ \fi\fi\fi
+}
+
+\let\luatexko@orig@selectfont\selectfont
+\protected\def\selectfont{\luatexko@orig@selectfont
+ \luatexko@hangul@selectfont\luatexko@hanja@selectfont}
+
+% don't forget to redefine \normalfont
+\protected\edef\normalfont{\unexpanded{\let\hangul@font\luatexko@undefined}%
+ \unexpanded\expandafter{\normalfont}}
+\let\reset@font\normalfont
+
+% normal : finemathattr = 1
+% tt : finemathattr = 0
+% verbatim : finemathattr = off
+\protected\edef\ttfamily{\unexpanded\expandafter{\ttfamily
+ \finemathattr\z@}}
+\edef\verbatim@font{\unexpanded\expandafter{\verbatim@font
+ \unsetluatexattribute\finemathattr}}
+
+%% hangul in math --- latex
+\protected\def\setmathhangulfont{%
+ \@ifnextchar[{\setmathhangul@font@}{\setmathhangul@font@[]}}
+\def\setmathhangul@font@[#1]#2{%
+ \zf@fontspec{#1}{#2}\xdef\luatexko@math@hangul@family{\zf@family}}
+\AtBeginDocument{%
+ \begingroup
+ \unless\ifdefined\luatexko@math@hangul@family
+ \check@hangul@family
+ \ifdefined\hangul@font \hangul@font \fi
+ \xdef\luatexko@math@hangul@family{\f@family}%
+ \fi
+ \endgroup
+ \DeclareSymbolFont{mathhangul}\zf@enc\luatexko@math@hangul@family\mddefault\updefault
+ \ifcsname\zf@enc/\luatexko@math@hangul@family/\bfdefault/\updefault\endcsname
+ \SetSymbolFont{mathhangul}{bold}\zf@enc\luatexko@math@hangul@family\bfdefault\updefault
+ \fi
+ \setmathhangulblock{AC00}{D7A3}
+}
+
+%% package options
+\newif\if@hangul
+\newif\if@hanja
+\newif\if@unfonts
+\DeclareOption{hangul}{\@hangultrue}
+\DeclareOption{hanja}{\@hangultrue\@hanjatrue}
+\DeclareOption{unfonts}{\@unfontstrue}
+\ProcessOptions\relax
+
+\if@unfonts
+ \setmainhangulfont[
+ InterHangul=-0.04em,
+ InterLatinCJK=0.125em,
+ PunctRaise=-0.125em,
+ SlantedFont=*, SlantedFeatures={FakeSlant=0.2},
+ ItalicFont=*, ItalicFeatures={FakeSlant=0.2},
+ BoldSlantedFont=*Bold, BoldSlantedFeatures={FakeSlant=0.2},
+ BoldItalicFont=*Bold, BoldItalicFeatures={FakeSlant=0.2},
+ ]{UnBatang}
+ \setsanshangulfont[
+ InterLatinCJK=0.125em,
+ PunctRaise=-0.125em,
+ SlantedFont=*, SlantedFeatures={FakeSlant=0.2},
+ ItalicFont=*, ItalicFeatures={FakeSlant=0.2},
+ BoldSlantedFont=*Bold, BoldSlantedFeatures={FakeSlant=0.2},
+ BoldItalicFont=*Bold, BoldItalicFeatures={FakeSlant=0.2},
+ ]{UnDotum}
+ \setmonohangulfont[
+ SlantedFont=*, SlantedFeatures={FakeSlant=0.2},
+ ItalicFont=*, ItalicFeatures={FakeSlant=0.2},
+ BoldSlantedFont=*Bold, BoldSlantedFeatures={FakeSlant=0.2},
+ BoldItalicFont=*Bold, BoldItalicFeatures={FakeSlant=0.2},
+ ]{UnDotum}
+\fi
+
+\AtBeginDocument{% [unfonts] 없는 경우 에러 방지
+\unless\ifdefined\serifhangul@font\let\serifhangul@font\relax\fi
+\unless\ifdefined\sanshangul@font \let\sanshangul@font\serifhangul@font\fi
+\unless\ifdefined\monohangul@font \let\monohangul@font\sanshangul@font\fi
+% for hyperref
+\@ifpackageloaded{hyperref}{\pdfstringdefDisableCommands{%
+ \let\dotemph\@firstofone
+ \let\ruby\@firstoftwo
+ \let\uline\@firstofone
+ \let\sout\@firstofone
+ \let\uuline\@firstofone
+ \let\xout\@firstofone
+ \let\uwave\@firstofone
+ \let\dashuline\@firstofone
+ \let\dotuline\@firstofone
+ \let\autojosaattr\@firstofone
+ }}{}
+}
+
+\RequirePackage{kolabels-utf}
+\if@hangul
+ \RequirePackage{konames-utf}
+ \linespread{1.3888}
+ \footnotesep=1.3888\footnotesep
+ \skip\footins=1.3888\skip\footins plus6pt minus3pt
+ \directlua{luatexko.hangulmain = true}
+\fi
+
+\endinput
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 916b86f6e09..d253aa2cc93 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -283,7 +283,7 @@ my @TLP_working = qw(
luaindex luainputenc luaintro lualatex-doc lualatex-doc-de
lualatex-math lualibs
luamplib luaotfload
- luasseq luatexbase luatexja luatextra luaxml
+ luasseq luatexbase luatexja luatexko luatextra luaxml
lxfonts ly1
m-tx macros2e mafr magaz mailing mailmerge
makebarcode makebox makecell makecirc makecmds makedtx makeglos makeplot
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index 9c067841d93..95564d1cb76 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -1417,6 +1417,7 @@ $standardtex='\.(.bx|cfg|sty|clo|ldf|cls|def|fd|cmap|4ht)$';
'lua2dox', 'NULL', # .def is lua code
'luaintro', 'NULL', # doc pkg
'lualatex-math', '\.sty', # not phst-doc.cls
+ 'luatexko', '\.lua|' . $standardtex,
'luaxml', '\.lua|' . $standardtex,
'magyar', 'NULL', # do not install in runtime, conflicts with babel
'manjutex', '\.sty|\.clo|\.ldf|\.cls|\.def|\.fd$|manju.tex',
diff --git a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
index f2b6af1907d..4b8612e1449 100644
--- a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
@@ -24,6 +24,7 @@ depend luamplib
depend luaotfload
depend luasseq
depend luatexbase
+depend luatexko
depend luatextra
depend luaxml
depend odsfile
diff --git a/Master/tlpkg/tlpsrc/luatexko.tlpsrc b/Master/tlpkg/tlpsrc/luatexko.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/luatexko.tlpsrc