Displaying pinyin over Chinese characters, without impacting word spacing

Now I add another answer using LI Qing's xpinyin package.

It's rather easy to use:

\documentclass{ctexart}

\usepackage{xpinyin}

\begin{document}
\Huge\sffamily

\begin{pinyinscope}
床前明月光,疑是地上霜。举头望明月,低头思故乡。
\end{pinyinscope}

\xpinyin*{床前明月光,疑是地上霜。举头望明月,低头思故乡。}

\end{document}

enter image description here


I think the ruby package (from the CJK package bundle) would be useful here:

\documentclass[a5paper]{article}
\usepackage{ctexcap}

\usepackage{ruby}
% Sets size of the `ruby' i.e. pinyin annotation; default is 0.4
\renewcommand\rubysize{0.3}

\setCJKmainfont{Adobe Heiti Std}
\setmainfont{Arial}
\begin{document}
    \Huge \noindent 床前明月光,疑是地上霜。举头望明月,低头思故乡。 \\    
\noindent\ruby{床}{chuáng}\ruby{前}{qián}\ruby{明}{míng}\ruby{月}{yuè}\ruby{光}{guāng},\ruby{疑}{yí}\ruby{是}{shì}\ruby{地}{dì}\ruby{上}{shàng}\ruby{霜}{shuāng}。
\ruby{举}{jǔ}\ruby{头}{tóu}\ruby{望}{wàng}\ruby{明}{míng}\ruby{月}{yuè},\ruby{低}{dī}\ruby{头}{tóu}\ruby{思}{sī}\ruby{故}{gù}\ruby{乡}{xiāng}。
\end{document}

Output:

Pinyin annotation as rubies


As LianTze Lim pointed out, ruby package in CJK bundle is specially designed for Japanese ruby characters and Chinese pinyin (拼音) or zhuyin (注音). However, it has some restrictions.

You can add \CJKglue at the end of the definition of \ruby, not only for proper spacing between Chinese characters, but also for correct line breaking. For example,

\documentclass{ctexart}

\usepackage{ruby}
\let\oldruby\ruby
\def\ruby#1#2{\oldruby{#1}{#2}\CJKglue}
\renewcommand\rubysize{0.3}

\begin{document}
\parindent=0pt
\Huge\sffamily

床前明月光,疑是地上霜。举头望明月,低头思故乡。 

\ruby{床}{chuáng}\ruby{前}{qián}\ruby{明}{míng}\ruby{月}{yuè}\ruby{光}{guāng},%
\ruby{疑}{yí}\ruby{是}{shì}\ruby{地}{dì}\ruby{上}{shàng}\ruby{霜}{shuāng}。%
\ruby{举}{jǔ}\ruby{头}{tóu}\ruby{望}{wàng}\ruby{明}{míng}\ruby{月}{yuè},%
\ruby{低}{dī}\ruby{头}{tóu}\ruby{思}{sī}\ruby{故}{gù}\ruby{乡}{xiāng}。
\end{document}

enter image description here

However, the result is still wrong sometimes: line break is allowed before punctuations now. And of course we have no puncutation spacing turning features then.

Although it is rather difficult to deal with all possible situations right now, we can do more if we use some TeX tricks (like \futurelet) and maybe hack into xeCJK. At least we can prevent linebreaking before punctuations:

\documentclass{ctexart}

\usepackage{ruby}
\renewcommand\rubysize{0.3}
\let\oldruby\ruby
\def\ruby#1#2{\oldruby{#1}{#2}\futurelet\next\addCJKglue}
\def\addCJKglue{\ifx\next\ruby \CJKglue \fi}

\begin{document}

\Huge\sffamily

床前明月光,疑是地上霜。

\ruby{床}{chuáng}\ruby{前}{qián}\ruby{明}{míng}\ruby{月}{yuè}\ruby{光}{guāng},%
\ruby{疑}{yí}\ruby{是}{shì}\ruby{地}{dì}\ruby{上}{shàng}\ruby{霜}{shuāng}。%

% Compare with old solution:
\def\ruby#1#2{\oldruby{#1}{#2}\CJKglue}
\ruby{床}{chuáng}\ruby{前}{qián}\ruby{明}{míng}\ruby{月}{yuè}\ruby{光}{guāng},%
\ruby{疑}{yí}\ruby{是}{shì}\ruby{地}{dì}\ruby{上}{shàng}\ruby{霜}{shuāng}。%

\end{document}

enter image description here