宏改进

宏改进

我希望简化和改进以下代码:

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{test.txt}
a an and the this by on of
\end{filecontents}

\begin{document}
\makeatletter

\in@false
\def\upfirst#1#2\upfirst{%
   \in@{#1#2}{a and of that this}%
   \ifin@{\LARGE#1#2}\else {\Huge\MakeUppercase#1}{\LARGE#2 }\fi
}

\def\smallcaps#1\upfirst{\textsc{#1} }

\def\boldfirst#1#2\upfirst{\textbf{\uppercase{#1}}#2 }

\def\everytoken#1#2{%
\def\everytoken@##1{%
   \@tempcntb=0
   \@tfor \i :=##1  \do{\expandafter#2\i\upfirst   
  }}
\everytoken@{#1}%
}

\everytoken {{the} {battle} {and} {the} {resistance} {of} {france}}{\upfirst}

\everytoken {{Life} {death} {and} {the} {Universe}}{\smallcaps}

\everytoken {{The} {battle} {and} {the} {Resistance} }{\boldfirst}

\makeatother
\end{document}

代码的作用是设置标题的样式,将首字母大写(如果该单词不在保留单词中),或者将标题设置为小写或粗体并将首字母大写。

在此处输入图片描述

我正在寻找界面上的改进(目前标题词必须用括号括起来)以及输入带有保留字的文件的方法,而不仅仅是直接输入它们。(请参阅周围的代码in@

答案1

当然还有一个 LaTeX3 版本等待。:)

\begin{filecontents*}{\jobname.dat}
that this
the
\end{filecontents*}
\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\everytoken}{O{}mm}
 {
  \group_begin:
  #1 % #1 are global formatting instructions
  \yiannis_everytoken:Nn #2 { #3 }
  \group_end:
 }

\seq_new:N \l__yiannis_words_seq
\seq_new:N \l__yiannis_final_seq
\seq_new:N \g_yiannis_reserved_words_seq
\tl_new:N \l__yiannis_first_word_tl
\cs_generate_variant:Nn \seq_put_left:Nn { Nf }

