下面就分配了整个表意文字补充平面和汉字“漢”为100。
%</zh>
\begin{lstlisting}
-\ltjdefcharrange{100}{"10000-"1FFFF,`漢}
+\ltjdefcharrange{100}{"20000-"2FFFF,`漢}
\end{lstlisting}
%<*en>
This assignment of numbers to ranges are always global, so you should
下列为“假想字符”列表:
%</zh>
\begin{list}{}{\def\makelabel{\ttfamily}\def\{{\char`\{}\def\}{\char`\}}\advance\leftmargin1\zw}
-\item['lineend']
-%<en>An ending of a line.
-%<ja>行の終端を表す.
-%<zh>行尾结束字符。
+%%\item['lineend']
+%%%<en>An ending of a line.
+%%%<ja>行の終端を表す.
+%%%<zh>行尾结束字符。
\item['diffmet']
%<en>Used at a boundary between two \textbf{JAchar}s whose JFM or size is different.
和文文字のワードラップ過程において挿入されたペナルティ(\emph{kinsoku}).
%</ja>
-\item[\textit{from\_jfm} (4)]
+\item[\textit{from\_jfm} (6)]
%<*en>
Glues/kerns from JFM.
%</en>
JFM由来のグルー/カーン.
%</ja>
-\item[\textit{line\_end} (5)]
-%<*en>
-Kerns for \ldots
-%</en>
-%<*ja>
-和文文字が行末にきたとき,行末との間に挿入されるカーンである.
-% ぶら下げ組への応用
-%</ja>
+%%\item[\textit{line\_end} (5)]
+%%%<*en>
+%%Kerns for \ldots
+%%%</en>
+%%%<*ja>
+%%和文文字が行末にきたとき,行末との間に挿入されるカーンである.
+%%% ぶら下げ組への応用
+%%%</ja>
-\item[\textit{kanji\_skip} (6)]
+\item[\textit{kanji\_skip} (9)]
%<*en>
Glues for \Param{kanjiskip}.
%</en>
\Param{kanjiskip}のグルー.
%</ja>
-\item[\textit{xkanji\_skip} (7)]
+\item[\textit{xkanji\_skip} (10)]
%<*en>
Glues for \Param{xkanjiskip}.
%</en>
\Param{xkanjiskip}のグルー.
%</ja>
-\item[\textit{processed} (8)]
+\item[\textit{processed} (11)]
%<*en>
Nodes which is already processed by \ldots.
%</en>
\LuaTeX-ja の内部処理によって既に処理されたノード.
%</ja>
-\item[\textit{ic\_processed} (9)]
+\item[\textit{ic\_processed} (12)]
%<*en>
Glues from an italic correction, but also already processed.
%</en>
\end{enumerate}
\end{description}
\paragraph{「左空白」の算出とそれに伴う補正}
-次に,「左空白」にあたる量を算出する:
-\begin{description}
-\item[line-end~{[E]}]
-\textit{Nq}と\textit{Np}の間で行分割が起きたときに,
-\textit{Nq}と行末の間に入る空白である.ぶら下げ組の組版などに用いられることを期待している.
-\begin{enumerate}
-\item 既に算出した「右空白」がカーンである場合は,「左空白」は挿入されない.
-\item 「右空白」がglueか未定義(長さ0のglueとみなす)の場合は,「左空白」は
-\textit{Nq}と「文字コード\texttt{'lineend'}の文字」との間に入るカーンとして,JFMから決定される.
-\item 2.で決まった「左空白」の長さが0でなければ,その分だけ先ほど算出した「右空白」の自然長を引く.
-\end{enumerate}
-\end{description}
+「左空白」は過去のバージョンでは定義していたが,このバージョンでは挿入は一切行われない(機能自体削除している).しかし,仕様は流動的であり,将来復活する可能性もあるため,マニュアル中の記述は今のとkろ極力変更しない.
+% 次に,「左空白」にあたる量を算出する:
+% \begin{description}
+% \item[line-end~{[E]}]
+% \textit{Nq}と\textit{Np}の間で行分割が起きたときに,
+% \textit{Nq}と行末の間に入る空白である.ぶら下げ組の組版などに用いられることを期待している.
+% \begin{enumerate}
+% \item 既に算出した「右空白」がカーンである場合は,「左空白」は挿入されない.
+% \item 「右空白」がglueか未定義(長さ0のglueとみなす)の場合は,「左空白」は
+% \textit{Nq}と「文字コード\texttt{'lineend'}の文字」との間に入るカーンとして,JFMから決定される.
+% \item 2.で決まった「左空白」の長さが0でなければ,その分だけ先ほど算出した「右空白」の自然長を引く.
+% \end{enumerate}
+% \end{description}
\paragraph{禁則用ペナルティの挿入}
まず,
\[
力命令を割り当てている (\cite{listings}).
しかし,そこでアクティブにする文字の中に,和文文
字がないためである.p\TeX 系列では,和文文字をアクティブにする手法がなく,
-\Pkg{jlisting.sty} というパッチ\cite{jlisting}を用いることで無理やり解決していたが,
-\LuaTeX-jaでは,(\LuaTeX がネイティブでUnicodeを理解することから)「和文
-文字をアクティブ化し,それらに対して適切に出力命令を設定する」というより正統的な
-方法を取ることにした.
+\Pkg{jlisting.sty} というパッチ\cite{jlisting}を用いることで無理やり解決していた.
+
+\LuaTeX-jaでは,\verb+process_input_buffer+ コールバックを利用することで,
+「各行に出現するU+0080以降の文字に対して,それらの出力命令を全治する」という方法をとっている.
+これにより,(入力には使用されていないかもしれない)和文文字をもすべてアクティブ化する手間もなく,
+見通しが良い実装になっている.
\LuaTeX-ja で利用される \Pkg{listings} パッケージへのパッチ \Pkg{lltjp-listings.sty} は,
\Pkg{listings.sty} と\LuaTeX-jaを読み込んでおけば,
さて,日本語の処理である.殆どの和文文字の前後では行分割が可能であるが,その一方で
括弧類や音引きなどでは禁則処理が必要なことから,\Pkg{lltjp-listings.sty} では,
-直前が和文文字であるかを示すフラグ \verb+lst@kanji+ を新たに導入した.
+直前が和文文字であるかを示すフラグ \verb+\lst@kanji+ を新たに導入した.
以降,説明のために以下のように文字を分類する:
\begin{center}
\small
\paragraph{和文文字扱いとなる文字}
\Pkg{listings} パッケージにおいて和文文字と扱われる
(前に述べたKanji, Open,あるいは「閉じ括弧類」分類)か否かは,
-通常の\textbf{JAchar}/\textbf{Alchar}の範囲の設定(\ref{ssec-setrange}節)とは全く関係ない.
-
-また,禁則処理に関する\Param{prebreakpenalty},~\Param{postbreakpenalty}の設定も
-\Pkg{listings} パッケージ内部ではまったく影響しない.
-
-\medskip
-現在の実装では,
+通常の\textbf{JAchar}/\textbf{Alchar}の範囲の設定(\ref{ssec-setrange}節)に従って行われる:
\begin{itemize}
-\item 基本多言語面のU+2000--U+FFFF,追加漢字面の文字は,以下の場合を除きKanji扱いとなり,
-また欧文文字2文字分の幅をとる..但し,以下は例外.
-\item U+FF61--U+FF9Fの半角カナはKanji扱いだが,欧文文字1文字分しか幅がない.
-\item 禁則処理のパラメータの標準値を定めている \texttt{luatexja-kinsoku.tex}\ %
-において \Param{prebreakpenalty} が
-10000と設定されている文字はClose扱いである.
-\item \texttt{luatexja-kinsoku.tex} で \Param{postbreakpenalty} が10000
-と設定されている文字はOpen扱いである.
+\item (U+0080以降の)\textbf{ALchar}は,すべてLetter扱いである.
+\item (U+0080以降の)\textbf{JAchar}については,以下の順序に従って文字種を決める:
+\begin{enumerate}
+\item \Param{prebreakpenalty} が0以上の文字はOpen扱いである.
+\item \Param{postbreakpenalty} が0以上の文字はClose扱いである.
+\item 上の2条件のどちらにも当てはまらなかった文字は,Kanji扱いである.
+\end{enumerate}
+なお,半角カナ(U+FF61--U+FF9F)以外の\textbf{JAchar}は欧文文字2文字分の幅をとるものとみなされる.
+半角カナは欧文文字1文字分の幅となる.
\end{itemize}
-これらの設定をユーザが\TeX ソースで変更させる仕組みはまだ作成していない.
+
+これらの文字種決定は,実際に \texttt{lstlisting} 環境などの内部で文字が出てくるたびに行われる.
%</ja>
%<*en>
\addcontentsline{toc}{section}{\refname}
\bibitem{texbytopic}
Victor Eijkhout, \emph{\TeX\ by Topic, A \TeX nician's Reference}, Addison-Wesley, 1992.
+\bibitem{listings} C.\ Heinz, B.\ Moses. The \textsf{Listings} Package.
+\bibitem{jlisting} Thor Watanabe. Listings\ -\ MyTeXpert.\newblock
+\url{http://mytexpert.sourceforge.jp/index.php?Listings}
\end{thebibliography}
\newpage
local ITALIC = 1
local PACKED = 2
local KINSOKU = 3
-local FROM_JFM = 4
-local LINE_END = 5
-local KANJI_SKIP = 6
-local XKANJI_SKIP = 7
-local PROCESSED = 8
-local IC_PROCESSED = 9
+local FROM_JFM = 6
+-- FROM_JFM: 4, 5, 6, 7, 8 →優先度高
+-- 6 が標準
+local KANJI_SKIP = 9
+local XKANJI_SKIP = 10
+local PROCESSED = 11
+local IC_PROCESSED = 12
local BOXBDD = 15
-local PROCESSED_BEGIN_FLAG = 16
+local PROCESSED_BEGIN_FLAG = 32
local kanji_skip
local xkanji_skip
-- p, q の走査で無視するもの:
-- ins, mark, adjust, whatsit, penalty
--
--- Nq.last .. + .. Bp.first .... Bp[last] .... * .. Np.first
--- +: kern from LINEEND はここに入る
+-- Nq.last .. Bp.first .... Bp[last] .... * .. Np.first
-- *: jfm glue はここに入る
local head -- the head of current list
-- We clear `predefined' entries of Np before pairs() loop,
-- because using only pairs() loop is slower.
Np.post, Np.pre, Np.xspc = nil, nil, nil
- Np.first, Np.id, Np.last, Np.lend, Np.met = nil, nil, nil, nil
+ Np.first, Np.id, Np.last, Np.met = nil, nil, nil
Np.auto_kspc, Np.auto_xspc, Np.char, Np.class, Np.nuc = nil, nil, nil, nil, nil
for k in pairs(Np) do Np[k] = nil end
local cls = ltjf_find_char_class(x.char, m)
if c ~= x.char and cls==0 then cls = ltjf_find_char_class(-c, m) end
Nx.class = cls; set_attr(x, attr_jchar_class, cls)
- Nx.lend = m.size_cache.char_type[cls].kern[fast_find_char_class('lineend', m)] or 0
Nx.met, Nx.var, Nx.char = m, m.var, c
Nx.pre = ltjs_fast_get_penalty_table('pre', c) or 0
Nx.post = ltjs_fast_get_penalty_table('post', c) or 0
-------------------- 最下層の処理
-local function lineend_fix(g)
- if g and g.id==id_kern then
- Nq.lend = 0
- elseif Nq.lend~=0 then
- if not g then
- g = node_new(id_kern); --copy_attr(g, Nq.nuc);
- g.subtype = 1; g.kern = -Nq.lend;
- set_attr(g, attr_icflag, LINEEND)
- else
- g.spec.width = g.spec.width - Nq.lend
- end
- end
- return g
-end
-
-- change penalties (or create a new penalty, if needed)
local function handle_penalty_normal(post, pre, g)
local a = (pre or 0) + (post or 0)
if #Bp == 0 then
- if (a~=0 and not(g and g.id==id_kern)) or Nq.lend~=0 then
+ if (a~=0 and not(g and g.id==id_kern)) then
local p = node_new(id_penalty); --copy_attr(p, Nq.nuc)
if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
p.penalty = a
local function handle_penalty_always(post, pre, g)
local a = (pre or 0) + (post or 0)
if #Bp == 0 then
- if not (g and g.id==id_glue) or Nq.lend~=0 then
+ if not (g and g.id==id_glue) then
local p = node_new(id_penalty); --copy_attr(p, Nq.nuc)
if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
p.penalty = a
-- Nq.last (kern w) .... (glue/kern g) Np.first
local function real_insert(w, g)
- if w~=0 then
- local h = node_new(id_kern); --copy_attr(h, Nq.nuc)
- set_attr(h, attr_icflag, LINE_END)
- h.kern = w; h.subtype = 1
- head = node.insert_after(head, Nq.last, h)
- end
if g then
head = insert_before(head, Np.first, g)
Np.first = g
-- (anything) .. jachar
local function handle_np_jachar(mode)
if Nq.id==id_jglyph or ((Nq.id==id_pbox or Nq.id==id_pbox_w) and Nq.met) then
- local g = lineend_fix(calc_ja_ja_glue() or get_kanjiskip()) -- M->K
- handle_penalty_normal(Nq.post, Np.pre, g); real_insert(Nq.lend, g)
+ local g = calc_ja_ja_glue() or get_kanjiskip() -- M->K
+ handle_penalty_normal(Nq.post, Np.pre, g); real_insert(0, g)
elseif Nq.met then -- Nq.id==id_hlist
local g = get_OA_skip() or get_kanjiskip() -- O_A->K
handle_penalty_normal(0, Np.pre, g); real_insert(0, g)
local function handle_nq_jachar()
if Np.pre then
if Np.id==id_hlist then Np.pre = 0 end
- local g = lineend_fix(get_OB_skip() or get_xkanjiskip(Nq)) -- O_B->X
- handle_penalty_normal(Nq.post, Np.pre, g); real_insert(Nq.lend, g)
+ local g = get_OB_skip() or get_xkanjiskip(Nq) -- O_B->X
+ handle_penalty_normal(Nq.post, Np.pre, g); real_insert(0, g)
else
- local g = lineend_fix(get_OB_skip()) -- O_B
+ local g = get_OB_skip() -- O_B
if Np.id==id_glue then handle_penalty_normal(Nq.post, 0, g)
elseif Np.id==id_kern then handle_penalty_suppress(Nq.post, 0, g)
else handle_penalty_always(Nq.post, 0, g)
end
- real_insert(Nq.lend, g)
+ real_insert(0, g)
end
end
-- (anything) .. (和文文字で始まる hlist)
local function handle_np_ja_hlist()
if Nq.id==id_jglyph or ((Nq.id==id_pbox or Nq.id == id_pbox_w) and Nq.met) then
- local g = lineend_fix(get_OB_skip() or get_kanjiskip()) -- O_B->K
- handle_penalty_normal(Nq.post, 0, g); real_insert(Nq.lend, g)
+ local g = get_OB_skip() or get_kanjiskip() -- O_B->K
+ handle_penalty_normal(Nq.post, 0, g); real_insert(0, g)
elseif Nq.met then -- Nq.id==id_hlist
local g = get_kanjiskip() -- K
handle_penalty_suppress(0, 0, g); real_insert(0, g)
local function handle_list_tail(mode)
adjust_nq(); Np = Nq
if mode then
- -- the current list is to be line-breaked:
- if Np.id == id_jglyph or (Np.id==id_pbox and Np.met) then
- if Np.lend~=0 then
- g = node_new(id_kern); g.subtype = 0; g.kern = Np.lend
- --copy_attr(g, Np.nuc);
- set_attr(g, attr_icflag, BOXBDD)
- node.insert_after(head, Np.last, g)
- end
- end
+ -- the current list is to be line-breaked.
-- Insert \jcharwidowpenalty
- Bp = widow_Bp; Np = widow_Np; Nq.lend = 0
+ Bp = widow_Bp; Np = widow_Np
if Np.first then
handle_penalty_normal(0,
ltjs_fast_get_penalty_table('jwp', 0) or 0)
and get_xkanjiskip_jfm or get_xkanjiskip_normal
Np = {
auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
- first=nil, id=nil, last=nil, lend=0, met=nil, nuc=nil,
+ first=nil, id=nil, last=nil, met=nil, nuc=nil,
post=nil, pre=nil, xspc=nil,
}
Nq = {
auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
- first=nil, id=nil, last=nil, lend=0, met=nil, nuc=nil,
+ first=nil, id=nil, last=nil, met=nil, nuc=nil,
post=nil, pre=nil, xspc=nil,
}
if mode then