![如果参数的最后一个字符是 's',则删除它](https://linux22.com/image/336289/%E5%A6%82%E6%9E%9C%E5%8F%82%E6%95%B0%E7%9A%84%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E6%98%AF%20's'%EF%BC%8C%E5%88%99%E5%88%A0%E9%99%A4%E5%AE%83.png)
我有一个语义注释\monster
来注释怪物的提及,以便对它们进行索引:
\newcommand{\indexMonster}[1]{\index{#1}}
\newcommand{\monster}[1]{#1\indexMonster{#1}}
现在,大多数怪物的提及都是复数,但有些不是。我希望索引条目是单数。所以我正在寻找一种方法来删除参数的最后一个字符,\monster
如果它是's'。
答案1
此解决方案使用xstring
。由于有一些可怕的怪物名叫信天翁这些都是非常可怕的,你当然会写很多关于它们的内容,我还制作了一个警告系统,用于在怪物名称发生变化时发出警告。当然,如果你愿意,你可以放弃它。如果你想覆盖以 结尾的怪物的测试s
,只需在怪物周围添加括号,如下例所示。
代码
\documentclass[11pt,draft]{article}
\usepackage{xstring}
\usepackage{ifdraft}
\newcommand{\indexMonster}[1]{\index{#1}}
\newcommand{\monster}[1]{%
\IfEndWith{#1}{s}{%
% Do nothing if ends with s.
\StrGobbleRight{#1}{1}[\result]%
\result\indexMonster{\result}%
% Issue a warning on changed monsters
\ifdraft{%
\marginpar{Monster \textbf{#1} was changed to \result.}%
}{}%%
}{%
#1\indexMonster{#1}}%
}
\begin{document}
\monster{Dogs} \monster{Dog} \monster{albatross} \monster{{albatross}}
\end{document}
第二种解决方案
这是我对此的尝试expl3
。我只是进行了文本替换,而不是索引,但这应该是微不足道的。
\documentclass[11pt]{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\monster}{m}
{
\l_wilx_monster:n { #1 }
}
\cs_new_protected:Nn \l_wilx_monster:n
{
% Check if last character is "s"
\str_if_eq_x:nnTF { \str_item:nn {#1} {-1} } {s}
% True: print string expect for last string (in other words, remove s)
{\str_range:nnn {#1} {1} {-2}} %
% False: Print string as usual
{#1}
}
\ExplSyntaxOff
\begin{document}
\monster{dogs}
\end{document}
答案2
下面是一个使用 TeX 基元去除最后一个元素的示例s
。可展开的宏\striplastS
已创建。\striplastS{texts}
展开为text
并\striplastS{text}
展开为text
也。
\def\striplastS#1{\striplastSa{#1}#1\end s\end\eend}
\def\striplastSa#1#2s\end#3\eend{\ifx\end#3\end#1\else#2\fi}
%test:
\message{\striplastS{text} \striplastS{texts}} % prints: text text
答案3
您可以使用stringstrings
Steven B. Segletes 的软件包:
\documentclass{article}
\usepackage{stringstrings}
\usepackage{makeidx}\makeindex
\begin{document}
\newcommand{\indexMonster}[1]{%
\testmatchingchar{#1}{$}{s}
\ifmatchingchar
\substring[q]{#1}{1}{$-1}\index{\thestring}
\else
\index{#1}
\fi}
\newcommand{\monster}[1]{#1\indexMonster{#1}}
\monster{zombies}
\pagebreak
\monster{zombie}
\printindex
\end{document}
答案4
你遇到的问题比你想象的还要多。
\documentclass{book}
\usepackage{etoolbox}
\usepackage{imakeidx}
\usepackage{fancyhdr}
\makeindex[name=monsters,title=Monster index]
\newcommand{\indexMonster}[1]{\index[monsters]{\stripfinals{#1}}}
\newrobustcmd{\monster}[1]{#1\indexMonster{#1}}
\makeatletter % Wipet's
\newcommand{\stripfinals}[1]{\strip@final@s{#1}#1\@nnil s\@nnil\@nil}
\def\strip@final@s#1#2s\@nnil#3\@nil{%
\ifx\@nnil#3\@nnil#1\else#2\fi
}
% we don't want monster to be indexed also in the table of contents
% or in headers
\newcommand{\fixmonster}{\let\monster\@firstofone}
\patchcmd{\addtocontents}
{\let}
{\fixmonster\let}
{}{}
\makeatother
\pagestyle{fancy}
\fancyhf{}
\fancyhead[LE,RO]{\thepage}
\makeatletter
\fancyhead[RE]{\fixmonster\leftmark}
\fancyhead[LO]{\fixmonster\rightmark}
\newcommand{\WviiSPOT}{\mbox{\monster{*S~P~O~T*}}}
\begin{document}
\frontmatter
\tableofcontents
\mainmatter
\chapter{\monster{zombies} and \WviiSPOT}
\monster{asasas}, \monster{zombies} and \WviiSPOT
\clearpage
\monster{zombie} and \monster{uss}
\printindex[monsters]
\end{document}