7

First of all, make sure you have installed Kanji Stroke Order font before trying to compile the following MWE. The font can be downloaded here (click).

I want to create a note about my study in Japanese language. In the enumerate environment I will make a list of sentences in both Japanese and English. The Chinese characters will be rendered twice, i.e., first in the Japanese sentences and second in the table. The desired output of my code is as follows.

enter image description here

Minimal Working Example

\documentclass[dvipsnames]{article}
\usepackage[a5paper,hmargin=1cm,vmargin=15mm]{geometry}

\usepackage{xeCJK}
\setmainfont{Cambria}
\setCJKmainfont{ipaexm.ttf} % For furigana and other Japanese characters
\newCJKfontfamily\strokefont{KanjiStrokeOrders_v3.001.ttf} % For stroke order

\usepackage{ruby}
\usepackage[many]{tcolorbox}

\def\GlobalSettings{%
    \renewcommand\rubysep{0pt}%
    \renewcommand\rubysize{0.4}%
    \let\oldruby\ruby%
    \renewcommand\ruby[2]{\oldruby{##1}{\textcolor{Red}{##2}}}%
}

\AtBeginDocument{\GlobalSettings}


\def\LocalSettings{%
    \renewcommand\rubysep{1ex}%
    \renewcommand\rubysize{.3}%
    \renewcommand\ruby[2]{\oldruby{\fontsize{65}{0}\selectfont\strokefont##1}{\fontsize{15}{0}\selectfont\textcolor{Red}{##2}}}%
}


\def\FlashCard[#1]#2{\begin{tcolorbox}\LocalSettings{\fontsize{15}{0}\selectfont#1\par}\vspace{15pt}\textcolor{Cyan}{\bfseries#2}\end{tcolorbox}}

\newcommand\DeclareWord[4][]{%
    \expandafter\newcommand\csname #2#1\endcsname{#3}%
    \expandafter\gdef\csname #2#1FC\endcsname{\FlashCard[#3]{#4}}%
}


\newenvironment{Table}
{\begin{tcbraster}[%
        raster height=\textwidth,
        raster width=\linewidth,
        raster columns=2,
        raster rows=3,
        size=fbox,
        sharp corners,
        halign=flush center,
        valign=center,
        boxrule=2pt,    % line width
        raster column skip=-2pt,    % negative line width
        raster row skip=-2pt,   % negative line width
        colframe=Red,
        colback=White,
]}
{\end{tcbraster}}




\begin{document}

\begin{enumerate}
    \item \DeclareWord{kare}{\ruby{彼}{かれ}}{he}%
                \DeclareWord{samui}{\ruby{寒}{さむ}い}{cold}%
                \kare は\samui です。\\
                \textcolor{red}{He is cold.}
                \Table
                    \kareFC
                    \samuiFC
                \endTable
    \item \DeclareWord{jikan}{\ruby{時}{じ}\ruby{間}{かん}}{time}%
                \DeclareWord{kichou}{\ruby{貴}{き}\ruby{重}{ちょう}}{precious}%
                \DeclareWord{kenmei}{\ruby{賢}{けん}\ruby{明}{めい}}{wise}%
                \DeclareWord{tsukau}{\ruby{使}{つか}う}{to use (N1)}%
                \jikan は\kichou なので、\kenmei にそれを\ruby{使}{つか}います。\\
                \textcolor{red}{As time is precious, use it wisely.}
                \Table
                    \jikanFC
                    \kichouFC
                    \kenmeiFC
                    \tsukauFC
                \endTable
\end{enumerate}
\end{document}

Problems

To make the input file as simple as possible, I think I don't need to write

..............

                \Table
                    \kareFC
                    \samuiFC
                \endTable

..............

                \Table
                    \jikanFC
                    \kichouFC
                    \kenmeiFC
                    \tsukauFC
                \endTable

..............

I mean that creating the table should be done automatically. How to do this?

1 Answers1

6

I was unable to get the font working, but I have an approach that might work:

For each of the words that are defined, an additional numbered command is defined as one would do for an "array" which, when executed, calls the associated flash card command. Once all of the desired words are defined, a command is called which establishes the environment and loops through the defined commands, calling each of the flash cards. At the end, the counter is reset, preparing the "array" for the next set of words. This infrastructure is handled with the following (\begin{figure}[h] was used in place of \Table to alleviate font issues):

\usepackage{etoolbox}
% Array for words
\makeatletter
    \newcounter{jwordcount}%
    \newcommand\setjword[2]{\csdef{jword#1}{#2}}%
    \newcommand\addjword[1]{\stepcounter{jwordcount}\setjword{\thejwordcount}{#1}}%
    \newcommand\getjword[1]{\csuse{jword#1}}%

    %%% Basic Loop
    %Taken from the aloop pof David Salomon's The Advanced TeXbook pg 191
    %Use:
    %\newcount\temp
    %\loop\temp=1 step 1 until 10 do {something} \endloop\temp
    \def\loop#1=#2 {%
        \long\def\next step ##1 until ##2 do ##3 \endloop#1{%
            ##3%
            \advance#1 by ##1
            \ifnum#1>##2\relax\else\next step ##1 until ##2 do ##3 \endloop#1 \fi%
            }%end of \next
        #1=#2 \next}%end of \loop

    %Return the table containing the current words, reset the counter
    \newcommand\currentwordtable{%
        \begin{figure}[h]%Replace with \Table
            \newcount\temp\loop\temp=1 step 1 until {\thejwordcount} do {\expandafter\getjword{\@arabic\temp}\ifnum\temp<\thejwordcount\else\fi} \endloop\temp%
            \setcounter{jwordcount}{0}%reset for the next group of words
        \end{figure}}%replace with \endTable
\makeatother

In addition to changing the environment above, this would be incorporated into your workflow by inserting \addjword into your \DeclareWord command, specifically:

\newcommand\DeclareWord[4][]{%
    \expandafter\newcommand\csname #2#1\endcsname{#3}%
    \expandafter\gdef\csname #2#1FC\endcsname{\FlashCard[#3]{#4}}%
    \expandafter\addjword{\csname #2#1FC\endcsname}%
}

Finally, to use it you would replace your \Table ... \endTable block with \currentwordtable{}.

Edit: It's all greek to me

Here is the result with greek letters substituted and \ruby calls omitted:

\documentclass[dvipsnames]{article}
\usepackage[a5paper,hmargin=1cm,vmargin=15mm]{geometry}

\usepackage{xeCJK}
\setmainfont{Cambria}
\setCJKmainfont{ipaexm.ttf} % For furigana and other Japanese characters
\newCJKfontfamily\strokefont{KanjiStrokeOrders_v3.001.ttf} % For stroke order

\usepackage{ruby}
\usepackage[many]{tcolorbox}

\def\GlobalSettings{%
    \renewcommand\rubysep{0pt}%
    \renewcommand\rubysize{0.4}%
    \let\oldruby\ruby%
    \renewcommand\ruby[2]{\oldruby{##1}{\textcolor{Red}{##2}}}%
}

\AtBeginDocument{\GlobalSettings}


\def\LocalSettings{%
    \renewcommand\rubysep{1ex}%
    \renewcommand\rubysize{.3}%
    \renewcommand\ruby[2]{\oldruby{\fontsize{65}{0}\selectfont\strokefont##1}{\fontsize{15}{0}\selectfont\textcolor{Red}{##2}}}%
}


\def\FlashCard[#1]#2{\begin{tcolorbox}\LocalSettings{\fontsize{15}{0}\selectfont#1\par}\vspace{15pt}\textcolor{Cyan}{\bfseries#2}\end{tcolorbox}}

\newcommand\DeclareWord[4][]{%
    \expandafter\newcommand\csname #2#1\endcsname{#3}%
    \expandafter\gdef\csname #2#1FC\endcsname{\FlashCard[#3]{#4}}%
    \expandafter\addjword{\csname #2#1FC\endcsname}%
}


\newenvironment{Table}
{\begin{tcbraster}[%
        raster height=\textwidth,
        raster width=\linewidth,
        raster columns=2,
        raster rows=3,
        size=fbox,
        sharp corners,
        halign=flush center,
        valign=center,
        boxrule=2pt,    % line width
        raster column skip=-2pt,    % negative line width
        raster row skip=-2pt,   % negative line width
        colframe=Red,
        colback=White,
]}
{\end{tcbraster}}


\usepackage{etoolbox}
% Array for words
\makeatletter
    \newcounter{jwordcount}%
    \newcommand\setjword[2]{\csdef{jword#1}{#2}}%
    \newcommand\addjword[1]{\stepcounter{jwordcount}\setjword{\thejwordcount}{#1}}%
    \newcommand\getjword[1]{\csuse{jword#1}}%

    %%% Basic Loop
    %Taken from the aloop pof David Salomon's The Advanced TeXbook pg 191
    %Use:
    %\newcount\temp
    %\loop\temp=1 step 1 until 10 do {something} \endloop\temp
    \def\loop#1=#2 {%
        \long\def\next step ##1 until ##2 do ##3 \endloop#1{%
            ##3%
            \advance#1 by ##1
            \ifnum#1>##2\relax\else\next step ##1 until ##2 do ##3 \endloop#1 \fi%
            }%end of \next
        #1=#2 \next}%end of \loop

    %Return the table containing the current words, reset the counter
    \newcommand\currentwordtable{%
        \Table
            \newcount\temp\loop\temp=1 step 1 until {\thejwordcount} do {\expandafter\getjword{\@arabic\temp}\ifnum\temp<\thejwordcount\else\fi} \endloop\temp%
            \setcounter{jwordcount}{0}%reset for the next group of words
        \endTable}
\makeatother






\begin{document}

\begin{enumerate}
    \item \DeclareWord{kare}{$\alpha$}{he}%
                \DeclareWord{samui}{$\beta$}{cold}%
                \kare $\alpha$\samui $\beta$\\
                \textcolor{red}{He is cold.}
                \currentwordtable
%                \Table
%                    \kareFC
%                    \samuiFC
%                \endTable
    \item \DeclareWord{jikan}{$\gamma$}{time}%
                \DeclareWord{kichou}{$\delta$}{precious}%
                \DeclareWord{kenmei}{$\epsilon$}{wise}%
                \DeclareWord{tsukau}{$\zeta$}{to use (N1)}%
                \jikan $gamma$\kichou $\delta$ \kenmei $\epsilon$ $\zeta$\\
                \textcolor{red}{As time is precious, use it wisely.}
                \currentwordtable
%                \Table
%                    \jikanFC
%                    \kichouFC
%                    \kenmeiFC
%                    \tsukauFC
%                \endTable
\end{enumerate}
\end{document}

Yields:

greek

Guho
  • 6,115
  • If it is possible, please make the call of \currentwordtable automatically done at the end of each \item. Could you make it possible? Thank you. – kiss my armpit Oct 18 '15 at 07:24
  • @kissmyarmpit: You would have to modify your approach a bit. Adding \let\old@item=\item \def\item#1{\old@item{#1 \currentwordtable}} to the preamble will automatically call \currentwordtable as the last command in the content of the \item. This will only work if you enclose the contents of the \item in braces (e.g., for the first \item: \item{ \DeclareWord{kare}{$\alpha$}{he}% and \textcolor{red}{He is cold.}}. – Guho Oct 18 '15 at 07:52