From 5e514c20c590569dee9a6ae13ab7ac8ed0878822 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 17 May 2013 22:32:58 +0000 Subject: luatexko (17may13) git-svn-id: svn://tug.org/texlive/trunk@30533 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/luatex/luatexko/README | 138 ++ .../doc/luatex/luatexko/luatexko-doc.pdf | Bin 0 -> 465585 bytes .../doc/luatex/luatexko/luatexko-doc.tex | 392 +++++ .../tex/luatex/luatexko/luatexko-core.sty | 355 ++++ .../tex/luatex/luatexko/luatexko-normalize.lua | 486 ++++++ .../tex/luatex/luatexko/luatexko-uhc2utf8.lua | 130 ++ Master/texmf-dist/tex/luatex/luatexko/luatexko.lua | 1720 ++++++++++++++++++++ Master/texmf-dist/tex/luatex/luatexko/luatexko.sty | 248 +++ Master/tlpkg/bin/tlpkg-ctan-check | 2 +- Master/tlpkg/libexec/ctan2tds | 1 + Master/tlpkg/tlpsrc/collection-luatex.tlpsrc | 1 + Master/tlpkg/tlpsrc/luatexko.tlpsrc | 0 12 files changed, 3472 insertions(+), 1 deletion(-) create mode 100644 Master/texmf-dist/doc/luatex/luatexko/README create mode 100644 Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf create mode 100644 Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex create mode 100644 Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty create mode 100644 Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua create mode 100644 Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua create mode 100644 Master/texmf-dist/tex/luatex/luatexko/luatexko.lua create mode 100644 Master/texmf-dist/tex/luatex/luatexko/luatexko.sty create mode 100644 Master/tlpkg/tlpsrc/luatexko.tlpsrc 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 . + + +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=] +Set spacing between Hangul characters. + + [InterLatinCJK=] +Set spacing between CJK and Latin characters. + + [PunctRaise=] +Raise Latin fullstop and comma after CJK character. + + [QuoteRaise=] +Raise Latin quotation marks and parentheses around CJK text. + + [CharRaise=] +Raise CJK characters by . + + +Other User Commands +=================== + \luatexuhcinputencoding= +When is 1 or greater, UHC (aka. Windows CP949) input encoding +is allowed. 0 restores UTF-8, the default input encoding. + + \dotemph{...} +Emphasise Hangul or Hanja by putting dot above. + + \ruby{}{} +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 Binary files /dev/null and b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf 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 +%% 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{\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 +% +% 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 +-- +-- 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 +-- +-- 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 +-- +-- 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 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 +% +% 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 -- cgit v1.2.3