使用 mfirstuc 和 catcode 12 个字符

使用 mfirstuc 和 catcode 12 个字符

我正在尝试让我的文档读取自己的文件名(已知是连字符分隔的单词和数字)并对其进行解析。对于某个连字符后的所有内容,我想用空格替换连字符,然后将每个“重要”单词大写(“重要”定义为未出现在列表中的单词mfirstuc-english)。我的代码除了最后一步外都正确执行 - 所有单词都大写,无论它们是否重要。几个小时的搜索表明差异一定在于命令如何ecapitalisewords扩展宏,但目前我无法解决此问题。任何帮助都将不胜感激。

这是我在 MWE 中的最佳尝试,其中我使用的文件名是test-the-document-that-reads-the-filename.tex

\documentclass{article}
\usepackage{mfirstuc-english}

\makeatletter
\newcommand{\hyphentospace}[1]{\@hyphentospace[#1-]}
\def\@hyphentospace[#1-#2]{#1%
  \if\relax\detokenize{#2}\relax
  \else%
    \space \@hyphentospace[#2]%
  \fi%
}
\makeatother

\makeatletter
    \newcommand{\filenameparse}[1]{\expandafter\filename@parse@#1\@nil}
    \def\filename@parse@#1-#2-#3\@nil{%
      \gdef\firstpart{#1}% first part
      \gdef\secondpart{#2}% second part
      \gdef\thirdpart{#3}% third part
    }
\makeatother

\newcommand{\spaced}[1]{\expandafter\hyphentospace\expandafter{#1}} %Replace hyphens with spaces in the third part
\newcommand{\cappedspaced}[1]{\expandafter\ecapitalisewords{\spaced{#1}}} %Capitalise the first letter in the important words in the spaced third part

\newcommand{\inputtext}{document-that-reads-the-filename} %Manually supply the third part of the file name

\begin{document}
\filenameparse{\jobname}

\cappedspaced{\thirdpart} %Returns ``Document That Reads The Filename''

\cappedspaced{\inputtext} %Returns ``Document That Reads the Filename''

\end{document}

答案1

问题不是扩展而是 catcodes: 中的所有字符\jobname都有 catcode 12。但mfirstuc-english仅为具有正常字母的单词(catcode 11)设置“大写例外”。您可以使用以下方法重现问题(并解决它)\detokenize

\documentclass{article}
\usepackage{mfirstuc-english}


\begin{document}

\capitalisewords{There is a bird in a tree}

\ecapitalisewords{\detokenize{There is a bird in a tree}}

\expandafter\MFUnocap\expandafter{\detokenize{a}}
\expandafter\MFUnocap\expandafter{\detokenize{in}}
\expandafter\MFUnocap\expandafter{\detokenize{is}}
\MFUnocap{is}

\capitalisewords{There is a bird in a tree}

\ecapitalisewords{\detokenize{There is a bird in a tree}}

\end{document}

在此处输入图片描述

答案2

主要事实是,它\jobname扩展为类别代码 12 的字母,正如 Ulrike Fischer 所说。

解决方案expl3

\documentclass{article}
\usepackage{mfirstuc-english}
\usepackage{xparse}

\ExplSyntaxOn

\tl_new:N \g_adam_spaced_job_name_tl
\seq_new:N \g_adam_job_name_seq
% rescan \jobname
\tl_gset_rescan:Nnx \g_adam_spaced_job_name_tl { } { \c_job_name_tl }
\seq_gset_split:NnV \g_adam_job_name_seq { - } \g_adam_spaced_job_name_tl
% replace hyphens by spaces
\tl_greplace_all:Nnn \g_adam_spaced_job_name_tl { - } { ~ }

\NewDocumentCommand{\thisfilename}{}
 {
  % just print the (spaced) file name
  \tl_use:N \g_adam_spaced_job_name_tl
 }
\NewDocumentCommand{\casedthisfilename}{}
 {
  % apply \ecapitalisewords to the variable
  \adam_ecapitalise_words:V \g_adam_spaced_job_name_tl
 }
\NewDocumentCommand{\thisfilenamepart}{m}
 {
  \seq_item:Nn \g_adam_job_name_seq { #1 }
 }
% syntactic sugar
\cs_set_eq:NN \adam_ecapitalise_words:n \ecapitalisewords
\cs_generate_variant:Nn \adam_ecapitalise_words:n { V }

\ExplSyntaxOff

\begin{document}

\thisfilename

\casedthisfilename

\thisfilenamepart{1} \thisfilenamepart{2} \thisfilenamepart{3}
\thisfilenamepart{4} \thisfilenamepart{5} \thisfilenamepart{6}
\thisfilenamepart{7}

\end{document}

在此处输入图片描述

用于提取复杂文件名的部分,例如

fall-15-math-150a-quiz-02-approximating-the-derivative.tex

您可以使用一些更先进的expl3设施。

\documentclass{article}
\usepackage{mfirstuc-english}
\usepackage{xparse}

\ExplSyntaxOn

% allocate some variables
\tl_new:N \g_adam_spaced_job_name_tl
\tl_new:N \g_adam_file_classifier_tl
\tl_new:N \g_adam_file_title_tl
\seq_new:N \g_adam_job_name_seq

% rescan \jobname
\tl_gset_rescan:Nnx \g_adam_spaced_job_name_tl { } { \c_job_name_tl }
% split the file name into parts at hyphens
\seq_gset_split:NnV \g_adam_job_name_seq { - } \g_adam_spaced_job_name_tl

% make the classifier with the first six parts
\tl_gset:Nx \g_adam_file_classifier_tl { \seq_item:Nn \g_adam_job_name_seq { 1 } }
\int_step_inline:nnnn { 2 } { 1 } { 6 }
 {
  \tl_gput_right:Nx \g_adam_file_classifier_tl { - \seq_item:Nn \g_adam_job_name_seq { #1 } }
 }
% make the title with the remaining parts
\tl_gset:Nx \g_adam_file_title_tl { \seq_item:Nn \g_adam_job_name_seq { 7 } }
\int_step_inline:nnnn { 8 } { 1 } { \seq_count:N \g_adam_job_name_seq }
 {
  \tl_gput_right:Nx \g_adam_file_title_tl { ~ \seq_item:Nn \g_adam_job_name_seq { #1 } }
 }

% user level commands
\NewDocumentCommand{\thisfileclassifier}{}
 {
  % just print the file classifier
  \tl_use:N \g_adam_file_classifier_tl
 }
\NewDocumentCommand{\thisfiletitle}{}
 {
  % just print the (spaced) file name
  \tl_use:N \g_adam_file_title_tl
 }
\NewDocumentCommand{\casedthisfiletitle}{}
 {
  % apply \ecapitalisewords to the variable
  \adam_ecapitalise_words:V \g_adam_file_title_tl
 }
\NewDocumentCommand{\thisfilenamepart}{m}
 {
  % access to generic file name parts
  \seq_item:Nn \g_adam_job_name_seq { #1 }
 }
% syntactic sugar
\cs_set_eq:NN \adam_ecapitalise_words:n \ecapitalisewords
\cs_generate_variant:Nn \adam_ecapitalise_words:n { V }

\ExplSyntaxOff

\begin{document}

\thisfileclassifier

\thisfiletitle

\casedthisfiletitle

\thisfilenamepart{1}

\end{document}

在此处输入图片描述

相关内容