summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty
blob: 0dacf32bf8d327c473fd8c78f7f3b9a52ea89638 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
%
% luatexja-ruby.sty
%

% LaTeX only!
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{luatexja-ruby}[2020-12-25 v0.51]
\RequirePackage{luatexja}

%%------------------
\newattribute\ltj@rubyattr
\ltj@rubyattr=0
\RequireLuaTeXjaSubmodule{ruby}

% ltjset/getparameter への追加設定
% これらは段落単位の設定.

%% 引数:ルビ全角を単位とした実数
%% この文字への pre-, post-intrusion の許容量
\define@key[ltj]{japaram}{rubypreintrusion}{%
  \ltj@@set@stack@real{RIPRE}{-0x7FFFFFFF}{0x7FFFFFFF}#1 }
\define@key[ltj]{japaram}{rubypostintrusion}{%
  \ltj@@set@stack@real{RIPOST}{-0x7FFFFFFF}{0x7FFFFFFF}#1 }
\def\ltj@@set@stack@real#1#2#3{%
  \directlua{luatexja.stack.set_stack_perchar(luatexja.stack_table_index.#1,
    #2, #3, token.scan_word)}}

% ルビ用のキー設定
\def\ltj@@rkeydef#1{
  \define@key[ltj]{ruby}{#1}{\expandafter\def\csname ltj@@rubyip@#1\endcsname{##1}}
}
%% attr_ruby_mode
%% bit 0: intrusion を有効にするか(1: 有効)
%% bit 1: 前後の intrusion 許容量を小さい方に揃える (1: yes)
%% bit 2, 3: intrusion をどう使って親文字を配置するか
%%   00: intrusion なしでとりあえず計算し,左右の突出分を進入に割り当てる
%%   01: pre-intrusion でまかなえるだけまかない,無理なら post- も使う
%%   10: post を優先
%%   11: 2 min (pre,post) までは pre, post に均等配分しようとする
%%     >=01 で,intrusion で賄えきれなかった場合はいつものように伸長する.
%% bit 4: 熟語ルビの際の処理方法(0: 常にグループ,1: 可能な限りブロックごとに)
%%        ↑bit 4 は今は無効
\ltj@@rkeydef{mode}
%% intrusion 量強制固定(bit 0, bit 1 より優先,負数で「自動」)
%% attr は sp 単位だが,ユーザーはルビ全角単位で指定する
%% attr_ruby_maxprep, attr_ruby_maxpostp
\ltj@@rkeydef{pre}
\ltj@@rkeydef{post}
%% 親文字伸長の際の比,{0}{1}{1} などと0--7 の数 3 つで指定
%% attr_ruby_stretch (bol left,middle,right)(eol)(middle) 27-bits 
\ltj@@rkeydef{stretchbol} % 行頭形
\ltj@@rkeydef{stretcheol}  % 行末形
\ltj@@rkeydef{stretch}     % 行中形
%% ルビが伸長するときの比 {1}{2}{1} などと0--7 の数 3 つで指定
%% attr_ruby_mode 上位部分
\ltj@@rkeydef{stretchruby}
%% ルビ<親のとき,ルビと親文字の端の最大値 
%% attr_ruby_maxmargin
%% attr は sp 単位だが,ユーザーは親文字全角単位で指定
\ltj@@rkeydef{maxmargin}
%% ルビと親文字の垂直方向の空き
%% attr_ruby_intergap
%% attr は sp 単位だが,ユーザーは親文字全角単位で指定
\ltj@@rkeydef{intergap}

%% epsilon: モノルビ * n にする際に,ルビの方がどれだけ親文字より長い
%% 状況を許容するか.親文字全角単位.計算誤差を想定.
\ltj@@rkeydef{epsilon}

\ltj@@rkeydef{kenten}%% 圏点文字
\ltj@@rkeydef{fontcmd}%% フォント
\define@boolkey[ltj]{ruby}{rubysmash}[true]{}

\ltj@@rkeydef{ybaseheight} % 縦組以外 (yoko, utod, dtou)
\ltj@@rkeydef{tbaseheight} % 縦組
\define@key[ltj]{ruby}{baseheight}{%
  \expandafter\def\csname ltj@@rubyip@ybaseheight\endcsname{#1}%
  \expandafter\def\csname ltj@@rubyip@tbaseheight\endcsname{#1}%
}
%% これらの値が正のとき,親文字の高さをこの値(\zh 単位)とみなす
\define@boolkey[ltj]{ruby}{intrude_jfmgk}[true]{}
\define@boolkey[ltj]{ruby}{intrude_xkanjiskip}[true]{}
\define@boolkey[ltj]{ruby}{intrude_kanjiskip}[true]{}


%%%%%%%% setkeys の別名
\protected\def\ltjsetruby{\setkeys[ltj]{ruby}}

% ここからは ruby マクロ内でなんとかされる事項
%% ルビと親文字の大きさの比
\ltj@@rkeydef{size}

% 中つき用簡易設定.
\define@key[ltj]{ruby}{naka}[none]{\setkeys[ltj]{ruby}{mode=1, stretch=121, stretchruby=121}}
% 肩つき用簡易設定.
\define@key[ltj]{ruby}{kata}[none]{\setkeys[ltj]{ruby}{mode=9, stretch=121, stretchruby=001}}

%%%%%%%% 補助関数

% Lua ソースに渡す table 生成
\bgroup
\catcode`\_=11
\gdef\ltj@@ruby@create@table#1{% #1: ルビ全角
    \string{
      eps = \ltj@safe@dimen{\ltj@@rubyip@epsilon\zw},
      before_jfmgk = 0, after_jfmgk = 0,
      rubyzw = \ltj@safe@dimen{#1}, 
      maxmargin = \ltj@safe@dimen{\ltj@@rubyip@maxmargin\zw},
      pre = \ltj@safe@dimen{\ltj@@rubyip@pre#1},
      post = \ltj@safe@dimen{\ltj@@rubyip@post#1},
      intergap =  \ltj@safe@dimen{\ltj@@rubyip@intergap\zh},
      stretch 
        = 262144 * \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretchbol
	  + 512 * \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretcheol
	  + \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretch,
      mode 
        = (2097152 * \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretchruby
          + \ltj@safe@num{\ltj@@rubyip@mode}
          + 1048576 * \ifltj@ruby@rubysmash1\else0\fi),
      baseheight = \ltj@safe@dimen{\ifnum\ltjgetparameter{direction}=3
                     \ltj@@rubyip@tbaseheight\else\ltj@@rubyip@ybaseheight\fi\zh},
      intrude_jfmgk = \string{
       \ifltj@ruby@intrude_jfmgk [luatexja.icflag_table.FROM_JFM]=true,\fi
       \ifltj@ruby@intrude_kanjiskip
          [luatexja.icflag_table.KANJI_SKIP]=true,
          [luatexja.icflag_table.KANJI_SKIP_JFM]=true,
       \fi
       \ifltj@ruby@intrude_xkanjiskip
          [luatexja.icflag_table.XKANJI_SKIP]=true,
          [luatexja.icflag_table.XKANJI_SKIP_JFM]=true,
       \fi
       \string}
    \string}
}
\egroup
%%%
%%% 1098765432109876543210976543210
%%%   |st_ruby|!               |--| ← mode 
\def\ltj@@ruby@cts#1#2#3{%
  ((\ltj@safe@num{#1}) * 64 + (\ltj@safe@num{#2}) * 8 + \ltj@safe@num{#3})%
}


%%%%%%%% ZR さんの PXrubrica パッケージ中のコードから引用・改変
% \pxrr@decompbar: a|bc -> \ltj@@ruby@mark{a}\ltj@@ruby@mark{bc}
\let\pxrr@res\empty
\def\pxrr@ifx#1{%
  \ifx#1\expandafter\@firstoftwo
  \else\expandafter\@secondoftwo
  \fi
}
\def\pxrr@nil{\noexpand\pxrr@nil}
\def\pxrr@end{\noexpand\pxrr@end}
\def\pxrr@appto#1#2{%
  \expandafter\def\expandafter#1\expandafter{#1#2}%
}
\def\pxrr@decompbar#1{%
  \let\pxrr@res\@empty
  \pxrr@decompbar@loopa\pxrr@nil#1|\pxrr@end|%
}
\def\pxrr@decompbar@loopa#1|{%
  \expandafter\pxrr@decompbar@loopb\expandafter{\@gobble#1}%
}
\def\pxrr@decompbar@loopb#1{%
  \pxrr@decompbar@loopc#1\relax\pxrr@nil{#1}%
}
\def\pxrr@decompbar@loopc#1#2\pxrr@nil#3{%
  \pxrr@ifx{#1\pxrr@end}{}{%
    \ifx\pxrr@res\@empty
      \def\pxrr@res{\ltj@@ruby@mark}%
    \else
      \pxrr@appto\pxrr@res{\ltj@@ruby@mark}%
    \fi
    \pxrr@appto\pxrr@res{{#3}}%
    \pxrr@decompbar@loopa\pxrr@nil
  }%
}
%%%%%%%% ここまで

%%%%%%%% TeX command
\protected\def\ltjruby{\@ifnextchar[\ltj@@ruby{\ltj@@ruby[]}}%]
\AtBeginDocument{%
  \ifdefined\ruby\else\let\ruby=\ltjruby\fi
  \directlua{luatexja.ruby.read_old_break_info()}%
}
\def\ltj@@ruby[#1]#2#3{{% #1: option #2: 親文字群,#3: ルビ文字列群,共に| 区切り
  \setkeys[ltj]{ruby}{#1}%
  \directlua{luatexja.ruby.ruby_tmplist_r = \string{\string};
	luatexja.ruby.ruby_tmplist_p = \string{\string}}%
  \leavevmode\dimen0=\f@size pt\dimen1=\ltj@@rubyip@size\dimen0%
  % 引数展開,テーブルにセット
  \pxrr@decompbar{#2}{\let\ltj@@ruby@mark\ltj@@ruby@sp\pxrr@res}%
  \pxrr@decompbar{#3}{\let\ltj@@ruby@mark\ltj@@ruby@sr\pxrr@res}%
  {\fontsize{\ltj@@rubyip@size\dimen0}\z@\selectfont\ltj@@rubyip@fontcmd\global\dimen1=\zw}%
  \directlua{%
    luatexja.ruby.texiface(\ltj@@ruby@create@table{\dimen1},
    luatexja.ruby.ruby_tmplist_r, luatexja.ruby.ruby_tmplist_p)}%
}}

\def\ltj@@ruby@sr#1{%
  \setbox0=\hbox{\fontsize{\dimen1}\z@\ltj@@rubyip@fontcmd\selectfont#1}%
  \directlua{table.insert(luatexja.ruby.ruby_tmplist_r, luatexja.ruby.cpbox())}%
}
\def\ltj@@ruby@sp#1{%
  \setbox0=\hbox{\selectfont#1}%
  \directlua{table.insert(luatexja.ruby.ruby_tmplist_p, luatexja.ruby.cpbox())}%
}

\protected\def\ltjkenten{\@ifnextchar[\ltj@@kenten{\ltj@@kenten[]}}%]
\let\kenten=\ltjkenten
\def\ltj@@kenten[#1]#2{{%
  \setkeys[ltj]{ruby}{#1, stretchruby=101}%
  \@tfor\ltj@@kenten@temp:=#2\do{\ltj@@ruby[]{\ltj@@kenten@temp}{\ltj@@rubyip@kenten}}%
}}

% 初期値.要調整
%% ひらがな
\count@="3040\loop\relax\ifnum \count@<"30A0
  \ltjsetparameter{rubypreintrusion={\the\count@,1}, 
    rubypostintrusion={\the\count@,1}}
  \advance\count@1\repeat
%% カタカナ
\count@="30A0\loop\relax\ifnum \count@<"3100
  \ltjsetparameter{rubypreintrusion={\the\count@,1}, 
    rubypostintrusion={\the\count@,1}}
  \advance\count@1\repeat
%% Kana Supplement
\count@="1B000\loop\relax\ifnum \count@<"1B170
  \ltjsetparameter{rubypreintrusion={\the\count@,1}, 
    rubypostintrusion={\the\count@,1}}
  \advance\count@1\repeat
%% 開き括弧・閉じ括弧
\@for\@tmp:=`\‘,`\“,`\〈,`\《,`\「,`\『,`\【,`\〔,`\〖,`\〘,`\〝,`\(,`\[,`\{,`\⦅ \do
  {\ltjsetparameter{rubypreintrusion={\@tmp,-1}}}
\@for\@tmp:=`\’,`\”,`\〉,`\》,`\」,`\』,`\】,`\〕,`\〗,`\〙,`\〟,`\),`\],`\},`\⦆ \do
  {\ltjsetparameter{rubypostintrusion={\@tmp,-1}}}
%% 中点類
\@for\@tmp:=`\・,`\:,`\;,`\―,`\‥,`\…,`〳,`\〴,`\〵,"2014 \do
  {\ltjsetparameter{rubypreintrusion={\@tmp,0.5},rubypostintrusion={\@tmp,0.5}}}
%% 読点・句点
\@for\@tmp:=`\、,`\,,`\。,`\. \do
  {\ltjsetparameter{rubypostintrusion={\@tmp,-1}}}
%% 段落インデント部分
\ltjsetparameter{rubypreintrusion={-1,1}}

\setkeys[ltj]{ruby}{
  pre=-1, post=-1, mode=1, 
  stretchruby={1}{2}{1}, stretch = {1}{2}{1},
  stretchbol={0}{1}{1}, stretcheol={1}{1}{0},
  maxmargin=0.5, size=0.5, intergap=0, rubysmash=false,
  kenten=\textbullet, fontcmd=\relax, ybaseheight=0.88, tbaseheight=0.5,
  intrude_jfmgk, intrude_kanjiskip, intrude_xkanjiskip,
  epsilon=0.0001,
}

\endinput