3

I want to place Zhuyin next to enlarged characters in a line of text. I abstracted it down to this (with X representing a Chinese character and A/AB/ABC the Zhuyin:

enter image description here

\documentclass{article}
\usepackage{tabularx}
\usepackage{graphicx}

\begin{document}
\renewcommand{\arraystretch}{0.5}

lorem ipsum \raisebox{-2mm}{\Huge X}
\hspace{-2mm}\scalebox{0.8}{
    \begin{tabularx}{1em}{@{}l@{}}
        \textit{A}\\ \textit{B}\\ \textit{C}
    \end{tabularx}}
dolor sit \raisebox{-2mm}{\Huge X}
\hspace{-2mm}\scalebox{0.8}{
    \begin{tabularx}{1em}{@{}l@{}}
        \textit{A}\\
    \end{tabularx}}
amet \raisebox{-2mm}{\Huge X}
\hspace{-2mm}\scalebox{0.8}{
    \begin{tabularx}{1em}{@{}l@{}}
        \textit{A}\\ \textit{B}
    \end{tabularx}}

\end{document}

What I'd like to achieve is replacing this:

\hspace{-2mm}\scalebox{0.8}{
    \begin{tabularx}{1em}{@{}l@{}}
        \textit{A}\\ \textit{B}\\ \textit{C}
    \end{tabularx}}

by this:

\zhuyin{ABC}

It is important to notice that the Zhuyin will always be 1, 2 or 3 characters long and I would love to have one single command that can deal with \zhuyin{A} and \zhuyin{AB} as well instead of 3 separate commands depending on whether it's 1, 2 or 3 characters in length.

It basically comes down to "how do I separate a 1-to-3-char argument into {1st char} or {1st char}\\{2nd char} or {1st char}\\{2nd char}\\{3rd char} depending on the length of the argument".

Treating it as three (or two or one) separate arguments won't work since afaik LaTeX commmands can't be overloaded like functions in many programming languages.

Thanks for your ideas in advance! I really appreciate this community!

3
  • 1
    Would a syntax with three arguments of which two are optional be acceptable? Like \zhuyin{A} lipsum \zhuyin{A}{B}{C} lipsum \zhuyin{A}{B} etc?
    – Marijn
    Feb 7, 2021 at 10:50
  • Yes, it would! I had just assumed it would be impossible to have optional arguments in \newcommands. Feb 7, 2021 at 10:55
  • 1
    For LaTeX2e (i.e., \newcommand) you can have at most 1 optional argument, and it needs to be the first. LaTeX3 (\NewDocumentCommand) is more flexible and allows for multiple optional arguments at any position.
    – Marijn
    Feb 7, 2021 at 10:59

3 Answers 3

4

Something like this?

enter image description here

If the symbols in the column vector to the right of the \Huge character are too small for your taste, feel free to replace \tiny with \scriptsize.

\documentclass{article}
\usepackage{array}
\newcommand\zhuyin[2]{\begingroup % localize scope of next instruction
                      \renewcommand{\arraystretch}{0.55}%
                      \begin{tabular}{@{}>{\Huge}l@{}} #1 \end{tabular}%
                      \begin{tabular}{@{}>{\tiny\itshape}l@{}} #2 \end{tabular}%
                      \endgroup}

\begin{document}
lorem ipsum \zhuyin{X}{A \\ B \\ C} dolor sit \zhuyin{X}{A} amet \zhuyin{X}{A \\ B}
\end{document}
1
  • 1
    Looks good, thanks a lot! I actually just found another way myself, I'll post another answer for future learners. Feb 7, 2021 at 11:21
2

You could attempt to activate the OpenType vertical-writing features, but fontspec does not actually support vertical writing. It does allow you to select the OpenType vrt2 feature, which in theory might provide rotated glyphs, and place them in a \rotatebox.

However, the following code did not work correctly when I tested:

\documentclass{article}
\tracinglostchars=2
\usepackage[nil]{babel}
\usepackage{unicode-math}
\usepackage{graphicx}

\babelprovide[import=zh-hans, main]{chinese} % Or import=zh-hant for Traditional Chinese

\defaultfontfeatures{ Scale=MatchUppercase,
                      Ligatures=TeX,
                      Renderer=HarfBuzz }

\defaultfontfeatures[NotoSerifCJKsc]{
  Ligatures={Common,Discretionary},
  UprightFont = *-Regular ,
  BoldFont = *-Bold ,
  Extension = .otf}

\babelfont{rm}
          [Scale=1.0]{Latin Modern Roman}
\babelfont[chinese]{rm}
          {NotoSerifCJKsc}
\setmathfont{NewCMMath-Book}

\newcommand{\zhuyin}[1]{%
  \rotatebox[origin=c]{-90}{%
    \foreignlanguage{chinese}{%
      \addfontfeature{Vertical={RotatedGlyphs,HalfMetrics,Kerning}}%
      #1}}}

\begin{document}
瓶\zhuyin{ㄆㄧㄥ}子\zhuyin{ㄗ}
\end{document}

Specifically, although Noto Serif CJK supports the vertical-layout OpenType features, the zhuyin appeared and were rotated in their original forms, and so came out in the wrong orientation. If you know of a font that provides rotated Unicode bopomofo, you might try this solution with that font.

1

Turns out I just found the xstring package which made it pretty easy so in addition to Mico's answer, I could also solve it myself:

\documentclass{article}
\usepackage{tabularx}
\usepackage{graphicx}
\usepackage{xstring}

\renewcommand{\arraystretch}{0.5}

\newcommand{\zhuyin}[1]{%
  \StrLen{#1}[\length]%
  \hspace{-0.8mm}\scalebox{0.8}{
  \begin{tabularx}{1em}{@{}>{\itshape}l@{}}
    \ifnum\length=1
      \StrChar{#1}{1}
    \else
      \ifnum\length=2
        \StrChar{#1}{1}\\
        \StrChar{#1}{2}
      \else
        \StrChar{#1}{1}\\
        \StrChar{#1}{2}\\
        \StrChar{#1}{3}
      \fi
    \fi
  \end{tabularx}}
}

\begin{document}

lorem ipsum \raisebox{-2mm}{\Huge X}\zhuyin{ABC}
dolor sit \raisebox{-2mm}{\Huge X}\zhuyin{A}
amet \raisebox{-2mm}{\Huge X}\zhuyin{AB}

\end{document}

EDIT:

@Mico: Totally correct, tabular totally suffices, no need for tabularx. I also added another optional argument for the tone mark. This is the result:

\documentclass{article}
\usepackage{fontspec} % for Kaiti and Ming (Song)
\usepackage{graphicx} % for scalebox
\usepackage{xstring} % for string slicing in \zhuyin command

\newfontfamily\kaitiTW{TW-Kai-98_1.ttf}

\newcommand{\trad}[1]{{\kaitiTW \large #1}}

\newcommand{\zhuyin}[2][]{%
\smash{
  \StrLen{#2}[\length]%
  \hspace{-3mm}
  \parbox[c][][c]{3mm}{%
  \scalebox{0.45}{%
    \renewcommand{\arraystretch}{0.8}
    \begin{tabular}{@{}>{\kaitiTW}l@{}}
      \ifnum\length=1
        \StrChar{#2}{1}%
      \else
        \ifnum\length=2
          \StrChar{#2}{1}\\
          \StrChar{#2}{2}%
        \else
          \StrChar{#2}{1}\\
          \StrChar{#2}{2}\\
          \StrChar{#2}{3}%
        \fi
      \fi
    \hspace{-0.7em} \smash{\raisebox{0.7em}{\scalebox{0.6}{\kaitiTW #1}}}
  \end{tabular}}}}
  \hspace{-2mm}
}

\begin{document}

\trad{黑}\zhuyin{ㄏㄟ}\textit{hēi},
\trad{狂}\zhuyin[ˊ]{ㄎㄨㄤ}\textit{kuáng},
\trad{短}\zhuyin[ˇ]{ㄉㄨㄢ}\textit{duǎn},
\trad{鬱}\zhuyin[ˋ]{ㄩ}\textit{yǜ}

\end{document}

Obviously has to be compiled with XeLaTeX. Font used can be found here.

output

1
  • 1
    I don't think it's appropriate to use a tabularx environment for the use case at hand, especially as (a) there is no need for automatic line breaking in the cells, (b) you're not employing a single X-type column in the tabularx environment, and (c) the target width of 1em seems excessive. I think a simple tabular environment with an l column type would be more appropriate.
    – Mico
    Feb 7, 2021 at 12:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .