summaryrefslogtreecommitdiff
path: root/macros/latex/contrib
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-06-18 03:01:13 +0000
committerNorbert Preining <norbert@preining.info>2021-06-18 03:01:13 +0000
commit3ecc00c27119bc47ba26b518b7d26c00b69599df (patch)
treedb60a75c06403ca74ed76bc3339d80958159ae3e /macros/latex/contrib
parent5f3280db1e6f333f79e9930e5609d3f5175d5af7 (diff)
CTAN sync 202106180301
Diffstat (limited to 'macros/latex/contrib')
-rw-r--r--macros/latex/contrib/bjfuthesis/README.md10
-rw-r--r--macros/latex/contrib/docassembly/README.md23
-rw-r--r--macros/latex/contrib/docassembly/aeb_pro.js177
-rw-r--r--macros/latex/contrib/docassembly/docassembly.dtx510
-rw-r--r--macros/latex/contrib/docassembly/docassembly.ins59
-rw-r--r--macros/latex/contrib/docassembly/docs/docassembly.pdfbin0 -> 335594 bytes
-rw-r--r--macros/latex/contrib/docassembly/docs/install_jsfiles.pdfbin0 -> 189663 bytes
-rw-r--r--macros/latex/contrib/docassembly/docs/install_jsfiles.tex325
-rw-r--r--macros/latex/contrib/docassembly/examples/attach-files.tex31
-rw-r--r--macros/latex/contrib/docassembly/examples/certifyinvisible.pdfbin0 -> 135837 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/certifyinvisible.tex151
-rw-r--r--macros/latex/contrib/docassembly/examples/create-templates.tex66
-rw-r--r--macros/latex/contrib/docassembly/examples/doc-saveas.tex27
-rw-r--r--macros/latex/contrib/docassembly/examples/extract-pages.tex24
-rw-r--r--macros/latex/contrib/docassembly/examples/graphics/AdobeDon-btn.pdfbin0 -> 80868 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/graphics/AdobeDon.pdfbin0 -> 85289 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/graphics/AdobeDonIcon.pdfbin0 -> 78327 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/graphics/AeB_Logo.pdfbin0 -> 34683 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/graphics/girl.pdfbin0 -> 415673 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/graphics/man1.pdfbin0 -> 416225 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/graphics/scot.pdfbin0 -> 409204 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/import-icons.tex56
-rw-r--r--macros/latex/contrib/docassembly/examples/import-sound.tex24
-rw-r--r--macros/latex/contrib/docassembly/examples/insert-pages.tex20
-rw-r--r--macros/latex/contrib/docassembly/examples/mail-doc.tex31
-rw-r--r--macros/latex/contrib/docassembly/examples/open-doc.tex34
-rw-r--r--macros/latex/contrib/docassembly/examples/resources/myStory.pdfbin0 -> 34655 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/resources/supportDoc.pdfbin0 -> 7358 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/sign.pdfbin0 -> 171458 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/sign.tex206
-rw-r--r--macros/latex/contrib/docassembly/examples/sounds/trek.wavbin0 -> 89864 bytes
-rw-r--r--macros/latex/contrib/docassembly/examples/watermark-file.tex25
-rw-r--r--macros/latex/contrib/docassembly/examples/watermark-text.tex26
-rw-r--r--macros/latex/contrib/easybook/easybook.dtx79
-rw-r--r--macros/latex/contrib/easybook/easybook.pdfbin333334 -> 334646 bytes
-rw-r--r--macros/latex/contrib/gs1/GS1.dtx120
-rw-r--r--macros/latex/contrib/gs1/GS1.pdfbin672475 -> 727465 bytes
-rw-r--r--macros/latex/contrib/gs1/README.distributors10
-rw-r--r--macros/latex/contrib/gs1/rule-D.dtx31
-rw-r--r--macros/latex/contrib/gs1/rule-D.pdfbin396465 -> 428683 bytes
-rw-r--r--macros/latex/contrib/msu-thesis/README.md4
-rw-r--r--macros/latex/contrib/msu-thesis/msu-thesis.cls186
-rw-r--r--macros/latex/contrib/msu-thesis/msu-thesis.pdfbin222407 -> 224666 bytes
-rw-r--r--macros/latex/contrib/msu-thesis/msu-thesis.tex52
-rw-r--r--macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.pdfbin55385 -> 0 bytes
-rw-r--r--macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.tex55
-rw-r--r--macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdfbin199924 -> 196098 bytes
-rw-r--r--macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.tex36
-rw-r--r--macros/latex/contrib/ocgx2/ChangeLog4
-rw-r--r--macros/latex/contrib/ocgx2/ocgx2.sty2272
-rw-r--r--macros/latex/contrib/projlib/ProjLib-doc-cn.pdfbin226031 -> 226676 bytes
-rw-r--r--macros/latex/contrib/projlib/ProjLib-doc-cn.tex38
-rw-r--r--macros/latex/contrib/projlib/ProjLib-doc-en.pdfbin142661 -> 141933 bytes
-rw-r--r--macros/latex/contrib/projlib/ProjLib-doc-en.tex40
-rw-r--r--macros/latex/contrib/projlib/ProjLib.dtx117
-rw-r--r--macros/latex/contrib/projlib/ProjLib.ins2
-rw-r--r--macros/latex/contrib/projlib/README.md12
-rw-r--r--macros/latex/contrib/siunitx/CHANGELOG.md31
-rw-r--r--macros/latex/contrib/siunitx/siunitx-code.pdfbin1486326 -> 1489673 bytes
-rw-r--r--macros/latex/contrib/siunitx/siunitx-complex.dtx72
-rw-r--r--macros/latex/contrib/siunitx/siunitx-compound.dtx2
-rw-r--r--macros/latex/contrib/siunitx/siunitx-locale.dtx2
-rw-r--r--macros/latex/contrib/siunitx/siunitx-number.dtx13
-rw-r--r--macros/latex/contrib/siunitx/siunitx-quantity.dtx22
-rw-r--r--macros/latex/contrib/siunitx/siunitx-symbol.dtx42
-rw-r--r--macros/latex/contrib/siunitx/siunitx-table.dtx14
-rw-r--r--macros/latex/contrib/siunitx/siunitx-table.pdfbin475888 -> 0 bytes
-rw-r--r--macros/latex/contrib/siunitx/siunitx-unit.dtx8
-rw-r--r--macros/latex/contrib/siunitx/siunitx.dtx15
-rw-r--r--macros/latex/contrib/siunitx/siunitx.pdfbin634773 -> 635013 bytes
-rw-r--r--macros/latex/contrib/siunitx/siunitx.tex23
71 files changed, 3610 insertions, 1517 deletions
diff --git a/macros/latex/contrib/bjfuthesis/README.md b/macros/latex/contrib/bjfuthesis/README.md
index d93e2fa758..173951390f 100644
--- a/macros/latex/contrib/bjfuthesis/README.md
+++ b/macros/latex/contrib/bjfuthesis/README.md
@@ -1,7 +1,7 @@
# 北京林业大学 (BJFU) 毕业论文模板 (LaTeX)
Copyright (C) 2021 Liu Changxin
-Version 1.0.5 (2021-06-15)
+Version 1.1.0 (2021-06-17)
## Abstract
This is a class file for producing dissertations and theses according to the Beijing Forestry University (BJFU) Guidelines for Undergraduate Theses and Dissertations.
@@ -15,7 +15,7 @@ bjfuthesis是北京林业大学 (BJFU) 毕业生撰写毕业论文使用的LaTeX
注:虽然同时包含了.lyx文件与.tex文件,但.tex文件不再更新,只起示例作用。推荐使用LyX。
1. 下载并安装MiKTeX:https://miktex.org/download
1. 下载并安装LyX:https://www.lyx.org/Download
-1. (可选)导入bjfuthesis.layout
+1. 导入bjfuthesis.layout
1. 将bjfuthesis.layout文件复制至&lt;LyX安装目录&gt;/Resources/layouts中
1. LyX中点击 工具 -> 重新配置 LyX
1. 重新启动LyX
@@ -35,7 +35,5 @@ You may obtain a copy of the License at
https://www.gnu.org/licenses/gpl-3.0.html
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License. \ No newline at end of file
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and limitations under the License. \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/README.md b/macros/latex/contrib/docassembly/README.md
new file mode 100644
index 0000000000..56dd576cc8
--- /dev/null
+++ b/macros/latex/contrib/docassembly/README.md
@@ -0,0 +1,23 @@
+docassembly
+Dated: 2021-06-11
+Author: D. P. Story
+
+Targeted audience: LaTeX authors who love their pdflatex, lualtex, xelatex,
+or dvips -> ps2pdf workflow, who also own Acrobat Pro application.
+
+The docassembly package defines the docassembly environment in which
+JavaScript code can be written to execute once and only once the newly
+created PDF in the Acrobat application. The package also defines a series of
+helper commands to execute security restricted JavaScript methods. Using
+these security restricted commands, you can place watermarks on the document,
+attached files, import icons and sounds, insert pages, extract pages, send
+email, and so on. All these methods I have used for years through the aeb_pro
+package, which generally restricted to a dvips -> distiller workflow. Now,
+these methods are available to all those who own Acrobat, no matter what PDF
+creator used.
+
+Now, I simply must get back to my retirement.
+
+D. P. Story
+dpstory@acrotex.net
+
diff --git a/macros/latex/contrib/docassembly/aeb_pro.js b/macros/latex/contrib/docassembly/aeb_pro.js
new file mode 100644
index 0000000000..5dbfe4d53a
--- /dev/null
+++ b/macros/latex/contrib/docassembly/aeb_pro.js
@@ -0,0 +1,177 @@
+/*
+ AEB Pro Document Assembly Methods
+
+ Copyright (C) 2012 -- 2021 AcroTeX.Net
+ D. P. Story
+ http://www.acrotex.net
+
+ Version 1.6.1
+
+ v1.6.1 aebCreateTemplate now returns an object
+ v1.6 Added aebAddWatermarkFromText, aebLaunchURL
+ v1.5 Added aebCertifyInvisibleSign
+*/
+
+if ( typeof aebTrustedFunctions == "undefined") {
+ aebTrustedFunctions = app.trustedFunction( function ( doc, oFunction, oArgs )
+ {
+ app.beginPriv();
+ var retn = oFunction( oArgs, doc );
+ app.endPriv();
+ return retn;
+ });
+}
+aebAddWatermarkFromFile = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebAddWatermarkFromFile.msg==undefined)?("Add Watermark from File Error: " + e.toString()):aebAddWatermarkFromFile.msg;}
+ app.beginPriv();
+ try { doc.addWatermarkFromFile(oArgs); } catch(e) {console.println(Msg(e));}
+ app.endPriv();
+ aebAddWatermarkFromFile.msg=undefined;
+});
+aebAddWatermarkFromText = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.addWatermarkFromText(oArgs);
+ app.endPriv();
+});
+aebImportIcon = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.importIcon(oArgs);
+ app.endPriv();
+});
+aebInsertPages = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebInsertPages.msg==undefined)?("Insert Pages Error: " + e.toString()):aebInsertPages.msg;}
+ app.beginPriv();
+ try { doc.insertPages(oArgs); } catch(e) {console.println(Msg(e));}
+ app.endPriv();
+ aebInsertPages.msg=undefined;
+})
+aebAppOpenDoc = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebAppOpenDoc.msg==undefined)?("App Open Doc Error: " + e.toString()):aebAppOpenDoc.msg;}
+ app.beginPriv();
+ try { return app.openDoc(oArgs); } catch(e) {console.println(Msg(e));}
+ app.endPriv();
+ aebAppOpenDoc.msg=undefined;
+ return retn;
+})
+aebImportTextData = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.importTextData(oArgs);
+ app.endPriv();
+});
+aebImportSound = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.importSound(oArgs);
+ app.endPriv();
+});
+aebSaveAs = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ app.execMenuItem("Save");
+ app.endPriv();
+});
+aebDocSaveAs = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebDocSaveAs.msg==undefined)?("Doc SaveAs Error: " + e.toString()):aebDocSaveAs.msg;}
+ app.beginPriv();
+ try {
+ return doc.saveAs(oArgs);
+ } catch(e){console.println(Msg(e));}
+ app.endPriv();
+ aebDocSaveAs.msg=undefined;
+
+});
+aebExtractPages = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.extractPages(oArgs);
+ app.endPriv();
+});
+aebMailDoc = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.mailDoc(oArgs);
+ app.endPriv();
+});
+aebImportDataObject = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.importDataObject(oArgs);
+ app.endPriv();
+});
+aebSignatureSign = app.trustPropagatorFunction( function ( oArgs, field )
+{
+ app.beginPriv();
+ return field.signatureSign(oArgs);
+ app.endPriv();
+});
+aebSecurityHandlerLogin = app.trustPropagatorFunction( function ( oArgs, securityHandler )
+{
+ app.beginPriv();
+ return securityHandler.login(oArgs);
+ app.endPriv();
+});
+aebTimestampSign = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return doc.timestampSign(oArgs);
+ app.endPriv();
+});
+aebSecurityGetHandler = app.trustPropagatorFunction( function ( oArgs, security )
+{
+ app.beginPriv();
+ return security.getHandler(oArgs);
+ app.endPriv();
+});
+aebAppGetPath = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return app.getPath(oArgs);
+ app.endPriv();
+ return retn;
+});
+aebSignatureSetSeedValue = app.trustPropagatorFunction( function ( oArgs, field )
+{
+ app.beginPriv();
+ return field.signatureSetSeedValue( oArgs )
+ app.endPriv();
+});
+aebCertifyInvisibleSign = app.trustPropagatorFunction( function ( oArgs, field )
+{
+ app.beginPriv();
+ return field.certifyInvisibleSign( oArgs )
+ app.endPriv();
+});
+aebAddIcon=app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ doc.addIcon(oArgs);
+ app.endPriv();
+});
+aebCreateTemplate = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebCreateTemplate.msg==undefined)?("Create Template Error: " + e.toString()):aebCreateTemplate.msg;}
+ app.beginPriv();
+ try { return doc.createTemplate(oArgs); } catch(e) {console.println(Msg(e));}
+ app.endPriv();
+ aebCreateTemplate.msg=undefined;
+
+})
+aebBrowseForDoc=app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ var retn = app.browseForDoc(oArgs);
+ app.endPriv();
+});
+aebLaunchURL=app.trustPropagatorFunction ( function ( oArgs )
+{
+ app.beginPriv();
+ var retn = app.launchURL(oArgs);
+ app.endPriv();
+});
diff --git a/macros/latex/contrib/docassembly/docassembly.dtx b/macros/latex/contrib/docassembly/docassembly.dtx
new file mode 100644
index 0000000000..53bf22dae8
--- /dev/null
+++ b/macros/latex/contrib/docassembly/docassembly.dtx
@@ -0,0 +1,510 @@
+%\iffalse
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% docassembly.sty package, %%
+%% Copyright (C) 2021 D. P. Story %%
+%% dpstory@acrotex.net %%
+%% %%
+%% This program can redistributed and/or modified under %%
+%% the terms of the LaTeX Project Public License %%
+%% Distributed from CTAN archives in directory %%
+%% macros/latex/base/lppl.txt; either version 1.2 of %%
+%% the License, or (at your option) any later version. %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01]
+%<package>\ProvidesPackage{docassembly}
+%<package> [2021/06/11 v1.0 docassembly: Post PDF creation assembly (dps)]
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{amstext}
+\usepackage[colorlinks,hyperindex=false]{hyperref}
+\pdfstringdefDisableCommands{\let\\\textbackslash}
+\def\CMD#1{\textbackslash{#1}}\def\EXCL{!}
+\let\opt\texttt \let\app\textsf \let\pkg\textsf \let\env\texttt
+\OnlyDescription % comment out for implementation details
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\bgroup\ttfamily
+\gdef\brpr#1{\char123\relax#1\char125\relax}\egroup
+\let\darg\brpr
+\let\env\texttt
+\let\opt\texttt
+\let\app\textsf
+\let\uif\textsf
+\def\visispace{\symbol{32}}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}}
+\let\tops\texorpdfstring
+\makeatletter
+\let\@latex@warning@no@line\@gobble
+\renewcommand{\paragraph}
+ {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}
+ {\normalfont\normalsize\bfseries}}
+\makeatother
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{docassembly}{Inputting aebdocfmt.def}}
+ {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+ \PackageInfo{docassembly}{aebdocfmt.def cannot be found}}
+\begin{document}
+ \GetFileInfo{docassembly.sty}
+ \title{The \pkg{docassembly} package}
+ \author{D. P. Story\\
+ Email: \texttt{dpstory@acrotex.net}}
+ \date{processed \today}
+ \maketitle
+ \tableofcontents
+ \DocInput{docassembly.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here. Execute
+ \[\texttt{makeindex -s gind.ist -o docassembly.ind docassembly.idx}\] on the command line and recompile
+ \texttt{docassembly.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute
+ \[\texttt{makeindex -s gglo.ist -o docassembly.gls docassembly.glo}\] on the command line and recompile
+ \texttt{docassembly.dtx}.}
+\end{document}
+%</driver>
+% \fi
+% \MakeShortVerb{|}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{docassembly}{Inputting aebdonotindex.def}}
+% {\PackageInfo{docassembly}{cannot find aebdonotindex.def}}
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \section{Introduction}
+%
+% The \pkg{docassembly} package provides access some security related features of the
+% Acrobat JavaScript API.
+% The content of this package was extracted from \pkg{aeb\_pro}
+% so these important and useful methods can be available to document authors that own
+% \app{Acrobat}, but enjoy the use of \app{pdflatex}, \app{xelatex}, \app{lualatex},
+% \app{ps2pdf}, or (in the worst case scenario) \app{Adobe Distiller} as PDF creators.
+% \begin{center}
+% \fbox{\begin{minipage}{.67\linewidth}
+% \textbf{Important:} Run for your lives! This package requires
+% \app{Adobe Acrobat}! Run! Do not look back!. However, if it makes you feel better,
+% you can use any of the usual
+% PDF creators (\app{pdflatex}, \app{lualatex}, \app{xelatex}, \app{dvips \texttt{->} ps2pdf},
+% or even the much hated \app{dvips \texttt{->} Adobe Distiller}).
+% \end{minipage}}
+% \end{center}
+% This package requires \pkg{insdljs}, which loads \pkg{hyperref}. It also requires
+% the successful installation of the file \texttt{aeb\_pro.js}, which is distributed
+% with this package, as well as with the \pkg{aeb\_pro} package. Version 1.6.1 of
+% \texttt{aeb\_pro.js} is required.\footnote{If you already have \pkg{aeb\_pro} installed on your
+% system, be sure you have Version 1.6.1 of \texttt{aeb\_pro.js}, if not, use the version
+% of \texttt{aeb\_pro.js} that comes with \pkg{docassembly}.} Installation of \texttt{aeb\_pro.js}
+% is covered in \texttt{docs/install\_jsfiles.pdf}.
+%
+% \changes{v1.0}{2021/06/11}{First publication version of this package}
+%
+% \section{Documentation}
+%
+% The documentation of this file is minimal. Most of
+% the ``teaching'' of how to use the methods supported by this package is contained
+% in the demo files.
+%
+% The package defines one environment, the \env{docassembly} environment, and several
+% ``helper'' commands that are used within the \env{docassembly} environment. Refer
+% to \hyperref[s:DAM]{Section~\ref*{s:DAM}} for details.
+%
+%
+% \paragraph*{Installation of \texttt{aeb\_pro.js}.} This file is essential to the
+% correct functioning of this package. It is important, therefore, to correctly
+% install it. Follow the instructions of \texttt{docs/install\_jsfiles.pdf}.
+%
+% \paragraph*{Demo files.} Demo files are contained in the \texttt{examples} folder.
+% They illustrate all the security restricted methods of this package.
+% Most of the demo files have a minimal preamble.
+% Several of the files also uses \pkg{eforms}, since form fields
+% are used in those demo files.
+%
+% \paragraph*{End this package early.}
+% If \pkg{aeb\_pro} is already loaded, terminate this package early
+% since \pkg{aeb\_pro} contains the content of this package already.
+% \begin{macrocode}
+\@ifpackageloaded{aeb_pro}{\PackageInfo{docassembly}
+ {aeb_pro detected, early exit from\MessageBreak
+ the docassembly package}\endinput}{}
+\edef\da@restoreCats{%
+ \catcode`\noexpand\"=\the\catcode`\"\relax
+ \catcode`\noexpand\,=\the\catcode`\,\relax
+ \catcode`\noexpand\(=\the\catcode`\(\relax
+ \catcode`\noexpand\!=\the\catcode`\!\relax
+}
+\@makeother\"\@makeother\,\@makeother\(\@makeother\!
+% \end{macrocode}
+% \section{Package requirements}
+% Require \pkg{insdljs} for this little exercise.
+% \begin{macrocode}
+\RequirePackage{insdljs}
+\execJSOn
+% \end{macrocode}
+%
+% \section{Document Assembly Methods}\label{s:DAM}
+% Special ``helper'' commands and one environment are defined to take advantage of \app{Acrobat}'s extensive
+% library of security restricted methods. It is assumed the document author has properly
+% installed \texttt{aeb\_pro.js}.
+%
+% \subsection{The \texttt{docassembly} environment}
+%
+% \begin{environment}{docassembly}
+% This is a wrapper environment for the \texttt{execJS} environment of the
+% \textsf{insDLJS} Package. Place JavaScript lines in this environment and
+% the script will execute one time after the PDF has been created and opened
+% in \app{Acrobat Pro} for the first time.
+% \begin{macrocode}
+\newenvironment{docassembly}{\execJS{docassembly}}{\endexecJS}
+% \end{macrocode}
+% \end{environment}
+% \subsection{Supported Assembly JS API}
+%
+% These are convenience commands -- called JavaScript helper commands -- to
+% executing security restricted JavaScript. The JS methods are defined in the
+% \texttt{aeb\_pro.js} file, kept as folder JavaScript. These commands are
+% executed in a verbatim environment where `\verb!\!' is still the escape
+% character. Each of the JavaScript helper commands expects a left
+% parenthesis `\texttt{(}' following the command name \emph{on the
+% same line} as the command name.\footnote{This requirement is consistent with JavaScript function usage.}
+% See the example below for correct usage.
+%\begin{verbatim}
+%\begin{docassembly}
+%\addWatermarkFromFile({
+% bOnTop:false,
+% cDIPath:"/C/AcroTeX/AcroPackages/ManualBGs/Manual_BG_Print_AeB.pdf"
+%});
+%\end{docassembly}
+%\end{verbatim}
+% For each of the methods below, see the \textsl{JavaScript for Acrobat API Reference}.
+%
+%\medskip\noindent The command \cs{theDocObject} is normally set to \texttt{this}, meaning
+% the current document. You may need to set it to some other doc object if you are trying to
+% access a doc object other than the current one.
+% The following are support commands for changing \cs{theDocObject}
+% from within the \texttt{docassembly} environment.
+% \begin{macro}{\chngDocObjectTo}
+% All the JavaScript helper commands use \cs{theDocObject}, which is defined to be the \texttt{this}
+% object. To change it within the \env{docassembly} environment is difficult. The next command
+% aids in that problem.
+% \begin{macrocode}
+\let\ap@mrk\@empty
+\def\ap@gobtocomma#1,{}
+\providecommand\chngDocObjectTo[2]{%
+ \def#1##1\ap@mrk{#2,\ap@gobtocomma##1}}
+% \end{macrocode}
+% \end{macro}
+% The above defines a new command given by \texttt{\#1}. The command has one argument which is all content
+% up to the terminating mark \cs{ap@mrk}. The trick to removing \cs{thisDocObject} and replacing it with
+% \texttt{\#2}, in the above definition, we insert `\texttt{(\#2}' followed by \cs{ap@gobtocomma}, which absorbs
+% \cs{thisDocObject,} (absorbs everything through the first comma), followed by all content (\texttt{\#\#1});
+% the second \cs{@gobble} absorbs the left
+% parenthesis that opens the argument.
+% \begin{macrocode}
+\def\ap@TF{aebTrustedFunctions}
+% \end{macrocode}
+% An example of usage of \cs{chngDocObject} is \verb~\chngDocObjectTo{\newDO}{doc}~
+% expanded above the \texttt{docassembly} environment. Later, we can say,
+%\begin{verbatim}
+% \chngDocObjectTo{\newDO}{doc}
+% \begin{docassembly}
+% ...
+% \docSaveAs\newDO({ cPath: _path });
+% ...
+% \end{docassembly}
+%\end{verbatim}
+%That is, it is placed immediately after any of the commands below that uses \cs{theDocObject}.
+% \begin{macro}{\theDocObject}
+% This command is used in the definition of all JavaScript helper commands, as seen in the
+% definition of \cs{DeclareJSHelper} below. It is set to the doc object \texttt{this}. It can
+% be changed using \cs{chngDocObjectTo}, as described above.
+% \begin{macrocode}
+\def\theDocObject{this}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\DeclareJSHelper}
+% A general purpose command for defining what I am calling JavaScript helper commands.
+% \begin{macrocode}
+\providecommand\DeclareJSHelper[2]{%
+ \def#1##1({\ap@TF(##1\theDocObject,#2,\ap@mrk}}
+% \end{macrocode}
+% For example, we declare |\DeclareJSHelper{\docSaveAs}{aebDocSaveAs}| below, the declaration defines a new command,
+% \cs{docSaveAs}:
+%\begin{verbatim}
+% \def\docSaveAs#1({\ap@TF(#1\theDocObject,aebDocSaveAs,\ap@mrk}}
+%\end{verbatim}
+% Note that the argument of \cs{docSaveAs} is delimited by the left parenthesis, thus \texttt{\#1} is everything through that opening
+% parenthesis. This approach allows more flexibility in the definition, there can be spaces following the
+% command name |\docSaveAs ({path: _path})|, for example.
+% \end{macro}
+% \begin{macro}{\retnAbsPathAs}
+% Several methods require an absolute path to the current folder. The code is,
+%\begin{verbatim}
+%var _path=this.path;
+%var pos=_path.lastIndexOf("/");
+%_path=_path.substring(0,pos);
+%\end{verbatim}
+%We simplify this code for the document author in the form of the
+%command \cs{rtnAbsPathAs(\ameta{js-var});}, where \ameta{js-var} is a JavaScript
+%variable that will hold the absolute path to the current folder; eg, |\rtnAbsPathAs(_path);|
+%expands to the above code.
+% \begin{macrocode}
+\def\retnAbsPathAs(#1){var #1=this.path;^^J%
+ var pos=#1.lastIndexOf("/");^^J%
+ #1=#1.substring(0,pos)}
+% \end{macrocode}
+% \end{macro}
+% We new begin the documentation of the ``helper'' commands. For documentation
+% of the arguments of these commands, refer to the \textsl{\href{https://opensource.adobe.com/dc-acrobat-sdk-docs/acrobatsdk/documentation.html}{JavaScript${}^{\text{\textsc{tm}}}$ for Acrobat${}^{\text{\copyright}}$ API Reference}}.
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{addWatermarkFromFile}}
+% \begin{macro}{\addWatermarkFromFile}
+% This is the method \texttt{\textsl{Doc}.addWatermarkFromFile}.\\
+% \textbf{Demo file:} \texttt{watermark-file.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\addWatermarkFromFile}{aebAddWatermarkFromFile}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{addWatermarkFromText}}
+% \begin{macro}{\addWatermarkFromText}
+% This is the method \texttt{\textsl{Doc}.addWatermarkFromText}.\\
+% \textbf{Demo file:} \texttt{watermark-text.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\addWatermarkFromText}{aebAddWatermarkFromText}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{importIcon}}
+% \begin{macro}{\importIcon}
+% This is the method \texttt{\textsl{Doc}.importIcon}.\\
+% \textbf{Demo file:} \texttt{import-icons.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\importIcon}{aebImportIcon}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{importSound}}
+% \begin{macro}{\importSound}
+% This is the method \texttt{\textsl{Doc}.importSound}.\\
+% \textbf{Demo file:} \texttt{import-sound.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\importSound}{aebImportSound}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{appopenDoc}}
+% \begin{macro}{\appopenDoc}
+% This is the method \texttt{app.openDoc}. Opens a document and return
+% a \texttt{Doc} object.\\
+% \textbf{Demo file:} \texttt{open-doc.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\appopenDoc}{aebAppOpenDoc}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{docSaveAs}}
+% \begin{macro}{\docSaveAs}
+% This is the method \texttt{\textsl{Doc}.saveAs}. Saves a PDF or converts a PDF
+% to another format to a specified path.\\
+% \textbf{Demo file:} \texttt{doc-saveas.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\docSaveAs}{aebDocSaveAs}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{insertPages}}
+% \begin{macro}{\insertPages}
+% This is the method \texttt{\textsl{Doc}.insertPages}.\\
+% \textbf{Demo file:} \texttt{insert-pages.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\insertPages}{aebInsertPages}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{extractPages}}
+% \begin{macro}{\extractPages}
+% This is the method \texttt{\textsl{Doc}.extractPages}.\\
+% \textbf{Demo file:} \texttt{extract-pages.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\extractPages}{aebExtractPages}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{createTemplate}}
+% \begin{macro}{\createTemplate}
+% This is the method \texttt{\textsl{Doc}.createTemplate}. This is a feature that I had great
+% hopes for. With templates, you can create hidden pages that can be made visible (in \app{AA});
+% once a template is created, it can be spawned and deleted in \uif{AR}.
+% \begin{macrocode}
+\DeclareJSHelper{\createTemplate}{aebCreateTemplate}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{importDataObject}}
+% \begin{macro}{\importDataObject}
+% This is the method \texttt{\textsl{Doc}.importDataObject}, used to attach files to a PDF; alternately,
+% \cs{attachFile} is a more intuitive name for the operation performed.\DescribeMacro
+% \attachFile\\
+% \textbf{Demo file:} \texttt{attach-files.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\importDataObject}{aebImportDataObject}
+\DeclareJSHelper{\attachFile}{aebImportDataObject}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{executeSave}}
+% \begin{macro}{\executeSave}
+% To save the document, use at the \emph{end of the doc assembly environment}. Usage:
+% \verb!\executeSave()!. The \cs{@gobble} used below absorbs the comma that is placed immediately
+% after the second argument by \cs{DeclareJSHelper}.
+% \begin{macrocode}
+\DeclareJSHelper{\executeSave}{aebSaveAs,"Save"\@gobble}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{\tops{\protect\cs}{\textbackslash}{mailDoc}}
+% \begin{macro}{\mailDoc}
+% This is the method \texttt{\textsl{Doc}.mailDoc}.
+% Attach the current PDF and email it someone. Must have a default mail client
+% registered by \app{Acrobat} under \uif{Edit \texttt> Preferences \texttt> Mail Accounts}.\\
+% \textbf{Demo file:} \texttt{mail-doc.tex}
+% \begin{macrocode}
+\DeclareJSHelper{\mailDoc}{aebMailDoc}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{Signature related commands}
+% \textbf{Demo files:} \texttt{sign.tex}, \texttt{certifyinvisible.tex}\par\medskip
+% \noindent
+% The \cs{sigInfo} command is used for entering signing formation into what will
+% become an object. \cs{signatureSign} takes no arguments, but uses the info
+% entered by \cs{sigInfo}. An example is
+%\begin{verbatim}
+%\begin{docassembly}
+%\sigInfo{
+% cSigFieldName: "sigOfDPS",
+% ohandler: security.PPKLiteHandler,
+% cert: "<name>.pfx", password: "<password>",
+% oInfo: { location: "Niceville, FL",
+% reason: "I am approving this document",
+% contactInfo: "dpstory@acrotex.net",
+% appearance: "My Signature" }
+%};
+%\signatureSign
+%\end{docassembly}
+%\end{verbatim}
+% \begin{macro}{\sigInfo}
+% The \cs{sigInfo} command is a latex interface to creating the
+% \texttt{oSigInfo} object.
+% \begin{macrocode}
+\newcommand{\sigInfo}{var oSigInfo=}
+\def\sigFieldObj(#1){var oSigField=this.getField(#1)}
+% \end{macrocode}
+% \end{macro}
+% For the \cs{signatureSetSeedValue}, the field object is required.
+% This function assumes that the JavaScript variable \texttt{oSigField}
+% is the field object. For examle,
+%\begin{verbatim}
+%\begin{docassembly}
+%\sigFieldObj("sigOfDPS");
+%\signatureSetSeedValue({
+% lockDocument:true,
+% appearanceFilter:"My Signature",
+% reasons: ["This is a reason", "This is a better reason"],
+% flags:0x80|0x100|0x8
+%});
+%\end{docassembly}
+%\end{verbatim}
+% The \texttt{signatureSetSeedValue()} method seeds a signature field with various default values
+% available to the signer.
+%\begin{verbatim}
+%\begin{docassembly}
+%var sv={
+% mdp: "defaultAndComments",
+% reasons: ["This is a reason", "This is a better reason"],
+% flags:0x80|0x100|0x8
+%};
+%\sigFieldObj("sigOfDPS");
+%\signatureSetSeedValue(sv);
+%\end{docassembly}
+%\end{verbatim}
+% \begin{macro}{\signatureSetSeedValue}
+% This is the \texttt{\textsl{Field}.signatureSetSeedValue} method. The field name
+% is passed to this method through the \texttt{cSigFieldName} property of the \texttt{oSigField} object.
+% \begin{macrocode}
+\def\signatureSetSeedValue#1{%
+ \ap@TF( oSigField, aebSignatureSetSeedValue, }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\signatureSign}
+% This is the \texttt{\textsl{Field}.signatureSign} method. The field name
+% is passed to this method through the \texttt{cSigFieldName} property of the \texttt{oSigField} object.
+% The function \cs{signatureSign} takes the info in the \texttt{oSigInfo} object,
+% gets the security handler object, logs into the handler, calls
+% \texttt{signatureSetSeedValue} if the \texttt{sv} property is in the
+% \texttt{oSigInfo} object, and signs the field.
+%
+% \begin{macrocode}
+\begin{defineJS}[\makecmt\%\dfnJSCR{^^J}]{\signatureSign}
+if ( typeof oSigInfo.oHandler=="undefined" )
+ oSigInfo.oHandler=security.PPKLiteHandler;
+var engine=aebTrustedFunctions( security,%
+aebSecurityGetHandler, oSigInfo.oHandler );
+var path2Cert = (typeof oSigInfo.path2Cert == "undefined") ? %
+aebTrustedFunctions( this, aebAppGetPath,%
+{cCategory:"user"} )+"/Security"+"/"+oSigInfo.cert : %
+oSigInfo.path2Cert;
+aebTrustedFunctions( engine, aebSecurityHandlerLogin,%
+{ cPassword: oSigInfo.password, cDIPath: path2Cert});
+var oSigField = this.getField(oSigInfo.cSigFieldName);
+oSigInfo.oInfo.password=oSigInfo.password;
+if ( typeof oSigInfo.sv!="undefined" ) {
+ for (var o in oSigInfo.sv )
+ oSigInfo.oInfo[o]=oSigInfo.sv[o];
+}
+var oSigArgs={ oSig: engine, oInfo: oSigInfo.oInfo };
+if ( typeof oSigInfo.cLegalAttest!="undefined" )
+ oSigArgs.cLegalAttest=oSigInfo.cLegalAttest;
+if ( typeof oSigInfo.cDIPath!="undefined")
+ oSigArgs.cDIPath=oSigInfo.cDIPath;
+if ( typeof oSigInfo.bUI!="undefined")
+ oSigArgs.bUI=oSigInfo.bUI;
+aebTrustedFunctions( oSigField, aebSignatureSign, oSigArgs );
+\end{defineJS}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\certifyInvisibleSign}
+% This is the \texttt{\textsl{Doc}.certifyInvisibleSign} method.
+% This command uses the trusted version of \texttt{certifyInvisibleSign} to sign. The command
+% requires that \cs{sigInfo} is populated appropriately.
+%\begin{verbatim}
+%\begin{docassembly}
+%\sigInfo{
+% cert: "<name>.pfx",
+% password: "<password>",
+% cLegalAttest: "Certified using JavaScript",
+% bUI:false,
+% oInfo: {
+% location: "Niceville, FL",
+% reason: "I am certifying this document",
+% mdp: "defaultAndComments",
+% }
+%};
+%\certifyInvisibleSign
+%\end{docassembly}
+%\end{verbatim}
+% \begin{macrocode}
+\begin{defineJS}[\makecmt\%\dfnJSCR{^^J}]{\certifyInvisibleSign}
+if ( typeof oSigInfo.oHandler=="undefined" )
+ oSigInfo.oHandler=security.PPKLiteHandler;
+var engine=aebTrustedFunctions( security, %
+aebSecurityGetHandler, oSigInfo.oHandler );
+var path2Cert=aebTrustedFunctions( this, aebAppGetPath, %
+{cCategory:"user"} )+"/Security"+"/"+oSigInfo.cert;
+aebTrustedFunctions( engine, aebSecurityHandlerLogin, %
+{ cPassword: oSigInfo.password, cDIPath: path2Cert});
+oSigInfo.oInfo.password=oSigInfo.password;
+var oSigArgs={ oSig: engine, oInfo: oSigInfo.oInfo };
+if ( typeof oSigInfo.cLegalAttest!="undefined" )
+ oSigArgs.cLegalAttest=oSigInfo.cLegalAttest;
+if ( typeof oSigInfo.cDIPath!="undefined")
+ oSigArgs.cDIPath=oSigInfo.cDIPath;
+if ( typeof oSigInfo.bUI!="undefined")
+ oSigArgs.bUI=oSigInfo.bUI;
+aebTrustedFunctions( this, aebCertifyInvisibleSign, oSigArgs );
+\end{defineJS}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\da@restoreCats
+%</package>
+% \end{macrocode}
+% \Finale
+\endinput
diff --git a/macros/latex/contrib/docassembly/docassembly.ins b/macros/latex/contrib/docassembly/docassembly.ins
new file mode 100644
index 0000000000..b028064e05
--- /dev/null
+++ b/macros/latex/contrib/docassembly/docassembly.ins
@@ -0,0 +1,59 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright 2021 D. P. Story
+%%
+%% This file is part of the AcroTeX eDucation Bundle (AeB).
+%% -------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.2 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.2 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\filedate{2021/06/11}
+\def\batchfile{docassembly.ins}
+
+\input docstrip
+\ifx\generate\undefined
+ \Msg{**********************************************}
+ \Msg{*}
+ \Msg{* This installation requires docstrip}
+ \Msg{* version 2.4 or later.}
+ \Msg{*}
+ \Msg{* An older version of docstrip has been input}
+ \Msg{*}
+ \Msg{**********************************************}
+ \errhelp{Move or rename old docstrip.tex and get a newer one.}
+ \errmessage{Old docstrip in input path}
+ \batchmode
+ \csname @@end\endcsname\end
+\fi
+
+\keepsilent
+\askforoverwritefalse
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\preamble
+\endpreamble
+
+\generate{%
+ \file{docassembly.sty}{\from{docassembly.dtx}{copyright,package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files }
+\Msg{*}
+\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
diff --git a/macros/latex/contrib/docassembly/docs/docassembly.pdf b/macros/latex/contrib/docassembly/docs/docassembly.pdf
new file mode 100644
index 0000000000..a343c72fb4
--- /dev/null
+++ b/macros/latex/contrib/docassembly/docs/docassembly.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/docs/install_jsfiles.pdf b/macros/latex/contrib/docassembly/docs/install_jsfiles.pdf
new file mode 100644
index 0000000000..53d92d55d4
--- /dev/null
+++ b/macros/latex/contrib/docassembly/docs/install_jsfiles.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/docs/install_jsfiles.tex b/macros/latex/contrib/docassembly/docs/install_jsfiles.tex
new file mode 100644
index 0000000000..6c46402905
--- /dev/null
+++ b/macros/latex/contrib/docassembly/docs/install_jsfiles.tex
@@ -0,0 +1,325 @@
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+%
+% the driver line is not necessary if you
+% have aebpro.cfg configured to your driver.
+%
+\usepackage[web]{aeb_pro}
+\usepackage{eforms}
+\usepackage[altbullet]{lucidbry}
+\usepackage{pifont}
+
+\usepackage{fancyvrb}
+
+\makeatletter
+\renewcommand{\paragraph}
+ {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}
+ {\normalfont\normalsize\bfseries}}
+\renewcommand{\subparagraph}
+ {\@startsection{subparagraph}{5}{\parindent}{6pt}{-3pt}%
+ {\normalfont\normalsize\bfseries}}
+\makeatother
+
+\mathindent\parindent
+
+\def\AEBP{\app{AeB Pro}}
+\def\AEB{\app{AeB}}
+\def\app#1{\textsf{#1}}
+\def\amtIndent{\parindent}
+\def\meta#1{$\langle\textit{\texttt{#1}}\rangle$}
+\def\SC#1{{\small#1}}
+\def\PDF{\SC{PDF}}
+\let\opt\texttt
+\let\pkg\textsf
+
+\def\copyGetPath{\qquad\pushButton[\TU{Copy app.getPath to console}
+\CA{getPath}\A{\JS{console.show();\r
+console.println('\\napp.getPath("user");');
+}}]{cpyGtPth}{}{11bp}}
+
+\def\copyGetPathJS{\qquad\pushButton[\TU{Copy app.getPath to console}
+\CA{getPath}\A{\JS{console.show();\r
+console.println('\\napp.getPath("user", "javascript");');
+}}]{cpyGtPthJS}{}{11bp}}
+
+%\reversemarginpar
+\def\jsSupInstr{How to install JavaScript support files}
+\title{\jsSupInstr}
+\author{D. P. Story}
+\version{1.0}
+
+\chngDocObjectTo{\newDO}{doc}
+\begin{docassembly}
+var titleOfManual="How to install JavaScript files";
+var manualfilename="Manual_BG_Print_jsfiles.pdf";
+var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown
+var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate;
+var doc;
+var buildIt=false;
+if ( buildIt ) {
+ console.println("Creating new " + manualfilename + " file.");
+ doc = \appopenDoc({cPath: _pathToBlank, bHidden: true});
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ _path=_path.substring(0,pos)+"/"+manualfilename;
+ \docSaveAs\newDO ({ cPath: _path });
+ doc.closeDoc();
+ doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true});
+ f=doc.getField("ManualTitle");
+ f.value=titleOfManual;
+ doc.flattenPages();
+ \docSaveAs\newDO({ cPath: manualfilename });
+ doc.closeDoc();
+} else {
+ console.println("Using the current "+manualfilename+" file.");
+}
+\retnAbsPathAs(_path);
+_path += "/"+manualfilename;
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+_path=_path.substring(0,pos)+"/"+manualfilename;
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\maketitle
+
+\begin{center}
+ \fcolorbox{blue}{white}{\begin{minipage}{.75\linewidth}
+ \textbf{\textcolor{red}{Note:}} These are the installation instructions
+ for Folder JavaScript files \texttt{aeb.js} and \texttt{aeb\_pro.js}. The \pkg{docassembly} package
+ uses \texttt{aeb\_pro.js}, so follow these instructions.\medskip
+ \end{minipage}}
+\end{center}
+
+\section{Introduction}
+
+
+\noindent
+Because some of the \app{Acrobat} JavaScript methods have security
+restrictions, they can be only executed in the console window, or as part
+of a batch sequence, or from the JavaScript folder reserved by
+\app{Acrobat} for that use. The developer (of {\LaTeX} packages or {\PDF}
+form documents) may want to use these restricted JavaScript methods as
+part of document assembly. To use the restricted methods, they must be
+called from the user JavaScript folder. The scripts are contained in a
+\SC{JS} file that \app{Acrobat} reads when it first starts up.
+
+In this article, we provide detailed steps for locating the user
+JavaScript folder. For {\AEB} and {\AEBP}, the files \texttt{aeb.js} and
+\texttt{aeb\_pro.js} are placed in the folder. Other JavaScript files may
+be placed in the folder as well, for example, the \texttt{config.js} file
+is one that is commonly used for general purposes.
+
+Before we get started, if you are using a version of \app{Acrobat} prior
+to version~8.1, you need not read any further. The security restrictions
+described below were not in effect for those versions.
+
+\section{Installing the JavaScript support files}
+
+The functionality of {\AEB} and {\AEBP} depends, to some extent, on the
+proper installation of their JavaScript support files.
+\begin{itemize}
+ \item \AEB: For authors using the $\app{dvips}+\app{Acrobat Distiller}$
+ workflow, \texttt{aeb.js} is required; this file is not used by
+ \app{pdflatex} or \app{xelatex} users.
+
+ \item \AEBP: For authors using the $\app{dvips}+\app{Acrobat
+ Distiller}$ workflow, \texttt{aeb\_pro.js} is required; for authors
+ that prefer \app{pdflatex}, \app{lualatex}, or \app{xelatex} as the
+ {\PDF} creator \emph{and who own} the \app{Acrobat} application,
+ the \texttt{aeb\_pro.js} is required with the \opt{useacrobat}
+ option of \AEBP. When using the \opt{nopro} option of \AEBP, the
+ JavaScript file \texttt{aeb\_pro.js} is not used.
+
+\end{itemize}
+The placement of the JavaScript files has changed over the years and is a
+function of the version number \meta{ver}. Start \app{Acrobat} and open the
+console debugger window by pressing \texttt{Ctrl+J} (for \app{Windows OS})
+or \texttt{Cmd+J} (for \app{Mac OS}). Now execute the code
+\texttt{app.getPath("user")} in the console window. To do this, press the
+\textsf{getPath} button provided below, which copies the necessary code to
+the console window.
+\begin{equation}
+\begin{minipage}{.8\linewidth}
+\begin{Verbatim}[commandchars={!~@}]
+app.getPath("user");!copyGetPath
+\end{Verbatim}
+\end{minipage}\label{display:getPath}
+\end{equation}
+Now, with the cursor on the line containing the script, press the
+\texttt{Ctrl+Enter} (for \app{Windows OS}) or \texttt{Cmd+Enter} (for
+\app{Mac~OS}) key. This will execute the JavaScript and return the `root'
+path to the user's application data for \app{Acrobat}.
+
+The rest of the instructions depend on your operating system,
+\app{Windows} or \app{Mac}.
+
+\subsection{For users of \app{Windows OS}}
+
+There are several cases, jump to the numbered paragraph that describes your
+version (\meta{ver}) of \app{Acrobat}.
+
+%/C/Users/D. P. Story/AppData/Roaming/Adobe/Acrobat/11.0
+%/C/Users/D. P. Story/AppData/Roaming/Adobe/Acrobat/Privileged/11.0/JavaScripts
+
+\def\Stepi{\ding{182}\enspace}
+\def\Stepii{\ding{183}\enspace}
+\def\Stepiii{\ding{184}\enspace}
+
+\paragraph*{{\Stepi}For $\boldmath\text{\meta{ver}}$, $\boldmath 8.1 \le
+\text{\meta{ver}} < 10.1.1$.} For the \app{Windows OS}, executing the script
+in display~\eqref{display:getPath} returns a string of the
+form:\footnote{This string is for \app{Windows OS} beyond \app{WinXP}.}
+\begin{equation}
+\begin{minipage}{.8\linewidth}
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/!meta(ver)
+\end{Verbatim}
+\end{minipage}\label{display:path}
+\end{equation}
+Navigate to this folder location. The correct location for the \SC{JS}
+files is in the \texttt{JavaScripts} subfolder. If the folder does not
+exist, create it. The final path for the JavaScript support files is then
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/!meta(ver)/JavaScripts
+\end{Verbatim}
+Finally, copy \texttt{aeb.js} (and \texttt{aeb\_pro.js}, if applicable)
+into this folder. Close \app{Acrobat}, the next time \app{Acrobat}
+is started, it will read in the \SC{JS} files.
+
+\paragraph*{{\Stepii}For $\boldmath\text{\meta{ver}}$, $\boldmath10.1.1 \le
+\text{\meta{ver}} < 12$.} For these versions of \app{Acrobat} security has
+have tightened up even more; the \texttt{JavaScripts} folder is now a
+subfolder of a special \texttt{Privileged} folder. Execute
+\texttt{app.getPath("user")} in the console window, as in
+display~\eqref{display:getPath}. The method brings back a string similar to
+the one in display~\eqref{display:path}. The correct path is obtained by
+simply inserting \texttt{Privileged} into the path in
+display~\eqref{display:path}, between \texttt{Acrobat} and \meta{ver}, as
+displayed below.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/!textbf(Privileged)/!meta(ver)/JavaScripts
+\end{Verbatim}
+But this is a mere description of the correct location, the path must
+exist! The path must be created, if it does not already exist.
+
+Navigate to the folder, one folder above the path shown in
+display~\eqref{display:path}, that is, navigate to,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/
+\end{Verbatim}
+If a \texttt{Privileged} folder exists, enter into it; otherwise, create
+it, then enter it.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/Privileged
+\end{Verbatim}
+Now create a folder named \meta{ver}, unless it already exists, and enter
+it. The version is always the major release \texttt{8.0}, \texttt{9.0},
+\texttt{10.0}, or \texttt{11.0}.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/Privileged/!meta(ver)
+\end{Verbatim}
+Finally, create the \texttt{JavaScript} folder, unless it already exists,
+to obtain the final path to the user folder JavaScripts:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/Privileged/!meta(ver)/JavaScripts
+\end{Verbatim}
+Copy \texttt{aeb.js} (and \texttt{aeb\_pro.js}, if applicable) into this
+folder. Close \textsf{Acrobat}, the next time \textsf{Acrobat} is started,
+it will read in the \SC{JS} files.
+
+\paragraph*{{\Stepiii}For $\boldmath\text{\meta{ver}}$, $\boldmath
+\text{\meta{ver}} > 12 $.} Beginning with the next major version following
+version~11, Adobe changed its versioning scheme. There are now two tracks,
+\emph{subscription} and \emph{classic} (also called \emph{perpetual}). For
+subscription, the version, as I understand it, will always be \texttt{DC}
+(Document Cloud), and for the classic, for which you've purchased a
+\emph{perpetual license}, the \meta{ver} is a calendar year. The first
+classic version is \texttt{2015}, the next one is most likely \texttt{2017},
+since major releases occur about every two years.
+
+Execute the code of display~\eqref{display:getPath} by pressing the button
+provided to obtain a path of the form,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/DC
+\end{Verbatim}
+for the subscription license or,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/2015
+\end{Verbatim}
+for the classic (or perpetual) license. Of course, this last path is for
+the first classic version.
+
+Now, to obtain the path to the \texttt{JavaScripts} folder, follow the
+instructions for numbered paragraph \ding{183}, but with \meta{ver} equal
+to either \texttt{DC} or \texttt{2015} (a calendar year).
+
+%/C/Users/D. P. Story/AppData/Roaming/Adobe/Acrobat/Privileged/11.0/JavaScripts
+
+\subsection{For users of \app{Mac OS}}
+
+\app{Mac OS} does not have the security restrictions that \app{Windows OS}
+does, as described in paragraphs \ding{183} and \ding{184}.
+
+Follow the instructions of paragraph \ding{182}, by first pressing the button
+provided in display~\eqref{display:getPath}, then, in the console window,
+execute this script as described in the paragraph following
+display~\eqref{display:getPath}. After working through \ding{182}, one
+obtains any of the following paths depending on the version (\meta{ver}) you
+are using:\medskip
+
+\noindent
+For $\text{\meta{ver}} = \texttt{8.0}, \texttt{9.0}, \texttt{10.0},
+\texttt{11.0}$:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/!meta(ver)/JavaScripts
+\end{Verbatim}
+\medskip
+
+\noindent
+For $\text{\meta{ver}} > 12$, the path is,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/DC/JavaScripts
+\end{Verbatim}
+for a subscription license, and,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/2015/JavaScripts
+\end{Verbatim}
+or more generally,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/!meta(year)/JavaScripts
+\end{Verbatim}
+for the perpetual license.
+
+In all cases, if the \texttt{JavaScripts} folder does not exist, it must
+be created. Copy any \SC{JS} support files into the \texttt{JavaScripts}
+folder. The script files are read the next time \app{Acrobat} is started.
+
+\section{Testing the placement of the JavaScript support files}
+
+Assuming you have successfully followed the instructions and created the
+\texttt{JavaScripts} folder, test the validity of what you have done by
+closing \app{Acrobat} then opening it again. Open the console window
+(\texttt{Ctrl+J} or \texttt{Cmd+J}, for \app{Mac OS}) and execute this
+command in the console window:
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars={!~@}]
+app.getPath("user","javascript");!quad!copyGetPathJS
+\end{Verbatim}
+If you have followed the instructions, the return string should read the
+complete path to the \texttt{JavaScripts} folder.
+\end{document}
diff --git a/macros/latex/contrib/docassembly/examples/attach-files.tex b/macros/latex/contrib/docassembly/examples/attach-files.tex
new file mode 100644
index 0000000000..6bec57abdd
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/attach-files.tex
@@ -0,0 +1,31 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseAttachments}
+
+% Look in the Adobe Acrobat JavaScript manual under the doc.importDataObject to see all the possible parameters.
+\begin{docassembly}
+% Or use \attachFile instead of \importDataObject
+var retn = \importDataObject({
+ cName: "job",
+ cDIPath: "\jobname.tex"
+});
+% The next line creates a meaningful description of the attachment
+if (retn) this.getDataObject("job").description="Source file for this PDF";
+% You can have more than one file attachments
+var retn = \attachFile({
+ cName: "AdobeDon",
+ cDIPath: "graphics/AdobeDon.pdf"
+});
+% The next line creates a meaningful description of the attachment
+if (retn) this.getDataObject("AdobeDon").description="The one and only AdobeDon";
+% ...
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/certifyinvisible.pdf b/macros/latex/contrib/docassembly/examples/certifyinvisible.pdf
new file mode 100644
index 0000000000..d00c77048d
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/certifyinvisible.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/certifyinvisible.tex b/macros/latex/contrib/docassembly/examples/certifyinvisible.tex
new file mode 100644
index 0000000000..b4205b7165
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/certifyinvisible.tex
@@ -0,0 +1,151 @@
+\documentclass[12pt]{article}
+\usepackage{eforms}
+\usepackage{docassembly}
+\usepackage{fancyvrb}
+
+\hypersetup{pdfpagemode=UseNone}
+
+\newcommand{\cs}[1]{\texttt{\char`\\#1}}
+
+\pagestyle{empty}
+\parskip\medskipamount
+\parindent0pt
+
+% Do not compile until you have a digital ID and password
+% Actually, you can compile, but do not bring the PDF into Acrobat until you have a digital ID and password.
+% You can view the PDF in other PDF viewers such as SumatraPDF.
+\begin{docassembly}
+\sigInfo{
+ cert: "<name>.pfx",
+ password: "<password>",
+ oInfo: {
+ location: "AcroTeX Central, FL",
+ reason: "I am certifying this document",
+ mdp: "defaultAndComments",
+ contactInfo: "dpspeaker@talking@edu"
+ }
+};
+\certifyInvisibleSign
+\end{docassembly}
+
+\begin{document}
+
+
+%\maketitle
+
+\hfill\smash{\raisebox{-\baselineskip}{March 23, 2009}}
+
+\begin{tabular}{@{}ll}
+To: &Honorable Barrister Maxwell Frimpong\\
+From: &D. P. Speaker\\
+Subject: &On Business Proposal\\
+\end{tabular}
+
+\vspace{2\baselineskip}
+
+Dear Mr.\ Frimpong;
+
+Thank you for thinking of me concerning an ``important business proposal'' in
+your recent and brief email to me on March 23, 2009. Recovering \$12,000,000
+(twelve million Us dollars) in claims sounds intriguing and exciting to me.
+Such a large amount of money would certainly come in handy in these tough
+times. Yet, regrettably, I must decline your kind offer; though I am in
+retirement, I am, none-the-less, quite busy lately sorting my button
+collection and don't really have the time to pick up all this easy money.
+
+Thank you again, Barrister Frimpong, for your offer. Please keep me
+in mind should future opportunities arise.
+
+
+\vspace{2\baselineskip}
+
+Best regards,\\
+\sigField{sigOfDPS}{2.5in}{4\baselineskip}\\[3pt]
+Dr.\ D. P. Speaker\\
+Department of Rhetoric\\
+Talking University\\
+Talkville, FL 12345\\
+\texttt{dpspeaker@talking.edu}
+
+\newpage
+
+\section{Creating and Signing a Certified Invisible Signature}
+
+The \textsf{docassembly} package can create a \emph{certified invisible
+signature}. You create an certified invisible signature either through the
+user-interface of \textsf{Acrobat} or programmatically using JavaScript. With
+JavaScript (and \textsf{docassembly}, a trusted version of the
+\texttt{\textsl{Doc}.certifyInvisibleSign()} method is used to certify the
+document. The certification can be seen by opening the Signature panel
+(part of the left-hand panel system of the user-interface).
+
+Also included is an approval signature, as usual, at the end of the letter. Open
+this PDF and sign using your own digital ID. Signing should not invalidate
+the certification.
+
+The certify invisible sign is done within the \texttt{docassembly}
+environment, the script follows:
+\begin{Verbatim}[xleftmargin=20pt,fontsize=\small]
+\begin{docassembly}
+\sigInfo{
+ cert: "<name>.pfx", password: "<password>",
+ oInfo: {
+ location: "AcroTeX Central, FL",
+ reason: "I am certifying this document",
+ mdp: "defaultAndComments",
+ contactInfo: "dpspeaker@talking.edu"
+ }
+};
+\certifyInvisibleSign
+\end{docassembly}
+\end{Verbatim}
+The setup is similar to certify sign, but without the key
+\texttt{cSigFieldName}, used to specify a particular field to be signed.
+An invisible signature field \emph{is created and signed} using the method
+\texttt{\textsl{Doc}.certifyInvisibleSign()}.
+
+
+The \cs{sigInfo} contains the usual property list, excluding
+\texttt{cSigFieldName}. The command \cs{certifyInvisibleSign}
+uses the information in this object and calls the trusted version
+of \texttt{\textsl{Doc}.certifyInvisibleSign()}, which is defined in
+\texttt{aeb\_pro.js}.
+
+Additional information on signatures is found at the
+\textbf{Acrobat Developer Center}.\footnote{\url{http://www.adobe.com/go/acrobat_developer}}
+Refer to the \emph{JavaScript for Acrobat API Reference}, also found at the \textbf{Acrobat Developer Center},
+for details on these methods and their parameters. Adobe is
+notorious for moving its reference documents and renaming them, year after
+year. Good luck searching the Adobe web site for the references you need.
+
+\section{Compiling this file}
+
+In the preamble of this document, the \texttt{docassembly} environment is found:
+\begin{Verbatim}[xleftmargin=20pt,fontsize=\small]
+\begin{docassembly}
+\sigInfo{
+ cert: "<name>.pfx", password: "<password>",
+ oInfo: {
+ location: "AcroTeX Central, FL",
+ reason: "I am certifying this document",
+ mdp: "defaultAndComments",
+ contactInfo: "dpspeaker@talking.edu"
+ }
+};
+\certifyInvisibleSign
+\end{docassembly}
+\end{Verbatim}
+To compile this document yourself, you need to create a digital ID using
+\textsf{Acrobat}. Replace \texttt{<name>} with the file name of your digital
+ID. and of course replace \texttt{<password>} with the password you selected
+when you created your digital ID. Modify the \texttt{oInfo} property as
+designed.
+
+
+Now, back to my retirement.
+
+\end{document}
+
+References: Try
+Digital Signatures Workflow Guide
+http://www.adobe.com/devnet-docs/acrobatetk/tools/DigSig/index.html
diff --git a/macros/latex/contrib/docassembly/examples/create-templates.tex b/macros/latex/contrib/docassembly/examples/create-templates.tex
new file mode 100644
index 0000000000..62694179a6
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/create-templates.tex
@@ -0,0 +1,66 @@
+\documentclass{article}
+\usepackage{xcolor}
+\usepackage{docassembly}
+\usepackage{eforms}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone,colorlinks}
+
+\begin{defineJS}{\ADActn}
+if (typeof tmplObj != "object")
+ tmplObj=this.getTemplate("AdobeDon");
+tmplObj.spawn({
+ nPage: 0,
+ bOverlay:false,
+ oXObject: tmplObj
+});
+\end{defineJS}
+\begin{defineJS}{\contActn}
+if (typeof tmplObjSpawn != "object") {
+ var tmplObjSpawn=this.getTemplate("myStory");
+ tmplObjSpawn.spawn({
+ nPage: this.pageNum+1,
+ bOverlay:false,
+ oXObject: tmplObjSpawn
+ });
+ this.pageNum++;
+}
+\end{defineJS}
+
+% Look in the Adobe Acrobat JavaScript manual under the Doc.createTemplate to see all the possible parameters.
+\begin{docassembly}
+\insertPages({
+ nPage: -1,
+ cPath: "graphics/AdobeDon-btn.pdf"
+});
+var tmplObj=\createTemplate({cName: "AdobeDon", nPage: 0});
+tmplObj.hidden=true;
+\insertPages({
+ nPage: -1,
+ cPath: "resources/myStory.pdf"
+});
+var tmplObj1=\createTemplate({cName: "myStory", nPage: 0});
+tmplObj1.hidden=true;
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\noindent
+\pushButton[\CA{View author}\AAmouseup{\ADActn}]{vTmpl}{}{11bp}\medskip
+
+\noindent
+\lipsum[1-4]\medskip
+
+\noindent
+Write a short history of your life. Press the \textsf{Continue} link if you need more space for your story, and then continue on the
+next page.\medskip
+
+\noindent
+\textField[\Ff\FfMultiline]{myStory}{\linewidth}{3\baselineskip}\\[6bp]\null
+\hfill\setLink[\A{\JS{\contActn}}\linktxtcolor{red}]{Continue on next page as needed}
+
+\newpage
+\noindent\lipsum[5-10]
+
+\end{document}
diff --git a/macros/latex/contrib/docassembly/examples/doc-saveas.tex b/macros/latex/contrib/docassembly/examples/doc-saveas.tex
new file mode 100644
index 0000000000..38df5985fa
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/doc-saveas.tex
@@ -0,0 +1,27 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the doc.saveAs() to see all the possible parameters.
+\begin{docassembly}
+% save a copy of this PDF for the archives
+var retn=\docSaveAs({
+ cPath: "\jobname-copy.pdf",
+ bCopy: true
+});
+% This method can also be used to make conversions, for example, you can save a PDF as a PNG
+% Here, we make a PNG image of each page in this document.
+var retn=\docSaveAs({
+ cConvID: "com.adobe.acrobat.png",
+ cPath: "\jobname.png"
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/extract-pages.tex b/macros/latex/contrib/docassembly/examples/extract-pages.tex
new file mode 100644
index 0000000000..7cfc1af7d7
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/extract-pages.tex
@@ -0,0 +1,24 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the doc.extractPages to see all the possible parameters.
+% nStart and nEnd are 0-based page numbers, so nStart:1 and nEnd:2 extracts pages 2 and 3
+\begin{docassembly}
+\retnAbsPathAs(_path);
+_path += "/extracted-pages.pdf";
+\extractPages({
+ nStart: 1,
+ nEnd: 2,
+ cPath: _path
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/graphics/AdobeDon-btn.pdf b/macros/latex/contrib/docassembly/examples/graphics/AdobeDon-btn.pdf
new file mode 100644
index 0000000000..7ec1ff9880
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/graphics/AdobeDon-btn.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/graphics/AdobeDon.pdf b/macros/latex/contrib/docassembly/examples/graphics/AdobeDon.pdf
new file mode 100644
index 0000000000..2968aa40b7
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/graphics/AdobeDon.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/graphics/AdobeDonIcon.pdf b/macros/latex/contrib/docassembly/examples/graphics/AdobeDonIcon.pdf
new file mode 100644
index 0000000000..284f3d8c09
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/graphics/AdobeDonIcon.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/graphics/AeB_Logo.pdf b/macros/latex/contrib/docassembly/examples/graphics/AeB_Logo.pdf
new file mode 100644
index 0000000000..c41d81c44c
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/graphics/AeB_Logo.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/graphics/girl.pdf b/macros/latex/contrib/docassembly/examples/graphics/girl.pdf
new file mode 100644
index 0000000000..4ab32d829a
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/graphics/girl.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/graphics/man1.pdf b/macros/latex/contrib/docassembly/examples/graphics/man1.pdf
new file mode 100644
index 0000000000..1072158851
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/graphics/man1.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/graphics/scot.pdf b/macros/latex/contrib/docassembly/examples/graphics/scot.pdf
new file mode 100644
index 0000000000..3133d053b6
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/graphics/scot.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/import-icons.tex b/macros/latex/contrib/docassembly/examples/import-icons.tex
new file mode 100644
index 0000000000..147839fa29
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/import-icons.tex
@@ -0,0 +1,56 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{eforms}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the doc.importIcon to see all the possible parameters.
+\begin{docassembly}
+ var retn=\importIcon({cName:"A man",cDIPath:"graphics/man1.pdf"});
+ if ( retn < 0 ) console.println("The file man1.pdf could not be opened or is invalid");
+ var retn=\importIcon({cName:"A girl",cDIPath:"graphics/girl.pdf"});
+ if ( retn < 0 ) console.println("The file girl.pdf could not be opened or is invalid");
+ var retn=\importIcon({cName:"A scotsman",cDIPath:"graphics/scot.pdf"});
+ if ( retn < 0 ) console.println("The file scot.pdf could not be opened or is invalid");
+ var retn=\importIcon({cName:"AdobeDon",cDIPath:"graphics/AdobeDonIcon.pdf"});
+ if ( retn < 0 ) console.println("The file AdobeDonIcon.pdf could not be opened or is invalid");
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\begin{defineJS}{\cycleJS}
+if (typeof indexIcon == "undefined") var indexIcon=0;
+var oIconName=this.icons[indexIcon].name;
+var f=this.getField("iconContainer");
+var oIcon=this.getIcon(oIconName);
+f.buttonPosition=position.iconTextV;
+f.buttonSetIcon(oIcon);
+f.buttonSetCaption(oIconName);
+indexIcon = (indexIcon+1) \% (this.icons.length);
+\end{defineJS}
+% define a clear button feature, it clears the button iconContainer
+% so it no longer displays an icon; pressing the Cycle button resumes
+% the display as before.
+\begin{defineJS}{\clearJS}
+f=this.getField("iconContainer")
+// save
+var sv=f.buttonPosition;
+var cptn=f.buttonGetCaption();
+// clear
+f.buttonPosition=position.textOnly;
+f.buttonSetCaption("");
+\end{defineJS}
+
+\begin{center}\Large\bfseries
+A slide show of Icons and Photos
+\end{center}
+
+\begin{center}
+\pushButton[\BG{}\TP{2}\S{S}]{iconContainer}{100bp}{100bp}\vcgBdry[6bp]
+\pushButton[\CA{Cycle}\AAmouseup{\cycleJS}]{cycleBtn}{}{11bp}\cgBdry[3bp]
+\pushButton[\CA{Clear}\AAmouseup{\clearJS}]{clearBtn}{}{11bp}
+\end{center}
+\end{document}
+
diff --git a/macros/latex/contrib/docassembly/examples/import-sound.tex b/macros/latex/contrib/docassembly/examples/import-sound.tex
new file mode 100644
index 0000000000..19f7be117c
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/import-sound.tex
@@ -0,0 +1,24 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{eforms}
+%\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the doc.importSound to see all the possible parameters.
+\begin{docassembly}
+\importSound({cName: "StarTrek", cDIPath: "sounds/trek.wav" });
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+
+\begin{center}
+\pushButton[\CA{Star Trek}\S{S}\W{0}\AAmouseup{%
+ var s = this.getSound("StarTrek");\r
+ s.play();
+}]{stSound}{}{11bp}
+
+\end{center}
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/insert-pages.tex b/macros/latex/contrib/docassembly/examples/insert-pages.tex
new file mode 100644
index 0000000000..eedbaab1e7
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/insert-pages.tex
@@ -0,0 +1,20 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Review doc.insertPages in the Acrobat JavaScript reference
+\begin{docassembly}
+\insertPages({
+ nPage: this.numPages-1,
+ cPath: "graphics/AdobeDon.pdf"
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/mail-doc.tex b/macros/latex/contrib/docassembly/examples/mail-doc.tex
new file mode 100644
index 0000000000..6240c9459c
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/mail-doc.tex
@@ -0,0 +1,31 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the doc.mailDoc to see all the possible parameters.
+\begin{docassembly}
+% Prior to sending this document, you can attach files this this PDF
+% Refer to attach-files.tex
+var retn = \attachFile({
+ cName: "AdobeDon",
+ cDIPath: "graphics/AdobeDon.pdf"
+});
+% The next line creates a meaningful description of the attachment
+if (retn) this.getDataObject("AdobeDon").description="The one and only AdobeDon";
+\executeSave();
+\mailDoc({
+ bUI: false,
+ cTo: "dpstory@hotmail.com",
+ cSubject: "I'm testing things out",
+ cMsg: "Good to hear from you again Don. I'm emailing this PDF, attached, for your review."
+});
+%\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/open-doc.tex b/macros/latex/contrib/docassembly/examples/open-doc.tex
new file mode 100644
index 0000000000..4b861b795e
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/open-doc.tex
@@ -0,0 +1,34 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the app.openDoc() to see all the possible parameters.
+\begin{docassembly}
+% Open supportDoc.pdf, but hide it
+var doc=\appopenDoc({
+ oDoc: this,
+ cPath: "resources/supportDoc.pdf",
+ bHidden: true
+});
+console.clear(); console.show();
+console.println("Opening " + doc.documentFileName);
+% Get the field object, for the text field that has title of "Name"
+console.println("Getting the field value of \"Name\"");
+var f=doc.getField("Name");
+% Show the value of that text field and display it in the console
+console.println("The value of \"Name\" is "+f.value);
+% Close the hidden doc
+console.println("Closing " + doc.documentFileName);
+doc.closeDoc();
+% Save the current document
+console.println("Saving the current document " + this.documentFileName);
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/resources/myStory.pdf b/macros/latex/contrib/docassembly/examples/resources/myStory.pdf
new file mode 100644
index 0000000000..a4549d217f
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/resources/myStory.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/resources/supportDoc.pdf b/macros/latex/contrib/docassembly/examples/resources/supportDoc.pdf
new file mode 100644
index 0000000000..c34ac72fe4
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/resources/supportDoc.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/sign.pdf b/macros/latex/contrib/docassembly/examples/sign.pdf
new file mode 100644
index 0000000000..b1fdef0f15
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/sign.pdf
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/sign.tex b/macros/latex/contrib/docassembly/examples/sign.tex
new file mode 100644
index 0000000000..0581f1ebc5
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/sign.tex
@@ -0,0 +1,206 @@
+% C:\Users\dpstory\AppData\Roaming\Adobe\Acrobat\Beta\Security\DonStory.pfx
+\documentclass[12pt]{article}
+\usepackage{eforms}
+\usepackage{docassembly}
+\usepackage{fancyvrb}
+
+\hypersetup{pdfpagemode=UseNone}
+
+
+\newcommand{\cs}[1]{\texttt{\char`\\#1}}
+
+\pagestyle{empty}
+\parskip\medskipamount
+\parindent0pt
+
+% Do not compile until you have a digital ID and password
+% Actually, you can compile, but do not bring the PDF into Acrobat until you have a digital ID and password.
+% You can view the PDF in other PDF viewers such as SumatraPDF.
+\begin{docassembly}
+\sigInfo{
+ cSigFieldName: "sigOfDPS",
+ cert: "D_P_Speaker.pfx",
+ password: "password",
+ oInfo: {
+ location: "AcroTeX Central, FL",
+ reason: "I am approving this document for distribution",
+ contactInfo: "dpspeaker@talking.edu",
+ appearance: "My Signature"
+% appearance: "My Image"
+ }
+};
+\signatureSign
+\end{docassembly}
+
+\begin{document}
+
+
+%\maketitle
+
+\hfill\smash{\raisebox{-\baselineskip}{March 23, 2009}}
+
+\begin{tabular}{@{}ll}
+To: &Honorable Barrister Maxwell Frimpong\\
+From: &D. P. Speaker\\
+Subject: &On Business Proposal\\
+\end{tabular}
+
+\vspace{2\baselineskip}
+
+Dear Mr.\ Frimpong;
+
+Thank you for thinking of me concerning an ``important business proposal'' in
+your recent and brief email to me on March 23, 2009. Recovering \$12,000,000
+(twelve million US dollars) in claims sounds intriguing and exciting to me.
+Such a large amount of money would certainly come in handy in these tough
+times. Yet, regrettably, I must decline your kind offer; though I am in
+retirement, I am, none-the-less, quite busy lately sorting my button
+collection, and don't really have the time to pick up all this easy money.
+
+Thank you again, Barrister Frimpong, for your offer. Please keep me
+in mind should future opportunities arise.
+
+
+\vspace{2\baselineskip}
+
+Best regards,\\
+\sigField{sigOfDPS}{2.5in}{4\baselineskip}\\[3pt]
+Dr.\ D. P. Speaker\\
+Department of Rhetoric,\\
+Talking University\\
+Talkville, FL 12345\\
+\texttt{dpspeaker@talking.edu}
+
+
+\newpage
+
+\section{Creating and Signing a Signature Field}
+
+The \textsf{eforms} package can create a signature field with the \cs{sigField} command, and
+using the \textsf{aeb\_pro} package with its \texttt{docassembly} environment, can also sign the field
+from a {\LaTeX} source.
+
+The {\LaTeX} code for creating the signature field of this document is
+\begin{Verbatim}[xleftmargin=20pt,fontsize=\small]
+Best regards,\\
+\sigField{sigOfDPS}{2.5in}{4\baselineskip}\\[3pt]
+Dr.\ D. P. Speaker\\
+Department of Rhetoric,\\
+Talking University\\
+Talkville, FL 12345\\
+\texttt{dpspeaker@talking.edu}
+\end{Verbatim}
+The \cs{sigField} command appears in the second line, and uses the usual
+syntax for form fields, as defined in the \textsf{eforms} package.
+Here's what the field looks like when it is unsigned.
+
+\sigField{sigOfDPS1}{2.5in}{4\baselineskip}
+
+Once the field is created, it can be signed using the Acrobat or Adobe
+Reader (version 10.0.1 or later) user interface.
+
+A signature field may also be signed programmatically from the {\LaTeX}
+source file using AeB Pro. The first signature field of this document
+was automatically signed when the newly created PDF is brought into
+Acrobat.
+\begin{Verbatim}[xleftmargin=20pt,fontsize=\footnotesize]
+\begin{docassembly}
+\sigInfo{
+ cSigFieldName: "sigOfDPS",
+ cert: "<name>.pfx", password: "<password>",
+ oInfo: {
+ location: "AcroTeX Central, FL",
+ reason: "I am approving this document for distribution",
+ contactInfo: "dpspeaker@talking.edu",
+ appearance: "My Signature" }
+};
+\signatureSign
+\end{docassembly}
+\end{Verbatim}
+The script above was used to programmatically sign the signature field
+with field name of \texttt{sigOfDPS}. The value of the \texttt{password}
+key to protect my secrets. The first command, \cs{sigInfo}, creates an
+JavaScript object, \texttt{oSigInfo}. The command \cs{signatureSign} uses
+the information in this object to sign the field designated by the
+\texttt{cSigFieldName} property.
+
+The general syntax of the argument of \cs{sigInfo} is displayed below.
+\def\meta#1{$\langle\textsl{\texttt{#1}}\rangle$}
+\begin{Verbatim}[xleftmargin=20pt,fontsize=\footnotesize,commandchars={!()}]
+\sigInfo{
+ cSigFieldName: "!meta(sigFldName)",
+ oHandler: !meta(securityHandlerObj),
+ path2Cert: !meta(path),
+ cert: "!meta(certName).pfx",
+ password: "!meta(password)",
+ bUI: true|false;
+ oInfo: {
+ !meta(various properties)
+ }
+}
+\end{Verbatim}
+The first five keys are used by AeB Pro to build the proper information
+needed sign the field.
+\begin{description}
+ \item[\normalfont\texttt{cSigFieldName} (required)] The
+ name of the signature field to be signed.
+ \item[\normalfont\texttt{oHandler} (optional)] The security
+ handler to be used. If this key is not present,
+ \texttt{security.PPKLiteHandler} is used.
+ \item[\normalfont\texttt{path2Cert} (optional)] The
+ device-independent path to the PFX file to be used. If not
+ present, AeB Pro uses the name provided by the \texttt{cert} key
+ and builds the path to where Acrobat normally saves digital IDs.
+ \item[\normalfont\texttt{cert} (optional)] The name of the digital
+ ID to be used for signing. Optional if \texttt{path2Cert} is
+ provided, required otherwise.
+ \item[\normalfont\texttt{password} (required)] The password for the PFX file
+ provided, necessary to login to the security handler (\texttt{oHandler}).
+ \item [\normalfont\texttt{bUI} (optional)] A Boolean, if
+ \texttt{true} the security handler displays the user interface
+ when signing. The default is \texttt{false}.
+ \item[\normalfont\texttt{oInfo} (optional)] The \texttt{oInfo} property key is
+ one that appears in the argument property list of the
+ \texttt{\textsl{Field}.signatureSign()} method. It is passed to
+ the argument of this JavaScript method. See the documentation of
+ \texttt{\textsl{Field}.signatureSign()} in the
+ \emph{JavaScript for Acrobat API Reference} for more information.
+\end{description}
+
+Additional information on signatures is found at the
+\textbf{Acrobat Developer Center}.\footnote{\url{http://www.adobe.com/go/acrobat_developer}}
+Refer to the \emph{JavaScript for Acrobat API Reference}, also found at the \textbf{Acrobat Developer Center},
+for details on these methods and their parameters. Adobe is
+notorious for moving its reference documents and renaming them, year after
+year. Good luck searching the Adobe web site for the references you need.
+
+\section{Compiling this file}
+
+In the preamble of this document, the \texttt{docassembly} environment is found:
+\begin{Verbatim}[xleftmargin=20pt,fontsize=\small]
+\begin{docassembly}
+\sigInfo{
+ cert: "<name>.pfx", password: "<password>",
+ oInfo: {
+ location: "AcroTeX Central, FL",
+ reason: "I am certifying this document",
+ mdp: "defaultAndComments",
+ contactInfo: "dpspeaker@talking.edu"
+ }
+};
+\certifyInvisibleSign
+\end{docassembly}
+\end{Verbatim}
+To compile this document yourself, you need to create a digital ID using
+\textsf{Acrobat}. Replace \texttt{<name>} with the file name of your digital
+ID. and of course replace \texttt{<password>} with the password you selected
+when you created your digital ID. Modify the \texttt{oInfo} property as
+designed.
+
+
+Now, back to my retirement.
+
+\end{document}
+
+Digital Signatures Workflow Guide
+http://www.adobe.com/devnet-docs/acrobatetk/tools/DigSig/index.html
diff --git a/macros/latex/contrib/docassembly/examples/sounds/trek.wav b/macros/latex/contrib/docassembly/examples/sounds/trek.wav
new file mode 100644
index 0000000000..b8d9e65dd8
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/sounds/trek.wav
Binary files differ
diff --git a/macros/latex/contrib/docassembly/examples/watermark-file.tex b/macros/latex/contrib/docassembly/examples/watermark-file.tex
new file mode 100644
index 0000000000..c7b9f10f42
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/watermark-file.tex
@@ -0,0 +1,25 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the addWatermarkFromFile to see all the possible parameters.
+\begin{docassembly}
+\retnAbsPathAs(_path);
+_path += "/graphics/AeB_Logo.pdf";
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ nOpacity: 0.2,
+ nRotation: 90,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/docassembly/examples/watermark-text.tex b/macros/latex/contrib/docassembly/examples/watermark-text.tex
new file mode 100644
index 0000000000..4b4c123bc2
--- /dev/null
+++ b/macros/latex/contrib/docassembly/examples/watermark-text.tex
@@ -0,0 +1,26 @@
+\documentclass{article}
+\usepackage{docassembly}
+\usepackage{lipsum}
+
+\hypersetup{pdfpagemode=UseNone}
+
+% Look in the Adobe Acrobat JavaScript manual under the addWatermarkFromText to see all the possible parameters.
+\begin{docassembly}
+\addWatermarkFromText({
+ cText: "Confidential",
+ aColor: color.red,
+ nFontSize: 72,
+ cFont:font.HelvB,
+ bOnTop:false,
+ bOnPrint:false,
+ nOpacity: 0.2,
+ nRotation: 45
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\lipsum[1-30]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/easybook.dtx b/macros/latex/contrib/easybook/easybook.dtx
index 67902b529b..8a99557d42 100644
--- a/macros/latex/contrib/easybook/easybook.dtx
+++ b/macros/latex/contrib/easybook/easybook.dtx
@@ -28,7 +28,7 @@
%
% \title{\sffamily easybook 文档类手册}
% \author{瞿毅}
-% \date{2021/06/16\hskip\ccwd\relax v1.26d\thanks{\url{https://gitee.com/texl3/easybook}}}
+% \date{2021/06/16\hskip\ccwd\relax v1.26e\thanks{\url{https://gitee.com/texl3/easybook}}}
%
% \maketitle
% \begin{abstract}
@@ -157,7 +157,7 @@
% floatpage = <true|(false)>
% \end{syntax}
% 开启这个选项后浮动环境 \env{table} 和 \env{figure} 的比例参数会使用默认值,关闭它则尽可能避免出现浮动页,使图表环境与正文段落更加紧凑,减少多余的空白版面。
-% \changes{v1.26d}{2021/06/15}{增加浮动环境比例参数选项 \opt{floatpage}。}
+% \changes{v1.26e}{2021/06/15}{增加浮动环境比例参数选项 \opt{floatpage}。}
% \end{function}
%
% \subsection{article 模式}
@@ -204,7 +204,7 @@
% aftertitle = <目录标题后的代码>
% pagestyle = <标题页的页面格式>
% \end{syntax}
-% \opt{multoc} 与 \opt{style/multoc} 选项具有相同的效果,但是具有优先性且可单独设置不同目录是否多栏排版,默认为双栏,可使用 \opt{columns} 更改。\opt{title} 选项用于更改目录的标题,标题之间用一个英文逗号分开,也可以只有一部分,表示中文目录的标题。当设置了英文目录标题时,英文目录标题将会自动加入主文档目录,与 \tn{tableofcontents+} 配合输出。
+% \opt{multoc} 与 \opt{style/multoc} 选项具有相同的效果,但是具有优先性且可单独设置不同目录是否多栏排版,栏数默认为双栏,可使用 \opt{columns} 更改。\opt{title} 选项用于更改目录的标题,标题之间用一个英文逗号分开,也可以只有一部分,表示中文目录的标题。当设置了英文目录标题时,英文目录标题将会自动加入主文档目录,与 \tn{tableofcontents+} 配合输出。
% \changes{v1.23}{2021/03/15}{为几个目录增加键值列表的选项,可设置标题输出级别以及是否加入主目录。}
% \changes{v1.24}{2021/04/04}{目录命令的可选参数增加标题键值。}
% \changes{v1.25}{2021/06/02}{目录可设置多栏,并在 article 模式仍然生效。}
@@ -239,7 +239,7 @@
% \tn{EBeforeAddBitoc*}\marg{加入目录英文标题前的代码}
% \end{syntax}
% \tn{appendix} 命令后的章节标题变为附录形式。英文目录中附录标题的格式用可选参数修改,英文附录目录前名字默认为 Appendix\tn{space},后名字默认为空,名字之间用一个半角逗号分开,也可以只有一部分,表示英文附录目录前名字。英文附录目录数字输出命令默认为 \tn{Alph}\{chapter\}。
-% \changes{v1.26d}{2021/06/13}{增加调整英文目录格式的钩子 \tn{EBeforeAddBitoc}。}
+% \changes{v1.26e}{2021/06/13}{增加调整英文目录格式的钩子 \tn{EBeforeAddBitoc}。}
% \end{function}
%
% \tn{EBeforeAddBitoc} 是一个作用于局部范围的英文目录钩子,可以插入标题或目录设置的命令改变英文目录中标题的显示格式,也可以覆盖上述的目录前后名字和编号等设置,带有星号的命令会重置之前的代码,放置在导言区或 \tn{bichapter} 等命令前生效。
@@ -250,7 +250,7 @@
% \begin{syntax}
% \tn{ctexset}\marg{键值列表}
% \end{syntax}
-% \cls{easybook} 扩展了 \CTeX 宏集 \LaTeX 3风格键值的通用控制命令 \tn{ctexset},接口选项同样可用它设置, 原有的键值列表仍然可用。本文档类目前有九个模块用于实现常规的排版功能,如下表所示,它们既是统一接口 \tn{ctexset} 的路径,也是相关模块的接口命令名
+% \cls{easybook} 扩展了 \CTeX 宏集 \LaTeX 3风格键值的通用控制命令 \tn{ctexset},接口选项同样可用它设置, 原有的 \meta{键值列表} 仍然可用。本文档类目前有九个模块用于实现常规的排版功能,如下表所示,它们既是统一接口 \tn{ctexset} 的路径,也是相关模块的接口命令名
% \begin{center}
% \begin{tabular}{*{5}{c}}
% \toprule
@@ -373,11 +373,11 @@
% \label{subsec:other font}
% \begin{function}[EXP,added = 2021-01-08,updated = 2021-05-19]{table-cap,figure-cap,listing-cap,footnote,marginpar,math}
% \begin{syntax}
-% table-cap = <\tn{sffamily}\tn{small}>
-% figure-cap = <\tn{sffamily}\tn{small}>
-% listing-cap = <\tn{sffamily}\tn{small}>
-% footnote = <\tn{rmfamily}>
-% marginpar = <\tn{rmfamily}\tn{footnotesize}>
+% table-cap = <(\tn{sffamily}\tn{small})>
+% figure-cap = <(\tn{sffamily}\tn{small})>
+% listing-cap = <(\tn{sffamily}\tn{small})>
+% footnote = <(\tn{rmfamily})>
+% marginpar = <(\tn{rmfamily}\tn{footnotesize})>
% math = <times|(noto)|notosans|scholax|stix|charter|ebgaramond|libertine|none>
% \end{syntax}
% \ding{229} 以上选项路径为 \opt{subfont/...}
@@ -387,11 +387,11 @@
% \end{function}
%
% \begin{optdesc}
-% \item[table-cap] 表格标题的字体设置。
-% \item[figure-cap] 图片标题的字体设置。
-% \item[listing-cap] 代码标题的字体设置。
-% \item[footnote] 脚注的字体设置,包括脚注标记与内容的字体。
-% \item[marginpar] 边注的字体设置。
+% \item[table-cap] 表格标题的字体设置,包括字体族、字体系列和字体形状命令。
+% \item[figure-cap] 图片标题的字体设置,包括字体族、字体系列和字体形状命令。
+% \item[listing-cap] 代码标题的字体设置,包括字体族、字体系列和字体形状命令。
+% \item[footnote] 设置脚注标记与内容的字体,包括字体族、字体系列和字体形状命令。
+% \item[marginpar] 边注的字体设置,包括字体族、字体系列和字体形状命令。
% \item[math] 选择合适的数学字体,将会加载 \pkg{newtxmath} 和 \pkg{bm} 宏包。使用选项 \opt{none} 时可以使用 \pkg{unicode-math} 等其它数学字体宏包定义字体。
% \end{optdesc}
%
@@ -426,7 +426,7 @@
% \end{function}
%
% \begin{optdesc}
-% \item[\tn{printbibliography}] 两种方式 \textbf{均使用} 此命令打印参考文献,不同处理后端此命令的键值列表不同。使用 \hologo{BibTeX} 处理时选项与小节 \ref{subsec:document command} 目录的选项相同,使用 \hologo{biber} 处理时常用的选项如下
+% \item[\tn{printbibliography}] 两种方式 \textbf{均使用} 此命令打印参考文献,不同处理后端此命令的 \meta{键值列表} 不同。使用 \hologo{BibTeX} 处理时选项与小节 \ref{subsec:document command} 目录的选项相同,使用 \hologo{biber} 处理时常用的选项如下
% \begin{function}{heading,title}
% \begin{syntax}
% heading = <bibliography|subbibliography|(bibintoc)|subbibintoc>
@@ -449,10 +449,10 @@
% bodyfont = <(empty)>
% notefont = <(empty)>
% headfont = <(\tn{color}\{ctex@emph\}\tn{sffamily})>
-% headindent = <(0\tn{ccwd})>
-% spaceabove = <(0.75ex plus .1ex)>
-% spacebelow = <(0.75ex plus .1ex)>
-% spacepost = <(\tn{ccwd})>
+% headindent = <刚性长度|(0\tn{ccwd})>
+% spaceabove = <弹性长度|(0.75ex plus .1ex)>
+% spacebelow = <弹性长度|(0.75ex plus .1ex)>
+% spacepost = <刚性长度|(\tn{ccwd})>
% headformat = <(\tn{NAME}\tn{space}\tn{NUMBER}\tn{NOTE})>
% \end{syntax}
% \ding{229} 以上选项路径为 \opt{thmset/...}
@@ -482,7 +482,7 @@
% 文档类已预置8个定理环境,环境名及对应的定理标题名见小节 \ref{subsec:theorem},如果需要新的定理标题名或定理样式可使用这两个命令,由 \pkg{thmtools} 提供支持,用法与它的同名命令一致。
% \changes{v1.23}{2021/03/12}{重新定义了新定理环境命令 \tn{newtheorem}。}
% \changes{v1.24}{2021/04/25}{增加定义定理环境命令 \tn{EBNewTheorem}。}
-% \changes{v1.26d}{2021/06/15}{定义新定理环境的命令调整为 \tn{declaretheorem}。}
+% \changes{v1.26e}{2021/06/15}{定义新定理环境的命令调整为 \tn{declaretheorem}。}
% \end{function}
%
% \begin{optdesc}
@@ -531,7 +531,7 @@
% includehead = <true|(false)>
% \end{syntax}
% \ding{229} 以上选项路径为 \opt{geoset/...} \\
-% 预置的页面尺寸与 \cls{Word} 的默认值接近,\opt{geoset} 会将前两个之外的选项交给 \pkg{geometry} 宏包接口命令 \tn{geometry} 处理,并且选项的键值列表与之相同,上面的选项仅是一小部分,支持的参数可查阅宏包帮助文档。当在此设置页面大小时,会覆盖 \opt{paper} 选项的设置。
+% 预置的页面尺寸与 \cls{Word} 的默认值接近,\opt{geoset} 会将前两个之外的选项交给 \pkg{geometry} 宏包接口命令 \tn{geometry} 处理,并且 \meta{键值列表} 的选项与之相同,上面的选项仅是一小部分,支持的参数可查阅宏包帮助文档。当在此设置页面大小时,会覆盖 \opt{paper} 选项的设置。
% \changes{v1.21}{2021/01/13}{增加配置页面尺寸的选项。}
% \end{function}
%
@@ -588,7 +588,7 @@
% \tn{markrule}\oarg{长度|(\tn{textwidth})}\parg{颜色名}\marg{线宽|(0.75pt)}[<上间距>+<下间距>]
% \end{syntax}
% 命令 \tn{easyhead} 和 \tn{easyfoot} 的使用方法与 \tn{fancyhead} 和 \tn{fancyfoot} 完全相同,它们需要在 \opt{head-foot} 选项中使用,设置的是一个名为 \opt{fancy} 的页面风格。\pkg{fancyhdr} 将页眉页脚分成了左中右和奇数页(odd)、偶数页(even)共12个部分,可选参数中E、O代表偶数、奇数,L、C、R代表左、中、右部分。单面打印时,含有偶数的选项无效。
-% \changes{v1.26d}{2021/06/14}{增加页眉页脚的横线绘制命令 \tn{markrule}。}
+% \changes{v1.26e}{2021/06/14}{增加页眉页脚的横线绘制命令 \tn{markrule}。}
% \end{function}
%
% 命令 \tn{markrule} 用于绘制页眉页脚横线,长度默认为页面文本区的宽度,上下间距为横线与上下方部件的间距,带有长度单位,间距长度之间用+号分开,若只有一部分则表示上间距,这个命令也可以在正文中绘制横线。下面举一个设置页眉内容的例子
@@ -667,12 +667,12 @@
%
% \begin{function}[EXP,added = 2021-01-13,updated = 2021-05-14]{level/belowoffset,lolskip,tocline-fig,tocline-tab,tocline-lst,belowoffset,line-align,hang,numsep-all,indent-all,rule-all}
% \begin{syntax}
-% belowoffset = <(0pc)>
-% lolskip = <(0.8pc)>
+% belowoffset = <长度|(0pc)>
+% lolskip = <长度|(0.8pc)>
% tocline-fig = <图片目录标签>
% tocline-tab = <表格目录标签>
% tocline-lst = <代码目录标签>
-% belowoffset = <(-1pc)>
+% belowoffset = <长度|(-1pc)>
% line-align = <(true)|false>
% hang = <true|(false)>
% numsep-all = <编号后间距|(\tn{ccwd})>
@@ -735,7 +735,7 @@
% \ \tn{item} <列表内容>
% \tn{end}\marg{环境名}
% \end{syntax}
-% \pkg{enumitem} 宏包为系统预置的列表环境 \env{enumerate}、\env{itemize}和 \env{description} 提供了更灵活的标签以及间距的控制,可使用 \tn{setlist} 命令设置原有的三种列表格式,也可以直接使用可选参数的键值列表,具体选项见 \pkg{enumitem} 宏包文档。已为三种列表预置了三个级别的格式可相互嵌套,默认标签与 \cls{book} 文档类相同,若自定义标签可例如
+% \pkg{enumitem} 宏包为系统预置的列表环境 \env{enumerate}、\env{itemize}和 \env{description} 提供了更灵活的标签以及间距的控制,可使用 \tn{setlist} 命令设置原有的三种列表格式,也可以直接使用可选参数的 \meta{键值列表},具体选项见 \pkg{enumitem} 宏包文档。已为三种列表预置了三个级别的格式可相互嵌套,默认标签与 \cls{book} 文档类相同,若自定义标签可例如
% \changes{v1.24}{2021/04/08}{重新优化列表环境的配置。}
% \end{function}
%
@@ -796,7 +796,7 @@
% \ \tn{item} <习题内容>
% \tn{end}\marg{exercise}
% \end{syntax}
-% 习题环境 \env{exercise} 的标题紧接上一节编号并加入目录与页眉,当使用星号参数时不进行编号,使用+号参数独立编号并启用 \pkg{tcolorbox} 支持生成标题,并使 \opt{color} 生效。第三个键值列表的选项与小节 \ref{subsec:sort list} 排序列表相同,\opt{number} 的编号格式也是如此。第一个键值列表中包含的选项如下
+% 习题环境 \env{exercise} 的标题紧接上一节编号并加入目录与页眉,当使用星号参数时不进行编号,使用+号参数独立编号并启用 \pkg{tcolorbox} 支持生成标题,并使 \opt{color} 生效。第三个 \meta{键值列表} 的选项与小节 \ref{subsec:sort list} 排序列表相同,\opt{number} 的编号格式也是如此。第一个 \meta{键值列表} 中包含的选项如下
% \changes{v1.23}{2021/02/08}{增加准确的习题盒子标题目录锚点。}
% \end{function}
%
@@ -807,7 +807,7 @@
% number = <习题编号格式|(1.)>
% numsep = <编号与标题的间距|(0.5\tn{ccwd})>
% \end{syntax}
-% 第二个键值列表选项在是否使用+号参数时用法不同,使用+号参数时为 \pkg{tcolorbox} 的盒子选项,例如 \opt{boxrule} 和 \opt{fontupper}。不使用+号参数时相当于设置 \tn{ctexset}\{section = {\#1}\} 键值选项列表,例如 \opt{format} 和 \opt{beforeskip}。另外还可以使用 \tn{exerprologue} 命令在习题环境开始前插入一段内容,可以是文本或者代码,需要在每一个习题环境前使用。
+% 第二个 \meta{键值列表} 在是否使用+号参数时用法不同,使用+号参数时为 \pkg{tcolorbox} 的盒子选项,例如 \opt{boxrule} 和 \opt{fontupper}。不使用+号参数时相当于设置 \tn{ctexset}\{section = {\#1}\} 键值选项列表,例如 \opt{format} 和 \opt{beforeskip}。另外还可以使用 \tn{exerprologue} 命令在习题环境开始前插入一段内容,可以是文本或者代码,需要在每一个习题环境前使用。
% \end{function}
%
% \begin{ctexexam}
@@ -820,7 +820,7 @@
%
% \subsection{盒子}
% \label{subsec:box}
-% 使用盒子以及小节 \ref{subsec:exercise} 中的 \env{exercise} 环境需要在导言区 \textbf{手动载入} \pkg{tcolorbox} 宏包,它们的配置键值列表选项同样由 \pkg{tcolorbox} 提供支持,具体选项可见宏包文档的 Option Keys 一节,可以进行边距、字体及背景颜色等各种个性化设置,一些配置会覆盖之前预置的设置。
+% 使用盒子以及小节 \ref{subsec:exercise} 中的 \env{exercise} 环境需要在导言区 \textbf{手动载入} \pkg{tcolorbox} 宏包,它们的配置 \meta{键值列表} 选项同样由 \pkg{tcolorbox} 提供支持,具体选项可见宏包文档的 Option Keys 一节,可以进行边距、字体及背景颜色等各种个性化设置,一些配置会覆盖之前预置的设置。
%
% \subsubsection{摘要盒子}
% \begin{function}[added = 2021-01-05,updated = 2021-05-02]{outline}
@@ -933,7 +933,7 @@
% \tn{index}\marg{标签}
% \tn{printindex*+}\parg{索引名}\oarg{键值列表}
% \end{syntax}
-% \pkg{imakeidx} 宏包可使用索引的功能,重新定义了它的 \tn{printindex} 命令用于生成索引目录,键值列表及用法与小节 \ref{subsec:document command} 相同,但 \opt{multoc} 选项和 \pkg{imakeidx} 原本的接口命令 \tn{indexsetup} 部分选项失效。仅做了简单的设置如将索引设为双栏并加入目录,其他选项可另外配置。
+% \pkg{imakeidx} 宏包可使用索引的功能,重新定义了它的 \tn{printindex} 命令用于生成索引目录,\meta{键值列表} 及选项与小节 \ref{subsec:document command} 相同,但 \opt{multoc} 选项和 \pkg{imakeidx} 原本的接口命令 \tn{indexsetup} 部分选项失效。仅做了简单的设置如将索引设为双栏并加入目录,其他选项可另外配置。
% \changes{v1.24}{2021/05/01}{重新定义 \tn{printindex} 命令与文档适配。}
% \end{function}
%
@@ -1081,7 +1081,7 @@
%<*class>
\NeedsTeXFormat{LaTeX2e}[2020/10/01]
\RequirePackage{l3keys2e}
-\ProvidesExplClass{easybook}{2021/06/16}{1.26d}{beta}
+\ProvidesExplClass{easybook}{2021/06/16}{1.26e}{beta}
\bool_set_false:N \l__eb_compile_draft_bool
\bool_set_false:N \l__eb_title_newline_bool
@@ -1327,15 +1327,16 @@
%<*package>
\NeedsTeXFormat{LaTeX2e}[2020/10/01]
\RequirePackage{etoolbox}
-\ProvidesExplPackage{easybase}{2021/06/16}{1.26d}{beta}
+\ProvidesExplPackage{easybase}{2021/06/16}{1.26e}{beta}
\cs_generate_variant:Nn \eb_ctex_define:nn { nx }
\cs_generate_variant:Nn \int_to_arabic:n { v }
\cs_generate_variant:Nn \int_to_alph:n { v }
-\cs_generate_variant:Nn \dim_add:Nn { NV }
+\cs_generate_variant:Nn \dim_add:Nn { NV,Nv }
\cs_generate_variant:Nn \eb_put_hyperref:n { x }
\cs_generate_variant:Nn \seq_set_from_clist:Nn { No }
\cs_generate_variant:Nn \int_compare:nNnT { oNnT }
+\cs_generate_variant:Nn \prop_set_from_keyval:Nn { NV }
\cs_new_protected:Npn \eb_ctex_define:nn #1
{ \keys_define:nn { ctex/#1 } }
\cs_new_protected:Npn \eb_patch_cmd:nnn #1#2#3
@@ -2240,11 +2241,10 @@
\cs_new_protected:Npn \eb_toc_list_parse:nnnnn #1#2#3#4#5
{
\group_begin:
- \exp_args:NNc
- \tl_set_eq:NN \eb@toc@title { list#4name }
+ \tl_set_eq:Nc \eb@toc@title { list#4name }
\IfValueT{#3}{\keys_set:nn { eb/listoc } {#3}}
\eb_title_number_intoc_bool:nn {#2} {#1}
- \exp_args:NNc \dim_add:NV
+ \dim_add:Nv
\l__eb_toc_offset_dim { l__eb_toc_#4_offset_dim }
\vspace*{\dim_use:N \l__eb_toc_offset_dim}
\eb_toc_start_multicol_bool:n {#5}
@@ -2607,9 +2607,8 @@
within = \l__eb_thm_within_tl,
headformat = \l__eb_thm_headformat_tl
}
-\exp_args:NNV
-\prop_set_from_keyval:Nn \l__eb_thmtools_entry_prop
-\c__eb_thmtools_entry_clist
+\prop_set_from_keyval:NV
+\l__eb_thmtools_entry_prop \c__eb_thmtools_entry_clist
\prop_map_inline:Nn \l__eb_thmtools_entry_prop
{ \eb_ctex_define:nn { thmset } { #1 .tl_set:N = #2 } }
\eb_ctex_define:nn { thmset }
diff --git a/macros/latex/contrib/easybook/easybook.pdf b/macros/latex/contrib/easybook/easybook.pdf
index eae8692d09..fe384ab0a3 100644
--- a/macros/latex/contrib/easybook/easybook.pdf
+++ b/macros/latex/contrib/easybook/easybook.pdf
Binary files differ
diff --git a/macros/latex/contrib/gs1/GS1.dtx b/macros/latex/contrib/gs1/GS1.dtx
index 0f6508d9ce..a69bbf41e8 100644
--- a/macros/latex/contrib/gs1/GS1.dtx
+++ b/macros/latex/contrib/gs1/GS1.dtx
@@ -18,7 +18,7 @@
%
%<*driver|package|test>
\RequirePackage{expl3}[2017/05/29]
-\GetIdInfo$Id: GS1.dtx 22 2017-07-15 18:03:18Z mjk $
+\GetIdInfo$Id: GS1.dtx 23 2021-06-17 07:00:36Z mjk $
{GS1 code handler and barcode generator}
%</driver|package|test>
%<*driver>
@@ -311,10 +311,10 @@
%
% \section{\pkg{GS1} implementation}
% \label{sec:implementation}
-% \iffalse
-%<*package>
+%
+% \begin{macrocode}
%<@@=GS>
-% \fi
+% \end{macrocode}
%
% The implementation has been done in two parts. The first part is the L3
% code with all the functions and variables. The second part is the
@@ -322,12 +322,14 @@
%
% But before this, we just declare, what this is:
% \begin{macrocode}
+%<*package>
\ProvidesExplPackage
{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
% \end{macrocode}
% and what it requires:
% \begin{macrocode}
\RequirePackage{rule-D}
+%</package>
% \end{macrocode}
%
% \subsection{Implementation of Functions and Variables}
@@ -340,12 +342,14 @@
% While this is an internal function, that should allow only some tokens at
% the arguments, it is declared \texttt{nopar}.
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \@@_new_seq_c:cn #1#2
{
\seq_new:c {c@@_ #1 _seq}
\seq_set_split:Nnn \l_tmpa_seq {} {#2}
\seq_gset_eq:cN {c@@_ #1 _seq} \l_tmpa_seq
}
+%</package>
% \end{macrocode}
% \end{macro}
%
@@ -355,6 +359,7 @@
% These constants represent the generation rules of the left side of an EAN-13
% barcode. See figure~5.2.1.3.1-1 of the GS1 specification.
% \begin{macrocode}
+%<*package>
\@@_new_seq_c:cn {AB0} {AAAAAA}
\@@_new_seq_c:cn {AB1} {AABABB}
\@@_new_seq_c:cn {AB2} {AABBAB}
@@ -365,6 +370,7 @@
\@@_new_seq_c:cn {AB7} {ABABAB}
\@@_new_seq_c:cn {AB8} {ABABBA}
\@@_new_seq_c:cn {AB9} {ABBABA}
+%</package>
% \end{macrocode}
% \end{variable}
%
@@ -379,6 +385,7 @@
% the module sequences of type C are same like type A but start with a black
% module instead of a white one.
% \begin{macrocode}
+%<*package>
\@@_new_seq_c:cn {A0} {3211} % start white (C0 same but start with black)
\@@_new_seq_c:cn {A1} {2221}
\@@_new_seq_c:cn {A2} {2122}
@@ -404,14 +411,17 @@
\@@_new_seq_c:cn {special} {111111} % start white
\@@_new_seq_c:cn {extra_margin} {112} % start black
\@@_new_seq_c:cn {extra_separator} {11} % start white
+%</package>
% \end{macrocode}
% \end{variable}
%
% There are some basic dimensions for the modules at the specification:
% \begin{variable}{\c__GS_module_min_width_dim, \c__GS_module_norm_width_dim}
% \begin{macrocode}
+%<*package>
\dim_const:Nn \c_@@_module_min_width_dim {0.264mm}
\dim_const:Nn \c_@@_module_norm_width_dim {0.33mm}
+%</package>
% \end{macrocode}
% \end{variable}
%
@@ -428,6 +438,7 @@
% Needed to set both \cmd{\l_GS_code_type_tl} and \cmd{\l_GS_code_size_int}
% with one key. Together they are the type of code, to be handled.
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \@@_set_key_code:nn #1#2
{
\tl_if_exist:NF \l_GS_code_type_tl { \tl_new:N \l_GS_code_type_tl }
@@ -459,6 +470,7 @@
add_control .bool_set:N = \l_GS_add_control_bool,
add_control .initial:n = false,
}
+%</package>
% \end{macrocode}
% \end{variable}
%
@@ -471,7 +483,9 @@
% This will be used later for several local GS1 sequences. It is private
% and also shouldn't be used in global context.
% \begin{macrocode}
+%<*package>
\seq_new:N \l_@@_code_seq
+%</package>
% \end{macrocode}
% \end{variable}
%
@@ -482,6 +496,7 @@
% only EAN-8 and EAN-13 are supported, both with or without control
% digit. This message will be used as an error message.
% \begin{macrocode}
+%<*package>
\msg_new:nnnn { GS1 } { EAN-code-size }
{
#1~isn't~a~valid~EAN~code~\msg_line_context:.
@@ -491,12 +506,14 @@
nor~a~EAN-13~with~or~without~control~digit.\\\\
The~GS1~module~currently~only~supports~EAN-8~and~EAN~13.
}
+%</package>
% \end{macrocode}
%
% Another message is only a warning message. It will be used whenever the used
% module width would be less than the minimum module width given by the GS1
% specification.
% \begin{macrocode}
+%<*package>
\msg_new:nnn { GS1 } { module/minwidth }
{
Resulting~module~width~is~less~than~allowed~minimum~\msg_line_context:.\\\\
@@ -504,6 +521,7 @@
Currently~the~module~with~would~be~#1.\\
To~avoid~problems,~I'll~increase~module~width~to~#2.
}
+%</package>
% \end{macrocode}
%
% \subsubsection{Functions}
@@ -512,6 +530,7 @@
% \begin{macro}{\GS_set_code_digit_seq:Nn}
% Convert a string into a code sequence ignoring all but digits.
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \GS_set_code_digit_seq:Nn #1#2
{
\seq_set_eq:NN #1 \c_empty_seq
@@ -526,13 +545,12 @@
}
}
}
+%</package>
% \end{macrocode}
%
% \TestFiles{GS_set_code_digit.tex}\UnitTested
-% \iffalse meta-comment
-%</package>
-%<*test&GS.set.code.digit.seq>
% \begin{macrocode}
+%<*test&GS.set.code.digit.seq>
\ExplSyntaxOn
\seq_new:N \l_testa_seq
\seq_new:N \l_testb_seq
@@ -569,10 +587,8 @@ Sequence~for~ISBN~978-3-86541-459-5~is:~
}
\ExplSyntaxOff
-% \end{macrocode}
%</test&GS.set.code.digit.seq>
-%<*package>
-% \fi
+% \end{macrocode}
% \end{macro}
%
% \begin{macro}[updated = 2017-07-15]{\GS_cut_EAN_control_digit:N}
@@ -583,6 +599,7 @@ Sequence~for~ISBN~978-3-86541-459-5~is:~
% a 8 or 13 digits sequence. 7 or 12 digit sequences are already without
% control digit. All other sequences are not supported.
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \GS_cut_EAN_control_digit:N #1
{
\int_case:nnF
@@ -597,13 +614,12 @@ Sequence~for~ISBN~978-3-86541-459-5~is:~
\msg_error:nnn { GS1 } { EAN-code-size } { #1 }
}
}
+%</package>
% \end{macrocode}
-% \TestFiles{GS_cut_EAN_control_digit.tex}\UnitTested
%
-% \iffalse meta-comment
-%</package>
-%<*test&GS.cut.EAN.control.digit>
+% \TestFiles{GS_cut_EAN_control_digit.tex}\UnitTested
% \begin{macrocode}
+%<*test&GS.cut.EAN.control.digit>
\raggedright
\ExplSyntaxOn
\seq_new:N \l_testa_seq
@@ -625,18 +641,17 @@ With~control:~\seq_use:Nnnn \l_testa_seq { ,~ } { ,~} { ,~ }\\
}
Without~control:~\seq_use:Nnnn \l_testa_seq { ,~ } { ,~} { ,~ }\\
\ExplSyntaxOff
-% \end{macrocode}
%</test&GS.cut.EAN.control.digit>
-%<*package>
-% \fi
+% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_set_to_EAN_control_digit:NN}
-% Sets an integer to the control digit calculated with the EAN control digit
-% algorithm for a given code sequence. Note, that the complete code
-% sequence will be used to calculate the control digit. So, if you have a
-% EAN-8 or EAN-13 code sequence, you should cut of the control digit first.
+% Sets an integer to the control digit calculated with the EAN control digit
+% algorithm for a given code sequence. Note, that the complete code
+% sequence will be used to calculate the control digit. So, if you have a
+% EAN-8 or EAN-13 code sequence, you should cut of the control digit first.
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \int_set_to_EAN_control_digit:NN #1#2
{
\int_zero:N #1
@@ -656,13 +671,12 @@ Without~control:~\seq_use:Nnnn \l_testa_seq { ,~ } { ,~} { ,~ }\\
}
\int_set:Nn #1 { \int_mod:nn { 10 - \int_mod:nn { #1 } { 10 } } { 10 } }
}
+%</package>
% \end{macrocode}
-% \TestFiles{int_set_to_EAN_control_digit.tex}\UnitTested
%
-% \iffalse meta-comment
-%</package>
-%<*test&int.set.to.EAN.control.digit>
+% \TestFiles{int_set_to_EAN_control_digit.tex}\UnitTested
% \begin{macrocode}
+%<*test&int.set.to.EAN.control.digit>
\ExplSyntaxOn
\seq_new:N \l_testa_seq
\tl_new:N \l_control_tl
@@ -681,28 +695,26 @@ Control~digit~should~be~\tl_use:N \l_control_tl{} ~
{ \int_set_to_EAN_control_digit:NN }
}
\ExplSyntaxOff
-% \end{macrocode}
%</test&int.set.to.EAN.control.digit>
-%<*package>
-% \fi
+% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\GS_set_EAN_control_digit:N}
% Add a new control digit to a EAN sequence
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \GS_set_EAN_control_digit:N #1
{
\GS_cut_EAN_control_digit:N #1
\int_set_to_EAN_control_digit:NN \l_tmpa_int #1
\seq_put_right:NV #1 \l_tmpa_int
}
+%</package>
% \end{macrocode}
-% \TestFiles{GS_set_EAN_control_digit.tex}\UnitTested
%
-% \iffalse meta-comment
-%</package>
-%<*test&GS.set.EAN.control.digit>
+% \TestFiles{GS_set_EAN_control_digit.tex}\UnitTested
% \begin{macrocode}
+%<*test&GS.set.EAN.control.digit>
\ExplSyntaxOn
\seq_new:N \l_testa_seq
\GS_set_code_digit_seq:Nn \l_testa_seq {ISBN 978-3-86541-459-5}
@@ -720,17 +732,15 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
~but~it~\tl_use:N \t_testa_tl .
\msg_error:nnn { GS1/test } { function } { \GS_set_EAN_control_digit:N }
}
-
\ExplSyntaxOff
-% \end{macrocode}
%</test&GS.set.EAN.control.digit>
-%<*package>
-% \fi
+% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\__GS_modules:Nn, \__GS_modules:NnN, \__GS_modules:cn,
% \__GS_modules_start_black:Nn, \__GS_modules_start_white:Nn}
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \@@_modules:Nn #1#2
{
\seq_map_inline:Nn #1
@@ -775,6 +785,7 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
}
\cs_generate_variant:Nn \@@_modules:Nn { c }
+%</package>
% \end{macrocode}
% \TestFiles{EANBarcode.tex}\UnitTested
% \end{macro}
@@ -783,6 +794,7 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
% Puts the digits, rules, and gaps for an EAN barcode into the input
% stream.
% \begin{macrocode}
+%<*package>
\cs_new_nopar:Npn \GS_use_as_EAN_barcode:N #1
{
\seq_set_eq:NN \l_@@_code_seq #1
@@ -829,6 +841,7 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
\hbox_to_wd:nn { \l_GS_module_wd_dim * 7 } { }
}
+%</package>
% \end{macrocode}
% \TestFiles{EANBarcode.tex}\UnitTested
% \end{macro}
@@ -839,6 +852,7 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
%
% For this, additional packages are needed:
% \begin{macrocode}
+%<*package>
\RequirePackage{xparse}
% \end{macrocode}
%
@@ -854,13 +868,12 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
\int_to_arabic:n { \l_tmpa_int }
\group_end:
}
+%</package>
% \end{macrocode}
% \TestFiles{EANControlDigit.tex}\UnitTested
%
-% \iffalse meta-comment
-%</package>
-%<*test&EANControlDigit>
% \begin{macrocode}
+%<*test&EANControlDigit>
\begin{tabular}{ll}
\hline
Calculated & Known \\
@@ -871,14 +884,13 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
EAN-8: 2012345\EANControlDigit{2012345} & EAN-8: 20123451 \\
\hline
\end{tabular}
-% \end{macrocode}
%</test&EANControlDigit>
-%<*package>
-% \fi
+% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\EANBarcode}
% \begin{macrocode}
+%<*package>
\NewDocumentCommand \EANBarcode
{ o m }
{
@@ -950,13 +962,12 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
\box_use:N \l_tmpa_box
\group_end:
}
+%</package>
% \end{macrocode}
% \TestFiles{EANBarcode.tex}\UnitTested
%
-% \iffalse meta-comment
-%</package>
-%<*test&EANBarcode|GSSetup>
% \begin{macrocode}
+%<*test&EANBarcode|GSSetup>
\raggedright
\verb|\EANBarcode{ISBN 978-3-86541-459-5}|:
\EANBarcode{ISBN 978-3-86541-459-5}
@@ -973,24 +984,22 @@ Control~digit~should~be~ \tl_use:N \l_testb_tl {} ~
\verb|\EANBarcode[code=EAN-8,ocrb=false,add_control]{2012345}|:
\EANBarcode[code=EAN-8,ocrb=false,add_control]{2012345}
-% \end{macrocode}
%</test&EANBarcode|GSSetup>
-%<*package>
-% \fi
+% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\GSSetup}
% \begin{macrocode}
+%<*package>
\NewDocumentCommand \GSSetup
{ m }
{ \keys_set:nn { GS1 } { #1 } }
+%</package>
% \end{macrocode}
-% \TestFiles{GSSetup.tex}\UnitTested
%
-% \iffalse meta-comment
-%</package>
-%<*test&GSSetup>
+% \TestFiles{GSSetup.tex}\UnitTested
% \begin{macrocode}
+%<*test&GSSetup>
After \verb|\GSSetup{ocrb=false,add_control}|:
\GSSetup{ocrb=false,add_control}
@@ -1001,17 +1010,12 @@ After \verb|\GSSetup{ocrb=false,add_control}|:
\EANBarcode[code=EAN-8,ocrb,add_control=false]{20123451}
%</test&GSSetup>
-%<*package>
-% \fi
+% \end{macrocode}
% \end{macro}
%
-%
% \iffalse
-%</package>
%<*test>
-% \begin{macrocode}
\end{document}
-% \end{macrocode}
%</test>
% \fi
% \end{implementation}
diff --git a/macros/latex/contrib/gs1/GS1.pdf b/macros/latex/contrib/gs1/GS1.pdf
index 621c30aba9..9cb7557730 100644
--- a/macros/latex/contrib/gs1/GS1.pdf
+++ b/macros/latex/contrib/gs1/GS1.pdf
Binary files differ
diff --git a/macros/latex/contrib/gs1/README.distributors b/macros/latex/contrib/gs1/README.distributors
deleted file mode 100644
index a56d43dcaa..0000000000
--- a/macros/latex/contrib/gs1/README.distributors
+++ /dev/null
@@ -1,10 +0,0 @@
-Distributors please note:
-
-GS1 is an experimental package using expl3.
-
-Directory GS1 is a distribution of source an doc, that
-may be used by CTAN for tex-archive/macros/latex/contrib/GS1.
-
-GS1.tds.zip is a TDS distribution of GS1.
-You may use it for distributions like CTAN's
-/tex-archive/install/macros/latex/contrib/GS1.tds.zip.
diff --git a/macros/latex/contrib/gs1/rule-D.dtx b/macros/latex/contrib/gs1/rule-D.dtx
index 6397e62b3b..98cd347dfe 100644
--- a/macros/latex/contrib/gs1/rule-D.dtx
+++ b/macros/latex/contrib/gs1/rule-D.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-%% File: rule-D.dtx Copyright (C) 2012 Markus Kohm
+%% File: rule-D.dtx Copyright (C) 2017-2021 Markus Kohm
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -17,8 +17,8 @@
%% -------------------------------------------------------------------------
%
%<*driver|package>
-\RequirePackage{expl3}[2017/05/29]
-\GetIdInfo$Id: rule-D.dtx 22 2017-07-15 18:03:18Z mjk $
+\RequirePackage{expl3}[2019/01/17]
+\GetIdInfo$Id: rule-D.dtx 23 2021-06-17 07:00:36Z mjk $
{rule functions for LaTeX3}
%</driver|package>
%<*driver>
@@ -80,9 +80,10 @@
% \section{\pkg{rule-D} implementation}
% \label{sec:rule-D:implementation}
%
-%\iffalse meta-comment
+% \begin{macrocode}
%<*package>
-%\fi
+%<@@=rule>
+% \end{macrocode}
%
% First of all we have to setup package information:
% \begin{macrocode}
@@ -91,7 +92,7 @@
{experimental~L3~rule~functions}
% \end{macrocode}
%
-% \begin{macro}{\rule:nn , \rule:nnn}
+% \begin{macro}[updated = 2021-06-17]{\rule:nn , \rule:nnn}
% \begin{macrocode}
\cs_new:Npn \rule:nn #1#2
{
@@ -100,10 +101,12 @@
\cs_new:Npn \rule:nnn #1#2#3
{
% \end{macrocode}
-% Following line is same like \cs{leavevmode}, but it's \LaTeX3 instead of
-% plain\TeX.
+% \changes{v23}{2021/06/17}{deprecated \cs{hbox_unpack_clear} replaced by
+% \cs{hbox_unpack_drop}}
+% Following line is same like \cs{leavevmode}, but it's \LaTeX3 instead of
+% plain\TeX.
% \begin{macrocode}
- \hbox_unpack_clear:N \c_empty_box
+ \hbox_unpack_drop:N \c_empty_box
\hbox:n
{
\tex_vrule:D width \dim_eval:n { #2 }
@@ -114,9 +117,9 @@
% \end{macrocode}
% \end{macro}
%
-%\iffalse meta-comment
+% \begin{macrocode}
%</package>
-%\fi
+% \end{macrocode}
%
% \end{implementation}
%
@@ -125,3 +128,9 @@
\endinput
%
% end of file
+
+% \endinput
+% Local Variables:
+% mode: doctex
+% TeX-master: t
+% End:
diff --git a/macros/latex/contrib/gs1/rule-D.pdf b/macros/latex/contrib/gs1/rule-D.pdf
index ac07a34437..d228b0148d 100644
--- a/macros/latex/contrib/gs1/rule-D.pdf
+++ b/macros/latex/contrib/gs1/rule-D.pdf
Binary files differ
diff --git a/macros/latex/contrib/msu-thesis/README.md b/macros/latex/contrib/msu-thesis/README.md
index 725896b877..37e6fc2f2e 100644
--- a/macros/latex/contrib/msu-thesis/README.md
+++ b/macros/latex/contrib/msu-thesis/README.md
@@ -1,4 +1,4 @@
-# MSU Thesis Class Version 2.9c 2021/05/07
+# MSU Thesis Class Version 3.0 2021/06/10
Copyright 2011-2021 by Alan Munn <amunn@msu.edu>
@@ -49,7 +49,7 @@ A template file:
A test file and a test bibliography:
`MSU-thesis-testfile.tex`
- `MSU-theis-testfile.bib`
+ `MSU-thesis-testfile.bib`
Use at your own risk! Report bugs/problems/questions to [amunn@msu.edu](mailto:amunn@msu.edu) or use the [GitHub repository bug tracker](https://github.com/amunn/msu-thesis/issues).
diff --git a/macros/latex/contrib/msu-thesis/msu-thesis.cls b/macros/latex/contrib/msu-thesis/msu-thesis.cls
index f9c1c273f7..8fc9939364 100644
--- a/macros/latex/contrib/msu-thesis/msu-thesis.cls
+++ b/macros/latex/contrib/msu-thesis/msu-thesis.cls
@@ -151,14 +151,23 @@
% Added warning when public abstract is used.
% Minor changes to the documentation
% Removed unified.bst from distribution; replaced with apalike in the test file.
+% Version 3.0 2021/06/10 Full support for per-chapter appendices and bibliographies.
+% Added global chapter counter for proper hyperrefs to appendices
+% Added a formatting hook for appendix numbering. We'll see how this works in practice.
+% Added spacing hooks for bibliographies to make users' lives a little easier
%
% Report bugs/problems/questions to <amunn@msu.edu>
%
-\def\msu@version{2.9c}
-\def\msu@date{2021/05/07}
+\def\msu@version{3.0}
+\def\msu@date{2021/06/10}
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{msu-thesis}[\msu@date\space Michigan State University Thesis Class version \msu@version]
\newif\ifmsu@dissertation\msu@dissertationtrue % added v2.7 boolean for \msu@thesistype
+\newif\ifmsu@chapterbib\msu@chapterbibfalse % added v3.0
+\def\msu@bibtype{BIB}
+\newif\ifmsu@chapterapp\msu@chapterappfalse % added v3.0
+\def\msu@apptype{APP}
+\newcommand*\msuappendixnumformat{\Alph{chapter}}% Appendices are Alpha numbered
\newif\ifmsu@lscape\msu@lscapefalse
\newif\ifmsu@stupidtoc\msu@stupidtocfalse
\newif\ifmsu@mixedtoc\msu@mixedtocfalse
@@ -188,7 +197,14 @@
\DeclareOption{boldtoc}{\msu@stupidtoctrue\msu@plaintocfalse\msu@mixedtocfalse}
\DeclareOption{plaintoc}{\msu@plaintoctrue\msu@stupidtocfalse\msu@mixedtocfalse}
\DeclareOption{mixedtoc}{\msu@mixedtoctrue\msu@stupidtocfalse\msu@plaintocfalse}
-\DeclareOption{12pt}{\def\msu@sizeoption{12pt}} % added v 2.9
+\DeclareOption{chapterbib}{\global\msu@chapterbibtrue\def\msu@bibtype{CHAPBIB}} % per-chapter bibliographies added v3.0
+\DeclareOption{chapterapp}{
+ \global\msu@chapterapptrue
+ \def\msu@apptype{CHAPAPP}
+ % per-chapter appendices added v3.0
+ \renewcommand\msuappendixnumformat{\the@ppsavesec\Alph{chapter}} % Appendix numbers per-chapter (now permitted)
+}
+\DeclareOption{12pt}{\def\msu@sizeoption{12pt}} % added v2.9
\DeclareOption{11pt}{\def\msu@sizeoption{11pt}}
\DeclareOption{10pt}{\def\msu@sizeoption{10pt}}
\ExecuteOptions{PhD,12pt}
@@ -201,12 +217,12 @@
\ifx\e@alloc\@undefined
\RequirePackage{etex}
\fi
+\RequirePackage{etoolbox}
% set up landscape page numbering
% make a boolean for selecting pagestyle properly if \chapter appears in a landscape environment
\newif\ifmsu@lscapemode\msu@lscapemodefalse
\ifmsu@lscape
\RequirePackage{pdflscape} % this will cause physical pages to be rotated in the PDF
- \RequirePackage{etoolbox}
\AtBeginEnvironment{landscape}{\msu@lscapemodetrue} % to get chapter pagestyle correct
\RequirePackage{tikz}
% adjust \msu@landscapeyshift to meet the thesis office requirements
@@ -239,6 +255,9 @@
\newcommand*{\msu@titleintro}{A~} % this is the beginning to the title page phrase
\newcommand*{\msu@fieldseparator}{\textendash} % this is between the degree name and field of study
+\newcounter{msu@hchap} % global counter for chapters used by hyperref
+
+
% make title 2in from top of page
% This value is crazy because the grad school doesn’t know how to measure
\setlength{\droptitle}{.25in} % changed again due to topskip removal 12/13/17
@@ -246,6 +265,7 @@
% set up the title page
% Because the title is set to \MakeUppercase we need to \protect line
% breaks within the title. This has now been documented in the user docs.
+% Using \onelineskip here instead of \baselineskip because thesis office doesn't know how to measure
\newcommand*\msu@thesistype{\ifmsu@dissertation{DISSERTATION}\else{THESIS}\fi}
\pretitle{\begin{center}\MakeUppercase}
\posttitle{\\[\onelineskip]\end{center}}
@@ -269,6 +289,8 @@
\renewcommand{\parttitlefont}{\SingleSpacing\bfseries}
\renewcommand{\printpartname}{\partnamefont{\MakeUppercase{\partname}}}
\renewcommand{\printparttitle}[1]{\parttitlefont \MakeUppercase#1}
+% Set epigraph fonts to \normalsize
+\renewcommand{\epigraphsize}{\normalsize} % added 2/26/21
% set up the section styles
@@ -311,19 +333,52 @@
\fi
%
-% This code from http://tex.stackexchange.com/q/232121/
+% This code technique from http://tex.stackexchange.com/q/232121/
% Makes appendices formatted as sections not chapters in the TOC
% This is due to MSU idiocy, and also will make the appendix name
% upper case (because of MSU case matching requirements in TOC/chap)
% So the appendices are chapters in the document but formatted as
-% sections in the TOC. Code needs to be changed back for the bibliography
+% sections in the TOC. Code needs to be changed back for subsequent chapters.
+% This also accounts for the bizarre formatting of per-chapter appendices and
+% bibliographies which look like chapters except for the spacing in the TOC
+%
+% This allows for a uniform user interface for both end of document
+% and per chapter appendices.
+
+% This code leaves the spacing alone
\cftinsertcode{APP}{
+ \renewcommand\cftsectionfont{\msu@tocfont} % fixed 12/13/17
+ \renewcommand\cftchapterpagefont{\msu@tocfont}
+% \renewcommand*{\cftappendixname}{APPENDIX\space}
+}
+% This code removes the before chapter spaces for in-chapter apps
+\cftinsertcode{CHAPAPP}{
+ \setlength\cftbeforechapterskip{0pt}
+ \renewcommand\cftsectionfont{\msu@tocfont} % fixed 12/13/17
+ \renewcommand\cftchapterpagefont{\msu@tocfont}
+ \renewcommand*{\cftappendixname}{APPENDIX\space}
+}
+
+% This code adds extra space in the TOC margin for the APPENDIX name, and
+% makes the appendices formatted like sections even though they are
+% chapters in the source
+
+\newlength\apptoclen
+\settowidth{\apptoclen}{APPENDIX M}
+\cftinsertcode{APPENDICES}{
\setlength\cftchapterindent{\cftsectionindent}
+ \setlength\cftsectionnumwidth{\apptoclen} % add the extra space
\setlength\cftbeforechapterskip{0pt}
\renewcommand\cftsectionfont{\msu@tocfont} % fixed 12/13/17
\renewcommand\cftchapterpagefont{\msu@tocfont}
\renewcommand*{\cftappendixname}{APPENDIX\space}
}
+
+% This code resets the TOC back to normal section spacing if appendices have been used
+
+\cftinsertcode{CHAPAPPR}{
+\cftsetindents{section}{1.5em}{2.3em}
+}
% This code resets the changes made in the APP code back to normal
% so that the bibliography will appear correctly in the TOC
\cftinsertcode{BIB}{
@@ -333,6 +388,14 @@
\renewcommand\cftchapterpagefont{\msu@chapfont}
}
+\cftinsertcode{CHAPBIB}{
+ \setlength\cftchapterindent{0em}
+ \setlength\cftbeforechapterskip{0pt}
+ \renewcommand\cftsectionfont{\msu@tocfont} % fixed 12/13/17
+ \renewcommand\cftchapterpagefont{\msu@tocfont}
+}
+
+
% Set up all the font styles for the TOC
\renewcommand*{\cftchapterfont}{\msu@chapfont}
\renewcommand*{\cftchapterpagefont}{\msu@chapfont}
@@ -356,6 +419,7 @@
% Added to make sure that chapters within landscape mode have correct pagestyle
\renewcommand\chapter{%
+ \refstepcounter{msu@hchap}
\ifartopt\par\@nameuse{chapterblock}\else
\clearforchapter
\ifmsu@lscapemode
@@ -418,7 +482,7 @@
\newcounter{msu@pubabspages}
\newcommand{\publicabstractname}{\abstractname}
\newenvironment{publicabstract}{%
- \ClassWarning{msu-thesis}{You have provided a public abstract. Please make sure you ALSO have a regular abstract!}
+ \ClassWarningNoLine{msu-thesis}{You have provided a public abstract. Please make sure you ALSO have a regular abstract!}
\setcounter{msu@pubabspages}{\value{page}}
\setlength{\afterchapskip}{\onelineskip} % changed 2020/12/14 again removed manual spacing from 2016
\chapter*{\publicabstractname}
@@ -474,10 +538,6 @@
\renewcommand{\mainmatter}{%
\DoubleSpacing\pagestyle{plain}\@ifstar{\@smemmain}{\@memmain}}
-% This should probably be changed to {\null\vfill} + \afterpartskip
-% But we'll worry about this later.
-%\renewcommand{\beforepartskip}{\vspace*{.35\textheight}}
-%\renewcommand{\beforepartskip}{\vspace*{\fill}}
\renewcommand{\beforepartskip}{\null\vfill}
\renewcommand{\afterpartskip}{\null\vfill\newpage}
@@ -488,35 +548,68 @@
% Also, since the Grad School doesn't allow a single appendix to have a letter name
% we remove it for the title, but not for the section headings.
% Redefining \@apppage as well to get the spacing right 2016/06/08
+% Modified 2021/06/10 to deal with both in-chapter and end of document appendices
%
\newcommand{\msu@apppage}{%
\@setuppart
+ \cftinserthook{toc}{\msu@apptype} % extra space or not added 2021/06/10
\mempreaddapppagetotochook
\addappheadtotoc
\mempostaddapppagetotochook
\partmark{\appendixpagename}%
\memapppageinfo{\appendixpagename}%
+ \cftinserthook{toc}{APPENDICES} % reset for subappendices added 2021/06/10
{\centering
\interlinepenalty \@M
\normalfont
\printparttitle{\appendixpagename}\par}%
+ \cftinserthook{toc}{CHAPAPPR} % reset added 2021/06/10
\@endpart}
-\let\orig@appendix\appendix
-\let\orig@appendices\appendices
-\renewcommand*{\appendix}{
- \renewcommand\appendixpagename{Appendix}
- \renewcommand\appendixtocname{Appendix}
- \msu@apppage
- \settocdepth{part}
- \orig@appendix
- \renewcommand\thechapter{}
- \renewcommand\thesection{A.\arabic{section}}}
-\renewcommand*{\appendices}{
- \msu@apppage
- \cftinserthook{toc}{APP}
- \settocdepth{chapter}
- \orig@appendices}
+%
+% Code for appendix/appendices
+% Because the thesis office wants chapter appendices to look like chapters
+% we make the same code work for per-chapter or global appendices
+%
+% Instead of using \appendix we create an {appendix} environment for a single
+% appendix. This allows the same code to be used for both global and per chapter
+% appendices.
+%
+\renewenvironment{appendix}%
+ {\renewcommand{\appendixname}{Appendix}
+ \renewcommand{\appendixtocname}{Appendix}
+ \renewcommand{\appendixpagename}{Appendix}
+ \ifmsu@chapterapp\else\renewcommand\msuappendixnumformat{}\fi% make sure single appendix doesn't have a number if global
+ \msu@apppage\settocdepth{part}\@resets@pp\anappendixtrue}%
+ {\@ppsaveapp\@pprestoresec\anappendixfalse}
+
+\renewenvironment{appendices}%
+ {\msu@apppage\settocdepth{chapter}
+ \@resets@pp\anappendixtrue}%
+ {\@ppsaveapp\@pprestoresec\anappendixfalse}
+
+% The default numbering that memoir assumes is for appendices
+% is sequential throughout the document; the thesis office
+% requires them to restart from A every chapter. In case they
+% ever allow a saner numbering system we provide the \msuappendixnumberformat hook
+% for modifying the numbering scheme if allowed.
+%
+
+\renewcommand{\@resets@pp}{%
+ \par
+ \@ppsavesec
+ \setcounter{section}{0}%
+ \setcounter{chapter}{0}%
+ \renewcommand\@chapapp{\appendixname}%
+ \renewcommand\thechapter{\msuappendixnumformat}%
+ \restoreapp
+ }
+
+
+% Don't save the appendix counters even for per-chapter appendices
+
+\let\restoreapp\relax
+
% make the bibliography page
% new version modelled after memoir code for appendix page
@@ -524,7 +617,7 @@
\newcommand\msu@bibpage{%
\let\bibtocname\bibname % moved inside this page to beat apacite
\let\bibpagename\bibname
- \cftinserthook{toc}{BIB}
+ \cftinserthook{toc}{\msu@bibtype}
\settocdepth{subsubsection} % changed v2.7 to allow for chapter bibs
\@setuppart
\msu@preaddbibpagetotochook
@@ -536,14 +629,21 @@
\interlinepenalty \@M
\normalfont
\printparttitle{\bibpagename}\par}%
- \@endpart}
+ \@endpart
+ \cftinserthook{toc}{BIB}}
+
\newcommand\msu@preaddbibpagetotochook{}
\newcommand\msu@postaddbibpagetotochook{}
\newcommand{\msu@bibpageinfo}[1]{}
\renewcommand{\prebibhook}{\vspace{\cftparskip}} % add extra space before entries to match ToC etc. 6/15/17
\newcommand\msu@addbibheadtotoc{%
- \phantomsection\addcontentsline{toc}{chapter}{\bibtocname}}
+ \ifmsu@chapterbib
+ \phantomsection\addcontentsline{toc}{section}{\bibtocname}
+ \else
+ \phantomsection\addcontentsline{toc}{chapter}{\bibtocname}
+ \fi
+ }
% Since the bibliography page is the TOC entry we remove the bib in the TOC
% when it's introduced
\nobibintoc
@@ -551,18 +651,27 @@
% This should also work for biblatex even though memoir doesn't check for it
\newcommand*{\makebibliographypage}{\msu@bibpage}
-\let\makebibliographycover\makebibliographypage
+%\let\makebibliographycover\makebibliographypage No longer needed for compatibility
+
+% Informational warnings
+%
+\AtEndDocument{%
+\ifmsu@dissertation\else\ClassWarningNoLine{msu-thesis}{Masters theses MUST have chapters to be formatted correctly!}\fi
+}
% Do some stuff at begin document:
\AtBeginDocument{%
\let\msucaptiondelim\@contdelim
% Moved to AtBeginDocument to override apacite
\@ifpackageloaded{apacite}{\@tocbibfalse}{} % added 6/22/17
+% Make bibliography spacing more automatic for biblatex and natbib users 2021/06/10
+% This should cover most cases. Otherwise just set single spacing
+\@ifpackageloaded{biblatex}
+ {\renewcommand{\bibsetup}{\SingleSpacing\setlength{\bibitemsep}{\baselineskip}}} % biblatex
+ {\@ifpackageloaded{natbib}
+ {\AtBeginEnvironment{thebibliography}{\SingleSpacing\setlength{\bibsep}{\baselineskip}}} % natbib
+ {\AtBeginEnvironment{thebibliography}{\SingleSpacing}}} % any other bib package
%\topskip=0pt % setting this because the Grad School doesn’t know how to measure -changed back 6/15/17
\checkandfixthelayout
-
-% Set epigraph fonts to \normalsize
-\renewcommand{\epigraphsize}{\normalsize} % added 2/26/21
-
%
% set up subscript sizes so that 10 pt is the smallest
% (MSU Requirement)
@@ -577,15 +686,18 @@
% Thanks to Florent Chervet for the code.
% Added hypersetup to remove borders around links 5/9/16
\@ifpackageloaded{hyperref}%
-{\hypersetup{pdfborder= 0 0 0}\msu@hyperloadedtrue
+{\hypersetup{pdfborder= 0 0 0}
+\msu@hyperloadedtrue
\def\MakeLinkUppercase \hyper@linkstart #1#2#3\hyper@linkend
{\hyper@linkstart {#1}{#2}{\MakeUppercase{#3}}\hyper@linkend }
\pdfstringdefDisableCommands{\let\MakeUppercase \@firstofone }
\renewcommand*{\l@chapter}[2]{%
\l@chapapp{\MakeLinkUppercase #1}{#2}{\cftchaptername}} % Format chapter names
\renewcommand*{\l@appendix}[2]{%
- \l@chapapp{\MakeLinkUppercase #1}{#2}{\cftappendixname}}} % Format appendix names (changed 13/12/17)
-% if no hyperref
+ \l@chapapp{\MakeLinkUppercase #1}{#2}{\cftappendixname}} % Format appendix names (changed 13/12/17)
+\apptocmd{\@resets@pp}{\gdef\theHchapter{\Alph{msu@hchap}}}{}{} % get hypertargets in appendices right (added v3.0)
+}
+ % if no hyperref
{\relax}
}
\endinput
diff --git a/macros/latex/contrib/msu-thesis/msu-thesis.pdf b/macros/latex/contrib/msu-thesis/msu-thesis.pdf
index ade9bd139c..96496dc77b 100644
--- a/macros/latex/contrib/msu-thesis/msu-thesis.pdf
+++ b/macros/latex/contrib/msu-thesis/msu-thesis.pdf
Binary files differ
diff --git a/macros/latex/contrib/msu-thesis/msu-thesis.tex b/macros/latex/contrib/msu-thesis/msu-thesis.tex
index 0b0b57ddf5..5afea970ad 100644
--- a/macros/latex/contrib/msu-thesis/msu-thesis.tex
+++ b/macros/latex/contrib/msu-thesis/msu-thesis.tex
@@ -2,8 +2,8 @@
\documentclass[11pt]{article}
-\def\msuversion{2.9c}
-\def\msudate{2021/05/07}
+\def\msuversion{3.0}
+\def\msudate{2021/06/10}
\title{\textbf{Using the MSU Thesis Class}}
\author{\textbf{Alan Munn}\\Department of Linguistics and Languages\\\texttt{\href{mailto:amunn@msu.edu}{amunn@msu.edu}}}
\date{Version \msuversion\\\msudate}
@@ -70,11 +70,11 @@
\abstract{\noindent\begin{quote} This is a class file for MSU theses and dissertations. It is based on the \pkg{memoir} class, and therefore supports all of the functionality of that class. It should generate a document which meets all the basic formatting requirements laid out by the \href{https://grad.msu.edu/etd/formatting-guide}{Formatting Guide For Submission of Master’s Theses and Doctoral Dissertations} (March 2020) produced by the Graduate School, including requirements for margins, titlepage, page numbering, section titles, sub- and superscript sizes etc.\end{quote}}
\section{Introduction}
-Formatting a dissertation according to a University's thesis requirements is not always a simple task in \LaTeX, especially since the requirements are generally aimed at MSWord users. Furthermore, most of the work of formatting a document is supposed to be done by the document class itself, and not by the individual user. Fortunately, Michigan State University's thesis requirements are actually sane, and fairly straightforward. The present class file is designed to further make the process easier for \LaTeX\ users, by doing all the heavy lifting for you, so that you can focus on the content and not the formatting.
+Formatting a dissertation according to a University's thesis requirements is not always a simple task in \LaTeX, especially since the requirements are generally aimed at MSWord users. Furthermore, most of the work of formatting a document is supposed to be done by the document class itself, and not by the individual user. Fortunately, Michigan State University's thesis requirements are for the most part sane, and fairly straightforward. The present class file is designed to further make the process easier for \LaTeX\ users, by doing all the heavy lifting for you, so that you can focus on the content and not the formatting.
\section{Background}
The MSU Thesis Class is based on the \pkg{memoir} document class. The \pkg{memoir} class is an extensive class that incorporates the functionality of many other packages into it. The class is extensively documented, and the documentation (\pkg{memman.pdf}) should be available with any \TeX\ distribution. I strongly recommend that you familiarize yourself with \pkg{memoir} as you use the present class.
\section{Class Options}
-In addition to any options passed to the \pkg{memoir} class (e.g. |oldfontcommands|; see Section \ref{sec:fonts}, font size), the \pkg{msu-thesis} takes three options: one to specify the type of degree, (see Table~\ref{degrees}), one to enable landscape page numbering, and one to make small adjustments to Table of Contents. If no degree option is specified, a Ph.D. dissertation is assumed.
+In addition to any options passed to the \pkg{memoir} class (e.g. |oldfontcommands|; see Section \ref{sec:fonts}, font size), the \pkg{msu-thesis} takes five options: one to specify the type of degree, (see Table~\ref{degrees}), one to enable landscape page numbering, two to enable per-chapter bibliographies and appendices, and one to make small adjustments to Table of Contents. If no degree option is specified, a Ph.D. dissertation is assumed.
\begin{table}
\centering
\begin{tabularx}{.8\textwidth}{>{\ttfamily}lX}
@@ -84,6 +84,7 @@ In addition to any options passed to the \pkg{memoir} class (e.g. |oldfontcomman
{[PhD]} & Doctor of Philosophy (default)\\
{[DEd]} & Doctor of Education\\
{[DMA]} & Doctor of Musical Arts\\
+{[DNP]} & Doctor of Nursing Practice\\
{[MA]} & Master of Arts\\
{[MS]} & Master of Science\\
{[MAT]} & Master of Arts for Teachers \\
@@ -103,6 +104,10 @@ In addition to any options passed to the \pkg{memoir} class (e.g. |oldfontcomman
\end{table}
\subsection{The \pkg{[lscape]} option}
The Formatting Guide requires that any lansdscape pages be numbered in landscape mode (i.e. along the long edge of the page) rather than in portrait mode, and rotated in the final PDF. The |[lscape]| option enables this. The option loads both the \pkg{pdflscape} package and \pkg{tikz}, and is implemented as a class option so that you are not required to load those packages if they are not needed.
+\subsection{The \pkg{[chapterbib]} option}
+This option enables per-chapter bibliographies. Each chapter must have its own bibliography. If you are using \pkg{natbib} for bibliographies, per-chapter bibliographies can be implemented using the \pkg{chapterbib} package. Please read its documentation carefully, as it requires each chapter to be a separate file. An newer alternative which I highly recommend is to use \pkg{biblatex} for your bibliography, which makes per-chapter bibliographies very simple. If you have per-chapter bibliographies you cannot have a global bibliography.
+\subsection{The \pkg{[chapterapp]} option}
+This option enables per-chapter appendices. Any appendix must be associated with its own chapter. If you have per-chapter appendices you cannot have any global appendices.
\subsection{The contents options}
In 2013 I received reports that the thesis office now requires all elements in the Table of Contents to have the same formatting as they are in the main document, which means that all section, subsection, and subsubsection headings need to be bold. Since this looks very ugly, I have created two options to turn it off, the |[plaintoc]| option (which makes all ToC entries plain) and |[mixedtoc]| option (which makes Chapters bold and other elements plain). I suspect that the thesis office checkers don't notice this all the time so if you want to have a prettier table of contents and are willing to have that format be corrected, you can use these options to turn off the MSWord inspired ugliness of an entirely bold Table of Contents. I've made |[plaintoc]| the default. If you are forced by the thesis office to have an entirely bold ToC, use the |[boldtoc]| option.
\subsection{Font size options}\label{fontsize}
@@ -170,7 +175,7 @@ The \pkg{memoir} class provides commands for single and double spacing (|\Single
\sloppy The \pkg{memoir} class enforces the so-called ``new'' font changing commands (although they have now been in use for many years.) This means that it does not allow you to use the commands |\bf|, |\it|, |\rm|, etc. Unfortunately there are some old packages that still use these commands, and there is also some outdated information on the web that might have examples using these commands. You should generally not use these commands (see \href{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=2letterfontcmd}{Two Letter Font Commands}); if you do encounter problems, you can pass the option |[oldfontcommands]| to the class.
\subsection{Extra Packages}
The \pkg{memoir} class replicates the functionality of many independent packages, so if you are transferring \LaTeX\ source from other documents using the \pkg{article} class, you may encounter some warnings or errors. The \pkg{memoir} documentation has substantial information about the packages it emulates, and the packages for which it provides equivalent functionality. See Chap. 18 Sec. 24 of the \pkg{memoir} manual for details. Quoting from the manual:
-\begin{quote} \pkg{memoir} emulates the following packages: {\sffamily abstract, appendix, array, booktabs, ccaption, chngcntr, crop, dcolumn, delarray, enumerate, epigraph, ifmtarg, ifpdf, index, makeidx, moreverb, needspace, newfile, nextpage, pagenote, patchcmd, parskip, setspace, shortvrb, showidx, tabularx, titleref, tocbibind, tocloft, verbatim}, and {\sffamily verse}. It also provides functions equivalent to those in the following packages, although the class does not prevent you from using them: {\sffamily fancyhdr, framed, geometry, sidecap, subfigure}, and \sffamily{titlesec}.\\\hfill{\normalfont\emph{The Memoir Class} 8th Ed. 2010, p.339}
+\begin{quote} At the time of writing the emulated packages are: {\sffamily abstract, appendix, booktabs, ccaption, chngcntr, crop, enu- merate, epigraph, ifmtarg, ifpdf, index, makeidx, moreverb, needspace, newfile, nextpage, pagenote, patchcmd, parskip, setspace, shortvrb, showidx, titleref, tocbibind, tocloft, verbatim, and verse.} As well as the emulated packages memoir provides functions equivalent to those in the following packages, although the class does not prevent you from using them: {\sffamily fancyhdr, framed, geometry, sidecap, subfigure, and titlesec.}\\\hfill{\normalfont\emph{The Memoir Class} 10th impression, 2015, p.345}
\end{quote}
\subsection{Captions}
\subsubsection{Caption delimiter}
@@ -243,15 +248,16 @@ If you have large figures and tables that must be rotated, you should use the |[
The |landscape| environment makes all pages within it landscape, so if you have multiple landscape figures in a row, you can put all of them inside a single |landscape| environment. This option correctly rotates the landscape pages within the pdf document itself, which the thesis office seems to require.
\subsection{Appendices}
-Appendices in a thesis are usually at the end of the document, but before the bibliography. MSU requires appendices to be preceded by a cover page which says either ``Appendix'' (if there is only one) or ``Appendices'' if there is more than one. Memoir deals with multiple appendices by using an |appendices| environment.
+Appendices in a thesis are usually at the end of the document, but before the bibliography. MSU requires appendices to be preceded by a cover page which says either ``Appendix'' (if there is only one) or ``Appendices'' if there is more than one. The class implements this with two environments: |{appendix}| for a single appendix and |{appendices}| for multiple appendices. If your thesis organization requires appendices per-chapter, you must use the |[chapterapp]| class option. In either case, the code for appendices is identical.
\subsubsection{Single appendix}
-If you have a single appendix, your code should look like this:
+If you have a single appendix, your code should look like this:
\begin{quote}
\begin{lstlisting}
-\appendix
+\begin{appendix}
\chapter{Your appendix title}
Appendix text goes here
+\end{appendix}
\end{lstlisting}
\end{quote}
@@ -270,20 +276,12 @@ Appendix text goes here
\end{quote}
\subsubsection{Appendices per chapter}
-If you need to add an appendix or appendices to a chapter, you should use the |subappendices| environment and use |\section| for each appendix. So your code should look like this:
+If you need to add an appendix or appendices to a chapter, you must use the \pkg{[chapterapp]} class option. The code for the appendices themselves is exactly as described above.
-\begin{quote}
-\begin{lstlisting}
-\begin{subappendices}
-\section{Your first appendix title}
-Appendix text goes here
-\section{Your second appendix title}
-Appendix text goes here
-\end{subappendices}
-\end{lstlisting}
-\end{quote}
-\subsection{Bibliography spacing}\label{bibspacing}
-Please note that although bibliography entries must be single spaced, there must be a space between each entry. This parameter is set by your bibliography package and not by the class itself. If you are using |natbib| it is |\bibsep| and if you are using |biblatex| it is |\bibitemsep|. These are lengths and may be set by using |\setlength|. Depending on your bibliography style, you may need to set these to be |\baselineskip|, e.g. |\setlength{\bibitemsep}{\baselineskip}|.
+\subsection{Bibliographies}
+The class places no constraints on how you do your bibliography. If you have per-chapter bibliographies, you must use the |[chapterbib]| class option. Before any bibliography (whether global or per-chapter) you should use the |\makebibliographypage| command.
+\subsubsection{Bibliography spacing}\label{bibspacing}
+Please note that although bibliography entries must be single spaced, there must be a space between each entry. This parameter is set by your bibliography package and not by the class itself. If you are using \pkg{natbib} or \pkg{biblatex} these spacing parameters are set for you by the class. If you are using another package for your bibliography you are responsible for adjusting the relevant spacing parameters.
\subsection{Customizing the look of things}
I have created a basic looking style for Chapter headings based on the |thatcher| style in |memoir|. If you want to change these things, you may, using the appropriate |\renewcommand| commands. More information can be found in the |memoir| documentation. The Thesis Office seems to require dotted leaders for the List of Figures/Tables in the Table of Contents, (despite the guide saying they are optional) even though they get typeset as Chapters. If you wish your Chapter headings to have no leaders, add the following command just after the |\mainmatter| command. To put the dots back for the Bibliography, repeat the same command right after the |\backmatter| command, but replace |\cftnodots| with |\cftdotsep|. The default template leaves dots everywhere, which should appease the thesis office.
@@ -297,25 +295,25 @@ I have created a basic looking style for Chapter headings based on the |thatcher
Despite there being no explicit formatting requirements for Chapter headings (other than that they start 1 in from the top of the page), the thesis office has been known to dislike many things, so if you do decide to change things, be prepared for rejection or a frustrating fight.
\subsection{Things to watch out for}
\begin{itemize}[label={\textbullet}]
-\item If you are having problems with the Thesis office about non-conforming formatting, please check first whether you have a local copy of the class instead of the latest version distributed via CTAN. The log file will reflect the date of the current version number. Remember if you are using the most current and updated TeXLive or MikTeX you will automatically have the latest version already and you should not need to install a local version.
+\item If you are having problems with the Thesis office about non-conforming formatting, please check first whether you have a local copy of the class instead of the latest version distributed via CTAN. The log file will reflect the date of the current version number. Remember if you are using the most current and updated TeXLive or MikTeX you will automatically have the latest version already and you should not need to install a local version. Overleaf users may need a local copy, since Overleaf is usually a year behind the TeXLive distribution schedule.
\item If your title is long and you want to put a newline (|\\|) into it to improve the spacing, you must precede the newline with |\protect|.
\item Make sure you pay attention to any ``Overfull hbox'' warnings when you are producing your final copy. You should make sure you eliminate all of them or else the thesis office is likely to reject your thesis. One common way to eliminate such warnings is to place the command |\sloppy| at the beginning of the paragraph that triggers the warning. You should only use this technique at the very end when you are completely done with everything. Alternatively, rewording the text may also fix things.
\item Remember to use the |\tableofcontents*| command so that your table of contents is not listed in the table of contents.
-\item Remember to use the |appendices| environment instead of |\appendix| if you have more than one appendix.
-\item Remember to add the |\makebibliographypage| command before your bibliography.
+\item Remember to use the |{appendix}| environment for single appendices, and the |{appendices}| environment for multiple appendices. Do not use the standard LaTeX |\appendix| command.
+\item Remember to add the |\makebibliographypage| command before any bibliography in your document.
\end{itemize}
\subsection{Master’s Theses}
Master’s theses are sometimes relatively short, and you may think that you can just have |\section| commands with no chapters. This will \emph{not} work. The class is designed to use chapters (and as far as I can tell, the Graduate School also expects chapters).
\section{Bugs and redistribution}
\subsection{Current version}
-The latest copy of \pkg{msu-thesis} will always be available on \href{https://ctan.org/pkg/msu-thesis?lang=en}{CTAN}. If you use MiKTeX, or a current year TeX Live then their respective package managers will update or install the latest version. If you are using Overleaf, you may or may not have the most recent version, since Overleaf is usually about one year behind in it’s TeX distribution. If you are using a Linux-based distribution, or your TeXLive distribution is not the most recent year, you may need to install the latest copy in your local |texmf| directory. If you want others to use the class, \textsc{please} point them to CTAN, or tell them to use an up-to-date TeX distribution so that they can use an up-to-date version with all accompanying documentation and examples rather than passing along your copy. Please report \textsc{any} problems you have with the class to me \href{mailto:amunn@msu.edu}{amunn@msu.edu}, as this will aid in making things easier for those who follow you. If you prefer, you may also report issues using GitHub: \href{https://github.com/amunn/msu-thesis}{github.com/amunn/msu-thesis}. The Graduate School rarely announces changes it makes to the formatting requirements, so your problem reports are extremely helpful for keeping the class in compliance with the latest standards.
+The latest copy of \pkg{msu-thesis} will always be available on \href{https://ctan.org/pkg/msu-thesis?lang=en}{CTAN}. If you use MiKTeX, or a current year TeX Live then their respective package managers will update or install the latest version. If you are using Overleaf, you may or may not have the most recent version, since Overleaf is usually about one year behind in its TeX distribution. If you are using a Linux-based distribution, or your TeXLive distribution is not the most recent year, you may need to install the latest copy in your local |texmf| directory. If you want others to use the class, \textsc{please} point them to CTAN, or tell them to use an up-to-date TeX distribution so that they can use an up-to-date version with all accompanying documentation and examples rather than passing along your copy. Please report \textsc{any} problems you have with the class to me \href{mailto:amunn@msu.edu}{amunn@msu.edu}, as this will aid in making things easier for those who follow you. If you prefer, you may also report issues using GitHub: \href{https://github.com/amunn/msu-thesis}{github.com/amunn/msu-thesis}. The Graduate School rarely announces changes it makes to the formatting requirements, so your problem reports are extremely helpful for keeping the class in compliance with the latest standards.
\subsection{Archiving your thesis for the future}
Since the current version of the \pkg{msu-thesis} class satisfies the Graduate School requirements at any one time, as these requirements change, you may find that if you need to recompile your thesis after you have graduated that the formatting changes. To avoid this, I would recommend saving an archived version of the \pkg{msu-thesis.cls} file in the same folder as your thesis file. You only need to do this once you have completely finished your thesis however; there's no need to do it during the writing process.
\subsection{Version history}
-Previous versions of \pkg{msu-thesis} (versions 1.0--1.4b) were created for non-electronic submission and should not be used. Versions 1.5--1.6 (the first electronic submission versions) contained a |\makeabstract| command and a separate |msuabstract| environment. These have been removed as of version 1.7. Users who are upgrading from earlier versions to version 1.7 do not need to change these commands however but their use will trigger a warning.) Version 2.0 implemented landscape pages; version 2.1 added support for \pkg{hyperref}. Versions 2.2--2.5 mainly accommodated to the ever changing whims of the MSU Graduate School. Version 2.6 fixed some appendix bugs introduced by the previous whim accommodation. Version 2.7 fixed various small spacing issues, fixed a bug which prevented a new chapter page to be a landscape page, added support for the \pkg{apacite} package, and updated degree options. Version 2.8 fixed some spacing and capitalization issues and added support for the the public abstract. Version 2.9 removed subscript/superscript size restrictions, added font size options and made small spacing changes to appease the thesis office.
+Previous versions of \pkg{msu-thesis} (versions 1.0--1.4b) were created for non-electronic submission and should not be used. Versions 1.5--1.6 (the first electronic submission versions) contained a |\makeabstract| command and a separate |msuabstract| environment. These have been removed as of version 1.7. Users who are upgrading from earlier versions to version 1.7 do not need to change these commands however but their use will trigger a warning.) Version 2.0 implemented landscape pages; version 2.1 added support for \pkg{hyperref}. Versions 2.2--2.5 mainly accommodated to the ever changing whims of the MSU Graduate School. Version 2.6 fixed some appendix bugs introduced by the previous whim accommodation. Version 2.7 fixed various small spacing issues, fixed a bug which prevented a new chapter page to be a landscape page, added support for the \pkg{apacite} package, and updated degree options. Version 2.8 fixed some spacing and capitalization issues and added support for the public abstract. Version 2.9 removed subscript/superscript size restrictions, added font size options and made small spacing changes to appease the thesis office. Version 3.0 added full support for per-chapter bibliographies and appendices, and automated bibliography spacing for |natbib| and |biblatex| produced bibliographies.
\section{Acknowledgements}
-Thanks to Lars Madsen, Ulrike Fischer and Peter Wilson for help with setting up parts of the memoir code for versions 1.0--1.4 (now eliminated due to changed requirements). Thanks to Wolfgang Sternefeld for supplying the \pkg{linguex} spacing fix code, Leo Liu for the landscape page numbering code, which greatly simplified my original version, and Florent Chervet for the hyperref code. Thanks also to the following students who have reported problems over the years: Irina Agafonova, Ali Al-jiboory, Dmitriy Bryndin, Greg Christian, Kyle Crayne, Matt Husband, Changkuk Jung, Adam Liter, William Muir, Adam Soliman, Alicia Parrish, Neil ver Planck, Michael Wojcik, Eremey Valetov, Matthew Vincent and Yisu Zhou. A special thank you to Non Thongprong who graciously provided a copy of his entire thesis which allowed me to debug some especially subtle spacing inconsistencies.
+Thanks to Lars Madsen, Ulrike Fischer and Peter Wilson for help with setting up parts of the memoir code for versions 1.0--1.4 (now eliminated due to changed requirements). Thanks to Wolfgang Sternefeld for supplying the \pkg{linguex} spacing fix code, Leo Liu for the landscape page numbering code, which greatly simplified my original version, and Florent Chervet for the \pkg{hyperref} code. Thanks also to the following students who have reported problems over the years: Irina Agafonova, Ali Al-jiboory, Dmitriy Bryndin, Greg Christian, Kyle Crayne, Matt Husband, Changkuk Jung, Adam Liter, William Muir, Alicia Parrish, Neil ver Planck, Adam Soliman, Erik Stitt, Michael Wojcik, Eremey Valetov, Matthew Vincent and Yisu Zhou. A special thank you to Non Thongprong who graciously provided a copy of his entire thesis which allowed me to debug some especially subtle spacing inconsistencies.
\appendix
\renewcommand{\thesection}{Appendix \Alph{section}}
diff --git a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.pdf b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.pdf
deleted file mode 100644
index 93ded329af..0000000000
--- a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.tex b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.tex
index 926c2a5093..c82f6e0020 100644
--- a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.tex
+++ b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.tex
@@ -1,10 +1,11 @@
% This is a template for use with the MSU Thesis class
-% Vesion 2.9c 2021/05/07
+% Vesion 3.0 2021/06/10
%
% Class options:
%[PhD] Doctor of Philosophy (default)
%[DEd] Doctor of Education
%[DMA] Doctor of Musical Arts
+%[DNP] Doctor of Nursing Practice
%[MA] Master of Arts
%[MS] Master of Science
%[MAT] Master of Arts for Teachers
@@ -32,16 +33,20 @@
%
% If you have large tables/figures that need to be in landscape mode, add the [lscape] option
%
-% The class accepts 12pt, 11pt or 10pt font size options. For Times New Roman use 12pt (default).
-
-% This is standard fontenc/inputenc for pdflatex
+% The class accepts 12pt, 11pt or 10pt font size options.
+% For Times New Roman as in this example document, use 12pt (default).
+%
+% If you require per-chapter appendices add the [chapterapp] option
+%
+% If you require per-chapter bibliographies add the [chapterbib] option
+%
+% This is standard fontenc for pdflatex
% If you use LuaLaTeX or XeLaTeX you should replace this with the fontspec package
-\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
%
% If the thesis office requires Times, we'll give them Times
% You can experiment with other font packages here if you like.
-% If you are using XeLaTeX or LuaLaTeX load the Times or Times New Roman font with \setmainfont
+% If you are using XeLaTeX or LuaLaTeX load TeX Gyre Termes, Times or Times New Roman font with \setmainfont
\usepackage{newtxtext,newtxmath}
%
% Load any extra packages here
@@ -62,16 +67,23 @@
\frontmatter
% First make the title page
\maketitlepage
-% Next make the abstract
+
+% if you have public abstract (optional) it should go here
+%\begin{publicabstract}
+% Public abstract goes here
+%\end{publicabstract}
+
+% Next make the regular abstract (obligatory)
\begin{abstract}
% Your abstract goes here. Master's 1 page max. PhD 2 page max.
\end{abstract}
% Force a newpage
\clearpage
-% Make the copyright page. The Graduate School ridiculously prohibits you
-% from having a copyright page unless you pay ProQuest to register the copyright.
-% This should be illegal, but I didn't make up the rule.
+% Make the copyright page. The Graduate School ridiculously claims that you
+% can't have a copyright page unless you pay ProQuest to register the copyright.
+% This is simply not the case, so put in your copyright page whether or not you
+% intend to pay Proquest to register the copyright.
\makecopyrightpage
@@ -117,15 +129,20 @@ Your acknowledgements here.
%
%
% If you have appendices, they would go here.
-% Comment these lines out if you don't
+% If you only have one appendix it will look like this: (comment this out if you have no appendices)
+\begin{appendix}
+\chapter{Your appendix}
+\end{appendix}
+%
+%
% If you have more than one appendix, you need to use
% \begin{appendices}
% \chapter{First appendix}
% \chapter{Second appendix}
% \end{appendices}
%
-\appendix
-\chapter{Your appendix}
+% If each chapter has its own set of appendices, then load the class with the [chapterapp] option
+% and put your {appendix} or {appendices} environments at the end of each chapter.
%
\backmatter
% The next lines add the dots back into the References/Bibliography heading
@@ -135,14 +152,20 @@ Your acknowledgements here.
% \protect\renewcommand{\protect\cftchapterdotsep} {\cftdotsep}}
%
\makebibliographypage % make the bibliography cover page
-% Bibliography can be single spaced
%
-\SingleSpacing
%
-% Your bibliography command here (e.g. \bibliography{your-bib-file}) if using natbib
+% Your bibliography command here
+% e.g. \bibliography{your-bib-file}) if using natbib
+% e.g. \printbibliography if using biblatex
%
% Remember that although the bibliography is single spaced, there needs to
% be a blank line between entries. This is set by your bibliography package
% If you are using natbib it is \bibsep; if using biblatex it's \bibitemsep
+% These are set automatically by the class if you are using these packages
+%
+% If you need per-chapter bibliographies, you need to use the [chapterbib]
+% class option and you would use \makebibliographypage before each
+% chapter level bibliography and then the relevant bibliography command
+%
\end{document}
diff --git a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf
index 7e4e651ae8..1370069e3f 100644
--- a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf
+++ b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf
Binary files differ
diff --git a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.tex b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.tex
index b6c8f12d8d..d9a2196b85 100644
--- a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.tex
+++ b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.tex
@@ -1,5 +1,5 @@
% !TEX TS-program = pdflatexmk
-% v2.9c Testfile
+% v3.0 Testfile
\listfiles
\documentclass[lscape]{msu-thesis}
@@ -10,7 +10,7 @@
\usepackage{newtxtext,newtxmath} % If they want Times we’ll give them Times
\usepackage{amsmath}
%
-\usepackage[]{natbib}
+\usepackage{natbib}
\bibliographystyle{apalike}
@@ -96,7 +96,6 @@ This is some text that precedes a section.
\trans A French example.}
\end{xlist}
\end{exe}
-
\lipsum[1]
\lipsum[2]\cite{Munn1999} says the following.\footnote{A footnote. This is a footnote with a subscript$_{\text{i}_{\text{j}}}$. \lipsum[9]} \lipsum[2]
\begin{table}
@@ -191,6 +190,8 @@ This is another listing
\caption{Another listing caption}
\end{listing}
\lipsum[8]
+\section{A section with no subsection following it}
+\lipsum[9]
Now sample page in landscape (need to use [lscape] option for this)
First clear the page. Then make the page style {lscape}
\clearpage\pagestyle{lscape}
@@ -202,7 +203,6 @@ This is another listing
\begin{table}
\centering
\begin{tabular}{lllllll}
-
\toprule
A & B & C & D & E & F & G \\
\midrule
@@ -221,10 +221,8 @@ A & B & C & D & E & F & G \\
487.6847246 & 200.8682708 & 739.9673152 & 395.1695216 & 524.7826343 & 228.4705562 & 39.95541901 \\
207.8091332 & 300.6871609 & 627.8808013 & 740.4949976 & 128.9558068 & 176.2158891 & 296.1642661 \\
336.7537922 & 859.907318 & 704.2503641 & 426.845866 & 773.8926695 & 883.1773631 & 64.85043069 \\
-
\bottomrule
\end{tabular}
-
\caption{Some random data that takes up too much room.}
\end{table}
@@ -262,22 +260,24 @@ A & B & C & D & E & F & G \\
%% at the end of the {landscape} environment, make the page style {plain}
\pagestyle{plain}
%
-
-
%\begin{appendices} ... \end{appendices}
% use this if you have more than one appendix
\clearpage
-%\appendix % use this if you have only one appendix
-\begin{appendices} % use this if you have more than one appendix
-\chapter{An appendix}
-\section{An appendix section}
-\lipsum[9-15]
-\chapter{A second appendix}
-\section{An appendix section}
-\lipsum[16-17]
-\end{appendices}
+%\begin{appendix} ... \end{appendix} % use this if you have only one appendix
+\begin{appendix}
+\chapter{A single appendix}
+\lipsum[11]
+\end{appendix}
+
+%\begin{appendices} % use this if you have more than one appendix
+%\chapter{An appendix}
+%\section{An appendix section}
+%\lipsum[9-15]
+%\chapter{A second appendix}
+%\section{An appendix section}
+%\lipsum[16-17]
+%\end{appendices}
\backmatter
-\SingleSpacing
% This command creates the cover page for the bibliography
\makebibliographypage
\bibliography{MSU-thesis-testfile}
diff --git a/macros/latex/contrib/ocgx2/ChangeLog b/macros/latex/contrib/ocgx2/ChangeLog
index 4b91f95c79..0597209e2f 100644
--- a/macros/latex/contrib/ocgx2/ChangeLog
+++ b/macros/latex/contrib/ocgx2/ChangeLog
@@ -1,3 +1,7 @@
+2021-06-16
+ * v0.53: ocgx2.sty
+ * fix: tikz option breaks package loading
+
2021-06-11
* v0.52: ocgx2.sty
* v0.20: ocgbase.sty
diff --git a/macros/latex/contrib/ocgx2/ocgx2.sty b/macros/latex/contrib/ocgx2/ocgx2.sty
index 101537322e..cb9c7822d0 100644
--- a/macros/latex/contrib/ocgx2/ocgx2.sty
+++ b/macros/latex/contrib/ocgx2/ocgx2.sty
@@ -1,609 +1,635 @@
%%%%%%%%%%%%%%%%%%%%%% pdfmanagement-testphase %%%%%%%%%%%%%%%%%%%
\newif\if@ocgxii@testphase
\ExplSyntaxOn
-\bool_if:nT {
+\bool_if:nTF{
\bool_lazy_and_p:nn {\cs_if_exist_p:N \pdfmanagement_if_active_p:} { \pdfmanagement_if_active_p: }
-}{\@ocgxii@testphasetrue}
-\ExplSyntaxOff
-\if@ocgxii@testphase\else
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% ocgx2.sty
-%
-% Copyright 2015--\today, Alexander Grahn
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% The intent of this package is to be a drop-in replacement for the already
-% existing CTAN package `ocgx' by Paul Gaborit, and also for `ocg-p' and `ocg'.
-%
-% It re-implements the functionality of the ocg, ocgx and ocg-p packages
-% and adds support for all known engines and backends including
-% latex+dvips+ps2pdf, xelatex, latex+dvipdfmx, lualatex.
-%
-% With ocgx2, PDF layers may extend across page breaks.
-%
-% ocgx2 implements OCMDs (optional content membership dictionaries)
-%
-% Adds some minor improvements, such as package options, remembering option.
-% settings of reopened ocgs, correct behaviour of ocg switching links that were
-% themselves placed on layers, compatibility with the animate and media9
-% packages.
-%
-% Re-implements hyperref's `ocgcolorlinks' option to produce coloured links
-% that may wrap around line breaks and page breaks.
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+}{\@ocgxii@testphasetrue}{
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ % ocgx2.sty
+ %
+ % Copyright 2015--\today, Alexander Grahn
+ %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ % The intent of this package is to be a drop-in replacement for the already
+ % existing CTAN package `ocgx' by Paul Gaborit, and also for `ocg-p' and `ocg'.
+ %
+ % It re-implements the functionality of the ocg, ocgx and ocg-p packages
+ % and adds support for all known engines and backends including
+ % latex+dvips+ps2pdf, xelatex, latex+dvipdfmx, lualatex.
+ %
+ % With ocgx2, PDF layers may extend across page breaks.
+ %
+ % ocgx2 implements OCMDs (optional content membership dictionaries)
+ %
+ % Adds some minor improvements, such as package options, remembering option.
+ % settings of reopened ocgs, correct behaviour of ocg switching links that were
+ % themselves placed on layers, compatibility with the animate and media9
+ % packages.
+ %
+ % Re-implements hyperref's `ocgcolorlinks' option to produce coloured links
+ % that may wrap around line breaks and page breaks.
+ %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License.
-%
-% The latest version of this license is in
-% http://mirrors.ctan.org/macros/latex/base/lppl.txt
-%
-% This work has the LPPL maintenance status `maintained'.
-%
-% The Current Maintainer of this work is A. Grahn.
+ % This work may be distributed and/or modified under the
+ % conditions of the LaTeX Project Public License.
+ %
+ % The latest version of this license is in
+ % http://mirrors.ctan.org/macros/latex/base/lppl.txt
+ %
+ % This work has the LPPL maintenance status `maintained'.
+ %
+ % The Current Maintainer of this work is A. Grahn.
-\RequirePackage{l3keys2e}
+ \RequirePackage{l3keys2e}
-\def\g@ocgxii@date@tl{2021/06/11}
-\def\g@ocgxii@version@tl{0.52}
+ \def\g@ocgxii@date@tl{2021/06/16}
+ \def\g@ocgxii@version@tl{0.53}
-\ProvidesExplPackage{ocgx2}{\g@ocgxii@date@tl}{\g@ocgxii@version@tl}
-{ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}
+ \ProvidesExplPackage{ocgx2}{\g@ocgxii@date@tl}{\g@ocgxii@version@tl}
+ {ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}
-%creating global definitions
-\cs_new_protected:Npn\ocgxii@newkey#1#2{\tl_gset:cx{#1}{#2}}
-\cs_new_protected:Npn\ocgxii@newkeynoexp#1#2{\tl_gset:cn{#1}{#2}}
+ %creating global definitions
+ \cs_new_protected:Npn\ocgxii@newkey#1#2{\tl_gset:cx{#1}{#2}}
+ \cs_new_protected:Npn\ocgxii@newkeynoexp#1#2{\tl_gset:cn{#1}{#2}}
-\AtBeginDocument{
- \iow_now:Nx\@mainaux{
- \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkey[2]{}
- }
- \iow_now:Nx\@mainaux{
- \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkeynoexp[2]{}
- }
- \iow_now:Nx\@mainaux{
- \token_to_str:N\providecommand\token_to_str:N\ocgxii@ocg@stack@on@page[2]{}
- }
- \iow_now:Nx\@mainaux{
- \token_to_str:N\providecommand
- \token_to_str:N\ocgxii@lnkcol@stack@on@page[2]{}
+ \AtBeginDocument{
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkey[2]{}
+ }
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\providecommand\token_to_str:N\ocgxii@newkeynoexp[2]{}
+ }
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\providecommand\token_to_str:N\ocgxii@ocg@stack@on@page[2]{}
+ }
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\providecommand
+ \token_to_str:N\ocgxii@lnkcol@stack@on@page[2]{}
+ }
}
-}
-\msg_set:nnn{ocgx2}{generic~msg}{#1\\#2}
+ \msg_set:nnn{ocgx2}{generic~msg}{#1\\#2}
-\msg_set:nnn{ocgx2}{missing~package}{
- Package~`#1'~must~be~loaded~before~ocgx2.\\\\
- Put\\\\
- \space\space\string\usepackage#2{#1}\\
- \space\space\string\usepackage[ocgcolorlinks]{ocgx2}\\\\
- to~the~preamble~of~your~document.
-}
-
-\msg_set:nnn{ocgx2}{beamer~and~ocgcolorlinks}{
- Option~`ocgcolorlinks'~cannot~be~used~with~class~Beamer.\\\\
- Using~`colorlinks'~instead.
-}
-
-%package opts
-%unknown package option error message
-\msg_set:nnnn{ocgx2}{unknown~package~option}{Unknown~package~option~`#1'.}{
- Package option~'#1'~is~unknown;\\
- perhaps~it~is~spelled~incorrectly.
-}
+ \msg_set:nnn{ocgx2}{missing~package}{
+ Package~`#1'~must~be~loaded~before~ocgx2.\\\\
+ Put\\\\
+ \space\space\string\usepackage#2{#1}\\
+ \space\space\string\usepackage[ocgcolorlinks]{ocgx2}\\\\
+ to~the~preamble~of~your~document.
+ }
-\bool_new:N\g_ocgxii_dvipdfmx_bool
-\bool_new:N\l_ocgxii_tikz_bool
-\bool_new:N\l_ocgxii_ocgcolorlinks_bool
-\bool_new:N\g_ocgxii_showingui_bool
-\bool_new:N\l_ocgxii_showingui_bool
+ \msg_set:nnn{ocgx2}{beamer~and~ocgcolorlinks}{
+ Option~`ocgcolorlinks'~cannot~be~used~with~class~Beamer.\\\\
+ Using~`colorlinks'~instead.
+ }
-\keys_define:nn{ocgx2}{
- xetex .code:n = {}, %dummy
+ %package opts
+ %unknown package option error message
+ \msg_set:nnnn{ocgx2}{unknown~package~option}{Unknown~package~option~`#1'.}{
+ Package option~'#1'~is~unknown;\\
+ perhaps~it~is~spelled~incorrectly.
+ }
- dvipdfmx .code:n = {
- \PassOptionsToPackage{dvipdfmx}{ocgbase}
- \PassOptionsToPackage{dvipdfmx}{pdfbase}
- \bool_gset_true:N\g_ocgxii_dvipdfmx_bool
- },
+ \bool_new:N\g_ocgxii_dvipdfmx_bool
+ \bool_new:N\l_ocgxii_tikz_bool
+ \bool_new:N\l_ocgxii_ocgcolorlinks_bool
+ \bool_new:N\g_ocgxii_showingui_bool
+ \bool_new:N\l_ocgxii_showingui_bool
- viewocg .choice:,
- viewocg / always .code:n={
- \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/ON>>}},
- viewocg / never .code:n={
- \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/OFF>>}},
- viewocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_view_tl},
- viewocg .default:n={ifvisible},
+ \keys_define:nn{ocgx2}{
+ xetex .code:n = {}, %dummy
- printocg .choice:,
- printocg / always .code:n={
- \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/ON>>}},
- printocg / never .code:n={
- \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
- printocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_print_tl},
- printocg .default:n={ifvisible},
+ dvipdfmx .code:n = {
+ \PassOptionsToPackage{dvipdfmx}{ocgbase}
+ \PassOptionsToPackage{dvipdfmx}{pdfbase}
+ \bool_gset_true:N\g_ocgxii_dvipdfmx_bool
+ },
- exportocg .choice:,
- exportocg / always .code:n={
- \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/ON>>}},
- exportocg / never .code:n={
- \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
- exportocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_export_tl},
- exportocg .default:n={ifvisible},
+ viewocg .choice:,
+ viewocg / always .code:n={
+ \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/ON>>}},
+ viewocg / never .code:n={
+ \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/OFF>>}},
+ viewocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_view_tl},
+ viewocg .default:n={ifvisible},
+
+ printocg .choice:,
+ printocg / always .code:n={
+ \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/ON>>}},
+ printocg / never .code:n={
+ \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
+ printocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_print_tl},
+ printocg .default:n={ifvisible},
+
+ exportocg .choice:,
+ exportocg / always .code:n={
+ \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/ON>>}},
+ exportocg / never .code:n={
+ \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
+ exportocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_export_tl},
+ exportocg .default:n={ifvisible},
+
+ showingui .choices:nn = {true,false,always,never,iffirstuse}{
+ \bool_if:nTF{
+ \str_if_eq_p:ee{#1}{false} ||
+ \str_if_eq_p:ee{#1}{never}
+ }{
+ \bool_gset_false:N\g_ocgxii_showingui_bool
+ }{
+ \bool_gset_true:N\g_ocgxii_showingui_bool
+ }
+ },
+ showingui .default:n={true},
- showingui .choices:nn = {true,false,always,never,iffirstuse}{
- \bool_if:nTF{
- \str_if_eq_p:ee{#1}{false} ||
- \str_if_eq_p:ee{#1}{never}
- }{
- \bool_gset_false:N\g_ocgxii_showingui_bool
- }{
- \bool_gset_true:N\g_ocgxii_showingui_bool
- }
- },
- showingui .default:n={true},
+ listintoolbar .meta:n = {showingui=#1},
+ listintoolbar .default:n={true},
- listintoolbar .meta:n = {showingui=#1},
- listintoolbar .default:n={true},
+ tikz .bool_set:N = \l_ocgxii_tikz_bool,
+ tikz .default:n = true,
- tikz .bool_set:N = \l_ocgxii_tikz_bool,
- tikz .default:n = true,
+ ocgcolorlinks .bool_set:N = \l_ocgxii_ocgcolorlinks_bool,
+ ocgcolorlinks .default:n = true,
- ocgcolorlinks .bool_set:N = \l_ocgxii_ocgcolorlinks_bool,
- ocgcolorlinks .default:n = true,
-
- unknown .code:n = {
- \msg_error:nnx{ocgx2}{unknown~package~option}{\l_keys_key_tl}
+ unknown .code:n = {
+ \msg_error:nnx{ocgx2}{unknown~package~option}{\l_keys_key_tl}
+ }
}
-}
-%package options preset
-\keys_set:nn{ocgx2}{viewocg,printocg,exportocg,showingui,tikz=false}
+ %package options preset
+ \keys_set:nn{ocgx2}{viewocg,printocg,exportocg,showingui,tikz=false}
-%process package options
-\ProcessKeysOptions{ocgx2}
-\sys_if_engine_xetex:T{\bool_gset_true:N\g_ocgxii_dvipdfmx_bool}
+ %process package options
+ \ProcessKeysOptions{ocgx2}
+ \sys_if_engine_xetex:T{\bool_gset_true:N\g_ocgxii_dvipdfmx_bool}
-\RequirePackage{ocgbase} %also loads pdfbase.sty
+ \RequirePackage{ocgbase} %also loads pdfbase.sty
-%re-implement ocg-p's `ocg' environment
-\DeclareDocumentEnvironment{ocg}{O{}mmm}{
- \ocgxii_begin_ocg:nnnn{#1}{#2}{#3}{#4}
-}{
- \ocgxii_end_ocg:
-}
+ %re-implement ocg-p's `ocg' environment
+ \DeclareDocumentEnvironment{ocg}{O{}mmm}{
+ \ocgxii_begin_ocg:nnnn{#1}{#2}{#3}{#4}
+ }{
+ \ocgxii_end_ocg:
+ }
-\cs_new_protected_nopar:Nn\ocgxii_begin_ocg:nnnn{
- \group_begin:
- \ocgxii_reset_cmd_opts: % ... to the user-set package options
- \tl_set:Nx\l_ocgxii_argiv_tl{\tl_trim_spaces:n{#4}}
- \tl_if_exist:cTF{ocgxii_ocg_#3}{ %re-open existing layer
- \tl_set:Nx\l_tempa_tl{\tl_use:c{ocgxii_ocg_#3.opts},#1}
- \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl} %new options appended
- \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
- \bool_if:nTF{ %initial visibility
- \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{1} ||
- \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{on} ||
- \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{true}
- }{
- \ocgbase_del_from_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
+ \cs_new_protected_nopar:Nn\ocgxii_begin_ocg:nnnn{
+ \group_begin:
+ \ocgxii_reset_cmd_opts: % ... to the user-set package options
+ \tl_set:Nx\l_ocgxii_argiv_tl{\tl_trim_spaces:n{#4}}
+ \tl_if_exist:cTF{ocgxii_ocg_#3}{ %re-open existing layer
+ \tl_set:Nx\l_tempa_tl{\tl_use:c{ocgxii_ocg_#3.opts},#1}
+ \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl} %new options appended
+ \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
+ \bool_if:nTF{ %initial visibility
+ \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{1} ||
+ \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{on} ||
+ \str_if_eq_p:ee{\l_ocgxii_argiv_tl}{true}
+ }{
+ \ocgbase_del_from_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
+ }{
+ \ocgbase_add_to_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
+ }
}{
- \ocgbase_add_to_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
- }
- }{
- \tl_set:Nx\l_tempa_tl{#1}
- \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl}
- \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
- \ocgbase_new_ocg:nnn{#2}{
- \l_ocgxii_view_tl\l_ocgxii_print_tl\l_ocgxii_export_tl
- }{\l_ocgxii_argiv_tl}
- \tl_gset:cx{ocgxii_ocg_#3}{\ocgbase_last_ocg:}
- \tl_gset:cx{ocgx2.ocg.\ocgbase_last_ocg:}{\ocgbase_last_ocg:}
- \tl_gset:cx{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
- \iow_now:Nx\@mainaux{
- \token_to_str:N\ocgxii@newkey{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
+ \tl_set:Nx\l_tempa_tl{#1}
+ \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl}
+ \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
+ \ocgbase_new_ocg:nnn{#2}{
+ \l_ocgxii_view_tl\l_ocgxii_print_tl\l_ocgxii_export_tl
+ }{\l_ocgxii_argiv_tl}
+ \tl_gset:cx{ocgxii_ocg_#3}{\ocgbase_last_ocg:}
+ \tl_gset:cx{ocgx2.ocg.\ocgbase_last_ocg:}{\ocgbase_last_ocg:}
+ \tl_gset:cx{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\ocgxii@newkey{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
+ }
}
- }
- \bool_if:nT{
- !\cs_if_exist:cTF{ocgx2.ocg.#3}{
- \str_if_eq_p:ee{\tl_use:c{ocgx2.ocg.#3}}{\tl_use:c{ocgxii_ocg_#3}}
+ \bool_if:nT{
+ !\cs_if_exist:cTF{ocgx2.ocg.#3}{
+ \str_if_eq_p:ee{\tl_use:c{ocgx2.ocg.#3}}{\tl_use:c{ocgxii_ocg_#3}}
+ }{
+ \c_false_bool
+ }
}{
- \c_false_bool
+ \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
+ \tl_new:N\g_ocgxii_rerunwarned_tl
+ \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
+ }
}
- }{
- \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
- \tl_new:N\g_ocgxii_rerunwarned_tl
- \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
+ \seq_map_inline:Nn\l_ocgxii_rbgrps_seq{% process list of radio btn groups
+ \ocgbase_add_ocg_to_radiobtn_grp:nn{##1}{\tl_use:c{ocgxii_ocg_#3}}
}
- }
- \seq_map_inline:Nn\l_ocgxii_rbgrps_seq{% process list of radio btn groups
- \ocgbase_add_ocg_to_radiobtn_grp:nn{##1}{\tl_use:c{ocgxii_ocg_#3}}
- }
- \ocgbase_open_stack_push:n{\tl_use:c{ocgxii_ocg_#3}}
+ \ocgbase_open_stack_push:n{\tl_use:c{ocgxii_ocg_#3}}
+ \ocgxii_make_oc_entry:
+ \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
+ % insert OCG into Order tree
+ \bool_if:NT\l_ocgxii_showingui_bool{
+ \ocgbase_tree_node_begin:n{\tl_use:c{ocgxii_ocg_#3}}
+ }
+ \group_end:
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_#3}}
+ \ignorespaces
+ }
+
+ \cs_new_protected_nopar:Nn\ocgxii_end_ocg:{
+ \unskip
+ \ocgbase_oc_emc:
+ \ocgbase_tree_node_end:
+ \ocgbase_open_stack_pop:N\l_trash_tl
\ocgxii_make_oc_entry:
\ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
- % insert OCG into Order tree
- \bool_if:NT\l_ocgxii_showingui_bool{
- \ocgbase_tree_node_begin:n{\tl_use:c{ocgxii_ocg_#3}}
- }
- \group_end:
- \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_#3}}
- \ignorespaces
-}
-
-\cs_new_protected_nopar:Nn\ocgxii_end_ocg:{
- \unskip
- \ocgbase_oc_emc:
- \ocgbase_tree_node_end:
- \ocgbase_open_stack_pop:N\l_trash_tl
- \ocgxii_make_oc_entry:
- \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
-}
+ }
-% OCMD implementation
-\DeclareDocumentEnvironment{ocmd}{O{}m}{
- \ocgxii_begin_ocmd:on{#1}{#2}
- \ignorespaces
-}{
- \unskip
- \ocgxii_end_ocmd:
-}
+ % OCMD implementation
+ \DeclareDocumentEnvironment{ocmd}{O{}m}{
+ \ocgxii_begin_ocmd:on{#1}{#2}
+ \ignorespaces
+ }{
+ \unskip
+ \ocgxii_end_ocmd:
+ }
-\cs_new_protected_nopar:Nn\ocgxii_begin_ocmd:nn{ % #1: id,
- \bool_if:nTF{ % #2: visib. expr. or policy
- \tl_if_blank:oTF{#1}{
- \c_false_bool
+ \cs_new_protected_nopar:Nn\ocgxii_begin_ocmd:nn{ % #1: id,
+ \bool_if:nTF{ % #2: visib. expr. or policy
+ \tl_if_blank:oTF{#1}{
+ \c_false_bool
+ }{
+ \tl_if_exist_p:c{ocgxii_ocmd_#1}
+ }
}{
- \tl_if_exist_p:c{ocgxii_ocmd_#1}
- }
- }{
- % re-open existing ocmd
- \tl_set_eq:Nc\l_ocgxii_cur_ocmd_tl{ocgxii_ocmd_#1}
- }{
- % new ocmd
- \group_begin:
- \ocgxii_ocmd_read_visbility:nN{#2}\l_ocgxii_ocmd_visibility_tl
- \pbs_pdfobj:nnn{}{dict}{/Type/OCMD\l_ocgxii_ocmd_visibility_tl}
- %if only visb. policy is given, generate equivalent visib. expression,
- %needed for stack of open layers and \ocgxii_make_oc_entry: command
- \ocgxii_ocmd_make_equiv_ve:nN{#2}\l_ocgxii_ocmd_equiv_ve_tl
- \tl_gset:co{ocgx2.ocmd.\pbs_pdflastobj:}{\l_ocgxii_ocmd_equiv_ve_tl}
- \group_end:
- \tl_set:Nx\l_ocgxii_cur_ocmd_tl{\pbs_pdflastobj:}
- \tl_if_blank:oF{#1}{
- \tl_gset:cx{ocgxii_ocmd_#1}{\pbs_pdflastobj:}
- \iow_now:Nn\@mainaux{\ocgxii@newkeynoexp{ocgx2.ocmd.#1}{#2}}
+ % re-open existing ocmd
+ \tl_set_eq:Nc\l_ocgxii_cur_ocmd_tl{ocgxii_ocmd_#1}
+ }{
+ % new ocmd
+ \group_begin:
+ \ocgxii_ocmd_read_visbility:nN{#2}\l_ocgxii_ocmd_visibility_tl
+ \pbs_pdfobj:nnn{}{dict}{/Type/OCMD\l_ocgxii_ocmd_visibility_tl}
+ %if only visb. policy is given, generate equivalent visib. expression,
+ %needed for stack of open layers and \ocgxii_make_oc_entry: command
+ \ocgxii_ocmd_make_equiv_ve:nN{#2}\l_ocgxii_ocmd_equiv_ve_tl
+ \tl_gset:co{ocgx2.ocmd.\pbs_pdflastobj:}{\l_ocgxii_ocmd_equiv_ve_tl}
+ \group_end:
+ \tl_set:Nx\l_ocgxii_cur_ocmd_tl{\pbs_pdflastobj:}
+ \tl_if_blank:oF{#1}{
+ \tl_gset:cx{ocgxii_ocmd_#1}{\pbs_pdflastobj:}
+ \iow_now:Nn\@mainaux{\ocgxii@newkeynoexp{ocgx2.ocmd.#1}{#2}}
+ }
}
+ \ocgbase_open_stack_push:n{\l_ocgxii_cur_ocmd_tl}
+ \ocgxii_make_oc_entry:
+ \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
+ \ocgbase_oc_bdc:n{\l_ocgxii_cur_ocmd_tl}
+ }
+ \cs_generate_variant:Nn\ocgxii_begin_ocmd:nn{on}
+ \cs_new_protected_nopar:Nn\ocgxii_end_ocmd:{
+ \ocgbase_oc_emc:
+ \ocgbase_open_stack_pop:N\l_trash_tl
+ \ocgxii_make_oc_entry: %update
+ \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
}
- \ocgbase_open_stack_push:n{\l_ocgxii_cur_ocmd_tl}
- \ocgxii_make_oc_entry:
- \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
- \ocgbase_oc_bdc:n{\l_ocgxii_cur_ocmd_tl}
-}
-\cs_generate_variant:Nn\ocgxii_begin_ocmd:nn{on}
-\cs_new_protected_nopar:Nn\ocgxii_end_ocmd:{
- \ocgbase_oc_emc:
- \ocgbase_open_stack_pop:N\l_trash_tl
- \ocgxii_make_oc_entry: %update
- \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
-}
-%visibility expressions
-\cs_new_protected_nopar:Nn\ocgxii_ocmd_read_visbility:nN{
- \int_zero:N\l_ocgxii_ve_cnt_int
- \int_zero:N\l_ocgxii_vp_cnt_int
- \tl_clear_new:N#2
- \clist_map_inline:nn{#1}{\ocgxii_omcd_parse_argument:nN{##1}#2}
-}
-\cs_new_protected_nopar:Nn\ocgxii_omcd_parse_argument:nN{
- \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
- \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
- \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
- \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
- \cs_set_eq:NN\Not\ocgxii_ve_check:n
- \cs_set_eq:NN\And\ocgxii_ve_check:n
- \cs_set_eq:NN\Or \ocgxii_ve_check:n
- \tl_if_exist:cTF{ocgx2.ocg.#1}{
- \msg_error:nnxx{ocgx2}{generic~msg}{
- OCG~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
- `ocmd'~environment.
- }{\g_ocgxii_help_msg_tl}
- }{
- \tl_if_exist:cTF{ocgx2.ocmd.#1}{
+ %visibility expressions
+ \cs_new_protected_nopar:Nn\ocgxii_ocmd_read_visbility:nN{
+ \int_zero:N\l_ocgxii_ve_cnt_int
+ \int_zero:N\l_ocgxii_vp_cnt_int
+ \tl_clear_new:N#2
+ \clist_map_inline:nn{#1}{\ocgxii_omcd_parse_argument:nN{##1}#2}
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_omcd_parse_argument:nN{
+ \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\Not\ocgxii_ve_check:n
+ \cs_set_eq:NN\And\ocgxii_ve_check:n
+ \cs_set_eq:NN\Or \ocgxii_ve_check:n
+ \tl_if_exist:cTF{ocgx2.ocg.#1}{
\msg_error:nnxx{ocgx2}{generic~msg}{
- OCMD~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
+ OCG~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
`ocmd'~environment.
}{\g_ocgxii_help_msg_tl}
}{
- \tl_if_exist:cTF{ocgxii_#1}{
- \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
- {VisExpr}{
- \int_incr:N\l_ocgxii_ve_cnt_int
- \int_compare:nNnTF{\l_ocgxii_ve_cnt_int}>{1}{
- \msg_error:nnnn{ocgx2}{generic~msg}{
- More~than~one~visibility~expression~passed~to~the~`ocmd'~
- environment.
+ \tl_if_exist:cTF{ocgx2.ocmd.#1}{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ OCMD~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
+ `ocmd'~environment.
+ }{\g_ocgxii_help_msg_tl}
+ }{
+ \tl_if_exist:cTF{ocgxii_#1}{
+ \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
+ {VisExpr}{
+ \int_incr:N\l_ocgxii_ve_cnt_int
+ \int_compare:nNnTF{\l_ocgxii_ve_cnt_int}>{1}{
+ \msg_error:nnnn{ocgx2}{generic~msg}{
+ More~than~one~visibility~expression~passed~to~the~`ocmd'~
+ environment.
+ }{
+ At~most~one~visibility~expression~is~allowed.~A~visibility~
+ expression~is~a~boolean~expression~built~by~nesting~any~number~of~
+ \And{...},~\Or{...},~\Not{...}~commands.
+ }
}{
- At~most~one~visibility~expression~is~allowed.~A~visibility~
- expression~is~a~boolean~expression~built~by~nesting~any~number~of~
- \And{...},~\Or{...},~\Not{...}~commands.
+ \tl_put_right:Nx#2{/VE~}
+ \ocgxii_ocmd_expression_parser:nN{#1}#2
}
- }{
- \tl_put_right:Nx#2{/VE~}
- \ocgxii_ocmd_expression_parser:nN{#1}#2
}
- }
- {VisPol}{
- \int_incr:N\l_ocgxii_vp_cnt_int
- \int_compare:nNnTF{\l_ocgxii_vp_cnt_int}>{1}{
- \msg_error:nnnn{ocgx2}{generic~msg}{
- More~than~one~visibility~policy~passed~to~the~`ocmd'~environment.
+ {VisPol}{
+ \int_incr:N\l_ocgxii_vp_cnt_int
+ \int_compare:nNnTF{\l_ocgxii_vp_cnt_int}>{1}{
+ \msg_error:nnnn{ocgx2}{generic~msg}{
+ More~than~one~visibility~policy~passed~to~the~`ocmd'~environment.
+ }{
+ At~most~one~visibility~policy~out~of~\AllOn{...},~\AnyOn{...},~
+ \AnyOff{...},~\AllOff{...}~is~allowed.~Any~number~of~OCG~IDs,~
+ separated~by~commas,~may~be~passed~as~arguments~to~these~
+ commands,~but~commands~may~not~be~nested.~For~complex~visibilty~
+ relations,~consider~using~a~visibility~expression.
+ }
}{
- At~most~one~visibility~policy~out~of~\AllOn{...},~\AnyOn{...},~
- \AnyOff{...},~\AllOff{...}~is~allowed.~Any~number~of~OCG~IDs,~
- separated~by~commas,~may~be~passed~as~arguments~to~these~
- commands,~but~commands~may~not~be~nested.~For~complex~visibilty~
- relations,~consider~using~a~visibility~expression.
+ \ocgxii_ocmd_expression_parser:nN{#1}#2
}
- }{
- \ocgxii_ocmd_expression_parser:nN{#1}#2
}
}
+ }{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ The~visibility~argument~of~the~`ocmd'~environment~cannot~be~parsed.
+ }{\g_ocgxii_help_msg_tl}
}
- }{
- \msg_error:nnxx{ocgx2}{generic~msg}{
- The~visibility~argument~of~the~`ocmd'~environment~cannot~be~parsed.
- }{\g_ocgxii_help_msg_tl}
}
}
}
-}
-\cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{xN}
-\cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{oN}
-\cs_new_protected_nopar:Nn\ocgxii_ocmd_expression_parser:nN{
- \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
- \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
- \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
- \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
- \cs_set_eq:NN\Not\ocgxii_ve_check:n
- \cs_set_eq:NN\And\ocgxii_ve_check:n
- \cs_set_eq:NN\Or \ocgxii_ve_check:n
- \tl_if_exist:cTF{ocgx2.ocg.#1}{% ocg reference
- \tl_put_right:Nx#2{~\tl_use:c{ocgx2.ocg.#1}}
- }{
- \tl_if_exist:cTF{ocgx2.ocmd.#1}{% ocmd reference
- \ocgxii_ocmd_expression_parser:vN{ocgx2.ocmd.#1}#2
+ \cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{xN}
+ \cs_generate_variant:Nn\ocgxii_omcd_parse_argument:nN{oN}
+ \cs_new_protected_nopar:Nn\ocgxii_ocmd_expression_parser:nN{
+ \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\Not\ocgxii_ve_check:n
+ \cs_set_eq:NN\And\ocgxii_ve_check:n
+ \cs_set_eq:NN\Or \ocgxii_ve_check:n
+ \tl_if_exist:cTF{ocgx2.ocg.#1}{% ocg reference
+ \tl_put_right:Nx#2{~\tl_use:c{ocgx2.ocg.#1}}
}{
- \tl_if_exist:cTF{ocgxii_#1}{% visib. bool expression or policy directive
- \bool_if:nTF{
- \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisExpr} &&
- \bool_if_p:N\l_ocgxii_vp_open_bool ||
- \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisPol} &&
- \bool_if_p:N\l_ocgxii_ve_open_bool
- }{
- \msg_error:nnxx{ocgx2}{generic~msg}{
- Visibility~policy~and~expression~commands~cannot~be~mixed.
- }{\g_ocgxii_help_msg_tl}
- }{
- \bool_if:nT{
+ \tl_if_exist:cTF{ocgx2.ocmd.#1}{% ocmd reference
+ \ocgxii_ocmd_expression_parser:vN{ocgx2.ocmd.#1}#2
+ }{
+ \tl_if_exist:cTF{ocgxii_#1}{% visib. bool expression or policy directive
+ \bool_if:nTF{
+ \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisExpr} &&
+ \bool_if_p:N\l_ocgxii_vp_open_bool ||
\str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisPol} &&
- \bool_if_p:N\l_ocgxii_vp_open_bool
+ \bool_if_p:N\l_ocgxii_ve_open_bool
}{
\msg_error:nnxx{ocgx2}{generic~msg}{
- Visibility~policy~commands~cannot~be~nested.~For~more~complex~
- visibilty~relations,~consider~using~a~visibility~expression.
+ Visibility~policy~and~expression~commands~cannot~be~mixed.
}{\g_ocgxii_help_msg_tl}
+ }{
+ \bool_if:nT{
+ \str_if_eq_p:ee{\tl_use:c{ocgxii_#1}}{VisPol} &&
+ \bool_if_p:N\l_ocgxii_vp_open_bool
+ }{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ Visibility~policy~commands~cannot~be~nested.~For~more~complex~
+ visibilty~relations,~consider~using~a~visibility~expression.
+ }{\g_ocgxii_help_msg_tl}
+ }
+ }
+ \cs_set_eq:NN\AllOn \ocgxii_vp_allon:nN
+ \cs_set_eq:NN\AnyOn \ocgxii_vp_anyon:nN
+ \cs_set_eq:NN\AnyOff\ocgxii_vp_anyoff:nN
+ \cs_set_eq:NN\AllOff\ocgxii_vp_alloff:nN
+ \cs_set_eq:NN\Not\ocgxii_ve_not:nN
+ \cs_set_eq:NN\And\ocgxii_ve_and:nN
+ \cs_set_eq:NN\Or \ocgxii_ve_or:nN
+ #1#2
+ }{
+ \msg_warning:nnx{ocgx2}{undefined~OCG}{#1}
+ \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
+ \tl_new:N\g_ocgxii_refundefwarned_tl
+ \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
}
- }
- \cs_set_eq:NN\AllOn \ocgxii_vp_allon:nN
- \cs_set_eq:NN\AnyOn \ocgxii_vp_anyon:nN
- \cs_set_eq:NN\AnyOff\ocgxii_vp_anyoff:nN
- \cs_set_eq:NN\AllOff\ocgxii_vp_alloff:nN
- \cs_set_eq:NN\Not\ocgxii_ve_not:nN
- \cs_set_eq:NN\And\ocgxii_ve_and:nN
- \cs_set_eq:NN\Or \ocgxii_ve_or:nN
- #1#2
- }{
- \msg_warning:nnx{ocgx2}{undefined~OCG}{#1}
- \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
- \tl_new:N\g_ocgxii_refundefwarned_tl
- \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
}
}
}
}
-}
-\cs_generate_variant:Nn\ocgxii_ocmd_expression_parser:nN{vN}
-% visib. policy directives
-\cs_new_protected_nopar:Nn\ocgxii_vp_allon:nN{
- \bool_set_true:N\l_ocgxii_vp_open_bool
- \tl_put_right:Nx#2{/P/AllOn/OCGs~\g_ocgxii_left_bracket_tl}
- \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
- \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
- \bool_set_false:N\l_ocgxii_vp_open_bool
-}
-\cs_new_protected_nopar:Nn\ocgxii_vp_anyon:nN{
- \bool_set_true:N\l_ocgxii_vp_open_bool
- \tl_gput_right:Nx#2{/P/AnyOn/OCGs~\g_ocgxii_left_bracket_tl}
- \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
- \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
- \bool_set_false:N\l_ocgxii_vp_open_bool
-}
-\cs_new_protected_nopar:Nn\ocgxii_vp_anyoff:nN{
- \bool_set_true:N\l_ocgxii_vp_open_bool
- \tl_gput_right:Nx#2{/P/AnyOff/OCGs~\g_ocgxii_left_bracket_tl}
- \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
- \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
- \bool_set_false:N\l_ocgxii_vp_open_bool
-}
-\cs_new_protected_nopar:Nn\ocgxii_vp_alloff:nN{
- \bool_set_true:N\l_ocgxii_vp_open_bool
- \tl_gput_right:Nx#2{/P/AllOff/OCGs~\g_ocgxii_left_bracket_tl}
- \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
- \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
- \bool_set_false:N\l_ocgxii_vp_open_bool
-}
-% policy to expression conversion
-\cs_new_protected_nopar:Nn\ocgxii_ocmd_make_equiv_ve:nN{
- \int_zero:N\l_ocgxii_ve_cnt_int
- \tl_clear_new:N#2
- \clist_map_inline:nn{#1}{\ocgxii_omcd_convert_vp:nN{##1}#2}
-}
-\cs_new_protected_nopar:Nn\ocgxii_omcd_convert_vp:nN{
- \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
- \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
- \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
- \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
- \cs_set_eq:NN\Not\ocgxii_ve_check:n
- \cs_set_eq:NN\And\ocgxii_ve_check:n
- \cs_set_eq:NN\Or \ocgxii_ve_check:n
- \tl_if_exist:cT{ocgxii_#1}{
- \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
- {VisExpr}{
- \int_incr:N\l_ocgxii_ve_cnt_int
- \tl_set:Nn#2{#1}
- }
- {VisPol}{
- \int_compare:nNnT{\l_ocgxii_ve_cnt_int}={0}{
- \cs_set_eq:NN\AllOn \ocgxii_allon_to_ve:n
- \cs_set_eq:NN\AnyOn \ocgxii_anyon_to_ve:n
- \cs_set_eq:NN\AnyOff\ocgxii_anyoff_to_ve:n
- \cs_set_eq:NN\AllOff\ocgxii_alloff_to_ve:n
- \tl_set:No#2{#1}
+ \cs_generate_variant:Nn\ocgxii_ocmd_expression_parser:nN{vN}
+ % visib. policy directives
+ \cs_new_protected_nopar:Nn\ocgxii_vp_allon:nN{
+ \bool_set_true:N\l_ocgxii_vp_open_bool
+ \tl_put_right:Nx#2{/P/AllOn/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
+ \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ \bool_set_false:N\l_ocgxii_vp_open_bool
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_vp_anyon:nN{
+ \bool_set_true:N\l_ocgxii_vp_open_bool
+ \tl_gput_right:Nx#2{/P/AnyOn/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
+ \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ \bool_set_false:N\l_ocgxii_vp_open_bool
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_vp_anyoff:nN{
+ \bool_set_true:N\l_ocgxii_vp_open_bool
+ \tl_gput_right:Nx#2{/P/AnyOff/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
+ \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ \bool_set_false:N\l_ocgxii_vp_open_bool
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_vp_alloff:nN{
+ \bool_set_true:N\l_ocgxii_vp_open_bool
+ \tl_gput_right:Nx#2{/P/AllOff/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
+ \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ \bool_set_false:N\l_ocgxii_vp_open_bool
+ }
+ % policy to expression conversion
+ \cs_new_protected_nopar:Nn\ocgxii_ocmd_make_equiv_ve:nN{
+ \int_zero:N\l_ocgxii_ve_cnt_int
+ \tl_clear_new:N#2
+ \clist_map_inline:nn{#1}{\ocgxii_omcd_convert_vp:nN{##1}#2}
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_omcd_convert_vp:nN{
+ \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\Not\ocgxii_ve_check:n
+ \cs_set_eq:NN\And\ocgxii_ve_check:n
+ \cs_set_eq:NN\Or \ocgxii_ve_check:n
+ \tl_if_exist:cT{ocgxii_#1}{
+ \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
+ {VisExpr}{
+ \int_incr:N\l_ocgxii_ve_cnt_int
+ \tl_set:Nn#2{#1}
+ }
+ {VisPol}{
+ \int_compare:nNnT{\l_ocgxii_ve_cnt_int}={0}{
+ \cs_set_eq:NN\AllOn \ocgxii_allon_to_ve:n
+ \cs_set_eq:NN\AnyOn \ocgxii_anyon_to_ve:n
+ \cs_set_eq:NN\AnyOff\ocgxii_anyoff_to_ve:n
+ \cs_set_eq:NN\AllOff\ocgxii_alloff_to_ve:n
+ \tl_set:No#2{#1}
+ }
}
}
}
}
-}
-\cs_new_protected_nopar:Nn\ocgxii_allon_to_ve:n{\And{#1}}
-\cs_new_protected_nopar:Nn\ocgxii_anyon_to_ve:n{\Or{#1}}
-\cs_new_protected_nopar:Nn\ocgxii_anyoff_to_ve:n{\Not{\And{#1}}}
-\cs_new_protected_nopar:Nn\ocgxii_alloff_to_ve:n{\Not{\Or{#1}}}
-% visib. boolean expressions
-\cs_new_protected_nopar:Nn\ocgxii_ve_and:nN{
- \bool_set_true:N\l_ocgxii_ve_open_bool
- \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/And}
- \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
- \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
- \bool_set_false:N\l_ocgxii_ve_open_bool
-}
-\cs_new_protected_nopar:Nn\ocgxii_ve_or:nN{
- \bool_set_true:N\l_ocgxii_ve_open_bool
- \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Or}
- \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
- \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
- \bool_set_false:N\l_ocgxii_ve_open_bool
-}
-\cs_new_protected_nopar:Nn\ocgxii_ve_not:nN{
- \bool_set_true:N\l_ocgxii_ve_open_bool
- % only one item allowed in \Not{...} argument
- \int_compare:nNnT{\clist_count:n{#1}}>{\c_one_int}{
- \msg_error:nnnn{ocgx2}{generic~msg}{
- More~than~one~item~passed~to~\Not{...}.
- }{
- Only~one~item~is~allowed.
- }
- }
- \int_compare:nNnT{\clist_count:n{#1}}={\c_one_int}{
- \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Not}
+ \cs_new_protected_nopar:Nn\ocgxii_allon_to_ve:n{\And{#1}}
+ \cs_new_protected_nopar:Nn\ocgxii_anyon_to_ve:n{\Or{#1}}
+ \cs_new_protected_nopar:Nn\ocgxii_anyoff_to_ve:n{\Not{\And{#1}}}
+ \cs_new_protected_nopar:Nn\ocgxii_alloff_to_ve:n{\Not{\Or{#1}}}
+ % visib. boolean expressions
+ \cs_new_protected_nopar:Nn\ocgxii_ve_and:nN{
+ \bool_set_true:N\l_ocgxii_ve_open_bool
+ \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/And}
\clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
\tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ \bool_set_false:N\l_ocgxii_ve_open_bool
}
- \bool_set_false:N\l_ocgxii_ve_open_bool
-}
-\cs_new_protected_nopar:Nn\ocgxii_ve_check:n{VisExpr}
-\tl_set:cn{ocgxii_VisExpr}{VisExpr}
-\cs_new_protected_nopar:Nn\ocgxii_vp_check:n{VisPol}
-\tl_set:cn{ocgxii_VisPol}{VisPol}
-\tl_set:Nx\g_ocgxii_left_bracket_tl{\tl_to_str:N[}
-\tl_set:Nx\g_ocgxii_right_bracket_tl{\tl_to_str:N]}
-\int_new:N\l_ocgxii_vp_cnt_int %number of visib. policies
-\int_new:N\l_ocgxii_ve_cnt_int %number of visib. expressions
-\bool_new:N\l_ocgxii_vp_open_bool %for nesting test
-\bool_new:N\l_ocgxii_ve_open_bool %for nesting test
-\tl_set:Nn\g_ocgxii_help_msg_tl{
- At~most~one~visibility~policy~and,~separated~by~a~comma,~at~most~one~
- visibility~expression~may~be~passed~as~the~2nd~argument~to~the~`ocmd'~
- environment.~A~visibility~
- policy~is~defined~by~one~of~\AllOn{...},~\AnyOn{...},~\AnyOff{...},~
- \AllOff{...}.~A~visibility~expression~is~a~boolean~expression~built~by~
- nesting~any~number~of~\And{...},~\Or{...},~\Not{...}~commands.~If~both~are~
- provided,~the~visibility~expression~takes~precedence~over~the~policy,~but~the~
- latter~may~be~used~as~fallback~by~non-conforming~PDF~viewers.
-}
-%command that builds /OC entry from open layer stack
-\cs_new_nopar:Nn\ocgxii_make_oc_entry:{
- \group_begin:
- \tl_gclear:N\g_ocgxii_oc_entry_tl
- \tl_clear:N\l_tempa_tl
- \seq_if_empty:NF\g_ocgbase_open_stack_seq{
- \seq_clear:N\l_tempa_seq
- %additional level of braces around indirect PDF objects (needed for dvips)
- \seq_map_inline:Nn\g_ocgbase_open_stack_seq{
- \seq_put_right:Nn\l_tempa_seq{{##1}}
+ \cs_new_protected_nopar:Nn\ocgxii_ve_or:nN{
+ \bool_set_true:N\l_ocgxii_ve_open_bool
+ \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Or}
+ \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
+ \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ \bool_set_false:N\l_ocgxii_ve_open_bool
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_ve_not:nN{
+ \bool_set_true:N\l_ocgxii_ve_open_bool
+ % only one item allowed in \Not{...} argument
+ \int_compare:nNnT{\clist_count:n{#1}}>{\c_one_int}{
+ \msg_error:nnnn{ocgx2}{generic~msg}{
+ More~than~one~item~passed~to~\Not{...}.
+ }{
+ Only~one~item~is~allowed.
+ }
}
- \ocgxii_omcd_parse_argument:xN{
- \exp_not:N\And{\seq_use:Nn\l_tempa_seq{,}}
- }\l_tempa_tl
- \tl_gset:Nx\g_ocgxii_oc_entry_tl{/OC~<</Type/OCMD\l_tempa_tl>>}
+ \int_compare:nNnT{\clist_count:n{#1}}={\c_one_int}{
+ \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Not}
+ \clist_map_inline:nn{#1}{\ocgxii_ocmd_expression_parser:nN{##1}#2}
+ \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ }
+ \bool_set_false:N\l_ocgxii_ve_open_bool
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_ve_check:n{VisExpr}
+ \tl_set:cn{ocgxii_VisExpr}{VisExpr}
+ \cs_new_protected_nopar:Nn\ocgxii_vp_check:n{VisPol}
+ \tl_set:cn{ocgxii_VisPol}{VisPol}
+ \tl_set:Nx\g_ocgxii_left_bracket_tl{\tl_to_str:N[}
+ \tl_set:Nx\g_ocgxii_right_bracket_tl{\tl_to_str:N]}
+ \int_new:N\l_ocgxii_vp_cnt_int %number of visib. policies
+ \int_new:N\l_ocgxii_ve_cnt_int %number of visib. expressions
+ \bool_new:N\l_ocgxii_vp_open_bool %for nesting test
+ \bool_new:N\l_ocgxii_ve_open_bool %for nesting test
+ \tl_set:Nn\g_ocgxii_help_msg_tl{
+ At~most~one~visibility~policy~and,~separated~by~a~comma,~at~most~one~
+ visibility~expression~may~be~passed~as~the~2nd~argument~to~the~`ocmd'~
+ environment.~A~visibility~
+ policy~is~defined~by~one~of~\AllOn{...},~\AnyOn{...},~\AnyOff{...},~
+ \AllOff{...}.~A~visibility~expression~is~a~boolean~expression~built~by~
+ nesting~any~number~of~\And{...},~\Or{...},~\Not{...}~commands.~If~both~are~
+ provided,~the~visibility~expression~takes~precedence~over~the~policy,~but~the~
+ latter~may~be~used~as~fallback~by~non-conforming~PDF~viewers.
+ }
+ %command that builds /OC entry from open layer stack
+ \cs_new_nopar:Nn\ocgxii_make_oc_entry:{
+ \group_begin:
+ \tl_gclear:N\g_ocgxii_oc_entry_tl
+ \tl_clear:N\l_tempa_tl
+ \seq_if_empty:NF\g_ocgbase_open_stack_seq{
+ \seq_clear:N\l_tempa_seq
+ %additional level of braces around indirect PDF objects (needed for dvips)
+ \seq_map_inline:Nn\g_ocgbase_open_stack_seq{
+ \seq_put_right:Nn\l_tempa_seq{{##1}}
+ }
+ \ocgxii_omcd_parse_argument:xN{
+ \exp_not:N\And{\seq_use:Nn\l_tempa_seq{,}}
+ }\l_tempa_tl
+ \tl_gset:Nx\g_ocgxii_oc_entry_tl{/OC~<</Type/OCMD\l_tempa_tl>>}
+ }
+ \group_end:
}
- \group_end:
-}
-%programmer/author command that inserts /OC << >> entry; for use in
-%annotation/xobject dicts, in order to make them layer-aware
-\cs_new_nopar:Nn\ocgxii_insert_oc:{\g_ocgxii_oc_entry_tl}
-\cs_gset_eq:NN\ocgbase_insert_oc:\ocgxii_insert_oc:
-\cs_gset_eq:NN\ocgbase@insert@oc\ocgxii_insert_oc:
-\tl_new:N\g_ocgxii_oc_entry_tl
+ %programmer/author command that inserts /OC << >> entry; for use in
+ %annotation/xobject dicts, in order to make them layer-aware
+ \cs_new_nopar:Nn\ocgxii_insert_oc:{\g_ocgxii_oc_entry_tl}
+ \cs_gset_eq:NN\ocgbase_insert_oc:\ocgxii_insert_oc:
+ \cs_gset_eq:NN\ocgbase@insert@oc\ocgxii_insert_oc:
+ \tl_new:N\g_ocgxii_oc_entry_tl
-\cs_new_protected_nopar:Nn\ocgxii_stack_shipout:NN{
- \iow_shipout_x:Nx\@mainaux{
- \token_to_str:N#1{
- \exp_not:N\int_use:N\g_ocgxii_page_int
- }{\seq_use:Nn#2{,}}
+ \cs_new_protected_nopar:Nn\ocgxii_stack_shipout:NN{
+ \iow_shipout_x:Nx\@mainaux{
+ \token_to_str:N#1{
+ \exp_not:N\int_use:N\g_ocgxii_page_int
+ }{\seq_use:Nn#2{,}}
+ }
}
-}
-\cs_new_protected_nopar:Npn\ocgxii@ocg@stack@on@page#1#2{
- \seq_gset_from_clist:cn{g_pending_ocgs_on_#1_seq}{#2}
- %re-add braces around items for dvips
- \bool_if:nT{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
- \seq_map_inline:cn{g_pending_ocgs_on_#1_seq}{
- \seq_gpop_left:cN{g_pending_ocgs_on_#1_seq}\l_trash_tl
- \seq_gput_right:cn{g_pending_ocgs_on_#1_seq}{{##1}}
+ \cs_new_protected_nopar:Npn\ocgxii@ocg@stack@on@page#1#2{
+ \seq_gset_from_clist:cn{g_pending_ocgs_on_#1_seq}{#2}
+ %re-add braces around items for dvips
+ \bool_if:nT{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
+ \seq_map_inline:cn{g_pending_ocgs_on_#1_seq}{
+ \seq_gpop_left:cN{g_pending_ocgs_on_#1_seq}\l_trash_tl
+ \seq_gput_right:cn{g_pending_ocgs_on_#1_seq}{{##1}}
+ }
}
}
-}
-\ocgxii@ocg@stack@on@page{0}{} %initialize
+ \ocgxii@ocg@stack@on@page{0}{} %initialize
-\cs_new_protected_nopar:Npn\ocgxii@lnkcol@stack@on@page#1#2{
- \seq_gset_from_clist:cn{g_pending_lnkcols_on_#1_seq}{#2}
- %re-add braces around items
- \seq_map_inline:cn{g_pending_lnkcols_on_#1_seq}{
- \seq_gpop_left:cN{g_pending_lnkcols_on_#1_seq}\l_trash_tl
- \seq_gput_right:cn{g_pending_lnkcols_on_#1_seq}{{##1}}
+ \cs_new_protected_nopar:Npn\ocgxii@lnkcol@stack@on@page#1#2{
+ \seq_gset_from_clist:cn{g_pending_lnkcols_on_#1_seq}{#2}
+ %re-add braces around items
+ \seq_map_inline:cn{g_pending_lnkcols_on_#1_seq}{
+ \seq_gpop_left:cN{g_pending_lnkcols_on_#1_seq}\l_trash_tl
+ \seq_gput_right:cn{g_pending_lnkcols_on_#1_seq}{{##1}}
+ }
}
-}
-\ocgxii@lnkcol@stack@on@page{0}{} %initialize
+ \ocgxii@lnkcol@stack@on@page{0}{} %initialize
-%end-of-page action
-\pbs_eop_action:n{
- \seq_if_exist:cT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
- %check whether end-of-page link colour stack has settled
+ %end-of-page action
+ \pbs_eop_action:n{
+ \seq_if_exist:cT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
+ %check whether end-of-page link colour stack has settled
+ \iow_shipout:Nx\@mainaux{
+ \token_to_str:N\ocgxii@newkey{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
+ \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
+ }
+ }
+ \bool_if:nT{
+ !\cs_if_exist:cTF{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
+ \str_if_eq_p:ee{
+ \tl_use:c{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}
+ }{
+ \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
+ }
+ }{
+ \c_false_bool
+ }
+ }{
+ \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
+ \tl_new:N\g_ocgxii_rerunwarned_tl
+ \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
+ }
+ }
+ % now close the colourlink opened last
+ \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
+ \tl_gset:Nx\g_ocgxii_lnkcol_tl{{\l_tmpa_tl}}
+ \ocgxii_colourlink_end:
+ }
+ }
+ %check whether end-of-page ocg stack has settled
\iow_shipout:Nx\@mainaux{
- \token_to_str:N\ocgxii@newkey{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
- \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
+ \token_to_str:N\ocgxii@newkey{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
+ \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
}
}
\bool_if:nT{
- !\cs_if_exist:cTF{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
+ !\cs_if_exist:cTF{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
\str_if_eq_p:ee{
- \tl_use:c{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}
+ \tl_use:c{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}
}{
- \seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
+ \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
}
}{
\c_false_bool
@@ -614,306 +640,300 @@
\AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
}
}
- % now close the colourlink opened last
- \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
- \tl_gset:Nx\g_ocgxii_lnkcol_tl{{\l_tmpa_tl}}
- \ocgxii_colourlink_end:
- }
- }
- %check whether end-of-page ocg stack has settled
- \iow_shipout:Nx\@mainaux{
- \token_to_str:N\ocgxii@newkey{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
- \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
- }
- }
- \bool_if:nT{
- !\cs_if_exist:cTF{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
- \str_if_eq_p:ee{
- \tl_use:c{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}
- }{
- \seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
- }
- }{
- \c_false_bool
- }
- }{
- \tl_if_exist:NF\g_ocgxii_rerunwarned_tl{
- \tl_new:N\g_ocgxii_rerunwarned_tl
- \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
- }
- }
- %now close pending ocgs
- \seq_map_variable:cNn{
- g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
- }\l_tmpb_tl{\ocgbase_oc_emc:}
-}
-
-%begin-of-page action
-\pbs_bop_action:n{
- % re-open all pending ocgs in original order
- \seq_set_eq:Nc\l_ocgxii_pending_ocgs_seq{
- g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
- }
- \seq_reverse:N\l_ocgxii_pending_ocgs_seq
- \seq_map_variable:NNn\l_ocgxii_pending_ocgs_seq\l_tmpa_tl{
- \ocgbase_oc_bdc:n{\l_tmpa_tl}
- }
- % re-open the colourlink opened last
- \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
- \tl_gset:Nx\g_ocgxii_lnkcol_tl{{\l_tmpa_tl}}
- \ocgxii_colourlink_begin:
- }
- \int_gincr:N\g_ocgxii_page_int
- % copy pending ocg stack from previous page, if it has not been initialized
- % yet from aux file
- \seq_if_exist:cF{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{
- \seq_gset_eq:cc{
+ %now close pending ocgs
+ \seq_map_variable:cNn{
g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
- }{
- g_pending_ocgs_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
- }
- }
- %the same for link colour stack
- \seq_if_exist:cF{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
- \seq_gset_eq:cc{
- g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq
- }{
- g_pending_lnkcols_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
- }
+ }\l_tmpb_tl{\ocgbase_oc_emc:}
}
-}
-\int_new:N\g_ocgxii_page_int %abs. page counter
-\cs_new_protected_nopar:Nn\ocgxii_ocglist_reset:{
- \tl_clear_new:N\l_ocgxii_u_list_tl
- \tl_clear_new:N\l_ocgxii_d_list_tl
- \tl_clear_new:N\l_ocgxii_e_list_tl
- \tl_clear_new:N\l_ocgxii_x_list_tl
-}
-
-\cs_new_protected_nopar:Nn\ocgxii_ocglist_build:Nn{
- \tl_set:Nx\l_ocglistarg_tl{#2}\tl_trim_spaces:N\l_ocglistarg_tl
- % first try splitting at commas (ocgx2 syntax)
- \tl_set_eq:NN\l_tmpa_tl\l_ocglistarg_tl
- \tl_remove_all:Nn\l_tmpa_tl{~}
- \seq_set_split:NnV\l_ocgxii_ocglistarg_seq{,}\l_tmpa_tl
- \seq_remove_all:Nn\l_ocgxii_ocglistarg_seq{}
- \tl_set:Nx\l_tmpa_tl{\seq_count:N\l_ocgxii_ocglistarg_seq}
- % now at spaces (legacy ocgx/ocg-p)
- \tl_set_eq:NN\l_tmpb_tl\l_ocglistarg_tl
- \tl_remove_all:Nn\l_tmpb_tl{,}
- \seq_set_split:NnV\l_tmpb_seq{~}\l_tmpb_tl
- \seq_remove_all:Nn\l_tmpb_seq{}
- \tl_set:Nx\l_tmpb_tl{\seq_count:N\l_tmpb_seq}
- %take the seq having more elements (guessing the separator most likely used)
- \int_compare:nT{\l_tmpb_tl>\l_tmpa_tl}{
- \seq_set_eq:NN\l_ocgxii_ocglistarg_seq\l_tmpb_seq
- }
- \seq_map_variable:NNn\l_ocgxii_ocglistarg_seq\l_tempa_tl{
- \ocgxii_process_ocgref:NN#1\l_tempa_tl
- }
-}
-
-\cs_new_protected:Nn\ocgxii_commalist_process:n{
- \seq_set_split:Nnn\l_tmpa_seq{,}{#1}
- \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{\seq_item:Nn\l_tmpa_seq{1}}
- \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{\seq_item:Nn\l_tmpa_seq{2}}
- \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{\seq_item:Nn\l_tmpa_seq{3}}
- \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{\seq_item:Nn\l_tmpa_seq{4}}
-}
-
-\cs_new_protected_nopar:Nn\ocgxii_ocglist_process_idlist:nn{
- \ocgxii_ocglist_reset:
- \tl_set:Nx\l_ocgxii_opt_tl{#1}\tl_remove_all:Nn\l_ocgxii_opt_tl{~}
- \str_case_e:nnF{\l_ocgxii_opt_tl}{
- {onmouseup}{
- \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{#2}
+ %begin-of-page action
+ \pbs_bop_action:n{
+ % re-open all pending ocgs in original order
+ \seq_set_eq:Nc\l_ocgxii_pending_ocgs_seq{
+ g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
}
- {onmousedown}{
- \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{#2}
+ \seq_reverse:N\l_ocgxii_pending_ocgs_seq
+ \seq_map_variable:NNn\l_ocgxii_pending_ocgs_seq\l_tmpa_tl{
+ \ocgbase_oc_bdc:n{\l_tmpa_tl}
}
- {onmouseenter}{
- \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{#2}
+ % re-open the colourlink opened last
+ \seq_get:cNT{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}\l_tmpa_tl{
+ \tl_gset:Nx\g_ocgxii_lnkcol_tl{{\l_tmpa_tl}}
+ \ocgxii_colourlink_begin:
}
- {onmouseexit}{
- \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{#2}
+ \int_gincr:N\g_ocgxii_page_int
+ % copy pending ocg stack from previous page, if it has not been initialized
+ % yet from aux file
+ \seq_if_exist:cF{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{
+ \seq_gset_eq:cc{
+ g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
+ }{
+ g_pending_ocgs_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
+ }
}
- {onmouseall}{
- \ocgxii_commalist_process:n{#2}
+ %the same for link colour stack
+ \seq_if_exist:cF{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{
+ \seq_gset_eq:cc{
+ g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq
+ }{
+ g_pending_lnkcols_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
+ }
}
- }{
- \msg_error:nnx{ocgx2}{unknown~option}{\l_ocgxii_opt_tl}
}
-}
-
-\int_new:N\g_ocgxii_widcount_int% widget counter
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% re-implement commands from ocgx.sty (all engines including ps2pdf [gs>=9.15])
-% adding optional `*' (arg 1) -> non-breakable link instead of plain (multiline)
-% Link;
-% adding optional 2nd argument -> Button Widget (non-breakable) with one of
-% various mouse triggers (`troggerocgs` option from ocg-p)
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\DeclareDocumentCommand\switchocg{s O{} m +m}{
- \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{}{}{#4}
-}
-
-\DeclareDocumentCommand\showocg{s O{} m +m}{
- \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{#3}{}{#4}
-}
-
-\DeclareDocumentCommand\hideocg{s O{} m +m}{
- \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{}{#3}{#4}
-}
-
-\DeclareDocumentCommand\actionsocg{s O{} m m m +m}{
- \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{#4}{#5}{#6}
-}
-
-\bool_new:N\l_ocgxii_mouse_triggers_bool
-\bool_new:N\l_ocgxii_nobreak_bool
-\cs_new_protected:Nn\ocgxii_actionsocg:nnnnnn{
- \leavevmode
- \bool_set_false:N\l_ocgxii_mouse_triggers_bool
- \bool_set_false:N\l_ocgxii_nobreak_bool
- % explicitly non-breakable?
- \bool_if:nT{#1}{\bool_set_true:N\l_ocgxii_nobreak_bool}
- %
- %clear actions for various mouse triggers (e,d,x)
- \tl_clear:N\l_ocgxii_toswitch_e_tl
- \tl_clear:N\l_ocgxii_toswitch_x_tl
- \tl_clear:N\l_ocgxii_toswitch_d_tl
- \tl_clear:N\l_ocgxii_toshow_e_tl
- \tl_clear:N\l_ocgxii_toshow_x_tl
- \tl_clear:N\l_ocgxii_toshow_d_tl
- \tl_clear:N\l_ocgxii_tohide_e_tl
- \tl_clear:N\l_ocgxii_tohide_x_tl
- \tl_clear:N\l_ocgxii_tohide_d_tl
- %
- %process *all* mouse triggers (e,d,u,x)
- \ocgxii_ocglist_process_idlist:nn{
- \tl_if_blank:oTF{#2}{onmouseup}{#2}
- }{#3}
- \tl_set_eq:NN\l_ocgxii_toswitch_e_tl\l_ocgxii_e_list_tl
- \tl_set_eq:NN\l_ocgxii_toswitch_x_tl\l_ocgxii_x_list_tl
- \tl_set_eq:NN\l_ocgxii_toswitch_d_tl\l_ocgxii_d_list_tl
- \tl_set_eq:NN\l_ocgxii_toswitch_u_tl\l_ocgxii_u_list_tl
- \ocgxii_ocglist_process_idlist:nn{
- \tl_if_blank:oTF{#2}{onmouseup}{#2}
- }{#4}
- \tl_set_eq:NN\l_ocgxii_toshow_e_tl\l_ocgxii_e_list_tl
- \tl_set_eq:NN\l_ocgxii_toshow_x_tl\l_ocgxii_x_list_tl
- \tl_set_eq:NN\l_ocgxii_toshow_d_tl\l_ocgxii_d_list_tl
- \tl_set_eq:NN\l_ocgxii_toshow_u_tl\l_ocgxii_u_list_tl
- \ocgxii_ocglist_process_idlist:nn{
- \tl_if_blank:oTF{#2}{onmouseup}{#2}
- }{#5}
- \tl_set_eq:NN\l_ocgxii_tohide_e_tl\l_ocgxii_e_list_tl
- \tl_set_eq:NN\l_ocgxii_tohide_x_tl\l_ocgxii_x_list_tl
- \tl_set_eq:NN\l_ocgxii_tohide_d_tl\l_ocgxii_d_list_tl
- \tl_set_eq:NN\l_ocgxii_tohide_u_tl\l_ocgxii_u_list_tl
- %any triggers apart from mouse-up?
- \str_if_eq:eeF{
- \l_ocgxii_toswitch_e_tl\l_ocgxii_toswitch_x_tl\l_ocgxii_toswitch_d_tl
- \l_ocgxii_toshow_e_tl\l_ocgxii_toshow_x_tl\l_ocgxii_toshow_d_tl
- \l_ocgxii_tohide_e_tl\l_ocgxii_tohide_x_tl\l_ocgxii_tohide_d_tl
- }{}{
- \bool_set_true:N\l_ocgxii_mouse_triggers_bool
- }
- %
- \bool_if:nTF{\l_ocgxii_nobreak_bool || \l_ocgxii_mouse_triggers_bool}{
- \hbox_set:Nn\l_tmpa_box{#6}
- \pbs_pdfannot:nnnn{
- \dim_use:N\box_wd:N\l_tmpa_box}{
- \dim_use:N\box_ht:N\l_tmpa_box}{
- \dim_use:N\box_dp:N\l_tmpa_box
+ \int_new:N\g_ocgxii_page_int %abs. page counter
+
+ \cs_new_protected_nopar:Nn\ocgxii_ocglist_reset:{
+ \tl_clear_new:N\l_ocgxii_u_list_tl
+ \tl_clear_new:N\l_ocgxii_d_list_tl
+ \tl_clear_new:N\l_ocgxii_e_list_tl
+ \tl_clear_new:N\l_ocgxii_x_list_tl
+ }
+
+ \cs_new_protected_nopar:Nn\ocgxii_ocglist_build:Nn{
+ \tl_set:Nx\l_ocglistarg_tl{#2}\tl_trim_spaces:N\l_ocglistarg_tl
+ % first try splitting at commas (ocgx2 syntax)
+ \tl_set_eq:NN\l_tmpa_tl\l_ocglistarg_tl
+ \tl_remove_all:Nn\l_tmpa_tl{~}
+ \seq_set_split:NnV\l_ocgxii_ocglistarg_seq{,}\l_tmpa_tl
+ \seq_remove_all:Nn\l_ocgxii_ocglistarg_seq{}
+ \tl_set:Nx\l_tmpa_tl{\seq_count:N\l_ocgxii_ocglistarg_seq}
+ % now at spaces (legacy ocgx/ocg-p)
+ \tl_set_eq:NN\l_tmpb_tl\l_ocglistarg_tl
+ \tl_remove_all:Nn\l_tmpb_tl{,}
+ \seq_set_split:NnV\l_tmpb_seq{~}\l_tmpb_tl
+ \seq_remove_all:Nn\l_tmpb_seq{}
+ \tl_set:Nx\l_tmpb_tl{\seq_count:N\l_tmpb_seq}
+ %take the seq having more elements (guessing the separator most likely used)
+ \int_compare:nT{\l_tmpb_tl>\l_tmpa_tl}{
+ \seq_set_eq:NN\l_ocgxii_ocglistarg_seq\l_tmpb_seq
+ }
+ \seq_map_variable:NNn\l_ocgxii_ocglistarg_seq\l_tempa_tl{
+ \ocgxii_process_ocgref:NN#1\l_tempa_tl
+ }
+ }
+
+ \cs_new_protected:Nn\ocgxii_commalist_process:n{
+ \seq_set_split:Nnn\l_tmpa_seq{,}{#1}
+ \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{\seq_item:Nn\l_tmpa_seq{1}}
+ \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{\seq_item:Nn\l_tmpa_seq{2}}
+ \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{\seq_item:Nn\l_tmpa_seq{3}}
+ \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{\seq_item:Nn\l_tmpa_seq{4}}
+ }
+
+ \cs_new_protected_nopar:Nn\ocgxii_ocglist_process_idlist:nn{
+ \ocgxii_ocglist_reset:
+ \tl_set:Nx\l_ocgxii_opt_tl{#1}\tl_remove_all:Nn\l_ocgxii_opt_tl{~}
+ \str_case_e:nnF{\l_ocgxii_opt_tl}{
+ {onmouseup}{
+ \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{#2}
+ }
+ {onmousedown}{
+ \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{#2}
+ }
+ {onmouseenter}{
+ \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{#2}
+ }
+ {onmouseexit}{
+ \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{#2}
+ }
+ {onmouseall}{
+ \ocgxii_commalist_process:n{#2}
+ }
}{
- \bool_if:NTF\l_ocgxii_mouse_triggers_bool{
- % e,d,x mouse triggers require (non-breakable) /Widget annot with AA
- % (additional actions) dict
- /Subtype/Widget/Ff~65536/FT/Btn/BS<</W~0>>
- /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
- %treat mouse-up as mouse-click --> handle through /A dictionary
- \str_if_eq:eeF{}{
- \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
- }{
- /A <</S/SetOCGState/State [
- \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
- /Toggle~\l_ocgxii_toswitch_u_tl
- }
- \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
- /ON~\l_ocgxii_toshow_u_tl
- }
- \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
- /OFF~\l_ocgxii_tohide_u_tl
- }
- ]>>
- }
- /AA <<
- %\str_if_eq:eeF{}{ % mouse-up
- % \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
- %}{
- % /U <</S/SetOCGState/State [
- % \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
- % /Toggle~\l_ocgxii_toswitch_u_tl
- % }
- % \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
- % /ON~\l_ocgxii_toshow_u_tl
- % }
- % \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
- % /OFF~\l_ocgxii_tohide_u_tl
- % }
- % ]>>
- %}
- \str_if_eq:eeF{}{ % mouse-down
- \l_ocgxii_toswitch_d_tl\l_ocgxii_toshow_d_tl\l_ocgxii_tohide_d_tl
- }{
- /D <</S/SetOCGState/State [
- \str_if_eq:VnF\l_ocgxii_toswitch_d_tl{}{
- /Toggle~\l_ocgxii_toswitch_d_tl
- }
- \str_if_eq:VnF\l_ocgxii_toshow_d_tl{}{
- /ON~\l_ocgxii_toshow_d_tl
- }
- \str_if_eq:VnF\l_ocgxii_tohide_d_tl{}{
- /OFF~\l_ocgxii_tohide_d_tl
- }
- ]>>
- }
- \str_if_eq:eeF{}{ % mouse-enter
- \l_ocgxii_toswitch_e_tl\l_ocgxii_toshow_e_tl\l_ocgxii_tohide_e_tl
- }{
- /E <</S/SetOCGState/State [
- \str_if_eq:VnF\l_ocgxii_toswitch_e_tl{}{
- /Toggle~\l_ocgxii_toswitch_e_tl
- }
- \str_if_eq:VnF\l_ocgxii_toshow_e_tl{}{
- /ON~\l_ocgxii_toshow_e_tl
- }
- \str_if_eq:VnF\l_ocgxii_tohide_e_tl{}{
- /OFF~\l_ocgxii_tohide_e_tl
- }
- ]>>
- }
- \str_if_eq:eeF{}{ % mouse-exit
- \l_ocgxii_toswitch_x_tl\l_ocgxii_toshow_x_tl\l_ocgxii_tohide_x_tl
+ \msg_error:nnx{ocgx2}{unknown~option}{\l_ocgxii_opt_tl}
+ }
+ }
+
+ \int_new:N\g_ocgxii_widcount_int% widget counter
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % re-implement commands from ocgx.sty (all engines including ps2pdf [gs>=9.15])
+ % adding optional `*' (arg 1) -> non-breakable link instead of plain (multiline)
+ % Link;
+ % adding optional 2nd argument -> Button Widget (non-breakable) with one of
+ % various mouse triggers (`troggerocgs` option from ocg-p)
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \DeclareDocumentCommand\switchocg{s O{} m +m}{
+ \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{}{}{#4}
+ }
+
+ \DeclareDocumentCommand\showocg{s O{} m +m}{
+ \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{#3}{}{#4}
+ }
+
+ \DeclareDocumentCommand\hideocg{s O{} m +m}{
+ \ocgxii_actionsocg:nnnnnn{#1}{#2}{}{}{#3}{#4}
+ }
+
+ \DeclareDocumentCommand\actionsocg{s O{} m m m +m}{
+ \ocgxii_actionsocg:nnnnnn{#1}{#2}{#3}{#4}{#5}{#6}
+ }
+
+ \bool_new:N\l_ocgxii_mouse_triggers_bool
+ \bool_new:N\l_ocgxii_nobreak_bool
+ \cs_new_protected:Nn\ocgxii_actionsocg:nnnnnn{
+ \leavevmode
+ \bool_set_false:N\l_ocgxii_mouse_triggers_bool
+ \bool_set_false:N\l_ocgxii_nobreak_bool
+ % explicitly non-breakable?
+ \bool_if:nT{#1}{\bool_set_true:N\l_ocgxii_nobreak_bool}
+ %
+ %clear actions for various mouse triggers (e,d,x)
+ \tl_clear:N\l_ocgxii_toswitch_e_tl
+ \tl_clear:N\l_ocgxii_toswitch_x_tl
+ \tl_clear:N\l_ocgxii_toswitch_d_tl
+ \tl_clear:N\l_ocgxii_toshow_e_tl
+ \tl_clear:N\l_ocgxii_toshow_x_tl
+ \tl_clear:N\l_ocgxii_toshow_d_tl
+ \tl_clear:N\l_ocgxii_tohide_e_tl
+ \tl_clear:N\l_ocgxii_tohide_x_tl
+ \tl_clear:N\l_ocgxii_tohide_d_tl
+ %
+ %process *all* mouse triggers (e,d,u,x)
+ \ocgxii_ocglist_process_idlist:nn{
+ \tl_if_blank:oTF{#2}{onmouseup}{#2}
+ }{#3}
+ \tl_set_eq:NN\l_ocgxii_toswitch_e_tl\l_ocgxii_e_list_tl
+ \tl_set_eq:NN\l_ocgxii_toswitch_x_tl\l_ocgxii_x_list_tl
+ \tl_set_eq:NN\l_ocgxii_toswitch_d_tl\l_ocgxii_d_list_tl
+ \tl_set_eq:NN\l_ocgxii_toswitch_u_tl\l_ocgxii_u_list_tl
+ \ocgxii_ocglist_process_idlist:nn{
+ \tl_if_blank:oTF{#2}{onmouseup}{#2}
+ }{#4}
+ \tl_set_eq:NN\l_ocgxii_toshow_e_tl\l_ocgxii_e_list_tl
+ \tl_set_eq:NN\l_ocgxii_toshow_x_tl\l_ocgxii_x_list_tl
+ \tl_set_eq:NN\l_ocgxii_toshow_d_tl\l_ocgxii_d_list_tl
+ \tl_set_eq:NN\l_ocgxii_toshow_u_tl\l_ocgxii_u_list_tl
+ \ocgxii_ocglist_process_idlist:nn{
+ \tl_if_blank:oTF{#2}{onmouseup}{#2}
+ }{#5}
+ \tl_set_eq:NN\l_ocgxii_tohide_e_tl\l_ocgxii_e_list_tl
+ \tl_set_eq:NN\l_ocgxii_tohide_x_tl\l_ocgxii_x_list_tl
+ \tl_set_eq:NN\l_ocgxii_tohide_d_tl\l_ocgxii_d_list_tl
+ \tl_set_eq:NN\l_ocgxii_tohide_u_tl\l_ocgxii_u_list_tl
+ %any triggers apart from mouse-up?
+ \str_if_eq:eeF{
+ \l_ocgxii_toswitch_e_tl\l_ocgxii_toswitch_x_tl\l_ocgxii_toswitch_d_tl
+ \l_ocgxii_toshow_e_tl\l_ocgxii_toshow_x_tl\l_ocgxii_toshow_d_tl
+ \l_ocgxii_tohide_e_tl\l_ocgxii_tohide_x_tl\l_ocgxii_tohide_d_tl
+ }{}{
+ \bool_set_true:N\l_ocgxii_mouse_triggers_bool
+ }
+ %
+ \bool_if:nTF{\l_ocgxii_nobreak_bool || \l_ocgxii_mouse_triggers_bool}{
+ \hbox_set:Nn\l_tmpa_box{#6}
+ \pbs_pdfannot:nnnn{
+ \dim_use:N\box_wd:N\l_tmpa_box}{
+ \dim_use:N\box_ht:N\l_tmpa_box}{
+ \dim_use:N\box_dp:N\l_tmpa_box
+ }{
+ \bool_if:NTF\l_ocgxii_mouse_triggers_bool{
+ % e,d,x mouse triggers require (non-breakable) /Widget annot with AA
+ % (additional actions) dict
+ /Subtype/Widget/Ff~65536/FT/Btn/BS<</W~0>>
+ /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
+ %treat mouse-up as mouse-click --> handle through /A dictionary
+ \str_if_eq:eeF{}{
+ \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
}{
- /X <</S/SetOCGState/State [
- \str_if_eq:VnF\l_ocgxii_toswitch_x_tl{}{
- /Toggle~\l_ocgxii_toswitch_x_tl
+ /A <</S/SetOCGState/State [
+ \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
+ /Toggle~\l_ocgxii_toswitch_u_tl
}
- \str_if_eq:VnF\l_ocgxii_toshow_x_tl{}{
- /ON~\l_ocgxii_toshow_x_tl
+ \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
+ /ON~\l_ocgxii_toshow_u_tl
}
- \str_if_eq:VnF\l_ocgxii_tohide_x_tl{}{
- /OFF~\l_ocgxii_tohide_x_tl
+ \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
+ /OFF~\l_ocgxii_tohide_u_tl
}
]>>
}
- >>
- }{
- %mouse-up alone may go with simple /Link annot
+ /AA <<
+ %\str_if_eq:eeF{}{ % mouse-up
+ % \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
+ %}{
+ % /U <</S/SetOCGState/State [
+ % \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
+ % /Toggle~\l_ocgxii_toswitch_u_tl
+ % }
+ % \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
+ % /ON~\l_ocgxii_toshow_u_tl
+ % }
+ % \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
+ % /OFF~\l_ocgxii_tohide_u_tl
+ % }
+ % ]>>
+ %}
+ \str_if_eq:eeF{}{ % mouse-down
+ \l_ocgxii_toswitch_d_tl\l_ocgxii_toshow_d_tl\l_ocgxii_tohide_d_tl
+ }{
+ /D <</S/SetOCGState/State [
+ \str_if_eq:VnF\l_ocgxii_toswitch_d_tl{}{
+ /Toggle~\l_ocgxii_toswitch_d_tl
+ }
+ \str_if_eq:VnF\l_ocgxii_toshow_d_tl{}{
+ /ON~\l_ocgxii_toshow_d_tl
+ }
+ \str_if_eq:VnF\l_ocgxii_tohide_d_tl{}{
+ /OFF~\l_ocgxii_tohide_d_tl
+ }
+ ]>>
+ }
+ \str_if_eq:eeF{}{ % mouse-enter
+ \l_ocgxii_toswitch_e_tl\l_ocgxii_toshow_e_tl\l_ocgxii_tohide_e_tl
+ }{
+ /E <</S/SetOCGState/State [
+ \str_if_eq:VnF\l_ocgxii_toswitch_e_tl{}{
+ /Toggle~\l_ocgxii_toswitch_e_tl
+ }
+ \str_if_eq:VnF\l_ocgxii_toshow_e_tl{}{
+ /ON~\l_ocgxii_toshow_e_tl
+ }
+ \str_if_eq:VnF\l_ocgxii_tohide_e_tl{}{
+ /OFF~\l_ocgxii_tohide_e_tl
+ }
+ ]>>
+ }
+ \str_if_eq:eeF{}{ % mouse-exit
+ \l_ocgxii_toswitch_x_tl\l_ocgxii_toshow_x_tl\l_ocgxii_tohide_x_tl
+ }{
+ /X <</S/SetOCGState/State [
+ \str_if_eq:VnF\l_ocgxii_toswitch_x_tl{}{
+ /Toggle~\l_ocgxii_toswitch_x_tl
+ }
+ \str_if_eq:VnF\l_ocgxii_toshow_x_tl{}{
+ /ON~\l_ocgxii_toshow_x_tl
+ }
+ \str_if_eq:VnF\l_ocgxii_tohide_x_tl{}{
+ /OFF~\l_ocgxii_tohide_x_tl
+ }
+ ]>>
+ }
+ >>
+ }{
+ %mouse-up alone may go with simple /Link annot
+ /Subtype/Link
+ /A <</S/SetOCGState
+ /State [
+ \str_if_eq:VnF{\l_ocgxii_toswitch_u_tl}{}{
+ /Toggle~\l_ocgxii_toswitch_u_tl}~
+ \str_if_eq:VnF{\l_ocgxii_toshow_u_tl}{}{/ON~\l_ocgxii_toshow_u_tl}~
+ \str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_u_tl}
+ ]
+ >>
+ /Border~[0~0~0]
+ }
+ \cs_if_exist:NT\@pdfhighlight{
+ \ifx\@pdfhighlight\@empty\else/H\@pdfhighlight\fi
+ }
+ }\box_use_drop:N\l_tmpa_box
+ \bool_if:NT\l_ocgxii_mouse_triggers_bool{
+ \pbs_appendtofields:n{\pbs_pdflastann:}
+ \int_gincr:N\g_ocgxii_widcount_int
+ }
+ }{
+ %line-breakable annotation
+ \pbs_pdflink:nn{
/Subtype/Link
/A <</S/SetOCGState
/State [
@@ -923,379 +943,370 @@
\str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_u_tl}
]
>>
- /Border~[0~0~0]
- }
- \cs_if_exist:NT\@pdfhighlight{
- \ifx\@pdfhighlight\@empty\else/H\@pdfhighlight\fi
- }
- }\box_use_drop:N\l_tmpa_box
- \bool_if:NT\l_ocgxii_mouse_triggers_bool{
- \pbs_appendtofields:n{\pbs_pdflastann:}
- \int_gincr:N\g_ocgxii_widcount_int
- }
- }{
- %line-breakable annotation
- \pbs_pdflink:nn{
- /Subtype/Link
- /A <</S/SetOCGState
- /State [
- \str_if_eq:VnF{\l_ocgxii_toswitch_u_tl}{}{
- /Toggle~\l_ocgxii_toswitch_u_tl}~
- \str_if_eq:VnF{\l_ocgxii_toshow_u_tl}{}{/ON~\l_ocgxii_toshow_u_tl}~
- \str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_u_tl}
- ]
- >>
- %look and feel of hyperref links, if hyperref has been loaded
- \cs_if_exist:NTF\Hy@setpdfborder{
- \Hy@setpdfborder\g_ocgxii_patch_tl
- \ifx\@pdfhighlight\@empty\else/H\@pdfhighlight\fi
- \ifx\@linkbordercolor\relax\else/C[\@linkbordercolor]\fi
- \ifHy@pdfa /F~4\fi
+ %look and feel of hyperref links, if hyperref has been loaded
+ \cs_if_exist:NTF\Hy@setpdfborder{
+ \Hy@setpdfborder\g_ocgxii_patch_tl
+ \ifx\@pdfhighlight\@empty\else/H\@pdfhighlight\fi
+ \ifx\@linkbordercolor\relax\else/C[\@linkbordercolor]\fi
+ \ifHy@pdfa /F~4\fi
+ }{
+ /Border~[0~0~0]
+ }
}{
- /Border~[0~0~0]
+ \cs_if_exist:NTF\Hy@colorlink{
+ \Hy@colorlink\@linkcolor#6\Hy@endcolorlink\Hy@VerboseLinkStop
+ }{#6}
}
- }{
- \cs_if_exist:NTF\Hy@colorlink{
- \Hy@colorlink\@linkcolor#6\Hy@endcolorlink\Hy@VerboseLinkStop
- }{#6}
}
}
-}
-%mimic commands from ocg-p
-\keys_define:nn{ocgx2/ocgpcmd}{
- triggerocg .choices:nn = {
- onmouseenter, onmouseexit, onmousedown, onmouseup, allactions
- }{
- \str_if_eq:eeTF{\l_keys_choice_tl}{allactions}{
- \tl_set:Nn\l_ocgxii_trigger_tl{onmouseall}
+ %mimic commands from ocg-p
+ \keys_define:nn{ocgx2/ocgpcmd}{
+ triggerocg .choices:nn = {
+ onmouseenter, onmouseexit, onmousedown, onmouseup, allactions
}{
- \tl_set_eq:NN\l_ocgxii_trigger_tl\l_keys_choice_tl
+ \str_if_eq:eeTF{\l_keys_choice_tl}{allactions}{
+ \tl_set:Nn\l_ocgxii_trigger_tl{onmouseall}
+ }{
+ \tl_set_eq:NN\l_ocgxii_trigger_tl\l_keys_choice_tl
+ }
}
}
-}
-\DeclareDocumentCommand\toggleocgs{O{} m +m}{
- \tl_clear_new:N\l_ocgxii_trigger_tl
- \keys_set:nn{ocgx2/ocgpcmd}{#1}
- \switchocg*[\l_ocgxii_trigger_tl]{#2}{#3}
-}
-\DeclareDocumentCommand\showocgs{O{} m +m}{
- \tl_clear_new:N\l_ocgxii_trigger_tl
- \keys_set:nn{ocgx2/ocgpcmd}{#1}
- \showocg*[\l_ocgxii_trigger_tl]{#2}{#3}
-}
-\DeclareDocumentCommand\hideocgs{O{} m +m}{
- \tl_clear_new:N\l_ocgxii_trigger_tl
- \keys_set:nn{ocgx2/ocgpcmd}{#1}
- \hideocg*[\l_ocgxii_trigger_tl]{#2}{#3}
-}
-\DeclareDocumentCommand\setocgs{O{} m m m +m}{
- \tl_clear_new:N\l_ocgxii_trigger_tl
- \keys_set:nn{ocgx2/ocgpcmd}{#1}
- \actionsocg*[\l_ocgxii_trigger_tl]{#2}{#3}{#4}{#5}
-}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\cs_new_protected:Nn\ocgxii_process_ocgref:NN{
- \tl_if_exist:cTF{ocgx2.ocg.#2}{
- \tl_put_right:Nx#1{~\tl_use:c{ocgx2.ocg.#2}}
- }{
- \msg_warning:nnx{ocgx2}{undefined~OCG}{#2}
- \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
- \tl_new:N\g_ocgxii_refundefwarned_tl
- \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
- }
+ \DeclareDocumentCommand\toggleocgs{O{} m +m}{
+ \tl_clear_new:N\l_ocgxii_trigger_tl
+ \keys_set:nn{ocgx2/ocgpcmd}{#1}
+ \switchocg*[\l_ocgxii_trigger_tl]{#2}{#3}
}
-}
-
-%ocg environment opts
-\keys_define:nn{ocgx2/ocgenv}{
- viewocg .choice:,
- viewocg / always .code:n={
- \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/ON>>}},
- viewocg / never .code:n={
- \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/OFF>>}},
- viewocg / ifvisible .code:n={
- \tl_clear:N\l_ocgxii_view_tl},
- viewocg .default:n={ifvisible},
-
- printocg .choice:,
- printocg / always .code:n={
- \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/ON>>}},
- printocg / never .code:n={
- \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
- printocg / ifvisible .code:n={
- \tl_clear:N\l_ocgxii_print_tl},
- printocg .default:n={ifvisible},
-
- exportocg .choice:,
- exportocg / always .code:n={
- \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/ON>>}},
- exportocg / never .code:n={
- \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
- exportocg / ifvisible .code:n={\tl_clear:N\l_ocgxii_export_tl},
- exportocg .default:n={ifvisible},
+ \DeclareDocumentCommand\showocgs{O{} m +m}{
+ \tl_clear_new:N\l_ocgxii_trigger_tl
+ \keys_set:nn{ocgx2/ocgpcmd}{#1}
+ \showocg*[\l_ocgxii_trigger_tl]{#2}{#3}
+ }
+ \DeclareDocumentCommand\hideocgs{O{} m +m}{
+ \tl_clear_new:N\l_ocgxii_trigger_tl
+ \keys_set:nn{ocgx2/ocgpcmd}{#1}
+ \hideocg*[\l_ocgxii_trigger_tl]{#2}{#3}
+ }
+ \DeclareDocumentCommand\setocgs{O{} m m m +m}{
+ \tl_clear_new:N\l_ocgxii_trigger_tl
+ \keys_set:nn{ocgx2/ocgpcmd}{#1}
+ \actionsocg*[\l_ocgxii_trigger_tl]{#2}{#3}{#4}{#5}
+ }
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- showingui .choices:nn = {true,false,always,never,iffirstuse}{
- \bool_if:nTF{
- \str_if_eq_p:ee{#1}{false} ||
- \str_if_eq_p:ee{#1}{never}
- }{
- \bool_set_false:N\l_ocgxii_showingui_bool
+ \cs_new_protected:Nn\ocgxii_process_ocgref:NN{
+ \tl_if_exist:cTF{ocgx2.ocg.#2}{
+ \tl_put_right:Nx#1{~\tl_use:c{ocgx2.ocg.#2}}
}{
- \bool_set_true:N\l_ocgxii_showingui_bool
- }
- },
- showingui .default:n={true},
-
- listintoolbar .meta:n = {showingui=#1},
- listintoolbar .default:n={true},
-
- radiobtngrps .code:n = {
- \clist_map_inline:nn{#1}{
- \seq_if_in:NxF\l_ocgxii_rbgrps_seq{##1}{
- \seq_put_right:Nx\l_ocgxii_rbgrps_seq{##1}
+ \msg_warning:nnx{ocgx2}{undefined~OCG}{#2}
+ \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
+ \tl_new:N\g_ocgxii_refundefwarned_tl
+ \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
}
}
- },
- radiobtngrps .value_required:n = {true},
- radiobtngrp .meta:n={radiobtngrps={#1}},
- radiobtngrp .value_required:n = {true}
-}
-
-\cs_new_protected:Nn\ocgxii_reset_cmd_opts:{
- \tl_set_eq:NN\l_ocgxii_view_tl\g_ocgxii_view_tl
- \tl_set_eq:NN\l_ocgxii_print_tl\g_ocgxii_print_tl
- \tl_set_eq:NN\l_ocgxii_export_tl\g_ocgxii_export_tl
- \bool_set_eq:NN\l_ocgxii_showingui_bool\g_ocgxii_showingui_bool
- %stack of radio button group names the current ocg belongs to
- \seq_clear_new:N\l_ocgxii_rbgrps_seq
-}
+ }
-\msg_set:nnn{ocgx2}{rerun}{Rerun~to~get~OCG~references~right!}
-\msg_set:nnn{ocgx2}{undefined~OCG}{
- Line~\msg_line_number: :~OCG~`#1'~is~not~defined.
-}
-\msg_set:nnn{ocgx2}{undefined~OCGs}{There~were~undefined~OCGs!}
-\msg_set:nnn{ocgx2}{unknown~option}{
- Line~\msg_line_number: :~unknown~option~`#1'.
-}
+ %ocg environment opts
+ \keys_define:nn{ocgx2/ocgenv}{
+ viewocg .choice:,
+ viewocg / always .code:n={
+ \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/ON>>}},
+ viewocg / never .code:n={
+ \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/OFF>>}},
+ viewocg / ifvisible .code:n={
+ \tl_clear:N\l_ocgxii_view_tl},
+ viewocg .default:n={ifvisible},
+
+ printocg .choice:,
+ printocg / always .code:n={
+ \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/ON>>}},
+ printocg / never .code:n={
+ \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
+ printocg / ifvisible .code:n={
+ \tl_clear:N\l_ocgxii_print_tl},
+ printocg .default:n={ifvisible},
+
+ exportocg .choice:,
+ exportocg / always .code:n={
+ \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/ON>>}},
+ exportocg / never .code:n={
+ \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
+ exportocg / ifvisible .code:n={\tl_clear:N\l_ocgxii_export_tl},
+ exportocg .default:n={ifvisible},
+
+ showingui .choices:nn = {true,false,always,never,iffirstuse}{
+ \bool_if:nTF{
+ \str_if_eq_p:ee{#1}{false} ||
+ \str_if_eq_p:ee{#1}{never}
+ }{
+ \bool_set_false:N\l_ocgxii_showingui_bool
+ }{
+ \bool_set_true:N\l_ocgxii_showingui_bool
+ }
+ },
+ showingui .default:n={true},
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% patch hyperref to ensure compatibility with our `ocgcolorlinks' option
-%
-% Plus:
-%
-% * add `ocgcolorlinks' support to all drivers
-%
-% * allows for `ocgcolorlinks' extending over
-%
-% line-breaks AND page-breaks
-%
-% with pdftex, luatex, xetex, dvipdfmx drivers
-%
-% based on Ben Lerner's idea
-% http://tex.stackexchange.com/a/104227;
-% with some improvements
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ listintoolbar .meta:n = {showingui=#1},
+ listintoolbar .default:n={true},
-\cs_new_protected_nopar:Nn\ocgxii_colourlink_begin:{}
-\cs_new_protected_nopar:Nn\ocgxii_colourlink_end:{}
-\cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_begin:{
- \hbox_set:Nw\l_tmpa_box\color@begingroup
- \tl_set_eq:NN\color@setgroup\group_begin:
-}
-\cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_end:{
- \color@endgroup\hbox_set_end:
- \mbox{
- \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
- \hbox_to_zero:n{\box_use:N\l_tmpa_box\hss}
- \ocgbase_oc_emc:
- \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
- \group_begin:
- \exp_after:wN\HyColor@UseColor\l_ocgxii_lnkcol_tl
- \box_use_drop:N\l_tmpa_box
- \group_end:
- \ocgbase_oc_emc:
+ radiobtngrps .code:n = {
+ \clist_map_inline:nn{#1}{
+ \seq_if_in:NxF\l_ocgxii_rbgrps_seq{##1}{
+ \seq_put_right:Nx\l_ocgxii_rbgrps_seq{##1}
+ }
+ }
+ },
+ radiobtngrps .value_required:n = {true},
+ radiobtngrp .meta:n={radiobtngrps={#1}},
+ radiobtngrp .value_required:n = {true}
}
-}
-\seq_new:N\g_ocgxii_lnk_color_seq %stack of colours of currently open links
-\tl_new:N\g_ocgxii_patch_tl % `BorderArrayPatch' for dvips
+ \cs_new_protected:Nn\ocgxii_reset_cmd_opts:{
+ \tl_set_eq:NN\l_ocgxii_view_tl\g_ocgxii_view_tl
+ \tl_set_eq:NN\l_ocgxii_print_tl\g_ocgxii_print_tl
+ \tl_set_eq:NN\l_ocgxii_export_tl\g_ocgxii_export_tl
+ \bool_set_eq:NN\l_ocgxii_showingui_bool\g_ocgxii_showingui_bool
+ %stack of radio button group names the current ocg belongs to
+ \seq_clear_new:N\l_ocgxii_rbgrps_seq
+ }
-%we'll be using the downscaled space character (32) from the pzdr
-% (dingbats) font at the end of every ocgcolorlink in order to prevent
-% empty links from flooding the page with link colour
-\cs_new_nopar:Npn\ocgxii_tiny_space_char:{
- \group_begin: \font\l_tmpa_tl=pzdr~scaled~1\l_tmpa_tl\char32 \group_end:
-}
+ \msg_set:nnn{ocgx2}{rerun}{Rerun~to~get~OCG~references~right!}
+ \msg_set:nnn{ocgx2}{undefined~OCG}{
+ Line~\msg_line_number: :~OCG~`#1'~is~not~defined.
+ }
+ \msg_set:nnn{ocgx2}{undefined~OCGs}{There~were~undefined~OCGs!}
+ \msg_set:nnn{ocgx2}{unknown~option}{
+ Line~\msg_line_number: :~unknown~option~`#1'.
+ }
-\bool_if:nTF{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
- % non-breakable links in dvips
- \cs_new_protected_nopar:Nn\ocgxii_enable_ocglinks:{
- \def\Hy@colorlink##1{
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % patch hyperref to ensure compatibility with our `ocgcolorlinks' option
+ %
+ % Plus:
+ %
+ % * add `ocgcolorlinks' support to all drivers
+ %
+ % * allows for `ocgcolorlinks' extending over
+ %
+ % line-breaks AND page-breaks
+ %
+ % with pdftex, luatex, xetex, dvipdfmx drivers
+ %
+ % based on Ben Lerner's idea
+ % http://tex.stackexchange.com/a/104227;
+ % with some improvements
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ \cs_new_protected_nopar:Nn\ocgxii_colourlink_begin:{}
+ \cs_new_protected_nopar:Nn\ocgxii_colourlink_end:{}
+ \cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_begin:{
+ \hbox_set:Nw\l_tmpa_box\color@begingroup
+ \tl_set_eq:NN\color@setgroup\group_begin:
+ }
+ \cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_end:{
+ \color@endgroup\hbox_set_end:
+ \mbox{
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
+ \hbox_to_zero:n{\box_use:N\l_tmpa_box\hss}
+ \ocgbase_oc_emc:
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
\group_begin:
- \tl_set:Nn\l_ocgxii_lnkcol_tl{##1}
- \ocgxii_colourlink_nobreak_begin:
- }
- \def\Hy@endcolorlink{
- \ocgxii_colourlink_nobreak_end:
+ \exp_after:wN\HyColor@UseColor\l_ocgxii_lnkcol_tl
+ \box_use_drop:N\l_tmpa_box
\group_end:
+ \ocgbase_oc_emc:
}
}
- \tl_gset:Nn\g_ocgxii_patch_tl{BorderArrayPatch}
-}{
- % pdftex,luatex,xetex,dvipdfmx:
- % ocgcolorlinks that extend over line and page breaks
- \cs_new_protected_nopar:Nn\ocgxii_enable_ocglinks:{
- \def\Hy@colorlink##1{
- \ifx\Hy@setbreaklinks\@gobble\else
- \Hy@breaklinkstrue
- \fi
- \ifHy@breaklinks
- \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
- \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
- \ocgxii_colourlink_end:
- }
- \group_begin:
- \ocgxii_colourlink_begin:
- \seq_gpush:Nx\g_ocgxii_lnk_color_seq{{##1}}
- \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
- \else
+
+ \seq_new:N\g_ocgxii_lnk_color_seq %stack of colours of currently open links
+ \tl_new:N\g_ocgxii_patch_tl % `BorderArrayPatch' for dvips
+
+ %we'll be using the downscaled space character (32) from the pzdr
+ % (dingbats) font at the end of every ocgcolorlink in order to prevent
+ % empty links from flooding the page with link colour
+ \cs_new_nopar:Npn\ocgxii_tiny_space_char:{
+ \group_begin: \font\l_tmpa_tl=pzdr~scaled~1\l_tmpa_tl\char32 \group_end:
+ }
+
+ \bool_if:nTF{\sys_if_output_dvi_p: && !\g_ocgxii_dvipdfmx_bool}{
+ % non-breakable links in dvips
+ \cs_new_protected_nopar:Nn\ocgxii_enable_ocglinks:{
+ \def\Hy@colorlink##1{
\group_begin:
\tl_set:Nn\l_ocgxii_lnkcol_tl{##1}
\ocgxii_colourlink_nobreak_begin:
- \fi
- }
- \def\Hy@endcolorlink{
- \ifHy@breaklinks
- \seq_gpop:NN\g_ocgxii_lnk_color_seq\l_tmpa_tl
- \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
- \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
- \ocgxii_colourlink_end:
- \group_end:
- \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
- \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
- \ocgxii_colourlink_begin:
- }
- \else
+ }
+ \def\Hy@endcolorlink{
\ocgxii_colourlink_nobreak_end:
\group_end:
- \fi
+ }
}
- }
- \bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
- \cs_gset_nopar:Nn\ocgxii_colourlink_begin:{
- %tiny space char put here in order to neutralise possible transformation
- %matrix modifications from previous \pdfliteral{} (TikZ makes a lot use of it)
- \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
- \pbs_literal:nn{page}{q~7~Tr}
- }
- \cs_gset_nopar:Nn\ocgxii_colourlink_end:{
- %a tiny space char should keep empty link annots from flooding the page
- % with link colour
- \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
- \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
- \pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
- \ocgbase_oc_emc:
- \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
- \group_begin:
- \exp_after:wN\HyColor@UseColor\g_ocgxii_lnkcol_tl
+ \tl_gset:Nn\g_ocgxii_patch_tl{BorderArrayPatch}
+ }{
+ % pdftex,luatex,xetex,dvipdfmx:
+ % ocgcolorlinks that extend over line and page breaks
+ \cs_new_protected_nopar:Nn\ocgxii_enable_ocglinks:{
+ \def\Hy@colorlink##1{
+ \ifx\Hy@setbreaklinks\@gobble\else
+ \Hy@breaklinkstrue
+ \fi
+ \ifHy@breaklinks
+ \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
+ \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
+ \ocgxii_colourlink_end:
+ }
+ \group_begin:
+ \ocgxii_colourlink_begin:
+ \seq_gpush:Nx\g_ocgxii_lnk_color_seq{{##1}}
+ \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
+ \else
+ \group_begin:
+ \tl_set:Nn\l_ocgxii_lnkcol_tl{##1}
+ \ocgxii_colourlink_nobreak_begin:
+ \fi
+ }
+ \def\Hy@endcolorlink{
+ \ifHy@breaklinks
+ \seq_gpop:NN\g_ocgxii_lnk_color_seq\l_tmpa_tl
+ \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
+ \ocgxii_stack_shipout:NN\ocgxii@lnkcol@stack@on@page\g_ocgxii_lnk_color_seq
+ \ocgxii_colourlink_end:
+ \group_end:
+ \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
+ \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
+ \ocgxii_colourlink_begin:
+ }
+ \else
+ \ocgxii_colourlink_nobreak_end:
+ \group_end:
+ \fi
+ }
+ }
+ \bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
+ \cs_gset_nopar:Nn\ocgxii_colourlink_begin:{
+ %tiny space char put here in order to neutralise possible transformation
+ %matrix modifications from previous \pdfliteral{} (TikZ makes a lot use of it)
+ \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
+ \pbs_literal:nn{page}{q~7~Tr}
+ }
+ \cs_gset_nopar:Nn\ocgxii_colourlink_end:{
+ %a tiny space char should keep empty link annots from flooding the page
+ % with link colour
+ \hbox_overlap_left:n{\ocgxii_tiny_space_char:}
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
\pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
- \group_end:
- \ocgbase_oc_emc:
- \pbs_literal:nn{page}{0~Tr~Q}
+ \ocgbase_oc_emc:
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
+ \group_begin:
+ \exp_after:wN\HyColor@UseColor\g_ocgxii_lnkcol_tl
+ \pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
+ \group_end:
+ \ocgbase_oc_emc:
+ \pbs_literal:nn{page}{0~Tr~Q}
+ }
}
}
-}
-% user command for protecting graphical content (external file, inline
-% [e. g. TikZ], \fbox{...}) inside breakable ocgcolorlink
-\bool_if:NTF\l_ocgxii_ocgcolorlinks_bool{
- \DeclareDocumentCommand\ocglinkprotect{m}{
- \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
- \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
- \ocgxii_colourlink_end:
+ % user command for protecting graphical content (external file, inline
+ % [e. g. TikZ], \fbox{...}) inside breakable ocgcolorlink
+ \bool_if:NTF\l_ocgxii_ocgcolorlinks_bool{
+ \DeclareDocumentCommand\ocglinkprotect{m}{
+ \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
+ \tl_gset_eq:NN\g_ocgxii_lnkcol_tl\l_tmpa_tl
+ \ocgxii_colourlink_end:
+ \group_begin:
+ \tl_set_eq:NN\l_ocgxii_lnkcol_tl\l_tmpa_tl
+ \ocgxii_colourlink_nobreak_begin:
+ }
\group_begin:
- \tl_set_eq:NN\l_ocgxii_lnkcol_tl\l_tmpa_tl
- \ocgxii_colourlink_nobreak_begin:
- }
- \group_begin:
- \cs_set_nopar:Npn\ocglinkprotect##1{##1} % in case of nesting
- \sys_if_output_pdf:TF{
- \leavevmode
- \hbox_set:Nn\l_tmpb_box{#1}
- \hbox_to_wd:nn{\box_wd:N\l_tmpb_box}{
- \vrule~width~\c_zero_dim~height~\box_ht:N\l_tmpb_box~
- depth~\box_dp:N\l_tmpb_box
- \pbs_pdfxform:nnnnn{1}{0}{}{}{\l_tmpb_box}
- \pbs_pdfrefxform:n{\pbs_pdflastxform:}
- \hss
- }
- }{#1}
- \group_end:
- \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
- \ocgxii_colourlink_nobreak_end:
+ \cs_set_nopar:Npn\ocglinkprotect##1{##1} % in case of nesting
+ \sys_if_output_pdf:TF{
+ \leavevmode
+ \hbox_set:Nn\l_tmpb_box{#1}
+ \hbox_to_wd:nn{\box_wd:N\l_tmpb_box}{
+ \vrule~width~\c_zero_dim~height~\box_ht:N\l_tmpb_box~
+ depth~\box_dp:N\l_tmpb_box
+ \pbs_pdfxform:nnnnn{1}{0}{}{}{\l_tmpb_box}
+ \pbs_pdfrefxform:n{\pbs_pdflastxform:}
+ \hss
+ }
+ }{#1}
\group_end:
- \ocgxii_colourlink_begin:
+ \seq_get_left:NNT\g_ocgxii_lnk_color_seq\l_tmpa_tl{
+ \ocgxii_colourlink_nobreak_end:
+ \group_end:
+ \ocgxii_colourlink_begin:
+ }
}
+ }{
+ \DeclareDocumentCommand\ocglinkprotect{m}{#1}
}
-}{
- \DeclareDocumentCommand\ocglinkprotect{m}{#1}
-}
-% option ocgcolorlinks and beamer are not compatible
-\bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
- \@ifclassloaded{beamer}{
- \bool_set_false:N\l_ocgxii_ocgcolorlinks_bool
- \hypersetup{colorlinks}
- \msg_warning:nn{ocgx2}{beamer~and~ocgcolorlinks}
- }{}
-}
+ % option ocgcolorlinks and beamer are not compatible
+ \bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
+ \@ifclassloaded{beamer}{
+ \bool_set_false:N\l_ocgxii_ocgcolorlinks_bool
+ \hypersetup{colorlinks}
+ \msg_warning:nn{ocgx2}{beamer~and~ocgcolorlinks}
+ }{}
+ }
-\bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
- \@ifpackageloaded{hyperref}{
- \Hy@colorlinkstrue
- \AtBeginDocument{
- \ocgbase_new_ocg:nnn{OCView}{
- /Print<</PrintState/OFF>>
- /Export<</ExportState/OFF>>
- }{on}
- \tl_gset:cx{ocgxii_ocg_OCView}{\ocgbase_last_ocg:}
- %in case somebody wants to reopen with \begin{ocg}...
- \tl_gset:cx{ocgxii_ocg_OCView.opts}{
- showingui=never,printocg=never,exportocg=never
- }
- \ocgbase_new_ocg:nnn{OCPrint}{
- /Print<</PrintState/ON>>
- /Export<</ExportState/ON>>
- }{off}
- \tl_gset:cx{ocgxii_ocg_OCPrint}{\ocgbase_last_ocg:}
- \tl_gset:cx{ocgxii_ocg_OCPrint.opts}{
- showingui=never,printocg=always,exportocg=always
- }
- \ocgxii_enable_ocglinks:
- \iow_now:Nx\@mainaux{
- \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCView}{
- \tl_use:c{ocgxii_ocg_OCView}}
- }
- \iow_now:Nx\@mainaux{
- \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCPrint}{
- \tl_use:c{ocgxii_ocg_OCPrint}}
+ \bool_if:NT\l_ocgxii_ocgcolorlinks_bool{
+ \@ifpackageloaded{hyperref}{
+ \Hy@colorlinkstrue
+ \AtBeginDocument{
+ \ocgbase_new_ocg:nnn{OCView}{
+ /Print<</PrintState/OFF>>
+ /Export<</ExportState/OFF>>
+ }{on}
+ \tl_gset:cx{ocgxii_ocg_OCView}{\ocgbase_last_ocg:}
+ %in case somebody wants to reopen with \begin{ocg}...
+ \tl_gset:cx{ocgxii_ocg_OCView.opts}{
+ showingui=never,printocg=never,exportocg=never
+ }
+ \ocgbase_new_ocg:nnn{OCPrint}{
+ /Print<</PrintState/ON>>
+ /Export<</ExportState/ON>>
+ }{off}
+ \tl_gset:cx{ocgxii_ocg_OCPrint}{\ocgbase_last_ocg:}
+ \tl_gset:cx{ocgxii_ocg_OCPrint.opts}{
+ showingui=never,printocg=always,exportocg=always
+ }
+ \ocgxii_enable_ocglinks:
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCView}{
+ \tl_use:c{ocgxii_ocg_OCView}}
+ }
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCPrint}{
+ \tl_use:c{ocgxii_ocg_OCPrint}}
+ }
}
+ }{
+ \msg_error:nnn{ocgx2}{missing~package}{hyperref}
}
- }{
- \msg_error:nnn{ocgx2}{missing~package}{hyperref}
}
+ \bool_if:NT\l_ocgxii_tikz_bool{\cs_set_eq:NN\ocgxii@trmspc\tl_trim_spaces:N}
}
-
+\group_begin:
+\bool_if:nF{
+ \bool_lazy_or_p:nn{
+ \bool_lazy_and_p:nn{
+ \cs_if_exist_p:N\pdfmanagement_if_active_p:
+ }{
+ \pdfmanagement_if_active_p:
+ }
+ }{
+ \bool_if_p:N\l_ocgxii_tikz_bool
+ }
+}{\aftergroup\endinput}
+\group_end:
+\ExplSyntaxOff
+\if@ocgxii@testphase\else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TikZ related code follows (to be enabled with package option `tikz')
-\bool_if:NT\l_ocgxii_tikz_bool{
-\cs_set_eq:NN\ocgxii@trmspc\tl_trim_spaces:N
-\ExplSyntaxOff
\RequirePackage{tikz}
\usetikzlibrary{calc}
@@ -1499,7 +1510,6 @@
}
}
}
-}
\fi
\begingroup
\if@ocgxii@testphase\else\aftergroup\endinput\fi
@@ -1547,8 +1557,8 @@
\RequirePackage{l3keys2e}
-\def\g@ocgxii@date@tl{2021/06/11}
-\def\g@ocgxii@version@tl{0.52}
+\def\g@ocgxii@date@tl{2021/06/16}
+\def\g@ocgxii@version@tl{0.53}
\ProvidesExplPackage{ocgx2}{\g@ocgxii@date@tl}{\g@ocgxii@version@tl}
{ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}
@@ -2779,13 +2789,13 @@
\ocgxii_colourlink_begin:
}{#1}
}
+\group_begin:
+\bool_if:NF\l_ocgxii_tikz_bool{\aftergroup\endinput}
+\group_end:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TikZ related code follows (to be enabled with package option `tikz')
-\group_begin:
-\bool_if:NF\l_ocgxii_tikz_bool{\aftergroup\endinput}
-\group_end:
\cs_set_eq:NN\ocgxii@trmspc\tl_trim_spaces:N
\ExplSyntaxOff
\RequirePackage{tikz}
diff --git a/macros/latex/contrib/projlib/ProjLib-doc-cn.pdf b/macros/latex/contrib/projlib/ProjLib-doc-cn.pdf
index 0e513e7abd..7c3d32aef4 100644
--- a/macros/latex/contrib/projlib/ProjLib-doc-cn.pdf
+++ b/macros/latex/contrib/projlib/ProjLib-doc-cn.pdf
Binary files differ
diff --git a/macros/latex/contrib/projlib/ProjLib-doc-cn.tex b/macros/latex/contrib/projlib/ProjLib-doc-cn.tex
index dfc162bea3..426944dffc 100644
--- a/macros/latex/contrib/projlib/ProjLib-doc-cn.tex
+++ b/macros/latex/contrib/projlib/ProjLib-doc-cn.tex
@@ -1,10 +1,10 @@
%! TEX program = xelatex
-\documentclass[allowbf,regionalref]{lebhart}
+\documentclass[allowbf,regionalref,puretext]{lebhart}
%%================================
%% 引入工具集
%%================================
-\usepackage{PJLtoolkit}
+\usepackage{ProjLib}
\usepackage{longtable} % breakable tables
\usepackage{hologo} % more TeX logo
@@ -32,7 +32,7 @@
}
\providecommand{\meta}[1]{$\langle${\normalfont\itshape#1}$\rangle$}
\lstset{moretexcs=%
- {color,NameTheorem,CreateTheorem,proofideanameCN,cref,dnf,needgraph,UseLanguage,UseOtherLanguage,AddLanguageSetting,maketitle,address,curraddr,email,keywords,subjclass,thanks,dedicatory,PJLdate,ProjLib
+ {color,NameTheorem,CreateTheorem,proofideanameCN,cref,dnf,needgraph,UseLanguage,UseOtherLanguage,AddLanguageSetting,maketitle,address,curraddr,email,keywords,subjclass,thanks,dedicatory,PLdate,PJLdate,ProjLib
}
}
\lstnewenvironment{code}%
@@ -61,10 +61,11 @@
%%================================
%% 名称
%%================================
+\providecommand{\ProjLibPackage}{\textsf{ProjLib}}
\providecommand{\PJLtoolkit}{\textsf{PJLtoolkit}}
\providecommand{\PJLamssim}{\textsf{PJLamssim}}
\providecommand{\PJLauthor}{\textsf{PJLauthor}}
-\providecommand{\PJLdatestr}{\textsf{PJLdate}}
+\providecommand{\PJLdatePackage}{\textsf{PJLdate}}
\providecommand{\PJLdraft}{\textsf{PJLdraft}}
\providecommand{\PJLlang}{\textsf{PJLlang}}
\providecommand{\PJLlogo}{\textsf{PJLlogo}}
@@ -78,43 +79,44 @@
\title{\ProjLib{} 工具集\\[.3\baselineskip]\normalsize 使用指南}
\author{许锦文}
-\thanks{对应版本.~~\texttt{\ProjLib{}~2021/06/07}}
+\thanks{对应版本.~~\texttt{\ProjLib{}~2021/06/17}}
\date{2021年6月,北京}
\maketitle
\begin{abstract}
- \ProjLib{} 工具集之设计目的为简化 \LaTeX{} 文档撰写前的准备工作。只需要加载 \PJLtoolkit{},多语言设置就已准备就绪,定理类环境已被设置好可供直接使用,并且引入了一系列辅助功能。
+ \ProjLib{} 工具集之设计目的为简化 \LaTeX{} 文档撰写前的准备工作。只需要加载 \ProjLibPackage{},多语言设置就已准备就绪,定理类环境已被设置好可供直接使用,并且引入了一系列辅助功能。
\end{abstract}
% \tableofcontents
-\section{PJLtoolkit}
+\section{主宏包}
\subsection{如何加载}
只需要在导言部分加入这一行即可:
\begin{code}
- \usepackage{PJLtoolkit}
+ \usepackage{ProjLib}
\end{code}
\begin{tip}[注意事项]
- 由于其内部使用了 \textsf{cleveref},\PJLtoolkit{} 需要放在 \textsf{varioref}、\textsf{hyperref} 的后面。
+ 由于其内部使用了 \textsf{cleveref},\ProjLibPackage{} 需要放在 \textsf{varioref}、\textsf{hyperref} 的后面。
\end{tip}
\medskip
\subsection{选项}
-\PJLtoolkit{} 提供下列选项以供选择:
+\ProjLibPackage{} 提供下列选项以供选择:
\begin{itemize}
\item \texttt{draft} 或 \texttt{fast}
\begin{itemize}
\item 快速模式。功能会适当缩减,但能够提高编译速度,建议在撰写阶段使用。
\end{itemize}
- \item \texttt{palatino}、\texttt{times}、\texttt{garamond}、\texttt{biolinum}
+ \item \texttt{palatino}、\texttt{times}、\texttt{garamond}、\texttt{biolinum} $|$ \texttt{useosf}
\begin{itemize}
\item 字体选项。顾名思义,会加载相应名称的字体。
+ \item \texttt{useosf} 选项用来启用“旧式”数字。
\end{itemize}
\item \texttt{author}
\begin{itemize}
@@ -162,7 +164,7 @@
\subsection{PJLdate}
-\PJLdatestr{} 提供了 \lstinline|\PJLdate|\meta{yyyy-mm-dd} 命令,以将 \meta{yyyy-mm-dd} 转换为当前语言的日期格式显示。例如,在当前的中文语境下,\lstinline|\PJLdate{2022-04-01}| 会被显示为“\PJLdate{2022-04-01}”,而在英文语境下则会被显示为“\UseOtherLanguage{English}{\PJLdate{2022-04-01}}”。
+\PJLdatePackage{} 提供了 \lstinline|\PLdate|\meta{yyyy-mm-dd} (或 \lstinline|\PJLdate|\meta{yyyy-mm-dd}) 命令,以将 \meta{yyyy-mm-dd} 转换为当前语言的日期格式显示。例如,在当前的中文语境下,\lstinline|\PLdate{2022-04-01}| 会被显示为“\PJLdate{2022-04-01}”,而在英文语境下则会被显示为“\UseOtherLanguage{English}{\PJLdate{2022-04-01}}”。
关于如何选定语言,请参阅关于 \PJLlang{} 的小节。
@@ -389,13 +391,13 @@
\subsection{标准文档类}
-在标准文档类中,通常只需简要设置页面尺寸、超链接,再载入 \PJLtoolkit{},即可直接开始写作。下面是一段完整的示例。
+在标准文档类中,通常只需简要设置页面尺寸、超链接,再载入 \ProjLibPackage{},即可直接开始写作。下面是一段完整的示例。
\begin{code}
\documentclass{article}
\usepackage[a4paper,margin=.75in]{geometry}
\usepackage[hidelinks]{hyperref}
-\usepackage[palatino]{PJLtoolkit} % Load the toolkit and use font Palatino
+\usepackage[palatino]{ProjLib} % Load the toolkit and use font Palatino
\UseLanguage{French} % Use French from here
@@ -424,20 +426,20 @@ Référence du théorème: \cref{thm:abc} % It is recommended to use clever refe
\end{code}
\bigskip
-如果使用了 \PJLamssim{},那么文章中就可以采用 \AmS{} 文档类的写法 (当然,此时原始的写法也是成立的,因此始终添加 \texttt{amssim} 这一参数通常是没有问题的)。此时上文引入 \PJLtoolkit{} 的那一行应该写为:
+如果使用了 \PJLamssim{},那么文章中就可以采用 \AmS{} 文档类的写法 (当然,此时原始的写法也是成立的,因此始终添加 \texttt{amssim} 这一参数通常是没有问题的)。此时上文引入 \ProjLibPackage{} 的那一行应该写为:
\begin{code}
-\usepackage[amssim,palatino]{PJLtoolkit}
+\usepackage[amssim,palatino]{ProjLib}
\end{code}
\clearpage
\subsection{\texorpdfstring{\AmS{}}{AMS} 文档类}
-在 \AmS{} 文档类中,通常只需简要设置页面尺寸、超链接,再载入 \PJLtoolkit{},即可直接开始写作。下面是一段完整的示例。
+在 \AmS{} 文档类中,通常只需简要设置页面尺寸、超链接,再载入 \ProjLibPackage{},即可直接开始写作。下面是一段完整的示例。
\begin{code}
\documentclass{amsart}
\usepackage[a4paper,margin=.75in]{geometry}
\usepackage[hidelinks]{hyperref}
-\usepackage[palatino]{PJLtoolkit} % Load the toolkit and use font Palatino
+\usepackage[palatino]{ProjLib} % Load the toolkit and use font Palatino
\UseLanguage{French} % Use French from here
diff --git a/macros/latex/contrib/projlib/ProjLib-doc-en.pdf b/macros/latex/contrib/projlib/ProjLib-doc-en.pdf
index cce553440a..47ba1e28f6 100644
--- a/macros/latex/contrib/projlib/ProjLib-doc-en.pdf
+++ b/macros/latex/contrib/projlib/ProjLib-doc-en.pdf
Binary files differ
diff --git a/macros/latex/contrib/projlib/ProjLib-doc-en.tex b/macros/latex/contrib/projlib/ProjLib-doc-en.tex
index 4cbffde7fa..707cf5c8d4 100644
--- a/macros/latex/contrib/projlib/ProjLib-doc-en.tex
+++ b/macros/latex/contrib/projlib/ProjLib-doc-en.tex
@@ -1,10 +1,10 @@
%! TEX program = xelatex
-\documentclass[allowbf,regionalref]{lebhart}
+\documentclass[allowbf,regionalref,puretext]{lebhart}
%%================================
%% Import toolkit
%%================================
-\usepackage{PJLtoolkit}
+\usepackage{ProjLib}
\usepackage{longtable} % breakable tables
\usepackage{hologo} % more TeX logo
@@ -30,7 +30,7 @@
}
\providecommand{\meta}[1]{$\langle${\normalfont\itshape#1}$\rangle$}
\lstset{moretexcs=%
- {color,NameTheorem,CreateTheorem,proofideanameEN,cref,dnf,needgraph,UseLanguage,UseOtherLanguage,AddLanguageSetting,maketitle,address,curraddr,email,keywords,subjclass,thanks,dedicatory,PJLdate,ProjLib
+ {color,NameTheorem,CreateTheorem,proofideanameEN,cref,dnf,needgraph,UseLanguage,UseOtherLanguage,AddLanguageSetting,maketitle,address,curraddr,email,keywords,subjclass,thanks,dedicatory,PLdate,PJLdate,ProjLib
}
}
\lstnewenvironment{code}%
@@ -59,10 +59,11 @@
%%================================
%% 名称
%%================================
+\providecommand{\ProjLibPackage}{\textsf{ProjLib}}
\providecommand{\PJLtoolkit}{\textsf{PJLtoolkit}}
\providecommand{\PJLamssim}{\textsf{PJLamssim}}
\providecommand{\PJLauthor}{\textsf{PJLauthor}}
-\providecommand{\PJLdatestr}{\textsf{PJLdate}}
+\providecommand{\PJLdatePackage}{\textsf{PJLdate}}
\providecommand{\PJLdraft}{\textsf{PJLdraft}}
\providecommand{\PJLlang}{\textsf{PJLlang}}
\providecommand{\PJLlogo}{\textsf{PJLlogo}}
@@ -76,43 +77,44 @@
\title{\ProjLib{}~\,Toolkit\\[.3\baselineskip]\normalsize User Manual}
\author{Jinwen Xu}
-\thanks{Corresponding to: \texttt{\ProjLib{}~2021/06/07}}
+\thanks{Corresponding to: \texttt{\ProjLib{}~2021/06/17}}
\date{June 2021, Beijing}
\maketitle
\begin{abstract}
- The \ProjLib{} toolkit is designed to simplify the preparation before writing \LaTeX{} documents. With \PJLtoolkit{} loaded, you no longer need to set up the theorem-like environments nor configure the appropriate multilingual settings. Additionally, a series of auxiliary functionalities are introduced.
+ The \ProjLib{} toolkit is designed to simplify the preparation before writing \LaTeX{} documents. With \ProjLibPackage{} loaded, you no longer need to set up the theorem-like environments nor configure the appropriate multilingual settings. Additionally, a series of auxiliary functionalities are introduced.
\end{abstract}
% \tableofcontents
-\section{PJLtoolkit}
+\section{The main package}
\subsection{How to load it}
Just add the following line to your preamble:
\begin{code}
- \usepackage{PJLtoolkit}
+ \usepackage{ProjLib}
\end{code}
\begin{tip}[Attention]
- Since \textsf{cleveref} is used internally, \PJLtoolkit{} needs to be placed after \textsf{varioref} and \textsf{hyperref}.
+ Since \textsf{cleveref} is used internally, \ProjLibPackage{} needs to be placed after \textsf{varioref} and \textsf{hyperref}.
\end{tip}
\medskip
\subsection{Options}
-\PJLtoolkit{} offers the following options:
+\ProjLibPackage{} offers the following options:
\begin{itemize}
\item \texttt{draft} or \texttt{fast}
\begin{itemize}
\item Fast mode. The functionality is appropriately reduced to get faster compilation speed, recommended to use during the writing phase.
\end{itemize}
- \item \texttt{palatino}, \texttt{times}, \texttt{garamond}, \texttt{biolinum}
+ \item \texttt{palatino}, \texttt{times}, \texttt{garamond}, \texttt{biolinum} $|$ \texttt{useosf}
\begin{itemize}
- \item Font options. As the name suggest, font with corresponding name will be loaded.
+ \item Font options. As the name suggest, font with corresponding name will be loaded.
+ \item The \texttt{useosf} option is used to enable the old-style figures.
\end{itemize}
\item \texttt{author}
\begin{itemize}
@@ -160,7 +162,7 @@ The mutual order of \lstinline|\address|, \lstinline|\curraddr| and \lstinline|\
\subsection{PJLdate}
-\PJLdatestr{} offers the \lstinline|\PJLdate|\meta{yyyy-mm-dd} macro to convert \meta{yyyy-mm-dd} into the date format of the currently selected language. For example, in current English context, \lstinline|\PJLdate{2022-04-01}| would become ``\PJLdate{2022-04-01}'', while in French context as ``\UseOtherLanguage{French}{\PJLdate{2022-04-01}}''.
+\PJLdatePackage{} offers the \lstinline|\PLdate|\meta{yyyy-mm-dd} (or \lstinline|\PJLdate|\meta{yyyy-mm-dd}) macro to convert \meta{yyyy-mm-dd} into the date format of the currently selected language. For example, in current English context, \lstinline|\PLdate{2022-04-01}| would become ``\PLdate{2022-04-01}'', while in French context as ``\UseOtherLanguage{French}{\PLdate{2022-04-01}}''.
For details on how to select a language, please refer to the section on \PJLlang{}.
@@ -388,13 +390,13 @@ defines an unnumbered environment \lstinline|proofidea*| and a numbered environm
\subsection{Standard classes}
-In standard classes, one usually only need to configure the page size, hyperlinks and load \PJLtoolkit{} before actually start writing the document. Below is a complete example.
+In standard classes, one usually only need to configure the page size, hyperlinks and load \ProjLibPackage{} before actually start writing the document. Below is a complete example.
\begin{code}
\documentclass{article}
\usepackage[a4paper,margin=.75in]{geometry}
\usepackage[hidelinks]{hyperref}
-\usepackage[palatino]{PJLtoolkit} % Load the toolkit and use font Palatino
+\usepackage[palatino]{ProjLib} % Load the toolkit and use font Palatino
\UseLanguage{French} % Use French from here
@@ -423,20 +425,20 @@ Référence du théorème: \cref{thm:abc} % It is recommended to use clever refe
\end{code}
\bigskip
-If \PJLamssim{} is loaded, then one can adopt the \AmS{} writing style in the document (of course, the original way is also valid, so always adding the option \texttt{amssim} usually does not cause problems). This way, the line that introduces \PJLtoolkit{} should be written as:
+If \PJLamssim{} is loaded, then one can adopt the \AmS{} writing style in the document (of course, the original way is also valid, so always adding the option \texttt{amssim} usually does not cause problems). This way, the line that introduces \ProjLibPackage{} should be written as:
\begin{code}
-\usepackage[amssim,palatino]{PJLtoolkit}
+\usepackage[amssim,palatino]{ProjLib}
\end{code}
\clearpage
\subsection{The \texorpdfstring{\AmS{}}{AMS} classes}
-In \AmS{} classes, one usually only need to configure the page size, hyperlinks and load \PJLtoolkit{} before actually start writing the document. Below is a complete example.
+In \AmS{} classes, one usually only need to configure the page size, hyperlinks and load \ProjLibPackage{} before actually start writing the document. Below is a complete example.
\begin{code}
\documentclass{amsart}
\usepackage[a4paper,margin=.75in]{geometry}
\usepackage[hidelinks]{hyperref}
-\usepackage[palatino]{PJLtoolkit} % Load the toolkit and use font Palatino
+\usepackage[palatino]{ProjLib} % Load the toolkit and use font Palatino
\UseLanguage{French} % Use French from here
diff --git a/macros/latex/contrib/projlib/ProjLib.dtx b/macros/latex/contrib/projlib/ProjLib.dtx
index 5abd7bf8b5..52dd38e55b 100644
--- a/macros/latex/contrib/projlib/ProjLib.dtx
+++ b/macros/latex/contrib/projlib/ProjLib.dtx
@@ -16,49 +16,54 @@
%</driver>
\NeedsTeXFormat{LaTeX2e}[2020-10-01]
%
+%<*ProjLib>
+\ProvidesPackage{ProjLib}
+ [2021/06/17 The collective interface of ProjLib toolkit]
+%</ProjLib>
+%
%<*PJLamssim>
\ProvidesPackage{PJLamssim}
- [2021/06/07 Simulate some features of amsart]
+ [2021/06/17 Simulate some features of amsart]
%</PJLamssim>
%
%<*PJLauthor>
\ProvidesPackage{PJLauthor}
- [2021/06/07 Enhanced author information block]
+ [2021/06/17 Enhanced author information block]
%</PJLauthor>
%
%<*PJLdate>
\ProvidesPackage{PJLdate}
- [2021/06/07 Convert yyyy-mm-dd to normal datetime format]
+ [2021/06/17 Convert yyyy-mm-dd to normal datetime format]
%</PJLdate>
%
%<*PJLdraft>
\ProvidesPackage{PJLdraft}
- [2021/06/07 Some useful macros for the draft stage]
+ [2021/06/17 Some useful macros for the draft stage]
%</PJLdraft>
%
%<*PJLlang>
\ProvidesPackage{PJLlang}
- [2021/06/07 Multi-language configuration]
+ [2021/06/17 Multi-language configuration]
%</PJLlang>
%
%<*PJLlogo>
\ProvidesPackage{PJLlogo}
- [2021/06/07 The ProjLib logo]
+ [2021/06/17 The ProjLib logo]
%</PJLlogo>
%
%<*PJLpaper>
\ProvidesPackage{PJLpaper}
- [2021/06/07 Paper style configuration]
+ [2021/06/17 Paper style configuration]
%</PJLpaper>
%
%<*PJLthm>
\ProvidesPackage{PJLthm}
- [2021/06/07 Theorem setup and configuration]
+ [2021/06/17 Theorem setup and configuration]
%</PJLthm>
%
%<*PJLtoolkit>
\ProvidesPackage{PJLtoolkit}
- [2021/06/07 Collective interface of ProjLib Toolkit]
+ [2021/06/17 Collective interface of ProjLib Toolkit]
%</PJLtoolkit>
%
\RequirePackage{kvoptions}
@@ -173,9 +178,15 @@
\ifx\@date\@empty\vspace{-2\baselineskip}%
\else\@date\fi%
\ifx\PJL@dedicatory\@empty\else%
- \par\vspace{-\parskip}\bigskip%
- {\itshape\PJL@dedicatory}\fi}
- {}{\FAIL}
+ \ifx\@date\@empty\vspace{2\baselineskip}\fi%
+ \par\vspace{-\parskip}\bigskip%
+ {\itshape\PJL@dedicatory}%
+ \ifx\@date\@empty%
+ \vspace{-1.7\baselineskip}%
+ \vspace{-\parskip}%
+ \fi%
+ \fi%
+}{}{\FAIL}
% Add keywords to maketitle
\pretocmd{\maketitle}{%
\ifx\PJL@keywords\@empty\else%
@@ -317,6 +328,7 @@
\if@PJLdate@draft
\@PJLdate@fasttrue
\fi
+\DeclareDocumentCommand{\PLdate}{}{\PJLdate}
\if@PJLdate@fast\let\PJLdate\relax\endinput\fi
\RequirePackage{PJLlang}
@@ -591,41 +603,49 @@
}
\RequirePackage{setspace}
-%
+% Line spacing configuration
\def\PJL@config@linespacing{\setstretch{1.00}}
\def\PJL@config@CJKlinespacing{\onehalfspacing}
\newcommand{\PJLsetlinespacing}[1]{\renewcommand{\PJL@config@linespacing}{#1}}
\newcommand{\PJLsetCJKlinespacing}[1]{\renewcommand{\PJL@config@CJKlinespacing}{#1}}
+% Parindent configuration
+\def\PJL@config@parindent{\ltx@ifpackageloaded{parskip}{}{\setlength{\parindent}{1.5em}}}
+\def\PJL@config@CJKparindent{\ltx@ifpackageloaded{parskip}{}{\setlength{\parindent}{2em}}}
+\newcommand{\PJLsetparindent}[1]{\renewcommand{\PJL@config@parindent}{\ltx@ifpackageloaded{parskip}{}{\setlength{\parindent}{#1}}}}
+\newcommand{\PJLsetCJKparindent}[1]{\renewcommand{\PJL@config@CJKparindent}{\ltx@ifpackageloaded{parskip}{}{\setlength{\parindent}{#1}}}}
+% All-in-all configuration
+\def\PJL@config@CJK{\PJL@config@CJKlinespacing\PJL@config@CJKparindent}
+\def\PJL@config@Latin{\PJL@config@linespacing\PJL@config@parindent}
%
\newcommand{\UseLanguageCORE}[1]{%
\PJLlang@langconfig@common%
\lowercase{\IfStrEqCase{#1}}{%
- {cn}{\PJL@config@CJKlinespacing\PJLlang@langconfig@chinese}%
- {chinese}{\PJL@config@CJKlinespacing\PJLlang@langconfig@chinese}%
- {schinese}{\PJL@config@CJKlinespacing\PJLlang@langconfig@chinese}%
- {simplifiedchinese}{\PJL@config@CJKlinespacing\PJLlang@langconfig@chinese}%
- {tc}{\PJL@config@CJKlinespacing\PJLlang@langconfig@tchinese}%
- {tchinese}{\PJL@config@CJKlinespacing\PJLlang@langconfig@tchinese}%
- {traditionalchinese}{\PJL@config@CJKlinespacing\PJLlang@langconfig@tchinese}%
- {jp}{\PJL@config@CJKlinespacing\PJLlang@langconfig@japanese}%
- {japanese}{\PJL@config@CJKlinespacing\PJLlang@langconfig@japanese}%
- {en}{\PJL@config@linespacing\PJLlang@langconfig@english}%
- {english}{\PJL@config@linespacing\PJLlang@langconfig@english}%
- {fr}{\PJL@config@linespacing\PJLlang@langconfig@french}%
- {french}{\PJL@config@linespacing\PJLlang@langconfig@french}%
- {de}{\PJL@config@linespacing\PJLlang@langconfig@german}%
- {ngerman}{\PJL@config@linespacing\PJLlang@langconfig@german}%
- {german}{\PJL@config@linespacing\PJLlang@langconfig@german}%
- {it}{\PJL@config@linespacing\PJLlang@langconfig@italian}%
- {italian}{\PJL@config@linespacing\PJLlang@langconfig@italian}%
- {pt}{\PJL@config@linespacing\PJLlang@langconfig@portuguese}%
- {portuguese}{\PJL@config@linespacing\PJLlang@langconfig@portuguese}%
- {br}{\PJL@config@linespacing\PJLlang@langconfig@brazilian}%
- {brazilian}{\PJL@config@linespacing\PJLlang@langconfig@brazilian}%
- {es}{\PJL@config@linespacing\PJLlang@langconfig@spanish}%
- {spanish}{\PJL@config@linespacing\PJLlang@langconfig@spanish}%
- {ru}{\PJL@config@linespacing\PJLlang@langconfig@russian}%
- {russian}{\PJL@config@linespacing\PJLlang@langconfig@russian}%
+ {cn}{\PJL@config@CJK\PJLlang@langconfig@chinese}%
+ {chinese}{\PJL@config@CJK\PJLlang@langconfig@chinese}%
+ {schinese}{\PJL@config@CJK\PJLlang@langconfig@chinese}%
+ {simplifiedchinese}{\PJL@config@CJK\PJLlang@langconfig@chinese}%
+ {tc}{\PJL@config@CJK\PJLlang@langconfig@tchinese}%
+ {tchinese}{\PJL@config@CJK\PJLlang@langconfig@tchinese}%
+ {traditionalchinese}{\PJL@config@CJK\PJLlang@langconfig@tchinese}%
+ {jp}{\PJL@config@CJK\PJLlang@langconfig@japanese}%
+ {japanese}{\PJL@config@CJK\PJLlang@langconfig@japanese}%
+ {en}{\PJL@config@Latin\PJLlang@langconfig@english}%
+ {english}{\PJL@config@Latin\PJLlang@langconfig@english}%
+ {fr}{\PJL@config@Latin\PJLlang@langconfig@french}%
+ {french}{\PJL@config@Latin\PJLlang@langconfig@french}%
+ {de}{\PJL@config@Latin\PJLlang@langconfig@german}%
+ {ngerman}{\PJL@config@Latin\PJLlang@langconfig@german}%
+ {german}{\PJL@config@Latin\PJLlang@langconfig@german}%
+ {it}{\PJL@config@Latin\PJLlang@langconfig@italian}%
+ {italian}{\PJL@config@Latin\PJLlang@langconfig@italian}%
+ {pt}{\PJL@config@Latin\PJLlang@langconfig@portuguese}%
+ {portuguese}{\PJL@config@Latin\PJLlang@langconfig@portuguese}%
+ {br}{\PJL@config@Latin\PJLlang@langconfig@brazilian}%
+ {brazilian}{\PJL@config@Latin\PJLlang@langconfig@brazilian}%
+ {es}{\PJL@config@Latin\PJLlang@langconfig@spanish}%
+ {spanish}{\PJL@config@Latin\PJLlang@langconfig@spanish}%
+ {ru}{\PJL@config@Latin\PJLlang@langconfig@russian}%
+ {russian}{\PJL@config@Latin\PJLlang@langconfig@russian}%
}%
}
\newcommand{\UseLanguage}[1]{%
@@ -789,9 +809,11 @@
\pagecolor{paper}
\PJLglobalcolor{maintext}
+\AtEndPreamble{
\ifdefined\tcbset%
\tcbset{colupper=maintext,collower=maintext}
\fi
+}
%</PJLpaper>
%
%<*PJLthm>
@@ -1477,7 +1499,7 @@
}
%</PJLthm>
%
-%<*PJLtoolkit>
+%<*ProjLib,PJLtoolkit>
\SetupKeyvalOptions{
family = @PJLtoolkit,
prefix = @PJLtoolkit@,
@@ -1488,6 +1510,7 @@
\DeclareBoolOption[false]{amssim}
\DeclareBoolOption[false]{nothms}
\DeclareBoolOption[false]{regionalref}
+\DeclareBoolOption[false]{useosf}
\DeclareBoolOption[false]{palatino}
\DeclareBoolOption[false]{times}
\DeclareBoolOption[false]{garamond}
@@ -1541,6 +1564,7 @@
\RequirePackage{newpxmath}
\let\openbox\relax
\PJLsetlinespacing{\setstretch{1.07}}
+ \if@PJLtoolkit@useosf\useosf\fi
\fi
\if@PJLtoolkit@times
@@ -1550,11 +1574,14 @@
\RequirePackage{newtxmath}
\let\openbox\relax
\PJLsetlinespacing{\setstretch{1.00}}
+ \if@PJLtoolkit@useosf\useosf\fi
\fi
\if@PJLtoolkit@garamond
\RequirePackage{amssymb}
- \PassOptionsToPackage{lining}{ebgaramond}
+ \if@PJLtoolkit@useosf\else
+ \PassOptionsToPackage{lining}{ebgaramond}
+ \fi
\RequirePackage{ebgaramond-maths}
\RequirePackage{ebgaramond}
% \RequirePackage{garamondlibre}
@@ -1566,6 +1593,9 @@
% \RequirePackage{mathpazo}
% \RequirePackage[sansmath]{libertinust1math}
\ifPDFTeX
+ \if@PJLtoolkit@useosf
+ \PassOptionsToPackage{osf}{biolinum}
+ \fi
\RequirePackage{biolinum}
\renewcommand*\familydefault{\biolinum@family}
\else
@@ -1574,7 +1604,8 @@
\setmainfont{LinBiolinum_R.otf}[
BoldFont = LinBiolinum_RB.otf ,
ItalicFont = LinBiolinum_RI.otf ,
- BoldItalicFont = LinBiolinum_RBO.otf ]
+ BoldItalicFont = LinBiolinum_RBO.otf,
+ \if@PJLtoolkit@useosf Numbers = OldStyle\fi ]
\fi
\PJLsetlinespacing{\setstretch{1.05}}
\RequirePackage[italic,defaultmathsizes]{mathastext}
@@ -1583,6 +1614,6 @@
\fi
\RequirePackage{microtype}
-%</PJLtoolkit>
+%</ProjLib,PJLtoolkit>
\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/projlib/ProjLib.ins b/macros/latex/contrib/projlib/ProjLib.ins
index d51b90e70d..a0d0c5099d 100644
--- a/macros/latex/contrib/projlib/ProjLib.ins
+++ b/macros/latex/contrib/projlib/ProjLib.ins
@@ -39,6 +39,7 @@ and version 1.3c or later is part of all distributions of LaTeX version
\def\mypreamble{\copyright\lppllicense}
\usepreamble\mypreamble
+\generate{\file{ProjLib.sty}{\from{ProjLib.dtx}{ProjLib}}}
\generate{\file{PJLamssim.sty}{\from{ProjLib.dtx}{PJLamssim}}}
\generate{\file{PJLauthor.sty}{\from{ProjLib.dtx}{PJLauthor}}}
\generate{\file{PJLdate.sty}{\from{ProjLib.dtx}{PJLdate}}}
@@ -55,6 +56,7 @@ and version 1.3c or later is part of all distributions of LaTeX version
\Msg{* To finish the installation you have to move the following *}
\Msg{* files into a directory searched by TeX: *}
\Msg{* *}
+\Msg{* ProjLib.sty *}
\Msg{* PJLamssim.sty *}
\Msg{* PJLauthor.sty *}
\Msg{* PJLdate.sty *}
diff --git a/macros/latex/contrib/projlib/README.md b/macros/latex/contrib/projlib/README.md
index 59d887b3be..8a38c50415 100644
--- a/macros/latex/contrib/projlib/README.md
+++ b/macros/latex/contrib/projlib/README.md
@@ -6,7 +6,7 @@
## Introduction
-`ProjLib` is a collection of tools that help you write LaTeX document. With `PJLtoolkit` loaded, you no longer need to set up the theorem-like environments nor to manually configure the appropriate multilingual settings. In addition, a series of auxiliary functionalities are introduced.
+`ProjLib` is a collection of tools that help you write LaTeX document. With package `ProjLib` loaded (note that it is case-sensitive), you no longer need to set up the theorem-like environments nor to manually configure the appropriate multilingual settings. In addition, a series of auxiliary functionalities are introduced.
The collection includes:
1. `PJLamssim.sty`
@@ -15,7 +15,7 @@ The collection includes:
- Enhanced author information block
- Offers `\address`, `\curraddr` and `\email`
1. `PJLdate.sty`
- - Offers a macro `\PJLdate` to convert `yyyy-mm-dd` to normal datetime format, with multi-language support
+ - Offers a macro `\PLdate` (or `\PJLdate`) to convert `yyyy-mm-dd` to normal datetime format, with multi-language support
1. `PJLdraft.sty`
- Useful macros during the draft stage: `\dnf` and `\needgraph`, with multi-language support
1. `PJLlang.sty`
@@ -30,7 +30,7 @@ The collection includes:
- Theorem setup and configuration
- Offers a macro `\CreateTheorem` for creating theorem-like environments with multi-language support
- Preset environments include: `assumption`, `axiom`, `conjecture`, `convention`, `corollary`, `definition`, `definition-proposition`, `definition-theorem`, `example`, `exercise`, `fact`, `hypothesis`, `lemma`, `notation`, `observation`, `problem`, `property`, `proposition`, `question`, `remark`, `theorem`, and the corresponding unnumbered version with an asterisk `*` in the name.
-1. `PJLtoolkit.sty`, *the all-in-one solution*
+1. `PJLtoolkit.sty` (this is the internal name of the `ProjLib` package)
- A collective interface of ProjLib Toolkit, loading all the packages above
- Provide some pre-defined font configuration
@@ -47,11 +47,11 @@ latex ProjLib.ins
\documentclass{amsart}
\usepackage[a4paper,margin=.75in]{geometry}
\usepackage[hidelinks]{hyperref}
-\usepackage[palatino]{PJLtoolkit}
+\usepackage[palatino]{ProjLib}
%% You can also comment the above lines and try the following (require xelatex or lualatex):
% \documentclass[a4paper,allowbf]{lebhart}
-% \usepackage{PJLtoolkit}
+% \usepackage{ProjLib}
%% Using \UseLanguage to select language, by default "English" is selected
\UseLanguage{French} % Use French from here
@@ -65,7 +65,7 @@ latex ProjLib.ins
\author{Auteur 1}
\address{Adresse 1}
\email{\href{Courriel 2}{Courriel 2}}
-\date{\PJLdate{2022-04-01}}
+\date{\PLdate{2022-04-01}}
\subjclass{*****}
\keywords{...}
diff --git a/macros/latex/contrib/siunitx/CHANGELOG.md b/macros/latex/contrib/siunitx/CHANGELOG.md
index 364058db97..1266b1623b 100644
--- a/macros/latex/contrib/siunitx/CHANGELOG.md
+++ b/macros/latex/contrib/siunitx/CHANGELOG.md
@@ -7,6 +7,33 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
## [Unreleased]
+## [v3.0.14]
+
+### Changed
+- Auto-enable `table-fixed-width` when setting `table-column-width`
+ to a positive value
+- Expand `table-format` input before splitting
+
+### Fixed
+- Incorrect handling of `{}` in literal units (issue #487)
+- Placement of sign in some complex numbers (issue #488)
+- Printing of units in quantities when `uncertainty-mode` is
+ `separate` and an exponent is present (issue #490)
+
+## [v3.0.13]
+
+### Added
+- Catalan translations for lists and ranges
+
+### Fixed
+- Position of complex root when no real part is present (issue #481)
+- Skip defining `\unit` if the `units` package is loaded (issue #482)
+- Printing units in compound quantities when `parse-numbers` is
+ false (issue #484)
+- Printing of `1` when both `print-zero-exponent` and
+ `print-unity-mantissa` are false (issue #485)
+- Printing of ohm symbol in text mode with `fourier` package (issue #486)
+
## [v3.0.12]
### Fixed
@@ -1368,7 +1395,9 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
### Added
- First public testing release (as `si`)
-[Unreleased]: https://github.com/josephwright/siunitx/compare/v3.0.12...HEAD
+[Unreleased]: https://github.com/josephwright/siunitx/compare/v3.0.14...HEAD
+[v3.0.14]: https://github.com/josephwright/siunitx/compare/v3.0.13...v3.0.14
+[v3.0.13]: https://github.com/josephwright/siunitx/compare/v3.0.12...v3.0.13
[v3.0.12]: https://github.com/josephwright/siunitx/compare/v3.0.11...v3.0.12
[v3.0.11]: https://github.com/josephwright/siunitx/compare/v3.0.10...v3.0.11
[v3.0.10]: https://github.com/josephwright/siunitx/compare/v3.0.9...v3.0.10
diff --git a/macros/latex/contrib/siunitx/siunitx-code.pdf b/macros/latex/contrib/siunitx/siunitx-code.pdf
index b62b22632d..ff484ac37d 100644
--- a/macros/latex/contrib/siunitx/siunitx-code.pdf
+++ b/macros/latex/contrib/siunitx/siunitx-code.pdf
Binary files differ
diff --git a/macros/latex/contrib/siunitx/siunitx-complex.dtx b/macros/latex/contrib/siunitx/siunitx-complex.dtx
index 1a81054a5c..ca4262bdce 100644
--- a/macros/latex/contrib/siunitx/siunitx-complex.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-complex.dtx
@@ -597,12 +597,12 @@
%
% \begin{macro}{\@@_format:n}
% \begin{macro}{\@@_format_auxi:n}
-% \begin{macro}{\@@_format_unary:nnnnnnn}
% \begin{macro}{\@@_format_auxii:n}
% \begin{macro}{\@@_drop_exponent:nnnnnnn}
% \begin{macro}{\@@_format_sign:nnnnnnn}
% \begin{macro}{\@@_extract_exponent:nw}
% \begin{macro}{\@@_extract_exponent_aux:w}
+% \begin{macro}{\@@_format_unary:nnnnnnn}
% \begin{macro}[EXP]{\@@_format_bracket:n}
% We start here checking that there is something to do.
% \begin{macrocode}
@@ -614,53 +614,24 @@
{ \@@_format_auxi:n {#1} }
}
% \end{macrocode}
+% We split based on whether the number has a complex part at all,
+% then print the result.
% \begin{macrocode}
\cs_new_protected:Npn \@@_format_auxi:n #1
{
\tl_clear:N \l_@@_tmp_tl
- \tl_if_empty:NTF \l_@@_real_tl
+ \tl_if_empty:NTF \l_@@_img_tl
{
- \@@_format_units:n {#1}
- \exp_after:wN \@@_format_unary:nnnnnnn \l_@@_img_tl
+ \siunitx_number_process:NN \l_@@_real_tl \l_@@_real_tl
\tl_set:Nx \l_@@_tmp_tl
- {
- \siunitx_number_output:N \l_@@_img_tl
- \exp_not:V \l_@@_output_root_tl
- }
- }
- {
- \tl_if_empty:NTF \l_@@_img_tl
- {
- \siunitx_number_process:NN \l_@@_real_tl \l_@@_real_tl
- \tl_set:Nx \l_@@_tmp_tl
- { \siunitx_number_output:N \l_@@_real_tl }
- }
- { \@@_format_auxii:n {#1} }
+ { \siunitx_number_output:N \l_@@_real_tl }
}
+ { \@@_format_auxii:n {#1} }
\tl_if_blank:nTF {#1}
{ \siunitx_print_number:V \l_@@_tmp_tl }
{ \siunitx_quantity_print:VV \l_@@_tmp_tl \l_@@_unit_tl }
}
% \end{macrocode}
-% An imaginary part that is exactly $1$ is omitted, with only the complex
-% root printed. That means checking and removing a lone $1$ here.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_format_unary:nnnnnnn #1#2#3#4#5#6#7
- {
- \tl_set:Nx \l_@@_img_tl
- {
- \exp_not:n { {#1} {#2} }
- \tl_if_blank:nTF {#4}
- {
- \str_if_eq:nnTF {#3} { 1 }
- { { } { } }
- { \exp_not:n { {#3} {#4} } }
- }
- { \exp_not:n { {#3} {#4} } }
- \exp_not:n { {#5} {#6} {#7} }
- }
- }
-% \end{macrocode}
% If we get to this stage we have both parts to a complex number. We
% need to process both and do some massaging, then it's just a question
% of reassembly with the right parts in the right places.
@@ -668,8 +639,10 @@
\cs_new_protected:Npn \@@_format_auxii:n #1
{
\@@_format_units:n {#1}
- \exp_after:wN \@@_drop_exponent:nnnnnnn \l_@@_real_tl
+ \tl_if_empty:NF \l_@@_real_tl
+ { \exp_after:wN \@@_drop_exponent:nnnnnnn \l_@@_real_tl }
\exp_after:wN \@@_format_sign:nnnnnnn \l_@@_img_tl
+ \exp_after:wN \@@_format_unary:nnnnnnn \l_@@_img_tl
\tl_set:Nx \l_@@_tmp_tl
{ \siunitx_number_output:NN \l_@@_img_tl \q_nil }
\exp_after:wN \@@_extract_exponent:w \l_@@_tmp_tl \q_stop
@@ -706,7 +679,11 @@
\tl_set:Nx \l_@@_img_tl
{
{ }
- { \tl_if_blank:nTF {#2} { + } { \exp_not:n {#2} } }
+ {
+ \tl_if_blank:nTF {#2}
+ { \tl_if_empty:NF \l_@@_real_tl { + } }
+ { \exp_not:n {#2} }
+ }
\tl_if_blank:nTF {#4}
{
\str_if_eq:nnTF {#3} { 1 }
@@ -733,6 +710,25 @@
\tl_set:Nn \l_@@_tmp_tl {#1#2}
\tl_set:Nn \l_@@_exp_tl {#3#4}
}
+% \end{macrocode}
+% An imaginary part that is exactly $1$ is omitted, with only the complex
+% root printed. That means checking and removing a lone $1$ here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_format_unary:nnnnnnn #1#2#3#4#5#6#7
+ {
+ \tl_set:Nx \l_@@_img_tl
+ {
+ \exp_not:n { {#1} {#2} }
+ \tl_if_blank:nTF {#4}
+ {
+ \str_if_eq:nnTF {#3} { 1 }
+ { { } { } }
+ { \exp_not:n { {#3} {#4} } }
+ }
+ { \exp_not:n { {#3} {#4} } }
+ \exp_not:n { {#5} {#6} {#7} }
+ }
+ }
\cs_new_protected:Npn \@@_format_bracket:n #1
{
\exp_not:V \l_@@_bracket_open_tl
diff --git a/macros/latex/contrib/siunitx/siunitx-compound.dtx b/macros/latex/contrib/siunitx/siunitx-compound.dtx
index f377585b78..5f119f1372 100644
--- a/macros/latex/contrib/siunitx/siunitx-compound.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-compound.dtx
@@ -666,6 +666,8 @@
{ \bool_set_false:N \l_siunitx_number_bracket_ambiguous_bool }
\bool_set_true:N \l_@@_unit_bool
\@@_format:nn {#1} {#2}
+ \bool_if:NF \l_siunitx_number_parse_bool
+ { \siunitx_unit_format:nN {#2} \l_@@_unit_tl }
\str_if_eq:VnT \l_siunitx_quantity_prefix_mode_tl { combine-exponent }
{ \tl_clear:N \l_@@_exp_tl }
\bool_if:NTF \l_@@_unit_repeat_bool
diff --git a/macros/latex/contrib/siunitx/siunitx-locale.dtx b/macros/latex/contrib/siunitx/siunitx-locale.dtx
index f037fcfae3..8535a74c20 100644
--- a/macros/latex/contrib/siunitx/siunitx-locale.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-locale.dtx
@@ -136,6 +136,8 @@
\file_if_exist:nT { translations.sty }
{
\RequirePackage { translations }
+ \DeclareTranslation { Catalan } { and } { i }
+ \DeclareTranslation { Catalan } { to~(numerical~range) } { a }
\DeclareTranslation { English } { to~(numerical~range) } { to }
\DeclareTranslation { French } { to~(numerical~range) } { à }
\DeclareTranslation { German } { to~(numerical~range) } { bis }
diff --git a/macros/latex/contrib/siunitx/siunitx-number.dtx b/macros/latex/contrib/siunitx/siunitx-number.dtx
index 2dfa66374c..737b503b37 100644
--- a/macros/latex/contrib/siunitx/siunitx-number.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-number.dtx
@@ -3165,9 +3165,16 @@
% \begin{macrocode}
\cs_new:Npn \@@_output_integer:nnn #1#2#3
{
- \bool_lazy_or:nnT
- { \l_@@_unity_mantissa_bool }
- { ! \str_if_eq_p:nn { #1 . #2 } { 1. } }
+ \bool_lazy_any:nT
+ {
+ { \l_@@_unity_mantissa_bool }
+ { ! \str_if_eq_p:nn { #1 . #2 } { 1. } }
+ {
+ \bool_lazy_and_p:nn
+ { \str_if_eq_p:nn {#3} { 0 } }
+ { ! \l_@@_zero_exponent_bool }
+ }
+ }
{ \@@_output_digits:nn { integer } {#1} }
}
\cs_new:Npn \@@_output_decimal:nn #1#2
diff --git a/macros/latex/contrib/siunitx/siunitx-quantity.dtx b/macros/latex/contrib/siunitx/siunitx-quantity.dtx
index 930f75c5fc..353fe94e6e 100644
--- a/macros/latex/contrib/siunitx/siunitx-quantity.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-quantity.dtx
@@ -221,6 +221,7 @@
% \begin{macro}{\@@_parsed_aux:w}
% \begin{macro}{\@@_parsed_aux:nnnw}
% \begin{macro}{\@@_parsed_aux:nnnn}
+% \begin{macro}{\@@_parsed_aux:nnn}
% For quantities, there is bit to do to combine things. The first question is
% whether we are parsing at all: if not, things are quite short. Notice that
% within this group we turn off bracketing in the number formatter: we
@@ -319,17 +320,28 @@
{
\bool_if:NTF \l_@@_uncert_repeat_bool
{
- \siunitx_quantity_print:nV {#1#2}
- \l_@@_unit_tl
- \siunitx_quantity_print:nV { { } #3 }
- \l_@@_unit_tl
- \siunitx_print_number:n { { } #4 }
+ \tl_if_blank:nTF {#4}
+ { \@@_parsed_aux:nnn {#1#2} {#3} { } }
+ { \@@_parsed_aux:nnn {#1#2} {#3} { { } #4 } }
}
{ \siunitx_quantity_print:nV {#1#2#3#4} \l_@@_unit_tl }
}
}
}
% \end{macrocode}
+% For the case of a separated uncertainty with repeated units, we print the
+% two parts independently. The third argument here is the exponent if there
+% is one, with the spacing correct in either case as we only pass the empty
+% group if one is required.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parsed_aux:nnn #1#2#3
+ {
+ \siunitx_quantity_print:nV {#1#3} \l_@@_unit_tl
+ \tl_if_blank:nF {#2}
+ { \siunitx_quantity_print:nV { { } #2#3 } \l_@@_unit_tl }
+ }
+% \end{macrocode}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
diff --git a/macros/latex/contrib/siunitx/siunitx-symbol.dtx b/macros/latex/contrib/siunitx/siunitx-symbol.dtx
index 6c7154d751..40b461bd84 100644
--- a/macros/latex/contrib/siunitx/siunitx-symbol.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-symbol.dtx
@@ -225,26 +225,38 @@
{ \group_end: }
% \end{macrocode}
% For |\ohm|, there is a math mode symbol we can use, so there has to be
-% a mode-dependent definition.
+% a mode-dependent definition. This doesn't work if the text mode symbol is
+% bust: the \pkg{fourier} package puts us in that position.
% \begin{macrocode}
\@@_if_replace:NnT \ohm { "03A9 }
{
\siunitx_declare_unit:Nx \ohm
{
- \exp_not:N \ifmmode
- \cs_if_exist:NTF \upOmega
- { \exp_not:N \upOmega }
- { \exp_not:N \Omega }
- \exp_not:N \else
- \exp_not:N \text
- {
- \bool_lazy_or:nnTF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
- { \@@_non_latin:n { "03A9 } }
- { \exp_not:N \textohm }
- }
- \exp_not:N \fi
+ \@ifpackageloaded { fourier }
+ {
+ \exp_not:N \ensuremath
+ {
+ \cs_if_exist:NTF \upOmega
+ { \exp_not:N \upOmega }
+ { \exp_not:N \Omega }
+ }
+ }
+ {
+ \exp_not:N \ifmmode
+ \cs_if_exist:NTF \upOmega
+ { \exp_not:N \upOmega }
+ { \exp_not:N \Omega }
+ \exp_not:N \else
+ \exp_not:N \text
+ {
+ \bool_lazy_or:nnTF
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_xetex_p: }
+ { \@@_non_latin:n { "03A9 } }
+ { \exp_not:N \textohm }
+ }
+ \exp_not:N \fi
+ }
}
}
% \end{macrocode}
diff --git a/macros/latex/contrib/siunitx/siunitx-table.dtx b/macros/latex/contrib/siunitx/siunitx-table.dtx
index 137c2e18d6..efd2c6bc9b 100644
--- a/macros/latex/contrib/siunitx/siunitx-table.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-table.dtx
@@ -584,10 +584,15 @@
% \begin{variable}{\l_@@_column_width_dim, \l_@@_fixed_width_bool}
% Settings which apply to aligned columns in general.
% \begin{macrocode}
+\dim_new:N \l_@@_column_width_dim
\keys_define:nn { siunitx }
{
- table-column-width .dim_set:N =
- \l_@@_column_width_dim ,
+ table-column-width .code:n =
+ {
+ \dim_set:Nn \l_@@_column_width_dim {#1}
+ \dim_compare:nNnT \l_@@_column_width_dim > \c_zero_dim
+ { \bool_set_true:N \l_@@_fixed_width_bool }
+ } ,
table-fixed-width .bool_set:N =
\l_@@_fixed_width_bool
}
@@ -776,7 +781,10 @@
\l_@@_auto_round_bool ,
table-format .code:n =
{
- \@@_split:nNNN {#1}
+ \group_begin:
+ \protected@edef \l_@@_tmp_tl {#1}
+ \exp_args:NNV \group_end:
+ \@@_split:nNNN \l_@@_tmp_tl
\l_@@_before_model_tl
\l_@@_model_tl
\l_@@_after_model_tl
diff --git a/macros/latex/contrib/siunitx/siunitx-table.pdf b/macros/latex/contrib/siunitx/siunitx-table.pdf
deleted file mode 100644
index 6c241941b5..0000000000
--- a/macros/latex/contrib/siunitx/siunitx-table.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/siunitx/siunitx-unit.dtx b/macros/latex/contrib/siunitx/siunitx-unit.dtx
index 3cbfa728fc..ab9c30a1c2 100644
--- a/macros/latex/contrib/siunitx/siunitx-unit.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-unit.dtx
@@ -1189,7 +1189,7 @@
% }
% \begin{macro}{\@@_format_literal_super:nn, \@@_format_literal_sub:nn}
% \begin{macro}{\@@_format_literal_add:n}
-% \begin{macro}{\@@_format_literal_auxvii:nn}
+% \begin{macro}{\@@_format_literal_auxix:nn}
% \begin{variable}{\l_@@_separator_tl}
% To format literal units, there are two tasks to do. The input is
% \texttt{x}-type expanded to force any symbolic units to be converted into
@@ -1285,7 +1285,7 @@
{
\tl_if_head_is_N_type:nTF {#2}
{ \@@_format_literal_auxvi:nN }
- { \@@_format_literal_auxvii:nn }
+ { \@@_format_literal_auxix:nn }
{#1} #2 \q_recursion_stop
}
\cs_new_protected:Npx \@@_format_literal_auxvi:nN #1#2
@@ -1308,7 +1308,7 @@
{
\str_if_eq:nnTF {#2} { \protect }
{ \@@_format_literal_auxviii:nN {#1} }
- { \@@_format_literal_auxvi:nN {#1#2} }
+ { \@@_format_literal_auxv:nw {#1#2} }
}
\cs_new_protected:Npn \@@_format_literal_auxviii:nN #1#2
{ \@@_format_literal_auxv:nw { #1 \protect #2 } }
@@ -1345,7 +1345,7 @@
}
\tl_clear:N \l_@@_separator_tl
}
-\cs_new_protected:Npn \@@_format_literal_auxvii:nn #1#2
+\cs_new_protected:Npn \@@_format_literal_auxix:nn #1#2
{ \@@_format_literal_auxvi:nN { #1 {#2} } }
\tl_new:N \l_@@_separator_tl
% \end{macrocode}
diff --git a/macros/latex/contrib/siunitx/siunitx.dtx b/macros/latex/contrib/siunitx/siunitx.dtx
index 53cfbd8426..75c494abb4 100644
--- a/macros/latex/contrib/siunitx/siunitx.dtx
+++ b/macros/latex/contrib/siunitx/siunitx.dtx
@@ -121,7 +121,7 @@
%
% Identify the package and give the over all version information.
% \begin{macrocode}
-\ProvidesExplPackage {siunitx} {2021-06-09} {3.0.12}
+\ProvidesExplPackage {siunitx} {2021-06-17} {3.0.14}
{A comprehensive (SI) units package}
% \end{macrocode}
%
@@ -309,6 +309,17 @@
\siunitx_print_number:V \l_@@_tmp_tl
\group_end:
}
+\@ifpackageloaded { units }
+ {
+ \msg_new:nnn { siunitx } { units-pkg }
+ {
+ Detected~the~"units"~package: \\
+ Omitting~definition~of~\token_to_str:N \unit.
+ }
+ \msg_warning:nn { siunitx } { units-pkg }
+ \use_none:nnnn
+ }
+ { }
\NewDocumentCommand \unit { O { } > { \TrimSpaces } m }
{
\mode_leave_vertical:
@@ -522,7 +533,7 @@
% \subsection{Document commands in bookmarks}
%
% In bookmarks, the \pkg{siunitx} document commands need to produce simple
-% strings that represent their input as far a possible.
+% strings that represent their input as far as possible.
%
% \begin{macro}{\@@_bookmark_cmd:Nn}
% To keep things fast, expandable versions of the document command are
diff --git a/macros/latex/contrib/siunitx/siunitx.pdf b/macros/latex/contrib/siunitx/siunitx.pdf
index 36c97918d0..02d552c6ad 100644
--- a/macros/latex/contrib/siunitx/siunitx.pdf
+++ b/macros/latex/contrib/siunitx/siunitx.pdf
Binary files differ
diff --git a/macros/latex/contrib/siunitx/siunitx.tex b/macros/latex/contrib/siunitx/siunitx.tex
index 28eaa37b2c..2be2483297 100644
--- a/macros/latex/contrib/siunitx/siunitx.tex
+++ b/macros/latex/contrib/siunitx/siunitx.tex
@@ -1748,7 +1748,9 @@ if no sign was present in the input.
\DescribeOption{print-zero-exponent}
Printing of a mantissa of $1$ and an exponent of $0$ is controllable by the
options \opt{print-unity-mantissa} and \opt{print-zero-exponent}. The standard
-settings print a mantissa of $1$ but omit an exponent of $0$.
+settings print a mantissa of $1$ but omit an exponent of $0$. Notice that where
+both are set to \opt{false}, the value $1$ will still be printed
+(\foreign{i.e.}~\opt{print-zero-exponent} has a higher priority).
\begin{LaTeXdemo}
\num{1e4} \\
\num[print-unity-mantissa = false]{1e4} \\
@@ -1993,7 +1995,7 @@ the \LaTeX3 floating-point unit, so is limited to $16$ decimal places.
\DescribeOption{number-angle-product}
The separator between the number and angle symbol (degrees, minutes or seconds)
can be set using the \opt{number-angle-product} option, independent of the
-related \opt{number-unit-product} option used by the \cs{qty} command.
+related \opt{quantity-product} option used by the \cs{qty} command.
\begin{LaTeXdemo}
\ang{2.67} \\
\ang[number-angle-product = \,]{2.67}
@@ -2102,6 +2104,14 @@ outside of the \cs{unit} and \cs{qty} arguments. When this option is
method to achieve this does not overwrite any existing macros: this behaviour
can be altered using the \opt{overwrite-commands} switch.
+When using the approach of \enquote{free-standing} unit commands, only macros
+created using \cs{DeclareSIUnit} are defined generally. Thus prefixes and
+powers should be combined with the desired unit into a single free-standing
+command, for example
+\begin{LaTeXdemo}[code only]
+ \DeclareSIUnit\kilometre{\kilo\metre}
+\end{LaTeXdemo}
+
\DescribeOption{space-before-unit}
\DescribeOption{unit-optional-argument}
\DescribeOption{use-xspace}
@@ -2324,7 +2334,7 @@ needed. This can be turned on using the \opt{allow-quantity-breaks} option.
\end{minipage}
\end{LaTeXdemo}
-\DescribeOption{number-unit-product}
+\DescribeOption{quantity-product}
The product symbol between the number and unit is set using the
\opt{quantity-product} option.
\begin{LaTeXdemo}
@@ -2742,7 +2752,8 @@ content. However, there are cases where a strictly fixed width is desirable.
For these cases, the \opt{table-fixed-width} and \opt{table-column-width}
options are available. The \opt{table-fixed-width} option activates fixed-width
columns, whilst \opt{table-column-width} defines the target width
-(Table~\ref{tab:width:fixed}).
+(Table~\ref{tab:width:fixed}). Setting \opt{table-column-width} to a positive
+value automatically enables \opt{table-fixed-width}.
\begin{LaTeXdemo}[code and float]
\begin{table}
\caption{Fixed-width columns.%
@@ -3026,6 +3037,10 @@ When the \pkg{physics} package is loaded before \pkg{siunitx}, the command
\cs{qty} is not defined: users will need to use the version~$2$ command
\cs{SI}.
+When the \pkg{units} package is loaded before \pkg{siunitx}, the command
+\cs{unit} is not defined: users will need to use the version~$2$ command
+\cs{si}.
+
\section{Hints for using \pkg{siunitx}}
\subsection{Adjusting \cs{litre} and \cs{liter}%