summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-10-23 03:02:00 +0000
committerNorbert Preining <norbert@preining.info>2020-10-23 03:02:00 +0000
commitc6303e38664a7a78e8f21a4390b69e5aa9cf5c93 (patch)
treeb95dddc8dde54ba0f7189d0edaf24877d61bb44b /macros
parent7448609d1256af02966b8f84fe8464234276ce7a (diff)
CTAN sync 202010230301
Diffstat (limited to 'macros')
-rw-r--r--macros/latex/contrib/askmaps/README6
-rw-r--r--macros/latex/contrib/askmaps/askmaps.pdfbin308877 -> 377937 bytes
-rw-r--r--macros/latex/contrib/askmaps/askmaps.sty571
-rw-r--r--macros/latex/contrib/askmaps/askmaps.tex870
-rw-r--r--macros/latex/contrib/ejpecp/README.md2
-rw-r--r--macros/latex/contrib/ejpecp/ejpecp.dtx25
-rw-r--r--macros/latex/contrib/ejpecp/ejpecp.pdfbin180717 -> 180735 bytes
-rw-r--r--macros/latex/contrib/ejpecp/getmref.py1809
-rw-r--r--macros/latex/contrib/ejpecp/mgetmref.py401
-rw-r--r--macros/latex/contrib/ejpecp/sample.pdfbin155832 -> 155933 bytes
-rw-r--r--macros/latex/contrib/ejpecp/sample.tex17
-rw-r--r--macros/latex/contrib/fgruler/README2
-rw-r--r--macros/latex/contrib/fgruler/fgruler.dtx45
-rw-r--r--macros/latex/contrib/fgruler/fgruler.ins4
-rw-r--r--macros/latex/contrib/fgruler/fgruler.pdfbin252700 -> 259375 bytes
-rw-r--r--macros/latex/contrib/hu-berlin-bundle/README.md5
-rw-r--r--macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.dtx34
-rw-r--r--macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.pdfbin307158 -> 367917 bytes
-rw-r--r--macros/latex/contrib/scrlttr2copy/README.md8
-rw-r--r--macros/latex/contrib/scrlttr2copy/copy.lco81
-rw-r--r--macros/latex/contrib/scrlttr2copy/letter-copy-test.pdfbin88554 -> 88546 bytes
-rw-r--r--macros/latex/contrib/scrlttr2copy/letter-copy-test.tex11
-rw-r--r--macros/latex/contrib/skills/README.md21
-rw-r--r--macros/latex/contrib/skills/skills.sty325
-rw-r--r--macros/latex/contrib/skills/skillsdoc.pdfbin0 -> 68738 bytes
-rw-r--r--macros/latex/contrib/skills/skillsdoc.tex733
-rw-r--r--macros/latex/contrib/snapshot/README126
-rw-r--r--macros/latex/contrib/snapshot/snapshot.dtx920
-rw-r--r--macros/latex/contrib/snapshot/snapshot.ins8
-rw-r--r--macros/latex/contrib/snapshot/snapshot.pdfbin193747 -> 236859 bytes
30 files changed, 4862 insertions, 1162 deletions
diff --git a/macros/latex/contrib/askmaps/README b/macros/latex/contrib/askmaps/README
index 24ec177312..ffa35746c8 100644
--- a/macros/latex/contrib/askmaps/README
+++ b/macros/latex/contrib/askmaps/README
@@ -9,7 +9,9 @@ askmaps.pdf - PDF version of the documentation
The Karnaugh maps are rendered with picture commands; only the pict2e package
is loaded.
-Current version is 0.1. At this point, only 2-5 variable Karnaugh maps
+The Tikz package can be used to shape the Karnaugh maps as pleased.
+
+Current version is 0.2. At this point, only 1-5 variable Karnaugh maps
are supported. People familiar with the Karnaugh package should have
no problem in using the macros in this package.
@@ -18,4 +20,4 @@ Suggestions and bug reports are welcome at J.E.J.opdenBrouw@hhs.nl
Happy TeX-ing!
Jesse op den Brouw
- 2013/12/04
+ 2020/10/23
diff --git a/macros/latex/contrib/askmaps/askmaps.pdf b/macros/latex/contrib/askmaps/askmaps.pdf
index b6803c7472..8cac0e43d3 100644
--- a/macros/latex/contrib/askmaps/askmaps.pdf
+++ b/macros/latex/contrib/askmaps/askmaps.pdf
Binary files differ
diff --git a/macros/latex/contrib/askmaps/askmaps.sty b/macros/latex/contrib/askmaps/askmaps.sty
index 9ff0122fbb..ab77400992 100644
--- a/macros/latex/contrib/askmaps/askmaps.sty
+++ b/macros/latex/contrib/askmaps/askmaps.sty
@@ -1,34 +1,62 @@
%%
%% askmaps.sty
%%
-%% American Style K-maps (2, 3, 4 and 5 variables)
+%% American Style K-maps (1, 2, 3, 4 and 5 variables)
%%
-%% (c)2013 Jesse op den Brouw, <J.E.J.opdenBrouw@hhs.nl>
+%% (c)2020 Jesse op den Brouw, <J.E.J.opdenBrouw@hhs.nl>
%%
%% LPPL LaTeX Public Project License
+%%
+%%
+%% Original rel 0.1 : 2013-12-04
+%% Update rel 0.2 : 2020-10-23
+%% added option oldstylef
+%% added option newstylef
+%% added askmapi - a K-map for one variable
+%% added askmapiiialt - alternate (vertical) version op K-map III
+%% added formatting index size, contents size and bit combination size.
+%% added support for \kvindex and \nokvindex macros when kvmacros.tex is
+%% loaded
+%% added formatting for left-placed variables
+%% implemented a debug possibility
+%% implemented linelength of variable separator
+%% resolved an issue with multiple overfull \hbox'es
+%% added a section on creating covers
+%% changed the use of \askmapindexsize et al. to include the size and
+%% shape of the fonts used
+%%
%%
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
%% Version and date
-\gdef\askmapsversion{0.1}
-\gdef\askmapsdate{2013/12/04}
+\gdef\askmapsversion{0.2}
+\gdef\askmapsdate{2020/10/23}
%
\ProvidesPackage{askmaps}[\askmapsdate\space Version \askmapsversion\space
LaTeX package for drawing American Style Karnaugh maps]
-%% This package provides 2, 3, 4 and 5 variable Karnaugh maps that can
+%% This package provides 1, 2, 3, 4 and 5 variable Karnaugh maps that can
%% be found in numerous american text books on digital design. Note
%% that it is possible to draw many different K-maps that are all
%% legitimate as long as a square (minterm) differs only in one
-%% literal with its adjacent squares.
+%% literal with its adjacent squares. There is an alternate form of the
+%% 3 variable K-map available.
%% This package draws K-maps where the most significant input variables
%% are placed on top of the columns and the least significant variables
-%% are placed left of the rows. Such K-maps can be found in the text books:
-%% Design of Logic Systems, 2nd, Lewin & Protheroe
-%% Digital System Design with VHDL, 2nd, Zwolinski
+%% are placed left of the rows.
%% Packages needed
\RequirePackage{pict2e}
+%% Get the only possible option
+\newcommand{\askmap@usecapf}{\askmap@optftrue}
+\DeclareOption{disablef}{\renewcommand{\askmap@usecapf}{\askmap@optffalse}}
+\DeclareOption*{\PackageWarning{askmaps}{Unknown '\CurrentOption' in package askmaps}}
+\ProcessOptions\relax
+
+%% For debugging purposes, currently draw rectangles around the maps
+%% Use only for debugging purposes
+\newif\ifaskmap@debug\askmap@debugfalse
+
%% The macros \askmapargumentstring, \askmapgetchar and \askmapgetonechar are
%% needed to process the variable-length parameters in \askmapxxx:
%% These routine politely reused from karnaugh package
@@ -40,17 +68,23 @@
\newdimen\askmapunitlength
\askmapunitlength=10mm
+%% The sizes (and shapes) of the text in the maps
+\newcommand{\askmapindexsize}{\scriptsize\slshape}
+\newcommand{\askmapcontentsize}{\normalsize}
+\newcommand{\askmapbitcombinationsize}{\footnotesize}
+
+%% Length of the line separating the input variables top-right and
+%% middle-left
+\newcommand{\askmapvarsep}{0.70}
+
%% Some use options
\newif\ifaskmap@opti% want indexes
\newif\ifaskmap@optf% want output function printed
\newif\ifaskmap@optb% want input variable bit combinations at columns and rows
-%% We want bit combinations along with the columns and rows
-%\askmap@optbtrue
-
%% Process user options
\def\askmap@processoptions#1{%
- \askmap@optifalse\askmap@optftrue\askmap@optbtrue%
+ \askmap@optifalse\askmap@usecapf\askmap@optbtrue%
\@tfor\askmap@opt:=#1\do{%
\if i\askmap@opt\askmap@optitrue\fi%
\if I\askmap@opt\askmap@optifalse\fi%
@@ -69,27 +103,82 @@
%% #3 = function input variables
%% #4 = list of function values
%% #5 = user picture commands
+%\newcommand{\askmap}[5]{}%
+% Starred version or not
+%\@ifstar{\gdef\askmap@printoutputname{f}\askmap@askmap}{\gdef\askmap@printoutputname{F}\askmap@askmap}%
+%}
+%\newcommand{\askmap@askmap}[5]{%
\newcommand{\askmap}[5]{%
-\if 2#1\relax
- \askmapii{#2}{#3}{f}{#4}{#5}%
+\def\askmap@printoutputname{f}
+%% Check if the \kvcurrentindex is set to using indexes
+\def\askmap@printindex{i}
+\ifx\kvcurrentindex\undefined
+\def\askmap@printindex{I}
\else
- \if 3#1\relax
- \askmapiii{#2}{#3}{f}{#4}{#5}%
- \else
- \if 4#1\relax
- \askmapiv{#2}{#3}{f}{#4}{#5}%
- \else
- \if 5#1\relax
- \askmapv{#2}{#3}{f}{#4}{#5}%
- \else
- \PackageWarning{askmaps}{Sorry, no K-maps with #1 variables supported by package askmaps!}
- \fi%
- \fi%
- \fi%
-\fi%
+\ifx\kvcurrentindex\empty
+\def\askmap@printindex{I}
+\fi
+\fi
+%% Sort out the 'call' to the right macro
+\ifcase#1\relax
+ \PackageWarning{askmaps}{Sorry, no K-maps with #1 variables supported by
+package askmaps!}
+\or
+ \askmapi{#2}{#3}{\askmap@printoutputname\askmap@printindex}{#4}{#5}%
+\or
+ \askmapii{#2}{#3}{\askmap@printoutputname\askmap@printindex}{#4}{#5}%
+\or
+ \askmapiii{#2}{#3}{\askmap@printoutputname\askmap@printindex}{#4}{#5}%
+\or
+ \askmapiv{#2}{#3}{\askmap@printoutputname\askmap@printindex}{#4}{#5}%
+\or
+ \askmapv{#2}{#3}{\askmap@printoutputname\askmap@printindex}{#4}{#5}%
+\else
+ \PackageWarning{askmaps}{Sorry, no K-maps with #1 variables supported by
+package askmaps!}
+\fi
}%
%% #1= output function variable
+%% #2= 1 input variable
+%% #3= options list
+%% #4= 2 function values
+%% #5= user defined picture commands
+\newcommand{\askmapi}[5]{%
+{\unitlength\askmapunitlength%
+\askmap@processoptions{#3}%
+\ifaskmap@debug\fboxsep0pt\fbox{\else\fi%
+\begin{picture}(4.4,2)(-1.2,0)%
+\linethickness{1pt}%
+\put(0,0){\framebox(2,1){}}%
+\put(1,0){\line(0,1){1}}%
+\ifaskmap@optf%
+\put(2.35,1.25){\askmapcontentsize#1}%
+\put(1.9,0.9){\line(1,1){0.4}}%
+\fi%
+\askmapargumentstring{#2}%
+\put(-0.4,1.55){\askmapcontentsize\askmapgetchar}%
+\ifaskmap@opti%
+\put(0.01,0.03){\askmapindexsize 0}%
+\put(1.03,0.03){\askmapindexsize 1}%
+\fi%
+\ifaskmap@optb%
+\put(0.5,1.1){\makebox(0,0)[b]{\askmapbitcombinationsize 0}}%
+\put(1.5,1.1){\makebox(0,0)[b]{\askmapbitcombinationsize 1}}%
+\fi%
+\askmapargumentstring{#4}%
+\put(0.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\thicklines%
+\put(0,1){\line(-1,1){\askmapvarsep}}%
+\thinlines%
+#5%
+\end{picture}%
+\ifaskmap@debug}\else\fi%
+}%
+}% end \askmapi
+
+%% #1= output function variable
%% #2= 2 input variables
%% #3= options list
%% #4= 4 function values
@@ -97,42 +186,47 @@
\newcommand{\askmapii}[5]{%
{\unitlength\askmapunitlength%
\askmap@processoptions{#3}%
+\ifaskmap@debug\fboxsep0pt\fbox{\else\fi%
\begin{picture}(4.4,3)(-1.2,0)%
\linethickness{1pt}%
-\put(0,0){\framebox(2,2)}%
+\put(0,0){\framebox(2,2){}}%
\put(1,0){\line(0,1){2}}%
\put(0,1){\line(1,0){2}}%
\ifaskmap@optf%
-\put(2.35,2.25){#1}%
+\put(2.35,2.25){\askmapcontentsize#1}%
\put(1.9,1.9){\line(1,1){0.4}}%
\fi%
\askmapargumentstring{#2}%
-\put(-0.4,2.55){\askmapgetchar}%
-\put(-0.9,2.1){\makebox(0.5,0){\askmapgetchar}}%
+\put(-0.4,2.55){\askmapcontentsize\askmapgetchar}%
+%\put(-0.9,2.1){\askmapcontentsize\askmapgetchar}%
+%\put(-1.0,1.9){\framebox(0.5,0.5)[r]{\askmapcontentsize\askmapgetchar}}%
+\put(-0.5,2.1){\makebox(0.0,0.0)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+%\put(-0.9,2.1){\makebox(0.5,0){\askmapcontentsize\askmapgetchar}}%
\ifaskmap@opti%
-\put(0.01,1.05){\scriptsize{\textsl{0}}}% a little bit to the edge because
-\put(0.01,0.03){\scriptsize{\textsl{1}}}% the edge line is thick
-\put(1.03,1.05){\scriptsize{\textsl{2}}}%
-\put(1.03,0.03){\scriptsize{\textsl{3}}}%
+\put(0.01,1.05){\askmapindexsize 0}% a little bit to the edge because
+\put(0.01,0.03){\askmapindexsize 1}% the edge line is thick
+\put(1.03,1.05){\askmapindexsize 2}%
+\put(1.03,0.03){\askmapindexsize 3}%
\fi%
\ifaskmap@optb%
-\put(-0.6,1.5){\makebox(0.5,0)[r]{\footnotesize{0}}}%
-\put(-0.6,0.5){\makebox(0.5,0)[r]{\footnotesize{1}}}%
-\put(0.5,2.2){\makebox(0,0){\footnotesize{0}}}%
-\put(1.5,2.2){\makebox(0,0){\footnotesize{1}}}%
+\put(-0.6,1.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 0}}%
+\put(-0.6,0.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 1}}%
+\put(0.5,2.1){\makebox(0,0)[b]{\askmapbitcombinationsize 0}}%
+\put(1.5,2.1){\makebox(0,0)[b]{\askmapbitcombinationsize 1}}%
\fi%
\askmapargumentstring{#4}%
-\put(0.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,0.5){\makebox(0,0){\askmapgetchar}}%
+\put(0.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
\thicklines%
-\put(0,2){\line(-1,1){0.70}}%
+\put(0,2){\line(-1,1){\askmapvarsep}}%
\thinlines%
#5%
\end{picture}%
-}%
+\ifaskmap@debug}\else\fi%
}% end \askmapii
+}
%% #1= output function variable
%% #2= 3 input variables
@@ -142,50 +236,58 @@
\newcommand{\askmapiii}[5]{%
{\unitlength\askmapunitlength%
\askmap@processoptions{#3}%
+\ifaskmap@debug\fboxsep0pt\fbox{\else\fi%
\begin{picture}(6.4,3)(-1.2,0)%
\linethickness{1pt}%
-\put(0,0){\framebox(4,2)}%
+\put(0,0){\framebox(4,2){}}%
\multiput(1,0)(1,0){3}{\line(0,1){2}}%
\put(0,1){\line(1,0){4}}%
\ifaskmap@optf%
-\put(4.35,2.25){#1}%
+\put(4.35,2.25){\askmapcontentsize#1}%
\put(3.9,1.9){\line(1,1){0.4}}%
\fi%
\askmapargumentstring{#2}%
-\put(-0.4,2.55){\askmapgetchar\askmapgetchar}%
-\put(-0.9,2.1){\makebox(0.5,0){\askmapgetchar}}%
+\put(-0.4,2.55){\askmapcontentsize\askmapgetchar\askmapgetchar}%
+%\put(-0.9,2.1){\framebox(0.5,0.5)[rt]{\askmapcontentsize\askmapgetchar}}%
+%\put(-1.0,1.9){\framebox(0.5,0.5)[rt]{\askmapcontentsize\askmapgetchar}}%
+%\put(-1.0,1.9){\framebox(0.5,0.5)[r]{\askmapcontentsize\askmapgetchar}}%
+%\put(-0.9,2.1){\askmapcontentsize\askmapgetchar}%
+%\put(-0.9,2.1){\makebox(0.5,0){\askmapcontentsize\askmapgetchar}}%
+\put(-0.5,2.1){\makebox(0.0,0.0)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+%\put(-1.0,1.9){\makebox(0.5,0.45)[rt]{\askmapcontentsize\askmapgetchar}}%
\ifaskmap@opti%
-\put(0.01,1.05){\scriptsize{\textsl{0}}}%
-\put(0.01,0.03){\scriptsize{\textsl{1}}}%
-\put(1.03,1.05){\scriptsize{\textsl{2}}}%
-\put(1.03,0.03){\scriptsize{\textsl{3}}}%
-\put(3.03,1.05){\scriptsize{\textsl{4}}}%
-\put(3.03,0.03){\scriptsize{\textsl{5}}}%
-\put(2.03,1.05){\scriptsize{\textsl{6}}}%
-\put(2.03,0.03){\scriptsize{\textsl{7}}}%
+\put(0.01,1.05){\askmapindexsize 0}%
+\put(0.01,0.03){\askmapindexsize 1}%
+\put(1.03,1.05){\askmapindexsize 2}%
+\put(1.03,0.03){\askmapindexsize 3}%
+\put(3.03,1.05){\askmapindexsize 4}%
+\put(3.03,0.03){\askmapindexsize 5}%
+\put(2.03,1.05){\askmapindexsize 6}%
+\put(2.03,0.03){\askmapindexsize 7}%
\fi%
\askmapargumentstring{#4}%
-\put(0.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,0.5){\makebox(0,0){\askmapgetchar}}%
+\put(0.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
\ifaskmap@optb%
-\put(-0.6,1.5){\makebox(0.5,0)[r]{\footnotesize{0}}}%
-\put(-0.6,0.5){\makebox(0.5,0)[r]{\footnotesize{1}}}%
-\put(0.5,2.2){\makebox(0,0){\footnotesize{00}}}%
-\put(1.5,2.2){\makebox(0,0){\footnotesize{01}}}%
-\put(2.5,2.2){\makebox(0,0){\footnotesize{11}}}%
-\put(3.5,2.2){\makebox(0,0){\footnotesize{10}}}%
+\put(-0.6,1.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 0}}%
+\put(-0.6,0.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 1}}%
+\put(0.5,2.1){\makebox(0,0)[b]{\askmapbitcombinationsize 00}}%
+\put(1.5,2.1){\makebox(0,0)[b]{\askmapbitcombinationsize 01}}%
+\put(2.5,2.1){\makebox(0,0)[b]{\askmapbitcombinationsize 11}}%
+\put(3.5,2.1){\makebox(0,0)[b]{\askmapbitcombinationsize 10}}%
\fi%
\thicklines%
-\put(0,2){\line(-1,1){0.70}}%
+\put(0,2){\line(-1,1){\askmapvarsep}}%
\thinlines%
#5%
\end{picture}%
+\ifaskmap@debug}\else\fi%
}%
}% end \askmapiii
@@ -194,71 +296,135 @@
%% #3= options list
%% #4= 16 function values
%% #5= user defined picture commands
+\newcommand{\askmapiiialt}[5]{%
+{\unitlength\askmapunitlength%
+\askmap@processoptions{#3}%
+\ifaskmap@debug\fboxsep0pt\fbox{\else\fi%
+\begin{picture}(4.4,5)(-1.2,0)%
+\linethickness{1pt}%
+\put(0,0){\framebox(2,4){}}%
+\put(1,0){\line(0,1){4}}%
+\multiput(0,1)(0,1){3}{\line(1,0){2}}%
+\ifaskmap@optf%
+\put(2.35,4.25){\askmapcontentsize#1}%
+\put(1.9,3.9){\line(1,1){0.4}}%
+\fi%
+\askmapargumentstring{#2}%
+\put(-0.4,4.55){\askmapcontentsize\askmapgetchar}%
+%\put(-1.0,4.1){\framebox(0.5,0){\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+%\put(-1.0,3.9){\framebox(0.5,0.5)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+\put(-0.5,4.1){\makebox(0.0,0.0)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+%\put(-0.9,4.1){\makebox(0.5,0){\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+\ifaskmap@opti%
+\put(0.01,3.05){\askmapindexsize 0}%
+\put(0.01,2.05){\askmapindexsize 1}%
+\put(0.01,0.03){\askmapindexsize 2}%
+\put(0.01,1.05){\askmapindexsize 3}%
+\put(1.03,3.05){\askmapindexsize 4}%
+\put(1.03,2.05){\askmapindexsize 5}%
+\put(1.03,0.03){\askmapindexsize 6}%
+\put(1.03,1.05){\askmapindexsize 7}%
+\fi%
+\askmapargumentstring{#4}%
+\put(0.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\ifaskmap@optb%
+\put(-0.6,3.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 00}}%
+\put(-0.6,2.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 01}}%
+\put(-0.6,1.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 11}}%
+\put(-0.6,0.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 10}}%
+\put(0.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 0}}%
+\put(1.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 1}}%
+\fi
+\thicklines%
+\put(0,4){\line(-1,1){\askmapvarsep}}%
+\thinlines%
+#5%
+\end{picture}%
+\ifaskmap@debug}\else\fi%
+}%
+}% end \askmapiiialt
+
+%% #1= output function variable
+%% #2= 4 input variables
+%% #3= options list
+%% #4= 16 function values
+%% #5= user defined picture commands
\newcommand{\askmapiv}[5]{%
{\unitlength\askmapunitlength%
\askmap@processoptions{#3}%
+\ifaskmap@debug\fboxsep0pt\fbox{\else\fi%
\begin{picture}(6.4,5)(-1.2,0)%
\linethickness{1pt}%
-\put(0,0){\framebox(4,4)}%
+\put(0,0){\framebox(4,4){}}%
\multiput(1,0)(1,0){3}{\line(0,1){4}}%
\multiput(0,1)(0,1){3}{\line(1,0){4}}%
\ifaskmap@optf%
-\put(4.35,4.25){#1}%
+\put(4.35,4.25){\askmapcontentsize#1}%
\put(3.9,3.9){\line(1,1){0.4}}%
\fi%
\askmapargumentstring{#2}%
-\put(-0.4,4.55){\askmapgetchar\askmapgetchar}%
-\put(-1.0,4.1){\makebox(0.5,0){\askmapgetchar\askmapgetchar}}%
+\put(-0.4,4.55){\askmapcontentsize\askmapgetchar\askmapgetchar}%
+%\put(-1.0,4.1){\framebox(0.5,0){\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+\put(-0.5,4.1){\makebox(0.0,0.0)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+%\put(-1.0,4.1){\makebox(0.5,0){\askmapcontentsize\askmapgetchar\askmapgetchar}}%
\ifaskmap@opti%
-\put(0.01,3.05){\scriptsize{\textsl{0}}}%
-\put(0.01,2.05){\scriptsize{\textsl{1}}}%
-\put(0.01,0.03){\scriptsize{\textsl{2}}}%
-\put(0.01,1.05){\scriptsize{\textsl{3}}}%
-\put(1.03,3.05){\scriptsize{\textsl{4}}}%
-\put(1.03,2.05){\scriptsize{\textsl{5}}}%
-\put(1.03,0.03){\scriptsize{\textsl{6}}}%
-\put(1.03,1.05){\scriptsize{\textsl{7}}}%
-\put(3.03,3.05){\scriptsize{\textsl{8}}}%
-\put(3.03,2.05){\scriptsize{\textsl{9}}}%
-\put(3.03,0.03){\scriptsize{\textsl{10}}}%
-\put(3.03,1.05){\scriptsize{\textsl{11}}}%
-\put(2.03,3.05){\scriptsize{\textsl{12}}}%
-\put(2.03,2.05){\scriptsize{\textsl{13}}}%
-\put(2.03,0.03){\scriptsize{\textsl{14}}}%
-\put(2.03,1.05){\scriptsize{\textsl{15}}}%
+\put(0.01,3.05){\askmapindexsize 0}%
+\put(0.01,2.05){\askmapindexsize 1}%
+\put(0.01,0.03){\askmapindexsize 2}%
+\put(0.01,1.05){\askmapindexsize 3}%
+\put(1.03,3.05){\askmapindexsize 4}%
+\put(1.03,2.05){\askmapindexsize 5}%
+\put(1.03,0.03){\askmapindexsize 6}%
+\put(1.03,1.05){\askmapindexsize 7}%
+\put(3.03,3.05){\askmapindexsize 8}%
+\put(3.03,2.05){\askmapindexsize 9}%
+\put(3.03,0.03){\askmapindexsize 10}%
+\put(3.03,1.05){\askmapindexsize 11}%
+\put(2.03,3.05){\askmapindexsize 12}%
+\put(2.03,2.05){\askmapindexsize 13}%
+\put(2.03,0.03){\askmapindexsize 14}%
+\put(2.03,1.05){\askmapindexsize 15}%
\fi%
\askmapargumentstring{#4}%
-\put(0.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,1.5){\makebox(0,0){\askmapgetchar}}%
+\put(0.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
\ifaskmap@optb%
-\put(-0.6,3.5){\makebox(0.5,0)[r]{\footnotesize{00}}}%
-\put(-0.6,2.5){\makebox(0.5,0)[r]{\footnotesize{01}}}%
-\put(-0.6,1.5){\makebox(0.5,0)[r]{\footnotesize{11}}}%
-\put(-0.6,0.5){\makebox(0.5,0)[r]{\footnotesize{10}}}%
-\put(0.5,4.2){\makebox(0,0){\footnotesize{00}}}%
-\put(1.5,4.2){\makebox(0,0){\footnotesize{01}}}%
-\put(2.5,4.2){\makebox(0,0){\footnotesize{11}}}%
-\put(3.5,4.2){\makebox(0,0){\footnotesize{10}}}%
+\put(-0.6,3.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 00}}%
+\put(-0.6,2.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 01}}%
+\put(-0.6,1.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 11}}%
+\put(-0.6,0.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 10}}%
+\put(0.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 00}}%
+\put(1.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 01}}%
+\put(2.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 11}}%
+\put(3.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 10}}%
\fi
\thicklines%
-\put(0,4){\line(-1,1){0.70}}%
+\put(0,4){\line(-1,1){\askmapvarsep}}%
\thinlines%
#5%
\end{picture}%
+\ifaskmap@debug}\else\fi%
}%
}% end \askmapiv
@@ -270,104 +436,109 @@
\newcommand{\askmapv}[5]{%
{\unitlength\askmapunitlength%
\askmap@processoptions{#3}%
+\ifaskmap@debug\fboxsep0pt\fbox{\else\fi%
\begin{picture}(10.4,5)(-1.2,0)%
\linethickness{1pt}%
-\put(0,0){\framebox(8,4)}%
+\put(0,0){\framebox(8,4){}}%
\multiput(1,0)(1,0){7}{\line(0,1){4}}%
\multiput(0,1)(0,1){3}{\line(1,0){8}}%
\ifaskmap@optf%
-\put(8.35,4.25){#1}%
+\put(8.35,4.25){\askmapcontentsize#1}%
\put(7.9,3.9){\line(1,1){0.4}}%
\fi%
\askmapargumentstring{#2}%
-\put(-0.4,4.55){\askmapgetchar\askmapgetchar\askmapgetchar}%
-\put(-1.0,4.1){\makebox(0.5,0){\askmapgetchar\askmapgetchar}}%
+\put(-0.4,4.55){\askmapcontentsize\askmapgetchar\askmapgetchar\askmapgetchar}%
+%\put(-1.0,3.9){\framebox(0.5,0.5)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+%\put(-1.0,4.1){\framebox(0.5,0)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}
+\put(-0.5,4.1){\makebox(0.0,0.0)[r]{\askmapcontentsize\askmapgetchar\askmapgetchar}}%
+%\put(-1.0,4.1){\makebox(0.5,0){\askmapcontentsize\askmapgetchar\askmapgetchar}}%
\ifaskmap@opti%
-\put(0.01,3.05){\scriptsize{\textsl{0}}}%
-\put(0.01,2.05){\scriptsize{\textsl{1}}}%
-\put(0.01,0.03){\scriptsize{\textsl{2}}}%
-\put(0.01,1.05){\scriptsize{\textsl{3}}}%
-\put(1.03,3.05){\scriptsize{\textsl{4}}}%
-\put(1.03,2.05){\scriptsize{\textsl{5}}}%
-\put(1.03,0.03){\scriptsize{\textsl{6}}}%
-\put(1.03,1.05){\scriptsize{\textsl{7}}}%
-\put(3.03,3.05){\scriptsize{\textsl{8}}}%
-\put(3.03,2.05){\scriptsize{\textsl{9}}}%
-\put(3.03,0.03){\scriptsize{\textsl{10}}}%
-\put(3.03,1.05){\scriptsize{\textsl{11}}}%
-\put(2.03,3.05){\scriptsize{\textsl{12}}}%
-\put(2.03,2.05){\scriptsize{\textsl{13}}}%
-\put(2.03,0.03){\scriptsize{\textsl{14}}}%
-\put(2.03,1.05){\scriptsize{\textsl{15}}}%
-\put(7.03,3.05){\scriptsize{\textsl{16}}}%
-\put(7.03,2.05){\scriptsize{\textsl{17}}}%
-\put(7.03,0.03){\scriptsize{\textsl{18}}}%
-\put(7.03,1.05){\scriptsize{\textsl{19}}}%
-\put(6.03,3.05){\scriptsize{\textsl{20}}}%
-\put(6.03,2.05){\scriptsize{\textsl{21}}}%
-\put(6.03,0.03){\scriptsize{\textsl{22}}}%
-\put(6.03,1.05){\scriptsize{\textsl{23}}}%
-\put(4.03,3.05){\scriptsize{\textsl{24}}}%
-\put(4.03,2.05){\scriptsize{\textsl{25}}}%
-\put(4.03,0.03){\scriptsize{\textsl{26}}}%
-\put(4.03,1.05){\scriptsize{\textsl{27}}}%
-\put(5.03,3.05){\scriptsize{\textsl{28}}}%
-\put(5.03,2.05){\scriptsize{\textsl{29}}}%
-\put(5.03,0.03){\scriptsize{\textsl{30}}}%
-\put(5.03,1.05){\scriptsize{\textsl{31}}}%
+\put(0.01,3.05){\askmapindexsize 0}%
+\put(0.01,2.05){\askmapindexsize 1}%
+\put(0.01,0.03){\askmapindexsize 2}%
+\put(0.01,1.05){\askmapindexsize 3}%
+\put(1.03,3.05){\askmapindexsize 4}%
+\put(1.03,2.05){\askmapindexsize 5}%
+\put(1.03,0.03){\askmapindexsize 6}%
+\put(1.03,1.05){\askmapindexsize 7}%
+\put(3.03,3.05){\askmapindexsize 8}%
+\put(3.03,2.05){\askmapindexsize 9}%
+\put(3.03,0.03){\askmapindexsize 10}%
+\put(3.03,1.05){\askmapindexsize 11}%
+\put(2.03,3.05){\askmapindexsize 12}%
+\put(2.03,2.05){\askmapindexsize 13}%
+\put(2.03,0.03){\askmapindexsize 14}%
+\put(2.03,1.05){\askmapindexsize 15}%
+\put(7.03,3.05){\askmapindexsize 16}%
+\put(7.03,2.05){\askmapindexsize 17}%
+\put(7.03,0.03){\askmapindexsize 18}%
+\put(7.03,1.05){\askmapindexsize 19}%
+\put(6.03,3.05){\askmapindexsize 20}%
+\put(6.03,2.05){\askmapindexsize 21}%
+\put(6.03,0.03){\askmapindexsize 22}%
+\put(6.03,1.05){\askmapindexsize 23}%
+\put(4.03,3.05){\askmapindexsize 24}%
+\put(4.03,2.05){\askmapindexsize 25}%
+\put(4.03,0.03){\askmapindexsize 26}%
+\put(4.03,1.05){\askmapindexsize 27}%
+\put(5.03,3.05){\askmapindexsize 28}%
+\put(5.03,2.05){\askmapindexsize 29}%
+\put(5.03,0.03){\askmapindexsize 30}%
+\put(5.03,1.05){\askmapindexsize 31}%
\fi%
\askmapargumentstring{#4}%
-\put(0.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(0.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(1.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(3.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(2.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(7.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(7.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(7.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(7.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(6.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(6.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(6.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(6.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(4.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(4.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(4.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(4.5,1.5){\makebox(0,0){\askmapgetchar}}%
-\put(5.5,3.5){\makebox(0,0){\askmapgetchar}}%
-\put(5.5,2.5){\makebox(0,0){\askmapgetchar}}%
-\put(5.5,0.5){\makebox(0,0){\askmapgetchar}}%
-\put(5.5,1.5){\makebox(0,0){\askmapgetchar}}%
+\put(0.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(0.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(1.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(3.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(2.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(7.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(7.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(7.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(7.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(6.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(6.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(6.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(6.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(4.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(4.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(4.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(4.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(5.5,3.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(5.5,2.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(5.5,0.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
+\put(5.5,1.5){\makebox(0,0){\askmapcontentsize\askmapgetchar}}%
\ifaskmap@optb%
-\put(-0.6,3.5){\makebox(0.5,0)[r]{\footnotesize{00}}}%
-\put(-0.6,2.5){\makebox(0.5,0)[r]{\footnotesize{01}}}%
-\put(-0.6,1.5){\makebox(0.5,0)[r]{\footnotesize{11}}}%
-\put(-0.6,0.5){\makebox(0.5,0)[r]{\footnotesize{10}}}%
-\put(0.5,4.2){\makebox(0,0){\footnotesize{000}}}%
-\put(1.5,4.2){\makebox(0,0){\footnotesize{001}}}%
-\put(2.5,4.2){\makebox(0,0){\footnotesize{011}}}%
-\put(3.5,4.2){\makebox(0,0){\footnotesize{010}}}%
-\put(4.5,4.2){\makebox(0,0){\footnotesize{110}}}%
-\put(5.5,4.2){\makebox(0,0){\footnotesize{111}}}%
-\put(6.5,4.2){\makebox(0,0){\footnotesize{101}}}%
-\put(7.5,4.2){\makebox(0,0){\footnotesize{100}}}%
+\put(-0.6,3.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 00}}%
+\put(-0.6,2.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 01}}%
+\put(-0.6,1.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 11}}%
+\put(-0.6,0.5){\makebox(0.5,0)[r]{\askmapbitcombinationsize 10}}%
+\put(0.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 000}}%
+\put(1.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 001}}%
+\put(2.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 011}}%
+\put(3.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 010}}%
+\put(4.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 110}}%
+\put(5.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 111}}%
+\put(6.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 101}}%
+\put(7.5,4.1){\makebox(0,0)[b]{\askmapbitcombinationsize 100}}%
\fi%
\thicklines%
-\put(0,4){\line(-1,1){0.70}}%
+\put(0,4){\line(-1,1){\askmapvarsep}}%
\thinlines%
#5%
\end{picture}%
+\ifaskmap@debug}\else\fi%
}%
}% end \askmapv
diff --git a/macros/latex/contrib/askmaps/askmaps.tex b/macros/latex/contrib/askmaps/askmaps.tex
index 43dac8925d..a94c51148c 100644
--- a/macros/latex/contrib/askmaps/askmaps.tex
+++ b/macros/latex/contrib/askmaps/askmaps.tex
@@ -2,13 +2,19 @@
%%
%% askmaps.tex
%%
-%% (c)2013, J.E.J. op den Brouw <J.E.J.opdenBrouw@hhs.nl>
+%% (c)2020, J.E.J. op den Brouw <J.E.J.opdenBrouw@hhs.nl>
%%
-%% document v0.1 - 2013/12/04
+%% document v0.1 - 2013/12/04
+%% v0.1a - 2013/12/07
+%% - added \karnaughmap example
+%% - minor changes in text
+%% v0.2 - 2020/23/10
+%% - added section on how to render covers
+%% - changes to the text.
%%
\documentclass[a4paper,10pt]{ltxdoc}
-\usepackage[a4paper]{geometry}
+\usepackage[a4paper,left=1.5in,right=1.5in,top=1.5in,bottom=1.5in]{geometry}
%% PDF Version and compression...
\pdfminorversion=5
@@ -24,11 +30,13 @@
\usepackage{float}
\usepackage{listings}
\usepackage{array}
+\usepackage{tikz}
%% The next lines are commented out by default. If you want these to appear
-%% in the resulting PDF, you have to copy the kvmacros.tex file in the
-%% current directory, uncomment the next lines and LaTex this file.
+%% in the resulting PDF, you have to have the kvmacros.tex somewhere is your
+%% LaTeX search path or have a copy of the kvmacros.tex file in the
+%% current directory. If so, uncomment the next lines and LaTeX this file.
%%
-%%\input kvmacros
+\input kvmacros
%% Use askmaps
\usepackage{askmaps}
@@ -40,7 +48,7 @@
linkcolor=blue,
pdftitle={American Style Karnaugh Maps},
pdfauthor={J.E.J op den Brouw},
- pdfsubject={Drawing 2, 3, 4 and 5 variables K-maps},
+ pdfsubject={Drawing 1, 2, 3, 4 and 5 variables K-maps},
pdfkeywords={K-maps, Karnaugh maps, Digital Design}
}
\definecolor{red}{rgb}{1,0,0}
@@ -51,8 +59,13 @@
\definecolor{lightgray}{rgb}{0.95,0.95,0.95}
%% Making captions nicer...
-\usepackage[font=footnotesize,format=plain,labelfont=bf,up,textfont=it,up]
- {caption}
+\usepackage[font=footnotesize,format=plain,labelfont=bf,textfont=sl]{caption}
+\usepackage[labelformat=simple,font=footnotesize,format=plain,labelfont=bf,textfont=sl]{subcaption}
+\captionsetup[figure]{justification=centering,singlelinecheck=off,belowskip=-1ex}
+\captionsetup[table]{justification=centering,singlelinecheck=off,skip=1ex}
+\captionsetup[subtable]{justification=centering,singlelinecheck=off,skip=3pt}
+\renewcommand\thesubfigure{(\alph{subfigure})}
+\renewcommand\thesubtable{(\alph{subtable})}
%% Set up the LaTex language layout
\lstset{ %
@@ -63,7 +76,7 @@
numberstyle=\tiny\color{gray},
stepnumber=1,
numbersep=5pt,
- backgroundcolor=\color{lightgray},
+ %backgroundcolor=\color{lightgray},
showspaces=false,
showstringspaces=false,
showtabs=false,
@@ -79,7 +92,7 @@
}
%% Need one more footnote...
-%% Display package name boldface
+%% Display package name teletype...
\renewcommand*{\thefootnote}{\fnsymbol{footnote}}
\newcommand\Package[1]{\texttt{#1}}
@@ -123,20 +136,21 @@
%% No indent
\setlength{\parindent}{0pt}
+\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}
%% At last, the document...
\begin{document}
\title{The \Package{askmaps} package}
\author{Jesse op den Brouw\thanks{The Hague University of Applied Sciences,
- \url{J.E.J.opdenBrouw@hhs.nl}}}
+ \href{mailto:J.E.J.opdenBrouw@hhs.nl}{J.E.J.opdenBrouw@hhs.nl}}}
\date{\askmapsdate, version \askmapsversion}
\maketitle
\setcounter{footnote}{1}
\section{Abstract}
\label{sec:abstract}
-This package generates configurable American style Karnaugh maps for
-2, 3, 4 and 5 variables as can be found in numerous books on digital design.
+This package generates configurable American style Karnaugh maps for 1, 2, 3,
+4 and~5 variables as can be found in numerous books on digital design.
Note that there are many ways to draw correct Karnaugh
maps\footnote{E.g., a four-variable Karnaugh map can be drawn in 384 different
and correct ways} and this packages creates only one version.
@@ -144,63 +158,77 @@ and correct ways} and this packages creates only one version.
There are more packages and examples that produce Karnaugh maps. A highly
recommendable package is written by Andreas W. Wieland\footnote{See
\url{http://www.ctan.org/tex-archive/macros/latex/contrib/karnaugh}}.
-However, this package creates maps that are frequently found in dutch
-textbooks\footnote{E.g. Digitale Techniek, A.P. Thijssen}
-but not in American textbooks.
+This package creates maps that are frequently found in European
+textbooks\footnote{E.g. Digitale Techniek, A.P. Thijssen} but not in American
+textbooks.
\section{Overview}
\label{sec:overview}
-After \cmdinvoke{usepackage}{askmaps}, four new commands are loaded
-to draw Karnaugh maps using the picture environment:
+After \cmdinvoke{usepackage}[\textit{option}]{askmaps}, siz new commands are
+available to draw Karnaugh maps:% using the \Package{picture} environment:
\begin{table}[H]
-\begin{tabular}{p{2cm}p{10cm}}
-\cs{askmapii} & draws a two-variable Karnaugh map \\
-\cs{askmapiii} & draws a three-variable Karnaugh map \\
-\cs{askmapiv} & draws a four-variable Karnaugh map \\
-\cs{askmapv} & draws a five-variable Karnaugh map \\
+\begin{tabular}{p{2.8cm}p{10cm}}
+\cs{askmapi} & draws a one-variable Karnaugh map \\
+\cs{askmapii} & draws a two-variable Karnaugh map \\
+\cs{askmapiii} & draws a three-variable Karnaugh map \\
+\cs{askmapiiialt} & draws an alternate style three-variable Karnaugh map \\
+\cs{askmapiv} & draws a four-variable Karnaugh map \\
+\cs{askmapv} & draws a five-variable Karnaugh map \\
\end{tabular}
\end{table}
These commands have five parameters which have the same meaning for each
-commands. This will be explained in section \ref{sec:outline}. As can be seen
-later on, much of the parameters can include typesetting commands such as
+commands. This will be explained in Section \ref{sec:outline}. As can be seen
+later on, many of the parameters can include typesetting commands such as
coloring and math notation.
-The new dimension \cs{askmapunitlength} is available and specifies
-the length of the squares. It defaults to 1 cm (about 0.4 in) which is a good
-value for 12 pt font size.
+The new dimension \cs{askmapunitlength} is available and specifies the length
+and width of the squares. It defaults to 1 cm (about 0.4 in) which is good in
+combination with a~12 pt font size.
The global definitions \cs{askmapsversion} and \cs{askmapsdate} will render
to the current version and date respectively.
+There are three commands that control the size (and shape) of the rendered
+text. The \cs{askmapindexsize} command sets the size and shape of the index
+number, the default is \cs{scriptsize}\cs{slshape}. The \cs{askmapcontentsize} command sets
+the size of the contents of the cells. It defaults to \cs{normalsize}. The
+\cs{askmapbitcombinationsize} sets the the size of the bit combinations
+on the edges of the Karnaugh map. It defaults to \cs{footnotesize}. These
+sizes can be changed using the appropriate \cs{renewcommand} command.
+
+The command \cs{askmapvarsep} contains the length of the variable separator
+line in de Karnaugh maps. The default is 0.7. Note that it is merely a
+number, not a length. It can be altered using the appropriate
+\cs{renewcommand} command. See Section~\ref{sec:use} for more details.
+
The command \cs{askmap} provides drop-in replacement for the \cs{karnaughmap}
-command available in the \Package{kvdocs} package (although it is not really a
-package) and internally calls one of the four
-commands, but there are some drawbacks on using this command.
+command available in the \Package{kvmacros} package and internally calls one
+of the five commands (the \cs{askmapiiialt} command is not supported), but
+there are some drawbacks on using this command.
-\newpage
\section{Outline}
\label{sec:outline}
-All four functions take the form
-\cs{askmap<romannumber>\{\#1\}\{\#2\}\{\#3\}\{\#4\}\{\#5\}}
-where \texttt{<romannumber>} is one of \texttt{ii}, \texttt{iii}, \texttt{iv}
-or \texttt{v} and the parameters \texttt{\#1} to \texttt{\#5} have the
-following meaning:
+%% 2013/12/07: functions -> commands
+All six commands take the form
+\cs{askmap<spec>\{\#1\}\{\#2\}\{\#3\}\{\#4\}\{\#5\}} where \texttt{<spec>} is
+one of \texttt{i}, \texttt{ii}, \texttt{iii}, \texttt{iiialt}, \texttt{iv} or
+\texttt{v} and the parameters \texttt{\#1} to \texttt{\#5} have the following
+meaning:
\begin{itemize}
- \itemsep0pt
- %\labelsep0pt
- \item[\texttt{\#1}] is the function output variable.
- \item[\texttt{\#2}] is a list of function input variables.
- \item[\texttt{\#3}] contains a list op options, see table below.
- \item[\texttt{\#4}] is a list of function values.
- \item[\texttt{\#5}] can be used to display user defined picture commands.
+\itemsep0pt
+\item[\texttt{\#1}] is the function output variable.
+\item[\texttt{\#2}] is a list of function input variables.
+\item[\texttt{\#3}] contains a list op options, see table below.
+\item[\texttt{\#4}] is a list of function values.
+\item[\texttt{\#5}] can be used to display user defined picture commands.
\end{itemize}
If a parameter contains fewer elements than needed, you will get empty spaces
in the Karnaugh map. If a parameter contains more elements than needed, all
elements in excess are not printed. In both situations, you will not be
-notified.\newline
+notified.
The third parameter contains a list of options as explained below.
\begin{itemize}
@@ -210,10 +238,11 @@ The third parameter contains a list of options as explained below.
\item[\texttt{I}] no index numbers are printed (default).
\item[\texttt{f}] function output variable is printed at the upper right
corner of the Karnaugh map together with a small line
- extending from the square to the function name (default).
- \item[\texttt{F}] no function output variable is printed.
+ extending from the square to the function
+ name (default, see Package Option Handling).
+ \item[\texttt{F}] no function output variable is printed
\item[\texttt{b}] bit combinations of the function input variables are
- printed on top of the columns and at the right of the the
+ printed on top of the columns and at the left of the the
rows (default).
\item[\texttt{B}] bit combinations are not printed.
\item[\texttt{c}] shortcut for \texttt{ifb}.
@@ -222,13 +251,21 @@ The third parameter contains a list of options as explained below.
Options are evaluated from left to right, so a combination of \texttt{iI} will
yield in no index numbers being printed. Please note that macros are not
-expanded to a list of tokens but to one token.\newline
+expanded to a list of tokens but to one token.
+
+%%%%If you look at American style Karnaugh maps, you will see that the function
+%%%%output variable usually isn't printed with the map, but is printed below or
+%%%%besides the map (if it is printed at all). This behavior can be simulated by
+%%%%using the \texttt{F} option, in which case the first parameter (the function
+%%%%output variable) may be left unused.
-If you look at American style Karnaugh maps, you will see that the function
-output variable usually isn't printed with the map, but is printed below the
-map (if it is printed at all). This behavior can be simulated by using the
-\texttt{F} option, in which case the first parameter (the function output
-variable) may be left unused.
+\section{Package Option Handling}
+\label{sec:optionhandling}
+As of version 0.2, the option \texttt{disablef} disables the default rendering
+of the function output variable at the upper right corner of the Karnaugh map
+together with a small line extending from the square to the function name
+(option \texttt{f} in the third parameter). This is more common found in
+American textbooks.
\section{Use}
@@ -238,40 +275,41 @@ a and b and the function values 1, 0, 1 and 1 respectively.
\begin{table}[H]
\centering
-\caption{Truth table}
+\caption{A truth table.}
\begin{tabular}{cc|c}
-\hline
+%\hline
a & b & S \\ \hline
0 & 0 & 1 \\
0 & 1 & 0 \\
1 & 0 & 1 \\
1 & 1 & 1 \\
-\hline
+%\hline
\end{tabular}
\end{table}
-Using the command
+The command
\begin{verbatim}
\askmapii{S}{ab}{i}{1011}{}
\end{verbatim}
will produce the two-variable Karnaugh map as presented in
-figure~\ref{fig:askmapii}.
+Figure~\ref{fig:askmapii}.
\begin{figure}[h]
\centering
\askmapunitlength=0.88cm
\askmapii{S}{ab}{i}{1011}{}%
-\caption{Karnaughmap for two variables}
+\caption{Karnaugh map for two variables.}
\label{fig:askmapii}
\end{figure}
As you can see, the function output variable is printed top right of the
Karnaugh map, with a small line from the variable to the top right square.
The most significant function input variable is printed on the top left just
-above the small line extending from the top left square. The least significant
+above the small line extending from the top left square (the variable
+separator line). The least significant
function input variable is printed just below that line. The bit combinations
-for the most significant function input variable is printed on top of the
+for the most significant function input variables are printed on top of the
columns, the bit combinations of the least significant function input variable
-is printed on the left of the rows. You can see how the function values are
+are printed left of the rows. You can see how the function values are
placed in the squares by observing the small index numbers in the lower left
corners of the squares.
\medskip
@@ -281,18 +319,36 @@ The command
\askmapiii{S}{abc}{}{10110110}{}
\end{verbatim}
will produce a three-variable Karnaugh map as presented in
-figure~\ref{fig:askmapiii}. In this case, the index numbers are not printed.
+Figure~\ref{fig:askmapiii}. In this case, the index numbers are not printed.
\begin{figure}[H]
\centering
\askmapunitlength=0.88cm
\askmapiii{S}{abc}{}{10110110}{}%
-\caption{Karnaugh map for three variables}
+\caption{Karnaugh map for three variables.}
\label{fig:askmapiii}
\end{figure}
-Let's draw a Karnaugh map for a logic function with four inputs and one output.
-The output will become logic 1 if three or four inputs are logic 1, otherwise
+Sometimes you need a three-variable Karnaugh map that is printed in the
+vertical direction. It will leave you room to print accompanying text to
+the left or right of the map. The command
+
+\begin{verbatim}
+ \askmapiiialt{S}{abc}{}{10110110}{}
+\end{verbatim}
+will produce the vertical oriented version of the three-variable Karnaugh map
+as can been seen in Figure~\ref{fig:askmapiiialt}.
+
+\begin{figure}[H]
+\centering
+\askmapunitlength=0.88cm
+\askmapiiialt{S}{abc}{}{10110110}{}%
+\caption{Vertical version of the Karnaugh map for three variables.}
+\label{fig:askmapiiialt}
+\end{figure}
+
+Let's draw a Karnaugh map for a logic function with four inputs.
+The output will become logic~1 if three or four inputs are logic 1, otherwise
the output is logic 0. (Of course you can set up a truth table first; this is
left as an exercise to the reader).
The command
@@ -300,13 +356,13 @@ The command
\askmapiv{S}{abcd}{}{0000000100010111}{}
\end{verbatim}
will produce a four-variable Karnaugh map for the given logic function and is
-presented in figure~\ref{fig:askmapiv}.
+presented in Figure~\ref{fig:askmapiv}.
\begin{figure}[H]
\centering
\askmapunitlength=0.88cm
- \askmapiv{S}{abdc}{}{0000000100010111}{}
-\caption{Karnaugh map for four variables}
+ \askmapiv{S}{abcd}{}{0000000100010111}{}
+\caption{Karnaugh map for four variables.}
\label{fig:askmapiv}
\end{figure}
@@ -314,17 +370,17 @@ Using the command
\begin{verbatim}
\askmapv{S}{abcde}{}{00101101010010111011110011101011}{}
\end{verbatim}
-will produce a five-variable Karnaugh map as shown in figure \ref{fig:askmapv}.
+a five-variable Karnaugh map is produced as shown in Figure~\ref{fig:askmapv}.
\begin{figure}[H]
\centering
\askmapunitlength=0.88cm
\askmapv{S}{abcde}{}{00101101010010111011110011101011}{}
-\caption{Karnaugh map for five variables}
+\caption{Karnaugh map for five variables.}
\label{fig:askmapv}
\end{figure}
-Of course you can do a lot more with the parameters of the commands. You
+Of course you can do a lot more with the arguments of the commands. You
can use inline math to produce sophisticated variable names, you can
use coloring for the function values. However, please note that the second
and fourth parameter act as a list of tokens, so you have to use braces to
@@ -343,77 +399,518 @@ will not work. You have to write
\end{verbatim}
The fifth parameter can be used to supply user created picture commands
-such as dashed rectangles of ovals to emphasize the simplifications
-in the function. Note that the origin
-of the picture (0,0) is at the lower left corner of the lower left square.
-Section \ref{sec:examples} shows some examples.
+such as dashed rectangles or ovals to emphasize the simplifications in the
+function. Note that the origin of the picture (0,0) is at the lower left
+corner of the lower left square. Sections~\ref{sec:drawing} and~%
+\ref{sec:examples} show some examples.
\bigskip
-The size of the indexes is scriptsize, the size of the bit combinations
-on the edges of the Karnaugh maps is footnotesize. All other text is
-in normalsize. Note that there are no commands to change the font sizes
-in the Karnaugh diagrams.
+%%%The size of the indexes is scriptsize, the size of the bit combinations
+%%%on the edges of the Karnaugh maps is footnotesize. All other text is
+%%%in normalsize. Note that there are no commands to change the font sizes
+%%%in the Karnaugh maps.
+%%%\bigskip
The command \cs{askmap} provides a drop-in replacement for the command
\cs{karnaughmap} from the Karnaugh package. The command
\begin{verbatim}
- \askmap{4}{F}{abcd}{0100101010100011}{}
+ \askmap{4}{S}{abcd}{0100101010100011}{}
\end{verbatim}
-produces the Karnaugh map in figure \ref{fig:askmap}.
+produces the Karnaugh map in Figure \ref{fig:askmap}.
\begin{figure}[H]
\centering
\askmapunitlength=0.88cm
- \askmap{4}{F}{abcd}{0100101010100011}{}
-\caption{Karnaugh map using drop-in replacement}
+ \askmap{4}{S}{abcd}{0100101010100011}{}
+\caption{Karnaugh map using drop-in replacement.}
\label{fig:askmap}
\end{figure}
-Only Karnaugh maps of two to five variables are supported, any other number
-will trigger a warning. Please note that the \cs{kvindex}, \cs{kvindexsize}
-and \cs{kvcontentsize} commands are not supported.
-\medskip
+Note that when using this command the output function variable is always
+printed.
+
+Only Karnaugh maps of one to five variables are supported, any other number
+will trigger a warning. Please note that \cs{kvindex} and \cs{kvnoindex} are
+supported as can be seen in Figure~\ref{fig:karnaughmapindex}, but
+\cs{kvindexsize} and \cs{kvcontentsize} commands are not supported.
+\begin{verbatim}
+ \kvindex
+ \askmap{4}{f(a,b,c,d):}{abcd}{1110011001100110}{}
+\end{verbatim}
+\begin{figure}[H]
+\centering
+\askmapunitlength=0.88cm
+ \kvindex
+ \askmap{4}{f(a,b,c,d):}{abcd}{1110011001100110}{}
+\caption{Karnaugh map using the \Package{kvmacros} package.}
+\label{fig:karnaughmapindex}
+\end{figure}
%% The next lines are commented out by default. If you want these to appear
%% in the resulting PDF, you have to copy the kvmacros.tex file in the
%% current directory, uncomment the next lines and LaTex this file.
%%
-%%The packages \Package{kvmacros} and \Package{askmaps} can be used in the same
-%%document.
-%%\begin{figure}[H]
-%%\centering
-%% \karnaughmap{4}{f(a,b,c,d):}{abcd}{1110011001100110}{}
-%%\caption{Karnaugh map using the \Package{kvmacros} package}
-%%\label{fig:karnaughmap}
-%%\end{figure}
+The packages \Package{kvmacros} and \Package{askmaps} can be used in the same
+document as shown in Figure \ref{fig:karnaughmapnoindex}.
+\begin{verbatim}
+ \kvnoindex
+ \karnaughmap{4}{f(a,b,c,d):}{abcd}{1110011001100110}{}
+\end{verbatim}
+\begin{figure}[H]
+\centering
+ \kvnoindex
+ \karnaughmap{4}{f(a,b,c,d):}{abcd}{1110011001100110}{}
+\caption{Karnaugh map using the \Package{kvmacros} package.}
+\label{fig:karnaughmapnoindex}
+\end{figure}
-\newpage
+The lenght of the line separating the input variables can be set to a
+different value as shown in Figure~\ref{fig:difflenvarsep}.
+
+\begin{verbatim}
+ \renewcommand{\askmapvarsep}{0.6}
+ \askmapiii{S}{abc}{}{00111010}{}
+ \renewcommand{\askmapvarsep}{0.9}
+ \askmapiii{F}{xyz}{}{11111010}{}
+\end{verbatim}
+\begin{figure}[H]
+\centering
+\renewcommand{\askmapvarsep}{0.6}
+\askmapiii{S}{abc}{}{00111010}{}
+\renewcommand{\askmapvarsep}{0.9}
+\askmapiii{F}{xyz}{}{11111010}{}
+\caption{Different lengths of the variable separator line.}
+\label{fig:difflenvarsep}
+\end{figure}
+
+
+
+\section{Drawing covers and more}
+\label{sec:drawing}
+One of the uses of Karnaugh maps is to simplify logic functions. The
+simplifications are usually shown as (part of) circles or ovals (also squares can be used) combining
+the function values that make up the simplified terms (either product terms
+or sum terms).% These
+
+Let's begin with a simple example. The code is shown below, the map is
+shown in Figure~\ref{fig:kmapsthree}. Note that one function variable is
+covered by all three ovals, hence it looks as if it is covered by a circle.
+
+\begin{minipage}[c]{0.5\textwidth}
+\begin{verbatim}
+ \askmapiii{s}{abc}{}{00010111}{%
+ \put(2.5,1.0){\oval(0.8,1.8)}%
+ \put(2.0,0.5){\oval(1.8,0.8)}%
+ \put(3.0,0.5){\oval(1.8,0.8)}%
+ }%
+\end{verbatim}
+\end{minipage}\hfill%
+\begin{minipage}[c]{0.5\textwidth}
+\begin{figure}[H]
+\centering
+\askmapunitlength=0.88cm
+\askmapiii{s}{abc}{}{00010111}{%
+\put(2.5,1.0){\oval(0.8,1.8)}%
+\put(2.0,0.5){\oval(1.8,0.8)}%
+\put(3.0,0.5){\oval(1.8,0.8)}%
+}%
+\caption{Karnaugh map for three variables.}
+\label{fig:kmapsthree}
+\end{figure}
+\end{minipage}
+\bigskip
+
+Function values on the edges of Karnaugh maps can be combined in one term.
+The values are not adjacent in the maps so covering oval or circle has to be
+split. This is shown in Figure~\ref{fig:kmapsthreemarkedges}. The code is
+shown left. As can be seen, for marking the edges only half a circle has to
+be drawn. Note the lines extending the edges of the map.
+
+
+\bigskip
+\begin{minipage}[c]{0.5\textwidth}
+\begin{verbatim}
+ \askmapiii{s}{abc}{}{11100111}{%
+ \put(2.5,1.0){\oval(0.8,1.8)}%
+ \put(1.0,1.5){\oval(1.8,0.8)}%
+ \put(3.5,0.5){\oval(0.8,0.8)[l]}%
+ \put(3.5,0.9){\line(1,0){0.7}}%
+ \put(3.5,0.1){\line(1,0){0.7}}%
+ \put(0.5,0.5){\oval(0.8,0.8)[r]}%
+ \put(0.5,0.9){\line(-1,0){0.7}}%
+ \put(0.5,0.1){\line(-1,0){0.7}}%
+ }%
+\end{verbatim}
+\end{minipage}\hfill%
+\begin{minipage}[c]{0.5\textwidth}
+\vspace*{-3\baselineskip}
+\begin{figure}[H]
+\centering
+\askmapiii{s}{abc}{}{11100111}{%
+\put(2.5,1.0){\oval(0.8,1.8)}%
+\put(1.0,1.5){\oval(1.8,0.8)}%
+\put(3.5,0.5){\oval(0.8,0.8)[l]}%
+\put(3.5,0.9){\line(1,0){0.7}}%
+\put(3.5,0.1){\line(1,0){0.7}}%
+\put(0.5,0.5){\oval(0.8,0.8)[r]}%
+\put(0.5,0.9){\line(-1,0){0.7}}%
+\put(0.5,0.1){\line(-1,0){0.7}}%
+}%
+\caption{Example of how to mark edges.}
+\label{fig:kmapsthreemarkedges}
+\end{figure}
+\end{minipage}
+\bigskip
+
+Making ``square'' ovals doesn't always produce a good result as can be seen
+in Figure~\ref{fig:kmapsquareoval}. The column second to the right seems to
+be covered by it's own oval.
+
+\bigskip
+\begin{minipage}[c]{0.5\textwidth}
+\begin{verbatim}
+ \askmapiii{s}{abc}{}{00111111}{%
+ \put(2.5,1.0){\oval(0.8,1.8)[rb]}%
+ \put(2.5,1.0){\oval(0.8,1.8)[rt]}%
+ \put(1.5,1.0){\oval(0.8,1.8)[lb]}%
+ \put(1.5,1.0){\oval(0.8,1.8)[lt]}%
+ \put(1.5,1.9){\line(1,0){1.0}}%
+ \put(1.5,0.1){\line(1,0){1.0}}%
+ \put(3.5,1.0){\oval(0.8,1.8)[rb]}%
+ \put(3.5,1.0){\oval(0.8,1.8)[rt]}%
+ \put(2.5,1.0){\oval(0.8,1.8)[lb]}%
+ \put(2.5,1.0){\oval(0.8,1.8)[lt]}%
+ \put(2.5,1.9){\line(1,0){1.0}}%
+ \put(2.5,0.1){\line(1,0){1.0}}%
+ }%
+\end{verbatim}
+\end{minipage}\hfill%
+\begin{minipage}[c]{0.5\textwidth}
+\vspace*{-3\baselineskip}
+\begin{figure}[H]
+\centering
+\askmapiii{s}{abc}{}{00111111}{%
+\put(2.5,1.0){\oval(0.8,1.8)[rb]}% the square oval
+\put(2.5,1.0){\oval(0.8,1.8)[rt]}% in the middle
+\put(1.5,1.0){\oval(0.8,1.8)[lb]}% of the map
+\put(1.5,1.0){\oval(0.8,1.8)[lt]}%
+\put(1.5,1.9){\line(1,0){1.0}}%
+\put(1.5,0.1){\line(1,0){1.0}}%
+\put(3.5,1.0){\oval(0.8,1.8)[rb]}% the square oval
+\put(3.5,1.0){\oval(0.8,1.8)[rt]}% on the right
+\put(2.5,1.0){\oval(0.8,1.8)[lb]}% of the map
+\put(2.5,1.0){\oval(0.8,1.8)[lt]}%
+\put(2.5,1.9){\line(1,0){1.0}}%
+\put(2.5,0.1){\line(1,0){1.0}}%
+}%
+\caption{Example of bad use of ovals.}
+\label{fig:kmapsquareoval}
+\end{figure}
+\end{minipage}
+\bigskip
+
+
+
+
+
+Let's try a four-variable map, see Figure~\ref{fig:kmapsthreemarkedges2}
+and accompanying code. Here we have deliberately used an oval with a
+bigger size (see code line marked \textasteriskcentered) otherwise it will
+interfere with the covering of the lower left and right edges. An example
+of good use of a ``square'' oval can be found in
+Figure~\ref{fig:kmapforfourvarcorner}.
+
+\bigskip
+\begin{minipage}[c]{0.5\textwidth}
+\begin{verbatim}
+ \askmapiv{s}{abcd}{}{0111010001110111}{%
+ \put(2.0,2.5){\oval(3.8,0.8)}%
+ \put(0.5,1.0){\oval(0.8,1.8)[rb]}%
+ \put(0.5,1.0){\oval(0.8,1.8)[rt]}%
+ \put(0.5,1.9){\line(-1,0){0.7}}%
+ \put(0.5,0.1){\line(-1,0){0.7}}%
+ \put(3.0,1.0){\oval(1.8,1.8)}% (*)
+ \put(3.5,1.0){\oval(0.8,1.8)[lb]}%
+ \put(3.5,1.0){\oval(0.8,1.8)[lt]}%
+ \put(3.5,1.9){\line(1,0){0.7}}%
+ \put(3.5,0.1){\line(1,0){0.7}}%
+ }%
+\end{verbatim}
+\end{minipage}\hfill%
+\begin{minipage}[c]{0.5\textwidth}
+\vspace*{-2\baselineskip}
+\begin{figure}[H]
+\centering
+\askmapiv{s}{abcd}{}{0111010001110111}{%
+\put(2.0,2.5){\oval(3.8,0.8)}%
+\put(0.5,1.0){\oval(0.8,1.8)[rb]}%
+\put(0.5,1.0){\oval(0.8,1.8)[rt]}%
+\put(0.5,1.9){\line(-1,0){0.7}}%
+\put(0.5,0.1){\line(-1,0){0.7}}%
+\put(3.0,1.0){\oval(1.8,1.8)}%
+\put(3.5,1.0){\oval(0.8,1.8)[lb]}%
+\put(3.5,1.0){\oval(0.8,1.8)[lt]}%
+\put(3.5,1.9){\line(1,0){0.7}}%
+\put(3.5,0.1){\line(1,0){0.7}}%
+}%
+\caption{Example of how to mark edges.}
+\label{fig:kmapsthreemarkedges2}
+\end{figure}
+\end{minipage}
+\bigskip
+
+
+
+Every textbook on using Karnaugh maps shows how to combine the corners of a
+four-variable map. The complete code is shown below. The result is shown in
+Figure~\ref{fig:kmapforfourvarcorner}. Each corner marking
+consists of three drawing command: two lines (to the left, right up or
+down) and one (part of a) oval (right-bottom, left-bottom, right-top
+and right-bottom).
+
+
+\begin{verbatim}
+ \begin{figure}[H]
+ \centering
+ \askmapiv{s}{abcd}{}{1010000010100000}{%
+ \put(0.5,3.5){\oval(0.8,0.8)[rb]}% left-top
+ \put(0.5,3.1){\line(-1,0){0.7}}%
+ \put(0.9,3.5){\line(0,1){0.7}}%
+ \put(3.5,3.5){\oval(0.8,0.8)[lb]}% right-top
+ \put(3.5,3.1){\line(1,0){0.7}}%
+ \put(3.1,3.5){\line(0,1){0.7}}%
+ \put(0.5,0.5){\oval(0.8,0.8)[rt]}% left-bottom
+ \put(0.5,0.9){\line(-1,0){0.7}}%
+ \put(0.9,0.5){\line(0,-1){0.7}}%
+ \put(3.5,0.5){\oval(0.8,0.8)[lt]}% right-bottom
+ \put(3.5,0.9){\line(1,0){0.7}}%
+ \put(3.1,0.5){\line(0,-1){0.7}}%
+ \put(2.5,2.0){\oval(0.8,1.8)[rb]}% the square oval
+ \put(2.5,2.0){\oval(0.8,1.8)[rt]}% in the middle
+ \put(1.5,2.0){\oval(0.8,1.8)[lb]}% of the map
+ \put(1.5,2.0){\oval(0.8,1.8)[lt]}%
+ \put(1.5,2.9){\line(1,0){1.0}}%
+ \put(1.5,1.1){\line(1,0){1.0}}%
+ }%
+ \caption{The corners of the Karnaugh map are connected.}
+ \label{fig:kmapforfourvarcorner}
+ \end{figure}
+\end{verbatim}
+
+\begin{figure}[H]
+\centering
+\askmapiv{s}{abcd}{}{1010010110100101}{%
+\put(0.5,3.5){\oval(0.8,0.8)[rb]}% left-top
+\put(0.5,3.1){\line(-1,0){0.7}}%
+\put(0.9,3.5){\line(0,1){0.7}}%
+\put(3.5,3.5){\oval(0.8,0.8)[lb]}% right-top
+\put(3.5,3.1){\line(1,0){0.7}}%
+\put(3.1,3.5){\line(0,1){0.7}}%
+\put(0.5,0.5){\oval(0.8,0.8)[rt]}% left-bottom
+\put(0.5,0.9){\line(-1,0){0.7}}%
+\put(0.9,0.5){\line(0,-1){0.7}}%
+\put(3.5,0.5){\oval(0.8,0.8)[lt]}% right-bottom
+\put(3.5,0.9){\line(1,0){0.7}}%
+\put(3.1,0.5){\line(0,-1){0.7}}%
+\put(2.5,2.0){\oval(0.8,1.8)[rb]}% the square oval
+\put(2.5,2.0){\oval(0.8,1.8)[rt]}% in the middle
+\put(1.5,2.0){\oval(0.8,1.8)[lb]}% of the map
+\put(1.5,2.0){\oval(0.8,1.8)[lt]}%
+\put(1.5,2.9){\line(1,0){1.0}}%
+\put(1.5,1.1){\line(1,0){1.0}}%
+}%
+\caption{The corners of the Karnaugh map are connected.}
+\label{fig:kmapforfourvarcorner}
+\end{figure}
+
+
+When writing a textbook on the use of Karnaugh maps, it sometimes helps if
+a cover is accompanied with the term it covers.
+Below is a fine example of explaining the simplification of a logic function
+by showing the product term at each cover. The truth table is shown at the
+right.
+
+\begin{verbatim}
+\begin{figure}[H]
+\begin{subfigure}[c]{0.5\textwidth}
+\centering
+\askmapiii{s}{abc}{}{00010111}{%
+\put(2.5,1.0){\oval(0.8,1.8)}%
+\put(3.0,3.0){\makebox(0,0){$a\cdot b$}}%
+\put(3.0,2.8){\line(-1,-5.0){0.2}}%
+\put(2.0,0.5){\oval(1.8,0.8)}%
+\put(0.5,-0.8){\makebox(0,0){$b\cdot c$}}%
+\put(0.5,-0.6){\line(1,0.9){0.8}}%
+\put(3.0,0.5){\oval(1.8,0.8)}%
+\put(4.5,-0.8){\makebox(0,0){$a\cdot c$}}%
+\put(4.5,-0.6){\line(-1,0.9){0.8}}%
+}%
+\end{subfigure}%
+\begin{subfigure}[c]{0.5\textwidth}
+\centering
+\begin{tabular}{ccc|c}
+$a$ & $b$ & $c$ & $s$ \\ \hline
+ 0 & 0 & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ 0 & 1 & 0 & 0 \\
+ 0 & 1 & 1 & 1 \\
+ 1 & 0 & 0 & 0 \\
+ 1 & 0 & 1 & 1 \\
+ 1 & 1 & 0 & 1 \\
+ 1 & 1 & 1 & 1 \\
+\end{tabular}
+\end{subfigure}%
+\bigskip\caption{Karnaugh map for three variables.}
+\label{fig:karnaughmajorfunctie}
+\end{figure}
+\end{verbatim}
+
+
+\begin{figure}[H]
+\begin{subfigure}[c]{0.5\textwidth}
+\centering
+\askmapunitlength=0.88cm
+\askmapiii{s}{abc}{}{00010111}{%
+\put(2.5,1.0){\oval(0.8,1.8)}%
+\put(3.0,3.0){\makebox(0,0){$a\cdot b$}}%
+\put(3.0,2.8){\line(-1,-5.0){0.2}}%
+\put(2.0,0.5){\oval(1.8,0.8)}%
+\put(0.5,-0.8){\makebox(0,0){$b\cdot c$}}%
+\put(0.5,-0.6){\line(1,0.9){0.8}}%
+\put(3.0,0.5){\oval(1.8,0.8)}%
+\put(4.5,-0.8){\makebox(0,0){$a\cdot c$}}%
+\put(4.5,-0.6){\line(-1,0.9){0.8}}%
+}%
+\end{subfigure}%
+\begin{subfigure}[c]{0.5\textwidth}
+\centering
+\begin{tabular}{ccc|c}
+$a$ & $b$ & $c$ & $s$ \\ \hline
+ 0 & 0 & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ 0 & 1 & 0 & 0 \\
+ 0 & 1 & 1 & 1 \\
+ 1 & 0 & 0 & 0 \\
+ 1 & 0 & 1 & 1 \\
+ 1 & 1 & 0 & 1 \\
+ 1 & 1 & 1 & 1 \\
+\end{tabular}
+\end{subfigure}%
+\bigskip\caption{Karnaugh map for three variables.}
+\label{fig:karnaughmajorfunction}
+\end{figure}
+
+A very notable feature is when you use Ti\textsl{k}Z. When you use the package with
+
+\begin{verbatim}
+\usepackage{tikz}
+\end{verbatim}
+
+you can use Ti\textsl{k}Z' opacity control to add opaque solid rectangles in the back:
+
+\begin{verbatim}
+\askmapii{F}{xy}{f}{0111}{
+\setlength\fboxsep{0pt}\linethickness{0pt}
+\put(1.1,0.1){\pgfsetfillopacity{0.2}\colorbox{red}{\framebox(0.8,1.8){}}\pgfsetfillopacity{1}}%
+\put(0.1,0.1){\pgfsetfillopacity{0.2}\colorbox{blue}{\framebox(1.8,0.8){}}\pgfsetfillopacity{1}}%
+}
+\end{verbatim}
+
+\askmapii{F}{xy}{f}{0111}{
+\setlength\fboxsep{0pt}\linethickness{0pt}
+\put(1.1,0.1){\pgfsetfillopacity{0.2}\colorbox{red}{\framebox(0.8,1.8){}}\pgfsetfillopacity{1}}%
+\put(0.1,0.1){\pgfsetfillopacity{0.2}\colorbox{blue}{\framebox(1.8,0.8){}}\pgfsetfillopacity{1}}%
+}
+
+\bigskip
+In fact, you can use a \texttt{tikzpicture} environment to use Ti\textsl{k}Z commands
+but you have to set an invisible point to coordinate to (0,0):
+
+\begin{verbatim}
+\askmapii{F}{xy}{f}{0111}{%
+\begin{tikzpicture}[x=\askmapunitlength,y=\askmapunitlength]%
+\draw[draw=none,fill=none] (0,0) -- (0,0); % Set default corner
+\draw[red, ultra thick] (0,0) rectangle (2,2);%
+\end{tikzpicture}%
+}
+\end{verbatim}
+
+\askmapii{F}{xy}{f}{0111}{%
+\begin{tikzpicture}[x=\askmapunitlength,y=\askmapunitlength]%
+\draw[draw=none,fill=none] (0,0) -- (0,0); % Set default corner
+\draw[red,ultra thick] (0,0) rectangle (2,2);%
+\end{tikzpicture}%
+}
+
+
+\section{Additional command}
+The command \cmdinvoke{askmapindexsize} sets the size and typeface of the minterm numbers in the cells. The default definition is set to
+
+\begin{lstlisting}
+\newcommand{\askmapindexsize}{\scriptsize\slshape}
+\end{lstlisting}
+
+The command \cmdinvoke{askmapcontentsize} sets the size and typeface for the cell's contents. The default definition is
+
+\begin{lstlisting}
+\newcommand{\askmapcontentsize}{\normalsize}
+\end{lstlisting}
+
+The command \cmdinvoke{askmapbitcombinationsize} sets the size and typeface for the bit combinations at the top and the left. The default definition is
+
+\begin{lstlisting}
+\newcommand{\askmapbitcombinationsize}{\footnotesize}
+\end{lstlisting}
+
+The command \cmdinvoke{askmapvarsep} sets the relative line length of the variable separator on the left of the Karnaugh map. The default definition is
+
+\begin{lstlisting}
+\newcommand{\askmapvarsep}{0.70}
+\end{lstlisting}
+
+These commands may be changed using the appropriate \cmdinvoke{renewcommand} command.
+
+
+%\newpage
\section{Examples}
\label{sec:examples}
\askmapunitlength=0.88cm
-The Karnaugh maps for two variables: plain, with indexes, without function
-output variable.
+The most simple Karnaugh maps you can make with only one variable.
+\begin{verbatim}
+ \askmapi{s}{a}{i}{00}{}
+ \askmapi{s}{a}{}{01}{}
+ \askmapi{s}{a}{}{10}{}
+ \askmapi{s}{a}{}{11}{}
+\end{verbatim}
+\askmapi{s}{a}{i}{00}{}%
+\askmapi{s}{a}{}{01}{}%
+\askmapi{s}{a}{}{10}{}%
+\askmapi{s}{a}{}{11}{}%
+\bigskip\bigskip
+
+The Karnaugh maps for two variables: plain, with indexes and output
+variable.
\begin{verbatim}
- \askmapii{S}{ab}{}{1010}{}
+ \askmapii{S}{ab}{F}{1010}{}
\askmapii{S}{ab}{i}{1110}{}
- \askmapii{S}{ab}{F}{1110}{}
+ \askmapii{S}{ab}{}{1110}{}
\end{verbatim}
-\askmapii{S}{ab}{}{1010}{}
+\askmapii{S}{ab}{F}{1010}{}
\askmapii{S}{ab}{i}{1110}{}
-\askmapii{S}{ab}{F}{1110}{}
+\askmapii{S}{ab}{}{1110}{}
\bigskip\bigskip
-The Karnaugh maps for three variables: plain, with indexes but without function
+The Karnaugh maps for three variables: plain, with indexes and function
output variable.
\begin{verbatim}
- \askmapiii{S}{abc}{}{00111010}{}
- \askmapiii{F}{xyz}{iF}{11111010}{}
+ \askmapiii{S}{abc}{F}{00111010}{}
+ \askmapiii{F}{xyz}{i}{11111010}{}
\end{verbatim}
-\askmapiii{S}{abc}{}{00111010}{}
-\askmapiii{F}{xyz}{iF}{11111010}{}
+\askmapiii{S}{abc}{F}{00111010}{}
+\askmapiii{F}{xyz}{i}{11111010}{}
\bigskip\bigskip
-The Karnaugh maps for four variables: without function output variable, with
+The Karnaugh maps for four variables: plain, with function output variable and
indexes.
\begin{verbatim}
\askmapiv{f}{wxyz}{F}{1110001101000101}{}
@@ -425,19 +922,17 @@ indexes.
You can also do math things by using the known \$ signs... and you can make an
empty map for your exams...
-\newpage
\begin{verbatim}
\askmapii{$S_{0}$}{{$a_{1}$}{$a_{0}$}}{}{1010}{}
- \askmapii{}{}{}{}{}
+ \askmapii{}{}{F}{}{}
\end{verbatim}
\askmapii{$S_{0}$}{{$a_{1}$}{$a_{0}$}}{}{1010}{}
-\askmapii{}{}{}{}{}
+\askmapii{}{}{F}{}{}
\bigskip\bigskip
-You can do the math thing in roman font... and of course you can make a
-\textsl{really} empty map for your exams...
+You can do the math thing in roman upright font... and of course you can make
+a \textsl{really} empty map for your exams...
\begin{verbatim}
- \begin{verbatim}
\askmapiii{$\mathrm{M^{n+1}_{0}}$}{{$\mathrm{M^{n}_{2}}$}{$\mathrm{M^{n}_{1}}$}
{$\mathrm{M^{n}_{0}}$}}{}{11100111}{}
\askmapiii{}{}{BF}{}{}
@@ -447,13 +942,48 @@ You can do the math thing in roman font... and of course you can make a
\askmapiii{}{}{BF}{}{}
\bigskip\bigskip
+The vertical version of the three variable map, used in a \verb|minipage|
+environment:
+\begin{verbatim}
+\begin{minipage}[c]{0.25\textwidth}
+\askmapiiialt{s}{{c$_{in}$}ab}{}{01101001}{}
+\end{minipage}
+\begin{minipage}[c]{0.25\textwidth}
+\askmapiiialt{c$_{out}$}{{c$_{in}$}ab}{}{00010111}{}
+\end{minipage}\hfill%
+\begin{minipage}[c]{0.40\textwidth}
+As you can see on the left, the function of the sum of the full adder cannot
+be simplified as all 1's are placed diagonal in the map. This means that the
+function for the sum can be expressed with XOR ports.
+
+The carry-out function on the otherhand can be simplified.
+\end{minipage}
+\end{verbatim}
+
+\begin{minipage}[c]{0.25\textwidth}
+\askmapiiialt{s}{{c$_{in}$}ab}{}{01101001}{}
+\end{minipage}
+\begin{minipage}[c]{0.25\textwidth}
+\askmapiiialt{c$_{out}$}{{c$_{in}$}ab}{}{00010111}{}
+\end{minipage}\hfill%
+\begin{minipage}[c]{0.40\textwidth}
+As you can see on the left, the function of the sum of the full adder cannot
+be simplified as all 1's are placed diagonal in the map. This means that the
+function for the sum can be expressed with XOR ports.
+
+The carry-out function on the otherhand can be simplified.
+\end{minipage}
+
+\bigskip\bigskip
+
+
You can do things with don't cares...
\begin{verbatim}
\askmapii{S}{ab}{}{011-}{}
- \askmapiii{S}{abc}{F}{001--10-}{}
+ \askmapiii{S}{abc}{}{001--10-}{}
\end{verbatim}
\askmapii{S}{ab}{}{011-}{}
-\askmapiii{S}{abc}{F}{001--10-}{}
+\askmapiii{S}{abc}{}{001--10-}{}
\bigskip\bigskip
You can use colors and empty function values and variables as values too...
@@ -467,7 +997,7 @@ You can use colors and empty function values and variables as values too...
\askmapii{S}{ab}{}{{$i_{0}$}{$i_{1}$}{$i_{2}$}{$i_{3}$}}{}
\bigskip
-\newpage
+
You can set the font to something else ... and use sans math font ...
\begin{verbatim}
{\fontfamily{phv}\selectfont%
@@ -492,9 +1022,11 @@ that the origin of the picture (0,0) is at the lower left corner of the lower
left square. It is also possible to use \cs{raisebox} in conjuction with
horizontal spacing to adjust the placing of the left (least significant)
variable(s).
+
+%\newpage
\begin{verbatim}
{\fontfamily{phv}\selectfont\sansmath
- \askmapiii{F}{xy{\raisebox{2ex}{\ \ z}}}{}{11100111}{% raise Z input
+ \askmapiii{F}{xy{\raisebox{2ex}{\ \ z}}}{f}{11100111}{% raise Z input
\color{red}\put(0.1,0.1){\dashbox{0.1}(0.8,1.8){}}%
\color{blue}\put(1.1,1.1){\dashbox{0.1}(1.8,0.8){}}%
\color{darkgreen}\put(2.1,0.1){\dashbox{0.1}(1.8,0.8){}}%
@@ -511,7 +1043,7 @@ variable(s).
}}%
\end{verbatim}
{\fontfamily{phv}\selectfont\sansmath
-\askmapiii{F}{xy{\raisebox{1.5ex}{\ \ z}}}{}{11100111}{% raise Z input
+\askmapiii{F}{xy{\raisebox{1.5ex}{\ \ z}}}{f}{11100111}{% raise Z input
\color{red}\put(0.1,0.1){\dashbox{0.1}(0.8,1.8){}}%
\color{blue}\put(1.1,1.1){\dashbox{0.1}(1.8,0.8){}}%
\color{darkgreen}\put(2.1,0.1){\dashbox{0.1}(1.8,0.8){}}%
@@ -541,19 +1073,21 @@ affect the rendering of the text...
\askmapii{S}{ab}{}{1011}{}
\end{verbatim}
-{\askmapunitlength=1cm
-\askmapii{S}{ab}{}{1011}{}
-\askmapunitlength=0.88cm
-\askmapii{S}{ab}{}{1011}{}
-\askmapunitlength=0.8cm
-\askmapii{S}{ab}{}{1011}{}
-\askmapunitlength=0.5cm
+{\askmapunitlength=1cm%
+\askmapii{S}{ab}{}{1011}{}%
+\askmapunitlength=0.88cm%
+\askmapii{S}{ab}{}{1011}{}%
+\askmapunitlength=0.8cm%
+\askmapii{S}{ab}{}{1011}{}%
+\askmapunitlength=0.5cm%
\askmapii{S}{ab}{}{1011}{}}
\bigskip\bigskip
+%\newpage
An example directly from the Karnaugh package:
\begin{verbatim}
+ \kvnoindex
\askmap{4}{$f(a,b,c,d):$}{{$a$}{$b$}{$c$}{$d$}}%
{0110011001100110}%
{%
@@ -564,26 +1098,88 @@ An example directly from the Karnaugh package:
}
\end{verbatim}
{\askmapunitlength=0.88cm
+\kvnoindex
\askmap{4}{$f(a,b,c,d):$}{{$a$}{$b$}{$c$}{$d$}}%
{0110011001100110}%
{%
-\put(0,2){\oval(1.9,1.9)[r]}
-\put(4,2){\oval(1.9,1.9)[l]}
-\put(2,0){\oval(1.9,1.9)[t]}
-\put(2,4){\oval(1.9,1.9)[b]}
+\put(0,2){\oval(1.8,1.8)[r]}
+\put(4,2){\oval(1.8,1.8)[l]}
+\put(2,0){\oval(1.8,1.8)[t]}
+\put(2,4){\oval(1.8,1.8)[b]}
}}
\bigskip
-but please note that the ovals do not cover the logic 1's in the Karnaughmap
-because the function values are placed differently.
+but please note that the ovals do not cover the logic 1's in the Karnaugh map
+because the function values are placed in a different order.
+
+One can use Ti\textsl{k}Z. Please note you have to set a default corner to
+(0,0), because Ti\textsl{k}Z will create a bounding box around the the
+\texttt{tikzpicture}:
+
+\begin{verbatim}
+A static hazard can be found by inspecting the Karnaugh map and see if a change
+of minterms will cross implicants:
+
+\askmapiii{F}{xyz}{}{011100100}{%
+\begin{tikzpicture}[x=\askmapunitlength,y=\askmapunitlength]%
+\draw[draw=none,fill=none] (0,0) -- (0,0); % Set default corner
+\draw[red] (0.1,0.1) rectangle (1.9,0.9);
+\draw[blue] (1.1,1.1) rectangle (2.9,1.9);
+\draw[purple,thick,->] (1.6,1.5) to[bend left] (1.6,0.5);
+\end{tikzpicture}%
+}
+
+The function is $F = \overline{x}z + y\overline{z}$. But if the circuit is
+changing from minterm $m_2$ to $m_3$, a static hazard will occur as can
+be seen by the arrow.
+\end{verbatim}
+
+
+A static hazard can be found by inspecting the Karnaugh map and see if a change
+of minterms will cross implicants:
+
+\askmapiii{F}{xyz}{}{011100100}{%
+\begin{tikzpicture}[x=\askmapunitlength,y=\askmapunitlength]%
+\draw[draw=none,fill=none] (0,0) -- (0,0); % Set default corner
+\draw[red] (0.1,0.1) rectangle (1.9,0.9);
+\draw[blue] (1.1,1.1) rectangle (2.9,1.9);
+\draw[purple,thick,->] (1.6,1.5) to[bend left] (1.6,0.5);
+\end{tikzpicture}%
+}
+
+The function is $F = \overline{x}z + y\overline{z}$. But if the circuit is
+changing from minterm $m_2$ to $m_3$, a static hazard will occur as can
+be seen by the arrow.
+
+
+
+\section{Changelog}
+\label{sec:changelog}
+\begin{verbatim}
+ 4-dec-2013 -- v0.1
+ initial release
+ 23-oct-2020 -- v0.2
+ added option disablef
+ added askmapi - a K-map for one variable
+ added askmapiiialt - alternate (vertical) version op K-map III
+ added formatting index size, contents size and bit combination size.
+ added support for \kvindex and \nokvindex macros when kvmacros.tex is loaded
+ added formatting for left-placed variables
+ implemented a debug possibility
+ implemented linelength of variable separator
+ resolved an issue with multiple overfull \hbox'es
+ added a section on creating covers
+ added examples with Tikz
+\end{verbatim}
+
\newpage
\section{The source code}
\label{sec:sourcecode}
The source code is pretty straight forward. It uses a lot of picture primitives
for drawing the maps. The package uses three macros for processing
-variable-length parameters, which were completely reused from the karnaugh
-package.
+variable-length parameters, which were completely reused from the
+\Package{kvmacros} package.
\lstinputlisting{askmaps.sty}
diff --git a/macros/latex/contrib/ejpecp/README.md b/macros/latex/contrib/ejpecp/README.md
index 8deecbb803..d30626bca4 100644
--- a/macros/latex/contrib/ejpecp/README.md
+++ b/macros/latex/contrib/ejpecp/README.md
@@ -68,6 +68,8 @@ https://github.com/vtex-soft/texsupport.ims-ejpecp
## CHANGELOG
+- 2020/10/21 v1.9.0
+ - Supplement environment added
- 2020/08/26 v1.8.3
- Updated URLs
- 2020/08/05
diff --git a/macros/latex/contrib/ejpecp/ejpecp.dtx b/macros/latex/contrib/ejpecp/ejpecp.dtx
index bc8a7ecaf1..8e9d67c4e1 100644
--- a/macros/latex/contrib/ejpecp/ejpecp.dtx
+++ b/macros/latex/contrib/ejpecp/ejpecp.dtx
@@ -26,7 +26,7 @@
%<class>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<class>\ProvidesClass{ejpecp}
%<*class>
- [2020/08/26 v1.8.3 class for EJP and ECP journals]
+ [2020/10/21 v1.9.0 class for EJP and ECP journals]
%</class>
%<class>\ClassInfo{ejpecp}{Copyright (c) 2019-2020 Edgaras SAKURAS, VTeX, Lithuania.}
%<class>\ClassInfo{ejpecp}{Copyright (c) 2018 Deimantas GALCIUS, VTeX, Lithuania.}
@@ -47,7 +47,7 @@
%</driver>
% \fi
%
-% \CheckSum{805}
+% \CheckSum{845}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -81,6 +81,7 @@
% \changes{v1.7}{2019/04/04}{merged with production version: fixltx2e removed, natbib setup with afterpackage, etc}
% \changes{v1.8.2}{2020/07/30}{no. prefix updated and msc2020}
% \changes{v1.8.3}{2020/08/26}{Update URLs}
+% \changes{v1.9.0}{2020/10/21}{Supplement envirnment}
% \GetFileInfo{ejpecp.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment}
@@ -382,6 +383,26 @@
\hypersetup{pdfauthor={Please see \@doiprefix\@DOI}}%
}%END-PDFFIELDS
+%% Supplement
+\def\supplement@name{Supplementary Material}
+\def\stitle#1{\def\@stitle{#1}}
+\def\stitle@fmt#1{\textbf{#1.}\ }
+\def\sdescription#1{\def\@sdescription{#1}}
+\def\suppsection@fmt{\section*{\supplement@name}}
+\long\def\supplement{\@ifnextchar[{\@supplement}{\@supplement[]}}
+\long\def\@supplement[#1]{%
+ \suppsection@fmt
+ \global\let\suppsection@fmt\smallskip
+ }
+\def\endsupplement{%
+ \@ifundefined{@stitle}%
+ {}%
+ {\stitle@fmt{\@stitle}}%
+ %
+ \@ifundefined{@sdescription}{}{\@sdescription}%
+ \par
+ }
+
%% Bibliography
\def\@MRExtract#1 #2!{#1} % thanks, Martin!
\newcommand{\MR}[1]{% we need to strip the "(...)"
diff --git a/macros/latex/contrib/ejpecp/ejpecp.pdf b/macros/latex/contrib/ejpecp/ejpecp.pdf
index 7c703f05ea..290f565d11 100644
--- a/macros/latex/contrib/ejpecp/ejpecp.pdf
+++ b/macros/latex/contrib/ejpecp/ejpecp.pdf
Binary files differ
diff --git a/macros/latex/contrib/ejpecp/getmref.py b/macros/latex/contrib/ejpecp/getmref.py
new file mode 100644
index 0000000000..3241aac3aa
--- /dev/null
+++ b/macros/latex/contrib/ejpecp/getmref.py
@@ -0,0 +1,1809 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+##################################################################################
+#
+# getmref.py - gets the references links to MathSciNet through the BatchMRef:
+# https://mathscinet.ams.org/batchmref?qdata=xmldocument
+#
+# Copyright (C) 2017 Sigitas Tolusis, VTeX Ltd., Jim Pitman, Dept. Statistics,
+# U.C. Berkeley and Lolita Tolene, VTeX Ltd.
+# E-mail: latex-support@vtex.lt
+# http://www.stat.berkeley.edu/users/pitman
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# Requires:
+# - python ver. >=2.2
+# - [ for option --enc=auto ]
+# Universal Encoding Detector library, written by Mark Pilgrim.
+#
+# Usage:
+# getmref.py <bbl or tex file>
+#
+# Program (description):
+# - makes inputfile copy to <inputfilename>.getmref.bak;
+# - for each successful bibitem reference search adds line \MR{<mrid>},
+# where <mrid> is data from XML tag <mrid> without front symbols "MR";
+# - writes all adds to <inputfilename>;
+# - generates log file <inputfilename>.getmref.log;
+# - writes to stdout log info
+#
+# Changes:
+# 2004/04/26 - \bibitem line removed from the query
+# 2017/01/12 - input file may contain 'amsrefs', 'bibtex' and 'tex' type
+# references (all at once);
+# input references can be formatted as 'amsrefs', 'bibtex',
+# 'tex' or 'html' type references
+#
+#
+##################################################################################
+
+__version__ = "GetMRef, v2.4"
+
+import sys
+import os
+import re
+import string
+import urllib
+import urllib2
+import ssl
+import shutil
+import logging
+from time import time, sleep
+from xml.dom.minidom import parseString
+from xml.parsers.expat import ExpatError
+
+BASICFORMATTER = logging.Formatter('%(message)s')
+DEBUGFORMATTER = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+
+log = logging.getLogger(__name__)
+log.addHandler(logging.NullHandler())
+flog = slog = log
+
+
+class RefTypes(object):
+ """ This class declares recognized bibliography reference formats
+
+ Formats description
+ -------------------
+ Source: only AMS
+ "tex": LaTeX code without any specific beginning/ending;
+ MR number is given in plain text
+ "html": <a href="http://www.ams.org/mathscinet-getitem?mr=7digits">
+ 7digits
+ </a>
+
+ Source: only user
+ "bibitem": \bibitem[<name-year info>]{<cite_key>}
+ ...
+ \MR{<7 digits>}
+ \endbibitem,
+ where '[<name-year info>]' and '\endbibitem' are optional
+ Requires environment
+ \begin{thebibliography}{<ref no>}
+ ...
+ \end{thebibliography}
+
+ Source: AMS and user
+ "bibtex": @<ref type>{<cite_key>,
+ <key1>={<value1>},
+ <key2>={<value2>},
+ MRNUMBER={<7 digits>}
+ ...}
+ "amsrefs": \bib{<cite_key>}{<ref type>}{
+ <key1>={<value1>},
+ <key2>={<value2>},
+ review={\MR{<7 digits>}}
+ ...}
+ Requires environment
+ \begin{biblist}
+ ...
+ \end{biblist}
+ """
+
+ TEX = "tex"
+ BIBITEM = "bibitem"
+ IMS = "ims"
+ BIBTEX = "bibtex"
+ AMSREFS = "amsrefs"
+ HTML = "html"
+
+ # Reference input formats
+ ITYPES = (BIBITEM, BIBTEX, AMSREFS)
+
+ # Reference output formats
+ OTYPES = (TEX, BIBTEX, IMS, AMSREFS, HTML)
+
+
+class LessThanFilter(logging.Filter):
+ """ This class allows to add an upper bound to the logged messages
+
+ Example
+ -------
+ One needs to log all non-error messages to stdout, and all errors
+ (higher level) only to stderr
+ """
+
+ def __init__(self, exclusive_maximum, name=""):
+ super(LessThanFilter, self).__init__(name)
+ self.max_level = exclusive_maximum
+
+ def filter(self, record):
+ # A non-zero return means we log this message
+ return 1 if record.levelno <= self.max_level else 0
+
+
+class FilesHandler(RefTypes):
+ """ This class unites methods and attributes related to
+ files I/O actions """
+
+ IN = 'in'
+ BAK = 'bak'
+ OUT = 'out'
+ DATA = 'data'
+ TMP = 'tmp'
+ AUX = 'aux'
+ BIB = 'bib'
+ HTML = 'html'
+ LOG = 'log'
+ ERR = 'err'
+
+ # File status map:
+ # if True file will be open until closed;
+ # if False it will be opened on demand
+ FILE_STATUS = {OUT: True,
+ LOG: False,
+ ERR: False,
+ DATA: True,
+ BIB: True,
+ AUX: True,
+ HTML: True,
+ TMP: False}
+
+ READ = 'r'
+ WRITE = 'w'
+
+ GMR_SUFFIX = 'getmref'
+
+ def __init__(self, infile, outputtype):
+ """ Initiate file handling methods and attributes
+
+ Parameters
+ ----------
+ infile : str or None
+ Path to input file
+ outputtype : str or None
+ Required bibliography reference output format type
+ """
+
+ self.infile = infile
+ self._basename = os.path.splitext(infile)[0]
+
+ # Determining needed file types for given reference output type
+ msg = ("The given references will be formatted in '%s' format. "
+ % (outputtype if outputtype is not None else "orig"))
+
+ unnecessary = [self.DATA, self.BIB, self.AUX, self.HTML]
+ if outputtype in [self.BIBTEX, self.IMS]:
+ unnecessary = [self.DATA, self.HTML]
+ # Referring to 'BIB' file as 'DATA'
+ self.DATA = self.BIB
+ msg += "Additional files will be created: *.%s, *.%s" \
+ % (self.BIB, self.AUX)
+ elif outputtype == self.HTML:
+ unnecessary = [self.DATA, self.BIB, self.AUX]
+ # Referring to 'HTML' file as 'DATA'
+ self.DATA = self.HTML
+ msg += "Additional file will be created: *.%s" % self.HTML
+ elif outputtype in [self.TEX, self.AMSREFS]:
+ unnecessary = [self.HTML, self.BIB, self.AUX]
+ msg += "Additional file will be created: *.%s" % self.DATA
+
+ self.files = dict()
+ for suffix, status in self.FILE_STATUS.items():
+ # Deleting old files
+ self._delete(suffix)
+ if suffix in unnecessary:
+ continue
+ if status:
+ self.open(suffix)
+ continue
+ self.files.update({suffix: self.get_fname(suffix)})
+
+ flog.info("File: %s" % infile)
+ if not (os.path.isfile(infile) and os.path.exists(infile)):
+ logging.shutdown()
+ for suffix in self.FILE_STATUS:
+ self.close_and_delete(suffix)
+ raise ValueError("Provided source file does not exist! "
+ "Please provide the valid one.")
+
+ flog.debug("Workdir: %s" % os.path.abspath(os.path.dirname(infile)))
+ flog.debug(msg)
+
+ def set_fname(self, suffix):
+ """ Set a filepath for a file with the provided suffix
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+
+ Returns
+ -------
+ str
+ """
+ return ("%s.%s.%s" % (self._basename, self.GMR_SUFFIX, suffix)
+ if suffix != self.IN else self.infile)
+
+ def get_fname(self, suffix):
+ """ Get filepath of a file with the required suffix
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+
+ Returns
+ -------
+ str
+ If requested file is open, returning file object name,
+ or the filepath otherwise
+ """
+ target = self.files.get(suffix, self.set_fname(suffix))
+ if isinstance(target, file):
+ return target.name
+ return target
+
+ def open(self, suffix, mask=WRITE):
+ """ Open file for the selected action
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+ mask : str
+ Possible actions are read or write
+
+ File is opened and file object is added to the dictionary
+ for later access
+ """
+ self.files.update({suffix: file(self.get_fname(suffix), mask)})
+
+ def read(self, suffix):
+ """ Get the content of a file with the required suffix
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+
+ Yields
+ ------
+ str
+ """
+ with open(self.get_fname(suffix), self.READ) as ifile:
+ for iline in ifile:
+ yield iline
+
+ def write(self, suffix, msg):
+ """ Write to the file with the required suffix
+ only if this file is open
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+ msg : str
+ """
+ target = self.files.get(suffix, None)
+ if isinstance(target, file):
+ target.write(msg)
+
+ def close(self, suffix):
+ """ Close the file with the required suffix
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+ """
+ fileobj = self.files.get(suffix, "")
+ if isinstance(fileobj, file):
+ fileobj.close()
+
+ def _delete(self, suffix):
+ """ Delete the file with the required suffix
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+ """
+ dfile = self.get_fname(suffix)
+ try:
+ os.unlink(dfile)
+ flog.debug("Deleted: %s" % os.path.split(dfile)[1])
+ except OSError:
+ if os.path.isfile(dfile) and os.path.exists(dfile):
+ flog.exception("Can't remove file: %s" % dfile)
+
+ def close_and_delete(self, suffix):
+ """ Close and delete the file with the required suffix
+
+ Parameters
+ ----------
+ suffix : str
+ File suffix without punctuation
+ """
+ self.close(suffix)
+ self._delete(suffix)
+
+ def close_files(self):
+ """ Close all open files and logging instances,
+ create backup of the input file and
+ overwrite it with the new content, delete auxiliary files
+ """
+ flog.debug("Closing files...")
+ for suffix in self.files:
+ self.close(suffix)
+
+ self._delete(self.TMP)
+
+ bfile = self.get_fname(self.BAK)
+ if os.path.exists(bfile):
+ shutil.copy2(self.infile, bfile)
+ else:
+ os.rename(self.infile, bfile)
+ flog.debug("Created backup of the input file: %s"
+ % os.path.split(bfile)[1])
+
+ ofile = self.get_fname(self.OUT)
+ if os.path.exists(ofile):
+ shutil.copy2(ofile, self.infile)
+ self._delete(self.OUT)
+ else:
+ os.rename(ofile, self.infile)
+ flog.debug("The input file is overwritten with: %s"
+ % os.path.split(ofile)[1])
+
+ logging.shutdown()
+
+
+class RefHandler(RefTypes):
+ """ This class unites methods and attributes related to bibliography
+ reference format types and their content modifications """
+
+ # Bibliography environment
+ BIBL_ENV = "environment"
+ BIBL_BEGIN = "begin"
+ BIBL_END = "end"
+
+ # Declaration of typical reference type ending and
+ # MR id format for this type
+ FORMAT_PROPERTIES = {
+ RefTypes.BIBTEX: {
+ "ref_ending": "}",
+ "mr_format": ",\nMRNUMBER={%s},\n"
+ },
+ RefTypes.AMSREFS: {
+ "ref_ending": "}",
+ "mr_format": ",\nreview={\MR{%s}},\n"
+ },
+ RefTypes.BIBITEM: {
+ "ref_ending": "\\endbibitem",
+ "mr_format": "\n\\MR{%s}\n"
+ }
+ }
+
+ # Meaningful reference keys for AMS Batch MR Lookup query
+ KEYS = {"0AUTH": ("author",),
+ "1TTL": ("title", "maintitle"),
+ "2JOUR": ("journal", "journaltitle", "fjournal", "booktitle"),
+ "3VID": ("volume",),
+ "4IID": ("number", "series"),
+ "5PID": ("pages",),
+ "6YNO": ("year", "date"),
+ "7ISSN": ("issn", "isrn", "isbn")}
+
+ PATTERN_KEY_VALUE = "^\s*([\w-]+)\s*=\s*(.*?)$"
+
+ PATTERN_LINE_END = r'(\r?\n)+'
+ PATTERN_PAR = r'(\r?\n){2}'
+
+ PATTERN_BIBL_ENV = (r'\s*\\(?P<envstatus>begin|end)\s*'
+ r'\{(thebibliography|biblist\*?)\}(.*)$')
+
+ PATTERN_BIBRE = r'^\s*\\bibitem.*'
+ PATTERN_BIBREF = (r'\s*\\bibitem\s*(?P<biblabel>\[.*?\])*?\s?'
+ r'\{(?P<citekey>.*?)\}(?P<text>.*)$')
+ PATTERN_BIBTEX = (r'^\s*(@\S+)(?<!@preamble)\s*'
+ r'{(?P<citekey>\S+)\s*,(?P<text>.*)$')
+ PATTERN_AMSREFS = r"\\bib\s*{(?P<citekey>.*)}\s*{(.*)}\s*{(?P<text>.*)$"
+
+ def __init__(self, outputtype):
+ """ Initiate reference handling methods and attributes
+
+ Parameters
+ ----------
+ outputtype : str or None
+ Required reference output format type
+ """
+
+ self.outputtype = outputtype
+
+ self.re_bibl_env = re.compile(self.PATTERN_BIBL_ENV)
+ self.re_bibre = re.compile(self.PATTERN_BIBRE)
+ self.re_bibreF = re.compile(self.PATTERN_BIBREF, re.S)
+ self.re_bibtex = re.compile(self.PATTERN_BIBTEX, re.M)
+ self.re_amsrefs = re.compile(self.PATTERN_AMSREFS, re.M)
+
+ self.re_lineend = re.compile(self.PATTERN_LINE_END)
+ self.re_par = re.compile(self.PATTERN_PAR)
+ self.re_key_value = re.compile(self.PATTERN_KEY_VALUE, re.DOTALL)
+
+ def find_reference(self, line):
+ """ Identify reference environment or element by using regex patterns
+
+ Parameters
+ ----------
+ line : str
+
+ Returns
+ -------
+ str or None
+ If match is found, returns the reference type, None otherwise
+ dict
+ Dictionary contains regex pattern group names and their matches
+
+ The value of the key 'text' is the line part without user
+ defined strings, such as citekey and biblabel, because they may
+ contain some misleading information for BatchMRef query
+ """
+
+ elems = {self.BIBL_ENV: self.re_bibl_env,
+ self.BIBTEX: self.re_bibtex,
+ self.AMSREFS: self.re_amsrefs}
+
+ # BIBITEM search starts with an additional check
+ # which other reference types doesn't have
+ if self.re_bibre.search(line) is not None:
+ elems = {self.BIBITEM: self.re_bibreF}
+
+ for reftype, pattern in elems.items():
+ match = pattern.search(line)
+ if match is not None:
+ return reftype, match.groupdict()
+ elif reftype == self.BIBITEM:
+ # If final search for BIBITEM fails, it means that the typical
+ # structure for this reference type is placed on several lines,
+ # therefore the current line is prepended to the next input line
+ return reftype, {"line": line}
+ return None, dict()
+
+ def extract_keys_data(self, lines):
+ """ Extract values from selected keys in reference
+
+ Parameters
+ ----------
+ lines : list
+
+ Returns
+ -------
+ str
+ Output contains extracted values separated by commas
+ """
+ flog.debug(">> Extracting key values from reference")
+ querystring = ""
+ user_key = None
+ found = list()
+ for line in lines:
+ match = self.re_key_value.search(line)
+ if match:
+ user_key, user_value = match.groups()
+ user_key = user_key.lower()
+ for key, value in sorted(self.KEYS.items()):
+ if user_key in value and (user_key in found or key not in found):
+ found.append(key)
+ found.append(user_key)
+ querystring += "%s, " % user_value.strip().rstrip(",")\
+ .strip().strip('"')\
+ .strip().rstrip("}")\
+ .lstrip("{").strip()
+ break
+ elif len(found) > 0 and found[-1] == user_key:
+ querystring = "%s %s, " % (querystring.strip(", "),
+ line.strip().rstrip(",").strip().strip('"')
+ .strip().rstrip("}").lstrip("{")
+ .strip().rstrip(",").strip())
+
+ return querystring.strip(", ")
+
+ def insert_mrid(self, reftype, refstring, mrid):
+ """ Format MR number according to the input reference format and
+ append it to the input reference
+
+ Parameters
+ ----------
+ reftype : str
+ Determined input bibliography reference item type
+ refstring : str
+ Input bibliography reference item content
+ mrid : str
+ MR number returned by query to BatchMRef
+
+ Returns
+ -------
+ str
+ Output contains input bibliography reference element including
+ according to reftype formatted mrid.
+ """
+ properties = self.FORMAT_PROPERTIES.get(reftype, None)
+ if properties is None:
+ outstring = self.re_lineend.sub('\n', refstring)
+ return '%s\\MR{%s}\n\n' % (outstring, mrid)
+
+ mr_string = properties["mr_format"] % mrid
+ ending_index = refstring.rfind(properties["ref_ending"])
+ if ending_index == -1:
+ paragraph = self.re_par.search(refstring)
+ if paragraph is not None:
+ ending_index = paragraph.start()
+ mr_string += "\n"
+
+ if ending_index != -1:
+ return "%s%s%s" % (refstring[:ending_index].strip().strip(","),
+ mr_string,
+ refstring[ending_index:].lstrip())
+
+ return refstring.strip() + mr_string + "\n"
+
+ def insert_citekey(self, outref, citekey, biblabel, querystring):
+ """ Add a cite key, extracted from an input reference item,
+ to the reference content, returned by the query to BatchMRef
+ (XML tag <outref>), in the required reference output format
+
+ Parameters
+ ----------
+ outref : str or None
+ Reference item content returned by the query to BatchMRef
+ citekey : str
+ Input bibliography reference item cite key
+ biblabel : str or None
+ Input bibliography reference item label,
+ provided in optional parameter of reference type of BIBITEM
+ querystring : str
+ Input bibliography reference item formatted for query
+ to BatchMRef
+
+ Returns
+ -------
+ str or None
+ Returned string is the outref including the citekey and
+ the biblabel (if provided) if reference has been found in
+ the AMS MR DB, else string is formatted according to the
+ requested output type.
+
+ If allowed output type is not provided, None is returned
+ """
+
+ if self.outputtype is None:
+ return None
+
+ if outref is None:
+ if self.outputtype == self.TEX:
+ return ("\\bibitem%s{%s}\n Not Found!\n\n"
+ % (biblabel if biblabel is not None else "",
+ citekey))
+ if self.outputtype == self.BIBTEX:
+ return '@MISC {%s,\n NOTE = {Not Found!}\n}\n\n' % citekey
+ if self.outputtype == self.IMS:
+ return ('@MISC {%s,\n HOWPUBLISHED = {%s},\n}\n\n'
+ % (citekey, querystring))
+ if self.outputtype == self.AMSREFS:
+ return ('\\bib{%s}{misc}{\n note = {Not Found!}\n}\n\n'
+ % citekey)
+ if self.outputtype == self.HTML:
+ return '<!-- %s -->\nNot Found!\n<br/><br/>\n\n' % citekey
+ return None
+
+ outref = outref.strip() + '\n\n'
+ if self.outputtype == self.TEX:
+ return ('\\bibitem%s{%s}\n%s'
+ % (biblabel if biblabel is not None else "",
+ citekey, outref))
+ if self.outputtype in [self.BIBTEX, self.IMS]:
+ return self.re_bibtex.sub(r'\1 {%s,' % citekey, outref)
+ if self.outputtype == self.AMSREFS:
+ return self.re_amsrefs.sub(r'\\bib\0{%s}{\2}' % citekey, outref)
+ if self.outputtype == self.HTML:
+ return '<!-- %s -->\n%s<br/><br/>\n' % (citekey, outref)
+ return None
+
+
+class RefElement(object):
+ """ This is a container for one bibliography reference item,
+ containing all data related to it """
+
+ FORMAT_PROPERTIES = RefHandler.FORMAT_PROPERTIES
+
+ def __init__(self, refid=None, reftype=None, citekey=None, biblabel=None):
+ """ Initiate reference item container
+
+ Parameters
+ ----------
+ refid : int or None
+ reftype : str or None
+ Input bibliography reference type (one of RefTypes.ITYPES).
+ citekey : str or None
+ Input bibliography reference cite key
+ biblabel : str or None
+ Input bibliography reference label,
+ provided in the optional parameter of RefTypes.BIBITEM type
+ reference item
+ """
+
+ self.reftype = reftype
+ self.refid = refid
+ self.citekey = citekey
+ self.biblabel = biblabel
+
+ self.orig_lines = list()
+ self.cleaned_lines = list()
+ self.query_lines = list()
+ self.comment_lines = list()
+
+ self.errno = 0
+ self._init_querystring = None
+ self._querystring = None
+ self._mrid = None
+ self.outref = None
+
+ def normalize(self, lines):
+ """ Normalize the reference item content
+ Parameters
+ ----------
+ lines : list
+
+ Returns
+ -------
+ str
+ Returned string doesn't contain trailing spaces and
+ typical ending for the reference of reftype (if found)
+ """
+ nstring = re.sub('\s+', ' ', ''.join(lines)).strip()
+ ending = self.FORMAT_PROPERTIES.get(self.reftype,
+ dict()).get("ref_ending", "")
+ ending_index = nstring.rfind(ending)
+ if ending_index != -1:
+ nstring = nstring[:ending_index].strip()
+ return nstring
+
+ @property
+ def init_querystring(self):
+ if self._init_querystring is not None:
+ return self._init_querystring
+
+ flog.debug(">> Normalizing the reference")
+ self._init_querystring = self.normalize(self.query_lines)
+
+ return self._init_querystring
+
+ @property
+ def querystring(self):
+ if self._querystring is not None:
+ return self._querystring
+ return self.init_querystring
+
+ @querystring.setter
+ def querystring(self, istring):
+ self._querystring = istring
+
+ @property
+ def mrid(self):
+ return self._mrid
+
+ @mrid.setter
+ def mrid(self, mrid):
+ """ Normalize MR number, returned by the query to BatchMRef
+
+ Parameters
+ ----------
+ mrid : str
+
+ Returns
+ -------
+ str
+ If original MR number is shorter than 7 symbols, prepending 0,
+ till it reaches 7 symbol length
+ """
+ if mrid is not None:
+ self._mrid = mrid.encode('ascii').lstrip("MR").rjust(7, '0')
+
+ def __repr__(self):
+ result = "<%s:\n" % self.__class__.__name__
+ for key, value in sorted(self.__dict__.items()):
+ if key.startswith("_"):
+ continue
+ result += " %s = %s\n" % (key, repr(value))
+ result += " >\n"
+ return result
+
+ def __str__(self):
+ return self.__repr__()
+
+
+class RefsContainer(object):
+ """ This is a container holding as many bibliography reference items as
+ is allowed by the denoted query to BatchMRef limit and data common
+ to all of them """
+
+ def __init__(self):
+ super(RefsContainer, self).__init__()
+ self.elems = list()
+ self.qerrno = 0
+
+ def append_elem(self, ref_element):
+ """ Add bibliography reference item instance to the container
+
+ Parameters
+ ----------
+ ref_element : RefElement() instance
+ """
+
+ self.elems += (ref_element,)
+
+ def get_elem_by_refid(self, refid):
+ """ Get bibliography reference item instance by its id
+
+ Parameters
+ ----------
+ refid : int
+
+ Returns
+ -------
+ RefElement() instance or None
+ If element with required id is not found, None is returned
+ """
+
+ elem = [e for e in self.elems if e.refid == refid]
+ if elem:
+ return elem[0]
+
+ def __str__(self):
+ result = "<%s:\n" % self.__class__.__name__
+ for key, value in sorted(self.__dict__.items()):
+ if key == "elems":
+ for elem in value:
+ result += " %s" % repr(elem)
+ elif key not in ["elems", "qresult", "xml"]:
+ result += " GLOBAL: {} = {}\n".format(key, value)
+ result += " >\n"
+ return result
+
+
+class QueryHandler(RefTypes):
+ """ This class unites methods and attributes related to actions necessary
+ for the AMS BatchMRef query """
+
+ AUTO_ENC = "auto"
+ LATIN1 = 'latin1'
+ ASCII = "ascii"
+
+ AMS_URL = 'https://mathscinet.ams.org/batchmref'
+
+ # AMS BatchMRef limit of items no per query
+ QUERY_ITEMS_LIMIT = 100
+
+ QUERY_XML_HEADING_STRING = '<?xml version="1.0" encoding="UTF-8"?>\n'
+
+ QUERY_HEADING_STRING = (
+ '<mref_batch>\n'
+ ' %s'
+ '</mref_batch>'
+ )
+
+ QUERY_ITEM_STRING = (
+ '<mref_item outtype="%s">\n'
+ ' <inref>\n'
+ ' %s\n'
+ ' </inref>\n'
+ ' <myid>%d</myid>\n'
+ '</mref_item>\n'
+ )
+
+ QUERY_FORMATS = {
+ RefTypes.TEX: RefTypes.TEX,
+ RefTypes.BIBTEX: RefTypes.BIBTEX,
+ RefTypes.IMS: RefTypes.BIBTEX,
+ RefTypes.AMSREFS: RefTypes.AMSREFS,
+ RefTypes.HTML: RefTypes.HTML,
+ None: RefTypes.TEX
+ }
+
+ PATTERN_MREF_ITEM = '(\<mref_item outtype="(?:bibtex|tex|amsrefs|html)"\>.*?\</mref_item\>)'
+ PATTERN_BATCH_ERROR = '\<batch_error\>(.*?)\</batch_error\>'
+
+ # AMS gives the following message in HTML if requested website is broken
+ AMS_MSG = "The AMS Website is temporarily unavailable."
+
+ def __init__(self, encoding, outputtype, refscontainer, address=AMS_URL):
+ """ Initiate query to BatchMRef handling methods and attributes
+
+ Parameters
+ ----------
+ encoding : str
+ Input file encoding
+ outputtype : str or None
+ Reference output format type passed for BatchMRef query
+ refscontainer : RefsContainer() instance
+ address : str
+ BatchMRef query address
+ """
+
+ self.encoding = encoding
+ flog.debug("Provided encoding format: %s" % encoding)
+ self.address = address
+ self.query_format = self.QUERY_FORMATS.get(outputtype, self.TEX)
+ flog.debug("Query settings: URL = %s, output format = %s"
+ % (address, self.query_format))
+ self.outputtype = outputtype
+
+ self.errno = 0
+ self.qresult = None
+ self.qcode = None
+ self.xml = None
+ self.re_mref_item = re.compile(self.PATTERN_MREF_ITEM, re.DOTALL)
+ self.re_batch_error = re.compile(self.PATTERN_BATCH_ERROR, re.DOTALL)
+
+ self._refscontainer = refscontainer
+ self.query_elems = list()
+
+ @property
+ def refscontainer(self):
+ return self._refscontainer
+
+ def _encode_str(self, istring):
+ """ Change query string encoding into the ASCII
+
+ Parameters
+ ----------
+ istring : str
+
+ Returns
+ -------
+ str
+ """
+
+ str_enc = self.encoding
+ self.errno = 0
+ if str_enc == self.AUTO_ENC:
+ detector = UniversalDetector()
+ detector.feed(istring)
+ detector.close()
+ str_enc = detector.result.get('encoding', self.ASCII)
+ flog.debug(">> Determined string encoding: %s" % str_enc)
+
+ if str_enc == self.ASCII:
+ return istring
+ if str_enc is None:
+ flog.debug(">> Encoding determination has FAILED! ")
+ return istring
+
+ try:
+ return istring.decode(str_enc.lower()).encode(self.ASCII,
+ errors='replace')
+ except:
+ flog.debug(">> encoding given reference element FAILED!")
+ msg = (">> encoding given reference element FAILED!\n"
+ "[Input string]:\n%s\n" % istring)
+ flog.exception(msg)
+ self.errno = -2
+ return istring
+
+ @staticmethod
+ def _escape_tex(istring):
+ """ Convert TeX symbols into XML valid symbols
+
+ Parameters
+ ----------
+ istring : str
+
+ Returns
+ -------
+ str
+ """
+
+ flog.debug(">> Converting TeX symbols into XML valid symbols")
+ return reduce(lambda a, b: string.replace(a, b[0], b[1]),
+ (istring, ("\\&", '&amp;'), ("<", '&lt;'), (">", '&gt;'),
+ ("&", '&amp;'), (r"\ndash ", "-")))
+
+ def _parse_str(self, istring, check=False):
+ """ Parse string into XML object
+
+ Parameters
+ ----------
+ istring : str
+ check : bool
+ If True, checking if string parses to valid XML.
+ If False, saving parsed XML or an error code
+ if parsing was unsuccessful
+ """
+
+ try:
+ xml = parseString(istring)
+ if not check:
+ self.xml = xml
+ else:
+ flog.debug("VALIDATING XML string ...")
+ flog.debug(">> XML contains no errors")
+ except ExpatError as err:
+ flog.debug(">> Parsing given XML FAILED!")
+ msg = (">> Parsing given XML FAILED!\n",
+ "[Parse query]:\n%s\n" % istring)
+ flog.exception(msg)
+ self.errno = err.code
+
+ def prepare_query_str(self, refid, querystring):
+ """ Format the reference as an XML string and validate it
+
+ Parameters
+ ----------
+ refid : int
+ RefElement() instance id
+ querystring : str
+
+ Returns
+ -------
+ int
+ If query string was encoded and parsed into valid XML
+ successfully, it is appended to a future query strings list
+ and error code is set to 0
+
+ If something went wrong, non-zero value is returned
+ """
+
+ self.errno = 0
+ flog.debug("PREPARING query reference")
+
+ single_qstring = self._encode_str(
+ self.QUERY_ITEM_STRING % (self.query_format,
+ self._escape_tex(querystring),
+ refid)
+ )
+ flog.debug(">> Formed query XML:\n"
+ + "~" * 70 + "\n%s\n" % single_qstring + "~" * 70)
+
+ # Checking if formed string is a valid XML
+ self._parse_str(single_qstring, check=True)
+ if self.errno != 0:
+ return self.errno
+
+ self.query_elems.append(single_qstring)
+ return self.errno
+
+ def _send_query(self, querystring):
+ """ Send query to BatchMRef
+
+ Parameters
+ ----------
+ querystring : str
+ Validated XML query string, containing as many reference items
+ as QueryHandler.QUERY_ITEMS_LIMIT allows
+
+ If request to BatchMRef was successful, saving query result,
+ otherwise non-zero error code is saved
+ """
+
+ queryinfo = {'qdata': querystring}
+ queryval = urllib.urlencode(queryinfo)
+ try:
+ flog.debug("SENDING query ...")
+ req = urllib2.Request(url=self.address, data=queryval)
+ flog.debug(">> Query POST data: %s" % req.get_data())
+ context = ssl._create_unverified_context()
+ batchmref = urllib2.urlopen(req, context=context)
+ self.qcode = batchmref.getcode()
+ flog.debug(">> Query result code: %s" % self.qcode)
+ self.qresult = batchmref.read()
+
+ if self.qcode == 200 and \
+ self.qresult.startswith(self.QUERY_XML_HEADING_STRING):
+ flog.debug(">> Query result string:\n"
+ + "~"*70 + "\n%s\n" % self.qresult.strip() + "~"*70)
+ else:
+ msg = "\n%s" % self.AMS_MSG if self.AMS_MSG in self.qresult else ""
+ flog.debug(">> Query FAILED! %s" % msg)
+ flog.error("Query returned an error:\n%s\n\n%s"
+ % (msg, self.qresult))
+ self.errno = self.qcode if self.qcode != 200 else -2
+ self.qresult = None
+
+ batchmref.close()
+ except:
+ msg = ">> Query FAILED!"
+ flog.debug(msg)
+ flog.exception(msg)
+ self.errno = -2
+ self.qresult = None
+
+ @staticmethod
+ def _extract_xml_data(xml_elem, tag):
+ """ Extract text data from an XML object
+
+ Parameters
+ ----------
+ xml_elem : XML object
+ tag : str
+ XML tag of interest
+
+ Returns
+ -------
+ str or None
+ Content of XML element with the requested tag.
+ If element with the tag hasn't been found, None is returned
+ """
+
+ childelem = xml_elem.getElementsByTagName(tag)
+ if childelem:
+ childnodes = childelem[0].childNodes
+ if childnodes:
+ return childnodes[0].data
+
+ def _analyze_xml(self, xml):
+ """ Extract reference data from the BatchMRef returned XML string,
+ parsed into XML object
+
+ Parameters
+ ----------
+ xml : XML object
+
+ If no matches have been found in the AMS MR DB,
+ current RefElement() instance gets a non-zero error code.
+ Otherwise MR number and reference content (if requested output type
+ is not None) are saved in the current RefElement() instance
+ """
+
+ mref_item = xml.getElementsByTagName("mref_item")[0]
+ refid = int(self._extract_xml_data(mref_item, "myid"))
+ elem = self.refscontainer.get_elem_by_refid(refid)
+
+ matches = self._extract_xml_data(mref_item, "matches")
+ if matches == '1':
+ flog.debug(">> MRef DB: reference `%s' found!" % elem.citekey)
+ elem.mrid = self._extract_xml_data(mref_item, "mrid")
+ flog.debug(">> MRef ID: %s" % elem.mrid)
+
+ if self.outputtype is not None:
+ elem.outref = self._extract_xml_data(mref_item, "outref")
+ flog.debug(">> MRef output reference:\n"
+ + "~"*70 + "\n%s\n" % elem.outref.strip() + "~"*70)
+ else:
+ elem.errno = -1
+ flog.debug(">> MRef DB: reference `%s' not found!" % elem.citekey)
+
+ def query(self):
+ """ Send a request to AMS BatchMRef and analyze the returned data
+
+ If query result contains 'batch_error' element or returned
+ XML string can't be parsed into XML object,
+ RefsContainer() instance gets a non-zero error code.
+ """
+
+ self.errno = 0
+ self.qresult = None
+
+ querystring = (self.QUERY_XML_HEADING_STRING
+ + self.QUERY_HEADING_STRING % ("\n".join(self.query_elems)))
+ if self.errno == 0:
+ self._send_query(querystring)
+ if self.qresult is not None:
+ error_obj = self.re_batch_error.search(self.qresult)
+ if error_obj:
+ flog.debug(">> Query XML contains an ERROR!")
+ flog.error("[batch_error]:\n%s\n\n[querystring]:\n%s"
+ % (self._encode_str(error_obj.group(1)),
+ querystring))
+ self.errno = -2
+ flog.debug("Splitting query result and analyzing parts separately")
+ for item_qresult in self.re_mref_item.finditer(self.qresult):
+ self.xml = None
+ self._parse_str(self._encode_str(item_qresult.group()))
+ if self.xml is not None:
+ self._analyze_xml(self.xml)
+
+ self.refscontainer.qerrno = self.errno
+ self.query_elems = list()
+
+
+class HandleBBL(RefTypes):
+ """ This is the main class containing and initiating other classes'
+ methods and attributes for provided input data processing """
+
+ # MR number pattern matching all recognized reference formats
+ PATTERN_MR = r'MRNUMBER=\{.*?\}(,|)|review=\{\\MR\{.*?\}\}(,|)|\\MR\{.*?\}'
+
+ PATTERN_BIBRE_LINE = r'^%.*\r?\n$'
+ PATTERN_BIBRE_PART = r'\s*(.*?)(?<!\\)%.*\r?\n$'
+
+ PATTERN_TEX_ACCENTS = r"""(?:\{|)\\(?:"|'|`|\^|-|H|~|c|k|=|b|\.|d|r|u|v|A)(?:|\{)([a-zA-Z])\}(?:\}|)"""
+ PATTERN_BRACED_LETTERS = r"""(\s)(?<!\\)([a-zA-Z]*)\{([A-Z]+)\}"""
+
+ # Mark of the input file ending
+ EOF = "EOF"
+
+ # Default bibstyle format
+ PLAIN = 'plain'
+
+ def __init__(self, inputfile, encoding, clean_comments,
+ itemno, wait, outputtype, bibstyle, debug, version=str()):
+ """ Initiate all methods and attributes required to process input data
+
+ Parameters
+ ----------
+ inputfile : str or None
+ encoding : str
+ Input file encoding
+ clean_comments : bool
+ If TeX comments cleaning is selected,
+ full comment lines will be moved to the beginning of each
+ identified bibliography reference item
+ itemno : int
+ Limit of reference items per query to BatchMRef
+ wait: int
+ Pause length after each query to BatchMRef
+ outputtype : str or None
+ If not None, additional files with the requested references,
+ extracted from the AMS MR DB in the requested output format,
+ will be generated
+ bibstyle : str or None
+ Used only if the requested output type is BIBTEX or IMS
+ debug : int
+ If debug value is greater than 0, debug messages will be
+ written to the FileHandler.LOG file. Also, depending on the
+ given debug value, final data written to the input file will
+ contain TeX comments with query data.
+ version : str
+ """
+
+ self.refscontainer = RefsContainer()
+
+ self.fh = FilesHandler(inputfile, outputtype)
+ self.rh = RefHandler(outputtype)
+ self.qh = QueryHandler(encoding, outputtype, self.refscontainer)
+
+ if itemno < self.qh.QUERY_ITEMS_LIMIT:
+ self.qh.QUERY_ITEMS_LIMIT = itemno
+ self.wait = wait
+
+ self.outputtype = outputtype
+ self.bibstyle = bibstyle
+ flog.debug("Comments will be cleaned from the output: %s"
+ % clean_comments)
+ self.clean_comments = clean_comments
+ self.debug = debug
+ self.version = version
+
+ self.re_bibre_line = re.compile(self.PATTERN_BIBRE_LINE)
+ self.re_bibre_part = re.compile(self.PATTERN_BIBRE_PART)
+ self.re_MR = re.compile(self.PATTERN_MR)
+ self.re_tex_accents = re.compile(self.PATTERN_TEX_ACCENTS)
+ self.re_braced_letters = re.compile(self.PATTERN_BRACED_LETTERS)
+
+ self.eof = False
+ self.ifile_end_lines = list()
+
+ @property
+ def icontent(self):
+ """ Input file content """
+ return self.fh.read(self.fh.IN)
+
+ @property
+ def write(self):
+ return self.fh.write
+
+ @property
+ def get_fname(self):
+ return self.fh.get_fname
+
+ def preprocess_ofiles(self):
+ """ Depending on the requested bibliography output type,
+ certain files are pre-filled with required data.
+ Writing action is fulfilled only if requested file was pre-opened.
+ """
+ self.write(self.fh.AUX, '\\bibstyle{%s}\n' % self.bibstyle)
+ self.write(self.fh.HTML, "<!DOCTYPE html>\n<html>\n<body>\n\n")
+
+ def postprocess_ofiles(self, refcount):
+ """ Depending on the requested bibliography output type,
+ certain files are filled up with the required data.
+ Writing action is fulfilled only if requested file was pre-opened.
+
+ Parameters
+ ----------
+ refcount: int
+ If refcount is 0, it means no references have been found
+ in the input file, and pre-opened additional files are deleted
+
+ If requested bibliography output type is TEX,
+ number of bibliography items found is written to the first line of
+ FileHandler.DATA file. Therefore this file is written twice into.
+ """
+
+ if refcount == 0:
+ self.fh.close_and_delete(self.fh.DATA)
+ self.fh.close_and_delete(self.fh.AUX)
+ return None
+
+ datafilepath = self.get_fname(self.fh.DATA)
+ self.write(self.fh.AUX,
+ '\\bibdata{%s}' % os.path.splitext(datafilepath)[0])
+ self.write(self.fh.HTML, "\n</body>\n</html>\n")
+
+ # Formatting the DATA file output according to requested output format
+ obiblenv = {
+ self.TEX: {
+ "begin": "\\begin{thebibliography}{%s}\n"
+ "\\csname bibmessage\\endcsname\n\n",
+ "end": "\\end{thebibliography}\n"
+ },
+ self.AMSREFS: {
+ "begin": "\\begin{bibdiv}\n\\begin{biblist}\n\n",
+ "end": "\\end{biblist}\n\\end{bibdiv}"
+ }
+ }
+
+ strings = obiblenv.get(self.outputtype, None)
+ if strings is None:
+ return None
+
+ start_string, finish_string = sorted(strings.values())
+ self.write(self.fh.DATA, finish_string)
+
+ # Total items count is known only after processing all references and
+ # writing to the DATA file, therefore 'thebibliography' environment
+ # starting string is written to this file when all processing is
+ # finished
+ self.fh.close(self.fh.DATA)
+ os.rename(datafilepath, self.get_fname(self.fh.TMP))
+ self.fh.open(self.fh.TMP, self.fh.READ)
+
+ if self.outputtype == self.TEX:
+ start_string = start_string % refcount
+ self.fh.open(self.fh.DATA, self.fh.WRITE)
+ self.write(self.fh.DATA, start_string)
+
+ shutil.copyfileobj(self.fh.files[self.fh.TMP],
+ self.fh.files[self.fh.DATA])
+
+ def _remove_tex_comments(self, line):
+ """ Remove TeX comments
+
+ Parameters
+ ----------
+ line : str
+
+ Returns
+ -------
+ str
+ """
+ fmtline = self.re_bibre_line.sub('', line)
+ if fmtline:
+ matchobj = self.re_bibre_part.search(fmtline)
+ if matchobj is not None:
+ return "%s\n" % matchobj.groups(1)[0]
+ return fmtline
+ return fmtline
+
+ def _remove_tex_accents(self, line):
+ """ Remove TeX accents and braces around upper case letters
+
+ BatchMRef may not found a reference in the AMS MR DB because of
+ braces and accents present in reference string (tested), therefore
+ accented letters "{\'a}" and "\'{a}" are changed to plain "a".
+ Also "{ABC}" is changed to "ABC".
+
+ Parameters
+ ----------
+ line : str
+
+ Returns
+ -------
+ str
+ """
+ mline = self.re_tex_accents.sub(r'\1', line)
+ if mline:
+ return self.re_braced_letters.sub(r'\1\2\3', mline)
+ return mline
+
+ def gather_records(self, require_env):
+ """ Extract bibliography reference items from the input file
+
+ Parameters
+ ----------
+ require_env : bool
+ If True, get bibliography reference items only inside
+ the bibliography environment. If False, gel all bibliography
+ reference items found in the input file
+
+ Yields
+ -------
+ str
+ Denotes reference format type (one of ITYPES),
+ bibliography environment state (RefHandler.BIBL_BEGIN or
+ RefHandler.BIBL_END),
+ or input file end mark (EOF)
+
+ RefElement() instance, str, or None
+ If reference of one of ITYPES type has been found,
+ a RefElement() instance is returned with the following
+ attributes filled in:
+ reftype, citekey, biblabel,
+ orig_lines, cleaned_lines, query_lines
+
+ If end of input file has been determined, None is returned
+
+ Otherwise current line is returned
+ """
+
+ def sort_comments_out(comment_lines):
+ """ Assign gathered comment lines to the rightful reference item
+
+ Parameters
+ ----------
+ comment_lines : list
+
+ Returns
+ -------
+ list
+ Comment lines, belonging to current reference item
+ list
+ Comment lines, belonging to the next reference item
+ """
+
+ next_elem_comments = []
+ reversed_comments = comment_lines[::-1]
+ reversed_comments_backup = comment_lines[::-1]
+ advanced_by = 0
+ for no, cline in enumerate(reversed_comments):
+ if len(element.orig_lines) < (no + 1 + advanced_by):
+ break
+ while not element.orig_lines[-(no + 1 + advanced_by)].strip():
+ # skipping empty lines
+ advanced_by += 1
+ if cline == element.orig_lines[-(no + 1 + advanced_by)]:
+ reversed_comments_backup.pop(0)
+ next_elem_comments.append(reversed_comments[no])
+ current_elem_comments = reversed_comments_backup[::-1]
+ return current_elem_comments, next_elem_comments
+
+ # Allowing gathering the references according to
+ # the bibliography environment status
+ envmap = {self.rh.BIBL_BEGIN: True,
+ self.rh.BIBL_END: False,
+ "not found": False if require_env else True}
+ gather = envmap["not found"]
+ search = True
+
+ multiline = ""
+ element = RefElement()
+ envstatus = None
+ for line in self.icontent:
+ line = multiline + line
+ clean_line = self._remove_tex_comments(line)
+
+ if not clean_line and element.orig_lines:
+ element.orig_lines.append(line)
+ element.comment_lines.append(line)
+ continue
+
+ reftype = None
+ if search:
+ reftype, additional_info = self.rh.find_reference(clean_line)
+
+ if require_env and reftype == self.rh.BIBL_ENV:
+ if element.reftype is not None:
+ # Full bibliography item
+ element.comment_lines, next_elem_comments = \
+ sort_comments_out(element.comment_lines)
+ yield element.reftype, element
+ element = RefElement()
+ element.comment_lines = next_elem_comments
+
+ # Bibliography environment
+ envstatus = additional_info.pop("envstatus", None)
+ if envstatus in envmap:
+ gather = envmap[envstatus]
+ search = gather
+ yield envstatus, line
+ continue
+
+ elif reftype in self.ITYPES:
+ multiline = additional_info.get("line", "")
+ if multiline:
+ continue
+
+ if element.reftype is not None:
+ # Full bibliography item
+ element.comment_lines, next_elem_comments = \
+ sort_comments_out(element.comment_lines)
+ yield element.reftype, element
+ element = RefElement()
+ element.comment_lines = next_elem_comments
+
+ if gather:
+ element.reftype = reftype
+ element.citekey = additional_info.get("citekey", None)
+ element.biblabel = additional_info.get("biblabel", None)
+ element.orig_lines.append(line)
+
+ mrid_free_line = self.re_MR.sub('', clean_line)
+ element.cleaned_lines.append(mrid_free_line)
+
+ ref_format_free_line = additional_info.get("text", clean_line)
+ mrid_free_line = self.re_MR.sub('', ref_format_free_line)
+ accent_free_line = self._remove_tex_accents(mrid_free_line)
+ element.query_lines.append(accent_free_line)
+ continue
+
+ if gather and element.reftype is not None:
+ element.orig_lines.append(line)
+ mrid_free_line = self.re_MR.sub('', clean_line)
+ element.cleaned_lines.append(mrid_free_line)
+ accent_free_line = self._remove_tex_accents(mrid_free_line)
+ element.query_lines.append(accent_free_line)
+ else:
+ # Before and after the bibliography environment
+ yield envstatus, line
+
+ if element.reftype is not None:
+ # The last full bibliography item
+ element.comment_lines, _ = sort_comments_out(element.comment_lines)
+ yield element.reftype, element
+
+ yield self.EOF, None
+
+ def transfer_to_file(self):
+ """ After each query to BatchMRef write gathered data into files
+
+ Returns
+ -------
+ int
+ Number of references, for which data has been successfully
+ obtained
+ """
+
+ successful = 0
+
+ for elem in self.refscontainer.elems:
+ if self.refscontainer.qerrno != 0:
+ elem.errno = self.refscontainer.qerrno
+ outstring = ''.join(elem.cleaned_lines if self.clean_comments else
+ elem.orig_lines)
+
+ elem.outref = self.rh.insert_citekey(
+ elem.outref, elem.citekey, elem.biblabel,
+ elem.normalize(elem.cleaned_lines[1:]))
+ if elem.mrid is not None:
+ outstring = self.rh.insert_mrid(elem.reftype, outstring, elem.mrid)
+ slog.info(elem.mrid)
+ elif elem.errno == -1:
+ slog.warn('NotFound')
+ else:
+ slog.error('QueryError')
+
+ if self.clean_comments:
+ outstring = "".join(elem.comment_lines) + outstring
+
+ if self.debug == 1:
+ outstring = '%%%% %s\n%s' % (elem.querystring, outstring)
+ elif self.debug == 2:
+ outstring = '%%%% %s\n%s' % (elem.errno, outstring)
+ elif self.debug == 3:
+ outstring = '%%%% %s\n%%%% %s\n%s' % (elem.querystring,
+ elem.errno,
+ outstring)
+
+ flog.debug("\n" + ">" * 70
+ + "\nFINAL reference with MR id in original format:\n"
+ + "\n%s\n" % outstring.strip())
+
+ if elem.outref is not None:
+ flog.debug("FINAL reference in '%s' format:\n" % self.outputtype
+ + "\n%s\n" % elem.outref.strip() + "<" * 70)
+ self.write(self.fh.OUT, outstring)
+ self.write(self.fh.DATA, elem.outref if elem.outref else "")
+ self.write(self.fh.AUX, '\\citation{%s}\n' % elem.citekey)
+
+ if elem.errno == 0 and self.refscontainer.qerrno == 0:
+ successful += 1
+
+ if self.eof:
+ while self.ifile_end_lines:
+ self.write(self.fh.OUT, self.ifile_end_lines.pop(0))
+
+ self.refscontainer = RefsContainer()
+ self.qh._refscontainer = self.refscontainer
+
+ return successful
+
+ def get_mr_codes(self, require_env):
+ """ Analyze input file content and process found reference items
+
+ Parameters
+ ----------
+ require_env : bool
+ If True, and if no bibliography reference items have been found
+ inside the bibliography environment, or an environment hasn't
+ been found at all, parameter is set to False this method and
+ reruns itself in order to search reference items in
+ the whole input file.
+
+ Returns
+ -------
+ int
+ Total bibliography reference items found
+ int
+ Total number of references, for which data has been
+ successfully obtained
+ int
+ Reference items processed with errors count
+
+ If reference item of ITYPES has been found, current
+ RefElement() instance attribute 'refid' is assigned a value
+ """
+
+ msg = ("in the bibliography environment only"
+ if require_env else "in the whole input file")
+ flog.debug("SEARCHING for reference items: %s" % msg)
+
+ total = 0
+ valid = 0
+ successful = 0
+ records = self.gather_records(require_env=require_env)
+ pseudo_citekey = 0
+ for reftype, record in records:
+ if reftype == self.EOF:
+ self.eof = True
+
+ elif reftype not in self.ITYPES:
+ if reftype != self.rh.BIBL_END:
+ self.write(self.fh.OUT, record)
+ else:
+ self.ifile_end_lines.append(record)
+ continue
+
+ elif valid == 0 or valid % self.qh.QUERY_ITEMS_LIMIT != 0:
+ total += 1
+
+ record.refid = total
+ if not record.citekey:
+ pseudo_citekey += 1
+ record.citekey = '%s' % pseudo_citekey
+
+ flog.debug("=" * 70)
+ flog.debug("FOUND reference %s: type=%s, cite_key=%s, biblabel=%s"
+ % (total, reftype, record.citekey, record.biblabel))
+
+ if reftype != self.BIBITEM:
+ record.querystring = self.rh.extract_keys_data(record.query_lines)
+ self.refscontainer.append_elem(record)
+ record.errno = self.qh.prepare_query_str(record.refid,
+ record.querystring)
+ if record.errno == 0:
+ valid += 1
+
+ if valid != 0 and (valid % self.qh.QUERY_ITEMS_LIMIT == 0
+ or self.eof):
+ self.qh.query()
+ successful += self.transfer_to_file()
+ valid = 0
+ if not self.eof:
+ sleep(self.wait)
+
+ if total == 0 and require_env:
+ # If no bibliography items were found in the bibliography
+ # environment, then trying to search for them everywhere
+ # in the input file
+ flog.debug("FOUND no references! Changing the search mode ... ")
+ self.eof = False
+ self.ifile_end_lines = list()
+ self.fh.close(self.fh.OUT)
+ self.fh.open(self.fh.OUT)
+ return self.get_mr_codes(require_env=False)
+
+ if self.ifile_end_lines:
+ self.transfer_to_file()
+
+ flog.debug("=" * 70)
+ errors = total - successful
+ return total, successful, errors
+
+ def run(self, require_env):
+ """ Main method
+
+ Parameters
+ ----------
+ require_env : bool
+
+ Returns
+ -------
+ get_mr_codes() output
+ """
+
+ slog.info("# %s #\nJob started:" % self.version)
+ starttime = time()
+
+ self.preprocess_ofiles()
+ total, successful, errors = self.get_mr_codes(require_env=require_env)
+ self.postprocess_ofiles(refcount=total)
+
+ flog.info(" total: %s, found: %s, not found: %s, time: %ss"
+ % (total, successful, errors, int(round(time()-starttime))))
+
+ slog.info("Job ended")
+ slog.info("Total: %s, found: %s, not found: %s"
+ % (total, successful, errors))
+ slog.info('Job completed in %ss' % int(round(time()-starttime)))
+
+ self.fh.close_files()
+ return total, successful, errors
+
+
+if __name__ == '__main__':
+ import argparse
+
+ # Logging to console
+ osh = logging.StreamHandler(stream=sys.stdout)
+ osh.setFormatter(BASICFORMATTER)
+ osh.setLevel(logging.INFO)
+ osh.addFilter(LessThanFilter(logging.INFO))
+
+ esh = logging.StreamHandler(stream=sys.stderr)
+ esh.setFormatter(BASICFORMATTER)
+ esh.setLevel(logging.WARN)
+
+ slog = logging.getLogger("%s.StreamLogger" % __name__)
+ slog.setLevel(logging.INFO)
+ slog.addHandler(osh)
+ slog.addHandler(esh)
+
+ # Logging to files
+ flog = logging.getLogger("%s.FileLogger" % __name__)
+ flog.setLevel(logging.DEBUG)
+
+ def setup_logging_files(debug, basename=""):
+ """ Set up logging files
+
+ Parameters
+ ----------
+ debug : int
+ basename: str
+ Input file name
+
+ Returns
+ -------
+ logging instance
+ """
+
+ if debug == 0:
+ log_min_level = logging.INFO
+ log_max_level = logging.INFO
+ formatter = BASICFORMATTER
+ else:
+ log_min_level = logging.DEBUG
+ log_max_level = logging.WARN
+ formatter = DEBUGFORMATTER
+
+ ofh = logging.FileHandler(filename="{}.{}.{}".format(basename,
+ FilesHandler.GMR_SUFFIX,
+ FilesHandler.LOG),
+ mode='w', delay=True)
+ ofh.setFormatter(formatter)
+ ofh.setLevel(log_min_level)
+ ofh.addFilter(LessThanFilter(log_max_level))
+ flog.addHandler(ofh)
+
+ efh = logging.FileHandler(filename="{}.{}.{}".format(basename,
+ FilesHandler.GMR_SUFFIX,
+ FilesHandler.ERR),
+ mode='w', delay=True)
+ efh.setFormatter(DEBUGFORMATTER)
+ efh.setLevel(logging.ERROR)
+ flog.addHandler(efh)
+ return flog
+
+ VERSION = __version__.split("-")[0]
+ DESCRIPTION = (
+ "Tool %s, is designed for: " % VERSION
+ + "(1) getting MR numbers for given references from AMS MRef database, "
+ + "(2) formatting the given references in one of AMS allowed formats. "
+ + "Maintainer: L.Tolene <lolita.tolene@vtex.lt>."
+ )
+
+ def get_cmd_args():
+ """ Command line input parser """
+
+ parser = argparse.ArgumentParser(
+ description=DESCRIPTION,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+ parser.add_argument("filepath", help="References containing file")
+ parser.add_argument(
+ "--enc", '-e', type=str, default=QueryHandler.LATIN1,
+ help="Source file encoding or 'auto'"
+ )
+ parser.add_argument(
+ "--format", '-f', choices=set(RefTypes.OTYPES),
+ help="Outputs the given references in provided format. "
+ "For more information about these formats please "
+ "consult the AMS MRef tool website. The 'ims' format "
+ "is almost the same as the 'bibtex' format"
+ )
+ parser.add_argument(
+ "--bibstyle", '-s', default=HandleBBL.PLAIN,
+ help="BibTeX style. For more information please consult "
+ "the BibTeX documentation"
+ )
+ parser.add_argument(
+ "--nobibenv", action='store_true',
+ help="If activated, references are searched throughout "
+ "all source file content; otherwise searching only "
+ "inside the bibliography environment. Currently "
+ "recognizable are the 'thebibliography' and 'biblist' "
+ "environments"
+ )
+ parser.add_argument(
+ "--clean", '-c', action='store_true',
+ help="If activated, cleans comments appearing in references"
+ )
+ parser.add_argument(
+ "--itemno", default=100, type=int,
+ help="Maximum item count for one AMS query. "
+ "AMS batchmref has a limit of 100 items per query."
+ )
+ parser.add_argument(
+ "--wait", default=10, type=int,
+ help="time (in seconds) to wait between queries to AMS batchmref."
+ )
+ parser.add_argument(
+ "--debug", '-d', choices={0, 1, 2, 3}, default=0, type=int,
+ help="Outputs additional info for debugging purposes."
+ )
+ parser.add_argument(
+ "--version", '-v', action='version', version=VERSION,
+ help="Module version."
+ )
+ args = parser.parse_args()
+ return (args.filepath, args.enc, args.format, args.bibstyle,
+ args.nobibenv, args.clean, args.itemno, args.wait, args.debug)
+
+ # Get input parameter values
+ inputfile, encoding, output_format, bibstyle, nobibenv, clean, itemno, wait, debug \
+ = get_cmd_args()
+
+ # Load additional library is needed
+ if encoding == QueryHandler.AUTO_ENC:
+ from chardet.universaldetector import UniversalDetector
+
+ # Setup logging files
+ flog = setup_logging_files(debug=debug,
+ basename=os.path.splitext(inputfile)[0])
+
+ # Create HandleBBL() instance
+ bblobj = HandleBBL(inputfile=inputfile, encoding=encoding,
+ clean_comments=clean, itemno=itemno, wait=wait,
+ outputtype=output_format, bibstyle=bibstyle,
+ debug=debug, version=VERSION)
+
+ # Process input file
+ bblobj.run(require_env=not nobibenv)
diff --git a/macros/latex/contrib/ejpecp/mgetmref.py b/macros/latex/contrib/ejpecp/mgetmref.py
deleted file mode 100644
index 8910556c82..0000000000
--- a/macros/latex/contrib/ejpecp/mgetmref.py
+++ /dev/null
@@ -1,401 +0,0 @@
-#! /usr/bin/env python
-##################################################################################
-#
-# getmref.py - gets the references links to MathSciNet throught the BatchMRef:
-# http://www.ams.org/batchref?qdata=xmldocument
-#
-# Copyright (C) 2004 Sigitas Tolusis, VTeX Ltd. and Jim Pitman, Dept. Statistics,
-# U.C. Berkeley
-# E-mail: sigitas@vtex.let
-# http://www.stat.berkeley.edu/users/pitman
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# Requires python ver. 2.2
-#
-# Usage:
-# getmref.py <bbl or tex file>
-#
-# Program (description):
-# - makes inputfile copy to <inputfilename>.getmref.bak;
-# - for each successful bibitem reference search adds line \MR{<mrid>},
-# where <mrid> is data from XML tag <mrid> without front symbols "MR";
-# - writes all adds to <inputfilename>;
-# - generates log file <inputfilename>.getmref.log;
-# - writes to stdout log info
-#
-# Changes:
-# 2004/04/26 - \bibitem line removed from the query
-#
-#
-###################################################################################
-SVNinfo = "$Id: getmref.py 46 2006-03-30 07:02:14Z sigitas $"
-
-import sys, urllib, re, os.path, time, string
-from xml.dom.minidom import parseString
-import xml.parsers.expat as par
-
-starttime = time.time()
-res = re.search(r'\S+:\s\S+\s+(.*?)\s.*\$', SVNinfo)
-if res:
- ver = res.group(1)
-else:
- ver = '0.0'
-print "# getmref, v. %s #" % ver
-
-#
-# bbl file parsing /begin
-#
-
-def escapetex(instr):
- res = reduce(lambda a,b: string.replace(a, b[0], b[1]), (instr, ("\\&", '&amp;'), ("<", '&lt;'), (">", '&gt;')))
- return res
-
-def query(instring, bibID, address = 'http://www.ams.org/batchmref'):
- domas = None; res = None; err = 0
- escapetexstring = escapetex(instring)
- querystring = r'''<?xml version = "1.0" encoding = "UTF-8"?>
-<mref_batch>
-<mref_item outtype="tex">
-<inref>
-%s
-</inref>
-<myid>%s</myid>
-</mref_item>
-</mref_batch>''' % (escapetexstring, bibID)
- try:
- indom = parseString(querystring)
- except par.ExpatError, err:
- print >>sys.stderr,"[parse query]: %s" % querystring
- print >>sys.stderr,sys.exc_info()
- pass
- else:
- queryinfo = {}
- queryinfo['qdata'] = querystring
- queryval = urllib.urlencode(queryinfo)
- try:
- batchmref = urllib.urlopen(address, queryval)
- res = batchmref.read()
- domas = parseString(res)
- except err:
- print >>sys.stderr,"[parse res]: %s" % res
- print >>sys.stderr,sys.exc_info()
- pass
- return domas, res, err
-
-def remcomm(line):
- "Removes TeX comments"
- bibre = re.compile(r'\s*(.*?)(?<!\\)%.*\n$')
- fmtline = re.sub('^%.*\n$','', line)
- if fmtline:
- matchobj = bibre.search(fmtline)
- if matchobj:
- return matchobj.groups(1)[0]
- else:
- return fmtline
- else:
- return fmtline
-
-def formatbibitem(bibID, domas):
- errstring = None; outtype = None; mrid = None; myid = bibID; outref = None; err = 0
- try:
- mref = domas.getElementsByTagName("mref_batch")[0]
- mref_errors = mref.getElementsByTagName("batch_error")
- if len(mref_errors):
- errlist = [ mref_error.childNodes[0].nodeValue() for mref_error in mref_errors ]
- errstring = ''.join(errlist)
- err = -2
- else:
- mref_items = [item for item in mref.getElementsByTagName("mref_item")]
- matches = mref_items[0].getElementsByTagName("matches")[0].childNodes[0]._get_nodeValue()
- if matches == '1':
- for item in mref_items:
- outtype = dict(item.attributes.items())["outtype"]
- mrid = item.getElementsByTagName("mrid")[0].childNodes[0]._get_nodeValue()
- err = 0
- if mrid[:2] == "MR":
- mrid = mrid[2:]
- myids = item.getElementsByTagName("myid")
- if len(myids):
- myid = myids[0].childNodes[0]._get_nodeValue()
- else:
- myid = bibID
- outref = string.strip(item.getElementsByTagName("outref")[0].childNodes[0]._get_nodeValue())
- else:
- err = -1
- except:
- err = -3
- print >>sys.stderr,"[formatbibitem]: %s" % bibID
- print >>sys.stderr,sys.exc_info()
- pass
- return mrid, outref, err
-
-
-def handlebibitem(lines, bibID, biblabel=None):
- res = 0; err = None; outref = None
- outstring = string.strip(''.join(lines))
- lines[:] = [re.sub(r'\\MR\{.*?\}', '', a) for a in lines]
- biblines = [x for x in [remcomm(a) for a in lines] if x]
- bibstring = re.sub(r'\n', ' ', ''.join(biblines))
- match = re.search(r'\\bibitem\s*?(?:\[.*?\])?\s?\{(?:.*?)\}(.*)(\\endbibitem)?$',bibstring.strip())
- if match:
- querystring = match.group(1).strip()
- else:
- querystring = bibstring
- domas = None
- try:
- domas, xmlres, err = query(querystring, bibID)
- except:
- res = -2
- print >>sys.stderr,"[parse query]: %s" % querystring
- print >>sys.stderr,sys.exc_info()
- print 'Error',
- else:
- mrid, outref, err = formatbibitem(bibID, domas)
- if not mrid:
- print 'Not Found',
- res = -1
- else:
- print mrid,
- if mrid[:2] == "MR":
- outstring = bibstring + '\\MR{%s}' % mrid[2:].rjust(7,'0')
- else:
- outstring = bibstring + '\\MR{%s}' % mrid.rjust(7,'0')
- outstrip, nsub = re.subn(r'\\endbibitem',r'',outstring)
- if nsub:
- outstrip += '\n\\endbibitem'
- outstring = re.sub(r' ', r' ', outstrip)
- if not outref:
- outref = "Not found!"
- else:
- outref = re.sub(r'(?<!\\)#',r'\#', outref)
- if biblabel:
- print >>datafile, '\\bibitem%s{%s}\n%s\n' % (biblabel, bibID, outref)
- else:
- print >>datafile, '\\bibitem{%s}\n%s\n' % (bibID, outref)
- return '%s\n' % outstring, res
-
-def handleextra(extralines):
- if len(extralines):
- print >>outputfile, ''.join(extralines),
-
-def handlebbl(inputfile, out=sys.stdout, data=sys.stdout):
- print "Job started:",
- total = 0; successful = 0; errors = 0; state = 0; pseudobibID = 0; readbib = ''
- bibl_begin = re.compile(r'\s*\\begin\s*\{thebibliography\}.*$')
- bibre = re.compile(r'^\s*\\bibitem.*')
- bibreF = re.compile(r'\s*\\bibitem\s*(\[.*?\])*?\s?\{(.*?)\}.*$',re.S)
- comments = re.compile(r'\s*%.*$')
- bibl_end = re.compile(r'\s*\\end\s*\{thebibliography\}.*$')
- for line in inputfile:
- if len(readbib):
- readbib += line
- matchobj = bibreF.search(readbib)
- if matchobj:
- line = "%s" % readbib
- readbib = ''
- else:
- continue
- if line:
- if state == 0:
- matchobj = bibl_begin.search(line)
- if matchobj:
- print >>data,matchobj.group(0)
- print >>data,"\\csname bibmessage\\endcsname\n"
- state = 1
- print >>out, line,
- continue
- elif state == 1:
- matchobj = bibre.search(line)
- if matchobj:
- matchobj = bibreF.search(line)
- if matchobj:
- biblabel, bibID = matchobj.groups()
- if not len(bibID):
- pseudobibID += 1
- bibID = '%s' % pseudobibID
- state = 2
- lines = [line]
- extralines = []
- continue
- else:
- readbib = line
- continue
- else:
- print >>out, line,
- continue
- elif state == 2:
- matchobj = bibre.search(line)
- if matchobj:
- matchobj = bibreF.search(line)
- if matchobj:
- total += 1
- print >>data,line
- outstring, sres = handlebibitem(lines, bibID, biblabel)
- if not sres:
- successful += 1
- else:
- errors += 1
- print >>out, outstring,
- handleextra(extralines)
- lines = [line]
- extralines = []
- biblabel, bibID = matchobj.groups()
- if not len(bibID):
- pseudobibID += 1
- bibID = '%s' % pseudobibID
- continue
- else:
- readbib = line
- continue
- else:
- matchobj = bibl_end.search(line)
- if matchobj:
- state = 0
- total += 1
- outstring, sres = handlebibitem(lines, bibID, biblabel)
- if not sres:
- successful += 1
- else:
- errors += 1
- print >>out, outstring,
- handleextra(extralines)
- print >>out, line,
- print >>data,matchobj.group(0)
- continue
- else:
- if line[:-1] == '':
- state = 3
- extralines = [line]
- continue
- matchobj = comments.search(line)
- if matchobj:
- state = 3
- extralines = [line]
- continue
- lines.append(line)
- continue
- elif state == 3:
- matchobj = bibre.search(line)
- if matchobj:
- matchobj = bibreF.search(line)
- if matchobj:
- state = 2
- total += 1
- outstring, sres = handlebibitem(lines, bibID, biblabel)
- if not sres:
- successful += 1
- else:
- errors += 1
- print >>out, outstring,
- handleextra(extralines)
- lines = [line]
- extralines = []
- biblabel, bibID = matchobj.groups()
- if not len(bibID):
- pseudobibID += 1
- bibID = '%s' % pseudobibID
- continue
- else:
- readbib = line
- continue
- else:
- matchobj = bibl_end.search(line)
- if matchobj:
- state = 0
- total += 1
- outstring, sres = handlebibitem(lines, bibID, biblabel)
- if not sres:
- successful += 1
- else:
- errors += 1
- print >>out, outstring,
- handleextra(extralines)
- print >>out, line,
- print >>data,matchobj.group(0)
- continue
- else:
- if line[:-1] == '':
- extralines.append(line)
- continue
- matchobj = comments.search(line)
- if matchobj:
- extralines.append(line)
- continue
- state = 2
- lines.extend(extralines)
- lines.append(line)
- extralines = []
- continue
- else:
- break
- print "Job ended"
- print "Total: %s, found: %s, errors: %s" % (total, successful, errors)
- return (total, successful, errors)
-
-#
-# bbl file parsing /end
-#
-
-if len(sys.argv) < 2:
- progname = os.path.basename(sys.argv[0])
- print "Usage:\n %s <bbl or tex file>" % progname
- sys.exit(1)
-infilename = sys.argv[1]
-filebase = os.path.splitext(infilename)[0]
-outfilename = "%s.getmref.tmp" % filebase
-datafilename = "%s.getmref.data" % filebase
-logfilename = "%s.getmref.log" % filebase
-
-inputfile = file(infilename, 'r')
-outputfile = file(outfilename, 'w')
-datafile = file(datafilename, 'w')
-logfile = file(logfilename, 'w')
-if os.path.isfile("%s.getmref.bak" % filebase):
- os.unlink("%s.getmref.bak" % filebase)
-
-sys.stderr = file("%s.getmref.err" % filebase, 'w')
-total = 0; successful = 0; errors = 0
-print >>logfile, "File: %s" % infilename
-try:
- total, successful, errors = handlebbl(inputfile, outputfile, datafile)
-except:
- print >>sys.stderr,"[handlebbl]"
- print >>sys.stderr,sys.exc_info()
-print >>logfile, " total: %s, found: %s, errors: %s, time: %ss" % (total, successful,
- errors, int(round(time.time()-starttime)))
-
-inputfile.close()
-outputfile.close()
-datafile.close()
-logfile.close()
-sys.stderr.close()
-sys.stderr = sys.__stderr__
-if os.path.isfile("%s.getmref.err" % filebase):
- if not os.stat("%s.getmref.err" % filebase)[6]:
- os.unlink("%s.getmref.err" % filebase)
-if os.path.isfile("%s.getmref.bak" % filebase):
- os.unlink("%s.getmref.bak" % filebase)
-os.rename(infilename, "%s.getmref.bak" % filebase)
-
-#mes modif
-#os.rename(outfilename, infilename)
-f=open(outfilename,"r")
-g=open(infilename,"w")
-x=f.read()
-g.write(re.sub(r"\r"," ",x))
-
-#fin de la modif
-
-print 'Job completed in %ss' % int(round(time.time()-starttime))
-
-
-
diff --git a/macros/latex/contrib/ejpecp/sample.pdf b/macros/latex/contrib/ejpecp/sample.pdf
index 79f20ac7fa..aa47175278 100644
--- a/macros/latex/contrib/ejpecp/sample.pdf
+++ b/macros/latex/contrib/ejpecp/sample.pdf
Binary files differ
diff --git a/macros/latex/contrib/ejpecp/sample.tex b/macros/latex/contrib/ejpecp/sample.tex
index 2930a08567..fed48e097e 100644
--- a/macros/latex/contrib/ejpecp/sample.tex
+++ b/macros/latex/contrib/ejpecp/sample.tex
@@ -114,7 +114,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\VOLUME{0}
-\YEAR{2016}
+\YEAR{2020}
\PAPERNUM{0}
\DOI{10.1214/YY-TN}
@@ -459,6 +459,21 @@ and in that case, you should provide the MR number instead of the arXiv
identifier. It is acceptable to leave arXiv links in the bibliography
(alongside MR links) even if the article has been published.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Supplementary Material, if any, should be provided in %%
+%% {supplement} environment with title and short description. %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{supplement}
+\stitle{Title of Supplement A.}
+\sdescription{Short description of Supplement A.}
+\end{supplement}
+\begin{supplement}
+\stitle{Title of Supplement B.}
+\sdescription{Short description of Supplement B.}
+\end{supplement}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
diff --git a/macros/latex/contrib/fgruler/README b/macros/latex/contrib/fgruler/README
index de38814440..266910338c 100644
--- a/macros/latex/contrib/fgruler/README
+++ b/macros/latex/contrib/fgruler/README
@@ -1,6 +1,6 @@
fgruler.sty package
-Copyright 2017- by Tibor Tomacs
+Copyright 2017-2020 by Tibor Tomacs
Package for drawing rulers on the foreground or in the text
diff --git a/macros/latex/contrib/fgruler/fgruler.dtx b/macros/latex/contrib/fgruler/fgruler.dtx
index 18d16a6260..dd7ec0ba06 100644
--- a/macros/latex/contrib/fgruler/fgruler.dtx
+++ b/macros/latex/contrib/fgruler/fgruler.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright 2017- by Tibor Tomacs
+% Copyright 2017-2020 by Tibor Tomacs
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -20,8 +20,8 @@
%<*driver>
\ProvidesFile{fgruler.dtx}
%</driver>
-%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
-%<package>\ProvidesPackage{fgruler}[2017/01/16 v1.0 Package for drawing rulers on the foreground or in the text]
+%<package>\NeedsTeXFormat{LaTeX2e}[2020/10/01]
+%<package>\ProvidesPackage{fgruler}[2020/10/22 v1.1 Package for drawing rulers on the foreground or in the text]
%
%<*driver>
\documentclass{ltxdoc}
@@ -60,7 +60,7 @@ keepspaces]}
%
% \GetFileInfo{fgruler.sty}
%
-% \title{The {\bfseries\sffamily fgruler} package\\{\large v1.0 (2017/01/16)}}
+% \title{The {\bfseries\sffamily fgruler} package\\{\large v1.1 (2020/10/22)}}
% \author{Tibor T\'{o}m\'{a}cs\\{\normalsize\url{tomacs.tibor@uni-eszterhazy.hu}}}
% \date{}
% \maketitle
@@ -1053,7 +1053,7 @@ keepspaces]}
\else
-\@ifpackageloaded{eso-pic}{}{\RequirePackage{eso-pic}}
+\@ifpackageloaded{eso-pic}{}{\RequirePackage{eso-pic}[2020/10/14]}
\def\fgruler@frame{%
\begingroup
@@ -1085,30 +1085,27 @@ keepspaces]}
\endgroup
}
-\let\fgruler@shipout\AtBeginShipoutUpperLeftForeground
\def\fgruler@output@{}
+
\ESO@isMEMOIR{%
-\def\AtBeginShipoutUpperLeftForeground#1{%
- \fgruler@shipout{#1%
- \put(\fgruler@lentounit{\@tempdima},\fgruler@lentounit{\@tempdimb}){%
- \iffgruler@showframe\fgruler@frame\fi%
- \fgruler@output%
- \fgruler@output@%
- \global\let\fgruler@output@\@empty%
- }%
- }%
+ \AddToHook{shipout/foreground}{%
+ \ESO@MEMOIR@corr
+ \put(\ESO@tempdima,\ESO@tempdimb){%
+ \iffgruler@showframe\fgruler@frame\fi%
+ \fgruler@output%
+ \fgruler@output@%
+ \global\let\fgruler@output@\@empty%
}%
+ }%
}{%
-\def\AtBeginShipoutUpperLeftForeground#1{%
- \fgruler@shipout{#1%
- \put(0,\fgruler@lentounit{\ESO@yoffsetI}){%
- \iffgruler@showframe\fgruler@frame\fi%
- \fgruler@output%
- \fgruler@output@%
- \global\let\fgruler@output@\@empty%
- }%
- }%
+ \AddToHook{shipout/foreground}{%
+ \put(0,\ESO@yoffsetI){%
+ \iffgruler@showframe\fgruler@frame\fi%
+ \fgruler@output%
+ \fgruler@output@%
+ \global\let\fgruler@output@\@empty%
}%
+ }%
}
\fgruler@activate@type
diff --git a/macros/latex/contrib/fgruler/fgruler.ins b/macros/latex/contrib/fgruler/fgruler.ins
index 13ea6a1a4b..38cac59ba0 100644
--- a/macros/latex/contrib/fgruler/fgruler.ins
+++ b/macros/latex/contrib/fgruler/fgruler.ins
@@ -1,5 +1,5 @@
-% Copyright 2017- by Tibor Tomacs
+% Copyright 2017-2020 by Tibor Tomacs
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -19,7 +19,7 @@
\preamble
This is a generated file.
-Copyright 2017- by Tibor Tomacs
+Copyright 2017-2020 by Tibor Tomacs
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/fgruler/fgruler.pdf b/macros/latex/contrib/fgruler/fgruler.pdf
index 04352acad0..eb3be627b8 100644
--- a/macros/latex/contrib/fgruler/fgruler.pdf
+++ b/macros/latex/contrib/fgruler/fgruler.pdf
Binary files differ
diff --git a/macros/latex/contrib/hu-berlin-bundle/README.md b/macros/latex/contrib/hu-berlin-bundle/README.md
index b803882b22..31ca809bcb 100644
--- a/macros/latex/contrib/hu-berlin-bundle/README.md
+++ b/macros/latex/contrib/hu-berlin-bundle/README.md
@@ -67,6 +67,11 @@ All notable changes to this project will be documented in the [README.md](https:
This project **does not** adhere to [Semantic Versioning](http://semver.org/).
The markdown syntax is inspired by the conventions proposed by [keepachangelog.com](http://keepachangelog.com/).
+### v1.0.6 (2020-10-22)
+* (letter) changed address separator
+* (letter) fixed empty minipage when no metadata given
+* (letter) changed default backaddress
+
### v1.0.5 (2020-04-28)
* (general) Changed logo format to `.pdf`
* (letter) Changed `\ifkomavarempty` to `\ifkomavarempty`, fixes
diff --git a/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.dtx b/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.dtx
index 497c7fedbf..efce1463da 100644
--- a/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.dtx
+++ b/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.dtx
@@ -1,6 +1,6 @@
% \iffalse
%<*internal|cls|sty>
-\def\Version{2020/04/28 v1.0.5}
+\def\Version{2020/10/22 v1.0.6}
%</internal|cls|sty>
%<*internal>
\iffalse
@@ -304,6 +304,12 @@ All notable changes to this project will be documented in the [README.md](https:
This project **does not** adhere to [Semantic Versioning](http://semver.org/).
The markdown syntax is inspired by the conventions proposed by [keepachangelog.com](http://keepachangelog.com/).
+### v1.0.6 (2020-10-22)
+* (letter) changed address separator
+* (letter) fixed empty minipage when no metadata given
+* (letter) changed default backaddress
+
+
### v1.0.5 (2020-04-28)
* (general) Changed logo format to `.pdf`
* (letter) Changed `\ifkomavarempty` to `\ifkomavarempty`, fixes
@@ -511,10 +517,11 @@ you get all these various files described above.
% If your backaddress is to long
% – it will be set up automatically –
% you can redefine it.
+%
% \begin{macrocode}
-\setkomavar{backaddress}{HU Berlin\\
-Unter den Linden 6\\
-D-10099 Berlin}
+%% \setkomavar{backaddress}{HU Berlin\\
+%% Unter den Linden 6\\
+%% D-10099 Berlin}
% \end{macrocode}
% Selfexplaining: the faculty.
% \begin{macrocode}
@@ -960,11 +967,19 @@ Thank you very much for your letter.
% \end{macrocode}
% then the faculty
% \begin{macrocode}
+\Ifkomavarempty{faculty}
+% \end{macrocode}
+% This is a fake space to avoid any trouble
+% if no custom metadata are given.
+% \begin{macrocode}
+ {\hspace*{1em}}
{\usekomafont{faculty}%
\usekomavar{faculty}\\[1\baselineskip]}
% \end{macrocode}
% and the institute.
% \begin{macrocode}
+\Ifkomavarempty{institute}
+ {}
{\usekomafont{institute}\usekomavar{institute}\\[1\baselineskip]}
% \end{macrocode}
% Now anything else regarding the institute.
@@ -1166,8 +1181,15 @@ Thank you very much for your letter.
% \begin{macrocode}
\setkomavar*{fromaddress}{Postanschrift:}
\setkomavar{fromaddress}{%
- Humboldt-Universität zu Berlin\par
- Unter den Linden 6\par
+ Humboldt-Universität zu Berlin\\
+ Unter den Linden 6\\
+ D-10099 Berlin}
+% \end{macrocode}
+% The default backaddress is slightly changed:
+% \begin{macrocode}
+\setkomavar{backaddress}{%
+ Humboldt-Universität zu Berlin\\
+ UdL 6\\
D-10099 Berlin}
% \end{macrocode}
%
diff --git a/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.pdf b/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.pdf
index f801de6173..d66602637e 100644
--- a/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.pdf
+++ b/macros/latex/contrib/hu-berlin-bundle/hu-berlin-bundle.pdf
Binary files differ
diff --git a/macros/latex/contrib/scrlttr2copy/README.md b/macros/latex/contrib/scrlttr2copy/README.md
index 77e30b6f8e..cea1bb15a4 100644
--- a/macros/latex/contrib/scrlttr2copy/README.md
+++ b/macros/latex/contrib/scrlttr2copy/README.md
@@ -1,5 +1,5 @@
# scrlttr2copy
-A letter class option file for automatically creation of copies.
+A letter class option file for automatically creation of page copies.
The file `copy.lco` provides the new class option »copy« for the KOMA-Script
letter class »scrlttr2«. If the option »copy« is given all pages of a specific
@@ -7,6 +7,10 @@ letter are duplicated with background text marking as copies.
For more details see the example document `letter-copy-test.tex`.
-[Rolf Niepraschk](mailto:Rolf.Niepraschk@gmx.de), 2016-02-13
+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.
+
+Rolf Niepraschk
diff --git a/macros/latex/contrib/scrlttr2copy/copy.lco b/macros/latex/contrib/scrlttr2copy/copy.lco
index 260d3c6eb8..989449a59c 100644
--- a/macros/latex/contrib/scrlttr2copy/copy.lco
+++ b/macros/latex/contrib/scrlttr2copy/copy.lco
@@ -12,7 +12,7 @@
%%
%% This work has the LPPL maintenance status "author-maintained".
-\ProvidesFile{copy.lco}[2020/10/20 v0.2a copy letter-class-option (RN)]
+\ProvidesFile{copy.lco}[2020/10/22 v0.3a copy letter-class-option (RN)]
\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion}
\IfFormatAtLeastTF{2020/10/01}{}{%
\PackageError{copy.lco}{%
@@ -25,49 +25,20 @@
\RequirePackage{xcolor,graphicx}
-\newcounter{copy@pages}
-
-\AtBeginLetter{\shipout@copy}% Output the copy of the pages of the previous letter
-\AtEndDocument{\shipout@copy}% Output the copy of the pages of the last letter
-
-\newcommand*\shipout@copy{%
- \ifnum\c@copy@pages>\z@% ignore the following in the first \AtBeginLetter
- \RemoveFromHook{shipout/before}[CP@save]
- \if@twoside\ifodd\c@copy@pages
- \@latex@info@no@line{Shipout an empty page}%
- \shipout\null
- \fi\fi
- \immediate\closeout\@mainaux
- \immediate\openout\@mainaux\jobname.aux
- \begingroup
- \c@page=\z@
- \AddToHook{shipout/background}[CP@marker]{\LetterCopyMarker}%
- \loop\ifnum\c@page<\c@copy@pages
- \advance\c@page\@ne
- \@latex@info@no@line{Shipout copy of page \the\c@page}%
- \setbox\ShipoutBox=\box\csname out@box\the\c@page\endcsname
- \shipout\box\ShipoutBox
- \repeat
- \RemoveFromHook{shipout/background}[CP@marker]
- \endgroup
- \c@copy@pages=\z@
- \fi
- % Saving all pages of the next letter
- \AddToHook{shipout/before}[CP@save]{\save@page@copies}
+\AtEndLetter{% Saving the number of total pages of each letter in a separate macro
+ \expandafter\xdef\csname CP@max@pages@\the\c@letter\endcsname{\the\c@page}%
}
-\newcommand*\save@page@copies{%
- \@ifundefined{out@box\the\c@page}{%
- \@latex@info@no@line{Alloc savebox for page \the\c@page}%
- \expandafter\newsavebox\csname out@box\the\c@page\endcsname
- }{%
- \@latex@info@no@line{Savebox for page \the\c@page\space already exist}%
- }%
- \@latex@info@no@line{Save page \the\c@page\space to \string\out@box\the\c@page}%
- \global\setbox\csname out@box\the\c@page\endcsname=\copy\ShipoutBox
- \global\c@copy@pages=\c@page
+\newcommand*\save@page@copies{% Saving each output page in a separate box
+ \expandafter\newsavebox\csname page@box@\the\c@letter @\the\c@page\endcsname
+ \@latex@info@no@line{Save page \the\c@page\space of letter \the\c@letter
+ \space to \string\page@box@\the\c@letter @\the\c@page}%
+ \global\setbox\csname page@box@\the\c@letter @\the\c@page\endcsname=
+ \copy\ShipoutBox
}
+\AddToHook{shipout/before}[CP@save]{\save@page@copies}
+
\newcommand*\LetterCopyMarker{%
\put(0.5\paperwidth,-0.5\paperheight){%
\makebox(0,0)[c]{\resizebox{\textwidth}{!}{\rotatebox{45}{%
@@ -75,6 +46,34 @@
}%
}
+\AddToHook{enddocument/afteraux}[CP@shipout]{%
+ \RemoveFromHook{shipout/before}[CP@save]%
+ \if@twoside\ifodd\ReadonlyShipoutCounter
+ \@latex@info@no@line{Output an empty page}%
+ \shipout\null
+ \fi\fi
+ \AddToHook{shipout/background}[CP@marker]{\LetterCopyMarker}%
+ \@tempcnta=\z@
+ \loop% iterate over all letters
+ \advance\@tempcnta\@ne
+ {%
+ \c@page=\z@
+ \edef\@tempa{\@nameuse{CP@max@pages@\the\@tempcnta}}% total pages
+ \loop% iterate over all pages of this letter
+ \advance\c@page\@ne
+ \@latex@info@no@line{Output of the copy of page \the\c@page\space
+ of letter \the\@tempcnta}%
+ \setbox\ShipoutBox=\box\@nameuse{page@box@\the\@tempcnta @\the\c@page}%
+ \shipout\box\ShipoutBox
+ \ifnum \c@page < \@tempa
+ \repeat
+ }%
+ \ifnum \@tempcnta < \c@letter
+ \repeat
+ \RemoveFromHook{shipout/background}[CP@marker]
+ \RemoveFromHook{enddocument/afteraux}[CP@shipout]
+}
+
\newkomavar[\copyname]{copy}
\newcommand*\copyname{Copy}
@@ -82,7 +81,7 @@
english,newzealand,UKenglish,USenglish}\copyname{Copy}%
\defcaptionname{german,ngerman,austrian,naustrian,%
swissgerman,nswissgerman}\copyname{Kopie}
-\defcaptionname{acadian,canadien,francais,french}\copyname{Copie}
+\defcaptionname{acadian,francais,french}\copyname{Copie}
\defcaptionname{spanish,italian,portugese}\copyname{Copia}
\defcaptionname{polish}\copyname{Kopia}
\defcaptionname{russian}\copyname{Копия}
diff --git a/macros/latex/contrib/scrlttr2copy/letter-copy-test.pdf b/macros/latex/contrib/scrlttr2copy/letter-copy-test.pdf
index aee604b509..6a5f347143 100644
--- a/macros/latex/contrib/scrlttr2copy/letter-copy-test.pdf
+++ b/macros/latex/contrib/scrlttr2copy/letter-copy-test.pdf
Binary files differ
diff --git a/macros/latex/contrib/scrlttr2copy/letter-copy-test.tex b/macros/latex/contrib/scrlttr2copy/letter-copy-test.tex
index 1669762527..6ff0819a9c 100644
--- a/macros/latex/contrib/scrlttr2copy/letter-copy-test.tex
+++ b/macros/latex/contrib/scrlttr2copy/letter-copy-test.tex
@@ -1,4 +1,4 @@
-
+\listfiles
\documentclass[%
,copy
,ngerman
@@ -18,15 +18,18 @@
%\setkomavar*{copy}{Zweitschrift}
+% It is possible to redefine the \LetterCopyMarker macro to have a different
+% background for the copied pages.
+
\begin{document}
-\setkomavar{subject}{Ihr Schreiben vom 11.\,5.\,2015}
+\setkomavar{subject}{Ihr Schreiben vom 11.\,5.\,2015}
\begin{letter}{%
Ellen Bogen \\
Dorfstraße 1\\
12345 Musterhausen
-}
+}
\opening{Sehr geehrte Frau Bogen,}
@@ -50,6 +53,6 @@ Dorfstraße 1\\
\closing{Mit freundlichen Grüßen}
-\end{letter}
+\end{letter}
\end{document}
diff --git a/macros/latex/contrib/skills/README.md b/macros/latex/contrib/skills/README.md
new file mode 100644
index 0000000000..2b1f7f43a8
--- /dev/null
+++ b/macros/latex/contrib/skills/README.md
@@ -0,0 +1,21 @@
+# skills v1.0.0 (2020-10-21)
+
+Author: Pierre-Amiel Giraud
+
+## License
+
+This material is subject to 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 2003/12/01 or later.
+
+- This work has the LPPL maintenance status "maintained".
+- The Current Maintainer of this work is Pierre-Amiel Giraud.
+- This work consists of the files `skills.sty` (the package itself) and `skillsdoc.tex` (its documentation).
+
+Copyright 2020 Pierre-Amiel Giraud
+
+## Description
+
+This package attempts to make it easy for even a LaTeX novice to prepare proficiency tests, especially in combination with the `exam` document class. Thus, almost all command names are very similar.
+
+After defining skills in the preamble or in an external file, they are declared using labels, and can optionally be set as global skills. A skills table is generated to summarize the evaluated competencies and to allow for writing down the resulting proficiency level.
+
+The user's guide `skillsdoc.tex` attempts to explain all of the possibilities in a readable way, with many examples. \ No newline at end of file
diff --git a/macros/latex/contrib/skills/skills.sty b/macros/latex/contrib/skills/skills.sty
new file mode 100644
index 0000000000..a750f5b9c7
--- /dev/null
+++ b/macros/latex/contrib/skills/skills.sty
@@ -0,0 +1,325 @@
+% skills.sty
+%
+% A LaTeX2e package for preparing proficiency tests.
+
+%% skills.sty
+%% Copyright (c) 2020 Pierre-Amiel Giraud
+%
+% 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 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% This work consists of the files skills.sty and skillsdoc.tex.
+
+
+% The user's guide for skills.sty is in the file skillsdoc.tex.
+
+
+%%% Pierre-Amiel Giraud
+%%% History & Geography teacher
+%%% Chambery Middle School
+%%% 33140 Villenave d'Ornon
+%%% pierre-amiel.giraud@ac-bordeaux.fr
+
+% The newest version of this package should always be available
+% from its git repository: https://framagit.org/pagiraud/skills
+
+\NeedsTeXFormat{LaTeX2e}[1994/06/01]
+\ProvidesPackage{skills}[2020/10/21 Easing the making of proficiency tests]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Different defaults if exam class is used %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\@ifclassloaded{exam}{%
+ \newcommand{\skillcounter}{question}%
+ \newcommand{\putglobalskills}{}
+ %New question function : \skillquestion
+ \usepackage{xparse}
+ \NewDocumentCommand \skillquestion {o o}
+ {
+ \IfNoValueTF{#2}
+ {\IfNoValueTF{#1}
+ {\question}
+ {\question \skills{#1}}
+ }
+ {\question[#2] \skills{#1}}
+ }
+ \NewDocumentEnvironment{skillquestions}{o}
+ {
+ \IfNoValueTF{#1}
+ {\begin{questions}}
+ {\ifthenelse{\equal{before}{\putglobalskills}}
+ {\begin{questions}
+ \globalskills{#1}
+ }
+ {\begin{questions}}
+ }
+ }
+ {
+ \IfNoValueTF{#1}
+ {\end{questions}}
+ {
+ \ifthenelse{\equal{before}{\putglobalskills}}
+ {\end{questions}}
+ {\globalskills{#1}
+ \end{questions}}
+ }
+ }
+}{%
+ \newcommand{\skillcounter}{section}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Build upon the package glossaries functionalities %
+% to ease skills evaluation. %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Allowing to change the default counter
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage{iftex}
+\RequirePackage{kvoptions}
+
+\SetupKeyvalOptions{
+ family=SkillsOpt,
+ prefix=SkillsOpt@
+}
+
+\DeclareStringOption[]{counter}
+\ProcessKeyvalOptions*
+
+\ifx\SkillsOpt@counter\@empty
+\else
+ \renewcommand*{\skillcounter}{\SkillsOpt@counter}
+\fi
+
+% Allowing to avoid the making of the glossary
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newif\if@makenoidxglossaries \@makenoidxglossariesfalse
+\DeclareOption{makenoidxglossaries}{\@makenoidxglossariestrue}
+\DeclareOption{donotmakenoidxglossaries}{\@makenoidxglossariesfalse}
+\DeclareOption*{}%Ne pas charger une option inconnue
+\ExecuteOptions{makenoidxglossaries}
+
+\ProcessOptions\relax
+
+%\PassOptionsToPackage{counter=\skillcounter}{glossaries}
+\RequirePackage{glossaries}
+
+\newglossary*{skills}{}[\skillcounter]
+
+\if@makenoidxglossaries
+ % Make the glossaries with standard compilation
+ \makenoidxglossaries
+\fi
+
+\usepackage{tabularx}
+%\renewcommand{\tabularxcolumn}[1]{>m{#1}}
+% Definiton of the skill table (basically, a glossary style)
+% \renewglossarystyle{skillstable}{def} can be used to custom it.
+\newglossarystyle{skillstable}{%
+ \renewenvironment{theglossary}%
+ {%\begin{center}
+ \renewcommand{\arraystretch}{1.5}
+ %\begin{tabular}{|rp{.58\linewidth}|>{\centering\arraybackslash}p{.12\linewidth}|>{\centering\arraybackslash}p{.1\linewidth}|}}%
+ \tabularx{\linewidth}{|rX|>{\centering\arraybackslash}p{.15\linewidth}|c|}}
+ {\endtabularx
+ }%
+ \renewcommand*{\glossaryheader}{\hline%
+ \multicolumn{2}{|c|}{\descriptionname} & \pagelistname & \skilllevelname \tabularnewline\hline}%
+ \renewcommand{\glossentry}[2]{%
+ \glsentryitem{##1}\glstarget{##1}{\glossentryname{##1}} &
+ \glossentrydesc{##1}\glspostdescription\space & ##2 &\tabularnewline\hline
+ }%
+% \renewcommand{\subglossentry}[3]{%
+% &
+% \glssubentryitem{##2}%
+% \glstarget{##2}{\strut}\glossentrydesc{##2}\glspostdescription\space &
+% ##3 & \tabularnewline
+% }%
+\renewcommand*{\glsgroupskip}{}%
+}
+
+% So that no space is left to display a glossary title
+\renewcommand{\glossarysection}[2][]{}
+
+% Print the skills table
+\newcommand{\skillstable}[1][use]{
+ \printnoidxglossary[type=skills, style=skillstable, sort=#1]}
+
+% Code to define a new skill as a new glossary entry
+\newcommand{\skilldef}[3]{\newglossaryentry{#1}{type=skills, name=#2,description={#3}}}
+
+% Code to use a defined skill as a glossary reference
+\newcommand{\skill}[1]{\gls{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Configuring the way skills are displayed along the evaluation %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Define the skills enclosement in the question
+\newcommand{\defaultskillsopening}{(}
+\newcommand{\defaultskillsclosing}{)}
+
+\newcommand{\skillsopening}{\defaultskillsopening}
+\newcommand{\skillsclosing}{\defaultskillsclosing}
+
+% A function to ease skills enclosement modification by users
+\newcommand{\skillsenclosement}[2]{
+ \renewcommand{\skillsopening}{#1}
+ \renewcommand{\skillsclosing}{#2}
+}
+
+% The separator betwenn skills in the question
+\newcommand{\skillssep}{ }
+
+% Putting it all together
+\newcommand{\multiskills}[1]{%
+ \def\nextitem{\def\nextitem{\skillssep}}%
+ \skillsopening
+ \@for \el:=#1\do{\nextitem\skill{\el}}%
+ \skillsclosing
+}
+
+% Shortcuts for the three possibilities offered for points in the exam class
+\newcommand{\bracketedskills}{\skillsenclosement{[}{]}}
+\newcommand{\nobracketedskills}{\defaultskillsenclosement}
+
+
+% Two more shortcut for displaying only skills, without any decoration
+\newcommand{\onlyskills}{\skillsenclosement{}{}}
+\newcommand{\defaultskillsenclosement}{\skillsenclosement{\defaultskillsopening}{\defaultskillsclosing}}
+\newcommand{\notonlyskills}{\defaultskillsenclosement}
+
+\usepackage{etoolbox}
+\usepackage{marginnote}
+
+\newcommand{\skills}[1]{\multiskills{#1}}
+
+\newtoggle{SkillsInMargin}
+\newtoggle{SkillsInLeftMargin}
+\newtoggle{BoxedSkills}
+
+\renewcommand*{\raggedleftmarginnote}{\raggedright}
+\renewcommand*{\raggedrightmarginnote}{\raggedleft}
+\newcommand{\skillsinmarginvadjust}[1]{\renewcommand{\marginnotevadjust}{#1}}
+
+\newcommand{\PrintingSkillsConfiguration}{
+ \iftoggle{SkillsInMargin}
+ {% If skills are to be printed in the margin
+ \iftoggle{SkillsInLeftMargin}
+ {%If skills are to be printed in the left margin
+ \reversemarginpar
+ \iftoggle{BoxedSkills}
+ { %If skills are to be printed in a box in the left margin
+ \renewcommand{\skills}[1]{\marginnote[\fbox{\parbox{\marginparwidth}{\multiskills{##1}}}]{}}
+ }
+ { %If skills are to be printed without a box in the left margin
+ \renewcommand{\skills}[1]{\marginnote[\multiskills{##1}]{}}
+ }
+ }
+ { %Else : if skills are to be printed in the right margin
+ \normalmarginpar
+ \iftoggle{BoxedSkills}
+ {% If skills are to be printed in a box in the right margin
+ \renewcommand{\skills}[1]{\marginnote{\fbox{\parbox{\marginparwidth}{\multiskills{##1}}}}}
+ }
+ {% If skills are to be printed without a box in the right margin
+ \renewcommand{\skills}[1]{\marginnote{\multiskills{##1}}}
+ }
+ }
+ } % Endif
+ {% Else : skills are to be printed inline
+ \iftoggle{BoxedSkills}
+ {% If skills are to be printed inline in a box
+ \renewcommand{\skills}[1]{\fbox{\multiskills{##1}}}
+ }
+ {%If skills are to be printed inline without a box (default)
+ \renewcommand{\skills}[1]{\multiskills{##1}}
+ }
+ }
+}
+
+\newcommand{\skillsinrightmargin}{
+ \toggletrue{SkillsInMargin}
+ \togglefalse{SkillsInLeftMargin}
+ \PrintingSkillsConfiguration
+}
+
+\newcommand{\skillsinleftmargin}{
+ \toggletrue{SkillsInMargin}
+ \toggletrue{SkillsInLeftMargin}
+ \PrintingSkillsConfiguration
+}
+
+\newcommand{\skillsinmargin}{\skillsinleftmargin}
+
+\newcommand{\noskillsinmargin}{
+ \togglefalse{SkillsInMargin}
+ \PrintingSkillsConfiguration
+}
+
+\newcommand{\noskillsinrightmargin}{\noskillsinmargin}
+
+\newcommand{\boxedskills}{
+ \toggletrue{BoxedSkills}
+ \onlyskills
+ \skillsinmarginvadjust{-\baselineskip}
+ \PrintingSkillsConfiguration
+}
+
+\newcommand{\noboxedskills}{
+ \togglefalse{BoxedSkills}
+ \defaultskillsenclosement
+ \skillsinmarginvadjust{0pt}
+ \PrintingSkillsConfiguration
+}
+
+% The case of global skills
+\newcommand*{\glsgobblenumber}[1]{}
+% \renewcommand*{\glsgobblenumber}[1]{#1}% uncomment for testing
+
+\newcommand*{\globalskill}[2][]{%
+ \glsdoifexists{#2}%
+ {%
+ % \def\@glsnumberformat{glsnumberformat}% DELETED
+ \def\@glsnumberformat{glsgobblenumber}% NEW
+ \edef\@gls@counter{\csname glo@#2@counter\endcsname}%
+ \setkeys{glossadd}{#1}%
+ \@gls@saveentrycounter
+ \@do@wrglossary{#2}%
+ }%
+}
+
+\newcommand{\globalskills}[1]{%
+ \@for \el:=#1\do{\globalskill{\el}}%
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Localization. Work on it is needed %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% English (no localization)
+\renewcommand{\descriptionname}{Skill}
+\renewcommand{\pagelistname}{Questions}
+\newcommand{\skilllevelname}{Proficiency}
+
+% French
+\newcommand{\FrenchLocalization}{
+ \addto\captionsfrench{
+ \renewcommand{\pagelistname}{Questions}
+ \renewcommand{\descriptionname}{Compétence}
+ \renewcommand{\skilllevelname}{Maîtrise}
+ }
+}
+
+\@ifpackageloaded{polyglossia}{\FrenchLocalization}{}
+\@ifpackageloaded{babel}{\FrenchLocalization}{}
+
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/skills/skillsdoc.pdf b/macros/latex/contrib/skills/skillsdoc.pdf
new file mode 100644
index 0000000000..e60985763f
--- /dev/null
+++ b/macros/latex/contrib/skills/skillsdoc.pdf
Binary files differ
diff --git a/macros/latex/contrib/skills/skillsdoc.tex b/macros/latex/contrib/skills/skillsdoc.tex
new file mode 100644
index 0000000000..ee3cca4195
--- /dev/null
+++ b/macros/latex/contrib/skills/skillsdoc.tex
@@ -0,0 +1,733 @@
+%--------------------------------------------------------------------
+%--------------------------------------------------------------------
+% skillsdoc.tex
+%
+% This is the user's guide for the skills package,
+% by Pierre-Amiel Giraud.
+%
+% The skills package itself is in the file skills.sty.
+
+
+%%% Copyright (c) 2020
+% Pierre-Amiel Giraud
+%
+% 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 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Pierre-Amiel Giraud.
+%
+% This work consists of the files skills.sty and skillsdoc.tex.
+
+% The user's guide for skills.sty is in the file skillsdoc.tex.
+
+
+%%% Pierre-Amiel Giraud
+%%% History and Geography Teacher
+%%% Chambery Middle School
+%%% 33140 Villenave d'Ornon (France)
+%%% pierre-amiel.giraud@ac-bordeaux.fr
+
+% The newest version of this package should always be available
+% from my Gitlab page: https://framagit.org/pagiraud/skills/
+
+
+%--------------------------------------------------------------------
+%--------------------------------------------------------------------
+
+\documentclass[12pt]{exam}
+
+\usepackage{luatextra}
+\setmainfont{Linux Libertine O}
+\usepackage{polyglossia}
+\usepackage{microtype}
+
+\usepackage{amssymb}
+
+\usepackage{makeidx}
+
+\usepackage[counter=section]{skills}
+\skilldef{writing}{L1.1}{Writing to argue and write to communicate and share ideas}
+\skilldef{vocabulary}{H3.2}{Learning specific vocabulary and using it in context}
+\skilldef{situationInTime}{C1.1}{Situating in time and elaborating chronological landmarks}
+\renewcommand{\skillcounter}{section}
+
+\usepackage[colorlinks]{hyperref}
+
+% In case we're not using hyperref.sty:
+\providecommand{\texorpdfstring}[2]{#1}
+% The following can be used in \section commands
+% without generating pdf warnings:
+\newcommand{\bs}{\texorpdfstring{\char`\\}{}}
+
+\newcommand{\docversion}{1.0.0}
+\newcommand{\docdate}{October 21, 2020}
+%\newcommand{\docdate}{Draft: \today}
+
+%--------------------------------------------------------------------
+%
+% Changes since version 2.4 are described in the comments
+% near the beginning of the file exam.cls.
+%
+%--------------------------------------------------------------------
+
+\makeindex
+
+\newcommand{\indc}[1]{\index{#1@\texttt{\char`\\#1}}}
+\newcommand{\indcsub}[2]{\index{#1@\texttt{\char`\\#1}!#2}}
+\newcommand{\indcstart}[1]{\index{#1@\texttt{\char`\\#1}|(}}
+\newcommand{\indcstop}[1]{\index{#1@\texttt{\char`\\#1}|)}}
+
+\newcommand{\indt}[1]{\index{#1@\texttt{#1}}}
+\newcommand{\indtsub}[2]{\index{#1@\texttt{#1}!#2}}
+\newcommand{\indtstart}[1]{\index{#1@\texttt{#1}|(}}
+\newcommand{\indtstop}[1]{\index{#1@\texttt{#1}|)}}
+
+%---------------------------------------------------------------------
+\newenvironment{example}%
+ {\bigskip\filbreak
+ \subsubsection{Example:}
+ }%
+ {}
+
+\def\samplehead#1#2#3#4{%
+ \begin{trivlist}
+ \item[]
+ \leavevmode
+ \hbox to \textwidth{%
+ \rlap{\parbox[b]{\textwidth}{\raggedright#1\strut}}%
+ \hfil\parbox[b]{\textwidth}{\centering#2\strut}\hfil
+ \llap{\parbox[b]{\textwidth}{\raggedleft#3\strut}}%
+ }% hbox
+ #4
+ \end{trivlist}
+}
+
+\def\samplefoot#1#2#3#4{%
+ \begin{trivlist}
+ \item[]
+ \leavevmode
+ #1
+ \vskip 3pt
+
+ \hbox to \textwidth{%
+ \rlap{\parbox[t]{\textwidth}{\raggedright#2}}%
+ \hfil\parbox[t]{\textwidth}{\centering#3}\hfil
+ \llap{\parbox[t]{\textwidth}{\raggedleft#4}}%
+ }% hbox
+ \end{trivlist}
+}
+
+% \makeatletter
+% \@ifundefined{AmS}{\def\AmS{{\protect\the\textfont\tw@
+% A\kern-.1667em\lower.5ex\hbox{M}\kern-.125emS}}}
+% {}
+% \makeatother
+
+
+%---------------------------------------------------------------------
+%---------------------------------------------------------------------
+%---------------------------------------------------------------------
+%---------------------------------------------------------------------
+
+\begin{document}
+
+\title{Using the skills package}
+
+\author{Pierre-Amiel Giraud\\
+ History \& geography teacher\\
+ Chambery Middle School\\
+ 33140 Villenave d'Ornon (France)\\
+ pierre-amiel.giraud@ac-bordeaux.fr\\[\bigskipamount]
+ Copyright \copyright~2020\\
+ Pierre-Amiel Giraud}
+
+\date{\docdate}
+
+\maketitle
+
+\begin{center}
+ \small
+ This is the user's guide for version~\docversion{} of the
+ \verb"skills" package.
+\end{center}
+
+\tableofcontents
+%--------------------------------------------------------------------
+\section{Introduction}
+
+The file \verb"skills.sty" provides the \verb"skills" package,
+which attempts to make it easy for even a \LaTeX{} novice to prepare
+proficiency tests, especially in combination with the \verb|exam| document
+class.
+
+Here, what is called a proficiency test is an exam where questions are assigned
+one or more skills, and where the proficiency of the pupil is evaluated for each skill.
+It seems it can also be called, depending on the context and the country, skills assessment
+or skill-based assessment. As far as I know, proficiency tests are more often used in French-speaking areas, where they are called "\textit{évaluations par compétences}". This package has
+been designed with the French approach in mind. If you are using proficiency tests
+but this package doesn't fill your needs, your suggestions or code contributions are welcome.
+
+The \verb|skills| package has also been designed to be best used within the \verb|exam| document class. Thus, almost all command names are very similar. However, the package can be used within a variety of document classes: only a very small subset of the package commands is specific to the \verb|exam| document class.
+
+Some other packages, such as the \verb|competences| packages by Christophe Bares, follow the
+same goal but with different approaches. They might be of some interest if the present
+\verb|skills| package doesn't fill your needs.
+
+The latest version of \verb"skills.sty" (possibly a
+%
+beta\index{beta test} test version) should always be available at
+\verb"https://framagit.org/pagiraud/skills/"\index{web page}.
+
+%--------------------------------------------------------------------
+\subsection{License}
+
+\begin{itemize}
+\item This work may be distributed and/or modified under the
+ %
+ \index{Latex Project Public License@\LaTeX{} Project Public License}
+ %
+ conditions of the \LaTeX{} Project Public
+ License\index{license},\index{LPPL} either version~1.3 of this
+ license or (at your option) any later version. The latest version
+ of this license is in \verb"http://www.latex-project.org/lppl.txt"
+ and version 1.3 or later is part of all distributions of \LaTeX{}
+ version 2003/12/01 or later.
+\item This work has the LPPL maintenance status ``maintained''.
+\item The Current Maintainer of this work is Pierre-Amiel Giraud
+\item This work consists of the files \verb"skills.sty" and
+ \verb"skillsdoc.tex".
+\end{itemize}
+
+\subsection{Version Notes}
+
+\begin{description}
+ \item[v1.0.0] Initial release
+\end{description}
+
+%--------------------------------------------------------------------
+%--------------------------------------------------------------------
+\section{Usage instructions}
+\label{sec:Usage}
+
+This section details how to use the package and the commands it provides,
+from basic usage to customization. Some features are only available when
+the package is loaded within the \verb|exam| document class. They will be
+indicated as such.
+%--------------------------------------------------------------------
+\subsection{Loading the \texttt{skills} package}
+\label{sec:UsageLoadingPackage}
+
+To use the \verb|skills| package, you must load it, like every package,
+with the command
+\begin{center}
+ \verb"\usepackage{skills}"
+\end{center}
+
+\subsubsection*{Package options (advanced use only)}
+The package has only three options:
+\begin{itemize}
+ \item \verb|makenoidxglossaries| (default)
+ \item \verb|donotmakenoidxglossaries|
+ \item \verb|counter=<value>|
+\end{itemize}
+
+The \verb|donotmakenoidxglossaries| option is of any use only if you want to
+use the \verb|glossaries| package, upon which \verb|skills| is based,
+in your document. It deactivates the \verb|\makenoidxglossaries| command included in the \verb|skills.sty| file,
+so that you can handle your glossaries with the indexing option of your
+choice. Please refer to the \verb|glossaries| package documentation for
+more details.
+
+So, if you want to use the \verb|glossaries| and the \verb|skills| packages
+together in your document, it is advised to load the \verb|skills| package
+as follows:
+\begin{center}
+ \verb|\usepackage[donotmakenoidxglossaries]{skills}|
+\end{center}
+
+The \verb|counter| option is to be used only if you to change the default counter for grouping the skills in the skills table (question for the \verb|exam| class, \verb|section| for other classes). The section counter was chosen because it is probably the most widespread logical counter (as opposed to the page counter). This very document, written with the \verb|exam| class, loads the \verb|skills| package with
+
+\begin{verbatim}
+ \usepackage[counter=section]{skills}
+\end{verbatim}
+
+Indeed, multiple \verb|questions| environments are used all along the documentation, and using question as a counter would needlessly clutter the skills table. Any available counter can be used.
+%--------------------------------------------------------------------
+\subsection{Defining skills}
+\label{sec:UsageDefiningSkills}
+
+Skills must be defined in the preamble, using the \verb|skilldef| command:
+\begin{center}
+ \verb|\skilldef{label}{reference}{description}|
+\end{center}
+
+The first argument, \verb|label|, is a simple keyword that will be used in your document
+to indicate that you are evaluating mastery of this skill. The \verb|reference|
+is the code of the skill in your competency framework. Finally, \verb|description| is the
+place where you can put the title of your skill along with some description.
+
+Defining a skill doesn't imply that it will be used. Thus, you can define your whole
+competency framework (or a significant subset) in a file and then simply load it
+with the \verb|\input| command in every proficiency test you make: all skills will
+be available for declaration, but only those explicitly declared in the document body
+will appear on the output file.
+
+For the sake of example, we will define three skills that will be used all along this
+manual:
+
+\begin{verbatim}
+ \skilldef{writing}{L1.1}{Writing to argue and write to communicate
+ and share ideas}
+ \skilldef{vocabulary}{H3.2}{Learning specific vocabulary and using
+ it in context}
+ \skilldef{situationInTime}{C1.1}{Situating in time and elaborating
+ chronological landmarks}
+\end{verbatim}
+
+%--------------------------------------------------------------------
+\subsection{Declaring skills}
+\label{sec:UsageDeclaringSkills}
+
+There are two ways for declaring skills. The first, and the simplest, is available
+only if the loaded document class is \verb|exam|. The second one is class agnostic.
+
+\subsubsection{The easy way (\texttt{exam} document class only)}
+\label{sec:UsageDeclaringSkillsExamClass}
+
+When the \verb|skills| package is used together with the \verb|exam| document class,
+the \verb|skillquestions| environment and the \verb|\skillquestion| command become
+available to the user.
+
+They behave like the \verb|questions| environment and \verb|\question| command from
+the \verb|exam| document class, except they have one more optional argument, used for
+declaring skills:
+
+\begin{center}
+ \begin{verbatim}
+ \begin{skillquestions}[optional list of comma separated skills]
+ \skillquestion[optional list of comma separated skills][optional number of
+ points for the question] Some question
+ \end{skillquestions}
+ \end{verbatim}
+\end{center}
+
+The skills declared as arguments to the \verb|skillquestions| environment are global:
+they are not linked to any specific question in the exam, but are rather evaluated throughout
+the exam and will be flagged as such in the skills table (see subsection~\ref{sec:UsageSkillsTable}). Those declared as arguments
+to a \verb|\skillquestion| command are evaluated only in the questions where they are declared.
+
+Some details need specific attention:
+\begin{itemize}
+ \item The label chosen when defining a skill is used to declare it in the exam.
+ \item If you don't want to declare global skills or if, for any reason, you don't want to declare skills for a question, you should omit the square brackets containing them: don't use empty brackets.
+ \item Don't use spaces in the skills list: write \verb|writing,vocabulary|, not \verb|writing, vocabulary|.
+ \item A skill can't be declared as global and question specific in the same exam. If you try to
+ do so, the question-level declaration will overwrite the global one.
+ \item The \verb|skillquestions| environment and the \verb|\skillquestion| command are only wrappers around the \verb|questions| environment and the \verb|question| command from the \verb|exam| document class. As such, they can be freely mixed: \verb|\question| and \verb|\skillquestion| can be used together both within the \verb|questions| and \verb|skillquestions| environments. Points of \verb|\question| and \verb|skillquestion| add up nicely.
+\end{itemize}
+
+A very basic example, using the three previously defined skills, could thus be:
+
+\begin{verbatim}
+ \begin{skillquestions}[writing]
+ \skillquestion A first question without any skill declared
+ \skillquestion[situationInTime,vocabulary] A second question with two skills
+ \skillquestion[vocabulary][2] A third question with one skill and 2 points.
+ \question[3] A last question without any skill declared but 3 points.
+ \end{skillquestions}
+\end{verbatim}
+
+And would results in:
+ \begin{skillquestions}[writing]
+ \skillquestion A first question without any skill declared
+ \skillquestion[situationInTime,vocabulary] A second question with two skills
+ \skillquestion[vocabulary][2] A third question with one skill and 2 points.
+ \question[3] A last question without any skill declared but 3 points.
+\end{skillquestions}
+
+\bigskip
+
+As you can see, the declared global skill isn't printed: it will be shown only in the skills table (see subsection~\ref{sec:UsageSkillsTable}), which summarizes all declared skills in the exam.
+
+\subsubsection{The other but also easy way (any document class)}
+\label{sec:UsageDeclaringSkillsAnyClass}
+
+Skills and global skills can also be declared with the \verb|\skills| and \verb|\globalskills| commands:
+
+\begin{center}
+ \verb|\skills{list of comma separated skills}|
+ \verb|\globalskills{list of comma separated skills}|
+\end{center}
+
+As for \verb|skillquestion| and \verb|skillquestions|, the separator must be only a comma:don't
+use spaces. In the default configuration (see subsection~\ref{sec:CustomizeWhere} for customization), the skills will appear right
+were you write them. If you type:
+
+\begin{verbatim}
+ Some text \skills{vocabulary} that goes on and on and on.
+\end{verbatim}
+
+You will get:
+
+\bigskip
+Some text \skills{vocabulary} that goes on and on and on.
+\bigskip
+
+So, the \verb|\skills| command can be used in any class. That includes the \verb|exam| document class,
+if you want, for instance, to declare skills at the \verb|subquestion| or \verb|part| level. This won't
+have any effect on the way skills are grouped in the skills table. By default, they are grouped per question in the \verb|exam| class and per section for other document classes.
+
+The \verb|\globalskills| command doesn't print anything. If you type:
+
+\begin{verbatim}
+ Some text \globalskills{writing} that goes on and on and on.
+\end{verbatim}
+
+You will get:
+
+\bigskip
+Some text \globalskills{writing} that goes on and on and on.
+\bigskip
+
+But the place where you put the \verb|\globalskills| command has a direct effect on the skills table, as the skills appear in the order they are firstly declared. What's more, typing the \verb|globalskills| command anywhere in the document will likely result in undesired commas in the skills table. Therefore, as a rule of thumb, all global skills should be declared at once, in the same \verb|\globalskills| command:
+
+\begin{itemize}
+ \item right after \verb|\begin{document}| if you want the global skills to be printed at the beginning of the skills table;
+ \item right before \verb|\end{document}| if you want them to be printed at the end of the skills table.
+\end{itemize}
+
+The \verb|\globalskills| command shouldn't be used at all in the \verb|exam| class, at least in the \verb|skillquestions| environment is used.
+
+%margins. For the full story, see section~\ref{sec:points}.
+
+
+%--------------------------------------------------------------------
+\subsection{Printing the skills table}
+\label{sec:UsageSkillsTable}
+
+There would be very little interest in defining then declaring skills evaluated in an exam if they are not listed somewhere. With the \verb|skills| package, this is done with the command:
+
+\begin{center}
+ \verb|\skillstable[optional sorting argument]|
+\end{center}
+
+So, for most users, a simple \verb|\skillstable| is enough. If you are unhappy with the default sorting (skills sorted in the order they are firstly declared in the document), which is equivalent of typing \verb|\skillstable[use]|, some other options are available: word, letter, standard, def, nocase, case. For more information on these, please refer to the \verb|glossaries| package documentation (chapter 10, Displaying a glossary).
+
+Here, if I type:
+
+\begin{verbatim}
+ \skillstable
+\end{verbatim}
+
+I get:
+
+\bigskip
+
+\noindent
+\skillstable
+
+\bigskip
+
+The global skills can easily be seen as no question number appears in the Questions column.
+
+If the \verb|\globalskills| command is used to declare global skills, the place of the skills in the table is determined by the place the command is put in the document (see subsection~\ref{sec:UsageDeclaringSkillsAnyClass}). If the global skills are
+declared with the optional argument of the \verb|skillquestions| environment, by default, they are put after the other skills in the table, but this can be changed by typing:
+
+\begin{center}
+ \verb|\renewcommand{\putglobalskills}{before}|
+\end{center}
+
+%---------------------------------------------------------------------
+%--------------------------------------------------------------------
+\section{Customizing the display of the skills}
+\label{sec:Customize}
+
+For now, we have only seen how to setup a proficiency test, without modifying
+the default appearance, that is:
+
+\begin{itemize}
+ \item In the \verb|\skills| and \verb|\skillquestion| commands, if several skills are
+ declared, a blank space is used as a separator.
+\end{itemize}
+
+%--------------------------------------------------------------------
+\subsection{The separator in the \texttt{\textbackslash skills} and \texttt{\textbackslash skillquestion} commands}
+\label{sec:CustomizeSeparator}
+
+The default blank space can be changed by renewing the \verb|\skillssep| command. For instance, if you want the skills to be separated with a comma followed by a blank space, type:
+
+\begin{verbatim}
+ \renewcommand{\skillssep}{, }
+\end{verbatim}
+
+\renewcommand{\skillssep}{, }
+
+And now, if you type:
+
+\begin{verbatim}
+ \skills{vocabulary,situationInTime}
+\end{verbatim}
+
+You get:
+
+\bigskip
+\skills{vocabulary,situationInTime}
+\bigskip
+
+\renewcommand{\skillssep}{ }
+%--------------------------------------------------------------------
+\subsection{Where the skills will be printed}
+\label{sec:CustomizeWhere}
+
+The default is that the skills references will be inserted at the beginning of the question with \verb|\skillquestion| or right where the \verb|\skills| command is used, but, for one-sided documents
+
+\begin{itemize}
+ \item the command \verb|\skillsinmargin| (or, equivalently, the command \verb|\skillsinleftmargin|) will cause the skills references to be set in the left margin,
+ \item the command \verb|\skillsinrightmargin| will cause the skills references to be set in the right margin,
+ \item the commands \verb|\noskillsinmargin| and \verb|\noskillsinrightmargin| are equivalent, and either of them will revert to the default situation.
+\end{itemize}
+
+For two-sided documents, \verb|\skillsinmargin| and \verb|\skillsinleftmargin| print skills in the inner margin, while \verb|\skillsinrightmargin| prints them in the outer margin.
+
+If you chose to print the skills references inline (default), you can move where they appear simply by changing the place you type the \verb|\skills| command. For instance, if you want to print the skills at the end of a question, in the \verb|exam| class, you can type:
+
+\begin{verbatim}
+\begin{questions}
+ \skillquestion A very good question. \skills{vocabulary}
+\end{questions}
+\end{verbatim}
+
+You will get:
+
+\bigskip
+\begin{skillquestions}
+ \skillquestion A very good question. \skills{vocabulary}
+\end{skillquestions}
+\bigskip
+
+When the skills are set in a margin, they start on the line they were declared. Sometimes, for instance if you declare bot points and skills for a \verb|\skillquestion| to be shown in the same margin, the skills and points overlap, so you need to move vertically the skills using:
+
+\begin{center}
+ \verb|\skillsinmarginvadjust{some length}|
+\end{center}
+
+Let's see an example:
+\begin{verbatim}
+\begin{questions}
+ \pointsinrightmargin
+ \skillsinrightmargin
+ \skillquestion[vocabulary][2] Some question
+ \skillsinmarginvadjust{\baseline}
+ \skillquestion[vocabulary][2] Some question
+\end{questions}
+\end{verbatim}
+
+\bigskip
+\begin{questions}
+ \pointsinrightmargin
+ \skillsinrightmargin
+ \skillquestion[vocabulary][2] Some question
+ \skillsinmarginvadjust{\baselineskip}
+ \skillquestion[vocabulary][2] Some question
+\end{questions}
+\bigskip
+
+\verb|\skillsinmarginvadjust| can be changed as often as you need.
+
+%-----------------------------------------------------------------
+\subsection{Surronunding the skills: parentheses, brackets, a box, and more}
+\label{CustomizeSurrounding}
+
+By default, skills references are enclosed in parentheses. The package provides two ways for changing this.
+
+\subsubsection{Very quick way}
+Following the syntax used in the \verb|exam| class (but not requiring you to use it), you can very quickly change the way skills are enclosed.
+
+For instance, if you want to have the skills references enclosed in brackets:
+
+\begin{center}
+ \verb|\bracketedskills|
+\end{center}
+
+For example, if you give the command \verb|\bracketedskills|, typing some questions will produce something as follows:
+
+\begin{questions}
+ \bracketedskills
+ \skillquestion[vocabulary] Why is there air?
+ \skillquestion[vocabulary,situationInTime] What if there were no air?
+\end{questions}
+
+If you prefer having the skills enclosed in a box instead of in parentheses, give the command
+
+\begin{center}
+ \verb|\boxedskills|
+\end{center}
+
+For example, if you give the command \verb|\boxedskills|, then the questions typed above will produce
+
+\begin{questions}
+ \boxedskills
+ \skillquestion[vocabulary] Why is there air?
+ \skillquestion[vocabulary,situationInTime] What if there were no air?
+\end{questions}
+
+If you give the commands \verb|\boxedskills| and \verb|\skillsinmargin|, then the above questions will produce
+
+\begin{questions}
+ \boxedskills
+ \skillsinmargin
+ \skillquestion[vocabulary] Why is there air?
+ \skillquestion[vocabulary,situationInTime] What if there were no air?
+\end{questions}
+
+If you want the skills to be not enclosed at all, you can give the command:
+
+\begin{verbatim}
+ \onlyskills
+\end{verbatim}
+
+If you give the commands \verb|\onlyskills| and \verb|\skillsinrightmargin|, then the above questions will produce
+
+\begin{questions}
+ \onlyskills
+ \skillsinrightmargin
+ \skillquestion[vocabulary] Why is there air?
+ \skillquestion[vocabulary,situationInTime] What if there were no air?
+\end{questions}
+
+Other combinations of these commands will produce similar effects.
+
+If you want to switch back and forth between formats during the proficiency test, you can do so by giving one of the commands
+
+\begin{center}
+ \begin{tabular}{l}
+ \verb"\bracketedskills"\\
+ \verb"\nobracketedskills"\\
+ \verb"\boxedskills"\\
+ \verb"\noboxedskills"\\
+ \verb"\onlyskills"\\
+ \verb"\notonlyskills"
+ \end{tabular}
+\end{center}
+
+whenever you want to switch. The commands \verb|\nobracketedskills|, \verb|\noboxedskills| and \verb|\notonlyskills| are equivalent: they all return to the default of putting parentheses around the skills references.
+
+\subsubsection{Using the \texttt{\textbackslash skillsenclosement} command}
+
+It is possible to enclose the skills references with any string of characters, using the \verb|\skillsenclosement| command:
+
+\begin{center}
+ \verb|\skillsenclosement{opening string}{closing string}|
+\end{center}
+
+Actually, \verb|\bracketedskills| and \verb|\onlyskills| definitions are
+
+\begin{verbatim}
+ \newcommand{\bracketedskills}{\skillsenclosement{[}{]}}
+ \newcommand{\onlyskills}{\skillsenclosement{}{}}
+\end{verbatim}
+
+But one can be more imaginative with, for instance
+
+\begin{verbatim}
+ \skillsenclosement{**}{**}
+\end{verbatim}
+
+or even
+
+\begin{verbatim}
+ \skillsenclosement{oO}{Oo}
+\end{verbatim}
+
+This last example would produce
+
+\begin{questions}
+ \skillsenclosement{oO }{ Oo}
+ \skillquestion[vocabulary] Why is there air?
+ \skillquestion[vocabulary,situationInTime] What if there were no air?
+\end{questions}
+
+The \verb|\boxedskills| command uses another mechanism: after triggering an \verb|\onlyskills|, it puts a \verb|\fbox| or a \verb|\parbox| in a \verb|\fbox| around the skills, depending on whether the latter are printed inline or in a margin. It means one can use \verb|\skillsenclosement| after \verb|\boxedskills|. For instance, typing the following commands
+
+\begin{verbatim}
+ \boxedskills
+ \skillsenclosement{oO }{ Oo}
+\end{verbatim}
+
+before the questions printed above would produce
+
+\begin{questions}
+ \boxedskills
+ \skillsenclosement{oO }{ Oo}
+ \skillquestion[vocabulary] Why is there air?
+ \skillquestion[vocabulary,situationInTime] What if there were no air?
+\end{questions}
+
+%--------------------------------------------------------------------
+\subsection{The skills table}
+\label{sec:CustomizeSkillsTable}
+We have already talked about the \verb|\putglobalskills| command (see subsection~\ref{sec:UsageSkillsTable}).
+
+It is also possible to rename the columns of the table by renewing some commands before typing \verb|\skillstable|:
+
+\begin{itemize}
+ \item \verb|\renewcommand{\descriptionname}{Some name}| for the first column (default: Skill)
+ \item \verb|\renewcommand{\pagelistname}{Some name}| for the second column (default: Questions)
+ \item \verb|\renewcommand{\skilllevelname}{Some name}| for the third column (default: Proficiecncy)\\
+\end{itemize}
+
+If you are using the package \verb|polyglossia| or \verb|babel| with French as main language, these names are localized by the \verb|skills| package as "Compétences", "Questions" and "Maîtrise".
+
+It is also possible to totally change the look of the skills table with the command
+
+\begin{verbatim}
+ \renewglossarystyle{skillstable}{A new skills table look}
+\end{verbatim}
+
+This requires some knowledge about the \verb|glossaries| package. Please refer to its documentation, especially section 15.2 (Defining your own glossary style).
+
+%---------------------------------------------------------------------
+%--------------------------------------------------------------------
+\section{Technical informations}
+\label{sec:Technical}
+
+\subsection{Loaded packages}
+\label{sec:TechnicalPackages}
+
+The \verb|skills| package loads some other packages, namely and unordered: \verb|glossaries|, \verb|marginnote|, \verb|xparse|, \verb|tabularx|, \verb|etoolbox|, \verb|iftex| and \verb|kvoptions|.
+
+They are all loaded without any option.
+
+\subsection{Possible improvements (this is not a roadmap)}
+\label{sec:TechnicalImprovements}
+
+In next versions, if any, some improvements will be made:
+\begin{itemize}
+ \item A code cleanup is needed, because I started coding the package with the assumption that the naming convention for commands in the \LaTeX world was all lowercase. Then, I understood that the convention consisted rather in using lowercase names for user commands and camel case names for other commands.
+ \item A deeper code refactoring would replace \LaTeX commands by plain TeX control sequences and limit the dependency to external packages. This lower dependency would also help mitigating the probability of side effects.
+ \item Allowing for multiple skills tables on the same document, for instance on a per part or per section basis.
+ \item Offering some competency framework, that could be chosen with a key/value system as a package option.
+\end{itemize}
+
+%--------------------------------------------------------------------
+
+% The following is necessary to avoid warnings, since we have multiple
+% questions environments in this documentation file:
+\makeatletter
+\@pointschangedfalse
+\makeatother
+
+
+
+
+\end{document}
+%--------------------------------------------------------------------
+%--------------------------------------------------------------------
+%--------------------------------------------------------------------
diff --git a/macros/latex/contrib/snapshot/README b/macros/latex/contrib/snapshot/README
index 570861d37d..4c50606d36 100644
--- a/macros/latex/contrib/snapshot/README
+++ b/macros/latex/contrib/snapshot/README
@@ -1,17 +1,119 @@
-README for snapshot 2019/09/17
-https://www.ams.org/arc/resources/snapshot-about.html
-tech-support@ams.org
+README file for package snapshot 2.14 [2020/06/17]
-The snapshot package helps the owner of a LaTeX document
-obtain a list of the external dependencies of the document, in a
-form that can be embedded at the top of the document. To put it
-another way, it provides a snapshot of the current processing
-context of the document, insofar as it can be determined from
-inside LaTeX.
-
-Originally written by Michael J. Downes, the snapshot package
-is currently maintained by the American Mathematical Society.
+Copyright 1999-2003, 2004, 2010, 2012, 2020 American Mathematical Society.
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 2005/12/01 or later.
+
+This work has the LPPL maintenance status `maintained'.
+
+The Current Maintainer of this work is the American Mathematical
+Society.
+
+American Mathematical Society
+Technical Support
+Publications Technical Group
+201 Charles Street
+Providence, RI 02904
+USA
+tel: (401) 455-4080
+ (800) 321-4267 (USA and Canada only)
+fax: (401) 331-3842
+email: tech-support@ams.org
+
+========================================================================
+ CONTENTS
+I. OVERVIEW
+II. REMARKS ON THIS RELEASE
+II. CHANGE LOG
+
+========================================================================
+I. OVERVIEW
+
+Complete documentation of all package options is available in
+snapshot.pdf.
+
+Typical usage involves the following steps:
+
+1. Add a \RequirePackage statement at the top of the document:
+
+ \RequirePackage{snapshot}
+ \documentclass{article}
+
+ \usepackage{graphicx}
+
+ \begin{document}
+
+ hello, world
+
+ \end{document}
+
+ Note that snapshot should be the very first thing loaded, even
+ before the \documentclass. Otherwise snapshot will not be able to
+ capture the information for the document class and any packages
+ loaded inside it.
+
+2. Run LaTeX on the document. This will produce a dependency list in a
+ file \jobname.dep.
+
+3. Insert the .dep file at the top of the document, before
+ \documentclass. The following example shows what you would
+ typically end up with for a document that used the article
+ documentclass and the graphicx package:
+
+ \RequirePackage{snapshot}
+
+ \RequireVersions{
+ *{application}{pdfTeX} {0000/00/00 v1.40.21}
+ *{format} {LaTeX2e} {2020-02-02 v2.e}
+ *{package}{snapshot} {2020/06/17 v2.14}
+ *{class} {article} {2019/12/20 v1.4l}
+ *{file} {size10.clo} {2019/12/20 v1.4l}
+ *{package}{graphicx} {2019/11/30 v1.2a}
+ *{package}{keyval} {2014/10/28 v1.15}
+ *{package}{graphics} {2019/11/30 v1.4a}
+ *{package}{trig} {2016/01/03 v1.10}
+ *{file} {graphics.cfg}{2016/06/04 v1.11}
+ *{file} {dvips.def} {2017/06/20 v3.1d}
+ *{file} {l3backend-dvips.def}{2020-05-05 v3}
+ }
+
+ \documentclass{article}
+ [...]
+
+ Now each time you recompile the document, snapshot will compare the
+ list of files actually loaded against the list recorded in
+ \RequireVersions and warn you of any changes.
+
+========================================================================
+II. REMARKS ON THIS RELEASE
+
+Since the snapshot package was originally released, there has been a
+tremendous amount of evolution among TeX engines (what snapshot calls
+the "application"). In addition to the introduction of two major new
+engines, three other engines that were once distinct have effectively
+merged. The algorithm for detecting the identify of the engine has
+been updated to reflect the state of the TeX world as reflected in TeX
+Live 2020.
+
+COMPATIBILITY NOTE: As a result of these improvements, the
+*{application} entry of your documents will almost certainly change.
+The snapshot package does not warn of changes in this entry, but if
+you have an external application that makes use of this information,
+you will probably need to update it.
+
+========================================================================
+III. CHANGE LOG
+
+2020-06-17 snapshot.dtx v2.14
+ -- Added code to detect the aleph, ptex, eptex, uptex, euptex,
+ luatex, and xetex engines in addition to etex, pdftex, and
+ pdfetex. Also distinguish between the various engines which
+ incorporate the eTeX extensions.
+ -- Made snapshot more tolerant of macros in the optional argument
+ to \Provides... declarations.
diff --git a/macros/latex/contrib/snapshot/snapshot.dtx b/macros/latex/contrib/snapshot/snapshot.dtx
index f79605dbf6..38c6b7d656 100644
--- a/macros/latex/contrib/snapshot/snapshot.dtx
+++ b/macros/latex/contrib/snapshot/snapshot.dtx
@@ -1,6 +1,6 @@
% \def\filename{snapshot.dtx}
-% \def\fileversion{2.13}
-% \def\filedate{2012/08/06}
+% \def\fileversion{2.14}
+% \def\filedate{2020/06/17}
%
% \iffalse meta-comment
%
@@ -15,7 +15,7 @@
% fax: (401) 331-3842
% email: tech-support@ams.org
%
-% Copyright 1999-2003, 2004, 2010, 2012 American Mathematical Society.
+% Copyright 1999-2003, 2004, 2010, 2012, 2020 American Mathematical Society.
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
@@ -35,7 +35,10 @@
% \iffalse
%<*driver>
\NeedsTeXFormat{LaTeX2e}
-\documentclass[oneside]{amsdtx}
+\documentclass{amsdtx}
+
+\usepackage{hyperref}
+
\providecommand{\qq}[1]{\textquotedblleft#1\textquotedblright}
\providecommand{\mdash}{\textemdash\penalty\exhyphenpenalty}
\providecommand{\lat}[1]{\protect\LaTeX{}}
@@ -44,12 +47,18 @@
\CodelineIndex
-\begin{document}
\title{The \pkg{snapshot} package}
-\author{American Mathematical Society\\Michael Downes}
+
+\author{American Mathematical Society}
+
\date{Version \fileversion, \filedate}
+
+\begin{document}
+
\DocInput{snapshot.dtx}
+
\PrintIndex
+
\end{document}
%</driver>
% \fi
@@ -57,6 +66,9 @@
% \MakeShortVerb{\|}
%
% \maketitle
+%
+% \tableofcontents
+%
% \section{Introduction}
%
% The \pkg{snapshot} package helps the owner of a \LaTeX{} document
@@ -122,7 +134,6 @@
% \begin{verbatim}
% \RequirePackage[log]{snapshot}
% \end{verbatim}
-%
% Making the necessary arrangements to ensure that future \latex/
% runs of the document actually call in the specified versions is a
% separate problem. The \pkg{snapshot} package only provides a way to
@@ -333,7 +344,7 @@
% Standard declaration of package name and date.
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[1994/12/01]
-\ProvidesPackage{snapshot}[2012/08/06 v2.13]
+\ProvidesPackage{snapshot}[2020/06/17 v2.14]
% \end{macrocode}
%
% Calling the \pkg{snapshot} package in a document causes \latex/ to
@@ -367,11 +378,17 @@
% their documents.
% \end{minipage}\end{center}
%
+% \begin{macro}{\@xp}
+% \begin{macro}{\@nx}
% A couple of shorthand forms.
% \begin{macrocode}
\let\@xp=\expandafter \let\@nx=\noexpand
% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
+% \begin{macro}{\str@cmp}
+% \begin{macro}{\str@equal}
% A function to compare two strings and return FT or TT (for use with
% \cs{if}).
% \begin{macrocode}
@@ -382,6 +399,8 @@
\str@cmp#1\relax\str@cmp#2{\relax\@gobbletwo}\@nil TT%
}
% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\RequireVersions}
%
@@ -390,86 +409,219 @@
% \tex/ inputs path.
% \begin{macrocode}
\newcommand{\RequireVersions}[2][]{}%
+
\renewcommand{\RequireVersions}[1][]{%
- \def\snap@check{\snap@compare@versions}%
- \toks@{#1}\afterassignment\snap@storem
- \let\@let@token=
+ \def\snap@check{\snap@compare@versions}%
+ \toks@{#1}%
+ \afterassignment\snap@storem
+ \let\@let@token=
}
+
+\@onlypreamble\RequireVersions
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\snap@storem}
+% \begin{macrocode}
\def\snap@storem{%
- \ifx\@let@token\bgroup
- \else
- \PackageError{snapshot}{Expected a `\@charlb' character here}\@ehc
- \@xp\@gobblefour
- \fi
- \futurelet\@let@token\snap@branch
+ \ifx\@let@token\bgroup \else
+ \PackageError{snapshot}{Expected a `\@charlb' character here}\@ehc
+ \@xp\@gobblefour
+ \fi
+ \futurelet\@let@token\snap@branch
}
-\@onlypreamble\RequireVersions
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@check}
% \begin{macrocode}
\let\snap@check\@gobble
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@finish}
% \begin{macrocode}
\def\snap@finish{\toks@\bgroup}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@branch}
% \begin{macrocode}
\def\snap@branch{%
- \ifx\@let@token\egroup
- \@xp\snap@finish
- \else\ifx\@let@token *%
- \let\reserved@c\snap@store@version
- \else\ifx\@let@token\@sptoken
- \lowercase{\def\reserved@c} {\futurelet\@let@token\snap@branch}%
- \else
- \let\reserved@c\snap@store@error
- \fi\fi\fi
- \reserved@c
+ \ifx\@let@token\egroup
+ \@xp\snap@finish
+ \else\ifx\@let@token *%
+ \let\reserved@c\snap@store@version
+ \else\ifx\@let@token\@sptoken
+ \lowercase{\def\reserved@c} {\futurelet\@let@token\snap@branch}%
+ \else
+ \let\reserved@c\snap@store@error
+ \fi\fi\fi
+ \reserved@c
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@store@error}
% \begin{macrocode}
\def\snap@store@error#1{%
- \PackageError{snapshot}{Expected '*' here, not '#1'}\@ehc
+ \PackageError{snapshot}{Expected '*' here, not '#1'}\@ehc
}
+
\@onlypreamble\snap@store@error
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@store@version}
% \begin{macrocode}
\def\snap@store@version #1#2#3#4{%
- \@xp\snap@store@b\csname snapx@#2\endcsname{#2}{#3}{#4}%
+ \@xp\snap@store@b\csname snapx@#2\endcsname{#2}{#3}{#4}%
}
+
\@onlypreamble\snap@store@version
% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Determining the engine}
+%
+% \begin{macro}{\snapshotApplication}
+
+% Check for the engines that are active in \TeX Live 2020. Note
+% that in in modern versions of \TeX Live, there is no distinction
+% between \fn{etex}, \fn{pdfetex}, and \fn{pdftex}. I believe this
+% code will distinguish between distinct legacy binaries, but I
+% have not tested this thoroughly. Similar remarks apply to the
+% p\TeX\ family.
%
-% Detection of e-\LaTeX{}, pdf\LaTeX{}, pdfe\LaTeX{}, and Lambda
-% [Omega]:
% \begin{macrocode}
-\ifx\OmegaVersion\@@undefined
-\else
- \edef\snapshotApplication{%
- {Omega}\space\space\space
- {0000/00/00 v\OmegaVersion}%
- }%
-\fi
-\ifx\eTeXversion\@@undefined
-\else
- \edef\snapshotApplication{%
- {eTeX}\space\space\space\space
- {0000/00/00 v\number\eTeXversion\eTeXrevision}%
- }%
+\let\snapshotApplication\@empty
+
+\ifx\OmegaVersion\@@undefined \else
+ \edef\snapshotApplication{%
+ \ifx\AlephVersion\@@undefined
+ {Omega}\space\space\space
+ {0000/00/00 v\OmegaVersion}%
+ \else
+ {Aleph}\space\space\space
+% \end{macrocode}
+% \cs{AlephVersion} appears to be incorrectly set to 0.0, so
+% include the Omega version as well.
+% \begin{macrocode}
+ {0000/00/00 v\OmegaVersion-\AlephVersion}%
+ \fi
+ }%
\fi
-\ifx\pdftexversion\@@undefined
-\else
- \edef\snapshotApplication{%
- \ifx\eTeXversion\@@undefined
- {pdfTeX}\space\space
+
+\ifx\ptexversion\@@undefined\else
+ \edef\snapshotApplication{%
+ {pTeX}\space\space\space\space
+ {0000/00/00 v\number\ptexversion
+ \ifx\ptexminorversion\undefined \u \else.\number\ptexminorversion\fi
+ \ifx\ptexrevision\undefined \u \else\ptexrevision\fi}%
+ }%
+ \ifx\uptexversion\@@undefined
+ \ifx\epTeXversion\@@undefined\else
+ \edef\snapshotApplication{%
+ {epTeX}\space\space\space
+ {0000/00/00 v\number\epTeXversion}%
+ }%
+ \fi
\else
- {pdfeTeX}\space
+ \ifx\epTeXversion\@@undefined
+ \edef\snapshotApplication{%
+ {upTeX}\space\space\space
+ {0000/00/00 v\number\uptexversion
+ \ifx\uptexrevision\undefined \u \else\uptexrevision\fi}%
+ }%
+ \else
+% \end{macrocode}
+% There is no separate \cs{euptexversion}, so use a combination of
+% the underlying up\TeX\ and ep\TeX\ versions.
+% \begin{macrocode}
+ \edef\snapshotApplication{%
+ {eupTeX}\space\space
+ {0000/00/00 v\number\uptexversion
+ \ifx\uptexrevision\undefined \u \else\uptexrevision\fi
+ --\number\epTeXversion}%
+ }%
+ \fi
+ \fi
+\fi
+
+\ifx\snapshotApplication\@empty
+ \ifx\XeTeXversion\@@undefined\else
+ \edef\snapshotApplication{%
+ {XeTeX}\space\space\space
+ {0000/00/00 v\number\XeTeXversion
+ \ifx\XeTeXrevision\undefined\else\XeTeXrevision\fi}%
+ }%
+ \fi
+\fi
+
+\ifx\snapshotApplication\@empty
+ \ifx\luatexversion\@@undefined\else
+ \begingroup
+ \@tempcnta\luatexversion
+ \divide\@tempcnta by 100
+ \edef\@tempa{\the\@tempcnta}%
+ \multiply\@tempcnta by 100
+ \@tempcntb\luatexversion
+ \advance\@tempcntb by -\@tempcnta
+ \edef\@tempa{\@tempa.\the\@tempcntb.\luatexrevision}%
+ \xdef\snapshotApplication{%
+ {luaTeX}\space\space
+ {0000/00/00 v\@tempa}%
+ }%
+ \endgroup
+ \fi
+\fi
+
+\ifx\snapshotApplication\@empty
+ \ifx\pdftexversion\@@undefined \else
+ \begingroup
+ \ifx\eTeXversion\@@undefined
+ \@tempswafalse
+ \else
+ \@tempswatrue
+ \fi
+ \@tempcnta\pdftexversion
+ \divide\@tempcnta by 100
+ \edef\@tempa{\the\@tempcnta}%
+ \multiply\@tempcnta by 100
+ \@tempcntb\pdftexversion
+ \advance\@tempcntb by -\@tempcnta
+% \end{macrocode}
+% e\TeX\ was folded into pdf\TeX\ as of version 1.40.
+% \begin{macrocode}
+ \ifnum\@tempcntb > 39
+ \@tempswafalse
+ \fi
+ \edef\@tempa{\@tempa.\the\@tempcntb.\pdftexrevision}%
+ \xdef\snapshotApplication{%
+ \if@tempswa
+ {pdfeTeX}\space
+ \else
+ {pdfTeX}\space\space
+ \fi
+ {0000/00/00 v\@tempa}%
+ }%
+ \endgroup
+ \fi
+\fi
+
+\ifx\snapshotApplication\@empty
+ \ifx\eTeXversion\@@undefined \else
+ \edef\snapshotApplication{%
+ {eTeX}\space\space\space\space
+ {0000/00/00 v\number\eTeXversion
+ \ifx\eTeXrevision\undefined
+ \ifx\eTeXminorversion\undefined\else.\number\eTeXminorversion\fi
+ \else
+ \eTeXrevision
+ \fi
+ }%
+ }%
\fi
- {0000/00/00 v0.\number\pdftexversion\pdftexrevision}%
- }%
\fi
% \end{macrocode}
% If none of the above information is available, the exact version
@@ -477,13 +629,14 @@
% fall back to using a nominal date of 1990/03/25, which is when
% version 3.0 of \fn{tex.web} was released by Knuth.
% \begin{macrocode}
-\@ifundefined{snapshotApplication}{%
- \edef\snapshotApplication{%
- {TeX}\space\space\space\space\space
- {1990/03/25 v3.x}%
- }%
-}{}
+\ifx\snapshotApplication\@empty
+ \edef\snapshotApplication{%
+ {TeX}\space\space\space\space\space
+ {1990/03/25 v3.x}%
+ }%
+\fi
% \end{macrocode}
+% \end{macro}
%
% \begin{macrocode}
\def\@fmtextension{fmt}
@@ -499,57 +652,62 @@
\expandafter\let\csname snapx@-------\endcsname\snapx@end
% \end{macrocode}
%
+% \begin{macro}{\snap@store@b}
% For a package named \fn{foo.sty}, this function defines
% \cs{rqv@foo.sty} to hold the date and version information.
% \begin{macrocode}
\def\snap@store@b#1#2#3#4{%
- \ifx#1\snapx@end
- \@xp\snap@finish
- \else
- \ifx#1\relax \let#1\@empty\fi
- \def\@tempa##1 ##2 ##3\@nil{##1 ##2}%
+ \ifx#1\snapx@end
+ \@xp\snap@finish
+ \else
+ \ifx#1\relax \let#1\@empty\fi
+ \def\@tempa##1 ##2 ##3\@nil{##1 ##2}%
% \end{macrocode}
%
% \begin{macrocode}
- \ifx#1\snapx@application
- \@xp\xdef\csname rqv@#3#1\endcsname{\@tempa#4 v?.? ? \relax\@nil}%
- \else
- \xdef\rqv@list{\rqv@list{#3#1}}%
- \@xp\xdef\csname rqv@#3#1\endcsname{\@tempa#4 v?.? ? \relax\@nil}%
- \snap@intest{#3}{#1}%
- \ifx#1\snapx@format \snap@check{#3.fmt}%
+ \ifx#1\snapx@application
+ \@xp\xdef\csname rqv@#3#1\endcsname{\@tempa#4 v?.? ? \relax\@nil}%
+ \else
+ \xdef\rqv@list{\rqv@list{#3#1}}%
+ \@xp\xdef\csname rqv@#3#1\endcsname{\@tempa#4 v?.? ? \relax\@nil}%
+ \snap@intest{#3}{#1}%
+ \ifx#1\snapx@format \snap@check{#3.fmt}\else
% \end{macrocode}
% Test if current file is \fn{snapshot.sty}. Need to pre-expand the
% extension part to ensure the test is correct.
% \begin{macrocode}
- \else
- \edef\@tempa{\@nx\string@equal{snapshot.sty}{#3#1}}%
- \if\@tempa \snap@selfcheck \fi
- \fi
+ \edef\@tempa{\@nx\string@equal{snapshot.sty}{#3#1}}%
+ \if\@tempa \snap@selfcheck \fi
+ \fi
+ \fi
\fi
- \fi
- \futurelet\@let@token\snap@branch
+ \futurelet\@let@token\snap@branch
}
+
\@onlypreamble\snap@store@b
% \end{macrocode}
-% \end{macro}
+% \end{macro}
%
+% \begin{macro}{\snap@write}
% Default setup is geared to write the dependency list to a \fn{.dep}
% file. The option \opt{log} means write it to the \tex/ log instead.
% \begin{macrocode}
\def\snap@write{\immediate\write\snap@out}
\let\snap@out\sixt@@n % fallback, probably never used
% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Package options}
%
% \begin{macrocode}
\DeclareOption{dep}{%
- \def\snap@write{\immediate\write\snap@out}%
+ \def\snap@write{\immediate\write\snap@out}%
}
% \end{macrocode}
%
% \begin{macrocode}
\DeclareOption{log}{%
- \let\snap@write\typeout
+ \let\snap@write\typeout
}
% \end{macrocode}
%
@@ -577,32 +735,39 @@
% in the \fn{.dvi} file.
% \begin{macrocode}
\DeclareOption{tfm}{%
- \typeout{Option 'tfm' not implemented yet [1999/09/23]}%
+ \typeout{Option 'tfm' not implemented yet [1999/09/23]}%
}
% \end{macrocode}
%
-% Warnings and errors.
+% \subsubsection{Warnings and errors}
+% \begin{macro}{\snap@mismatch@warning}
+% \begin{macro}{\snap@mismatch}
% \begin{macrocode}
\def\snap@mismatch@warning#1#2#3{\PackageWarningNoLine{#1}{#2}}
\def\snap@mismatch{\snap@mismatch@warning}
% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
% \begin{macrocode}
\DeclareOption{error}{%
- \def\snap@mismatch{\PackageError}%
- \def\snap@selfcheck{\snap@selfcheck@a}%
- \ifx\snap@select\@empty \let\snap@select\snap@select@all \fi
+ \def\snap@mismatch{\PackageError}%
+ \def\snap@selfcheck{\snap@selfcheck@a}%
+ \ifx\snap@select\@empty \let\snap@select\snap@select@all \fi
}
% \end{macrocode}
%
% \begin{macrocode}
\DeclareOption{warning}{%
- \def\snap@mismatch{\snap@mismatch@warning}%
- \def\snap@selfcheck{\snap@selfcheck@a}%
- \ifx\snap@select\@empty \let\snap@select\snap@select@all \fi
+ \def\snap@mismatch{\snap@mismatch@warning}%
+ \def\snap@selfcheck{\snap@selfcheck@a}%
+ \ifx\snap@select\@empty \let\snap@select\snap@select@all \fi
}
% \end{macrocode}
%
+%
+% \begin{macro}{\snap@select@all}
+% \begin{macro}{\snap@select}
% Because the exact form of the version number is not mandated by
% \LaTeX{}, just take the first two ``words'' delimited by spaces.
% And take a little extra care to properly handle multiple spaces
@@ -611,7 +776,12 @@
\def\snap@select@all#1#2 #3#4 #5\@nil{#1#2 #3#4}
\let\snap@select\@empty
% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
+% \begin{macro}{\snap@seldate}
+% \begin{macro}{\snap@selversion}
+% \begin{macro}{\snap@selmajor}
% If the naming conventions seem a little peculiar here, it's because
% I had to add some pieces later that I didn't think of initially,
% and I wanted to minimize the chances of compatibility problems for
@@ -621,21 +791,31 @@
\def\snap@selversion#1#2 #3{\snap@select@version #3}%
\def\snap@selmajor#1#2 #3{\snap@select@major #3}%
% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macrocode}
\DeclareOption{date}{\let\snap@select=\snap@seldate}
% \end{macrocode}
%
+% \begin{macro}{\snap@select@version}
% \begin{macrocode}
\def\snap@select@version#1{%
\ifodd 0#11 \@xp\snap@sva\@xp#1\else\@xp\snap@select@version\fi
}
\def\snap@sva#1.#2 #3\@nil{#1.#2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\snap@select@major}
+% \begin{macrocode}
\def\snap@select@major#1{%
\ifodd 0#11 \@xp\snap@svm\@xp#1\else\@xp\snap@select@major\fi
}
\def\snap@svm#1.#2\@nil{#1}
% \end{macrocode}
+% \end{macro}
%
% \begin{macrocode}
\DeclareOption{version}{\let\snap@select\snap@selversion}
@@ -647,30 +827,34 @@
\DeclareOption{bbinfo}{\def\snap@bbinfo{00}}
% \end{macrocode}
%
+% \begin{macro}{\snap@splitter}
% Give this an inert definition, for the time being, until we are
% ready to do the split.
% \begin{macrocode}
\let\snap@splitter=?
\AtBeginDocument{%
- \xdef\@filelist{\@filelist\snap@splitter}%
+ \xdef\@filelist{\@filelist\snap@splitter}%
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@selfcheck}
% \begin{macrocode}
\let\snap@selfcheck\@empty
\let\snap@selfcheck@a\@empty
% \end{macrocode}
+% \end{macro}
%
% The \opt{self-warning} option would normally be used in conjunction
% with the \opt{error} option.
% \begin{macrocode}
\DeclareOption{self-warning}{%
- \def\snap@selfcheck{%
- \begingroup
- \def\snap@mismatch{\snap@mismatch@warning}%
- \snap@selfcheck@a
- \endgroup
- }
+ \def\snap@selfcheck{%
+ \begingroup
+ \def\snap@mismatch{\snap@mismatch@warning}%
+ \snap@selfcheck@a
+ \endgroup
+ }
}
% \end{macrocode}
%
@@ -679,16 +863,19 @@
\ProcessOptions\relax
% \end{macrocode}
%
+% \begin{macro}{\snap@restore@extensions}
% We need the following patch to make up for the fact that
% \cs{@pkgextension} and \cs{@clsextension} are marked in the \latex/
% kernel as \qq{only preamble}.
% \begin{macrocode}
\edef\snap@restore@extensions{%
- \def\@nx\@pkgextension{\@pkgextension}%
- \def\@nx\@clsextension{\@clsextension}%
+ \def\@nx\@pkgextension{\@pkgextension}%
+ \def\@nx\@clsextension{\@clsextension}%
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@pad}
% Pad filename strings out to 8+3 length so that the list will look
% pretty.
% \begin{macrocode}
@@ -696,7 +883,9 @@
\def\snap@pad@a#1#2#3#4#5\@nil{\snap@pad@b#1#2#3#4\space\@nil}
\def\snap@pad@b#1\space#2\@nil#3{\def#3{#2}}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@trim@version}
% First stage: discard leading spaces before the first and second
% nonspace strings in the argument. Take the first nonspace string as
% the date. Since we only do equal/not-equal testing on dates, it
@@ -716,6 +905,7 @@
% \begin{macrocode}
\def\snap@trim@c#1#2 #3\@nil{#2}
% \end{macrocode}
+% \end{macro}
%
% \begin{macrocode}
\let\rqv@list=\@empty
@@ -726,13 +916,14 @@
\edef\@tempc#1\fmtname{#1\fmtname}\@tempc
\def\@tempa#1,\fmtname.fmt,#2#3\@nil{#2}
\edef\@tempb{\@nx\@tempa,\@filelist,\fmtname.fmt,}
+
\if ?\@tempb?\@nil
- \edef\@filelist{\fmtname.fmt,\@filelist}%
- \def\@tempc{LaTeX2e}%
- \@xp\edef\csname ver@\fmtname.fmt\endcsname{%
- \fmtversion\space
- v\ifx\@tempc\fmtname 2.e\else ?.?\fi
- }%
+ \edef\@filelist{\fmtname.fmt,\@filelist}%
+ \def\@tempc{LaTeX2e}%
+ \@xp\edef\csname ver@\fmtname.fmt\endcsname{%
+ \fmtversion\space
+ v\ifx\@tempc\fmtname 2.e\else ?.?\fi
+ }%
\fi
% \end{macrocode}
% Ensure that files get recorded.
@@ -740,81 +931,100 @@
\listfiles
% \end{macrocode}
%
+% \begin{macro}{\snap@doit}
% \begin{macrocode}
\def\snap@doit#1{%
- \begingroup
- \ifx\delimiter#1\delimiter
- \else
- \filename@parse{#1}%
- \let\@tempd\@empty
- \ifx\filename@ext\relax
- \def\@tempa{file}\def\@tempb{~~~}%
- \else\ifx\filename@ext\@pkgextension
- \def\@tempa{package}\let\@tempb\@empty
- \else\ifx\filename@ext\@clsextension
- \def\@tempa{class}\def\@tempb{~~}%
- \else\ifx\filename@ext\@fmtextension
- \def\@tempa{format}\def\@tempb{~}%
- \else\ifx\filename@ext\@tfmextension
- \def\@tempa{tfm}\def\@tempb{~~~~}%
- \else
- \def\@tempa{file}\edef\@tempd{.\filename@ext}%
- \def\@tempb{~~~}%
- \fi\fi\fi\fi\fi
- \@xp\let\@xp\@tempe
- \csname ver@\filename@base %
- \ifx\filename@ext\relax\else.\filename@ext\fi\endcsname
- \ifx\@tempe\@empty \let\@tempe\relax \fi
- \edef\@tempe{%
- \ifx\@tempe\relax 0000/00/00 v0.0%
- \else
- \@xp\@xp\@xp\snap@trim@version\@xp\@tempe\space v0.0 v0.0 \@nil
- \fi
- }%
- \edef\@tempc{\filename@area\filename@base\@tempd}% full file name
- \@xp\snap@pad\@tempc\space~~~~~~~~~~~~~~~~\@nil\@tempd
- \let~\space
- \snap@write{\space\space *{\@tempa}\@tempb{\@tempc}\@tempd{\@tempe}}%
- \fi
- \aftergroup\snap@doit
- \endgroup
-}%
+ \begingroup
+ \ifx\delimiter#1\delimiter \else
+ \filename@parse{#1}%
+ \let\@tempd\@empty
+ \ifx\filename@ext\relax
+ \def\@tempa{file}\def\@tempb{~~~}%
+ \else\ifx\filename@ext\@pkgextension
+ \def\@tempa{package}\let\@tempb\@empty
+ \else\ifx\filename@ext\@clsextension
+ \def\@tempa{class}\def\@tempb{~~}%
+ \else\ifx\filename@ext\@fmtextension
+ \def\@tempa{format}\def\@tempb{~}%
+ \else\ifx\filename@ext\@tfmextension
+ \def\@tempa{tfm}\def\@tempb{~~~~}%
+ \else
+ \def\@tempa{file}%
+ \edef\@tempd{.\filename@ext}%
+ \def\@tempb{~~~}%
+ \fi\fi\fi\fi\fi
+ \@xp\let\@xp\@tempe
+ \csname ver@\filename@base %
+ \ifx\filename@ext\relax\else.\filename@ext\fi\endcsname
+ \ifx\@tempe\@empty \let\@tempe\relax \fi
+ \edef\@tempe{%
+ \ifx\@tempe\relax 0000/00/00 v0.0%
+ \else
+ \@xp\@xp\@xp\snap@trim@version\@xp\@tempe\space v0.0 v0.0 \@nil
+ \fi
+ }%
+ \edef\@tempc{\filename@area\filename@base\@tempd}% full file name
+ \@xp\snap@pad\@tempc\space~~~~~~~~~~~~~~~~\@nil\@tempd
+ \let~\space
+ \snap@write{\space\space *{\@tempa}\@tempb{\@tempc}\@tempd{\@tempe}}%
+ \fi
+ \aftergroup\snap@doit
+ \endgroup
+}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@bracify}
% \begin{macrocode}
\def\snap@bracify#1#2,{%
\ifx\@empty#1\expandafter\@gobble\else {#1#2}\fi \snap@bracify
}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\snap@splitter@a}
+% \begin{macrocode}
\def\snap@splitter@a{%
- \iffalse{{\fi }}% close current file name, end definition
- \xdef\specific@files{%
- \iffalse}\fi
- \specific@files
- \expandafter\@gobble\string % discard one closing brace
+ \iffalse{{\fi }}% close current file name, end definition
+ \xdef\specific@files{%
+ \iffalse}\fi
+ \specific@files
+ \expandafter\@gobble\string % discard one closing brace
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@fdcheck}
% \begin{macrocode}
\def\snap@fdcheck#1{%
- \ifx\delimiter#1\@xp\@gobble
- \else\snap@fda#1\@empty.fd\@empty ?\@nil
- \fi
- \snap@fdcheck
+ \ifx\delimiter#1%
+ \@xp\@gobble
+ \else
+ \snap@fda#1\@empty.fd\@empty ?\@nil
+ \fi
+ \snap@fdcheck
}
+
\def\snap@fda#1.fd\@empty#2#3\@nil{%
- \if ?#2%
- \xdef\specific@files{\specific@files {#1}}%
- \else
- \xdef\general@files{\general@files {#1.fd}}%
- \fi
+ \if ?#2%
+ \xdef\specific@files{\specific@files {#1}}%
+ \else
+ \xdef\general@files{\general@files {#1.fd}}%
+ \fi
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\general@files}
+% \begin{macro}{\specific@files}
% \begin{macrocode}
\let\general@files\@empty
\let\specific@files\@empty
% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
+% \begin{macro}{\SpecialInput}
% The \cn{SpecialInput} command is related to the \opt{packages-only}
% option. Apart from some ad hoc handling for \fn{.fd} files that get
% loaded on demand, all files that are input after
@@ -826,128 +1036,149 @@
% go in the specific-files list.
% \begin{macrocode}
\newcommand{\SpecialInput}[1]{%
- \xdef\specific@files{\specific@files{#1}}%
- \@@input#1\relax
+ \xdef\specific@files{\specific@files{#1}}%
+ \@@input#1\relax
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\@dofilelist}
% Our definition of \cs{@dofilelist} does not retain much resemblance
% to the original in the \LaTeX{} kernel.
% \begin{macrocode}
\def\@dofilelist{%
- \snap@restore@extensions
- \xdef\general@files{\@xp\snap@bracify \@filelist \@empty,\@empty,}%
- \let\snap@splitter\snap@splitter@a
- \xdef\general@files{\general@files}%
- \let\@tempa\specific@files \global\let\specific@files\@empty
- \@xp\snap@fdcheck\@tempa{\delimiter}%
- \ifx\rqv@list\@empty
- \else \rqv@compare@lists
- \fi
- \ifx\snap@write\typeout
- \else
- \newwrite\snap@out
- \immediate\openout\snap@out=\jobname.dep \relax
- \fi
- \snap@write{\string\RequireVersions\@charlb}%
- \snap@write{\space\space *{application}%
- \snapshotApplication
- }%
- \@xp\snap@doit\general@files{\delimiter\aftergroup\@gobble\@gobble}%
- \ifx\specific@files\@empty
- \else
- \snap@specific
- \fi
- \snap@write{\@charrb}%
- \ifx\snap@write\typeout
- \else \immediate\closeout\snap@out
- \typeout{Dependency list written on \jobname.dep.}%
- \fi
-}%
+ \snap@restore@extensions
+ \xdef\general@files{\@xp\snap@bracify \@filelist \@empty,\@empty,}%
+ \let\snap@splitter\snap@splitter@a
+ \xdef\general@files{\general@files}%
+ \let\@tempa\specific@files
+ \global\let\specific@files\@empty
+ \@xp\snap@fdcheck\@tempa{\delimiter}%
+ \ifx\rqv@list\@empty \else
+ \rqv@compare@lists
+ \fi
+ \ifx\snap@write\typeout \else
+ \newwrite\snap@out
+ \immediate\openout\snap@out=\jobname.dep \relax
+ \fi
+ \snap@write{\string\RequireVersions\@charlb}%
+ \snap@write{\space\space *{application}%
+ \snapshotApplication
+ }%
+ \@xp\snap@doit\general@files{\delimiter\aftergroup\@gobble\@gobble}%
+ \ifx\specific@files\@empty \else
+ \snap@specific
+ \fi
+ \snap@write{\@charrb}%
+ \ifx\snap@write\typeout \else
+ \immediate\closeout\snap@out
+ \typeout{Dependency list written on \jobname.dep.}%
+ \fi
+}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@specific}
% \begin{macrocode}
\def\snap@specific{%
- \snap@write{ \space *{-------}{Document-specific files:}{----}}%
- \@xp\snap@doit\specific@files{\delimiter\aftergroup\@gobble\@gobble}%
+ \snap@write{ \space *{-------}{Document-specific files:}{----}}%
+ \@xp\snap@doit\specific@files{\delimiter\aftergroup\@gobble\@gobble}%
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\rqv@condense}
% The \cs{rqv@compare@lists} function checks to see if any files
% are found only in the RequireVersions list or only in the
% \cs{general@files} list.
% \begin{macrocode}
\def\rqv@condense#1{%
- \@xp\ifx\csname ver@#1\endcsname\N
- \else
- \edef\L{\L{#1}}%
- \@xp\let\csname ver@#1\endcsname=\N
- \fi
- \rqv@condense
+ \@xp\ifx\csname ver@#1\endcsname\N \else
+ \edef\L{\L{#1}}%
+ \@xp\let\csname ver@#1\endcsname=\N
+ \fi
+ \rqv@condense
}
+
\def\rqv@condend{\endcsname ?\fi
- \@xp\@xp\@xp\@gobbletwo\csname @xp\iftrue}
+ \@xp\@xp\@xp\@gobbletwo\csname @xp\iftrue}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\rqv@overloaded}
% \begin{macrocode}
\def\rqv@overloaded#1{%
- \snap@mismatch{snapshot}{^^J%
- File #1 loaded though not in \noexpand\RequireVersions list%
- }\@ehc
+ \snap@mismatch{snapshot}{^^J%
+ File #1 loaded though not in \noexpand\RequireVersions list%
+ }\@ehc
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\rqv@notloaded}
% \begin{macrocode}
\def\rqv@notloaded#1{%
- \snap@mismatch{snapshot}{^^J%
- File #1 [\csname rqv@#1\endcsname] required but not loaded%
- }\@ehc
+ \snap@mismatch{snapshot}{^^J%
+ File #1 [\csname rqv@#1\endcsname] required but not loaded%
+ }\@ehc
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\rqv@set}
+% \begin{macro}{\rqv@test}
% \begin{macrocode}
\def\rqv@set#1{\@xp\let\csname ver@#1\endcsname\N \rqv@set}
\def\rqv@test#1{\csname ver@#1\endcsname{#1}\rqv@test}
% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
+% \begin{macro}{\rqv@compare@lists}
% \begin{macrocode}
\def\rqv@compare@lists{%
- \begingroup
+ \begingroup
% \end{macrocode}
% Clear up duplicate file names (just in case) to avoid redundant
% warning messages. This should seldom be necessary in practice.
% \begin{macrocode}
- \def\N{1}\let\L\@empty
- \@xp\rqv@condense\rqv@list\rqv@condend
- \global\let\rqv@list=\L
- \def\N{2}\let\L\@empty
- \@xp\rqv@condense\general@files\rqv@condend
- \global\let\general@files=\L
+ \def\N{1}%
+ \let\L\@empty
+ \@xp\rqv@condense\rqv@list\rqv@condend
+ \global\let\rqv@list=\L
+ \def\N{2}%
+ \let\L\@empty
+ \@xp\rqv@condense\general@files\rqv@condend
+ \global\let\general@files=\L
% \end{macrocode}
% Let's make a shorthand for the code that terminates our recursion.
% \begin{macrocode}
- \def\T{\@firstoftwo{\endcsname\@empty\@gobbletwo}}%
+ \def\T{\@firstoftwo{\endcsname\@empty\@gobbletwo}}%
% \end{macrocode}
% Set all the loaded general files to an error function.
% \begin{macrocode}
- \let\N\rqv@overloaded \@xp\rqv@set\general@files \T
+ \let\N\rqv@overloaded \@xp\rqv@set\general@files \T
% \end{macrocode}
% Set all the required files to an ignore function.
% \begin{macrocode}
- \let\N\@gobble \@xp\rqv@set\rqv@list \T
+ \let\N\@gobble
+ \@xp\rqv@set\rqv@list \T
% \end{macrocode}
% Execute all the general files.
% \begin{macrocode}
- \@xp\rqv@test\general@files{\endcsname\csname @gobbletwo}%
+ \@xp\rqv@test\general@files{\endcsname\csname @gobbletwo}%
% \end{macrocode}
% And now do essentially the same thing in the reverse direction.
% \begin{macrocode}
- \let\N\rqv@notloaded \@xp\rqv@set\rqv@list \T
- \let\N\@gobble \@xp\rqv@set\general@files \T
- \@xp\rqv@test\rqv@list{\endcsname\csname @gobbletwo}%
- \endgroup
+ \let\N\rqv@notloaded
+ \@xp\rqv@set\rqv@list \T
+ \let\N\@gobble
+ \@xp\rqv@set\general@files \T
+ \@xp\rqv@test\rqv@list{\endcsname\csname @gobbletwo}%
+ \endgroup
}
% \end{macrocode}
+% \end{macro}
%
% Compensate for a bug in old versions of \fn{amsgen.sty}. This is a
% little tricky.
@@ -958,13 +1189,14 @@
% \begin{macrocode}
%\@namedef{ver@amsgen.sty}{1996/10/29 v1.2b}
\AtBeginDocument{%
- \@ifundefined{ver@amsgen}{}{%
- \@xp\let\csname ver@amsgen.sty\@xp\endcsname
- \csname ver@amsgen\endcsname
- }%
+ \@ifundefined{ver@amsgen}{}{%
+ \@xp\let\csname ver@amsgen.sty\@xp\endcsname
+ \csname ver@amsgen\endcsname
+ }%
}
% \end{macrocode}
%
+% \begin{macro}{\ProvidesFile}
% Because \cs{ProvidesFile} is used in \fn{.fd} files which are
% normally read with special catcodes, there tend to
% be problems with whitespace characters being erroneously lost from
@@ -973,10 +1205,10 @@
% affected some older versions of \latex/.
% \begin{macrocode}
\def\ProvidesFile#1{%
- \def\snap@checker{\snap@check{#1}}%
- \begingroup
- \aftergroup\snap@checker
- \catcode`\ 10
+ \def\snap@checker{\snap@check{#1}}%
+ \begingroup
+ \aftergroup\snap@checker
+ \catcode`\ 10
% \end{macrocode}
% Added guards from 2001/06/01 version of \latex/. These are
% necessary because, for example, \pkg{inputenc} sets
@@ -984,17 +1216,19 @@
% reading input encoding files. The guards prevent an ``invalid
% character'' error.
% \begin{macrocode}
- \ifnum\endlinechar < 256
- \ifnum \endlinechar>\m@ne
- \catcode\endlinechar 10
+ \ifnum\endlinechar < 256
+ \ifnum \endlinechar>\m@ne
+ \catcode\endlinechar 10
+ \fi
\fi
- \fi
- \@makeother\/%
- \@makeother\&%
- \kernel@ifnextchar[{\snap@providesfile{#1}}{\snap@providesfile{#1}[]}%
+ \@makeother\/%
+ \@makeother\&%
+ \kernel@ifnextchar[{\snap@providesfile{#1}}{\snap@providesfile{#1}[]}%
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@graphic@test}
% Normally the string found in the second arg of \cs{ProvidesFile}
% (for a nongraphics file) would begin with the usual date string.
% The \cs{includegraphics} command, however, begins the second arg
@@ -1005,18 +1239,29 @@
% \begin{macrocode}
\def\snap@graphic@test#1#2#3\@nil{r\if G#1#2\else X\fi}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@providesfile}
% \begin{macrocode}
\def\snap@providesfile#1[#2]{%
- \wlog{File: #1 #2}%
- \if\snap@graphic@test#2@@\@nil
- \snap@record@graphic#1\relax #2 (type ??)\@nil
- \else
- \expandafter\xdef\csname ver@#1\endcsname{#2}%
- \fi
- \endgroup
+ \wlog{File: #1 #2}%
+% \end{macrocode}
+% Adopt a suggestion made by user egrep on the \TeX\ stack exchange
+% (\url{https://tex.stackexchange.com/questions/508985}) but
+% without the use of the \cs{expanded} extension. This makes it
+% more likely that \pkg{snapshot} can deal with macros inside the
+% optional arguments of \cs{Provides...} commands.
+% \begin{macrocode}
+ \edef\@tempa{#2}%
+ \if\@xp\snap@graphic@test\@tempa @@\@nil
+ \snap@record@graphic#1\relax #2 (type ??)\@nil
+ \else
+ \@xp\xdef\csname ver@#1\endcsname{#2}%
+ \fi
+ \endgroup
}
% \end{macrocode}
+% \end{macro}
%
% This is what \cn{includegraphics} does to record graphic file
% information.
@@ -1028,77 +1273,90 @@
%#2<-Graphic file (type eps)
%\end{verbatim}
%
+% \begin{macro}{\snap@record@graphic}
% Check the graphics info.
% \begin{macrocode}
\def\snap@record@graphic#1\relax #2(type #3)#4\@nil{%
- \expandafter\xdef\csname ver@#1\endcsname{%
- Graphic%
- \if\snap@bbinfo :bb=\Gin@llx/\Gin@lly/\Gin@urx/\Gin@ury\fi
- \space v0.0%
- }%
+ \expandafter\xdef\csname ver@#1\endcsname{%
+ Graphic%
+ \if\snap@bbinfo :bb=\Gin@llx/\Gin@lly/\Gin@urx/\Gin@ury\fi
+ \space v0.0%
+ }%
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\@pr@videpackage}
% \begin{macrocode}
\def\@pr@videpackage [#1]{%
- \expandafter\xdef\csname ver@\@currname.\@currext\endcsname{#1}%
- \ifx\@currext\@clsextension
- \typeout{Document Class: \@gtempa\space#1}%
- \else
- \wlog{Package: \@gtempa\space#1}%
- \fi
- \snap@check{\@currname.\@currext}%
+ \expandafter\xdef\csname ver@\@currname.\@currext\endcsname{#1}%
+ \ifx\@currext\@clsextension
+ \typeout{Document Class: \@gtempa\space#1}%
+ \else
+ \wlog{Package: \@gtempa\space#1}%
+ \fi
+ \snap@check{\@currname.\@currext}%
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@selfcheck@a}
% \begin{macrocode}
\def\snap@selfcheck@a{\snap@check{snapshot.sty}}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\@nofmt}
% \begin{macrocode}
\def\@nofmt#1.fmt.#2 {#1 }
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@mismatch@a}
% \begin{macrocode}
\def\snap@mismatch@a#1#2#3{%
- \snap@mismatch{snapshot}{^^J%
- \space\space Required version #2 of \@nofmt#1.fmt. and^^J%
- \space\space provided version #3 do not match%
- }\@ehc
+ \snap@mismatch{snapshot}{^^J%
+ \space\space Required version #2 of \@nofmt#1.fmt. and^^J%
+ \space\space provided version #3 do not match%
+ }\@ehc
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@compare@versions}
% When comparing \cs{rqv@foo.sty} (information from a previous
% \latex/ run) with \cs{ver@foo.sty} (information from current run),
% we first call \cs{snap@trim@version} on the latter to clear away
% any idiosyncrasies in the contents.
% \begin{macrocode}
\def\snap@compare@versions#1{%
- \begingroup
- \@ifundefined{rqv@#1}{}{%
- \edef\0{\csname rqv@#1\endcsname}%
- \edef\1{\csname ver@#1\endcsname}%
- \edef\1{\@xp\snap@trim@version\1 v0.0 v0.0 \@nil}%
- \edef\@tempa{\@xp\snap@select\0 v0.0 v0.0 \@nil}%
- \edef\@tempb{\@xp\snap@select\1 v0.0 v0.0 \@nil}%
- \ifx\@tempa\@tempb
- \else
- \edef\@tempd{\@nx\snap@mismatch@a{#1}{\@tempa}{\@tempb}}%
- \@xp\@tempd
- \fi
- }%
- \endgroup
+ \begingroup
+ \@ifundefined{rqv@#1}{}{%
+ \edef\0{\csname rqv@#1\endcsname}%
+ \edef\1{\csname ver@#1\endcsname}%
+ \edef\1{\@xp\snap@trim@version\1 v0.0 v0.0 \@nil}%
+ \edef\@tempa{\@xp\snap@select\0 v0.0 v0.0 \@nil}%
+ \edef\@tempb{\@xp\snap@select\1 v0.0 v0.0 \@nil}%
+ \ifx\@tempa\@tempb \else
+ \edef\@tempd{\@nx\snap@mismatch@a{#1}{\@tempa}{\@tempb}}%
+ \@xp\@tempd
+ \fi
+ }%
+ \endgroup
% \end{macrocode}
% When the \opt{test} option is in effect, jump out of the current
% file instead of continuing.
% \begin{macrocode}
- \snap@test@abort
+ \snap@test@abort
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@test@abort}
% \begin{macrocode}
\let\snap@test@abort=\@empty
% \end{macrocode}
+% \end{macro}
%
% \section{Compatibility}
%
@@ -1122,8 +1380,8 @@
%
% \begin{macrocode}
\ifx\snap@select\@empty
- \let\snap@compare@versions\@gobble
- \let\snap@check\@gobble
+ \let\snap@compare@versions\@gobble
+ \let\snap@check\@gobble
\fi
% \end{macrocode}
%
@@ -1155,13 +1413,13 @@
% \begin{macrocode}
\def\restore@some@catcodes{}
\def\save@some@catcodes{%
- \edef\restore@some@catcodes{%
- \catcode\number`\@=\number\catcode`\@
- \catcode\number`\"=\number\catcode`\"
- \catcode\number`\^=\number\catcode`\^
- \catcode\number`\_=\number\catcode`\_
- \relax
- }%
+ \edef\restore@some@catcodes{%
+ \catcode\number`\@=\number\catcode`\@
+ \catcode\number`\"=\number\catcode`\"
+ \catcode\number`\^=\number\catcode`\^
+ \catcode\number`\_=\number\catcode`\_
+ \relax
+ }%
}
% \end{macrocode}
%
@@ -1187,82 +1445,99 @@
% executed and that the \cs{if@compatibility} switch got set
% accordingly.
%
+% \begin{macro}{\snap@intest}
% \begin{macrocode}
\def\snap@intest#1#2{%
- \message{^^J}%
- \begingroup \edef\0{#1#2}\def\9{latex209.def}%
- \ifx\0\9\global\@compatibilitytrue \fi
- \ifx#2\snapx@format
+ \message{^^J}%
+ \begingroup
+ \edef\0{#1#2}%
+ \def\9{latex209.def}%
+ \ifx\0\9\global\@compatibilitytrue \fi
+ \ifx#2\snapx@format
% \end{macrocode}
% If arg1 + arg2 = ``LaTeX2e.fmt'', the calling function
% \cs{snap@storeb} will run \cs{snap@check} separately.
% This is a crude way of making things work in that case without
% much extra trouble.
% \begin{macrocode}
- \def\snap@test@abort{\endgroup}%
- \else
- \edef\N{%
- \noexpand\snap@intest@b{#1#2}%
- {#1}{\@xp\@gobble#2\@empty}%
- {\csname rqv@#1#2\endcsname}}%
- \expandafter\endgroup\N
- \fi
+ \def\snap@test@abort{\endgroup}%
+ \else
+ \edef\N{%
+ \noexpand\snap@intest@b{#1#2}%
+ {#1}{\@xp\@gobble#2\@empty}%
+ {\csname rqv@#1#2\endcsname}}%
+ \expandafter\endgroup\N
+ \fi
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@intest@b}
% \begin{macrocode}
\def\snap@intest@b#1#2#3#4{%
- \def\@currname{#2}\def\@currext{#3}%
- \begingroup \lccode`\/=`\0\relax\lowercase{\endgroup
- \ifnum\snap@seldate#4 00 0\@nil>\z@
- }% matches \lowercase
- \save@some@catcodes
- \@@input #1 \relax
- \restore@some@catcodes
- \else
- \snap@specialtest{#1}{#4}%
- \fi
+ \def\@currname{#2}%
+ \def\@currext{#3}%
+ \begingroup
+ \lccode`\/=`\0\relax\lowercase{\endgroup
+ \ifnum\snap@seldate#4 00 0\@nil>\z@
+ }% matches \lowercase
+ \save@some@catcodes
+ \@@input #1 \relax
+ \restore@some@catcodes
+ \else
+ \snap@specialtest{#1}{#4}%
+ \fi
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\snap@specialtest}
% \begin{macrocode}
\def\snap@specialtest#1#2{%
- \fake@input{#1}%
+ \fake@input{#1}%
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\fake@input}
% \begin{macrocode}
\def\fake@input#1{%
- \begingroup
- % Ensure that outer \foo or unmatched braces don't trip us up
- \catcode`\\=12 \catcode`\{=12 \catcode`\}=12
- \endinput
+ \begingroup
+ % Ensure that outer \foo or unmatched braces don't trip us up
+ \catcode`\\=12
+ \catcode`\{=12
+ \catcode`\}=12
+ \endinput
% \end{macrocode}
% Note that these definitions of \cs{G} and \cs{?} are local, and
% recall that one-letter cs names don't use up hash table entries.
% \begin{macrocode}
- \def\G{\@car\endgroup}%
- \expandafter\futurelet\expandafter\?\expandafter\G\@@input#1 \relax\@nil
+ \def\G{\@car\endgroup}%
+ \expandafter\futurelet\expandafter\?\expandafter\G\@@input#1 \relax\@nil
}
% \end{macrocode}
+% \end{macro}
%
% \begin{macrocode}
\let\snap@test@abort=\endinput
\let\snap@selfcheck=\@empty
% \end{macrocode}
%
+% \begin{macro}{\snap@finish}
% There's an extra close-brace left hanging around at the end, but I
% guess we don't care.
% \begin{macrocode}
\def\snap@finish{%%
- \endgroup \message{^^J}%
- \def\X##1{##1,\X}%
- \edef\@filelist{\@xp\X\rqv@list{\@gobbletwo}}%
- \def\X##1,?{##1}\edef\@filelist{\@xp\X\@filelist ?}%
- \@dofilelist
- \@@end
-}%
+ \endgroup
+ \message{^^J}%
+ \def\X##1{##1,\X}%
+ \edef\@filelist{\@xp\X\rqv@list{\@gobbletwo}}%
+ \def\X##1,?{##1}\edef\@filelist{\@xp\X\@filelist ?}%
+ \@dofilelist
+ \@@end
+}
% \end{macrocode}
+% \end{macro}
%
% \begin{macrocode}
\def\snap@mismatch#1#2#3{}
@@ -1273,25 +1548,24 @@
% \cs{ProvidesFile} at all.
% \begin{macrocode}
\renewcommand{\RequireVersions}[2][]{%
- \begingroup
- \makeatletter
- \def\snap@check{\snap@compare@versions}%%
- \let\snapx@tfm=\snap@ignore
+ \begingroup
+ \makeatletter
+ \def\snap@check{\snap@compare@versions}%%
+ \let\snapx@tfm=\snap@ignore
% \end{macrocode}
% This seems to help, with english.ldf for example, to prevent an
% endless loop when attempting to load babel.def.
% \begin{macrocode}
- \def\ProvidesLanguage##1{\ProvidesFile{##1.ldf}}%
- \iffalse{\fi \futurelet\@let@token\snap@branch #2}%
- \endgroup
+ \def\ProvidesLanguage##1{\ProvidesFile{##1.ldf}}%
+ \iffalse{\fi \futurelet\@let@token\snap@branch #2}%
+ \endgroup
}
% \end{macrocode}
%
+% \section{Finale}
+%
% The usual \cs{endinput} to ensure that random garbage at the end of
% the file doesn't get copied by \fn{docstrip}.
% \begin{macrocode}
\endinput
% \end{macrocode}
-%
-% \CheckSum{1209}
-% \Finale
diff --git a/macros/latex/contrib/snapshot/snapshot.ins b/macros/latex/contrib/snapshot/snapshot.ins
index 262760e4c9..289c09b82c 100644
--- a/macros/latex/contrib/snapshot/snapshot.ins
+++ b/macros/latex/contrib/snapshot/snapshot.ins
@@ -1,6 +1,6 @@
%% filename: snapshot.ins
-%% version: 1.00
-%% date: 2010/08/13
+%% version: 1.01
+%% date: 2020/06/16
%%
%% American Mathematical Society
%% Technical Support
@@ -13,7 +13,7 @@
%% fax: (401) 331-3842
%% email: tech-support@ams.org
%%
-%% Copyright 2010 American Mathematical Society.
+%% Copyright 2010, 2020 American Mathematical Society.
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3c
@@ -38,7 +38,7 @@
\preamble
-Copyright 2001, 2004, 2006, 2007, 2010, 2012 American Mathematical Society.
+Copyright 1999-2003, 2004, 2010, 2012, 2020 American Mathematical Society.
American Mathematical Society
Technical Support
diff --git a/macros/latex/contrib/snapshot/snapshot.pdf b/macros/latex/contrib/snapshot/snapshot.pdf
index 0dfa0f13f6..45cc249e31 100644
--- a/macros/latex/contrib/snapshot/snapshot.pdf
+++ b/macros/latex/contrib/snapshot/snapshot.pdf
Binary files differ