From 7b6cdf4c23e6ed232601dabc70f5553a8dee9c9b Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Wed, 19 Oct 2022 03:01:25 +0000 Subject: CTAN sync 202210190301 --- macros/latex/contrib/mfirstuc/CHANGES | 52 + macros/latex/contrib/mfirstuc/README | 14 +- macros/latex/contrib/mfirstuc/mfirstuc-code.pdf | Bin 266637 -> 352549 bytes macros/latex/contrib/mfirstuc/mfirstuc-manual.html | 3101 +++++++++----------- macros/latex/contrib/mfirstuc/mfirstuc-manual.pdf | Bin 301928 -> 294879 bytes macros/latex/contrib/mfirstuc/mfirstuc-manual.tex | 2495 ++++++++++------ macros/latex/contrib/mfirstuc/mfirstuc.dtx | 2030 +++++++++---- macros/latex/contrib/mfirstuc/mfirstuc.ins | 10 +- macros/latex/contrib/mfirstuc/sample-mfirstuc.pdf | Bin 121084 -> 122108 bytes macros/latex/contrib/mfirstuc/sample-mfirstuc.tex | 292 -- 10 files changed, 4560 insertions(+), 3434 deletions(-) delete mode 100644 macros/latex/contrib/mfirstuc/sample-mfirstuc.tex (limited to 'macros/latex/contrib/mfirstuc') diff --git a/macros/latex/contrib/mfirstuc/CHANGES b/macros/latex/contrib/mfirstuc/CHANGES index a78e049ba9..d1cc1e183a 100644 --- a/macros/latex/contrib/mfirstuc/CHANGES +++ b/macros/latex/contrib/mfirstuc/CHANGES @@ -1,5 +1,57 @@ mfirstuc change log: +v2.08 (2022-10-14): + + * Reimplemented \makefirstuc in LaTeX3. This change supports + UTF-8 with pdflatex. + + Rollback to v2.07 provided: + + \usepackage{mfirstuc}[=v2.07] + + * New command \MFUsentencecase + + This just uses \text_titlecase_first:n + + Principle features of \MFUsentencecase vs \makefirstuc are + listed in Table 1 of the manual. + + * \makefirstuc has been rewritten to internally use + \MFUsentencecase (via \glsmakefirstuc), but it still parses + its argument as in previous versions. + + * New command \MFUexcl{} + + This adds a command to the case-changing exclusion list. + Both \MFUsentencecase and \makefirstuc will skip the + identified command and its argument, and apply sentence-casing + to the content that follows. + + For example, glossaries.sty v4.50 implements \MFUexcl{\glsadd} + + * New command \MFUblocker{} + + This adds a command to the blocker list. This is used by + \makefirstuc but not \MFUsentencecase. If the command is encountered + no case-change will be applied. This is designed for commands + that automatically implement a case-change that may have been nested. + + For example, glossaries.sty v4.50 implements \MFUblocker{\Gls} + + * New command \MFUaddmap{}{} + + Adds a mapping. This is used by \makefirstuc but not + \MFUsentencecase. If the first command is encountered + it will be replaced with the second . No case change + will be applied. (The case-change, if appropriate, + should be dealt with by the replacement command.) + + For example, glossaries.sty v4.50 implements \MFUaddmap{\gls}{\Gls} + + Order of precedence: map, blocker, exclusion + + * New commands \MFUsaveatend and \MFUsave + v2.07 (2021-10-15): * new commands: diff --git a/macros/latex/contrib/mfirstuc/README b/macros/latex/contrib/mfirstuc/README index 95e632cfc7..e7ba4933d8 100644 --- a/macros/latex/contrib/mfirstuc/README +++ b/macros/latex/contrib/mfirstuc/README @@ -1,6 +1,6 @@ -LaTeX Package : mfirstuc v2.07 +LaTeX Package : mfirstuc v2.08 -Last Modified : 2021-10-15 +Last Modified : 2022-10-14 Author : Nicola Talbot @@ -26,10 +26,12 @@ package. LaTeX2HTML -This package comes with a LaTeX2HTML style file mfirstuc.perl which -should be placed in the relevant LaTeX2HTML styles directory, but -note that some commands may not be implemented or may be implemented -in a different way. +This package comes with a LaTeX2HTML style file mfirstuc.l2h which +should be placed in the relevant LaTeX2HTML styles directory and may +need to have the file extension changed, but note that some commands +may not be implemented or may be implemented in a different way. +There's no guarantee that it will continue to work with new +versions of LaTeX2HTML. LICENCE diff --git a/macros/latex/contrib/mfirstuc/mfirstuc-code.pdf b/macros/latex/contrib/mfirstuc/mfirstuc-code.pdf index f02689d526..7da4d79d1d 100644 Binary files a/macros/latex/contrib/mfirstuc/mfirstuc-code.pdf and b/macros/latex/contrib/mfirstuc/mfirstuc-code.pdf differ diff --git a/macros/latex/contrib/mfirstuc/mfirstuc-manual.html b/macros/latex/contrib/mfirstuc/mfirstuc-manual.html index be92120e8f..b2c121f28d 100644 --- a/macros/latex/contrib/mfirstuc/mfirstuc-manual.html +++ b/macros/latex/contrib/mfirstuc/mfirstuc-manual.html @@ -1,1720 +1,1393 @@ - - - - - - - - - - + + + + + + mfirstuc.sty v2.08: +sentence and title casing - -

-

- - - -

- - - -

-
-

-

mfirstuc.sty v2.07: uppercasing first letter -

-
+ +
+
mfirstuc.sty v2.08: sentence and title casing
Nicola L.C. Talbot
+ + Dickimaw Books
+ + dickimaw-books.com
2022-10-14

+

+

+The mfirstuc package was originally part of the glossaries bundle (added to glossaries v1.12 in 2008) for use with commands like \Gls, which need to have the first letter converted to uppercase (sentence-case), but as the commands provided by mfirstuc may be used without glossaries, the two were split into separately maintained packages in 2015 (mfirstuc v2.0 and glossaries v4.18).
+

+Version 2.08 has reimplemented \makefirstuc using LaTeX3 commands. If there are any compatibility issues, you can rollback to v2.07:

\usepackage{mfirstuc}[=2.07]
+

+

+ + + +

+

1. Sentence-Case

+

+There are two sentence-case commands provided: \MFUsentencecase and \makefirstuc. A summary of the principle features of the two commands is given in Table 1.1.

+

+ + + + + + + + + + + + + + + + + + +
Table 1: Principle features of \MFUsentencecase and \makefirstuc
Feature \MFUsentencecase \makefirstuc
Can expand?
Supports exclusions?
Supports blockers?
Supports mappings?
Semantic commands must be robust?
+

+ + + +

+

1.1. Examples

+

+Text only (leading UTF-8 now supported):

+

+

+\makefirstuc{élite} /
+\MFUsentencecase{élite}
+
Élite / Élite

+

+Leading punctuation is ignored:

+

+

