% % ltj-base.sty % %! これは外から読まれない %% Avoid multiple loading. \csname luatexjabaseLoaded\endcsname \edef\ltj@base@AtEnd{% \endlinechar=\the\endlinechar \relax} \endlinechar=-1 % \def\luatexjabaseLoaded{\endinput} \ifltj@in@latex %<*LaTeX> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{ltj-base}[2017/05/05] \fi % %%------------------ Tiny helpers %% Registers %\newcount\ltj@tempcnta % defined at luatexja-core.sty \newcount\ltj@tempcntb \newcount\ltj@tempcntc \newdimen\ltj@tempdima % \newskip\ltj@tempskipa unused % \newtoks\ltj@temptoks unused \countdef\ltj@@count@zero=0 % \luatexattributedef\ltj@@attr@zero=0 % \dimendef\ltj@@dimen@zero=0 % \skipdef\ltj@@skip@zero=0 % %% Quarks %! ただ expl3 の quark とは異なり展開されるとエラーになる. %% \ltj@q@stop \protected\def\ltj@q@stop{\ltj@q@stop@} %% \ltj@q@nil \protected\def\ltj@q@nil{\ltj@q@nil@} %% \ltj@q@mark \protected\def\ltj@q@mark{\ltj@q@mark@} %! etoolbox の \letcs, \cslet, \csletcs. %% \ltj@letcs \protected\def\ltj@letcs#1#2{ \expandafter\let\expandafter#1\csname#2\endcsname } %% \ltj@cslet \protected\def\ltj@cslet#1#2{ \expandafter\let\csname#1\endcsname#2 } %% \ltj@csletcs \protected\def\ltj@csletcs#1#2{ \expandafter\let\csname#1\expandafter\endcsname \csname#2\endcsname } %% \ltj@ifx{}{}{} %! LaTeX 形式の \ifx. この形式の利点は自動的に条件ネストからの %! 脱出が可能であること. % Does \ifx test in LaTeX style. \long\def\ltj@ifx#1{ \ifx#1\expandafter\ltx@firstoftwo \else\expandafter\ltx@secondoftwo\fi } %% \ltj@if@empty{}{}{} %! が空であるか. % Checks if is empty. \long\def\ltj@if@empty#1{ \ltj@ifx{\ltj@@q@empty#1\ltj@@q@empty} } \protected\def\ltj@@q@empty{\ltj@@q@empty@} %% \ltj@if@blank{}{}{} %! が空または空白文字からなるか. % Checks if is either empty or consisting only of spaces. \def\ltj@if@blank#1{ \ltj@@if@blankA#1\ltj@@q@empty\ltj@@q@empty \ltx@secondoftwo\ltx@firstoftwo\ltj@q@nil } \long\def\ltj@@if@blankA#1#2\ltj@@q@empty#3#4#5\ltj@q@nil{ #4 } %%------------------ LaTeX vs plain \ifltj@in@latex %<*LaTeX> %% \ifltj@in@latex %! LaTeX であるか. %(Defined in luatexja-core.sty.) %% \ifltj@in@plain %! plain であるか. \ltj@csletcs{ifltj@in@plain}{iffalse} %% \ltj@require@package{}{} %! サブパッケージを読み込む. LaTeX では \RequirePackage、それ以外では %! \input を使う. は必須だが空でもよい. \def\ltj@require@package#1#2{ \RequirePackage{#1}[#2] } %% \ltj@print{} %! 端末への出力. \let\ltj@print\typeout \else %<*!LaTeX> %% \ifltj@in@plain \ifnum\pdf@strcmp{\fmtname}{plain}=0 % \ltj@csletcs{ifltj@in@plain}{iftrue} \else \ltj@csletcs{ifltj@in@plain}{iffalse} \fi %% \ltj@require@package{}{} \def\ltj@require@package#1#2{ \input #1.sty\relax } %% \ltj@print{} \def\ltj@print#1{ \immediate\write16{#1} } \fi % %%------------------ Value-token handling %% helper stuffs %% \ltj@gobble@num %! 次に続く整数を(2 回展開で)読み捨てる. \def\ltj@gobble@num{ \directlua{token.scan_int()} } %% \ltj@gobble@glue %! 次に続くグルー値を(2 回展開で)読み捨てる. \def\ltj@gobble@glue{ \directlua{token.scan_glue()} } %% \ltj@gobble@dimen %! 次に続く寸法値を(2 回展開で)読み捨てる. \def\ltj@gobble@dimen{ \directlua{token.scan_dimen()} } %% \ltj@grab@num %! 次に続く整数を読み取って, それと等しい整数を表すトークン列 %! (必ずしも整数表記とは限らない)を { } に入れたものに(2 回で) %! 展開する. %! ただし, 整数は以下の形式のいずれかでなければならない. %! - 整数表記(10 進, 8 進, 16 進, 文字) %! - chardef トークン %! - 内部整数パラメタ, countdef トークン %! (command_name が "assign_int" であるトークン). %! (注意: まだ文字表記(`A)に対応していません.) \def\ltj@grab@num{ \directlua{tex.sprint('{' .. token.scan_int() .. '}')} } %%------------------ Safe passing % These macros convert a token sequence denoting a TeX value to its % suitable notation in Lua, and when the argument is malformed then % 'nil' is returned. They are all fully-expandable. %! TeX の値を Lua 上の表記に変換する. 不正形式だと nil にする. \def\ltj@@safe@end{\noexpand\ltj@@safe@end} % behaves same as \relax but is distinct from it %% \ltj@safe@invalid % The value passed to lua instead of malformed value tokens. \def\ltj@safe@invalid{(nil)} %% \ltj@safe@num{} %! 整数. % For a number (integer). \def\ltj@safe@num{ \ltj@safe@num@or\ltj@safe@invalid } \def\ltj@safe@num@or#1#2{ \expandafter\expandafter\expandafter\ltj@@safe@numA \ltj@gobble@num#2\ltj@@safe@end{#2}{#1} } \def\ltj@@safe@numA#1\ltj@@safe@end#2#3{ \ltj@if@blank{#1}{ (\number#2) }{ #3 } } %% \ltj@safe@dimen{} %! 寸法値. % For a dimension. The result is a scaled-point value. \def\ltj@safe@dimen{ \ltj@safe@dimen@or\ltj@safe@invalid } \def\ltj@safe@dimen@or#1#2{ \expandafter\expandafter\expandafter\ltj@@safe@dimenA \ltj@gobble@dimen#2\ltj@@safe@end{#2}{#1} } \def\ltj@@safe@dimenA#1\ltj@@safe@end#2#3{ \ltj@if@blank{#1}{ (\number\dimexpr#2\relax) }{ #3 } } %% \ltj@safe@real{} %! 実数. これは十進表記に限る. % For a real number given in decimal notation or a macro that % expands to such notation. \def\ltj@safe@real#1{ (tonumber("\luatexluaescapestring{#1}")) } %% \ltj@val@counter{} %! LaTeX カウンタの現在値. % For the current value of a LaTeX counter. \def\ltj@val@counter#1{ (\expandafter\number\csname c@#1\endcsname) } %% \ltj@val@skip{} % For the current value of a skip (or LaTeX-length) parameter. %! グルーレジスタ(LaTeX 長さ変数). %! 整形式のグルー値にも使える. \def\ltj@val@skip#1{ (luatexja.base.to_skip("\the\glueexpr#1\relax")) } %! 整形式の整数 → 数値 : \number#1 %! 内部寸法 → 数値 : \number#1 %! 整形式の寸法 → 数値 : \number\dimexpr#1\relax %% \ltj@safe@str{} %! 文字列. (トークン列を非トークン化) % Converts a token sequence to Lua string notation. \def\ltj@safe@str#1{ "\luatexluaescapestring{\detokenize{#1}}" } %% \ltj@luaescape{} %! 非トークン化して Lua エスケープ. \def\ltj@luaescape#1{ \luatexluaescapestring{\detokenize{#1}} } %% \ltj@luaxescape{} %! 非トークン化せずに(展開ありで) Lua エスケープ. %! つまり単なる \luatexescape. \let\ltj@luaxescape\luatexluaescapestring %%------------------ Fully-expandable error messaging %! ixerrtrick パッケージから移植. %! 展開限定文脈でも使える \PackageError 等. %! Lua 関数版(luatexja/base.lua 参照)もある. %% \ltj@@error@message@a \begingroup \def~{ } \xdef\ltj@@error@message@a{% Type~~H ~~for immediate help% }% \endgroup %%<+> \ltj@MessageBreak % An analogue of \MessageBreak that is used in \ltj@GenericError, etc. % (\MessageBreak cannot be used there.) % NB: It is realized as a macro that expands to two instances % of the character of code 127. This marker is later detected % by the Lua process. \begingroup \lccode42=127 \lowercase{ \gdef\ltj@MessageBreak{**} \directlua{ luatexja.base._error_set_break("**") } } \endgroup %%<+> \ltj@GenericError{}{}{}{} % A variant of \GenericError that can be used in expansion-only % situation. The meanings of arguments are the same as the original % \GenericError. %%<+> \ltj@PlainError{}{} % A simpler error messenger available in expansion-only situations. % It behaves similarly to: % \errhelp{} \begingroup % with the same hack as in \GenericError... \lccode`\@=`\ % \lccode`\~=`\ % \lccode`\}=`\ % \lccode`\{=`\ % \catcode`\ =11\relax% \lowercase{% \endgroup% \def\ltj@GenericError#1#2#3#4{% not protected \directlua{% luatexja.base._error_set_message("\ltj@luaxescape{#1}",% "\ltj@luaxescape{#2.^^J^^J#3^^J\ltj@@error@message@a}",% "\ltj@luaxescape{#4}")% }% \ % use csname with four spaces as last expander } \def\ {% csname with four spaces \directlua{% luatexja.base._error_show(false)% and many spaces trail! % % }% }% \def\ltj@PlainError#1#2{% \directlua{% luatexja.base._error_set_message(" ",% "\ltj@luaxescape{#1}",% "\ltj@luaxescape{#2}")% }% \error % again a weird name is used } \def\error {% csname with two trailing spaces \directlua{% luatexja.base._error_show(true)% and many spaces trail! % % }% }% } %% \ltj@@error@on@line \def\ltj@@error@on@line{ on input line \the \inputlineno } %% \ltj@generic@warn@info \def\ltj@@generic@warn@info#1#2#3#4{ \begingroup \directlua{ luatexja.base._generic_warn_info("\ltj@luaxescape{#3}", "\ltj@luaxescape{#4}", (#1 > 0), (#2 > 0)) } \endgroup } %% \ltj@GenericWarning{}{} \def\ltj@GenericWarning{ \ltj@@generic@warn@info{1}{1} } %% \ltj@GenericWarningNoLine{}{} \def\ltj@GenericWarningNoLine{ \ltj@@generic@warn@info{1}{0} } %% \ltj@GenericInfo{}{} \def\ltj@GenericInfo{ \ltj@@generic@warn@info{0}{1} } %% \ltj@GenericInfoNoLine{}{} \def\ltj@GenericInfoNoLine{ \ltj@@generic@warn@info{0}{0} } %% \ltj@@space@seq@a \begingroup \def~{ } \xdef\ltj@@space@seq@a{~~~~~~~~~~~~~~~~} \xdef\ltj@@space@seq@b{~~~~~~~~~~~~~} \endgroup %% \ltj@PackageError{}{}{} \def\ltj@PackageError#1#2#3{% \ltj@GenericError{(#1)\ltj@@space@seq@a}% {Package #1 Error: #2}% {See the #1 package documentation for explanation.}% {#3}% } %% \ltj@PackageWarning{}{} \def\ltj@PackageWarning#1#2{% \ltj@GenericWarning{(#1)\ltj@@space@seq@a}% {Package #1 Warning: #2}% } %% \ltj@PackageWarningNoLine{}{} \def\ltj@PackageWarningNoLine#1#2{% \ltj@GenericWarningNoLine{(#1)\ltj@@space@seq@a}% {Package #1 Warning: #2}% } %% \ltj@PackageInfo{}{} \def\ltj@PackageInfo#1#2{% \ltj@GenericInfo{(#1)\ltj@@space@seq@b}% {Package #1 Info: #2}% } %% \ltj@PackageInfoNoLine{}{} \def\ltj@PackageInfoNoLine#1#2{% \ltj@GenericInfoNoLine{(#1)\ltj@@space@seq@b}% {Package #1 Info: #2}% } %%------------------ debug logging \ifdefined\LuaTeXjaDebugEnabled %% Load Lua module \RequireLuaModule{luatexja.debug} %% \ltj@debug{}{,...} \def\ltj@debug#1#2{ \directlua{ luatexja.base.debug(\ltj@safe@str{#1} \ltj@if@blank{#2}{}{, } #2) } } %% \ltj@package@debug{}{}{,...} \def\ltj@package@debug#1#2#3{ \directlua{ luatexja.base.package_debug(\ltj@safe@str{#1}, \ltj@safe@str{#2} \ltj@if@blank{#3}{}{, } #3) } } \else \def\ltj@debug#1#2{} \def\ltj@package@debug#1#2#3{} \fi %% \ltj@debug@logger\CS{} \def\ltj@debug@logger#1#2{ \def#1{\ltj@package@debug{#2}} } %% \ltj@afterbox %% -> \setbox\ltj@afbox %% from Sonja Maus, ``Looking Ahead for a '', %% TUGBoat, 11, No. 4, 1990. \newbox\ltj@afbox \protected\def\ltj@afterbox#1{% \def\ltj@afb@xarg{#1}% \afterassignment\ltj@afb@x \chardef\ltj@@next`.} \def\ltj@afb@x{\futurelet\ltj@@next\ltj@afb@xtest} \def\ltj@afb@xtest{% \ifcase\ifx\ltj@@next\hbox\tw@\fi \ifx\ltj@@next\vbox\tw@\fi \ifx\ltj@@next\vtop\tw@\fi \ifx\ltj@@next\box\@ne\fi \ifx\ltj@@next\copy\@ne\fi \ifx\ltj@@next\vsplit\@ne\fi \ifx\ltj@@next\lastbox\@ne\fi 0% ``A was ...'' error will be causes by \setbox later anyway. \or\afterassignment\ltj@afb@xarg \or\afterassignment\ltj@afb@xagarg \fi \setbox\ltj@afbox } \def\ltj@afb@xagarg{\aftergroup\ltj@afb@xarg} %%------------------ all done \ltj@base@AtEnd \endinput %% EOF