+%</ja>
+
+%<en>\section{Patch for the \Pkg{listings} Package}
+%<ja>\section{\Pkg{listings} パッケージへの対応}
+
+%<*en>
+It is well-known that the \Pkg{listings} package outputs weird results
+for Japanese input.
+The \Pkg{listings} package makes most of letters active and assigns
+output command for each letter~(\cite{listings}).
+But Japanese characters are not included in these activated letters.
+For \pTeX{} series, there is no method to make Japanese characters active;
+a patch \Pkg{jlisting.sty}~(\cite{jlisting}) resolves the problem forcibly.
+%</en>
+%<*ja>
+\Pkg{listings} パッケージが,そのままでは日本語をまともに出力できないこと
+はよく知られている.きちんと整形して出力するために,\Pkg{listings}パッケー
+ジは内部で「ほとんどの文字」をアクティブにし,各文字に対してその文字の出
+力命令を割り当てている(\cite{listings}).
+しかし,そこでアクティブにする文字の中に,和文文
+字がないためである.\pTeX 系列では,和文文字をアクティブにする手法がなく,
+\Pkg{jlisting.sty} というパッチ(\cite{jlisting})を用いることで無理やり解決していた.
+%</ja>
+
+%<*en>
+In \LuaTeX-ja, the problem is resolved by using the \verb+process_input_buffer+ callback.
+The callback function inserts the output command (active character \texttt{U+FFFFF})
+before each letter above \texttt{U+0080}.
+This method can omits the process to make all Japanese characters active
+(most of the activated characters are not used in many cases).
+%</en>
+%<*ja>
+\LuaTeX-jaでは,\verb+process_input_buffer+ コールバックを利用することで,
+「各行に出現する\texttt{U+0080}以降の文字に対して,それらの出力命令を前置する」
+という方法をとっている.出力命令としては,アクティブ文字化した \texttt{U+FFFFF} を用いている.
+これにより,(入力には使用されていないかもしれない)和文文字をもすべてアクティブ化する手間もなく,
+見通しが良い実装になっている.
+%</ja>
+
+
+%<*en>
+If the \Pkg{listings} package and \LuaTeX-ja were loaded,
+then the patch \Pkg{lltjp-listings} is loaded automatically at \verb+\begin{document}+.
+%</en>
+%<*ja>
+\LuaTeX-ja で利用される \Pkg{listings} パッケージへのパッチ \Pkg{lltjp-listings} は,
+\Pkg{listings} と\LuaTeX-jaを読み込んでおけば,
+\verb+\begin{document}+ の箇所において自動的に読み込まれるので,通常はあまり
+意識する必要はない.
+%</ja>
+
+%<en>\subsection{Notes}
+%<ja>\subsection{注意}
+%<*en>
+\paragraph{Escaping to \LaTeX}
+We used the \verb+process_input_buffer+ callback to output \textbf{JAchar}s.
+But it has a drawback; any commands whose name contains a \textbf{JAchar}
+cannot be used in any ``escape to \LaTeX''.
+
+Consider the following input:
+%</en>
+%<*ja>
+\paragraph{\LaTeX へのエスケープ}
+日本語対応を行うために \verb+process_input_buffer+ を使用したことで,
+\texttt{texcl},~\texttt{escapeinside}といった\emph{「\LaTeX へのエスケープ」中では,
+\textbf{JAchar}を名称の一部に含む制御綴は使用不可能}である.
+例えば次のような入力を考えよう:
+%</ja>
+\begin{verbatim*}
+\begin{lstlisting}[escapechar=\#]
+#\ほげ xぴよ#
+\end{lstlisting}
+\end{verbatim*}
+%<en>The line~2 is transformed by the callback to
+%<ja>ここで,2行目は \verb+process_input_buffer+ の作用により,
+\begin{lstlisting}[showspaces, escapechar=\!]
+#\!\IVSA FFFFF!ほ!\IVSA FFFFF !げ x!\IVSA FFFFF !ぴ!\IVSA FFFFF !よ#
+\end{lstlisting}
+%<*en>
+before the line is actually processed.
+In the escape (between the character ``\verb+#+''),
+the category code of \texttt{U+FFFFF} is set to 9~(\emph{ignored}).
+Hence the control symbol ``\verb+\+\IVSA FFFFF'' will be executed,
+instead of ``\verb+\ほげ+''.
+%</en>
+%<*ja>
+と変換されてから,実際の処理に回される.
+「\verb+#+」で挟まれた「\LaTeX へのエスケープ」中では\
+\texttt{U+FFFFF} のカテゴリーコードは9~(\textit{ignored})となるので,
+結局「\verb+\ほげ+」の代わりに
+「\verb+\+\IVSA FFFFF」というcontrol symbolが実行されることになる.
+%</ja>
+
+%<*ja>
+\paragraph{異体字セレクタの扱い}
+\texttt{lstlisting} 環境などの内部にある異体字セレクタを扱うため,
+\Pkg{lltjp-listings} では \texttt{vsraw} と \texttt{vscmd} という2つのキーを追加した.
+しかし,\Pkg{lltjp-listings} が実際にロードされるのは \verb+\begin{document}+\
+のところであるので,プリアンブル内ではこれらの追加キーは使用できない.
+
+\texttt{vsraw}は,ブール値の値をとるキーであり,標準ではfalseである.
+\begin{itemize}
+ \item trueの場合は,異体字セレクタは「直前の文字に続けて」出力される.
+もしもIVSサポート(\ref{ssec-ltjotf}節)が有効になっていた場合は,
+以下の例(左側は入力,右側はその出力)のようになる.
+\begin{LTXexample}
+\begin{lstlisting}[vsraw=true]
+葛󠄀城市,葛󠄁飾区,葛西
+\end{lstlisting}
+\end{LTXexample}
+\item falseの場合は,異体字セレクタは適当な命令によって「見える形で」出力される.
+どのような形で出力されるかを規定するのが \texttt{vscmd} キーであり,
+\Pkg{lltjp-listings} の標準設定では以下の例の右側のように出力される.
+\begin{LTXexample}
+\begin{lstlisting}[vsraw=false,
+ vscmd=\ltjlistingsvsstdcmd]
+葛󠄀城市,葛󠄁飾区,葛西
+\end{lstlisting}
+\end{LTXexample}
+ちなみに,本ドキュメントでは次のようにしている:
+\begin{lstlisting}[numbers=left]
+\def\IVSA#1#2#3#4#5{%
+ \textcolor{blue}{\raisebox{3.5pt}{\tt%
+ \fboxsep=0.5pt\fbox{\tiny \oalign{0#1#2\crcr#3#4#5\crcr}}}}%
+}
+{\catcode`\%=11
+ \gdef\IVSB#1{\expandafter\IVSA\directlua{
+ local cat_str = luatexbase.catcodetables['string']
+ tex.sprint(cat_str, string.format('%X', 0xE00EF+#1))
+}}}
+\lstset{vscmd=\IVSB}
+\end{lstlisting}
+\end{itemize}
+既定の出力命令を復活させたい場合は\ \verb+vsraw=\ltjlistingsvsstdcmd+\
+とすれば良い.
+%</ja>
+
+%<en>\subsection{Class of Characters}
+%<ja>\subsection{文字種}
+
+%<en>Roughly speaking, the \Pkg{listings} package processes input as follows:
+%<ja>\Pkg{listings} パッケージの内部では,大雑把に言うと
+\begin{enumerate}
+%<en>\item Collects \textit{letters} and \textit{digits}, which can be used for the name of identifiers.
+%<ja>\item 識別子として使える文字 (``letter'',~``digit'') たちを集める.
+%<en>\item When reading an \textit{other}, outputs the collected character string (with modification, if needed).
+%<ja>\item letterでもdigitでもない文字が現れた時に,収集した文字列を(必要なら修飾して)出力する.
+%<en>\item Collects \textit{others}.
+%<ja>\item 今度は逆に,letterでない文字たちをletterが現れるまで集める.
+%<en>\item When reading a \textit{letter} or a \textit{digit}, outputs the collected character string.
+%<ja>\item letterが出現したら集めた文字列を出力する.
+%<en>\item Turns back to 1.
+%<ja>\item 1.に戻る.
+\end{enumerate}
+%<*en>
+By the above process, line breaks inside of an identifier are blocked.
+A flag \verb+\lst@ifletter+ indicates whether the previous character can be used
+for the name of identifiers or not.
+%</en>
+%<*ja>
+という処理が行われている.これにより,識別子の途中では行分割が行われないようになっている.
+直前の文字が識別子として使えるか否かは \verb+\lst@ifletter+ というフラグに格納されている.
+%</ja>
+
+%<*en>
+For Japanese characters, line breaks are permitted on both sides
+except for brackets, dashes, etc.
+Hence the patch \Pkg{lltjp-listings} introduces
+a new flag \verb+\lst@ifkanji+, which indicates
+whether the previous character is a Japanese character or not.
+For illustration, we introduce following classes of characters:
+%</en>
+%<*ja>
+さて,日本語の処理である.殆どの和文文字の前後では行分割が可能であるが,その一方で
+括弧類や音引きなどでは禁則処理が必要なことから,\Pkg{lltjp-listings} では,
+直前が和文文字であるかを示すフラグ \verb+\lst@ifkanji+ を新たに導入した.
+以降,説明のために以下のように文字を分類する:
+%</ja>
+\begin{center}
+\small
+\begin{tabular}{lccccc}
+\toprule
+&Letter&Other&Kanji&Open&Close\\\midrule
+\verb+\lst@ifletter+&T&F&T&F&T\\
+\verb+\lst@ifkanji+&F&F&T&T&F\\
+%<en>Meaning&char in an identifier&other alphabet&%
+%<en>most of Japanese char&opening brackets&closing brackets\\
+%<ja>意図&識別子中の文字&その他欧文文字&殆どの和文文字&開き括弧類&閉じ括弧類\\
+\bottomrule
+\end{tabular}
+\end{center}
+%<*en>
+Note that \textit{digits} in the \Pkg{listings} package can be Letter or
+Other according to circumstances.
+%</en>
+%<*ja>
+なお,本来の\Pkg{listings} パッケージでの分類``digit''は,
+出現状況によって,上の表のLetterとOtherのどちらにもなりうる.
+また,KanjiとCloseは \verb+\lst@ifletter+ と \verb+\lst@ifkanji+ の値が一致しているが,
+これは間違いではない.
+%</ja>
+
+%<*en>
+For example, let us consider the case an Open comes after a Letter.
+Since an Open represents Japanese open brackets,
+it is preferred to be permitted to insert line break after the Letter.
+Therefore, the collected character string is output in this case.
+%</en>
+%<*ja>
+例えば,Letterの直後にOpenが来た場合を考える.
+文字種Openは和文開き括弧類を想定しているので,Letterの直後では行分割が可能であることが望ましい.
+そのため,この場合では,すでに収集されている文字列を出力することで行分割を許容するようにした.
+%</ja>
+
+%<*en>
+The following table summarizes $5\times 5=25$ cases:
+%</en>
+%<*ja>
+同じように,$5\times 5=25$通り全てについて書くと,次のようになる:
+%</ja>
+\begin{center}
+\small
+\begin{tabular}{llccccc}
+\toprule
+%<*en>
+&&\multicolumn{4}{c}{Next}\\\cmidrule(lr){3-7}
+&&\hbox to 4em{\hss Letter\hss}&\hbox to 4em{\hss Other\hss}
+&\hbox to 4em{\hss Kanji\hss}&\hbox to 4em{\hss Open\hss}&Close\\\midrule
+&Letter&collects&\multicolumn{3}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+&Other&outputs&collects&\multicolumn{2}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+Prev&Kanji&\multicolumn{4}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+&Open&\multicolumn{5}{c}{\hrulefill \ collects\ \hrulefill}\\
+&Close&\multicolumn{4}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+%</en>
+%<*ja>
+&&\multicolumn{4}{c}{後ろ側の文字}\\\cmidrule(lr){3-7}
+&&\hbox to 4em{\hss Letter\hss}&\hbox to 4em{\hss Other\hss}
+&\hbox to 4em{\hss Kanji\hss}&\hbox to 4em{\hss Open\hss}&Close\\\midrule
+直&Letter&収集&\multicolumn{3}{c}{\hrulefill \ 出力\ \hrulefill}&収集\\
+前&Other&出力&収集&\multicolumn{2}{c}{\hrulefill \ 出力\ \hrulefill}&収集\\
+文&Kanji&\multicolumn{4}{c}{\hrulefill \ 出力\ \hrulefill}&収集\\
+字&Open&\multicolumn{5}{c}{\hrulefill \ 収集\ \hrulefill}\\
+種&Close&\multicolumn{4}{c}{\hrulefill \ 出力\ \hrulefill}&収集\\
+%</ja>
+\bottomrule
+\end{tabular}
+\end{center}
+%<en>In the above table,
+%<ja>上の表において,
+\begin{itemize}
+%<en>\item ``outputs'' means to output the collected character string (i.e., line breaking is permitted there).
+%<ja>\item 「出力」は,それまでに集めた文字列を出力(≒ここで行分割可能)を意味する.
+
+%<en>\item ``collects'' means to append the next character to the collected character string (i.e., line breaking is prohibited there).
+%<ja>\item 「収集」は,後側の文字を,現在収集された文字列に追加(行分割不可)を意味する.
+\end{itemize}
+
+%<*en>
+Charatcers above \texttt{U+0080} \emph{except Variation Selectors}
+are classified into above 5~classes by the following rules:
+%</en>
+%<*ja>
+\texttt{U+0080}以降の\emph{異体字セレクタ以外の}各文字が
+Letter, Other, Kanji, Open, Closeのどれに属するかは次によって決まる:
+%</ja>
+\begin{itemize}
+%<en>\item \textbf{ALchar}s above \texttt{U+0080} are classified as Letter.
+%<ja>\item (\texttt{U+0080}以降の)\textbf{ALchar}は,すべてLetter扱いである.
+
+%<en>\item \textbf{JAchar}s are classified in the order as follows:
+%<ja>\item \textbf{JAchar}については,以下の順序に従って文字種を決める:
+\begin{enumerate}
+%<en>\item Characters whose \Param{\hyperlink{fld:prebp}{prebreakpenalty}} is greater than or equal to 0 are classified as Open.
+%<ja>\item \Param{\hyperlink{fld:prebp}{prebreakpenalty}}が0以上の文字はOpen扱いである.
+
+%<en>\item Characters whose \Param{\hyperlink{fld:postbp}{postbreakpenalty}} is greater than or equal to 0 are classified as Close.
+%<ja>\item \Param{\hyperlink{fld:postbp}{postbreakpenalty}}が0以上の文字はClose扱いである.
+
+%<en>\item Characters that don't satisfy the above two conditions are classified as Kanji.
+%<ja>\item 上の3条件のどちらにも当てはまらなかった文字は,Kanji扱いである.
+\end{enumerate}
+\end{itemize}
+
+%<*en>
+The width of halfwidth kana (\texttt{U+FF61}--\texttt{U+FF9F})
+is same as the width of \textbf{ALchar};
+the width of the other \textbf{JAchar}s is double the width of \textbf{ALchar}.
+%</en>
+%<*ja>
+なお,半角カナ(U+FF61--U+FF9F)以外の\textbf{JAchar}は欧文文字2文字分の幅をとるものとみなされる.
+半角カナは欧文文字1文字分の幅となる.
+%</ja>
+
+%<*en>
+This classification process is executed every time a character appears in
+the \texttt{lstlisting} environment or other environments/commands.
+%</en>
+%<*ja>
+これらの文字種決定は,実際に \texttt{lstlisting} 環境などの内部で文字が出てくるたびに行われる.
+%</ja>
+
+%<*ja>
+\section{和文の行長補正方法}
+\label{sec-adjspec}
+\Pkg{luatexja-adjust} で提供される優先順位付きの行長調整の詳細を述
+べる.大まかに述べると,次のようになる.
+\begin{itemize}
+\item 通常の\TeX の行分割方法に従って,段落を行分割する.この段階では,行
+ 長に半端が出た場合,その半端分は\textbf{JAglue}(\Param{\hyperlink{fld:xks}{xkanjiskip}},
+ \Param{\hyperlink{fld:kanjiskip}{kanjiskip}},JFMグルー)と
+ それ以外のグルーの全てで(優先順位なく)負担される.
+\item その後,\texttt{post\_linebreak\_filter} callbackを使い,\emph{段
+ 落中の各行ごとに},行末文字の位置を調整したり,優先度付きの行長調整
+ を実現するためにグルーの伸縮度を調整する.
+ その処理においては,グルーの自然長と\textbf{JAglue}以外の
+ グルーの伸び量・縮み量は変更せず,必要に応じて\textbf{JAglue}の伸び量・縮み量のみを
+ 変更する設計とした.
+
+\Pkg{luatexja-adjust} の作用は,この処理を行うcallbackを追加するだけであり,
+ この章の残りではcallbackでの処理について解説する.
+\end{itemize}
+
+\paragraph{準備:合計伸縮量の計算}
+グルーの伸縮度(\texttt{plus} や \texttt{minus} で指定されている値)には,
+有限値の他に,\texttt{fi},\texttt{fil},\texttt{fill},\texttt{filll}と
+いう4つの無限大レベル(後ろの方ほど大きい)があり,行の調整に
+\texttt{fi} などの\emph{無限大レベルの伸縮度が用いられている場合は,そ
+の行に対しての処理を中止}する.
+
+よって,以降,問題にしている行の行長調整は伸縮度が有限長のグルーを用いて
+行われているとして良い.さらに,簡単のため,この行はグルーが広げられている
+(自然長で組むと望ましい行長よりの短い)場合しか扱わない.
+
+まず,段落中の行中のグルーを
+\begin{itemize}
+\item \textbf{JAglue}ではないグルー
+\item JFMグルー(優先度\footnote{%
+ \ref{ssec-jfm-str}節にあるように,
+ 各JFMグルーには$-2$から2までの優先度がついている.}%
+別にまとめられる)
+\item 和欧文間空白(\Param{\hyperlink{fld:xks}{xkanjiskip}})
+\item 和文間空白(\Param{\hyperlink{fld:kanjiskip}{kanjiskip}})
+\end{itemize}
+の$1+1+5+1=8$つに類別し,それぞれの種別ごとに
+許容されている伸び量(\texttt{stretch}の値)の合計を計算する.
+また,行長と自然長との差を\textit{total}とおく.
+
+
+\subsection{行末文字の位置調整}
+行末が文字クラス$n$の\textbf{JAchar}であった場合,
+それを動かすことによって,\textit{total}のうち
+\textbf{JAglue}が負担する分を少なくしようとする.
+この行末文字の左右の移動可能量は,
+JFM中にある文字クラス$n$の定義の
+\texttt{end\_stretch},~\texttt{end\_shrink}フィールドに
+全角単位の値として記述されている.
+
+例えば,行末文字が句点「。」であり,そこで用いられているJFM中に
+\begin{verbatim}
+ [2] = {
+ chars = { '。', ... }, width = 0.5, ...,
+ end_stretch = 0.5, end_shrink = 0.5,
+ },
+\end{verbatim}
+という指定があった場合,この行末の句点は
+\begin{itemize}
+\item 通常の\TeX の行分割処理で「半角以上の詰め」が行われていた場合,
+この行中の\textbf{JAglue}の負担を軽減するため,
+行末の句点を半角だけ右に移動する(ぶら下げ組を行う).
+\item 通常の\TeX の行分割処理で「半角以上の空き」が行われていた場合,
+逆に行末句点を半角左に移動させる(見た目的に全角取りとなる).
+\item 以上のどちらでもない場合,行末句点の位置調整は行わない.
+\end{itemize}
+となる.
+
+行末文字を移動した場合,その分だけ\textit{total}の値を引いておく.
+
+\subsection{グルーの調整}
+\textit{total}の分だけが,行中のグルーの伸び量に応じて負担されることになる.
+負担するグルーの優先度は以下の順であり,
+できるだけ\Param{\hyperlink{fld:kanjiskip}{kanjiskip}}を自然長のままにすることを
+試みている.
+\begin{enumerate}\def\labelenumi{(\Alph{enumi})}
+ \item \textbf{JAglue}以外のグルー
+ \item 優先度2のJFMグルー
+ \item 優先度1のJFMグルー
+ \item 優先度0のJFMグルー
+ \item 優先度$-1$のJFMグルー
+ \item 優先度$-2$のJFMグルー
+ \item \Param{\hyperlink{fld:xks}{xkanjiskip}}
+ \item \Param{\hyperlink{fld:kanjiskip}{kanjiskip}}
+\end{enumerate}
+\begin{enumerate}
+ \item 行末の和文文字を移動したことで$\textit{total}=0$となれば,
+調整の必要はなく,行が格納されているhboxの
+\texttt{glue\_set}, \texttt{glue\_sign}, \texttt{glue\_order}を再計算すればよい.
+以降,$\textit{total}\neq 0$と仮定する.
+ \item \textit{total}が「\textbf{JAglue}以外のグルーの伸び量の合計」(以下,(A)の伸び量の
+ 合計,と称す)よりも小さければ,
+それらのグルーに\textit{total}を負担させ,\textbf{JAglue}達自身は自然長で組むことができる.
+よって,以下の処理を行う:
+\begin{enumerate}
+\item 各\textbf{JAglue}の伸び量を0とする.
+\item 行が格納されているhboxの
+\texttt{glue\_set}, \texttt{glue\_sign}, \texttt{glue\_order}を再計算する.
+これによって,\textit{total}は\textbf{JAglue}以外のグルーによって負担される.
+\end{enumerate}
+\item \textit{total}が「(A)の伸び量の合計」以上ならば,(A)--(H)のどこまで負担すれば
+\textit{total}以上になるかを計算する.
+例えば,
+\[\catcode`\<=12
+ \textit{total} = (\text{(A)--(B)の伸び量の合計}) + p\cdot (\text{(C)の伸び量の合計}),
+ \qquad 0\le p<1
+\]
+であった場合,各グルーは次のように組まれる:
+\begin{itemize}
+ \item (A),~(B)に属するグルーは各グルーで許された伸び量まで伸ばす.
+ \item (C)に属するグルーはそれぞれ$p\times (\text{伸び量})$だけ伸びる.
+ \item (D)--(H)に属するグルーは自然長のまま.
+\end{itemize}
+実際には,前に述べた「設計」に従い,次のように処理している:
+\begin{enumerate}
+\item (C)に属するグルーの伸び量を$p$倍する.
+\item (D)--(H)に属するグルーの伸び量を0とする.
+\item 行が格納されているhboxの
+\texttt{glue\_set}, \texttt{glue\_sign}, \texttt{glue\_order}を再計算する.
+これによって,\textit{total}は\textbf{JAglue}以外のグルーによって負担される.
+\end{enumerate}
+\item \textit{total}が(A)--(H)の伸び量の合計よりも大きい場合,どうしようもないので
+ \verb+^^;+何もしない.
+\end{enumerate}
+
+%</ja>
+
+%<*ja>
+\section{IVS対応}
+\verb+luatexja.otf.enable_ivs()+ を実行し,IVS対応を有効にした状態では,
+\verb+pre_linebreak_filter+ や \verb+hpack_filter+ コールバックには
+次の4つが順に実行される状態となっている:
+\begin{description}
+\item[\tt ltj.do\_ivs] \textit{glyph\_node}~$p$の直後に,異体字セレクタ(を表す\textit{glyph\_node})
+が連続した場合に,$p$のフォントに対応したが持つ「異体字情報」に従って出力するグリフを変える.
+
+しかし,単に$p.\textit{char}$を変更するだけでは,後から
+font featureの適用(すぐ下)により置換される可能性がある.そのため,
+\verb+\CID+ や \verb+\UTF+ と同じように,\textit{glyph\_node}~$p$の代わりに
+\texttt{user\_id} が\textit{char\_by\_cid}であるようなuser-defined whatsitを用いている.
+\item[(\Pkg{luaotfload} によるfont featureの適用)]
+\item[\tt ltj.otf] \texttt{user\_id} が\textit{char\_by\_cid}であるようなuser-defined whatsitを
+きちんと\textit{glyph\_node}に変換する.この処理は,\verb+\CID+, \verb+\UTF+やIVSによる置換が,
+font featureの適用で上書きされてしまうのを防止するためである.
+\item[\tt ltj.main\_process] \textbf{JAglue}の挿入処理(\ref{sec-jfmglue}章)と,
+JFMの指定に従って各\textbf{JAchar}の「寸法を補正」することを行う.
+\end{description}
+
+問題は各フォントの持っているIVS情報をどのように取得するか,である.
+\Pkg{luaotfload} はフォント番号<font\_number>の情報を\
+\texttt{fonts.hashes.identifiers[<font\_number>]} 以下に格納している.
+しかし,OpenTypeフォントのIVS情報は格納されていないようである%
+\footnote{TrueTypeフォントに関しては,
+\begin{center}
+\texttt{fonts.hashes.idenfiers[<font\_number>]%
+ .resources.variants[<selector>][<base\_char>]}
+\end{center}
+に,<base\_char>番の文字の後に異体字セレクタ<selector>が続いた場合に
+出力すべきグリフが書かれてある.}.
+%例えば,小塚明朝Pr6N~Rでは,
+
+一方,\LuaTeX 内部の \texttt{fontloader} の返すテーブルには
+OpenTypeフォントでもTrueTypeフォントでもIVS情報が格納されている.
+具体的には……
+
+そのため,\LuaTeX-jaのIVS対応においては,\LuaTeX 内部の\
+\texttt{fontloader} を直接用いることで,フォントのIVS情報を取得している.
+20140114.0以降でキャッシュを用いるようにした要因はここにあり,
+\texttt{fontloader} の呼び出しでかなり時間を消費することから,
+%%% to_table を使わなくしたことで,メモリ使用量は減った
+IVS情報をキャッシュに保存することで2回目以降の実行時間を節約している.
+
+
+\section{複数フォントの「合成」(未完)}
+
+\section{\LuaTeX-jaにおけるキャッシュ}
+\Pkg{luaotfload}パッケージが,各TrueType・]OpenTypeフォントの情報を
+キャッシュとして保存しているのと同様の方法で,
+\LuaTeX-jaもいくつかのキャッシュファイルを作成するようになった.
+\begin{itemize}
+ \item 通常,キャッシュは\texttt{\$TEXMFVAR/luatexja/}以下に保存され,
+そこから読み込みが行われる.
+ \item 「通常の」テキスト形式のキャッシュ(拡張子は \texttt{.lua})以外にも,
+それをバイナリ形式(バイトコード)に変換したものもサポートしている.
+\begin{itemize}
+ \item \LuaTeX とLuaJIT\TeX ではバイトコードの形式が異なるため,バイナリ形式の
+キャッシュは共有できない.\LuaTeX 用のバイナリキャッシュは \texttt{.luc},
+LuaJIT\TeX 用のは \texttt{.lub} と拡張子を変えることで対応している.
+ \item キャッシュを読み込む時,同名のバイナリキャッシュがあれば,
+テキスト形式のものよりそちらを優先して読み込む.
+ \item テキスト形式のキャッシュが更新/作成される際は,そのバイナリ版も
+同時に更新される.
+また,(バイナリ版が見つからず)テキスト形式のキャッシュ側が読み込まれたときは,
+\LuaTeX-jaはバイナリキャッシュを作成する.
+\end{itemize}
+\end{itemize}
+%</ja>
+%<*en>
+\section{Cache Management of \LuaTeX-ja}
+\LuaTeX-ja creates some cache files to reduce the loading time.
+in a similar way to the \Pkg{luaotfload} package:
+\begin{itemize}
+ \item Cache files are usually stored in (and loaded from)
+\texttt{\$TEXMFVAR/luatexja/}.
+ \item In addition to caches of the text form (the extension is ``\texttt{.lua}''),
+caches of the \emph{binary}, precompiled form are supported.
+\begin{itemize}
+ \item We cannot share same binary cache for \LuaTeX\ and LuaJIT\TeX.
+Hence we distinguish them by their extension, ``\texttt{.luc}'' for \LuaTeX\
+and ``\texttt{.lub}'' for LuaJIT\TeX.
+ \item In loading a cache, the binary cache precedes
+the text form.
+ \item When \LuaTeX-ja updates a cache \texttt{hoge.lua},
+its binary version is also updated.
+\end{itemize}
+\end{itemize}
+%</en>
+
+%<*ja>
+\subsection{キャッシュの使用箇所}
+
+\LuaTeX-ja では以下の3種類のキャッシュを使用している:
+\begin{list}{}%
+{\def\makelabel#1{\ttfamily#1}}
+\item[ltj-cid-auto-adobe-japan1.lua]
+Ryumin-Lightのような非埋め込みフォントの情報を格納しており,
+(それらが\LuaTeX-jaの標準和文フォントなので)\LuaTeX-jaの読み込み時に自動で読まれる.
+生成には\texttt{UniJIS2004-UTF32-H}, \texttt{Adobe-Japan1-UCS2}という2つの
+CMapが必要である.
+
+\pageref{para-cid}ページで述べたように,\texttt{cid}キーを使って
+非埋め込みの中国語・韓国語フォントを定義する場合,同様のキャッシュが生成される.
+キャッシュの名称,必要となるCMapについては表\ref{tab:cid-cache}を参照して欲しい.
+
+\item[ivs\_***.lua]
+フォント``\texttt{***}''における異体字情報を格納している.構造は以下の通り:
+%</ja>
+%<*en>
+\subsection{Use of Cache}
+
+\LuaTeX-ja uses the following cache:
+\begin{list}{}%
+{\def\makelabel#1{\ttfamily#1}}
+\item[ltj-cid-auto-adobe-japan1.lua]
+The font table of a CID-keyed non-embedded Japanese font.
+This is loaded in every run.
+It is created from two CMaps, \texttt{UniJIS2004-UTF32-H} and
+ \texttt{Adobe-Japan1-UCS2},
+and this is why these two CMaps are needed in the first run of \LuaTeX-ja.
+
+Similar caches are created as Table~\ref{tab:cid-cache},
+if you specified \texttt{cid} key in \verb+\jfont+
+to use other CID-keyed non-embedded fonts for Chinese or Korean,
+as in Page~\pageref{para-cid}.
+
+\item[ivs\_***.lua]
+This file stores the table of Unicode variants in a font ``\texttt{***}''.
+The structure of the table is the following:
+%</en>
+
+\begin{table}[!tb]
+ \centering\small
+\caption{\texttt{cid} key and corresponding files}
+\label{tab:cid-cache}
+\vspace*{\medskipamount}
+\begin{tabular}{>{\tt}l>{\tt}l>{\tt}l>{\tt}l}
+\toprule
+\bf \texttt{cid} key&\bf name of the cache &
+\multicolumn{2}{c}{\bf used CMaps}\\
+\midrule
+Adobe-Japan1-*<j-cid-auto-adobe-japan1.lua&UniJIS2004-UTF32-H&Adobe-Japan1-UCS2\\
+Adobe-Korea1-*<j-cid-auto-adobe-korea1.lua&UniKS-UTF32-H&Adobe-Korea1-UCS2\\
+Adobe-GB1-*<j-cid-auto-adobe-gb1.lua&UniGB-UTF32-H&Adobe-GB1-UCS2\\
+Adobe-CNS1-*<j-cid-auto-adobe-cns1.lua&UniCNS-UTF32-H&Adobe-CNS1-UCS2\\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\begin{lstlisting}
+return {
+ {
+ [10955]={ -- U+2ACB "Subset Of Above Not Equal To"
+ [65024]=983879, -- <2ACB FE00>
+ },
+ [37001]={ -- U+9089 "邉"
+ [0]=37001, -- <9089 E0100>
+ 991049, -- <9089 E0101>
+ ...
+ },
+ ...
+ },
+ ["chksum"]="FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", -- checksum of the fontfile
+ ["version"]=4, -- version of the cache
+}
+\end{lstlisting}
+%<*ja>
+\item[ltj-jisx0208.\{luc|lub\}]
+\LuaTeX-ja配布中の\texttt{ltj-jisx0208.lua}をバイナリ化したものである.
+これはJIS~X~0208とUnicodeとの変換テーブルであり,
+\pTeX との互換目的の文字コード変換命令で用いられる.
+%</ja>
+%<*en>
+\item[ltj-jisx0208.\{luc|lub\}]
+The binary version of \texttt{ltj-jisx0208.lua}.
+This is the conversion table between JIS~X~0208 and Unicode
+which is used in Kanji-code conversion commands for compatibility with \pTeX.
+%</en>
+\end{list}
+
+%<*en>
+\subsection{Internal}
+Cache management system of \LuaTeX-ja is stored in \texttt{luatexja.base}
+(\texttt{ltj-base.lua}).
+There are three public functions for cache management in \texttt{luatexja.base},
+where <filename> stands for the filename \emph{without suffix}:
+\begin{list}{}%
+{\def\makelabel#1{\ttfamily#1}}
+\item[save\_cache(<filename>, <data>)]
+Save a non-nil table <data> into a cache <filename>.
+Both the text form <filename>\texttt{.lua} and its binary version
+are created or updated.
+
+\item[save\_cache\_luc(<filename>, <data>{[, <serialized\_data>]})]\
+
+Same as \texttt{save\_cache}, except that only the binary cache is updated.
+The third argument <serialized\_data> is not usually given.
+But if this is given, it is treated as a string representation of <data>.
+
+\item[load\_cache(<filename>, <outdate>)]
+Load the cache <filename>.
+<outdate> is a function which takes one argument (the contents of the cache),
+and its return value is whether the cache is outdated.
+
+\texttt{load\_cache} first tries to
+read the binary cache <filename>\texttt{.\{luc|lub\}}.
+If its contents is up-to-date, \texttt{load\_cache} returns the contents.
+If the binary cache is not found or
+its contents is outdated, \texttt{load\_cache} tries to
+read the text form <filename>\texttt{.lua}.
+Hence, the return value of \texttt{load\_cache} is non-nil,
+if and only if the updated cache is found.
+\end{list}
+%</en>
+%<*ja>
+\subsection{内部命令}
+\LuaTeX-jaにおけるキャッシュ管理は,\texttt{luatexja.base}~(\texttt{ltj-base.lua})に
+実装しており,以下の3関数が公開されている.
+ここで,<filename>は保存するキャッシュのファイル名を\emph{拡張子なしで}指定する.
+\begin{list}{}%
+{\def\makelabel#1{\ttfamily#1}}
+\item[save\_cache(<filename>, <data>)]
+nilでない<data>をキャッシュ<filename>に保存する.
+テキスト形式の<filename>\texttt{.lua}のみならず,
+そのバイナリ版も作成/更新される.
+
+\item[save\_cache\_luc(<filename>, <data>{[, <serialized\_data>]})]\
+
+\texttt{save\_cache}と同様だが,バイナリキャッシュのみが更新される.
+第3引数<serialized\_data>が与えられた場合,それを
+<data>の文字列化表現として使用する.
+そのため,<serialized\_data>は普通は指定しないことになるだろう.
+
+\item[load\_cache(<filename>, <outdate>)]
+キャッシュ<filename>を読み込む.
+<outdate>は1引数(キャッシュの中身)をとる関数であり,
+その戻り値は「キャッシュの更新が必要」かどうかを示すブール値でないといけない.
+
+\texttt{load\_cache}は,まずバイナリキャッシュ<filename>\texttt{.\{luc|lub\}}を
+読みこむ.もしその内容が「新しい」,つまり<outdate>の評価結果が \texttt{false} なら
+\texttt{load\_cache}はこのバイナリキャッシュの中身を返す.
+もしバイナリキャッシュが見つからなかったか,「古すぎる」ならばテキスト版
+ <filename>\texttt{.lua}を読み込み,その値を返す.
+
+以上より,\texttt{load\_cache}自体がnilでない値を返すのは,ちょうど「新しい」キャッシュが
+見つかった場合である.
+\end{list}
+%</ja>
+
+
+%<*ja>
+\section{縦組の実装}
+