%D \module %D [ file=t-ruby, %D version=2012.12.01, %D title=\CONTEXT\ User Module, %D subtitle=Ruby Markup, %D author=Wolfgang Schuster, %D date=\currentdate, %D copyright=Wolfgang Schuster, %D email=schuster.wolfgang@googlemail.com, %D license=Public Domain] \writestatus{loading}{ConTeXt User Module / Ruby Markup} \unprotect %D simple ruby: %D %D \starttyping %D %D WWW %D World Wide Web %D %D \stoptyping %D %D complex ruby: %D %D \starttyping %D %D %D 10 %D 31 %D 2002 %D %D %D Month %D Day %D Year %D %D %D Expiration Date %D %D %D \stoptyping %D Constants/variables \startinterface all \setinterfaceconstant {basestyle} {basestyle} \setinterfaceconstant {basecolor} {basecolor} \setinterfaceconstant {rubybase} {rubybase} \setinterfaceconstant {rubytext} {rubytext} \stopinterface \startinterface all \setinterfacevariable {letter} {letter} \stopinterface %D Lua \startluacode thirddata = thirddata or { } thirddata.ruby = thirddata.ruby or { } function thirddata.ruby.doifelsecjk(string) local state = true for c in unicode.utf8.gmatch(string,".") do local n = scripts.hash[utf.byte(c)] if not ( n == "chinese" or n == "korean" ) then state = false break end end commands.doifelse(state) end \stopluacode %D Namespace \installnamespace {ruby} \installnamespace {rubyalign} \installnamespace {rubyalternative} \installnamespace {rubyhang} %D Additional registers \newdimen \d_ruby_width \newdimen \d_ruby_left \newdimen \d_ruby_right \newdimen \d_ruby_position \newsignal \s_ruby_signal \newcount \c_ruby_n \newtoks \t_ruby_base \newtoks \t_ruby_text \newbox \b_ruby_base \newbox \b_ruby_text \newbox \b_ruby_box %D \macros %D {defineruby,setupruby} \installcommandhandler \????ruby {ruby} \????ruby %D \macros %D {ruby} \unexpanded\def\ruby {\dontleavehmode \begingroup \let\currentruby\empty \dosingleempty\ruby_direct_indeed} \unexpanded\def\ruby_direct#name% {\dontleavehmode \begingroup \edef\currentruby{#name}% \dosingleempty\ruby_direct_indeed} \def\ruby_direct_indeed[#parameters]#rubybase#rubytext% {\setupcurrentruby[#parameters,\c!rubybase={#rubybase},\c!rubytext={#rubytext}]% % \scratchdimen\lastskip \ifdim\scratchdimen=\s_ruby_signal\else\global\d_ruby_width\zeropoint\fi % \global\advance\c_ruby_n\plusone % \xypos{rubyposition:\number\c_ruby_n}% \doifmodeelse\v!first {\d_ruby_position\onepoint} {\d_ruby_position\dimexpr\MPx{rubyposition:\number\c_ruby_n}-\MPx{text:\number\realpageno}\relax}% % \setbox\b_ruby_base\hbox{\userubystyleandcolor\c!basestyle\c!basecolor\directrubyparameter\c!rubybase}% \setbox\b_ruby_text\hbox{\userubystyleandcolor\c!textstyle\c!textcolor\directrubyparameter\c!rubytext}% % \edef\p_ruby_align {\rubyparameter\c!align }% \edef\p_ruby_alternative{\rubyparameter\c!alternative}% \edef\p_ruby_hang {\rubyparameter\c!hang }% % \ruby_align \ruby_alternative \ruby_hang % \hskip\s_ruby_signal\relax \endgroup} \appendtoks \setuevalue\currentruby{\ruby_direct{\currentruby}}% \to \everydefineruby %D Alignment %D %D \startitemize[packed] %D \item left %D \item middle %D \item right %D \item auto %D \item letter %D \item space %D \stopitemize \unexpanded\def\ruby_distribute_space #1{\processtokens{\hss }{\hss\hss}{\hss }{\hss\hss}{#1}} \unexpanded\def\ruby_distribute_letter#1{\processtokens{\relax}{\hss }{\relax}{\hss\hss}{#1}} \def\ruby_align_stretch {\d_ruby_left \zeropoint \d_ruby_right\zeropoint \ifdim\wd\b_ruby_base>\wd\b_ruby_text \setbox\b_ruby_base\hbox to \wd\b_ruby_base{\hss\box\b_ruby_base\hss}% \setbox\b_ruby_text\hbox to \wd\b_ruby_base{\userubystyleandcolor\c!textstyle\c!textcolor\normalexpanded{\ruby_distribute_space{\directrubyparameter\c!rubytext}}}% \else \setbox\b_ruby_base\hbox to \wd\b_ruby_text{\userubystyleandcolor\c!basestyle\c!basecolor\normalexpanded{\ruby_distribute_space{\directrubyparameter\c!rubybase}}}% \setbox\b_ruby_text\hbox to \wd\b_ruby_text{\hss\box\b_ruby_text\hss}% \fi} \def\ruby_align_letter {\d_ruby_left \zeropoint \d_ruby_right\zeropoint \ifdim\wd\b_ruby_base>\wd\b_ruby_test \setbox\b_ruby_base\hbox to \wd\b_ruby_base{\hss\box\b_ruby_base\hss}% \setbox\b_ruby_text\hbox to \wd\b_ruby_base{\userubystyleandcolor\c!textstyle\c!textcolor\normalexpanded{\ruby_distribute_letter{\directrubyparameter\c!rubytext}}}% \else \setbox\b_ruby_base\hbox to \wd\b_ruby_text{\userubystyleandcolor\c!basestyle\c!basecolor\normalexpanded{\ruby_distribute_letter{\directrubyparameter\c!rubybase}}}% \setbox\b_ruby_text\hbox to \wd\b_ruby_text{\hss\box\b_ruby_text\hss}% \fi} \def\ruby_align_auto {\ifdim\wd\b_ruby_base>\wd\b_ruby_text \ctxlua{thirddata.ruby.doifelsecjk("\directrubyparameter\c!rubybase")}\donetrue\donefalse \ifdone \ruby_align_stretch \else \ruby_align_middle \fi \else \ifdim\d_ruby_position=\zeropoint % begin of the line \ruby_align_left \else\ifdim\d_ruby_position=\dimexpr\textwidth-\wd\b_ruby_base\relax % end of the line \ruby_align_right \else \ctxlua{thirddata.ruby.doifelsecjk("\directrubyparameter\c!rubytext")}\donetrue\donefalse \ifdone \ruby_align_stretch \else \ruby_align_middle \fi \fi\fi \fi} \def\ruby_align_left {\ifdim\wd\b_ruby_base>\wd\b_ruby_text \d_ruby_left \zeropoint \d_ruby_right\zeropoint \else \d_ruby_left \zeropoint \d_ruby_right\dimexpr\wd\b_ruby_text-\wd\b_ruby_base\relax \fi \setbox\b_ruby_base\hbox to \wd\b_ruby_base{\box\b_ruby_base\hss}% \setbox\b_ruby_text\hbox to \wd\b_ruby_base{\box\b_ruby_text\hss}} \def\ruby_align_middle {\ifdim\wd\b_ruby_base>\wd\b_ruby_text \d_ruby_left \zeropoint \d_ruby_right\zeropoint \else \d_ruby_left \dimexpr(\wd\b_ruby_text-\wd\b_ruby_base)/2\relax \d_ruby_right\dimexpr(\wd\b_ruby_text-\wd\b_ruby_base)/2\relax \fi \setbox\b_ruby_base\hbox to \wd\b_ruby_base{\hss\box\b_ruby_base\hss}% \setbox\b_ruby_text\hbox to \wd\b_ruby_base{\hss\box\b_ruby_text\hss}} \def\ruby_align_right {\ifdim\wd\b_ruby_base>\wd\b_ruby_base \d_ruby_left \zeropoint \d_ruby_right\zeropoint \else \d_ruby_left \dimexpr\wd\b_ruby_text-\wd\b_ruby_base\relax \d_ruby_right\zeropoint \fi \setbox\b_ruby_base\hbox to \wd\b_ruby_base{\hss\box\b_ruby_base}% \setbox\b_ruby_text\hbox to \wd\b_ruby_base{\hss\box\b_ruby_text}} \def\ruby_align_margin {\ifdim\d_ruby_position=\zeropoint \ruby_align_left \else\ifdim\d_ruby_position=\dimexpr\textwidth-\wd\b_ruby_base\relax \ruby_align_right \else \ruby_align_middle \fi\fi} \def\ruby_align {\csname\????rubyalign \ifcsname\????rubyalign\p_ruby_align\endcsname\p_ruby_align\else\v!auto\fi \endcsname} \setvalue{\????rubyalign\v!auto }{\ruby_align_auto } \setvalue{\????rubyalign\v!left }{\ruby_align_left } \setvalue{\????rubyalign\v!right }{\ruby_align_right } \setvalue{\????rubyalign\v!middle }{\ruby_align_middle } \setvalue{\????rubyalign\v!letter }{\ruby_align_letter } \setvalue{\????rubyalign\v!stretch}{\ruby_align_stretch} \setvalue{\????rubyalign\v!margin }{\ruby_align_margin } %D Alternative %D %D \startitemize[packed] %D \item top %D \item bottom %D \item text %D \stopitemize % \setvalue{\????rubyalternative\v!none}% needed for \pdfactualtext % {\directrubyparameter\c!rubybase % \rubyparameter\c!separator % \rubyparameter\c!lefttext % \directrubyparameter\c!rubytext % \rubyparameter\c!righttext} \def\ruby_alternative_top {\setbox\b_ruby_box\vbox {\doifsomething{\rubyparameter\c!strut}{\setupstrut[\rubyparameter\c!strut]}% \offinterlineskip \hbox{\undepthed{\begstrut\box\b_ruby_text\endstrut}} \rubyparameter\c!inbetween \hbox{\begstrut\box\b_ruby_base\endstrut}}} \def\ruby_alternative_bottom {\setbox\b_ruby_box\vtop {\doifsomething{\rubyparameter\c!strut}{\setupstrut[\rubyparameter\c!strut]}% \offinterlineskip \hbox{\undepthed{\begstrut\box\b_ruby_base\endstrut}} \rubyparameter\c!inbetween \hbox{\begstrut\box\b_ruby_text\endstrut}}} \def\ruby_alternative_text {\setbox\b_ruby_box\box\voidbox \d_ruby_left \zeropoint \d_ruby_right\zeropoint \directrubyparameter\c!rubybase \rubyparameter\c!separator \rubyparameter\c!lefttext\directrubyparameter\c!rubytext\rubyparameter\c!righttext} \unexpanded\def\ruby_alternative_vertical_process#text% {\setbox\scratchbox\vbox {\userubystyleandcolor\c!textstyle\c!textcolor \setupinterlinespace[\rubyparameter\c!interlinespace]% \handletokens#text\with\hbox \par}% \lower\dimexpr(\ht\scratchbox+\strutdp-\strutht)/2-\rubyparameter\c!dy\relax\box\scratchbox} \def\ruby_alternative_vertical {\d_ruby_left \zeropoint \d_ruby_right\zeropoint \setbox\b_ruby_box\hbox\bgroup \begingroup \userubystyleandcolor\c!basestyle\c!basecolor \directrubyparameter\c!rubybase \endgroup \normalexpanded{\ruby_alternative_vertical_process{\directrubyparameter\c!rubytext}}% \egroup} \def\ruby_alternative {\csname\????rubyalternative \ifcsname\????rubyalternative\p_ruby_alternative\endcsname\p_ruby_alternative\else\v!text\fi \endcsname} \setvalue{\????rubyalternative\v!top }{\ruby_alternative_top } \setvalue{\????rubyalternative\v!bottom}{\ruby_alternative_bottom} \setvalue{\????rubyalternative\v!text }{\ruby_alternative_text } %D Overhang %D %D \startitemize[packed] %D \item left %D \item right %D \item auto %D \item none %D \stopitemize \def\ruby_hang_auto {\ifdim\d_ruby_width>\zeropoint \kern\dimexpr\d_ruby_left+\d_ruby_width\relax \fi \box\b_ruby_box \global\d_ruby_width\d_ruby_right} \def\ruby_hang_left {\box\b_ruby_box\kern\d_ruby_right \global\d_ruby_width\d_ruby_right} \def\ruby_hang_right {\ifdim\d_ruby_width>\zeropoint \kern\dimexpr\d_ruby_left+\d_ruby_width\relax \else \kern\d_ruby_left \fi \box\b_ruby_box \global\d_ruby_width\zeropoint} \def\ruby_hang_none {\kern\d_ruby_left\box\b_ruby_box\kern\d_ruby_right \global\d_ruby_width\zeropoint} \def\ruby_hang {\csname\????rubyhang \ifcsname\????rubyhang\p_ruby_hang\endcsname\p_ruby_hang\else\v!auto\fi \endcsname} \setvalue{\????rubyhang\v!auto }{\ruby_hang_auto } \setvalue{\????rubyhang\v!left }{\ruby_hang_left } \setvalue{\????rubyhang\v!right}{\ruby_hang_right} \setvalue{\????rubyhang\v!none }{\ruby_hang_none } %D Default values \setupruby [\c!alternative=\v!top, \c!align=\v!auto, \c!hang=\v!auto, \c!dy=\zeropoint, \c!separator={ }, \c!lefttext={(}, \c!righttext={)}, \c!strut=\v!no, \c!inbetween={\blank[\v!small]}, \c!textstyle=\txx] \protect \endinput