3

My system OS is MacOS I use Xelatex

The MWE is

\documentclass[12pt]{article}
\usepackage{fontspec,xunicode}
\defaultfontfeatures{Mapping=tex-text}
\XeTeXlinebreaklocale "zh"
\XeTeXlinebreakskip = 0pt plus 1pt minus 0.1pt
\newcommand\fontnamekai{STKaiti}

\setmainfont{\fontnamekai}
\setsansfont[BoldFont=\fontnamekai]{\fontnamekai}
\setmonofont{\fontnamekai}
\begin{document}

国学

\end{document}

The output is enter image description here

And I want it becomes to enter image description here

Some solutions such as example are provided. But they used \newcommand. As a result, I had to apply this command to each word, which contains thousands of words.

Maybe an environment is needed or just edit text showing way that when a text is shown it will be shown with square box automatically. Thank you very much.

1 Answer 1

3

You can create a command that parses every character of a string, and create an environment that applies that command to the contents of the environment.

The \scan code here (a bit of recursive black magic) is adapted from answers by @wipet on this site. You just create a new command with one argument and the \let\scando\yourcommand to apply that command to each character in the string passed to \scan{}.

I've simplified the MWE a bit and used a font that comes with the TeXLive distribution. The \strut inside the \fbox keeps the boxes all the same height.

\documentclass[12pt]{article}                                                                                                                                                                                                                 
\usepackage{fontspec}                                                                                                                                                                                                                         
\setmainfont{FandolKai}                                                                                                                                                                                                                       

\def\scando{}                                                                                                                                                                                                                                 
\def\scan#1{\scanA#1\end}                                                                                                                                                                                                                     
\def\scanA#1{\ifx\end#1\else\scando#1\expandafter\scanA\fi}                                                                                                                                                                                   

\newcommand{\boxed}[1]{\fbox{\strut#1}}                                                                                                                                                                                                       
\let\scando\boxed                                                                                                                                                                                                                             

\usepackage{environ}                                                                                                                                                                                                                          
\NewEnviron{boxedchars}{\expandafter\expandafter\scan\BODY}                                                                                                                                                                                   

\begin{document}                                                                                                                                                                                                                              

\scan{AB}                                                                                                                                                                                                                                     
\scan{国学}                                                                                                                                                                                                                                   

\begin{boxedchars}                                                                                                                                                                                                                            
    国学                                                                                                                                                                                                                                      
    国学                                                                                                                                                                                                                                      
    国学                                                                                                                                                                                                                                      
    国学                                                                                                                                                                                                                                      
\end{boxedchars}                                                                                                                                                                                                                              

\end{document}       

enter image description here

EDIT

OP would reasonably like the command to work across multiple paragraphs and allow for line breaks. This is done by adding \long to the definitions of \scan and \scanA so they will read past \par tokens created at paragraph breaks. Second, we have to add a conditional test to the \boxed code that checks for the \par; in this case I set it up so that it leaves \par in place. I also added a regular space after the \fbox command, which will allow TeX to break the line in between boxes.

\documentclass[12pt]{article}                                                                                         
\usepackage{fontspec}                                                                                                 
\setmainfont{FandolKai}                                                                                               

\def\scando{}                                                                                                         
\long\def\scan#1{\scanA#1\end}                                                                                        
\long\def\scanA#1{\ifx\end#1\else\scando#1\expandafter\scanA\fi}                                                      

\newcommand{\boxed}[1]{\ifx\par#1#1\else\fbox{\strut#1} \fi}                                                          
\let\scando\boxed                                                                                                     

\usepackage{environ}                                                                                                  
\NewEnviron{boxedchars}{\expandafter\expandafter\scan\BODY}                                                           

\usepackage{parskip} % just to make paragraph divisions more visible for example                                      
\begin{document}                                                                                                      

\scan{AB}                                                                                                             
\scan{国学}                                                                                                           

\begin{boxedchars}                                                                                                    
    国学 国学 国学 国学                                                                                               

    国学 国学 国学 国学                                                                                               
    国学 国学 国学 国学                                                                                               

    国学 国学 国学 国学                                                                                               
    国学 国学 国学 国学                                                                                               

    国学 国学 国学 国学                                                                                               
    国学 国学 国学 国学                                                                                               
    国学 国学 国学 国学                                                                                               
\end{boxedchars}                                                                                                      

\end{document}   

enter image description here

2
  • Thank you very much. I run it. This code works. But it gets error with blank lines. Also, it can't wrap the words. For example, if you have 100 words, it will only show one line.
    – yuxuan
    May 3, 2017 at 16:31
  • Please see the edit! May 3, 2017 at 16:47

You must log in to answer this question.

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