沿一定距离分布字母

沿一定距离分布字母

我知道\makebox[*length*][s]{t e x t},但我必须在每个字符之间留空格。如果我的文本很长,那就感觉不舒服了。

我见过这个答案经过埃格尔并且它几乎按照我想要的方式工作。我想将长度指定为第一个参数,并使用 xparse 将文本(不单独分隔每个字母)作为第二个参数传递。

\spread{20em}{distribute this text}
\spread{5em}{word}

但不幸的是,我无法修改代码以使其按我想要的方式工作。你能帮我吗?

答案1

首先是一个简单的解决方案,即在字母之间留一个空格,在单词之间留两个空格:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\spreadtext}{mm}
 {
  \tl_set:Nx \l_tmpa_tl { #2 }
  \tl_replace_all:Nnn \l_tmpa_tl { ~ } { {} }
  \makebox[#1][s]
   {
    \skip_set:Nn \spaceskip { 0pt plus 1fill }
    \tl_map_inline:Nn \l_tmpa_tl { ##1 ~ } \unskip
   }
 }
\ExplSyntaxOff

\begin{document}

\spreadtext{20em}{distribute this text}

\spreadtext{5em}{word}

\end{document}

在此处输入图片描述

稍有不同,单词之间有更多空格。

您可以先按空格拆分输入,然后按字母拆分每个单词。最后,排版所有内容,在字母之间插入空格,在单词之间插入更大的空格。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\spreadtext}{mm}
 {
  \antshar_spread_text:nn { #1 } { #2 }
 }

\seq_new:N \l__antshar_spread_in_seq
\seq_new:N \l__antshar_spread_out_seq
\seq_new:N \l__antshar_spread_word_seq

\cs_new_protected:Nn \antshar_spread_text:nn
 {
  \seq_set_split:Nnn \l__antshar_spread_in_seq { ~ } { #2 }
  \seq_set_map:NNn \l__antshar_spread_out_seq \l__antshar_spread_in_seq { \antshar_spread_word:n { ##1 } }
  \makebox[#1][s]
   {
    \seq_use:Nn \l__antshar_spread_out_seq { \hspace{1em plus 0.5em minus 0.3em} }
   }
 }
\cs_new_protected:Nn \antshar_spread_word:n
 {
  \seq_set_split:Nnn \l__antshar_spread_word_seq { } { #1 }
  \seq_use:Nn \l__antshar_spread_word_seq { ~ }
 }
\ExplSyntaxOff

\begin{document}

\spreadtext{20em}{distribute this text}

\spreadtext{5em}{word}

\end{document}

在此处输入图片描述

该版本还应对参数中的命令。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\spreadtext}{mm}
 {
  \antshar_spreadtext:nn { #1 } { #2 }
 }

\tl_new:N \l_antshar_spreadtext_tl

\cs_new_protected:Nn \__antshar_spreadtext_space:
 {
  \hspace{1em~plus~0.5em~minus~0.3em}
 }

\cs_new_protected:Nn \antshar_spreadtext:nn
 {
  \tl_set:Nn \l_antshar_spreadtext_tl { #2 }
  \regex_replace_all:nnN { \s } { \c{__antshar_spreadtext_space:} } \l_antshar_spreadtext_tl
  \regex_replace_all:nnN { (\w) } { \1 \  } \l_antshar_spreadtext_tl
  \regex_replace_all:nnN { \s(\c{.*}) } { \1  } \l_antshar_spreadtext_tl
  \tl_use:N \l_antshar_spreadtext_tl
 }
\ExplSyntaxOff

\begin{document}

\spreadtext{20em}{distribute \emph{this} text}

\spreadtext{5em}{word}

\end{document}

在此处输入图片描述

没有包,但不允许命令:

\documentclass{article}

\makeatletter
\newcommand{\spreadtext}[2]{%
  \makebox[#1][s]{\spread@text#2\spread@text}%
}
\def\spread@text{\futurelet\next\spread@@text}
\def\spread@@text{%
  \ifx\next\spread@text
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\unskip\@gobble}%
  {\spread@@@text}%
}
\def\spread@@@text{%
  \ifx\next\@sptoken
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\spread@space}%
  {\spread@char}%
}
\def\spread@space#1{%
  \hspace{1em plus 0.5em minus 0.3em}%
  \spread@text#1%
}
\def\spread@char#1{#1 \spread@text}
\makeatother

\begin{document}

\spreadtext{20em}{distribute this text}

\spreadtext{5em}{word}

\end{document}

答案2

使用tokcycle,我提供了两种形式。第一种,指定字符间距。这在包示例文档中提供。在第二种方法中,使用 OP 首选的语法,用户指定字符串的整体宽度。请注意,目标参数可以包含 完全遵循的格式化宏\spread

\spread相对于的缺点\spaceouttext是前者不会换行,而后者会。

\documentclass{article}
\usepackage{tokcycle}
\newcommand\spaceouttext[2]{%
  \tokcycle{\addcytoks{##1\nobreak\hspace{#1}}}%
  {\processtoks{##1}}{\addcytoks{##1}}%
  {\addcytoks{##1\hspace{#1}}}{#2}%
  \the\cytoks\unskip}
\newcommand\spread[2]{%
  \tokcycle
  {\addcytoks{##1\hfill}}
  {\processtoks{##1}}
  {\addcytoks{##1}}
  {\addcytoks{##1\hfill}}{#2}%
  \makebox[#1]{\the\cytoks\unskip}%
}
\begin{document}
\spaceouttext{3pt plus 3pt}{This \textit{text \textbf{is} very} spaced
out}. Back to regular text.

\spaceouttext{1.5pt}{This \textit{text \textbf{is} somewhat} spaced
out}. Back to regular text.

\fbox{\spread{20em}{distribute \textit{this} text}}

\fbox{\spread{5em}{word}}
\end{document}

在此处输入图片描述

相关内容