\cs_new_protected:Npn \yiannis_everytoken:Nn #1 #2
 {
  \seq_set_split:Nnn \l__yiannis_words_seq { ~ } { #2 }
  \seq_pop_left:NN \l__yiannis_words_seq \l__yiannis_first_word_tl
  \seq_clear:N \l__yiannis_final_seq
  \seq_map_inline:Nn \l__yiannis_words_seq
   {
    \yiannis_if_reserved:nTF { ##1 } 
      { \seq_put_right:Nn \l__yiannis_final_seq { ##1 } }
      { \seq_put_right:Nn \l__yiannis_final_seq { #1 { ##1 } } }
   }
  \seq_put_left:Nf \l__yiannis_final_seq { \exp_args:NNV \exp_not:N #1 \l__yiannis_first_word_tl }
  \seq_use:Nnnn \l__yiannis_final_seq { ~ } { ~ } { ~ }
 }

\prg_new_conditional:Npnn \yiannis_if_reserved:n #1 { TF }
 {
  \seq_if_in:NnTF \g_yiannis_reserved_words_seq { #1 }
   { \prg_return_true: }
   { \prg_return_false: }
 }

%%% Simple version
\NewDocumentCommand{\Hugeupfirst}{m}
 {
  \tl_to_uppercase:n { { \Huge \tl_head:n { #1 } } }
  \tl_tail:n { #1 }
 }

%%% Complex but more robust version (uncomment the following four lines)
%\RenewDocumentCommand{\Hugeupfirst}{m}
% {
%  \yiannis_Hugeupfirst:n { #1 }
% }
\cs_new_protected:Npn \yiannis_hugeupfirst:n #1
 {
  \tl_set:Nn \l__yiannis_temp_tl { #1 }
  \regex_replace_once:nnN
   { \A (.*? [A-Za-z]) }
   { \c{tl_to_uppercase:n} \cB\{ \cB\{ \c{Huge} \1 \cE\} \cE\} }
   \l__yiannis_temp_tl
  \tl_use:N \l__yiannis_temp_tl
 }
%%% end of more complex version

%%% Simple version
\NewDocumentCommand{\upfirst}{m}
 {
  \tl_to_uppercase:n { \tl_head:n { #1 } }
  \tl_tail:n { #1 }
 }

%%% Complex but more robust version (uncomment the following four lines)
%\RenewDocumentCommand{\upfirst}{m}
% {
%  \yiannis_upfirst:n { #1 }
% }
\cs_new_protected:Npn \yiannis_upfirst:n #1
 {
  \tl_set:Nn \l__yiannis_temp_tl { #1 }
  \regex_replace_once:nnN
   { \A (.*? [A-Za-z]) }
   { \c{tl_to_uppercase:n} \cB\{ \1 \cE\} }
   \l__yiannis_temp_tl
  \tl_use:N \l__yiannis_temp_tl
 }
%%% end of more complex version

\NewDocumentCommand{\setreservedwords}{m}
 {
  \clist_map_inline:nn { #1 }
   { \seq_gput_right:Nn \g_yiannis_reserved_words_seq { ##1 } }
 }

\ior_new:N \l_yiannis_input_ior
\NewDocumentCommand{\readreservedwords}{m}
 {
  \yiannis_read_reserved_words:n { #1 }
 }
\cs_new_protected:Npn \yiannis_read_reserved_words:n #1
 {
  \ior_open:Nn \l_yiannis_input_ior { #1 }
  \tl_clear:N \l_tempa_tl
  \ior_map_inline:Nn \l_yiannis_input_ior
   {
    \tl_put_right:Nn \l_tempa_tl { ##1 ~ }
   }
  \seq_set_split:NnV \l_tempa_seq { ~ } \l_tempa_tl
  \seq_gconcat:NNN \g_yiannis_reserved_words_seq \l_tempa_seq \g_yiannis_reserved_words_seq
  \seq_gremove_all:Nn \g_yiannis_reserved_words_seq { }
 }

\ExplSyntaxOff

\setreservedwords{a, and, of}
\readreservedwords{\jobname.dat}

\begin{document}

\everytoken{\Hugeupfirst}{The battle and the resistance of France}

\everytoken[\scshape]{\Hugeupfirst}{the battle and the resistance of france}

\everytoken[\scshape]{\upfirst}{the battle and the resistance of france}

\everytoken{\upfirst}{the battle and the resistance of france}

\end{document}

有两种方法可以添加保留字列表:要么使用逗号分隔列表作为参数,\setreservedwords要么使用文件作为参数,其中分隔符是空格或行尾\readreservedwords。您可以按任何顺序使用它们,并且每个命令都会添加到最初为空的列表中。

语法\everytoken

\everytoken[<global formatting>]{<first letter>}{<words>}

在哪里

  • <global formatting>是一组应用于所有字母的格式指令(例如,\bfseries\scshape
  • <first letter>是要应用于非保留字的第一个字母和第一个单词的宏
  • <words>是单词列表

我给出了“简单”版(无重音字符)和“复杂”版的示例\Hugeupfirst\upfirst使用“复杂”版,您可以管理\'equipe de secours简单版无法管理的内容。

在此处输入图片描述

答案2

这将从文件中读取单词,修复 in@ 测试中缺失的空格,并避免需要对每个单词进行括号。

输出并不像您显示的那样,因为文件中的单词列表版本包含the

在此处输入图片描述

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{test.txt}
a an and the this by on of
\end{filecontents*}

\begin{document}
\makeatletter

\newread\testtxt
\immediate\openin\testtxt test.txt

\immediate\read\testtxt to \foo 



\def\upfirst#1#2 {%
   \edef\tmp{\noexpand\in@{#1#2}{\foo}}\tmp%
   \ifin@{\LARGE#1#2 }\else {\Huge\MakeUppercase#1}{\LARGE#2 }\fi
}

\def\smallcaps#1 {\textsc{#1} }

\def\boldfirst#1#2 {\textbf{\uppercase{#1}}#2 }



\def\everytoken#1#2{\xeverytoken#2#1 \relax}

\def\xeverytoken#1#2 #3{%
#1#2
\ifx\relax#3%
\else
\expandafter\xeverytoken\expandafter#1%
\fi
#3}



\everytoken {the battle and the resistance of france}{\upfirst}

\everytoken {Life death and the Universe}{\smallcaps}

\everytoken {The battle and the Resistance}{\boldfirst}

\makeatother
\end{document}

要强制始终处理第一个单词,请稍微更改一些宏

\def\upfirst#1#2 {%
   \edef\tmp{\noexpand\in@{#1#2}{\foox}}\tmp%
   \ifin@{\LARGE#1#2 }\else {\Huge\MakeUppercase#1}{\LARGE#2 }\fi
}

\def\everytoken#1#2{%
\let\foox\@empty
\xeverytoken#2#1 \relax}

\def\xeverytoken#1#2 #3{%
#1#2
\let\foox\foo
\ifx\relax#3%
\else
\expandafter\xeverytoken\expandafter#1%
\fi
#3}

相关内容