From 9456871cc89612c1f974af157f0ed08b9630c4c6 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sun, 24 Jan 2021 03:03:37 +0000 Subject: CTAN sync 202101240303 --- macros/latex/contrib/eqexam/README.md | 5 +- macros/latex/contrib/eqexam/aebrandom.def | 201 ++- macros/latex/contrib/eqexam/doc/eqexam.pdf | Bin 806244 -> 745675 bytes macros/latex/contrib/eqexam/doc/eqexamman.pdf | Bin 624926 -> 671573 bytes macros/latex/contrib/eqexam/doc/eqexamman.tex | 46 +- macros/latex/contrib/eqexam/eqexam.def | 428 ++--- macros/latex/contrib/eqexam/eqexam.dtx | 65 +- macros/latex/contrib/eqexam/examples/fig1.pdf | Bin 12673 -> 11038 bytes macros/latex/contrib/eqexam/examples/hw.cfg.txt | 12 - macros/latex/contrib/eqexam/examples/quiz.cfg.txt | 7 - macros/latex/contrib/eqexam/examples/test01.pdf | Bin 0 -> 116251 bytes macros/latex/contrib/eqexam/examples/test01.tex | 4 +- macros/latex/contrib/eqexam/examples/test02.pdf | Bin 0 -> 216104 bytes macros/latex/contrib/eqexam/examples/test03.pdf | Bin 0 -> 161999 bytes .../contrib/eqexam/examples/test_matching.pdf | Bin 18253 -> 0 bytes macros/latex/contrib/fnpct/README | 13 +- macros/latex/contrib/fnpct/fnpct-manual.cls | 331 ++++ macros/latex/contrib/fnpct/fnpct-manual.pdf | Bin 0 -> 472808 bytes macros/latex/contrib/fnpct/fnpct-manual.tex | 615 +++++++ macros/latex/contrib/fnpct/fnpct.sty | 1883 +++++++++++--------- macros/latex/contrib/fnpct/fnpct_en.pdf | Bin 573765 -> 0 bytes macros/latex/contrib/fnpct/fnpct_en.tex | 1044 ----------- 22 files changed, 2400 insertions(+), 2254 deletions(-) delete mode 100644 macros/latex/contrib/eqexam/examples/hw.cfg.txt delete mode 100644 macros/latex/contrib/eqexam/examples/quiz.cfg.txt create mode 100644 macros/latex/contrib/eqexam/examples/test01.pdf create mode 100644 macros/latex/contrib/eqexam/examples/test02.pdf create mode 100644 macros/latex/contrib/eqexam/examples/test03.pdf delete mode 100644 macros/latex/contrib/eqexam/examples/test_matching.pdf create mode 100644 macros/latex/contrib/fnpct/fnpct-manual.cls create mode 100644 macros/latex/contrib/fnpct/fnpct-manual.pdf create mode 100644 macros/latex/contrib/fnpct/fnpct-manual.tex delete mode 100644 macros/latex/contrib/fnpct/fnpct_en.pdf delete mode 100644 macros/latex/contrib/fnpct/fnpct_en.tex (limited to 'macros') diff --git a/macros/latex/contrib/eqexam/README.md b/macros/latex/contrib/eqexam/README.md index ab464cabca..5e0bc68ab3 100644 --- a/macros/latex/contrib/eqexam/README.md +++ b/macros/latex/contrib/eqexam/README.md @@ -1,5 +1,5 @@ The eqexam Package -Dated: 2020-03-14 +Dated: 2021-01-20 Author: D. P. Story eqExam is a LaTeX package for writing exams, tests, quizzes, @@ -40,6 +40,9 @@ this package are as follows: folder. See also the series of blogs at http://www.acrotex.net/blog/?tag=fortextbook +What's New (2021-01-20) Defined \trackProblemsOn and \numPtsOfProblem; +added \doNoRandomizeChoices and \allowRandomizedChoices. See documentation. + What's New (2020-03-14) Defined several commands and one environment to support the insertion of a figure into a problem. Demo file that illustrates these new commands and environment is found at diff --git a/macros/latex/contrib/eqexam/aebrandom.def b/macros/latex/contrib/eqexam/aebrandom.def index f2952e463e..defbed5737 100644 --- a/macros/latex/contrib/eqexam/aebrandom.def +++ b/macros/latex/contrib/eqexam/aebrandom.def @@ -18,11 +18,11 @@ %% License, or (at your option) any later version. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ProvidesFile{aebrandom.def} - [2020/03/14 v8.5.10 % + [2021/01/20 v8.6.2 % Exerquiz support for randomization (dps)] \@ifundefined{nextrandom}{\input{random.tex}}{} \def\nextrandom{\begingroup - \ifnum\randomi<\@ne % then initialize with time + \ifnum\randomi<\@ne % then initialize with time \global\randomi\time \global\multiply\randomi388 \global\advance\randomi\year \global\multiply\randomi31 \global\advance\randomi\day @@ -30,139 +30,138 @@ \message{Randomizer initialized to \the\randomi.}% \nextrandom \nextrandom \nextrandom \xdef\InitSeedValue{\the\randomi}% - \fi - \count@ii\randomi - \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836 - \count@\count@ii - \multiply\count@ii 127773 - \global\advance\randomi-\count@ii % random mod 127773 - \global\multiply\randomi 16807 - \multiply\count@ 2836 - \global\advance\randomi-\count@ - \ifnum\randomi<\z@ \global\advance\randomi 2147483647\relax\fi + \fi + \count@ii\randomi + \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836 + \count@\count@ii + \multiply\count@ii 127773 + \global\advance\randomi-\count@ii % random mod 127773 + \global\multiply\randomi 16807 + \multiply\count@ 2836 + \global\advance\randomi-\count@ + \ifnum\randomi<\z@\global\advance\randomi 2147483647\relax\fi \endgroup } \def\writeSeedToSolnFile{\writeT@ExSolns{\string\randomi=\the\randomi}} -\def\@ansChoices[#1]% -{% - \global\let\@tempholdSaveAns\@empty % 5/24 - \global\let\@tempholdSaveChoice\@empty % 5/24 - \global\let\bChoiceLabel\@empty % 5/24 - \ifeq@randomizeallChoices - \setkeys{bchoice}{#1,random=true}\else - \setkeys{bchoice}{#1}\fi - \global\eq@tabColCnt=0 - \ifeq@randomizeChoices\expandafter\@@bChoices - \else\expandafter\@@ansChoices\fi +\def\@ansChoices[#1]{% + \global\let\@tempholdSaveAns\@empty + \global\let\@tempholdSaveChoice\@empty + \global\let\bChoiceLabel\@empty + \ifeq@randomizeallChoices + \setkeys{bchoice}{#1,random=true}\else + \setkeys{bchoice}{#1}\fi + \global\eq@tabColCnt=\z@ + \if@DoNotRandomize\eq@randomizeChoicesfalse\fi + \ifeq@randomizeChoices\expandafter\@@bChoices + \else\expandafter\@@ansChoices\fi } \def\@@ansChoices{% - \ifnum\aeb@numCols=1 % list mode - \def\eq@next{\@layoutListAns}% - \else % tabular mode - \edef\eq@next{\noexpand\@layoutTabularAns{\bChoiceNumCols}}% - \fi - \eq@next + \ifnum\aeb@numCols=\@ne % list mode + \def\eq@next{\@layoutListAns}% + \else % tabular mode + \edef\eq@next{\noexpand\@layoutTabularAns{\bChoiceNumCols}}% + \fi + \eq@next } \newcount\aeb@numChoices \newcount\aeb@ranChoice \newtoks\aeb@hold\aeb@hold={} \def\@@bChoices{\gdef\@temphold{}\gdef\@tempholdrandom{}% - \gdef\@tempholdfreeze{}\aeb@searchfortoken{\@getAns}% + \gdef\@tempholdfreeze{}\aeb@searchfortoken{\@getAns}% } \def\aeb@searchfortoken#1{% - \@ifnextchar\Ans{\advance\aeb@numChoices1\relax#1} - {\@ifnextchar\eFreeze{\expandafter\@getFreezeAns\@gobble} - {\@ifnextchar\par{\def\@@temp{\aeb@searchfortoken{#1}}% - \expandafter\@@temp\@gobble}{\@eChoices}}}% + \@ifnextchar\Ans{\advance\aeb@numChoices1\relax#1} + {\@ifnextchar\eFreeze{\expandafter\@getFreezeAns\@gobble} + {\@ifnextchar\par{\def\@@temp{\aeb@searchfortoken{#1}}% + \expandafter\@@temp\@gobble}{\@eChoices}}}% } \long\def\@getAns\Ans#1\eAns{% - \g@addto@macro\@temphold{{\Ans#1\eAns}}% - \aeb@searchfortoken{\@getAns}% + \g@addto@macro\@temphold{{\Ans#1\eAns}}% + \aeb@searchfortoken{\@getAns}% } \def\@getFreezeAns{\aeb@searchfortoken{\@@getFreezeAns}} \long\def\@@getFreezeAns\Ans#1\eAns{% - \g@addto@macro\@tempholdfreeze{\Ans#1\eAns}% - \aeb@searchfortoken{\@@getFreezeAns}% + \g@addto@macro\@tempholdfreeze{\Ans#1\eAns}% + \aeb@searchfortoken{\@@getFreezeAns}% } \long\def\@eChoices#1\eChoices{% - \aeb@randomizeChoices{\the\aeb@numChoices}% + \aeb@randomizeChoices{\the\aeb@numChoices}% } \def\aeb@randomizeChoices#1{% - \setrannum{\aeb@ranChoice}{1}{#1} - \eqtmpcnta\z@\aeb@hold=\expandafter{\@temphold}\def\@temphold{}% - \expandafter\@tfor\expandafter - \@temp\expandafter:\expandafter=\the\aeb@hold \do {% - \advance\eqtmpcnta\@ne - \ifnum\eqtmpcnta=\aeb@ranChoice\relax - \aeb@hold=\expandafter\expandafter\expandafter - {\expandafter\@tempholdrandom\@temp}% - \edef\@tempholdrandom{\the\aeb@hold}% - \else - \aeb@hold=\expandafter\expandafter\expandafter - {\expandafter\@temphold\expandafter{\@temp}}% - \edef\@temphold{\the\aeb@hold}% - \fi - }% - \aeb@numChoices=#1 - \advance\aeb@numChoices-1 - \ifnum\aeb@numChoices=0\relax - \def\aeb@next{\aeb@finishedRandomizing}\else - \def\aeb@next{\aeb@randomizeChoices{\the\aeb@numChoices}}\fi - \aeb@next + \setrannum{\aeb@ranChoice}{1}{#1} + \eqtmpcnta\z@\aeb@hold=\expandafter{\@temphold}\def\@temphold{}% + \expandafter\@tfor\expandafter + \@temp\expandafter:\expandafter=\the\aeb@hold \do {% + \advance\eqtmpcnta\@ne + \ifnum\eqtmpcnta=\aeb@ranChoice\relax + \aeb@hold=\expandafter\expandafter\expandafter + {\expandafter\@tempholdrandom\@temp}% + \edef\@tempholdrandom{\the\aeb@hold}% + \else + \aeb@hold=\expandafter\expandafter\expandafter + {\expandafter\@temphold\expandafter{\@temp}}% + \edef\@temphold{\the\aeb@hold}% + \fi + }% + \aeb@numChoices=#1 + \advance\aeb@numChoices\m@ne + \ifnum\aeb@numChoices=\z@ + \def\aeb@next{\aeb@finishedRandomizing}\else + \def\aeb@next{\aeb@randomizeChoices{\the\aeb@numChoices}}\fi + \aeb@next } \def\aeb@finishedRandomizing{% - \aeb@hold=\expandafter\expandafter\expandafter - {\expandafter\@tempholdrandom\@tempholdfreeze}% - \gdef\@temphold{}\gdef\@tempholdrandom{}\gdef\@tempholdfreeze{}% - \edef\finished@Randomizing{% - \noexpand\@@ansChoices - \the\aeb@hold - \noexpand\eChoices}% - \finished@Randomizing + \aeb@hold=\expandafter\expandafter\expandafter + {\expandafter\@tempholdrandom\@tempholdfreeze}% + \gdef\@temphold{}\gdef\@tempholdrandom{}\gdef\@tempholdfreeze{}% + \edef\finished@Randomizing{% + \noexpand\@@ansChoices + \the\aeb@hold + \noexpand\eChoices}% + \finished@Randomizing } \def\saveRandomSeed{\PackageInfo{exerquiz} - {The command \string\saveRandomSeed\space - is deprecated.\MessageBreak Seed automatically saved}} + {The command \string\saveRandomSeed\space + is deprecated.\MessageBreak Seed automatically saved}} \@ifpackageloaded{ran_toks}{% - \let\inputRandomSeed\useLastAsSeed - \let\useRandomSeed\useThisSeed + \let\inputRandomSeed\useLastAsSeed + \let\useRandomSeed\useThisSeed }{% - \def\inputRandomSeed{\eq@readRandomData}% - \def\useRandomSeed#1{\saveseedfalse\randomi=#1}% + \def\inputRandomSeed{\eq@readRandomData}% + \def\useRandomSeed#1{\saveseedfalse\randomi=#1}% } \def\InitSeedValue{\the\randomi} % dps \@ifundefined{ifsaveseed}{\newif\ifsaveseed\saveseedtrue}{} % dps -\def\eq@writeRandomData -{% - \ifsaveseed - \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{} - \immediate\openout \saveseedinfo \jobname_rt.sav - \let\verbatim@out\saveseedinfo - \def\eqrt@msgi{initializing seed value}% - \def\eqrt@msgii{last random number used}% - \uccode`c=`\%\uppercase{% - \immediate\write\verbatim@out - {\InitSeedValue\space c \eqrt@msgi}% - \immediate\write\verbatim@out - {\the\randomi\space c \eqrt@msgii}% - }\immediate\closeout\saveseedinfo - \fi +\def\eq@writeRandomData{% + \ifsaveseed + \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{} + \immediate\openout \saveseedinfo \jobname_rt.sav + \let\verbatim@out\saveseedinfo + \def\eqrt@msgi{initializing seed value}% + \def\eqrt@msgii{last random number used}% + \uccode`c=`\%\uppercase{% + \immediate\write\verbatim@out + {\InitSeedValue\space c \eqrt@msgi}% + \immediate\write\verbatim@out + {\the\randomi\space c \eqrt@msgii}% + }\immediate\closeout\saveseedinfo + \fi } \AtEndDocument{\eq@writeRandomData} \def\eq@readRandomData{\IfFileExists{\jobname_rt.sav}{% - \PackageInfo{exerquiz}{Inputting \jobname_rt.sav}% - \@ifundefined{readsavfile}{\newread\readsavfile}{}% - \openin\readsavfile=\jobname_rt.sav - \read\readsavfile to \InitSeedValue - \read\readsavfile to \eqlastRandomNum - \closein\readsavfile - \randomi=\eqlastRandomNum - \xdef\InitSeedValue{\the\randomi}% - \immediate\closeout\readsavfile + \PackageInfo{exerquiz}{Inputting \jobname_rt.sav}% + \@ifundefined{readsavfile}{\newread\readsavfile}{}% + \openin\readsavfile=\jobname_rt.sav + \read\readsavfile to \InitSeedValue + \read\readsavfile to \eqlastRandomNum + \closein\readsavfile + \randomi=\eqlastRandomNum + \xdef\InitSeedValue{\the\randomi}% + \immediate\closeout\readsavfile }{% - \PackageInfo{exerquiz}{\jobname_rt.sav cannot - be found, \MessageBreak - using the random initializer}% + \PackageInfo{exerquiz}{\jobname_rt.sav cannot + be found, \MessageBreak + using the random initializer}% }} \endinput %% diff --git a/macros/latex/contrib/eqexam/doc/eqexam.pdf b/macros/latex/contrib/eqexam/doc/eqexam.pdf index ea03c1f8fb..59d7861b27 100644 Binary files a/macros/latex/contrib/eqexam/doc/eqexam.pdf and b/macros/latex/contrib/eqexam/doc/eqexam.pdf differ diff --git a/macros/latex/contrib/eqexam/doc/eqexamman.pdf b/macros/latex/contrib/eqexam/doc/eqexamman.pdf index 9684fd4f9b..1fe69fa3bf 100644 Binary files a/macros/latex/contrib/eqexam/doc/eqexamman.pdf and b/macros/latex/contrib/eqexam/doc/eqexamman.pdf differ diff --git a/macros/latex/contrib/eqexam/doc/eqexamman.tex b/macros/latex/contrib/eqexam/doc/eqexamman.tex index 258bf56245..d580d1a4db 100644 --- a/macros/latex/contrib/eqexam/doc/eqexamman.tex +++ b/macros/latex/contrib/eqexam/doc/eqexamman.tex @@ -11,6 +11,8 @@ \usepackage[bypasspkgpagestyle,nomarginwrite,usecustomdesign, useclassmaketitle,flextended ]{eqexam} + + %\usepackage[designv, % latextoc,forcolorpaper, % centertitlepage]{web} @@ -150,7 +152,7 @@ part of the\texorpdfstring{\\}{ }\texorpdfstring{\AcroTeX}{AcroTeX} eDucation Bu \keywords{LaTeX, hyperref, PDF, exercises, quizzes} \university{{\AcroT} Software Development Team} \email{dpstory@acrotex.net} -\version{5.1.10, 2020/03/14} +\version{5.1.13, 2021/01/20} \copyrightyears{2005-\the\year} \renewcommand{\exsectitletext}{Solutions to exams in this manual} @@ -1603,7 +1605,7 @@ necessary in two situations: removing questions that have randomization). \end{enumerate} -\newtopic\textbf{Things to look for:} If \textsf{eqexam} is not rearranging the order +\newtopic\textbf{Things to look for: } If \textsf{eqexam} is not rearranging the order of the choices as you expect it to, it could be that \textsf{eqexam} is reading an old \texttt{.sav} file. Either delete that file in your source folder, or comment out \cs{inputRandomSeed} in your document. @@ -1624,10 +1626,19 @@ use that seed value for that class, for example \end{Verbatim} Of course comment out \cs{inputRandomSeed}. -\begin{Verbatim}[xleftmargin=\amtIndent] +\newtopic\textbf{Controlling randomization.} There are several commands that control whether +randomization occurs. +\settowidth{\aebdimen}{\cs{allowRandomizedChoices}}% +\begin{dCmd}[commandchars=!()]{\aebdimen+2\fboxsep+2\fboxrule} \turnOnRandomize \obeyLocalRandomize -\end{Verbatim} +\doNotRandomizeChoices +\allowRandomizedChoices +\end{dCmd} +%\begin{Verbatim}[xleftmargin=\amtIndent] +%\turnOnRandomize +%\obeyLocalRandomize +%\end{Verbatim} The command \cs{turnOnRandomize} overrides all local settings of \cs{bChoices} and causes all choice lists to be randomized. While \cs{obeyLocalRandomize} @@ -1658,13 +1669,19 @@ the choices will not be randomized, because the \texttt{random} option was not specified; or they will be randomized if the \texttt{random} option is used. +\newtopic\indent The command \cs{doNotRandomizeChoices} overrides the +\opt{allowrandomize} option; when in effect, randomization of the choices +does not occur. The companion command \cs{allowRandomizedChoices} restores the +authority of the \opt{allowrandomize} option. + \newtopic\textcolor{red}{Limitations:} There are natural limitations on the use of \cs{bChoices} and \cs{eChoices} and consequently, there are limitations on the randomization. The content between \cs{Ans} and \cs{eAns} cannot have any verbatim text. This is usually not a problem for mathematical content, but could be a limitation for -computer science where questions about syntax may be posed. I have -in mind a work-around, but haven't pursued the problem as of yet. +computer science where questions about syntax may be posed. + +%I have in mind a work-around, but haven't pursued the problem as of yet. \subsection{Labeling Choices} @@ -5186,6 +5203,23 @@ the figure around the text of the question. environment, named \texttt{\href{\urlAcroTeXBlog/?p=1419}{ins-fig.pdf}}, is found on the {\AcroBlog}. +\subsection{Tracking problem values} + +As an application to the \pkg{skills} package, three new commands are introduced +into the \pkg{eqexam} core. + +\settowidth{\aebdimen}{\ttfamily\string\numPtsOfProblem[\meta{exam-label}]\darg{\meta{prob-num}}}% +\def\1{\rlap{\hskip\linewidth\texttt{ \%}\textsf{ turn on problem tracking}}}% +\def\2{\rlap{\hskip\linewidth\texttt{ \%}\textsf{ turn off problem tracking}}}% +\def\3{\rlap{\hskip\linewidth\texttt{ \%}\textsf{ typeset points for problem}}}% +\begin{dCmd}[commandchars=!()]{\aebdimen+2\fboxsep+2\fboxrule} +!1\trackProblemsOn +!2\trackProblemsOff +!3\numPtsOfProblem[!meta(exam-label)]{!meta(prob-num)} +\end{dCmd} +When tracking is on (\cs{trackProblemsOn}), the number of points for each problem +is written to the AUX file. Use \cs{numPtsOfProblem} to typeset the amount of points for \ameta{prob-num} +of exam part \ameta{exam-label}. Turn off tracking with \cs{trackProblemsOff}. \newpage \markright{References} diff --git a/macros/latex/contrib/eqexam/eqexam.def b/macros/latex/contrib/eqexam/eqexam.def index 0d865559a7..55f3a9bcab 100644 --- a/macros/latex/contrib/eqexam/eqexam.def +++ b/macros/latex/contrib/eqexam/eqexam.def @@ -7,7 +7,7 @@ %% exerquiz.dtx (with options: `eqexam') %% \ProvidesFile{eqexam.def} - [2020/03/14 v8.5.10 % + [2021/01/20 v8.6.2 % Exerquiz support file for eqexam (dps)] \let\eq@YES=y \let\eq@NO=n \let\eq@One=1 \let\eq@Zero=0 @@ -41,8 +41,11 @@ \expandafter#2\fi} \newif\ifeq@randomizeChoices \eq@randomizeChoicesfalse \newif\ifeq@randomizeallChoices \eq@randomizeallChoicesfalse +\newif\if@DoNotRandomize \@DoNotRandomizefalse \def\turnOnRandomize{\eq@randomizeallChoicestrue} \def\obeyLocalRandomize{\eq@randomizeallChoicesfalse} +\def\doNotRandomizeChoices{\@DoNotRandomizetrue} +\def\allowRandomizedChoices{\@DoNotRandomizefalse} \let\saveRandomSeed\relax \let\inputRandomSeed\relax \newcommand{\exsolafter}{\eq@exsolafterDefault} @@ -1115,45 +1118,44 @@ \let\propQ@labelwidth\@empty \define@key{props@ques}{topsep}[\the\topsep]{\edef\propQ@topsep{#1}} \define@key{props@ques}{partopsep}[\the\partopsep]% - {\edef\propQ@partopsep{#1}} + {\edef\propQ@partopsep{#1}} \define@key{props@ques}{parsep}[\the\parsep]{\edef\propQ@parsep{#1}} \define@key{props@ques}{itemsep}[\the\itemsep]{\edef\propQ@itemsep{#1}} \define@key{props@ques}{labelsepTo}[\normalsize\normalfont\ ]% - {\def\propQ@labelsepTo{#1}} + {\def\propQ@labelsepTo{#1}} \define@key{props@ques}{labelsep}[\@empty]{\def\propQ@labelsep{#1}} \let\propQ@labelsep\@empty \define@key{props@ques}{color}[blue]{\quesNumColor{#1}} \setkeys{props@ques}{labelwidthTo,topsep,partopsep,parsep,% itemsep,labelsepTo,color}% -\newenvironment{questions}[1][] -{% - \ifnum\@eqquestiondepth>\tw@\@toodeep\else - \advance\@eqquestiondepth\@ne\fi - \def\@quesctr{eqquestionno\romannumeral\the\@eqquestiondepth}% - \toks@=\expandafter\expandafter\expandafter{#1}\expandafter - \xdef\csname quesOpts\@quesctr\endcsname{\the\toks@}% - \edef\tempexp{\noexpand\setkeys{props@ques}{\the\toks@}}\tempexp - \list{\qMark@Hook\prior@questionsHook - \insE@rlyAtQues\gdef\eqPTs{1}% - \global\let\eqQT\eq@na% - {\@tempcnta=0 \let\@thispr@b\@empty - \@whilenum\@tempcnta<\@eqquestiondepth\do{\advance\@tempcnta\@ne - \ifx\@thispr@b\@empty\edef\@thispr@b{% - \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\else - \edef\@thispr@b{\@thispr@b% - \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\fi - }\xdef\@currentQues{\@thispr@b}}% - \makebox[\labelwidth][r]{\normalfont\@nameuse{label\@quesctr}}% - \xdef\eq@pageThisQ{\the\c@page}% - \post@questionsHook}{\usecounter{\@quesctr}% +\newenvironment{questions}[1][]{% + \ifnum\@eqquestiondepth>\tw@\@toodeep\else + \advance\@eqquestiondepth\@ne\fi + \def\@quesctr{eqquestionno\romannumeral\the\@eqquestiondepth}% + \toks@=\expandafter\expandafter\expandafter{#1}\expandafter + \xdef\csname quesOpts\@quesctr\endcsname{\the\toks@}% + \edef\tempexp{\noexpand\setkeys{props@ques}{\the\toks@}}\tempexp + \list{\qMark@Hook\prior@questionsHook + \insE@rlyAtQues\gdef\eqPTs{1}% + \global\let\eqQT\eq@na% + {\@tempcnta=0 \let\@thispr@b\@empty + \@whilenum\@tempcnta<\@eqquestiondepth\do{\advance\@tempcnta\@ne + \ifx\@thispr@b\@empty\edef\@thispr@b{% + \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\else + \edef\@thispr@b{\@thispr@b% + \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\fi + }\xdef\@currentQues{\@thispr@b}}% + \makebox[\labelwidth][r]{\normalfont\@nameuse{label\@quesctr}}% + \xdef\eq@pageThisQ{\the\c@page}% + \post@questionsHook}{\usecounter{\@quesctr}% \ifx\propQ@labelsep\@empty - \settowidth{\labelsep}{\propQ@labelsepTo}\else - \setlength{\labelsep}{\propQ@labelsep}\fi + \settowidth{\labelsep}{\propQ@labelsepTo}\else + \setlength{\labelsep}{\propQ@labelsep}\fi \ifx\propQ@labelwidth\@empty - \settowidth{\labelwidth}% - {\propQ@labelwidthTo\hspace{\labelsep}}\else - \settowidth{\labelwidth}{\hspace{\propQ@labelwidth}% - \hspace{\labelsep}}\fi + \settowidth{\labelwidth}% + {\propQ@labelwidthTo\hspace{\labelsep}}\else + \settowidth{\labelwidth}{\hspace{\propQ@labelwidth}% + \hspace{\labelsep}}\fi \setlength{\topsep}{\propQ@topsep}% \setlength{\partopsep}{\propQ@partopsep}% \ifdim\parskip>\z@\addtolength{\topsep}{-\parskip}\fi @@ -1191,16 +1193,16 @@ }{\aeb@endshortquiz} \newenvironment{shortquiz*} {% - \xdef\eq@pageThisQ{\the\c@page}% - {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne - \xdef\@shortquizCnt{\the\eqtmpcnta}}% - \sqForms\@shortquiz + \xdef\eq@pageThisQ{\the\c@page}% + {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne + \xdef\@shortquizCnt{\the\eqtmpcnta}}% + \sqForms\@shortquiz }{\aeb@endshortquiz} \def\@shortquiz{\@ifnextchar[% - {\@@shortquiz}{\@@shortquiz[\@sqGenBaseName]}} + {\@@shortquiz}{\@@shortquiz[\@sqGenBaseName]}} \def\sq@setCLN#1{\ifx\aebTitleQuiz\@empty - \protected@edef\@currentlabelname{#1}\else - \protected@edef\@currentlabelname{\@currentlabelname}\fi + \protected@edef\@currentlabelname{#1}\else + \protected@edef\@currentlabelname{\@currentlabelname}\fi } \let\isQZ=q \let\isSQZ=s \let\eqQuizType\relax @@ -1217,7 +1219,7 @@ \let\@Ans\Ans@sq@f \ifx\oField\@empty \typeout{^^JExerquiz: Base field name required when using - shortquiz with '*' option}% + shortquiz with '*' option}% \PackageInfo{exerquiz}{Assuming link style^^J}% \let\@Ans\Ans@sq@l \fi @@ -1329,22 +1331,22 @@ \let\endeqQt\relax \let\prior@quizSolnHeaderHook\@empty \newcommand\quizSolnHeader[3][]{% - \prior@quizSolnHeaderHook - \ifeqforpaper\else\webnewpage\fi\noindent - #2% - \solnspace + \prior@quizSolnHeaderHook + \ifeqforpaper\else\webnewpage\fi\noindent + #2% + \solnspace } \newif\iftherearequizsolutions \therearequizsolutionsfalse \let\aeb@FLOverride\relax \def\includequizsolutions{\@ifstar - {\let\resetQZtsolns\relax\includequizsolutionsi} - {\def\resetQZtsolns{\global\let\include@quizsolutions\relax}% - \includequizsolutionsi}} + {\let\resetQZtsolns\relax\includequizsolutionsi} + {\def\resetQZtsolns{\global\let\include@quizsolutions\relax}% + \includequizsolutionsi}} \newcommand{\includequizsolutionsi}[1][]{% - \filterFor{#1}\includequizsolutionsii} + \filterFor{#1}\includequizsolutionsii} \def\includequizsolutionsii{\include@quizsolutions - \resetQZtsolns - \let\eqFilterArg\@empty} + \resetQZtsolns + \let\eqFilterArg\@empty} \newcommand\useForms{\def\aeb@FLOverride{f}} \newcommand\useLinks{\def\aeb@FLOverride{l}} \newcommand\restoreFLTypeDefault{\global\let\aeb@FLOverride\relax} @@ -1517,243 +1519,245 @@ \eq@hspanner\ignorespaces} \let\Ans@ck@sq@l\Ans@sq@l \let\rbf@Opts\@empty -\def\Ans@sq@f{% - \if\eq@listType\eq@One\stepcounter{quizno}\else - \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}} - {\ifwithinsoldoc\stepcounter{quizno}\else - \refstepcounter{quizno}\fi}\fi\PBS\raggedright - \settowidth{\eq@tmplength}{\eq@lw@f}% - \eq@tmpdima=\wd\eq@tmpbox% - \hangindent=\eq@tmplength\hangafter=1\relax - \insertGrayLetters % 6.3d - \Ans@sq@f@driver -\eq@hspanner\ignorespaces} +\def\Ans@sq@f{\if\eq@listType\eq@One + \stepcounter{quizno}\else + \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}} + {\ifwithinsoldoc\stepcounter{quizno}\else + \refstepcounter{quizno}\fi}\fi + \PBS\raggedright + \settowidth{\eq@tmplength}{\eq@lw@f}% + \eq@tmpdima=\wd\eq@tmpbox% + \hangindent=\eq@tmplength\hangafter=1\relax + \insertGrayLetters + \Ans@sq@f@driver + \eq@hspanner\ignorespaces} \let\Ans@ck@sq@f\Ans@sq@f \newskip\aboveanswersSkip \setlength\aboveanswersSkip{3pt} \providecommand\graylettersColor{gray} \def\insertGrayLetters{\ifaebshowgrayletters - \rlap{\makebox[\RadioFieldSize]% - {\textcolor{\graylettersColor}{\Alph{quizno}}}}\else\relax\fi} + \rlap{\makebox[\RadioFieldSize]% + {\textcolor{\graylettersColor}{\Alph{quizno}}}}\else\relax\fi} \newcount\eq@tabColCnt \define@key{bchoice}{nCols}{\def\bChoiceNumCols{#1}} \@for\eqi:=1,2,3,4,5,6,7,8,9,10 \do{\edef\temp@expand@def{% - \noexpand\define@key{bchoice}{\eqi}[\eqi]{% - \noexpand\def\noexpand\bChoiceNumCols{\eqi}}% - }\temp@expand@def + \noexpand\define@key{bchoice}{\eqi}[\eqi]{% + \noexpand\def\noexpand\bChoiceNumCols{\eqi}}% + }\temp@expand@def } \def\bChoiceNumCols{\aeb@numCols} \define@key{bchoice}{random}[true]{% - \csname if#1\endcsname\eq@randomizeChoicestrue - \else\eq@randomizeChoicesfalse\fi + \csname if#1\endcsname\eq@randomizeChoicestrue + \else\eq@randomizeChoicesfalse\fi } \define@key{bchoice}{label}[]{\xdef\bChoiceLabel{#1}} \def\bChoices{\@ifnextchar[{\@ansChoices}{\@ansChoices[\aeb@numCols]}} -\def\@ansChoices[#1]% -{% - \global\let\@tempholdSaveAns\@empty %4/5 - \global\let\@tempholdSaveChoice\@empty %4/5 - \global\let\bChoiceLabel\@empty %4/5 - \setkeys{bchoice}{#1}% - \global\eq@tabColCnt=0 - \ifnum\aeb@numCols=1 % list mode - \def\eq@next{\@layoutListAns}\else % tabular mode - \def\eq@next{\@layoutTabularAns{\bChoiceNumCols}}\fi - \eq@next +\def\@ansChoices[#1]{% + \global\let\@tempholdSaveAns\@empty %4/5 + \global\let\@tempholdSaveChoice\@empty %4/5 + \global\let\bChoiceLabel\@empty %4/5 + \setkeys{bchoice}{#1}% + \global\eq@tabColCnt=\z@ + \ifnum\aeb@numCols=\@ne % list mode + \def\eq@next{\@layoutListAns}\else % tabular mode + \def\eq@next{\@layoutTabularAns{\bChoiceNumCols}}\fi + \eq@next } \let\eChoices\relax \def\@layoutListAns{\@ifnextchar\Ans{\@getListAns}% - {\@lookforendansChoices{\@layoutListAns}}% + {\@lookforendansChoices{\@layoutListAns}}% } \newcommand{\eq@saveAns}[2][]{% - \let\eq@next\@@@SaveAnsGobbleAns - \ifx\bChoiceLabel\@empty\else - \def\eq@savedAnsOpt{#1}\def\eq@savedAnsZO{#2}% - \if\eq@savedAnsZO1 \let\eq@next\@@@SaveAns\fi - \fi\eq@next + \let\eq@next\@@@SaveAnsGobbleAns + \ifx\bChoiceLabel\@empty\else + \def\eq@savedAnsOpt{#1}\def\eq@savedAnsZO{#2}% + \if\eq@savedAnsZO1\let\eq@next\@@@SaveAns\fi + \fi\eq@next } \long\def\@@@SaveAns#1\eAns{% 4/5 - \g@addto@macro\@tempholdSaveAns{\\{\ignorespaces#1}}% - \addtocounter{quizno}{1}% - \edef\temp@expand{\noexpand\g@addto@macro\noexpand + \g@addto@macro\@tempholdSaveAns{\\{\ignorespaces#1}}% + \addtocounter{quizno}{1}% + \edef\temp@expand{\noexpand\g@addto@macro\noexpand \@tempholdSaveChoice{% - \noexpand\\{\ifx\sqstar\@empty\aebChoiceAltFmt\else - \ifaebshowgrayletters\Alph{quizno}\else - \linkContentFormat\fi\fi}}}\temp@expand - \addtocounter{quizno}{-1}% + \noexpand\\{\ifx\sqstar\@empty\aebChoiceAltFmt\else + \ifaebshowgrayletters\Alph{quizno}\else + \linkContentFormat\fi\fi}}}\temp@expand + \addtocounter{quizno}{-1}% } \newif\ifoxfordcomma \oxfordcommatrue \def\oxfordCommaOn{\oxfordcommatrue} \def\oxfordCommaOff{\oxfordcommafalse} \def\eq@insertComma{% - \ifx\eq@comma\@empty - \ifnum\@nameuse{NumAns\eq@namearg}>2\relax - \def\eq@comma{,}\fi - \else\ifx\eq@insertAnd\@empty\eq@comma\space - \else\ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}% - \ifoxfordcomma\eq@comma\fi\else\eq@comma\fi\space - \fi + \ifx\eq@comma\@empty + \ifnum\@nameuse{NumAns\eq@namearg}>\tw@ + \def\eq@comma{,}\fi + \else\ifx\eq@insertAnd\@empty\eq@comma\space + \else\ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}% + \ifoxfordcomma\eq@comma\fi\else\eq@comma\fi\space \fi + \fi } \newcommand\eqAnd{and}\def\eq@insertAnd{% - \ifnum\@nameuse{NumAns\eq@namearg}<2\relax\else - \ifnum\@nameuse{NumAns\eq@namearg}>2\relax - \else\leavevmode\space\fi\eqAnd\space\fi} -\long\def\eq@displayAns#1{\advance\@tempcnta1\relax - \eq@insertComma - \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1} + \ifnum\@nameuse{NumAns\eq@namearg}<\tw@\else + \ifnum\@nameuse{NumAns\eq@namearg}>\tw@\relax + \else\leavevmode\space\fi\eqAnd\space\fi +} +\long\def\eq@displayAns#1{\advance\@tempcnta\@ne + \eq@insertComma + \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1} \def\eq@displayAlts#1{\advance\@tempcnta1 - \eq@insertComma - \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi - \savedAltFmt{#1}} + \eq@insertComma + \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi + \savedAltFmt{#1}} \def\eq@displayAltsAns#1{\advance\@tempcnta1\relax - \eq@insertComma - \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1} + \eq@insertComma + \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1} \newcommand{\savedAltFmt}[1]{(#1)} \newcommand{\useSavedAns}{\bgroup\@ifstar{\useSavedAns@i} - {\let\eq@insertAnd\@empty\useSavedAns@i}} + {\let\eq@insertAnd\@empty\useSavedAns@i}} \newcommand{\useSavedAns@i}[2][]{\@tempcnta=0\relax - \def\eq@namearg{#2}\let\label\@gobble - \def\eq@argi{#1}\ifx\eq@argi\@empty - \let\eq@comma\@empty - \let\\\eq@displayAns\@nameuse{SavedAns#2}\else - \@nameuse{SavedAns#2-Idx#1}\fi - \egroup + \def\eq@namearg{#2}\let\label\@gobble + \def\eq@argi{#1}\ifx\eq@argi\@empty + \let\eq@comma\@empty + \let\\\eq@displayAns\@nameuse{SavedAns#2}\else + \@nameuse{SavedAns#2-Idx#1}\fi + \egroup } \newcommand{\useSavedAlts}{\bgroup\@ifstar{\useSavedAlts@i} - {\let\eq@insertAnd\@empty\useSavedAlts@i}} + {\let\eq@insertAnd\@empty\useSavedAlts@i}} \newcommand{\useSavedAlts@i}[2][]{\@tempcnta=0\relax - \def\eq@namearg{#2}\@nameuse{caseFor#2}% - \def\eq@argi{#1}\ifx\eq@argi\@empty - \let\eq@comma\@empty - \let\\\eq@displayAlts\@nameuse{SavedAlts#2}\else - \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}\fi - \egroup + \def\eq@namearg{#2}\@nameuse{caseFor#2}% + \def\eq@argi{#1}\ifx\eq@argi\@empty + \let\eq@comma\@empty + \let\\\eq@displayAlts\@nameuse{SavedAlts#2}\else + \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}\fi + \egroup } \newcommand{\useSavedAltsAns}{\bgroup\@ifstar{\useSavedAltsAns@i} - {\let\eq@insertAnd\@empty\useSavedAltsAns@i}} + {\let\eq@insertAnd\@empty\useSavedAltsAns@i}} \newcommand{\useSavedAltsAns@i}[2][]{\@tempcnta=0\relax - \def\eq@namearg{#2}\@nameuse{caseFor#2}\let\label\@gobble - \def\eq@argi{#1}\ifx\eq@argi\@empty - \let\eq@comma\@empty - \let\\\eq@displayAltsAns\@nameuse{SavedAltsAns#2}\else - \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}} - \@nameuse{SavedAns#2-Idx#1}\fi - \egroup + \def\eq@namearg{#2}\@nameuse{caseFor#2}\let\label\@gobble + \def\eq@argi{#1}\ifx\eq@argi\@empty + \let\eq@comma\@empty + \let\\\eq@displayAltsAns\@nameuse{SavedAltsAns#2}\else + \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}} + \@nameuse{SavedAns#2-Idx#1}\fi + \egroup } \newcommand{\useSavedNumAns}[1]{\@nameuse{NumAns#1}} -\long\def\@@@SaveAnsGobbleAns#1\eAns{} % 4/5 -\long\def\@getListAns\Ans#1\eAns{%\@@par %start new paragraph - \eq@saveAns#1\eAns % 4/5 - \Ans#1\vspace{\@rowskip}% - \@layoutListAns +\long\def\@@@SaveAnsGobbleAns#1\eAns{} +\long\def\@getListAns\Ans#1\eAns{%\@@par + \eq@saveAns#1\eAns + \Ans#1\vspace{\@rowskip}% + \@layoutListAns } \long\def\@lookforendansChoices#1{% - \@ifnextchar\eChoices{\rowsep{\rowsep@default}% - \expandafter\@findendans\@gobble}{\expandafter#1\@gobble}% + \@ifnextchar\eChoices{\rowsep{\rowsep@default}% + \expandafter\@findendans\@gobble}{\expandafter#1\@gobble}% } \def\@layoutTabularAns#1{% - \let\eq@tabSep\@empty - \xdef\numShortCols{#1}% - \ifnum#1>\aeb@numCols \xdef\numShortCols{\aeb@numCols}\fi - \@@layoutTabularAns + \let\eq@tabSep\@empty + \xdef\numShortCols{#1}% + \ifnum#1>\aeb@numCols \xdef\numShortCols{\aeb@numCols}\fi + \@@layoutTabularAns } \def\@@layoutTabularAns{% - \@ifnextchar\Ans{\@getTabAns}% - {\@lookforendansChoices{\@@layoutTabularAns}}% + \@ifnextchar\Ans{\@getTabAns}% + {\@lookforendansChoices{\@@layoutTabularAns}}% } \def\rowsep#1{\gdef\@rowsep{[#1]}\gdef\@rowskip{#1}}% \rowsep{\rowsep@default} \def\rowsepDefault#1{\def\rowsep@default{#1}} \def\rowsep@default{0pt} \long\def\@getTabAns\Ans#1\eAns{% - \eq@saveAns#1\eAns - \global\advance\eq@tabColCnt1 - \let\@save@tabSep=\eq@tabSep - \ifnum\eq@tabColCnt=\numShortCols - \global\eq@tabColCnt=0 - \xdef\eq@tabSep{\noexpand\\\noalign{\kern\@rowskip\relax}}% - \else - \gdef\eq@tabSep{&}% - \fi - \@ifnextchar\eChoices{\@save@tabSep\Ans#1\rowsep{\rowsep@default} - \expandafter\@findendans\@gobble}% - {\@save@tabSep\Ans#1\@@layoutTabularAns}% + \eq@saveAns#1\eAns + \global\advance\eq@tabColCnt1 + \let\@save@tabSep=\eq@tabSep + \ifnum\eq@tabColCnt=\numShortCols + \global\eq@tabColCnt=0 + \xdef\eq@tabSep{\noexpand\\\noalign{\kern\@rowskip\relax}}% + \else + \gdef\eq@tabSep{&}% + \fi + \@ifnextchar\eChoices{\@save@tabSep\Ans#1\rowsep{\rowsep@default} + \expandafter\@findendans\@gobble}% + {\@save@tabSep\Ans#1\@@layoutTabularAns}% } -\def\@findendans{\@ifnextchar\end{% 4/5 - \ifx\bChoiceLabel\@empty\else - \processLabeledAns\fi - }{\expandafter\@findendans\@gobble}}% +\def\@findendans{\@ifnextchar\end{% + \ifx\bChoiceLabel\@empty\else + \processLabeledAns\fi + }{\expandafter\@findendans\@gobble}}% \def\defineEachAns#1{\advance\eqtmpcnta\@ne - \@temptokena={#1}\csarg\xdef - {SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}{\the\@temptokena}% - \ifsolutionsonly\else - {\let\\\relax\eq@IWDefs{\string - \csarg\string\gdef{SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}% - {\the\@temptokena}}}\fi + \@temptokena={#1}\csarg\xdef + {SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}{\the\@temptokena}% + \ifsolutionsonly\else + {\let\\\relax\eq@IWDefs{\string + \csarg\string\gdef{SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}% + {\the\@temptokena}}}% + \fi } \def\defineEachChoice#1{\advance\eqtmpcnta\@ne - \@temptokena={#1}\csarg\xdef - {SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}% - {\the\@temptokena}\ifsolutionsonly\else - {\let\\\relax\eq@IWDefs{\string - \csarg\string - \gdef{SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}% - {\the\@temptokena}}}\fi + \@temptokena={#1}\csarg\xdef + {SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}% + {\the\@temptokena}\ifsolutionsonly\else + {\let\\\relax\eq@IWDefs{\string + \csarg\string + \gdef{SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}% + {\the\@temptokena}}}\fi } \def\processLabeledAns{% - \bgroup - \let\label\@gobble -\if\aeb@FLOverride\eq@l - \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\else - \ifaebshowgrayletters + \bgroup + \let\label\@gobble + \if\aeb@FLOverride\eq@l + \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\else + \ifaebshowgrayletters \global\@namedef{caseFor\bChoiceLabel}{\graylettersOn}\else \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\fi -\fi - \toks@=\expandafter{\@tempholdSaveAns}\csarg - \xdef{SavedAns\bChoiceLabel}{\the\toks@}% - \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string - \csarg\string\gdef{SavedAns\bChoiceLabel}{\the\toks@}}}\fi - \eqtmpcnta\z@\let\\\defineEachAns\the\toks@ - \xdef\@currNCntAns{\the\eqtmpcnta}\csarg - \xdef{NumAns\bChoiceLabel}{\@currNCntAns}% - \ifsolutionsonly\else{\eq@IWDefs{\string - \csarg\string\gdef{NumAns\bChoiceLabel}{\the\eqtmpcnta}}}\fi - \toks@=\expandafter{\@tempholdSaveChoice}\csarg - \xdef{SavedAlts\bChoiceLabel}{\the\toks@}% - \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string - \csarg\string\gdef{SavedAlts\bChoiceLabel}{\the\toks@}}}\fi - \eqtmpcnta\z@\relax\let\\\defineEachChoice\the\toks@ - \eqtmpcnta\@ne\toks@={}%{\ignorespaces\@gobble}% - \loop - \edef\temp@exp{\the\toks@\noexpand\\{% - \noexpand\useSavedAlts[\the\eqtmpcnta]{\bChoiceLabel} - \noexpand\useSavedAns[\the\eqtmpcnta]{\bChoiceLabel}}}% - \toks@=\expandafter{\temp@exp}% - \ifnum\eqtmpcnta<\@currNCntAns\relax - \advance\eqtmpcnta\@ne - \repeat - \csarg\xdef{SavedAltsAns\bChoiceLabel}{\the\toks@}% - \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string - \csarg\string\gdef{SavedAltsAns\bChoiceLabel}{\the\toks@}}}\fi - \egroup + \fi + \toks@=\expandafter{\@tempholdSaveAns}\csarg + \xdef{SavedAns\bChoiceLabel}{\the\toks@}% + \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string + \csarg\string\gdef{SavedAns\bChoiceLabel}{\the\toks@}}}\fi + \eqtmpcnta\z@\let\\\defineEachAns\the\toks@ + \xdef\@currNCntAns{\the\eqtmpcnta}\csarg + \xdef{NumAns\bChoiceLabel}{\@currNCntAns}% + \ifsolutionsonly\else{\eq@IWDefs{\string + \csarg\string\gdef{NumAns\bChoiceLabel}{\the\eqtmpcnta}}}\fi + \toks@=\expandafter{\@tempholdSaveChoice}\csarg + \xdef{SavedAlts\bChoiceLabel}{\the\toks@}% + \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string + \csarg\string\gdef{SavedAlts\bChoiceLabel}{\the\toks@}}}\fi + \eqtmpcnta\z@\relax\let\\\defineEachChoice\the\toks@ + \eqtmpcnta\@ne\toks@={}%{\ignorespaces\@gobble}% + \loop + \edef\temp@exp{\the\toks@\noexpand\\{% + \noexpand\useSavedAlts[\the\eqtmpcnta]{\bChoiceLabel} + \noexpand\useSavedAns[\the\eqtmpcnta]{\bChoiceLabel}}}% + \toks@=\expandafter{\temp@exp}% + \ifnum\eqtmpcnta<\@currNCntAns\relax + \advance\eqtmpcnta\@ne + \repeat + \csarg\xdef{SavedAltsAns\bChoiceLabel}{\the\toks@}% + \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string + \csarg\string\gdef{SavedAltsAns\bChoiceLabel}{\the\toks@}}}\fi + \egroup } \def\graylettersOn{\aebshowgrayletterstrue} \def\graylettersOff{\aebshowgraylettersfalse} \def\aeb@exiii{\expandafter\expandafter\expandafter} \def\REF{\@ifstar{\let\isREFstar\eq@One\aeb@REFstar} - {\let\isREFstar\eq@Zero\aeb@REF}} + {\let\isREFstar\eq@Zero\aeb@REF}} \def\aeb@REFstar#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}} - {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}% - \else\ref*{#1}\fi}% + {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}% + \else\ref*{#1}\fi}% } \def\aeb@REF#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}} - {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}% - \else\ref{#1}\fi}% + {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}% + \else\ref{#1}\fi}% } \def\aeb@buildUpperCaseRef#1{% - \xdef\tmp@expand{\aeb@exiii\@firstoftwo\csname r@#1\endcsname}% - \xdef\tmp@expand{\uppercase{\tmp@expand}}\tmp@expand + \xdef\tmp@expand{\aeb@exiii\@firstoftwo\csname r@#1\endcsname}% + \xdef\tmp@expand{\uppercase{\tmp@expand}}\tmp@expand } \endinput %% diff --git a/macros/latex/contrib/eqexam/eqexam.dtx b/macros/latex/contrib/eqexam/eqexam.dtx index d27fe47511..b9cc28503f 100644 --- a/macros/latex/contrib/eqexam/eqexam.dtx +++ b/macros/latex/contrib/eqexam/eqexam.dtx @@ -4,7 +4,7 @@ %<*copyright> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% eqexam.sty package, %% -%% Copyright (C) 2005--2020 D. P. Story %% +%% Copyright (C) 2005--2021 D. P. Story %% %% dpstory@uakron.edu %% %% %% %% This program can redistributed and/or modified under %% @@ -16,8 +16,8 @@ % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{eqexam} -% [2020/03/14 v5.1.10 An Exam Construction Package (dps)] -%\def\eqexamdefReq{2020/03/14} +% [2021/01/20 v5.1.13 An Exam Construction Package (dps)] +%\def\eqexamdefReq{2021/01/20} %<*driver> \documentclass{ltxdoc} \GlossaryPrologue{\section{{Change History}}}% @@ -26,7 +26,7 @@ \value{GlossaryColumns}=2 \usepackage{makeidx} \usepackage[colorlinks,hyperindex=false]{hyperref} -\def\darg#1{\texttt{\{#1\}}} +\gdef\darg#1{\texttt{\char123\relax#1\char125\relax}} \let\env\texttt \let\opt\texttt \let\app\textsf @@ -2291,8 +2291,8 @@ % \end{macrocode} % \DescribeMacro{\optsMlTxtFld} is used to pass options to the multi-line % text field. -% \changes{v5.1.10}{2020/03/14}{Introduced control over width of text field in -% for \string\texttt{online} option.} +% \changes{v5.1.10}{2020/03/14}{ \string\cs{optsMsTxtFld}: Pass options to the multi-line +% text field. in for \string\texttt{online} option.} % \begin{macrocode} \def\optsMlTxtFld#1{\def\eqe@optsmltf{#1}} \let\eqe@optsmltf\@empty @@ -4215,6 +4215,7 @@ % \end{macrocode} % Since everything is put a box, we set the \cs{linewidth}, and % set \cs{solutionparshape} to \cs{@empty}. +% \changes{v5.1.11}{2020/11/16}{Adj \string\cs{linewidth} in soln file} % \begin{macrocode} \ifx\solutionparshape\@empty\else \advance\linewidth-\leadinIndentPrtSep\fi %%dps @@ -4224,8 +4225,10 @@ {\vfill}\hfill\fi \minipage[b][\eqedepth][t]{\mp@Width}% {\lccode`C=`\%\lowercase{\eqe@IW{% - \string\def\string\panelgap{\panelgap}% - \string\setlength{\string\panelwidth}{\ss@Argiii}% + \string\def\string\panelgap{\panelgap}C^^J% + \string\setlength{\string\panelwidth}{\ss@Argiii}C^^J% + \string\setlength{\string\linewidth}{\string + \linewidth-\string\eqemargin}C^^J% \string\def\string\eqedepth {\ifeq@nosolutions\ss@Argii\else\ss@Argii\fi}C}}}% % \end{macrocode} @@ -5082,6 +5085,37 @@ \def\hidden@ttr{[#1]}\let\numpoints\@empty\else \let\hidden@ttr\relax\def\numpoints{#1}\fi \problem@cont} +% \end{macrocode} +% \DescribeMacro\probV@luesInsert This command writes the number of points to the AUX +% file; form of the macro name written is \texttt{value\ameta{exam-label}Prob\ameta{prob-no}}. +% \changes{v5.1.12}{2021/01/07}{Added \string\cs{probV@luesInsert} to support \string\pkg{skills} package} +% \begin{macrocode} +\let\probV@luesInsert\relax +\def\probV@@luesInsert{\bgroup\@tempcnta\value{eqquestionnoi}\advance + \@tempcnta\@ne % Jan21 + \eqe@IWO\@auxout{\string\csarg\string + \gdef{value\thisexamlabel Prob\the\@tempcnta}{\numpoints}}\egroup +} +% \end{macrocode} +% \DescribeMacro\trackProblemsOn This command (\cs{trackProblemsOn}) activates problem tracking (ie, write problems and values +% to the AUX file; \DescribeMacro\trackProblemsOff\cs{trackProblemsOff} turns off tracking. Tracking is +% off by default. When tracing is on, the value of each problem is saved in the form +% |\csarg\gdef{value|\ameta{exam-label}\texttt{Prob}\ameta{prob-num}|}|. This feature was developed to support +% the \pkg{skills} package. +% \changes{v5.1.12}{2021/01/07}{Added \string\cs{trackProblemsOn} and \string\cs{trackProblemsOff} to support \string\pkg{skills} package} +% \begin{macrocode} +\def\trackProblemsOn{\let\probV@luesInsert\probV@@luesInsert} +\def\trackProblemsOff{\let\probV@luesInsert\relax} +\trackProblemsOff +% \end{macrocode} +% \DescribeMacro\numPtsOfProblem\hskip-\marginparsep\texttt{[\ameta{exam-label}]\darg{\ameta{prob-num}}} +% The command \cs{numPtsOfProblem} typesets the number of points of problem \ameta{prob-num} from part \ameta{label-name}. +% \begin{macrocode} +\newcommand{\numPtsOfProblem}[2][\thisexamlabel]% + {\@nameuse{value#1Prob#2}} +% \end{macrocode} +% The \env{problem} environment continues. +% \begin{macrocode} \newcommand{\problem@cont}[1][]{\let\isProbEnv\eqe@YES \def\@rgi{#1}\ifx\hidden@ttr\relax % assume a number or empty \ifx\@rgi\@empty\else\def\hidden@ttr{[#1]}\fi\fi @@ -5107,6 +5141,7 @@ \def\@ltii{\let\@isitstar\eqe@Zero\eqe@gobbletoend}% \expandafter\@ifstar\expandafter\@lti \expandafter\@ltii\numpoints\end + \probV@luesInsert % Jan21 \if\@isitstar\eqe@One\addtocounter{eqpointvalue}{\numpoints}% \@marktotalvalue \ifdispl@yPoints @@ -5137,7 +5172,8 @@ % \begin{macrocode} \edef\ctrld@exp@exercise{\noexpand \begin{exercise}[eqquestionnoi]\hidden@ttr}% - \ctrld@exp@exercise\ignorespaces\eqe@p@gobnxtp@r} + \ctrld@exp@exercise\ignorespaces\eqe@p@gobnxtp@r +} % \end{macrocode} % \textbf{end problem env.} The code for the end of the problem environment. % \begin{macrocode} @@ -5719,6 +5755,7 @@ % \begin{macrocode} \let\marginpoints\@empty \else + \probV@luesInsert % Jan21 % \end{macrocode} % Points are displayed in margins or inline % \begin{macrocode} @@ -5727,6 +5764,7 @@ % \paragraph*{Total points specified} % \begin{macrocode} \ifx\marginpoints\@empty\else + \probV@luesInsert % Jan21 \if\@isitstar\eqe@One % \end{macrocode} % Points to appear ``in-line'' rather than in the margins @@ -5797,6 +5835,7 @@ \fi % \addtocounter{eqpointvalue}{\numpoints}\@marktotalvalue \ifx\marginpoints\@empty\else + \probV@luesInsert % Jan21 \ifdispl@yPoints \if\@isitstar\eqe@One % \end{macrocode} @@ -7242,6 +7281,7 @@ %The \cs{eqTWSave} is the saved value of the \cs{textwidth} in effect when %the \env{exam} environment is opened. The right totals box is placed in the right %margin based on this value. +%\changes{v5.1.10}{2020/03/14}{Define \string\cs{probInMinipage}} % \begin{macrocode} \def\probInMinipage{% \ifanswerkey @@ -7269,11 +7309,11 @@ % the total height of the typeset solution. It then calculates the difference between % \cs{sameVspace}, which should hold the value of the optional argument of \env{solution}, % and the actual height of the solution. It then executes a \cs{vspace} for that amount calculated. -% +% \changes{v5.1.10}{2020/03/14}{Add \string\env{vadjForSolnInBx} to correct for vertical space for a +% problem in a \string\env{minipage}} % \begin{macrocode} \newenvironment{vadjForSolnInBx}[1]{% - \setlength\@tempdima{#1}% - \setbox\z@\vbox\bgroup\hsize\@tempdima + \setlength\@tempdima{#1}\setbox\z@\vbox\bgroup\hsize\@tempdima }{% \egroup \ifanswerkey @@ -7296,6 +7336,7 @@ % use \cs{bProbInsert} with its argument. Place \DescribeMacro{\eProbInsert}\cs{eProbInsert} at the end of the statement of the % question, as illustrated below. \cs{bProbInsert} puts the question into a group, % \cs{eProbInsert} gets us out of the group. +% \changes{v5.1.10}{2020/03/14}{Define \string\cs{bProbInsert} and \string\cs{bItemInsert}} %\begin{verbatim} %\def\insertFig{\parpic[r]{\FIG}} %\bProbInsert{\insertFig} diff --git a/macros/latex/contrib/eqexam/examples/fig1.pdf b/macros/latex/contrib/eqexam/examples/fig1.pdf index 054fe38f56..134d03dfde 100644 Binary files a/macros/latex/contrib/eqexam/examples/fig1.pdf and b/macros/latex/contrib/eqexam/examples/fig1.pdf differ diff --git a/macros/latex/contrib/eqexam/examples/hw.cfg.txt b/macros/latex/contrib/eqexam/examples/hw.cfg.txt deleted file mode 100644 index 57511627ea..0000000000 --- a/macros/latex/contrib/eqexam/examples/hw.cfg.txt +++ /dev/null @@ -1,12 +0,0 @@ -\renewcommand\maketitledesign -{% - \makebox[\textwidth]{\normalsize - \shortstack[l]{\strut\underbar{\websubject}\\\@date}\hfill - \shortstack[l]{\underbar{\webtitle}\\\strut}\hfill - \shortstack[l]{\strut\underbar{Due \theduedate}\\\webauthor}}% -} -\rhead{\webauthor} -\def\exrtnlabelformat{$\square$} -\def\exrtnlabelformatwp{} -\def\eq@sqslrtnlabel{} -\everymath{\displaystyle} diff --git a/macros/latex/contrib/eqexam/examples/quiz.cfg.txt b/macros/latex/contrib/eqexam/examples/quiz.cfg.txt deleted file mode 100644 index bc9a15aed6..0000000000 --- a/macros/latex/contrib/eqexam/examples/quiz.cfg.txt +++ /dev/null @@ -1,7 +0,0 @@ -\renewcommand\maketitledesign -{% - \makebox[\textwidth]{\normalsize - \shortstack[l]{\strut\websubject\\\webauthor, \@date}\hfill - \shortstack[l]{\webtitle\\\strut}\hfill - \shortstack[l]{\strut\eq@ExamName\\\eq@SID}}% -} diff --git a/macros/latex/contrib/eqexam/examples/test01.pdf b/macros/latex/contrib/eqexam/examples/test01.pdf new file mode 100644 index 0000000000..92b9d6c52b Binary files /dev/null and b/macros/latex/contrib/eqexam/examples/test01.pdf differ diff --git a/macros/latex/contrib/eqexam/examples/test01.tex b/macros/latex/contrib/eqexam/examples/test01.tex index 102b7b61e0..a52cfafbf1 100644 --- a/macros/latex/contrib/eqexam/examples/test01.tex +++ b/macros/latex/contrib/eqexam/examples/test01.tex @@ -28,7 +28,7 @@ \turnContAnnotOn \optsFillIn{\BC{0.847 0.847 0.847}} -\optsMlTextField{\BC{0.847 0.847 0.847}} +\optsMlTxtFld{\BC{0.847 0.847 0.847}} \eqExamName[\Ff\FfRequired\BC{0.847 0.847 0.847}]{2.25in} \eqSID[\Ff\FfRequired\BC{0.847 0.847 0.847}]{2.25in} \cpSetSumryWidth{.55\textwidth-1em} @@ -45,7 +45,7 @@ \begin{instructions}[Part I.] Solve each of the problems without error. If you make an error, -points will be subtracted from your total score. +points will be subtracted from your total score. \end{instructions} \begin{problem}[5] diff --git a/macros/latex/contrib/eqexam/examples/test02.pdf b/macros/latex/contrib/eqexam/examples/test02.pdf new file mode 100644 index 0000000000..2a4c84b5d8 Binary files /dev/null and b/macros/latex/contrib/eqexam/examples/test02.pdf differ diff --git a/macros/latex/contrib/eqexam/examples/test03.pdf b/macros/latex/contrib/eqexam/examples/test03.pdf new file mode 100644 index 0000000000..58998f261c Binary files /dev/null and b/macros/latex/contrib/eqexam/examples/test03.pdf differ diff --git a/macros/latex/contrib/eqexam/examples/test_matching.pdf b/macros/latex/contrib/eqexam/examples/test_matching.pdf deleted file mode 100644 index 56eff4053c..0000000000 Binary files a/macros/latex/contrib/eqexam/examples/test_matching.pdf and /dev/null differ diff --git a/macros/latex/contrib/fnpct/README b/macros/latex/contrib/fnpct/README index 5a230d16e4..c9c58a4381 100644 --- a/macros/latex/contrib/fnpct/README +++ b/macros/latex/contrib/fnpct/README @@ -1,23 +1,22 @@ -------------------------------------------------------------------------- -the FNPCT package v0.5 +the FNPCT package v1.0 2021/01/21 footnote kerning -2019/10/05 -------------------------------------------------------------------------- Clemens Niederberger -Web: https://bitbucket.org/cgnieder/fnpct/ +Web: https://github.com/cgnieder/fnpct/ E-Mail: contact@mychemistry.eu -------------------------------------------------------------------------- -Copyright 2012--2019 Clemens Niederberger +Copyright 2012--2021 Clemens Niederberger This work may be distributed and/or modified under the -conditions of the LaTeX Project Public License, either version 1.3 +conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. The latest version of this license is in http://www.latex-project.org/lppl.txt -and version 1.3 or later is part of all distributions of LaTeX -version 2005/12/01 or later. +and version 1.3c or later is part of all distributions of LaTeX +version 2008/05/04 or later. This work has the LPPL maintenance status `maintained'. diff --git a/macros/latex/contrib/fnpct/fnpct-manual.cls b/macros/latex/contrib/fnpct/fnpct-manual.cls new file mode 100644 index 0000000000..0abdf7e405 --- /dev/null +++ b/macros/latex/contrib/fnpct/fnpct-manual.cls @@ -0,0 +1,331 @@ +% -------------------------------------------------------------------------- +% the FNPCT package +% +% footnote kerning +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/fnpct/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2012--2021 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% -------------------------------------------------------------------------- +\RequirePackage[multiple]{fnpct} +\ProvidesClass{fnpct-manual}[2021/01/17] + +\LoadClass[load-preamble,add-index]{cnltx-doc} +\RequirePackage{imakeidx} + +\setcnltx{ + package = {fnpct} , + info = {Footnote kerning and multiple footnotes} , + authors = Clemens Niederberger , + email = contact@mychemistry.eu , + url = https://github.com/cgnieder/fnpct/ , + abstract = {% + The \fnpct\ package basically does two things to footnotes: if footnote + marks are followed by a punctuation mark the order of footnote and + punctuation mark is reversed and the kerning gets adjusted. As a side + effect mutiple footnotes and footnote ranges are easily obtained..% + }, + add-cmds = { + AdaptNote, + AdaptNoteName, + AddPunctuation, + % kfc, + % kfp, + multfootnote, + MultVariant, + setfnpct + } , + add-silent-cmds = { + @mpfn, + anote, + anotecontent, + arabic, + DeclareNewFootnote, + endnote, + footcite + footnoteB, + footref, + IfBooleanTF, + IfNoValueTF, + multendnote, + multfootcite, + multparnote, + multsidenote, + myfn, + newfootnotes, + parnote, + parnotes, + sidenote, + theendnotes, + thempfootnote + } , + makeindex-setup = {options={-s cnltx.ist},columns=3,columnsep=1em} , + index-setup = {othercode=\footnotesize,level=\addsec} +} + +\RequirePackage{array,booktabs} + +\RequirePackage{endnotes} +\RequirePackage{parnotes} +\RequirePackage{sepfootnotes} + +\newfootnotes{a} + +\renewcommand\thempfootnote{\arabic{mpfootnote}} + +\DeclareTranslation{english}{cnltx-default}{Initial} + +\protected\def\@versionstar{\raisebox{-.25em}{*}} +\newcommand\versionstar{\texorpdfstring{\@versionstar}{*}} + +\newcommand*\TF{\textcolor{red}{\uline{\code{\textcolor{cs}{\textit{TF}}}}}} + +\RequirePackage{fontawesome} +\RequirePackage{datetime2} +\DTMsetup{useregional=numeric,datesep=/} +\newrobustcmd*\fnpct@add@version[2]{% + \csdef{ac@ver@#2}{% + \DTMdate{#1}% + \csgdef{ac@ver@#2used}{}% + \csdef{ac@ver@#2}{\DTMdate{#1}}% + }% +} + +\newrobustcmd*\ac@date[1]{\ifcsdef{ac@ver@#1used}{}{ (\csuse{ac@ver@#1})}} +\newrobustcmd*\ac@ifnew[1]{\ifcsstring{c_fnpct_version_tl}{#1}} +\newrobustcmd*\ac@NEW{\faStarO\ New} + +\renewrobustcmd*\sinceversion[1]{% + \ac@ifnew{#1}% + {\cnltx@version@note{\textcolor{red}{\ac@NEW}}}% + {\cnltx@version@note{\GetTranslation{cnltx-introduced}~v#1\ac@date{#1}}}% +} +\renewrobustcmd*\changedversion[1]{% + \cnltx@version@note{\GetTranslation{cnltx-changed}~v#1\ac@date{#1}}% +} + +\newnote*\sincechanged[2]{% + \GetTranslation{cnltx-introduced}~#1\ac@date{#1}, + changed with ~v#2\ac@date{#2}\ac@ifnew{#2}{ \ac@NEW}{}% +} + +\RenewDocumentEnvironment{commands}{} + {% + \cnltx@set@catcode_{12}% + \let\command\cnltx@command + \cnltxlist + } + {\endcnltxlist} + +\RequirePackage{tcolorbox,xsimverb} +\tcbuselibrary{skins,breakable} +\tcbset{enhanced,enhanced jigsaw} + +\newtcolorbox{bewareofthedog}{ + colback = red!2!white!98 , + colframe = red , + underlay={% + \path[draw=none] + (interior.south west) + rectangle node[red]{\Huge\bfseries !} + ([xshift=-4mm]interior.north west); + }% +} + +\newtcolorbox{cnltxcode}[1][]{ + boxrule = 1pt , + colback = cnltxbg , + colframe = cnltx , + arc = 5pt , + beforeafter skip = .5\baselineskip ,% + #1% +} + +\newcommand*\fnpctman@readoptions[1]{% + \catcode`\^^M=13 + \fnpctman@read@options{#1}% +} + +\begingroup +\catcode`\^^M=13 +\gdef\fnpctman@read@options#1#2^^M{% + \endgroup + \ifblank{#2}{}{\fnpctman@read@options@#2}% + #1% + \XSIMfilewritestart*{\jobname.tmp}% +}% +\endgroup +\def\fnpctman@read@options@[#1]{\pgfqkeys{/cnltx}{#1}} + +\RenewDocumentEnvironment{sourcecode}{} + {% + \begingroup + \fnpctman@readoptions{% + \setlength\cnltx@sidebysidewidth + {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}% + \expanded{% + \noexpand\lstset{ + style=cnltx, + \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} } + {linewidth=\cnltx@sidebysidewidth,}{}% + \expandonce\cnltx@local@listings@options + }% + }% + \XSIMgobblechars{2}% + }% + } + {% + \XSIMfilewritestop + \cnltxcode[breakable]% + \lstinputlisting[style=cnltx]{\jobname.tmp}% + \endcnltxcode + } + +\RenewDocumentEnvironment{example}{} + {% + \begingroup + \fnpctman@readoptions{% + \setlength\cnltx@sidebysidewidth + {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}% + \expanded{% + \noexpand\lstset{ + style=cnltx, + \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} } + {linewidth=\cnltx@sidebysidewidth,}{}% + \expandonce\cnltx@local@listings@options + }% + }% + \XSIMgobblechars{2}% + }% + } + {% + \XSIMfilewritestop + \ifbool{cnltx@sidebyside} + {% + \cnltxcode + \noindent + \minipage[c]{\cnltx@sidebysidewidth}% + \cnltx@pre@source@hook + \lstinputlisting[style=cnltx] {\jobname.tmp}% + \cnltx@after@source@hook + \endminipage\hfill + \minipage[c]{\cnltx@sidebysidewidth}% + \cnltx@pre@example@hook + \input {\jobname.tmp}% + \cnltx@after@example@hook + \endminipage + } + {% + \cnltxcode[breakable]% + \cnltx@pre@source@hook + \lstinputlisting{\jobname.tmp}% + \cnltx@after@source@hook + \ifbool{cnltx@float}{}{% + \tcblower + \cnltx@pre@example@hook + \input {\jobname.tmp}% + \cnltx@after@example@hook + } + }% + \endcnltxcode + \ifbool{cnltx@float}{% + \cnltx@float@start + \ifdefvoid\cnltx@float@caption{}{\caption{\cnltx@float@caption}}% + \expandafter\end\expandafter{\cnltx@float@type}% + }{}% + } + +\RequirePackage[ + backend=biber, + style=cnltx, + sortlocale=en_US, + indexing=cite]{biblatex} +\RequirePackage{csquotes,varioref} + +\defbibheading{bibliography}[\bibname]{\addsec{#1}} + +\RequirePackage[biblatex]{embrac}[2012/06/29] +\ChangeEmph{[}[,.02em]{]}[.055em,-.08em] +\ChangeEmph{(}[-.01em,.04em]{)}[.04em,-.05em] + +\NewDocumentCommand\noranges{sm}{% + \begin{bewareofthedog} + \IfBooleanTF{#1}{\pkg*}{\pkg}{#2} cannot be used together with + \keyis{ranges}{true}. + \end{bewareofthedog} +} + +\RequirePackage{hyperref} + +% additional packages: +\RequirePackage{longtable,array,booktabs,enumitem,amssymb} + +% ---------------------------------------------------------------------------- +\newrobustcmd*\pdfdisable[2]{% + \csdef{fnpct@@\cnltx@stripbs#1}##1{#2}% + \def#1##1{% + \csuse{fnpct_if_star_gobble:nTF}{##1}% + {\csuse{fnpct@@\cnltx@stripbs#1}}% + {\csuse{fnpct@@\cnltx@stripbs#1}{##1}}% + }% +} + +\pdfstringdefDisableCommands{% + \pdfdisable\template{#1}% + \pdfdisable\property{#1} + \pdfdisable\cs{\string\\#1}% + \pdfdisable\cmd{\string\\#1}% + \pdfdisable\option{#1}% + \def\oarg#1{[<#1>]}% + \def\Oarg#1{[#1]}% + \def\marg#1{\{<#1>\}}% + \def\Marg#1{\{#1\}}% + \def\fnpct{fnpct}% + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% +} +% ---------------------------------------------------------------------------- +\fnpct@add@version{2012-05-22}{0.1} +\fnpct@add@version{2012-05-23}{0.1a} +\fnpct@add@version{2012-05-26}{0.2} +\fnpct@add@version{2012-06-01}{0.2a} +\fnpct@add@version{2012-06-07}{0.2b} +\fnpct@add@version{2012-06-28}{0.2c} +\fnpct@add@version{2012-07-07}{0.2d} +\fnpct@add@version{2012-07-24}{0.2e} +\fnpct@add@version{2012-08-27}{0.2f} +\fnpct@add@version{2012-11-14}{0.2g} +\fnpct@add@version{2013-01-18}{0.2h} +\fnpct@add@version{2013-01-21}{0.2i} +\fnpct@add@version{2013-02-22}{0.2j} +\fnpct@add@version{2013-04-07}{0.2k} +\fnpct@add@version{2013-04-16}{0.3} +\fnpct@add@version{2013-06-14}{0.3a} +\fnpct@add@version{2013-12-22}{0.4} +\fnpct@add@version{2013-12-23}{0.4a} +\fnpct@add@version{2014-03-10}{0.4b} +\fnpct@add@version{2015-02-20}{0.4c} +\fnpct@add@version{2015-04-23}{0.4d} +\fnpct@add@version{2016-03-25}{0.4e} +\fnpct@add@version{2019-02-17}{0.4f} +\fnpct@add@version{2019-09-30}{0.4g} +\fnpct@add@version{2019-10-05}{0.5} +\fnpct@add@version{2020-01-12}{0.5a} +\fnpct@add@version{2021-01-21}{1.0} + +\endinput diff --git a/macros/latex/contrib/fnpct/fnpct-manual.pdf b/macros/latex/contrib/fnpct/fnpct-manual.pdf new file mode 100644 index 0000000000..dc85988bb4 Binary files /dev/null and b/macros/latex/contrib/fnpct/fnpct-manual.pdf differ diff --git a/macros/latex/contrib/fnpct/fnpct-manual.tex b/macros/latex/contrib/fnpct/fnpct-manual.tex new file mode 100644 index 0000000000..2dbc17dcdb --- /dev/null +++ b/macros/latex/contrib/fnpct/fnpct-manual.tex @@ -0,0 +1,615 @@ +% arara: pdflatex: { shell: on , interaction: nonstopmode } +% !arara: biber +% !arara: pdflatex +% !arara: pdflatex +% -------------------------------------------------------------------------- +% the FNPCT package +% +% footnote kerning +% +% -------------------------------------------------------------------------- +% Clemens Niederberger +% Web: https://github.com/cgnieder/fnpct/ +% E-Mail: contact@mychemistry.eu +% -------------------------------------------------------------------------- +% Copyright 2012--2021 Clemens Niederberger +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Clemens Niederberger. +% -------------------------------------------------------------------------- +\documentclass{fnpct-manual} + +\setfnpct{ + add-trailing-token = [0pt]:[-.05em]{colon} , + after-comma-space = -0.1em , + after-dot-space = -0.1em , + before-comma-space = -0.05em , + before-dot-space = -0.05em , + before-footnote-space = 0.05em +} + +\addbibresource{cnltx.bib} +\addbibresource{\jobname.bib} +\addbibresource{biblatex-examples.bib} +\begin{filecontents*}{\jobname.bib} +@book{bringhurst04, + title = {The Elements of Typographic Style}, + author = {Robert Bringhurst}, + year = {2004}, + version = {3.2}, + isbn = {978-0-88179-205-5}, + publisher = {Hartley \&\ Marks, Canada} +} +\end{filecontents*} + +\AdaptNote\footcite{m}{#NOTE{#1}} + +\newname\bringhurst{Robert Bringhurst} +\newname\lefloch{Bruno Le Floch} + +\setlength\parfillskip{0pt plus .8\textwidth} + +\begin{document} + +\section{Preface for those upgrading from version 0.x} + +\begin{bewareofthedog} + For those upgrading from versions~0 to version~1: a number of options have + been dropped or renamed. Please have a close look at your log file for + warnings. Also, the way commands are adapted and hence the syntax of + \cs{AdaptNote} has changed completely. In many if not all cases leaving them + as they were will lead to errors. \par + The \cs*{mult...} variants are not defined by default anymore. They can be + retained through the load-time option \option{multiple} if needed. Letting + the note commands behave as their \cs*{mult...} variants is not supported + any more. \par + \cs{innernote} is not provided anymore. Depending on user feedback I might + try to add it again to \fnpct. \par + Please read this manual carefully so you detect all changes. \par + \emph{I am sorry for the inconvenience but I am convinced that the new + syntax is more powerful and more flexible in the long run.} +\end{bewareofthedog} + +\section{License} +\license + +\section{What's it all about?} +\subsection{Introduction} +The purpose of this package is to offer kerning for footnote marks, \ie\ the +superscripts. This is not appropriate for all superscripts. Symbols must be +handled differently than numbers. And of course the amount depends on the +chosen font. \bringhurst\ says in \citetitle{bringhurst04}: + +\begin{cnltxquote}[\emph{\citetitle{bringhurst04}} \cite{bringhurst04}] + Superscripts frequently come at the ends of phrases or sentences. If they + are high above the line, they can be kerned over a comma or period, but this + may endanger readability, especially if the text is set in a modest size. +\end{cnltxquote} + +\fnpct\ can not make these decisions for you. It sets some initial values for +the comma and the full stop which looked good to me with the tested fonts. +Additionally it kerns the superscripts away from words when it follows +directly. The amounts of the kerning can be changed using options. + +\fnpct\ also switches the order of the superscript and the following comma or +full stop. Additional punctuation marks can be added to the switching +behavior and the amount of kerning can be set for each punctuation mark +individually. This behavior can also be turned off. + +\subsection{Basics} +The \fnpct\ package basically does two things to footnotes: +\begin{itemize} + \item if footnote marks are followed by a comma or a full stop\footnote{More + punctuation marks can be added through a package option.} the order of + footnote and punctuation mark is reversed +\item and the kerning gets adjusted. +\end{itemize} +As a side effect a new method of creating multiple +footnotes\multfootnote{like;this} is provided. + +In what way is the kerning adjusted? After being placed behind the +punctuation mark the footnote mark is moved a little bit back, namely by the +amount specified with the option \option{after-punct-space}. If the footnote +mark follows a word \emph{without} being followed by a +punctuation\footnote{Well, it does not necessarily have to follow a + \emph{word}. The important point is \emph{not being followed} by a + punctuation mark.}, there (obviously) is no order switching and a little +space is inserted before the footnote mark, namely the amount specified by the +option \option{before-footnote-space}. + +Now, let's see some action: +\begin{example} + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}, sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}. +\end{example} + +To ensure that the kerning is set the right way the footnote \emph{must} be +placed \emph{before} the full stop or the comma. \emph{The command can look + ahead but not look back}. This means if you place the \cs{footnote} command +after a full stop or a comma it is treated as if following a word, \ie\ a thin +space is inserted: effectively the opposite of the desired behavior. The +effects are demonstrated in figure~\vref{fig:effects}. + +The order-switching can be prevented using the option \option{reverse} since +not all countries and languages have the same typographic conventions. In +this case the full stop and the comma are moved a bit back, namely by the +amount specified with the option \option{before-punct-space}. + +\begin{figure} + \centering + \begin{tabular}{>{\setfnpct{dont-mess-around}}ll} + \toprule + without \fnpct & + with \fnpct \\ + \midrule + \strut\quad text.\footnotemark[1] & + \strut\quad text\footnotemark[1]. \\ + \strut\quad text\footnotemark[1]. & + \setfnpct{reverse}\strut\quad text\footnotemark[1]. \\ + \strut\quad text\footnotemark[1] & + \strut\quad text\footnotemark[1] \\ + \bottomrule + \end{tabular} + \caption{The effect of \fnpct.}\label{fig:effects} +\end{figure} + +\subsection{Temporarily disable (or enable) switching -- new syntax of the + \cs*{footnote} command} +One maybe want to put some footnote marks \emph{before} the punctuation and +some after, for example because the first one describes a single word but the +second one a whole sentence. For this purpose \fnpct\ adds a \sarg\ argument +to \cs{footnote} and \cs{footnotemark}. The complete new syntax now is as +follows: +\begin{commands} + \command{footnote}[\sarg\oarg{num>}\marg{footnote text}\meta{tpunct}] + new \sarg\ argument added. \meta{tpunct} is the optional trailing + punctuation mark. + \command{footnotemark}[\sarg\oarg{num>}\meta{tpunct}] + new \sarg\ argument added. \meta{tpunct} is the optional trailing + punctuation mark. +\end{commands} +The \sarg\ argument temporarily turns off the punctuation/footnote switching. +In case you set \keyis{reverse}{true} the \sarg\ argument temporarily +\emph{enables} the switching. + +\begin{example} + \begin{minipage}{.4\linewidth} + \noindent The three little pigs built their houses + out of straw\footnote*{not to be confused with hay}, + sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}. + \end{minipage}\hfil + \setfnpct{reverse} + \begin{minipage}{.4\linewidth} + \noindent The three little pigs built their houses + out of straw\footnote*{not to be confused with hay}, + sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}. + \end{minipage} +\end{example} + +\section{Options}\label{sec:options} +\begin{commands} + \command{setfnpct}[\marg{options}] + All available options are listed below. They are set with \cs{setfnpct}. + \default{Underlined} values are set if the option is used without value. +\end{commands} +\begin{options} + \keybool{dont-mess-around}\Default{false} + Switches of \fnpct's mechanism. + \keybool{reverse}\Default{false} + This option reverses the behavior of starred and un-starred footnotes. + \keybool{ranges}\Default{false} + Activates ranges for multiple footnotes. This is not compatible with + \pkg{hyperref} and does not work for the marks of some packages. + \keylit{add-trailing-token}{\oarg{before}\meta{token}\oarg{after}\marg{name}} + Adds \meta{token} to \fnpct's mechanism and activates it. \meta{before} + sets the default value for the newly created option + \option{before-\meta{name}-space}. \meta{after} sets the default value for + the newly created option \option{after-\meta{name}-space}. + Instead of the option you can also use the command \cs*{AddPunctuation}, + see section~\ref{sec:adapt}. + \keyval{activate-trailing-tokens}{tokenlist}\Default{.,} + Activates tokens that have been added with \option{add-trailing-token}. + \keyval{deactivate-trailing-tokens}{tokenlist} + Deactivates tokens that have been added with \option{add-trailing-token}. + \keyval{before-footnote-space}{dimension}\Default{.06em} + Sets the space that is inserted before a footnote that \emph{does not + follow a punctuation or other note} to \meta{dimension}. + \keyval{before-dot-space}{dimension}\Default{-.16em} + Sets the space that is inserted before a dot if the dot follows a footnote + mark to \meta{dimension}. + \keyval{before-comma-space}{dimension}\Default{-.16em} + Sets the space that is inserted before a comma if the dot follows a footnote + mark to \meta{dimension}. + \keyval{before-punct-space}{dimension} + Sets the space that is inserted before any punctuation mark known to + \fnpct\ if the punctuation mark follows a footnote mark to + \meta{dimension}. + \keyval{after-dot-space}{dimension}\Default{-.06em} + Sets the space that is inserted after a dot if the dot precedes a footnote + mark to \meta{dimension}. + \keyval{after-comma-space}{dimension}\Default{-.06em} + Sets the space that is inserted after a comma if the dot precedes a + footnote mark to \meta{dimension}. + \keyval{after-punct-space}{dimension} + Sets the space that is inserted after any punctuation mark known to + \fnpct\ if the punctuation mark precedes a footnote mark to + \meta{dimension}. + \keyval{mult-fn-delim}{code}\Default{\code{;}} + Sets the symbol that divides the seperate notes in the \cs*{mult...} + variants. + \keyval{separation-symbol}{value}\default{\code{,}} + Redefines \cs{multfootsep} to \meta{value}. This symbol separates + multiple footnotes if \keyis{ranges}{false}. + \keyval{range-symbol}{value}\Default{\code{--}} + Redefines \cs{multfootrange} to \meta{value}. This symbol separates + multiple footnotes if \keyis{ranges}{true}. + \keyval{print-separation}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootsep}}} + The actual code placed between multiple footnotes if \keyis{ranges}{false}. + \keyval{print-range}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootrange}}} + The actual code placed between multiple footnotes if \keyis{ranges}{true}. +\end{options} + +% \subsection{Language Specific Settings} +% Package \pkg{babel}'s~\cite{pkg:babel} French settings redefine +% \cs*{@footnotemark}. \fnpct\ resets this redefinition but sets the +% \option{before-footnote-space} equal to a thin space (\code{.16667em}). + +% In case the automatic kerning doesn't work for whatever reason the spaces are +% available as user commands as well: +% \begin{commands} +% \command{kfp} +% Insert \option{after-dot-space} or (if \keyis{punct-after}{true}) +% \option{before-dot-space}. +% \command{kfc} +% Insert \option{after-comma-space} or (if \keyis{punct-after}{true}) +% \option{before-comma-space}. +% \end{commands} + +\section{Multiple footnotes}\label{sec:multiple} +\subsection{Basics} +Since multiple footnotes have to be treated differently\footnote{see these + footnotes}\footnote{for an example}, \fnpct\ recognizes if \cs*{footnote} is +used multiple times in a row: + +\begin{example} + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}, sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}\footnote{or something else}. +\end{example} + +\subsection{Ranges} +Starting with a minimum number of three footnotes in a row \fnpct\ can also +display the footnote marks as a range. +\begin{example} + \setfnpct{ ranges = true } + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}, sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}% + \footnote{or something else}\footnote{what do I know}. +\end{example} +It is important to note that this has limits: ranges do not work well with +\pkg{hyperref}. For that reason \fnpct' disables ranges if it detects that +\pkg{hyperref} has been loaded. If you insist on using ranges together with +\pkg{hyperref} use +\begin{options} + \keybool{keep-ranges}\Default{false} + to enable them again. +\end{options} + +\subsection{The delimiter and separator} +Some packages or classes like the \KOMAScript\ classes define +\cs{multfootsep}. If it is not predefined it is defined by \fnpct: +\begin{commands} + \command{multfootsep}\Default{,} + In its default definition this command simply expands to a comma. + \command{multfootrange}\Default{--} + In its default definition this command simply expands to an endash. +\end{commands} +This commands can be redefined to adapt to your needs. You can do this with +\cs*{renewcommand} or by using these options: +\begin{options} + \keyval{separation-symbol}{value}\default{\code{,}} + Redefines \cs{multfootsep} to \meta{value}. This symbol separates + multiple footnotes if \keyis{ranges}{false}. + \keyval{range-symbol}{value}\Default{\code{--}} + Redefines \cs{multfootrange} to \meta{value}. This symbol separates + multiple footnotes if \keyis{ranges}{true}. +\end{options} +Both symbols are placed inside \cs*{textsuperscript}. This can also be +redefined if necessary: +\begin{options} + \keyval{print-separation}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootsep}}} + The actual code placed between multiple footnotes if \keyis{ranges}{false}. + \keyval{print-range}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootrange}}} + The actual code placed between multiple footnotes if \keyis{ranges}{true}. +\end{options} + +\subsection{\cs*{mult...} variants} + +\begin{bewareofthedog} + The commands presented in this section are defined to keep some backwards + compatibility to versions of \fnpct\ prior to v1.0. In order to use them + you have to call the package with + \cs*{usepackage}\Oarg{multiple}\Marg{fnpct}. +\end{bewareofthedog} +In earlier versions of \fnpct\ detecting following footnotes was not as +reliable as it is now. For that reason it defined the following command: +\begin{commands} + \command{multfootnote}[\sarg\Marg{\meta{list};\meta{of};\meta{footnotes}}\meta{tpunct}] + Different footnotes are separated with a semicolon. The \sarg\ turns the + footnote/punctuation switching temporarily off. +\end{commands} +\begin{example} + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}, sticks\footnote{or lumber according to some sources} + and bricks\multfootnote{probably fired clay bricks;or something else}. +\end{example} +This command splits its content at every occurrence of \code{;} and creates a +footnote for each. This delimiter can be changed: +\begin{options} + \keyval{mult-fn-delim}{code}\Default{;} + Sets the symbol that divides the seperate notes in the \cs*{mult...} + variants. +\end{options} + +Since the semicolon might be part of the footnote text you might have some +trouble. Enclosing it in braces should work: +\begin{example} + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}, sticks\footnote{or lumber according to some sources} + and bricks\multfootnote{probably fired clay bricks{;} or something else;what + do I know}. +\end{example} + +\section{Extend \fnpct} +\subsection{Additional punctuation marks} +So if you want to extend the punctuation switching and kerning to other punctuation +marks you can do something like this: +\begin{sourcecode} + \setfnpct{ add-trailing-token = !{bang} } +\end{sourcecode} +\setfnpct{ add-trailing-token = !{bang} } +After that the bang is recognized and footnotes switch position: +\begin{example} + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}? Sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}! +\end{example} + +New options have also been defined: +\begin{example} + \setfnpct{ after-bang-space = .03em } + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}? Sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}! +\end{example} + +And option \option{after-punct-space} is obeyed: +\begin{example} + \setfnpct{ after-punct-space = 2pt } + The three little pigs built their houses out of straw\footnote{not to be + confused with hay}? Sticks\footnote{or lumber according to some sources} + and bricks\footnote{probably fired clay bricks}! +\end{example} + +\begin{bewareofthedog} + Please note that you should not use \option{add-trailing-token} inside a + group. Ideally it is used in the document preamble only. Using it inside of + a group can lead to unwanted side effects and should not be attempted. +\end{bewareofthedog} + +\setfnpct{ deactivate-trailing-tokens = ! } + +\subsection{Make note commands known to \fnpct}\label{sec:adapt} +If a package is not natively supported you can try and adapt commands +yourself. Before you do so please check section~\vref{sec:other:packages}. +\begin{commands} + % \AdaptNote + \command{AdaptNote}[\Marg{\cs*{cs}}\marg{arguments}\oarg{counter name}\marg{code}] + This redefines \cs*{cs}. How the redefinition works is best demonstrated + with an example. See below for an example. The arguments \meta{arguments} + are defined with the same syntax as \pkg{xparse}'s + \cs*{NewDocumentCommand}. See the \pkg{xparse} manual~\cite{pkg:xparse} + for a complete description. Within \meta{code} \code{\#NOTE} is replaced + with the original command. If the optional argument is not used the + counter name \code{cs} for a note command \cs*{cs} is assumed. + + In addition to the arguments specified in \meta{arguments} an optional + star as first argument is defined which reverses \fnpct's behavior. + \meta{code} is also placed inside a group. + % \AdaptNoteName + \command{AdaptNoteName}[\marg{csname}\marg{arguments}\oarg{counter name}\marg{code}] + Like \cs{AdaptNote} but the first argument expects a csname instead of a + command sequence token. + % \MultVariant + \command{MultVariant}[\Marg{\cs*{cs}}] + Defines a command \cs*{multcs} which splits is argument at each occurence + of the token set by the option \option{mult-fn-delim} and turns it into a + series of calls of \cs*{cs}. \cs*{multcs} also has a starred variant in + order to create a series of starred calls of \cs*{cs}. + % \MultVariantName + \command{MultVariantName}[\marg{csname}] + Like \cs{MultVariant} but the argument expects a csname instead of a + command sequence token. + % \AddPunctuation + \command*{AddPunctuation}[\oarg{before}\meta{token}\oarg{after}\marg{name}] + Adds \meta{token} to \fnpct's mechanism and activates it. \meta{before} + sets the default value for the newly created option + \option{before-\meta{name}-space}. \meta{after} sets the default value for + the newly created option \option{after-\meta{name}-space}. This is the + same as using option \option{add-trailing-token}. +\end{commands} + +\fnpct\ adapts \LaTeX's standard footnote commands the following +way\footnote{Using \cs*{@mpfn} as counter name is essential to make ranges + work in minipages.}: +\begin{sourcecode} + \AdaptNote\footnote{o+m}[\@mpfn]{\IfNoValueTF{#1}{#NOTE{#2}}{#NOTE[#1]{#2}}} + \AdaptNote\footnotemark{o}{\IfNoValueTF{#1}{#NOTE}{#NOTE[#1]}} + \MultVariant\footnote + % KOMA-Script's or memoir's \footref: + \AdaptNote\footref{m}{#NOTE{#1}} +\end{sourcecode} +You essentially have to rebuild the syntax of the original command and place +\code{\#NOTE} in the code where it should be called. This may seem cumbersome +at first but allows to adapt commands with a more or less arbitrary kind of +syntax. + +The command \cs{AdaptNote} can be used multiple times on the same command in +order to change a previous redefinition. + +\section{Other packages}\label{sec:other:packages} +\fnpct\ tries its best to support other footnote and related +packages\footnote{If you find some package missing please let me know.}. Each +of the following subsections is dedicated to one of these packages and if and +how they work together with \fnpct. Fortunately most of them do quite well. + +Most notably the \option{ranges} option cannot deal with some packages, often +due to the lack of a suiting \cs*{...text} + +\subsection{bigfoot}\label{sec:bigfoot} +The package \pkg{bigfoot}~\cite{pkg:bigfoot} is supported. + +You need to be a bit cautious, though: \emph{verbatim material won't work + inside footnotes anymore}. You might use \lefloch's \pkg{cprotect} +package~\cite{pkg:cprotect} if you really need verbatim material in footnotes +\emph{and} want to use \fnpct. Since \fnpct\ does not redefine any +\cs{footnotetext} like command it will still work inside one of them. + +\subsection{endnotes}\label{sec:endnotes} +The package \pkg{endnotes}~\cite{pkg:endnotes} is supported. + +\subsection{enotez}\label{sec:enotez} +The package \pkg{enotez}~\cite{pkg:enotez} is supported. + +\subsection{fixfoot}\label{sec:fixfoot} +The \pkg{fixfoot}~\cite{pkg:fixfoot} package provides a possibility to create +repeating footnotes. \fnpct\ supports this package provided you take care of +the following: + +\emph{Use \cs{DeclareFixedFootnote} only in the preamble but \emph{after} + loading \fnpct.} + +\cs*{DeclareFixedFootnote}\Marg{\cs*{cs}}\marg{footnote text} is used to store +the \meta{footnote text} in \cs*{cs} which in turn creates a footnote mark for +it but doesn't repeat the footnote text on the same page in the bottom. The +document needs several runs to get all the numbers and footnotes right. + +Every fixed footnote declared with \cs{DeclareFixedFootnote} gets an optional +\sarg\ to prevent the punctuation switching. + +\noranges{fixfoot} + +\subsection{footmisc}\label{sec:footmisc} +The \pkg{footmisc} package~\cite{pkg:footmisc} provides a range of options to +customize footnotes, for example output them as margin notes or count +footnotes per page. + +Testing showed no incompatibilities with \pkg{footmisc}. The only thing is +that you won't have to (and shouldn't) use its \option{multiple} option. + +\subsection{footnote}\label{sec:footnote} + +Testing showed no incompatibilities with \pkg{footnote}. It cannot adapt its +environment \env*{footnote}, though. + +\subsection{manyfoot}\label{sec:manyfoot} +The package \pkg{manyfoot}~\cite{pkg:manyfoot} is supported. + +\subsection{pagenote}\label{sec:pagenote} +The package \pkg{pagenote}~\cite{pkg:pagenote} is supported. + +\noranges{pagenote} + +\subsection{parnotes}\label{sec:parnotes} +The package \pkg{parnotes}~\cite{pkg:parnotes} is supported. + +\noranges{parnotes} + +\subsection{sepfootnotes}\label{sec:sepfootnotes} +The package \pkg{sepfootnotes}~\cite{pkg:sepfootnotes} is supported. Define +new footnote types \emph{after} \fnpct\ has been loaded. + +\subsection{sidenotes}\label{sec:sidenotes} +\begin{bewareofthedog} + The package \pkg{sidenotes}~\cite{pkg:sidenotes} is \emph{not} supported! +\end{bewareofthedog} +\fnpct\ is not able to adapt \pkg{sidenotes}' commands due to the current +implementation of \pkg{sidenotes}. + +\subsection{snotez}\label{sec:snotez} +The package \pkg{snotes}~\cite{pkg:snotez} is supported. + +\subsection{tablefootnote}\label{sec:tablefootnote} +The package \pkg{tablefootnote}~\cite{pkg:tablefootnote} is supported. + +\noranges{tablefootnote} + +\subsection{tufte-latex's \cs*{sidenote}}\label{sec:tufte} +The \cs*{sidenote} command from the \pkg*{tufte-latex} classes +\cls{tufte-book} and \cls{tufte-handout} is supported. + +\noranges*{tufte-latex} + +More precisely: the \cs*{sidenote} command from \pkg*{tufte-latex} does not +work with \option{ranges}. But since \cs*{sidenote} is only a synonym for +\cs*{footnote} for \pkg*{tufte-latex} you can use the latter. + +\subsection{biblatex's \cs*{footcite}}\label{sec:biblatex} +If you're willing to sacrifice \cs*{footcite}'s \sarg\ argument (which it has +in some styles) you can adapt the commands provided by +\pkg{biblatex}~\cite{pkg:biblatex} as well: +\begin{sourcecode} + \AdaptNote\footcite{oo+m}[footnote]{% + \setfnpct{dont-mess-around}% + \IfNoValueTF{#1} + {#NOTE{#3}} + {\IfNoValueTF{#2}{#NOTE[#1]{#3}}{#NOTE[#1][#2]{#3}}}% + } +\end{sourcecode} +You could use another token for the star, though, if needed: +\begin{sourcecode} + \AdaptNote\footcite{t+oo+m}[footnote]{% + \setfnpct{dont-mess-around}% + \IfBooleanTF{#1}{% + \IfNoValueTF{#2} + {#NOTE{#4}} + {\IfNoValueTF{#3}{#NOTE[#2]{#4}}{#NOTE[#2][#3]{#4}}}% + }{% + \IfNoValueTF{#2} + {#NOTE*{#4}} + {\IfNoValueTF{#3}{#NOTE*[#2]{#4}}{#NOTE*[#2][#3]{#4}}}% + } +\end{sourcecode} +Testing showed no problems whatsoever but \fnpct\ does not adapt the command +itself. + +\begin{bewareofthedog} + Turning \fnpct\ off inside of \cs*{footcite} is advised as shown in above + examples. \cs*{footcite} calls \cs*{footnote} internally which else might + lead to inconsistent and unwanted spaces. +\end{bewareofthedog} + + +\appendix + +\printbibliography + +\end{document} +TODO: +- memoir, \mutfootsep +- \thanks +- French +- nested notes and \AdaptText\footnotetext{om}{\IfNoValueTF{#1}{#NOTE{#2}}{#NOTE[#1]{#2}}} diff --git a/macros/latex/contrib/fnpct/fnpct.sty b/macros/latex/contrib/fnpct/fnpct.sty index bdd63448cd..4485a3bada 100644 --- a/macros/latex/contrib/fnpct/fnpct.sty +++ b/macros/latex/contrib/fnpct/fnpct.sty @@ -5,35 +5,31 @@ % % -------------------------------------------------------------------------- % Clemens Niederberger -% Web: https://bitbucket.org/cgnieder/fnpct/ +% Web: https://github.com/cgnieder/fnpct/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- -% Copyright 2012--2019 Clemens Niederberger +% Copyright 2012--2021 Clemens Niederberger % % This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- -% the package is inspired by the following question on TeX.SE: -% http://tex.stackexchange.com/q/56094/5049 -% -------------------------------------------------------------------------- -\RequirePackage {xparse,l3keys2e,scrlfile} +\RequirePackage {l3keys2e} \ExplSyntaxOn -\tl_const:Nn \c_fnpct_date_tl {2019/10/05} -\tl_const:Nn \c_fnpct_version_major_number_tl {0} -\tl_const:Nn \c_fnpct_version_minor_number_tl {5} +\DeclareHookRule {begindocument} {fnpct} {after} {hyperref} + +\tl_const:Nn \c_fnpct_date_tl {2021/01/21} +\tl_const:Nn \c_fnpct_version_major_number_tl {1} +\tl_const:Nn \c_fnpct_version_minor_number_tl {0} \tl_const:Nn \c_fnpct_version_subrelease_tl {} \tl_const:Nx \c_fnpct_version_number_tl { @@ -54,107 +50,129 @@ {\c_fnpct_info_tl} % -------------------------------------------------------------------------- -% this is plain's \nobreak: -\cs_new:Npn \fnpct_no_break: { \tex_penalty:D 10000 \scan_stop: } - -% -------------------------------------------------------------------------- -% variables: +% scratch variables and variants of kernel functions: \tl_new:N \l__fnpct_tmpa_tl -\tl_new:N \l__fnpct_tmpb_tl -\dim_new:N \l__fnpct_tmpa_dim -\dim_new:N \l__fnpct_tmpb_dim +\seq_new:N \l__fnpct_tmpa_seq -\int_new:N \l__fnpct_tmpa_int +\cs_generate_variant:Nn \tl_remove_all:Nn {NV} +\cs_generate_variant:Nn \prop_item:Nn {NV} +\cs_generate_variant:Nn \prop_get:NnN {NV} +\cs_generate_variant:Nn \prop_put:Nnn {Nx,Nnx,Nxx} +\cs_generate_variant:Nn \seq_put_right:Nn {Nx} +\cs_generate_variant:Nn \seq_set_split:Nnn {NV} +\cs_generate_variant:Nn \regex_replace_all:nnN {nx} +\cs_generate_variant:Nn \str_remove_once:Nn {NV} +\cs_generate_variant:Nn \msg_warning:nnn {nnV} +\cs_generate_variant:Nn \msg_warning:nnnn {nnV} +\cs_generate_variant:Nn \msg_error:nnn {nnV} -\seq_new:N \l__fnpct_tmpa_seq -\seq_new:N \l__fnpct_tmpb_seq - -\dim_new:N \l__fnpct_after_comma_dim -\dim_set:Nn \l__fnpct_after_comma_dim {-.06em} -\dim_new:N \l__fnpct_after_dot_dim -\dim_set:Nn \l__fnpct_after_dot_dim {-.06em} -\dim_new:N \l__fnpct_before_comma_dim -\dim_set:Nn \l__fnpct_before_comma_dim {-.16em} -\dim_new:N \l__fnpct_before_dot_dim -\dim_set:Nn \l__fnpct_before_dot_dim {-.16em} -\dim_new:N \l__fnpct_before_footnote_dim -\dim_set:Nn \l__fnpct_before_footnote_dim {.06em} -\dim_new:N \l__fnpct_normal_mark_width_dim -\dim_set:Nn \l__fnpct_normal_mark_width_dim {1em} -\dim_new:N \l__fnpct_normal_indent_dim -\dim_set:Nn \l__fnpct_normal_indent_dim {1.5em} -\dim_new:N \l__fnpct_normal_parindent_dim -\dim_set:Nn \l__fnpct_normal_parindent_dim {1em} -\dim_new:N \l__fnpct_french_before_footnote_space_dim -\dim_set:Nn \l__fnpct_french_before_footnote_space_dim {.16667em} - -\int_new:N \l__fnpct_multiple_notes_int - -\tl_new:N \l__fnpct_multiple_footnotes_delimiter_tl -\tl_set:Nn \l__fnpct_multiple_footnotes_delimiter_tl {;} -\tl_new:N \l__fnpct_multiple_footnote_separator_tl -\tl_new:N \l__fnpct_last_punct_mark_tl -\tl_new:N \l__fnpct_punctuation_marks_tl -\tl_set:Nn \l__fnpct_punctuation_marks_tl {.,} -\tl_new:N \l__fnpct_multiple_true_tl -\tl_new:N \l__fnpct_multiple_false_tl - -\bool_new:N \l__fnpct_strict_bool -\bool_new:N \l__fnpct_punct_after_bool +\prg_generate_conditional_variant:Nnn \tl_if_eq:nn {v,V} {T,F,TF} + +% -------------------------------------------------------------------------- +% variables +\bool_new:N \l_fnpct_trailing_action_bool +\bool_new:N \l__fnpct_trailing_tokens_bool \bool_new:N \l__fnpct_dont_mess_around_bool -\bool_new:N \l__fnpct_multiple_default_bool -\bool_new:N \l__fnpct_multiple_footnotes_bool -\bool_new:N \l__fnpct_reverse_switch_bool -\bool_new:N \l__fnpct_normal_marks_bool -\bool_new:N \l__fnpct_hyperref_bool -\bool_new:N \g__fnpct_after_punctuation_bool -\bool_new:N \g__fnpct_only_text_bool -\bool_new:N \l__fnpct_makepagenote_bool - -\seq_new:N \l__fnpct_multiple_footnotes_seq +\bool_new:N \l__fnpct_ranges_bool +\bool_new:N \l__fnpct_inside_range_bool +\bool_new:N \l__fnpct_collection_bool +\bool_new:N \l__fnpct_switched_bool +\bool_new:N \l__fnpct_end_collection_bool +\bool_new:N \l__fnpct_automatic_adaption_bool +\bool_new:N \l__fnpct_reverse_bool +\bool_new:N \l__fnpct_keep_ranges_bool +\bool_new:N \g__fnpct_multiple_bool +\bool_new:N \g__fnpct_text_bool +\bool_new:N \l__fnpct_debug_bool + +\tl_new:N \l_fnpct_action_tl +\tl_new:N \l_fnpct_last_action_tl +\tl_new:N \l_fnpct_trailing_token_tl +\tl_new:N \l__fnpct_trailing_tokens_tl +\tl_new:N \l__fnpct_range_tl +\tl_new:N \l__fnpct_separate_tl +\tl_new:N \l__fnpct_multiple_footnotes_delimiter_tl +\tl_set:Nn \l__fnpct_multiple_footnotes_delimiter_tl {;} +\tl_new:N \g__fnpct_this_note_tl + +\prop_new:N \l__fnpct_trailing_tokens_prop +\prop_new:N \l__fnpct_trailing_actions_prop +\prop_new:N \l__fnpct_trailing_classes_prop +\prop_new:N \g__fnpct_actions_prop +\prop_new:N \g__fnpct_action_classes_prop + +\seq_new:N \l__fnpct_trailing_tokens_seq +\seq_new:N \l__fnpct_classes_seq +\seq_new:N \g__fnpct_actions_seq \seq_new:N \l__fnpct_footnote_class_seq +\seq_new:N \l__fnpct_collection_seq +\seq_new:N \g__fnpct_inner_seq +\seq_new:N \l__fnpct_adapted_commands_seq -\prop_new:N \l__fnpct_punctuation_marks_after_prop -\prop_new:N \l__fnpct_punctuation_marks_before_prop -\prop_new:N \l__fnpct_sepfootnote_foot_classes_prop -\prop_new:N \l__fnpct_sepfootnote_end_classes_prop -\prop_new:N \l__fnpct_sepfootnote_symbol_classes_prop -\prop_new:N \g__fnpct_adapted_notes_prop -\prop_new:N \g__fnpct_inner_footnote_prop -\prop_new:N \g__fnpct_inner_footnote_hyperref_prop -\prop_new:N \l__fnpct_footnote_fixfoot_prop +\int_new:N \l__fnpct_collection_int -% -------------------------------------------------------------------------- -% variants: -\cs_generate_variant:Nn \str_remove_once:Nn {NV} -\cs_generate_variant:Nn \tl_remove_all:Nn {NV} -\cs_generate_variant:Nn \tl_put_right:Nn {NV} -\cs_generate_variant:Nn \seq_set_split:Nnn {NnV,NV} -\cs_generate_variant:Nn \prop_gput:Nnn {Nxn,Nxo} -\cs_generate_variant:Nn \prop_put:Nnn {Nnx} -\cs_generate_variant:Nn \prop_if_in:NnTF {Nx} +\dim_new:N \l__fnpct_before_footnote_dim % -------------------------------------------------------------------------- % messages: -\cs_new_protected:Npn \fnpct_dont_mess_around: +\msg_new:nnn {fnpct} {load-time-option} + { + `#1'~ is~ a~ load-time~ option! \\ + You~ cannot~ set~ it~ with~ \token_to_str:N \setfnpct ! \\ + You~ need~ to~ use~ \token_to_str:N \usepackage [#1] {fnpct} . + } + +\msg_new:nnn {fnpct} {unknown-option} + { + Unknown~ option~ `#1'! \\ + I~ don't~ know~ the~ option~ `#1'.~ Please~ make~ sure~ there~ is~ no~ + typo.~ Check~ the~ manual~ for~ help. + } + +\msg_new:nnn {fnpct} {dont-mess-around} + { + All~ right,~ not~ messing~ around.~ :( \\ + I'd~ really~ love~ to,~ though! \\ + https://www.youtube.com/results?search_query=mess+around+ray+charles + } + +\msg_new:nnn {fnpct} {class-not-defined} + { The~ action~ class~ `#1'~ is~ not~ defined~ \msg_line_context: } + +\msg_new:nnn {fnpct} {command-not-adapted} + { The~ command~ `#1'~ doesn't~ seem~ to~ be~ adapted,~ yet,~ \msg_line_context: } + +\msg_new:nnn {fnpct} {cannot-adapt} + { + Due~ to~ the~ implementation~ of~ the~ `#1'~ package~ I~ am~ not~ yet~ + able~ to~ adapt~ its~ commands. + } + +\msg_new:nnn {fnpct} {cannot-adapt-with-ranges} { - \iow_log:n { ................................................. } - \iow_log:n { . ~ fnpct~info: } - \iow_log:n { . } - \iow_log:n { . ~ All~right,~not~messing~around.~:( } - \iow_log:n { . ~ But~I'd~really~love~to. } - \iow_log:n { . ~ (https://www.youtube.com/results?search_query=mess+around+ray+charles) } - \iow_log:n { ................................................. } + Due~ to~ the~ implementation~ of~ the~ `#1'~ package~ I~ am~ not~ yet~ + able~ to~ adapt~ its~ commands~ while~ also~ using~ the~ option~ `ranges~ + =~ true'.~ #2 } -\msg_new:nnn {fnpct} {already-adapted} +\msg_new:nnn {fnpct} {ranges-hyperref} { - The~ command~ \token_to_str:N #1 \c_space_tl has~ already~ been~ - adapted. \\ - I~ will~ do~ nothing~ instead. + Using~ the~ option~ `ranges~ =~ true'~ together~ with~ package~ + `hyperref'~ does~ not~ work~ well.~ Disabling~ ranges.~ If~ you~ insist~ + then~ set~ `keep-ranges~ =~ true'. } +\msg_new:nnn {fnpct} {keep-ranges-hyperref} + { + Using~ the~ option~ `ranges~ =~ true'~ together~ with~ package~ + `hyperref'~ does~ not~ work~ well.~ Keeping~ them~ anyway.~ But~ don't~ + say~ you~ haven't~ been~ warned. + } + +\msg_new:nnn {fnpct} {ranges-disabled} + { Using~ ranges~ is~ disabled~ \msg_line_context: . } + \msg_new:nnn {fnpct} {pagenote} { If~ you~ use~ the~ `pagenote'~ package~ with~ `fnpct'~ please~ make~ sure~ @@ -162,20 +180,64 @@ `fnpct'! } -\msg_new:nnn {fnpct} {deprecated} +\msg_new:nnn {fnpct} {option-deprecated} { - You've~ tried~ setting~ #1~ `#2'~ \msg_line_context: .~ However,~ - #1~ `#2'~ is~ deprecated.~ - \tl_if_blank:nF {#3} {Please~ use~ #1~ `#3'~ instead.~} - Refer~ to~ the~ manual~ for~ details. + The~ option~ `#1'~ is~ deprecated + \tl_if_blank:nF {#2} + { .~ Please~ use~ option~ `#2'~ instead } + \c_space_tl \msg_line_context: . } -\cs_new_protected:Npn \fnpct_message:nx #1#2 +\msg_new:nnn {fnpct} {command-removed} + { The~ command~ #1~ has~ been~ removed~ from~ fnpct. } + +% -------------------------------------------------------------------------- +\cs_new_protected:Npn \__fnpct_loadtime_error:n #1 + { \msg_error:nnV {fnpct} {#1} \l_keys_key_str } + +\cs_new_protected:Npn \__fnpct_loadtime_warning:n #1 + { \msg_warning:nnV {fnpct} {#1} \l_keys_key_str } + +\keys_define:nn {fnpct/package} { - \bool_if:NTF \l__fnpct_strict_bool - { \msg_error:nnx {fnpct} {#1} } - { \msg_warning:nnx {fnpct} {#1} } - {#2} + multiple .bool_gset:N = \g__fnpct_multiple_bool , + multiple .initial:n = false , + debug .bool_gset:N = \g__fnpct_debug_bool , + debug .initial:n = false , + dont-mess-around .choice: , + dont-mess-around / true .code:n = + \bool_set_true:N \l__fnpct_dont_mess_around_bool + \msg_info:nn {fnpct} {dont-mess-around} , + dont-mess-around / false .code:n = + \bool_set_false:N \l__fnpct_dont_mess_around_bool , + dont-mess-around .default:n = true , + dont-mess-around .initial:n = false , + unknown .code:n = + \__fnpct_loadtime_warning:n {unknown-option} + } + +\ProcessKeysPackageOptions {fnpct/package} + +\keys_define:nn {fnpct/package} + { + multiple .code:n = \__fnpct_loadtime_error:n {load-time-option} , + debug .code:n = \__fnpct_loadtime_error:n {load-time-option} , + dont-mess-around .code:n = \__fnpct_loadtime_error:n {load-time-option} + } + +% -------------------------------------------------------------------------- +\prg_new_conditional:Npnn \fnpct_if_multiple: {T,F,TF} + { + \bool_if:NTF \g__fnpct_multiple_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \fnpct_if_debug: {T,F,TF} + { + \bool_if:NTF \g__fnpct_debug_bool + { \prg_return_true: } + { \prg_return_false: } } % -------------------------------------------------------------------------- @@ -186,979 +248,1098 @@ { \prg_return_false: } } -% -------------------------------------------------------------------------- -% multiple footnote input and output variables: -% check for KOMA-Script's \multfootsep: -\cs_if_exist:NTF \KOMAClassName - { \tl_set:Nn \l__fnpct_multiple_footnote_separator_tl { \multfootsep } } - { \tl_set:Nn \l__fnpct_multiple_footnote_separator_tl {,} } +\prg_new_conditional:Npnn \fnpct_if_class_loaded:n #1 {p,T,F,TF} + { + \@ifclassloaded {#1} + { \prg_return_true: } + { \prg_return_false: } + } % -------------------------------------------------------------------------- -% #1: before/after -% #2: punctuation mark -% #3: dimension -\cs_new_protected:Npn \fnpct_set_punctuation_dim:nnn #1#2#3 +% #1: cs +\prg_new_conditional:Npnn \fnpct_if_adapted:N #1 {T,F,TF} { - \prop_put:cnx { l__fnpct_punctuation_marks_#1_prop } - {#2} - { \dim_eval:n {#3} } + \seq_if_in:NnTF \l__fnpct_adapted_commands_seq {#1} + { \prg_return_true: } + { \prg_return_false: } } -\cs_generate_variant:Nn \fnpct_set_punctuation_dim:nnn {nV} -\fnpct_set_punctuation_dim:nnn {after} {.} { \l__fnpct_after_dot_dim } -\fnpct_set_punctuation_dim:nnn {after} {,} { \l__fnpct_after_comma_dim } -\fnpct_set_punctuation_dim:nnn {before} {.} { \l__fnpct_before_dot_dim } -\fnpct_set_punctuation_dim:nnn {before} {,} { \l__fnpct_before_comma_dim } +\prg_generate_conditional_variant:Nnn \fnpct_if_adapted:N {c} {T,F,TF} -\cs_new_protected:Npn \fnpct_rm_punctuation:n #1 +% -------------------------------------------------------------------------- +\cs_new_protected:Npn \fnpct_nobreak: { \tex_penalty:D 10000 \scan_stop: } +\cs_new_protected:Npn \fnpct_skip_nobreak:N #1 { - \tl_remove_all:Nn \l__fnpct_punctuation_marks_tl {#1} - \prop_del:Nn \l__fnpct_punctuation_marks_after_prop {#1} - \prop_del:Nn \l__fnpct_punctuation_marks_before_prop {#1} + \fnpct_nobreak: + \skip_horizontal:N #1 + \fnpct_nobreak: } +\cs_generate_variant:Nn \fnpct_skip_nobreak:N {c} -\cs_new_protected:Npn \fnpct_add_punctuation:n #1 - { \__fnpct_add_punctuation:w #1 [ \q_no_value ] \q_no_value \q_stop } -\cs_generate_variant:Nn \fnpct_add_punctuation:n {V} +% -------------------------------------------------------------------------- +% checking for trailing tokens - reuse an idea from acro +% #1: name +\cs_new_protected:Npn \fnpct_new_class:n #1 + { + \seq_put_right:Nn \l__fnpct_classes_seq {#1} + \seq_new:c {g__fnpct_class_#1_seq} + } -\cs_new_protected:Npn \__fnpct_add_punctuation:w #1[#2]#3 \q_stop +\prg_new_conditional:Npnn \fnpct_class_if_exist:n #1 {p,T,F,TF} { - \quark_if_no_value:nTF {#2} - { - % there is no option at all - \tl_map_inline:nn {#1} - { - \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {##1} - \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt} - \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} - \tl_set:No \l__fnpct_last_punct_mark_tl {##1} - } - } + \seq_if_in:NnTF \l__fnpct_classes_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } + +% #1: name +% #2: code +\cs_new_protected:Npn \fnpct_do_action:nnw #1#2 \fnpct_end: + { + \prop_if_in:NnTF \g__fnpct_actions_prop {#1} + { \fnpct_end: \prop_item:Nn \g__fnpct_actions_prop {#1} } + { \fnpct_end: \use:n } + {#2} + } +\cs_generate_variant:Nn \fnpct_do_action:nnw {V} + +% #1: name +% #2: class +% #3: default before dim +% #4: default after dim +% #5: code requiring two n-type arguments (code and token) +\cs_new_protected:Npn \fnpct_new_action:nnnnn #1#2#3#4#5 + { + \fnpct_class_if_exist:nTF {#2} { - \tl_if_blank:nTF {#1} - { - % #2 is a second option (= before space) - \fnpct_set_punctuation_dim:nVn {before} - \l__fnpct_last_punct_mark_tl - {#2} - } + \seq_if_in:NnTF \g__fnpct_actions_seq {#1} { - % #2 is a first option (= after space), #1 might be more than one token: - \tl_if_single_token:nTF {#1} + \keys_set:nn {fnpct} { - \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {#1} - \fnpct_set_punctuation_dim:nnn {after} {#1} {#2} - \fnpct_set_punctuation_dim:nnn {before} {#1} {0pt} - \tl_set:No \l__fnpct_last_punct_mark_tl {#1} - } - { - \int_zero:N \l__fnpct_tmpa_int - \tl_map_inline:nn {#1} - { - \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {##1} - \int_compare:nTF { \l__fnpct_tmpa_int < ( \tl_count:n {#1} - 1 ) } - { - \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt} - \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} - } - { - \fnpct_set_punctuation_dim:nnn {after} {##1} {#2} - \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} - } - \tl_set:No \l__fnpct_last_punct_mark_tl {##1} - \int_incr:N \l__fnpct_tmpa_int - } + before-#1-space = #3 , + after-#1-space = #4 } } - } - % is there more? - \tl_if_eq:nnF {#3} { [\q_no_value]\q_no_value } - { - \quark_if_no_value:nF {#3} { - \tl_set:Nn \l__fnpct_tmpa_tl {#3} - \tl_remove_all:Nn \l__fnpct_tmpa_tl { [\q_no_value]\q_no_value } - \fnpct_add_punctuation:V \l__fnpct_tmpa_tl + \seq_gput_right:Nn \g__fnpct_actions_seq {#1} + \prop_gput:Nnn \g__fnpct_action_classes_prop {#1} {#2} + \prop_gput:Nnn \g__fnpct_actions_prop {#1} {#5} + \seq_gput_right:cn {g__fnpct_class_#2_seq} {#1} + \dim_new:c {l__fnpct_before_#1_dim} + \dim_new:c {l__fnpct_after_#1_dim} + \keys_define:nn {fnpct} + { + before-#1-space .dim_set:c = {l__fnpct_before_#1_dim} , + before-#1-space .initial:n = #3 , + after-#1-space .dim_set:c = {l__fnpct_after_#1_dim} , + after-#1-space .initial:n = #4 + } } } + { \msg_error:nnn {fnpct} {class-not-defined} {#2} } } -% -------------------------------------------------------------------------- -% options: -\keys_define:nn {fnpct} +\prg_new_conditional:Npnn \fnpct_action_if_exist:n #1 {p,T,F,TF} { - bigfoot-default-top .code:n = - \msg_warning:nnnn {fnpct} {deprecated} {option} {bigfoot-default-top} , - strict .bool_set:N = \l__fnpct_strict_bool , - after-comma-space .code:n = - \fnpct_set_punctuation_dim:nnn {after} {,} {#1} , - after-dot-space .code:n = - \fnpct_set_punctuation_dim:nnn {after} {.} {#1} , - before-comma-space .code:n = - \fnpct_set_punctuation_dim:nnn {before} {,} {#1} , - before-dot-space .code:n = - \fnpct_set_punctuation_dim:nnn {before} {.} {#1} , - after-punct-space .code:n = - \prop_map_inline:Nn \l__fnpct_punctuation_marks_after_prop - { \fnpct_set_punctuation_dim:nnn {after} {##1} {#1} } , - before-punct-space .code:n = - \prop_map_inline:Nn \l__fnpct_punctuation_marks_before_prop - { \fnpct_set_punctuation_dim:nnn {before} {##1} {#1} } , - before-footnote-space .dim_set:N = \l__fnpct_before_footnote_dim , - french-before-footnote-space .dim_set:N = - \l__fnpct_french_before_footnote_space_dim , - punct-after .bool_set:N = \l__fnpct_punct_after_bool , - dont-mess-around .code:n = - \prop_map_inline:Nn \l__fnpct_punctuation_marks_after_prop - { \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt} } - \prop_map_inline:Nn \l__fnpct_punctuation_marks_before_prop - { \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} } - \dim_zero:N \l__fnpct_before_footnote_dim - \bool_set_true:N \l__fnpct_punct_after_bool - \bool_set_true:N \l__fnpct_dont_mess_around_bool - \fnpct_dont_mess_around: , - mult-fn-delim .tl_set:N = \l__fnpct_multiple_footnotes_delimiter_tl , - mult-fn-sep .tl_set:N = \l__fnpct_multiple_footnote_separator_tl , - multiple .bool_set:N = \l__fnpct_multiple_default_bool , - normal-marks .bool_set:N = \l__fnpct_normal_marks_bool , - normal-mark-width .dim_set:N = \l__fnpct_normal_mark_width_dim , - normal-indent .dim_set:N = \l__fnpct_normal_indent_dim , - normal-parindent .dim_set:N = \l__fnpct_normal_parindent_dim , - verb-format .tl_set:N = \l__fnpct_verbatim_format_tl , - add-punct-marks .code:n = \fnpct_add_punctuation:n {#1} , - remove-punct-marks .code:n = - \tl_map_function:nN {#1} \fnpct_rm_punctuation:n - } - -\ProcessKeysOptions {fnpct} + \seq_if_in:NnTF \g__fnpct_actions_seq {#1} + { \prg_return_true: } + { \prg_return_false: } + } -% -------------------------------------------------------------------------- -% MAIN INTERNAL FOOTNOTE FUNCTION: -% write the notes: -\cs_new:Npn \__fnpct_no_value_or_quark_no_value:nTF #1#2#3 +% register a new token but don't activate its action: +% #1: token +% #2: action +\cs_new_protected:Npn \fnpct_new_trailing_token:Nn #1#2 { - \IfNoValueTF {#1} {#2} - { \quark_if_no_value:nTF {#1} {#2} {#3} } + \prop_put:Nnn \l__fnpct_trailing_tokens_prop {#1} {#1} + \prop_put:Nnn \l__fnpct_trailing_actions_prop {#1} {#2} + \prop_put:Nnx \l__fnpct_trailing_classes_prop {#1} + { \prop_item:Nn \g__fnpct_action_classes_prop {#2} } + \seq_put_right:Nn \l__fnpct_trailing_tokens_seq {#1} } -\cs_new:Npn \fnpct_write_note:Nnnn #1#2#3#4 +% #1: class +% #2: code where `#1' refers to the action name +\cs_new:Npn \fnpct_foreach_action:nn #1#2 { - \__fnpct_no_value_or_quark_no_value:nTF {#2} - { #1 {#4} } - { - \__fnpct_no_value_or_quark_no_value:nTF {#3} - { #1 [#2] {#4} } - { #1 [#2] [#3] {#4} } - } + \fnpct_class_if_exist:nT {#1} + { \seq_map_inline:cn {g__fnpct_class_#1_seq} {#2} } } -% check for punctuation: -\cs_new_protected:Npn \fnpct_check_punctuation:TF #1#2 - { \__fnpct_check_punctuation:nTF {0} {#1} {#2} } +\cs_new_eq:NN \fnpct_action_break: \seq_map_break: -\cs_new_protected:Npn \__fnpct_check_punctuation:nTF #1#2#3 +% #1: token +\cs_new_protected:Npn \fnpct_remove_trailing_token:N #1 { - \__fnpct_get_head:NN - \l__fnpct_current_punct_mark_tl - \l__fnpct_punctuation_marks_tl - \exp_args:NV \peek_meaning_remove:NTF \l__fnpct_current_punct_mark_tl - {#2} - { - \__fnpct_check_punctuation_aux:nnn {#1} - { \__fnpct_check_punctuation:VTF \l__fnpct_tmpa_int {#2} {#3} } - {#3} - } + \seq_remove_all:Nn \l__fnpct_trailing_tokens_seq {#1} + \prop_remove:Nn \l__fnpct_trailing_tokens_prop {#1} + \prop_remove:Nn \l__fnpct_trailing_actions_prop {#1} + \prop_remove:Nn \l__fnpct_trailing_classes_prop {#1} } -\cs_new_protected:Npn \__fnpct_check_punctuation_aux:nnn #1#2#3 +\cs_new_protected:Npn \fnpct_for_all_trailing_tokens_do:n #1 + { \seq_map_inline:Nn \l__fnpct_trailing_tokens_seq {#1} } + +% activate a token: +\cs_new_protected:Npn \fnpct_activate_trailing_token:n #1 { - \int_set:Nn \l__fnpct_tmpa_int {#1} - \int_incr:N \l__fnpct_tmpa_int - \tl_set:Nx \l__fnpct_tmpb_tl { \int_to_arabic:n { \l__fnpct_tmpa_int } } - \tl_remove_all:NV \l__fnpct_punctuation_marks_tl - \l__fnpct_current_punct_mark_tl - \tl_put_right:NV \l__fnpct_punctuation_marks_tl - \l__fnpct_current_punct_mark_tl - \int_compare:nTF { \l__fnpct_tmpa_int < \tl_count:V \l__fnpct_punctuation_marks_tl } - {#2} - {#3} + \prop_get:NnN \l__fnpct_trailing_tokens_prop {#1} \l__fnpct_tmpa_tl + \tl_put_right:NV \l__fnpct_trailing_tokens_tl \l__fnpct_tmpa_tl } -\cs_generate_variant:Nn \__fnpct_check_punctuation:nTF {V} - -\cs_new_protected:Npn \__fnpct_get_head:NN #1#2 - { \tl_set:Nx #1 { \tl_head:V #2 } } -% check for multiple notes: -\cs_new_protected:Npn \fnpct_check_multiple:TF #1#2 +% deactivate a token: +\cs_new_protected:Npn \fnpct_deactivate_trailing_token:n #1 { - \tl_set:Nn \l__fnpct_multiple_true_tl {#1} - \tl_set:Nn \l__fnpct_multiple_false_tl {#2} - \bool_gset_false:N \g__fnpct_after_punctuation_bool - \peek_after:Nw \__fnpct_check_multiple: + \prop_get:NnN \l__fnpct_trailing_tokens_prop {#1} \l__fnpct_tmpa_tl + \tl_remove_all:NV \l__fnpct_trailing_tokens_tl \l__fnpct_tmpa_tl } -\cs_new_protected:Npn \__fnpct_check_multiple: +% #1: tokenlist +\prg_new_protected_conditional:Npnn \fnpct_if_trailing_tokens:n #1 {T,F,TF} { - \prop_map_inline:Nn \g__fnpct_adapted_notes_prop + \bool_set_false:N \l__fnpct_trailing_tokens_bool + \tl_map_inline:nn {#1} { - \tl_set_rescan:Nnn \l__fnpct_tmpb_tl {} {##1} - \exp_args:NV - \token_if_eq_meaning:NNTF \l__fnpct_tmpb_tl \l_peek_token + \bool_if:cT {l__fnpct_trailing_##1_bool} { - \bool_set_true:N \l__fnpct_multiple_footnotes_bool - \prop_map_break: + \bool_set_true:N \l__fnpct_trailing_tokens_bool + \tl_map_break: } - { \bool_set_false:N \l__fnpct_multiple_footnotes_bool } - } - \bool_if:NTF \l__fnpct_multiple_footnotes_bool - { \tl_use:N \l__fnpct_multiple_true_tl } - { \tl_use:N \l__fnpct_multiple_false_tl } - } - -% check which mode is active: -\prg_new_conditional:Npnn \fnpct_punct_if_after: {T,TF} - { - \bool_if:nTF - { - \bool_xor_p:nn - { \l__fnpct_punct_after_bool } - { \l__fnpct_reverse_switch_bool } } + \bool_if:NTF \l__fnpct_trailing_tokens_bool { \prg_return_true: } { \prg_return_false: } } -% this is where the magic happens: -\cs_new_protected:Npn \fnpct_handle_punctuation:n #1 +% -------------------------------------------------------------------------- +% #1: token +\prg_new_protected_conditional:Npnn \__fnpct_check_trail:N #1 {T,F,TF} { - \fnpct_check_punctuation:TF - { - % this is need as some commands like biblatex's \autocite may in turn - % call \footnote. It then must not insert the pre-footnote-space: - \bool_gset_true:N \g__fnpct_after_punctuation_bool - % A: after=1 && reverse=0 - % after=0 && reverse=1 - % B: after=1 && reverse=1 - % after=0 && reverse=0 - \fnpct_punct_if_after:TF - { - \fnpct_no_break: - \skip_horizontal:N \l__fnpct_before_footnote_dim - } - { - \tl_use:N \l__fnpct_current_punct_mark_tl - \prop_get:NVNT \l__fnpct_punctuation_marks_after_prop - \l__fnpct_current_punct_mark_tl - \l__fnpct_tmpa_tl - { - \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } - \fnpct_no_break: - \skip_horizontal:N \l__fnpct_tmpa_dim - \fnpct_no_break: - \skip_horizontal:N \c_zero_skip - \fnpct_no_break: - } - } - #1 - \bool_gset_false:N \g__fnpct_after_punctuation_bool - \fnpct_punct_if_after:T - { - \fnpct_no_break: - \prop_get:NVNT \l__fnpct_punctuation_marks_before_prop - \l__fnpct_current_punct_mark_tl - \l__fnpct_tmpa_tl - { - \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } - \fnpct_no_break: - \skip_horizontal:N \l__fnpct_tmpa_dim - \fnpct_no_break: - \skip_horizontal:N \c_zero_skip - \fnpct_no_break: - } - \tl_use:N \l__fnpct_current_punct_mark_tl - } - \bool_set_false:N \l__fnpct_reverse_switch_bool - } + \bool_set_false:N \l_fnpct_trailing_action_bool + \tl_clear:N \l_fnpct_trailing_token_tl + \bool_if:NTF \l__fnpct_dont_mess_around_bool + { \prg_return_false: } { - % what about multiple footnotes? (their usage is discouraged with - % this package, but anyway...) - % this check should probably/maybe be removed (?!) - \fnpct_check_multiple:TF - { - \bool_set_true:N \l__fnpct_multiple_footnotes_bool - \fnpct_no_break: - \bool_if:NF \g__fnpct_after_punctuation_bool - { \skip_horizontal:N \l__fnpct_before_footnote_dim } - #1 - \fnpct_no_break: - \textsuperscript { \l__fnpct_multiple_footnote_separator_tl } - } + \tl_if_empty:NTF \l__fnpct_trailing_tokens_tl + { \prg_return_false: } { - % else insert space and then note - \bool_if:NTF \l__fnpct_multiple_footnotes_bool - { \bool_set_false:N \l__fnpct_multiple_footnotes_bool } + \tl_map_inline:Nn \l__fnpct_trailing_tokens_tl { - \fnpct_no_break: - \bool_if:NF \g__fnpct_after_punctuation_bool - { \skip_horizontal:N \l__fnpct_before_footnote_dim } + \token_if_eq_meaning:NNT #1 ##1 + { + \bool_set_true:N \l_fnpct_trailing_action_bool + \tl_set:Nn \l_fnpct_trailing_token_tl {##1} + \tl_map_break: + } } - #1 - \bool_set_false:N \l__fnpct_reverse_switch_bool + \bool_if:NTF \l_fnpct_trailing_action_bool + { \prg_return_true: } + { \prg_return_false: } } } } - -% #1: original command -% #2: optional argument of original command -% #3: second optional argument of original command -% #4: mandatory argument of original command -% #5: boolean flag for starred version -\cs_new_protected:Npn \fnpct_handle_note:Nnnnn #1#2#3#4#5 +% #1: class name +\prg_new_protected_conditional:Npnn \fnpct_if_class:n #1 {T,F,TF} { - % if a punctuation mark follows remove it, insert dot, skip back - % and then insert footnote - \bool_if:NF \l__fnpct_dont_mess_around_bool + \bool_if:NTF \l_fnpct_trailing_action_bool { - \IfBooleanT {#5} - { \bool_set_true:N \l__fnpct_reverse_switch_bool } - } - \fnpct_handle_punctuation:n - { - \fnpct_write_note:Nnnn #1 {#2} {#3} {#4} - \fnpct_write_inner:N #1 + \prop_get:NVN \l__fnpct_trailing_classes_prop + \l_fnpct_trailing_token_tl + \l__fnpct_tmpa_tl + \tl_if_eq:VnTF \l__fnpct_tmpa_tl {#1} + { \prg_return_true: } + { \prg_return_false: } } + { \prg_return_false: } } -\cs_generate_variant:Nn \fnpct_handle_note:Nnnnn { cnnnn } -% -------------------------------------------------------------------------- -% MULTIPLE FOOTNOTES -% #1: original note command -% #2: star -% #3: multiple notes separated by \l__fnpct_multiple_footnotes_delimiter_tl -\cs_new_protected:Npn \fnpct_mult_note:Nnn #1#2#3 +% #1: action name +\prg_new_protected_conditional:Npnn \fnpct_if_action:n #1 {T,F,TF} { - \bool_if:NF \l__fnpct_dont_mess_around_bool + \bool_if:NTF \l_fnpct_trailing_action_bool { - \IfBooleanT {#2} - { \bool_set_true:N \l__fnpct_reverse_switch_bool } + \prop_get:NVN \l__fnpct_trailing_actions_prop + \l_fnpct_trailing_token_tl + \l__fnpct_tmpa_tl + \tl_if_eq:VnTF \l__fnpct_tmpa_tl {#1} + { \prg_return_true: } + { \prg_return_false: } } - % split input: - \seq_set_split:NVn \l__fnpct_multiple_footnotes_seq - \l__fnpct_multiple_footnotes_delimiter_tl - {#3} - \fnpct_handle_punctuation:n - { \fnpct_write_notes:NN #1 \l__fnpct_multiple_footnotes_seq } - + { \prg_return_false: } } -\cs_generate_variant:Nn \fnpct_mult_note:Nnn {cnn} -% #1: original note command -% #2: sequence variable holding the note arguments -\cs_new_protected:Npn \fnpct_write_notes:NN #1#2 - { - \int_zero:N \l__fnpct_multiple_notes_int - \seq_map_inline:Nn #2 - { - \__fnpct_read_note_with_option:w ##1 \q_stop {#1} - \int_incr:N \l__fnpct_multiple_notes_int - } - } +% -------------------------------------------------------------------------- +% saving and using the note commands: +\cs_new:Npn \__fnpct_remove_backslash:N #1 + { \exp_after:wN \use_none:n \token_to_str:N #1 } -% this shouldn't be a document command but is a really easy way to make -% biblatex's \footcite et.al. compatible with the `multiple' option -% #1: optional star => only invoke \footnotetext -% #2: optional argument to original note command -% #3: second optional argument to original note command -% #4: mandatory argument to original note command -% #5: original note command -\NewDocumentCommand \__fnpct_read_note_with_option:w { soo+u{\q_stop}m } +% this is dangerous - it relies on undocumented innards of xparse - however, +% it should probably be rather safe, anyway: +\cs_new_protected:Npn \fnpct_save_note_command:N #1 { - \bool_if:nT - { - \int_compare_p:n { \l__fnpct_multiple_notes_int > 0 } - && - \int_compare_p:n - { - \l__fnpct_multiple_notes_int - < - \seq_count:N \l__fnpct_multiple_footnotes_seq - } - } - { - \IfBooleanTF {#1} - { \tex_unskip:D } - { \textsuperscript { \l__fnpct_multiple_footnote_separator_tl } } + \cs_undefine:c {fnpct_original_ \__fnpct_remove_backslash:N #1 :w} + \cs_if_exist:cTF { \__fnpct_remove_backslash:N #1 ~ code } + {% xparse command + \cs_new_eq:cc + { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } + { \__fnpct_remove_backslash:N #1 ~ code } } - \IfBooleanTF {#1} { - % TODO: maybe provide option to change \footnotetext? Or do it - % automatically? - \bool_gset_true:N \g__fnpct_only_text_bool - \IfNoValueTF {#2} - { \footnotetext {#4} } - { \footnotetext [#2] {#4} } + \cs_if_exist:cTF { \__fnpct_remove_backslash:N #1 ~ } + {% robust command + \cs_new_eq:cc + { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } + { \__fnpct_remove_backslash:N #1 ~ } + } + { \cs_new_eq:cN { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } #1 } } - { \fnpct_write_note:Nnnn #5 {#2} {#3} {#4} } - \fnpct_write_inner:N #5 + \seq_put_right:Nn \l__fnpct_adapted_commands_seq {#1} + \fnpct_set_counter_name:Nx #1 { \__fnpct_remove_backslash:N #1 } } -% -------------------------------------------------------------------------- -% NESTED FOOTNOTES: -% 1 layer of nesting... -% this shouldn't be a document command! But for the time being I'll stick to -% this easy solution... -\NewDocumentCommand \fnpct_inner_footnote:w {o+m} +\cs_new_protected:Npn \fnpct_set_counter_name:Nn #1#2 + { \cs_set:cpn { fnpct_ \__fnpct_remove_backslash:N #1 _counter: } {#2} } +\cs_generate_variant:Nn \fnpct_set_counter_name:Nn {c,Nx} + +\cs_new:Npn \__fnpct_counter:N #1 + { \use:c { fnpct_ \__fnpct_remove_backslash:N #1 _counter: } } + +\hook_new:n {fnpct/rangesetup} + +\cs_new_protected:Npn \fnpct_use_note_command:N #1 { - \IfNoValueTF {#1} + \fnpct_if_debug:T + { \iow_term:x { fnpct~ info:~ \exp_not:N #1 \msg_line_context:} } + \tl_gset:Nx \g__fnpct_this_note_tl { \__fnpct_remove_backslash:N #1 } + \cs_if_exist:cTF {fnpct_original_ \__fnpct_remove_backslash:N #1 :w} { - % TODO: maybe detect what type of note we're in and use the appropriate mark? - % Or provide a user interface to choose the appropriate mark? - \fnpct_orig_footnotemark:w - \prop_gput:Nxn \g__fnpct_inner_footnote_prop { \thefootnote } {#2} - \bool_if:NT \l__fnpct_hyperref_bool + \fnpct_inside_range:TF { - \prop_gput:Nxo \g__fnpct_inner_footnote_hyperref_prop - { \thefootnote } { \Hy@footnote@currentHref } + \refstepcounter { \__fnpct_counter:N #1 } + \tl_set_eq:NN \l__fnpct_current_tl #1 + \hook_use:n {fnpct/rangesetup} + \use:c { \__fnpct_remove_backslash:N #1 text } } + { \use:c {fnpct_original_ \__fnpct_remove_backslash:N #1 :w} } } + { \msg_error:nnn {fnpct} {command-not-adapted} {#1} } + } +\cs_generate_variant:Nn \fnpct_use_note_command:N {c} + +\prg_new_conditional:Npnn \fnpct_if_current:N #1 {T,F,TF} + { + \tl_if_eq:NNTF \l__fnpct_current_tl #1 + { \prg_return_true: } + { \prg_return_false: } + } +\prg_generate_conditional_variant:Nnn \fnpct_if_current:N {c} {T} + +% -------------------------------------------------------------------------- +% action macros +\prg_new_conditional:Npnn \fnpct_if_collection: {p,T,F,TF} + { + \bool_if:NTF \l__fnpct_collection_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \fnpct_if_ranges: {T,F,TF} + { + \bool_if:NTF \l__fnpct_ranges_bool + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \fnpct_inside_range: {T,F,TF} + { + \bool_if:NTF \l__fnpct_inside_range_bool + { \prg_return_true: } + { \prg_return_false: } + } + +% swapping: +% #1: all the new footnote code, arguments already read +% #2: the trailing punctuation +\cs_new_protected:Npn \fnpct_swap:nn #1#2 + { + \fnpct_if_collection:TF { - \fnpct_orig_footnotemark:w [#1] - \prop_gput:Nnn \g__fnpct_inner_footnote_prop {#1} {#2} - \bool_if:NT \l__fnpct_hyperref_bool + \__fnpct_swap:nn { - \prop_gput:Nno \g__fnpct_inner_footnote_hyperref_prop - {#1} { \Hy@footnote@currentHref } + \fnpct_before: + \fnpct_print_collection: + \fnpct_print_note:w #1 + \fnpct_after: } + {#2} } + { \__fnpct_swap:nn {#1} {#2} } } -\cs_new_protected:Npn \fnpct_write_inner:N #1 +\cs_new_protected:Npn \__fnpct_swap:nn #1#2 { - \token_if_eq_meaning:NNF #1 \fnpct_inner_footnote:w + \fnpct_if_switched:TF { - \prop_map_inline:Nn \g__fnpct_inner_footnote_prop - { - \footnotetext [##1] - { - \bool_if:NT \l__fnpct_hyperref_bool - { - \prop_get:NnN \g__fnpct_inner_footnote_hyperref_prop - {##1} \l__fnpct_tmpa_tl - \Hy@raisedlink - { \exp_args:NV \hyper@@anchor \l__fnpct_tmpa_tl } - } - ##2 - } - } - \prop_gclear:N \g__fnpct_inner_footnote_prop + \use:nn + { \fnpct_skip_nobreak:N \l__fnpct_before_footnote_dim #1 } + { \fnpct_add_punctuation_space:n {before} #2 } } + { \use_ii_i:nn {#1} {#2} } } -\NewDocumentCommand \writeinnernotes {} - { \fnpct_write_inner:N X } +\cs_new:Npn \fnpct_print_note:w \fnpct_before: #1 \fnpct_after: +{ \exp_not:n { #1 } } -% -------------------------------------------------------------------------- -% MANUAL KERNING: -\cs_new_protected:Npn \fnpct_kfp: +% multiple footnotes and ranges: +\cs_new_protected:Npn \__fnpct_collect:n #1 { - \fnpct_no_break: - \prop_get:NnNT \l__fnpct_punctuation_marks_before_prop {.} - \l__fnpct_tmpa_tl - { \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } } - \prop_get:NnNT \l__fnpct_punctuation_marks_after_prop {.} - \l__fnpct_tmpb_tl - { \dim_set:Nn \l__fnpct_tmpb_dim { \l__fnpct_tmpb_tl } } - \bool_if:NTF \l__fnpct_punct_after_bool - { \skip_horizontal:N \l__fnpct_tmpa_dim } - { \skip_horizontal:N \l__fnpct_tmpb_dim } + \int_incr:N \l__fnpct_collection_int + \seq_put_right:Nx \l__fnpct_collection_seq { \fnpct_print_note:w #1 } } -\cs_new_protected:Npn \fnpct_kfc: +% #1: all the new footnote code, arguments already read +% #2: e.g. the token \footnote +\cs_new_protected:Npn \fnpct_collect:nn #1#2 { - \fnpct_no_break: - \prop_get:NnNT \l__fnpct_punctuation_marks_before_prop {,} - \l__fnpct_tmpa_tl - { \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } } - \prop_get:NnNT \l__fnpct_punctuation_marks_after_prop {,} - \l__fnpct_tmpb_tl - { \dim_set:Nn \l__fnpct_tmpb_dim { \l__fnpct_tmpb_tl } } - \bool_if:NTF \l__fnpct_punct_after_bool - { \skip_horizontal:N \l__fnpct_tmpa_dim } - { \skip_horizontal:N \l__fnpct_tmpb_dim } + \fnpct_if_collection:F + { + % we're starting a collection + \seq_clear:N \l__fnpct_collection_seq + \int_set:Nn \l__fnpct_collection_int {1} + \bool_set_true:N \l__fnpct_collection_bool + } + \__fnpct_collect:n {#1} + #2 } -\NewDocumentCommand \kfp {} { \fnpct_kfp: } -\NewDocumentCommand \kfc {} { \fnpct_kfc: } - -% -------------------------------------------------------------------------- -% NORMAL MARKS: -\AtBeginDocument +\cs_new_protected:Npn \fnpct_print_collection: { - \bool_if:NT \l__fnpct_normal_marks_bool + \bool_set_false:N \l__fnpct_collection_bool + \bool_set_true:N \l__fnpct_end_collection_bool + % DEBUG: + \fnpct_if_ranges:TF { - \cs_if_exist:NF \KOMAoption - { \RequirePackage { scrextend } } - \deffootnote - [ \l__fnpct_normal_mark_width_dim ] - { \l__fnpct_normal_indent_dim } - { \l__fnpct_normal_parindent_dim } - { \thefootnotemark . \enskip } + \seq_item:Nn \l__fnpct_collection_seq {1} + \seq_pop_left:NN \l__fnpct_collection_seq \l__fnpct_tmpa_tl + \tl_clear:N \l__fnpct_tmpa_tl + \bool_set_true:N \l__fnpct_inside_range_bool + \seq_use:Nn \l__fnpct_collection_seq { } + \bool_set_false:N \l__fnpct_inside_range_bool + \int_compare:nNnTF \l__fnpct_collection_int = {2} + { \__fnpct_separate: } + { \l__fnpct_range_tl } } + { + \seq_use:Nn \l__fnpct_collection_seq { \__fnpct_separate: } + \__fnpct_separate: + } + } + +\cs_new_protected:Npn \__fnpct_separate: + { + \bool_if:NTF \g__fnpct_text_bool + { \bool_gset_false:N \g__fnpct_text_bool } + { \l__fnpct_separate_tl } + } + +% -------------------------------------------------------------------------- +% define some classes and actions: +\fnpct_new_class:n {punctuation} +\fnpct_new_class:n {note} + +\fnpct_new_action:nnnnn {dot} {punctuation} {-.16em} {-0.06em} { \fnpct_swap:nn } +\fnpct_new_action:nnnnn {comma} {punctuation} {-.16em} {-0.06em} { \fnpct_swap:nn } +\fnpct_new_action:nnnnn {collect} {note} {0pt} {0pt} { \fnpct_collect:nn } + +\fnpct_new_trailing_token:Nn . {dot} +\fnpct_new_trailing_token:Nn , {comma} + +% #1: default before dim +% #2: token +% #3: default after dim +% #4: name +\NewDocumentCommand \AddPunctuation {O{0pt}mO{0pt}m} + { + \fnpct_new_action:nnnnn {#4} {punctuation} {#1} {#3} { \fnpct_swap:nn } + \fnpct_new_trailing_token:Nn #2 {#4} + \keys_set:nn {fnpct} { activate-trailing-tokens = #2 } } % -------------------------------------------------------------------------- -% LET'S MAKE IT EASIER TO ADAPT EXISTING FUNCTIONS: -% COPY, RENEW AND CREATE MULT +% build up the frame for the adapted note commands: -\prg_new_conditional:Npnn \fnpct_if_adapted:N #1 {p,T,F,TF} +\prg_new_conditional:Npnn \fnpct_if_switched: {p,T,F,TF} { - \prop_if_in:NnTF \g__fnpct_adapted_notes_prop {#1} + \bool_if:NTF \l__fnpct_switched_bool { \prg_return_true: } { \prg_return_false: } } -\cs_new_protected:Npn \fnpct_add_to_adapted:NN #1#2 - { - % \tl_show:n {1:~#1} \tl_show:n {2:~#2} - \prop_gput:Nnn \g__fnpct_adapted_notes_prop {#1} {#2} - } +\cs_new_protected:Npn \__fnpct_execute: {} -% standard \footnote[]{} like commands -% #1: old new name -% #2: internal name of old definition -% #3: mult-variant -% -% \footnote[]{} like: -\cs_new_protected:Npn \fnpct_renew_and_mult:NNN #1#2#3 +% #1: boolean +\cs_new_protected:Npn \fnpct_begin: + { \__fnpct_check_after_end:w } + +% #1: code +\cs_new_protected:Npn \__fnpct_check_after_end:w #1 \fnpct_end: { - \fnpct_if_adapted:NF #1 + \cs_set_protected:Npn \__fnpct_execute: { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \fnpct_create_mult_variant:NN #3#2 - \bool_if:NTF \l__fnpct_multiple_default_bool - { \cs_set_eq:NN #1#3 } + \__fnpct_check_trail:NTF \l_peek_token { - \RenewDocumentCommand #1 {so+m} - { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} } + \prop_get:NVN \l__fnpct_trailing_actions_prop + \l_fnpct_trailing_token_tl + \l_fnpct_action_tl + \fnpct_do_action:Vnw \l_fnpct_action_tl {#1} } - } - } -\cs_generate_variant:Nn \fnpct_renew_and_mult:NNN {ccc,NcN} - -% \footnote{} like: -\cs_new_protected:Npn \fnpct_renew_and_mult_no_opt:NNN #1#2#3 - { - \fnpct_if_adapted:NF #1 - { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \fnpct_create_mult_variant:NN #3#2 - \bool_if:NTF \l__fnpct_multiple_default_bool - { \cs_set_eq:NN #1#3 } { - \RenewDocumentCommand #1 {s+m} + % no trailing punctuation + \bool_lazy_or:nnT + { \fnpct_if_collection_p: } + { \fnpct_if_switched_p: } { - \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } - {##2} {##1} + \fnpct_skip_nobreak:N \l__fnpct_before_footnote_dim + \fnpct_if_collection:T { \fnpct_print_collection: } } + #1 } + \fnpct_end: } + \peek_after:Nw \__fnpct_execute: } -\cs_generate_variant:Nn \fnpct_renew_and_mult_no_opt:NNN {Nc,ccc} -% renew but don't create mult-variant: -% \footnote[]{} like: -\cs_new_protected:Npn \fnpct_renew:NN #1#2 +\cs_new_protected:Npn \fnpct_end: { } + +\cs_new_protected:Npn \fnpct_before: { - \fnpct_if_adapted:NF #1 + \bool_if:NF \l__fnpct_dont_mess_around_bool { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \RenewDocumentCommand #1 {so+m} - { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} } + \fnpct_if_switched:F + { \fnpct_add_punctuation_space:n {after} } + \bool_if:NF \l_fnpct_trailing_action_bool + { % no punctiation following + \bool_if:NF \l__fnpct_end_collection_bool + { \fnpct_skip_nobreak:N \l__fnpct_before_footnote_dim } + } } } -\cs_generate_variant:Nn \fnpct_renew:NN {cc,Nc} -% new -\cs_new_protected:Npn \fnpct_new:NN #1#2 +\cs_new_protected:Npn \fnpct_add_punctuation_space:n #1 { - \fnpct_if_adapted:NF #1 + \fnpct_if_class:nT {punctuation} { - \fnpct_add_to_adapted:NN #1#2 - \NewDocumentCommand #1 {so+m} - { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} } + \fnpct_foreach_action:nn {punctuation} + { + \fnpct_if_action:nT {##1} + { + \fnpct_skip_nobreak:c {l__fnpct_#1_##1_dim} + \fnpct_action_break: + } + } } } -\cs_generate_variant:Nn \fnpct_new:NN {cc,Nc} - -% \note[][]{} like: -\cs_new_protected:Npn \fnpct_renew_and_mult_opt:NNN #1#2#3 + +\cs_new_protected:Npn \fnpct_after: { - \fnpct_if_adapted:NF #1 + \bool_if:NF \l__fnpct_dont_mess_around_bool { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \fnpct_create_mult_variant:NN #3#2 - \bool_if:NTF \l__fnpct_multiple_default_bool - { \cs_set_eq:NN #1#3 } + \fnpct_if_switched:T { - \RenewDocumentCommand #1 {soo+m} - { \fnpct_handle_note:Nnnnn #2 {##2} {##3} {##4} {##1} } + \fnpct_if_class:nT {punctuation} + { + \bool_set_false:N \l__fnpct_collection_bool + \fnpct_foreach_action:nn {punctuation} + { + \fnpct_if_action:nT {##1} + { + \fnpct_skip_nobreak:c {l__fnpct_before_##1_dim} + \fnpct_action_break: + } + } + } + \bool_set_false:N \l__fnpct_end_collection_bool + \bool_set_false:N \l__fnpct_switched_bool } } } -\cs_generate_variant:Nn \fnpct_renew_and_mult_opt:NNN {ccc,NcN} -\cs_new_protected:Npn \fnpct_renew_opt:NN #1#2 +% #1: command +% #2: argument spec +% #3: code where #NOTE refers to the original note + +\cs_new_protected:Npn \fnpct_adapt_note:Nnn #1#2#3 { \fnpct_if_adapted:NF #1 { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \RenewDocumentCommand #1 {soo+m} - { \fnpct_handle_note:Nnnnn #2 {##2} {##3} {##4} {##1} } + \fnpct_save_note_command:N #1 + \fnpct_new_trailing_token:Nn #1 {collect} + \keys_set:nn {fnpct} { activate-trailing-tokens = {#1} } + } + \tl_set:Nn \l__fnpct_tmpa_tl {#3} + \regex_replace_all:nnN {\cP\#\cP\#} {$$$$} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#8} {\cP\#9} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#7} {\cP\#8} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#6} {\cP\#7} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#5} {\cP\#6} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#4} {\cP\#5} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#3} {\cP\#4} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#2} {\cP\#3} \l__fnpct_tmpa_tl + \regex_replace_all:nnN {\cP\#1} {\cP\#2} \l__fnpct_tmpa_tl + \regex_replace_all:nxN + {\cP\#NOTE} + { + \exp_not:N \c{fnpct_use_note_command:N} + \exp_not:N \c{\__fnpct_remove_backslash:N #1} + } + \l__fnpct_tmpa_tl + % we need to double inner arguments yet one more, so it can appear inside + % the replacement text of \__fnpct_execute: + \regex_replace_all:nnN {\$\$\$\$} {\cP\#\cP\#\cP\#\cP\#} \l__fnpct_tmpa_tl + \tl_put_left:Nn \l__fnpct_tmpa_tl { \fnpct_start:w } + \tl_put_right:Nn \l__fnpct_tmpa_tl { \fnpct_stop: } + \use:x + { + \exp_not:n { \RenewDocumentCommand #1 {s#2} } + { + \exp_not:n { \fnpct_reverse:n {##1} } + \exp_not:V \l__fnpct_tmpa_tl + } } } -\cs_generate_variant:Nn \fnpct_renew_opt:NN {cc,Nc} +\cs_generate_variant:Nn \fnpct_adapt_note:Nnn {c} -% \note{} like -\cs_new_protected:Npn \fnpct_renew_no_opt:NN #1#2 +\cs_new_protected:Npn \fnpct_reverse:n #1 { - \fnpct_if_adapted:NF #1 - { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \RenewDocumentCommand #1 {s+m} - { \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } {##2} {##1} } - } + \bool_if:NTF \l__fnpct_reverse_bool + { \bool_if:nF } + { \bool_if:NT } + {#1} { \bool_set_true:N \l__fnpct_switched_bool } } -\cs_generate_variant:Nn \fnpct_renew_no_opt:NN {cc,Nc} -% \note like -\cs_new_protected:Npn \fnpct_renew_no_arg:NN #1#2 +% #1: code +\cs_new_protected:Npn \fnpct_start:w #1 \fnpct_stop: { - \fnpct_if_adapted:NF #1 - { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \RenewDocumentCommand #1 {s} - { \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } { } {##1} } - } + \fnpct_begin: + \fnpct_before: + \group_begin: + #1 + \group_end: + \fnpct_after: + \fnpct_end: } -\cs_generate_variant:Nn \fnpct_renew_no_arg:NN {cc} -% create mult-variant -\cs_new_protected:Npn \fnpct_create_mult_variant:NN #1#2 +\cs_new_protected:Npn \fnpct_text: { - \NewDocumentCommand #1 {s+m} - { \fnpct_mult_note:Nnn #2 {##1} {##2} } + \bool_set_false:N \l__fnpct_inside_range_bool + \bool_gset_true:N \g__fnpct_text_bool } -% \footnotemark[] like commands: -\cs_new_protected:Npn \fnpct_renew_mark:NN #1#2 +% -------------------------------------------------------------------------- +% #1: note command +% #2: arguments +% #3: counter name +% #4: code +\NewDocumentCommand \AdaptNote {mmom} { - \fnpct_if_adapted:NF #1 - { - \fnpct_add_to_adapted:NN #1#2 - \cs_new_eq:NN #2#1 - \RenewDocumentCommand #1 {so} - { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } { } {##1} } - } + \fnpct_adapt_note:Nnn #1 {#2} {#4} + \IfNoValueF {#3} + { \fnpct_set_counter_name:Nn #1 {#3} } } -\cs_generate_variant:Nn \fnpct_renew_mark:NN {cc,Nc} -% user commands: -\NewDocumentCommand \AdaptNote {mm} +\NewDocumentCommand \AdaptNoteName {mmom} { - \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } - { \fnpct_message:nx {already-adapted} {#1} } - { \fnpct_renew_and_mult:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 } + \fnpct_adapt_note:cnn {#1} {#2} {#4} + \IfNoValueF {#3} + { \fnpct_set_counter_name:cn {#1} {#3} } } -\NewDocumentCommand \AdaptNoteNoMult {m} +\NewDocumentCommand \AdaptText {mmm} { - \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } - { \fnpct_message:nx {already-adapted} {#1} } - { \fnpct_renew:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } } + \fnpct_adapt_note:Nnn #1 {#2} + { \fnpct_text: #3 } } -\NewDocumentCommand \AdaptNoteOpt {mm} +\NewDocumentCommand \innernote {+m} + { \msg_warning:nn {fnpct} {command-removed} \use:n {#1} } + +\NewExpandableDocumentCommand \ifcurrentnoteTF {m} + { \fnpct_if_current:NTF #1 } + +\NewExpandableDocumentCommand \ifcurrentnoteT {m} + { \fnpct_if_current:NT #1 } + +\NewExpandableDocumentCommand \ifcurrentnoteF {m} + { \fnpct_if_current:NF #1 } + +% -------------------------------------------------------------------------- +% OPTIONS +\NewDocumentCommand \setfnpct {m} + { \keys_set:nn {fnpct} {#1} } + +\cs_new_protected:Npn \fnpct_deprecate_option:n #1 + { \msg_warning:nnVn {fnpct} {option-deprecated} \l_keys_key_str {#1} } + +\cs_new_protected:Npn \fnpct_deprecate_option: + { \msg_warning:nnV {fnpct} {option-deprecated} \l_keys_key_str } + +\keys_define:nn {fnpct} { - \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } - { \fnpct_message:nx {already-adapted} {#1} } - { \fnpct_renew_and_mult_opt:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 } + add-trailing-token .code:n = \AddPunctuation #1 , + activate-trailing-tokens .code:n = + \tl_map_inline:nn {#1} { \fnpct_activate_trailing_token:n {##1} } , + activate-trailing-tokens .initial:n = {.,} , + deactivate-trailing-tokens .code:n = + \tl_map_inline:nn {#1} { \fnpct_deactivate_trailing_token:n {##1} } , + before-footnote-space .dim_set:N = \l__fnpct_before_footnote_dim , + before-footnote-space .initial:n = .06em , + ranges .bool_set:N = \l__fnpct_ranges_bool , + ranges .initial:n = false , + keep-ranges .bool_set:N = \l__fnpct_keep_ranges_bool , + keep-ranges .initial:n = false , + dont-mess-around .bool_set:N = \l__fnpct_dont_mess_around_bool , + dont-mess-around .initial:n = false , + mult-fn-delim .code:n = + \tl_set:Nn \l__fnpct_multiple_footnotes_delimiter_tl {#1} , + separation-symbol .code:n = + \renewcommand* \multfootsep {#1} , + range-symbol .code:n = + \renewcommand* \multfootrange {#1} , + print-separation .tl_set:N = \l__fnpct_separate_tl , + print-separation .initial:n = \textsuperscript { \multfootsep } , + print-range .tl_set:N = \l__fnpct_range_tl , + print-range .initial:n = \textsuperscript { \multfootrange } , + reverse .bool_set:N = \l__fnpct_reverse_bool , + after-punct-space .code:n = + \fnpct_foreach_action:nn {punctuation} + { \keys_set:nn {fnpct} { after-##1-space = #1 } } , + before-punct-space .code:n = + \fnpct_foreach_action:nn {punctuation} + { \keys_set:nn {fnpct} { before-##1-space = #1 } } } -\NewDocumentCommand \AdaptNoteOptNoMult {m} +% deprecate options of earlier version unless it still exists: +\clist_map_inline:nn { - \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } - { \fnpct_message:nx {already-adapted} {#1} } - { \fnpct_renew_opt:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } } + bigfoot-default-top , + strict , + after-comma-space , + after-dot-space , + before-comma-space , + before-dot-space , + after-punct-space , + before-punct-space , + before-footnote-space , + french-before-footnote-space , + punct-after , + dont-mess-around , + mult-fn-delim , + mult-fn-sep , + multiple , + normal-marks , + normal-mark-width , + normal-indent , + normal-parindent , + verb-format , + add-punct-marks , + remove-punct-marks , } + { + \keys_if_exist:nnF {fnpct} {#1} + { \keys_define:nn {fnpct} { #1 .code:n = \fnpct_deprecate_option: } } + } + +% -------------------------------------------------------------------------- +% define \multfootnote and friends for some transition period -\NewDocumentCommand \AdaptNoteNoOpt {mm} +\cs_new_protected:Npn \fnpct_create_mult_variant:N #1 { - \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } - { \fnpct_message:nx {already-adapted} {#1} } - { \fnpct_renew_and_mult_no_opt:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 } + \exp_args:Nc \NewDocumentCommand + { mult \__fnpct_remove_backslash:N #1 } + { sm } + { + \seq_set_split:NVn \l__fnpct_tmpa_seq + \l__fnpct_multiple_footnotes_delimiter_tl + {##2} + \tl_clear:N \l__fnpct_tmpa_tl + \seq_map_inline:Nn \l__fnpct_tmpa_seq + { + \tl_put_right:Nx \l__fnpct_tmpa_tl + { \exp_not:n {#1} \IfBooleanT{##1}{*} \exp_not:n {{####1}} } + } + \l__fnpct_tmpa_tl + } } +\cs_generate_variant:Nn \fnpct_create_mult_variant:N {c} + +\NewDocumentCommand \MultVariant {m} + { \fnpct_create_mult_variant:N #1 } + +\NewDocumentCommand \MultVariantName {m} + { \fnpct_create_mult_variant:c {#1} } -\NewDocumentCommand \AdaptNoteNoOptNoMult {m} +% -------------------------------------------------------------------------- +% TAKE CARE OF FRENCH SETTINGS +\RequirePackage {translations} +\hook_gput_code:nnn {begindocument/end} {fnpct} { - \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1:w } - { \fnpct_message:nx {already-adapted} {#1} } - { \fnpct_renew_no_opt:Nc #1 { fnpct_orig_ \cs_to_str:N #1:w } } + \ifcurrentbaselanguage {French} + { + \cs_set_eq:NN \@footnotemark \@footnotemarkORI + \StandardFootnotes + \keys_set:nn {fnpct} { before-footnote-space = .16667em } + } + {} } -\NewDocumentCommand \AdaptNoteMark {m} +% -------------------------------------------------------------------------- + +\hook_gput_code:nnn {begindocument} {fnpct} { - \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w } - { \fnpct_message:nx {already-adapted} {#1} } - { \fnpct_renew_mark:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } } + \fnpct_if_class_loaded:nTF {memoir} + { \renewcommand* } + { \providecommand* } + \multfootsep {,} + \providecommand* \multfootrange {--} + \tl_set:Nn \l__fnpct_range_tl { \textsuperscript { \multfootrange } } } % -------------------------------------------------------------------------- % DO THE REDEFINING: % -% `bigfoot' loads `manyfoot' which saves its footnote classes in a 2e list: -\str_const:Nn \c__fnpct_footins_str {\footins} -\str_remove_once:Nn \c__fnpct_footins_str {~} +% before we start make the testing more comfortable: +\cs_new_protected:Npn \fnpct_treatment:nn #1#2 + { \fnpct_if_package_loaded:nT {#1} {#2} } + +\cs_new_protected:Npn \fnpct_special_treatment:nn #1#2 + { + \fnpct_if_package_loaded:nTF {#1} {#2} + { \hook_gput_code:nnn {package/after/#1} {fnpct} {#2} } + } + +% `manyfoot' (loaded by `bigfoot') saves its footnote classes in a 2e list: +\str_new:N \l__fnpct_footins_str +\str_set:Nn \l__fnpct_footins_str {\footins} +\str_remove_once:Nn \l__fnpct_footins_str {~} \cs_new_protected:Npn \__fnpct_grab_second:Nnw #1#2#3 \q_stop { \str_set:Nn \l__fnpct_tmpa_str {#3} \str_remove_once:Nn \l__fnpct_tmpa_str {~} - \str_remove_once:NV \l__fnpct_tmpa_str \c__fnpct_footins_str + \str_remove_once:NV \l__fnpct_tmpa_str \l__fnpct_footins_str \seq_put_right:Nx #1 { \l__fnpct_tmpa_str } } \cs_new_protected:Npn \__fnpct_get_fnclasses:NN #1#2 { - \seq_set_split:NnV \l__fnpct_tmpa_seq {\@elt } #1 + \seq_set_split:NnV \l__fnpct_tmpa_seq { \@elt } #1 \seq_pop_left:NN \l__fnpct_tmpa_seq \l__fnpct_tmpa_tl \seq_map_inline:Nn \l__fnpct_tmpa_seq { \__fnpct_grab_second:Nnw #2 ##1 \q_stop } \seq_remove_duplicates:N #2 } -% before we start make the testing more comfortable: -\cs_new_protected:Npn \fnpct_treatment:nn #1#2 - { \fnpct_if_package_loaded:nT {#1} {#2} } - -\cs_new_protected:Npn \fnpct_special_treatment:nn #1#2 - { \fnpct_if_package_loaded:nTF {#1} {#2} { \AfterPackage* {#1} {#2} } } - -% and now get going: -\AtBeginDocument +% `fixfoot' package +\fnpct_special_treatment:nn {fixfoot} { - \fnpct_if_package_loaded:nTF {hyperref} - { \bool_set_true:N \l__fnpct_hyperref_bool } + % hook into \DeclareFixedFootnote so we can redefine all fixed footnotes + % defined be users + \seq_new:N \l__fnpct_footnote_fixfoot_seq + \cs_new_eq:NN \fnpct_new_fixnote:w \DeclareFixedFootnote + \RenewDocumentCommand \DeclareFixedFootnote {smm} { - \cs_if_exist:NF \AfterBeginDocument - { \cs_new:Npn \AfterBeginDocument #1 {#1} } + \seq_put_right:Nn \l__fnpct_footnote_fixfoot_seq {#2} + \IfBooleanTF {#1} + { \fnpct_new_fixnote:w * {#2} {#3} } + { \fnpct_new_fixnote:w {#2} {#3} } } - \AfterBeginDocument + } + +% `pagenote' package: +\fnpct_special_treatment:nn {pagenote} + { + \bool_new:N \l__fnpct_makepagenote_bool + \tl_put_left:Nn \makepagenote + { \bool_set_true:N \l__fnpct_makepagenote_bool } + } + +\fnpct_special_treatment:nn {sepfootnotes} + { + \cs_new_eq:NN \fnpct_sepfootnote_new:n \sep@new + \seq_new:N \l__fnpct_sepfootnotes_seq + \cs_set_protected:Npn \sep@new #1 { + \seq_put_right:Nn \l__fnpct_sepfootnotes_seq {#1} + \fnpct_sepfootnote_new:n {#1} + } + } + +\hook_gput_code:nnn {begindocument} {fnpct} + { + \fnpct_if_package_loaded:nT {hyperref} { - \AdaptNote \footnote \multfootnote - \AdaptNoteMark \footnotemark - \cs_if_exist:NT \footref - { \AdaptNoteNoOptNoMult \footref } - \fnpct_new:NN \innernote \fnpct_inner_footnote:w - %% the `endnotes' package: - \fnpct_treatment:nn {endnotes} + \fnpct_if_ranges:T { - \AdaptNote \endnote \multendnote - \AdaptNoteMark \endnotemark + \bool_if:NTF \l__fnpct_keep_ranges_bool + { \msg_warning:nn {fnpct} {keep-ranges-hyperref} } + { + \msg_warning:nn {fnpct} {ranges-hyperref} + \bool_set_false:N \l__fnpct_ranges_bool + \keys_define:nn {fnpct} + { ranges .code:n = \msg_warning:nn {fnpct} {ranges-disabled} } + } } - %% the `enotez' package: - \fnpct_treatment:nn {enotez} - { \AdaptNote \endnote \multendnote } - %% the `snotez' package: - \fnpct_treatment:nn {snotez} + } + %% LaTeX's defaults: + \fnpct_if_class_loaded:nTF {beamer} + { + \AdaptNote \footnote{d<>o+m} [\beamer@mpfn] { - \AdaptNoteOpt \sidenote \multsidenote - \AdaptNoteMark \sidenotemark + \IfNoValueTF{#1} + {\IfNoValueTF{#2}{#NOTE{#3}}{#NOTE[#2]{#3}}} + {\IfNoValueTF{#2}{#NOTE<#1>{#3}}{#NOTE<#1>[#2]{#3}}} } - %% the `parnotes' package: - \fnpct_treatment:nn {parnotes} - { \AdaptNote \parnote \multparnote } - %% the `pagenote' package: - \fnpct_treatment:nn {pagenote} + \AdaptNote \footnotemark {o} [\beamer@mpfn] + { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} } + } + { + \AdaptNote \footnote {o+m} [\@mpfn] + { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} } + \AdaptNote \footnotemark {o} [\@mpfn] + { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} } + } + \fnpct_if_multiple:T { \MultVariant \footnote } + % TODO: should we adapt \thanks? Not with memoir, though... + % \AdaptNote \thanks {+m} { \cs_set_eq:NN \rlap \use:n #NOTE{#1} } + %% KOMA-Script and memoir: + \cs_if_exist:NT \footref + { \AdaptNote \footref {m} { #NOTE{#1} } } + %% snotez: + \fnpct_treatment:nn {snotez} + { + \AdaptNote \sidenote {d()oo+m} { - \bool_if:NTF \l__fnpct_makepagenote_bool - { \AdaptNote \pagenote \multpagenote } - { \msg_warning:nn {fnpct} {pagenote} } + \IfNoValueTF {#1} + { + \IfNoValueTF {#2} + {#NOTE{#4}} + { \IfNoValueTF {#3} {#NOTE[#2]{#4}} {#NOTE[#2][#3]{#4}} } + } + { \IfNoValueTF {#2} {#NOTE(#1){#4}} {#NOTE(#1)[#2]{#4}} } } - %% the `tablefootnote' package: - \fnpct_treatment:nn {tablefootnote} - { \AdaptNote \tablefootnote \multtablefootnote } - %% the `manyfoot' package (also loaded by `bigfoot'): - \fnpct_treatment:nn {manyfoot} + \AdaptNote \sidenotemark {o} [sidenote] + { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} } + \fnpct_if_multiple:T { \MultVariant \sidenote } + } + % sidenotes: + \fnpct_treatment:nn {sidenotes} + { + % `sidenotes' implements its \sidenote in terms of the user + % commands \sidenotemark and \sidenotetext; this makes it quite + % difficult if not impossible to adapt its commands + \msg_warning:nnn {fnpct} {cannot-adapt} {sidenotes} + } + \bool_lazy_or:nnT + { \fnpct_if_class_loaded_p:n {tufte-handout} } + { \fnpct_if_class_loaded_p:n {tufte-book} } + { + \fnpct_if_ranges:TF { - \__fnpct_get_fnclasses:NN \MFL@list \l__fnpct_footnote_class_seq - \seq_map_inline:Nn \l__fnpct_footnote_class_seq + \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges} + {tufte-latex} { - \str_if_eq:nnTF {#1} {default} - { - \cs_if_exist:NT \footnotedefault - { - \fnpct_renew_and_mult:ccc {footnote#1} - {fnpct_orig_footnote#1:w} - {multfootnote#1} - \fnpct_renew_mark:cc {footnotemark#1} - {fnpct_orig_footnotemark#1:w} - } - } - { - \fnpct_renew_and_mult:ccc {footnote#1} - {fnpct_orig_footnote#1:w} - {multfootnote#1} - \fnpct_renew_mark:cc {footnotemark#1} - {fnpct_orig_footnotemark#1:w} - } + The~ command~ \sidenote~ misses~ a~ suitable~ \sidenotetext~ + version. } } - %% the `bigfoot' package: - \fnpct_special_treatment:nn {bigfoot} { - \cs_if_exist:NT \footnotedefault + \AdaptNote \sidenote {oo+m} [\@mpfn] { - % re-set basics: - \cs_set_eq:NN \footnote \footnotedefault - \cs_set_eq:NN \footnotemark \footnotemarkdefault - \cs_set_eq:NN \multfootnote \multfootnotedefault + \IfNoValueTF {#1} + {#NOTE{#3}} + { \IfNoValueTF {#2} {#NOTE[#1]{#3}} {#NOTE[#1][#2]{#3}} } } } - %% the `fixfoot' package: - \fnpct_treatment:nn {fixfoot} + } + %% endnotes: + \fnpct_treatment:nn {endnotes} + { + \AdaptNote \endnote {o+m} + { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} } + \AdaptNote \endnotemark {o} [endnote] + { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} } + \fnpct_if_multiple:T { \MultVariant \endnote } + } + % enotez: + \fnpct_treatment:nn {enotez} + { + \AdaptNote \endnote {o+m} { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} } + \AdaptNote \endnotemark {o} [endnote] { \IfNoValueTF {#1} {#NOTE} {#NOTE{#1}} } + \fnpct_if_multiple:T { \MultVariant \endnote } + \hook_gput_code:nnn {fnpct/rangesetup} {enotez} { - \prop_map_inline:Nn \l__fnpct_footnote_fixfoot_prop - { \fnpct_renew_no_arg:cc {#2} {fnpct_orig_fix_#2:w} } + \fnpct_if_current:NT \endnote + { \int_gincr:N \g__enotez_endnote_id_int } } - %% the `sepfootnotes' package: - \fnpct_treatment:nn {sepfootnotes} + } + %% manyfoot/bigfoot + \fnpct_treatment:nn {manyfoot} + { + \__fnpct_get_fnclasses:NN \MFL@list \l__fnpct_footnote_class_seq + \seq_map_inline:Nn \l__fnpct_footnote_class_seq { - \prop_map_inline:Nn \l__fnpct_sepfootnote_foot_classes_prop + \str_if_eq:nnTF {#1} {default} { - \fnpct_renew_and_mult_no_opt:ccc {#2note} - {fnpct_orig_sep_#2:w} {#2multnote} - \fnpct_renew_and_mult_no_opt:ccc {#2quicknote} - {fnpct_orig_sep_#2_quick:w} {#2multquicknote} - \fnpct_renew_no_opt:cc {#2notemark} {fnpct_orig_sep_#2_mark:w} + \cs_if_exist:NT \footnotedefault + { + \AdaptNoteName {footnote#1} {o+m} + { \IfNoValueTF {##1} {##NOTE{##2}} {##NOTE[##1]{##2}} } + \AdaptNoteName {footnotemark#1} {o} [footnote#1] + { \IfNoValueTF {##1} {##NOTE} {##NOTE[##1]} } + \fnpct_if_multiple:T { \MultVariantName {footnote#1} } + } } - \prop_map_inline:Nn \l__fnpct_sepfootnote_end_classes_prop { - \fnpct_renew_and_mult_no_opt:ccc {#2note} - {fnpct_orig_sep_#2:w} {#2multnote} - \fnpct_renew_no_opt:cc {#2notemark} {fnpct_orig_sep_#2_mark:w} + \AdaptNoteName {footnote#1} {o+m} + { \IfNoValueTF {##1} {##NOTE{##2}} {##NOTE[##1]{##2}} } + \AdaptNoteName {footnotemark#1} {o} [footnote#1] + { \IfNoValueTF {##1} {##NOTE} {##NOTE[##1]} } + \fnpct_if_multiple:T { \MultVariantName {footnote#1} } } } } - } - -% `bigfoot' package -% \fnpct_special_treatment:nn {fixfoot} -% { -% \bool_if:NT \l__fnpct_bigfoot_default_top_bool -% { \DeclareNewFootnote {default} } -% } - -% `fixfoot' package -\fnpct_special_treatment:nn {fixfoot} - { - % hook into \DeclareFixedFootnote so we can redefine all footnote - % classes defined be users - \cs_new_eq:NN \fnpct_new_fixnote:w \DeclareFixedFootnote - \RenewDocumentCommand \DeclareFixedFootnote {smm} + %% fixfoot + \fnpct_treatment:nn {fixfoot} { - \prop_put:Nnx \l__fnpct_footnote_fixfoot_prop {#2} - { \cs_to_str:N #2 } - \IfBooleanTF {#1} - { \fnpct_new_fixnote:w * {#2} {#3} } - { \fnpct_new_fixnote:w {#2} {#3} } + \fnpct_if_ranges:TF + { + \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges} + {fixfoot} + { + There~ cannot~ be~ suitable~ \..text~ versions~ for~ the~ + fixed~ notes. + } + } + { + \seq_map_inline:Nn \l__fnpct_footnote_fixfoot_seq + { \AdaptNote #1 {} { ##NOTE } } + } } - } - -% `pagenote' package: -\fnpct_special_treatment:nn {pagenote} - { - \tl_put_left:Nn \makepagenote - { \bool_set_true:N \l__fnpct_makepagenote_bool } - } - -% `sepfootnotes' package: -\fnpct_special_treatment:nn {sepfootnotes} - { - \cs_new_eq:NN \fnpct_orig_new_footnotes:w \newfootnotes - \cs_new_eq:NN \fnpct_orig_new_endnotes:n \newendnotes - \cs_new_eq:NN \fnpct_orig_new_symbolnotes:w \newsymbolfootnotes - \RenewDocumentCommand \newfootnotes {sm} + %% pagenote + \fnpct_treatment:nn {pagenote} { - \prop_put:Nnn \l__fnpct_sepfootnote_foot_classes_prop {#2} {#2} - \IfBooleanTF {#1} - { \fnpct_orig_new_footnotes:w * {#2} } - { \fnpct_orig_new_footnotes:w {#2} } + \fnpct_if_ranges:TF + { + \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges} + {pagenote} + { + The~ command~ \pagenote~ misses~ a~ suitable~ \pagenotetext~ + version. + } + } + { + \bool_if:NTF \l__fnpct_makepagenote_bool + { + \AdaptNote \pagenote {o+m} + { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} } + \fnpct_if_multiple:T { \MultVariant \pagenote } + } + { \msg_warning:nn {fnpct} {pagenote} } + } } - \RenewDocumentCommand \newendnotes {m} + %% parnotes + \fnpct_treatment:nn {parnotes} { - \prop_put:Nnn \l__fnpct_sepfootnote_end_classes_prop {#1} {#1} - \fnpct_orig_new_endnotes:n {#1} + \fnpct_if_ranges:TF + { + \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges} + {parnotes} + { + The~ command~ \parnote~ misses~ a~ suitable~ \parnotetext~ + version. + } + } + { + \AdaptNote \parnote {o+m} + { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} } + \fnpct_if_multiple:T { \MultVariant \parnote } + } } - \RenewDocumentCommand \newsymbolfootnotes {om} + %% tablefootnote + \fnpct_treatment:nn {tablefootnote} { - \prop_put:Nnn \l__fnpct_sepfootnote_symbol_classes_prop {#2} {#2} - \IfNoValueTF {#1} - { \fnpct_orig_new_symbolnotes:w {#2} } - { \fnpct_orig_new_symbolnotes:w [#1] {#2} } + \fnpct_if_ranges:TF + { + \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges} + {tablefootnote} + { + The~ command~ \tablefootnote~ misses~ a~ suitable~ + \tablefootnotetext~ version. + } + } + { + \AdaptNote \tablefootnote {o+m} [footnote] + { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} } + } } - } - -% -------------------------------------------------------------------------- -\RequirePackage{translations} -\AtBeginDocument{ - \ifcurrentbaselanguage{French} + %% sepfootnotes + \fnpct_treatment:nn {sepfootnotes} { - \AfterBeginDocument{ - \cs_if_exist:NT \@footnotemarkORI + \cs_set:Nn \__fnpct_sep_mark:n {\footnotemark} + \seq_map_inline:Nn \l__fnpct_sepfootnotes_seq { - \let\@footnotemark\@footnotemarkORI - \setfnpct{ - before-footnote-space = - \l__fnpct_french_before_footnote_space_dim - } + \cs_if_eq:cNTF {#1notemark} \__fnpct_sep_mark:n + {% defined with \newfootnotes + \AdaptNoteName {#1note} {m} [\@mpfn] {##NOTE{##1}} + } + {% defined with \newfootnotes* or \newendnotes + \AdaptNoteName {#1note} {m} {##NOTE{##1}} + \hook_gput_code:nnn {fnpct/rangesetup} {sepfootnotes} + { + \fnpct_if_current:cT {#1note} + { + \addtocounter {#1note} {-1} + \sep@refstepcounter {#1note} + } + } + } + \AdaptNoteName {#1notemark} {m} {##NOTE{##1}} + \AdaptNoteName {#1quicknote} {m} {##NOTE{##1}} + \fnpct_if_multiple:T { \MultVariantName {#1note} } + \fnpct_if_multiple:T { \MultVariantName {#1quicknote} } } } - }{} -} + } +\file_input_stop: % -------------------------------------------------------------------------- -% SETUP COMMAND: -\NewDocumentCommand \setfnpct {m} - { \keys_set:nn {fnpct} {#1} } - -\file_input_stop: +% OTHER PACKAGES: +# should just work: +footnpag +ednotes +yafoot + +# cannot be adapted for the time being: +sidenotes + +# works: +endnotes +snotez +footmisc +footnote (not the environment) +manyfoot +bigfoot +enotez +sepfootnotes + +# works, but not with ranges: +fixfoot +pagenote +parnotes +tablefootnote % -------------------------------------------------------------------------- % HISTORY: -2012/05/18 v0.1alpha - various changes still possible without announcement - until declared `v0.1' -2012/05/19 v0.1beta - considered ready for public use, needs feedback, though -2012/05/20 v0.1beta-a - minor changes -2012/05/20 v0.1beta-b - added `pagenote' support - - added `tablefootnote' support -2012/05/20 v0.1beta-c - optional star argument to \multfootnote that only invokes - \footnotetext - - option `dont-mess-around': disable switching and kerning -2012/05/21 v0.1beta-d - \innernote for nesting - - `hyperref' support - - bugfix in \multfootnote -2012/05/21 v0.1beta-e - `sepfootnotes' support -2012/05/22 v0.1beta-f - reorganized code -2012/05/22 v0.1 - a bit more cleaning up of the code - - completed documentation - - ready for CTAN +2012/05/22 v0.1 - ready for CTAN 2012/05/23 v0.1a - \AdaptNoteNoMult, \AdaptNoteOpt, \AdaptNoteOptNoMult - support `sidenotes' package - better support for citing commands @@ -1212,9 +1393,11 @@ 2019/10/05 v0.5 - fix issue 18 - remove option `bigfoot-default-top' - support `manyfoot' package - -% -------------------------------------------------------------------------- -% NOTES: -- `footnote' package => not compatible -- `ednotes' package => not tested; who knows? -- `sidenotes' package => mot easily patchable, see pull request #1 +2020/01/12 v0.5a - support `snotez' with `dblrg=false' +2021/01/21 v1.0 - new implementation: + * support footnote ranges when possible + * support more packages + * more flexible way to adapt unknown note commands + with less commands + * drop support of \innernote (maybe re-implement it in + future versions, depending on user feedback) diff --git a/macros/latex/contrib/fnpct/fnpct_en.pdf b/macros/latex/contrib/fnpct/fnpct_en.pdf deleted file mode 100644 index 7ce6a35d4a..0000000000 Binary files a/macros/latex/contrib/fnpct/fnpct_en.pdf and /dev/null differ diff --git a/macros/latex/contrib/fnpct/fnpct_en.tex b/macros/latex/contrib/fnpct/fnpct_en.tex deleted file mode 100644 index e84a68f15e..0000000000 --- a/macros/latex/contrib/fnpct/fnpct_en.tex +++ /dev/null @@ -1,1044 +0,0 @@ -% arara: pdflatex: { shell: on , interaction: nonstopmode } -% !arara: biber -% !arara: pdflatex -% !arara: pdflatex -% -------------------------------------------------------------------------- -% the FNPCT package -% -% footnote kerning -% -% -------------------------------------------------------------------------- -% Clemens Niederberger -% Web: https://bitbucket.org/cgnieder/fnpct/ -% E-Mail: contact@mychemistry.eu -% -------------------------------------------------------------------------- -% Copyright 2012--2019 Clemens Niederberger -% -% This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 -% of this license or (at your option) any later version. -% The latest version of this license is in -% http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. -% -% This work has the LPPL maintenance status `maintained'. -% -% The Current Maintainer of this work is Clemens Niederberger. -% -------------------------------------------------------------------------- -% If you have any ideas, questions, suggestions or bugs to report, please -% feel free to contact me. -% -------------------------------------------------------------------------- -% the package is inspired by the following question on TeX.SE: -% http://tex.stackexchange.com/q/56094/5049 -% -------------------------------------------------------------------------- -\documentclass[load-preamble+]{cnltx-doc} -\usepackage{sepfootnotes,fnpct} -\setcnltx{ - package = fnpct , - authors = Clemens Niederberger , - email = contact@mychemistry.eu , - url = https://bitbucket.org/cgnieder/fnpct/ , - abstract = { - The \fnpct\ package basically does two things to footnotes: if footnote - marks are followed by a punctuation mark the order of footnote and - punctuation mark is reversed and the kerning gets adjusted. As a side - effect a new method of creating multiple footnotes and some other - features are provided.% - }, - add-cmds = { - AdaptNote, - AdaptNoteMark, - innernote, - kfc, - kfp, - multfootnote, - setfnpct, - writeinnernotes - } , - add-silent-cmds = { - anote, - anotecontent, - arabic, - DeclareNewFootnote, - endnote, - footnoteB, - multendnote, - multfootcite, - multparnote, - multsidenote, - myfn, - newfootnotes, - parnote, - parnotes, - sidenote, - theendnotes, - thempfootnote, - }, - makeindex-setup = {options={-s cnltx.ist},columns=3,columnsep=1em} , - index-setup = {othercode=\footnotesize,level=\addsec} -} - -\defbibheading{bibliography}[\bibname]{\addsec{#1}} - -\usepackage{array,booktabs} - -\setfnpct{multiple,add-punct-marks=:[0pt][-.05em]} - -\usepackage{endnotes} -\usepackage{parnotes} - -\newfootnotes{a} - -\renewcommand\thempfootnote{\arabic{mpfootnote}} - -\addbibresource{\jobname.bib} -\addbibresource{biblatex-examples.bib} -\usepackage{filecontents} -\begin{filecontents*}{\jobname.bib} -@book{bringhurst04, - title = {The Elements of Typographic Style}, - author = {Robert Bringhurst}, - year = {2004}, - version = {3.2}, - isbn = {978-0-88179-205-5}, - publisher = {Hartley \&\ Marks, Canada} -} -\end{filecontents*} - -\AdaptNoteOpt\footcite\multfootcite - -\newname\bringhurst{Robert Bringhurst} -\newname\lefloch{Bruno Le Floch} - -\begin{document} - -\section{License and Requirements} -\license\ - -\fnpct\ depends on the packages \bnd{l3kernel}~\cite{bnd:l3kernel}, -\pkg{xparse} and \pkg{l3keys2e} from the \bnd{l3packages} -bundle~\cite{bnd:l3packages}, \pkg{scrlfile} from the \KOMAScript\ -bundle~\cite{bnd:koma-script}, and \pkg{translations}~\cite{pkg:translations}. - -\section{What's it all about?} -\subsection{Introduction} -The purpose of this package is to offer kerning for footnote marks, \ie\ the -superscripts. This is not appropriate for all superscripts. Symbols must be -handled differently than numbers. And of course the amount depends on the -chosen font. \bringhurst\ says in \citetitle{bringhurst04}: - -\begin{cnltxquote}[\emph{\citetitle{bringhurst04}} \cite{bringhurst04}] - Superscripts frequently come at the ends of phrases or sentences. If they - are high above the line, they can be kerned over a comma or period, but this - may endanger readability, especially if the text is set in a modest size. -\end{cnltxquote} - -\fnpct\ can not make these decisions for you. It sets some initial values for -the comma and the full stop which looked good to me with the tested fonts. -Additionally it kerns the superscripts away from words when it follows -directly. The amounts of the kerning can be changed using an option. - -As a side effect \fnpct\ switches the order of the superscript and the -following comma or full stop. Additional punctuation marks can be added to -the switching behaviour and the amount of kerning can be set for each -punctuation mark individually. - -\subsection{Basics} -The \fnpct\ package basically does two things to footnotes: if footnote marks -are followed by a comma or a full stop\footnote{More punctuation marks can be - added through a package option.} the order of footnote and punctuation mark -is reversed and the kerning gets adjusted. As a side effect a new method of -creating multiple footnotes\footnote{like;this} is provided, see -section~\ref{sec:multiple} for details. - -In what way is the kerning adjusted? After being placed behind the -punctuation mark the footnote mark is moved a little bit back, namely by the -amount specified with the option \option{after-punct-space} (see -section~\ref{sec:options}). If the footnote mark follows a word -\emph{without} being followed by a punctuation\footnote{Well, it does not - necessarily have to follow a \emph{word}. The important point is \emph{not - being followed} by a punctuation mark.}, there (obviously) is no order -switching and a little space is inserted before the footnote mark, namely the -amount specified by the option \option{before-footnote-space} (see -section~\ref{sec:options}). - -\begin{sourcecode} - \renewcommand\thempfootnote{\arabic{mpfootnote}} -\end{sourcecode} - -Now, let's see some action: -\begin{example} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. - \end{minipage} -\end{example} - -To ensure that the kerning is set the right way the footnote \emph{must} be -placed \emph{before} the full stop or the comma. \emph{The command can look - ahead but not look back}. This means if you place the \cs{footnote} command -after a full stop or a comma it is treated as if following a word, \ie\ a thin -space is inserted: effectively the opposite of the desired behaviour. - -The order-switching can be prevented using a package option since not all -countries and languages have the same typographic conventions. In this case -the full stop and the comma are moved a bit back. - -\begin{figure}[ht] - \centering - \begin{tabular}{>{\setfnpct{dont-mess-around}}ll} - \toprule - without \fnpct & - with \fnpct \\ - \midrule - \strut\quad text.\footnotemark[1] & - \strut\quad text\footnotemark[1]. \\ - \strut\quad text\footnotemark[1]. & - \setfnpct{punct-after}\strut\quad text\footnotemark[1]. \\ - \strut\quad text\footnotemark[1] & - \strut\quad text\footnotemark[1] \\ - \bottomrule - \end{tabular} - \caption{The effect of \fnpct.} -\end{figure} - -\begin{options} - \keybool{punct-after}\Default{false} - When \code{true} the punctuation sign will be placed \emph{after} the - footnote. -\end{options} -Like all options it can also be set using the setup command. -\begin{commands} - \command{setfnpct}[\marg{options}] - Set up options. Can be used anywhere in the document. Some options can - only be set in the preamble, though. -\end{commands} -\begin{example} - \setfnpct{punct-after} - \begin{minipage}{\linewidth} - \noindent The three little pigs built - their houses out of straw\footnote{not - to be confused with hay}, sticks% - \footnote{or lumber according to some - sources} and bricks\footnote{probably - fired clay bricks}. - \end{minipage} -\end{example} - -\subsection{Temporarily disable or enable switching} -One maybe want to put some footnote marks \emph{before} the punctuation and -some after, for example because the first one describes a single word but the -second one a whole sentence. For this purpose \fnpct\ adds a \sarg\ argument -to \cs{footnote} and \cs{footnotemark}. The complete new syntax now is as -follows: -\begin{commands} - \command{footnote}[\sarg\oarg{num>}\marg{footnote text}\meta{tpunct}] - new \sarg\ argument added. \meta{tpunct} is the optional trailing - punctuation mark. - \command{footnotemark}[\sarg\oarg{num>}\meta{tpunct}] - new \sarg\ argument added. \meta{tpunct} is the optional trailing - punctuation mark. -\end{commands} -The \sarg\ argument temporarily turns off the punctuation/footnote switching. -In case you set \keyis{punct-after}{true} the \sarg\ argument temporarily -\emph{enables} the switching. -\begin{example} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote*{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. - \end{minipage}\hfil - \setfnpct{punct-after} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote*{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. - \end{minipage} -\end{example} - -\subsection{Language Specific Settings} -Package \pkg{babel}'s~\cite{pkg:babel} French settings redefine -\cs*{@footnotemark}. \fnpct\ resets this redefinition but sets the -\option{before-footnote-space} equal to a thin space (\code{.16667em}). - -\subsection{Changes in v0.5}\label{ssec:news} - -\begin{itemize} - \item the option \option{bigfoot-default-top} has been removed - \item the \pkg{manyfoot} package is now supported -\end{itemize} - -\section{Options}\label{sec:options} -Most package options are listed below. They all can be set as a package -option or with the \cs{setfnpct} command. Most of them are for adjusting the -kerning. - -\default{Underlined} values are set if the option is used without value. -\begin{options} - \keychoice{add-punct-marks}{\meta{mark}\oarg{space after}\oarg{space before}} - Add another punctuation mark for the position switching and spacify - kerning if necessary. An existing entry will be overwritten. This option - accepts a list of marks. - % - \keyval{remove-punct-marks}{mark} - Remove punctuation mark from the kerning/position switching behaviour. - This option accepts a list of marks. - % - \keyval{after-dot-space}{dim}\Default{-.06em} - Space to be inserted after a footnote mark and before the full stop - (``footnote \emph{after} dot''). A negative space will move the full stop - further to the footnote mark. - % - \keyval{after-comma-space}{dim}\Default{-.06em} - Space to be inserted after a footnote mark and before the comma - (``footnote \emph{after} comma''). A negative space will move the comma - further to the footnote mark. - % - \keyval{after-punct-space}{dim} - Set \emph{all} spaces, \ie\ also the ones for marks you've added with - \option{add-punct-marks}. - % - \keybool{punct-after}\Default{false} - When \code{true} the punctuation sign will be placed \emph{after} the - footnote. - % - \keyval{before-dot-space}{dim}\Default{-.16em} - Space to be inserted after a footnote mark and before the full stop - (``footnote \emph{before} dot''), \ie\ with \keyis{punct-after}{true}. - % - \keyval{before-comma-space}{dim}\Default{-.16em} - space to be inserted after a footnote mark and before the comma - (``footnote \emph{before} comma''), \ie\ with \keyis{punct-after}{true}. - % - \keyval{before-punct-space}{dim} - Set \emph{all} spaces, \ie\ also the ones for marks you've added with - \option{add-punct-marks}. - % - \keyval{before-footnote-space}{dim}\Default{.06em} - Space to be inserted between a word and the following footnote mark. - % - \keybool{dont-mess-around}\Default{false} - Sets all mentioned lengths to \code{0pt} and \keyis{punct-after}{true}. - Basically this should look like as if you hadn't loaded \fnpct\ except the - multiple footnote commands and \cs{innernote} are still available, see - sections~\ref{sec:multiple} and~\ref{sec:nested}, respectively. - % - \keybool{multiple}\Default{false} - Lets \cs{footnote} be equal to \cs{multfootnote}. - % - \keyval{mult-fn-delim}{delimiter}\Default{;} - Sets the delimiter for the \cs{multfootnote} command. - % - \keyval{mult-fn-sep}{separator}\Default{,} - Sets the separator between multiple footnote marks. - % - \keybool{normal-marks}\Default{false}\label{opt:normal-marks} - Sets the footnote marks in the foot not as superscripts but as normal - font. If you're not using a \KOMAScript\ class this option will load - the package \pkg{scrextend}. See section~\ref{sec:normal} for more - information. \emph{This option can only be set in the preamble}. -\end{options} - -So if you want to extend the punctuation switching and kerning to other punctuation -marks you can do something like this: -\begin{example} - \setfnpct{add-punct-marks=!?} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}? - Sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}! - \end{minipage} -\end{example} - -Or with some additional spacing: -\begin{example} - \setfnpct{add-punct-marks=![.03em]?[.03em]} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}? - Sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}! - \end{minipage} -\end{example} - -Let's take a look at an example with some ridiculous settings: -\begin{example} - % some ridiculous settings: - \setfnpct{after-punct-space=2pt,before-footnote-space=2pt} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. - \end{minipage} -\end{example} - -And now the same with switched order: -\begin{example} - % some ridiculous settings: - \setfnpct{punct-after,before-punct-space=2pt,before-footnote-space=2pt} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. - \end{minipage} -\end{example} - -In case the automatic kerning doesn't work for whatever reason the spaces are -available as user commands as well: -\begin{commands} - \command{kfp} - Insert \option{after-dot-space} or (if \keyis{punct-after}{true}) - \option{before-dot-space}. - \command{kfc} - Insert \option{after-comma-space} or (if \keyis{punct-after}{true}) - \option{before-comma-space}. -\end{commands} - -Some of the options are explained in a bit more detail in the next sections. - -\section{Multiple footnotes}\label{sec:multiple} -\subsection{Basics} -Since multiple footnotes have to be treated differently\footnote{see these - footnotes;for an example}, \fnpct\ provides an extra command for that: -\begin{commands} - \command{multfootnote}[\sarg\Marg{\meta{list};\meta{of};\meta{footnotes}}\meta{tpunct}] - Different footnotes are separated with a semicolon. The \sarg\ turns the - footnote/punctuation switching temporarily off. -\end{commands} -\begin{example} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\multfootnote{probably fired clay bricks;or - something else}. - \end{minipage} -\end{example} - -Every of the items of the list has an optional argument equivalent to the -optional argument of \cs{footnotetext}: -\begin{commands} - \command{multfootnote}[\Marg{\sarg\oarg{mark}\meta{footnote text};\ldots}] - The syntax of \cs{multfootnote}'s footnote text argument. -\end{commands} -\begin{example} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\multfootnote{probably fired clay bricks;[5]or - something else}. - \end{minipage} -\end{example} - -Additionally every item has an optional \sarg\ which only invokes -\cs{footnotetext}. This enables for example to set nested footnotes without -disrupting the multiple setting. The following example is shown in -figure~\ref{fig:nested:mult}: -\begin{example}[compile,float,caption={Nested footnotes.\label{fig:nested:mult}}] - \documentclass{article} - \usepackage[ - paperwidth=.5\textwidth, - paperheight=12\baselineskip, - margin=5pt, - bottom=1.5cm]{geometry} - - \usepackage{fnpct} - - \begin{document} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\multfootnote{probably fired clay bricks% - \footnotemark;*or something else;what do I know}. - \end{document} -\end{example} - -\subsection{The delimiter and separator} -Since the semicolon might be part of the footnote text you might have some -trouble. But there are ways around. Maybe try enclosing it in braces: -\begin{example} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\multfootnote{probably fired clay bricks{;} - or something else;what do I know}. - \end{minipage} -\end{example} - -There also are options which lets you choose the (input) delimiter and the (output) -separator: -\begin{options} - \keyval{mult-fn-delim}{delimiter}\Default{;} - Choose delimiter for the \cs{multfootnote}. - \keyval{mult-fn-sep}{separator}\Default{,} - Choose the separator that is put between footnote marks. -\end{options} -\begin{example} - \setfnpct{mult-fn-delim=//,mult-fn-sep=;} - \begin{minipage}[t]{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\multfootnote{probably fired clay bricks; - or something else//what do I know}. - \end{minipage}\hfil - \setfnpct{mult-fn-delim=;,mult-fn-sep=} - \renewcommand*\thempfootnote{\fnsymbol{mpfootnote}} - \begin{minipage}[t]{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\multfootnote{probably fired clay bricks; - or something else}. - \end{minipage} -\end{example} - -\subsection{Automagic} -If you want you can turn all footnotes into \cs{multfootnote}s. -\begin{options} - \keybool{multiple}\Default{false} - Let \cs{footnote} behave like \cs{multfootnote}. \emph{This option can - only be set in the preamble}. -\end{options} -\begin{example} - % in preamble: \setfnpct{multiple} - % or \usepackage[multiple]{fnpct} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks;or - something else}. - \end{minipage} -\end{example} - -\section{Nested Footnotes}\label{sec:nested} -\fnpct\ provides preliminary support for nested footnotes. There are some -restrictions, though. The command below can be used inside \cs{footnote} and -\cs{multfootnote}, but not inside another \cs{innernote}. \cs{innernote} -really is a ``inner footnote'', it doesn't work with endnotes, for example. -\begin{commands} - \command{innernote}[\sarg\oarg{mark}\marg{text}\meta{tpunct}] - A nested footnote. -\end{commands} -The inner node uses a \cs{footnotemark} internally and the mark will be set -with the definition it has at begin document. - -The output of the following code can be seen in figure~\ref{fig:nested:a}. -\begin{example}[compile,float,caption={\cs*{innernote} example (a)\label{fig:nested:a}}] - \documentclass{article} - \usepackage[ - paperwidth=.5\textwidth, - paperheight=12\baselineskip, - margin=5pt, - bottom=1.5cm]{geometry} - - \usepackage{fnpct} - - \begin{document} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks% - \innernote{or not}}. - \end{document} -\end{example} - -This is especially useful if you have more than one additional footnote inside -a footnote, a case that can't be solved in a satisfying (\ie\ automatic) way -with the method mentioned in section~\ref{sec:multiple}. See -figure~\ref{fig:nested:b} for the output of this code: -\begin{example}[compile,float,caption={\cs*{innernote} example (b)\label{fig:nested:b}}] - \documentclass{article} - \usepackage[ - paperwidth=.5\textwidth, - paperheight=12\baselineskip, - margin=5pt, - bottom=1.5cm]{geometry} - - \usepackage{fnpct} - - \begin{document} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably\innernote{just guessing} - fired clay bricks\innernote{or not}}. - \end{document} -\end{example} - -\cs{innernote} can also be used to escape minipages. In this case use -\cs{innernote} as a replacement for \cs{footnote} and call this command later: -\begin{commands} - \command{writeinnernotes} - Writes all \cs{footnotetext}s to the inner footnotes when invoked. This - is usually done automatically by the \cs{footnote} command but there are - possible needs for it. -\end{commands} -See figure~\ref{fig:nested:c} for the output of the following code: -\begin{example}[compile,float,caption={\cs*{innernote} example (c)\label{fig:nested:c}}] - \documentclass{article} - \usepackage[ - paperwidth=.5\textwidth, - paperheight=12\baselineskip, - margin=5pt, - bottom=1.5cm]{geometry} - - \usepackage{fnpct} - - \begin{document} - \noindent\fbox{% - \begin{minipage}{.9\linewidth} - The three little pigs built their houses - out of straw\innernote{not to be confused with hay}, - sticks\innernote{or lumber according to some sources} - and bricks\innernote{probably}. - \end{minipage}}\writeinnernotes - \end{document} -\end{example} - -\section{Normal notes}\label{sec:normal} -The package option \option{normal-marks} (see p.\,\pageref{opt:normal-marks}) -changes the layout of the footnote marks in the foot by using \KOMAScript's -\cs{deffootnote} command: -\begin{commands} - \command{deffootnote}[\oarg{mark indent}\marg{indent}\marg{par - indent}\marg{format code}] - \KOMAScript's command to define the output of the footnote text in the - foot. -\end{commands} - -The following code is shown in figure~\ref{fig:normal}. -\begin{example}[compile,float,caption={Demonstration of the - \option*{normal-marks} option.\label{fig:normal}}] - \documentclass{article} - \usepackage[ - paperwidth=.5\textwidth, - paperheight=12\baselineskip, - margin=5pt, - bottom=1.5cm]{geometry} - - \usepackage[normal-marks]{fnpct} - - \begin{document} - - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. - - \end{document} -\end{example} - -The three indent values used by \fnpct\ can be changed with the following -options: -\begin{options} - \keyval{normal-mark-width}{dim}\Default{1em} - The width of the box within which the marks are set. - \keyval{normal-indent}{dim}\Default{1.5em} - The indent of each footnote line \emph{except} the first. - \keyval{normal-par-indent}{dim}\Default{1em} - Additional indent of a new paragraph inside the footnote text. -\end{options} - -\section{Other packages}\label{sec:other:packages} -\fnpct\ tries its best to support other footnote and related -packages\footnote{If you find some package missing please let me know.}. Each -of the following subsections is dedicated to one of these packages and if and -how they work together with \fnpct. Fortunately most of them do quite well. - -\subsection{bigfoot and manyfoot}\label{ssec:bigfoot} -The \pkg{bigfoot}~\cite{pkg:bigfoot} package extends the possibilities of the -\pkg{manyfoot} package~\cite{pkg:manyfoot} (see section~\ref{ssec:manyfoot}). -The main visible feature is to use different classes of footnotes which are -typeset in different apparatus on the bottom of the page. - -\fnpct\ is compatible with \pkg{bigfoot}. - -You need to be a bit cautious, though: \emph{verbatim material won't work - inside footnotes anymore}. You can of course use \lefloch's -\pkg{cprotect}~\cite{pkg:cprotect} if you really need verbatim material in -footnotes \emph{and} want to use \fnpct. Since \fnpct\ does not redefine any -\cs{footnotetext} like command it will still work inside one of them. - -For every footnote class defined with \cs*{DeclareNewFootnote} the commands -\cs*{footnote\meta{class}} and \cs*{footnotemark\meta{class}} are redefined -with the starred variant and a \cs*{multfootnote\meta{class}} is defined. The -\option{multiple} option will turn all \cs*{footnote\meta{class}} commands -into the corresponding \cs*{multfootnote\meta{class}}. - -Since this document cannot easily combine \emph{every} footnote package at the -same time for demonstration purposes the following code is shown in -figure~\ref{fig:bigfoot}: -\begin{example}[compile,float,caption={\pkg*{bigfoot} example\label{fig:bigfoot}}] - \documentclass{article} - \usepackage[ - paperwidth=.5\textwidth, - paperheight=12\baselineskip, - margin=5pt, - bottom=1.5cm]{geometry} - - \usepackage{bigfoot} - \usepackage{fnpct} - \setfnpct{multiple} - \DeclareNewFootnote{default} - \DeclareNewFootnote[para]{B}[alph] - - \begin{document} - - \noindent The three little pigs built their houses - out of straw\footnote*{not to be confused with hay% - \footnoteB{let alone grass}}, sticks\footnote{or - lumber according to some sources} and bricks% - \footnote{probably fired clay bricks;or something}. - - \end{document} -\end{example} - -\subsection{endnotes} -The \pkg{endnotes}~\cite{pkg:endnotes} package povides the commands -\cs{endnote} and \cs{endnotemark} which can be used to output all notes at the -end of a chapter, say. - -If the package is loaded both commands are adapted\footnote*{see - section~\ref{sec:adapt} on manual adaption}: -\begin{sourcecode} - % `fnpct' does this for you: - \AdaptNote\endnote\multendnote - \AdaptNoteMark\endnotemark -\end{sourcecode} - -Everything else stays the same: -\begin{example} - \begin{minipage}[t]{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\endnote{not to be confused with hay}, - sticks\endnote{or lumber according to some sources} - and bricks\endnote{probably fired clay bricks}. - - \theendnotes - \end{minipage}\hfil - \begin{minipage}[t]{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\endnote*{not to be confused with hay}, - sticks\endnote{or lumber according to some sources} - and bricks\multendnote{probably fired clay bricks;or - something else}. - - \theendnotes - \end{minipage} -\end{example} - -\subsection{enotez} -The \pkg{enotez}~\cite{pkg:enotez} package povides the command \cs{endnote} -which can be used to output all notes at the end of a chapter, say. - -If the package is loaded the command is adapted\footnote*{see - section~\ref{sec:adapt} on manual adaption}: -\begin{sourcecode} - % `fnpct' does this for you: - \AdaptNote\endnote\multendnote -\end{sourcecode} - -\subsection{fixfoot} -The \pkg{fixfoot}~\cite{pkg:fixfoot} package provides a possibility to create -repeating footnotes. \fnpct\ supports this package provided you take care of -the following: - -\emph{Use \cs{DeclareFixedFootnote} only in the preamble but \emph{after} - loading \fnpct.} - -\cs*{DeclareFixedFootnote}\Marg{\cs*{cs}}\marg{footnote text} is used to store -the \meta{footnote text} in \cs*{cs} which in turn creates a footnote mark for -it but doesn't repeat the footnote text on the same page in the bottom. The -document needs several runs to get all the numbers and footnotes right. - -Every fixed footnote declared with \cs{DeclareFixedFootnote} gets an optional -\sarg\ to prevent the punctuation switching. \emph{There is \emph{no} - mult-variant of the fixed notes!} - -Since this document cannot easily combine \emph{every} footnote package at the -same time for demonstration purposes the following code is shown in -figure~\ref{fig:fixfoot}: -\begin{example}[compile,float,caption={\pkg*{fixfoot} - example\label{fig:fixfoot}}] - \documentclass{article} - \usepackage[ - paperwidth=.55\textwidth, - paperheight=12\baselineskip, - margin=5pt, - bottom=1.5cm]{geometry} - - \usepackage{fixfoot} - \usepackage{fnpct} - - \DeclareFixedFootnote{\myfn}{I'm confused: what do I want to say?} - - \begin{document} - - \noindent The three little pigs\myfn\ built their houses - out of straw\myfn*, sticks\footnote{or lumber according - to some sources} and bricks\footnote{probably fired clay - bricks}. - - \end{document} -\end{example} - -\subsection{footmisc}\label{ssec:footmisc} -The \pkg{footmisc} package~\cite{pkg:footmisc} provides a range of options to -customize footnotes, for example output them as margin notes or count -footnotes per page. - -Testing showed no incompatibilities with \pkg{footmisc}. The only thing is -that you won't have to (and shouldn't) use its \option{multiple} option. - -\subsection{footnote}\label{ssec:footnote} -Unfortunately \fnpct\ is not compatible with the \pkg{footnote} -package~\cite{pkg:footnote}. Or more precisely it is not compatible if the -command pair \cs*{savenotes}/\cs*{spewnotes} is invoked. This disables -\pkg{footnote}'s environments as well as its environment escaping mechanism -through \cs{makesavenoteenv}. - -\subsection{manyfoot}\label{ssec:manyfoot} -The package \pkg{manyfoot}~\cite{pkg:manyfoot} is supported. See -section~\ref{ssec:bigfoot} for more details. - -\subsection{pagenote}\label{ssec:pagenote} -The package \pkg{pagenote}~\cite{pkg:pagenote} is supported and its -\cs*{pagenote} command is treated the same way as all other note commands: it -got an optional \sarg\ argument and an additional \cs*{multpagenote} is -defined. - -\subsection{parnotes}\label{ssec:parnotes} -The function of the package \pkg{parnotes}~\cite{pkg:parnotes} is similar to the -\pkg{endnotes} package. basically it allows to output the footnote text after -a paragraph, either by using a special environment or by invoking -\cs*{parnotes}. - -If \pkg{parnotes} is loaded \fnpct\ extends its functionality analogous to the -one of \pkg{endnotes}. - -Again the \option{multiple} option turns all \cs*{parnote}s into -\cs*{multparnote}s. -\begin{example} - \begin{minipage}[t]{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\parnote{not to be confused with hay}, - sticks\parnote{or lumber according to some sources} - and bricks\parnote{probably fired clay bricks}. - - \parnotes - \end{minipage}\hfil - \begin{minipage}[t]{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\parnote*{not to be confused with hay}, - sticks\parnote{or lumber according to some sources} - and bricks\multparnote{probably fired clay bricks;or - something else}. - - \parnotes - \end{minipage} -\end{example} - -\subsection{sepfootnotes}\label{ssec:sepfootnotes} -\fnpct\ supports the \pkg{sepfootnotes} package~\cite{pkg:sepfootnotes}. Each -note type you have created with with one of the commands -\begin{description} - \item \cs*{newfootnotes}\marg{prefix}, - \item \cs*{newendnotes}\marg{prefix} or - \item \cs*{newsymbolfootnotes}\marg{prefix} -\end{description} -gets the additional optional \sarg\ to prevent punctuation switching. Also -the corresponding mult-variant \cs*{\meta{prefix}multnote} is defined. The -option \option{multiple} again turns all note commands into their -mult-variant. - -You have to use the \cs*{newfootnotes} commands in the document preamble after -loading \fnpct. - -\begin{example} - % preamble \newfootnotes{a} - \anotecontent{first}{not to be confused with hay} - \anotecontent{second}{or lumber according to some sources} - \anotecontent{third}{probably fired clay bricks} - \begin{minipage}{.4\linewidth} - \noindent The three little pigs built their houses - out of straw\anote{first}, sticks\anote{second} and - bricks\anote{third}. - \end{minipage} -\end{example} - -\subsection{sidenotes}\label{ssec:sidenotes} -The package \pkg{sidenotes}~\cite{pkg:sidenotes} is \emph{not} supported. -For the time being users can use the following code\footnote{Since the code - depends on the implementation of \pkg{sidenotes} this may break with each - update of \pkg{sidenotes}.;Thanks to Marijn van Vliet for - providing it!}: -\begin{sourcecode} - \ExplSyntaxOn - \makeatletter - \NewDocumentCommand \origsidenotemark {o} - { - \@sidenotes@multichecker - \IfNoValueOrEmptyTF {#1} - { \@sidenotes@thesidenotemark { \thesidenote } } - { \@sidenotes@thesidenotemark {#1} } - \@sidenotes@multimarker - } - - \NewDocumentCommand \origsidenote {oo+m} - { - \origsidenotemark [#1] - \sidenotetext [#1] [#2] {#3} - \@sidenotes@multimarker - } - - \fnpct_create_mult_variant:NN \multsidenote \origsidenote - - \RenewDocumentCommand \sidenote {soo+m} - { \fnpct_handle_note:Nnnnn \origsidenote {#2} {#3} {#4} {#1} } - - \RenewDocumentCommand \sidenotemark {so} - { \fnpct_handle_note:Nnnnn \origsidenotemark {#2} { \q_no_value } { } {#1} } - \makeatother - \ExplSyntaxOff -\end{sourcecode} - -\subsection{snotez}\label{ssec:snotez} -The package \pkg{snotez}~\cite{pkg:snotez} is supported and its commands -\cs*{sidenote} and \cs*{sidenotemark} are treated the same way as footnotes: -they got an optional \sarg\ argument and the additional \cs*{multsidenote} is -created. The option \option{multiple} turns all note commands into their -mult-variant. - -\subsection{tablefootnote}\label{ssec:tablefootnote} -The package \pkg{tablefootnote}~\cite{pkg:tablefootnote} is supported and its -\cs*{tablefootnote} command is treated the same way as all other note -commands: it got an optional \sarg\ argument and an additional -\cs*{multtablefootnote} is defined. The option \option{multiple} turns all -note commands into their mult-variant. - -\subsection{yafoot}\label{ssec:yafoot} -Currently no issues are known when using \fnpct\ with one or all of the -packages of the \bnd{yafoot}~\cite{bnd:yafoot} bundle. Just for reference: -these packages are \pkg*{pfnote}, \pkg*{fnpos} and \pkg*{dblfnote}. - -\section{Adapting note commands}\label{sec:adapt} -If a package is not natively supported you can try and adapt commands yourself. -You'll need to use one of the following commands. Please be aware that if the -adapted command does not match the required syntax it will get the required syntax -afterwards. This can result in dummy arguments or an overwritten \code{*} argument. - -\begin{commands} - % \AdaptNote - \command{AdaptNote}[\Marg{\cs*{cs}}\Marg{\cs*{multcs}}] - This lets \cs*{cs} adapt to the kerning behaviour and adds an optional - \sarg. It also creates a corresponding mult-variant. The package option - \option{multiple} will now turn \cs*{cs} into its mult-variant. Required - syntax: \cs*{cs}\oarg{oarg}\marg{marg} - % \AdaptNoteNoMult - \command{AdaptNoteNoMult}[\Marg{\cs*{cs}}] - Like \cs{AdaptNote} but doesn't create a mult-variant and thus there is no - change in behaviour when the option \option{multiple} is used. Required - syntax: \cs*{cs}\oarg{oarg}\marg{marg} - % \AdaptNoteOpt - \command{AdaptNoteOpt}[\Marg{\cs*{cs}}\Marg{\cs*{multcs}}] - This lets \cs*{cs} adapt to the kerning behaviour and adds an optional - \sarg. It also creates a corresponding mult-variant. The package option - \option{multiple} will now turn \cs*{cs} into its mult-variant. Required - syntax: \cs*{cs}\oarg{oarg}\oarg{oarg}\marg{marg} - % \AdaptNoteOptNoMult - \command{AdaptNoteOptNoMult}[\Marg{\cs*{cs}}] - Like \cs{AdaptNoteOpt} but doesn't create a mult-variant and thus there is - no change in behaviour when the option \option{multiple} is used. - Required syntax: \cs*{cs}\oarg{oarg}\oarg{oarg}\marg{marg} - % \AdaptNoteNoOpt - \command{AdaptNoteNoOpt}[\Marg{\cs*{cs}}\Marg{\cs*{multcs}}] - \sinceversion{0.3}Like \cs{AdaptNote} but requires \cs*{cs} not to have an - optional argument. If it had one it wouldn't have it any more after the - adaption. The package option \option{multiple} will now turn \cs*{cs} - into its mult-variant. Required syntax: \cs*{cs}\marg{marg} - % \AdaptNoteNoOptNoMult - \command{AdaptNoteNoOptNoMult}[\Marg{\cs*{cs}}] - \sinceversion{0.3}Like \cs{AdaptNoteNoOpt} but doesn't create a - mult-variant. Required syntax: \cs*{cs}\Marg{marg} - % \AdaptNoteMark - \command{AdaptNoteMark}[\Marg{\cs*{cs}}] - This lets \cs*{cs} adapt to the kerning behaviour and adds an optional - \sarg. Required syntax: \cs*{cs}\oarg{oarg} - % strict -\end{commands} -\begin{options} - \keybool{strict}\Default{false} When \code{true} - \cs{AdaptNote} (and the others) will issue errors if the note command in - question has already been adapted. -\end{options} - -\subsection{tufte-latex's side notes} -For example using the \cs{sidenote} command from the \cls*{tufte-handout} -class is easily possible, see also figure~\ref{fig:tufte}: -\begin{example}[compile,float,caption={Adapt - \bnd*{tufte-latex}.\label{fig:tufte}},graphics={trim=2.5cm 24.5cm 2cm - 1cm,scale=.65}] - \documentclass{tufte-handout} - \usepackage[multiple]{fnpct} - \AdaptNote\sidenote\multsidenote - \begin{document} - Some text in the document body\sidenote{Some - text in a sidenote.;A second sidenote.}. - \end{document} -\end{example} - -\subsection{Adapting \cs*{footcite} and siblings}\label{ssec:adapt:footcite} -If you're willing to sacrifice \cs*{footcite}'s \sarg\ argument (which it has -in some styles) you can adapt the commands provided by -\pkg{biblatex}~\cite{pkg:biblatex} as well: - -\begin{example} - % used in preamble: \AdaptNoteOpt\footcite\multfootcite - \begin{minipage}{.5\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. The - companion has nothing on this topic\multfootcite{[see] - [but there's nothing there]companion;[or see][but there's - also nothing]knuth:ct:a}. - \end{minipage} -\end{example} - -The option \option{multiple} turns all \cs*{footcite}s into -\cs*{multfootcite}s now. Remember that the optional arguments then are inside -the braces! - -\begin{example} - % used in preamble: \AdaptNoteOpt\footcite\multfootcite - % with option `multiple': - \begin{minipage}{.5\linewidth} - \noindent The three little pigs built their houses - out of straw\footnote{not to be confused with hay}, - sticks\footnote{or lumber according to some sources} - and bricks\footnote{probably fired clay bricks}. The - companion has nothing on this topic\footcite{[see][but - there's nothing there]companion;[or see][but there's also - nothing]knuth:ct:a}. - \end{minipage} -\end{example} - - -\appendix - -\end{document} - -% TODO: update documentation and explain what happens when babel's french is -% used -- cgit v1.2.3