+\makefirstuc{`word'} /
+\MFUsentencecase{`word'}
+
‘Word’ / ‘Word’

+ However, if the punctuation character is followed by a blocker or mapping command, the punctuation will need to be excluded otherwise the command will be treated as an exclusion. If possible, use semantic markup instead of directly including the punctuation.

+Fragile commands need to be protected with \MFUsentencecase:

\newcommand{\alert}[1]{\textcolor{red}{\textbf{#1}}}
+\makefirstuc{\alert{élite}} /
+\MFUsentencecase{\protect\alert{élite}}
+
+ Élite / Élite
+

+Exclusions are supported by both \makefirstuc and \MFUsentencecase:

\MFUexcl{\index}
+\makefirstuc{\index{word}example} /
+\MFUsentencecase{\index{word}example}
+
+ Example / Example
+

+Blockers are only supported by \makefirstuc. They are treated as exclusions with \MFUsentencecase, which produces a different result:

\MFUblocker{\nameref}
+\makefirstuc{\nameref{sec:sentencecase} section} /
+\MFUsentencecase{\nameref{sec:sentencecase} section}
+
+ Sentence-Case section / Sentence-Case Section
+

+Mappings are only supported by \makefirstuc. They are treated as exclusions with \MFUsentencecase, which produces a different result:

\newrobustcmd{\secref}[1]{section~\ref{#1}}
+\newrobustcmd{\Secref}[1]{Section~\ref{#1}}
+\MFUaddmap{\secref}{\Secref}
+\makefirstuc{\secref{sec:sentencecase} example} /
+\MFUsentencecase{\secref{sec:sentencecase} example}
+
+ Section 1 example / section 1 Example
+

+Argument expansion: \MFUsentencecase expands its argument and then skips exclusions whereas \makefirstuc parses its argument without expansion and then passes the relevant content to \glsmakefirstuc. Note that different results will occur with the expanded and unexpanded package options. For example:

\usepackage[expanded]{mfirstuc}
+\newcommand{\testa}{sample}
+\newcommand{\testb}{\testa\ test}
+\begin{document}
+\makefirstuc{\testb} / \xmakefirstuc{\testb} /
+\emakefirstuc{\testb} / \MFUsentencecase{\testb}
+\end{document}
+
+Sample test / Sample test / Sample test / Sample test
+ With the default unexpanded option the result is:
+ sample test / sample Test / Sample test / Sample test
+ Note that this is different from the result in earlier versions of mfirstuc.
\usepackage{mfirstuc}[=v2.07]
+\newcommand{\testa}{sample}
+\newcommand{\testb}{\testa\ test}
+\begin{document}
+\makefirstuc{\testb} / \xmakefirstuc{\testb} /
+\emakefirstuc{\testb}
+\end{document}
+
This produces:
+SAMPLE TEST / SAMPLE test / Sample test
+ If this old result is required, either use rollback or try the grabfirst option.

+Argument expansion with mappings (and the default unexpanded option):

\newrobustcmd{\secref}[1]{section~\ref{#1}}
+\newrobustcmd{\Secref}[1]{Section~\ref{#1}}
+\MFUaddmap{\secref}{\Secref}
+\newcommand{\testa}{\secref{sec:sentencecase}}
+\newcommand{\testb}{\testa\ example}
+\makefirstuc{\testb} / \xmakefirstuc{\testb} /
+\emakefirstuc{\testb} / \MFUsentencecase{\testb}
+
+ section 1 example / section 1 Example / Section 1 example / section 1 Example
+

+ +

+ +
+

1.2. Sentence Case Commands

+

+

+\MFUsentencecase{text}
+ This simply uses \text_titlecase_first:n, which is provided by the LaTeX3 kernel. Note that this fully expands the argument. If you use this command, ensure that your semantic commands are robust. For example:
\newrobustcmd{\alert}[1]{\textcolor{red}{\textbf{#1}}}
+\MFUsentencecase{\alert{sample} text}
+
+ Sample text
+ Note that the following will fail:
\newcommand{\alert}[1]{\textcolor{red}{\textbf{#1}}}
+\MFUsentencecase{\alert{sample} text}
+
This is because the expansion that’s performed before the case-change will result in:
\textcolor{Red}{\textbf{sample}} text
+
This triggers an error since Red isn’t a recognised colour name.

+

+\makefirstuc{text}
+ This is the original command provided by mfirstuc, which was written to assist sentence-casing in the glossaries package and had to take markup into account. It parses its argument to try to determine which part needs the case-change. The actual case-change is performed by \glsmakefirstuc.

+As from v2.08, the definition of \makefirstuc has been updated to use LaTeX3 code, but the argument is still parsed, which allows for non-robust semantic commands, and now also takes blockers and mappings into account. For example:

\newcommand{\alert}[1]{\textcolor{red}{\textbf{#1}}}
+\makefirstuc{\alert{sample} text}
+
+ Sample text
+

+The rules used when parsing \makefirstuc{text} are as follows: +

    +
  1. 1.if text is empty do nothing;

    +

  2. 2.if text consists of a single item or starts with a group do \glsmakefirstuc{text};

    +

  3. 3.if text starts with a command cs:

    + +

      +
    1. (a)if cs is \protect, skip it and continue to the next step where the command cs under inspection is now the one that follows \protect:

      +

    2. (b)if cs has been identified as a blocker, just do text (that is, no case-change is applied);

      +

    3. (c)if cs isn’t followed by a group then do \glsmakefirstuc{text};

      +

    4. (d)otherwise assume the format is cs{arg}following (where following may be empty) and then:

      + +

        +
      1. i.if cs has been mapped to Cs then do Cs{arg}following;

        +

      2. ii.if cs has been identified as an exclusion, do cs{arg}\makefirstuc{following};

        +

      3. iii.otherwise do cs{\makefirstuc{arg}}following. +
      +

      + +

    +

    +

  4. 4.otherwise do \glsmakefirstuc{text}. +
+

+Note that the above algorithm uses recursion. The termination points are: don’t implement a change, replace a command with another command, or apply the case-change via \glsmakefirstuc.

+For convenience, the following commands are also provided:

+\xmakefirstuc{text}
+ This is simply a shortcut for:
\expandafter\makefirstuc\expandafter{text}
+
This ensures the first token in text is expanded before being passed to \makefirstuc.

+

+\emakefirstuc{text}
+ This fully expands its argument before passing it to \makefirstuc. For example:
\newcommand{\test}[1]{sample #1}
+\newcommand{\tmp}{\test{text}}
+\makefirstuc{\tmp} /
+\xmakefirstuc{\tmp} /
+\emakefirstuc{\tmp}
+
+ sample text / sample Text / Sample text
+ If you don’t have any mappings or blockers set up, it’s simpler to use \MFUsentencecase instead of \emakefirstuc.

+

+With \emakefirstuc, mappings and blockers will only be detected if they are robust or protected, otherwise they will expand too soon to be detected.
+

+

+\glsmakefirstuc{text}
+ This command is used by \makefirstuc to perform the case-change. The “gls” prefix is for historical reasons as the original code was part of the glossaries package. With the default unexpanded option, this command is defined as:
\MFUsentencecase{\unexpanded{text}}
+
The use of \unexpanded inhibits the expansion of text that would otherwise occur. This allows \makefirstuc to maintain as much backward-compatibility with version 2.07 as possible. This is particularly important when using the glossaries package with a style that automatically converts the description to sentence-case, as there may well be documents with complex descriptions that contain fragile commands.

+The expanded package option will redefine \glsmakefirstuc to use \MFUsentencecase without \unexpanded. The grabfirst package option will redefine \glsmakefirstuc to use \mfugrabfirstuc to emulates the behaviour of \glsmakefirstuc in v2.07 and below without using rollback.

+

+\mfugrabfirstuc{text}

+

avoid where possible
+
+ This robust command is provided to emulate v2.07 and its use is discouraged. Note that you may still have different results compared to v2.07, so you may need to use rollback instead. (Note that the grabfirst option additionally redefines \mfirstucMakeUppercase to \MakeUppercase, which you will also need.)

+This applies \mfirstucMakeUppercase to the first token in text and leaves the remainder unchanged. This won’t work if text starts with a UTF-8 character unless you use XeLaTeX or LuaLaTeX, so avoid using this method where possible. For example:

\renewcommand{\mfirstucMakeUppercase}[1]{% 
+  \MakeUppercase{#1}% 
+}
+\mfugrabfirstuc{sample}
+
This is equivalent to:
\mfirstucMakeUppercase{s}ample
+
Whereas
\renewcommand{\mfirstucMakeUppercase}[1]{% 
+  \MakeUppercase{#1}% 
+}
+\mfugrabfirstuc{élite}
+
only works with XeLaTeX or LuaLaTeX.

+

+As with earlier implementations of \makefirstuc that tried to only apply the case-change to the first token, this won’t produce the desired result if the argument starts with a punctuation character.
+

+For example:

\mfugrabfirstuc{`sample'}
+
This is equivalent to:
\mfirstucMakeUppercase{`}sample'
+
so no case-change is applied.

+ +

+ +
+

1.3. Exclusions

+

+

+Exclusions will apply to all LaTeX3 case-changing commands, so will also affect \mfirstucMakeUppercase, but this is generally desirable.
+

+

+\MFUexcl{cs}
+ Identifies the text-block command cs{arg} as an exclusion. That is, one that should have its argument excluded from a case-change.

+Internally, \MFUexcl adds cs to LaTeX3’s exclusion list \l_text_case_exclude_arg_tl, which means that \MFUsentencecase will skip the command and its argument and apply the case-change to the following content. Some common commands (\begin \cite \end \label and \ref) are automatically added by the LaTeX3 kernel. The exclusions are also recognised by \makefirstuc when it parses its argument.

+

+The command \NoCaseChange is automatically treated as an exclusion by the LaTeX3 case-changing commands with recent LaTeX kernels. You may want to add it as a blocker for \makefirstuc and keep \MFUskippunc for exclusions.

+Note that \ensuremath is added as an exclusion by mfirstuc otherwise \makefirstuc will pass its argument to \MFUsentencecase, which will cause a problem.

+

+Another way of identifying content that should be excluded with \makefirstuc is to encapsulate it with:

+\MFUskippunc{content}
+ This is a robust command that simply does its argument and is automatically added to the exclusion list. This may be used for cases where the excluded command isn’t a simple text-block command that only has one mandatory argument or where leading punctuation is followed by a blocker or mapping.

+The command name stems from earlier versions where leading punctuation needed to be skipped. This is no longer necessary, but the command remains as a general purpose robust exclusion command.

+For example, \glsadd (provided by glossaries) should have its argument skipped, since its argument is a label, so the following will ensure that \glsadd{label} will be skipped, and the case-change will be applied to the following text for both \MFUsentencecase and \makefirstuc.

\MFUexcl{\glsadd}
+\makefirstuc{\glsadd{ex}some text}
+\MFUsentencecase{\glsadd{ex}some text}
+
This will be equivalent to:
\glsadd{ex}Some text
+
However, \glsadd can take an optional argument which, if present, will cause a problem. For example:
\MFUexcl{\glsadd}
+\makefirstuc{\glsadd[counter=section]{ex}some text}
+\MFUsentencecase{\glsadd[counter=section]{ex}some text}
+
Both commands will cause the following error:
! Package glossaries Error: Glossary entry `[' has not been defined.
+
This is because the open square bracket is assumed to be the argument of \glsadd, so this effectively becomes:
\glsadd{[}Counter=section] exsome text
+\glsadd{[}Counter=section] exsome text
+
which means that now [ is considered the label and everything that follows is just text.

+For this situation to work, you need to encapsulate the problematic content with an exclusion command, such as \NoCaseChange or \MFUskippunc:

\makefirstuc{\MFUskippunc{\glsadd[counter=section]{ex}}some text}
+
This will also work with \MFUsentencecase because mfirstuc automatically adds \MFUskippunc to the exclusion list.

+

+As from glossaries v4.50, \glsadd is automatically added as an exclusion, but be aware of the problem with using the optional argument, as described above.
+

+Punctuation characters are skipped by \MFUsentencecase. For example:

+

+

+\MFUsentencecase{`word'}
+
‘Word’

+ However, leading punctuation will result in \makefirstuc passing its entire argument to \MFUsentencecase (since the argument doesn’t start with cs{arg}), which means that \makefirstuc won’t detect any blocker or mapping.

+For example:

\MFUblocker{\nameref}
+\newcommand*{\qt}[1]{``#1''}
+\makefirstuc{``\nameref{sec:sentencecase} section''} /
+\makefirstuc{\MFUskippunc{``}\nameref{sec:sentencecase} section''} /
+\makefirstuc{\qt{\nameref{sec:sentencecase} section}}
+
+ “Sentence-Case Section’’ / “Sentence-Case section’’ / Sentence-Case section”
+ If you are using a package such as csquotes, bear in mind that if the command is followed by an asterisk (a “starred command”) or an optional argument then it won’t fit the expected cs{arg} format and unexpected results will occur.

+ +

+ +
+

1.4. Blockers

+

+A blocker is a command that prevents any case-change if it occurs at the start of \makefirstuc or after the argument of an exclusion. Blockers are not supported by \MFUsentencecase but are instead treated as exclusions.

+

+\MFUblocker{cs}
+ Identifies cs as a blocker. Since blockers aren’t supported by \MFUsentencecase, this automatically implements \MFUexcl{cs} to protect its argument from \MFUsentencecase, but it won’t prevent subsequent content from being changed.

+For example:

\MFUblocker{\nameref}
+\makefirstuc{\nameref{sec:sentencecase} section} 
+
+ Sentence-Case section
+

+In the following, the blocker isn’t detected by \makefirstuc because the content doesn’t start with cs{arg} or \protectcs{arg}. This means that the entire content is passed to \MFUsentencecase which treats \nameref as an exclusion:

\MFUblocker{\nameref}
+\makefirstuc{\relax\nameref{sec:sentencecase} section} 
+
+ Sentence-Case Section
+

+

+If a blocking command is inside the definition of another command, it won’t be visible to \makefirstuc unless the other command is expanded before applying \makefirstuc. For example, by using \xmakefirstuc or \emakefirstuc. If it doesn’t get expanded until after it has been passed to \MFUsentencecase, then it will be treated as an exclusion instead.
+

+Recent LaTeX kernels provide \NoCaseChange and automatically add it as an exclusion. You may want to add it as a blocker for \makefirstuc. For example:

\makefirstuc{\ensuremath{\alpha}-particle} /
+\makefirstuc{$\alpha$-particle} /
+\MFUsentencecase{\ensuremath{\alpha}-particle} /
+\MFUsentencecase{$\alpha$-particle}
+
+\MFUblocker{\NoCaseChange}% 
+\makefirstuc{\ensuremath{\alpha}-particle} /
+\makefirstuc{\NoCaseChange{$\alpha$}-particle} /
+\MFUsentencecase{\ensuremath{\alpha}-particle} /
+\MFUsentencecase{\NoCaseChange{$\alpha$}-particle}
+
Note that mfirstuc adds \ensuremath as an exclusion so \makefirstuc will skip it. Whereas the example above that starts with $ will have the entire argument passed to \MFUsentencecase, which skips the maths content. In the first paragraph, \NoCaseChange is only an exclusion, but in the second paragraph it’s also a blocker.
+Exclusion: 𝛼-Particle / 𝛼-Particle / 𝛼-Particle / 𝛼-Particle

+Blocker: 𝛼-Particle / 𝛼-particle / 𝛼-Particle / 𝛼-Particle

+

+ +

+ +
+

1.5. Mappings

+

+A mapping indicates that one command should be substituted for another, instead of applying a case-change. The assumption is that the substituted command should perform the case-change instead. Mappings are not supported by \MFUsentencecase but are instead treated as exclusions.

+

+\MFUaddmap{cs1}{cs2}
+ Identifies a mapping which indicates that \makefirstuc should replace cs1 with cs2 and not apply a case-change. This automatically implements:
\MFUexcl{cs1}\MFUblocker{cs2}
+
This means that cs2 is identified as a blocker (since it’s assumed to already be a sentence-case command) and cs1 is identified as an exclusion to protect its argument from \MFUsentencecase, which doesn’t support mappings.

+

+If either cs1 or cs2 is empty, no mapping is established, but an exclusion or blocker will be set for the non-empty argument.
+

+For example (with glossaries):

\MFUaddmap{\gls}{\Gls}
+\makefirstuc{\gls{ex} some text}
+
This will be converted to:
\Gls{ex} some text
+
Note that this and similar mappings are automatically added in glossaries v4.50+ and glossaries-extra v1.49+.

+

+If a mapped command is inside the definition of another command, it won’t be visible to \makefirstuc unless the other command is expanded before applying \makefirstuc. For example, by using \xmakefirstuc or \emakefirstuc. If it doesn’t get expanded until after it has been passed to \MFUsentencecase, then it will be treated as an exclusion instead.
+

+ +

+ +
+

1.6. Package Options

+

+

+expanded
+ Redefines \glsmakefirstuc to simply use \MFUsentencecase.

+

+unexpanded
+ Redefines \glsmakefirstuc to use \MFUsentencecase without expanding its argument.

+

+grabfirst

+

avoid where possible
+
+ Redefines \glsmakefirstuc to use \mfugrabfirstuc and also redefines \mfirstucMakeUppercase to use \MakeUppercase.

+This option is best avoided and is only provided to emulate the v2.07 behaviour of \glsmakefirstuc. However, you may still have different results compared to v2.07, so you may need to use rollback instead.

+ +

+ +
+

2. Title-Case

+

+The title-case commands are designed to convert the first letter of each word in a phrase to uppercase. These commands are robust.

+\capitalisewords{text}
+ This command applies a sentence-case command to each word in text where the space character is used as the word separator. Note that it has to be an ordinary space character, not another form of space, such as ~ or \space. Note that no expansion is performed on text. For example: +

+

+\capitalisewords{a sample phrase}
+
A Sample Phrase

+ See §2.1 for excluding words (such as “of”) from the case-changing.

+

+This isn’t the same as the LaTeX3 command \text_titlecase:n, which converts the first letter to uppercase and all other letters to lowercase.
+

+For convenience, there are shortcut commands if expansion is required before parsing the argument:

+\xcapitalisewords{text}
+ This is a shortcut for:
\expandafter\capitalisewords\expandafter{text}
+
+\ecapitalisewords{text}
+ This fully expands text before passing it to \capitalisewords.

+The parser used by \capitalisewords first splits up the text on each space character. Each of these space-separated words may actually be a compound, so further parsing is performed on each “word”. The divisions within the compound word should be marked up with:

+\MFUwordbreak{text}
+ For example: +

+

+\capitalisewords{a 
+big\MFUwordbreak{/}small idea}
+
A Big/Small Idea

+ Each sub-word within the compound word is encapsulated with:

+\MFUcapword{text}
+ Since it’s inconvenient to have to markup every hyphen, \MFUcapword can be enabled to check for hyphens.
+\ifMFUhyphen true\else false\fiinitial: \iffalse
+ This conditional determines whether or not \MFUcapword should consider a hyphen a word break. If this conditional is true, then \MFUcapword will encapsulate its argument with:
+\MFUhyphencapword{text}
+ This will parse text for hyphen characters and apply the case change to each hyphen-separated word. Otherwise \MFUcapword will treat its argument as a single word.

+The conditional can be set to true with:

+\MFUhyphentrue
+ and switched back off with:
+\MFUhyphenfalse
+

+For example:

\capitalisewords{server-side includes} /
+\MFUhyphentrue
+\capitalisewords{server-side includes}
+
+Server-side Includes / Server-Side Includes
+

+The actual case-change of each word is performed with:

+\MFUcapwordfirstuc{word}
+ This defaults to \makefirstuc{word} but may be redefined to use \MFUsentencecase, if preferred.

+

+Hyphens and \MFUwordbreak must be visible to the parser that searches for word breaks. This means they won’t be detected if they are within a group or in the definition of a command.
+

+Formatting for the entire phrase must go outside \capitalisewords (unlike \makefirstuc). For example:

\capitalisewords{\emph{a sample phrase}} /
+\emph{\capitalisewords{a sample phrase}}
+
+A sample phrase / A Sample Phrase
+

+If your phrase is likely to contain formatting commands, you can instead use:

+\capitalisefmtwords{text}modifier: *
+ where text may be just words (as with \capitalisewords):
\capitalisefmtwords{words}
+
or may be entirely enclosed in a formatting command in the form:
\capitalisefmtwords{cs{words}}
+
or contain formatted sub-phrases:
\capitalisefmtwords{words cs{sub-phrase} words}
+
The starred form only permits a text-block command at the start of the phrase. See §2.3 for examples.

+

+Avoid declarations, such as \bfseries or \em.
+

+If expansion is required, you can use:

+\xcapitalisefmtwords{text}modifier: *
+ which is a shortcut for:
\expandafter\capitalisefmtwords\expandafter{text}
+
(The star modifier will be applied with \xcapitalisefmtwords* in an appropriate manner.)

+

+\ecapitalisefmtwords{text}modifier: *
+ This will fully expand its argument before passing it to \capitalisefmtwords. Again, the star modifier may be used.

+

+The unstarred \capitalisefmtwords is only designed for phrases that contain text-block commands with a single argument, which should be a word or sub-phrase. Anything more complicated is likely to break. Instead, use the starred form or \capitalisewords.
+

+ +

+ +
+

2.1. Excluding Words From Case-Changing

+

+Some words typically shouldn’t have their case changed unless they occur at the start. These words can be identified with:

+\MFUnocap{word}
+ This only has a local effect. The global version is:
+\gMFUnocap{word}
+ The list of words that shouldn’t be capitalised can be cleared using:
+\MFUclear
+

+For example:

\capitalisewords{the wind in the willows}
+
+\MFUnocap{in}% 
+\MFUnocap{the}% 
+
+\capitalisewords{the wind in the willows}
+
+The Wind In The Willows

+

+The Wind in the Willows

+

+Since the case-change is ultimately performed by \makefirstuc, you can also use an exclusion to prevent an individual word from being changed. For example:

\newcommand{\NoChange}[1]{#1}
+\MFUexcl{\NoChange}
+\MFUclear
+\capitalisewords{the \NoChange{wind} in the willows}
+
+ The wind In The Willows
+ This can also work if you redefine \MFUcapwordfirstuc to use \MFUsentencecase provided the exclusion command doesn’t expand (so \NoChange would need to be protected or made robust in the above example).

+

+Exceptions only apply to (non-leading) whole words or words separated with \MFUwordbreak but not to parts of a hyphenated word that are split by \MFUhyphencapword.
+

+Examples: +

    +
  1. 1.Exceptions aren’t applied if \MFUwordbreak occurs before the first space.
    \MFUnocap{a}\MFUnocap{the}% 
    +\capitalisewords{a\MFUwordbreak{/}the something}
    +
    +A/The Something
    +

    +

  2. 2.Exceptions are applied for non-leading words:
    \MFUnocap{and}\MFUnocap{or}% 
    +\capitalisewords{one and\MFUwordbreak{/}or another}
    +
    +One and/or Another
    +

    +

  3. 3.Exceptions aren’t applied for hyphenated parts:
    \MFUhyphentrue
    +\MFUnocap{and}\MFUnocap{or}% 
    +\capitalisewords{one and-or another}
    +
    +One And-Or Another
    -> Nicola L.C. Talbot Dickimaw Books -http://www.dickimaw-books.com/ -
-

2021-10-15

- - - -

Contents

- - - - -

1. Introduction

-

The mfirstuc package was originally part of the glossaries bundle for use with commands -like \Gls, but as the commands provided by mfirstuc may be used without glossaries, the two -have been split into separately maintained packages. -

The commands described here all have limitations. To minimise problems, use text-block -style semantic commands with one argument (the text that requires case-changing), and avoid -scoped declarations.
-

-

Here are some examples of semantic commands: -

    -
  1. -

    Quoted material: - - - -

    -
    -     \newcommand{\qt}[1]{``#1''}
    -
    -

    (or use the csquotes package). With this, the following works: - - - -

    -
    -     \makefirstuc{\qt{word}}
    -
    -

    This produces: -
    “Word” -
    - Whereas - - - -

    -
    -     \makefirstuc{``word''}
    -
    -

    fails (no case-change and double open quote becomes two single open quotes): - -
    ‘‘word” -
    -

  2. -
  3. -

    Font styles or colours: - - - -

    -
    -     \newcommand*{\alert}[1]{\textcolor{red}{#1}}
    -
    -

    Now the following is possible: - - - -

    -
    -     \makefirstuc{\alert{word}}
    -
    -

    This produces -
    Word -
    - Note that \makefirstuc{\textcolor{red}{word}} fails (with an error) because the - case-changing interferes with the label.

-

Define these semantic commands robustly if you intend using any of the commands -that fully expand their argument (\emakefirstuc, \ecapitalisewords and -\ecapitalisefmtwords). - - - -

-

-

Top

2. Capitalising the First Letter of a Word

-

A simple word can be capitalised just using the standard LaTeX upper casing command. -For example, - - - -

-
-\MakeUppercase word
-
-

but for commands like \Gls the word may be embedded within the argument of another -command, such as a font changing command. This makes things more complicated for -a general purpose solution, so the mfirstuc package provides: -


\makefirstuc  \makefirstuc{stuff}

-

-This makes the first object of ⟨stuff ⟩ upper case unless ⟨stuff ⟩ starts with a control sequence -followed by a non-empty group, in which case the first object in the group is converted to -upper case. No expansion is performed on the argument. -

If ⟨stuff ⟩ starts with punctuation that should be skipped over, use: -


\MFUskippunc  \MFUskippunc{punctuation}

-

-

If ⟨stuff ⟩ starts with a control sequence that takes more than one argument, the -case-changing will always be applied to the first argument. If the text that requires the case -change is in one of the other arguments, you must hide the earlier arguments in a wrapper -command. For example, instead of \textcolor{red}{text} you need to define, say, \red as -\color{red} and use \red{text}.
-

-

Examples:

-
    -
  • -

    \makefirstuc{abc} produces Abc. -

  • -
  • -

    \makefirstuc{\emph{abc}} produces Abc (\MakeUppercase has been applied to the - letter “a” rather than \emph). Note however that - - - -

    -
    -     \makefirstuc{{\em abc}}
    -
    -

    produces ABC (first object is {\em abc} so this is equivalent to \MakeUppercase{\em abc}), - and - - - -

    -
    -     {\makefirstuc{\em abc}}
    -
    -

    produces abc (\em doesn’t have an argument therefore first object is \em and so is - equivalent to {\MakeUppercase{\em}abc}). -

  • -
  • -

    \makefirstuc{{\’a}bc} produces Ábc. -

  • -
  • -

    \makefirstuc{\ae bc} produces Æbc. -

  • -
  • -

    \makefirstuc{{\ae}bc} produces Æbc. -

  • -
  • -

    \makefirstuc{{ä}bc} produces Äbc. -

  • -
  • -

    \makefirstuc{\MFUskippunc{’}tis the season} produces ’Tis the season. -

    -
-

Note that non-Latin or accented characters appearing at the start of the text should be -placed in a group (even if you are using the inputenc package). The reason for this restriction -is detailed in §4. UTF-8. -

New to version 2.04: There is now limited support for UTF-8 characters with the -inputenc package, provided that you load datatool-base (at least v2.24) before mfirstuc -(datatool-base is loaded automatically with newer versions of glossaries). If available mfirstuc -will now use datatool-base’s \dtl@getfirst@UTFviii command which is still experimental. -See the datatool manual for further details. - - - -

-
-\documentclass{article}
-\usepackage[T1]{fontenc}
-\usepackage[utf8]{inputenc}
-\usepackage{datatool-base}[2016/01/12]% v2.24+
-\usepackage{mfirstuc}
-\begin{document}
-\makefirstuc{élite}
-\end{document}
-
-

(Package ordering is important.) -

In version 1.02 of mfirstuc, a bug fix resulted in a change in output if the first object is a -control sequence followed by an empty group. Prior to version 1.02, \makefirstuc{\ae{}bc} -produced æBc. However as from version 1.02, it now produces Æbc.
-

-

Note also that - - - -

-
-\newcommand{\abc}{abc}
-\makefirstuc{\abc}
-
-

produces: ABC. This is because the first object in the argument of \makefirstuc is \abc, so -it does \MakeUppercase{\abc}. Whereas: - - - -

-
-\newcommand{\abc}{abc}
-\expandafter\makefirstuc\expandafter{\abc}
-
-

produces: Abc. There is a short cut command which will do this: -


\xmakefirstuc  \xmakefirstuc{stuff}

-

-This is equivalent to \expandafter\makefirstuc\expandafter{stuff }. So - - - -

-
-\newcommand{\abc}{abc}
-\xmakefirstuc{\abc}
-
-

produces: Abc. -

\xmakefirstuc only performs one level expansion on the first object in its argument. It -does not fully expand the entire argument.
-

-

As from version 1.10, there is now a command that fully expands the entire argument -before applying \makefirstuc: -


\emakefirstuc  \emakefirstuc{text}

-

-

Examples: - - - -

-
-\newcommand{\abc}{\xyz a}
-\newcommand{\xyz}{xyz}
-No expansion: \makefirstuc{\abc}.
-First object one-level expansion: \xmakefirstuc{\abc}.
-Fully expanded: \emakefirstuc{\abc}.
-
-

produces: No expansion: XYZA. First object one-level expansion: XYZa. Fully expanded: -Xyza. -

If you use mfirstuc without the glossaries package, the standard \MakeUppercase command -is used. If used with glossaries, \MakeTextUppercase (defined by the textcase package) is used -instead. If you are using mfirstuc without the glossaries package and want to use -\MakeTextUppercase instead, you can redefine -


\glsmakefirstuc  \glsmakefirstuc{text}

-

-For example: - - - -

-
-\renewcommand{\glsmakefirstuc}[1]{\MakeTextUppercase #1}
-
-

Remember to also load textcase (glossaries loads this automatically). - - - -

-

-

Top

3. Capitalise the First Letter of Each Word in a Phrase or Sentence (Title Case)

-

New to mfirstuc v1.06: -


\capitalisewords  \capitalisewords{text}

-

-This command applies \makefirstuc to each word in ⟨text⟩ where the space character is used -as the word separator. Note that it has to be a plain space character, not another form of -space, such as ~ or \space. Note that no expansion is performed on ⟨text⟩. See §3.2 Excluding Words From Case-Changing for excluding words (such as “of”) from the -case-changing. -

The actual capitalisation of each word is done using -


\MFUcapwordfirstuc  \MFUcapwordfirstuc{word}

-

-This just does \makefirstuc{word} by default. There’s a conditional that determines -whether or not to consider a hyphen a word break: -


\ifMFUhyphen  \ifMFUhyphen

-

-

If you want to title case each part of a compound word containing hyphens, you can enable -this using -


\MFUhyphentrue  \MFUhyphentrue

-

-or switch it back off again using: -


\MFUhyphenfalse  \MFUhyphenfalse

-

-Compare - - - -

-
-\capitalisewords{server-side includes}
-
-

which produces: -
Server-side Includes -
-with - - - -

-
-\MFUhyphentrue
-\capitalisewords{server-side includes}
-
-

which produces: -
Server-Side Includes -
-Note that this won’t apply exceptions to each part of the hyphenated word. -

For other punctuation you need to markup the character with: -


\MFUwordbreak  \MFUwordbreak{punctuation}

-

-For example: - - - -

-
-\capitalisewords{a big\MFUwordbreak{/}small idea}
-
-

which produces: -
A Big/Small Idea -
-In this case, exceptions are applied. For example, if mfirstuc-english is loaded then: - - - -

-
-\capitalisewords{one and\MFUwordbreak{/}or another}
-
-

produces: -
One and/or Another -
-Note that you can’t hide \MFUwordbreak inside a command or group. -

Exceptions aren’t applied if \MFUwordbreak occurs before the first space. For -example: - - - -

-
-\MFUnocap{a}\MFUnocap{the}%
-\capitalisewords{a\MFUwordbreak{/}the something}
-
-

produces: -
A/The Something -
-

Formatting for the entire phrase must go outside \capitalisewords (unlike -\makefirstuc). Compare: - - - -

-
-\capitalisewords{\textbf{a sample phrase}}
-
-

which produces: -
A sample phrase -
-with: - - - -

-
-\textbf{\capitalisewords{a sample phrase}}
-
-

which produces: -
A Sample Phrase -
-

As from version 2.03, there is now a command for phrases that may include a formatting -command: -


\capitalisefmtwords{phrase}

-

-where ⟨phrase⟩ may be just words (as with \capitalisewords) or may be entirely enclosed in a -formatting command in the form

-
-\capitalisefmtwords{cs{phrase}} -
-
or contain formatted sub-phrases
-
-\capitalisefmtwords{words cs{sub-phrase} words} -
-
Avoid scoped declarations. -

\capitalisefmtwords is only designed for phrases that contain text-block commands -with a single argument, which should be a word or sub-phrase. Anything more complicated is -likely to break. Instead, use the starred form or \capitalisewords.
-

-

The starred form only permits a text-block command at the start of the phrase. -

Examples: -

    -
  1. -

    Phrase entirely enclosed in a formatting command: - - - -

    -
    -     \capitalisefmtwords{\textbf{a small book of rhyme}}
    -
    -

    produces: -
    A Small Book Of Rhyme -
    -

  2. -
  3. -

    Sub-phrase enclosed in a formatting command: - - - -

    -
    -     \capitalisefmtwords{a \textbf{small book} of rhyme}
    -
    -

    produces: -
    A Small Book Of Rhyme -
    -

  4. -
  5. -

    Nested text-block commands: - - - -

    -
    -     \capitalisefmtwords{\textbf{a \emph{small book}} of rhyme}
    -
    -

    produces: -
    A Small Book Of Rhyme -
    -

  6. -
  7. -

    Indicating words that shouldn’t have the case changed (see §3.2 Excluding - Words From Case-Changing): - - - -

    -
    -     \MFUnocap{of}
    -     \capitalisefmtwords{\textbf{a \emph{small book}} of rhyme}
    -
    -

    produces: -
    A Small Book of Rhyme -
    -

  8. -
  9. -

    Starred form: - - - -

    -
    -     \MFUnocap{of}
    -     \capitalisefmtwords*{\emph{a small book of rhyme}}
    -
    -

    produces: -
    A Small Book of Rhyme -
    -

  10. -
  11. -

    The starred form also works with just text (no text-block command): - - - -

    -
    -     \MFUnocap{of}
    -     \capitalisefmtwords*{a small book of rhyme}
    -
    -

    produces: -
    A Small Book of Rhyme -
    -

    -
-

If there is a text-block command within the argument of the starred form, it’s assumed to -be at the start of the argument. Unexpected results can occur if there are other commands. -For example - - - -

-
-\MFUnocap{of}
-\capitalisefmtwords*{\emph{a small} book \textbf{of rhyme}}
-
-

produces: -
A Small Book Of rhyme -
-(In this case \textbf{of rhyme} is considered a single word.) Similarly if the text-block -command occurs in the middle of the argument: - - - -

-
-\MFUnocap{of}
-\capitalisefmtwords*{a \emph{very small} book of rhyme}
-
-

produces: -
A Very small Book of Rhyme -
-(In this case \emph{very small} is considered a single word.) -

Grouping causes interference: - - - -

-
-\capitalisefmtwords{{a \emph{small book}} of rhyme}
-
-

produces: -
A Small book Of Rhyme -
-As with all the commands described here, avoid declarations. For example, the following -fails: - - - -

-
-\capitalisefmtwords{{\bfseries a \emph{small book}} of rhyme}
-
-

produces: -
a Small book Of Rhyme -
-

Avoid complicated commands in the unstarred version. For example, the following -breaks: - - - -

-
-\newcommand*{\swap}[2]{{#2}{#1}}
-\capitalisefmtwords{a \swap{bo}{ok} of rhyme}
-
-

However it works okay with the starred form and the simpler \capitalisewords: - - - -

-
-\newcommand*{\swap}[2]{{#2}{#1}}
-\capitalisefmtwords*{a \swap{bo}{ok} of rhyme}
-\capitalisewords{a \swap{bo}{ok} of rhyme}
-
-

Produces: -
A okBo Of Rhyme -
A okBo Of Rhyme -
-Note that the case change is applied to the first argument. -


\xcapitalisewords  \xcapitalisewords{text}

-

-This is a short cut for \expandafter\capitalisewords\expandafter{text}. -

As from version 1.10, there is now a command that fully expands the entire argument -before applying \capitalisewords: -


\ecapitalisewords  \ecapitalisewords{text}

-

-

There are also similar shortcut commands for the version that allows text-block -commands: -


\xcapitalisefmtwords  \xcapitalisefmtwords{text}

-

-The unstarred version is a short cut for \expandafter\capitalisefmtwords\expandafter -{text}. Similarly the starred version of \xcapitalisefmtwords uses the starred version of -\capitalisefmtwords. -

For full expansion: -


\ecapitalisefmtwords  \ecapitalisefmtwords{text}

-

-Take care with this as it may expand non-robust semantic commands to replacement -text that breaks the functioning of \capitalisefmtwords. Use robust semantic -commands where possible. Again this has a starred version that uses the starred form of -\capitalisefmtwords. -

Examples: - - - -

-
-\newcommand{\abc}{\xyz\space four five}
-\newcommand{\xyz}{one two three}
-No expansion: \capitalisewords{\abc}.
-First object one-level expansion: \xcapitalisewords{\abc}.
-Fully expanded: \ecapitalisewords{\abc}.
-
-

produces: -
No expansion: ONE TWO THREE FOUR FIVE. -
First object one-level expansion: ONE TWO THREE four Five. -
Fully expanded: One Two Three Four Five. -
-

(Remember that the spaces need to be explicit. In the second case above, using -\xcapitalisewords, the space before “four” has been hidden within \space so it’s not -recognised as a word boundary, but in the third case, \space has been expanded to an actual -space character.) -

Examples: -

    -
  1. -

    - - - -

    -
    -     \capitalisewords{a book of rhyme.}
    -
    -

    produces: A Book Of Rhyme. -

  2. -
  3. -

    - - - -

    -
    -     \capitalisewords{a book\space of rhyme.}
    -
    -

    produces: A Book of Rhyme. -

  4. -
  5. -

    - - - -

    -
    -     \newcommand{\mytitle}{a book\space of rhyme.}
    -     \capitalisewords{\mytitle}
    -
    -

    produces: A BOOK OF RHYME. (No expansion is performed on \mytitle.) Compare - with next example: -

  6. -
  7. -

    - - - -

    -
    -     \newcommand{\mytitle}{a book\space of rhyme.}
    -     \xcapitalisewords{\mytitle}
    -
    -

    produces: A Book of Rhyme. -

    However - - - -

    -
    -     \ecapitalisewords{\mytitle}
    -
    -

    produces: A Book Of Rhyme. (\space has been expanded to an actual space - character.) -

  8. -
  9. -

    - - - -

    -
    -     \newcommand*{\swap}[2]{{#2}{#1}}
    -     \capitalisewords{a \swap{bo}{ok} of rhyme}
    -     \ecapitalisewords{a \swap{bo}{ok} of rhyme}
    -
    -

    produces: -
    A okBo Of Rhyme -
    A OKbo Of Rhyme -
    - This is because the argument of \ecapitalisewords is fully expanded before being - passed to \capitalisewords so that last example is equivalent to: - - - -

    -
    -     \capitalisewords{a {ok}{bo} of rhyme}
    -
    -

-

Top

3.1 PDF Bookmarks

-

If you are using hyperref and want to use \capitalisewords, \capitalisefmtwords or -\makefirstuc (or the expanded variants) in a section heading, the PDF bookmarks won’t be -able to use the command as it’s not expandable, so you will get a warning that looks -like: - - - -

-
-Package hyperref Warning: Token not allowed in a PDF string
+
+

+

+\usepackage{mfirstuc-english}
+ The supplementary package mfirstuc-english loads mfirstuc and uses \MFUnocap to add common English articles and conjunctions, such as “a”, “an”, “and”, “but”. You may want to add other words to this list, such as prepositions but, as there’s some dispute over whether prepositions should be capitalised, I don’t intend to add them to this package. Note that you need to explicitly load mfirstuc-english if you require it. There’s no automatic language detection performed by mfirstuc.

+If you want to write a similar package for another language, all you need to do is create a file with the extension .sty that starts with:

\NeedsTeXFormat{LaTeX2e}
+
The next line should identify the package. For example, if you have called the file mfirstuc-french.sty then you need:
\ProvidesPackage{mfirstuc-french}
+
It’s a good idea to also add a version in the final optional argument, for example:
\ProvidesPackage{mfirstuc-french}[2014/07/30 v1.0]
+
Next load mfirstuc:
\RequirePackage{mfirstuc}
+
Now add all your \MFUnocap commands. For example:
\MFUnocap{de}
+
At the end of the file add:
\endinput
+

+Put the file somewhere on TeX’s path, and now you can use this package in your document. You might also consider uploading it to CTAN in case other users find it useful.

+ + + +

+

2.2. PDF Bookmarks

+

+If you are using hyperref and want to use \capitalisewords or \capitalisefmtwords (or the expanded variants) in a section heading, the PDF bookmarks won’t be able to use the command as it’s not expandable, so you will get a warning that looks like:

Package hyperref Warning: Token not allowed in a PDF string 
 (PDFDocEncoding):
-(hyperref)                removing `\capitalisewords'
-
-

-

-

If you want to provide an alternative for the PDF bookmark, you can use hyperref’s -\texorpdfstring command. For example: - - - -

-
-\chapter{\texorpdfstring
-  {\capitalisewords{a book of rhyme}}% TeX
-  {A Book of Rhyme}% PDF
+(hyperref)                removing `\capitalisewords'
+

+If you want to provide an alternative for the PDF bookmark, you can use hyperref’s \texorpdfstring command. For example:

\chapter{\texorpdfstring
+  {\capitalisewords{a book of rhyme}}%  TeX
+  {A Book of Rhyme}%  PDF
 }
-
-

Alternatively, you can use hyperref’s mechanism for disabling commands within the -bookmarks. For example: - - - -

-
-\pdfstringdefDisableCommands{%
- \let\capitalisewords\@firstofone
+
Alternatively, you can use hyperref’s mechanism for disabling commands within the bookmarks. For example:
\pdfstringdefDisableCommands{% 
+ \let\capitalisewords\@firstofone
 }
-
-

-

See the hyperref manual for further details. -

-

-

Top

3.2 Excluding Words From Case-Changing

-

As from v1.09, you can specify words which shouldn’t be capitalised unless they occur at the -start of ⟨text⟩ using: -


\MFUnocap  \MFUnocap{word}

-

-This only has a local effect. The global version is: -


\gMFUnocap  \gMFUnocap{word}

-

-

For example: - - - -

-
-\capitalisewords{the wind in the willows}
-\MFUnocap{in}%
-\MFUnocap{the}%
-\capitalisewords{the wind in the willows}
-
-

produces: -
The Wind In The Willows -
The Wind in the Willows -
-The list of words that shouldn’t be capitalised can be cleared using -


\MFUclear  \MFUclear

-

-

You can also simply place an empty group in front of a word if you don’t want that specific -instance to be capitalised. For example: - - - -

-
-\MFUclear
-\capitalisewords{the {}wind in the willows}
-
-

produces: -
The wind In The Willows -
-This is also a useful way of protecting commands that shouldn’t be parsed. For -example: - - - -

-
-\capitalisewords{this is section {}\nameref{sec:nocap}.}
-
-

produces -
This Is Section Excluding Words From Case-Changing. -
-(No case-changing is applied to \nameref{sec:nocap}. It just happens to already be in title -case.) -

The package mfirstuc-english loads mfirstuc and uses \MFUnocap to add common -English articles and conjunctions, such as “a”, “an”, “and”, “but”. You may want -to add other words to this list, such as prepositions but, as there’s some dispute -over whether prepositions should be capitalised, I don’t intend to add them to this -package. -

If you want to write a similar package for another language, all you need to do is create a -file with the extension .sty that starts with - - - -

-
-\NeedsTeXFormat{LaTeX2e}
-
-

The next line should identify the package. For example, if you have called the file -mfirstuc-french.sty then you need: - - - -

-
-\ProvidesPackage{mfirstuc-french}
-
-

It’s a good idea to also add a version in the final optional argument, for example: - - - -

-
-\ProvidesPackage{mfirstuc-french}[2014/07/30 v1.0]
-
-

Next load mfirstuc: - - - -

-
-\RequirePackage{mfirstuc}
-
-

Now add all your \MFUnocap commands. For example: - - - -

-
-\MFUnocap{de}
-
-

At the end of the file add: - - - -

-
-\endinput
-
-

-

Put the file somewhere on TeX’s path, and now you can use this package in your -document. You might also consider uploading it to CTAN in case other users find it -useful. - - - -

-

-

Top

4. UTF-8

-

(See Binary Files, Text Files and File Encodings if you are confused about how file -encodings such as UTF-8 relate to text files.) -

The \makefirstuc command works by utilizing the fact that, in most cases, TeX doesn’t -require a regular argument to be enclosed in braces if it only consists of a single token. (This is -why you can do, say, \frac12 instead of \frac{1}{2} or x^2 instead of x^{2}, although some -users frown on this practice.) -

A simplistic version of the \makefirstuc command is: - - - -

-
-\newcommand*{\FirstUC}[1]{\MakeUppercase #1}
-
-

Here - - - -

-
-\FirstUC{abc}
-
-

is equivalent to - - - -

-
-\MakeUppercase abc
-
-

and since \MakeUppercase requires an argument, it grabs the first token (the character “a” in -this case) and uses that as the argument so that the result is: Abc. -

The glossaries package needs to take into account the fact that the text may be contained -in the argument of a formatting command, such as \acronymfont, so \makefirstuc has to be -more complicated than the trivial \FirstUC shown above, but at its basic level, \makefirstuc -uses this same method and is the reason why, in most cases, you don’t need to enclose the first -character in braces. So if

-
-\MakeUppercase stuff⟩ -
-
works, then
-
-\makefirstuc{stuff} -
-
should also work and so should
-
-\makefirstuc{\foo{stuff}} -
-
but if
-
-\MakeUppercase stuff⟩ -
-
doesn’t work, then neither will
-
-\makefirstuc{stuff} -
-
nor
-
-\makefirstuc{\foo{stuff}} -
-
-

Try the following document:

- - - -
-\documentclass{article} -
-
\usepackage[utf8]{inputenc} -
\usepackage[T1]{fontenc} -
-
\begin{document} -
-
\MakeUppercase ãbc -
-
\end{document} -
-
-

This will result in the error: - - - -

-
-! Argument of \UTFviii@two@octets has an extra }.
-
-

This is why \makefirstuc{ãbc} won’t work. It will only work if the character ã is placed -inside a group. -

The reason for this error message is due to TeX having been written before Unicode was -invented. Although ã may look like a single character in your text editor, from TeX’s point of -view it’s two tokens. So

-
-\MakeUppercase ãbc -
-
tries to apply \MakeUppercase to just the first octet of ã. This means that the second octet -has been separated from the first octet, which is the cause of the error. In this case the -argument isn’t a single token, so the two tokens (the first and second octet of ã) must be -grouped:
-
-\MakeUppercase{ã}bc -
-
Over recent years the LaTeX kernel has changed to allow the use of UTF-8 characters within -labels but the fundamental problem of each octet been viewed as a separated token -remains. -

Note that XeTeX (and therefore XeLaTeX) is a modern implementation of TeX designed -to work with Unicode and therefore doesn’t suffer from this drawback. Now let’s look at the -XeLaTeX equivalent of the above example:

-
-\documentclass{article} -
-
\usepackage{fontspec} -
-
\begin{document} -
-
\MakeUppercase ãbc -
-
\end{document} -
-
-

This works correctly when compiled with XeLaTeX. This means that \makefirstuc{ãbc} -will work provided you use XeLaTeX and the fontspec package. -

Version 2.24 of datatool-base added the command \dtl@getfirst@UTFviii which -attempts to grab both octets. If this command has been defined, mfirstuc will use it when it -tries to split the first character from the rest of the word. See the datatool documented code -for further details. - - - -

-

-

Top

Index

- C -
\capitalisewords  8
-

D -datatool-base package  6, 20
-

E -\ecapitalisefmtwords  13
-\ecapitalisewords  13
-\emakefirstuc  7
-

F -fontspec package  20
-

G -glossaries package  6, 7, 18
-\glsmakefirstuc  7
-\gMFUnocap  15
-

H -hyperref package  15
-

I -\ifMFUhyphen  8
-inputenc package  6
-

M -\makefirstuc  5
-mfirstuc package  6, 20
- - - -mfirstuc-english package  9, 16
-\MFUcapwordfirstuc  8
-\MFUclear  16
-\MFUhyphenfalse  8
-\MFUhyphentrue  8
-\MFUnocap  15
-\MFUskippunc  5
-\MFUwordbreak  9
-

T -textcase package  7
-

X -\xcapitalisefmtwords  13
-\xcapitalisewords  13
-\xmakefirstuc  7
-

- - - - - - + The same applies to \makefirstuc. You can, however, use the expandable \MFUsentencecase. So you may prefer:
\pdfstringdefDisableCommands{% 
+ \let\capitalisewords\MFUsentencecase
+ \let\makefirstuc\MFUsentencecase
+}
+

+See the hyperref manual for further details.

+ + + +

+

2.3. Examples

+

+ +

    +
  1. 1.Text only: +

    +

    +\capitalisewords{a little book of rhyme}
    +
    A Little Book Of Rhyme

    +

    +

  2. 2.Excluding words (see §2.1): +

    +

    +\MFUnocap{of}
    +\capitalisewords{a little book of rhyme}
    +
    A Little Book of Rhyme

    +

    +

  3. 3.\space isn’t recognised as a word boundary:
    \capitalisewords{a book of rhyme.}
    +
    +\capitalisewords{a book\space of rhyme.}
    +
    +A Book Of Rhyme.

    +A Book of Rhyme.

    +

    +

  4. 4.Phrase entirely enclosed in a formatting command:
    \capitalisefmtwords{\emph{a small book of rhyme}}
    +
    +A Small Book Of Rhyme
    +

    +

  5. 5.Sub-phrase enclosed in a formatting command:
    \capitalisefmtwords{a \emph{small book} of rhyme}
    +
    +A Small Book Of Rhyme
    +

    +

  6. 6.Nested text-block commands:
    \capitalisefmtwords{\textbf{a \emph{small book}} of rhyme}
    +
    +A Small Book Of Rhyme
    +

    +

  7. 7.Formatting and case-change exception (see §2.1):
    \MFUnocap{of}
    +\capitalisefmtwords{\textbf{a \emph{small book}} of rhyme}
    +
    + A Small Book of Rhyme
    +

    +

  8. 8.Starred form:
    \MFUnocap{of}
    +\capitalisefmtwords*{\emph{a small book of rhyme}}
    +
    + A Small Book of Rhyme
    +

    +

  9. 9.The starred form also works with just text (no text-block command):
    \MFUnocap{of}
    +\capitalisefmtwords*{a small book of rhyme}
    +
    + A Small Book of Rhyme
    +

    +

  10. 10.Expansion:
    \newcommand{\abc}{\xyz\space four five}
    +\newcommand{\xyz}{one two three}
    +No expansion: \capitalisewords{\abc}.
    +
    +First object one-level expansion: \xcapitalisewords{\abc}.
    +
    +Fully expanded: \ecapitalisewords{\abc}.
    +
    + No expansion: one two three four five.

    +First object one-level expansion: one two three Four Five.

    +Fully expanded: One Two Three Four Five.

    +

    +Remember that the spaces need to be explicit. In the second case above, using \xcapitalisewords, the space before “four” has been hidden within \space so it’s not recognised as a word boundary, but in the third case, \space has been expanded to an actual space character.

    + +

+

+If there is a text-block command within the argument of the starred form, it’s assumed to be at the start of the argument. Unexpected results can occur if there are other commands. For example:

\MFUnocap{of}
+\capitalisefmtwords*{\emph{a small} book \textbf{of rhyme}}
+
+ A Small Book Of rhyme
+ In this case \textbf{of rhyme} is considered a single word. Similarly if the text-block command occurs in the middle of the argument:
\MFUnocap{of}
+\capitalisefmtwords*{a \emph{very small} book of rhyme}
+
+ A Very small Book of Rhyme
+ In this case \emph{very small} is considered a single word.

+Grouping causes interference. As with all the commands described here, avoid declarations.

\capitalisefmtwords{{\bfseries a \emph{small book}} of rhyme}
+

+

+As a general rule, it’s better to define semantic commands rather than directly using font commands and declarations within the document.
+

+Avoid complicated commands in the unstarred version. For example, the following breaks:

\newcommand*{\swap}[2]{{#2}{#1}}
+\capitalisefmtwords{a \swap{bo}{ok} of rhyme}
+
However it can work with the starred form and the simpler \capitalisewords:
\newcommand*{\swap}[2]{{#2}{#1}}
+\capitalisefmtwords*{a \swap{bo}{ok} of rhyme}
+
+\capitalisewords{a \swap{bo}{ok} of rhyme}
+
+ A okBo Of Rhyme

+A okBo Of Rhyme

+ Note that the case change is applied to the first argument.

+ +

+ +
+

3. Miscellaneous

+

+ +

+ +
+

3.1. Saving exclusions, blockers and mappings in the aux File

+

+If the exclusions, mappings and blockers are required by some external tool, the information can be saved in the aux file.

+

+\MFUsaveatend
+ This saves the information at the end of the document using a delayed write. This means that it can register all information identified throughout the document, but there’s a chance the document may end before the write takes place (for example, if the last page only contains floats). This command may be counteracted by:
+\MFUsave
+ This saves the information using a protected write at the point where this command occurs, which may be too soon if additional exclusions, mappings or blockers are identified later. This command will counteract any instance of \MFUsaveatend, regardless of whether or not \MFUsaveatend comes before or after \MFUsave.

+The associated aux commands are listed below. In each case, a definition is provided in the aux file that does nothing.

+\@mfu@excls{exclusions}
+ Lists all exclusions. For example:
\@mfu@excls{\begin \cite \end \label
+\ref \cite \NoCaseChange \ensuremath
+\MFUskippunc \gls \glspl}
+

+

+\@mfu@blockers{blockers}
+ Lists all blockers. For example:
\@mfu@blockers{\Gls \Glspl }
+

+

+\@mfu@mappings{mappings}
+ Lists all mappings as a key=value list. For example:
\@mfu@mappings{ {\gls }= {\Gls }, {\glspl }= {\Glspl }}
+

+ +

+ +
+

3.2. All-Caps

+

+

+\mfirstucMakeUppercase{text}
+ This command was originally used to perform the actual conversion to uppercase and was defined to use command \MakeUppercase. The glossaries package (before v4.50) formerly loaded the textcase package and redefined \mfirstucMakeUppercase to use \MakeTextUppercase, which was better than \MakeUppercase.

+The textcase package has been deprecated as from 2022 and it now simply sets \MakeTextUppercase to \MakeUppercase because the new kernel now defines \MakeUppercase to use the newer LaTeX3 command \text_uppercase:n. Although that command is expandable, \MakeUppercase is robust.

+As from v2.08, mfirstuc now defines \mfirstucMakeUppercase so that it uses \text_titlecase_first:n directly, rather than indirectly through \MakeUppercase, which means that it’s now expandable. However, \mfirstucMakeUppercase is no longer used by mfirstuc except in \mfugrabfirstuc, which is provided to emulate v2.07. Note that the grabfirst option will also redefine \mfirstucMakeUppercase to use \MakeUppercase.

+ +

+ +
+

3.3. UTF-8

+

+

+See Binary Files, Text Files and File Encodings if you are confused about how file encodings, such as UTF-8, relate to text files.
+

+This section only applies to rollback or the use of \mfugrabfirstuc (implemented via the grabfirst option).

+Prior to version 2.08, the case-change applied by the \glsmakefirstuc command worked by utilizing the fact that, in most cases, TeX doesn’t require a regular argument to be enclosed in braces if it only consists of a single token. (This is why you can do, say, \frac12 instead of \frac{1}{2} or x^2 instead of x^{2}, although this practice is discouraged by some.)

+A simplistic version of the original \glsmakefirstuc command is:

\newcommand*{\FirstUC}[1]{\MakeUppercase #1}
+
Here
\FirstUC{abc}
+
is equivalent to
\MakeUppercase abc
+
and since \MakeUppercase requires an argument, it grabs the first token (the character “a” in this case) and uses that as the argument so that the result is “Abc”. This behaviour can be achieved with \mfugrabfirstuc.

+Unfortunately, this will fail if the content starts with a UTF-8 character and you are using pdfLaTeX, where each octet of the UTF-8 character is a separate token. This isn’t a problem with XeLaTeX and LuaLaTeX which both treat the entire multibyte character as a single token.

+LaTeX3 now provides \text_titlecase_first:n to convert the first character to uppercase, so now the case-change can be applied with:

\ExplSyntaxOn
+\text_titlecase_first:n{élite}
+\ExplSyntaxOff
+
This is exactly what \MFUsentencecase does without the need to switch on LaTeX3 syntax. The difference with the default definition of \glsmakefirstuc is that it prevents its argument from being expanded.

+ +

+ +
+

Symbols

+ +
+
📌
+
The syntax and usage of a command, environment or option etc.
+
+
An important message.
+
🛈
+
Prominent information.
+
🖹
+
LaTeX code to insert into your document.
+
🖹🛇
+
Problematic code which should be avoided.
+
🖺
+
How the example code should appear in the PDF.
+
🔎
+
Text in a transcript or log file or written to STDOUT or STDERR.
+
🗋U
+
Code that requires a native Unicode engine (XeLaTeX or LuaLaTeX).
+
𝍢
+
An option that doesn’t take a value.
+
+
A warning.
+ +
+ +
+ +
+

Glossary

+ +
+
Blocker
+
A command that prohibits case-changing. If encountered by \makefirstuc, it won’t attempt to apply any case-changing. See §1.4.
+
Exclusion command
+
A command whose argument should be skipped by the case-changer. The content that follows the command should have its case-changed instead. See §1.3.
+
Exclusion word
+
A word that shouldn’t have its case changed by title-case commands, unless the word occurs at the start.
+
Mapping
+
A command that should be substituted by another, if encountered by \makefirstuc, instead of applying a case-change. See §1.5.
+
Semantic command
+
Essentially, this is a command associated with a particular element, idea or topic that hides the font and other stylistic formatting inside its definition. For example, Latin taxonomy is usually displayed in italic. Explicitly using font commands, for example
\textit{Clostridium}
is syntactic markup. Whereas defining a command called, say, \bacteria that displays its argument in italics is a semantic command. The actual styling is hidden and the command relates specifically to a particular concept.
Syntactic: \textit{Clostridium}
+
+\newrobustcmd*{\bacteria}[1]\emph{#1}%
Semantic: \bacteria{Clostridium}
The end result is the same:
+Syntactic: Clostridium

+Semantic: Clostridium

+ The advantage with semantic commands is that it’s much easier to change the style, simply by adjusting the command definition. Note that I’ve used \newrobustcmd to make the semantic command robust as the style commands can cause a problem if they expand too soon.
+
Sentence-case
+
Content that should appear at the start of a sentence that needs to have its first significant character converted to uppercase. See §1.
+
Title-case
+
Content that needs to appear in a title that should have each significant word converted to sentence-case. See §2.
+
Unicode Transformation Format (8-bit) (UTF-8)
+
A variable-width encoding that uses 8-bit code units. This means that some characters are represented by more that one byte. XeLaTeX and LuaLaTeX treat the multi-byte sequence as a single token, but the older LaTeX formats have single-byte tokens, which can cause complications, although these have mostly been addressed with the newer kernels introduced over the past few years. Related blog article: Binary Files, Text Files and File Encodings.
+ +
+ +
+ +
+

Command Summary

+ +
+ +
+

@

+
\@mfu@blockers{blockers}mfirstuc v2.08+
+

+An aux file command that lists all the identified blockers. §3.1; 27

+

\@mfu@excls{exclusions}mfirstuc v2.08+
+

+An aux file command that lists all the identified exclusions. §3.1; 26

+

\@mfu@mappings{mappings}mfirstuc v2.08+
+

+An aux file command that lists all the identified mappings as a key=value list. §3.1; 27

+ +

+ +
+

C

+
\capitalisefmtwords{text}modifier: * mfirstuc v2.03+
+

+Similar to \capitalisewords but for content that may contain formatting commands. §2; 16

+

\capitalisewords{text}mfirstuc v1.06+
+

+Applies title-case to text. This will apply \MFUcapword to each word in text (unless the word has been identified as an exclusion word and doesn’t occur at the start of text). §2; 14

+ +

+ +
+

E

+
\ecapitalisefmtwords{text}modifier: * mfirstuc v2.03+
+

+Fully expands text and passes it to \capitalisefmtwords including the * modifier, if provided. §2; 17

+

\ecapitalisewords{text}mfirstuc v1.10+
+

+Fully expands text before passing it to \capitalisewords. §2; 14

+

\emakefirstuc{text}mfirstuc v1.10+
+

+Fully expands text before passing it to \makefirstuc. §1.2; 6

+ +

+ +
+

G

+
\glsmakefirstuc{text}mfirstuc v1.05+
+

+Used by \makefirstuc to perform the case-change. This uses \MFUsentencecase{text} but by default will prevent its argument from being expanded. §1.2; 6

+

\gMFUnocap{word}mfirstuc v1.09+
+

+Globally adds word to the exclusion word list for \capitalisewords. §2.1; 18

+ +

+ +
+

I

+
\ifMFUhyphen true\else false\fiinitial: \iffalse; mfirstuc v2.03+
+

+Conditional that determines whether or not hyphens should be considered word boundaries by the title-case commands. §2; 15

+ +

+ +
+

M

+
\makefirstuc{text}mfirstuc v1.0+
+

+Converts text to sentence-case internally using \glsmakefirstuc to perform the case-change, but first parses text to deal with special cases. §1.2; 4

+

+

+Converts text to uppercase. Now only used in \mfugrabfirstuc. §3.2; 27

+

\MFUaddmap{cs1}{cs2}mfirstuc v2.08+
+

+Identifies a mapping from the command cs1 to command cs2. §1.5; 12

+

\MFUblocker{cs}mfirstuc v2.08+
+

+Locally identifies cs as a blocker command. §1.4; 11

+

\MFUcapword{text}mfirstuc v2.03+
+

+Uses either \MFUhyphencapword or \MFUcapwordfirstuc depending on \ifMFUhyphen. §2; 15

+

\MFUcapwordfirstuc{word}mfirstuc v2.07+
+

+Used by \MFUcapword and \MFUhyphencapword to apply the case-change to the given word. This just does \makefirstuc{text} by default. §2; 16

+

+

+Locally clears the exclusion word list for \capitalisewords. §2.1; 18

+

\MFUexcl{cs}mfirstuc v2.08+
+

+Locally identifies cs as an exclusion command. §1.3; 8

+

\mfugrabfirstuc{text}mfirstuc v2.08+

+

(avoid where possible)
+
+

+Provide to emulate \glsmakefirstuc in v2.07 and below, but can still produce different results to v2.07. This will attempt to grab only the first character of text and convert it to uppercase, leaving the rest of text unchanged. This won’t work if text starts with a UTF-8 character, unless you are using XeLaTeX or LuaLaTeX. §1.2; 7

+

\MFUhyphencapword{text}mfirstuc v2.07+
+

+Used by \MFUcapword to apply \MFUcapwordfirstuc to each hyphen-separated word in text, if hyphens should indicate a word-break. §2; 15

+

+

+Sets \ifMFUhyphen to false. §2; 15

+

+

+Sets \ifMFUhyphen to true. §2; 15

+

\MFUnocap{word}mfirstuc v1.09+
+

+Locally adds word to the exclusion word list for \capitalisewords. §2.1; 17

+

+

+Saves the list of exclusions, blockers and mappings to the aux file (if required by some external tool). This command sets itself to \relax so it doesn’t repeat the action if used multiple times, and counteracts any use of \MFUsaveatend. §3.1; 26

+

+

+Saves the list of exclusions, blockers and mappings to the aux file (if required by some external tool) at the end of the document. This command sets itself to \relax so it doesn’t repeat the action if used multiple times, but it can be overridden by \MFUsave. §3.1; 26

+

\MFUsentencecase{text}mfirstuc v2.08+
+

+Converts text to sentence-case with expansion. §1.2; 4

+

\MFUskippunc{content}mfirstuc v2.07+
+

+An exclusion command. §1.3; 8

+

\MFUwordbreak{text}mfirstuc v2.07+
+

+Used to markup a character or command that should be treated as a word break by the title-case commands. §2; 15

+ +

+ +
+

X

+
\xcapitalisefmtwords{text}modifier: * mfirstuc v2.03+
+

+Shortcut for \expandafter\capitalisefmtwords\expandafter{text} including the * modifier, if provided. §2; 17

+

\xcapitalisewords{text}mfirstuc v1.06+
+

+Shortcut for \expandafter\capitalisewords\expandafter{text}. §2; 14

+

\xmakefirstuc{text}mfirstuc v1.01+
+

+Shortcut for \expandafter\makefirstuc\expandafter{text}. §1.2; 5

+ +

+ +
+

Index

+
Symbols @ B C E F G H I L M N P R S T U X
+ +
+ +
+

Symbols

+ + + +
+ +
+

@

+ + + + +
+ +
+

B

+
\begin826
+
blockerTable 1.1; 1, 2, 5, 912, 26, 27, 31, 33, 3537
+ +
+ +
+

C

+ + +
\cite826
+
csquotes package10
+ +
+ +
+

E

+ + + +
\end826
+
\ensuremath8, 1226
+
exclusion commandTable 1.1; 1, 2, 5, 8, 1013, 18, 26, 31, 33, 3637
+
exclusion word17, 31, 3336
+ + +
+ +
+

F

+
file formats
+
aux26
+ +
+ +
+

G

+
glossaries-extra package13
+
glossaries packagea, 4, 6, 9, 10, 12, 1327
+
\Glsa, 1327
+
\gls13, 2627
+
\glsadd910
+ +
\Glspl27
+
\glspl2627
+ + + +
+ +
+

H

+
hyperref package2021
+ +
+ +
+

I

+ +
\index2
+ +
+ +
+

L

+
\label826
+
lowercase14
+
\l_text_case_exclude_arg_tl8
+ +
+ +
+

M

+ +
\MakeTextUppercase27
+
\MakeUppercase7, 13, 2728
+
mappingTable 1.1; 13, 5, 9, 10, 12, 13, 26, 27, 31, 33, 3537
+ +
mfirstuc package4
+ + + + + + + + + + + + + + + + + + +
+ +
+

N

+
\nameref2, 1011
+
\NoCaseChange8, 9, 11, 1226
+ +
+ +
+

P

+
\pdfstringdefDisableCommands21
+
\protect5
+
punctuation1, 910
+ +
+ +
+

R

+
\ref826
+ +
+ +
+

S

+
semantic command1, 4, 5, 2431
+
sentence-casea, 1, 6, 12, 14, 32, 3537
+
\space14, 21, 2324
+ +
+ +
+

T

+
\texorpdfstring20
+
textcase package27
+
\text_titlecase:n14
+
\text_titlecase_first:n4, 2728
+
\text_uppercase:n27
+
title-case14, 31, 32, 33, 3437
+ +
+ +
+

U

+
\unexpanded6
+ +
uppercase14, 27, 32, 3536
+
UTF-81, 7, 28, 3236
+ +
+ +
+

X

+ + + +

+ +

+ + + diff --git a/macros/latex/contrib/mfirstuc/mfirstuc-manual.pdf b/macros/latex/contrib/mfirstuc/mfirstuc-manual.pdf index cc7cf0cf77..9a9a108bf8 100644 Binary files a/macros/latex/contrib/mfirstuc/mfirstuc-manual.pdf and b/macros/latex/contrib/mfirstuc/mfirstuc-manual.pdf differ diff --git a/macros/latex/contrib/mfirstuc/mfirstuc-manual.tex b/macros/latex/contrib/mfirstuc/mfirstuc-manual.tex index e741c6d45d..c53b166eb4 100644 --- a/macros/latex/contrib/mfirstuc/mfirstuc-manual.tex +++ b/macros/latex/contrib/mfirstuc/mfirstuc-manual.tex @@ -1,933 +1,1758 @@ -\documentclass[report]{nlctdoc} - -\usepackage[a4paper,left=1.75in]{geometry} -\usepackage{alltt} -\usepackage{mfirstuc} -\usepackage{pifont} -\usepackage[utf8]{inputenc} -\ifpdf - \usepackage[T1]{fontenc} - \usepackage{metalogo} -\else - \providecommand{\XeLaTeX}{XeLaTeX} - \providecommand{\XeTeX}{XeTeX} -\fi -\usepackage{cmap} -\usepackage[colorlinks, - bookmarks, - hyperindex=false, - pdfauthor={Nicola L.C. Talbot}, - pdftitle={mfirstuc.sty: uppercasing first letter}, - pdfkeywords={LaTeX,package,uppercase}]{hyperref} - -\IndexPrologue{% -\chapter*{\indexname}\markright{\indexname} -\addcontentsline{toc}{chapter}{\indexname}} +% arara: lualatex +% arara: bib2gls: { group: on, options: [ "--replace-quotes" ] } +% arara: lualatex +% arara: bib2gls: { group: on, options: [ "--replace-quotes" ] } if found ("log", "Glossary entry `sym.") +% arara: lualatex +% arara: lualatex if found ("log", "Rerun to") + +% This document requires glossaries-extra v1.49, bib2gls v3.0 +% and nlctuserguide.sty. If they haven't already +% been uploaded to CTAN, they will be in a few days. + +\documentclass[titlepage=false,oneside, + fontsize=12pt,captions=tableheading]{scrbook} + +\usepackage + %[debug=showwrgloss] + {nlctuserguide} + +\nlctuserguidegls +{ + % \MFUsentencecase + \gcmd{MFU\-sen\-tence\-case} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{text}}% + \desc{converts \meta{text} to \idx+{sentence-case} with expansion} + } + % \MFUexcl + \gcmd{MFU\-excl} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{cs}}% + \desc{locally identifies \meta{cs} as an \idx{exclusion} command} + \field{seealso}{MFUblocker,MFUaddmap} + } + % \MFUblocker + \gcmd{MFU\-blocker} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{cs}}% + \desc{locally identifies \meta{cs} as a \idx{blocker} command} + \field{seealso}{MFUexcl,MFUaddmap} + } + % \MFUaddmap + \gcmd{MFU\-add\-map} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{cs1}\margm{cs2}}% + \desc{identifies a \idx{mapping} from the command \meta{cs1} to + command \meta{cs2}} + \field{seealso}{MFUexcl,MFUblocker} + } + % \MFUsaveatend + \gcmd{MFU\-save\-at\-end} + { + \providedby{\sty{mfirstuc} v2.08+} + \desc{saves the list of \idxpl{exclusion}, \idxpl{blocker} + and \idxpl{mapping} to the \ext{aux} file (if required by some + external tool) at the end of the document. + This command sets itself to \cmd{relax} so it + doesn't repeat the action if used multiple times, but it can + be overridden by \gls{MFUsave}} + } + % \MFUsave + \gcmd{MFU\-save} + { + \providedby{\sty{mfirstuc} v2.08+} + \desc{saves the list of \idxpl{exclusion}, \idxpl{blocker} + and \idxpl{mapping} to the \ext{aux} file (if required by some + external tool). + This command sets itself to \cmd{relax} so it + doesn't repeat the action if used multiple times, and + counteracts any use of \gls{MFUsaveatend}} + } + % \@mfu@excls + \gcmd{@mfu\-@\-excls} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{exclusions}} + \desc{an \ext{aux} file command that lists all the identified + \idxpl{exclusion}} + \field{seealso}{MFUsave,MFUsaveatend} + } + % \@mfu@blockers + \gcmd{@mfu\-@\-blockers} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{blockers}} + \desc{an \ext{aux} file command that lists all the identified + \idxpl{blocker}} + \field{seealso}{MFUsave,MFUsaveatend} + } + % \@mfu@mappings + \gcmd{@mfu\-@\-mappings} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{mappings}} + \desc{an \ext{aux} file command that lists all the identified + \idxpl{mapping} as a \keyval\ list} + \field{seealso}{MFUsave,MFUsaveatend} + } + % \mfirstucMakeUppercase + \gcmd{mfirst\-uc\-Make\-Up\-per\-case} + { + \providedby{\sty{mfirstuc} v1.07+} + \syntax{\margm{text}}% + \desc{converts \meta{text} to \idx{uppercase}. + Now only used in \gls{mfugrabfirstuc}} + } + % \emakefirstuc + \gcmd{e\-make\-first\-uc} + { + \providedby{\sty{mfirstuc} v1.10+} + \syntax{\margm{text}}% + \desc{fully expands \meta{text} before passing it to + \gls{makefirstuc}} + } + % \xmakefirstuc + \gcmd{x\-make\-first\-uc} + { + \providedby{\sty{mfirstuc} v1.01+} + \syntax{\margm{text}}% + \desc{shortcut for + \code{\cmd{expandafter}\gls{makefirstuc}\cmd{expandafter}\margm{text}}} + } + % \makefirstuc + \gcmd{make\-first\-uc} + { + \providedby{\sty{mfirstuc} v1.0+} + \syntax{\margm{text}}% + \desc{converts \meta{text} to \idx+{sentence-case} internally using + \gls{glsmakefirstuc} to perform the case-change, but first parses + \meta{text} to deal with special cases} + } + % \glsmakefirstuc + \gcmd{gls\-make\-first\-uc} + { + \providedby{\sty{mfirstuc} v1.05+} + \syntax{\margm{text}}% + \desc{used by \gls{makefirstuc} to perform the case-change. This + uses \code{\gls{MFUsentencecase}\margm{text}} but by default + will prevent its argument from being expanded} + } + % \mfugrabfirstuc + \gcmd{mfu\-grab\-first\-uc} + { + \providedby{\sty{mfirstuc} v2.08+} + \syntax{\margm{text}} + \note{avoid where possible} + \desc{provide to emulate \gls{glsmakefirstuc} in v2.07 and + below, but can still produce different results to v2.07. + This will attempt to grab only the first character of + \meta{text} and convert it to \idx{uppercase}, leaving the rest of + \meta{text} unchanged. This won't work if \meta{text} starts + with a \gls{utf8} character, unless you are using \XeLaTeX\ or + \LuaLaTeX} + } + % \MFUskippunc + \gcmd{MFU\-skip\-punc} + { + \providedby{\sty{mfirstuc} v2.07+} + \syntax{\margm{content}}% + \desc{an \idx{exclusion} command} + } + % \capitalisewords + \gcmd{cap\-i\-talise\-words} + { + \providedby{\sty{mfirstuc} v1.06+} + \syntax{\margm{text}}% + \desc{applies \idx+{title-case} to \meta{text}. This will apply + \gls{MFUcapword} to each word in \meta{text} (unless the word has been + identified as an \idx{exclusion-word} and doesn't occur at the start of + \meta{text})} + \field{seealso}{capitalisefmtwords,MFUnocap,gMFUnocap,ifMFUhyphen} + } + % \xcapitalisewords + \gcmd{x\-cap\-i\-talise\-words} + { + \providedby{\sty{mfirstuc} v1.06+} + \syntax{\margm{text}}% + \desc{shortcut for + \code{\cmd{expandafter}\gls{capitalisewords}\cmd{expandafter}\margm{text}}} + } + % \ecapitalisewords + \gcmd{e\-cap\-i\-talise\-words} + { + \providedby{\sty{mfirstuc} v1.10+} + \syntax{\margm{text}}% + \desc{fully expands \meta{text} before passing it to \gls{capitalisewords}} + } + % \capitalisefmtwords + \gcmd{cap\-i\-talise\-fmt\-words} + { + \providedby{\sty{mfirstuc} v2.03+} + \syntax{\margm{text}}% + \desc{similar to \gls{capitalisewords} but for content that may + contain formatting commands} + \field{modifiers}{*} + \field{seealso}{capitalisewords,MFUnocap,gMFUnocap,ifMFUhyphen} + } + % \xcapitalisefmtwords + \gcmd{x\-cap\-i\-talise\-fmt\-words} + { + \providedby{\sty{mfirstuc} v2.03+} + \syntax{\margm{text}}% + \desc{shortcut for + \code{\cmd{expandafter}\gls{capitalisefmtwords}\cmd{expandafter}\margm{text}} + including the \code{*} modifier, if provided} + \field{modifiers}{*} + } + % \ecapitalisefmtwords + \gcmd{e\-cap\-i\-talise\-fmt\-words} + { + \providedby{\sty{mfirstuc} v2.03+} + \syntax{\margm{text}}% + \desc{fully expands \meta{text} and passes it to + \gls{capitalisefmtwords} including the \code{*} modifier, if provided} + \field{modifiers}{*} + } + % \ifMFUhyphen + \gcond{if\-MFU\-hyphen} + { + \initval{\cmd{iffalse}} + \providedby{\sty{mfirstuc} v2.03+} + \desc{conditional that determines whether or not hyphens should + be considered word boundaries by the \idx{title-case} commands} + } + % \MFUhyphentrue + \gcmd{MFU\-hyphen\-true} + { + \providedby{\sty{mfirstuc} v2.03+} + \desc{sets \gls{ifMFUhyphen} to true} + } + % \MFUhyphenfalse + \gcmd{MFU\-hyphen\-false} + { + \providedby{\sty{mfirstuc} v2.03+} + \desc{sets \gls{ifMFUhyphen} to false} + } + % \MFUwordbreak + \gcmd{MFU\-word\-break} + { + \providedby{\sty{mfirstuc} v2.07+} + \syntax{\margm{text}}% + \desc{used to markup a character or command that should be + treated as a word break by the \idx{title-case} commands} + } + % \MFUcapword + \gcmd{MFU\-cap\-word} + { + \providedby{\sty{mfirstuc} v2.03+} + \syntax{\margm{text}}% + \desc{uses either \gls{MFUhyphencapword} or \gls{MFUcapwordfirstuc} + depending on \gls{ifMFUhyphen}} + } + % \MFUcapwordfirstuc + \gcmd{MFU\-cap\-word\-first\-uc} + { + \providedby{\sty{mfirstuc} v2.07+} + \syntax{\margm{word}}% + \desc{used by \gls{MFUcapword} and \gls{MFUhyphencapword} to + apply the case-change to the given word. This just does + \code{\gls{makefirstuc}\margm{text}} by default} + \field{seealso}{MFUcapword,MFUhyphencapword} + } + % \MFUhyphencapword + \gcmd{MFU\-hyphen\-cap\-word} + { + \providedby{\sty{mfirstuc} v2.07+} + \syntax{\margm{text}}% + \desc{used by \gls{MFUcapword} to apply \gls{MFUcapwordfirstuc} to + each hyphen-separated word in \meta{text}, if hyphens should + indicate a word-break} + \field{seealso}{ifMFUhyphen,MFUcapword} + } + % \MFUnocap + \gcmd{MFU\-no\-cap} + { + \providedby{\sty{mfirstuc} v1.09+} + \syntax{\margm{word}}% + \desc{locally adds \meta{word} to the \idx{exclusion-word} list for + \gls{capitalisewords}} + \field{seealso}{gMFUnocap,MFUclear} + } + % \gMFUnocap + \gcmd{gMFU\-no\-cap} + { + \providedby{\sty{mfirstuc} v1.09+} + \syntax{\margm{word}}% + \desc{globally adds \meta{word} to the \idx{exclusion-word} list for + \gls{capitalisewords}} + \field{seealso}{MFUnocap,MFUclear} + } + % \MFUclear + \gcmd{MFU\-clear} + { + \providedby{\sty{mfirstuc} v1.09+} + \desc{locally clears the \idx{exclusion-word} list for \gls{capitalisewords}} + \field{seealso}{gMFUnocap,MFUnocap} + } + % PACKAGE OPTIONS + % option grabfirst + \gopt{grab\-first} + {% + \providedby{\sty{mfirstuc} v2.08+} + \note{avoid where possible} + \desc{redefines \gls{glsmakefirstuc} to use \gls{mfugrabfirstuc} + and \gls{mfirstucMakeUppercase} to use \gls{MakeUppercase}} + } + % option expanded + \gopt{expanded} + {% + \providedby{\sty{mfirstuc} v2.08+} + \desc{redefines \gls{glsmakefirstuc} to use \gls{MFUsentencecase} + without inhibiting the expansion of its argument} + } + % option unexpanded + \gopt{unexpanded} + {% + \providedby{\sty{mfirstuc} v2.08+} + \desc{redefines \gls{glsmakefirstuc} to use \gls{MFUsentencecase} + but inhibits expansion of its argument} + } + % COMMANDS: index only + \gcmd{text\dsb title\-case\dsb first:n}{} + \gcmd{text\dsb title\-case:n}{} + \gcmd{text\dsb upper\-case:n}{} + \gcmd{l\dsb text\dsb case\dsb ex\-clude\dsb arg\dsb tl}{} + \gcmd{protect}{} + \gcmd{unexpanded}{} + \gcmd{glsadd}{} + \gcmd{gls}{} + \gcmd{Gls}{} + \gcmd{GLS}{} + \gcmd{glspl}{} + \gcmd{Glspl}{} + \gcmd{GLSpl}{} + \gcmd{Make\-Upper\-case}{}% \MakeUppercase + \gcmd{Make\-Text\-Upper\-case}{}% \MakeTextUppercase + \gcmd{No\-Case\-Change}{}% \NoCaseChange + \gcmd{ensure\-math}{} + \gcmd{begin}{} + \gcmd{end}{} + \gcmd{cite}{} + \gcmd{label}{} + \gcmd{ref}{} + \gcmd{index}{} + \gcmd{space}{} + \gcmd{name\-ref}{}% \nameref + \gcmd{tex\-or\-pdf\-string}{}% \texorpdfstring + \gcmd{pdf\-string\-def\-Dis\-able\-Commands}{}% \pdfstringdefDisableCommands + \gpunc{nbsp}{\name{\code{\textasciitilde}}}% ~ + % packages + \gpkg{mfirst\-uc}{\common} + \gpkg{mfirstuc\dhyphen english}{} + \gpkg{glossaries}{} + \gpkg{glossaries\dhyphen extra}{} + \gpkg{text\-case}{}% textcase + \gpkg{cs\-quotes}{}% csquotes + \gpkg{hyper\-ref}{}% hyperref + % file extensions + \gext{aux}{} + % terms + \gterm{exclusion}{\name{exclusion command}\field{text}{exclusion} + \desc{a command whose argument should be skipped + by the case-changer. The content that follows the command should + have its case-changed instead. See \sectionref{sec:exclusions}}} + \gterm{blocker}{\desc{a command that prohibits case-changing. If + encountered by \gls{makefirstuc}, it won't attempt to apply any + case-changing. See \sectionref{sec:blockers}}} + \gterm{mapping}{\desc{a command that should be substituted by + another, if encountered by \gls{makefirstuc}, instead of applying + a case-change. See \sectionref{sec:mappings}}} + \gterm{sentence-case}{\desc{content that should appear at the + start of a sentence that needs to have its first significant + character converted to \idx{uppercase}. See \sectionref{sec:sentencecase}}} + \gterm{title-case}{\desc{content that needs to appear in a title + that should have each significant word converted to + \idx{sentence-case}. See \sectionref{sec:capitalisewords}}} + \gterm{exclusion-word}{\name{exclusion word} + \desc{a word that shouldn't have its case changed by + \idx{title-case} commands, unless the word occurs at the start}} + \gtermacr{utf8}{UTF-8}{Unicode Transformation Format (8-bit)} + {% + \desc{a variable-width encoding that uses 8-bit code units. This + means that some characters are represented by more that one byte. + \XeLaTeX\ and \LuaLaTeX\ treat the multi-byte sequence as a single + token, but the older \LaTeX\ formats have single-byte tokens, which + can cause complications, although these have mostly been addressed with + the newer kernels introduced over the past few years. Related blog article: + \blog{binary-files-text-files-and-file-encodings/}{Binary Files, + Text Files and File Encodings}} + } + \gterm{semanticcommand}{\name{semantic command} + \desc{essentially, this is a command associated with a + particular element, idea or topic that hides the font + and other stylistic formatting inside its definition. For + example, Latin taxonomy is usually displayed in italic. + Explicitly using font commands, for example + \begin{compactcodebox}\cmd{textit}\marg{Clostridium}\end{compactcodebox} + is syntactic markup. + Whereas defining a command called, say, \cmd{bacteria} that + displays its argument in italics is a semantic command. The + actual styling is hidden and the command relates specifically to + a particular concept. +\begin{codebox} +Syntactic: \cmd{textit}\marg{Clostridium}^^J\codepar +\cmd{newrobustcmd}*\marg{\cmd{bacteria}}[1]{\cmd{emph}\marg{\#1}}\%\newline +Semantic: \cmd{bacteria}\marg{Clostridium} +\end{codebox} + The end result is the same: +\begin{resultbox} +Syntactic: \textit{Clostridium}\glspar +Semantic: \emph{Clostridium} +\end{resultbox} + The advantage with semantic commands is that it's much easier to + change the style, simply by adjusting the command definition. + Note that I've used \cmd{newrobustcmd} to make the semantic + command robust as the style commands can cause a problem if they + expand too soon} + } + % index only + \gidx{punctuation}{} + \gpunc{sym.dollar}{\name{\code{\$}}}% $ + \gidx{uppercase}{} + \gidx{lowercase}{} +} -\begin{document} -\MakeShortVerb{|} - \title{mfirstuc.sty v2.07: -uppercasing first letter} - \author{Nicola L.C. Talbot\\[10pt] +\title{mfirstuc.sty v2.08: +sentence and title casing} +\author{Nicola L.C. Talbot\\[10pt] Dickimaw Books\\ -\url{http://www.dickimaw-books.com/}} - - \date{2021-10-15} - \maketitle - \tableofcontents - - \chapter{Introduction} - \label{sec:intro} +\href{https://www.dickimaw-books.com/}{\nolinkurl{dickimaw-books.com}}} +\date{2022-10-14 +} -The \styfmt{mfirstuc} package was originally part of the -\styfmt{glossaries} bundle for use with commands like \cs{Gls}, but -as the commands provided by \styfmt{mfirstuc} may be used without -\styfmt{glossaries}, the two have been split into separately -maintained packages. +\begin{document} +\maketitle + +\htmlavailable + +\begin{information} +The \sty{mfirstuc} package was originally part of the +\sty{glossaries} bundle (added to \sty{glossaries} v1.12 +in 2008) for use with commands like \gls{Gls}, +which need to have the first letter converted to uppercase +(\idx{sentence-case}), but as the commands provided by +\sty{mfirstuc} may be used without \sty{glossaries}, the two +were split into separately maintained packages in 2015 +(\sty{mfirstuc} v2.0 and \sty{glossaries} v4.18). +\end{information} + +Version 2.08 has reimplemented \gls{makefirstuc} using \LaTeX3 +commands. If there are any compatibility issues, you can rollback to +v2.07: +\begin{codebox} +\cmd{usepackage}\marg{mfirstuc}[=2.07] +\end{codebox} + +\frontmatter +\tableofcontents + +\mainmatter +\chapter{Sentence-Case} +\label{sec:sentencecase} + +There are two \idx{sentence-case} commands provided: \gls{MFUsentencecase} +and \gls{makefirstuc}. A summary of the principle features of +the two commands is given in +\tableref{tab:sentencecasesummary}. + +\begin{table}[htbp] +\caption{Principle features of +\glsfmttext{MFUsentencecase} and \glsfmttext{makefirstuc}} +\label{tab:sentencecasesummary} +\centering +\begin{tabular}{lcc} +\bfseries Feature & \bfseries \gls{MFUsentencecase}[] +& \bfseries \gls{makefirstuc}[]\\ +Can expand? & \proyes & \prono\\ +Supports \idxpl{exclusion}? & \proyes & \proyes\\ +Supports \idxpl{blocker}? & \prono & \proyes\\ +Supports \idxpl{mapping}? & \prono & \proyes\\ +Semantic commands must be robust? & \conyes & \conno +\end{tabular} +\end{table} + +\section{Examples} +\label{sec:sentencecaseex} + +Text only (leading \idx{utf8} now supported): +\begin{coderesult} +\gls{makefirstuc}\marg{élite} / +\gls{MFUsentencecase}\marg{élite} +\tcblower +\makefirstuc{élite} / +\MFUsentencecase{élite} +\end{coderesult} + +Leading \idx{punctuation} is ignored: +\begin{coderesult} +\gls{makefirstuc}\marg{`word'} / +\gls{MFUsentencecase}\marg{`word'} +\tcblower +\makefirstuc{`word'} / +\MFUsentencecase{`word'} +\end{coderesult} +However, if the \idx{punctuation} character is followed by a +\idx{blocker} or \idx{mapping} command, the \idx{punctuation} will +need to be excluded otherwise the command will be treated as an +\idx{exclusion}. If possible, use \idxc{semanticcommand}{semantic +markup} instead of directly including the \idx{punctuation}. + +Fragile commands need to be protected with +\gls{MFUsentencecase}: +\begin{codebox} +\cmd{newcommand}\marg{\cmd{alert}}[1]\marg{\cmd{textcolor}\marg{red}\marg{\cmd{textbf}\marg{\#1}}} +\gls{makefirstuc}\marg{\cmd{alert}\marg{élite}} / +\gls{MFUsentencecase}\marg{\strong{\cmd{protect}}\cmd{alert}\marg{élite}} +\end{codebox} +\begin{resultbox} +\newcommand{\alert}[1]{\textcolor{red}{\textbf{#1}}} +\makefirstuc{\alert{élite}} / +\MFUsentencecase{\protect\alert{élite}} +\end{resultbox} + +\Idxpl{exclusion} are supported by both \gls{makefirstuc} and +\gls{MFUsentencecase}: +\begin{codebox} +\gls{MFUexcl}\marg{\gls+{index}} +\gls{makefirstuc}\marg{\gls{index}\marg{word}example} / +\gls{MFUsentencecase}\marg{\gls{index}\marg{word}example} +\end{codebox} +\begin{resultbox} +\MFUexcl{\index} +\makefirstuc{\index{example}example} / +\MFUsentencecase{\index{example}example} +\end{resultbox} + +\Idxpl{blocker} are only supported by \gls{makefirstuc}. +They are treated as \idxpl{exclusion} with +\gls{MFUsentencecase}, which produces a different result: +\begin{codebox} +\gls{MFUblocker}\marg{\gls+{nameref}} +\gls{makefirstuc}\marg{\gls{nameref}\marg{sec:sentencecase} section} / +\gls{MFUsentencecase}\marg{\gls{nameref}\marg{sec:sentencecase} section} +\end{codebox} +\begin{resultbox} +\MFUblocker{\nameref} +\makefirstuc{\nameref{sec:sentencecase} section} / +\MFUsentencecase{\nameref{sec:sentencecase} section} +\end{resultbox} + +\Idxpl{mapping} are only supported by \gls{makefirstuc}. +They are treated as \idxpl{exclusion} with +\gls{MFUsentencecase}, which produces a different result: +\begin{codebox} +\cmd{newrobustcmd}\marg{\cmd{secref}}[1]\marg{section\glstildechar\cmd{ref}\marg{\#1}} +\cmd{newrobustcmd}\marg{\cmd{Secref}}[1]\marg{Section\glstildechar\cmd{ref}\marg{\#1}} +\gls{MFUaddmap}\marg{\cmd{secref}}\marg{\cmd{Secref}} +\gls{makefirstuc}\marg{\cmd{secref}\marg{sec:sentencecase} example} / +\gls{MFUsentencecase}\marg{\cmd{secref}\marg{sec:sentencecase} example} +\end{codebox} +\begin{resultbox} +\newrobustcmd{\secref}[1]{section~\ref{#1}} +\newrobustcmd{\Secref}[1]{Section~\ref{#1}} +\MFUaddmap{\secref}{\Secref} +\makefirstuc{\secref{sec:sentencecase} example} / +\MFUsentencecase{\secref{sec:sentencecase} example} +\end{resultbox} + +Argument expansion: \gls{MFUsentencecase} expands its argument +and then skips exclusions whereas \gls{makefirstuc} parses its +argument without expansion and then passes the relevant content to +\gls{glsmakefirstuc}. Note that different results will occur with +the \opt{expanded} and \opt{unexpanded} package options. +For example: +\begin{codebox} +\cmd{usepackage}[\opt{expanded}]\marg{mfirstuc} +\cmd{newcommand}\marg{\cmd{testa}}\marg{sample} +\cmd{newcommand}\marg{\cmd{testb}}\marg{\cmd{testa}\cmd{ }test} +\cbeg{document} +\gls{makefirstuc}\marg{\cmd{testb}} / \gls{xmakefirstuc}\marg{\cmd{testb}} / +\gls{emakefirstuc}\marg{\cmd{testb}} / \gls{MFUsentencecase}\marg{\cmd{testb}} +\cend{document} +\end{codebox} +\begin{resultbox} +\newcommand{\testa}{sample}% +\newcommand{\testb}{\testa\ test}% +\renewcommand*{\glsmakefirstuc}[1]{\MFUsentencecase{#1}}% +\makefirstuc{\testb} / \xmakefirstuc{\testb} / +\emakefirstuc{\testb} / \MFUsentencecase{\testb} +\end{resultbox} +With the default \opt{unexpanded} option the result is: +\begin{resultbox} +\newcommand{\testa}{sample} +\newcommand{\testb}{\testa\ test} +\makefirstuc{\testb} / \xmakefirstuc{\testb} / +\emakefirstuc{\testb} / \MFUsentencecase{\testb} +\end{resultbox} +Note that this is different from the result in earlier versions of +\sty{mfirstuc}. +\begin{codebox} +\cmd{usepackage}\marg{mfirstuc}[=v2.07] +\cmd{newcommand}\marg{\cmd{testa}}\marg{sample} +\cmd{newcommand}\marg{\cmd{testb}}\marg{\cmd{testa}\cmd{ }test} +\cbeg{document} +\gls{makefirstuc}\marg{\cmd{testb}} / \gls{xmakefirstuc}\marg{\cmd{testb}} / +\gls{emakefirstuc}\marg{\cmd{testb}} +\cend{document} +\end{codebox} +This produces: +\begin{resultbox} +SAMPLE TEST / SAMPLE test / Sample test +\end{resultbox} +If this old result is required, either use rollback or try +the \opt{grabfirst} option. + +Argument expansion with \idxpl{mapping} (and the default +\opt{unexpanded} option): +\begin{codebox} +\cmd{newrobustcmd}\marg{\cmd{secref}}[1]\marg{section\glstildechar\cmd{ref}\marg{\#1}} +\cmd{newrobustcmd}\marg{\cmd{Secref}}[1]\marg{Section\glstildechar\cmd{ref}\marg{\#1}} +\gls{MFUaddmap}\marg{\cmd{secref}}\marg{\cmd{Secref}} +\cmd{newcommand}\marg{\cmd{testa}}\marg{\cmd{secref}\marg{sec:sentencecase}} +\cmd{newcommand}\marg{\cmd{testb}}\marg{\cmd{testa}\cmd{ }example} +\gls{makefirstuc}\marg{\cmd{testb}} / \gls{xmakefirstuc}\marg{\cmd{testb}} / +\gls{emakefirstuc}\marg{\cmd{testb}} / \gls{MFUsentencecase}\marg{\cmd{testb}} +\end{codebox} +\begin{resultbox} +\newrobustcmd{\secref}[1]{section~\ref{#1}} +\newrobustcmd{\Secref}[1]{Section~\ref{#1}} +\MFUaddmap{\secref}{\Secref} +\newcommand{\testa}{\secref{sec:sentencecase}} +\newcommand{\testb}{\testa\ example} +\makefirstuc{\testb} / \xmakefirstuc{\testb} / +\emakefirstuc{\testb} / \MFUsentencecase{\testb} +\end{resultbox} + +\section{Sentence Case Commands} +\label{sec:sentencecasecmds} + +\cmddef{MFUsentencecase} +This simply uses \gls{texttitlecasefirst:n}, which is provided by +the \LaTeX3 kernel. Note that this fully expands the argument. +If you use this command, ensure that your \idxpl{semanticcommand} are +robust. For example: +\begin{codebox} +\cmd{newrobustcmd}\marg{\cmd{alert}}[1]\marg{\cmd{textcolor}\marg{red}\marg{\cmd{textbf}\marg{\#1}}} +\gls{MFUsentencecase}\marg{\cmd{alert}\marg{sample} text} +\end{codebox} +\begin{resultbox} +\newrobustcmd{\alert}[1]{\textcolor{red}{\textbf{#1}}} +\MFUsentencecase{\alert{sample} text} +\end{resultbox} +Note that the following will fail: +\begin{badcodebox} +\cmd{newcommand}\marg{\cmd{alert}}[1]\marg{\cmd{textcolor}\marg{red}\marg{\cmd{textbf}\marg{\#1}}} +\gls{MFUsentencecase}\marg{\cmd{alert}\marg{sample} text} +\end{badcodebox} +This is because the expansion that's performed before the case-change will result in: +\begin{badcodebox} +\cmd{textcolor}\marg{Red}\marg{\cmd{textbf}\marg{sample}} text +\end{badcodebox} +This triggers an error since \code{Red} isn't a recognised colour +name. + +\cmddef{makefirstuc} +This is the original command provided by \sty+{mfirstuc}, which was +written to assist sentence-casing in the \sty{glossaries} package +and had to take markup into account. It parses its argument to try +to determine which part needs the case-change. The actual +case-change is performed by \gls{glsmakefirstuc}. + +As from v2.08, the definition of \gls{makefirstuc} has been updated to use \LaTeX3 +code, but the argument is still parsed, which allows for non-robust +\idxpl{semanticcommand}, and now also takes \idxpl{blocker} and \idxpl{mapping} into +account. For example: +\begin{codebox} +\cmd{newcommand}\marg{\cmd{alert}}[1]\marg{\cmd{textcolor}\marg{red}\marg{\cmd{textbf}\marg{\#1}}} +\gls{makefirstuc}\marg{\cmd{alert}\marg{sample} text} +\end{codebox} +\begin{resultbox} +\newcommand{\alert}[1]{\textcolor{red}{\textbf{#1}}} +\makefirstuc{\alert{sample} text} +\end{resultbox} + +The rules used when parsing \code{\gls{makefirstuc}\margm{text}} are as follows: +\begin{enumerate} +\item if \meta{text} is empty do nothing; -\begin{important} -The commands described here all have limitations. To minimise -problems, use text-block style semantic commands with one argument -(the text that requires case-changing), and avoid scoped -declarations. -\end{important} +\item if \meta{text} consists of a single item or starts +with a group do \code{\gls{glsmakefirstuc}\margm{text}}; -Here are some examples of semantic commands: -\begin{enumerate} -\item Quoted material: -\begin{verbatim} -\newcommand{\qt}[1]{``#1''} -\end{verbatim} -(or use the \styfmt{csquotes} package). With this, the following -works: -\begin{verbatim} -\makefirstuc{\qt{word}} -\end{verbatim} -This produces: -\begin{display} -\makefirstuc{\qt{word}} -\end{display} -Whereas -\begin{verbatim} -\makefirstuc{``word''} -\end{verbatim} -fails (no case-change and double open quote becomes two single open -quotes): -\begin{display} -\makefirstuc{``word''} -\end{display} - -\item Font styles or colours: -\begin{verbatim} -\newcommand*{\alert}[1]{\textcolor{red}{#1}} -\end{verbatim} -Now the following is possible: -\begin{verbatim} -\makefirstuc{\alert{word}} -\end{verbatim} -This produces -\begin{display} -\newcommand*{\alert}[1]{\textcolor{red}{#1}}% -\makefirstuc{\alert{word}} -\end{display} -Note that \verb|\makefirstuc{\textcolor{red}{word}}| fails -(with an error) because the case-changing interferes with the label. -\end{enumerate} +\item if \meta{text} starts with a command \meta{cs}: -Define these semantic commands robustly if you intend using -any of the commands that fully expand their argument -(\cs{emakefirstuc}, \cs{ecapitalisewords} and -\cs{ecapitalisefmtwords}). - -\chapter{Capitalising the First Letter of a Word} -\label{sec:makefirstuc} - -A simple word can be capitalised just using the standard \LaTeX\ -upper casing command. For example, -\begin{verbatim} -\MakeUppercase word -\end{verbatim} -but for commands like \cs{Gls} the word may be embedded within the -argument of another command, such as a~font changing command. This -makes things more complicated for a~general purpose solution, so -the \styfmt{mfirstuc} package provides: -\begin{definition}[\DescribeMacro{\makefirstuc}] -\cs{makefirstuc}\marg{stuff} -\end{definition} -This makes the first object of -\meta{stuff} upper case unless \meta{stuff} starts with a control -sequence followed by a non-empty group, in which case the first -object in the group is converted to upper case. -\textbf{No expansion is performed on the argument.} - -If \meta{stuff} starts with punctuation that should be skipped over, -use: -\begin{definition}[\DescribeMacro\MFUskippunc] -\cs{MFUskippunc}\marg{punctuation} -\end{definition} + \begin{enumerate} + \item if \meta{cs} is \gls{protect}, skip it and continue to + the next step where the command \meta{cs} under inspection + is now the one that follows \gls{protect}: -\begin{important} -If \meta{stuff} starts with a control sequence that takes more than -one argument, the case-changing will always be applied to the -\emph{first} argument. If the text that requires the case change is -in one of the other arguments, you must hide the earlier arguments -in a wrapper command. For example, instead of \verb|\textcolor{red}{text}| -you need to define, say, \verb|\red| as \verb|\color{red}| and use -\verb|\red{text}|. -\end{important} + \item if \meta{cs} has been identified as a \idx{blocker}, just do + \meta{text} (that is, no case-change is applied); -Examples: -\begin{itemize} -\item |\makefirstuc{abc}| produces \makefirstuc{abc}. + \item if \meta{cs} isn't followed by a group then do + \code{\gls{glsmakefirstuc}\margm{text}}; -\item |\makefirstuc{\emph{abc}}| produces \makefirstuc{\emph{abc}} -(\ics{MakeUppercase} has been applied to the letter \qt{a} rather -than \cs{emph}). Note however that -\begin{verbatim} -\makefirstuc{{\em abc}} -\end{verbatim} -produces \makefirstuc{{\em abc}} (first object is |{\em abc}| so -this is equivalent to |\MakeUppercase{\em abc}|), and -\begin{verbatim} -{\makefirstuc{\em abc}} -\end{verbatim} -produces {\makefirstuc{\em abc}} (|\em| doesn't have an argument -therefore first object is |\em| and so is equivalent to -|{\MakeUppercase{\em}abc}|). + \item otherwise assume the format is \code{\meta{cs}\margm{arg}\meta{following}} + (where \meta{following} may be empty) and then: -\item |\makefirstuc{{\'a}bc}| produces \makefirstuc{{\'a}bc}. + \begin{enumerate} + \item if \meta{cs} has been \idxc{mapping}{mapped} to + \meta{Cs} then do \code{\meta{Cs}\margm{arg}\meta{following}}; -\item |\makefirstuc{\ae bc}| produces \makefirstuc{\ae bc}. + \item if \meta{cs} has been identified as an \idx{exclusion}, + do \code{\meta{cs}\margm{arg}\gls{makefirstuc}\margm{following}}; -\item |\makefirstuc{{\ae}bc}| produces \makefirstuc{{\ae}bc}. + \item otherwise do \code{\meta{cs}\marg{\gls{makefirstuc}\margm{arg}}\meta{following}}. + \end{enumerate} -\item |\makefirstuc{{ä}bc}| produces \makefirstuc{{ä}bc}. + \end{enumerate} -\item |\makefirstuc{\MFUskippunc{'}tis the season}| produces -\makefirstuc{\MFUskippunc{'}tis the season}. +\item otherwise do \code{\gls{glsmakefirstuc}\margm{text}}. +\end{enumerate} -\end{itemize} +Note that the above algorithm uses recursion. The termination points +are: don't implement a change, replace a command with another +command, or apply the case-change via \gls{glsmakefirstuc}. + +For convenience, the following commands are also provided: +\cmddef{xmakefirstuc} +This is simply a shortcut for: +\begin{compactcodebox} +\cmd{expandafter}\gls{makefirstuc}\cmd{expandafter}\margm{text} +\end{compactcodebox} +This ensures the first token in \meta{text} is expanded before being +passed to \gls{makefirstuc}. + +\cmddef{emakefirstuc} +This fully expands its argument before passing it to +\gls{makefirstuc}. For example: +\begin{codebox} +\cmd{newcommand}\marg{\cmd{test}}[1]\marg{sample \#1} +\cmd{newcommand}\marg{\cmd{tmp}}\marg{\cmd{test}\marg{text}} +\gls{makefirstuc}\marg{\cmd{tmp}} / +\gls{xmakefirstuc}\marg{\cmd{tmp}} / +\gls{emakefirstuc}\marg{\cmd{tmp}} +\end{codebox} +\begin{resultbox} +\newcommand{\test}[1]{sample #1} +\newcommand{\tmp}{\test{text}} +\makefirstuc{\tmp} / +\xmakefirstuc{\tmp} / +\emakefirstuc{\tmp} +\end{resultbox} +If you don't have any mappings or blockers set up, it's simpler to +use \gls{MFUsentencecase} instead of \gls{emakefirstuc}. -Note that non-Latin or accented characters appearing at the -start of the text should be placed in a group (even if you are -using the \sty{inputenc} package). The reason for this restriction -is detailed in \sectionref{sec:utf8}. +\begin{important} +With \gls{emakefirstuc}, mappings and blockers will only be +detected if they are robust or protected, otherwise they will expand too soon to +be detected. +\end{important} -\textbf{New to version 2.04:} There is now limited support for -UTF-8 characters with the \sty{inputenc} package, provided that -you load \sty{datatool-base} (at least v2.24) before -\styfmt{mfirstuc} (\sty{datatool-base} is loaded automatically with newer versions -of \sty{glossaries}). If available -\sty{mfirstuc} will now use \sty{datatool-base}'s -\ics{dtl@getfirst@UTFviii} command which is still experimental. -See the \styfmt{datatool} manual for further details. +\cmddef{glsmakefirstuc} +This command is used by \gls{makefirstuc} to perform the +case-change. The \qt{gls} prefix is for historical reasons as the original code +was part of the \sty{glossaries} package. With the default +\opt{unexpanded} option, this command is defined as: +\begin{compactcodebox} +\gls{MFUsentencecase}\marg{\gls+{unexpanded}\margm{text}} +\end{compactcodebox} +The use of \gls{unexpanded} inhibits the expansion of \meta{text} +that would otherwise occur. This allows \gls{makefirstuc} to +maintain as much backward-compatibility with version 2.07 as +possible. This is particularly important when using the +\sty{glossaries} package with a style that automatically converts +the description to \idx{sentence-case}, as there may well be +documents with complex descriptions that contain fragile commands. + +The \opt{expanded} package option will redefine \gls{glsmakefirstuc} +to use \gls{MFUsentencecase} without \gls{unexpanded}. The +\opt{grabfirst} package option will redefine \gls{glsmakefirstuc} +to use \gls{mfugrabfirstuc} to emulates the behaviour of +\gls{glsmakefirstuc} in v2.07 and below without using rollback. + +\cmddef{mfugrabfirstuc} +This robust command is provided to emulate v2.07 and its use is discouraged. +Note that you may still have different results compared to v2.07, so +you may need to use rollback instead. (Note that the \opt{grabfirst} option +additionally redefines \gls{mfirstucMakeUppercase} to +\gls{MakeUppercase}, which you will also need.) + +This applies \gls{mfirstucMakeUppercase} to the first token in \meta{text} +and leaves the remainder unchanged. This won't work if \meta{text} +starts with a \gls{utf8} character unless you use \XeLaTeX\ or +\LuaLaTeX, so avoid using this method where possible. For example: +\begin{codebox} +\cmd{renewcommand}\marg{\gls{mfirstucMakeUppercase}}[1]\marg{\comment{} + \gls{MakeUppercase}\marg{\#1}\comment{} +} +\gls{mfugrabfirstuc}\marg{sample} +\end{codebox} +This is equivalent to: +\begin{codebox} +\gls{mfirstucMakeUppercase}\marg{s}ample +\end{codebox} +Whereas +\begin{unicodebox} +\cmd{renewcommand}\marg{\gls{mfirstucMakeUppercase}}[1]\marg{\comment{} + \gls{MakeUppercase}\marg{\#1}\comment{} +} +\gls{mfugrabfirstuc}\marg{\'elite} +\end{unicodebox} +only works with \XeLaTeX\ or \LuaLaTeX. -\begin{verbatim} -\documentclass{article} +\begin{warning} +As with earlier implementations of \gls{makefirstuc} that +tried to only apply the case-change to the first token, +this won't produce the desired result if the argument starts with a +punctuation character. +\end{warning} -\usepackage[T1]{fontenc} -\usepackage[utf8]{inputenc} +For example: +\begin{codebox} +\gls{mfugrabfirstuc}\marg{`sample'} +\end{codebox} +This is equivalent to: +\begin{compactcodebox} +\gls{mfirstucMakeUppercase}\marg{`}sample' +\end{compactcodebox} +so no case-change is applied. + +\section{Exclusions} +\label{sec:exclusions} + +\begin{information} +Exclusions will apply to all \LaTeX3 case-changing commands, so will +also affect \gls{mfirstucMakeUppercase}, but this is generally +desirable. +\end{information} + +\cmddef{MFUexcl} +Identifies the text-block command \code{\meta{cs}\margm{arg}} as +an \idx{exclusion}. That is, one that should have its argument +excluded from a case-change. + +Internally, \gls{MFUexcl} adds \meta{cs} to \LaTeX3's exclusion list +\gls{ltextcaseexcludeargtl}, which means that \gls{MFUsentencecase} +will skip the command and its argument and apply the case-change to +the following content. Some common commands (\gls{begin} \gls{cite} +\gls{end} \gls{label} and \gls{ref}) are automatically added by the +\LaTeX3 kernel. +The exclusions are also recognised by \gls{makefirstuc} when it +parses its argument. + +\begin{information} +The command \gls{NoCaseChange} is automatically treated as an +exclusion by the \LaTeX3 case-changing commands with recent \LaTeX\ +kernels. You may want to add it as a blocker for \gls{makefirstuc} +and keep \gls{MFUskippunc} for exclusions. + +Note that \gls{ensuremath} is added as an exclusion by \sty{mfirstuc} otherwise +\gls{makefirstuc} will pass its argument to \gls{MFUsentencecase}, +which will cause a problem. +\end{information} + +Another way of identifying content that should be excluded with +\gls{makefirstuc} is to encapsulate it with: +\cmddef{MFUskippunc} +This is a robust command that simply does its argument and is +automatically added to the exclusion list. This may be used for +cases where the excluded command isn't a simple text-block command +that only has one mandatory argument or where leading punctuation is +followed by a \idx{blocker} or \idx{mapping}. + +The command name stems from earlier versions where leading +\idx{punctuation} needed to be skipped. This is no longer necessary, +but the command remains as a general purpose robust exclusion command. + +For example, \gls{glsadd} (provided by \sty{glossaries}) should have +its argument skipped, since its argument is a label, so the +following will ensure that \code{\gls{glsadd}\margm{label}} will be +skipped, and the case-change will be applied to the following text +for both \gls{MFUsentencecase} and \gls{makefirstuc}. +\begin{codebox} +\gls{MFUexcl}\marg{\gls{glsadd}} +\gls{makefirstuc}\marg{\gls{glsadd}\marg{ex}some text} +\gls{MFUsentencecase}\marg{\gls{glsadd}\marg{ex}some text} +\end{codebox} +This will be equivalent to: +\begin{compactcodebox} +\gls{glsadd}\marg{ex}Some text +\end{compactcodebox} +However, \gls{glsadd} can take an optional argument which, if +present, will cause a problem. For example: +\begin{badcodebox} +\gls{MFUexcl}\marg{\gls{glsadd}} +\gls{makefirstuc}\marg{\gls{glsadd}\oarg{counter=section}\marg{ex}some text} +\gls{MFUsentencecase}\marg{\gls{glsadd}\oarg{counter=section}\marg{ex}some text} +\end{badcodebox} +Both commands will cause the following error: +\begin{transcript} +! Package glossaries Error: Glossary entry `\nlctopensqbracket' has not been defined. +\end{transcript} +This is because the open square bracket is assumed to be the +argument of \gls{glsadd}, so this effectively becomes: +\begin{compactcodebox} +\gls{glsadd}\marg{\nlctopensqbracket}Counter=section\nlctclosesqbracket exsome text +\gls{glsadd}\marg{\nlctopensqbracket}Counter=section\nlctclosesqbracket exsome text +\end{compactcodebox} +which means that now \code{\nlctopensqbracket} is considered the label and everything +that follows is just text. + +For this situation to work, you need to encapsulate the problematic +content with an exclusion command, such as \gls{NoCaseChange} or \gls{MFUskippunc}: +\begin{codebox} +\gls{makefirstuc}\marg{\gls{MFUskippunc}\marg{\gls{glsadd}\oarg{counter=section}\marg{ex}}some text} +\end{codebox} +This will also work with \gls{MFUsentencecase} because +\sty{mfirstuc} automatically adds \gls{MFUskippunc} to the exclusion +list. + +\begin{information} +As from \sty{glossaries} v4.50, \gls{glsadd} is automatically added +as an exclusion, but be aware of the problem with using the optional +argument, as described above. +\end{information} + +\Idx{punctuation} characters are skipped by \gls{MFUsentencecase}. +For example: +\begin{coderesult} +\gls{MFUsentencecase}\marg{`word'} +\tcblower +\MFUsentencecase{`word'} +\end{coderesult} +However, leading \idx{punctuation} will result in \gls{makefirstuc} +passing its entire argument to \gls{MFUsentencecase} (since the +argument doesn't start with \code{\meta{cs}\margm{arg}}), which +means that \gls{makefirstuc} won't detect any \idx{blocker} or +\idx{mapping}. -\usepackage{datatool-base}[2016/01/12]% v2.24+ -\usepackage{mfirstuc} +For example: +\begin{codebox} +\gls{MFUblocker}\marg{\gls+{nameref}} +\cmd{newcommand}*\marg{\cmd{qt}}[1]\marg{``\#1''} +\gls{makefirstuc}\marg{``\gls{nameref}\marg{sec:sentencecase} section''} / +\gls{makefirstuc}\marg{\gls{MFUskippunc}\marg{``}\gls{nameref}\marg{sec:sentencecase} section''} / +\gls{makefirstuc}\marg{\cmd{qt}\marg{\gls{nameref}\marg{sec:sentencecase} section}} +\end{codebox} +\begin{resultbox} +\MFUblocker{\nameref} +\makefirstuc{``\nameref{sec:sentencecase} section''} / +\makefirstuc{\MFUskippunc{``}\nameref{sec:sentencecase} section''} / +\makefirstuc{\qt{\nameref{sec:sentencecase} section}} +\end{resultbox} +If you are using a package such as \sty{csquotes}, bear in mind that +if the command is followed by an asterisk (a \qt{starred command}) +or an optional argument then it won't fit the expected +\code{\meta{cs}\margm{arg}} format and unexpected results will occur. + +\section{Blockers} +\label{sec:blockers} + +A \idx{blocker} is a command that prevents any case-change if it occurs at +the start of \gls{makefirstuc} or after the argument of an +\idx{exclusion}. Blockers are not supported by +\gls{MFUsentencecase} but are instead treated as exclusions. + +\cmddef{MFUblocker} +Identifies \meta{cs} as a \idx{blocker}. Since \idxpl{blocker} +aren't supported by \gls{MFUsentencecase}, this automatically +implements \code{\gls{MFUexcl}\margm{cs}} to protect its argument +from \gls{MFUsentencecase}, but it won't prevent subsequent content +from being changed. -\begin{document} -\makefirstuc{élite} -\end{document} -\end{verbatim} -(Package ordering is important.) +For example: +\begin{codebox} +\gls{MFUblocker}\marg{\gls+{nameref}} +\gls{makefirstuc}\marg{\gls{nameref}\marg{sec:sentencecase} section} +\end{codebox} +\begin{resultbox} +\MFUblocker{\nameref} +\makefirstuc{\nameref{sec:sentencecase} section} +\end{resultbox} + +In the following, the \idx{blocker} isn't detected by +\gls{makefirstuc} because the content doesn't start with +\code{\meta{cs}\margm{arg}} or +\code{\cmd{protect}\meta{cs}\margm{arg}}. This means that the entire +content is passed to \gls{MFUsentencecase} which treats +\gls{nameref} as an \idx{exclusion}: +\begin{codebox} +\gls{MFUblocker}\marg{\gls{nameref}} +\gls{makefirstuc}\marg{\cmd{relax}\gls{nameref}\marg{sec:sentencecase} section} +\end{codebox} +\begin{resultbox} +\MFUblocker{\nameref} +\makefirstuc{\relax\nameref{sec:sentencecase} section} +\end{resultbox} \begin{important} -In version 1.02 of \styfmt{mfirstuc}, a bug fix resulted in a change -in output if the first object is a control sequence followed by -an empty group. Prior to version 1.02, |\makefirstuc{\ae{}bc}| -produced \ae Bc. However as from version 1.02, it now produces -\AE bc. +If a \idxc{blocker}{blocking command} is inside the definition of +another command, it won't be visible to \gls{makefirstuc} unless +the other command is expanded before applying \gls{makefirstuc}. +For example, by using \gls{xmakefirstuc} or \gls{emakefirstuc}. +If it doesn't get expanded until after it has been passed to +\gls{MFUsentencecase}, then it will be treated as an \idx{exclusion} +instead. \end{important} -Note also that -\begin{verbatim} -\newcommand{\abc}{abc} -\makefirstuc{\abc} -\end{verbatim} -produces: ABC. This is because the first object in the argument of -\cs{makefirstuc} is \cs{abc}, so it does |\MakeUppercase{\abc}|. -Whereas: -\begin{verbatim} -\newcommand{\abc}{abc} -\expandafter\makefirstuc\expandafter{\abc} -\end{verbatim} -produces: Abc. There is a short cut command which will do this: -\begin{definition}[\DescribeMacro{\xmakefirstuc}] -\cs{xmakefirstuc}\marg{stuff} -\end{definition} -This is equivalent to \cs{expandafter}\cs{makefirstuc}\cs{expandafter}\marg{stuff}. So -\begin{verbatim} -\newcommand{\abc}{abc} -\xmakefirstuc{\abc} -\end{verbatim} -produces: -\newcommand{\abc}{abc}% -\xmakefirstuc{\abc}. +Recent \LaTeX\ kernels provide \gls{NoCaseChange} and automatically +add it as an \idx{exclusion}. You may want to add it as a +\idx{blocker} for \gls{makefirstuc}. For example: +\begin{codebox} +\gls{makefirstuc}\marg{\gls{ensuremath}\marg{\cmd{alpha}}-particle} / +\gls{makefirstuc}\marg{\idx{dollar}\cmd{alpha}\idx{dollar}-particle} / +\gls{MFUsentencecase}\marg{\gls{ensuremath}\marg{\cmd{alpha}}-particle} / +\gls{MFUsentencecase}\marg{\idx{dollar}\cmd{alpha}\idx{dollar}-particle} +\codepar +\gls{MFUblocker}\marg{\gls{NoCaseChange}}\comment{} +\gls{makefirstuc}\marg{\gls{ensuremath}\marg{\cmd{alpha}}-particle} / +\gls{makefirstuc}\marg{\gls{NoCaseChange}\marg{\idx{dollar}\cmd{alpha}\idx{dollar}}-particle} / +\gls{MFUsentencecase}\marg{\gls{ensuremath}\marg{\cmd{alpha}}-particle} / +\gls{MFUsentencecase}\marg{\gls{NoCaseChange}\marg{\idx{dollar}\cmd{alpha}\idx{dollar}}-particle} +\end{codebox} +Note that \sty{mfirstuc} adds \gls{ensuremath} as an exclusion so +\gls{makefirstuc} will skip it. Whereas the example above that +starts with \idx{dollar} will have the entire argument passed to +\gls{MFUsentencecase}, which skips the maths content. +In the first paragraph, \gls{NoCaseChange} is only an +\idx{exclusion}, but in the second paragraph it's also a +\idx{blocker}. +\begin{resultbox} +Exclusion: +\makefirstuc{\ensuremath{\alpha}-particle} / +\makefirstuc{$\alpha$-particle} / +\MFUsentencecase{\ensuremath{\alpha}-particle} / +\MFUsentencecase{$\alpha$-particle} + +Blocker: +\MFUblocker{\NoCaseChange}% +\makefirstuc{\ensuremath{\alpha}-particle} / +\makefirstuc{\NoCaseChange{$\alpha$}-particle} / +\MFUsentencecase{\ensuremath{\alpha}-particle} / +\MFUsentencecase{\NoCaseChange{$\alpha$}-particle} +\end{resultbox} + +\section{Mappings} +\label{sec:mappings} + +A \idx{mapping} indicates that one command should be substituted for +another, instead of applying a case-change. The assumption is that +the substituted command should perform the case-change instead. +\Idxpl{mapping} are not supported by \gls{MFUsentencecase} +but are instead treated as exclusions. + +\cmddef{MFUaddmap} +Identifies a mapping which indicates that \gls{makefirstuc} should +replace \meta{cs1} with \meta{cs2} and not apply a case-change. +This automatically implements: +\begin{compactcodebox} +\gls{MFUexcl}\margm{cs1}\gls{MFUblocker}\margm{cs2} +\end{compactcodebox} +This means that \meta{cs2} is identified as a \idx{blocker} (since +it's assumed to already be a \idx{sentence-case} command) and +\meta{cs1} is identified as an \idx{exclusion} to protect its +argument from \gls{MFUsentencecase}, which doesn't support +\idxpl{mapping}. + +\begin{information} +If either \meta{cs1} or \meta{cs2} is empty, no mapping is established, but an +\idx{exclusion} or \idx{blocker} will be set for the non-empty argument. +\end{information} + +For example (with \sty{glossaries}): +\begin{codebox} +\gls{MFUaddmap}\marg{\gls+{gls}}\marg{\gls+{Gls}} +\gls{makefirstuc}\marg{\gls{gls}\marg{ex} some text} +\end{codebox} +This will be converted to: +\begin{compactcodebox} +\gls{Gls}\marg{ex} some text +\end{compactcodebox} +Note that this and similar \idxpl{mapping} are automatically added +in \sty{glossaries} v4.50+ and \sty{glossaries-extra} v1.49+. \begin{important} -\cs{xmakefirstuc} only performs one level expansion on the -\emph{first} object in its argument. It does not fully expand the entire -argument. +If a \idxc{mapping}{mapped command} is inside the definition of +another command, it won't be visible to \gls{makefirstuc} unless +the other command is expanded before applying \gls{makefirstuc}. +For example, by using \gls{xmakefirstuc} or \gls{emakefirstuc}. +If it doesn't get expanded until after it has been passed to +\gls{MFUsentencecase}, then it will be treated as an \idx{exclusion} +instead. \end{important} -As from version 1.10, there is now a command that fully expands the -entire argument before applying \cs{makefirstuc}: -\begin{definition}[\DescribeMacro\emakefirstuc] -\cs{emakefirstuc}\marg{text} -\end{definition} +\section{Package Options} +\label{sec:pkgoptions} -Examples: -\begin{verbatim} -\newcommand{\abc}{\xyz a} -\newcommand{\xyz}{xyz} -No expansion: \makefirstuc{\abc}. -First object one-level expansion: \xmakefirstuc{\abc}. -Fully expanded: \emakefirstuc{\abc}. -\end{verbatim} -produces: -\renewcommand{\abc}{\xyz a}% -\newcommand{\xyz}{xyz} -No expansion: \makefirstuc{\abc}. -First object one-level expansion: \xmakefirstuc{\abc}. -Fully expanded: \emakefirstuc{\abc}. - -If you use \styfmt{mfirstuc} without the \sty{glossaries} package, -the standard \cs{MakeUppercase} command is used. If used with -\sty{glossaries}, \ics{MakeTextUppercase} (defined by the \sty{textcase} -package) is used instead. If you are using \styfmt{mfirstuc} -without the \styfmt{glossaries} package and want to use -\ics{MakeTextUppercase} instead, you can redefine -\begin{definition}[\DescribeMacro\glsmakefirstuc] -\cs{glsmakefirstuc}\marg{text} -\end{definition} -For example: -\begin{verbatim} -\renewcommand{\glsmakefirstuc}[1]{\MakeTextUppercase #1} -\end{verbatim} -Remember to also load \sty{textcase} (\styfmt{glossaries} loads this -automatically). +\optiondef{expanded} +Redefines \gls{glsmakefirstuc} to simply use \gls{MFUsentencecase}. -\chapter{Capitalise the First Letter of Each Word in a Phrase or Sentence (Title Case)} +\optiondef{unexpanded} +Redefines \gls{glsmakefirstuc} to use \gls{MFUsentencecase} +without expanding its argument. + +\optiondef{grabfirst} +Redefines \gls{glsmakefirstuc} to use \gls{mfugrabfirstuc} and also +redefines \gls{mfirstucMakeUppercase} to use \gls{MakeUppercase}. + +This option is best avoided and is only provided to emulate the v2.07 +behaviour of \gls{glsmakefirstuc}. However, you may still have +different results compared to v2.07, so you may need to use rollback +instead. + +\chapter{Title-Case} \label{sec:capitalisewords} -New to mfirstuc v1.06: -\begin{definition}[\DescribeMacro{\capitalisewords}] -\cs{capitalisewords}\marg{text} -\end{definition} -This command applies \ics{makefirstuc} to each word in \meta{text} +The \idx{title-case} commands are designed to convert the first letter of each +word in a phrase to uppercase. These commands are robust. +\cmddef{capitalisewords} +This command applies a \idx{sentence-case} command to each word in \meta{text} where the space character is used as the word separator. Note that -it has to be a plain space character, not another form of space, -such as \verb|~| or \cs{space}. Note that no expansion is performed -on \meta{text}. See \sectionref{sec:nocap} for excluding -words (such as \qt{of}) from the case-changing. - -The actual capitalisation of each word is done using -\begin{definition}[\DescribeMacro\MFUcapwordfirstuc] -\cs{MFUcapwordfirstuc}\marg{word} -\end{definition} -This just does \cs{makefirstuc}\marg{word} by default. -There's a conditional that determines whether or not to consider a -hyphen a word break: -\begin{definition}[\DescribeMacro\ifMFUhyphen] -\cs{ifMFUhyphen} -\end{definition} - -If you want to title case each part of -a compound word containing hyphens, you can enable this using -\begin{definition}[\DescribeMacro\MFUhyphentrue] -\cs{MFUhyphentrue} -\end{definition} -or switch it back off again using: -\begin{definition}[\DescribeMacro\MFUhyphenfalse] -\cs{MFUhyphenfalse} -\end{definition} -Compare -\begin{verbatim} -\capitalisewords{server-side includes} -\end{verbatim} -which produces: -\begin{display} -\capitalisewords{server-side includes} -\end{display} -with -\begin{verbatim} -\MFUhyphentrue -\capitalisewords{server-side includes} -\end{verbatim} -which produces: -\begin{display} -\MFUhyphentrue -\capitalisewords{server-side includes} -\end{display} -Note that this won't apply exceptions to each part of the hyphenated -word. - -For other punctuation you need to markup the character with: -\begin{definition}[\DescribeMacro\MFUwordbreak] -\cs{MFUwordbreak}\marg{punctuation} -\end{definition} +it has to be an ordinary space character, not another form of space, +such as \idx{nbsp} or \gls{space}. Note that no expansion is performed +on \meta{text}. For example: -\begin{verbatim} -\capitalisewords{a big\MFUwordbreak{/}small idea} -\end{verbatim} -which produces: -\begin{display} +\begin{coderesult} +\gls{capitalisewords}\marg{a sample phrase} +\tcblower +\capitalisewords{a sample phrase} +\end{coderesult} +See \sectionref{sec:nocap} for excluding words (such as \qt{of}) +from the case-changing. + +\begin{information} +This isn't the same as the \LaTeX3 command \gls{texttitlecase:n}, +which converts the first letter to \idx{uppercase} and all other +letters to \idx{lowercase}. +\end{information} + +For convenience, there are shortcut commands if expansion is +required before parsing the argument: +\cmddef{xcapitalisewords} +This is a shortcut for: +\begin{compactcodebox} +\cmd{expandafter}\gls{capitalisewords}\cmd{expandafter}\margm{text} +\end{compactcodebox} +\cmddef{ecapitalisewords} +This fully expands \meta{text} before passing it to +\gls{capitalisewords}. + +The parser used by \gls{capitalisewords} first splits up the text on +each space character. Each of these space-separated words may +actually be a compound, so further parsing is performed on each +\qt{word}. The divisions within the compound word should be marked +up with: +\cmddef{MFUwordbreak} +For example: +\begin{coderesult} +\gls{capitalisewords}\marg{a +big\gls{MFUwordbreak}\marg{/}small idea} +\tcblower \capitalisewords{a big\MFUwordbreak{/}small idea} -\end{display} -In this case, exceptions are applied. For example, if -\sty{mfirstuc-english} is loaded then: -\begin{verbatim} -\capitalisewords{one and\MFUwordbreak{/}or another} -\end{verbatim} -produces: -\begin{display} -\MFUnocap{and}\MFUnocap{or}% -\capitalisewords{one and\MFUwordbreak{/}or another} -\end{display} -Note that you can't hide \cs{MFUwordbreak} inside a command or group. +\end{coderesult} +Each sub-word within the compound word is encapsulated with: +\cmddef{MFUcapword} +Since it's inconvenient to have to markup every hyphen, +\gls{MFUcapword} can be enabled to check for hyphens. + +\cmddef{ifMFUhyphen} +This conditional determines whether or not \gls{MFUcapword} should +consider a hyphen a word break. If this conditional is true, then +\gls{MFUcapword} will encapsulate its argument with: +\cmddef{MFUhyphencapword} +This will parse \meta{text} for hyphen characters and apply the case +change to each hyphen-separated word. Otherwise \gls{MFUcapword} +will treat its argument as a single word. + +The conditional can be set to true with: +\cmddef{MFUhyphentrue} +and switched back off with: +\cmddef{MFUhyphenfalse} -Exceptions aren't applied if \cs{MFUwordbreak} occurs before the -first space. For example: -\begin{verbatim} -\MFUnocap{a}\MFUnocap{the}% -\capitalisewords{a\MFUwordbreak{/}the something} -\end{verbatim} -produces: -\begin{display} -\MFUnocap{a}\MFUnocap{the}% -\capitalisewords{a\MFUwordbreak{/}the something} -\end{display} +For example: +\begin{codebox} +\gls{capitalisewords}\marg{server-side includes} / +\gls{MFUhyphentrue} +\gls{capitalisewords}\marg{server-side includes} +\end{codebox} +\begin{resultbox} +\capitalisewords{server-side includes} / +\MFUhyphentrue +\capitalisewords{server-side includes} +\end{resultbox} + +The actual case-change of each word is performed with: +\cmddef{MFUcapwordfirstuc} +This defaults to \code{\gls{makefirstuc}\margm{word}} but may be +redefined to use \gls{MFUsentencecase}, if preferred. + +\begin{important} +Hyphens and \gls{MFUwordbreak} must be visible to the parser that +searches for word breaks. This means they won't be detected if they +are within a group or in the definition of a command. +\end{important} Formatting for the entire phrase must go outside -\cs{capitalisewords} (unlike \cs{makefirstuc}). Compare: -\begin{verbatim} -\capitalisewords{\textbf{a sample phrase}} -\end{verbatim} -which produces: -\begin{display} -\capitalisewords{\textbf{a sample phrase}} -\end{display} -with: -\begin{verbatim} -\textbf{\capitalisewords{a sample phrase}} -\end{verbatim} -which produces: -\begin{display} -\textbf{\capitalisewords{a sample phrase}} -\end{display} - -As from version 2.03, there is now a command for phrases that may -include a formatting command: -\begin{definition} -\cs{capitalisefmtwords}\marg{phrase} -\end{definition} -where \meta{phrase} may be just words (as with \cs{capitalisewords}) -or may be entirely enclosed in a formatting command in the form -\begin{alltt} -\cs{capitalisefmtwords}\{\meta{cs}\marg{phrase}\} -\end{alltt} -or contain formatted sub-phrases -\begin{alltt} -\cs{capitalisefmtwords}\{\meta{words} \meta{cs}\marg{sub-phrase} \meta{words}\} -\end{alltt} -Avoid scoped declarations. +\gls{capitalisewords} (unlike \gls{makefirstuc}). +For example: +\begin{codebox} +\gls{capitalisewords}\marg{\cmd{emph}\marg{a sample phrase}} / +\cmd{emph}\marg{\gls{capitalisewords}\marg{a sample phrase}} +\end{codebox} +\begin{resultbox} +\capitalisewords{\emph{a sample phrase}} / +\emph{\capitalisewords{a sample phrase}} +\end{resultbox} + +If your phrase is likely to contain formatting commands, you can instead use: +\cmddef{capitalisefmtwords} +where \meta{text} may be just words (as with \gls{capitalisewords}): +\begin{compactcodebox} +\gls{capitalisefmtwords}\margm{words} +\end{compactcodebox} +or may be entirely enclosed in a formatting command in the form: +\begin{compactcodebox} +\gls{capitalisefmtwords}\marg{\meta{cs}\margm{words}} +\end{compactcodebox} +or contain formatted sub-phrases: +\begin{compactcodebox} +\gls{capitalisefmtwords}\marg{\meta{words} \meta{cs}\margm{sub-phrase} \meta{words}} +\end{compactcodebox} +The starred form only permits a text-block command at the +start of the phrase. See \sectionref{sec:titlecaseexamples} for +examples. + +\begin{warning} +Avoid declarations, such as \cmd{bfseries} or \cmd{em}. +\end{warning} + +If expansion is required, you can use: +\cmddef{xcapitalisefmtwords} +which is a shortcut for: +\begin{compactcodebox} +\cmd{expandafter}\gls{capitalisefmtwords}\cmd{expandafter}\margm{text} +\end{compactcodebox} +(The star modifier will be applied with +\code{\gls{xcapitalisefmtwords}*} in an appropriate manner.) + +\cmddef{ecapitalisefmtwords} +This will fully expand its argument before passing it to +\gls{capitalisefmtwords}. Again, the star modifier may be used. \begin{important} -\cs{capitalisefmtwords} is only designed for phrases that contain -text-block commands with a single +The unstarred \gls{capitalisefmtwords} is only designed for phrases that contain +text-block commands with a single argument, which should be a word or sub-phrase. Anything more complicated is likely to break. Instead, use the -starred form or \cs{capitalisewords}. +starred form or \gls{capitalisewords}. \end{important} -The starred form only permits a text-block command at the -start of the phrase. +\section{Excluding Words From Case-Changing} +\label{sec:nocap} + +\glsadd{exclusion-word}Some words typically shouldn't have their case changed unless they +occur at the start. These words can be identified with: +\cmddef{MFUnocap} +This only has a local effect. The global version is: +\cmddef{gMFUnocap} +The list of words that shouldn't be capitalised can be cleared +using: +\cmddef{MFUclear} + + +For example: +\begin{codebox} +\gls{capitalisewords}\marg{the wind in the willows} +\codepar +\gls{MFUnocap}\marg{in}\comment{} +\gls{MFUnocap}\marg{the}\comment{} +\codepar +\gls{capitalisewords}\marg{the wind in the willows} +\end{codebox} +\begin{resultbox} +\capitalisewords{the wind in the willows} + +\MFUnocap{in}% +\MFUnocap{the}% + +\capitalisewords{the wind in the willows} +\end{resultbox} + +Since the case-change is ultimately performed by \gls{makefirstuc}, +you can also use an \idx{exclusion} to prevent an individual word +from being changed. For example: +\begin{codebox} +\cmd{newcommand}\marg{\cmd{NoChange}}[1]\marg{\#1} +\gls{MFUexcl}\marg{\cmd{NoChange}} +\gls{MFUclear} +\gls{capitalisewords}\marg{the \cmd{NoChange}\marg{wind} in the willows} +\end{codebox} +\begin{resultbox} +\providecommand{\NoChange}[1]{#1} +\MFUexcl{\NoChange} +\MFUclear +\capitalisewords{the \NoChange{wind} in the willows} +\end{resultbox} +This can also work if you redefine \gls{MFUcapwordfirstuc} to use +\gls{MFUsentencecase} provided the exclusion command doesn't expand +(so \cmd{NoChange} would need to be protected or made robust in the above +example). + +\begin{important} +Exceptions only apply to (non-leading) whole words or words separated with +\gls{MFUwordbreak} but not to parts of a hyphenated +word that are split by \gls{MFUhyphencapword}. +\end{important} Examples: \begin{enumerate} +\item +Exceptions aren't applied if \gls{MFUwordbreak} occurs before the +first space. +\begin{codebox} +\gls{MFUnocap}\marg{a}\gls{MFUnocap}\marg{the}\comment{} +\gls{capitalisewords}\marg{a\gls{MFUwordbreak}\marg{/}the something} +\end{codebox} +\begin{resultbox} +\MFUnocap{a}\MFUnocap{the}% +\capitalisewords{a\MFUwordbreak{/}the something} +\end{resultbox} + +\item +Exceptions are applied for non-leading words: +\begin{codebox} +\gls{MFUnocap}\marg{and}\gls{MFUnocap}\marg{or}\comment{} +\gls{capitalisewords}\marg{one and\gls{MFUwordbreak}\marg{/}or another} +\end{codebox} +\begin{resultbox} +\MFUnocap{and}\MFUnocap{or}% +\capitalisewords{one and\MFUwordbreak{/}or another} +\end{resultbox} + +\item +Exceptions aren't applied for hyphenated parts: +\begin{codebox} +\gls{MFUhyphentrue} +\gls{MFUnocap}\marg{and}\gls{MFUnocap}\marg{or}\comment{} +\gls{capitalisewords}\marg{one and-or another} +\end{codebox} +\begin{resultbox} +\MFUhyphentrue +\MFUnocap{and}\MFUnocap{or}% +\capitalisewords{one and-or another} +\end{resultbox} +\end{enumerate} + +\pkgdef{mfirstuc-english} +The supplementary package \sty{mfirstuc-english} loads \sty{mfirstuc} and uses +\gls{MFUnocap} to add common English articles and conjunctions, such +as \qt{a}, \qt{an}, \qt{and}, \qt{but}. You may want to add other +words to this list, such as prepositions but, as there's some +dispute over whether prepositions should be capitalised, I~don't +intend to add them to this package. Note that you need to explicitly +load \sty{mfirstuc-english} if you require it. There's no automatic +language detection performed by \sty{mfirstuc}. + +If you want to write a similar package for another language, all you +need to do is create a file with the extension \filefmt{.sty} +that starts with: +\begin{compactcodebox} +\cmd{NeedsTeXFormat}\marg{LaTeX2e} +\end{compactcodebox} +The next line should identify the package. For example, if you have +called the file \filefmt{mfirstuc-french.sty} then you need: +\begin{compactcodebox} +\cmd{ProvidesPackage}\marg{mfirstuc-french} +\end{compactcodebox} +It's a good idea to also add a version in the final optional +argument, for example: +\begin{compactcodebox} +\cmd{ProvidesPackage}\marg{mfirstuc-french}[2014/07/30 v1.0] +\end{compactcodebox} +Next load \sty{mfirstuc}: +\begin{compactcodebox} +\cmd{RequirePackage}\marg{mfirstuc} +\end{compactcodebox} +Now add all your \gls{MFUnocap} commands. For example: +\begin{compactcodebox} +\gls{MFUnocap}\marg{de} +\end{compactcodebox} +At the end of the file add: +\begin{compactcodebox} +\cmd{endinput} +\end{compactcodebox} + +Put the file somewhere on \TeX's path, and now you can use this +package in your document. You might also consider +\href{http://ctan.org/upload}{uploading it to CTAN} in case +other users find it useful. + + +\section{PDF Bookmarks} +\label{sec:pdfbookmarks} + +If you are using \sty{hyperref} and want to use +\gls{capitalisewords} or \gls{capitalisefmtwords} (or the expanded +variants) in a section heading, the PDF bookmarks won't be able to +use the command as it's not expandable, so you will get a warning +that looks like: +\begin{transcript} +Package hyperref Warning: Token not allowed in a PDF string +(PDFDocEncoding): +(hyperref) removing `\gls{capitalisewords}' +\end{transcript} + +If you want to provide an alternative for the PDF bookmark, you can +use \sty{hyperref}'s \gls{texorpdfstring} command. For example: +\begin{codebox} +\cmd{chapter}\marg{\gls{texorpdfstring} + \marg{\gls{capitalisewords}\marg{a book of rhyme}}\comment{ TeX} + \marg{A Book of Rhyme}\comment{ PDF} +} +\end{codebox} +Alternatively, you can use \sty{hyperref}'s mechanism for +disabling commands within the bookmarks. For example: +\begin{codebox*} +\gls{pdfstringdefDisableCommands}\marg{\comment{} + \cmd{let}\gls{capitalisewords}\cmd{@firstofone} +} +\end{codebox*} +The same applies to \gls{makefirstuc}. You can, however, use +the expandable \gls{MFUsentencecase}. So you may prefer: +\begin{codebox*} +\gls{pdfstringdefDisableCommands}\marg{\comment{} + \cmd{let}\gls{capitalisewords}\cmd{MFUsentencecase} + \cmd{let}\gls{makefirstuc}\cmd{MFUsentencecase} +} +\end{codebox*} + +See the \sty{hyperref} manual for further details. + +\section{Examples} +\label{sec:titlecaseexamples} + +\begin{enumerate} +\item Text only: +\begin{coderesult} +\gls{capitalisewords}\marg{a little book of rhyme} +\tcblower +\capitalisewords{a little book of rhyme} +\end{coderesult} + +\item Excluding words (see \sectionref{sec:nocap}): +\begin{coderesult} +\gls{MFUnocap}\marg{of} +\gls{capitalisewords}\marg{a little book of rhyme} +\tcblower +\MFUnocap{of} +\capitalisewords{a little book of rhyme} +\end{coderesult} + +\item \gls{space} isn't recognised as a word boundary: +\begin{codebox} +\gls{capitalisewords}\marg{a book of rhyme.} +\codepar +\gls{capitalisewords}\marg{a book\gls{space} of rhyme.} +\end{codebox} +\begin{resultbox} +\capitalisewords{a book of rhyme.} + +\capitalisewords{a book\space of rhyme.} +\end{resultbox} + \item Phrase entirely enclosed in a formatting command: -\begin{verbatim} -\capitalisefmtwords{\textbf{a small book of rhyme}} -\end{verbatim} -produces: -\begin{display} -\capitalisefmtwords{\textbf{a small book of rhyme}} -\end{display} +\begin{codebox} +\gls{capitalisefmtwords}\marg{\cmd{emph}\marg{a small book of rhyme}} +\end{codebox} +\begin{resultbox} +\capitalisefmtwords{\emph{a small book of rhyme}} +\end{resultbox} \item Sub-phrase enclosed in a formatting command: -\begin{verbatim} -\capitalisefmtwords{a \textbf{small book} of rhyme} -\end{verbatim} -produces: -\begin{display} -\capitalisefmtwords{a \textbf{small book} of rhyme} -\end{display} +\begin{codebox} +\gls{capitalisefmtwords}\marg{a \cmd{emph}\marg{small book} of rhyme} +\end{codebox} +\begin{resultbox} +\capitalisefmtwords{a \emph{small book} of rhyme} +\end{resultbox} \item Nested text-block commands: -\begin{verbatim} +\begin{codebox} +\gls{capitalisefmtwords}\marg{\cmd{textbf}\marg{a \cmd{emph}\marg{small book}} of rhyme} +\end{codebox} +\begin{resultbox} \capitalisefmtwords{\textbf{a \emph{small book}} of rhyme} -\end{verbatim} -produces: -\begin{display} -\capitalisefmtwords{\textbf{a \emph{small book}} of rhyme} -\end{display} - -\item Indicating words that shouldn't have the case changed -(see \sectionref{sec:nocap}): -\begin{verbatim} +\end{resultbox} + +\item Formatting and case-change exception (see \sectionref{sec:nocap}): +\begin{codebox} +\gls{MFUnocap}\marg{of} +\gls{capitalisefmtwords}\marg{\cmd{textbf}\marg{a \cmd{emph}\marg{small book}} of rhyme} +\end{codebox} +\begin{resultbox} \MFUnocap{of} \capitalisefmtwords{\textbf{a \emph{small book}} of rhyme} -\end{verbatim} -produces: -\begin{display} -\MFUnocap{of} -\capitalisefmtwords{\textbf{a \emph{small book}} of rhyme} -\end{display} +\end{resultbox} \item Starred form: -\begin{verbatim} -\MFUnocap{of} -\capitalisefmtwords*{\emph{a small book of rhyme}} -\end{verbatim} -produces: -\begin{display} +\begin{codebox} +\gls{MFUnocap}\marg{of} +\gls{capitalisefmtwords}*\marg{\cmd{emph}\marg{a small book of rhyme}} +\end{codebox} +\begin{resultbox} \MFUnocap{of} \capitalisefmtwords*{\emph{a small book of rhyme}} -\end{display} +\end{resultbox} \item The starred form also works with just text (no text-block command): -\begin{verbatim} +\begin{codebox} +\gls{MFUnocap}\marg{of} +\gls{capitalisefmtwords}*\marg{a small book of rhyme} +\end{codebox} +\begin{resultbox} \MFUnocap{of} \capitalisefmtwords*{a small book of rhyme} -\end{verbatim} -produces: -\begin{display} -\MFUnocap{of} -\capitalisefmtwords*{a small book of rhyme} -\end{display} +\end{resultbox} + +\item Expansion: +\begin{codebox} +\cmd{newcommand}\marg{\cmd{abc}}\marg{\cmd{xyz}\gls+{space} four five} +\cmd{newcommand}\marg{\cmd{xyz}}\marg{one two three} +No expansion: \gls{capitalisewords}\marg{\cmd{abc}}. +\codepar +First object one-level expansion: \gls{xcapitalisewords}\marg{\cmd{abc}}. +\codepar +Fully expanded: \gls{ecapitalisewords}\marg{\cmd{abc}}. +\end{codebox} +\begin{resultbox} +\newcommand{\abc}{\xyz\space four five} +\newcommand{\xyz}{one two three} +No expansion: \capitalisewords{\abc}. + +First object one-level expansion: \xcapitalisewords{\abc}. + +Fully expanded: \ecapitalisewords{\abc}. +\end{resultbox} + +Remember that the spaces need to be explicit. In the second case +above, using \gls{xcapitalisewords}, the space before \qt{four} has +been hidden within \gls{space} so it's not recognised as a word +boundary, but in the third case, \gls{space} has been expanded to an +actual space character. + \end{enumerate} If there is a text-block command within the argument of the starred form, it's assumed to be at the start of the argument. Unexpected results can occur if there are other commands. -For example -\begin{verbatim} -\MFUnocap{of} -\capitalisefmtwords*{\emph{a small} book \textbf{of rhyme}} -\end{verbatim} -produces: -\begin{display} +For example: +\begin{badcodebox} +\gls{MFUnocap}\marg{of} +\gls{capitalisefmtwords}*\marg{\cmd{emph}\marg{a small} book \cmd{textbf}\marg{of rhyme}} +\end{badcodebox} +\begin{resultbox} \MFUnocap{of} \capitalisefmtwords*{\emph{a small} book \textbf{of rhyme}} -\end{display} -(In this case \verb|\textbf{of rhyme}| is considered a -single word.) Similarly if the text-block command occurs +\end{resultbox} +In this case \code{\cmd{textbf}\marg{of rhyme}} is considered a +single word. Similarly if the text-block command occurs in the middle of the argument: -\begin{verbatim} +\begin{badcodebox} +\gls{MFUnocap}\marg{of} +\gls{capitalisefmtwords}*\marg{a \cmd{emph}\marg{very small} book of rhyme} +\end{badcodebox} +\begin{resultbox} \MFUnocap{of} \capitalisefmtwords*{a \emph{very small} book of rhyme} -\end{verbatim} -produces: -\begin{display} -\MFUnocap{of} -\capitalisefmtwords*{a \emph{very small} book of rhyme} -\end{display} -(In this case \verb|\emph{very small}| is considered a -single word.) - -Grouping causes interference: -\begin{verbatim} -\capitalisefmtwords{{a \emph{small book}} of rhyme} -\end{verbatim} -produces: -\begin{display} -\capitalisefmtwords{{a \emph{small book}} of rhyme} -\end{display} +\end{resultbox} +In this case \code{\cmd{emph}\marg{very small}} is considered a +single word. + +Grouping causes interference. As with all the commands described here, avoid declarations. -For example, the following fails: -\begin{verbatim} -\capitalisefmtwords{{\bfseries a \emph{small book}} of rhyme} -\end{verbatim} -produces: -\begin{display} -\capitalisefmtwords{{\bfseries a \emph{small book}} of rhyme} -\end{display} +\begin{badcodebox} +\gls{capitalisefmtwords}\marg{\marg{\cmd{bfseries} a \cmd{emph}\marg{small book}} of rhyme} +\end{badcodebox} + +\begin{information} +As a general rule, it's better to define \idxpl{semanticcommand} rather +than directly using font commands and declarations within the +document. +\end{information} Avoid complicated commands in the unstarred version. For example, the following breaks: -\begin{verbatim} -\newcommand*{\swap}[2]{{#2}{#1}} -\capitalisefmtwords{a \swap{bo}{ok} of rhyme} -\end{verbatim} -However it works okay with the starred form and the simpler -\cs{capitalisewords}: -\begin{verbatim} -\newcommand*{\swap}[2]{{#2}{#1}} -\capitalisefmtwords*{a \swap{bo}{ok} of rhyme} - -\capitalisewords{a \swap{bo}{ok} of rhyme} -\end{verbatim} -Produces: -\begin{display} +\begin{badcodebox} +\cmd{newcommand}*\marg{\cmd{swap}}[2]\marg{\marg{\#2}\marg{\#1}} +\gls{capitalisefmtwords}\marg{a \cmd{swap}\marg{bo}\marg{ok} of rhyme} +\end{badcodebox} +However it can work with the starred form and the simpler +\gls{capitalisewords}: +\begin{codebox} +\cmd{newcommand}*\marg{\cmd{swap}}[2]\marg{\marg{\#2}\marg{\#1}} +\gls{capitalisefmtwords}*\marg{a \cmd{swap}\marg{bo}\marg{ok} of rhyme} +\codepar +\gls{capitalisewords}\marg{a \cmd{swap}\marg{bo}\marg{ok} of rhyme} +\end{codebox} +\begin{resultbox} \newcommand*{\swap}[2]{{#2}{#1}} \capitalisefmtwords*{a \swap{bo}{ok} of rhyme} \capitalisewords{a \swap{bo}{ok} of rhyme} -\end{display} +\end{resultbox} Note that the case change is applied to the first argument. -\begin{definition}[\DescribeMacro{\xcapitalisewords}] -\cs{xcapitalisewords}\marg{text} -\end{definition} -This is a short cut for -\cs{expandafter}\cs{capitalisewords}\cs{expandafter}\marg{text}. - -As from version 1.10, there is now a command that fully expands the -entire argument before applying \cs{capitalisewords}: -\begin{definition}[\DescribeMacro\ecapitalisewords] -\cs{ecapitalisewords}\marg{text} -\end{definition} - -There are also similar shortcut commands for the version that allows -text-block commands: -\begin{definition}[\DescribeMacro{\xcapitalisefmtwords}] -\cs{xcapitalisefmtwords}\marg{text} -\end{definition} -The unstarred version is a short cut for -\cs{expandafter}\cs{capitalisefmtwords}\cs{expandafter}\marg{text}. -Similarly the starred version of \cs{xcapitalisefmtwords} -uses the starred version of \cs{capitalisefmtwords}. - -For full expansion: -\begin{definition}[\DescribeMacro\ecapitalisefmtwords] -\cs{ecapitalisefmtwords}\marg{text} -\end{definition} -Take care with this as it may expand non-robust semantic commands -to replacement text that breaks the functioning of -\cs{capitalisefmtwords}. Use robust semantic commands -where possible. Again this has a starred version that uses -the starred form of \cs{capitalisefmtwords}. - -Examples: -\begin{verbatim} -\newcommand{\abc}{\xyz\space four five} -\newcommand{\xyz}{one two three} -No expansion: \capitalisewords{\abc}. -First object one-level expansion: \xcapitalisewords{\abc}. -Fully expanded: \ecapitalisewords{\abc}. -\end{verbatim} -produces: -\begin{display} -\renewcommand{\abc}{\xyz\space four five}% -\renewcommand{\xyz}{one two three} -No expansion: \capitalisewords{\abc}. -First object one-level expansion: \xcapitalisewords{\abc}. -Fully expanded: \ecapitalisewords{\abc}. -\end{display} - -(Remember that the spaces need to be explicit. In the second case -above, using \cs{xcapitalisewords}, the space before \qt{four} has -been hidden within \cs{space} so it's not recognised as a word -boundary, but in the third case, \cs{space} has been expanded to an -actual space character.) - -Examples: -\begin{enumerate} -\item -\begin{verbatim} -\capitalisewords{a book of rhyme.} -\end{verbatim} -produces: -\capitalisewords{a book of rhyme.} - -\item -\begin{verbatim} -\capitalisewords{a book\space of rhyme.} -\end{verbatim} -produces: -\capitalisewords{a book\space of rhyme.} - -\item -\begin{verbatim} -\newcommand{\mytitle}{a book\space of rhyme.} -\capitalisewords{\mytitle} -\end{verbatim} -produces: -\newcommand{\mytitle}{a book\space of rhyme.} -\capitalisewords{\mytitle} -(No expansion is performed on \cs{mytitle}.) Compare with next example: - -\item -\begin{verbatim} -\newcommand{\mytitle}{a book\space of rhyme.} -\xcapitalisewords{\mytitle} -\end{verbatim} -produces: -\xcapitalisewords{\mytitle} - -However -\begin{verbatim} -\ecapitalisewords{\mytitle} -\end{verbatim} -produces: -\ecapitalisewords{\mytitle} -(\cs{space} has been expanded to an actual space character.) - -\item -\begin{verbatim} -\newcommand*{\swap}[2]{{#2}{#1}} -\capitalisewords{a \swap{bo}{ok} of rhyme} - -\ecapitalisewords{a \swap{bo}{ok} of rhyme} -\end{verbatim} -produces: -\begin{display} -\newcommand*{\swap}[2]{{#2}{#1}} -\capitalisewords{a \swap{bo}{ok} of rhyme} - -\ecapitalisewords{a \swap{bo}{ok} of rhyme} -\end{display} -This is because the argument of \cs{ecapitalisewords} is -fully expanded before being passed to \cs{capitalisewords} so -that last example is equivalent to: -\begin{verbatim} -\capitalisewords{a {ok}{bo} of rhyme} -\end{verbatim} -\end{enumerate} - -\section{PDF Bookmarks} -\label{sec:pdfbookmarks} - -\begin{important} -If you are using \sty{hyperref} and want to use -\cs{capitalisewords}, \cs{capitalisefmtwords} -or \ics{makefirstuc} (or the expanded variants) -in a section heading, the PDF bookmarks won't be able to use the command -as it's not expandable, so you will get a warning that looks like: -\begin{verbatim} -Package hyperref Warning: Token not allowed in a PDF string -(PDFDocEncoding): -(hyperref) removing `\capitalisewords' -\end{verbatim} -\end{important} - -If you want to provide an alternative for the PDF bookmark, you can -use \sty{hyperref}'s \ics{texorpdfstring} command. For example: -\begin{verbatim} -\chapter{\texorpdfstring - {\capitalisewords{a book of rhyme}}% TeX - {A Book of Rhyme}% PDF -} -\end{verbatim} -Alternatively, you can use \sty{hyperref}'s mechanism for -disabling commands within the bookmarks. For example: -\begin{verbatim} -\pdfstringdefDisableCommands{% - \let\capitalisewords\@firstofone -} -\end{verbatim} - -See the \sty{hyperref} manual for further details. - -\section{Excluding Words From Case-Changing} -\label{sec:nocap} - -As from v1.09, you can specify words which shouldn't be capitalised unless they -occur at the start of \meta{text} using: -\begin{definition}[\DescribeMacro\MFUnocap] -\cs{MFUnocap}\marg{word} -\end{definition} -This only has a local effect. The global version is: -\begin{definition}[\DescribeMacro\gMFUnocap] -\cs{gMFUnocap}\marg{word} -\end{definition} - +\chapter{Miscellaneous} +\label{sec:misc} + +\section{Saving \Glsfmtplural{exclusion}, \Glsfmtplural{blocker} and +\Glsfmtplural{mapping} in the \exttext{aux} File} +\label{sec:savetoaux} + +If the \idxpl{exclusion}, \idxpl{mapping} and \idxpl{blocker} are +required by some external tool, the information can be saved in the +\ext+{aux} file. + +\cmddef{MFUsaveatend} +This saves the information at the end of the document using a delayed +write. This means that it can register all information identified +throughout the document, but there's a chance the document may end +before the write takes place (for example, if the last page only +contains floats). This command may be counteracted by: +\cmddef{MFUsave} +This saves the information using a protected write at the point +where this command occurs, which may be too soon if additional +\idxpl{exclusion}, \idxpl{mapping} or \idxpl{blocker} are identified +later. This command will counteract any instance of +\gls{MFUsaveatend}, regardless of whether or not \gls{MFUsaveatend} +comes before or after \gls{MFUsave}. + +The associated \ext{aux} commands are listed below. In each case, a +definition is provided in the \ext{aux} file that does nothing. +\cmddef{@mfu@excls} +Lists all \idxpl{exclusion}. For example: -\begin{verbatim} -\capitalisewords{the wind in the willows} - -\MFUnocap{in}% -\MFUnocap{the}% - -\capitalisewords{the wind in the willows} -\end{verbatim} -produces: -\begin{display} -\capitalisewords{the wind in the willows} - -\MFUnocap{in}% -\MFUnocap{the}% - -\capitalisewords{the wind in the willows} -\end{display} -The list of words that shouldn't be capitalised can be cleared using -\begin{definition}[\DescribeMacro\MFUclear] -\cs{MFUclear} -\end{definition} - -You can also simply place an empty group in front of a word -if you don't want that specific instance to be capitalised. +\begin{compactcodebox*} +\gls{@mfu@excls}\marg{\gls{begin} \gls{cite} \gls{end} \gls{label} +\gls{ref} \gls{cite} \gls{NoCaseChange} \gls{ensuremath} +\gls{MFUskippunc} \gls{gls} \gls{glspl}} +\end{compactcodebox*} + +\cmddef{@mfu@blockers} +Lists all \idxpl{blocker}. For example: -\begin{verbatim} -\MFUclear -\capitalisewords{the {}wind in the willows} -\end{verbatim} -produces: -\begin{display} -\MFUclear -\capitalisewords{the {}wind in the willows} -\end{display} -This is also a useful way of protecting commands that -shouldn't be parsed. For example: -\begin{verbatim} -\capitalisewords{this is section {}\nameref{sec:nocap}.} -\end{verbatim} -produces -\begin{display} -\capitalisewords{this is section {}\nameref{sec:nocap}.} -\end{display} -(No case-changing is applied to \verb|\nameref{sec:nocap}|. -It just happens to already be in title case.) - -The package \sty{mfirstuc-english} loads \styfmt{mfirstuc} and uses -\cs{MFUnocap} to add common English articles and conjunctions, such -as ``a'', ``an'', ``and'', ``but''. You may want to add other -words to this list, such as prepositions but, as there's some -dispute over whether prepositions should be capitalised, I~don't -intend to add them to this package. - -If you want to write a similar package for another language, all you -need to do is create a file with the extension \texttt{.sty} -that starts with -\begin{verbatim} -\NeedsTeXFormat{LaTeX2e} -\end{verbatim} -The next line should identify the package. For example, if you have -called the file \texttt{mfirstuc-french.sty} then you need: -\begin{verbatim} -\ProvidesPackage{mfirstuc-french} -\end{verbatim} -It's a good idea to also add a version in the final optional -argument, for example: -\begin{verbatim} -\ProvidesPackage{mfirstuc-french}[2014/07/30 v1.0] -\end{verbatim} -Next load \styfmt{mfirstuc}: -\begin{verbatim} -\RequirePackage{mfirstuc} -\end{verbatim} -Now add all your \cs{MFUnocap} commands. For example: -\begin{verbatim} -\MFUnocap{de} -\end{verbatim} -At the end of the file add: -\begin{verbatim} -\endinput -\end{verbatim} - -Put the file somewhere on \TeX's path, and now you can use this -package in your document. You might also consider -\href{http://ctan.org/upload}{uploading it to CTAN} in case -other users find it useful. +\begin{compactcodebox*} +\gls{@mfu@blockers}\marg{\gls{Gls} \gls{Glspl} } +\end{compactcodebox*} -\chapter{UTF-8} +\cmddef{@mfu@mappings} +Lists all \idxpl{mapping} as a \keyval\ list. +For example: +\begin{compactcodebox*} +\gls{@mfu@mappings}\marg{ \marg{\gls{gls} }= \marg{\gls{Gls} }, \marg{\gls{glspl} }= \marg{\gls{Glspl} }} +\end{compactcodebox*} + +\section{All-Caps} +\label{sec:allcaps} + +\cmddef{mfirstucMakeUppercase} +This command was originally used to perform the actual conversion to +\idx+{uppercase} and was defined to use command \gls{MakeUppercase}. +The \sty{glossaries} package (before v4.50) formerly loaded the +\sty{textcase} package and redefined \gls{mfirstucMakeUppercase} to +use \gls{MakeTextUppercase}, which was better than +\gls{MakeUppercase}. + +The \sty{textcase} package has been deprecated as from 2022 and +it now simply sets \gls{MakeTextUppercase} to \gls{MakeUppercase} +because the new kernel now defines \gls{MakeUppercase} to use the +newer \LaTeX3 command \gls{textuppercase:n}. Although that command +is expandable, \gls{MakeUppercase} is robust. + +As from v2.08, \sty{mfirstuc} now defines \gls{mfirstucMakeUppercase} +so that it uses \gls{texttitlecasefirst:n} directly, rather than +indirectly through \gls{MakeUppercase}, which means that it's now +expandable. However, \gls{mfirstucMakeUppercase} is no longer used +by \sty{mfirstuc} except in \gls{mfugrabfirstuc}, which is provided +to emulate v2.07. Note that the \opt{grabfirst} option will also +redefine \gls{mfirstucMakeUppercase} to use \gls{MakeUppercase}. + +\section{UTF-8} \label{sec:utf8} -(See -\href{https://dickimaw-books.com/blog/binary-files-text-files-and-file-encodings/}{Binary +\begin{information} +See \blog{binary-files-text-files-and-file-encodings/}{Binary Files, Text Files and File Encodings} if you are confused about how -file encodings such as UTF-8 relate to text files.) +file encodings, such as \gls{utf8}, relate to text files. +\end{information} + +This section only applies to rollback or the use of \gls{mfugrabfirstuc} +(implemented via the \opt{grabfirst} option). -The \cs{makefirstuc} command works by utilizing the fact that, in +Prior to version 2.08, the case-change applied by the +\gls{glsmakefirstuc} command worked by utilizing the fact that, in most cases, \TeX\ doesn't require a regular argument to be enclosed in braces if it only consists of a single token. (This is why you -can do, say, \verb|\frac12| instead of \verb|\frac{1}{2}| or -\verb|x^2| instead of \verb|x^{2}|, although some users -frown on this practice.) - -A~simplistic version of the \cs{makefirstuc} command is: -\begin{verbatim} -\newcommand*{\FirstUC}[1]{\MakeUppercase #1} -\end{verbatim} +can do, say, \code{\cmd{frac}12} instead of +\code{\cmd{frac}\marg{1}\marg{2}} or \code{x\char`\^2} +instead of \code{x\char`\^\marg{2}}, although this +practice is discouraged by some.) + +A~simplistic version of the original \gls{glsmakefirstuc} command is: +\begin{codebox} +\cmd{newcommand}*\marg{\cmd{FirstUC}}[1]\marg{\gls{MakeUppercase} \#1} +\end{codebox} Here -\begin{verbatim} -\FirstUC{abc} -\end{verbatim} +\begin{codebox} +\cmd{FirstUC}\marg{abc} +\end{codebox} is equivalent to -\begin{verbatim} -\MakeUppercase abc -\end{verbatim} -and since \cs{MakeUppercase} requires an argument, it grabs the -first token (the character ``a'' in this case) and uses that as the -argument so that the result is: Abc. - -The \sty{glossaries} package needs to take into account the fact -that the text may be contained in the argument of a formatting -command, such as \cs{acronymfont}, so \cs{makefirstuc} has to be -more complicated than the trivial \cs{FirstUC} shown above, but at -its basic level, \cs{makefirstuc} uses this same method and is the -reason why, in most cases, you don't need to enclose the first -character in braces. So if -\begin{alltt} -\cs{MakeUppercase} \meta{stuff} -\end{alltt} -works, -then -\begin{alltt} -\cs{makefirstuc}\marg{stuff} -\end{alltt} -should also work and so should -\begin{alltt} -\cs{makefirstuc}\{\cs{foo}\marg{stuff}\} -\end{alltt} -but if -\begin{alltt} -\cs{MakeUppercase} \meta{stuff} -\end{alltt} -doesn't work, then neither will -\begin{alltt} -\cs{makefirstuc}\marg{stuff} -\end{alltt} -nor -\begin{alltt} -\cs{makefirstuc}\{\cs{foo}\marg{stuff}\} -\end{alltt} - -Try the following document: -\begin{alltt} -\cs{documentclass}\{article\} - -\cs{usepackage}[utf8]\{inputenc\} -\cs{usepackage}[T1]\{fontenc\} - -\cs{begin}\{document\} - -\cs{MakeUppercase} \~abc - -\cs{end}\{document\} -\end{alltt} - -This will result in the error: -\begin{verbatim} -! Argument of \UTFviii@two@octets has an extra }. -\end{verbatim} -This is why \verb|\makefirstuc{|\texttt{\~abc}\verb|}| won't work. -It will only work if the character \texttt{\~a} is placed inside a -group. - -The reason for this error message is due to \TeX\ having been written before -Unicode was invented. Although \texttt{\~a} may look like a single -character in your text editor, from \TeX's point of view it's \emph{two} -tokens. So -\begin{alltt} -\cs{MakeUppercase} \~abc -\end{alltt} -tries to apply \cs{MakeUppercase} to just the first octet of \~a. -This means that the second octet has been separated from the first octet, -which is the cause of the error. In this case the argument isn't a -single token, so the two tokens (the first and second octet of \~a) -must be grouped: -\begin{alltt} -\cs{MakeUppercase}\{\~a\}bc -\end{alltt} -Over recent years the \LaTeX\ kernel has changed to allow the use of -UTF-8 characters within labels but the fundamental problem of each -octet been viewed as a separated token remains. - -Note that \XeTeX\ (and therefore \XeLaTeX) is a modern -implementation of \TeX\ designed to work with Unicode and therefore -doesn't suffer from this drawback. Now let's look at the \XeLaTeX\ -equivalent of the above example: -\begin{alltt} -\cs{documentclass}\{article\} - -\cs{usepackage}\{fontspec\} - -\cs{begin}\{document\} - -\cs{MakeUppercase} \~abc - -\cs{end}\{document\} -\end{alltt} - -This works correctly when compiled with \XeLaTeX. This means -that \cs{makefirstuc}\verb|{|\texttt{\~abc}\verb|}| will work -\emph{provided you use \XeLaTeX\ and the \sty{fontspec} package}. - -Version 2.24 of \sty{datatool-base} added the -command \cs{dtl@getfirst@UTFviii} which attempts to grab both octets. If this command -has been defined, \sty{mfirstuc} will use it when it tries to split -the first character from the rest of the word. See the -\href{http://mirrors.ctan.org/macros/latex/contrib/datatool/datatool-code.pdf}{\styfmt{datatool} -documented code} for further details. - -\PrintIndex +\begin{codebox} +\gls{MakeUppercase} abc +\end{codebox} +and since \gls{MakeUppercase} requires an argument, it grabs the +first token (the character \qt{a} in this case) and uses that as the +argument so that the result is \qt{Abc}. This behaviour can be +achieved with \gls{mfugrabfirstuc}. + +Unfortunately, this will fail if the content starts with a \gls{utf8} +character and you are using \pdfLaTeX, where each octet of the +\gls{utf8} character is a separate token. This isn't a problem +with \XeLaTeX\ and \LuaLaTeX\ which both treat the entire multibyte +character as a single token. + +\LaTeX3 now provides \gls{texttitlecasefirst:n} +to convert the first character to uppercase, so now the +case-change can be applied with: +\begin{codebox} +\cmd{ExplSyntaxOn} +\gls{texttitlecasefirst:n}\marg{élite} +\cmd{ExplSyntaxOff} +\end{codebox} +This is exactly what \gls{MFUsentencecase} does without the need to +switch on \LaTeX3 syntax. The difference with the default definition +of \gls{glsmakefirstuc} is that it prevents its argument from being +expanded. + +\backmatter +\printterms +\printsummary +\printuserguideindex + \end{document} diff --git a/macros/latex/contrib/mfirstuc/mfirstuc.dtx b/macros/latex/contrib/mfirstuc/mfirstuc.dtx index 2aa2008f41..a88c20e131 100644 --- a/macros/latex/contrib/mfirstuc/mfirstuc.dtx +++ b/macros/latex/contrib/mfirstuc/mfirstuc.dtx @@ -1,21 +1,22 @@ %\iffalse % mfirstuc.dtx generated using makedtx version 1.2 (c) Nicola Talbot % Command line args: -% -setambles ".*\.perl=>\nopreamble\nopostamble" -% -setambles ".*\.tex=>\nopreamble\nopostamble" +% -macrocode ".*\.l2h" +% -macrocode ".*\.tex" +% -comment ".*\.l2h" +% -comment ".*\.tex" +% -codetitle "Main Package Code" +% -doc "mfirstuc-codedoc.tex" % -author "Nicola Talbot" % -src "mfirstuc.sty\Z=>mfirstuc.sty" % -src "mfirstuc-english.sty\Z=>mfirstuc-english.sty" +% -src "(mfirstuc-[0-9]+-[0-9]+-[0-9]+.sty)\Z=>\1" % -src "(sample.*\.tex)\Z=>\1" -% -src "(.*\.perl)\Z=>\1" -% -macrocode ".*\.perl" -% -macrocode ".*\.tex" -% -codetitle "Main Package Code" -% -doc "mfirstuc-codedoc.tex" -% -comment ".*\.perl" -% -comment ".*\.tex" +% -src "(.*\.l2h)\Z=>\1" +% -setambles ".*\.l2h=>\nopreamble\nopostamble" +% -setambles ".*\.tex=>\nopreamble\nopostamble" % mfirstuc -% Created on 2021/10/15 17:46 +% Created on 2022/10/18 9:21 %\fi %\iffalse %<*package> @@ -38,66 +39,70 @@ %\fi % \iffalse % Doc-Source file to use with LaTeX2e -% Copyright (C) 2021 Nicola Talbot, all rights reserved. +% Copyright (C) 2022 Nicola Talbot, all rights reserved. % \fi % \iffalse %<*driver> -\documentclass{nlctdoc} - \iffalse mfirstuc-codedoc.tex is a stub file used by makedtx to create mfirstuc.dtx \fi -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} -\usepackage[colorlinks, - bookmarks, - hyperindex=false, - pdfauthor={Nicola L.C. Talbot}, - pdftitle={mfirstuc.sty: Documented code}]{hyperref} +\documentclass{article} +\usepackage{doc} + +\CheckSum{1753} \RecordChanges +\PageIndex +\SetupDoc{reportchangedates} +\setcounter{IndexColumns}{2} + +\usepackage[T1]{fontenc} +\usepackage{tcolorbox} -\renewcommand*{\main}[1]{\hyperpage{#1}} +\definecolor{defbackground}{rgb}{1,1,0.75} -\setcounter{IndexColumns}{2} -\setlength\IndexMin{100pt} +\newtcolorbox{definition}{halign=flush left, + colframe=black,colback=defbackground, + fontupper=\ttfamily, + before upper={\frenchspacing\obeylines}, + after={\par\noindent\ignorespacesafterend} +} + +\NewDocElement{Option}{option} -\CheckSum{771} +\providecommand{\sty}[1]{\textsf{#1}} + +\providecommand\marg[1]{% + \texorpdfstring{\allowbreak{\ttfamily\char`\{}\meta{#1}{\ttfamily\char`\}}} + {\{#1\}}} +\providecommand\oarg[1]{% + \texorpdfstring{\allowbreak{\ttfamily[}\meta{#1}{\ttfamily]}} + {[#1]}} \begin{document} \DocInput{mfirstuc.dtx} \end{document} % %\fi -%\MakeShortVerb{"} -%\DeleteShortVerb{\|} % -% \title{Documented Code For mfirstuc v2.07} +% \title{Documented Code For mfirstuc v2.08} % \author{Nicola L.C. Talbot\\[10pt] %Dickimaw Books\\ %\url{http://www.dickimaw-books.com/}} % -% \date{2021-10-15} +% \date{2022-10-14} % \maketitle % %\tableofcontents % %\section{Introduction} % -%This is the documented code for the \styfmt{mfirstuc} package. +%This is the documented code for the \sty{mfirstuc} package. %See \texttt{mfirstuc-manual.pdf} for the main user guide. % -% -%\StopEventually{% -% \phantomsection -% \addcontentsline{toc}{section}{Change History}% -% \raggedright -% \PrintChanges -% \PrintIndex -%} -% +%\StopEventually{\clearpage\PrintChanges \clearpage\PrintIndex} % % %\section{Main Package Code} @@ -106,58 +111,401 @@ mfirstuc.dtx %<*mfirstuc.sty> % \end{macrocode} %\fi -%\subsection{Mfirstuc Documented Code} +%\section{Mfirstuc Documented Code} %\label{sec:code:mfirstuc} %\changes{2.0}{2015/09/09}{package split from glossaries} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{mfirstuc}[2021/10/15 v2.07 (NLCT)] +% \end{macrocode} +% Rollback releases: +% \begin{macrocode} +\DeclareRelease{v2.07}{2021-10-15}{mfirstuc-2021-10-15.sty} +\DeclareCurrentRelease{v2.08}{2022-10-14} +% \end{macrocode} +% Declare package: +% \begin{macrocode} +\ProvidesPackage{mfirstuc}[2022/10/14 v2.08 (NLCT)] % \end{macrocode} % Requires \sty{etoolbox}:\changes{1.06}{2012/05/21}{now requires % etoolbox} % \begin{macrocode} \RequirePackage{etoolbox} % \end{macrocode} +%Version 2.07 has switched to LaTeX3 for the actual case-changing. +%The original \cs{makefirstuc} has been reimplemented to use LaTeX3 +%code. There is also a new command \cs{MFUsentencecase} which just +%uses \cs{text\_titlecase\_first:n}. Note that \cs{MFUsentencecase} is +%internally used by \cs{glsmakefirstuc}, which in turn is used by +%\cs{makefirstuc} to perform the actual case-change. +% +%\begin{macro}{\glsmakefirstuc} +%\changes{1.05}{2011/04/02}{new} +% Provide a user command to make it easier to customise. This is +% used internally by \cs{makefirstuc}. (The original commands +% provided by \sty{mfirstuc} were part of the \sty{glossaries} +% package, hence the ``gls'' prefix.) +% \begin{macrocode} +\newcommand*{\glsmakefirstuc}[1]{\MFUsentencecase{\unexpanded{#1}}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\mfirstucMakeUppercase} +% This was originally provided to allow user to replace +%\cs{MakeUppercase} with another case-changing command. +% This is now only used with \cs{mfugrabfirstuc}. +% \begin{macrocode} +\ExplSyntaxOn +\newcommand*{\mfirstucMakeUppercase}[1]{\text_uppercase:n{#1}} +% \end{macrocode} +%\end{macro} +% +%\begin{option}{expanded} +%\changes{2.08}{2022-10-14}{new} +%Allow argument to expand. +%This also resets the definition of \cs{mfirstucMakeUppercase} +%in case it was changed by grabfirst. +% \begin{macrocode} +\DeclareOption{expanded}{% + \renewcommand*{\glsmakefirstuc}[1]{\MFUsentencecase{#1}}% + \renewcommand*{\mfirstucMakeUppercase}[1]{\text_uppercase:n{#1}}% +} +% \end{macrocode} +%\end{option} +% +%\begin{option}{unexpanded} +%\changes{2.08}{2022-10-14}{new} +%Prevent argument of \cs{glsmakefirstuc} from expanding. +%This also resets the definition of \cs{mfirstucMakeUppercase} +%in case it was changed by grabfirst, but note that it doesn't use +%\cs{unexpanded}. +% \begin{macrocode} +\DeclareOption{unexpanded}{% + \renewcommand*{\glsmakefirstuc}[1]{\MFUsentencecase{\unexpanded{#1}}}% + \renewcommand*{\mfirstucMakeUppercase}[1]{\text_uppercase:n{#1}}% +} +\ExplSyntaxOff +% \end{macrocode} +%\end{option} +% +%\begin{macro}{\mfugrabfirstuc} +%\changes{2.08}{2022-10-14}{new} +%Used by the grabfirst option to emulate v2.07. +% \begin{macrocode} +\newrobustcmd*{\mfugrabfirstuc}[1]{\@mfu@grabfirstuc#1\empty} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@mfu@grabfirstuc} +%\changes{2.08}{2022-10-14}{new} +% \begin{macrocode} +\newcommand*{\@mfu@grabfirstuc}[2]{\mfirstucMakeUppercase{#1}#2} +% \end{macrocode} +%\end{macro} +% +%\begin{option}{grabfirst} +%\changes{2.08}{2022-10-14}{new} +%Emulate v2.07 method. +% \begin{macrocode} +\DeclareOption{grabfirst}{% + \renewcommand*{\glsmakefirstuc}[1]{\mfugrabfirstuc{#1}}% + \renewcommand*{\mfirstucMakeUppercase}[1]{\MakeUppercase{#1}}% +} +% \end{macrocode} +%\end{option} +% +%Process options. +% \begin{macrocode} +\ProcessOptions +% \end{macrocode} +% +%There are differences between \cs{makefirstuc} and +%\cs{MFUsentencecase}, the principle ones being expansion occurs differently and +%\cs{makefirstuc} stops at exclusions whereas +%\cs{MFUsentencecase} skips them. +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +%\begin{macro}{\MFUsentencecase} +%\changes{2.08}{2022-10-14}{new} +%New command provided that simply uses LaTeX3, which expands the +%content. This may be preferred over \cs{makefirstuc} depending on +%the content. +% \begin{macrocode} +\newcommand{\MFUsentencecase}[1]{\text_titlecase_first:n{#1}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\MFUexcl} +%\changes{2.08}{2022-10-14}{new} +%Add a command to the exclusion list. This is used by +%\cs{text\_titlecase\_first:n} +%to skip commands that shouldn't have their argument changed (such +%as \cs{ref}). It's also used by \cs{makefirstuc}. +% \begin{macrocode} +\newcommand{\MFUexcl}[1]{ + \tl_if_empty:nF { #1 } + { + \tl_if_in:NnF \l_text_case_exclude_arg_tl {#1} + { + \tl_put_right:Nn \l_text_case_exclude_arg_tl {#1} + } + } +} +% \end{macrocode} +%\end{macro} +%Add \cs{ensuremath} as an exclusion otherwise \cs{makefirstuc} +%will try passing its argument to \cs{MFUsentencecase}, which will +%fail. +% \begin{macrocode} +\MFUexcl{\ensuremath} +% \end{macrocode} +% +%Test if the given command is in the exclusion list. +% \begin{macrocode} +\cs_new:Npn \mfirstuc_if_excluded:NTF #1 #2 #3 + { + \tl_if_in:NnTF \l_text_case_exclude_arg_tl {#1} {#2} {#3} + } +% \end{macrocode} +%Provide an implementation of \cs{makefirstuc} that matches +%older versions as much as possible. +% \begin{macrocode} +\tl_new:N \l__mfirstuc_stack_tl +\tl_new:N \l__mfirstuc_head_tl +\tl_new:N \l__mfirstuc_next_tl +% \end{macrocode} +%In addition to exclusions, also provide blockers. These are only +%supported by \cs{makefirstuc}. Exclusions and +%their argument are skipped, whereas blockers prevent case-change. +%For example, sentence-casing \verb|\label{ex}some text| should skip +%\verb|\label{ex}|, whereas \verb|\nameref{ex} some text| shouldn't +%have any case change applied. +% \begin{macrocode} +\tl_new:N \l__mfirstuc_blocker_tl +% \end{macrocode} +% +%\begin{macro}{\MFUblocker} +%\changes{2.08}{2022-10-14}{new} +%Add a command to the blocker list. +% \begin{macrocode} +\newcommand{\MFUblocker}[1]{ + \tl_if_empty:nF { #1 } + { + \tl_if_in:NnF \l__mfirstuc_blocker_tl {#1} + { + \tl_put_right:Nn \l__mfirstuc_blocker_tl {#1} + } + \MFUexcl { #1 } + } +} +% \end{macrocode} +%\end{macro} +%Test if the given command is in the blocker list. +% \begin{macrocode} +\cs_new:Npn \tl_if_mfirstuc_blocker:nTF #1 #2 #3 + { + \tl_if_in:NnTF \l__mfirstuc_blocker_tl {#1} {#2} {#3} + } +% \end{macrocode} +%Is there a way to do this without \cs{expandafter}? +% \begin{macrocode} +\cs_new:Npn \tl_if_mfirstuc_blocker:VTF #1 #2 #3 + { + \expandafter \tl_if_mfirstuc_blocker:nTF \expandafter {#1} {#2} {#3} + } +% \end{macrocode} +% %\begin{macro}{\makefirstuc} -% Syntax: %\begin{definition} % \cs{makefirstuc}\marg{text} %\end{definition} -% Makes the first letter uppercase, but will -% skip initial control sequences if they are followed by a group -% and make the first thing in the group uppercase, unless the group -% is empty. -% Thus \verb|\makefirstuc{abc}| will produce: Abc, -% \verb|\makefirstuc{\ae bc}| will produce: \AE bc, but -% \verb|\makefirstuc{\emph{abc}}| will produce \emph{Abc}. -% This is required by \ics{Gls} and \ics{Glspl}. %\changes{1.08}{2013-11-04}{made robust} +%\changes{2.08}{2022-10-14}{reimplement using \LaTeX3} +% \begin{macrocode} +\newrobustcmd{\makefirstuc}[1]{% + \tl_set:Nn \l__mfirstuc_stack_tl {#1} + \tl_if_empty:NF \l__mfirstuc_stack_tl + { + \tl_if_single:NTF \l__mfirstuc_stack_tl + { + \glsmakefirstuc{#1} + } + { + \tl_if_head_is_group:nTF {#1} + { + \glsmakefirstuc{#1} + } + { + \tl_if_head_eq_catcode:nNTF {#1} \relax + { + \tl_set:NV \l_tmpa_tl \l__mfirstuc_stack_tl + \tl_set:Nx \l__mfirstuc_head_tl { \tl_head:V \l_tmpa_tl } + \tl_set:Nx \l__mfirstuc_stack_tl { \tl_tail:N \l__mfirstuc_stack_tl } + \tl_if_eq:NnTF \l__mfirstuc_head_tl { \protect } + { + \tl_set:NV \l_tmpa_tl \l__mfirstuc_stack_tl + \tl_set:Nx \l__mfirstuc_head_tl { \tl_head:V \l_tmpa_tl } + \tl_set:Nx \l__mfirstuc_stack_tl { \tl_tail:N \l__mfirstuc_stack_tl } + } + {} + \tl_if_mfirstuc_blocker:VTF \l__mfirstuc_head_tl + { #1 } + { + \let \l_tmpa_tl \l__mfirstuc_stack_tl + \tl_set:Nx \l__mfirstuc_next_tl { \tl_head:N \l_tmpa_tl } + \tl_if_single:NTF \l__mfirstuc_next_tl + { + \glsmakefirstuc{#1} + } + { + \tl_set:Nx \l__mfirstuc_stack_tl { \tl_tail:N \l__mfirstuc_stack_tl } + \tl_clear:N \l_tmpa_tl + \tl_put_right:Nn \l_tmpa_tl { \__mfirstuc_inner:nnn } + \tl_put_right:NV \l_tmpa_tl \l__mfirstuc_head_tl + \tl_put_right:Nx \l_tmpa_tl + { + { \expandonce \l__mfirstuc_next_tl } + { \expandonce \l__mfirstuc_stack_tl } + } + \tl_use:N \l_tmpa_tl + } + } + } + { + \glsmakefirstuc{#1} + } + } + } + } +} +% \end{macrocode} +%\end{macro} +% % \begin{macrocode} -\newif\if@glscs -\newtoks\@glsmfirst -\newtoks\@glsmrest -\newrobustcmd*{\makefirstuc}[1]{% +\cs_new_protected:Npn \__mfirstuc_inner:nnn #1 #2 #3 + { % \end{macrocode} -% Check if argument starts with \cs{protect} which needs to be -% skipped. -%\changes{2.01}{2015-12-08}{added check for \cs{protect}} +% Mappings trump exclusions. % \begin{macrocode} - \@MFU@p@makefirstuc#1\relax\relax\relax\@end@MFU@protected{#1}% + \mfirstuc_get_map:NN #1 \l_tmpb_tl + \quark_if_no_value:NTF \l_tmpb_tl + { + \mfirstuc_if_excluded:NTF #1 + { #1{#2}\makefirstuc{#3} } + { #1{\makefirstuc{#2}}#3 } + } + { + \l_tmpb_tl {#2} #3 + } + } +% \end{macrocode} +%Mappings. +% \begin{macrocode} +\prop_new:N \l__mfirstuc_mappings_prop +% \end{macrocode} +%\begin{macro}{\MFUaddmap} +%\changes{2.08}{2022-10-14}{new} +%Adds a mapping from a control sequence to the appropriate sentence +%case version. No map is added if either argument is empty. +% \begin{macrocode} +\newrobustcmd*{\MFUaddmap}[2]{% + \tl_if_empty:nF { #1 } + { + \tl_if_empty:nF { #2 } + { + \prop_put:Nnn \l__mfirstuc_mappings_prop {#1} {#2} + } + } + \MFUexcl { #1 } + \MFUblocker { #2 } +} +% \end{macrocode} +%\end{macro} +% \begin{macrocode} +\cs_new:Npn \mfirstuc_get_map:NN #1 #2 + { + \prop_get:NnN \l__mfirstuc_mappings_prop {#1} #2 + } +% \end{macrocode} +%\begin{macro}{\MFUsaveatend} +%\changes{2.08}{2022-10-14}{new} +%Save exclusions, blockers and mappings in the aux file, if required +%by some external tool, but delays action to the end of the document. +% \begin{macrocode} +\newcommand{\MFUsaveatend}{ + \AtEndDocument { \@MFUsavetoaux } +% \end{macrocode} +%Disable this command. +% \begin{macrocode} + \let\MFUsaveatend\relax } % \end{macrocode} %\end{macro} +%\begin{macro}{\MFUsave} +%\changes{2.08}{2022-10-14}{new} +%As above but do now. +% \begin{macrocode} +\newcommand{\MFUsave}{ + \@MFUsavetoaux +% \end{macrocode} +%Disable further attempts. +% \begin{macrocode} + \let\@MFUsavetoaux\relax + \let\MFUsave\relax + \let\MFUsaveatend\relax +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@MFUsavetoaux} +%\changes{2.08}{2022-10-14}{new} +%Save exclusions, blockers and mappings in the aux file, if required +%by some external tool. +% \begin{macrocode} +\newcommand{\@MFUsavetoaux}{ + \protected@write\@auxout{} + { \tl_to_str:n { \providecommand{\@mfu@excls}[1]{} } } + \protected@write\@auxout{} + { \tl_to_str:n { \providecommand{\@mfu@blockers}[1]{} } } + \protected@write\@auxout{} + { \tl_to_str:n { \providecommand{\@mfu@mappings}[1]{} } } +% \end{macrocode} +%Save current values. +% \begin{macrocode} + \protected@write\@auxout{} + { + \string\@mfu@excls { \tl_to_str:V \l_text_case_exclude_arg_tl } + } + \protected@write\@auxout{} + { + \string\@mfu@blockers { \tl_to_str:V \l__mfirstuc_blocker_tl } + } + \protected@write\@auxout{} + { + \string\@mfu@mappings + { \expandonce { \prop_to_keyval:N \l__mfirstuc_mappings_prop } } + } +} +% \end{macrocode} +%\end{macro} +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +%The remaining code hasn't been converted to LaTeX3 yet, but may in +%the future, so don't rely on internal commands. % -%\begin{macro}{\@MFU@protect} -%\changes{2.03}{2016-07-29}{new} +%\begin{macro}{\emakefirstuc} +%\changes{1.10}{2015/05/03}{new} +% Fully expand argument before applying case-change. % \begin{macrocode} -\newcommand*{\@MFU@protect}{\protect} +\newrobustcmd*{\emakefirstuc}[1]{% + \protected@edef\@MFU@caparg{#1}% + \expandafter\makefirstuc\expandafter{\@MFU@caparg}% +} % \end{macrocode} %\end{macro} % -%\begin{macro}{\@MFU@skippunc} -%\changes{2.07}{2021-10-15}{new} +%\begin{macro}{\xmakefirstuc} % \begin{macrocode} -\newcommand*{\@MFU@skippunc}{\MFUskippunc} +\newcommand*{\xmakefirstuc}[1]{\expandafter\makefirstuc\expandafter{#1}} % \end{macrocode} %\end{macro} % @@ -165,25 +513,978 @@ mfirstuc.dtx %\changes{2.07}{2021-10-15}{new} % \begin{macrocode} \newrobustcmd*{\MFUskippunc}[1]{#1} +\MFUexcl{\MFUskippunc} % \end{macrocode} %\end{macro} % -%\begin{macro}{\@MFU@p@makefirstuc} -% Internal command to do the required action. +%Title case commands. Each word has the first letter converted to +%upper case using \cs{MFUcapwordfirstuc}. This uses \cs{makefirstuc} +%by default. It may be redefined to use \cs{MFUsentencecase} or +%\cs{text\_titlecase:n} as applicable. +%\begin{macro}{\MFUcapwordfirstuc} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\newcommand*{\MFUcapwordfirstuc}[1]{% + \makefirstuc{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\capitalisewords} +%\changes{1.06}{2012/05/21}{new} +% Capitalise each word in the argument. Words are considered to be +% separated by plain spaces (i.e.\ non-breakable spaces won't be +% considered a word break). +%\changes{1.08}{2013-11-04}{made robust} +%\changes{1.09}{2017-07-30}{added check for words that shouldn't be +%capitalised} +% \begin{macrocode} +\newrobustcmd*{\capitalisewords}[1]{% + \let\@mfu@checkword\@gobble + \def\gls@add@space{}% + \let\@mfu@domakefirstuc\@MFU@dofirst@capword + \mfu@capitalisewords#1 \@nil\mfu@endcap +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@mfu@mid@capitalisewords} +%\changes{2.03}{2016-07-29}{new} +%\cs{@mfu@checkword} needs to be set before use. +% \begin{macrocode} +\newcommand*{\@mfu@mid@capitalisewords}[1]{% + \def\gls@add@space{}% + \let\@mfu@domakefirstuc\@MFU@do@capword + \mfu@capitalisewords#1 \@nil\mfu@endcap +} +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +\def\mfu@capitalisewords#1 #2\mfu@endcap{% + \def\mfu@cap@first{#1}% + \def\mfu@cap@second{#2}% + \gls@add@space + \@mfu@checkword{#1}% + \@mfu@domakefirstuc{#1}% + \def\gls@add@space{ }% + \ifx\mfu@cap@second\@nnil + \let\next@mfu@cap\mfu@noop + \else + \let\next@mfu@cap\mfu@capitalisewords + \let\@mfu@checkword\mfu@checkword + \fi + \next@mfu@cap#2\mfu@endcap +} +\def\mfu@noop#1\mfu@endcap{} +% \end{macrocode} +% +%\begin{macro}{\ifMFUhyphen} +%\changes{2.03}{2016-07-29}{new} +%Split on hyphens. +% \begin{macrocode} +\newif\ifMFUhyphen +\MFUhyphenfalse +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFU@do@capword} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\newcommand*{\@MFU@do@capword}[1]{% + \let\@MFU@cappingword\MFUcapword + \@MFUwordbreak#1\MFUwordbreak{}\@nil\@endMFUwordbreak +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFU@dofirst@capword} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\newcommand*{\@MFU@dofirst@capword}[1]{% + \let\@MFU@cappingword\MFUcapword + \@MFUfirstwordbreak#1\MFUwordbreak{}\@nil\@endMFUfirstwordbreak +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\MFUcapword} +%\changes{2.03}{2016-07-29}{new} % \begin{macrocode} +\newcommand*{\MFUcapword}[1]{% + \ifMFUhyphen + \MFUhyphencapword{#1}% + \else + \MFUcapwordfirstuc{#1}% + \fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\MFUwordbreak} +%\changes{2.07}{2021-10-15}{new} +%Markup a character (or command) that should be treated as a word +%break. +% \begin{macrocode} +\newrobustcmd*{\MFUwordbreak}[1]{#1} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\MFUhyphencapword} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\newcommand*{\MFUhyphencapword}[1]{% + \@MFUcapword#1-\@nil\@endMFUcapword +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFUcapword} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\def\@MFUcapword#1-#2\@endMFUcapword{% + \MFUcapwordfirstuc{#1}% + \def\@mfu@argii{#2}% + \ifx\@mfu@argii\@nnil + \else + -\@MFUcapword#2\@endMFUcapword + \fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFUwordbreak} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\def\@MFUwordbreak#1\MFUwordbreak#2#3\@endMFUwordbreak{% + \def\@mfu@argiii{#3}% + \ifx\@mfu@argiii\@nnil + \@MFU@cappingword{#1}% + \else + \let\@MFU@cappingword\@MFU@wordbreakcapword + \@MFU@cappingword{#1}% + #2\@MFUwordbreak#3\@endMFUwordbreak + \fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFU@wordbreakcapword} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\newcommand*{\@MFU@wordbreakcapword}[1]{% + \mfu@checkword{#1}% + \@mfu@domakefirstuc{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFUfirstwordbreak} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\def\@MFUfirstwordbreak#1\MFUwordbreak#2#3\@endMFUfirstwordbreak{% + \def\@mfu@argiii{#3}% + \ifx\@mfu@argiii\@nnil + \@MFU@cappingword{#1}% + \else + \let\@MFU@cappingword\@MFU@firstwordbreakcapword + \@MFU@cappingword{#1}% + #2\@MFUfirstwordbreak#3\@endMFUfirstwordbreak + \fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFU@firstwordbreakcapword} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\newcommand*{\@MFU@firstwordbreakcapword}[1]{% + \@mfu@domakefirstuc{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\mfu@checkword} +% Check if word should be capitalised. +% This originally used \sty{etoolbox}'s \cs{ifinlist} command +% but this doesn't work if the word contains grouping. +%\changes{1.09}{2017-07-30}{new} +%\changes{2.02}{2015-12-17}{modified to use loop instead of \cs{ifinlist}} +% \begin{macrocode} +\newcommand*\mfu@checkword[1]{% + \def\mfu@checkword@arg{#1}% + \let\@mfu@domakefirstuc\@MFU@do@capword + \forlistloop\mfu@checkword@do\@mfu@nocaplist +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\mfu@checkword@do} +% Handler for loop used by \cs{mfu@checkword} +%\changes{2.02}{2015-12-17}{new} +% \begin{macrocode} +\newcommand*{\mfu@checkword@do}[1]{% + \def\mfu@checkword@argii{#1}% + \ifdefequal\mfu@checkword@arg\mfu@checkword@argii + {% + \let\@mfu@domakefirstuc\@firstofone + \listbreak + }% + {% +% \end{macrocode} +%Need to check if \cs{@mfu@terminator} has been tacked onto the end. +% \begin{macrocode} + \def\mfu@checkword@argii{#1{\@mfu@terminator}}% + \ifdefequal\mfu@checkword@arg\mfu@checkword@argii + {% + \let\@mfu@domakefirstuc\@firstofone + \listbreak + }% + {}% + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@mfu@nocaplist} +% List of words that shouldn't be capitalised. +%\changes{1.09}{2017-07-30}{new} +% \begin{macrocode} +\newcommand*{\@mfu@nocaplist}{} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\MFUnocap} +% Provide the user with a means to add a word to the list. +% (No expansion performed on the argument.) +%\changes{1.09}{2017-07-30}{new} +% \begin{macrocode} +\newcommand*{\MFUnocap}[1]{\listadd{\@mfu@nocaplist}{#1}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\gMFUnocap} +% Global version. +%\changes{1.09}{2017-07-30}{new} +% \begin{macrocode} +\newcommand*{\gMFUnocap}[1]{\listgadd{\@mfu@nocaplist}{#1}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\MFUclear} +% Clear the list +%\changes{1.09}{2017-07-30}{new} +% \begin{macrocode} +\newcommand*{\MFUclear}{\renewcommand*{\@mfu@nocaplist}{}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xcapitalisewords} +%\changes{1.06}{2012/05/21}{new} +% Short-cut command: +% \begin{macrocode} +\newcommand*{\xcapitalisewords}[1]{% + \expandafter\capitalisewords\expandafter{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\ecapitalisewords} +%\changes{1.10}{2015/05/03}{new} +% Fully expand argument before applying \cs{capitalisewords} +% \begin{macrocode} +\newrobustcmd*{\ecapitalisewords}[1]{% + \protected@edef\@MFU@caparg{#1}% + \expandafter\capitalisewords\expandafter{\@MFU@caparg}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@mfu@nil} +% \begin{macrocode} +\newcommand\@mfu@nil{\unskip} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@mfu@nnil} +% \begin{macrocode} +\newcommand*\@mfu@nnil{\@mfu@nil} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\capitalisefmtwords} +%\changes{2.03}{2016-07-29}{new} +%Like \cs{capitalisewords} but assumes that the phrase contains +%formatting text-block commands. +% \begin{macrocode} +\newcommand*{\capitalisefmtwords}{% + \@ifstar\@s@capitalisefmtwords\@ns@capitalisefmtwords +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@s@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% Starred form. +% \begin{macrocode} +\newcommand*{\@s@capitalisefmtwords}[1]{% + \@@s@checkgrp@@capitalisefmtwords#1\@nil +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@s@checkgrp@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\newcommand*{\@@s@checkgrp@@capitalisefmtwords}{% + \@ifnextchar\bgroup{\@@s@nocs@capitalisefmtwords}{\@@s@capitalisefmtwords}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@s@nocs@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +%Argument starts with a group. +% \begin{macrocode} +\def\@@s@nocs@capitalisefmtwords#1\@nil{% + \capitalisewords{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@s@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\newcommand*{\@@s@capitalisefmtwords}[1]{% + \def\gls@argi{#1}% + \ifx\gls@argi\@MFU@protect +% \end{macrocode} +%Skip \cs{protect} +% \begin{macrocode} + \let\@mfu@capfmtwordsnext\@@s@capitalisefmtwords + \else + \ifx\gls@argi\@nnil +% \end{macrocode} +%Nothing to do. +% \begin{macrocode} + \let\@mfu@capfmtwordsnext\relax + \else + \def\@gls@tmp{\ #1}% + \@onelevel@sanitize\@gls@tmp + \expandafter\@gls@checkcs\@gls@tmp\relax\relax + \if@glscs + \def\@mfu@capfmtwordsnext{\@@s@cs@capitalisefmtwords#1}% + \else + \def\@mfu@capfmtwordsnext{\@@s@nocs@capitalisefmtwords#1}% + \fi + \fi + \fi + \@mfu@capfmtwordsnext +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@s@cs@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\newcommand*{\@@s@cs@capitalisefmtwords}[1]{% + \@ifnextchar\bgroup + {\@@s@cs@g@capitalisefmtwords#1}% + {\@@s@cs@ng@capitalisefmtwords#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@s@cs@g@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\def\@@s@cs@g@capitalisefmtwords#1#2#3\@nil{% + #1{\capitalisewords{#2}}% + \ifblank{#3}% + {}% + {% + \def\gls@add@space{}% + \let\@mfu@checkword\mfu@checkword + \mfu@capitalisewords#3 \@nil\mfu@endcap + }% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@s@cs@ng@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\def\@@s@cs@ng@capitalisefmtwords#1#2\@nil{% + \capitalisewords{#1#2}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@ns@capitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% Unstarred form. +% \begin{macrocode} +\newcommand*{\@ns@capitalisefmtwords}[1]{% + \let\@mfu@checkword\@gobble + \def\gls@add@space{}% + \@capitalisefmtwords#1 \@mfu@nil{} \unskip +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@capitalisefmtwords} +%\changes{2.03}{2016-07-29}{new} +%Take care of group at the start of the word. +% \begin{macrocode} +\newcommand*{\@capitalisefmtwords}{% + \@ifnextchar\bgroup{\@capitalise@g@fmtwords}{\@capitalise@ng@fmtwords}% +} +\newcommand*{\@capitalise@g@fmtwords}[1]{% + \@capitalise@ng@fmtwords{{#1}}% +} +\def\@mfu@ifnil#1#2\@mfu@end@nil#3#4{% + \def\gls@argi{#1}% + \ifx\gls@argi\@mfu@nnil + #3% + \else + #4% + \fi +} +\def\@capitalise@ng@fmtwords#1 {% + \@mfu@ifnil#1\relax\relax\@mfu@end@nil + {% + \def\@mfu@capfmtwordsnext{#1}% + }% + {% + \def\@mfu@capfmtwordsnext{% + \@capitalise@fmtwords#1\@mfu@nil + \def\gls@add@space{ }% + \let\@mfu@checkword\mfu@checkword + \@@cap@nofmtphrase}% + }% + \@mfu@capfmtwordsnext +}% +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@capitalise@fmtwords} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\def\@capitalise@fmtwords#1{% + \@mfu@ifnil#1\relax\relax\@mfu@end@nil + {% +% \end{macrocode} +%Do nothing. +% \begin{macrocode} + \def\@mfu@capfmtwordsnext{#1}% + }% + {% + \def\gls@argi{#1}% + \ifx\gls@argi\@MFU@protect +% \end{macrocode} +%Skip \cs{protect} +% \begin{macrocode} + \def\@mfu@capfmtwordsnext{\@capitalise@fmtwords}% + \else + \def\@gls@tmp{\ #1}% + \@onelevel@sanitize\@gls@tmp + \expandafter\@gls@checkcs\@gls@tmp\relax\relax + \if@glscs + \def\@mfu@capfmtwordsnext{\@@capitalisefmtwords#1}% + \else + \ifx\gls@argi\@empty + \def\@mfu@capfmtwordsnext{\@@capnofmtphrase{}}% + \else + \def\@mfu@capfmtwordsnext{\@@capnofmtphrase#1}% + \fi + \fi + \fi + }% + \@mfu@capfmtwordsnext +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@capitalisefmtwords} +%\changes{2.03}{2016-07-29}{new} +%Check for a group following argument. +% \begin{macrocode} +\def\@@capitalisefmtwords#1{% + \@ifnextchar\bgroup{\@@capfmtsubphrase#1}{\@@capnofmtphrase#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@capnofmtphrase} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\def\@@capnofmtphrase{% + \@ifnextchar\bgroup{\@@cap@g@nofmtphrase}{\@@cap@ng@nofmtphrase}% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@@cap@ng@nofmtphrase} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\def\@@cap@ng@nofmtphrase#1\@mfu@nil{% + \gls@add@space + \@mfu@mid@capitalisewords{#1}% + \def\gls@add@space{ }% +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@@cap@g@nofmtphrase} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\def\@@cap@g@nofmtphrase#1{% + \@@cap@ng@nofmtphrase{{#1}}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@mfu@terminator} +%\changes{2.04}{2016-07-31}{new} +% \begin{macrocode} +\newcommand*\@mfu@terminator{\hbox{}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@capfmtsubphrase} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\def\@@capfmtsubphrase#1#2#3{% +% \end{macrocode} +%Protect any trailing space at the end of the second argument. +% \begin{macrocode} + #1{\@capitalisefmtwords#2{\@mfu@terminator} \@mfu@nil{} \unskip}% + \def\gls@add@space{ }% + \let\@mfu@checkword\mfu@checkword + \@mfu@ifnil#1\relax\relax\@mfu@end@nil + {\let\@mfu@fmtsubphrasenext\relax}% + {\def\@mfu@fmtsubphrasenext{#3}}% + \@mfu@fmtsubphrasenext +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@@cap@nofmtphrase} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\def\@@cap@nofmtphrase#1 {% + \@mfu@ifnil#1\relax\relax\@mfu@end@nil + {% + \def\@mfu@capnofmtwordsnext{#1 }% + }% + {% + \def\@mfu@capnofmtwordsnext{% + \@capitalisefmtwords#1 \@mfu@nil{} \unskip + \def\gls@add@space{ }% + \let\@mfu@checkword\mfu@checkword + \@capitalisefmtwords + }% + }% + \@mfu@capnofmtwordsnext +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xcapitalisefmtwords} +%\changes{2.03}{2016-07-29}{new} +% Short-cut command: +% \begin{macrocode} +\newcommand*{\xcapitalisefmtwords}{% + \@ifstar\@s@xcapitalisefmtwords\@ns@xcapitalisefmtwords +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@s@xcapitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% Starred version +% \begin{macrocode} +\newcommand*{\@s@xcapitalisefmtwords}[1]{% + \expandafter\@s@capitalisefmtwords\expandafter{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@ns@xcapitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +% Unstarred version +% \begin{macrocode} +\newcommand*{\@ns@xcapitalisefmtwords}[1]{% + \expandafter\@ns@capitalisefmtwords\expandafter{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\ecapitalisefmtwords} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\newrobustcmd*{\ecapitalisefmtwords}{% + \@ifstar\@s@ecapitalisefmtwords\@ns@ecapitalisefmtwords +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@s@ecapitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +%Starred version +% \begin{macrocode} +\newcommand*{\@s@ecapitalisefmtwords}[1]{% + \protected@edef\@MFU@caparg{#1}% + \expandafter\@s@capitalisefmtwords\expandafter{\@MFU@caparg}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@ns@ecapitalisefmtwords} +%\changes{2.04}{2016-07-31}{new} +%Unstarred version +% \begin{macrocode} +\newcommand*{\@ns@ecapitalisefmtwords}[1]{% + \protected@edef\@MFU@caparg{#1}% + \expandafter\@ns@capitalisefmtwords\expandafter{\@MFU@caparg}% +} +% \end{macrocode} +%\end{macro} +% +%The remaining code is redundant and will be removed in future. +% +%\begin{macro}{\@org@makefirstuc} +% This is the original definition of \cs{makefirstuc}. It will be +% removed in later versions. +% Syntax: +%\begin{definition} +% \cs{makefirstuc}\marg{text} +%\end{definition} +%\changes{1.08}{2013-11-04}{made robust} +%\changes{2.08}{2022-10-14}{updated to use \cs{MFUsentencecase}} +% \begin{macrocode} +\newif\if@glscs +\newtoks\@glsmfirst +\newtoks\@glsmrest +\newrobustcmd*{\@org@makefirstuc}[1]{% +% \end{macrocode} +% Check if argument starts with \cs{protect} which needs to be +% skipped. +%\changes{2.01}{2015-12-08}{added check for \cs{protect}} +% \begin{macrocode} + \@MFU@p@makefirstuc#1\relax\relax\relax\@end@MFU@protected{#1}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFU@protect} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\newcommand*{\@MFU@protect}{\protect} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFU@skippunc} +%\changes{2.07}{2021-10-15}{new} +% \begin{macrocode} +\newcommand*{\@MFU@skippunc}{\MFUskippunc} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@MFU@p@makefirstuc} +% Internal command to do the required action. +% \begin{macrocode} +\def\@MFU@p@makefirstuc#1#2#3\@end@MFU@protected#4{% +% \end{macrocode} +%\changes{2.03}{2016-07-29}{changed test} +%Test if the first argument is \cs{protect}. +% \begin{macrocode} + \def\gls@argi{#1}% + \ifx\gls@argi\@MFU@protect + \@makefirstuc{#2#3}% + \else +% \end{macrocode} +% v2.07+ also check for \cs{MFUskippunc} +%\changes{2.07}{2021-10-15}{check for \cs{MFUskippunc}} +% \begin{macrocode} + \ifx\gls@argi\@MFU@skippunc + #2\@makefirstuc{#3}% + \else + \@makefirstuc{#4}% + \fi + \fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@makefirstuc} +% Internal command to do the required action. +% \begin{macrocode} +\newcommand*{\@makefirstuc}[1]{% + \def\gls@argi{#1}% + \ifx\gls@argi\@empty +% \end{macrocode} +% If the argument is empty, do nothing. +% \begin{macrocode} + \else +% \end{macrocode} +%\changes{1.03}{2008/12/22}{changed \cs{protected@edef} to \cs{def}} +% \begin{macrocode} + \def\@gls@tmp{\ #1}% + \@onelevel@sanitize\@gls@tmp + \expandafter\@gls@checkcs\@gls@tmp\relax\relax + \if@glscs +% \end{macrocode} +% Check if we have two sequential control sequences. +%\changes{2.0}{2015/09/09}{added check for two control sequences} +% \begin{macrocode} + \expandafter\def\expandafter\@gls@tmp\expandafter{\expandafter + \ \@gobble #1}% + \@onelevel@sanitize\@gls@tmp + \expandafter\@gls@checkcs\@gls@tmp\relax\relax + \if@glscs\@glscsfalse\else\@glscstrue\fi + \fi + \if@glscs + \@gls@getbody #1{}\@nil + \ifx\@gls@rest\@empty + \glsmakefirstuc{#1}% + \else + \expandafter\@gls@split\@gls@rest\@nil + \ifx\@gls@first\@empty + \glsmakefirstuc{#1}% + \else +% \end{macrocode} +%\changes{2.06}{2017-11-14}{check for inner control sequence} +%Does \cs{@gls@first} start with a control sequence? +% \begin{macrocode} + \edef\@gls@tmp\expandafter{\noexpand\ \expandonce\@gls@first}% + \@onelevel@sanitize\@gls@tmp + \expandafter\@gls@checkcs\@gls@tmp\relax\relax + \if@glscs + \edef\@gls@domfirstuc{\expandonce\@gls@body + {\noexpand\makefirstuc{\expandonce\@gls@first + \expandonce\@gls@rest}% + }% + }% + \else + \expandafter\@glsmfirst\expandafter{\@gls@first}% + \expandafter\@glsmrest\expandafter{\@gls@rest}% +% \end{macrocode} +%\changes{2.06}{2017-11-14}{added braces to \cs{glsmakefirstuc} argument} +% \begin{macrocode} + \edef\@gls@domfirstuc{\noexpand\@gls@body + {\noexpand\glsmakefirstuc{\the\@glsmfirst}}% + \the\@glsmrest}% + \fi + \@gls@domfirstuc + \fi + \fi + \else + \glsmakefirstuc{#1}% + \fi + \fi +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@gls@split} +% Put first argument in \cs{@gls@first} and second argument in +% \cs{@gls@rest}: +%\changes{2.03}{2016-07-29}{added check for datatool-base UTF-8 support} +% \begin{macrocode} +\ifdef\dtl@getfirst@UTFviii +{% + \def\@gls@split#1#2\@nil{% + \ifbool{@dtl@utf8} + {% + \expandafter\dtl@if@two@octets#1#2\relax\dtl@end@if@two@octets + {% + \dtl@getfirst@UTFviii#1#2\@nil\end@dtl@getfirst@UTFviii + \let\@gls@first\dtl@first + \let\@gls@rest\dtl@rest + }% + {% + \def\@gls@first{#1}\def\@gls@rest{#2}% + }% + }% + {% +% \end{macrocode} +%\changes{2.04}{2016-07-31}{added missing false part} +% \begin{macrocode} + \def\@gls@first{#1}\def\@gls@rest{#2}% + }% + } +}% +{% + \def\@gls@split#1#2\@nil{% + \def\@gls@first{#1}\def\@gls@rest{#2}% + } +} +% \end{macrocode} +%\end{macro} +% \begin{macrocode} +\def\@gls@checkcs#1 #2#3\relax{% + \def\@gls@argi{#1}\def\@gls@argii{#2}% + \ifx\@gls@argi\@gls@argii + \@glscstrue + \else + \@glscsfalse + \fi +} +% \end{macrocode} +% Has \sty{datatool-base} v2.24 (or above) been loaded? If so and we +% have UTF-8 enabled, we can grab the first octet. +%\begin{macro}{\@mfu@applytofirst} +%\changes{2.03}{2016-07-29}{new} +% \begin{macrocode} +\ifdef\dtl@getfirst@UTFviii +{% + \def\@mfu@applytofirst#1#2\@mfu@end@applytofirst#3{% + \expandafter\dtl@if@two@octets#1#2\relax\dtl@end@if@two@octets + {% + \dtl@getfirst@UTFviii#1#2\@nil\end@dtl@getfirst@UTFviii + \expandafter#3\expandafter{\dtl@first}\dtl@rest + }% + {% +% \end{macrocode} +%First argument needs to be grouped in case it consists of more than +%one token. +%\changes{2.05}{2017-11-10}{grouped first argument} +% \begin{macrocode} + #3{#1}#2% + }% + }% +}% +{% +% \end{macrocode} +%First argument needs to be grouped in case it consists of more than +%one token. +%\changes{2.05}{2017-11-10}{grouped first argument} +% \begin{macrocode} + \def\@mfu@applytofirst#1#2\@mfu@end@applytofirst#3{% + #3{#1}#2% + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\MFUapplytofirst} +%\changes{2.03}{2016-07-29}{new} +%\changes{2.08}{2022-10-14}{deprecated} +%\begin{definition} +%\cs{MFUapplytofirst}\marg{cs}\marg{text} +%\end{definition} +% Apply \meta{cs} to first token of text, or first UTF-8 character +% if \sty{datatool-base} v2.24 above has been loaded with the utf8 +% support enabled. Deprecated as from v2.08. +% \begin{macrocode} +\ifdef\dtl@getfirst@UTFviii +{% + \newcommand*{\MFUapplytofirst}[2]{% + \ifbool{@dtl@utf8} + {% + \ifblank{#2}% + {#1{#2}}% + {% + \ifblank{#1}% + {#1#2}% + {% + \@mfu@applytofirst#2\@mfu@end@applytofirst#1\relax + }% + }% + }% + {% + #1#2% + }% + } +}% +{% + \newcommand*{\MFUapplytofirst}[2]{% + #1#2% + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@gls@makefirstuc} +%\changes{2.08}{2022-10-14}{updated to use \cs{MFUsentencecase}} +%Deprecated. +% \begin{macrocode} +\def\@gls@makefirstuc#1{\MFUsentencecase{#1}} +% \end{macrocode} +%\end{macro} +% +% Get the first grouped argument and store in \cs{@gls@body}. +% \begin{macrocode} +\def\@gls@getbody#1#{\def\@gls@body{#1}\@gls@gobbletonil} +% \end{macrocode} +% Scoup up everything to \cs{@nil} and store in \cs{@gls@rest}: +% \begin{macrocode} +\def\@gls@gobbletonil#1\@nil{\def\@gls@rest{#1}} +% \end{macrocode} +% +%\iffalse +% \begin{macrocode} +% +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*mfirstuc-english.sty> +% \end{macrocode} +%\fi +%\subsection{Mfirstuc-english Documented Code} +%\label{sec:code:mfirstuc-english} +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{mfirstuc-english}[2022/10/14 v2.08 (NLCT)] +% \end{macrocode} +% Load \sty{mfirstuc} if not already loaded: +% \begin{macrocode} +\RequirePackage{mfirstuc} +% \end{macrocode} +% Add no-cap words. This list isn't complete. I~don't intend adding +% disputed words. Additional words can be added to the document in +% a~similar manner. +% \begin{macrocode} +\MFUnocap{a} +\MFUnocap{an} +\MFUnocap{and} +\MFUnocap{but} +\MFUnocap{for} +\MFUnocap{in} +\MFUnocap{of} +\MFUnocap{or} +\MFUnocap{no} +\MFUnocap{nor} +\MFUnocap{so} +\MFUnocap{some} +\MFUnocap{the} +\MFUnocap{with} +\MFUnocap{yet} +% \end{macrocode} +%\iffalse +% \begin{macrocode} +% +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*mfirstuc-2021-10-15.sty> +% \end{macrocode} +%\fi +% \section{Rollback v2.07 (mfirstuc-2021-10-15.sty)} +% Version 2.07 preserved for rollback. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{mfirstuc}[2021/10/15 v2.07 (NLCT)] +\RequirePackage{etoolbox} +\newif\if@glscs +\newtoks\@glsmfirst +\newtoks\@glsmrest +\newrobustcmd*{\makefirstuc}[1]{% + \@MFU@p@makefirstuc#1\relax\relax\relax\@end@MFU@protected{#1}% +} +\newcommand*{\@MFU@protect}{\protect} +\newcommand*{\@MFU@skippunc}{\MFUskippunc} +\newrobustcmd*{\MFUskippunc}[1]{#1} \def\@MFU@p@makefirstuc#1#2#3\@end@MFU@protected#4{% -% \end{macrocode} -%\changes{2.03}{2016-07-29}{changed test} -%Test if the first argument is \cs{protect}. -% \begin{macrocode} \def\gls@argi{#1}% \ifx\gls@argi\@MFU@protect \@makefirstuc{#2#3}% \else -% \end{macrocode} -% v2.07+ also check for \cs{MFUskippunc} -%\changes{2.07}{2021-10-15}{check for \cs{MFUskippunc}} -% \begin{macrocode} \ifx\gls@argi\@MFU@skippunc #2\@makefirstuc{#3}% \else @@ -191,30 +1492,14 @@ mfirstuc.dtx \fi \fi } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@makefirstuc} -% Internal command to do the required action. -% \begin{macrocode} \newcommand*{\@makefirstuc}[1]{% \def\gls@argi{#1}% \ifx\gls@argi\@empty -% \end{macrocode} -% If the argument is empty, do nothing. -% \begin{macrocode} \else -% \end{macrocode} -%\changes{1.03}{2008/12/22}{changed \cs{protected@edef} to \cs{def}} -% \begin{macrocode} \def\@gls@tmp{\ #1}% \@onelevel@sanitize\@gls@tmp \expandafter\@gls@checkcs\@gls@tmp\relax\relax \if@glscs -% \end{macrocode} -% Check if we have two sequential control sequences. -%\changes{2.0}{2015/09/09}{added check for two control sequences} -% \begin{macrocode} \expandafter\def\expandafter\@gls@tmp\expandafter{\expandafter \ \@gobble #1}% \@onelevel@sanitize\@gls@tmp @@ -230,10 +1515,6 @@ mfirstuc.dtx \ifx\@gls@first\@empty \glsmakefirstuc{#1}% \else -% \end{macrocode} -%\changes{2.06}{2017-11-14}{check for inner control sequence} -%Does \cs{@gls@first} start with a control sequence? -% \begin{macrocode} \edef\@gls@tmp\expandafter{\noexpand\ \expandonce\@gls@first}% \@onelevel@sanitize\@gls@tmp \expandafter\@gls@checkcs\@gls@tmp\relax\relax @@ -246,9 +1527,6 @@ mfirstuc.dtx \else \expandafter\@glsmfirst\expandafter{\@gls@first}% \expandafter\@glsmrest\expandafter{\@gls@rest}% -% \end{macrocode} -%\changes{2.06}{2017-11-14}{added braces to \cs{glsmakefirstuc} argument} -% \begin{macrocode} \edef\@gls@domfirstuc{\noexpand\@gls@body {\noexpand\glsmakefirstuc{\the\@glsmfirst}}% \the\@glsmrest}% @@ -261,13 +1539,6 @@ mfirstuc.dtx \fi \fi } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@gls@split} -% Put first argument in \cs{@gls@first} and second argument in -% \cs{@gls@rest}: -%\changes{2.03}{2016-07-29}{added check for datatool-base UTF-8 support} -% \begin{macrocode} \ifdef\dtl@getfirst@UTFviii {% \def\@gls@split#1#2\@nil{% @@ -284,9 +1555,6 @@ mfirstuc.dtx }% }% {% -% \end{macrocode} -%\changes{2.04}{2016-07-31}{added missing false part} -% \begin{macrocode} \def\@gls@first{#1}\def\@gls@rest{#2}% }% } @@ -296,9 +1564,6 @@ mfirstuc.dtx \def\@gls@first{#1}\def\@gls@rest{#2}% } } -% \end{macrocode} -%\end{macro} -% \begin{macrocode} \def\@gls@checkcs#1 #2#3\relax{% \def\@gls@argi{#1}\def\@gls@argii{#2}% \ifx\@gls@argi\@gls@argii @@ -307,12 +1572,6 @@ mfirstuc.dtx \@glscsfalse \fi } -% \end{macrocode} -% Has \sty{datatool-base} v2.24 (or above) been loaded? If so and we -% have UTF-8 enabled, we can grab the first octet. -%\begin{macro}{\@mfu@applytofirst} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \ifdef\dtl@getfirst@UTFviii {% \def\@mfu@applytofirst#1#2\@mfu@end@applytofirst#3{% @@ -322,35 +1581,13 @@ mfirstuc.dtx \expandafter#3\expandafter{\dtl@first}\dtl@rest }% {% -% \end{macrocode} -%First argument needs to be grouped in case it consists of more than -%one token. -%\changes{2.05}{2017-11-10}{grouped first argument} -% \begin{macrocode} #3{#1}#2% }% }% }% {% -% \end{macrocode} -%First argument needs to be grouped in case it consists of more than -%one token. -%\changes{2.05}{2017-11-10}{grouped first argument} -% \begin{macrocode} \def\@mfu@applytofirst#1#2\@mfu@end@applytofirst#3{#3{#1}#2} } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\MFUapplytofirst} -%\changes{2.03}{2016-07-29}{new} -%\begin{definition} -%\cs{MFUapplytofirst}\marg{cs}\marg{text} -%\end{definition} -% Apply \meta{cs} to first token of text, or first UTF-8 character -% if \sty{datatool-base} v2.24 above has been loaded with the utf8 -% support enabled. -% \begin{macrocode} \ifdef\dtl@getfirst@UTFviii {% \newcommand*{\MFUapplytofirst}[2]{% @@ -374,92 +1611,29 @@ mfirstuc.dtx {% \newcommand*{\MFUapplytofirst}[2]{#1#2} } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@gls@makefirstuc} -% Make first thing upper case: -% \begin{macrocode} \def\@gls@makefirstuc#1{\MFUapplytofirst\mfirstucMakeUppercase{#1}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\mfirstucMakeUppercase} -% Allow user to replace \cs{MakeUppercase} with another case -% changing command. -% \begin{macrocode} \newcommand*{\mfirstucMakeUppercase}{\MakeUppercase} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\glsmakefirstuc} -%\changes{1.05}{2011/04/02}{new} -% Provide a user command to make it easier to customise. -% \begin{macrocode} \newcommand*{\glsmakefirstuc}[1]{\@gls@makefirstuc{#1}} -% \end{macrocode} -%\end{macro} -% -% Get the first grouped argument and store in \cs{@gls@body}. -% \begin{macrocode} \def\@gls@getbody#1#{\def\@gls@body{#1}\@gls@gobbletonil} -% \end{macrocode} -% Scoup up everything to \cs{@nil} and store in \cs{@gls@rest}: -% \begin{macrocode} \def\@gls@gobbletonil#1\@nil{\def\@gls@rest{#1}} -% \end{macrocode} -% -%\begin{macro}{\xmakefirstuc} -% Expand argument once before applying \cs{makefirstuc} -% (added v1.01). -% \begin{macrocode} \newcommand*{\xmakefirstuc}[1]{% \expandafter\makefirstuc\expandafter{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\emakefirstuc} -%\changes{1.10}{2015/05/03}{new} -% Fully expand argument before applying \cs{makefirstuc} -% \begin{macrocode} \newrobustcmd*{\emakefirstuc}[1]{% \protected@edef\@MFU@caparg{#1}% \expandafter\makefirstuc\expandafter{\@MFU@caparg}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\capitalisewords} -%\changes{1.06}{2012/05/21}{new} -% Capitalise each word in the argument. Words are considered to be -% separated by plain spaces (i.e.\ non-breakable spaces won't be -% considered a word break). -%\changes{1.08}{2013-11-04}{made robust} -%\changes{1.09}{2017-07-30}{added check for words that shouldn't be -%capitalised} -% \begin{macrocode} \newrobustcmd*{\capitalisewords}[1]{% \let\@mfu@checkword\@gobble \def\gls@add@space{}% \let\@mfu@domakefirstuc\@MFU@dofirst@capword \mfu@capitalisewords#1 \@nil\mfu@endcap } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@mfu@mid@capitalisewords} -%\changes{2.03}{2016-07-29}{new} -%\cs{@mfu@checkword} needs to be set before use. -% \begin{macrocode} \newcommand*{\@mfu@mid@capitalisewords}[1]{% \def\gls@add@space{}% \let\@mfu@domakefirstuc\@MFU@do@capword \mfu@capitalisewords#1 \@nil\mfu@endcap } -% \end{macrocode} -%\end{macro} -% -% \begin{macrocode} \def\mfu@capitalisewords#1 #2\mfu@endcap{% \def\mfu@cap@first{#1}% \def\mfu@cap@second{#2}% @@ -476,40 +1650,16 @@ mfirstuc.dtx \next@mfu@cap#2\mfu@endcap } \def\mfu@noop#1\mfu@endcap{} -% \end{macrocode} -% -%\begin{macro}{\ifMFUhyphen} -%\changes{2.03}{2016-07-29}{new} -%Split on hyphens. -% \begin{macrocode} \newif\ifMFUhyphen \MFUhyphenfalse -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@MFU@do@capword} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \newcommand*{\@MFU@do@capword}[1]{% \let\@MFU@cappingword\MFUcapword \@MFUwordbreak#1\MFUwordbreak{}\@nil\@endMFUwordbreak } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@MFU@dofirst@capword} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \newcommand*{\@MFU@dofirst@capword}[1]{% \let\@MFU@cappingword\MFUcapword \@MFUfirstwordbreak#1\MFUwordbreak{}\@nil\@endMFUfirstwordbreak } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\MFUcapword} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \newcommand*{\MFUcapword}[1]{% \ifMFUhyphen \MFUhyphencapword{#1}% @@ -517,39 +1667,13 @@ mfirstuc.dtx \MFUcapwordfirstuc{#1}% \fi } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\MFUcapwordfirstuc} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \newcommand*{\MFUcapwordfirstuc}[1]{% \makefirstuc{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\MFUwordbreak} -%\changes{2.07}{2021-10-15}{new} -%Markup a character (or command) that should be treated as a word -%break. -% \begin{macrocode} \newrobustcmd*{\MFUwordbreak}[1]{#1} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\MFUhyphencapword} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \newcommand*{\MFUhyphencapword}[1]{% \@MFUcapword#1-\@nil\@endMFUcapword } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@MFUcapword} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \def\@MFUcapword#1-#2\@endMFUcapword{% \MFUcapwordfirstuc{#1}% \def\@mfu@argii{#2}% @@ -558,12 +1682,6 @@ mfirstuc.dtx -\@MFUcapword#2\@endMFUcapword \fi } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@MFUwordbreak} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \def\@MFUwordbreak#1\MFUwordbreak#2#3\@endMFUwordbreak{% \def\@mfu@argiii{#3}% \ifx\@mfu@argiii\@nnil @@ -574,22 +1692,10 @@ mfirstuc.dtx #2\@MFUwordbreak#3\@endMFUwordbreak \fi } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@MFU@wordbreakcapword} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \newcommand*{\@MFU@wordbreakcapword}[1]{% \mfu@checkword{#1}% \@mfu@domakefirstuc{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@MFUfirstwordbreak} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \def\@MFUfirstwordbreak#1\MFUwordbreak#2#3\@endMFUfirstwordbreak{% \def\@mfu@argiii{#3}% \ifx\@mfu@argiii\@nnil @@ -600,37 +1706,14 @@ mfirstuc.dtx #2\@MFUfirstwordbreak#3\@endMFUfirstwordbreak \fi } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@MFU@firstwordbreakcapword} -%\changes{2.07}{2021-10-15}{new} -% \begin{macrocode} \newcommand*{\@MFU@firstwordbreakcapword}[1]{% \@mfu@domakefirstuc{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\mfu@checkword} -% Check if word should be capitalised. -% This originally used \sty{etoolbox}'s \ics{ifinlist} command -% but this doesn't work if the word contains grouping. -%\changes{1.09}{2017-07-30}{new} -%\changes{2.02}{2015-12-17}{modified to use loop instead of \cs{ifinlist}} -% \begin{macrocode} \newcommand*\mfu@checkword[1]{% \def\mfu@checkword@arg{#1}% \let\@mfu@domakefirstuc\@MFU@do@capword \forlistloop\mfu@checkword@do\@mfu@nocaplist } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\mfu@checkword@do} -% Handler for loop used by \cs{mfu@checkword} -%\changes{2.02}{2015-12-17}{new} -% \begin{macrocode} \newcommand*{\mfu@checkword@do}[1]{% \def\mfu@checkword@argii{#1}% \ifdefequal\mfu@checkword@arg\mfu@checkword@argii @@ -639,9 +1722,6 @@ mfirstuc.dtx \listbreak }% {% -% \end{macrocode} -%Need to check if \cs{@mfu@terminator} has been tacked onto the end. -% \begin{macrocode} \def\mfu@checkword@argii{#1{\@mfu@terminator}}% \ifdefequal\mfu@checkword@arg\mfu@checkword@argii {% @@ -651,129 +1731,37 @@ mfirstuc.dtx {}% }% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@mfu@nocaplist} -% List of words that shouldn't be capitalised. -%\changes{1.09}{2017-07-30}{new} -% \begin{macrocode} -\newcommand*{\@mfu@nocaplist}{} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\MFUnocap} -% Provide the user with a means to add a word to the list. -% (No expansion performed on the argument.) -%\changes{1.09}{2017-07-30}{new} -% \begin{macrocode} -\newcommand*{\MFUnocap}[1]{\listadd{\@mfu@nocaplist}{#1}} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\gMFUnocap} -% Global version. -%\changes{1.09}{2017-07-30}{new} -% \begin{macrocode} -\newcommand*{\gMFUnocap}[1]{\listgadd{\@mfu@nocaplist}{#1}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\MFUclear} -% Clear the list -%\changes{1.09}{2017-07-30}{new} -% \begin{macrocode} +\newcommand*{\@mfu@nocaplist}{} +\newcommand*{\MFUnocap}[1]{\listadd{\@mfu@nocaplist}{#1}} +\newcommand*{\gMFUnocap}[1]{\listgadd{\@mfu@nocaplist}{#1}} \newcommand*{\MFUclear}{\renewcommand*{\@mfu@nocaplist}{}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\xcapitalisewords} -%\changes{1.06}{2012/05/21}{new} -% Short-cut command: -% \begin{macrocode} \newcommand*{\xcapitalisewords}[1]{% \expandafter\capitalisewords\expandafter{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\ecapitalisewords} -%\changes{1.10}{2015/05/03}{new} -% Fully expand argument before applying \cs{capitalisewords} -% \begin{macrocode} \newrobustcmd*{\ecapitalisewords}[1]{% \protected@edef\@MFU@caparg{#1}% \expandafter\capitalisewords\expandafter{\@MFU@caparg}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@mfu@nil} -% \begin{macrocode} \newcommand\@mfu@nil{\unskip} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@mfu@nnil} -% \begin{macrocode} \newcommand*\@mfu@nnil{\@mfu@nil} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\capitalisefmtwords} -%\changes{2.03}{2016-07-29}{new} -%Like \cs{capitalisewords} but assumes that the phrase contains -%formatting text-block commands. -% \begin{macrocode} \newcommand*{\capitalisefmtwords}{% \@ifstar\@s@capitalisefmtwords\@ns@capitalisefmtwords } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@s@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% Starred form. -% \begin{macrocode} \newcommand*{\@s@capitalisefmtwords}[1]{% \@@s@checkgrp@@capitalisefmtwords#1\@nil } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@s@checkgrp@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \newcommand*{\@@s@checkgrp@@capitalisefmtwords}{% \@ifnextchar\bgroup{\@@s@nocs@capitalisefmtwords}{\@@s@capitalisefmtwords}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@s@nocs@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -%Argument starts with a group. -% \begin{macrocode} \def\@@s@nocs@capitalisefmtwords#1\@nil{% \capitalisewords{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@s@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \newcommand*{\@@s@capitalisefmtwords}[1]{% \def\gls@argi{#1}% \ifx\gls@argi\@MFU@protect -% \end{macrocode} -%Skip \cs{protect} -% \begin{macrocode} \let\@mfu@capfmtwordsnext\@@s@capitalisefmtwords \else \ifx\gls@argi\@nnil -% \end{macrocode} -%Nothing to do. -% \begin{macrocode} \let\@mfu@capfmtwordsnext\relax \else \def\@gls@tmp{\ #1}% @@ -788,23 +1776,11 @@ mfirstuc.dtx \fi \@mfu@capfmtwordsnext } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@s@cs@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \newcommand*{\@@s@cs@capitalisefmtwords}[1]{% \@ifnextchar\bgroup {\@@s@cs@g@capitalisefmtwords#1}% {\@@s@cs@ng@capitalisefmtwords#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@s@cs@g@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \def\@@s@cs@g@capitalisefmtwords#1#2#3\@nil{% #1{\capitalisewords{#2}}% \ifblank{#3}% @@ -815,33 +1791,14 @@ mfirstuc.dtx \mfu@capitalisewords#3 \@nil\mfu@endcap }% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@s@cs@ng@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \def\@@s@cs@ng@capitalisefmtwords#1#2\@nil{% \capitalisewords{#1#2}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@ns@capitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% Unstarred form. -% \begin{macrocode} \newcommand*{\@ns@capitalisefmtwords}[1]{% \let\@mfu@checkword\@gobble \def\gls@add@space{}% \@capitalisefmtwords#1 \@mfu@nil{} \unskip } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@capitalisefmtwords} -%\changes{2.03}{2016-07-29}{new} -%Take care of group at the start of the word. -% \begin{macrocode} \newcommand*{\@capitalisefmtwords}{% \@ifnextchar\bgroup{\@capitalise@g@fmtwords}{\@capitalise@ng@fmtwords}% } @@ -870,25 +1827,14 @@ mfirstuc.dtx }% \@mfu@capfmtwordsnext }% -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@capitalise@fmtwords} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \def\@capitalise@fmtwords#1{% \@mfu@ifnil#1\relax\relax\@mfu@end@nil {% -% \end{macrocode} -%Do nothing. -% \begin{macrocode} \def\@mfu@capfmtwordsnext{#1}% }% {% \def\gls@argi{#1}% \ifx\gls@argi\@MFU@protect -% \end{macrocode} -%Skip \cs{protect} -% \begin{macrocode} \def\@mfu@capfmtwordsnext{\@capitalise@fmtwords}% \else \def\@gls@tmp{\ #1}% @@ -907,60 +1853,22 @@ mfirstuc.dtx }% \@mfu@capfmtwordsnext } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@capitalisefmtwords} -%\changes{2.03}{2016-07-29}{new} -%Check for a group following argument. -% \begin{macrocode} \def\@@capitalisefmtwords#1{% \@ifnextchar\bgroup{\@@capfmtsubphrase#1}{\@@capnofmtphrase#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@capnofmtphrase} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \def\@@capnofmtphrase{% \@ifnextchar\bgroup{\@@cap@g@nofmtphrase}{\@@cap@ng@nofmtphrase}% } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@cap@ng@nofmtphrase} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \def\@@cap@ng@nofmtphrase#1\@mfu@nil{% \gls@add@space \@mfu@mid@capitalisewords{#1}% \def\gls@add@space{ }% } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@@cap@g@nofmtphrase} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \def\@@cap@g@nofmtphrase#1{% \@@cap@ng@nofmtphrase{{#1}}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@mfu@terminator} -%\changes{2.04}{2016-07-31}{new} -% \begin{macrocode} \newcommand*\@mfu@terminator{\hbox{}} -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@capfmtsubphrase} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \def\@@capfmtsubphrase#1#2#3{% -% \end{macrocode} -%Protect any trailing space at the end of the second argument. -% \begin{macrocode} #1{\@capitalisefmtwords#2{\@mfu@terminator} \@mfu@nil{} \unskip}% \def\gls@add@space{ }% \let\@mfu@checkword\mfu@checkword @@ -969,12 +1877,6 @@ mfirstuc.dtx {\def\@mfu@fmtsubphrasenext{#3}}% \@mfu@fmtsubphrasenext } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@@cap@nofmtphrase} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \def\@@cap@nofmtphrase#1 {% \@mfu@ifnil#1\relax\relax\@mfu@end@nil {% @@ -990,110 +1892,30 @@ mfirstuc.dtx }% \@mfu@capnofmtwordsnext } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\xcapitalisefmtwords} -%\changes{2.03}{2016-07-29}{new} -% Short-cut command: -% \begin{macrocode} \newcommand*{\xcapitalisefmtwords}{% \@ifstar\@s@xcapitalisefmtwords\@ns@xcapitalisefmtwords } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@s@xcapitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% Starred version -% \begin{macrocode} \newcommand*{\@s@xcapitalisefmtwords}[1]{% \expandafter\@s@capitalisefmtwords\expandafter{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@ns@xcapitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -% Unstarred version -% \begin{macrocode} \newcommand*{\@ns@xcapitalisefmtwords}[1]{% \expandafter\@ns@capitalisefmtwords\expandafter{#1}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\ecapitalisefmtwords} -%\changes{2.03}{2016-07-29}{new} -% \begin{macrocode} \newrobustcmd*{\ecapitalisefmtwords}{% \@ifstar\@s@ecapitalisefmtwords\@ns@ecapitalisefmtwords } -% \end{macrocode} -%\end{macro} -%\begin{macro}{\@s@ecapitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -%Starred version -% \begin{macrocode} \newcommand*{\@s@ecapitalisefmtwords}[1]{% \protected@edef\@MFU@caparg{#1}% \expandafter\@s@capitalisefmtwords\expandafter{\@MFU@caparg}% } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\@ns@ecapitalisefmtwords} -%\changes{2.04}{2016-07-31}{new} -%Unstarred version -% \begin{macrocode} \newcommand*{\@ns@ecapitalisefmtwords}[1]{% \protected@edef\@MFU@caparg{#1}% \expandafter\@ns@capitalisefmtwords\expandafter{\@MFU@caparg}% } % \end{macrocode} -%\end{macro} -%\iffalse -% \begin{macrocode} -% -% \end{macrocode} -%\fi -%\iffalse -% \begin{macrocode} -%<*mfirstuc-english.sty> -% \end{macrocode} -%\fi -%\subsection{Mfirstuc-english Documented Code} -%\label{sec:code:mfirstuc-english} -% \begin{macrocode} -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{mfirstuc-english}[2021/10/15 v2.07 (NLCT)] -% \end{macrocode} -% Load \sty{mfirstuc} if not already loaded: -% \begin{macrocode} -\RequirePackage{mfirstuc} -% \end{macrocode} -% Add no-cap words. This list isn't complete. I~don't intend adding -% disputed words. Additional words can be added to the document in -% a~similar manner. -% \begin{macrocode} -\MFUnocap{a} -\MFUnocap{an} -\MFUnocap{and} -\MFUnocap{but} -\MFUnocap{for} -\MFUnocap{in} -\MFUnocap{of} -\MFUnocap{or} -\MFUnocap{no} -\MFUnocap{nor} -\MFUnocap{so} -\MFUnocap{some} -\MFUnocap{the} -\MFUnocap{with} -\MFUnocap{yet} -% \end{macrocode} %\iffalse % \begin{macrocode} -% +% % \end{macrocode} %\fi %\iffalse @@ -1122,7 +1944,32 @@ mfirstuc.dtx \tableofcontents -\section{First Letter Upper Case} +\section{Sentence Case (First Letter Upper Case)} +\label{sec:sentencecase} + +\verb|\MFUsentencecase{abc}.| +\MFUsentencecase{abc}. + +\verb|\MFUsentencecase{{\em abc}}.| +\MFUsentencecase{{\em abc}}. + +\verb|\MFUsentencecase{\emph{abc}}.| +\MFUsentencecase{\emph{abc}}. + +\verb|\MFUsentencecase{\ae bc}.| +\MFUsentencecase{\ae bc}. + +\verb|\MFUsentencecase{{\ae}bc}.| +\MFUsentencecase{{\ae}bc}. + +\verb|\newcommand{\abc}{abc}\MFUsentencecase{\abc}.| +\newcommand{\abc}{abc}% +\MFUsentencecase{\abc}. + +\verb|\MFUsentencecase{\ref{sec:sentencecase}bc}.| +\MFUsentencecase{\ref{sec:sentencecase}bc}. + +\verb|\makefirstuc| doesn't expand its argument and skips exclusions. \verb|\makefirstuc{abc}.| \makefirstuc{abc}. @@ -1133,31 +1980,29 @@ mfirstuc.dtx \verb|\makefirstuc{\emph{abc}}.| \makefirstuc{\emph{abc}}. -\verb|\makefirstuc{\ae bc}.| -\makefirstuc{\ae bc}. +\verb|\makefirstuc{\ref{sec:sentencecase}bc}.| +\makefirstuc{\ref{sec:sentencecase}bc}. -\verb|\makefirstuc{{\ae}bc}.| -\makefirstuc{{\ae}bc}. +\newcommand{\strong}[1]{\textcolor{red}{#1}} +\verb|\makefirstuc{\strong{abc}d}| +\makefirstuc{\strong{abc}d} -\verb|\newcommand{\abc}{abc}\xmakefirstuc{\abc}.| -\newcommand{\abc}{abc}% -\xmakefirstuc{\abc}. +\verb|\makefirstuc{\protect\strong{abc}d}| +\makefirstuc{\protect\strong{abc}d} + +Exclusions vs blockers: -% I know \textbf is robust already and doesn't need protecting. -% This is just to test what happens if the argument starts -% with \protect -\newcommand*{\mytext}{\protect\textbf{some text}} -Protected formatting: \xmakefirstuc{\mytext}. +\verb|\MFUsentencecase{\NoCaseChange{abc} xyz}| +\MFUsentencecase{\NoCaseChange{abc} xyz} -\renewcommand*{\mytext}{\ae\oe{some text}} -Sequential commands: \xmakefirstuc{\mytext}. +\verb|\makefirstuc{\NoCaseChange{abc} xyz}| +\makefirstuc{\NoCaseChange{abc} xyz} -\verb|\makefirstuc{\MFUskippunc{?`}c\'omo est\'as?}| -\makefirstuc{\MFUskippunc{?`}c\'omo est\'as?} +\begingroup +\verb|\MFUblocker{\NoCaseChange}\makefirstuc{\NoCaseChange{abc} xyz}| +\MFUblocker{\NoCaseChange}\makefirstuc{\NoCaseChange{abc} xyz} -\renewcommand{\mytext}{\MFUskippunc{?`}c\'omo est\'as?} -Fully expanded: -\emakefirstuc{\mytext} +\endgroup \section{Title Case (No Formatting Commands)} @@ -1412,20 +2257,28 @@ Compare with %\fi %\iffalse % \begin{macrocode} -%<*mfirstuc.perl> +%<*mfirstuc.l2h> % \end{macrocode} %\fi %\iffalse % \begin{macrocode} -# File : mfirstuc.perl +# File : mfirstuc.l2h # Author : Nicola L. C. Talbot -# Date : 2012-09-21 -# Version : 1.0 +# Version : 2.08 (2022-10-14) # Description : LaTeX2HTML (limited!) implementation of mfirstuc package # This is a LaTeX2HTML style implementing the mfirstuc package, and -# is distributed as part of the glossaries package. -# Copyright 2007 Nicola L.C. Talbot +# was distributed as part of the glossaries package, but is now +# distributed as part of the mfirstuc package. There's no guarantee +# that it still works with new versions of LaTeX2HTML. +# +# v2.08: +# - The version number has been updated +# - file extension changed from .perl to .l2h to more easily identify it as a +# LaTeX2HTML file rather than a standalone Perl script. +# - Added MFUsentencecase but it's identical to makefirstuc +# +# Copyright 2007-2022 Nicola L.C. Talbot # This work may be distributed and/or modified under the # conditions of the LaTeX Project Public License, either version 1.3 # of this license of (at your option) any later version. @@ -1453,6 +2306,17 @@ sub do_cmd_makefirstuc{ &translate_commands("\\glsmakefirstuc $text") . $_; } +sub do_cmd_MFUsentencecase{ + local($_) = @_; + + local($id,$text); + + $text = &missing_braces unless + s/$next_pair_pr_rx/$id=$1;$text=$2;''/eo; + + &translate_commands("\\glsmakefirstuc $text") . $_; +} + sub do_cmd_xmakefirstuc{ local($_) = @_; @@ -1550,7 +2414,7 @@ sub get_next_object{ %\fi %\iffalse % \begin{macrocode} -% +% % \end{macrocode} %\fi %\Finale diff --git a/macros/latex/contrib/mfirstuc/mfirstuc.ins b/macros/latex/contrib/mfirstuc/mfirstuc.ins index 02e695dcc1..c928c1ffe9 100644 --- a/macros/latex/contrib/mfirstuc/mfirstuc.ins +++ b/macros/latex/contrib/mfirstuc/mfirstuc.ins @@ -1,10 +1,10 @@ -% mfirstuc.ins generated using makedtx version 1.2 2021/10/15 17:46 +% mfirstuc.ins generated using makedtx version 1.2 2022/10/18 9:21 \input docstrip \preamble mfirstuc.dtx - Copyright 2021 Nicola Talbot + Copyright 2022 Nicola Talbot This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 @@ -18,7 +18,7 @@ The Current Maintainer of this work is Nicola Talbot. - This work consists of the files mfirstuc.dtx and mfirstuc.ins and the derived files mfirstuc.sty, mfirstuc-english.sty, sample-mfirstuc.tex, mfirstuc.perl. + This work consists of the files mfirstuc.dtx and mfirstuc.ins and the derived files mfirstuc.sty, mfirstuc-english.sty, mfirstuc-2021-10-15.sty, sample-mfirstuc.tex, mfirstuc.l2h. \endpreamble @@ -28,8 +28,10 @@ \usepostamble\defaultpostamble\from{mfirstuc.dtx}{mfirstuc.sty,package}} \file{mfirstuc-english.sty}{\usepreamble\defaultpreamble \usepostamble\defaultpostamble\from{mfirstuc.dtx}{mfirstuc-english.sty,package}} +\file{mfirstuc-2021-10-15.sty}{\usepreamble\defaultpreamble +\usepostamble\defaultpostamble\from{mfirstuc.dtx}{mfirstuc-2021-10-15.sty,package}} \file{sample-mfirstuc.tex}{\nopreamble\nopostamble\from{mfirstuc.dtx}{sample-mfirstuc.tex}} -\file{mfirstuc.perl}{\nopreamble\nopostamble\from{mfirstuc.dtx}{mfirstuc.perl}} +\file{mfirstuc.l2h}{\nopreamble\nopostamble\from{mfirstuc.dtx}{mfirstuc.l2h}} } \endbatchfile diff --git a/macros/latex/contrib/mfirstuc/sample-mfirstuc.pdf b/macros/latex/contrib/mfirstuc/sample-mfirstuc.pdf index 4433af0c32..ff8780d555 100644 Binary files a/macros/latex/contrib/mfirstuc/sample-mfirstuc.pdf and b/macros/latex/contrib/mfirstuc/sample-mfirstuc.pdf differ diff --git a/macros/latex/contrib/mfirstuc/sample-mfirstuc.tex b/macros/latex/contrib/mfirstuc/sample-mfirstuc.tex deleted file mode 100644 index 7438c770cc..0000000000 --- a/macros/latex/contrib/mfirstuc/sample-mfirstuc.tex +++ /dev/null @@ -1,292 +0,0 @@ - % This file is public domain - % If you want to use arara, you need the following directive: - % arara: pdflatex: { synctex: on } - % arara: pdflatex: { synctex: on } -\documentclass{article} - -\usepackage[a4paper]{geometry} -\usepackage{color} -\usepackage{mfirstuc-english}% also loads mfirstuc.sty -\usepackage[hidelinks]{hyperref} - -\title{Sample Document Illustrating the mfirstuc Package} -\author{Nicola Talbot} - -\begin{document} -\maketitle - -\tableofcontents - -\section{First Letter Upper Case} - -\verb|\makefirstuc{abc}.| -\makefirstuc{abc}. - -\verb|\makefirstuc{{\em abc}}.| -\makefirstuc{{\em abc}}. - -\verb|\makefirstuc{\emph{abc}}.| -\makefirstuc{\emph{abc}}. - -\verb|\makefirstuc{\ae bc}.| -\makefirstuc{\ae bc}. - -\verb|\makefirstuc{{\ae}bc}.| -\makefirstuc{{\ae}bc}. - -\verb|\newcommand{\abc}{abc}\xmakefirstuc{\abc}.| -\newcommand{\abc}{abc}% -\xmakefirstuc{\abc}. - -\newcommand*{\mytext}{\protect\textbf{some text}} -Protected formatting: \xmakefirstuc{\mytext}. - -\renewcommand*{\mytext}{\ae\oe{some text}} -Sequential commands: \xmakefirstuc{\mytext}. - -\verb|\makefirstuc{\MFUskippunc{?`}c\'omo est\'as?}| -\makefirstuc{\MFUskippunc{?`}c\'omo est\'as?} - -\renewcommand{\mytext}{\MFUskippunc{?`}c\'omo est\'as?} -Fully expanded: -\emakefirstuc{\mytext} - -\section{Title Case (No Formatting Commands)} - -\bgroup - -\verb|\capitalisewords{the wind in the willows}| -\capitalisewords{the wind in the willows} - -\verb|\capitalisewords{a small book of rhyme.}| -\capitalisewords{a small book of rhyme.} - -\medskip - -\verb|\space| isn't considered a word boundary for -\verb|\capitalisewords| as shown below: - -\begin{verbatim} -\capitalisewords{a small\space book of rhyme.} -\end{verbatim} -\capitalisewords{a small\space book of rhyme.} - -\medskip -No expansion is performed on the argument of -\verb|\capitalisewords|: - -\verb|\newcommand{\mytitle}{a small book of rhyme.}| -\newcommand{\mytitle}{a small book of rhyme.} - -\verb|\capitalisewords{\mytitle}| -\capitalisewords{\mytitle} - -\verb|\xcapitalisewords{\mytitle}| -\xcapitalisewords{\mytitle} - -\egroup - -Formatting for the entire phrase must go outside -\verb|\capitalisewords| (unlike \verb|\makefirstuc|). Compare: - -\begin{verbatim} -\capitalisewords{\textbf{a small book of rhyme.}} -\end{verbatim} -\capitalisewords{\textbf{a small book of rhyme.}} - -\begin{verbatim} -\textbf{\capitalisewords{a small book of rhyme.}} -\end{verbatim} -\textbf{\capitalisewords{a small book of rhyme.}} - -\medskip - -Use \verb|\capitalisefmtwords| instead. The starred form -is limited to one text-block command at the start of the argument. - -\begin{verbatim} -\capitalisefmtwords*{\emph{a small book of rhyme}} -\end{verbatim} -\capitalisefmtwords*{\emph{a small book of rhyme}} - -Additional text-block commands can cause unexpected results. - -\begin{verbatim} -\capitalisefmtwords*{\emph{a small} book \textbf{of rhyme}} -\end{verbatim} -\capitalisefmtwords*{\emph{a small} book \textbf{of rhyme}} - -\section{Title Case (Contains Text-Block Formatting Commands)} - -The unstarred form of \verb|\capitalisefmtwords| is still a bit -experimental and is only designed -for phrases that contain text-block commands with a single -argument, which should be a word or sub-phrase. - -\verb|\capitalisefmtwords{\textbf{a small book of rhyme}}.| -\capitalisefmtwords{\textbf{a small book of rhyme}}. - -\verb|\capitalisefmtwords{\textbf{a small book} of rhyme}.| -\capitalisefmtwords{\textbf{a small book} of rhyme}. - -\verb|\capitalisefmtwords{a \textbf{small book} of rhyme}.| -\capitalisefmtwords{a \textbf{small book} of rhyme}. - -\verb|\capitalisefmtwords{\textbf{a} small book of rhyme}.| -\capitalisefmtwords{\textbf{a} small book of rhyme}. - -\verb|\capitalisefmtwords{a small book \textbf{of rhyme}}.| -\capitalisefmtwords{a small book \textbf{of rhyme}}. - -\medskip - -Be careful of trailing spaces at the end a group. They can confuse -things. - -\verb|\capitalisefmtwords{\textbf{a small }book of rhyme}.| -\capitalisefmtwords{\textbf{a small }book of rhyme}. - -\verb|\capitalisefmtwords{\textbf{a small book }of rhyme}.| -\capitalisefmtwords{\textbf{a small book }of rhyme}. - -\verb|\capitalisefmtwords{\textbf{a small book of }rhyme}.| -\capitalisefmtwords{\textbf{a small book of }rhyme}. - -\medskip - -Use semantic commands for things like quotations: - -\begin{verbatim} -\newcommand*{\qt}[1]{``#1''} -\capitalisefmtwords{\qt{a small book of rhyme.}} -\end{verbatim} -\newcommand*{\qt}[1]{``#1''} -\capitalisefmtwords{\qt{a small book of rhyme.}} - -\smallskip - -(But make them robust if you intend using commands like -\verb|\ecapitalisefmtwords|.) -Similarly for other types of punctuation: -\begin{verbatim} -\newcommand*{\esq}[1]{'?#1?} -\capitalisefmtwords{\esq{D\'onde est\'a libro}} -\end{verbatim} -\newcommand*{\esq}[1]{?`#1?} -\capitalisefmtwords{\esq{D\'onde est\'a libro}} - -\medskip - -Anything more complicated than a simple one-argument text-block -command requires the starred version. - -\begin{verbatim} -\newcommand*{\swap}[2]{{#2}{#1}} -\capitalisefmtwords*{\textbf{an \swap{un}{usually} small book of} rhyme}. -\end{verbatim} -\newcommand*{\swap}[2]{{#2}{#1}} -\capitalisefmtwords*{\textbf{an \swap{un}{usually} small book of} rhyme}. - -\medskip - -Nested text-block commands: - -\begin{verbatim} -\capitalisefmtwords{\textbf{a \emph{small book} of} rhyme}. -\end{verbatim} -\capitalisefmtwords{\textbf{a \emph{small book} of} rhyme}. - -\begin{verbatim} -\capitalisefmtwords{\textbf{a \emph{small book}} of rhyme}. -\end{verbatim} -\capitalisefmtwords{\textbf{a \emph{small book}} of rhyme}. - -\begin{verbatim} -\capitalisefmtwords{\textbf{\emph{a small} book of} rhyme}. -\end{verbatim} -\capitalisefmtwords{\textbf{\emph{a small} book of} rhyme}. - -\medskip - -An empty brace at the start of a word will suppress the -case-changing. - -\begin{verbatim} -\capitalisefmtwords{\textbf{a small {}book of} rhyme}. -\end{verbatim} -\capitalisefmtwords{\textbf{a small {}book of} rhyme}. - -\medskip - -Suppress case-changing for problematic commands by inserting -an empty group in front: - -\begin{verbatim} -\capitalisefmtwords{{}\textcolor{red}{a} small book of -{}\textcolor{red}{rhyme}}. -\end{verbatim} -\capitalisefmtwords{{}\textcolor{red}{a} small book of -{}\textcolor{red}{rhyme}}. - -\medskip - -If possible provide semantic command instead. - -\begin{verbatim} -\newcommand*{\alert}[1]{\textcolor{red}{#1}} -\capitalisefmtwords{\alert{a} small book of \alert{rhyme}}. -\end{verbatim} -\newcommand*{\alert}[1]{\textcolor{red}{#1}} -\capitalisefmtwords{\alert{a} small book of \alert{rhyme}}. - -\medskip - -No formatting commands in the following example: - -\verb|\capitalisefmtwords{a small book of rhyme}.| -\capitalisefmtwords{a small book of rhyme}. - -\medskip - -Avoid scoped declarations. The next example doesn't work. - -\begin{verbatim} -\capitalisefmtwords{{\bfseries a \emph{small book} of} rhyme.} -\end{verbatim} -\capitalisefmtwords{{\bfseries a \emph{small book} of} rhyme.} - -\medskip - -If a command isn't followed by a grouped argument, the -case-change is applied to the command (on the assumption -that it's a character command, such as \verb|\ae|). This can -have an odd effect if case-changing has no meaning for that command. -As illustrated next: - -\verb|\capitalisefmtwords{\relax a book of rhyme.}| -\capitalisefmtwords{\relax a book of rhyme.} - -\section{Compound Words} - -Use \verb|\MFUhyphentrue| to title case each part of -a compound word. - -Default: -\begin{verbatim} -\capitalisewords{a fast-paced book of rhyme}. -\capitalisefmtwords{a \textbf{fast-paced} book of rhyme}. -\end{verbatim} -\capitalisewords{a fast-paced book of rhyme}. -\capitalisefmtwords{a \textbf{fast-paced} book of rhyme}. - -Compare with -\begin{verbatim} -\MFUhyphentrue -\capitalisewords{a fast-paced book of rhyme}. -\capitalisefmtwords{a \textbf{fast-paced} book of rhyme}. -\end{verbatim} -\MFUhyphentrue -\capitalisewords{a fast-paced book of rhyme}. -\capitalisefmtwords{a \textbf{fast-paced} book of rhyme}. - -\end{document} -- cgit v1.2.3