texlive[68515] trunk: memoize (11oct23)

commits+karl at tug.org commits+karl at tug.org
Wed Oct 11 22:46:52 CEST 2023


Revision: 68515
          https://tug.org/svn/texlive?view=revision&revision=68515
Author:   karl
Date:     2023-10-11 22:46:52 +0200 (Wed, 11 Oct 2023)
Log Message:
-----------
memoize (11oct23)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/Makefile.am
    trunk/Build/source/texk/texlive/linked_scripts/Makefile.in
    trunk/Build/source/texk/texlive/linked_scripts/scripts.lst
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/libexec/ctan2tds
    trunk/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc

Added Paths:
-----------
    trunk/Build/source/texk/texlive/linked_scripts/memoize/
    trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.pl
    trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.py
    trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.pl
    trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.py
    trunk/Master/bin/aarch64-linux/memoize-clean.pl
    trunk/Master/bin/aarch64-linux/memoize-clean.py
    trunk/Master/bin/aarch64-linux/memoize-extract.pl
    trunk/Master/bin/aarch64-linux/memoize-extract.py
    trunk/Master/bin/amd64-freebsd/memoize-clean.pl
    trunk/Master/bin/amd64-freebsd/memoize-clean.py
    trunk/Master/bin/amd64-freebsd/memoize-extract.pl
    trunk/Master/bin/amd64-freebsd/memoize-extract.py
    trunk/Master/bin/amd64-netbsd/memoize-clean.pl
    trunk/Master/bin/amd64-netbsd/memoize-clean.py
    trunk/Master/bin/amd64-netbsd/memoize-extract.pl
    trunk/Master/bin/amd64-netbsd/memoize-extract.py
    trunk/Master/bin/armhf-linux/memoize-clean.pl
    trunk/Master/bin/armhf-linux/memoize-clean.py
    trunk/Master/bin/armhf-linux/memoize-extract.pl
    trunk/Master/bin/armhf-linux/memoize-extract.py
    trunk/Master/bin/i386-freebsd/memoize-clean.pl
    trunk/Master/bin/i386-freebsd/memoize-clean.py
    trunk/Master/bin/i386-freebsd/memoize-extract.pl
    trunk/Master/bin/i386-freebsd/memoize-extract.py
    trunk/Master/bin/i386-linux/memoize-clean.pl
    trunk/Master/bin/i386-linux/memoize-clean.py
    trunk/Master/bin/i386-linux/memoize-extract.pl
    trunk/Master/bin/i386-linux/memoize-extract.py
    trunk/Master/bin/i386-netbsd/memoize-clean.pl
    trunk/Master/bin/i386-netbsd/memoize-clean.py
    trunk/Master/bin/i386-netbsd/memoize-extract.pl
    trunk/Master/bin/i386-netbsd/memoize-extract.py
    trunk/Master/bin/i386-solaris/memoize-clean.pl
    trunk/Master/bin/i386-solaris/memoize-clean.py
    trunk/Master/bin/i386-solaris/memoize-extract.pl
    trunk/Master/bin/i386-solaris/memoize-extract.py
    trunk/Master/bin/universal-darwin/memoize-clean.pl
    trunk/Master/bin/universal-darwin/memoize-clean.py
    trunk/Master/bin/universal-darwin/memoize-extract.pl
    trunk/Master/bin/universal-darwin/memoize-extract.py
    trunk/Master/bin/windows/memoize-clean.pl.exe
    trunk/Master/bin/windows/memoize-clean.py.exe
    trunk/Master/bin/windows/memoize-extract.pl.exe
    trunk/Master/bin/windows/memoize-extract.py.exe
    trunk/Master/bin/x86_64-cygwin/memoize-clean.pl
    trunk/Master/bin/x86_64-cygwin/memoize-clean.py
    trunk/Master/bin/x86_64-cygwin/memoize-extract.pl
    trunk/Master/bin/x86_64-cygwin/memoize-extract.py
    trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.pl
    trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.py
    trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.pl
    trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.py
    trunk/Master/bin/x86_64-linux/memoize-clean.pl
    trunk/Master/bin/x86_64-linux/memoize-clean.py
    trunk/Master/bin/x86_64-linux/memoize-extract.pl
    trunk/Master/bin/x86_64-linux/memoize-extract.py
    trunk/Master/bin/x86_64-linuxmusl/memoize-clean.pl
    trunk/Master/bin/x86_64-linuxmusl/memoize-clean.py
    trunk/Master/bin/x86_64-linuxmusl/memoize-extract.pl
    trunk/Master/bin/x86_64-linuxmusl/memoize-extract.py
    trunk/Master/bin/x86_64-solaris/memoize-clean.pl
    trunk/Master/bin/x86_64-solaris/memoize-clean.py
    trunk/Master/bin/x86_64-solaris/memoize-extract.pl
    trunk/Master/bin/x86_64-solaris/memoize-extract.py
    trunk/Master/texmf-dist/doc/generic/memoize/
    trunk/Master/texmf-dist/doc/generic/memoize/FILES
    trunk/Master/texmf-dist/doc/generic/memoize/INSTALL.md
    trunk/Master/texmf-dist/doc/generic/memoize/LICENCE
    trunk/Master/texmf-dist/doc/generic/memoize/README.md
    trunk/Master/texmf-dist/doc/generic/memoize/examples-src.zip
    trunk/Master/texmf-dist/doc/generic/memoize/examples.zip
    trunk/Master/texmf-dist/doc/generic/memoize/memoize-clean.1.md
    trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.pdf
    trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.sty
    trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.tex
    trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc-common.sty
    trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc.sty
    trunk/Master/texmf-dist/doc/generic/memoize/memoize-extract.1.md
    trunk/Master/texmf-dist/doc/generic/memoize/memoize.mst
    trunk/Master/texmf-dist/doc/generic/memoize/memoize.pdf
    trunk/Master/texmf-dist/doc/generic/memoize/memoize.tex
    trunk/Master/texmf-dist/doc/generic/memoize/yadoc.sty
    trunk/Master/texmf-dist/doc/man/man1/memoize-clean.1
    trunk/Master/texmf-dist/doc/man/man1/memoize-clean.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.1
    trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.1
    trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/memoize-extract.1
    trunk/Master/texmf-dist/doc/man/man1/memoize-extract.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.1
    trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.1
    trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.man1.pdf
    trunk/Master/texmf-dist/scripts/memoize/
    trunk/Master/texmf-dist/scripts/memoize/memoize-clean.pl
    trunk/Master/texmf-dist/scripts/memoize/memoize-clean.py
    trunk/Master/texmf-dist/scripts/memoize/memoize-extract.pl
    trunk/Master/texmf-dist/scripts/memoize/memoize-extract.py
    trunk/Master/texmf-dist/source/generic/memoize/
    trunk/Master/texmf-dist/source/generic/memoize/Makefile
    trunk/Master/texmf-dist/source/generic/memoize/memoize.edtx
    trunk/Master/texmf-dist/source/generic/memoize/memoize.ins
    trunk/Master/texmf-dist/tex/context/memoize/
    trunk/Master/texmf-dist/tex/context/memoize/t-memoizable.tex
    trunk/Master/texmf-dist/tex/context/memoize/t-memoize.tex
    trunk/Master/texmf-dist/tex/context/memoize/t-nomemoize.tex
    trunk/Master/texmf-dist/tex/latex/memoize/
    trunk/Master/texmf-dist/tex/latex/memoize/memoizable.sty
    trunk/Master/texmf-dist/tex/latex/memoize/memoize.sty
    trunk/Master/texmf-dist/tex/latex/memoize/nomemoize.sty
    trunk/Master/texmf-dist/tex/plain/memoize/
    trunk/Master/texmf-dist/tex/plain/memoize/memoizable.tex
    trunk/Master/texmf-dist/tex/plain/memoize/memoize-extract-one.tex
    trunk/Master/texmf-dist/tex/plain/memoize/memoize.tex
    trunk/Master/texmf-dist/tex/plain/memoize/nomemoize.tex
    trunk/Master/tlpkg/tlpsrc/memoize.tlpsrc

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.am
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2023-10-11 20:46:52 UTC (rev 68515)
@@ -182,6 +182,10 @@
 	make4ht/make4ht \
 	match_parens/match_parens \
 	mathspic/mathspic.pl \
+	memoize/memoize-clean.pl \
+	memoize/memoize-clean.py \
+	memoize/memoize-extract.pl \
+	memoize/memoize-extract.py \
 	mf2pt1/mf2pt1.pl \
 	mkgrkindex/mkgrkindex \
 	mkjobtexmf/mkjobtexmf.pl \

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.in
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2023-10-11 20:46:52 UTC (rev 68515)
@@ -398,6 +398,10 @@
 	make4ht/make4ht \
 	match_parens/match_parens \
 	mathspic/mathspic.pl \
+	memoize/memoize-clean.pl \
+	memoize/memoize-clean.py \
+	memoize/memoize-extract.pl \
+	memoize/memoize-extract.py \
 	mf2pt1/mf2pt1.pl \
 	mkgrkindex/mkgrkindex \
 	mkjobtexmf/mkjobtexmf.pl \

Added: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.pl	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,163 @@
+#!/usr/bin/env perl
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+use strict;
+use Getopt::Long;
+# I intend to rewrite this script using Path::Class.
+use Cwd 'realpath';
+use File::Spec;
+use File::Basename;
+
+my $VERSION = '2023/10/10 v1.0.0';
+
+my $usage = "usage: memoize-clean.py [-h] [--yes] [--all] [--quiet] [--prefix PREFIX] [mmz ...]\n";
+my $Help = <<END;
+Remove (stale) memo and extern files.
+
+positional arguments:
+  mmz                   .mmz record files
+
+options:
+  -h, --help            show this help message and exit
+  --version, -V         show version and exit
+  --yes, -y             Do not ask for confirmation.
+  --all, -a             Remove *all* memos and externs.
+  --quiet, -q
+  --prefix PREFIX, -p PREFIX
+                        A path prefix to clean; this option can be specified multiple times.
+
+For details, see the man page or the Memoize documentation.
+END
+
+my ($yes, $all, @prefixes, $quiet, $help, $print_version);
+GetOptions(
+    "yes|y"   => \$yes,
+    "all|a"   => \$all,
+    "prefix|p=s" => \@prefixes,
+    "quiet|q|?" => \$quiet,
+    "help|h|?" => \$help,
+    "version|V"  => \$print_version,
+    ) or die $usage;
+$help and die "$usage\n$Help";
+if ($print_version) { print("memoize-clean.pl of Memoize $VERSION\n"); exit 0 }
+
+my (%keep, %prefixes);
+
+my $curdir = Cwd::getcwd();
+
+for my $prefix (@prefixes) {
+    $prefixes{Cwd::realpath(File::Spec->catfile(($curdir), $prefix))} = '';
+}
+
+my @mmzs = @ARGV;
+
+for my $mmz (@mmzs) {
+    my ($mmz_filename, $mmz_dir) = File::Basename::fileparse($mmz);
+    @ARGV = ($mmz);
+    my $endinput = 0;
+    my $empty = -1;
+    my $prefix = "";
+    while (<>) {
+	if (/^ *$/) {
+	} elsif ($endinput) {
+	    die "Bailing out, \\endinput is not the last line of file $mmz.\n";
+	} elsif (/^ *\\mmzPrefix *{(.*?)}/) {
+	    $prefix = $1;
+	    $prefixes{Cwd::realpath(File::Spec->catfile(($curdir,$mmz_dir), $prefix))} = '';
+	    $empty = 1 if $empty == -1;
+	} elsif (/^%? *\\mmz(?:New|Used)(?:CC?Memo|Extern) *{(.*?)}/) {
+	    my $fn = $1;
+	    if ($prefix eq '') {
+		die "Bailing out, no prefix announced before file $fn.\n";
+	    }
+	    $keep{Cwd::realpath(File::Spec->catfile(($mmz_dir), $fn))} = 1;
+	    $empty = 0;
+	    if (rindex($fn, $prefix, 0) != 0) {
+		die "Bailing out, prefix of file $fn does not match " .
+		    "the last announced prefix ($prefix).\n";
+	    }
+	} elsif (/^ *\\endinput *$/) {
+	    $endinput = 1;
+	} else {
+	    die "Bailing out, file $mmz contains an unrecognized line: $_\n";
+	}
+    }
+    die "Bailing out, file $mmz is empty.\n" if $empty && !$all;
+    die "Bailing out, file $mmz does not end with \\endinput; this could mean that " .
+	"the compilation did not finish properly. You can only clean with --all.\n"
+	if $endinput == 0 && !$all;
+}
+
+my @tbdeleted;
+sub populate_tbdeleted {
+    my ($basename_prefix, $dir, $suffix_dummy) = @_;
+    opendir(MD, $dir) or die "Cannot open directory '$dir'";
+    while( (my $fn = readdir(MD)) ) {
+	my $path = File::Spec->catfile(($dir),$fn);
+	if ($fn =~ /\Q$basename_prefix\E[0-9A-F]{32}(?:-[0-9A-F]{32})?(?:-[0-9]+)?(\.memo|(?:-[0-9]+)?\.pdf|\.log)/ and ($all || !exists($keep{$path}))) {
+	    push @tbdeleted, $path;
+	}
+    }
+    closedir(MD);
+}
+for my $prefix (keys %prefixes) {
+    my ($basename_prefix, $dir, $suffix);
+    if (-d $prefix) {
+	populate_tbdeleted('', $prefix, '');
+    }
+    populate_tbdeleted(File::Basename::fileparse($prefix));
+}
+ at tbdeleted = sort(@tbdeleted);
+
+my @allowed_dirs = ($curdir);
+my @deletion_not_allowed;
+for my $f (@tbdeleted) {
+    my $f_allowed = 0;
+    for my $dir (@allowed_dirs) {
+	if ($f =~ /^\Q$dir\E/) {
+	    $f_allowed = 1;
+	    last;
+	}
+    }
+    push(@deletion_not_allowed, $f) if ! $f_allowed;
+}
+die "Bailing out, I was asked to delete these files outside the current directory:\n" .
+    join("\n", @deletion_not_allowed) if (@deletion_not_allowed);
+
+if (scalar(@tbdeleted) != 0) {
+    my $a;
+    unless ($yes) {
+	print("I will delete the following files:\n" .
+	      join("\n", at tbdeleted) . "\n" .
+	      "Proceed (y/n)? ");
+	$a = lc(<>);
+	chomp $a;
+    }
+    if ($yes || $a eq 'y' || $a eq 'yes') {
+	foreach my $fn (@tbdeleted) {
+	    print "Deleting ", $fn, "\n" unless $quiet;
+	    unlink $fn;
+	}
+    } else {
+	die "Bailing out.\n";
+    }
+} elsif (!$quiet) {
+    print "Nothing to do, the directory seems clean.\n";
+}


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.py
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.py	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+__version__ = '2023/10/10 v1.0.0'
+
+import argparse, re, sys, pathlib, os
+
+parser = argparse.ArgumentParser(
+    description="Remove (stale) memo and extern files.",
+    epilog = "For details, see the man page or the Memoize documentation."
+)
+parser.add_argument('--yes', '-y', action = 'store_true',
+                    help = 'Do not ask for confirmation.')
+parser.add_argument('--all', '-a', action = 'store_true',
+                    help = 'Remove *all* memos and externs.')
+parser.add_argument('--quiet', '-q', action = 'store_true')
+parser.add_argument('--prefix', '-p', action = 'append', default = [],
+    help = 'A path prefix to clean; this option can be specified multiple times.')
+parser.add_argument('mmz', nargs= '*', help='.mmz record files')
+parser.add_argument('--version', '-V', action = 'version',
+                    version = f"%(prog)s of Memoize " + __version__)
+args = parser.parse_args()
+
+re_prefix = re.compile(r'\\mmzPrefix *{(.*?)}')
+re_memo = re.compile(r'%? *\\mmz(?:New|Used)(?:CC?Memo|Extern) *{(.*?)}')
+re_endinput = re.compile(r' *\\endinput *$')
+
+prefixes = set(pathlib.Path(prefix).resolve() for prefix in args.prefix)
+keep = set()
+
+# We loop through the given .mmz files, adding prefixes to whatever manually
+# specified by the user, and collecting the files to keep.
+for mmz_fn in args.mmz:
+    mmz = pathlib.Path(mmz_fn)
+    mmz_parent = mmz.parent.resolve()
+    try:
+        with open(mmz) as mmz_fh:
+            prefix = ''
+            endinput = False
+            empty = None
+            for line in mmz_fh:
+                line = line.strip()
+                
+                if not line:
+                    pass
+                
+                elif endinput:
+                    raise RuntimeError(
+                        r'Bailing out, \endinput is not the last line of file $mmz_fn.')
+                
+                elif m := re_prefix.match(line):
+                    prefix = m[1]
+                    prefixes.add( (mmz_parent/prefix).resolve() )
+                    if empty is None:
+                        empty = True
+
+                elif m := re_memo.match(line):
+                    if not prefix:
+                        raise RuntimeError(
+                            f'Bailing out, no prefix announced before file "{m[1]}".')
+                    if not m[1].startswith(prefix):
+                        raise RuntimeError(
+                            f'Bailing out, prefix of file "{m[1]}" does not match '
+                            f'the last announced prefix ({prefix}).')
+                    keep.add((mmz_parent / m[1]))
+                    empty = False
+
+                elif re_endinput.match(line):
+                    endinput = True
+                    continue
+
+                else:
+                    raise RuntimeError(fr"Bailing out, "
+                        fr"file {mmz_fn} contains an unrecognized line: {line}")
+            
+        if empty and not args.all:
+            raise RuntimeError(fr'Bailing out, file {mmz_fn} is empty.')
+
+        if not endinput and empty is not None and not args.all:
+            raise RuntimeError(
+                fr'Bailing out, file {mmz_fn} does not end with \endinput; '
+                fr'this could mean that the compilation did not finish properly. '
+                fr'You can only clean with --all.'
+            )
+        
+    # It is not an error if the file doesn't exist.
+    # Otherwise, cleaning from scripts would be cumbersome.
+    except FileNotFoundError:
+        pass
+
+tbdeleted = []
+def populate_tbdeleted(folder, basename_prefix):
+    re_aux = re.compile(
+        re.escape(basename_prefix) + 
+        '[0-9A-F]{32}(?:-[0-9A-F]{32})?(?:-[0-9]+)?(?:\.memo|(?:-[0-9]+)?\.pdf|\.log)$')
+    try:
+        for f in folder.iterdir():
+            if re_aux.match(f.name) and (args.all or f not in keep):
+                tbdeleted.append(f)
+    except FileNotFoundError:
+        pass
+
+for prefix in prefixes:
+    # "prefix" is interpreted both as a directory (if it exists) and a basename prefix.
+    if prefix.is_dir():
+        populate_tbdeleted(prefix, '')
+    populate_tbdeleted(prefix.parent, prefix.name)
+
+allowed_dirs = [pathlib.Path().absolute()] # todo: output directory
+deletion_not_allowed = [f for f in tbdeleted if not f.is_relative_to(*allowed_dirs)]
+if deletion_not_allowed:
+    raise RuntimeError("Bailing out, "
+        "I was asked to delete these files outside the current directory:\n" +
+        "\n".join(str(f) for f in deletion_not_allowed))
+        
+_cwd_absolute = pathlib.Path().absolute()
+def relativize(path):
+    try:
+        return path.relative_to(_cwd_absolute)
+    except ValueError:
+        return path
+
+if tbdeleted:
+    tbdeleted.sort()
+    if not args.yes:
+        print('I will delete the following files:')
+        for f in tbdeleted:
+            print(relativize(f))
+        print("Proceed (y/n)? ")
+        a = input()
+    if args.yes or a == 'y' or a == 'yes':
+        for f in tbdeleted:
+            if not args.quiet:
+                print("Deleting", relativize(f))
+            try:
+                f.unlink()
+            except FileNotFoundError:
+                print(f"Cannot delete {f}")
+    else:
+        print("Bailing out.")
+elif not args.quiet:
+    print('Nothing to do, the directory seems clean.')


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-clean.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.pl	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,205 @@
+#!/usr/bin/env perl
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+use strict;
+use Getopt::Long;
+use Path::Class;
+use File::Spec;
+use File::Basename;
+use PDF::API2;
+
+my $VERSION = '2023/10/10 v1.0.0';
+
+my $usage = "usage: memoize-extract.pl [-h] [--pdf PDF] [--prune] [--keep] [--force] [--log LOG] [--warning-template WARNING_TEMPLATE] [--quiet] [--mkdir] mmz\n";
+my $Help = <<END;
+Extract extern pages out of the document PDF.
+
+positional arguments:
+  mmz                   the record file produced by Memoize: doc.mmz when compiling doc.tex
+
+options:
+  --help, -h            show this help message and exit
+  --version, -V         show version and exit
+  --pdf PDF, -P PDF     extract from file PDF
+  --prune, -p           remove the extern pages after extraction
+  --keep, -k            do not mark externs as extracted
+  --force, -f           extract even if the size-check fails
+  --log LOG, -l LOG     the log file
+  --warning-template WARNING_TEMPLATE, -w WARNING_TEMPLATE
+                        \warningtext in the template will be replaced by the warning message
+  --quiet, -q           don't describe what's happening
+  --embedded, -e        prefix all messages to the standard output with the script name
+  --mkdir, -m           create a directory (and exit)
+
+For details, see the man page or the Memoize documentation.
+END
+
+my ($pdf_arg, $prune, $keep, $log, $quiet, $embedded, $force, $mkdir, $help, $print_version);
+my $warning_template = '\warningtext';
+Getopt::Long::Configure ("bundling");
+GetOptions(
+    "pdf|P=s"   => \$pdf_arg,
+    "keep|k"    => \$keep,
+    "prune|p"   => \$prune,
+    "log|l=s"   => \$log,
+    "quiet|q" => \$quiet,
+    "embedded|e" => \$embedded,
+    "force|f" => \$force,
+    "warning-template|w=s" => \$warning_template,
+    "mkdir|m"   => \$mkdir,
+    "help|h|?"  => \$help,
+    "version|V"  => \$print_version,
+    ) or die $usage;
+if ($help) {print("$usage\n$Help"); exit 0}
+if ($print_version) { print("memoize-extract.pl of Memoize $VERSION\n"); exit 0 }
+die $usage unless @ARGV == 1;
+
+my $message_prefix = $embedded ? basename($0) . ': ' : '';
+print("\n") if ($embedded);
+
+my @output_paths = (dir()->absolute->resolve);
+my $texmfoutput = `kpsewhich --var-value=TEXMFOUTPUT`;
+$texmfoutput =~ s/^\s+|\s+$//g;
+if ($texmfoutput) {
+    my $texmfoutput_dir = dir($texmfoutput)->absolute->resolve;
+    push(@output_paths, $texmfoutput_dir) unless $texmfoutput_dir->dir_list == 1 && ! $texmfoutput_dir->volume;
+}
+
+sub paranoia {
+    my $file = $_[0];
+    die "${message_prefix}Cannot create a hidden file or dir: $file"
+	if $file->basename =~ /^\./;
+    my $parent = $file->parent->absolute->resolve;
+    die "${message_prefix}Cannot write outside the current working or output directory tree: $file"
+	unless grep($_->contains($parent), @output_paths);
+}
+
+my $mmz_arg = $ARGV[0];
+my $mmz_file = file($mmz_arg);
+my $mmz_dir = $mmz_file->parent;
+
+if ($mkdir) {
+    my $dir = dir($mmz_arg)->cleanup;
+    my $current = dir(File::Spec->catpath($dir->volume,
+					  $dir->is_absolute ? File::Spec->rootdir : File::Spec->curdir,
+					  ''))->absolute;
+    for my $c ($dir->components) {
+	$current = $current->subdir($c);
+	if (-d $current) {
+	    $current = $current->resolve;
+	} else {
+	    paranoia($current);
+	    mkdir($current);
+	    print("${message_prefix}Created directory $current\n") unless $quiet;
+	}
+    }
+    exit;
+} else {
+    die "${message_prefix}The 'mmz' argument should be a file with suffix '.mmz', not '$mmz_file'\n" unless $mmz_file->basename =~ /\.mmz$/;
+}
+
+# Enable in-place editing (of the .mmz file).
+paranoia($mmz_file) unless $keep;
+$^I = "" unless $keep;
+
+my $pdf_file = $pdf_arg ? file($pdf_arg) : $mmz_dir->file($mmz_file->basename =~ s/\.mmz$/\.pdf/r)->cleanup;
+paranoia($pdf_file) if $prune;
+
+if ($log) {
+    paranoia(file($log));
+    open LOG, ">$log";
+} else {
+    *LOG = *STDERR;
+}
+
+my ($pdf, %extern_pages);
+print "${message_prefix}Extracting externs from $pdf_file:\n" unless $quiet;
+
+my $tolerance = 0.01;
+my $done_message = "${message_prefix}Done (there was nothing to extract).\n";
+    
+while (<>) {
+    if (/^\\mmzNewExtern *{(?P<extern_path>(?P<prefix>.*?)(?P<code_md5sum>[0-9A-F]{32})-(?P<context_md5sum>[0-9A-F]{32})(?:-[0-9]+)?.pdf)}{(?P<page_n>[0-9]+)}{(?P<expected_width>[0-9.]*)pt}{(?P<expected_height>[0-9.]*)pt}/) {
+	my $extern_file = file($+{extern_path});
+	if (! $extern_file->is_absolute) {
+	    $extern_file = $mmz_dir->file($+{extern_path});
+	}
+	paranoia($extern_file);
+	my $page = $+{page_n};
+	my $expected_width_pt = $+{expected_width};
+	my $expected_height_pt = $+{expected_height};
+	my $c_memo_file = $mmz_dir->file($+{prefix} . $+{code_md5sum} . '.memo');
+	my $cc_memo_file = $mmz_dir->file($+{prefix} . $+{code_md5sum} . '-' . $+{context_md5sum} . '.memo');
+	if (!(-e $c_memo_file && -e $cc_memo_file)) {
+	    print LOG ($warning_template =~ s/\\warningtext/Not extracting page $page into extern $extern_file, because the associated (c)c-memo does not exist/gr), "\n\\endinput\n";
+	    last;
+	}
+	eval { $pdf = PDF::API2->open($pdf_file->stringify) unless $pdf; };
+	if ($@) {
+	    print LOG ($warning_template =~ s/\\warningtext/Cannot read file "$pdf_file". Perhaps you have to load Memoize earlier in the preamble?/gr), "\n\\endinput\n";
+	    close LOG;
+	    die "${message_prefix}File '$pdf_file' cannot be read, bailing out.\n";
+	}
+	my $extern = PDF::API2->new();
+	$extern->version($pdf->version);
+	$extern->import_page($pdf, $page);
+	my $extern_page = $extern->open_page(1);
+	my ($x0, $y0, $x1, $y1) = $extern_page->get_mediabox();
+	my $width_pt = ($x1 - $x0) / 72 * 72.27;
+	my $height_pt = ($y1 - $y0) / 72 * 72.27;
+	my $warning = '';
+	if (abs($width_pt - $expected_width_pt) > $tolerance
+	    || abs($height_pt - $expected_height_pt) > $tolerance)
+	{
+	    $warning = "I refuse to extract page $page from $pdf_file, because its size (${width_pt}pt x ${height_pt}pt) is not what I expected (${expected_width_pt}pt x ${expected_height_pt}pt)";
+	    print LOG ($warning_template =~ s/\\warningtext/$warning/gr), "\n";
+	}
+	if ($warning && !$force) {
+	    unlink $extern_file;
+	} else {
+	    $extern->saveas($extern_file->stringify);
+	    $done_message = "${message_prefix}Done.\n";
+	    print STDOUT "${message_prefix}  Page $page --> $extern_file\n" unless $quiet;
+	    $extern_pages{$page} = 1 if $prune;
+	    print("%") unless $keep;
+	}
+    }
+    print unless $keep;
+}
+
+print $done_message unless $quiet;
+
+if ($pdf and $prune) {
+    paranoia($pdf_file);
+    my $pruned_pdf = PDF::API2->new();
+    for (my $n = 1; $n <= $pdf->page_count(); $n++) {
+	if (! $extern_pages{$n}) {
+	    $pruned_pdf->import_page($pdf, $n);
+	}
+    }
+    $pruned_pdf->save($pdf_file->stringify);
+    print("${message_prefix}The following extern pages were pruned out of the PDF: ",
+	  join(",", sort(keys(%extern_pages))) . "\n") unless $quiet;
+}
+
+if ($log) {
+    print LOG "\\endinput\n";
+    close LOG;
+}


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.py
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.py	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,183 @@
+#!/usr/bin/env python3
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+__version__ = '2023/10/10 v1.0.0'
+
+import argparse, re, sys, os, pdfrw, subprocess, itertools
+from pathlib import Path
+
+parser = argparse.ArgumentParser(
+    description = "Extract extern pages out of the document PDF.",
+    epilog = "For details, see the man page or the Memoize documentation.",
+    prog = 'memoize-extract.py',
+)
+parser.add_argument('--pdf', '-P', help = 'extract from file PDF')
+parser.add_argument('--prune', '-p', action = 'store_true',
+    help = 'remove the extern pages after extraction')
+parser.add_argument('--keep', '-k', action = 'store_true',
+    help = 'do not mark externs as extracted')
+parser.add_argument('--force', '-f', action = 'store_true',
+    help = 'extract even if the size-check fails')
+parser.add_argument('--log', '-l', default = os.devnull, help = 'the log file')
+parser.add_argument('--warning-template', '-w', default = '\warningtext',
+    help = '\warningtext in the template will be replaced by the warning message')
+parser.add_argument('--quiet', '-q', action = 'store_true',
+    help = "describe what's happening")
+parser.add_argument('--embedded', '-e', action = 'store_true',
+    help = "prefix all messages to the standard output with the script name")
+parser.add_argument('--mkdir', '-m', action = 'store_true',
+    help = 'create a directory (and exit)')
+parser.add_argument('mmz',
+    help = 'the record file produced by Memoize: doc.mmz when compiling doc.tex')
+parser.add_argument('--version', '-V', action = 'version',
+                    version = f"%(prog)s of Memoize " + __version__)
+
+args = parser.parse_args()
+
+message_prefix = parser.prog + ': ' if args.embedded else ''
+if args.embedded:
+    print()
+
+# Even a bit more paranoid than required:
+# (a) disallowing TEXMFOUTPUT=/ (while allowing C:\ on Windows)
+# (b) waiting for access to '-output-directory'.
+output_paths = [Path.cwd()]
+if texmfoutput := subprocess.run(
+        ['kpsewhich', '--var-value=TEXMFOUTPUT'],
+        capture_output = True).stdout.decode().strip():
+    texmfoutput_dir = Path(texmfoutput).resolve()
+    if len(texmfoutput_dir.parts) != 1 or texmfoutput_dir.drive:
+        output_paths.append(texmfoutput_dir)
+
+def paranoia(f):
+    p = Path(f).resolve()
+    if p.stem.startswith('.'):
+        raise RuntimeError(f"{message_prefix}Cannot create a hidden file or dir: {f}")
+    if not any(p.is_relative_to(op) for op in output_paths):
+        raise RuntimeError(f"{message_prefix}Cannot write outside the current working or output directory tree: {f}")
+
+mmz_file = Path(args.mmz)
+    
+if args.mkdir: # Here, argument "mmz" is interpreted as the directory to create.
+    # We cannot simply say
+    # paranoia(mmz_file)
+    # mmz_file.mkdir(parents = True, exist_ok = True)
+    # because have be paranoid about the intermediate directories as well:
+    # memoize-extract.py -m a/../../BAD/../<cwd-name>/b
+    # Note that paranoia might kick in only after a part of the given path was
+    # already created.  This is in accord to how "mkdir" behaves wrt existing
+    # files.
+    for folder in itertools.chain(reversed(mmz_file.parents), (mmz_file,)):
+        if not folder.is_dir():
+            paranoia(folder)
+            folder.mkdir(exist_ok = True)
+            if not args.quiet:
+                print(f"{message_prefix}Created directory {folder}")
+    sys.exit()
+elif mmz_file.suffix != '.mmz':
+    raise RuntimeError(f"{message_prefix}The 'mmz' argument should be a file with suffix '.mmz', not '{mmz_file}'")
+
+mmz_dir = mmz_file.parent
+pdf_file = Path(args.pdf) if args.pdf else mmz_file.with_suffix('.pdf')
+paranoia(pdf_file)
+pdf = None
+extern_pages = []
+new_mmz = []
+args.log is os.devnull or paranoia(Path(args.log))
+re_newextern = re.compile(r'\\mmzNewExtern *{(?P<extern_fn>(?P<prefix>.*?)(?P<code_md5sum>[0-9A-F]{32})-(?P<context_md5sum>[0-9A-F]{32})(?:-[0-9]+)?.pdf)}{(?P<page_n>[0-9]+)}{(?P<expected_width>[0-9.]*)pt}{(?P<expected_height>[0-9.]*)pt}')
+tolerance = 0.01
+done_message = f"{message_prefix}Done (there was nothing to extract)."
+
+# Complication: I want to use 'with', but don't have to open stderr.
+with open(args.log, 'w') as log:
+    log = sys.stderr if args.log is os.devnull else log
+    try:
+        mmz = mmz_file.open()
+    except FileNotFoundError:
+        print(f'''{message_prefix}File "{mmz_file}" does not exist, assuming there's nothing to do.''',
+              file = sys.stderr)
+    else:
+        if not args.quiet:
+            print(f"{message_prefix}Extracting externs from {pdf_file}")
+        for line in mmz:
+            if m := re_newextern.match(line):
+                extern_file = mmz_dir / m['extern_fn']
+                paranoia(extern_file)
+                page_n = int(m['page_n'])-1
+                c_memo = mmz_dir / (m['prefix'] + m['code_md5sum'] + '.memo')
+                cc_memo = mmz_dir / (m['prefix'] + m['code_md5sum'] + '-' + m['context_md5sum'] + '.memo')
+                if not (c_memo.exists() and cc_memo.exists()):
+                    print(args.warning_template.replace('\warningtext', f'Not extracting page {page_n} into extern {extern_file}, because the associated (c)c-memo does not exist'), file = log)
+                    continue
+                if not pdf:
+                    try:
+                        pdf = pdfrw.PdfReader(pdf_file)
+                    except pdfrw.errors.PdfParseError:
+                        print(f'{message_prefix}File "{pdf_file}" cannot be read, bailing out.', file = sys.stderr)
+                        print(args.warning_template.replace('\warningtext', f'Cannot read file "{pdf_file}". Perhaps you have to load Memoize earlier in the preamble?'), file = log)
+                        args.keep = True
+                        break
+                extern = pdfrw.PdfWriter(extern_file)
+                page = pdf.pages[page_n]
+                expected_width_pt, expected_height_pt = float(m['expected_width']), float(m['expected_height'])
+                mb = page['/MediaBox']
+                width_bp, height_bp = float(mb[2]) - float(mb[0]), float(mb[3]) - float(mb[1])
+                width_pt = width_bp / 72 * 72.27
+                height_pt = height_bp / 72 * 72.27
+                warning = None
+                if abs(width_pt - expected_width_pt) > tolerance \
+                   or abs(height_pt - expected_height_pt) > tolerance:
+                    warning = (
+                        f'I refuse to extract page {page_n+1} from "{pdf_file}", '
+                        f'because its size ({width_pt}pt x {height_pt}pt) is not '
+                        f'what I expected ({expected_width_pt}pt x {expected_height_pt}pt)')
+                    print(args.warning_template.replace('\warningtext', warning), file = log)
+                if warning and not args.force:
+                    extern_file.unlink(missing_ok = True)
+                else:
+                    extern.addpage(page)
+                    if not args.quiet:
+                        print(f"{message_prefix}  Page {page_n+1} --> {extern_file}", file = sys.__stdout__)
+                    extern.write()
+                    done_message = f"{message_prefix}Done."
+                    if args.prune:
+                        extern_pages.append(page_n)
+                    if not args.keep:
+                        line = '%' + line
+            if not args.keep:
+                new_mmz.append(line)
+        mmz.close()
+        if not args.quiet:
+            print(done_message)
+        if not args.keep:
+            paranoia(mmz_file)
+            with open(mmz_file, 'w') as mmz:
+                for line in new_mmz:
+                    print(line, file = mmz, end = '')
+        if args.prune and extern_pages:
+            pruned_pdf = pdfrw.PdfWriter(pdf_file)
+            pruned_pdf.addpages(
+                page for n, page in enumerate(pdf.pages) if n not in extern_pages)
+            pruned_pdf.write()
+            if not args.quiet:
+                print(f"{message_prefix}The following extern pages were pruned out of the PDF:",
+                      ",".join(str(page+1) for page in extern_pages))
+    if args.log is not os.devnull:
+        print(r'\endinput', file = log)


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/memoize/memoize-extract.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Build/source/texk/texlive/linked_scripts/scripts.lst
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2023-10-11 20:46:52 UTC (rev 68515)
@@ -124,6 +124,10 @@
 make4ht/make4ht
 match_parens/match_parens
 mathspic/mathspic.pl
+memoize/memoize-clean.pl
+memoize/memoize-clean.py
+memoize/memoize-extract.pl
+memoize/memoize-extract.py
 mf2pt1/mf2pt1.pl
 mkgrkindex/mkgrkindex
 mkjobtexmf/mkjobtexmf.pl

Added: trunk/Master/bin/aarch64-linux/memoize-clean.pl
===================================================================
--- trunk/Master/bin/aarch64-linux/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/aarch64-linux/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/aarch64-linux/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/aarch64-linux/memoize-clean.py
===================================================================
--- trunk/Master/bin/aarch64-linux/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/aarch64-linux/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/aarch64-linux/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/aarch64-linux/memoize-extract.pl
===================================================================
--- trunk/Master/bin/aarch64-linux/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/aarch64-linux/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/aarch64-linux/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/aarch64-linux/memoize-extract.py
===================================================================
--- trunk/Master/bin/aarch64-linux/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/aarch64-linux/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/aarch64-linux/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-freebsd/memoize-clean.pl
===================================================================
--- trunk/Master/bin/amd64-freebsd/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-freebsd/memoize-clean.py
===================================================================
--- trunk/Master/bin/amd64-freebsd/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-freebsd/memoize-extract.pl
===================================================================
--- trunk/Master/bin/amd64-freebsd/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-freebsd/memoize-extract.py
===================================================================
--- trunk/Master/bin/amd64-freebsd/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-netbsd/memoize-clean.pl
===================================================================
--- trunk/Master/bin/amd64-netbsd/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-netbsd/memoize-clean.py
===================================================================
--- trunk/Master/bin/amd64-netbsd/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-netbsd/memoize-extract.pl
===================================================================
--- trunk/Master/bin/amd64-netbsd/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-netbsd/memoize-extract.py
===================================================================
--- trunk/Master/bin/amd64-netbsd/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armhf-linux/memoize-clean.pl
===================================================================
--- trunk/Master/bin/armhf-linux/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armhf-linux/memoize-clean.py
===================================================================
--- trunk/Master/bin/armhf-linux/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armhf-linux/memoize-extract.pl
===================================================================
--- trunk/Master/bin/armhf-linux/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armhf-linux/memoize-extract.py
===================================================================
--- trunk/Master/bin/armhf-linux/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-freebsd/memoize-clean.pl
===================================================================
--- trunk/Master/bin/i386-freebsd/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-freebsd/memoize-clean.py
===================================================================
--- trunk/Master/bin/i386-freebsd/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-freebsd/memoize-extract.pl
===================================================================
--- trunk/Master/bin/i386-freebsd/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-freebsd/memoize-extract.py
===================================================================
--- trunk/Master/bin/i386-freebsd/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-linux/memoize-clean.pl
===================================================================
--- trunk/Master/bin/i386-linux/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/i386-linux/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-linux/memoize-clean.py
===================================================================
--- trunk/Master/bin/i386-linux/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/i386-linux/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-linux/memoize-extract.pl
===================================================================
--- trunk/Master/bin/i386-linux/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/i386-linux/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-linux/memoize-extract.py
===================================================================
--- trunk/Master/bin/i386-linux/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/i386-linux/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-netbsd/memoize-clean.pl
===================================================================
--- trunk/Master/bin/i386-netbsd/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-netbsd/memoize-clean.py
===================================================================
--- trunk/Master/bin/i386-netbsd/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-netbsd/memoize-extract.pl
===================================================================
--- trunk/Master/bin/i386-netbsd/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-netbsd/memoize-extract.py
===================================================================
--- trunk/Master/bin/i386-netbsd/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-solaris/memoize-clean.pl
===================================================================
--- trunk/Master/bin/i386-solaris/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-solaris/memoize-clean.py
===================================================================
--- trunk/Master/bin/i386-solaris/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-solaris/memoize-extract.pl
===================================================================
--- trunk/Master/bin/i386-solaris/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-solaris/memoize-extract.py
===================================================================
--- trunk/Master/bin/i386-solaris/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/universal-darwin/memoize-clean.pl
===================================================================
--- trunk/Master/bin/universal-darwin/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/universal-darwin/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/universal-darwin/memoize-clean.py
===================================================================
--- trunk/Master/bin/universal-darwin/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/universal-darwin/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/universal-darwin/memoize-extract.pl
===================================================================
--- trunk/Master/bin/universal-darwin/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/universal-darwin/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/universal-darwin/memoize-extract.py
===================================================================
--- trunk/Master/bin/universal-darwin/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/universal-darwin/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/windows/memoize-clean.pl.exe
===================================================================
(Binary files differ)

Index: trunk/Master/bin/windows/memoize-clean.pl.exe
===================================================================
--- trunk/Master/bin/windows/memoize-clean.pl.exe	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/bin/windows/memoize-clean.pl.exe	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/bin/windows/memoize-clean.pl.exe
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/bin/windows/memoize-clean.py.exe
===================================================================
(Binary files differ)

Index: trunk/Master/bin/windows/memoize-clean.py.exe
===================================================================
--- trunk/Master/bin/windows/memoize-clean.py.exe	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/bin/windows/memoize-clean.py.exe	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/bin/windows/memoize-clean.py.exe
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/bin/windows/memoize-extract.pl.exe
===================================================================
(Binary files differ)

Index: trunk/Master/bin/windows/memoize-extract.pl.exe
===================================================================
--- trunk/Master/bin/windows/memoize-extract.pl.exe	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/bin/windows/memoize-extract.pl.exe	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/bin/windows/memoize-extract.pl.exe
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/bin/windows/memoize-extract.py.exe
===================================================================
(Binary files differ)

Index: trunk/Master/bin/windows/memoize-extract.py.exe
===================================================================
--- trunk/Master/bin/windows/memoize-extract.py.exe	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/bin/windows/memoize-extract.py.exe	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/bin/windows/memoize-extract.py.exe
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/bin/x86_64-cygwin/memoize-clean.pl
===================================================================
--- trunk/Master/bin/x86_64-cygwin/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-cygwin/memoize-clean.py
===================================================================
--- trunk/Master/bin/x86_64-cygwin/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-cygwin/memoize-extract.pl
===================================================================
--- trunk/Master/bin/x86_64-cygwin/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-cygwin/memoize-extract.py
===================================================================
--- trunk/Master/bin/x86_64-cygwin/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.pl
===================================================================
--- trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.py
===================================================================
--- trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwinlegacy/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.pl
===================================================================
--- trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.py
===================================================================
--- trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwinlegacy/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linux/memoize-clean.pl
===================================================================
--- trunk/Master/bin/x86_64-linux/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linux/memoize-clean.py
===================================================================
--- trunk/Master/bin/x86_64-linux/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linux/memoize-extract.pl
===================================================================
--- trunk/Master/bin/x86_64-linux/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linux/memoize-extract.py
===================================================================
--- trunk/Master/bin/x86_64-linux/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linuxmusl/memoize-clean.pl
===================================================================
--- trunk/Master/bin/x86_64-linuxmusl/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-linuxmusl/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linuxmusl/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linuxmusl/memoize-clean.py
===================================================================
--- trunk/Master/bin/x86_64-linuxmusl/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-linuxmusl/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linuxmusl/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linuxmusl/memoize-extract.pl
===================================================================
--- trunk/Master/bin/x86_64-linuxmusl/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-linuxmusl/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linuxmusl/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linuxmusl/memoize-extract.py
===================================================================
--- trunk/Master/bin/x86_64-linuxmusl/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-linuxmusl/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linuxmusl/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-solaris/memoize-clean.pl
===================================================================
--- trunk/Master/bin/x86_64-solaris/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/memoize-clean.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-solaris/memoize-clean.py
===================================================================
--- trunk/Master/bin/x86_64-solaris/memoize-clean.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-clean.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/memoize-clean.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-solaris/memoize-extract.pl
===================================================================
--- trunk/Master/bin/x86_64-solaris/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/memoize-extract.pl
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-solaris/memoize-extract.py
===================================================================
--- trunk/Master/bin/x86_64-solaris/memoize-extract.py	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/memoize/memoize-extract.py
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/memoize-extract.py
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/FILES
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/FILES	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/FILES	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,40 @@
+doc/man/man1/memoize-extract.1
+doc/man/man1/memoize-clean.py.1
+doc/man/man1/memoize-extract.py.1
+doc/man/man1/memoize-clean.1
+doc/man/man1/memoize-clean.pl.1
+doc/man/man1/memoize-extract.pl.1
+doc/generic/memoize/memoize-doc.sty
+doc/generic/memoize/LICENCE
+doc/generic/memoize/INSTALL.md
+doc/generic/memoize/memoize-doc-common.sty
+doc/generic/memoize/memoize-code.sty
+doc/generic/memoize/yadoc.sty
+doc/generic/memoize/memoize-clean.1.md
+doc/generic/memoize/memoize.tex
+doc/generic/memoize/memoize-code.pdf
+doc/generic/memoize/memoize-code.tex
+doc/generic/memoize/memoize-extract.1.md
+doc/generic/memoize/memoize.mst
+doc/generic/memoize/examples.zip
+doc/generic/memoize/examples-src.zip
+doc/generic/memoize/FILES
+doc/generic/memoize/memoize.pdf
+doc/generic/memoize/README.md
+scripts/memoize/memoize-clean.pl
+scripts/memoize/memoize-extract.py
+scripts/memoize/memoize-clean.py
+scripts/memoize/memoize-extract.pl
+tex/latex/memoize/memoize.sty
+tex/latex/memoize/memoizable.sty
+tex/latex/memoize/nomemoize.sty
+tex/context/memoize/t-nomemoize.tex
+tex/context/memoize/t-memoizable.tex
+tex/context/memoize/t-memoize.tex
+tex/plain/memoize/nomemoize.tex
+tex/plain/memoize/memoize-extract-one.tex
+tex/plain/memoize/memoizable.tex
+tex/plain/memoize/memoize.tex
+source/generic/memoize/memoize.edtx
+source/generic/memoize/memoize.ins
+source/generic/memoize/Makefile

Added: trunk/Master/texmf-dist/doc/generic/memoize/INSTALL.md
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/INSTALL.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/INSTALL.md	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,216 @@
+# Installation from the TDS archive
+
+If Memoize is not (yet) offered by your TeX distribution, the easiest way to
+install it is by downloading the TDS archive `memoize.tds.zip` from [Memoize's
+CTAN page](https://ctan.org/pkg/memoize), and unpacking it into your `texmf`
+directory.  You will most likely also have to do the same for two auxiliary
+packages Memoize depends on: [Advice](https://ctan.org/pkg/advice) and
+[CollArgs](https://ctan.org/pkg/collargs).
+
+Read on only if you have an unstoppable urge to install from source and/or
+compile the manual or the documented source code.
+
+# Installation from the source
+
+# Getting the sources
+
+There are several options:
+
+* Download and unpack the zip archive of the package from [Memoize's CTAN
+  page](https://ctan.org/pkg/memoize).
+   
+* Download and unpack the TDS archive, or copy the files from your local
+  distribution. The sources reside in `<texmf>/source/generic/memoize`.
+
+* Clone the [GitHub repository](https://github.com/sasozivanovic/memoize).
+
+## Generating runtime files
+
+The easiest way to generate the runtime files is by running `make`. The
+following command will generate (i) runtime TeX files for all supported formats
+(currently: LaTeX, plain TeX and ConTeXt), and (ii) the man pages for the
+accompanying scripts:
+
+```
+make runtime
+```
+
+To only generate the runtime TeX files, execute
+
+```
+make memoize.sty
+```
+
+Alternatively, you can generate the runtime files manually.  The source of this
+package was written using [EasyDTX](https://ctan.org/pkg/easydtx).  Therefore,
+you first have to convert the `.edtx` file into a regular `.dtx`:
+
+```
+edtx2dtx memoize.edtx > memoize.dtx
+```
+
+The next step is standard.  Produce the runtime files by compiling the
+installation file:
+
+```
+tex memoize.ins
+```
+
+If you require the ConTeXt runtime, replace all instances of `\expanded` and
+`\unexpanded` in `t-memoize.tex` by `\normalexpanded` and `\normalunexpanded`,
+respectively.  One way to do this is:
+
+```
+sed -i -s -e 's/\\\(un\)\?expanded/\\normal\1expanded/g;' t-memoize.tex
+```
+
+The man pages are produced by converting their MarkDown sources by `pandoc`
+(execute this in the `doc` subdirectory):
+
+```
+pandoc memoize-extract.1.md -s -t man -o memoize-extract.1
+pandoc memoize-clean.1.md -s -t man -o memoize-clean.1
+```
+
+Additionally, links from `memoize-x.pl.1` and `memoize-x.py.1` to `memoize-x.1`
+can be created by:
+
+```
+echo .so man1/memoize-extract.1 > memoize-extract.pl.1
+echo .so man1/memoize-extract.1 > memoize-extract.py.1
+echo .so man1/memoize-clean.1 > memoize-clean.pl.1
+echo .so man1/memoize-clean.1 > memoize-clean.py.1
+```
+
+## Installation
+
+It is recommended to install the files into a TDS-compliant `texmf` directory,
+as usual.  Inspect file `FILES` or the TDS archive `memoize.tds.zip` to see
+what goes where.
+
+Next, the scripts residing in `<texmf>/scripts/memoize` should be linked into
+some directory listed in the executable search `PATH`.  The scripts are the
+following:
+
+* `memoize-extract.pl`
+* `memoize-extract.py`
+* `memoize-clean.pl`
+* `memoize-clean.py`
+
+If you have downloaded the sources from GitHub, you can build the TDS
+directories/archives of both Memoize and its auxiliary packages Advice and
+CollArgs by issuing
+
+```
+make
+```
+
+This command creates: 
+
+* TDS directories `memoize.tds`, `advice.tds` and `collargs.tds`,
+
+* CTAN directories `ctan/memoize`, `ctan/advice` and `ctan/memoize`,
+
+* TDS archives `memoize.tds.zip`, `advice.tds.zip` and `collargs.tds.zip`
+  inside the CTAN directories, and 
+  
+* CTAN archives `memoize.zip`, `advice.zip` and `collargs.zip` inside directory
+  `ctan`.
+  
+The plain `make` shown above will also attempt to compile the documentation.
+If you're not ready for that (yet), you can avoid that by executing this
+instead:
+
+```
+make PDF=
+```
+
+# Compiling the documentation
+
+Compiling both the documented code listing and the manual requires a Unix-like
+operating system.  I have developed Memoize on Linux, but the documentation
+should also be compilable under Cygwin on Windows (not tested).
+
+The documentation of Advice and CollArgs, both their manuals and documented
+code listings, is included within Memoize's documentation.
+
+## Getting the source
+
+In principle, the options are the same as for the installation from the source,
+but the GitHub option is strongly preferred here, as the other two options
+require manually copying the sources of Advice and CollArgs into the Memoize
+directory.  That said:
+
+* Clone the [GitHub repository](https://github.com/sasozivanovic/memoize).
+  You're done.
+
+* Download and unpack the zip archives of all three packages from their CTAN
+  pages: https://ctan.org/pkg/memoize, https://ctan.org/pkg/advice and
+  https://ctan.org/pkg/collargs.
+   
+  Copy `advice.edtx` and `collargs.edtx` into the Memoize directory, alongside
+  `memoize.edtx`.
+   
+* From TDS archives (of all three packages), or your local distribution's
+  `<texmf>` folder.  This is not straightforward:
+  
+  1. Make a local copy of directory `<texmf>/source/generic/memoize`; we'll
+     call it "the Memoize directory".
+	 
+  2. Copy directory `<texmf>/doc/generic/memoize` into the the Memoize
+     directory as `doc`.
+	 
+  3. Copy `memoize-extract.pl`, `memoize-extract.py`, `memoize-clean.pl` and
+     `memoize-clean.py` from directory `<texmf>/scripts` into the Memoize
+     directory.
+  
+  4. Copy `advice.edtx` from `<texmf>/source/generic/advice` and
+     `collargs.edtx` from `<texmf>/source/generic/collargs` into the the
+     Memoize directory.
+
+## Compiling the documented code listing
+
+I have compiled the code docs with LuaLaTeX on a Linux system with
+TeXLive 2023.  If you have `make`, the easiest way to compile them is by
+issuing
+
+```
+make doc/memoize-code.pdf
+```
+
+Alternatively, you can use `latexmk`, but you first have to convert the `.edtx`
+sources of all three packages into `.dtx`, if you haven't done so yet:
+
+```
+edtx2dtx memoize.edtx > memoize.dtx
+edtx2dtx advice.edtx > advice.dtx
+edtx2dtx collargs.edtx > collargs.dtx
+```
+
+Then, you can execute `latexmk` from the `doc` subdirectory:
+
+```
+latexmk -lualatex -bibtex memoize-code
+```
+
+To compile the code docs manually, three iterations of `lualatex memoize-code`
+with `makeindex -s gind.ist memoize-code.idx` between them should suffice.
+
+## Compiling the manual
+
+I have compiled the manual with LuaLaTeX on a Linux system with TeXLive 2023,
+`make`, `latexmk`, `perl` and `sed` installed.  Furthermore, you absolutely
+have to run the compilation with some form of `--shell-escape`, as it executes
+`make` and `sed` to build the examples.  (There is no way to compile these from
+the command line, as the instructions are baked into the manual source.)
+
+Given all this, either of the following should do the trick:
+
+* `make doc/memoize.pdf` from the Memoize directory;
+
+* `latexmk -lualatex -bibtex memoize` for the `doc` subdirectory; or
+
+* quite a few runs of `lualatex memoize` interspersed by `makeindex memoize.idx`.
+	
+If all worked well, you can change `\usepackage{nomemoize}` in
+`doc/memoize.tex` to `\usepackage{memoize}` and observe Memoize at work.


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/INSTALL.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/LICENCE
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/LICENCE	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/LICENCE	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,416 @@
+The LaTeX Project Public License
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+LPPL Version 1.3c  2008-05-04
+
+Copyright 1999 2002-2008 LaTeX3 Project
+    Everyone is allowed to distribute verbatim copies of this
+    license document, but modification of it is not allowed.
+
+
+PREAMBLE
+========
+
+The LaTeX Project Public License (LPPL) is the primary license under
+which the LaTeX kernel and the base LaTeX packages are distributed.
+
+You may use this license for any work of which you hold the copyright
+and which you wish to distribute.  This license may be particularly
+suitable if your work is TeX-related (such as a LaTeX package), but 
+it is written in such a way that you can use it even if your work is 
+unrelated to TeX.
+
+The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
+below, gives instructions, examples, and recommendations for authors
+who are considering distributing their works under this license.
+
+This license gives conditions under which a work may be distributed
+and modified, as well as conditions under which modified versions of
+that work may be distributed.
+
+We, the LaTeX3 Project, believe that the conditions below give you
+the freedom to make and distribute modified versions of your work
+that conform with whatever technical specifications you wish while
+maintaining the availability, integrity, and reliability of
+that work.  If you do not see how to achieve your goal while
+meeting these conditions, then read the document `cfgguide.tex'
+and `modguide.tex' in the base LaTeX distribution for suggestions.
+
+
+DEFINITIONS
+===========
+
+In this license document the following terms are used:
+
+   `Work'
+    Any work being distributed under this License.
+    
+   `Derived Work'
+    Any work that under any applicable law is derived from the Work.
+
+   `Modification' 
+    Any procedure that produces a Derived Work under any applicable
+    law -- for example, the production of a file containing an
+    original file associated with the Work or a significant portion of
+    such a file, either verbatim or with modifications and/or
+    translated into another language.
+
+   `Modify'
+    To apply any procedure that produces a Derived Work under any
+    applicable law.
+    
+   `Distribution'
+    Making copies of the Work available from one person to another, in
+    whole or in part.  Distribution includes (but is not limited to)
+    making any electronic components of the Work accessible by
+    file transfer protocols such as FTP or HTTP or by shared file
+    systems such as Sun's Network File System (NFS).
+
+   `Compiled Work'
+    A version of the Work that has been processed into a form where it
+    is directly usable on a computer system.  This processing may
+    include using installation facilities provided by the Work,
+    transformations of the Work, copying of components of the Work, or
+    other activities.  Note that modification of any installation
+    facilities provided by the Work constitutes modification of the Work.
+
+   `Current Maintainer'
+    A person or persons nominated as such within the Work.  If there is
+    no such explicit nomination then it is the `Copyright Holder' under
+    any applicable law.
+
+   `Base Interpreter' 
+    A program or process that is normally needed for running or
+    interpreting a part or the whole of the Work.    
+
+    A Base Interpreter may depend on external components but these
+    are not considered part of the Base Interpreter provided that each
+    external component clearly identifies itself whenever it is used
+    interactively.  Unless explicitly specified when applying the
+    license to the Work, the only applicable Base Interpreter is a
+    `LaTeX-Format' or in the case of files belonging to the 
+    `LaTeX-format' a program implementing the `TeX language'.
+
+
+
+CONDITIONS ON DISTRIBUTION AND MODIFICATION
+===========================================
+
+1.  Activities other than distribution and/or modification of the Work
+are not covered by this license; they are outside its scope.  In
+particular, the act of running the Work is not restricted and no
+requirements are made concerning any offers of support for the Work.
+
+2.  You may distribute a complete, unmodified copy of the Work as you
+received it.  Distribution of only part of the Work is considered
+modification of the Work, and no right to distribute such a Derived
+Work may be assumed under the terms of this clause.
+
+3.  You may distribute a Compiled Work that has been generated from a
+complete, unmodified copy of the Work as distributed under Clause 2
+above, as long as that Compiled Work is distributed in such a way that
+the recipients may install the Compiled Work on their system exactly
+as it would have been installed if they generated a Compiled Work
+directly from the Work.
+
+4.  If you are the Current Maintainer of the Work, you may, without
+restriction, modify the Work, thus creating a Derived Work.  You may
+also distribute the Derived Work without restriction, including
+Compiled Works generated from the Derived Work.  Derived Works
+distributed in this manner by the Current Maintainer are considered to
+be updated versions of the Work.
+
+5.  If you are not the Current Maintainer of the Work, you may modify
+your copy of the Work, thus creating a Derived Work based on the Work,
+and compile this Derived Work, thus creating a Compiled Work based on
+the Derived Work.
+
+6.  If you are not the Current Maintainer of the Work, you may
+distribute a Derived Work provided the following conditions are met
+for every component of the Work unless that component clearly states
+in the copyright notice that it is exempt from that condition.  Only
+the Current Maintainer is allowed to add such statements of exemption 
+to a component of the Work. 
+
+  a. If a component of this Derived Work can be a direct replacement
+     for a component of the Work when that component is used with the
+     Base Interpreter, then, wherever this component of the Work
+     identifies itself to the user when used interactively with that
+     Base Interpreter, the replacement component of this Derived Work
+     clearly and unambiguously identifies itself as a modified version
+     of this component to the user when used interactively with that
+     Base Interpreter.
+     
+  b. Every component of the Derived Work contains prominent notices
+     detailing the nature of the changes to that component, or a
+     prominent reference to another file that is distributed as part
+     of the Derived Work and that contains a complete and accurate log
+     of the changes.
+  
+  c. No information in the Derived Work implies that any persons,
+     including (but not limited to) the authors of the original version
+     of the Work, provide any support, including (but not limited to)
+     the reporting and handling of errors, to recipients of the
+     Derived Work unless those persons have stated explicitly that
+     they do provide such support for the Derived Work.
+
+  d. You distribute at least one of the following with the Derived Work:
+
+       1. A complete, unmodified copy of the Work; 
+          if your distribution of a modified component is made by
+          offering access to copy the modified component from a
+          designated place, then offering equivalent access to copy
+          the Work from the same or some similar place meets this
+          condition, even though third parties are not compelled to
+          copy the Work along with the modified component;
+
+       2. Information that is sufficient to obtain a complete,
+          unmodified copy of the Work.
+
+7.  If you are not the Current Maintainer of the Work, you may
+distribute a Compiled Work generated from a Derived Work, as long as
+the Derived Work is distributed to all recipients of the Compiled
+Work, and as long as the conditions of Clause 6, above, are met with
+regard to the Derived Work.
+
+8.  The conditions above are not intended to prohibit, and hence do not
+apply to, the modification, by any method, of any component so that it
+becomes identical to an updated version of that component of the Work as
+it is distributed by the Current Maintainer under Clause 4, above.
+
+9.  Distribution of the Work or any Derived Work in an alternative
+format, where the Work or that Derived Work (in whole or in part) is
+then produced by applying some process to that format, does not relax or
+nullify any sections of this license as they pertain to the results of
+applying that process.
+     
+10. a. A Derived Work may be distributed under a different license
+       provided that license itself honors the conditions listed in
+       Clause 6 above, in regard to the Work, though it does not have
+       to honor the rest of the conditions in this license.
+      
+    b. If a Derived Work is distributed under a different license, that
+       Derived Work must provide sufficient documentation as part of
+       itself to allow each recipient of that Derived Work to honor the 
+       restrictions in Clause 6 above, concerning changes from the Work.
+
+11. This license places no restrictions on works that are unrelated to
+the Work, nor does this license place any restrictions on aggregating
+such works with the Work by any means.
+
+12.  Nothing in this license is intended to, or may be used to, prevent
+complete compliance by all parties with all applicable laws.
+
+
+NO WARRANTY
+===========
+
+There is no warranty for the Work.  Except when otherwise stated in
+writing, the Copyright Holder provides the Work `as is', without
+warranty of any kind, either expressed or implied, including, but not
+limited to, the implied warranties of merchantability and fitness for a
+particular purpose.  The entire risk as to the quality and performance
+of the Work is with you.  Should the Work prove defective, you assume
+the cost of all necessary servicing, repair, or correction.
+
+In no event unless required by applicable law or agreed to in writing
+will The Copyright Holder, or any author named in the components of the
+Work, or any other party who may distribute and/or modify the Work as
+permitted above, be liable to you for damages, including any general,
+special, incidental or consequential damages arising out of any use of
+the Work or out of inability to use the Work (including, but not limited
+to, loss of data, data being rendered inaccurate, or losses sustained by
+anyone as a result of any failure of the Work to operate with any other
+programs), even if the Copyright Holder or said author or said other
+party has been advised of the possibility of such damages.
+
+
+MAINTENANCE OF THE WORK
+=======================
+
+The Work has the status `author-maintained' if the Copyright Holder
+explicitly and prominently states near the primary copyright notice in
+the Work that the Work can only be maintained by the Copyright Holder
+or simply that it is `author-maintained'.
+
+The Work has the status `maintained' if there is a Current Maintainer
+who has indicated in the Work that they are willing to receive error
+reports for the Work (for example, by supplying a valid e-mail
+address). It is not required for the Current Maintainer to acknowledge
+or act upon these error reports.
+
+The Work changes from status `maintained' to `unmaintained' if there
+is no Current Maintainer, or the person stated to be Current
+Maintainer of the work cannot be reached through the indicated means
+of communication for a period of six months, and there are no other
+significant signs of active maintenance.
+
+You can become the Current Maintainer of the Work by agreement with
+any existing Current Maintainer to take over this role.
+
+If the Work is unmaintained, you can become the Current Maintainer of
+the Work through the following steps:
+
+ 1.  Make a reasonable attempt to trace the Current Maintainer (and
+     the Copyright Holder, if the two differ) through the means of
+     an Internet or similar search.
+
+ 2.  If this search is successful, then enquire whether the Work
+     is still maintained.
+
+  a. If it is being maintained, then ask the Current Maintainer
+     to update their communication data within one month.
+     
+  b. If the search is unsuccessful or no action to resume active
+     maintenance is taken by the Current Maintainer, then announce
+     within the pertinent community your intention to take over
+     maintenance.  (If the Work is a LaTeX work, this could be
+     done, for example, by posting to comp.text.tex.)
+
+ 3a. If the Current Maintainer is reachable and agrees to pass
+     maintenance of the Work to you, then this takes effect
+     immediately upon announcement.
+     
+  b. If the Current Maintainer is not reachable and the Copyright
+     Holder agrees that maintenance of the Work be passed to you,
+     then this takes effect immediately upon announcement.  
+    
+ 4.  If you make an `intention announcement' as described in 2b. above
+     and after three months your intention is challenged neither by
+     the Current Maintainer nor by the Copyright Holder nor by other
+     people, then you may arrange for the Work to be changed so as
+     to name you as the (new) Current Maintainer.
+     
+ 5.  If the previously unreachable Current Maintainer becomes
+     reachable once more within three months of a change completed
+     under the terms of 3b) or 4), then that Current Maintainer must
+     become or remain the Current Maintainer upon request provided
+     they then update their communication data within one month.
+
+A change in the Current Maintainer does not, of itself, alter the fact
+that the Work is distributed under the LPPL license.
+
+If you become the Current Maintainer of the Work, you should
+immediately provide, within the Work, a prominent and unambiguous
+statement of your status as Current Maintainer.  You should also
+announce your new status to the same pertinent community as
+in 2b) above.
+
+
+WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
+======================================================
+
+This section contains important instructions, examples, and
+recommendations for authors who are considering distributing their
+works under this license.  These authors are addressed as `you' in
+this section.
+
+Choosing This License or Another License
+----------------------------------------
+
+If for any part of your work you want or need to use *distribution*
+conditions that differ significantly from those in this license, then
+do not refer to this license anywhere in your work but, instead,
+distribute your work under a different license.  You may use the text
+of this license as a model for your own license, but your license
+should not refer to the LPPL or otherwise give the impression that
+your work is distributed under the LPPL.
+
+The document `modguide.tex' in the base LaTeX distribution explains
+the motivation behind the conditions of this license.  It explains,
+for example, why distributing LaTeX under the GNU General Public
+License (GPL) was considered inappropriate.  Even if your work is
+unrelated to LaTeX, the discussion in `modguide.tex' may still be
+relevant, and authors intending to distribute their works under any
+license are encouraged to read it.
+
+A Recommendation on Modification Without Distribution
+-----------------------------------------------------
+
+It is wise never to modify a component of the Work, even for your own
+personal use, without also meeting the above conditions for
+distributing the modified component.  While you might intend that such
+modifications will never be distributed, often this will happen by
+accident -- you may forget that you have modified that component; or
+it may not occur to you when allowing others to access the modified
+version that you are thus distributing it and violating the conditions
+of this license in ways that could have legal implications and, worse,
+cause problems for the community.  It is therefore usually in your
+best interest to keep your copy of the Work identical with the public
+one.  Many works provide ways to control the behavior of that work
+without altering any of its licensed components.
+
+How to Use This License
+-----------------------
+
+To use this license, place in each of the components of your work both
+an explicit copyright notice including your name and the year the work
+was authored and/or last substantially modified.  Include also a
+statement that the distribution and/or modification of that
+component is constrained by the conditions in this license.
+
+Here is an example of such a notice and statement:
+
+  %% pig.dtx
+  %% Copyright 2008 M. Y. Name
+  %
+  % This work may be distributed and/or modified under the
+  % conditions of the LaTeX Project Public License, either version 1.3
+  % of this license or (at your option) any later version.
+  % The latest version of this license is in
+  %   https://www.latex-project.org/lppl.txt
+  % and version 1.3c or later is part of all distributions of LaTeX
+  % version 2008 or later.
+  %
+  % This work has the LPPL maintenance status `maintained'.
+  % 
+  % The Current Maintainer of this work is M. Y. Name.
+  %
+  % This work consists of the files pig.dtx and pig.ins
+  % and the derived file pig.sty.
+
+Given such a notice and statement in a file, the conditions
+given in this license document would apply, with the `Work' referring
+to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
+generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
+referring to any `LaTeX-Format', and both `Copyright Holder' and
+`Current Maintainer' referring to the person `M. Y. Name'.
+
+If you do not want the Maintenance section of LPPL to apply to your
+Work, change `maintained' above into `author-maintained'.  
+However, we recommend that you use `maintained', as the Maintenance
+section was added in order to ensure that your Work remains useful to
+the community even when you can no longer maintain and support it
+yourself.
+
+Derived Works That Are Not Replacements
+---------------------------------------
+
+Several clauses of the LPPL specify means to provide reliability and
+stability for the user community. They therefore concern themselves
+with the case that a Derived Work is intended to be used as a
+(compatible or incompatible) replacement of the original Work. If
+this is not the case (e.g., if a few lines of code are reused for a
+completely different task), then clauses 6b and 6d shall not apply.
+
+
+Important Recommendations
+-------------------------
+
+ Defining What Constitutes the Work
+
+   The LPPL requires that distributions of the Work contain all the
+   files of the Work.  It is therefore important that you provide a
+   way for the licensee to determine which files constitute the Work.
+   This could, for example, be achieved by explicitly listing all the
+   files of the Work near the copyright notice of each file or by
+   using a line such as:
+
+    % This work consists of all files listed in manifest.txt.
+   
+   in that place.  In the absence of an unequivocal list it might be
+   impossible for the licensee to determine what is considered by you
+   to comprise the Work and, in such a case, the licensee would be
+   entitled to make reasonable conjectures as to which files comprise
+   the Work.
+

Added: trunk/Master/texmf-dist/doc/generic/memoize/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/README.md	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,11 @@
+Memoize is a package for externalization of graphics and memoization of
+compilation results in general, allowing the author to reuse the results of
+compilation-intensive code.
+
+Memoize (i) induces very little overhead, as all externalized graphics is
+produced in a single compilation. It features (ii) automatic recompilation upon
+the change of code or user-adjustable context, and (iii) automatic
+externalization of TikZ pictures and Forest trees, easily extensible to other
+commands and environments. Furthermore, Memoize (iv) supports
+cross-referencing, TikZ overlays and Beamer, (v) works with all major engines
+and formats, and (vi) is adaptable to any workflow.


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/examples-src.zip
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/generic/memoize/examples-src.zip
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/examples-src.zip	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/generic/memoize/examples-src.zip	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/examples-src.zip
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/examples.zip
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/generic/memoize/examples.zip
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/examples.zip	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/generic/memoize/examples.zip	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/examples.zip
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize-clean.1.md
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize-clean.1.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize-clean.1.md	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,62 @@
+---
+title: memoize-clean
+section: 1
+header: User Manual
+footer: memoize-clean of Memoize v1.0.0
+date: October 10, 2023
+hyphenate: false
+---
+
+# NAME
+memoize-clean.pl, memoize-clean.py - Remove (stale) memo and extern files
+
+
+# SYNOPSIS
+**memoize-clean.pl** [*OPTIONS*] [*document1.mmz* ...]
+
+**memoize-clean.py** [*OPTIONS*] [*document1.mmz* ...]
+
+
+# DESCRIPTION
+
+**memoize-clean** is a script accompanying Memoize, a TeX package which allows
+the author to reuse the results of compilation-intensive code such as TikZ
+pictures.
+
+By default, this script removes stale memo and extern files.  A stale memo or
+extern is an extern produced during a compilation of a previous version of the
+document which was neither used nor produced during the last compilation of the
+document.  Typically, stale files arise when we change the memoized code (or
+its context).
+
+**memoize-clean.pl** removes all memo and extern files with prefixes mentioned
+in the listed **.mmz** files and by options **\--prefix** which are not
+explicitly mentioned in the **.mmz** files.
+
+Before deleting anything, **memoize-clean.pl** lists all the files it would
+delete and asks for confirmation.
+
+# OPTIONS
+
+**-p, \--prefix**
+: Add a memo/extern prefix for cleaning. This option may be given multiple
+    times.
+
+**-a, \--all**
+: Remove all memos and externs, rather than only the stale ones.
+
+**-y, \--yes**
+: Do not ask for confirmation.
+
+**-q, \--quiet**
+: Don't describe what's happening.
+
+**-h, \--help**
+: Show help.
+
+**-V, \--version**
+: Show the Memoize version number and exit.
+
+# SEE ALSO
+
+[Memoize manual](https://ctan.org/pkg/memoize), section 6.6.3.


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize-clean.1.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.sty
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.sty	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,276 @@
+%% memoize-code.sty
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%% 
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+
+\ProvidesPackage{memoize-code}
+\RequirePackage{memoize-doc-common}
+
+% Typesetting the code & indentation
+\MacroIndent=0pt
+\MacroTopsep = 0pt
+\MacrocodeTopsep = 7pt plus 2pt minus 2pt
+\AddToHook{env/macrocode/before}{\macrocodepar}%
+\let\macrocodepar\par
+
+% A mark for extraction into the manual. We need to remove some vertical space
+% when this environment occurs alone in a doc block.
+\newenvironment{listingregion}[1]{%
+  \ifvmode
+    \let\macrocodepar\relax
+    \AddToHookNext{env/macrocode/begin}{\MacrocodeTopsep=0pt\relax}%
+    \def\listingregionskip{\vspace{-\baselineskip}}%
+    \listingregionskip
+  \else
+    \def\listingregionskip{}%
+  \fi
+}{\listingregionskip}
+
+\setlist{nosep}
+
+% Paragraph headings in the left margin, same as macro environments.
+\RenewDocumentCommand\paragraph{s t. m}{%
+  \setbox0=\hbox{%
+    \mbox{%
+      \textcolor{blue}{%
+        #3%
+        \IfBooleanT{#1}{\mbox{\ ---}}%
+        \IfBooleanT{#2}{\hspace{0.7em}}%
+      }%
+    }%
+  }%
+  \noindent
+  \ifdim\wd0>\marginparwidth
+    \hangindent\dimexpr\wd0-\marginparwidth\relax
+    \hangafter-1\relax
+  \fi
+  \marginpar{\ifdim\wd0<\marginparwidth\hfill\fi\box0}%
+  \AddToHookNext{env/macrocode/before}{\par\nohang}%
+  \pgf at keys@utilifnextchar\par{\myparagraph at gobblepar}{\ignorespaces}%
+}
+\long\def\myparagraph at gobblepar#1{\ignorespaces}
+
+\def\macrocodeenvname{macrocode}
+\def\MacroFont{\fontencoding\encodingdefault
+  \fontfamily\ttdefault
+  \fontseries\mddefault
+  \fontshape\shapedefault
+  \small
+  \ifx\@currenvir\macrocodeenvname\else\color{blue}\fi
+}
+\let\AltMacroFont\MacroFont  % No special font for guarded code.
+
+% Typeset one-line guards to the left, 
+% indent multi-line guard begin/ends by the guard level,
+% and let guards be orange.
+% Move the codeline number left.
+\def\Module#1{%
+  \begingroup
+  \IfBeginWith{#1}{*}{%
+    \def\next{}%
+  }{%
+    \IfBeginWith{#1}{/}{%
+      \def\next{}%
+      \advance\guard at level-1
+    }
+    {%
+      \def\next##1{%
+        \guard at level0
+        \setbox0=\lastbox
+        \llap{\unhbox0 ##1}%
+      }%
+    }%
+  }%
+  \next{%
+    \loop
+    \ifnum\guard at level>0
+      \hskip 1em
+      \advance\guard at level-1
+    \repeat
+    \color{orange}\mod at math@codes$\langle\mathsf{#1}\rangle$\hspace{0.1em}%
+  }%
+  \endgroup
+}
+
+
+% doc elements
+\NewDocElement[idxgroup={\texttt{/mmz} keys}, idxtype={\texttt{/mmz}}]{Key}{key}
+\NewDocElement[idxgroup={\texttt{/collargs} keys}, idxtype={\texttt{/collargs}}]{CollargsKey}{collargskey}
+\NewDocElement[idxgroup={\texttt{/advice} keys}, idxtype={\texttt{/advice}}]{AdviceKey}{advicekey}
+\NewDocElement[idxgroup={\texttt{/mmz/auto} keys}, idxtype={\texttt{/mmz/auto}}]{MmzAutoKey}{mmzautokey}
+\NewDocElement[idxgroup={\texttt{/handlers} keys}, idxtype={\texttt{/handlers}}]{HandlersKey}{handlerskey}
+\NewDocElement[idxgroup={\texttt{/advice/install} keys}, idxtype={\texttt{/advice/install}}]{AdviceInstallkey}{adviceinstallkey}
+
+% Funny: without repeating this here, I can't use commas to separate several macros.
+\RenewDocElement[macrolike=true, idxtype=,idxgroup=,printtype=]{Macro}{macro}
+\NewDocElement[idxtype={Lua function}, idxgroup=Lua functions]{LuaFunction}{luafun}
+
+
+\newcommand\PrintMainMacro[1]{{\MacroFont\string#1}\SpecialMainMacroIndex{#1}}
+
+\newcommand\MyIndex[3]{%
+  \global\advance\c at CodelineNo 1
+  \csuse{special at index}{#1\actualchar#2\encapchar#3}%
+  \global\advance\c at CodelineNo -1
+  \ignorespaces
+}
+\NewDocumentCommand\exclamationmark{}{!}
+
+
+% hanging indent for "key" and "macro" environments
+\newcommand\hang[2]{%
+  \setbox0=\hbox{\MacroFont \string#2\relax}% "\relax" is short enough to never trigger a hanging indent
+  \ifdim\wd0>\dimexpr\marginparwidth\relax
+    \hangindent\dimexpr\wd0-\marginparwidth\relax
+    \hangafter-#1\relax
+    \AddToHookNext{env/macrocode/before}{\par\nohang}%
+    \AddToHookNext{para/after}{\aftergroup\nohang}%
+  \fi
+  \ignorespaces
+}
+\newcommand\nohang{\hangindent 0pt\relax}
+\newcommand\indentmacrocode{%
+  \settowidth\MacroIndent{\theCodelineNo\ }%
+  \addtolength\MacroIndent{\hangindent}%
+}
+\newcommand\noindentmacrocode{%
+  \setlength\MacroIndent{0em}%
+  \AddToHookNext{env/macrocode/begin}{\MacrocodeTopsep 0pt\relax}%
+}
+
+% and now ... autohang!
+% (the macros should be listed without spaces after commas)
+\usepackage{advice}
+\pgfkeys{
+  /my/.cd,
+  .install advice,
+  advice/hang/.style={outer handler=\autohang},
+  advice=\key{hang},
+  advice=\macro{hang},
+  advice=\autokey{hang},
+  advice=\mmzautokey{hang},
+  advice=\collargskey{hang},
+  advice=\handlerskey{hang},
+  advice=\adviceinstallkey{hang},
+  advice=\luafun{hang},
+}
+\def\hangn{0}
+\def\hanglength{0}
+\def\hangstring{}
+\newcommand\autohang[2][]{%
+  \ifstrequal{#1}{noprint}{}{%
+    \def\temp{#2}%
+    \@for\hangtemp:=\temp\do{\computehang}%
+    \edef\temp{\noexpand\hang{\hangn}{\expandonce\hangstring}}\temp
+  }%
+  \AdviceOriginal[#1]{#2}%
+}
+\def\computehang{%
+  \StrLen{\expandafter\string\hangtemp}[\temp]%
+  \edef\hangn{\the\numexpr\hangn+1}
+  \ifnum\temp>\hanglength\relax
+    \let\hanglength\temp
+    \let\hangstring\hangtemp
+  \fi
+}
+
+
+
+%%% Various:
+\newcommand\MS{\textsuperscript{M}\S} % manual section
+
+% Read in the manual .aux, for \MS cross-references.
+\begingroup
+\let\orig at newlabel\newlabel
+\def\newlabel#1#2{%
+  \IfBeginWith{#1}{sec:}{\orig at newlabel{#1}{#2}}{}%
+}
+\def\doline{%
+  \expandafter\futurelet\expandafter\firsttoken\expandafter\dolinei\line\fi}
+\def\dolinei{\ifx\firsttoken\newlabel}%
+\openin0=memoize.aux
+\loop
+  \unless\ifeof0
+  \read0 to \line
+  \doline
+\repeat
+\closein0
+\endgroup
+
+
+
+%%%% Filter the index, keeping only the entries with a corresponding "main"
+%%%% entry.
+
+\AddToHook{enddocument/end}{%
+  \immediate\closeout\@indexfile  % it is never explicitly closed!
+  \filterindex
+}
+
+\newwrite\tempidx
+\def\filterindex{%
+  \IfFileExists{\jobname.idx}{%
+    \begingroup
+    \catcode`\%=12
+    \def\indexentry{\filterindex at parse\filterindex at first@pass}%
+    \immediate\openout\tempidx \jobname.idx.orig
+    \input \jobname.idx
+    \immediate\closeout\tempidx
+    \def\indexentry{\filterindex at parse\filterindex at second@pass}%
+    \immediate\openout\tempidx \jobname.idx
+    % \tracingall
+    \input \jobname.idx.orig
+    \immediate\closeout\tempidx
+    \endgroup
+  }{}%
+}
+
+\def\filterindex at parse{%
+  \catcode`\\=12
+  \filterindex at parse@i
+}
+\long\def\filterindex at parse@i#1#2#3{\filterindex at parse@ii#1#2{#3}}
+\long\def\filterindex at parse@ii#1#2=#3hdclindex#4#5#6{%
+  \catcode`\\=0
+  #1{#2}{#3}{#4}{#5}{#6}%
+}
+
+\long\def\filterindex at first@pass#1#2#3#4#5{%
+  \filterindex at write{#1}{#2}{#3}{#4}{#5}%
+  \IfStrEq{#4}{main}{%
+    \csdef{\detokenize{filt@#1}}{}%
+  }{}%
+}
+\long\def\filterindex at second@pass#1#2#3#4#5{%
+  \ifcsdef{\detokenize{filt@#1}}{%
+    \filterindex at write{#1}{#2}{#3}{#4}{#5}%
+  }{%
+  }%
+}
+\long\def\filterindex at write#1#2#3#4#5{%
+  \immediate\write\tempidx{\string\indexentry\detokenize{{#1=#2hdclindex{#3}{#4}}{#5}}}%
+}
+
+
+
+% Local Variables:
+% TeX-engine: luatex
+% TeX-master: "memoize-code.tex"
+% TeX-auto-save: nil
+% End:
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,120 @@
+\documentclass[a4paper,11pt]{ltxdoc}
+
+\usepackage[left=1cm,right=1cm,top=1cm,bottom=1cm,
+  marginparwidth=0cm,marginparsep=0pt,
+  nohead,includefoot
+]{geometry}
+\settowidth\marginparsep{\ }
+
+% There is a \mmzset in memoize-doc-common.
+\usepackage{nomemoize}
+
+% Hypdoc (which loads hyperref) must be loaded before memoize-code.
+\usepackage{hypdoc}
+\hypersetup{colorlinks=true, allcolors=blue}
+
+\usepackage{memoize-code} % Also loads memoize-doc-common
+
+\pdfsystem{makeindex -s gind.ist \jobname.idx}
+
+\CodelineIndex
+\EnableCrossrefs
+
+\title{The documented source of Memoize, Advice and CollArgs}
+\author{Sašo Živanović\\[2mm]
+  \emailsymbol~\url(mailto:){saso.zivanovic at guest.arnes.si}\\
+  \homepagesymbol~\url(http://){spj.ff.uni-lj.si/zivanovic}\\
+  \faGithub~\url(https://){github.com/sasozivanovic}}
+
+\datefrompackageversion{collargs}
+\edef\allpackagever{CollArgs v\packagever}
+\datefrompackageversion{advice}
+\epreto\allpackagever{Advice v\packagever, }
+\datefrompackageversion{memoize}
+\epreto\allpackagever{Memoize v\packagever, }
+\let\packagever\allpackagever
+
+\hypersetup{
+  % pdftitle={Memoize},
+  pdfauthor={Sašo Živanović},
+  pdfsubject={externalization},
+  pdfkeywords={LaTeX, externalization, memoization}
+}
+
+\begin{document}
+
+\maketitle
+
+\def\docdir{..}
+\DocInput{\docdir/memoize.dtx}
+
+\section{Auxiliary packages}
+\label{sec:code:utils}
+
+\subsection{Extending commands and environments with Advice}
+\label{sec:code:auto}
+
+\DocInput{\docdir/advice.dtx}
+
+\subsection{Argument collection with CollArgs}
+\label{sec:code:collargs}
+
+\DocInput{\docdir/collargs.dtx}
+
+\clearpage
+\restoregeometry
+
+\section{The scripts}
+\label{sec:code:scripts}
+
+\def\continuation{\llap{\textcolor{purple}{$\rightarrow$}\,}}
+
+\subsection{The Perl extraction script \texttt{memoize-extract.pl}}
+
+\lstinputlisting[firstline=20, % manual (exclude the license information)
+  language=Perl,
+  breaklines, breakindent=4em, postbreak=\continuation,
+  commentstyle=,
+]{../memoize-extract.pl}
+
+\subsection{The Python extraction script \texttt{memoize-extract.py}}
+
+\lstinputlisting[firstline=20, % manual (exclude the license information)
+  language=Python,
+  breaklines, breakindent=4em, postbreak=\continuation,
+  commentstyle=,
+]{../memoize-extract.py}
+
+\subsection{The Perl clean-up script \texttt{memoize-clean.pl}}
+
+\lstinputlisting[firstline=20, % manual (exclude the license information)
+  language=Perl,
+  breaklines, breakindent=4em, postbreak=\continuation,
+  commentstyle=,
+]{../memoize-clean.pl}
+
+\subsection{The Python clean-up script \texttt{memoize-clean.py}}
+
+\lstinputlisting[firstline=20, % manual (exclude the license information)
+  language=Python,
+  breaklines, breakindent=4em, postbreak=\continuation,
+  commentstyle=,
+]{../memoize-clean.py}
+
+\clearpage
+
+\IndexPrologue{\section*{Index}Numbers written in red refer to the code line
+  where the corresponding entry is defined; numbers in blue refer to the code
+  lines where the entry is used.}
+
+\setcounter{IndexColumns}{2}
+\def\main#1{\begingroup\hypercolor{link}{red}#1\endgroup}
+\PrintIndex
+
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-engine: luatex
+%%% TeX-master: t
+%%% End:


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize-code.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc-common.sty
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc-common.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc-common.sty	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,173 @@
+%% memoize-doc-common.sty
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%% 
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+
+\ProvidesPackage{memoize-doc-common}
+
+\usepackage[inline,shortlabels]{enumitem}
+\usepackage{tcolorbox}
+\tcbuselibrary{listings,hooks,raster,skins}
+\usepackage{tikz}
+\usepackage{xstring}
+\usepackage{microtype}
+
+\usepackage{listings}
+\lstset{
+  language=[LaTeX]TeX,
+  columns=fullflexible,
+  basicstyle=\ttfamily\small,
+  commentstyle=\color{purple},
+  moredelim={[is][\pstyle]{~}{~}}
+}
+\lstMakeShortInline[moredelim={[is][\pstyle]{~}{~}}]{ˇ}%
+\tcbset{
+  linerange/.style={listing options app={linerange=#1}},
+}
+
+
+%%%%%%%%%%%%%%
+% title page %
+
+\usepackage{pdftexcmds}
+\let\pdfsystem\pdf at system
+
+% version and date
+\def\datefrompackageversion#1{%
+  \setbox0=\hbox{%
+    \def\ProvidesPackage##1[##2]{%
+      \gdef\@packagever{##2}%
+      \endinput
+    }%
+    \input{#1.sty}%
+  }%
+  \expandafter\parsepackagever@\@packagever\parsepackagever@
+}
+\def\parsepackagever@#1/#2/#3 v#4 #5\parsepackagever@{%
+  \year=#1\relax\month=#2\relax\day=#3\relax
+  \def\packagever{#4}\def\packagedesc{#5}%
+}
+
+\renewcommand\maketitle{%
+  \begingroup
+  \mmzset{disable, auto={tcolorbox}{clear options}}% \mmznext does not work here -- todo: maybe it does now
+  \begin{tcolorbox}[
+      colback=emphcolor,
+      fonttitle=\LARGE\bf,
+      halign title=center,
+      halign upper=center,
+      halign lower=center,
+      tikznode lower,
+      adjusted title=\@title,
+    ]
+    \packagever\\
+    \@date
+    \tcblower
+    \Large\@author
+  \end{tcolorbox}
+  \endgroup
+}
+\colorlet{emphcolor}{yellow!90!black}
+\usepackage{marvosym}
+\let\emailsymbol\Letter
+\let\homepagesymbol\ComputerMouse
+\usepackage{fontawesome} % for \faGithub
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%
+% \verb at eol@error hack %
+
+% The problem: doc.sty (re)defines \verb "to check for newlines in its argument
+% since a missing delimiter is difficult to detect in doc source."  In
+% principle, that's great, but I really hate it that I can't use Emacs's
+% "fill-paragraph" without fear of getting the "Text for \noexpand\verb command
+% ended by end of line" error.
+% 
+% Solution: the original \verb at eol@error defines a newline (which is active at
+%   that point) to throw an error.  We redefine \verb at eol@error to define a
+% newline to gobble an immediately following percent character (assuming that
+%   we are processing .dtx documentation) and spaces.
+
+\begingroup
+  \obeylines%
+  \gdef\verb at eol@error{\obeylines%
+    \def^^M{\futurelet\verb at eol@nextchar\verb at eol@peek}%
+  }%
+\endgroup
+\gdef\verb at eol@peek{%
+  \if\@percentchar\verb at eol@nextchar
+    \expandafter\verb at eol@ignorepercentchar
+  \else
+    \space % we need one space, though!
+    \expandafter\verb at eol@ignorespaces
+  \fi
+}
+\def\verb at eol@ignorepercentchar#1{% #1 = "%"
+  \@xobeysp\verb at eol@ignorespaces}
+\begingroup\catcode`\ =13 \gdef\verb at eol@otherspace{ }\endgroup
+% |\ignorespaces| wouldn't work here, as our spaces are of category 13
+\def\verb at eol@ignorespaces{%
+  \futurelet\verb at eol@nextchar\verb at eol@ignorespaces at peek}
+\def\verb at eol@ignorespaces at peek{%
+  \expandafter\ifx\verb at eol@otherspace\verb at eol@nextchar
+    \expandafter\verb at eol@ignorespaces at space
+  \fi
+}
+\def\verb at eol@ignorespaces at space#1{\verb at eol@ignorespaces}
+
+% The same hack, but for \lstinline of package listings.
+% https://tex.stackexchange.com/a/473459/16819
+
+\def\lst at InlineM#1{\gdef\lst at inlinechars{%
+    \lst at Def{`#1}{\lst at DeInit\egroup\global\let\lst at inlinechars\@empty}%
+    \lst at Def{13}{\lst at ProcessSpace}}% <---
+    \lst at inlinechars}
+
+
+%%%%%%%%%%%
+% various %
+
+\usepackage{hologo}
+\def\TikZ;{{\rm Ti\emph{k}Z}}
+\def\PGF;{PGF}
+\newcommand\PGFmanual[1]{%
+  \href
+    {http://mirrors.ctan.org/graphics/pgf/base/doc/pgfmanual.pdf}
+    {\S#1 of the Ti\emph{k}Z \& \textsc{PGF} manual}%
+}
+\newcommand\Alt{\,$\vert$\,}
+\newcommand\hyp{\discretionary{}{}{}}
+\newcommand\fncomma{\ensuremath{{^,}}}
+
+
+% load hyperref before this
+
+\protected\def\hypercolor#1#2{% #1 = url/link/.., #2 = color
+  \expanded{%
+    \noexpand\HyColor at HyperrefColor{#2}\expandonce{\csname @#1color\endcsname}%
+  }%
+}
+
+\RenewDocumentCommand\url{ O{} D(){} m }{%
+  {\hypercolor{url}{#1}\href{#2#3}{\texttt{#3}}}}
+
+\def\pkgcolor{black}
+\NewDocumentCommand\pkg{O{\pkgcolor}m}{{%
+    \hypercolor{url}{#1}%
+    \href{https://ctan.org/pkg/#2}{\texttt{#2}}}}


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc-common.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc.sty
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc.sty	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,711 @@
+%% memoize-doc.sty
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%% 
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+
+% \usepackage{lstdoc} % this must be loaded before hyperref
+\usepackage{shortvrb}
+\AtBeginDocument{\MakeShortVerb{\|}}
+% \usepackage{hypdoc}
+\usepackage[hyperindex=false]{hyperref}
+\hypersetup{
+  colorlinks=true,
+  allcolors=black,
+  linkcolor=Hyperlink,
+}
+
+\usepackage{microtype}
+%\SetExpansion[context=sloppy,stretch=30,shrink=50,step=1]{encoding=*}{}%
+
+\usepackage{fnpct}
+\usepackage{memoize-doc-common}
+
+% explicitly load advice (and thereby collargs) for when we load nomemoize
+\usepackage{advice}
+
+\usepackage{forest}
+\useforestlibrary{edges}
+
+% \usepackage[extract=latex]{memoize}
+% \usepackage{memoize}
+\usepackage[infoshow]{tracefnt}
+
+\tcbuselibrary{xparse,breakable}
+
+\mmzset{
+  auto={tcolorbox}{memoize, options=verbatim},
+  auto={tcboxedraster}{memoize, options=verbatim},
+  auto={tcbraster}{memoize, options={verbatim,ignore spaces}},
+  auto={tcblisting}{memoize, options={verbatim,ignore spaces}},
+  auto csname={tcbinputexample code}{memoize, args=mmm+m, ignore spaces},
+  auto=\tcbinputlisting{memoize, args=m, options=ignore spaces},
+  % The following doesn't work perfectly, but it's good enough.
+  auto key={/tcb/breakable}{run if memoizing, outer handler=\makeunmemoizableunless{false}},
+  auto key={/tcb/float}{run if memoizing, outer handler=\makeunmemoizableunless{}},
+}
+
+\def\makeunmemoizableunless#1#2\pgfeov{%
+  \ifstrequal{#1}{#2}{}{\mmzUnmemoizable}%
+  \AdviceOriginal#1\pgfeov
+}
+
+\newcommand\introboxtitle[1]{\strut\textcolor{emphcolor}{\textbf{#1}}}
+
+\usepackage{fancyhdr}
+\usepackage[skip=0.3\baselineskip plus 2pt]{parskip}
+\usepackage[bottom]{footmisc}
+\usepackage{xparse}
+\usepackage{multicol}
+
+
+
+
+\usepackage{graphicx}
+
+\usepackage{cprotect}
+\setlist[description]{
+  itemsep=0.3\baselineskip plus 2pt minus 1pt,
+  parsep=0.3\baselineskip plus 2pt
+}
+\SetEnumitemKey{comma}{itemjoin={{, }}}
+\SetEnumitemKey{and}{itemjoin={{, }}, itemjoin*={{, and }}}
+
+% \usepackage{lstdoc} % this must be loaded before hyperref
+%\usepackage{lstautogobble} % todo: does not work!
+\def\listings at file@value at in@reset{}
+\tcbset{
+  listing file/.append code={%
+    \ifmemoizing
+      \ifstrequal{#1}{\jobname.listing}{%
+        % We're in tcolorbox's reset, do nothing
+      }{%
+        \mmzset{
+          context={%
+            listing file={#1},
+            md5sum=\csuse{pdf at filemdfivesum}{#1},
+          },
+        }%
+      }%
+    \fi
+  },
+  centering/.style={before=\centering},
+}
+\colorlet{pointcolor}{green!50!black}
+\def\pstyle{\color{pointcolor}}% todo: hyperlink?
+\setlength\textfloatsep{0.5\baselineskip plus 2pt minus 2pt}
+\tcbset{
+  top=1mm, bottom=1mm,
+  beforeafter skip balanced=0.5\baselineskip plus 2pt minus 2pt,
+  raster every box/.style={top=1mm, bottom=1mm},
+  before upper={\parskip0.3\baselineskip plus 2pt\relax},
+  every box on layer 1/.style={
+    fonttitle=\bfseries,
+  },
+  my listing options/.style={
+    listing options app={
+      moredelim={[is][\pstyle]{~}{~}},
+      commentstyle=\color{purple},
+      morekeywords={unexpanded,expanded,expandonce,NewDocumentCommand,IfValueTF},
+      breakindent=10pt,
+    },
+  },
+  my listing options,
+  % for listings inside a tcboxedraster ...
+  reset/.append style=my listing options,
+  % titles
+  attach shifted boxed title to top right/.style={
+    attach boxed title to top right={
+      xshift=1.5mm, yshift=-\tcboxedtitleheight/2, #1},
+  },
+  attach shifted boxed title to top right/.default={},
+  attach shifted boxed title to top left/.style={
+    attach boxed title to top left={
+      xshift=-1.5mm, yshift=-\tcboxedtitleheight/2, #1},
+  },
+  attach shifted boxed title to top left/.default={},
+  my boxed title/.style={
+    enhanced, title={#1},
+    fonttitle=\scriptsize,
+    boxed title style={size=small},
+  },
+  my boxed title/.value required,
+  extern page/.style={
+    my boxed title=extern page,
+    boxed title style={colback=blue!70!black, colframe=blue!25!white},
+    attach shifted boxed title to top right,
+  },
+  document page/.style={
+    my boxed title=document page,
+    boxed title style={colback=green!60!black, colframe=green!25!white},
+    attach shifted boxed title to top right,
+  },
+  % end titles
+  bad/.style={enhanced,
+    finish={
+      \begin{tcbclipinterior}
+        \draw[red!40!white, opacity=0.4, line width=1cm]
+        (interior.south west)--(interior.north east);
+      \end{tcbclipinterior}
+    },
+  },  
+  mark region/.style 2 args={
+    enhanced,
+    underlay={
+      \fill[pointcolor,opacity=0.1]
+      ([yshift=-\kvtcb at boxsep-\kvtcb at top-2.5ex*(#1-1)]interior.north west) rectangle ([yshift=-\kvtcb at boxsep-\kvtcb at top-2.5ex*#2]interior.north east);
+    },
+  },
+  warning/.style={colback=red!15},
+  to be continued on right/.style={
+    frame code={% line thickness is uniform and depends on tcolorbox's leftrule
+      \draw[color=tcbcolframe,
+        line width=2*\kvtcb at left@rule, rounded corners=2*\kvtcb at left@rule,
+      ]
+      (interior.north east)--(interior.north west)
+      --(interior.south west)--(interior.south east);
+    },
+    interior code app={
+      \draw[color=tcbcolframe,line width=\kvtcb at left@rule,dashed]
+        ([xshift=-0.5*\kvtcb at left@rule]interior.south east)
+        --([xshift=-0.5*\kvtcb at left@rule]interior.north east);
+    },
+  },
+}
+\def\examplepdfpath{\examplepath.c1.pdf}
+\NewDocumentCommand{\includeexamplepdf}{ O{} O{\examplepdfpath} D(){} m}{%
+  \mbox{%
+    \tcbincludegraphics[reset,capture=hbox,graphics options={clip,#4},#1]{#2}#3%
+  }%
+}%
+\def\ExampleName#1{\edef\examplename{#1}\ignorespaces}
+\def\makeexample#1{\pdfsystem{make -C \exampledir\space#1}\ignorespaces}
+% \def\makeexample#1{\pdfsystem{make -B -C \exampledir\space#1}}
+\def\examplepath{\exampledir\examplename}
+\RequirePackage{intopdf}
+\RequirePackage{fontawesome}
+\tcbset{
+  example title/.style={
+    enhanced,
+    % uniform height and (zero) depth
+    before title={\begingroup \setbox0\hbox\bgroup},
+    after title={\egroup\ht0 1.2ex \dp0 0pt \box0 \endgroup},
+    title={\texttt{#1}},
+    top=2mm,
+    attach shifted boxed title to top left,
+    fonttitle={\small\hypercolor{link}{white}},
+  },
+  example title/.default=\examplename.tex,
+  attachment/.estore in=\attachmentpath,
+  attachment name/.estore in=\attachmentname,
+  attachment name/.default=noname.tex,
+  no attachment/.style={attach/.style={}},
+  attachment=\jobname.listing.attachment,
+  attachment name,
+  % attach example/.style={
+  %   attachment/.expanded=\examplepath.tex.work,
+  %   attachment name/.expanded=\examplename.tex,
+  %   attach,
+  % },
+  attach/.style={
+    overlay app={%
+      \node at (frame.north east) [
+        fill=white, draw=gray, thick,
+        ellipse, inner xsep=-0.5mm, inner ysep=0, shift={(-2mm,-2mm)}, rotate=45,
+      ]{%
+        \pdfsystem{make -f examples/Makefile \attachmentpath}%
+        \expandafter\myattachandlink\expandafter[\attachmentname]{\attachmentpath}[application/x-tex]{Click here to open the code.}{\rotatebox{-45}{\faPaperclip}}
+      };
+    }
+  },
+  excerpt/.code 2 args={%
+    \makeexample{#2.excerpt SOURCE=#1}%
+  },
+}
+\NewDocumentCommand\attachexample{O{\examplename.tex} O{\examplepath.tex.c1.attachment}}{%
+  {\textsuperscript{\kern-0.25em \expandafter\myattachandlink\expandafter[#1]{#2}[application/x-tex]{Click here to open the code.}{\rotatebox{-45}{\faPaperclip}}\kern-0.25em \relax}}}
+\newcommand\myattachandlink[2][\filename]{%
+  \begingroup
+  \def\filename{#2}%
+  \immediate\write\attachments{#2 #1 ## line \the\inputlineno}%
+  \ifmemoizing
+    \xtoksapp\mmzCCMemo{%
+      \immediate\write\attachments{#2 #1 ## line \the\inputlineno}%
+    }%
+  \fi
+  \expanded{%
+    \endgroup
+    \noexpand\attachandlink[#1]{#2}%
+  }%
+}
+\newwrite\attachments
+\immediate\openout\attachments attachments.lst
+\AtEndDocument{\immediate\closeout\attachments}
+
+\NewTCBInputListing{\tcbinputexample}{
+  >{\edef\ProcessedArgument} D(){\examplename}  O{.tex} O{.c1} +m }
+{%
+  /mmz/context={dtxmd5sum=\csuse{pdf at filemdfivesum}{\exampledir#1#2.dtx}},
+  example title={#1#2},
+  % enlarge left by=\leftmargin,% this takes care of using this box in lists
+  listing and comment,
+  one file/.style={
+    listing file={\exampledir#1#2#3},
+    attachment={\exampledir#1#2#3},
+  },
+  listing file=\exampledir#1#2#3.listing,
+  /utils/exec={\edef\examplepdfpath{\exampledir#1#3.pdf}},%
+  attachment=\exampledir#1#2#3.attachment,
+  attachment name=#1#2,%
+  #4,
+  attach,
+}
+\nommzkeys{context}
+
+\tcbset{
+  full width/.style={grow to left by=\leftmargin},
+  listing and compile/.style={
+    listing and comment,
+    comment={%
+      \input\examplepath.tex.c#1
+    }
+  },
+  listing and compile/.default=1,
+}
+
+\pgfkeys{
+  /handlers/.detokenize/.style={\pgfkeyscurrentpath/.expand once=\detokenize{#1}},
+  /utils/typeout/.code={\typeout{#1}},
+}
+\let\pdfsystem\pdf at system
+\let\pdffilemdfivesum\pdf at filemdfivesum
+
+\usepackage{booktabs}
+\usepackage{tabularx}
+
+
+\usetikzlibrary{decorations.pathmorphing, arrows.meta}
+\usepackage{tikzlings-penguins,tikzlings-koalas,tikzlings-owls}
+\tikzset{
+  ->/.tip={Kite},
+  snake arrow/.style=
+  {->, decorate,
+    decoration={snake, amplitude=.4mm, segment length=2mm, post length=2mm},
+  },
+}
+
+% title page
+\renewcommand\abstractname{\vskip-\baselineskip}
+
+% sections
+\newtcbox{\section at box}[3]{tile,before=\noindent,after=,
+  fontupper=\normalfont#1\bfseries,capture=minipage,
+  colback=emphcolor,
+  boxsep=0mm,top=#2,bottom=#2,left=\oddsidemargin+1in,right=\oddsidemargin+1in,
+  spread sidewards,#3
+}
+
+\newif\ifsectionclearpage
+\sectionclearpagetrue
+\newif\ifsubsectionclearpage
+\subsectionclearpagetrue
+
+\renewcommand\section{%
+  \ifsectionclearpage\clearpage\fi
+  \@startsection{section}{1}{\z@}%
+  {5mm}{5mm}%
+  {\section at box{\Large}{4mm}{fuzzy halo=1mm with blue!50!gray}}}
+\renewcommand\subsection{%
+  \ifsubsectionclearpage\ifnum\c at subsection=0 \else\clearpage\fi\fi
+  \@startsection{subsection}{2}{\z@}%
+  {-3.25ex\@plus -1ex \@minus -.2ex}{1.5ex \@plus .2ex}%
+  {\section at box{\large}{2mm}{fuzzy halo=1mm with blue!50!gray}}}
+\renewcommand\subsubsection{%
+  \mmznext{disable}%
+  \@startsection{subsubsection}{2}{\z@}%
+  {-3.25ex\@plus -1ex \@minus -.2ex}{1.5ex \@plus .2ex}%
+  {\section at box{}{2mm}{}}}
+\newtcbox{\paragraph at box}{tile,before=,after=,capture=hbox,
+  fontupper=\normalfont\normalsize\bfseries\hypercolor{link}{black}\vphantom{dj},
+  box align=base,
+  boxsep=0mm,
+  left=\oddsidemargin+1in, enlarge left by=-\oddsidemargin-1in,
+  top=1.2mm, enlarge top by=-1.2mm,
+  bottom=1mm, enlarge bottom by=-1mm,
+  right=12mm, enlarge right by=-8mm, arc=0mm, rightrule=0mm,
+  interior style={left color=emphcolor, right color=white},
+}
+\let\oldparagraph\paragraph
+\def\paragraphskip{3.25ex \@plus1ex \@minus.2ex}
+\RenewDocumentCommand\paragraph{sm}{%
+  \mmznext{disable}%
+  \@startsection{paragraph}{4}{\z@}{\paragraphskip}{-1em}{\paragraph at box}{#2}%
+  \IfBooleanT{#1}{\hspace*{\dimexpr-8mm+0.5em}}%
+  \hskip 0pt plus .5em
+  \IfBooleanF{#1}{\nopagebreak}% % todo: this is bad, if the paragraph is long
+}
+
+\NewTotalTCBox{\Emph}{m}{my code box, fontupper=\rm}{#1}
+\NewTotalTCBox{\EmphTT}{m}{my code box}{#1}
+\NewTotalTCBox{\EmphVerbatim}{v}{my code box}{#1}
+\tikzset{
+  emphshade/.style={
+    opacity=0.6,
+    top color=#1, bottom color=#1, middle color=emphcolor,
+  },
+  emphshade/.default=white,
+}
+\tcbset{
+  my code box/.style={
+    reset, enhanced, verbatim,
+    boxsep=0pt, left=0.3ex,right=0.3ex, box align=base,
+    interior hidden, frame hidden,
+    overlay={\shade[emphshade]
+      ([yshift=0.7ex]frame.north west) rectangle ([yshift=-0.7ex]frame.south east);
+    },
+  },
+}
+
+% verbatim code in the implementation
+\lstdefinestyle{code}{style=tcblatex,xleftmargin=\leftmargin,aboveskip=\parskip}
+
+
+
+
+
+
+\newcommand\therefore{\ensuremath{\Rightarrow}}
+\newcommand\nohyphen{\discretionary{}{}{}}
+\let\gobble\@gobble
+
+\lstset{
+  rangebeginprefix=\ \ \%\%\%\ begin\ listing\ region:\ ,
+  rangebeginsuffix=,
+  rangeendprefix=\ \ \%\%\%\ end\ listing\ region:\ ,
+  rangeendsuffix=,
+  includerangemarker=false,
+  keepspaces=true,
+}
+
+\def\relaxmmzcommands{%
+  \let\mmzPrefix\gobble
+  \let\mmzNewCMemo\gobble
+  \let\mmzNewCCMemo\gobble
+  \def\mmzNewExtern##1##2##3##4##5{}%
+  \let\mmzUsedCMemo\gobble
+  \let\mmzUsedCCMemo\gobble
+  \let\mmzUsedExtern\gobble
+}
+
+\usepackage{xstring}
+\usepackage{placeins}
+
+\NewDocumentCommand\makeexcerpt{ m O{.tex} D(){../../memoize.edtx} }{%
+  \ExampleName{#1}%
+  \makeexample{#1#2.excerpt SOURCE=#3}%
+  \ignorespaces
+}
+
+\newcommand\sed[2]{%
+  \begingroup
+  \def\cmd##1{\noexpand\\##1}%
+  \def\0{\bslash0}%
+  \def\1{\bslash1}%
+  \def\2{\bslash2}%
+  \def\3{\bslash3}%
+  \def\4{\bslash4}%
+  \def\5{\bslash5}%
+  \def\6{\bslash6}%
+  \def\7{\bslash7}%
+  \def\8{\bslash8}%
+  \def\9{\bslash9}%
+  \def~{\noexpand~}%
+  \def\n{\string\n}%
+  \def\({\bslash(}%
+  \def\){\bslash)}%
+  \let\lbrace\sedlbrace
+  \let\rbrace\sedrbrace
+  \edef\nobrace{[^\sedlbrace\sedrbrace]}
+  \edef\marg{{[^\sedrbrace]*}}%
+  \def\repeat##1{\bslash\sedlbrace##1\bslash\sedrbrace}%
+  \pdfsystem{sed -i "#1" #2}%
+  \endgroup
+}
+\begingroup
+\catcode`\(=1
+\catcode`\)=2
+\catcode`\{=12
+\catcode`\}=12
+\gdef\sedlbrace({)%
+\gdef\sedrbrace(})%
+\endgroup
+
+\usepackage{pifont}
+\newcommand\yes{{\small\ding{51}}} % pifont
+\newcommand\no{{\small\ding{55}}} % pifont
+
+%\newcommand\oarg[1]{{\ttfamily[}\meta{#1}{\ttfamily]}}
+
+\definecolor{Option}{rgb}{0.118,0.546,0.222}
+\definecolor{Definition}{rgb}{0.784,0.06,0.176}
+\definecolor{ExampleFrame}{rgb}{0.628,0.705,0.942}
+\definecolor{ExampleBack}{rgb}{0.963,0.971,0.994}
+\definecolor{Hyperlink}{rgb}{0.281,0.275,0.485}
+\definecolor{Fade}{rgb}{0.5,0.5,0.5}
+\definecolor{EasyDefinition}{rgb}{0.06,0.784,0.176}
+
+{\catcode`\|=\z@ \catcode`\\=12
+|gdef|bslash{\}}
+\DeclareRobustCommand\cs[1]{\texttt{\bslash\detokenize{#1}}}%
+\DeclareRobustCommand\env[1]{\texttt{#1}}%
+%\def\marg#1{{\ttfamily\char`\{}\meta{#1}{\ttfamily\char`\}}}
+\def\marg#1{\hskip 0pt plus 1pt{\ttfamily\char`\{}\meta{#1}{\ttfamily\char`\}}}
+\def\oarg#1{\hskip 0pt plus 1pt{\ttfamily[}\meta{#1}{\ttfamily]}}
+\def\bracestt#1{\hskip 0pt plus 1pt{\ttfamily\char`\{#1\char`\}}}
+\def\braces#1{\hskip 0pt plus 1pt{\ttfamily\char`\{}#1{\ttfamily\char`\}}}
+\def\bracketstt#1{\hskip 0pt plus 1pt{\ttfamily[#1]}}
+\def\brackets#1{\hskip 0pt plus 1pt{\ttfamily[}#1{\ttfamily]}}
+\DeclareRobustCommand\meta[1]{%
+  \ensuremath\langle
+  \ifmmode \expandafter \nfss at text \fi
+  {%
+    \meta at font@select
+    \edef\meta at hyphen@restore{\hyphenchar\the\font\the\hyphenchar\font}%
+    \hyphenchar\font\m at ne
+    \language\l at nohyphenation
+    #1\/%
+    \meta at hyphen@restore
+  }%
+  \ensuremath\rangle
+}
+\def\meta at font@select{\rm\itshape}
+\DeclareRobustCommand\metabf[1]{%
+  \begingroup
+  \def\meta at font@select{\rm\itshape\bfseries}%
+  \meta{#1}%
+  \endgroup
+}
+{\catcode`\%=12 \gdef\percentchar{%}}
+\def\coloredpercentchar{\hbox{\textcolor{purple}{\percentchar}}}
+\newcommand\alt{\ensuremath{\vert}}% without space around, unlike \Alt
+\newcommand\code[1]{\texttt{\spaceskip 0.5em plus 0.2em minus 0.2em #1}}
+\newcommand\Arg[1]{\texttt{\##1}}
+
+\def\TikZ{\href{https://ctan.org/pkg/pgf}{{\rm Ti\emph{k}Z}}\xspace}
+\def\PGF{\href{https://ctan.org/pkg/pgf}{PGF}\xspace}
+\def\Emacs{\href{https://www.gnu.org/software/emacs}{Emacs}\xspace}
+\def\AucTeX{\href{https://www.gnu.org/software/auctex}{AUC\hologo{TeX}}\xspace}
+
+% collargs reference, pi = programmer's interface
+% Shrink the glyphs in the footnote if necessary.
+\tcbset{
+  pi/.style={
+    overlay={%
+      \node at (frame.north east) [anchor=north west, inner sep=0] {\footnotemark};
+    },
+    after app={%
+      \footnotetext{%
+        % \adjustspacing=2 % already 2 ... microtype?
+        \myfontexpansionon
+        \yadocset{before/.code={\cspreto{yadoc at name@prefix}{\myfontexpansionon}}}%
+        \mbox{The programmer's interface:} #1.%
+      }%
+    },
+  },
+}
+\DeclareRobustCommand\myfontexpansionon{%
+  \directlua{font.setexpansion(font.current(),50,50,1)}%
+}
+\DeclareRobustCommand\myfontexpansionoff{%
+  \directlua{font.setexpansion(font.current(),0,0,1)}%
+}
+
+\AtBeginDocument{%
+  \setbox0=\hbox{%
+    \footnotesize\ttfamily
+    \directlua{ninettfont=font.current()}%
+  }%
+}
+
+% \AtBeginDocument{%
+%   \setbox0=\hbox{%
+%     \footnotesize\ttfamily
+%     \global\expandafter\let\expandafter\fnttfont\font at name
+%     %\expandglyphsinfont\fnttfont 30 500 1 autoexpand
+%   }%
+% }
+
+\usepackage{yadoc}
+\newif\ifyadoc at short
+\newif\ifyadoc at long
+\yadocset{
+  name color=Definition,
+  before body=\parskip 0.3\baselineskip plus 2pt,
+  % after body=\medskip,
+  head/.style={
+    interior style={fill, left color=red!5,right color=red!5!black!2}, 
+  },
+  easy/.style={
+    name color=green!50!black,
+    head/.style={
+      interior style={fill, left color=green!5,right color=black!5}, 
+    },
+  },
+  keypath color opacity=30,
+  index encapsulator={`},
+  index annotation font=\color{gray},
+  def options/.append style={index page number format=colorhyperpage{red}},
+  aux options/.append style={index page number format=colorhyperpage{red}},
+  ref options/.append style={index page number format=hyperpage},
+  par/.style={parameters={#1}},
+  desc/.style={description={#1}},
+  keypath=/mmz,
+  xparse modifier item/.style={
+    index annotation=\texttt{xparse} modifier,
+    label prefix=xparse,
+  },
+  xparse type item/.style={
+    index annotation=\texttt{xparse} type,
+    label prefix=xparse,
+  },
+  script item/.style={
+    index annotation=script,
+    label prefix=script,
+    parameters prefix=\space,
+  },
+  key path item/.style={
+    index annotation=keypath,
+    label prefix:=keypath:/,
+    name prefix=/,
+    description=keypath,
+  },
+  option item/.style={
+    name prefix={\ifdefempty\yadoc at short@name{}{-\yadoc at short@name\,\Alt\,}--},
+    ref prefix={\protect\ifyadoc at short-\yadoc at short@name\protect\else--},
+    ref suffix={\protect\fi},
+    index prefix={--},
+    index suffix={\ifdefempty\yadoc at short@name{}{\Alt-\yadoc at short@name}},
+    parameters prefix=\ ,
+    label prefix:={\yadoc at of--},
+    index annotation=option of {\docref[into index=false,link color=gray]{\yadoc at of}},
+  },
+  short name/.store in=\yadoc at short@name,
+  short/.is if=yadoc at short,
+  long/.is if=yadoc at long,
+  conditional/.style={
+    parameters={\texttt{true}\Alt\texttt{false}},
+    /utils/exec={%
+      \appto\yadoc at description{default \texttt{true}, initially \texttt{#1}}%
+    },
+  },
+  conditional/.value required,
+  package item/.style={
+    index annotation=package,
+    label prefix=pkg,
+    description=package,
+  },
+  pkg/.style={
+    after/.style={index annotation/.append={\space of package \pkg{#1}}}
+  },
+  hook item/.style={
+    label prefix=hook,
+    index annotation=hook,
+  },
+  pdfvariable item/.style={
+    label prefix=pdfvar,
+    index annotation={\hologo{LuaTeX}'s \refcmd{pdfvariable} register},
+  },
+  pdfcmd item/.style={
+    label prefix=cmd,
+    name prefix={%
+      \textbackslash
+      \protect\ifyadoc at short
+      \protect\else
+        \protect\ifyadoc at long
+          pdf%
+        \protect\else
+          % todo: revert to the real original font rather than just say \rmfamily
+          \rmfamily(\ttfamily pdf\rmfamily)\ttfamily
+        \protect\fi
+      \protect\fi
+    },
+    index prefix=\textbackslash,
+  },
+}
+\def\colorhyperpage#1#2{%
+  \begingroup
+  \hypercolor{link}{#1}%
+  \hyperpage{#2}%
+  \endgroup
+}
+
+\patchcmd{\@setref}{??}{#3??}{}{}
+\patchcmd{\real at setref}{??}{#3??}{}{}
+
+\mmzset{
+  auto={tcb at manual@entry}{nomemoize},
+  auto={doc}{nomemoize},
+}
+
+\DeclareRobustCommand\refkey[2][]{\docref[#1]{key:#2}}
+\DeclareRobustCommand\refmmz[2][]{\docref[#1]{key:/mmz/#2}}
+\DeclareRobustCommand\refmmzauto[2][]{\docref[#1]{key:/mmz/auto/#2}}
+\DeclareRobustCommand\refmmzpath[2][]{\docref[#1]{key:/mmz/path/#2}}
+\DeclareRobustCommand\refcollargs[2][]{\docref[#1]{key:/collargs/#2}}
+\DeclareRobustCommand\refenv[2][]{\docref[#1]{env:#2}}
+\DeclareRobustCommand\refcmd[2][]{\docref[#1]{cmd:#2}}
+\DeclareRobustCommand\reffile[2][]{\docref[#1]{file:#2}}
+\DeclareRobustCommand\refkeypath[2][]{\docref[#1]{keypath:#2}}
+\DeclareRobustCommand\refpkg[2][]{\docref[#1]{pkg:#2}}
+\DeclareRobustCommand\refscript[2][]{\docref[#1]{script:#2}}
+
+\usepackage{xspace}
+\newcommand\dmmz{\docref{file:mmz}\xspace}
+
+\newcommand\hreftt[2]{\href{#1}{\texttt{#2}}}
+
+\ifcsname ifregion\endcsname
+  \ifregion{%
+      \AddToHook{begindocument/before}{%
+        \makeatletter
+        \InputIfFileExists{memoize.aux}{}{}%
+        \makeatother
+      }%
+      \AddToHook{enddocument}{%
+        \printindex
+      }%
+    }
+\fi
+    
+\AddToHook{begindocument}{%
+  \robustify\hyperref
+  \robustify\hologo
+  \robustify\Alt
+}
+
+\newcommand\noprint[1]{\setbox0=\hbox{#1}}
+\usepackage{wrapfig}
+
+
+% \usepackage{caption}
+% \captionsetup{labelformat=empty}
+
+% Local Variables:
+% TeX-master: "memoize.tex"
+% TeX-engine: luatex
+% End:


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize-doc.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize-extract.1.md
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize-extract.1.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize-extract.1.md	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,94 @@
+---
+title: memoize-extract
+section: 1
+header: User Manual
+footer: memoize-extract of Memoize v1.0.0
+date: October 10, 2023
+hyphenate: false
+---
+
+# NAME
+memoize-extract.pl, memoize-extract.py - Extract extern pages out of the PDF
+
+
+# SYNOPSIS
+**memoize-extract.pl** [*OPTIONS*] *document.mmz*
+
+**memoize-extract.py** [*OPTIONS*] *document.mmz*
+
+
+# DESCRIPTION
+
+**memoize-extract** is a script accompanying Memoize, a TeX package which
+allows the author to reuse the results of compilation-intensive code such as
+TikZ pictures.
+
+Memoize dumps the created externs (boxes containing the typeset material to be
+reused) onto their own pages in the produced PDF file.  It is the job of
+**memoize-extract** to extract these extern pages into separate PDF files. At
+subsequent compilations, Memoize will include those extern files into the
+document, without compiling their source again.
+
+Memoize communicates with **memoize-extract** through file *document.mmz*. When
+*document.tex* is compiled to produce *document.pdf*, Memoize produces
+*document.mmz*, which records which pages in the produced document are extern
+pages and to which extern files they should be extracted. Therefore, after
+compiling *document.tex*, the externs should be extracted by
+**memoize-extract** *document.mmz*.
+
+*document.mmz* also records the expected width and height of each extern. In
+case of a mismatch, **memoize-extract** refuses to extract the page and removes
+the extern file if it already exist, and prints a warning message to the
+standard error.  The script furthermore refuses to extract the page if a
+(c)c-memo associated to the extern does not exist, and to write to any file
+whose absolute path does not occur under the current directory or the directory
+set by TEXMFOUTPUT (in *texmf.cnf* or as an environment variable); TEXMFOUTPUT
+is also not allowed to point to the root directory, except on Windows, where it
+can only point to a drive root.
+
+The Perl (.pl) and the Python (.py) version of the script are functionally
+equivalent.  The Perl script requires library
+[PDF::API2](https://metacpan.org/pod/PDF::API2), and the Python script requires
+library [pdfrw2](https://pypi.org/project/pdfrw2).
+
+# OPTIONS
+
+**-P, \--pdf** *filename.pdf*
+: The externs will be extracted from *filename.pdf*.  By default,
+  they are extracted from *document.pdf*.
+
+**-p, \--prune**
+: Remove the extern pages from the PDF after extraction.
+
+**-k, \--keep**
+: Do not modify the *document.mmz* to mark the externs as extracted.  By
+  default, they are commented out to prevent double extraction.
+
+**-f, \--force**
+: Extract the extern even if the size-check fails.
+
+**-l, \--log** *filename*
+: Log size mismatches to *filename* rather than to the standard error.
+
+**-w, \--warning-template** *string*
+: Wrap the size mismatch warning text into the given template: \\warningtext in
+  the template will be replaced by the warning text.
+
+**-q, \--quiet**
+: Don't describe what's happening.
+
+**-e, \--embedded**
+: Prefix all messages to the standard output with the script name.
+
+**-m, \--mkdir**
+: A paranoid *mkdir -p*. (No extraction occurs, *document.mmz* is interpreted as a directory name.)
+
+**-h, \--help**
+: Show help and exit.
+
+**-V, \--version**
+: Show the Memoize version number and exit.
+
+# SEE ALSO
+
+[Memoize manual](https://ctan.org/pkg/memoize), section 6.6.1.


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize-extract.1.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize.mst
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize.mst	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize.mst	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+encap '`'

Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/generic/memoize/memoize.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/memoize.tex
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/memoize.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/memoize.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,9094 @@
+\documentclass[a4paper,11pt]{article}
+\usepackage[margin=2cm,top=1cm,bottom=1cm,nohead,includefoot]{geometry}
+
+\usepackage{nomemoize}
+\usepackage{memoize-doc}
+\mmzset{
+  % recompile,
+  % readonly,
+  % disable,
+  % inverse search=false,
+  % include context in ccmemo,
+  % direct ccmemo input,
+  % trace,
+}
+\def\exampledir{examples/}
+
+\title{\pkg[white]{Memoize}}
+\author{Sašo Živanović\\[2mm]
+  \emailsymbol~\url(mailto:){saso.zivanovic at guest.arnes.si}\\
+  \homepagesymbol~\url(http://){spj.ff.uni-lj.si/zivanovic}\\
+  \faGithub~\url(https://){github.com/sasozivanovic}}
+\datefrompackageversion{memoize}
+\preto\packagever{v}
+
+\hypersetup{
+  pdftitle={Memoize},
+  pdfauthor={Sašo Živanović},
+  pdfsubject={externalization},
+  pdfkeywords={LaTeX, externalization, memoization}
+}
+
+\usepackage{makeidx}
+\pdfsystem{makeindex -s memoize.mst \jobname.idx}
+\makeindex
+\usepackage[hangindent=1em,justific=raggedright,font=small]{idxlayout}
+\appto\indexfont{\def\pkgcolor{gray}}
+
+\AddToHook{begindocument}{% so that the region compilation takes these in
+  \docForeign{
+    scope={
+      after/.style={index annotation/.prefix={\hologo{LaTeX}\space}},
+      cmd={name=begin}, cmd={name=end},
+      cmd={name=label}, cmd={name=@currentlabel},
+      cmd={name=ref}, cmd={name=pageref},
+      cmd={name=index},
+      cmd={name=NewDocumentCommand}, cmd={name=GetDocumentCommandArgSpec},
+      env={name=verbatim},
+      cmd={name=ReadonlyShipoutCounter},
+      hook={name=begindocument},
+      cmd={name=usepackage},
+    },
+    scope={
+      before/.style={index annotation=\hologo{TeX} primitive},
+      cmd={name=shipout},
+      cmd={name=hbox}, cmd={name=vbox},
+      cmd={name=ignorespaces}, cmd={name=unskip},
+      cmd={name=errmessage},
+      cmd={name=catcode},
+      cmd={name=mag},
+    },
+    scope={
+      before/.style={index annotation=\hologo{eTeX} primitive},
+      cmd={name=scantokens},
+      cmd={name=currentgrouplevel},
+    },
+    scope={
+      before/.style={index annotation=\hologo{pdfTeX} primitive},
+      cmd={name=quitvmode},
+    },
+    scope={
+      before/.style={index annotation=\hologo{LuaTeX} primitive},
+      pdfcmd={name=savepos},
+      cmd={name=pdfvariable},
+    },
+    pdfvariable={name=compresslevel},
+    pdfvariable={name=horigin},
+    pdfvariable={name=vorigin},
+    scope={
+      after/.style={index annotation/.prefix={\hologo{ConTeXt}\space}},
+      cmd={name=realpageno},
+    },
+    pdfcmd={name=primitive, index annotation=\hologo{LuaTeX}/\hologo{XeTeX} primitive},
+    register={name=pdfmajorversion},
+    register={name=pdfminorversion},
+    scope={
+      after/.style={index annotation/.prefix={\hologo{plainTeX}\space}},
+      cmd={name=llap}, cmd={name=rlap},
+    },
+    scope={
+      pkg=forest,
+      env={name=forest},
+      cmd={name=Forest},
+    },
+    scope={
+      pkg=tikz, keypath=/tikz,
+      cmd={name=tikz},
+      env={name=tikzpicture},
+      key={name=remember picture},
+      key={name=overlay},
+      cmd={name=tikzexternalize},
+      cmd={name=pgfsys at getposition},
+    },
+    file={name=texmf.cnf},
+    env={name=tcblisting, pkg=tcolorbox},
+    cmd={name=vref, pkg=varioref},
+    cmd={name=cref, pkg=cleveref},
+    cmd={name=crefrange, pkg=cleveref},
+    xparse type={name=l, index annotation/.append={\ (up to begin-group)}},
+    xparse type={name=u, index annotation/.append={\ (until tokens)}},
+    xparse type={name=r, index annotation/.append={\ (required delimited)}},
+    xparse type={name=R, index annotation/.append={\ (required delimited with default)}},
+    xparse type={name=d, index annotation/.append={\ (optional delimited)}},
+    xparse type={name=D, index annotation/.append={\ (optional delimited with default)}},
+    xparse type={name=o, index annotation/.append={\ (standard optional)}},
+    xparse type={name=O, index annotation/.append={\ (standard optional with default)}},
+    xparse type={name=t, index annotation/.append={\ (optional token)}},
+    xparse type={name=s, index annotation/.append={\ (optional star)}},
+    xparse type={name=m, index annotation/.append={\ (mandatory)}},
+    xparse type={name=g, index annotation/.append={\ (optional group)}},
+    xparse type={name=G, index annotation/.append={\ (optional group with default)}},
+    xparse type={name=v, index annotation/.append={\ (verbatim)}},
+    xparse type={name=e, index annotation/.append={\ (embellishments)}},
+    xparse type={name=E, index annotation/.append={\ (embellishments with defaults)}},
+    xparse modifier={name=+, index annotation/.append={\ (long)}},
+    xparse modifier={name=!, index annotation/.append={\ (don't ignore spaces)}},
+    xparse modifier={name=>, index annotation/.append={\ (argument processor)}},
+    generic={name=shell-escape, name prefix=-, label prefix:=-,
+      index annotation=option of \hologo{TeX} binaries},
+    generic={name=enable-write18, name prefix=--, label prefix:=--,
+      index annotation=option of \hologo{TeX} binaries},
+    generic={name=TEXMFOUTPUT, index annotation={variable in
+        \reffile[into index=false]{texmf.cnf}}},
+  }%
+  \docindex{%
+    cmd={name=pdfprimitive, see={\refcmd[into index=false,short]{primitive}}},
+    cmd={name=pdfsavepos, see={\refcmd[into index=false,short]{savepos}}},
+    cmd={name=pdfhorigin, see={\docref[into index=false]{pdfvar:horigin}}},
+    cmd={name=pdfvorigin, see={\docref[into index=false]{pdfvar:vorigin}}},
+    cmd={name=pdfcompresslevel, see={\docref[into index=false]{pdfvar:compresslevel}}},
+    pdfvariable={name=majorversion, see={\docref[into index=false,long]{reg:pdfmajorversion}}},
+    pdfvariable={name=minorversion, see={\docref[into index=false,long]{reg:pdfminorversion}}},
+ }%
+}
+
+\begin{document}
+
+
+\maketitle
+\thispagestyle{empty}
+
+\begin{abstract}
+  Memoize is a package for externalization of graphics and memoization of
+  compilation results in general, allowing the author to reuse the results of
+  compilation-intensive code.
+  Memoize 
+  \begin{enumerate*}[(i)]
+  \item induces very little overhead, as all externalized graphics is produced
+    in a single compilation.  It features
+  \item automatic recompilation upon the change of code or user-adjustable
+    context, and
+  \item automatic externalization of \TikZ pictures and Forest trees, easily
+    extensible to other commands and environments.  Furthermore, Memoize
+  \item supports cross-referencing, \TikZ overlays and Beamer,
+  \item works with all major engines and formats, and
+  \item is adaptable to any workflow.
+  \end{enumerate*}
+\end{abstract}
+
+\bigskip
+
+\ExampleName{titlepage}
+\makeexample{\examplename.pdf N=2} % N=2, because we show the .mmz file later
+\begingroup
+\tcbset{page box/.style={
+    box align=center,boxsep=2mm,top=0pt,bottom=0pt,left=0pt,right=0pt,
+    enhanced, remember as=#1,
+  }}%
+\begin{tcboxedraster}
+  [raster columns=1]
+  {title=The two steps of externalization of graphics in Memoize}
+  \tcbinputexample{
+    title=\tt doc.tex,
+    listing only,
+    remember as=tex,
+  }
+  \begin{tcolorbox}[example title=doc.pdf, no attachment, remember as=pdf1]
+    \includeexamplepdf[page box=extern1]{page=1,trim=1in 1in 1in 1in}\hfill
+    \includeexamplepdf[page box=extern2]{page=2,trim=1in 1in 1in 1in}\hfill
+    \includeexamplepdf[page box=extern3]{page=3,trim=1in 1in 1in 1in}\hfill
+    \includeexamplepdf[page box=docpage]{page=4}%
+  \end{tcolorbox}
+  \vspace{10mm}
+  \begin{tcboxedraster}[raster columns=3, raster column skip=1cm]{blankest}
+    \begin{tcolorbox}[example title=.pdf]\centering
+      \includeexamplepdf[page box=externfile1]{page=1,trim=1in 1in 1in 1in}\hfill
+    \end{tcolorbox}
+    \begin{tcolorbox}[example title=.pdf]\centering
+      \includeexamplepdf[page box=externfile2]{page=2,trim=1in 1in 1in 1in}\hfill
+    \end{tcolorbox}
+    \begin{tcolorbox}[example title=.pdf]\centering
+      \includeexamplepdf[page box=externfile3]{page=3,trim=1in 1in 1in 1in}\hfill
+    \end{tcolorbox}
+  \end{tcboxedraster}
+\end{tcboxedraster}
+
+\medskip
+
+\begin{tcolorbox}[title=Using the externalized graphics]
+  \begin{tcolorbox}[example title=doc.pdf,
+    halign=center, remember as=pdf2]
+    \tcbox[remember, enhanced]{\footnotesize
+      We all love Ti\emph{k}Zlings!
+      \def\mytikzling#1#2{%
+        \tcbox[blankest, baseline=1mm, remember as=used extern #1]
+        {\tikz[x=0.3cm,y=0.3cm]{#2;}}}%
+      \mytikzling1{\penguin} is a penguin,
+      \mytikzling2{\koala} is a koala, and
+      \mytikzling3{\owl} is an owl.
+    }
+  \end{tcolorbox}
+\end{tcolorbox}
+
+\begin{tikzpicture}[remember picture, overlay]
+  \draw[->, snake arrow, thick, red] (tex.west) to[out=-90-60, in=90+60] (pdf1.west);
+  \draw[->, snake arrow, thick, red] (tex.east) to[out=-90+19, in=90-19] (pdf2.east);
+  \draw[->, thick, red] (extern1.south) to[out=south, in=north] (externfile1);
+  \draw[->, thick, red] (extern2.south) to[out=south, out looseness=1.1, in=north, in looseness=0.9] (externfile2);
+  \draw[->, thick, red] (extern3.south) to[out=south, out looseness=0.7, in=north, in looseness=0.9] (externfile3);
+  \draw[->, thick,blue] (externfile1) to[out=south, in=north] ([yshift=0.8mm]used extern 1.north);
+  \draw[->, thick,blue] (externfile2) to[out=south, in=north] (used extern 2.north);
+  \draw[->, thick,blue] (externfile3) to[out=south, in=north] ([yshift=0.3mm]used extern 3.north);
+\end{tikzpicture}
+\endgroup
+
+\begin{tcolorbox}[colback=emphcolor, fontupper=\footnotesize]
+  This manual also documents packages Advice
+  ({\datefrompackageversion{advice}v\packagever}) and CollArgs
+  ({\datefrompackageversion{collargs}v\packagever}).  These are auxiliary
+  packages which were developed alongside Memoize, but are distributed as
+  independent packages as they might be useful outside the context of Memoize,
+  as well.  See sections~\ref{sec:advice} and \ref{sec:ref:advice} for Advice, and
+  sections~\ref{sec:collargs} and \ref{sec:ref:collargs} for CollArgs.
+\end{tcolorbox}
+
+
+
+\section*{Introduction}
+\label{sec:intro}
+
+\begin{tcolorbox}[
+    title={\introboxtitle{What} is externalization and why you might want it?},
+  ]
+  If you have ever worked on a long document full of \TikZ pictures and maybe
+  Forest trees, you have probably had some compilation-enforced coffee breaks
+  --- even on modern computers, compiling pictures, trees and such takes a lot
+  of time.  And you might have wondered, why do I need to compile these
+  pictures over and over again? --- after all, I'm not changing them anymore!
+  Enter \emph{externalization}, a mechanism designed to deal precisely with
+  your issue, by saving the produced pictures into separate PDFs and including
+  those PDFs in subsequent compilations --- in no time at all!
+\end{tcolorbox}
+
+\begin{tcolorbox}[
+    title={\introboxtitle{Why} yet another externalization package?},
+  ]
+  \TikZ, the popular and all-powerful graphics language for \TeX, ships
+  including an externalization library (described in \PGFmanual{53}).  \TikZ's
+  library does an excellent job, but with one caveat.  Assume you're using it
+  for the first time (or after a clean-up) on that long document full of \TikZ
+  pictures and Forest trees.  It will take ages to produce all the externalized
+  graphics.  Why?  Because to get you up to speed, your document has to be
+  compiled many many times --- once for each and every externalized picture.
+  Even with \TikZ's advanced mechanism for skipping the parts of the document
+  irrelevant for the picture at hand, the first externalization can be a
+  daunting task.
+\end{tcolorbox}
+
+\begin{tcolorbox}[
+    title={\introboxtitle{How} does Memoize save your time?},
+  ]
+  There is a reason why \TikZ uses an entire compilation cycle to produce a
+  single externalized picture: \TeX\ itself can only produce a single PDF per
+  compilation (at least at the moment).  Memoize evades this limitation by
+  dumping the externalized pictures right in the middle of the document
+  (ouch!).  More precisely, an externalized picture occurs in the PDF twice,
+  first on a special page of its own and then on a regular page, where you
+  intended it to be.  The daring dump obviously necessitates a second step of
+  the procedure, when those special pages are \emph{extracted} into separate
+  PDFs, called \emph{externs}, which are then included into the document in
+  subsequent compilations.
+
+  This two-step procedure, illustrated on the cover page of this manual, is
+  very fast.  The first step, which externalizes \emph{all} the pictures into
+  the document itself (the squiggly red arrow), takes virtually no more time
+  than a regular compilation.  The time needed for the second step, extraction
+  (the normal red arrows), depends on the system setup, but it ranges from
+  little to almost none.
+\end{tcolorbox}
+
+\begin{tcolorbox}[
+    title={\introboxtitle{When} should I use Memoize?},
+  ]
+  In short, whenever you are writing a document containing lots of \TikZ
+  pictures, Forest trees, or other time-consuming constructs, and you are bored
+  waiting for the compilation to finish.
+
+  Using Memoize on a paper containing a single picture does not make much of a
+  difference.  But with more complex documents, the speed-up can be immense.
+  For example, the compilation time of my 400-page book containing about 160
+  Forest trees was reduced by more than half, and the compilation time of a
+  260-page Beamer presentation with a hundred complex dynamic trees went from
+  four minutes to a mere half minute!
+\end{tcolorbox}
+
+
+\begin{tcolorbox}[
+    title={\introboxtitle{How} much extra work does Memoize require?},
+  ]
+  In principle, none.
+
+  For one, while allowing for manual memoization of selected document chunks
+  (\S\ref{sec:tut:memoize}), Memoize features a system which automatically
+  triggers memoization at each invocation of selected commands and
+  environments.  Out of the box, Memoize \emph{automemoizes} \TikZ
+  pictures\noprint{\refenv{tikzpicture}} and Forest
+  trees\noprint{\refenv{forest}}, but the author can easily submit (almost) any
+  command or environment to automemoization (\S\ref{sec:tut:automemoization}).
+  Memoize also does its best to automatically prevent memoization of code that
+  cannot be externalized, like \TikZ pictures with \refkey{/tikz/remember
+    picture}, and to abort memoization in case the memoized code yields any
+  errors.
+\end{tcolorbox}
+
+
+\begin{tcolorbox}[
+    title={\introboxtitle{Why} is Memoize not called Externalize?},
+  ]
+  Fundamentally, Memoize is about producing and utilizing \emph{memos} ---
+  pieces of \hologo{TeX} code replicating the effect of the compilation of a
+  document chunk in a computationally less intensive manner.  Typically, each
+  memo has an associated extern, which is where the effect of
+  \emph{typesetting} is stored, but conceptually, memos come first.  For
+  example, the extern is included back into the document by the memo, and a
+  memo may be associated with any number of externs, including zero.
+
+  Memos solve several externalization-related problems in a generic fashion,
+  allowing for a multitude of applications.  For example, they store the
+  information about the associated externs, so that an extern can be integrated
+  back into the document as a box with the original orientation, width, height
+  and depth.  They solve the problem of cross-referencing from and into the
+  memoized code by storing its \emph{context} (\S\ref{sec:cross-referencing})
+  and replicating any \cs{label}s which occur in it.  They are also crucial for
+  externalizing pictures in Beamer frames overlay by overlay.
+  
+  Incidentally, the term ``memoization'' is used with some programming
+  languages to refer to the process of remembering the result of the function,
+  along with the given arguments, so that on subsequent invocations of the
+  function with the same arguments, the result can be returned from memory
+  rather than recomputing it.  I would say that, give or take the functions,
+  what Memoize does fits the bill.
+\end{tcolorbox}
+
+  
+\begin{tcolorbox}[
+    title={\introboxtitle{How} can I make my command (auto)memoizable?},
+  ]
+  Any command which interacts with the rest of the document, like a command
+  which produces a float, must receive special treatment.  Some issues can be
+  resolved from within Memoize.  Other issues require a memoization-compatible
+  (re)implementation of the command.  It is in the hope that package writers
+  will adapt their ``difficult'' commands to Memoize that this package offers a
+  documented interface to the memoization process, fully described in
+  sections~\ref{sec:tut:package}, \ref{sec:memoization-drivers}
+  and~\ref{sec:tut:automemoization-details}.
+
+  An advanced user might also want to know that Memoize ships with two
+  auxiliary packages, which form the base of Memoize's automemoization feature.
+  Package Advice implements a generic framework for extending the functionality
+  of selected commands and environments, while package CollArgs provides a
+  command which can determine the argument scope of any command whose argument
+  structure conforms to \pkg{xparse}'s argument specification.
+\end{tcolorbox}
+
+\begin{tcolorbox}[
+    title={\introboxtitle{What else} is out there?},
+  ]
+  Not long before submitting Memoize to CTAN, I became aware of another new
+  externalization package, \pkg{robust-externalize}, and it seems that the same
+  happened to the author of that package \Smiley, who found the
+  proof-of-concept version of Memoize, which was available
+  at \href{https://github.com/sasozivanovic/memoize}{GitHub} for a while.
+  
+  The key idea behind \pkg{robust-externalize} seems to be to extract the code
+  submitted to externalization into separate files, and add the necessary
+  preamble.  While a compilation from scratch takes more time than with Memoize
+  (but less than with \TikZ library), the approach allows for parallel
+  compilation of externs --- nice!
+\end{tcolorbox}
+
+\newpage
+\tableofcontents
+
+
+\section{Before you start}
+\label{sec:setup}
+
+\subsection{Installing the extern extraction software}
+\label{sec:install}
+
+Good news: using Memoize can be as easy as writing
+\EmphVerbatim{\usepackage{memoize}} in the preamble.
+
+Bad news: Memoize won't work out of the box.  The culprit is the extern
+extraction --- the process which ships the externalized graphics from the main
+document into separate extern files; for details, see the title page
+illustration and the ``How'' box in the Introduction.  For the extraction to
+work, you will probably have to install some additional software, and you might
+also have to allow your \hologo{TeX} to execute the extraction script.  But
+there's a silver lining: once Memoize is set up, it is set up for good.
+
+\begin{tcolorbox}[title=What do I have to do?]
+
+  In principle, all you have to do for Memoize to work \emph{under the default
+    configuration} is install Perl libraries
+  \hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2} and
+  \hreftt{https://metacpan.org/pod/Path::Class}{Path::Class}; see the Perl
+  section below for the installation guideline.
+
+\end{tcolorbox}
+
+Consult section~\ref{sec:extraction} if you want to use an extraction method
+other than the default \refmmz{extract=perl}-based method or adapt Memoize to
+your particular workflow (for example, if you're compiling via a Makefile).
+
+If you installed Memoize through the package manager of your \hologo{TeX}
+distribution, your system should be already set up to allow the execution of
+Memoize's extraction scripts.  If this is not the case, please contact either
+me or the maintainer of your distribution; until the issue is resolved, you
+have to either
+\begin{enumerate}[(a)]
+\item compile documents loading Memoize with command-line option
+  \docref{-shell-escape} (on \hologo{TeX}Live) or
+  \docref{--enable-write18} (on MiK\hologo{TeX}), or
+\item set up the restricted shell escape mode to allow for the execution of
+  \refscript{memoize-extract.pl}.\footnote{\label{fn:shell-escape-commands}On
+    \hologo{TeX}Live, execute \code{tlmgr conf texmf shell\_escape\_commands}
+    to get the list of currently allowed commands \meta{current}, then add the
+    script by executing \code{tlmgr conf texmf shell\_escape\_commands
+      \meta{current},memoize-extract.pl}.  On MiK\hologo{TeX}, you get the
+    \meta{current} list by \code{initexmf
+      --show-config-value=[Core]AllowedShellCommands[]}, and add to it by
+    \code{initexmf
+      --set-config-value=[Core]AllowedShellCommands[]=\meta{current};memoize-extract.pl}.}
+\end{enumerate}
+
+Once you have set up your system, I advise you to follow the instructions in
+section~\ref{sec:tut:test} to test if the setup was successful.
+
+
+\begingroup
+\setlength\intextsep{0pt}
+
+\paragraph{Perl} If you're running GNU/Linux or macOS, Perl is most likely
+already installed on your system.  On Windows, you might have to install it. I
+tested Memoize with Strawberry Perl, available
+at \url(https://){strawberryperl.com}; see \url(https://){www.perl.org} for
+other options.
+
+\begin{wrapfigure}[3]{r}{0.25\linewidth}
+  \raisebox{0.5mm}[\dimexpr\height-0.5mm][\depth]{%
+    \mmznext{no verbatim}
+    \begin{tcolorbox}[
+        % example title=Installing the required libraries in Perl,
+        % attach shifted boxed title to top right,
+        % top=2.5mm,
+        fontupper=\small,
+        left=2mm, 
+        force nobeforeafter,
+      ]
+      |cpan PDF::API2|
+      
+      |cpan Path::Class|
+    \end{tcolorbox}%
+  }%
+\end{wrapfigure}
+Once Perl is installed on your system, you will need to install two Perl
+libraries as well: the PDF processing library
+\hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2}, and the cross-platform
+path specification manipulation library
+\hreftt{https://metacpan.org/pod/Path::Class}{Path::Class}.  On some GNU/Linux
+distributions, these libraries are included as packages --- just use your
+package manager to install them.  Otherwise, install them from
+\hreftt{https://www.cpan.org}{CPAN} using
+\hreftt{https://metacpan.org/pod/CPAN}{cpan} tool, as shown in the box.
+
+
+\paragraph{Python} Installing (Python and) the required Python library is only
+necessary if you decide to use the Python-based extraction script; see
+section~\ref{sec:extraction}.
+
+If you're running GNU/Linux, install Python using your package manager.
+Otherwise, download the installer from \url(https://){www.python.org}.  You can
+install Python even if you don't have administrator privileges: simply uncheck
+the ``Install launcher for all users'' when running the installer.
+
+\begin{wrapfigure}[2]{r}{0.25\linewidth}
+  \raisebox{0.2mm}[\dimexpr\height-0.2mm][\depth]{%
+    \mmznext{no verbatim}
+    \begin{tcolorbox}[
+        % example title=Installing the required library in Python,
+        % attach shifted boxed title to top right,
+        % top=2.5mm,
+        fontupper=\small,
+        left=2mm,
+        nobeforeafter,
+      ]
+      |pip install pdfrw2|
+    \end{tcolorbox}%
+  }%
+\end{wrapfigure}
+
+Once Python is installed on your system, you will also need to install the
+|pdfrw2| library (or its predecessor, |pdfrw|, which will work just as well).
+Some GNU/Linux distributions offer this library as a package; if this is not
+the case, and on other operating systems, install it
+from \href{https://pypi.org}{The Python Package Index}
+using \href{https://pip.pypa.io}{pip} tool (if you
+run \href{https://pip.pypa.io}{pip} as a superuser, it will install the library
+system-wide, otherwise locally), as shown in the box.
+
+\endgroup % \intextsep
+
+
+\subsection{The configuration commands}
+\label{sec:mmzset}
+
+Memoize can be configured using command \Emph{\refcmd{mmzset}\marg{keylist}}
+(and friends). The \meta{keylist} argument is a comma-separated list of
+configuration settings, each setting having the form \meta{key}|=|\meta{value},
+or sometimes just \meta{key}.  The \meta{keylist} argument is processed by package
+\pkg{pgfkeys} (see \PGFmanual{88}), so you can use all the bells and whistles
+of that fantastic PGF utility (like easily defining your own styles).
+
+Here's some examples of \refcmd{mmzset}.  For one, to whet your appetite to learn
+about the various keys in the \refkeypath{/mmz} path, but more importantly now, to show
+you that white-space is irrelevant in the \meta{keylist} argument, so you can
+format the keylist as you wish --- as long as it does not contain an empty
+line.\footnote{I like to add a comma after the final key as well, as shown in
+  the bottom left example, because if I don't, I often forget to insert it when
+  I add more keys.}
+
+\begin{tcbraster}[raster columns=4, raster valign=bottom]
+  \begin{tcboxedraster}[raster columns=1]{blankest, raster multicolumn=3, valign=bottom}
+    \begin{tcblisting}{listing only}
+~\mmzset~{memo dir,recompile,memoize=circuitikz}
+    \end{tcblisting}
+    \begin{tcblisting}{listing only}
+~\mmzset~{memo dir, recompile, memoize=circuitikz}
+    \end{tcblisting}
+  \end{tcboxedraster}
+  \begin{tcblisting}{listing only}
+~\mmzset~{
+  memo dir,
+  recompile,
+  padding=2in}
+  \end{tcblisting}
+\end{tcbraster}\par
+\begin{tcbraster}[raster columns=4, raster valign=top]
+  \begin{tcblisting}{listing only, raster multicolumn=2}
+~\mmzset~{
+  memo dir, readonly,
+  memoize=\qrcode{om},
+  deactivate=\label,
+  disable,
+}
+  \end{tcblisting}
+  \begin{tcblisting}{listing only}
+~\mmzset~{
+  memo dir,
+  recompile,
+  % comment
+  padding=2in
+}
+  \end{tcblisting}
+  \begin{tcblisting}{listing only, bad}
+~\mmzset~{
+  memo dir,
+  recompile,
+  
+  padding=2in
+}
+  \end{tcblisting}
+\end{tcbraster}
+
+Command \refcmd{mmzset} can be used any time after loading the package.  It is
+very common in the preamble, but also useful in the document body, where its
+effect is local to the \hologo{TeX} group.\footnote{Any keys with a non-local
+  effect are explicitly marked as such in the reference section.} For example,
+you can use the idiom on the left below to force recompilation of a single
+Forest tree somewhere in the middle of the document (in the code listings
+below, highlighting marks the resulting scope of the \refmmz{recompile}
+directive).  However, as applying some setting to a single piece of
+automatically memoized code is common, Memoize provides a special command for
+the occasion: the keys given as the argument of \Emph{\refcmd{mmznext}} will be
+applied only at the next instance of automemoization, overriding any keys set
+by \refcmd{mmzset} in case of a conflict.  If the command is given more than
+once, only the final invocation takes effect.
+
+\begin{tcbraster}[raster columns=2, raster equal height=rows, raster force size=false]
+\begin{tcblisting}{listing only, mark region={3}{6}}
+~{~
+  ~\mmzset~{recompile}
+  \begin{forest}
+    [VP[V][DP]]
+  \end{forest}
+  % ...
+~}~
+\end{tcblisting}
+\begin{tcblisting}{listing only, add to width=-1em, mark region={3}{5}}
+% ...
+~\mmznext~{recompile}
+\begin{forest}
+  [VP[V][DP]]
+\end{forest}
+% ...
+
+\end{tcblisting} 
+\end{tcbraster}
+
+I like to follow |\usepackage{memoize}| by \refcmd{mmzset}, but if you prefer, you
+can also provide the document-wide configuration as \Emph{package options.}
+Note, however, that \hologo{LaTeX} removes spaces from package
+options, so keys such as \refmmz{memo dir} won't work.  That said, the following are
+equivalent --- both will force re-externalization of all the externs in the
+document.
+
+\begin{tcbraster}[raster columns=2, raster equal height=rows]
+  \begin{tcblisting}{listing only}
+\usepackage{memoize}
+\mmzset{recompile}
+  \end{tcblisting}
+  \begin{tcblisting}{listing only}
+\usepackage[recompile]{memoize}
+  \end{tcblisting}
+\end{tcbraster}
+
+
+\subsection{The configuration file}
+\label{sec:memoize.cfg}
+
+Memoize allows you to configure settings which apply to more than just one
+document.  It does that by attempting to load file \Emph{\reffile{memoize.cfg}}
+just before executing package options.  Given how \hologo{TeX} searches for
+files, the location of this file determines whether it applies system-wide,
+user-wide or directory-wide.  The directory-wide location is clearly the
+directory itself.  The user-wide and system-wide location depend on the
+\hologo{TeX} distribution and which format(s) you want to use
+\reffile{memoize.cfg} with:\footnote{The |memoize| subfolder is not
+  obligatory.}
+
+\begin{center}
+  \meta{the relevant texmf tree root}|/tex/|\meta{format}|/memoize/memoize.cfg|
+\end{center}
+
+You can say |generic| for \meta{format} if you want the configuration file to
+be accessible by all formats, otherwise \meta{format} should be one of the
+formats supported by Memoize: |plain|, |latex| or |context|.  The texmf root
+directory depends on the distribution, here's how to figure out what it is:
+
+\begin{tcboxedraster}
+  [raster columns=1, raster valign=top, raster force size=false]
+  {title=The roots of TEXMF trees}
+\begin{tcolorbox}[title={\hologo{TeX} Live\hfill\url[white](https://){tug.org/texlive}}]
+  \begin{description}[itemsep=0pt]
+  \item[user-wide]
+    |tlmgr conf texmf TEXMFHOME|
+    or |kpsewhich -var-value TEXMFHOME|\\
+    the default (on Linux): |/home/|\meta{username}|/texmf|
+  \item[system-wide]
+    |tlmgr conf texmf TEXMFLOCAL|
+    or |kpsewhich -var-value TEXMFLOCAL|\\
+    the default (on Linux): |/usr/local/texlive/texmf-local|
+  \end{description}
+
+  \smallskip
+  Don't forget to run |texhash| or |mktexlsr| after creating \reffile{memoize.cfg}.
+\end{tcolorbox}
+\begin{tcolorbox}[title={MiK\hologo{TeX}\hfill\url[white](https://){miktex.org}}, before upper={\parskip0.3\baselineskip plus 2pt\relax},]
+  Open the MiK\hologo{TeX} Console, select the ``Settings'' page and then the
+  ``Directories'' tab.
+
+  If there is a folder marked with the ``Generic'' purpose with attribute
+  ``User'' (for a user-wide \reffile{memoize.cfg}) or ``Common'' (for a system-wide
+    \reffile{memoize.cfg}), that's the folder you are looking for.  Otherwise, create a
+  folder following MiK\hologo{TeX}'s instructions and add it to the list.
+  
+  Don't forget to click ``Refresh file name database'' (in the ``Tools'' menu
+    of the MiK\hologo{TeX} Console) after creating \reffile{memoize.cfg}.
+\end{tcolorbox}
+\end{tcboxedraster}
+
+Note that a directory config file will override the user config, and the user
+config will in turn override the system-wide one.  This should not concern you
+too much, because you will probably only want to use the user-wide config
+anyway,\cprotect\footnote{If you want to have a directory-wide configuration
+  based on (rather than overriding) the user-wide configuration, your could
+  write down the real user-wide config in, say, |memoize.user.cfg| (located
+  user-wide), and then |\input| this file by both the user-wide and the
+  directory-wide \reffile{memoize.cfg}.  Of course, the same logic can be used to base
+  a user-wide config on the system-wide one.} which might look something like
+this:
+
+\ExampleName{memoize}
+\makeexample{\examplename.cfg.c1}
+\tcbinputexample[.cfg]{listing only}
+
+I recommend including \refmmz{memo dir} in your \reffile{memoize.cfg},
+as shown in the first line.  It reduces the clutter in the document
+directories; see section~\ref{sec:tut:memodir} for details.
+
+The \refmmz{extract} line concludes the story on ``permanently'' selecting the
+extraction method, started in chapter~\ref{sec:setup}.  As the final note,
+observe that key \refmmz{extract} only makes sense as a package option or as a
+\refcmd{mmzset} key in \reffile{memoize.cfg}.  It will have no effect as a
+\refcmd{mmzset} key in the document, because the extraction happens while the
+package is loaded.
+
+
+
+\section{Your first memoized documents}
+\label{sec:tut}
+
+\subsection{Let's see if it works!}
+\label{sec:tut:test}
+
+\ExampleName{test}
+\noprint{\refcmd{tikz}\refenv{tikzpicture}\refenv{forest}}%
+
+Take example file \texttt{\examplename.tex},\footnote{Where can you find
+  the example files?  For one, they are integrated into this manual, so if your
+  PDF viewer supports attachments, you can simply click on the paperclip icon
+  on the top right of the example box (even if you're offline).  Otherwise,
+  visit the |examples| subdirectory of wherever you found this document
+  \Smiley.  Online, the Memoize documentation can be found at CTAN:
+  \url{https://ctan.org/pkg/memoize}; and if your \hologo{TeX} installation
+  includes the documentation, you should also find it in directory \meta{the
+    root of your \hologo{TeX} installation}|/doc/generic/memoize|.
+  
+  Incidentally, while we present a full example document in this section, many
+  code listings will only present the parts of the file relevant for the
+  discussion, for brevity.  The example \emph{files}, however, will remain
+  full, compilable documents, including the document preamble etc.} or some
+simple document containing a \TikZ picture or a Forest tree, add
+\EmphVerbatim{\usepackage{memoize}} to the preamble,\footnote{Memoize likes to
+  be loaded early.  If you get the error \texttt{Extern extraction from
+    document \meta{jobname}.pdf was unsuccessful}, move
+  \cs{usepackage}\bracestt{memoize} up the preamble; see
+  section~\ref{sec:loading-order} for details.} and compile it twice.
+
+\begin{itemize}
+\item The first compilation of the example should produce a three-page PDF.
+  The first two pages are the \emph{extern pages} holding the externalized
+  graphics, while the final page is the (sole page of the) real document.  Note
+  that you can see each extern twice: first on a page of its own, and then
+  wherever it belongs to in the real document.
+\item At the second compilation, the extern pages should have disappeared from
+  the PDF, meaning they were successfully extracted into extern files, which
+  are now embedded into the main document.
+\end{itemize}
+
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside,
+  comment={\centering
+    \includeexamplepdf[extern page,left=2mm,right=2mm]{page=1,trim=1in 1in 1in 1in}\quad
+    \includeexamplepdf[extern page,left=2mm,right=2mm]{page=2,trim=1in 1in 1in 1in}\\[2ex]
+    \includeexamplepdf[document page]{page=3}
+  },
+}
+
+You might want to play with this example a bit now.
+For example, if you reverse the order of the \TikZ picture and the Forest
+tree, you should notice that the externs don't get recompiled.  You won't see
+any extern pages again until you change the actual code of the picture or the
+tree --- or until you add some other picture or tree, of course.
+
+If you \emph{don't} want to automatically memoize \TikZ pictures and/or Forest
+trees, you can switch off their \emph{automemoization} using key
+\Emph{\refmmz{deactivate}}.  This key takes a list of command and environment
+names.  As you can see below, the command and the environment must be
+deactivated separately.
+
+\begin{tcblisting}{listing only}
+\mmzset{
+  deactivate={\tikz, tikzpicture},   % deactivate automemoization of all TikZ pictures
+  deactivate=\tikz,                  % deactivate only the command
+  deactivate=tikzpicture,            % deactivate only the environment
+}
+\end{tcblisting}
+
+
+\subsection{Memoizing by hand}
+\label{sec:tut:memoize}
+
+In the previous section, we have compiled our very first document which used
+Memoize.  In that document, we only had to load the package, as Memoize knows
+how to externalize \TikZ pictures and Forest trees without any help from the
+author.  But what if you want to externalize some other code?  The manual way of
+doing this is by surrounding the code by a \Emph{\refenv{memoize}} environment,
+or by making it the argument of the \Emph{\refcmd{mmz}} command.  The only
+difference between the two is that the environment, but not the command,
+ignores any spaces surrounding the given code.
+
+\ExampleName{manual}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside, lefthand ratio=0.528,
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}\hfill
+    \includeexamplepdf[extern page]{page=2,trim=1in 1in 1in 1in}
+  },
+}
+
+Both the \refenv{memoize} environment and the \refcmd{mmz} command take a
+configuration keylist as the optional argument, so their full syntax is
+\cs{begin}\marg{\refenv{memoize}}\oarg{keylist}\meta{code to be
+  externalized}\cs{end}\marg{\refenv{memoize}} and and
+\refcmd{mmz}\oarg{keylist}\marg{code to be externalized}.  The keys given in
+this optional argument take precedence over the keys set by \refcmd{mmzset}.
+Note that \refcmd{mmznext} does not apply to manual memoization.
+
+Manual memoization is great for one-shot memoizations, but you can use it
+within your own macros as well.  For example, assume that you don't want to
+externalize \TikZ pictures in general (so you have \refmmz{deactivate}d
+automemoization of the \cs{tikz} command, as explained at the end of
+section~\ref{sec:tut:test}), but that you want to easily memoize selected
+pictures.  You could define a memoized variant of the \cs{tikz} command, as shown
+below (and similary for the environment).  (Note the |%| comment characters in
+the definition of |\mmztikz|.  The definition was intentionally broken into
+several lines to remind you that the spaces around the argument of \refcmd{mmz}
+matter.)
+
+\ExampleName{mmztikz}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}
+    \quad
+    \includeexamplepdf[document page]{page=2}
+  },
+}
+
+\clearpage
+\subsection{Memoizing automatically}
+\label{sec:tut:automemoization}
+
+Out of the box, Memoize automatically externalizes \TikZ pictures and Forest
+trees.  Let us see how other commands and environments can be submitted to this
+\emph{automemoization} process.
+
+We start with the simpler case of environments (fortunately, externalizing
+environments also makes sense more often than externalizing commands).  You can
+submit an environment to automemoization by writing
+\EmphTT{\refmmz{auto}=\marg{environment name}\braces{\refmmzauto{memoize}}} (as
+a key in \refcmd{mmzset}).  The natural (but not the only possible) location
+for this instruction is the preamble.  Below, we automemoize environment
+\env{circuitikz} of package \pkg{circuitikz}, used for drawing electronic
+circuits.\footnote{In section~\ref{sec:tut:test}, we learned that
+  automemoization can be switched off using key \refmmz{deactivate}.  Memoize
+  also offers key \refmmz{activate}, but you probably won't have to use it, as
+  an \refmmz{auto} declaration automatically activates the submitted command.}
+
+\ExampleName{automemoize-environment}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside, lefthand ratio=0.6,
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in,scale=0.8}
+  },
+}
+
+Commands are a bit harder to automemoize, because Memoize cannot possibly know
+how far the arguments of a command extend (in contrast, the end of an
+environment is clearly marked).  With commands, we must inform Memoize about
+their argument structure, which we achieve using key \refmmzauto{args} in the
+second argument of key \refmmz{auto}:
+\EmphTT{\refmmz{auto}=\meta{command}\braces{\refmmzauto{memoize},
+    \refmmzauto{args}=\marg{argument specification}}}.  We can only leave out
+\refmmzauto{args} if the command was defined by \refcmd{NewDocumentCommand} or
+similar; in this case, Memoize can retrieve the argument specification on its
+own.
+
+And how does the \meta{argument specification} look like?  It is a sequence of
+letters, each letter determining an argument type.  Memoize recognizes the same
+argument types and their letters as package \pkg{xparse} (which defines
+\refcmd{NewDocumentCommand} and friends), so you should look at (section 1 of)
+the documentation of that package for details, if and when you need them.
+Here, we focus on the two most commonly used types, \docref{xparse:m} and \docref{xparse:o}, and add the
+optional star for good measure:
+\begin{center}
+  \begin{tabular}{lll}
+    \toprule
+    letter & argument type & example\\
+    \midrule
+    \docref{xparse:m} & mandatory argument \\
+           & --- either surrounded with braces &  |\foo{arg}|\\
+           & --- or a single token & |\foo a|\\
+    \docref{xparse:o} & optional argument, surrounded with brackets & |\foo[arg]|\\
+    \docref{xparse:s} & optional star & |\foo*|\\
+    \bottomrule
+  \end{tabular}  
+\end{center}
+
+Below, we write |args=om| because command \cs{qrcode} (of package \pkg{qrcode})
+takes two arguments: a bracketed optional argument, followed by a mandatory
+argument (in braces).
+
+\ExampleName{automemoize-command}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside, lefthand ratio=0.603, top=0mm,
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}\quad
+    \includeexamplepdf[extern page]{page=2,trim=1in 1in 1in 1in}
+  },
+}
+
+This should get you started with automemoization.  We'll provide some further
+basic information in sections~\ref{sec:tut:working-on-a-picture}
+and~\ref{sec:tut:verbatim} of the tutorial, but only package writers will
+probably ever need the gory details from
+section~\ref{sec:tut:automemoization-details}.  It is my sincere hope that they
+will support Memoize in their packages, where necessary, so that you don't even
+have to write the \refmmz{auto} declarations, but there is one thing you should
+know if you encounter a package supporting Memoize: you should load it
+\emph{after} Memoize!
+
+
+
+\subsection{Working on a picture}
+\label{sec:tut:working-on-a-picture}
+
+
+Memoize automatically recompiles a picture when the code producing the picture
+changes.  However, sometimes we can modify a picture without changing its code,
+like when we modify the definition of a command used in the code.  In the
+example below, a predefined style |emph| is applied to the node, producing a
+node with a red background.  Let's say we compile the document (with
+memoization) and then change this style to set the yellow background.
+Curiously, the node will remain red.
+
+\ExampleName{recompile}
+\makeexample{\examplename.pdf N=3}
+\begin{tcbraster}[raster columns=2, raster valign=top, raster column skip=4mm]
+  \tcbinputexample{
+    after title pre={\ (version~1)},
+    comment={\centering
+      \includeexamplepdf[document page]{page=2}
+    },
+  }
+  \tcbinputexample[.tex][.c2]{
+    no attachment,
+    after title pre={\ (version~2)},
+    comment={\centering
+      \includeexamplepdf[document page]{page=1}
+    },
+  }
+\end{tcbraster}
+
+The curious thing happens (or rather, doesn't happen) because Memoize doesn't
+keep track of how commands and styles are defined; it just uses the extern file
+it created when the old style was in effect.  To get a yellow node, we must ask
+Memoize to reexternalize the picture.  The simplest way to do that is by using
+the \Emph{\refmmz{recompile}} key; below, we write
+\refcmd{mmznext}\bracestt{\refmmz{recompile}} just before the picture and
+compile the document again (remember from section~\ref{sec:mmzset} that
+whatever keys we provide through \refcmd{mmznext} only apply to the instance of
+automemoization).  After the compilation, we may (and should) remove the
+\refmmz{recompile} directive (otherwise, Memoize will produce the extern page
+again and again).
+
+\tcbinputexample[.tex][.c3]{
+  no attachment,
+  after title pre={\ (version~3)},
+  sidebyside, lefthand ratio=0.6,
+  comment={\centering
+    \includeexamplepdf[document page]{page=2}
+  },
+}
+
+It is also common to put (again, for the space of a single compilation)
+\refcmd{mmzset}\braces{\refmmz{recompile}} in the preamble, or to use
+\refmmz{recompile} as the package option.  Either will remake all the
+externalized graphics in the document, so you can be sure all of them use the
+latest version of your macros and styles.
+
+We'll revisit the issue of memoized code depending on macros and styles defined
+elsewhere in section~\ref{sec:tut:redefinitions}.  In this section, we will
+learn how the issue can be \emph{avoided}, at least to some extent.  One idea
+is to turn off memoization for the picture(s) we are currently working on;
+another idea is to let Memoize know which definitions the picture relies on.
+The simplest way to achieve the former is by using key \Emph{\refmmz{disable}};
+by putting it into a \hologo{TeX} group, we can localize its effect to the
+selected pictures.
+
+\ExampleName{disable}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside, 
+  lefthand ratio=0.6,
+  top=0mm, % manual top, bottoms and \\[...] to fit the page
+  comment={\centering
+    \includeexamplepdf[extern page,bottom=0.8mm]{page=1,trim=1in 1in 1in 1in}\\[0.5mm]
+    \includeexamplepdf[extern page,bottom=0.8mm]{page=2,trim=1in 1in 1in 1in}\\[0.5mm]
+    \includeexamplepdf[document page,bottom=0.8mm]{page=3}
+  },
+}
+
+\begin{tcolorbox}[warning]
+  As you can imagine, key \refmmz{disable} is complemented by \refmmz{enable},
+  but it is perhaps worth mentioning a problem that can arise if you disable
+  memoization for a part of your document by enclosing it in a pair of
+  \refcmd{mmzset}\braces{\refmmz{disable}} and
+  \refcmd{mmzset}\braces{\refmmz{enable}}.  Yes, it might work at the moment,
+  but say you later (e.g.\ when you are preparing the final version of the
+  document) decide to disable memoization for the entire document, and say you
+  try to do this by writing \refcmd{mmzset}\braces{\refmmz{disable}} in the
+  preamble.  As shown below on the left, you're in for a surprise: memoization
+  will still be enabled in the part of the document following
+  \refcmd{mmzset}\braces{\refmmz{enable}}!  The solution is to always disable
+  memoization for a part of the document by using
+  \refcmd{mmzset}\braces{\refmmz{disable}} in a \hologo{TeX} group (i.e.\ the
+  braces), as shown on the right.  (In the examples below, the shaded areas
+  mark the parts of the document where memoization is \emph{disabled}.)
+\end{tcolorbox}
+
+\makeexample{disable-bad.tex.c1}
+\makeexample{disable-good.tex.c1}
+\makeexample{disable-nomemoize.tex.c1}
+\makeexample{disable-nommz.tex.c1}
+\makeexample{disable-auto-cmd.tex.c1}
+\makeexample{disable-auto-env.tex.c1}
+
+\begin{tcbraster}[raster columns=2, raster equal height=rows]
+  \tcbinputexample(disable-bad){
+    listing and comment, bad, mark region={4}{7},
+    comment={\raggedright The upper \refcmd{mmzset}\braces{\refmmz{disable}}
+      does not have the intended effect,
+      i.e.\ it doesn't apply to the whole document!}}
+  \tcbinputexample(disable-good){
+    listing and comment, mark region={4}{10},
+    comment={\raggedright The upper \refcmd{mmzset}\braces{\refmmz{disable}} applies
+      to the entire document, as expected.}}
+\end{tcbraster}
+
+In fact, it might be better to disable memoization using environment
+\Emph{\refenv{nomemoize}} or macro \Emph{\refcmd{nommz}}.  I also like these
+commands because it is easy to add and remove prefix |no| to switch manual
+memoization (triggered using environment \refenv{memoize} or macro
+\refcmd{mmz}) off and on.
+
+\begin{tcbraster}[raster columns=2, raster equal height=rows]
+  \tcbinputexample(disable-nomemoize){listing and comment, mark region={2}{2},
+    comment=\raggedright Disable using the dedicated environment.}
+  \tcbinputexample(disable-nommz){listing and comment, mark region={2}{2},
+    comment=\raggedright Disable using the dedicated command.}
+\end{tcbraster}
+
+It is also possible to disable memoization for all occurrences of a selected
+command or environment.  In fact, we're already familiar with the procedure
+from section \ref{sec:tut:automemoization}, where we used key
+\refmmzauto{memoize} inside the second argument of \refmmz{auto} to
+automatically memoize all instances of the command or environment given as the
+first argument.  All we have to do to auto-disable rather than auto-memoize, is
+substitute \refmmzauto{nomemoize} for \refmmzauto{memoize}.  Note that this
+prevents memoization of not only the given command or environment, but also of
+any (manual or automatic) memoization which would otherwise occur during its
+execution; for example, if |\foo| executes \cs{tikz} under the hood,
+autodisabling |\foo| prevents memoization of the inner \cs{tikz}, even though
+that command is normally automemoized.
+
+\begin{tcbraster}[raster columns=2, raster equal height=rows]
+  \tcbinputexample(disable-auto-cmd){
+    listing and comment,
+    mark region={3}{3}, mark region={5}{5},
+    comment=\raggedright Autodisable within a command.,
+  }
+  \tcbinputexample(disable-auto-env){
+    listing and comment,
+    mark region={3}{5},
+    comment=\raggedright Autodisable within an environment.,
+  }
+\end{tcbraster}
+
+All that said, Memoize actually offers a neater way to switch off the
+externalization for the picture I'm currently working on.  The
+\Emph{\refmmz{readonly}} key instructs Memoize to use whatever externs it had
+already produced (thereby reducing the document compilation time), but to
+abstain from producing any new externs.  In effect, the stuff we are currently
+working on does not undergo memoization and therefore does not produce the
+clutter which can potentially lead to trouble described in the \refmmz{recompile}
+examples above.
+
+What I like to do is load the package using |\usepackage[readonly]{memoize}|,
+work on stuff, and once I'm happy with the most recent pictures, remove
+\refmmz{readonly} from the package options for one compilation.
+
+\ExampleName{readonly}
+\makeexample{\examplename.pdf N=2}
+
+\begin{tcbraster}[raster columns=5, raster valign=top, raster column skip=4mm]
+  \tcbinputexample{
+    raster multicolumn=2,
+    after title pre={\ (work in progress)},
+    comment={\centering
+      \includeexamplepdf[document page]{page=1}
+    },
+  }
+  \tcbinputexample[.tex][.c2]{
+    raster multicolumn=3,
+    no attachment,
+    title={\tt readonly.tex} (the final version),
+    comment={\centering
+      \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}\quad
+      \includeexamplepdf[document page]{page=2}
+    },
+  }
+\end{tcbraster}
+
+We're now ready to tackle a completely different way of avoiding the issue, by
+informing Memoize which definitions the externalized picture depends on.  We do
+this by appending these definitions to \emph{context} --- when the context of a
+picture changes, Memoize recompiles the picture, same as if the code of the
+picture itself was changed.  (We will talk about context in more detail in
+section~\ref{sec:cross-referencing}.)
+
+A command can be added as a dependency using key \Emph{\refmmz{meaning to
+    context}}.  Below, we make the following externalized picture depend on the
+definition of macro \cs{answer}; changing this definition will result in the
+recompilation of the extern.  In general, \refmmz{meaning to context} accepts a
+comma-separated list of command and environment names, e.g.\
+\code{\refmmz{meaning to context}=\bracestt{\cs{foo},bar}} (note the braces).
+
+Memoize offers several variants of \refmmz{meaning to context}, applicable to
+various types of commands.  For example, the easiest way of making the picture
+depend on the definition of a \pkg{pgfkeys} style is to use handler
+\Emph{\refkey{/handlers/.meaning to context}} --- note the dot in the name, and
+observe that \code{emph/.meaning to context} below is executed within
+\cs{tikzset}, not \refcmd{mmzset}; see \PGFmanual{87} to learn about key
+handlers.
+
+\ExampleName{meaning-to-context}
+\makeexample{\examplename.pdf N=2}
+\tcbinputexample{
+  after title pre={\ (version~1)},
+  sidebyside,
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}
+  },
+}
+
+\tcbinputexample[.tex][.c2]{
+  after title pre={\ (version~2)},
+  sidebyside,
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}
+  },
+  no attachment,
+}
+
+All variants of \refmmz{meaning to context} (see reference
+section~\ref{sec:ref:memoization:basic} for the full list) may be used within
+the externalized picture itself, e.g.\ \code{\cs{node}[emph,
+    emph/\refkey{/handlers/.meaning to context}]\bracestt{...}} is perfectly
+valid --- and also handy when you want to limit the effect of the handler to a
+single picture, as \refkey{/handlers/.meaning to context} cannot be used within
+\refcmd{mmznext}.
+
+
+
+\subsection{Keeping a clean house}
+\label{sec:tut:memodir}
+
+Memoize produces lots of auxiliary files.  For each piece of memoized code, it
+produces two \emph{memo} files (we will learn more about these in
+section~\ref{sec:memos}), which will be joined by the extern PDF upon the next
+compilation.\footnote{If you're using the \hologo{TeX}-based extraction, each
+  extern (|.pdf|) is also accompanied by a log file (|.log|) produced during
+  the compilation that extracted the extern.} You can recognize these files
+easily: their names start with the name of your document and include one or two
+long hexadecimal numbers.
+
+\ExampleName{dirty-house}
+\makeexample{\examplename.pdf}
+{
+  \relaxmmzcommands
+  \edef\marshal{%
+    \noexpand\def\noexpand\mynewextern.//\examplename
+  }\marshal.#1-#2.pdf\relax{%
+    \forestset{
+      append={[\examplename.#1.memo\vphantom{p},pointcolor]},
+      append={[\examplename.#1-#2.memo\vphantom{p},pointcolor]},
+      append={[\examplename.#1-#2.pdf,pointcolor]},
+    }%
+  }
+  \tcbinputexample{
+    comment={%
+      \begin{tcolorbox}[reset, left=2mm, bottom=0mm,
+          my boxed title=the folder contents (after two compilations),
+          attach shifted boxed title to top right,
+        ]
+        \begin{forest}
+          before typesetting nodes={for tree={
+              font=\scriptsize\tt, grow'=0, folder, s sep=0}},
+          [\meta{the document folder}, inner xsep=0,
+            TeX={%
+              \def\mmzNewExtern##1##2##3##4##5{\mynewextern##1\relax}%
+              \input{\examplepath.mmz}%
+            },
+            [\examplename.tex]
+            [\examplename.pdf]
+            [\normalsize\dots, no edge]
+            [\examplename.mmz, tikz={\draw[dotted](.east)--+(5em,0ex) node [anchor=south west, yshift=-1ex, align=justify, text width=14em, font=\footnotesize]{This is another auxiliary file produced by Memoize. We will mention it at the end of the section.};}]
+          ]
+        \end{forest}
+      \end{tcolorbox}
+    },
+  }
+}
+
+To top it off, changing the memoized code will produce new memo (and extern)
+files, with the old files staying in place.  This is all by design --- the
+first hexadecimal number in these filenames is the MD5 sum of the memoized code
+and that's how Memoize knows which memo belongs to which piece of
+code\footnote{The second hexadecimal number in the memo and extern filenames is
+  the MD5 sum of the \emph{context}.  The context is crucial for properly
+  externalizing code containing cross-references, see
+  section~\ref{sec:cross-referencing} for details.} --- but it has the downside
+that the folder containing your document can get quite cluttered (imagine the
+directory listing as above, but for a document with a hundred externalized
+pictures which you have been working on for a month).
+
+\ExampleName{clean-house}
+
+I like to keep a clean house by instructing Memoize to put memos and friends
+into their own directory.  This can be achieved by writing
+\refcmd{mmzset}\braces{\Emph{\refmmz{memo dir}}} into the preamble (anytime
+after loading the package).\footnote{The \refmmz{memo dir} key is in fact
+  merely an abbreviation for a sequence of \refmmzpath{dir} and
+  \refmmzpath{prefix} within \refmmz{path}; use these keys if you need more
+  control over the name and location of the auxiliary files. Furthermore, there
+  is also the \refmmz{no memo dir} key, which reverts the configuration back to
+  the dirty default.}  This will put the memo and the extern files into folder
+\meta{document name}|.memo.dir| (and it will also omit the \meta{document name}
+prefix in their filenames, because it makes no sense to repeat it there).
+
+\makeexample{\examplename.pdf}
+{%
+  \relaxmmzcommands
+  \edef\marshal{%
+    \noexpand\def\noexpand\mynewextern./\examplename
+  }\marshal.memo.dir/#1-#2.pdf\relax{%
+    \forestset{
+      append={[#1.memo\vphantom{p},pointcolor]},
+      append={[#1-#2.memo\vphantom{p},pointcolor]},
+      append={[#1-#2.pdf,pointcolor]},
+    }%
+  }
+  \tcbinputexample{
+    comment={%
+      \begin{tcolorbox}[reset, left=2mm, bottom=0mm,
+          my boxed title=the folder contents (after two compilations),
+          attach shifted boxed title to top right,
+        ]
+        \begin{forest}
+          before typesetting nodes={for tree={
+              font=\scriptsize\tt, grow'=0, folder, s sep=0}},
+          [\meta{the document folder}, inner xsep=0
+            [\examplename.tex]
+            [\examplename.pdf]
+            [\normalsize\dots, no edge]
+            [\examplename.mmz]
+            [\examplename.memo.dir,pointcolor,
+              % tikz={\draw[dotted](.east)--+(9em,0ex) node [anchor=south west, yshift=-1ex, font=\footnotesize, emphshade=black!5!white, text width=15em, align=justify]{You need to create this directory by hand, or allow Memoize to create it by adding |mkdir| to the list of restricted shell escape commands.};},
+              tikz={\draw[dotted](.east)--+(9em,0ex) node [anchor=west, font=\footnotesize, emphshade=black!5!white]{This directory must be created, somehow.};},
+              TeX={%
+                \def\mmzNewExtern##1##2##3##4##5{\mynewextern##1\relax}%
+                \input{\examplepath.mmz}%
+              },
+            ]
+          ]
+        \end{forest}
+      \end{tcolorbox}
+    },
+  }
+}
+
+\begin{tcolorbox}[title={Why is \refmmz[link color=white]{memo dir} not the default?}]
+  The \code{clean-house} example most likely compiled just fine, and you are
+  wondering why \refmmz{memo dir} is not in effect by default.  Well, out of
+  the box, \hologo{TeX} cannot create directories, so it is the fact that
+  Memoize \emph{can} create them (at least under the default settings) which
+  requires explanation.  By default, Memoize triggers extraction by executing
+  the Perl extraction script \refscript{memoize-extract.pl}, and it is this
+  script which actually creates the memo directory.  However, not everybody
+  will necessarily use this script \dots\ so \refmmz{memo dir} should not be
+  the default.
+
+  The Python extraction script \refscript{memoize-extract.pl}, used when
+  \refmmz{extract}|=|\refmmz{extract=python}, works the same as the Perl
+  variant.  With \hologo{TeX}-based extraction
+  \refmmz{extract}|=|\refmmz{extract=tex}, things are different.  If you are
+  compiling the document with a full shell escape mode
+  (\docref{-shell-escape}), Memoize successfully creates the directory with the
+  system command |mkdir|.\footnote{|mkdir| is the default value of key
+    \refmmz{mkdir command}, but executing the extraction method
+    \refmmz{extract=perl} or \refmmz{extract=python} overrides this default.}
+  However, if you're using the restricted shell escape mode, the attempt to
+  create the directory won't succeed unless you include |mkdir| among the
+  restricted shell escape commands (see footnote~\ref{fn:shell-escape-commands}
+  on page~\pageref{fn:shell-escape-commands} for how to do this, but note that
+  it is not recommended).
+
+  If you are using external extraction, you have to create directory
+  \texttt{\examplename.memo.dir} by hand, prior to the first compilation of the
+  document (with Memoize).  This is the case even if you are performing the
+  extraction using one of the shipped extraction methods, and it is due to the
+  fact that Memoize needs the memo directory to be present even before extern
+  extraction, because it writes the |.memo| files into the same directory.
+  (When Memoize uses the extraction script to create the memo directory, it
+  does so completely independently of extraction, and prior to creating any
+  |.memo| files.)
+\end{tcolorbox}
+
+I actually suggest adding \refcmd{mmzset}\braces{\refmmz{memo dir}} into your
+user-wide \reffile{memoize.cfg} (see section~\ref{sec:memoize.cfg} for details
+on this file).  This will keep all your houses clean --- without work! --- as
+Memoize will automatically use the memo directory for any document your create.
+
+It is always safe to delete memos (|.memo|) and externs (|.pdf|s residing next
+to memos), in the sense that you cannot lose data this way.\footnote{The same
+  goes for the extern |.log| files produced by the \hologo{TeX}-based
+  extraction.}
+
+\begin{itemize}
+
+\item Many memos and externs are typically stale anyway, i.e.\ they reflect
+  some previous state of your document and are not needed anymore.  These files
+  can be deleted without any repercussions whatsoever (unless you later revert
+  to a previous version of the document, of course).  In fact, you might
+  \emph{want} to delete them periodically, or at least once you finish writing
+  the document.  As it is hard to figure out which memos/externs are stale,
+  Memoize ships with a clean-up script: writing \refscript{memoize-clean.pl}
+  \meta{document name}\dmmz (replace |.pl| with |.py| if you use Python rather
+  than Perl) into the command line will delete all the \emph{stale} auxiliary
+  files belonging to the document.
+
+\item If you delete a memo or an extern currently in use, you will trigger
+  recompilation of their code --- so deleting a memo or an extern is actually a
+  perfectly legal alternative to using the \refmmz{recompile} key!\footnote{For the
+    users of the \hologo{TeX}-based extraction: deleting the |.log| file does
+    \emph{not} trigger recompilation.}
+
+\end{itemize}
+
+It is also safe to delete the \dmmz file (or any other kind of record file, see
+section~\ref{sec:record-files}) residing next to your document's |.pdf|.  The
+\dmmz file contains the information about which externs should be extracted
+from the |.pdf|.  Deleting it before this is done (by default, before compiling
+the document again) will prevent the extraction (same as if providing the
+package option \code{\refmmz{extract}=\refmmz{extract=no}}) and ultimately
+result in the recompilation of the externs produced in the previous run.
+Deleting it after the extraction will have almost no effect: it will only only
+prevent the clean-up script from working (the \dmmz file also lists the
+currently active memos and externs, and thereby indirectly informs the clean-up
+script which files are stale).  For further information on the \dmmz file, see
+section~\ref{sec:.mmz}.
+
+
+
+\subsection{Writing a book?}
+\label{sec:tut:multifile}
+
+Books and other long documents are usually produced from sources which reside
+in more than a single file, and to speed up the editing process, authors
+usually use some system which allows them to compile each chapter separately.
+Can Memoize --- designed for virtually the same task of speeding up the editing
+process --- work sensibly in this kind of situation?  More precisely, can the
+book and the individual chapters share the memos and the externs?  Yes they
+can!  If we instruct Memoize to use the same memo directory for both the book
+job and the chapter jobs, then we can externalize graphics when compiling a
+chapter and have the externs included when compiling the book (and vice
+versa).\footnote{Package \pkg{docmute} makes \hologo{LaTeX} ignore the preamble of
+  the chapter file when including this file into the main document.} All we
+need to do is use our old friend \refmmz{memo dir} from section~\ref{sec:tut:memodir}
+--- we see now that this setting is good for more than just keeping a clean
+house!
+
+\ExampleName{book}
+\makeexample{\examplename.tex.c1}
+\makeexample{chapters/chapter1.tex.c1}
+
+\begin{tcbraster}[raster columns=2, raster valign=top]
+  \tcbinputexample{listing only}
+  \tcbinputexample(chapters/chapter1){listing only}
+\end{tcbraster}
+
+In the above example, the individual chapters reside in files stored in the
+|chapters| subdirectory, and that's why the |book.tex| preamble uses
+\code{\refmmz{memo dir}=chapters/book} (rather than \code{\refmmz{memo
+    dir}=book} or just \refmmz{memo dir}).  However, Memoize has no trouble
+with a situation where the main file and the chapters reside in the same
+folder; the setup is even simpler, as we then say \code{\refmmz{memo dir}=book}
+in both the book and the chapter preamble.  The more complicated situation was
+chosen to point out the following potential problem with the setup where the
+chapters reside in a subdirectory.
+
+If you're anything like me, you would first go for having a memo directory
+immediately contained in the project directory (so |examples/book.memo.dir|
+above) and set up \refmmz{memo dir} as shown below.  Well, this won't work, or
+at least it won't work with the vanilla \hologo{TeX} Live, because \hologo{TeX}
+will refuse to \emph{write} into (memo) files outside the directory where it
+was executed,\cprotect\footnote{In \hologo{TeX} Live, the \reffile{texmf.cnf}
+  option controlling this behaviour is called |openout_any|.  By default, it is
+  set to |p| (paranoid), which ``disallow[s] opening dot files [and]
+  \emph{going to parent directories}, and restrict[s] absolute paths to be
+  under \texttt{\$TEXMFOUTPUT}'' (emphasis mine).}  and this is precisely what
+the chapter compilation is asked to do below.
+
+\begin{tcboxedraster}[raster columns=2, raster valign=top]{blankest, bad}
+  \begin{tcblisting}{example title, title=the main file, listing only}
+\mmzset{~memo dir=book~}
+% ...
+\input{chapters/chapter1.tex}
+  \end{tcblisting}
+  \begin{tcblisting}{example title, title=a chapter file, listing only}
+\mmzset{~memo dir=../book~}
+  \end{tcblisting}
+\end{tcboxedraster}
+
+\pagebreak % manual
+
+Section~\ref{sec:tut:working-on-a-picture} presented some ideas on how to work
+on a single picture.  Those ideas can be all easily applied to the multi-file
+situation.  For example, you could use \refmmz{readonly} on the chapter that you're
+working on (and that chapter only).  This way, the preview of the chapter will
+not be tarnished by the extern pages, and if you periodically compile it
+without \refmmz{readonly}, or compile the book (which does not have the \refmmz{readonly}
+set), you will have a reasonably up-to-date set of externs.
+
+\begin{tcboxedraster}[raster columns=2, raster valign=top]{blankest}
+  \begin{tcblisting}{example title, title=the main file, listing only}
+\mmzset{memo dir=chapters/book}
+% ...
+\input{chapters/chapter1.tex}
+  \end{tcblisting}
+  \begin{tcblisting}{example title, title=the current chapter file, listing only}
+\mmzset{memo dir=book, ~readonly~}
+  \end{tcblisting}
+\end{tcboxedraster}
+
+\ExampleName{memoize.cfg._region_}
+\makeexample{\examplename.tex.c1}
+\begin{tcolorbox}[title=For \Emacs users]
+  I often use this \refmmz{readonly} trick myself, but with a twist.  As an Emacs user,
+  I don't use a \hologo{TeX}-based mechanism (such as the \pkg{docmute} package) to
+  compile a chapter, but rely on the region compilation feature of Emacs'
+  AUC\hologo{TeX} package.  AUC\hologo{TeX} offers a way to compile the current
+  buffer (if you don't know what an Emacs buffer is, read ``file'') or region
+  (roughly speaking, the selected text).  It does that by putting the buffer or
+  the region into a file called |_region_.tex| while dressing it up in the
+  preamble of the original document (when I'm working on a multi-file document,
+  it correctly pulls the preamble from the main document).  This results in a
+  compilable region file.  My trick is to detect whether I'm compiling a region
+  (this is the job of |\ifregion|), and if so, put Memoize into the \refmmz{readonly}
+  mode (an alternative trick would be to \refmmz{disable} it).
+
+  This is the trick in a nutshell, but to make it really work we have to
+  address one further issue: the original document and the region have to share
+  memos and externs.  This happens automatically if the original document sets
+  \refmmz{memo dir} explicitly (e.g.\ if a document called |doc.tex| contains
+  \code{\refmmz{memo dir}=doc} in the preamble), but I'm lazy and don't want to
+  write this in every document --- if I have to do that, what's the point of
+  \refmmz{memo dir} I put into my \reffile{memoize.cfg} in
+  section~\ref{sec:tut:memodir}?  Fortunately, the region file starts with
+  |\message{ !name(|\meta{original document name}|.tex)}| to indicate the
+  origin.  The complicated part of the code below (everything following
+  \refcmd{mmzset}\braces{\refmmz{readonly}} parses this header to extract the
+  \meta{original document name}, which is then fed to \refmmz{memo dir}.  Now,
+  the trick works automatically for any document.\footnote{The assumption here
+    is that \refmmz{memo dir} is in effect for the original document.  If not,
+    the trick can be adapted to use (\refmmzpath{dir} and) \refmmzpath{prefix}
+    within \refmmz{path}.}
+
+  \tcbinputexample{
+    title=\tt memoize.cfg,
+    attachment name=memoize-region.cfg,
+    listing only,
+  }
+\end{tcolorbox}
+
+
+\subsection{Writing a presentation?}
+\label{sec:tut:beamer}
+
+Memoize ships with built-in support for the most widespread \hologo{LaTeX}
+presentation class, Beamer, in the sense that it can externalize a picture
+which changes from overlay to overlay.  Before we learn how to use that
+functionality, however, there's a peculiarity about loading Memoize in Beamer
+to address.
+
+\ExampleName{beamer}
+\makeexample{\examplename.pdf}
+
+\tcbinputexample{
+  comment and listing,
+  listing options app={lastline=2},
+  warning, no attachment, title=,
+  % 
+  comment={Beamer opens the document PDF while loading the class, while
+    Memoize requires the PDF from the previous compilation intact in order to
+    extract the externs (when extraction is triggered internally, which is the
+    default setting).  The solution is to load Memoize (a package) before
+    Beamer (a class), which can be done by using \cs{RequirePackage} instead of
+    the usual \cs{usepackage}. Easy, if hacky.},
+  %
+}
+
+To memoize a piece of code which produces different results on different
+overlays --- by virtue of containing |\pause|, |\only|, and\slash or related
+commands --- apply key \Emph{\refmmz{per overlay}}.  Without this key,
+externalization of the picture will end badly, with a single extern (the final
+one) appearing on all overlays.  The key may be invoked either from a prior
+\refcmd{mmznext} command,\footnote{Of course, \refmmz{per overlay} may also be
+  invoked from \refcmd{mmzset}, but I guess this won't make sense often.  For
+  example, if you set it for the entire presentation, and the presentation
+  contains static memoized pictures as well, you will compile those pictures
+  more times than necessary: once for each overlay, whereas once per frame
+  would suffice.  It might occasionally make sense, however, to use \refmmz{per
+    overlay} as an \refmmz{auto} option --- consult
+  section~\ref{sec:tut:verbatim} to learn what that is.}  or executed in the
+memoized code itself.  The example below illustrates the latter option, and
+also shows that we may invoke it via its full path,
+\refkeypath{/mmz}|/|\refmmz{per overlay}, when listed among options processed by
+\pkg{pgfkeys}.\footnote{Read section~\ref{sec:per-overlay} to learn how the
+  Beamer support is implemented.  The implementation only uses Memoize's public
+  interface, so understanding it should help if you need to support some other
+  presentation package.}
+
+\tcbinputexample{
+  listing options app={firstline=3},
+  middle=1mm,
+  comment={\def\dpwidth{0.27\linewidth}\def\epwidth{0.15\linewidth}%
+    \raisebox{-\height}{\includeexamplepdf[extern page,left=0mm,right=0mm]{width=\epwidth,page=1,trim=1in 1in 0.4in 0.6in}}\hfill
+    \raisebox{-\height}{\includeexamplepdf[document page,left=1mm,right=1mm]{page=2,width=\dpwidth}}\hfill
+    \raisebox{-\height}{\includeexamplepdf[extern page,left=0mm,right=0mm]{width=\epwidth,page=3,trim=1in 1in 0.4in 0.6in}}\hfill
+    \raisebox{-\height}{\includeexamplepdf[document page,left=1mm,right=1mm]{page=4,width=\dpwidth}}%
+  },
+}
+
+\begin{tcolorbox}[warning]
+  If the memoized code changes the value of Beamer's pause counter
+  |beamerpauses|, e.g.\ by issuing a |\pause|, take care that (i) \refmmz{per
+    overlay} is executed prior to any changes of |beamerpauses|, and that (ii)
+  the final value of this counter in the memoized code is the same for all
+  overlays.
+\end{tcolorbox}
+
+
+\subsection{When stuff sticks out}
+\label{sec:tut:padding}
+
+Some constructs --- like plain \hologo{TeX}'s \refcmd{llap} and \refcmd{rlap},
+and, notably, \TikZ overlays --- fool \hologo{TeX} into thinking that the
+``size'' of the typeset material is different than what it actually is.  This
+can cause trouble for externalization: a piece of your picture might disappear!
+In a sentence, the solution is to manually set the \emph{padding} of the
+externs, but let's slow down a bit.
+
+The \TikZ picture in the following example consists of node with a pin on the
+right, but let's say we want to horizontally center this picture so that only
+the node rather than the entire picture (including the pin) will be centered.
+This can be achieved by adding key \refkey{/tikz/overlay} to the pin (actually,
+we need to add it to both the pin and its edge).  \TikZ normally updates the
+extents (called the bounding box) of the picture every time it puts something
+in it; when \refkey{/tikz/overlay} is in effect, however, these updates are
+temporarily disabled.  In effect, the \refkey{/tikz/overlay} key on the pin
+below will fool \hologo{TeX} into thinking that the node is all there is to the
+picture, so centering will work as desired.
+
+\ExampleName{overlay}
+\makeexample{\examplename.pdf N=4}
+\tcbinputexample{
+  after title pre={\ (no memoization)},
+  comment={\centering
+    % \includeexamplepdf[document page]{page=1,trim=1.8in 7.4in 1.8in 1.7in}
+    \includeexamplepdf[document page]{page=1}
+  },
+}
+
+What happens when we try to externalize this picture?  The example below shows
+what would happen if Memoize had no concept of \emph{padding} --- which we
+simulate by setting \code{\refmmz{padding}=0pt}.\footnote{Unlike in the rest of
+  the manual, the extern pages in this section are shown without trimming the
+  whitespace.}  Along with the rest of \hologo{TeX}, Memoize would be fooled
+into thinking that the picture comprises of the node only, so the pin would
+never make it into the extern.  You would end up with a document missing the
+pin!\footnote{On the first compilation, the document page containing the figure
+  without padding looks fine, as it uses the result of the compilation rather
+  than the extern file.  But on the second compilation, when Memoize actually
+  uses the extern, the pin disappears.}
+
+\tcbinputexample[.tex][.c2]{
+  after title pre={\ (memoization without padding)},
+  attachment name=\examplename-no-padding.tex,
+  sidebyside, lefthand ratio=0.3,
+  comment={\centering
+    \includeexamplepdf[size=minimal,boxrule=0.5mm,extern page,
+      attach boxed title to top right={xshift=1.5mm,yshift=-1mm},
+    ]{page=1}
+  },
+}
+
+
+By default, Memoize puts an inch of space around (what it thinks is) the
+externalized picture, and if the overlayed parts of the picture fit into this
+inch of space, you will find them in the extern and therefore also in the
+document.  In our example, however, the default padding is not enough --- the
+pin is only partially visible.\footnote{You might wonder why I didn't make the
+  default padding much bigger, like 10 inches.  \hologo{TeX} wouldn't be
+  bothered (unless the resulting extern size exceeded its maximum dimension),
+  but you might be, because with such a large default padding, all the externs
+  would be huge, most often bigger than the document pages, and remember that
+  the externs are first dumped into the document, where they can bother you.}
+
+\tcbinputexample[.tex][.c3]{
+  after title pre={\ (memoization with default padding)},
+  attachment name=\examplename-default-padding.tex,
+  listing and comment,
+  middle=0.9mm,
+  comment={\centering
+    \includeexamplepdf[extern page,size=minimal,boxrule=0.5mm]{page=1}
+  },
+}
+
+The solution is to set the padding manually.  Below, I used \refmmz{padding
+  right} to only increase the padding on the right side (clearly, we also have
+\refmmz{padding left}, \refmmz{padding top} and \refmmz{padding bottom}), but
+if you're not bothered by a large extern, you can just use
+\Emph{\refmmz{padding}}, which sets all four sides at once.  By the way, having
+too much padding (almost) never hurts, and as you see, you can use (simple)
+arithmetics in the value of these keys.
+
+\tcbinputexample[.tex][.c4]{
+  after title pre={\ (memoization with extra padding)},
+  attachment name=\examplename-extra-padding.tex,
+  listing and comment,
+  middle=0.9mm,
+  comment={\centering
+    \includeexamplepdf[extern page,size=minimal,boxrule=0.5mm]{page=1}
+  },
+}
+
+\enlargethispage{1ex} % manual
+Incidentally, the \refmmz{padding} keys only change how
+the externalized picture is \emph{stored}.  Memoize remembers the size of the
+extern as seen by \hologo{TeX} (e.g.\ the bounding box of the picture as
+reported by \TikZ, with overlayed parts of the picture protruding out of it),
+and it uses that size when integrating the extern into the document --- so
+everything works as it should!
+
+
+
+\subsection{The verbatim mode}
+\label{sec:tut:verbatim}
+
+Not all code will peacefully submit to memoization.  In particular, this is the
+case for environments which process the environment body verbatim (or perform
+some other kind of \refcmd{catcode} magic).  A simple environment of this kind is the
+standard \hologo{LaTeX} \refenv{verbatim}, but let us illustrate the issue with
+\refenv{tcblisting}, which typesets a code listing alongside its compiled effect.
+(This environment is defined by the |listings| library of package \pkg{tcolorbox}
+and was used extensively during the production of this manual.)  To manually
+memoize a \refenv{tcblisting} environment, we enclose it in a \refenv{memoize}
+environment with a \Emph{\refmmz{verbatim}} key in the optional argument ---
+without this key, the example below would produce nothing but
+errors.\footnote{Memoize also offers a \emph{partial} verbatim mode, triggered
+  by key \refmmz{verb}; in this mode, the braces retain their usual category
+  codes.  Also note that the effect of \refmmz{verbatim} can be ``undone'' by
+  key \refmmz{no verbatim}.}
+
+\ExampleName{verbatim-manual}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside,
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}\\[1ex]
+    \footnotesize
+    (The document page is the same as for the \texttt{verbatim-auto} example below.)
+  },
+}
+
+Using \refmmz{verbatim} from \refcmd{mmzset} or \refcmd{mmznext} works just as
+well, and the latter can be very useful with automemoization, when some
+environment (say, \env{tcolorbox}) generally does not require the verbatim mode,
+but a specific occurrence does (say, because it contains some verbatim
+construction such as \verb!|!\meta{verbatim text}\verb!|! of the \pkg{ltxdoc}
+class).
+
+However, for an environment such as |tcblisting|, it makes the most sense to
+declare it verbatim in general, so that all instances of the environment will
+be processed in the verbatim mode.  This is simple to do: add \refmmz{verbatim}
+to the \refmmz{auto} keylist.
+
+\ExampleName{verbatim-auto}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside, % lefthand ratio=0.62,
+  comment={\centering
+    \footnotesize
+    (The extern page is the same as for the \texttt{verbatim-manual} example above.)\\[1ex]
+    \includeexamplepdf[document page]{page=2}\\
+  },
+}
+
+In fact, you can add any \refkeypath{/mmz} key to the \refmmz{auto} keylist,
+and the key will be applied to all occurrences of the command or the
+environment.  For example, adding \refmmz{recompile} to the declaration of
+|tcblisting| above would recompile all and only the |tcblisting| environments;
+and as an \refmmz{auto} declaration only updates (rather than completely
+replaces) a previous declaration, you can also say things like
+\code{\refmmz{auto}=\refcmd{tikz}\braces{\refmmz{recompile}}} to recompile all
+\TikZ pictures produced by the \cs{tikz} command (handy, as you don't know how
+automemoization for \cs{tikz} was declared unless you've read
+section~\ref{sec:tut:automemoization-details} or looked at the Memoize's source
+code).
+
+
+\subsection{The final version of your document}
+\label{sec:tut:final}
+
+Bluntly put, you might want to disable Memoize when compiling the final version
+of your document, at least if you intend to distribute it in electronic form,
+for two reasons:
+\begin{itemize}
+\item An externalized picture cannot contain hyperlinks.  Any hyperlinks (or
+  hyperlink anchors) contained in the original picture will silently disappear
+  during the production of the extern.
+\item When the document contains many externs, the size of the resulting PDF
+  can be several times the size of the PDF compiled without externalization.
+\end{itemize}
+
+Below, we list several ways of fully disabling Memoize.  You're of course
+already familar with the first two ways, but what's this \refpkg{nomemoize}
+package?  The rationale behind this package is that if you want to be
+absolutely sure that there is no trace of memoization in your document (for
+example, see the \refmmz{disable} -- \refmmz{enable} pitfall in
+section~\ref{sec:tut:working-on-a-picture}), the best thing to do is to not
+load the package at all.  However, you have all those \refcmd{mmzset}s etc.\ in
+your source, so the document won't compile without
+\cs{usepackage}\braces{\refpkg{memoize}}, right?  Right, but wrong.  Enter
+\Emph{\refpkg{nomemoize}}, a dummy package which accepts all the commands that
+Memoize does, but does nothing.  In effect, your document will compile, but you
+can be sure that not a single memo or extern was loaded or produced.
+
+\begin{tcbraster}[raster columns=3, raster force size=false, raster valign=top]
+  \begin{tcblisting}{listing only, add to width=2.4em, enhanced}
+\usepackage[~disable~]{memoize}
+  \end{tcblisting}
+  \begin{tcblisting}{listing only, add to width=-1.6em, enhanced}
+\usepackage{memoize}
+\mmzset{~disable~}
+  \end{tcblisting}
+  \begin{tcblisting}{listing only, add to width=-0.8em, enhanced}
+\usepackage{~no~memoize}
+  \end{tcblisting}
+\end{tcbraster}
+
+There is one issue you might need to resolve manually before package
+\refpkg{nomemoize} works as intended, though.  If you have used any
+\refkeypath{/mmz} keys outside \refcmd{mmzset}, you need to list them in
+\refcmd{nommzkeys}.  For example, if you used \refmmz{per overlay} in the manner
+illustrated in section~\ref{sec:tut:beamer}, i.e.\ as
+\refkeypath{/mmz}|/|\refmmz{per overlay} among the \TikZ keys, you need to
+write \refcmd{nommzkeys}\braces{\refmmz{per overlay}} into the document
+preamble.
+
+Another thing you might want to do once you have produced the final version of
+the document (in fact, just before you disable Memoize for good) is clean up.
+As we saw in sections~\ref{sec:tut:memodir} and~\ref{sec:tut:redefinitions},
+Memoize produces a lot of auxiliary files (memos and externs) and it keeps the
+old versions around!  Once your document is prepared, you can reduce the
+clutter (and save some disk space) by deleting memos and externs belonging to
+the work-in-progress versions of your document, and keep only those used in the
+final version.
+
+You could achieve this by deleting all the memos and externs (if you're using
+the \refmmz{memo dir} directive, this amounts to the entire contents of the
+memo directory) and compiling your document for the final couple of times.
+However, there is an easier (but \hologo{TeX}-external) way: on the command
+line, change into the directory containing your (main) document and write
+\EmphTT{\refscript{memoize-clean.pl}} \meta{document name}\dmmz (substitute
+|.py| for |.pl| to use Python rather than Perl). The script will inspect the
+contents of the \dmmz record file to see which memos and externs were used in
+the final compilation, and delete all other memos and externs belonging to the
+given document.
+
+\begin{tcolorbox}[warning]
+  Deleting memos and externs is never an irreversible operation, as you can
+  always recreate them, but it is still wise to be cautious when cleaning up.
+  For one, avoid cleaning up after a compilation which produced errors; a
+  failed compilation can lead to an incomplete \dmmz file, which can in turn
+  lead to over-deletion.  Another bad idea is cleaning up after disabling
+  Memoize for a part of a document, for the same reason.
+
+  All that said, Memoize takes some precautions itself.  It will cowardly
+  refuse to perform the clean-up when the \dmmz file is missing the
+  end-of-file marker (|\endinput|), assuming that this indicates a fatal error
+  in the previous compilation.  It will do the same in case the \dmmz file is
+  absent or empty.  The latter is assumed to be a result of a globally
+  \refmmz{disable}d memoization, but note that clean-up will be performed if
+  memoization was disabled using package \refpkg{nomemoize}: that package does not
+  touch the \dmmz file, so cleaning up should work as intended.
+\end{tcolorbox}
+
+As the final note, memos and externs (cleaned-up or not) may be copied (along
+the document source) to another directory or machine, where they should be
+picked up by Memoize.  There is no need to copy the \dmmz file (assuming that
+the document PDF contains no extern pages waiting for extraction).
+
+
+\section{Digging deeper}
+\label{sec:potential-pitfalls}
+
+
+
+\subsection{Good to know}
+\label{sec:tut:good-to-know}
+
+
+\paragraph{Line- and page-breaking} An extern can't be broken across lines or
+pages.
+
+Externalization of a chunk of code produces a PDF, which is included into the
+document at subsequent compilations as a picture --- an unbreakable object (a
+horizontal box) with fixed width and height.  Therefore, the original code
+should produce an unbreakable object as well.  For example, this means that you
+cannot externalize some text and expect \hologo{TeX} to break it across lines
+or pages on subsequent compilations.  If you try, the compilation will succeed
+--- without an error!  --- but your externalized text will end up in a single
+line, as shown below.
+
+\ExampleName{no-linebreaking}
+\makeexample{\examplename.pdf N=2}
+\tcbinputexample{
+  bad,
+  comment={\centering
+    \includeexamplepdf[extern page,to be continued on right]
+      {page=1,trim=1in 1in 14in 1in}\\[1ex]    
+    \includeexamplepdf[document page]{page=2}\\[1ex]
+    \includeexamplepdf[document page,title=the expected document page]
+                      [\examplepath.c2.pdf]{page=1}
+  },
+}
+
+That said, you \emph{can} externalize a paragraph or some other vertical mode
+material using \refmmz{capture}|=|\refmmz{capture=vbox}, but beware that the
+vertical spacing between the memoized material and its surroundings might
+change.
+
+
+\paragraph{\env{remember picture}}
+\TikZ pictures using this key cannot be externalized.
+
+Memoize will silently refuse to externalize any \TikZ picture using
+\refkey{/tikz/remember picture} (see \PGFmanual{17.13}).  Such pictures
+interact with the outside world --- they either reference or are referenced by
+other pictures --- and are as such unsuitable for externalization.  For
+example, while the colored boxes in this manual are generally externalized ---
+out of principle \Smiley\ --- the title page illustration is not, and it cannot
+be, because of the arrows connecting the various \TikZ pictures composing that
+illustration.  Some packages use the \refkey{/tikz/remember picture} mechanism
+under the hood, and are thus subject to this limitation; one example is package
+\pkg{todonotes}, but in general, any package dealing with absolute positions on the
+page will be limited in this way.
+
+How does Memoize deal with this situation?  Well, by cowardly refusing to
+externalize any code which uses \refkey{/tikz/remember picture} or a similar
+mechanism for dealing with absolute positions.  Luckily, any such mechanism
+eventually boils down to the \hologo{TeX} primitive \refcmd{savepos}, so
+Memoize hacks --- or as we will say in this manual, \emph{advises} --- this
+primitive to abort any ongoing memoization.  Initializing and then aborting the
+memoization takes some time, to be sure, but the overhead is negligible,
+especially in the light of the fact that \emph{not} aborting wreaks real havoc.
+
+Memoize actually provides a user interface for aborting memoization.
+Memoization can be aborted either manually, by executing \refcmd{mmzAbort}, or
+automatically.  The latter is a generalization of the automemoization idea: a
+command such as \refcmd{savepos} can be advised to abort memoization by
+\refmmz{auto}|=|\refcmd{savepos}\bracestt{\refmmzauto{abort}}.  In Memoize,
+commands take your advice seriously, so memoization will be aborted whenever
+the advised command or environment is encountered.
+
+
+\paragraph{Indirectly embedded environments} Such environments cannot be
+memoized.
+
+Read this if you got an error message such as |Environment "tikzpicture" ended
+as "foo"|.
+
+Some environments are defined so that they embed another environment using the
+idiom shown on the left: the begin-code of the outer environment opens the
+inner environment, and the end-code of the outer environment closes the inner
+environment.  While this is a fine, and common, idiom, it messes up the
+memoization of the inner environment. In the example on the right, trying to
+\emph{auto}memoize a \env{minipage} environment (not recommended at all!) causes
+trouble with package \pkg{sectionbox}.\footnote{This is a \texttt{Package
+    collargs Error} because Memoize outsources the actual work of collecting
+  the environment body to the auxiliary package CollArgs, described in
+  section~\ref{sec:collargs}.}\fncomma\cprotect\footnote{Why does this happen?
+  As mentioned in section~\ref{sec:tut:memodir}, Memoize keeps track of memos
+  and externs by the MD5 sum of the memoized code.  But to compute that sum for
+  an environment, Memoize has to \emph{grab} the environment body, meaning it
+  has to collect the body in advance.  This presents no problem when
+  \refcmd{end}\meta{environment name} is already present in the input stream at the
+time \refcmd{begin}\meta{environment name} is executed, like when you use the
+  environment normally in your document, or when some macro expands so that it
+  produces both \cs{begin}\meta{environment name} and \cs{end}\meta{environment
+    name} simultaneously --- so there would be no problem above if
+  |\end{minipage}| occured in the beginning code of \env{sectionbox}.  The idiom
+presented above is problematic for memoization because at the time \hologo{TeX}
+executes |\begin{sectionbox}|, putting |\begin{minipage}| into the input
+    stream, |\end{sectionbox}| is not yet executed and remains as it is.  The
+  input stream therefore contains a pair of |\begin{minipage}| and
+    |\end{sectionbox}|.  In the normal, non-memoizing course of events this
+  would not be a problem, because |\end{sectionbox}| would eventually expand to
+|\end{minipage}|.  During memoization, however, this \emph{is} a problem,
+because, as we said, Memoize needs to grab the environment body: upon
+encountering |\begin{minipage}|, it looks in the input stream for
+  |\end{minipage}| --- but there is no |\end{minipage}| in the input stream,
+there is only |\end{sectionbox}|, and this results in the |Environment
+"minipage" ended as "sectionbox"| error.}
+
+\begingroup
+\ExampleName{sectionbox}
+\makeexample{\examplename.tex.c1}
+\mmzset{disable}
+\begin{tcbraster}[raster equal height]
+\begin{tcblisting}{listing only, bad, valign=center}
+\newenvironment{foo}% ... args
+{% the begin-code of foo
+  % ...
+  \begin{tikzpicture}
+  % ...
+}
+{% the end-code of foo
+  % ...
+  \end{tikzpicture}
+  % ...
+}  
+\end{tcblisting}
+\tcbinputexample{
+    bad,
+    comment={\small\tt
+      ! Package collargs Error: Environment\\"minipage" ended as "sectionbox".
+    },
+  }
+\end{tcbraster}
+\endgroup
+
+What are your options in this kind of a situation?
+\begin{enumerate}
+\item The only way to perform any memoization here is to memoize the
+  \emph{outer} environment --- if that makes sense.\footnote{This avoids the
+    error because Memoize grabs and memoizes the outer environment, and while
+    it is memoizing it, further memoization is switched off.}  You can do this
+  either on a case-by-case basis, by enclosing it in the \refenv{memoize}
+  environment, or automemoize it: \code{\refmmz{auto}=\marg{outer
+      environment}\braces{\refmmzauto{memoize}}}.  
+\item But what if memoizing the outer environment is out of the question?
+  Then, the only way to avoid the error is to prevent the automemoization of
+  the inner environment.
+  \begin{enumerate}
+  \item If you are facing a single occurrence of the problem, it is perhaps
+    easiest to use key \refmmz{disable} just before the start of the outer
+    environment.
+  \item Otherwise, you can automatically disable memoization for the span of
+    each occurrence of the outer environment: \code{\refmmz{auto}=\marg{outer
+        environment}%
+      \braces{\refmmzauto{nomemoize}}}.
+  \item To deactivate the automemoization of the inner environment for the span
+    of the outer environment, but otherwise allow for memoization inside the
+    outer environment: \code{\refmmz{auto}=\marg{outer environment}%
+      \braces{\refmmzauto{noop}, \refmmz{deactivate}=\meta{inner
+          environment}}}. Key \refmmzauto{noop} does nothing but apply the
+    given options (in this case, \refmmz{deactivate}=\meta{inner environment})
+    to the advised command or environment.
+  \end{enumerate}
+\end{enumerate}
+
+\subsection{Extraction methods and modes}
+\label{sec:extraction}
+
+Remember that in Memoize, externalization is a two-step process.  First,
+externs are typeset on separate pages of the main document, called extern
+pages.  Then, these extern pages are extracted out of the main document PDF
+into extern files.  The process is illustrated on the title page.
+
+Memoize is flexible in terms of which piece of software is used to perform
+extern extraction.  It ships with three \emph{extraction methods}:
+
+\begin{description}
+\item[\refmmz{extract=perl}] A Perl script, \refscript{memoize-extract.pl}.
+  This method is the default because it is fast and because Perl is usually
+  already installed on a system running \hologo{TeX}.  However, you will most
+  likely still need to install two pieces of software that the script depends
+  on: Perl libraries \hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2} and
+  the \hreftt{https://metacpan.org/pod/Path::Class}{Path::Class}, the
+  installation guidelines can be found in section~\ref{sec:install}.
+\item[\refmmz{extract=python}] A Python script, \refscript{memoize-extract.py}.
+  This method is even faster than the Perl script, though not by much.  Try it
+  out if you have problems installing Perl or the required libraries, or if the
+  Perl script chokes on your document (see section~\ref{sec:troubleshooting}
+  for the list of known issues).  Besides Python ($\geq 3.8$), you will also
+  need the Python library \hreftt{https://pypi.org/project/pdfrw/}{pdfrw} or
+  \hreftt{https://pypi.org/project/pdfrw2/}{pdfrw2}.  For the installation
+  guidelines, see section~\ref{sec:install}.
+\item[\refmmz{extract=tex}] \hologo{TeX}-based extraction requires no
+  additional software, but it is much slower than the scripts.  As \hologo{TeX}
+  can only produce a single PDF per compilation, an instance of \hologo{TeX}
+  (loading the entire document PDF) has to be invoked for each extern, and this
+  takes time (although the entire process is still much faster than the
+  venerable \TikZ externalization library).
+\end{description}
+
+Memoize is also flexible in terms of how extern extraction is triggered,
+providing two \emph{extraction modes}:
+
+\begin{description}
+\item[internal]\label{item:setup:who} By default, extern extraction is
+  triggered internally, i.e.\ by Memoize during the compilation of the
+  document; more precisely, any externs produced in a compilation are extracted
+  during the next compilation.  To choose an extraction method other than the
+  default Perl script, load Memoize with the package option
+  \EmphTT{\refmmz{extract}=\meta{extraction method}}.
+
+\item[external] Loading Memoize with with package option
+  \EmphTT{\refmmz{extract}=\refmmz{extract=no}} instructs Memoize to \emph{not}
+  trigger the (internal) extraction.  When instructed to use extraction
+  ``method'' \refmmz{extract=no}, Memoize expects you to trigger the extraction
+  yourself, in any way that is convenient to you: manually from the command
+  line, or automatically through your editor, a Makefile, etc.  --- all Memoize
+  cares about is that the extraction takes place before the next compilation of
+  the document.
+\end{description}
+
+Summing up, the extraction mode and method are selected by providing the
+appropriate value to package option key \refmmz{extract}; the possible values
+are listed in the table below.  Note that this key can only be used as a
+package option, or in \refcmd{mmzset} within \reffile{memoize.cfg}.  In
+particular, it is disabled in the document preamble, because Memoize performs
+extraction while it is loaded.
+
+\medskip
+\begin{center}
+  \begin{tabular}{lll}
+    \toprule
+    extraction method&external program&Memoize invocation\\
+    \midrule
+    \refmmz{extract=perl}&\refscript{memoize-extract.pl}&\refcmd{usepackage}\braces{\refpkg{memoize}}\footnotemark\\
+    \refmmz{extract=python}&\refscript{memoize-extract.py}&\refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=python}}\braces{\refpkg{memoize}}\\
+    \refmmz{extract=tex}&|pdftex|&\refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=tex}}\braces{\refpkg{memoize}}\\
+    \refmmz{extract=no}&none (external extraction)&\refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=no}}\braces{\refpkg{memoize}}\\
+    \bottomrule
+  \end{tabular}%
+  \footnotetext{Or
+    \refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=perl}}%
+    \braces{\refpkg{memoize}}.  This is useful if you have changed the default
+    using \reffile{memoize.cfg}.}%
+\end{center}
+\smallskip
+
+For internal extraction, \hologo{TeX} must be allowed to execute the external
+program implementing the chosen extraction method.  Both |memoize-extract|
+scripts should be listed among restricted shell escape mode commands in your
+\hologo{TeX} distribution; their execution should therefore be allowed under
+the default, restricted shell escape mode.  However, the |pdftex| program,
+executed by extraction method \refmmz{extract=tex}, is not listed there, nor
+should it be.  If you are forced to use this fallback method, I suggest you
+compile documents loading Memoize under the full shell escape mode, by adding
+command-line option \docref{-shell-escape} (on \hologo{TeX}Live) or
+\docref{--enable-write18} (on MiK\hologo{TeX}) to the invocation of the
+\hologo{TeX} program.  The answers linked from question
+``\href{https://tex.stackexchange.com/q/598818/16819}{How can I enable
+  shell-escape?}''  on \href{https://tex.stackexchange.com}{\hologo{TeX}
+  StackExchange} will tell you how you can ask your editor to do this for you.
+  
+You may use any extraction method to perform external extraction.  The simplest
+option is to use the Perl or the Python script.  Supposing you are doing this
+manually from the command line, change into the directory containing your
+document, which should contain the auxiliary \dmmz file produced by Memoize,
+and execute:
+  
+\begin{enumerate}[(a)]
+\item \refscript{memoize-extract.pl} \meta{document name}\dmmz \hfill (for
+  the Perl script)
+\item \refscript{memoize-extract.py} \meta{document name}\dmmz \hfill (for
+  the Python script)
+\end{enumerate}
+
+See sections~\ref{sec:.mmz} and \ref{sec:ref:extraction-perl-python} for
+further details on the \dmmz file and the extraction scripts.
+
+Things are a bit more complicated if you want to use the \hologo{TeX}-based
+extraction method externally, because an instance of |pdftex| needs to be
+invoked for each extern (and these have unwieldy names and can be many in
+number), but Memoize can help you here by producing a shell script or a
+makefile, executing which will extract all the externs at once. To have Memoize
+produce a shell script, use package option
+\code{\refmmz{record}=\refmmz{record=sh}} (or
+\code{\refmmz{record}=\refmmz{record=bat}} on Windows); package option
+\code{\refmmz{record}=\refmmz{record=makefile}} will make a makefile.  By
+default, these files are named |memoize-extract.|\meta{document name} plus the
+|.sh|, |.bat| or |.makefile| suffix.  If neither a shell script nor a makefile
+works for you, you can also define your own kind of \emph{record file}, to be
+processed by the external tool of your choice (and implementation) in order to
+extract the externs; see section~\ref{sec:new-record-file} to learn how to do
+this.
+
+
+\subsection{From cross-references to the context}
+\label{sec:cross-referencing}
+
+Cross-referencing presents a challenge to externalization, because without
+special provisions, the ``communication channel'' between the \cs{label} and the
+\cs{ref} is broken once we start utilizing the extern.
+
+One direction of the issue occurs when a \refcmd{label} within the memoized
+code is referenced by a \cs{ref} on the outside.  Without the (built-in)
+workaround, the \cs{label} command would only be executed when the extern is
+being produced, but not on subsequent compilations of the document, when it is
+merely included.  Memoize addresses this problem by generalizing
+externalization (which can only produce a picture, the extern) to memoization
+(which can additionally produce arbitrary code).  When Memoize is externalizing
+code which contains a \cs{label}, it automatically replicates it into the
+\emph{memo}, which is input into the document on subsequent compilations. In
+effect, the memo--extern team will continue to produce the label even when it
+is utilized rather than compiled.  As far as the author is concerned, \cs{label}s
+in memoized code ``just work,'' without any observable differences to the
+situation without memoization.  This is why we will not discuss this direction
+of the issue here; a reader interested in how precisely the system works is
+invited to read section~\ref{sec:memos}.
+
+The other direction of the issue occurs when a \refcmd{ref} within the memoized
+code references \cs{label} on the outside.  In this situation, the extern
+should be recompiled when the value of the label it refers to changes.  Again,
+Memoize addresses this problem in full generality, by associating with each
+extern a \emph{context}, and recompiling the extern whenever the value of the
+context changes.\footnote{The dependency of an extern upon prior definitions
+  and such can also be addressed in a more \emph{ad hoc} manner, by recompiling
+  manually; we have already touched upon this subject in
+  section~\ref{sec:tut:working-on-a-picture}, and will revisit it in
+  section~\ref{sec:tut:redefinitions}.}  All that needs to be done for \cs{ref}
+and friends, specifically, is to advise them to add their reference keys to the
+context.
+
+As we shall see presently, for the author, the only difference between a
+non-memoized and a memoized \cs{ref} is that the latter will take one more
+compilation cycle to ``stabilize'' the resulting document.  (More precisely,
+the memoized situation will take one more cycle if the reference is undefined
+on the first compilation.)  Then, we will show how we can teach Memoize about
+cross-referencing commands other than \cs{ref} and \cs{pageref}.  Finally, we will
+learn about key \refmmz{context}, the backbone of the cross-referencing support
+in Memoize.  (The inner workings of the context are further explained in
+section~\ref{sec:c-memos}.)
+
+\ExampleName{ref}
+\makeexample{\examplename.pdf N=7}
+
+When the memoized code contains a \cs{ref} referring to a label given in another
+part of the document, the code is recompiled when (and only when) the reference
+changes.  Let us look at the following example, jumping in at the point where
+it was already compiled enough times that the resulting PDF had stabilized into
+a single (document) page with correct references.  (Environment
+\refenv{nomemoize} disables memoization
+of \href{https://ctan.org/pkg/tikzlings}{Ti\emph{k}Zlings}, so that their
+externs don't disturb us, and we can focus on the \cs{tikz} command, which does
+get externalized and contains a \cs{ref}.)
+
+\tcbinputexample[.tex][.c3]{
+  after title pre={\ (with stable output after three compilations)},
+  middle=1mm,
+  comment={\centering
+    \includeexamplepdf[document page]{page=1}
+  }
+}
+
+Let us add an owl in front of the penguin.  In the next compilation, neither
+the ``normal'' nor the memoized reference is yet updated, as expected --- in
+this compilation, the new value of the penguin label only makes it into the
+|.aux| file.
+
+\tcbinputexample[.tex][.c4]{
+  after title pre={\ (after the first compilation with the added owl)},
+  no attachment,
+  comment={\centering
+    \includeexamplepdf[document page]{page=1}
+  }
+}
+
+During the following compilation, the \refcmd{ref}s pick up the new value of the
+penguin label, and the \cs{ref} inside the automemoized \cs{tikz} command
+forces recompilation of the extern (\emph{how} this is done will be explained
+later).
+
+\tcbinputexample[.tex][.c5]{
+  after title pre={\ (after the second compilation with the added owl)},
+  comment only, no attachment,
+  comment={\centering
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}\quad
+    \includeexamplepdf[document page]{page=2}
+  }
+}
+
+In the next compilation, the resulting PDF is finally stabilized, as the
+updated extern is (extracted and) included into the document.  
+
+\tcbinputexample[.tex][.c6]{
+  after title pre={\ (after the third compilation with the added owl)},
+  comment only, no attachment,
+  comment={\centering
+    \includeexamplepdf[document page]{page=1}
+  }
+}
+
+The message to take home?  When some memoized code contains a reference and
+that reference changes, it will take three compilation cycles (so, one more
+cycle than without memoization) for the resulting document to ``stabilize.''
+
+Out of the box, Memoize supports the standard \hologo{LaTeX} cross-referencing
+commands \cs{ref} and \refcmd{pageref}.  To automatically recompile code
+containing some other cross-referencing command, like \refcmd{vref} of package
+\pkg{varioref}, we use the advising framework implemented by package Advice.
+This framework is a generalization of automemoization: we use the familiar
+\refmmz{auto}, but with advice offered by \Emph{\refmmzauto{ref}} rather than
+\refmmzauto{memoize}.
+
+{\ExampleName{vref}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{listing only}}
+
+Key \refmmzauto{ref} only works for commands which operate on a single
+reference key.  However, that single key (which must be enclosed in braces) may
+be preceded by optional argumen(s) of any kind.  Extensions to \refcmd{ref},
+e.g.\ the \pkg{hyperref}'s variant, which accepts an optional |*|, work out of
+the box.  Furthermore, Memoize offers support for cross-referencing commands
+which work on multireferences and reference ranges, such as \pkg{cleveref}'s
+\refcmd{cref} and \refcmd{crefrange}.  Those commands should be advised by
+\refmmz{auto} keys \refmmzauto{multiref} and \refmmzauto{refrange},
+respectively.
+
+We have jumped into first example of this section with the assumption that it
+had already been compiled several times, allowing the resulting PDF to
+stabilize.  Let us now take a look at what happens at the very first, fresh
+compilation of our original example (the one without the owl).  (Removing the
+|.aux| file before compiling the example again will start afresh.)  The curious
+thing is that we don't get the extern page containing
+\tikz[baseline]\node[draw=red,thick,fill=yellow,anchor=base,font=\bf]{??};.
+This is so because by default, Memoize aborts a memoization containing an
+undefined reference.
+
+\tcbinputexample[.tex][.c1]{
+  after title pre={\ (after the fresh compilation of the original example)},
+  comment only, no attachment,
+  comment={\centering
+    \includeexamplepdf[document page]{page=2}
+  }
+}
+
+Now sometimes you might want to produce an extern even if it contains an
+undefined reference --- for example, you might intend to write the code
+containing the \cs{label} much later but enjoy the speed-up offered by Memoize
+until then.  In that case, apply the \refmmz{auto} key \Emph{\refmmzauto{force
+    ref}} to \cs{ref}.
+
+\tcbinputexample[.tex][.c7]{
+  after title pre={\ (after the fresh compilation with \refmmzauto{force ref})},
+  attachment name=\examplename-force.tex,
+  comment={\centering
+    \includeexamplepdf[extern page][\examplepath.c1.pdf]{page=1,trim=1in 1in 1in 1in}\quad
+    \includeexamplepdf[document page][\examplepath.c1.pdf]{page=2}
+  }
+}
+
+However, note that when you use \refmmzauto{force ref}, \hologo{LaTeX} will
+\emph{not} complain about the undefined reference once the extern containing it
+is included (unless that reference also occurs in some non-memoized piece of
+code).  Using \refmmzauto{force ref} is therefore a tiny bit dangerous, and
+this is why \refmmzauto{ref}, with the abortion mechanism, is the default
+handler for \cs{ref} and \refcmd{pageref}.
+
+As already noted in the previous section, \refcmd{ref} works by appending the
+cross-reference to the \emph{context}, the change of which triggers
+recompilation.  Memoize initializes the context to contain the four
+\refmmz{padding}s --- as a result, an extern recompiles if we change the
+padding --- but we can append stuff to the context by ourselves, as well.
+Below, we use key \Emph{\refmmz{context}} to append the font size (we'll talk
+about the value given to this key a bit later); as a result, the picture is
+recompiled whenever the font size changes.  Below, we change the font size
+using command |\small|; changing the default size with a class option such as
+|12pt| works as well.
+
+\ExampleName{fontsize}
+\makeexample{\examplename.pdf N=2}
+\tcbinputexample{
+  sidebyside, lefthand ratio=0.7, after title pre={\ (the first version)},
+  comment={
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}
+  }
+}
+
+\tcbinputexample[.tex][.c2]{
+  sidebyside, lefthand ratio=0.7, after title pre={\ (the second version)},
+  no attachment,
+  comment={
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in}
+  }
+}
+
+How does this work? Key \refmmz{context} appends the given tokens to the
+\emph{context expression}.  When creating an extern or trying to use it,
+Memoize (fully) expands this expression and computes the MD5 sum of the
+expansion.  This \emph{context MD5 sum} then serves as a part of the extern's
+filename (see sections~\ref{sec:tut:memodir} and~\ref{sec:memos}).  In effect,
+Memoize will only find (and utilize) the extern if \emph{the context MD5 sum
+  computed during (attempted) utilization matches the one computed during
+  memoization}.  
+
+As revealed by looking at the \hologo{LaTeX} source code, \hologo{LaTeX} holds
+the current font size in macro |\f at size|, and above, we have effectively added
+the contents of this macro to the context.  Now, why didn't we simply write
+\refmmz{context}|=\f at size|?  First, we used |\csname ... \endcsname| because we
+were under the normal \hologo{LaTeX} catcode regime, where |@| cannot be a part
+of the command name.  Of course, we could have temporarily changed the catcode
+of |@| using |\makeatletter| and |\makeatother|, but I would advise against
+that, because the approach does not work in general: it fails when key
+\refmmz{context} is used \emph{within} memoized code (we will explain why in
+section~\ref{sec:memos}).  Another reason why I recommend the |\csname
+... \endcsname| approach is that it does not result in an error when the
+control sequence is not defined (|\csname ... \endcsname| will expand to
+|\relax| then); this behaviour is handy for undefined cross-references, for
+example.  Second, why did I write |fsize={...}| around the control sequence?
+Well, because I'm being paranoid, really.  Writing \refmmz{context}|={\csname
+  f at size\endcsname}| would work just as well, but I like to explicitly
+``announce'' the value to prevent any possibility of a conflict with an
+alternative context.  Imagine that we don't use the ``announcements'' and we
+decide to add some other dimension instead of the font size to the context.
+Now if that dimension happened to have the same value as the font size, Memoize
+would incorrectly pick up the ``font size extern'' instead of producing a new
+one.
+
+It bears emphasizing that whatever you add to the context expression must be
+fully expandable, and also not merely declared as robust.  So writing
+\code{\refmmz{context}=\cs{ref}\marg{key}}, for example, would be unwise, since
+it would not work as intended when package \pkg{hyperref} is loaded.  (This
+package declares \refcmd{ref} as robust, so it won't expand to the
+cross-reference value.)  You have to look up where the cross-references are
+stored internally; the cross-reference for \meta{key} turns out to be stored in
+the internal control sequence |\r@|\meta{key}, so it is |\csname
+r@|\meta{key}|\endcsname| that the \refmmzauto{ref} handler actually appends to
+the context.
+
+The padding and font-size contexts are useful quite generally.  However, the
+context can be pretty command-specific, as well.  Consider the \pkg{skak}
+package used for typesetting chess games.  The board is drawn using command
+|\showboard|, but this command has no arguments, because it draws the state of
+the board that is reached by the moves given by command |\mainline|.  Memoizing
+|\showboard| as such will therefore yield the wrong result --- all the boards
+will be one and the same board!  The solution is to provide the correct
+context: we dig into the \pkg{skak} sources and realize that the current
+board is stored in macro |\csname chessgame.skak.mainline\endcsname|.
+
+\ExampleName{skak}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside, lefthand ratio=0.48,
+  comment={
+    \includeexamplepdf[extern page]{page=1,trim=1in 1in 1in 1in,scale=0.45}\quad
+    \includeexamplepdf[extern page]{page=2,trim=1in 1in 1in 1in,scale=0.45}
+  }
+}
+
+If you remove \code{\refmmz{context}=\bracestt{...}} from the code above, you
+will end up with a document where the final board drawn takes place of all the
+boards.  This is so because in that case, all externs are written into the same
+file, so the final extern overwrites the previous ones, but note that you will
+only observe this after the second compilation, when the externs are actually
+used.
+
+
+
+\subsection{More on redefinitions and stale externs}
+\label{sec:tut:redefinitions}
+
+In this subsection, we elaborate on an issue touched upon at the beginning of
+section~\ref{sec:tut:working-on-a-picture}: what happens if the memoized code
+depends on some macro or style which gets redefined?  The answer was
+``nothing,'' and one solution was to \refmmz{recompile} the code.  Let us take
+the example from that section a bit further.  We will propose no new solution
+or workaround, but deepen our understanding of the issue.
+
+\ExampleName{redefinitions}
+\makeexample{\examplename.pdf N=6}
+\tcbset{
+  recompile step/.style={
+    sidebyside, lefthand ratio=0.74, title=,
+    comment={\includeexamplepdf[blankest][\examplepath.c\theenumi.pdf]{#1}},
+    /utils/exec={\addtocounter{enumi}{1}},
+    enhanced, overlay app={\node[at=(frame.north west), font=\scriptsize, circle, fill=black!80!white, text=white, inner sep=1pt]{\theenumi};},
+  },
+}
+\begin{tcboxedraster}[raster columns=1]{%
+    title=Working on \texttt{\examplename.tex}, enhanced, breakable}
+  \setcounter{enumi}{0}%
+  \tcbox[blankest]{I like red. My emphasized nodes will have red background.}
+  \tcbinputexample[.tex][.c1]{recompile step={page=2}}
+  \tcbox[blankest]{Hmm, this particular node is really important,
+    let me put the text in italics as well!}
+  \tcbinputexample[.tex][.c2]{recompile step={page=2}, no attachment}
+  \tcbox[blankest]{You know what? Perhaps yellow background would work better
+    --- in general.}
+  \tcbinputexample[.tex][.c3]{recompile step={page=1}, bad, no attachment}
+  \tcbox[blankest]{How come my node is still red?!  Oh yes, I changed the
+    style, so I have to recompile the extern!}
+  \tcbinputexample[.tex][.c4]{recompile step={page=2}, no attachment}
+  \tcbox[blankest]{Ahh, yellow background, that's much better.  But you know
+    what, this double emphasis won't do after all, let me go back to the
+    upright shape.}
+  \tcbinputexample[.tex][.c5]{recompile step={page=1}, bad, no attachment}
+  \tcbox[blankest]{Red???!???!? Ok, I know that recompiling will help, but what
+    happened here?}
+  \tcbinputexample[.tex][.c6]{recompile step={page=2}, no attachment}
+\end{tcboxedraster}
+
+What happened is that the externs from steps~1 and~5 share the very same code.
+In step~1, this code was compiled when the red |emph| style was in effect, and
+that extern lingered and was eventually picked up again in step~5, Memoize
+having no idea that it is including an extern produced with the obsolete
+definition of the style.
+
+There are two points to this story.  First (and forgetting for a moment about
+the context, which we started discussing in
+section~\ref{sec:cross-referencing}), Memoize identifies externs (and memos) by
+the code that produced them --- or more precisely, by the MD5 sum of the code,
+as each piece of code has a unique (well, unique enough) MD5 sum.  Each extern
+is saved in a file whose name contains this MD5 sum; see
+section~\ref{sec:tut:memodir} for illustration.  Generally, this is a very
+useful feature.  You can move your picture to another location in the document,
+insert some other (externalized) picture in front of it, and so on, all without
+triggering recompilation of the extern(s).  (None of this is possible with
+\TikZ's externalization library, which identifies the externs by the order in
+which they appear in the document.)
+
+The downside of the MD5 sum approach is the potential pitfall illustrated
+above, and the downside comes about because of the second point of the story:
+Memoize does not attempt to delete the ``old'' externs.  (However, as described
+in section~\ref{sec:tut:memodir}, stale memos and externs can be easily removed
+using the \refscript{memoize-clean.pl} script.) That would be not only
+dangerous (as any deletion inherently is) but also potentially wasteful: what
+if you have only temporarily removed some code, or compiled only a portion of
+the document --- you surely wouldn't want your hard-won externs to disappear in
+such a situation!
+
+The pitfall described above applies to any command which depends on parameters
+which can be set prior to the invocation of the command, like \TikZ pictures,
+which depend on the settings given in \cs{tikzset}.  After customizing the
+settings, you will have to recompile the externs:
+\refcmd{mmznext}\braces{\refmmz{recompile}} is useful when you only have to
+recompile a single extern; use \refcmd{mmzset}\braces{\refmmz{recompile}}, or
+the package option \refmmz{recompile}, to recompile all externs in the
+document; and there is also the middle road: if you have changed only Forest's
+settings, you can write
+\code{\refmmz{auto}=\braces{forest}\braces{\refmmz{recompile}}} to recompile
+all and only the Forest trees.
+
+Above, we have seen the ``same code, same extern'' issue manifested ``through
+time,'' i.e.\ Memoize was (incorrectly) reusing externs produced in previous
+compilations, but the issue can also manifest ``through space.''  This can
+happen if the same code appears twice in the same document --- but, crucially,
+with some parameters which it depends on changed from one occurrence to the
+next.  Observe what happens in the following example, where the settings for
+|\progressbar| are changed by |\progressbarchange|.  After the first
+compilation, everything looks fine.  But as both extern pages were produced by
+the same code, they will be stored into the same file, the second one
+overwriting the first one.  The second compilation pulls in the externs --- or
+rather, the single extern --- resulting in the document containing the second
+progressbar in the place of the first one as well.
+
+\ExampleName{progressbar}
+\makeexample{\examplename.pdf N=2}
+\tcbinputexample{
+  bad, float,
+  comment={
+    \begin{tcbitemize}[raster columns=3,raster equal height,halign=center,valign=center]
+      \tcbitem[title=After 1\textsuperscript{st} compilation]
+      \includeexamplepdf[extern page,remember as=extern1]{page=1,trim=1in 1in 1in 1in}\\
+      \includeexamplepdf[extern page,remember as=extern2]{page=2,trim=1in 1in 1in 1in}\\
+      \includeexamplepdf[document page]{page=3}
+      \tcbitem[title=After extern extraction\vphantom{p\textsuperscript{nd}}]
+      \includeexamplepdf[my boxed title=the extern file,attach shifted boxed title to top right,remember as=externfile]{page=2,trim=1in 1in 1in 1in}
+      \tcbitem[title=After 2\textsuperscript{nd} compilation]
+      \includeexamplepdf[document page,remember as=doc][\examplepath.c2.pdf]{page=1}
+    \end{tcbitemize}
+    \begin{tikzpicture}[remember picture,overlay]
+      \draw[->, thick, red] (extern1.east) to[out=east, in=west] ([yshift=0.5ex]externfile.west);
+      \draw[->, thick, red] (extern2.east) to[out=east, in=west] ([yshift=-0.5ex]externfile.west);
+      \draw[->, thick, blue] (externfile.east) to[out=east, in=west] (doc.west);
+    \end{tikzpicture}
+  },
+}
+
+The same ``extern duplication'' can arise due to how a particular command is
+implemented.  Say we deactivate automemoization of Forest trees
+(\code{\refmmz{deactivate}=forest}), but keep on automemoizing \TikZ pictures.
+Forest uses \refenv{tikzpicture}\noprint{\refenv{forest}} under the hood (a
+lot); in particular, the tree itself is typeset as a \env{tikzpicture}
+environment.  But the code that typesets it is the same for all trees,
+regardless of their content (the actual content of the tree is hidden in
+various macros and boxes, rather than ``pasted'' into the \env{tikzpicture}).
+Consequently, the final tree of the document will overwrite all other trees in
+the document, just as the second (and thus final) progress bar overwrote the
+first one above.\footnote{That is assuming that \hologo{TeX} doesn't simply
+  spew a bunch of errors. This can happen as well.  In the interest of full
+  disclosure, compiling a Forest tree in the situation described above would
+  actually also produce --- but only in the first compilation --- a number of
+  small empty extern pages, one for each node of the tree.  A promise: Forest
+  will soon fully support Memoize and (among other things) avoid this pitfall.
+  But the principle will remain.}  Ouch!
+
+Generally speaking, this final sort of extern duplication issue can arise
+whenever we have an ``outer'' command that we don't want to (auto)memoize which
+uses an ``inner'' command that we \emph{do} want to automemoize.  The solution
+is to use the \refmmz{auto} key \refmmzauto{nomemoize} on the outer command;
+remember that this key disables memoization for the space of the command or
+environment.  For example, the correct way to ``deactivate'' automemoization of
+\env{forest} environments (but keep automemoizing \TikZ pictures) is
+\code{\refmmz{auto}=\bracestt{forest}\braces{\refmmzauto{nomemoize}}}.
+
+
+
+
+\subsection{Supporting Memoize in your package}
+\label{sec:tut:package}
+
+\subsubsection{Loading Memoize?}
+\label{sec:loading-memoize}
+
+So you want to support Memoize in your package? That's great!
+
+What form precisely this support will take of course depends on your package.
+For some commands, a simple \refmmz{auto} declaration will suffice; for other
+commands, you might need to write a dedicated \emph{memoization driver}, as
+explained in section~\ref{sec:memoization-drivers}.  However, one thing is
+clear: you \emph{don't} want to require Memoize's presence by
+\cs{RequirePackage}\braces{\refpkg{memoize}} in your package.  That would
+trigger memoization, but triggering memoization should be left at the sole
+discretion of the author.  The question is, if you're not allowed to load
+Memoize, how can you even issue the \refmmz{auto} declaration?
+
+Well, it's not that you really want to \emph{memoize} anything; you want to
+make the commands of your package \emph{memoizable}.  So:
+\cs{RequirePackage}\braces{\Emph{\refpkg{memoizable}}} --- and note that in
+`memoizable', the final `e' of `memoize' is dropped, apparently this is the
+correct way to spell it.
+
+Loading \refpkg{memoizable} does nothing if Memoize is already loaded, and
+behaves like package \refpkg{nomemoize} otherwise --- remember from
+section~\ref{sec:tut:final} that \refpkg{nomemoize} is a dummy package which
+accepts all the commands that Memoize does, but does nothing.
+
+I have decided to require that Memoize must be loaded before any package that
+supports it.  Allowing for an arbitrary loading order would complicate the
+implementation (and possibly even turn out to be problematic), and furthermore,
+Memoize likes to be loaded early anyaway, because it needs to be loaded before
+the document PDF is opened if it is to perform the embedded extern extraction.
+I don't think the ordering requirement will cause any problems --- let me know
+if it does!  --- but perhaps it is wise to inform the author about it in the
+documentation of your package (I did so at the end of
+section~\ref{sec:tut:automemoization}).  Anyway, I have enforced the
+requirement by raising an error and refusing to load the package in case
+Memoize detects \refpkg{memoizable} to be loaded.
+
+Note that the loading order requirement implies that you can use
+|\@ifpackageloaded{memoize}| to specifically react to the presence Memoize, if
+necessary.
+
+
+\subsubsection{Memoizable design}
+\label{sec:memoizable-design}
+
+Many commands and environments can be submitted to externalization with a
+single-line \refmmz{auto} declaration, as illustrated in
+section~\ref{sec:tut:automemoization}, perhaps requiring an addition to the
+context (section~\ref{sec:cross-referencing}), or some pre- or post-memoization
+code (section~\ref{sec:tut:beamer}).  In some situations, however, these simple
+approaches won't work.  Most often, this will happen when the extern must be
+integrated into the document in some special way.  For example, a command might
+internally create floating material, or surround the core typeset material with
+some stretchable space.\footnote{Commands and environments of package
+  \pkg{tcolorbox} exhibit both these issues (see \pkg{tcolorbox} options |float|,
+  |before| and |after|), and were in fact the inspiration for several technical
+  details of Memoize.}  None of these behaviours can be replicated by merely
+including the extern; with respect to the stretchable space, remember that an
+extern, being a picture, has fixed size, so if our extra space ended up in the
+extern, it would lose the stretchability.
+
+The key to successful memoization of problematic commands is their design.  In
+a nutshell, the idea is to \emph{break up the command's definition into two
+  parts, the outer command and the inner command, and only submit the inner
+  command to automemoization}.  We will illustrate this with a simple
+environment --- |poormansbox| --- which produces a potentially framed box of
+the given width, and surrounds this box with some configurable material --- by
+default, this material will be stretchable vertical space, and this will be the
+source of our memoization problem.  (In terms of user experience, the solution
+in this section will leave something to be desired, but we will revisit the
+example in section~\ref{sec:memoization-complex-single-driver} and make things
+right.)
+
+Let us first take a look at a document using our to-be-developed box
+environment.  The |poormansbox| environment takes one optional argument, a
+keylist of options, which can also be set with the |\pmbset| command.  This
+being a \textbf{p}oor \textbf{m}an's \textbf{b}ox, it doesn't recognize many
+options.  One can set the |width| of the box, or request that it occurs in a
+|frame|, and the surrounding material can be configured using keys |before| and
+|after|.  As we will see later in the listing of the package, the box is
+|\linewidth| wide by default, has no frame, and is surrounded by vertical glue
+|\vskip 2ex plus 1ex minus 1ex| (|2ex| of natural vertical space which may both
+stretch and shrink for |1ex|); furthermore, the default value of |before|
+contains |\centering| to center the box horizontally (centering is of course
+only observable when we change the width of the box).
+
+\ExampleName{poormansbox}
+\makeexample{\examplename.sty}
+\makeexample{\examplename.pdf}
+\tcbinputexample{
+  sidebyside, lefthand ratio=0.482,
+  comment={\centering
+    \includeexamplepdf[document page,left=0pt,right=0pt]
+                      {page=1,scale=0.5,trim=0mm 3mm 0mm 3mm}
+  },
+}
+
+You might want to play with the example to see that the surrounding vertical
+space is indeed stretchable.  The example is set up so that the surrounding
+space is shrunk a bit to fit all the material onto one page.  But if you remove
+the final |\lipsum[144]|, the natural amount of all vertical space can be
+accommodated on the page, so you should observe an increase of vertical
+spacing.
+
+You might have noticed that the example contains nested |poormansbox|es: the
+second box (the one which contains |\lipsum[66]|) is nested within the first
+one (between |\lipsum[101]| and |\lipsum[75]|).  This is intentional: when we
+will revisit the |poormansbox| example in
+section~\ref{sec:memoization-complex-single-driver}, the implementation will
+have to pay special attention to nesting (which presents no problem to the
+implementation in this section).
+
+As you can see in the package listing below (\texttt{\examplename.sty}), the
+implementation of our environment is straightforward.  We first define the
+configuration command |\pmbset| and the option keys (we're using
+\pkg{pgfkeys}), and set the option defaults.  Then, we move on to the
+environment itself: we apply the given options, execute the pre-code, typeset
+the box (which is a |minipage| of the given width, potentially wrapped in a
+|\fbox|), and execute the post-code.
+
+\tcbinputexample[.sty]{listing only, float}
+
+\ExampleName{poormansbox-memoizable}
+Now let's make our |poormansbox| externalizable (\texttt{\examplename.sty}).  As
+announced above, the idea is to split the definition of the environment into
+the outer part (below, the user-level environment |poormansbox|), which
+(applies the options and) executes the pre- and the post-code, and the inner
+part (below, the macro |\@poormansbox|), which typesets the actual box.  If we
+then then submit |\@poormansbox|, rather than |poormansbox|, to
+automemoization, the outer part will be executed at every compilation (giving
+us stretchable space if we request it), while the inner command will be
+executed (and memoized) at the first compilation, and substituted for the
+extern (the fixed-size box) at subsequent compilations.\cprotect\footnote{You
+  might have wondered why our definition of the |poormansbox| environment grabs
+  the body into an argument (|+b|, yielding |#2|), necessitating the use of
+  |\NewDocumentEnvironment| over the venerable |\newenvironment|.  One reason
+  was that having the environment body as an argument simplifies wrapping the
+  |\fbox| around the |minipage|, but there is a more important reason.  If we
+  did not grab the environment body, we would have to implement the internal
+  part of the definition as an environment (|@poormansbox|) as well, and embed
+  it into the user-level environment using the following idiom:
+  |\newenvironment{poormansbox}[2][]{...\begin{@poormansbox}}{\end{@poormansbox}...}|.
+  However, as illustrated in section~\ref{sec:tut:good-to-know}, automemoizing
+  an environment indirectly embedded in such a way produces an error, because
+  Memoize is prevented from collecting the environment body.}
+
+\makeexample{\examplename.sty}
+\makeexample{\examplename.pdf}% just to know if it compiles fine
+\tcbinputexample[.sty]{listing only, float}
+
+Looking at the definition of the internal |\@poormansbox| command, it might
+strike you as weird that we have equipped this command with an optional
+argument (|#1|) it never uses.  However, this optional argument is crucial for
+memoization.  It will become a part of the memoized code (note
+\code{\refmmzauto{args}=om} in the \refmmz{auto} declaration) and thereby
+ensure that Memoize will produce separate externs for invocations of
+|\@poormansbox| with the same environment body but different options; or in
+other words, it will ensure that changing the options recompiles the
+extern.\cprotect\footnote{Of course, this only holds for options given in the
+  optional arguments; if the user changes an option value using a prior
+  \cs{pmbset} (and that option does not occur in the optional argument),
+  Memoize won't detect the change.  But the end-user knows about this issue, as
+  it was addressed in sections~\ref{sec:tut:working-on-a-picture}
+  and~\ref{sec:tut:redefinitions}, and she is also aware of two workarounds:
+  manual recompilation, or setting the context
+  (section~\ref{sec:cross-referencing}).
+
+  While we're on the subject of the context, note that it is also possible to
+  deploy context to trigger recompilation of the inner command upon change of
+  parameters it depends on.  We could simply omit the optional argument of
+  \cs{@poormansbox} and add
+  \refmmz{context}|={width=\pmb at width,frame=\ifpmb at frame true\else false\fi}|,
+  to the \refmmz{auto} declaration.  The advantage of such an approach is that
+  Memoize reacts to the change of parameters regardless of whether they are set
+  using the optional argument or \cs{pmbset}.  However, the approach is
+  unfeasible for commands depending on many parameters: can you imagine listing
+  all the \TikZ options in the context?  Not to mention that a particular
+  picture usually only depends on a small subset of these options --- by and
+  large, \TikZ externs would get recompiled too often if the context contained
+  all \TikZ options.}\footnote{I have toyed with the idea of
+  splitting (using \pkg{pgfkeys} key filtering) the given options into outer
+  options, relevant for the outer command, and inner options, relevant for the
+  inner command, and only passing the inner options to the inner command.  The
+  thought was that would (i) avoid recompiling the extern when only outer
+  options change, as these options don't affect the inner command, and (ii)
+  avoid applying the inner options when utilizing the extern, as these options
+  don't affect the outer command.  However, it then hit me that the end-user
+  might define a style which incorporated both inner and outer options --- I
+  know I do this with my |tcolorbox|es.}
+
+The downside to automemoizing an internal command is that this might be
+counter-intuitive for the author.  For example, to deactivate automemoization
+of |poormansbox|, the author will have to write
+\refcmd{mmzset}\bracestt{\refmmz{deactivate}=\cs{@poormansbox}} (note the
+|\@|), but they will have no clue they have to do this unless they have
+carefully read |poormansbox|'s documentation.  Even worse, the above
+\refcmd{mmzset} command will not work unless surrounded by |\makeatletter| and
+|\makeatother|, as it refers to an internal control sequence containing |@|.
+Well, Memoize offers \refmmz{auto csname}, \refmmz{activate csname} and
+\refmmz{deactivate csname}, so that |@| catagory code manipulations can be
+omitted by writing \refcmd{mmzset}\bracestt{\refmmz{deactivate
+    csname}|=@poormansbox|}, but still.
+
+Another downside could occur when you use the same (automemoized) internal
+command in service of several user interface commands.  For the sake of
+illustration, assume we have also defined an UI-macro |\pmb| which again relies
+on |\@poormansbox|.  How is the author to deactivate automemoization of |\pmb|
+but leave the |poormansbox| environment intact?  This is how:
+\refcmd{mmzset}\bracestt{\refmmz{auto}=\cs{pmb}\bracestt{\refmmzauto{args}=m,
+    \refmmzauto{nomemoize}}}.  Again, counter-intuitive; the author expects
+\refcmd{mmzset}\bracestt{\refmmz{deactivate}=\cs{pmb}} to work.
+
+One other consequence of this approach is that the code included in the c-memo
+(if \refmmz{include source in cmemo} is in effect) will not faithfully reflect
+the source: as shown in the c-memo listing below, it will contain
+|\@poormansbox{...}| instead of |\begin{poormansbox}...\end{poormansbox}| ---
+even if this might actually count as an advantage, as the discrepancy will at
+least inform the author who refuses to read the fine material accompanying our
+|poormansbox| that something funky is going on.
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCMemo#1{% fetch the last c-memo filename
+  \def\mycmemo{#1}%
+}
+\input{\examplepath.mmz.c1}
+\sed{%
+  s/[]]\lbrace/]\n\space\space\space\space\space\space\space
+           \space\space\space\space\space\space\space\lbrace/;
+}{\exampledir\mycmemo}
+\tcbinputlisting{
+  listing only,
+  listing file=\exampledir\mycmemo,
+  example title,
+  title=the c-memo of the last \texttt{poormansbox} environment,
+  left=0.5em, right=0em,
+}
+\endgroup
+
+In a nutshell, automemoizing an internal command might be counter-intuitive for
+the author.  But the core idea --- to support memoization of a resistant
+command by splitting its definition into the outer and the inner command --- is
+sound, and we will elaborate on this idea in
+section~\ref{sec:memoization-complex-single-driver}, where we will revisit our
+|poormansbox| example and develop a variant of this environment which is both
+memoizable and user-friendly.
+
+
+\section{Under the hood}
+\label{sec:under-the-hood}
+
+This chapter is written for three audiences: a curious user who wants to
+know how Memoize does what it does; a package writer who wants to support
+Memoize in a tricky situation; and myself, lest I forget why I made the design
+decisions that I made.
+
+\subsection{The entry point}
+\label{sec:Memoize}
+
+
+From the author's perspective, the functionality of this package is entered
+either through the manual memoization commands (macro \refcmd{mmz} and
+environment \refenv{memoize}), or via automemoization.  And while that is
+correct, those user interface entry points merely determine what code is
+submitted to memoization, and set any options specific to the upcoming
+memoization.  The real fun starts with command \Emph{\refcmd{Memoize}}, which
+is eventually executed by both manual and automatic memoization.
+
+Not every call to \refcmd{Memoize} results in memoization.  Calling this macro
+has three possible outcomes.  It can result in \emph{memoization}, which
+produces the memos and externs; in \emph{utilization} of the result of an
+earlier memoization (which boils down to inputting the memos); or in
+\emph{regular compilation}, whereby the code is compiled
+(almost)\footnote{\label{fn:regular-compilation-almost}This is absolutely true
+  for memoized code which is ``contained'' in the sense of not peeking into the
+  input stream following the memoized code.  In general, code which fails to
+  satisfy this containment requirement is most likely simply not memoizable;
+  but there are borderline cases.  For example, \refcmd{ignorespaces} at the
+  end of some code will have the expected effect in the absence of Memoize, but
+  no effect when executed either during memoization or regular compilation
+  under Memoize, simply because it will hit some code belonging to Memoize
+  rather than the continuation of the document.  Memoize offers the
+  \refmmz{ignore spaces} provision to work around this specific problem.} as if
+Memoize was not there.  Which outcome obtains depends on several factors.  The
+decision logic is depicted below, and note that you can \refmmz{trace} the
+action on the terminal.
+
+\begin{center}
+  \begin{forest}
+    yes/.style={edge=->,edge label={node[font=\scriptsize,pos=0.4,left,#1]{yes}}},
+    no/.style={edge=->,edge label={node[font=\scriptsize,pos=0.4,right,#1]{no}}},
+    use/.style={content=utilization\\(of the cc-memo)\vphantom{dj},fill=orange,align=center},
+    memoize/.style={content=memoization\vphantom{dj},fill=green},
+    compile/.style={content=regular compilation\vphantom{dj},fill=emphcolor},
+    for tree={
+      l sep*=1.5,
+      if n children={0}{}{align=center},
+      child anchor=north,
+    },
+    [Is Memoize enabled?\\(\refcmd{ifmemoize}),
+      [Are we currently undergoing memoization?\\(\refcmd{ifmemoizing}), yes
+        [,compile, yes]
+        [Is the\\\refmmz{recompile}\\mode in effect?, no
+          [,memoize, yes]
+          [Do the relevant\\memos and externs exist?, no
+            [,use, yes]
+            [Is the\\\refmmz{readonly}\\mode in effect?,no
+              [,compile, yes]
+              [,memoize, no]
+            ]
+          ]
+        ]
+      ]
+      [,compile, no]
+    ]
+  \end{forest}
+\end{center}
+
+As the memoization options were already set by the user interface entry points,
+you might expect, quite reasonably, that \refcmd{Memoize} takes a single
+argument, the code submitted to memoization.  After all, what more does it
+need?  Clearly, executing this code is what produces the typeset material, and
+to detect whether the code has ``changed'' (in order to recompile the memos and
+externs), we compute the MD5 sum of this very code, don't we?  Well, the
+reality is a bit more complicated.  When it comes to automemoized commands, the
+code which the MD5 sum is computed off of (and which is displayed in the c-memo
+if \refmmz{include source in cmemo} is in effect) is not exactly the same as
+the code we compile (during either memoization or regular compilation).  We'll
+see what the difference is in section~\ref{sec:tut:automemoization-details};
+what matters here is that we must provide \refcmd{Memoize} with both and that
+this macro therefore takes two arguments: the \emph{identification code}, which
+the MD5 sum is computed off of, and the \emph{executable code}, which, well, is
+the code that gets executed during memoization (or regular compilation).
+
+Let's illustrate this with an example which is probably entirely useless (but
+don't worry, we'll get to a realistic example in
+section~\ref{sec:tut:automemoization-details}).  We first memoize some text
+manually, using command \refcmd{mmz}, and then do something very stupid: we use
+this very text as the identification code for the following \refcmd{Memoize},
+even if the executable code of that command is completely different.  The
+second line of the typeset output should convince you that the first argument
+to that command was really used to produce the extern; and one further
+compilation should convince you that the first argument was indeed used to
+identify the extern: the extern produced by \refcmd{mmz} was overwritten by the
+extern produced by \refcmd{Memoize}, in the fashion of the |progressbar|
+example from section~\ref{sec:tut:redefinitions}.
+
+\ExampleName{memoize-internal}
+\makeexample{\examplename.pdf N=2}
+\tcbinputexample{
+  comment={%
+    \includeexamplepdf[document page,
+      after title pre={\ (after the first compilation)}
+    ]{page=3}\hfill
+    \includeexamplepdf[document page,
+      after title pre={\ (after the second compilation)}
+    ][\examplepath.c2.pdf]{page=1}
+  },
+}
+
+The example above also illustrates a(nother) peculiar feature of
+\refcmd{Memoize}.  \refcmd{Memoize} does not open a new \hologo{TeX} group, but
+it \emph{expects a group to be opened prior to calling it}, as it will issue an
+|\endgroup| at some point.  Specifically, the memoization group will be closed
+before regular compilation or utilization, but after memoization.  If you want
+to know why, read the boxed text below.
+
+\begin{tcolorbox}[title=\string\Memoize\ and grouping, enhanced, breakable]
+  One important desideratum behind the design of Memoize was that using the
+  package should disrupt the original, Memoize-less compilation as little as
+  possible.  In particular, if the memoized code contains local assignments
+  whose effect (in the original compilation) persists into the rest of the
+  document (until the end of the surrounding \hologo{TeX} group, of course),
+  wouldn't one want these local effects to persist when Memoize is around, as
+  well?  Fortunately, most memoized code does not have persistent local effects
+  (at least for me, it is usually environments, like \env{tikzpicture}s, that I
+  want to memoize, and environments introduce a group anyway) --- fortunately,
+  because there are design reasons for enclosing memoization in a \hologo{TeX}
+  group (or two), and this enclosure will of course cancel the effect of local
+  assignments in the memoized code.
+
+  For one, the user interface memoization commands, such as \refcmd{mmz} and
+  automemoized commands, allow for options specific to a particular piece of
+  memoized code (the options given as the optional argument to manual
+  memoization, the next-options and the auto-options), and to delimit their
+  effect, it makes most sense to apply them in a group.  I have toyed with the
+  idea of working around the introduction of a group by manually saving and
+  restoring all the options, but I quickly gave up on this line of thought.
+  For one, manually saving and restoring the options would be cumbersome and
+  error-prone, and probably also slower than using the group.  But even worse,
+  all that work would not really solve the problem of the persistence of local
+  effects, because memoization itself introduces a group, as well: during
+  memoization, the typeset material is collected into a box, and opening a box
+  introduces a group.  In some particular situations, this could be avoided by
+  typesetting the memoized code as-is and collecting the resulting material
+  using |\lastbox|, but this approach cannot work in general.  In general,
+  memoization will take place in a group, so the issue of local effects must be
+  addressed in some other way.  Memoize offers the following workaround: during
+  memoization, the memoized code can (globally) add code to the \refmmz{after
+    memoization} hook, which gets executed immediately after closing the
+  memoization group.
+
+  Does this mean it would be best if the user interface memoization commands
+  straightforwardly surrounded \refcmd{Memoize} by |\begingroup| and
+  |\endgroup|?  For example, \refcmd{mmz} would open the memoization group, let
+  \refcmd{Memoize} do its work, and then close the group.  Not really.
+  Remember that memoization is not the only possible outcome of calling
+  \refcmd{Memoize}.  Perhaps we can at least retain the local effects of a
+  regular compilation, and of utilization?
+
+  We can, by finely tuning the timing of the memoization group closure within
+  \refcmd{Memoize}.  This command is designed to close the memoization group
+  after memoization, but before regular compilation and utilization.  Closing
+  the group after memoization makes sure that the given options are in effect
+  during this process.  By closing the group prior to regular compilation,
+  regular compilation of the memoized code (which takes place when Memoize is
+  disabled, for example) is guaranteed to have (almost, see
+  footnote~\ref{fn:regular-compilation-almost}) exactly the same effect as the
+  compilation of that code in absence of Memoize; in particular, the effect of
+  any local assignments will persist into the rest of the document.  Finally,
+  closing the group before utilization simplifies the construction of the memo
+  in the cases where we need to replicate local effects of the memoized code
+  --- the group closed, there is no need to smuggle local assignments out of a
+  memo.
+\end{tcolorbox}
+
+\subsection{Memos}
+\label{sec:memos}
+
+Up until now, we have pretended that there is a single kind of a memo file.  In
+truth, there's two kinds: \emph{code memos}, or \emph{c-memos} for short; and
+\emph{code--context memos}, or \emph{cc-memos} for short.  In this section, we
+will learn what they are for, and how they look like --- and also a bit on how
+they are produced, even if the details on that will have to wait until
+section~\ref{sec:memoization-drivers}.
+
+We will see that when Memoize utilizes memos, c-memos are processed first.  But
+conceptually, cc-memos are more important, so we will start the discussion with
+these.
+
+\subsubsection{Cc-memos (and extern inclusion)}
+\label{sec:cc-memos}
+
+When it is input, a cc-memo replicates the effect of the memoized code.  This
+includes the reproduction of its visual output, which takes the form of
+inclusion of any externs produced by memoization.  And yes, you got the
+implication right: a cc-memo can have any number of associated externs,
+including zero, even if the most common case is that of exactly one extern per
+cc-memo.  The number of externs mostly depends on the memoization driver (see
+section~\ref{sec:memoization-drivers}); the default driver always produces
+exactly one extern.
+
+A cc-memo is located in the directory given via subkey \refmmzpath{dir} (and
+\refmmzpath{relative}) of key \refmmz{path}.  You can recognize it by its filename,
+which has the following form (\meta{prefix} is set via subkey \refmmzpath{prefix}):
+\begin{center}
+  \code{\meta{prefix}\meta{code md5sum}-\meta{context md5sum}.memo}
+\end{center}
+
+In fact, this is how Memoize recognizes --- or rather, searches for --- a
+cc-memo as well: Memoize will utilize a cc-memo when the code and the context
+MD5 sum computed during an attempted utilization match the code and the context
+MD5 sum computed during some previous memoization (for details on the context
+MD5 sum, see section~\ref{sec:c-memos}).  In detail, a cc-memo is created at
+the end of memoization, at which point Memoize computes the MD5 sum of the
+memoized code and the MD5 sum of the context, and writes the results of
+memoization into the cc-memo identified by (the prefix and) these two MD5 sums.
+And when Memoize, on a subsequent compilation, encounters a piece of memoized
+code, it again computes the MD5 sum of that code and the MD5 sum of the
+context, and tries to input the cc-memo identified by (the prefix and) these
+two MD5 sums.  If the inputting is successful, we have utilized the cc-memo
+(which in the typical case amounts to including the one associated extern); if
+the cc-memo cannot be found, Memoize starts the memoization process, which
+creates the memos and the externs.
+
+Let us take a look at the contents of a cc-memo in detail.  Here's a typical
+cc-memo (it belongs to the titlepage penguin):
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCCMemo#1{% fetch the first cc-memo filename
+  \def\myccmemo{#1}%
+  \endinput
+}
+\input{\exampledir titlepage.mmz.c1}
+\sed{%
+  s/\cmd{quitvmode} \cmd{mmzIncludeExtern}/\cmd{quitvmode}\n\cmd{mmzIncludeExtern}/;
+  s/\(\marg\marg\marg\)\(\marg\marg\marg\marg\marg\)/\1\space\2/;
+}{\exampledir\myccmemo}
+\tcbinputlisting{
+  listing only,
+  listing file=\exampledir\myccmemo,
+  example title=\myccmemo,
+}
+\endgroup
+
+A cc-memo begins by listing the externs which the memo will (actually, might)
+attempt to include into the document.  When the cc-memo is input, each
+\refcmd{mmzResource} command checks if the given extern exists.  If some
+existence check fails, Memoize enters the memoization mode, same as if the
+cc-memo itself did not exist.  If all the resources pass the existence check,
+Memoize inputs the core of the cc-memo, i.e.\ everything following the
+\refcmd{mmzMemo} marker.
+
+The core might contain arbitrary code, but most often, it will consist of only
+two commands.  The first one is \refcmd{quitvmode} and it is included if the
+extern was \refmmz{capture}d into a horizontal box (which is the usual
+situation).  The second one is \refcmd{mmzIncludeExtern}, and it is this
+command which actually includes the extern into the document upon inputting the
+cc-memo. The core code is executed without introducing any groups, i.e.\ the
+effect of any local assignments in the cc-memo will persist into the code
+following the memoized code.
+
+Command \refcmd{mmzIncludeExtern} takes nine parameters.  The first is the
+sequential number of the extern associated with the cc-memo, starting with 0;
+usually, this is simply 0 as most memos are associated with a single extern.
+The second one is a \refcmd{hbox} or \refcmd{vbox}, noting the type of the box
+the memoized code was externalized into.  The next three numbers are the
+expected width, height and the depth of the extern.  Finally, we have the four
+\refmmz{padding} amounts (left, bottom, right and top).  We should arrive at
+the expected size after trimming the extern PDF by the
+padding amounts; Memoize will complain if we don't.
+
+Let's look at a more interesting cc-memo.  Using the advising framework,
+described in section~\ref{sec:tut:automemoization-details}, Memoize hacks
+\refcmd{label} to support \cs{label}s inside memoized code --- the following
+code ``just works.''
+
+\ExampleName{label}
+\makeexample{\examplename.pdf N=3}
+\tcbinputexample{
+  comment={\centering
+    \includeexamplepdf[document page, after title pre={\ (compilation 1)},
+      left=1.5mm, right=1mm]{page=2}\quad
+    \includeexamplepdf[document page, after title pre={\ (compilation 2)},
+      left=1.5mm, right=1mm][\examplepath.c2.pdf]{page=1}\quad
+    \includeexamplepdf[document page, after title pre={\ (compilation 3)},
+      left=1.5mm, right=1mm][\examplepath.c3.pdf]{page=1}
+  },
+}
+
+Everything seems normal --- after the first compilation, we get ``\textbf{??}''
+because the label has not made it into the |.aux| file yet, but in subsequent
+compilations, we learn where the penguin lives --- but it is far from normal
+under the hood. If we de-hacked \cs{label} by writing
+\refcmd{mmzset}\bracestt{\refmmz{deactivate}=\cs{label}}, the third compilation
+(and subsequent compilations) would revert to ``\textbf{??}''.  Why would that
+happen?  The memoized code containing the \cs{label}s is only executed in the
+first compilation; in the subsequent compilations, we're simply inputting the
+cc-memo, so the memoized code, including any \cs{label}s in contains, is not
+compiled, and the labels don't get into the |.aux| file anymore.
+
+The \cs{label} hack deploys Memoize's ability to put arbitrary code into the
+cc-memo.  During memoization, the memoized code may add arbitrary code to
+register \refcmd{mmzCCMemo}, and the contents of this register at the end of
+the memoization form the free-form part of the cc-memo.\footnote{This is also
+  how the above-described code containing \refcmd{mmzIncludeExtern} gets into
+  the cc-memo.  The code is produced by \refcmd{mmzExternalizeBox} and appended
+  to \refcmd{mmzCCMemo} by the default memoization driver
+  \refcmd{mmzSingleExternDriver}; see section~\ref{sec:memoization-drivers} for
+  details.}  When the hacked \cs{label} is encountered during memoization, it
+appends \refcmd{mmzLabel}\marg{label name}\marg{current label value} to
+\refcmd{mmzCCMemo}, so this command winds up in the cc-memo.  It is then a
+simple job for \refcmd{mmzLabel}, executed when the cc-memo is input at
+subsequent compilations, to temporarily store \meta{current label value} (i.e.\
+the contents of \refcmd{@currentlabel} at the time the \cs{label} was invoked) back
+into \cs{@currentlabel} and to execute \cs{label}\marg{label name}.  In effect, any
+\cs{label} command contained within the memoized code is executed at every
+compilation, even if the memoized code itself is not compiled.
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCCMemo#1{% fetch the first cc-memo filename
+  \def\myccmemo{#1}%
+  \endinput
+}
+\input{\examplepath.mmz.c1}
+\sed{%
+  s/~//g;
+  s/\cmd{quitvmode} \cmd{mmzLabel}/\cmd{quitvmode}\n\cmd{mmzLabel}/;
+  s/\(\marg\)\cmd{mmzIncludeExtern}/\1\n\cmd{mmzIncludeExtern}/;
+  s/\(\cmd{mmzLabel}\) *\(\marg\marg\) */~\1\2~\space/g;
+  s/\(\marg\marg\marg\)\(\marg\marg\marg\marg\marg\)/\1\space\2/;
+}{\exampledir\myccmemo}
+\tcbinputlisting{float,
+  listing only, right=1.5mm,
+  listing file=\exampledir\myccmemo,
+  example title=\myccmemo,
+}
+\endgroup
+
+We will continue the discussion of \refcmd{label} in section~\ref{sec:label+} using
+a funkier example.
+
+
+\subsubsection{C-memos (and context)}
+\label{sec:c-memos}
+
+As explained in the previous section, a cc-memo belonging to a piece of
+memoized code is identified by two MD5 sums: the MD5 sum of the memoized code,
+and the MD5 sum of the associated context.  However, when Memoize encounters
+some code submitted to memoization, the context expression is not yet fully
+known, as it may be adjusted by the memoized code itself during memoization ---
+and this potential adjustment is crucial for \cs{ref} and friends to work as
+advertised (see section~\ref{sec:cross-referencing}).  Upon being invoked,
+Memoize therefore cannot immediately attempt to input the cc-memo; it needs to
+first learn about the context adjustments.  Here's where c-memos enter the
+picture: \emph{the primary job of a c-memo is to store the context adjustments
+  made by the memoized code}.  Let's see how this works in detail.
+
+Same as cc-memos, c-memos are located in the directory given via subkey
+\refmmzpath{dir} (and \refmmzpath{relative}) of key \refmmz{path}.  However, a c-memo
+belonging to some memoized code is identified by the MD5 sum of that code
+alone; its filename has the following form, where \meta{prefix} is again set
+via subkey \refmmzpath{prefix}:
+\begin{center}
+  \code{\meta{prefix}\meta{code md5sum}.memo}
+\end{center}
+
+The c-memo is created at the end of the memoization process.  At that time, the
+context expression is fully known, as the memoized code was already processed.
+Even more, Memoize keeps track of both the state of the context expression
+prior to memoization, stored in token register \refcmd{mmzContext}, and of the
+\emph{additions} to the context expression made by the memoized code, which are
+stored in token register \refcmd{mmzContextExtra}.  (Incidentally, key
+\refmmz{context} automatically adapts to the situation by appending to
+\refcmd{mmzContext} outside memoization and to \refcmd{mmzContextExtra} during
+memoization.)  The complete context expression is the concatenation of the
+contents of these two registers, but it is only the context expression
+additions, i.e.\ the contents of \refcmd{mmzContextExtra}, which Memoize stores
+into the c-memo, with the idea that during subsequent compilations, the initial
+context (\refcmd{mmzContext}) will be set up again via ``normal'' compilation,
+while inputting the c-memo will restore the additions, jointly reconstructing
+the complete context expression associated with a piece of memoized code to
+what it was at the end of memoization.
+
+We can now complete the picture of a utilization attempt started in
+section~\ref{sec:cc-memos}.  Memoize begins by trying to input the c-memo; this
+can be done as the c-memo can be identified based solely on (the MD5 sum of)
+the memoized code.  If the c-memo does not exist, Memoize starts the
+memoization process, which will produce the memos and the externs.  But if it
+does exist, inputting it reconstructs the context expression to the state at
+the end of memoization.  Therefore, as the MD5 sum of the \emph{expansion} of
+the context expression \emph{at the end of memoization} is baked into the
+cc-memo filename, trying to load the cc-memo identified by (the prefix, the
+code MD5 sum and) the MD5 sum of the \emph{expansion} of the context expression
+\emph{at attempted utilization} will succeed precisely when the context
+remained unchanged from memoization to attempted utilization.
+
+All this might have sounded very complicated, but in the end, most c-memos are
+quite boring, the titlepage penguin's c-memo shown below being no exception.  A
+c-memo starts with the \refcmd{mmzMemo} marker, which is always followed by a
+(global) assignment to token register \refcmd{mmzContextExtra}, holding the
+context expression additions.  As promised, the c-memo below is boring: it
+assigns an empty token list to this register, leaving the context expression
+as-is.  Next comes the free-form part of the memo.  Below, it is boringly empty
+as well (just the percent sign), but in principle, it will contain any code
+gathered in register \refcmd{mmzCMemo} during memoization; see
+\ref{sec:per-overlay} for an example.  A c-memo is concluded by an optional
+part consisting of the \refcmd{mmzSource} marker, followed by the memoized
+code.  The source code section is not used by Memoize in any way and can be
+switched off by \code{\refmmz{include source in cmemo}=false}; it is included
+by default so that an interested user can know which code produced which memo,
+which can be useful if one wants to trigger recompilation of an extern by
+deleting the corresponding memo.  Incidentally, any newlines in the source code
+are lost in the c-memo replica (unless \refmmz{verbatim} is in effect), but we
+will only see this once we arrive at the \pkg{beamer} example below.
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCMemo#1{% fetch the first c-memo filename
+  \def\mycmemo{#1}%
+  \endinput
+}
+\input{\exampledir titlepage.mmz.c1}
+\tcbinputlisting{
+  listing only,
+  listing file=\exampledir\mycmemo,
+  example title=\mycmemo,
+}
+\endgroup
+
+A c-memo of code containing a cross-reference will prove more interesting.  The
+following c-memo was produced by the |ref| example from section
+\ref{sec:cross-referencing}.  As we know from that section, when a \refcmd{ref} (as
+hacked by Memoize's \refmmzauto{ref} key) occurs in some memoized code, it
+appends the cross-reference to the context.  In the c-memo below, this is
+reflected by the (global) assignment of an expression containing the
+cross-reference macro to token register \refcmd{mmzContextExtra}, holding
+the context expression additions.
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCMemo#1{% fetch the first c-memo filename
+  \def\mycmemo{#1}%
+  \endinput
+}
+\input{\exampledir ref.mmz.c1}
+\sed{%
+  s/~//g;
+  s/\cmd{global}.*\marg/~\0~/;
+}{\exampledir\mycmemo}
+\tcbinputlisting{
+  listing only,
+  listing file=\exampledir\mycmemo,
+  example title=\mycmemo,
+}
+\endgroup
+
+
+\subsubsection{More on \texorpdfstring{\cs{label}}{\textbackslash label}}
+\label{sec:label+}
+
+A \refcmd{label} inside memoized code works out of the box in the usual situation
+when label value is fully determined by the memoized code, as in the example in
+section~\ref{sec:cc-memos}, where the memoized code contained the outermost
+(and only) \env{enumerate} environment.  However, the out of the box approach does
+not work if the label value is (fully or partially) determined outside the
+memoized code.  To illustrate the problem, and some potential solutions, we
+define two very simple enumeration environments, |listi| and |listii|, which
+use counters |counti| and |countii|, and which are intended as the outer and
+the inner environment, respectively.  Our interest here is in the inner
+environment, |listii|.  While it prefixes each item by an indented
+|\thecountii)|, the label is a composite of both counters:
+|\thecounti\thecountii|.  The label is stored into \refcmd{@currentlabel}, so
+referencing works as usual.  However, problems arise when we automemoize the
+inner environment.
+
+\ExampleName{label+}
+\makeexample{\examplename.tex.c1 N=6}
+\makeexample{\examplename.pdf N=2}
+\tcbinputexample{
+  sidebyside, lefthand ratio=0.53,
+  comment={\centering\includeexamplepdf[document page][\examplepath.c2.pdf]{page=1}},
+}
+
+While the result looks fine at first, changing the order of |listii|
+environments, for example by moving ``pets'' below ``domestic'', will result in a
+problem: the reference at the bottom will remain unchanged.  This is so because
+the reference text is baked into the cc-memo, as shown below.
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCCMemo#1{% fetch the first cc-memo filename
+  \def\myccmemo{#1}%
+  \endinput
+}
+\input{\examplepath.mmz.c1}
+\sed{%
+  s/~//g;
+  s/\cmd{mmzLabel} \marg\marg/~\0~/;
+  s/\(\marg\)\(\cmd{mmzIncludeExtern}\)/\1 \2/;
+  s/\(\marg\marg\marg\)\(\marg\marg\marg\marg\marg\)/\1\space\2/;
+}{\exampledir\myccmemo}
+\tcbinputlisting{
+  listing only,
+  listing file=\exampledir\myccmemo,
+  example title=\myccmemo,
+}
+\endgroup
+
+How can we remedy this?  The manual option is to force the recompilation of the
+extern by putting an (invisible) reference to the outer item into the inner
+item: add |\label{item:pets}| to item ``pets'' and refer to it at ``dog'' by
+\refcmd{mmzNoRef}|{item:pets}|.%
+\attachexample[\examplename mmzNoRef.tex][\examplepath.tex.c3.attachment]
+
+An automatic variant of the recompilation solution is to add \cs{@currentlabel}
+to the context upon memoizing |listii|.  This can be achieved by adding
+\refmmz{context}|={@currentlabel={\csuse{@currentlabel}}}| to the \refmmz{auto}
+declaration for |listii|. The downside of this approach is that every |listii|
+will get reexternalized upon movement, whether it actually contains a label or
+not.\attachexample[\examplename context.tex][\examplepath.tex.c4.attachment]
+
+In fact, given that the externs produced by the inner environment do not
+contain the value of the outer counter, it seems wasteful to recompile any
+extern just to change the reference.  And indeed, it is possible to avoid this,
+but the approach unfortunately requires adapting the inner environment code
+(and this is why I have not illustrated the problem using an environment of an
+elaborate package like \pkg{enumitem}).  The idea is to ``unbake'' the
+reference to the outer item in the cc-memo.  We can achieve this by changing
+|listii| to define \cs{@currentlabel} to be |\unexpanded{\thecounti}\thecountii|.
+Under this definition, the cc-memo will contain |\mmzLabel
+{item:dog}{\thecounti a}|, and rearranging |listii| environments will produce
+(upon two compilations, of course) the correct reference without recompiling
+the extern.  Note again, however, that this solution can only work when the
+value of the outer counter does not appear in the extern, i.e.\ it would not
+work the ``dog'' item was prefixed by |1a)| rather than simply |a)|.  In those
+cases, one should deploy one of the other solutions.%
+\attachexample[\examplename listii.tex][\examplepath.tex.c5.attachment]
+
+The final solution, presented below, is an elaboration on the second one.
+Rather than append \cs{@currentlabel} to the context immediately upon beginning
+to memoize environment |listii|, we will at that point redefine \cs{label} to do
+that.  In effect, changing the location of |listii| will only recompile it if
+it contains a \cs{label}.
+
+At announced, we redefine \cs{label} once the memoization of |listii| begins,
+so within \refmmz{at begin memoization}.\footnote{Another generally good
+  location for such redefinitions is among the auto-options of |listii|.  We
+  could include an \refmmz{auto}\cs{label}\marg{...} there, or a |/utils/exec|
+  with \refcmd{AdviceSetup}.  However, in this particular case this would be
+  wasteful, as it would be applied regardless of whether memoization will take
+  place or not, whereas we only need the redefined \cs{label} when memoizing.}
+However, we do not redefine \cs{label} directly, as Memoize advises this
+control sequence out of the box (see
+section~\ref{sec:tut:automemoization-details} for details).  What we redefine
+is the command which the advising framework executes instead of \cs{label} ---
+its so-called \refmmzauto{outer handler} --- and we do this by calling
+\refcmd{AdviceSetup}, the low-level variant of the familiar key
+\refmmz{auto}.\footnote{We could have also used \refmmz{auto}, but we don't,
+  because (a) \refcmd{AdviceSetup} is faster, (b) it is easier to prepend
+  material to a handler using the low-level interface, and (c) I wanted to
+  showcase \refcmd{AdviceSetup}.}  The first argument of \refcmd{AdviceSetup}
+is the installation path (|/mmz|), the second one the command or environment we
+are submitting to the framework (\cs{label}), and the third one the setup
+\emph{code} --- here lies the biggest difference between \refmmz{auto} and
+\refcmd{AdviceSetup}: the former expects a keylist, and the latter \hologo{TeX}
+code which directly manipulates settings macros like
+\refcmd{AdviceOuterHandler} (for the full list, see
+section~\ref{sec:tut:automemoization-details} or~\ref{sec:ref:advice}).
+
+\tcbinputexample[.tex][.c6]{listing only, float,
+  attachment name=\examplename auto.tex,
+}
+
+Within \refcmd{AdviceSetup}, we prefix (using macro \cs{preto} of package
+\pkg{etoolbox}) the original outer handler \refcmd{AdviceOuterHandler} by code
+which causes \cs{outerlabeltocontext} to be executed at the end of memoization
+(by globally appending this macro to \refcmd{mmzAtEndMemoizationExtra};
+``Extra'' because we're appending during memoization).  It is
+\cs{outerlabeltocontext} which then appends \refcmd{@currentlabel} to the
+context (\refcmd{mmzContextExtra}; again, ``Extra'' because we're appending
+during memoization),\footnote{As a courtesy, we clear out macro
+  \cs{outerlabeltocontext} once it did it's job, so that multiple \cs{label}s
+  do not include multiple \cs{@currentlabel}s into the context.  But the code
+  would work even without this addendum, can you see why?} and it is crucial
+that this happens at the end of memoization rather than when \cs{label} is
+executed.  When \cs{label} is executed, we're inside an inner item, and
+\cs{@currentlabel} refers to that item, while at the end of memoization, the
+value of this macro equals the value at the beginning of memoization, namely
+the label of the outer item.  While the outer list remains unshuffled, the
+value of \refcmd{@currentlabel} that contributes to the context MD5 sum during
+the utilization attempt will therefore match the value which contributed to the
+context MD5 sum during memoization, resulting in matching MD5 sums and
+therefore in actual utilization of the extern; once the outer list is shuffled,
+this will cease to be the case and the extern will be recompiled.
+
+
+\subsubsection{The Beamer support explained}
+\label{sec:per-overlay}
+
+The implementation of \refmmz{per overlay}, which makes memoization sensitive
+to Beamer overlays, provides an example of a complex interaction between
+various components of memoization.  At the core, the Beamer support works by
+adjusting the context, but we will also have the occasion to observe the
+free-form part of the c-memo, add a bit of extra code to the cc-memo, and
+deploy several memoization hooks.  We will show the complete Beamer support
+code later on; let us build our understanding of that code step by step.
+(Before you read on, you might want to refresh your memory about the \pkg{beamer}
+example from section~\ref{sec:tut:beamer}, as we will refer to it in the
+present section.)
+
+The core idea behind \refmmz{per overlay} is to append the current beamer
+overlay number to the context:\cprotect\footnote{As we saw in
+  section~\ref{sec:tut:beamer}, it is convenient to execute \refmmz{per
+    overlay} inside memoized code.  But remember, from
+  section~\ref{sec:cross-referencing}, that when \refmmz{context} is executed
+  from within the memoized code, its argument winds up in the c-memo.  As the
+  c-memo is processed under the normal category code regime, where |@| is not a
+  letter, we have to access |\beamer at overlaynumber| using the |\csname
+  ... \endcsname| construct.}  \refmmz{context}|={overlay=\csname
+  beamer at overlaynumber\endcsname}|.  This makes Memoize produce a separate
+extern for each overlay.  However, only the first of these externs will get
+utilized on subsequent compilations, in general at least.  Even worse, we will
+lose each frame whose creation is driven solely by the memoized code.  We will
+lose the second overlay in our example (i.e.\ in the \pkg{beamer} example from
+section~\ref{sec:tut:beamer}) as the second overlay was only created because
+Beamer encountered |only={2}{...}| (resolving to |\only<2>{...}| under the
+hood) inside the picture code; once we utilize the extern instead of compiling
+the picture on the first overlay, the |\only| command is not executed anymore,
+so Beamer thinks it is done with the frame.
+
+As the compilation of our picture is substituted by utilization of its
+cc-memos, we have to somehow drive the creation of the necessary overlays from
+these files.  An easy way to achieve this is to furnish them with a dummy
+|\only<|\meta{final overlay number}|>{}|,\footnote{`The final overlay' here
+  should be understood as relative to our memoized picture, i.e.\ as the final
+  overlay containing the memoized picture.}\footnote{Actually, putting this
+  \cs{only} command only into the first cc-memo would suffice, but would be
+  harder to implement.}  but there is a problem: the final overlay number is
+unknown when we're memoizing our picture --- it is unknown even when we're
+memoizing the picture on final overlay itself (we simply don't know yet that
+this overlay will end up being the final one), let alone during the memoization
+on the first overlay.
+
+The solution exploits the fact that \emph{the c-memo is rewritten at each
+  memoization}: at each memoization of our picture, we store the the
+\emph{current} overlay number to the c-memo; after all memoizations, the c-memo
+will thus contain the number of the \emph{final} overlay containing our
+memoized picture.  To access this number from the cc-memo, we store it as a
+macro definition, and then use the defined macro, |\mmzBeamerOverlays|, in the
+overlay specification of the dummy |\only|.  Below, you can see all this in
+code, as the argument to \refmmz{at begin memoization}.
+
+\ExampleName{per-overlay-v1}
+\makeexample{\examplename.sty}
+\tcbinputexample[.sty]{
+  listing only,
+  title={The implementation of \refmmz{per overlay} (first attempt)},
+}
+
+A couple of remarks are in order here.  First, the definition of
+|\mmzBeamerOverlays| in the c-memo is global, because it will be accessed from
+the cc-memo, but the cc-memo is input after closing the memoize group (which
+the c-memo \emph{is} processed in).  Second, using \refmmz{at begin
+  memoization} makes it possible to use \refmmz{per overlay} both outside and
+during memoization: if \refmmz{at begin memoization} is executed outside
+memoization, its argument is (locally) stored into hook
+\refcmd{mmzAtBeginMemoization}, to be called at the beginning of each
+memoization; if the key executed outside memoization, the argument is executed
+immediately.  Third, the Memoize keys in the definition of \refmmz{per overlay}
+are prefixed with \code{\refkeypath{/mmz}/}, so that this key can be called from
+\pkg{pgfkeys} option lists of other packages, for example the option list of
+the \env{tikzpicture} environment, as shown in the example in
+section~\ref{sec:tut:beamer}.
+
+I used the above version of \refmmz{per overlay} for quite a while.  In
+general, it worked as I expected, but there were glitches.  Occasionally, the
+picture would appear on the wrong overlay, or I would get an extra overlay, or
+perhaps lose an overlay.  Eventually, I figured out this happens when I play
+with the overlay structure of the frame: when I add or remove a \cs{pause} or
+similar.  In hindsight, it is easy to see what was happening.  Once the picture
+is memoized, it is fixed, forever, which extern will appear on which overlay.
+I cannot expect the extern--overlay correlation to change just because I added
+a \cs{pause} in front of the picture.  Furthermore, the number of overlays the
+memos will drive to be created is fixed as well.  If I memoize the picture
+while it follows a \cs{pause}, and the picture creates 10 overlays, the c-memo
+will define |\mmzBeamerOverlays| to 11.  So what, if I then remove that
+\cs{pause}!  The c-memo will still define |\mmzBeamerOverlays| to 11, and drive
+the creation of 11 overlays --- one too many.
+
+By now, the road ahead is probably clear --- we put the |beamerpauses| counter
+into the context --- but we will see there are still obstacles on the way.  The
+issue is that the context is evaluated at the \emph{end} of memoization (so
+that those cross-references from section~\ref{sec:cross-referencing} actually
+get into it).  However, the memoized code might contain a \cs{pause} or similar
+itself, and change the value of |beamerpauses|.  For one, this means that we
+have to write down the changed value of |beamerpauses| into the cc-memo; below,
+we do this using key \refmmz{at end memoization} (the code given code to this
+key is executed after the driver but before Memoize writes down the memos and
+ships out the extern pages; the key itself may be executed either before or
+during memoization).  Furthermore, if the memoized code changes the value of
+|beamerpauses|, the value of |beamerpauses| at the attempted utilization, which
+would nicely match the value from the start of memoization, will never match
+the changed, final value from the end of memoization, in effect preventing our
+hard-won externs from ever getting utilized.
+
+We therefore have to invent a way to get the memoization-\emph{initial} value
+of |beamerpauses| into the context.\footnote{This imposes a requirement on the
+  in-code usage of \refmmz{per overlay}, namely, that it should be executed
+  prior to any changes of |beamerpauses|.}  Fine, we store it in a
+macro,\footnote{We must define \cs{mmzBeamerPauses} globally, because
+  \refmmz{per overlay} can be arbitrarily deeply embedded in the memoized
+  code.} |\mmzBeamerPauses|, when we start the memoization (\refmmz{at begin
+  memoization}), and put |\mmzBeamerPauses| rather than |beamerpauses| into the
+context.  Will this work?  Not yet, because |\mmzBeamerPauses| is undefined at
+utilization.  We need to set up the context expression so that it will expand
+to the value of |\mmzBeamerPauses| at (the end of) memoization, and to the
+value of |beamerpauses| at utilization.  This leads to the
+|pauses=\ifmemoizing...| part of the context expression in (the final version
+  of) the Beamer support code below.
+
+\medskip % manual, to avoid an orphan
+
+\ExampleName{per-overlay}
+\makeexcerpt{per-overlay}
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file,
+  left=0pt, % manual indentation gobble
+  title={The implementation of \refmmz{per overlay}},
+}
+
+Are we done?  Almost.  The final issue is that once we have introduced support
+for pauses, we have to relativize |\mmzBeamerOverlays| (the final overlay
+number) to |beamerpause|.  So instead of a simple |\gdef\mmzBeamerOverlays| in
+the first version, we define |\mmzSetBeamerOverlays|\nohyphen\marg{beamer
+  pauses}\marg{final overlay number}, which sets |\mmzBeamerOverlays| only if
+\meta{beamer pauses} argument matches the value of |beamerpauses| (at its
+invocation in the c-memo).  Well, the macro has some other housekeeping to do
+as well: it is self-replicating, so that during potential memoization, the
+|\mmzBeamerOverlays| values belonging to non-current |beamerpauses| values get
+rewritten into the c-memo.\footnote{As replication should only occur during
+  memoization (actually, it \emph{can} only occur then, anyway), the
+  instruction to append to the c-memo is appended to the
+  \cs{mmzAtBeginMemoization} hook (the low-level interface to \refmmz{at begin
+    memoization}).  Note that the assignment to this hook must be local (once
+  local, always local), and it \emph{can} be local because of a little
+  implementation detail: while the c-memo is processed in the memoize
+  \hologo{TeX} group, we don't open an additional group to process it; so the
+  local effects from c-memo will persist into memoization (but not into
+  utilization, because remember that the memoize group is closed before
+  inputting the cc-memo).} (Fine, there is another fine detail, regarding
+anti-pollution: the macro also ensures that, relative to \marg{beamer pauses},
+only the instance with the greatest \meta{final overlay number} is replicated.)
+
+We are now truly done, and we can look at the final result, the c-memo and the
+cc-memo belonging to the extern on the first overlay of the example from
+section~\ref{sec:tut:beamer}.  Specifically, look at the |\mmzSetBeamerOverlays
+{1}{2}|, which says that the extern chain started when |beamerpauses| equals 1
+should continue up to overlay 2, and at the (expanded) context included at the
+end of the cc-memo, courtesy of \refmmz{include context in ccmemo}, where you
+can see that the cc-memo will be used when on the first overlay (|overlay=1|)
+when preceded by no \cs{pause} command (|pauses=1|).
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCMemo#1{% fetch the first c-memo filename
+  \def\mycmemo{#1}%
+}
+\def\mmzNewCCMemo#1{% fetch the first cc-memo filename
+  \def\myccmemo{#1}%
+  \endinput
+}
+\input{\exampledir beamer.mmz.c1}
+\sed{%
+  s/~//g;
+  s/\cmd{mmzSetBeamerOverlays} \marg\marg/~\0~/;
+}{\exampledir\mycmemo}
+\sed{%
+  s/~//g;
+  s/overlay=[0-9]*/~\0~/;
+  s/pauses=[0-9]*/~\0~/;
+  s/\(\cmd{quitvmode}\) \(\cmd{only}\)/\1\n\2/;
+  s/\rbrace\(\cmd{mmzIncludeExtern}\)/\rbrace\percentchar\n\1/;
+  s/\rbrace\(\cmd{setcounter}\)/\rbrace\percentchar\n\1/;
+  s/\(\marg\marg\marg\)\(\marg\marg\marg\marg\marg\)/\1\space\2/;
+}{\exampledir\myccmemo}
+
+\tcbinputlisting{
+  listing only,
+  listing file=\exampledir\mycmemo,
+  example title=\mycmemo,
+}
+
+\tcbinputlisting{
+  listing only, 
+  listing file=\exampledir\myccmemo,
+  example title=\myccmemo,
+}
+\endgroup
+
+
+\subsection{Record files}
+\label{sec:record-files}
+
+We have seen that externalization is a two-step process in Memoize: as it is
+impossible for \hologo{TeX} to create multiple PDFs during a single
+compilation, the externs are first dumped into the document PDF as special
+extern pages, and only later extracted from the main document into separate PDF
+files.  But extraction requires a complete PDF, which is unavailable even at
+the very end of the compilation which produces the externs.  The externs can
+therefore only be extracted \emph{after} that compilation (either before or at
+the beginning of the next one), and this necessitates some form of
+communication whereby the memoization step informs the extraction step which
+pages should be extracted from the document PDF and into which (PDF) files they
+should be stored.  This communication is implemented through auxiliary files
+called \emph{record files}.
+
+\subsubsection{The \texttt{.mmz} file}
+\label{sec:.mmz}
+
+By default, Memoize records the information needed for the extraction in a file
+named \meta{document name}\dmmz,\footnote{For \hologo{TeX}perts: the
+  \meta{document name} is of course the expansion of \cs{jobname}.} henceforth
+a \dmmz file.  In fact, this file contains more than information on externs
+created during the last compilation: it records which memos and externs were
+either used or created during the compilation.  The full information contained
+in the \dmmz file is used by the clean-up script \refscript{memoize-clean.pl}
+to safely remove stale memos and externs.  Let us take a look at the \dmmz file
+produced by the titlepage illustration.  In fact, we have two versions of this
+file, as it changes upon the second compilation.
+
+\ExampleName{titlepage}
+\makeexample{\examplename.pdf N=2}
+\sed{%
+  s/~//g;
+  s/\cmd{mmzNewExtern}/~\0~/;
+}{\examplepath.mmz.c1}
+\tcbinputexample[.mmz][.c1]{
+  listing only, one file, no attachment, float,
+  after title pre={\ (after the first compilation)},
+  listing options app={breakatwhitespace=false,prebreak=\coloredpercentchar},
+}
+\tcbinputexample[.mmz][.c2]{
+  listing only, one file, no attachment, float,
+  after title pre={\ (after subsequent compilations)},
+  listing options app={breakatwhitespace=false,prebreak=\coloredpercentchar},
+}
+
+As you can see, the \dmmz file takes the form of a \hologo{TeX} script (the
+format was chosen because it facilitated the implementation of the internally
+triggered \hologo{TeX}-based extraction).  The crucial lines in this file, and
+the only lines used by the extraction script, occur in the first version of the
+file: they contain command \refcmd{mmzNewExtern}, which informs the extraction
+script that it should extract the document page given by the second argument
+into the extern file given by the first argument.\footnote{If you look at the
+  \dmmz file after extracting the externs using \refscript{memoize-extract.pl}
+  without the \refscript{memoize-extract.pl--keep} option, you will find that
+  the \refcmd{mmzNewExtern} commands are commented out; this is to prevent
+  multiple extractions (even if they are harmless).}  (The following two
+arguments provide the expected width and height of the extern; the
+extraction script may check whether the extern size conforms to these
+expectations, but this is not crucial, as the extern size is checked every time
+it is included anyway.)
+
+A \dmmz file also contains a record of the memos (both c-memos and cc-memos)
+created in the last compilation; this information is provided by the sole
+argument of commands \refcmd{mmzNewCMemo} and \refcmd{mmzNewCCMemo}.  And once
+memos and externs get used in subsequent compilations, the \dmmz file will
+reflect this with \refcmd{mmzUsedCMemo}, \refcmd{mmzUsedCCMemo} and
+\refcmd{mmzUsedExtern}, as shown in the second version of the file above.
+
+Finally, both versions illustrate that a \dmmz file always begins with command
+\refcmd{mmzPrefix} and ends with the |\endinput| marker.  The argument of
+\refcmd{mmzPrefix} is the path prefix to the memo and extern files, as
+determined by the invocation of key \refmmz{path} (and its subkeys
+\refmmzpath{relative}, \refmmzpath{dir} and \refmmzpath{prefix}).  The initial
+\refcmd{mmzPrefix} line is written to the \dmmz file at the beginning of the
+document, but an additional \refcmd{mmzPrefix} line will occur for every
+invocation of \refmmz{path} in the document body.  Finally, the |\endinput|
+marker signals that the \dmmz file is complete.
+
+As mentioned above, the full contingent of \dmmz file commands is only used by
+the clean-up script \refscript{memoize-clean.pl}.  By default, this script
+removes all memos and externs with the prefix given by \refcmd{mmzPrefix}
+(relative to the directory hosting the \dmmz file) but those listed by any of
+\refcmd{mmzNewCMemo}, \refcmd{mmzNewCCMemo}, \refcmd{mmzNewExtern},
+\refcmd{mmzUsedCMemo}, \refcmd{mmzUsedCCMemo} and \refcmd{mmzUsedExtern}.
+Furthermore, the clean-up script will cowardly refuse to delete anything if the
+\dmmz file does not end with |\endinput|, as this means that the compilation
+ended prematurely and that the \dmmz file might not mention all memos and
+externs actually used in the document.  If given option
+\refscript{memoize-clean.pl--all}, the clean-up script removes even the memos
+and externs mentioned in the \dmmz file, and as this option is intended to
+bring Memoize to a clean slate after any ``disasters,'' the
+\refscript{memoize-clean.pl--all} mode also ignores the potential absence of
+the |\endinput| marker.  Incidentally, the \refscript{memoize-clean.pl--all}
+mode is also the raison d'être for \refcmd{mmzPrefix}: while the prefix is
+usually recognizable from \refcmd{mmzNewCMemo} and friends, these commands
+might not make it into the \dmmz file in a fatally failed compilation, but it
+is precisely such compilations that could occasionally require the full
+clean-up.
+
+\subsubsection{Defining a new record type}
+\label{sec:new-record-file}
+
+The \dmmz file is not the only kind of a record file that can be produced by
+Memoize.  Out of the box, it can also write down the extraction instructions
+into a makefile or a shell script.  These are useful on systems which have to
+employ the \hologo{TeX}-based extraction but cannot trigger it internally.
+Running the \hologo{TeX}-based extraction manually would be painful, as it must
+be done on extern-by-extern basis, so Memoize offers to automate the extraction
+by a makefile or a shell script; here, the record file is named
+\code{memoize-extract.\meta{document name}.\meta{record type}} by default,
+where \meta{record type} is either \refmmz{record=makefile},
+\refmmz{record=sh} (for shell scripts on Linux), or \refmmz{record=bat} (for
+shell scripts on Windows).
+
+To turn on recording of an alternate record type, use key
+\refmmz{record}|=|\meta{record type}.  Memoize can record any number of files
+simultaneously, so saying \code{\refmmz{record}=\refmmz{record=sh}} will
+produce the shell script alongside \dmmz (Memoize internally executes
+\code{\refmmz{record}=\refmmz{record=mmz}} to start recording the \dmmz file);
+this should not be a problem, but if you really want to disable the \dmmz file
+production, you can say \refmmz{no record}.
+
+The predefined record types are defined through a generic system open to the
+user.  To define an additional record type, one needs to define, using
+\pkg{pgfkeys}, the relevant hooks of the form \refkeypath{/mmz/record/record
+  type}|/|\meta{hook}.  The following \meta{hook}s can be defined (the hooks
+not needed for the record file type may be left undefined):
+\begin{itemize}
+\item Key \refmmz{record/record type/begin} will be executed at the beginning
+  of the document; it will receive no argument.  Use it to open the record
+  file.
+\item Key \refmmz{record/record type/end} will be executed at the end of the
+  document; it will receive no argument.  Use it to close the record file.
+\item Key \refmmz{record/record type/prefix} will be executed at the end of the
+  document and at every invocation of key \refmmz{path} in the document body;
+  it will receive a single argument, the path prefix determined by key
+  \refmmz{path}.
+\item Keys \refmmz{record/record type/new cmemo}, \refmmz{record/record
+    type/used cmemo}, \refmmz{record/record type/new ccmemo} and
+  \refmmz{record/record type/used ccmemo} will be executed after creating or
+  inputting a memo; they will receive a single argument, the full path to the
+  memo.
+\item Key \refmmz{record/record type/used extern} will be executed after an
+  extern was included into the document; it will receive a single argument, the
+  full path to the extern.
+\item Key \refmmz{record/record type/new extern} will be executed after
+  creating creating an extern, more precisely at the end of memoization, right
+  after shipping out the extern page.  It will receive a single argument, the
+  full path to the extern, but additionally, Memoize prepares the following
+  macros:
+  \begin{itemize}
+  \item \refcmd{ne:externbasepath} holds the full path to the extern, but (unlike |#1|)
+    without the |.pdf| suffix;
+  \item \refcmd{ne:pagenumber} holds the ``physical'' page number of the extern page in
+    the document (the numbering starts by $1$);
+  \item \refcmd{ne:expectedwidth} and \refcmd{ne:expectedheight} hold the width and
+    the height (total height, i.e.\ the sum of \hologo{TeX}'s height and depth)
+    of the extern page.
+  \end{itemize}
+\end{itemize}
+
+Below, we present two simple examples of a record file.  The first type simply
+records the names of all memos and externs used or created by Memoize; the
+resulting file could be included by |.gitignore| to have
+\hreftt{https://git-scm.com}{git} automatically ignore all files produced by
+Memoize.  The second type lists the new externs, each preceded by its page
+number in the |.pdf|; this file could be fed to a custom extern extraction
+tool.
+
+\ExampleName{record-files}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{listing only}
+
+\ExampleName{record-extern-pages}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{listing only}
+
+Finally, note that (unlike memos and externs) record files are auxiliary files
+and may be deleted at any time after the extraction of the externs produced in
+the final compilation --- actually, even if these externs were not yet
+extracted, deleting the record file(s) will merely force their recompilation.
+
+
+\subsection{The memoization process}
+\label{sec:memoization-drivers}
+
+We now turn to the memoization process itself.  The job of memoization is to,
+while compiling the given code in a regular fashion, prepare the cc-memo
+(which, when it is input, will replicate the effect of the given code),
+alongside any externs that the cc-memo will include (these hold the typeset
+material to be replicated).  Clearly, merely compiling the code cannot have
+this effect (unless that code was written specifically to support memoization;
+more on this later), and this is why the memoized code is typically wrapped by
+a \emph{memoization driver}, which can be set using key \Emph{\refmmz{driver}}.
+We'll inspect the default memoization driver, \refcmd{mmzSingleExternDriver},
+in the first subsection, and we will learn how to write specialized drivers in
+the remaining subsections.  But first, let us say some words about a
+grouping-related \hologo{TeX}nical detail we need to take care about during
+memoization.
+
+During memoization, we have to collect certain information, like build the
+contents of the cc-memo.  Some of that information might be contributed by the
+memoized code itself.  For example, a \cs{label} ``adds itself'' to the cc-memo
+(by appending to token register \refcmd{mmzCCMemo}); a
+\refkey{/tikz/remember picture} aborts memoization (by issuing
+\refcmd{mmzAbort}); etc.  The issue is that the memoized code might open any
+number of \hologo{TeX} groups; we have no idea how deeply embedded the
+\cs{label} or \refkey{/tikz/remember picture} might be.  Therefore, we have
+to collect all the information about the ongoing memoization \emph{globally}:
+all assignments to \refcmd{mmzCCMemo} must be global; \refcmd{mmzAbort} sets
+the underlying conditional globally; etc.  (Clearly, all these global variables
+are initialized at the start of memoization.)
+
+This was the easy part.  An additional complication arises with some options
+which may be set either outside memoization, or during this process.  For
+example, you can append the font size to the context expression in the preamble
+(see section~\ref{sec:cross-referencing}), so that the externs will be
+automatically recompiled when the font size changes, and clearly, this context
+adjustment should respect \hologo{TeX} grouping; but a \cs{ref} or some other
+cross-referencing command in the memoized code needs to append to the context
+as well, and as this \cs{ref} occurs \emph{within} the memoized code, the
+assignment must be global, as explained above.
+
+Mixing the local and global assignments to the token register
+\refcmd{mmzContext}, which holds the (in the actual implementation, local)
+context expression, will not do.  For one, we \emph{do} want to restore the
+pre-memoization context expression after we have memoized the code, and
+furthermore, mixing local and global assignments to the same variable is not
+recommended for save stack reasons anyway.
+
+Memoize addresses this issue by having \emph{two} context registers,
+\refcmd{mmzContext} and \refcmd{mmzContextExtra} --- when computing the context
+MD5 sum (which happens at the end of memoization), the two registers are
+concatenated (the local one comes first).  A package writer should know when to
+use which register, and how.  Outside memoization, one should assign to
+\refcmd{mmzContext} --- \emph{locally}.  During memoization, one should assign
+to \refcmd{mmzContextExtra} --- \emph{globally}.  The user interface key
+\refmmz{context} respects this requirement automatically: it locally appends to
+\refcmd{mmzContext} outside memoization, and it globally appends to
+\refcmd{mmzContextExtra} during memoization. (The same idea is applied to the
+post-memoization hooks \refmmz{at end memoization} and \refmmz{after
+  memoization}.)
+
+
+\subsubsection{The default memoization driver}
+\label{sec:memoization-driver-default}
+
+The default memoization driver, \refcmd{mmzSingleExternDriver}, produces
+exactly one extern, which contains whatever is typeset by the code submitted to
+memoization.  The driver compiles the code into a horizontal or vertical box
+depending on the value of key \refmmz{capture}.  Let us look at the definition
+of the driver line by line:
+
+\makeexcerpt{single-extern-driver}
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file,
+  listing options app={numbers=left, numberstyle=\tiny, numbersep=0.5em},
+  title=The default memoization driver,
+  float,
+}
+
+\begin{enumerate}
+\item Macro \refcmd{mmzSingleExternDriver} (and in fact any memoization
+  driver) takes a single argument, the code to compile.  Memoize will call the
+  driver with the code given as the second argument to \refcmd{Memoize}, but
+  wrapped in a macro which re-reads it using \refcmd{scantokens} when
+  \refmmz{verbatim} is in effect.
+\item If we're capturing into a horizontal box
+  (\refmmz{capture}|=|\refmmz{capture=hbox}), we put \refcmd{quitvmode} into
+  the cc-memo --- putting it to the very beginning should make sure that any
+  replicated \cs{label} and \cs{index} commands refer to the correct page.
+\item We compile the given code, storing the typeset material into a box
+  (above, a temporary box called |\mmz at box|).  |\mmz at capture| resolves into a
+  box construction command, depending on the value \refmmz{capture}.
+\item Macro \refcmd{mmzExternalizeBox} instructs Memoize to externalize the box
+  given as its first argument.  However, this macro does not directly produce
+  an extern page or write any instructions into the cc-memo; the road to this
+  final destination is indirect.  \refcmd{mmzExternalizeBox} has two effects.
+  First, it adds the contents of the given box (above, |\mmz at box|) to an
+  internal box dedicated to holding all the externs produced in this
+  memoization (the contents of |\mmz at box| remain as they are) --- it is only at
+  the end of memoization that the contents of this internal box are shipped off
+  to extern pages.  Second, \refcmd{mmzExternalizeBox} produces the code which
+  will include the extern into the document on subsequent compilations (this
+  will be a call to \refcmd{mmzIncludeExtern}, potentially prefixed by
+  \refcmd{quitvmode}; see section~\ref{sec:cc-memos} for details).  This code
+  is stored into the token register gives as the second argument (above,
+  |\mmz at temptoks|), and it is the responsibility of the driver to include it
+  into the cc-memo.  (In the interest of full disclosure,
+  \refcmd{mmzExternalizeBox} also updates the list of externs produced in this
+  memoization.  At the end of memoization, this list is written to the
+  beginning of the cc-memo, resulting in the \refcmd{mmzResource} lines
+  preceding the \refcmd{mmzMemo} marker.)
+\item The construction of the cc-memo is indirect as well.  In the third line
+  of the definition, we globally append the extern-inclusion code residing in
+  |\mmz at temptoks| to token register \refcmd{mmzCCMemo}.  At the end of
+  memoization, the contents of \refcmd{mmzCCMemo} are written into the cc-memo,
+  preceded by the \refcmd{mmzMemo} marker.
+\item We put the typeset material into the document, again preceded by
+  \refcmd{quitvmode} when capturing in a horizontal box.
+\end{enumerate}
+
+You might wonder why the construction of the extern pages and the cc-memo (and
+actually, of the c-memo as well) is indirect, as described above.
+\begin{itemize}
+\item For one, the indirect construction facilitates potential abortion of
+  memoization (see section~\ref{sec:tut:good-to-know}).  With the indirect route,
+  aborting is easy --- as nothing was permanently written anywhere yet, Memoize
+  simply skips the final part of the process, where extern boxes are shipped
+  into extern pages and the memo registers written into memo files --- and also
+  clean: if \refcmd{mmzExternalizeBox} immediately shipped out the extern
+  pages, these pages would remain in the document even in the case of abortion.
+\item Even more importantly, the cc-memo filename contains the \meta{context
+    md5sum} (see section~\ref{sec:cc-memos}), but the context expression is not
+  yet fully known when memoization starts --- remember (from
+  section~\ref{sec:cross-referencing}) that a \cs{ref} in the memoized code will
+  update the context!  The cc-memo can therefore only be opened at the end of
+  memoization, which necessitates a buffer (i.e.\ the \refcmd{mmzCCMemo}
+  register) for storing its contents during memoization.
+\end{itemize}
+
+
+\subsubsection{Pure memoization}
+\label{sec:pure-memoization}
+
+The default memoization driver discussed above is really an externalization
+driver: it produces a single extern.  We now move to examples of drivers with
+other functions, starting with a pure memoization driver, which does not
+externalize any typeset output --- simply because it does not call
+\refcmd{mmzExternalizeBox} at any point --- but rather remembers the result
+of a (pgfmath) computation (let's pretend that the computation is
+time-consuming).
+
+\ExampleName{pgfmathparse}
+\makeexample{\examplename.pdf}
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCCMemo#1{% fetch the first cc-memo filename
+  \def\myccmemo{#1}%
+  \endinput
+}
+\input{\examplepath.mmz.c1}
+\tcbinputexample{%
+  comment={%
+    \tcbinputlisting{
+      listing only, width=.4\linewidth, nobeforeafter,
+      listing file=\exampledir\myccmemo,
+      example title, title=the cc-memo,
+    }\quad
+    \includeexamplepdf[document page]{page=1}
+  },
+}
+\endgroup
+
+Command \refcmd{mmz} above memoizes its mandatory argument with the memoization
+\refmmz{driver} set to the previously defined macro \cs{mmzPgfmathDriver}.
+Just as the default driver above, \cs{mmzPgfmathDriver} first executes the
+given code.  However, there is no need to do this in the context of a
+|\setbox|, as the memoized code, which is obviously expected to consist of a
+single \cs{pgfmathparse} call, does not typeset anything: \cs{pgfmathparse}
+evaluates the given expression and stores the result into macro
+\cs{pgfmathresult}.  The driver has two jobs: first, it must store this result
+into the cc-memo, to be utilized in subsequent compilations; second, because
+the assignment to \cs{pgfmathresult} (within \cs{pgfmathparse}) is local, the
+driver also needs to somehow smuggle the result out of the \cs{endgroup} issued
+by \refcmd{Memoize} and thereby make it into the following code (the final line
+of the example, which typesets the equation).  Both jobs are easy enough: the
+expansion of |\def\noexpand\pgfmathresult{\pgfmathresult}| (in this case,
+|\def\pgfmathresult{42.0}|) is (globally) appended both to the token register
+\refcmd{mmzCCMemo}, which Memoize later writes into the cc-memo, and to the
+macro underlying the \refmmz{after memoization} hook, whose contents are
+executed \emph{after} closing the memoization group.
+
+Let us consider an alternative implementation of the same goal of memoizing the
+result of a pgfmath computation, showcasing a couple of useful tricks.
+
+\ExampleName{pgfmathparse-embellished}
+\makeexample{\examplename.pdf}
+\tcbinputexample{listing only}
+
+For one, this ``embellished'' example reminds us that we can list the
+\refmmz{driver} key among the auto-options (even if I don't really recommend
+automemoizing \cs{pgfmathparse}).  But even more importantly, the example shows
+that the driver consist of more than a single control sequence; the only
+requirement is that the given driver code will consume the memoized code.  In
+this example, we have developed a generic smuggling driver and applied it to
+\cs{pgfmathresult} in particular --- \cs{pgfmathresult} will become the first
+argument of \cs{mmzSmuggleOneDriver}, and the memoized code will become its
+second argument.
+
+In the first version of the example, we have appended the same code to macro
+\refcmd{mmzCCMemo} and to macro \refcmd{mmzAfterMemoizationExtra} --- no
+surprise here, as we want the effect of memoization and utilization to be the
+same.  In the embellished version, we advertise another way to achieve the same
+effect, a way which might be useful for complicated drivers: we simply smuggle
+out the entire cc-memo.  The idea works even when memoization procudes externs;
+in that case, however, the driver also has to say \cs{mmzkeepexternstrue} ---
+conditional \refcmd{ifmmzkeepexterns} decides whether Memoize keeps the externs
+around, in memory, even after shipping them out (but they are always gone at
+the start of the next memoization).
+
+Finally, remember that the default context expression contains the
+\refmmz{padding} values.  However, these really have no place in the context
+expression of some purely memoized code.  We have therefore emptied out the
+context expression using \refmmz{clear context}.
+
+
+\subsubsection{Multiple externs per memo}
+\label{sec:memoization-multiple-externs}
+
+In the next example, we show how to produce multiple externs for a single piece
+of memoized code.  The usage case I find most appealing is breaking the typeset
+material, like a table, across pages --- but of course, table-breaking is too
+complicated an example, so we illustrate the idea by defining command
+|\countdown|, which counts down from the given number, typesetting each number
+into its own line.  Clearly, if we were to externalize a call to this command
+using the default memoization driver, page breaking would stop working, as the
+entire countdown would be seen as a single, unbreakable box.  To externalize it
+properly, the chunks of the countdown that should appear on separate pages must
+be externalized into separate externs, as shown below.
+
+\ExampleName{countdown}
+\makeexample{\examplename.sty N=2}
+\makeexample{\examplename.pdf}
+\tcbinputexample{%
+  listing options app={
+    basicstyle=\ttfamily\footnotesize,
+  },
+  middle=1mm, bottom=0mm,
+  comment={\centering
+    \relaxmmzcommands
+    \def\mmzUsedExtern##1{%
+      \saveexpandmode\fullexpandarg
+      \StrGobbleRight{##1}{4}[\mytemp]%
+      \StrRight{\mytemp}{5}[\mytemp]%
+      \restoreexpandmode
+      \relaxmmzcommands
+    }%
+    \def\mmzNewExtern##1##2##3##4##5{\mmzUsedExtern{##1}}
+    \def\myexternname##1{extern \dots\texttt{\mytemp##1.pdf}}%
+    \input{\examplepath.mmz}%
+    \begin{tabular}{ccc}
+      \includeexamplepdf[extern page,title/.expand once=\myexternname{}]
+                        {page=2,trim=1in 1in 1in 1in,scale=0.333}&
+      \includeexamplepdf[extern page,title/.expand once=\myexternname{-1}]
+                        {page=3,trim=1in 1in 1in 1in,scale=0.333}&
+      \includeexamplepdf[extern page,title/.expand once=\myexternname{-2}]
+                        {page=4,trim=1in 1in 1in 1in,scale=0.333}\\
+      \includeexamplepdf[document page]{page=1,scale=0.333}&
+      \includeexamplepdf[document page]{page=5,scale=0.333}&
+      \includeexamplepdf[document page]{page=6,scale=0.333}
+    \end{tabular}
+  },
+}
+
+To achieve this, we will have to integrate the memoization driver into the very
+code of |\countdown|.  This approach contrasts sharply with the standard
+memoization driver, which is simply wrapped around the memoized code.  Let's
+say we have implemented a non-memoization-aware variant of |\countdown| as a
+loop which gathers the countdown lines into a vertical box, and periodically,
+when this box holds all the material that will fit onto the page, places it
+into the main vertical list (i.e.\ on the page).\footnote{Of course,
+  implementing \cs{countdown} this way would be idiotic; a sane implementation
+  would simply spit out the countdown lines one by one, and let \hologo{TeX}
+  deal with page-breaking.  However, remember that we are pretending that we
+  are typesetting (and page-breaking) some complex material, like a table; in
+  such a case, the loop outlined in the main text would make perfect sense.}
+To have this command support memoization, we have to externalize our box every
+time we're placing it into the main vertical list.  This is precisely what we
+do in the definition of |\countdowntypeset| below:\footnote{We omit the
+  definition of the core algorithm of \cs{countdown} in the listing, because it
+  is mostly irrelevant for our discussion, and only show the
+  memoization-related code.} the final line of this macro adds the material to
+the main vertical list, and the preceding lines externalize it (the two lines
+inside \cs{ifmemoizingcountdown} should be familiar from the definition of the
+standard memoization driver; we'll explain about the conditional below); note
+that Memoize automatically deals with the fact that our box is vertical.  As a
+result of having our memoization driver integrated into the loop of the core
+command, we can create as many externs as necessary, complete with the code in
+the cc-memo for including each and every one of them on subsequent
+compilations.  Each extern eventually makes it into its own extern file, and
+note that the filenames of the non-first externs have their sequential number
+(we start counting at $0$) appended to the basename, as shown in the
+example.\cprotect\footnote{The \refmmz{auto} declaration of |\countdown| adds
+  some relevant parameters to the context (see
+  section~\ref{sec:cross-referencing}).  The countdown will be recompiled upon
+  change of either the font size (|f at size|), the text height (|\textheight|),
+  or the height of the material in the main vertical list collected so far
+  (|\pagetotal|).  The |\pagetotal| parameter is especially important;
+  including it makes sure that the countdown will be recompiled when it is
+  pushed up or down the page.  Also note that we want the context to record the
+  value of |\pagetotal| when the (automemoized) |\countdown| is encountered
+  (rather than at the end of memoization), so we expand it when applying the
+  auto-options.}
+
+\tcbinputexample[.sty]{listing only, after title pre={\ (version 1)}}
+
+Of course, the chunks of the countdown should only be externalized when the
+code is actually being memoized, and not, say, when Memoize is disabled or
+performing regular compilation.  (Note that this is a problem that only affects
+integrated drivers and not wrapped drivers such as the default driver.) The
+first thought is to detect whether we're undergoing memoization using
+conditional \refcmd{ifmemoizing}, which Memoize sets to true at the start of
+every memoization.  This conditional is used in the run conditions of advice
+for \cs{ref} and \cs{label}, the idea being that they should add stuff to the
+context (\cs{ref}) and the cc-memo (\cs{label}) only when undergoing
+memoization.  However, deploying \refcmd{ifmemoizing} in the current example
+would not be exactly right.  It would work well with the main document as it
+is, but it would fail if |\countdown| was called from a piece of code that was
+independently submitted to memoization, e.g.\
+\refcmd{mmz}|{\countdown{30}}|.\footnote{Such embedding occurs more often than
+  you might think.  For example, \env{forest} calls \env{tikzpicture} under the
+  hood, and both environments are automemoized.} In that case, both the
+\refcmd{mmz} driver and the |\countdown| integrated driver would get executed,
+resulting in the creation (and in subsequent compilations, utilization) of four
+externs: first, the |\countdown| driver would externalize each countdown chunk
+separately, and then, the \refcmd{mmz} driver would externalize them, all
+together, yet again.  You can try this out by replacing
+\cs{ifmemoizingcountdown} in \cs{countdowntypeset} by \refcmd{ifmemoizing} (and
+wrapping the \cs{countdown} call in \cs{mmz}).
+
+The solution to the \refcmd{ifmemoizing} problem deployed in the example is to
+declare a new, \cs{countdown}-specific memoization conditional, and set it to
+true in \cs{countdown}'s formal driver, i.e.\ the macro set as the
+\refmmz{driver} in the \refmmz{auto} declaration for \cs{countdown}.  In fact,
+Memoize can do most of this for you: when we write \refmmzauto{integrated
+  driver}|=countdown|, Memoize creates the countdown-specific memoization
+conditional and declares the formal driver which sets this conditional to true;
+you only have to access this conditional in your code, and you should do this
+using the \hologo{LaTeX}-style conditional \refcmd{IfMemoizing}, as shown
+below.\footnote{You shouldn't directly use the plain \hologo{TeX}
+  countdown-specific conditional created by \refmmzauto{integrated driver} ---
+  to prevent accidental access, Memoize doesn't actually name it
+  \cs{ifmemoizingcountdown} --- because this conditional is undefined when
+  Memoize is not loaded, i.e.\ when only package \refpkg{memoizable} is in
+  effect.  Furthermore, \refcmd{IfMemoizing} addresses a problem faced by
+  integrated drivers of potentially recursive commands; we will talk about this
+  in section~\ref{sec:memoization-complex-single-driver}.}
+
+\tcbinputexample[.sty][.c2]{listing only, after title pre={\ (version 2)},
+  attachment name=\examplename-integrated-driver.sty,
+}
+
+
+\subsubsection{Driver-based memoizable design}
+\label{sec:memoization-complex-single-driver}
+
+In the previous section, we used the integrated driver approach to produce
+memos including multiple externs, but the approach can be useful for one-extern
+memos as well, when the extern must be integrated into the document in some
+special way.  We already discussed such situations in
+section~\ref{sec:memoizable-design}, where we suggested to split a
+``difficult'' command into the outer command and the inner command, and only
+submit the inner command to automemoization.  However, the vanilla flavour of
+this approach had a negative impact on the user interface to automemoization.
+In this section, we will deploy the memoization driver to overcome the issue.
+
+\ExampleName{poormansbox-driver}
+\makeexample{\examplename.sty}
+\makeexample{\examplename.pdf N=2}
+
+Let us revisit the |poormansbox| example from
+section~\ref{sec:memoizable-design}.  Remember that that environment produced
+a potentially framed box of a certain width, surrounded by some pre- and
+post-code, and that the issue was that the pre- and the post-code should not be
+memoized, but rather executed at every invocation of the command, as it was
+primarily intended to put some stretchable vertical space around the box.
+
+The document source\attachexample\ and the resulting PDF of the example are the
+same as in section~\ref{sec:memoizable-design}, so we will not repeat them
+here, but jump directly into a revised definition of the environment.  We will
+retain the core idea from the original implementation: the outer command will
+execute the pre- and the post-code, and the inner command will typeset the box.
+But unlike in the original implementation, we will not automemoize the inner,
+internal command (this was the source of the author's discomfort) but the outer,
+user-level command --- and we will equip it with a custom memoization driver.
+The major idea here is to have the driver compose a cc-memo which not only
+includes the extern, but also executes the outer command.
+
+\tcbinputexample[.sty]{listing only, float}
+
+In detail, the implementation (partially shown in the |.sty| listing) is as
+follows.  The outer command (|\poormansbox at outer|) first applies the options
+(|#1|) and then wraps the pre-code (|\pmb at before|) and the post-code
+(|\pmb at after|) around some arbitrary code (|#2|).  During memoization or
+regular compilation, the outer command is invoked through the |poormansbox|
+environment, and you can see that in the definition of that environment, the
+second argument to |\poormansbox at outer| is a call to the inner command
+(|\poormansbox at inner|; this command takes two arguments, the options and the
+environment body).  During utilization, the outer command is invoked from the
+cc-memo,\cprotect\footnote{As you can see, in the cc-memo the outer command is invoked
+  by |\csuse{poormansbox at outer}|.  A straight |\poormansbox at outer| would not
+  work because we're in the middle of the document where |@| is not a letter,
+  and including a |\makeatletter| in front of it (and in a group) only works if
+  \refmmz{direct ccmemo input} was in effect.  Under the default, indirect
+  cc-memo input regime, the core cc-memo is tokenized before |\makeatletter| can
+  take effect.} and as you can see in the cc-memo listing below, the second
+argument to |\poormansbox at outer| there is a call to \refcmd{mmzIncludeExtern}.
+
+\begingroup
+\relaxmmzcommands
+\def\mmzNewCCMemo#1{%
+  \def\mmzNewCCMemo##1{% fetch the second cc-memo filename
+    \def\myccmemo{##1}%
+    \endinput
+  }%
+}
+\input{\examplepath.mmz.c1}
+\sed{%
+  s/~//g;
+  s/\(\cmd{csuse} *{poormansbox at outer}\) *\({\nobrace*\marg\nobrace*}\)\({.*}\rbrace\)/~\1~\2~\3~/;
+  s/\(\marg\marg\marg\)\(\marg\marg\marg\marg\marg\)/\1\space\2/;
+}{\exampledir\myccmemo}
+\tcbinputlisting{
+  listing only, left=1.5mm, right=1mm,
+  listing options app={basicstyle=\tt\small},
+  listing file=\exampledir\myccmemo,
+  example title, title=the second poor man's box's cc-memo,
+}%
+\endgroup
+
+And how does |\poormansbox at outer| get into the cc-memo, which normally only
+includes a call to \refcmd{mmzIncludeExtern}, you ask? This is the job of the
+memoization driver, which is in this case integrated into the inner command.
+The overall shape of the driver is the same as the shape of the standard
+driver, discussed in section~\ref{sec:memoization-driver-default}: typeset the
+extern material into a box, externalize this box, append the extern-inclusion
+code to the cc-memo, and put the extern box into the document.  It is the
+cc-memo part which interests us right now: unlike the standard driver, we don't
+simply append the contents of |\mmz at temptoks|, i.e.\ a
+\refcmd{mmzIncludeExtern} call; we rather append a call to
+|\poormansbox at outer|, which gets the \refcmd{mmzIncludeExtern} call as its
+second argument (and the options as its first argument).
+
+The core part of the driver, which externalizes the box and appends to the
+cc-memo, is embedded inside the true branch of conditional
+\refcmd{IfMemoizing}|[1]{pmb}|.  We already used this conditional in
+section~\ref{sec:memoization-multiple-externs}, but without the optional
+argument.  Such usage will not work here, because it is not recursion-safe.
+Unlike in the \cs{countdown} situation, one |poormansbox| environment can be
+embedded in another one (and, in our example, it is).  If we deployed
+\refcmd{IfMemoizing}|{pmb}| in the inner command, the driver would be executed for
+\emph{both} the outer and the inner instance of the environment, whereas it
+should really be executed only for the outer instance.
+
+When used in a recursion-safe way, i.e.\ with the optional argument,
+\refcmd{IfMemoizing} first tests whether the auxiliary command-specific
+conditional from the previous section is true, and then proceeds to compare the
+current group level (\hologo{eTeX}'s \refcmd{currentgrouplevel}) to the group
+level at the start of memoization (which Memoize stored in
+\refcmd{memoizinggrouplevel}).  Only if these group levels match do we know
+that we're working on the outer instance of the environment, and that we should
+therefore execute the memoization driver.  Importantly, though, the two group
+levels are compared modulo the offset, given as the optional parameter to
+\refcmd{IfMemoizing}: in our example, the offset is 1, because the driver is
+located inside the |poormansbox| environment, which opens a group --- note that
+0 zero (no offset) is not the default optional parameter; the absence of the
+optional parameter indicates that the non-recursion safe method should be
+used.\footnote{Even this approach is not completely bullet-proof.  It will only
+  work when the inner instance of the command is guaranteed to occur in an
+  additional group, i.e.\ when our command opens up a group for any free-form
+  code.  I will assume that situations which require externalization of a
+  potentially recursive command which, for some reason, cannot open the group
+  before processing a free-form argument, are rare enough to not warrant a
+  generic solution here.}
+
+
+\FloatBarrier
+
+
+\subsubsection{Shipout}
+
+Memoize is a hypocrite: when it is creating extern pages, it uses
+\refcmd{primitive}\refcmd{shipout} to bypass the regular shipout routine of the
+format, but it is offended if anyone else does that.
+
+Memoize bypasses the regular shipout because the extern pages should really not
+be modified or discarded by a foreign package.  But using the primitive
+\refcmd{shipout} means that extern shipouts can't be detected by another
+package, at all.  To facilitate peaceful coexistence with a potential package
+which needs to know about our extern pages, we offer public counter
+\refcmd{mmzExternPages} holding the number of externs shipped out so far.  And
+if anyone really needs to \emph{do} something at every extern shipout, they can
+always (ab)use \refmmz[show keypath]{record/record type/new extern} as a
+post-extern-shipout hook.
+
+The other side of the story is about Memoize needing to know the ``physical''
+page numbers of its externs in the document PDF --- how else are we to extract
+them?  Memoize computes these page numbers by adding the values of several
+counters: \refcmd{mmzRegularPages}, which holds the number of regular shipouts;
+the above-mentioned \refcmd{mmzExternPages}, which holds the number of extern
+shipouts; and \refcmd{mmzExtraPages}, which holds the number of other shipouts.
+The latter counter should be advanced by a package which, like Memoize,
+bypasses the regular shipout routine.
+
+\hologo{LaTeX} and \hologo{ConTeXt} kindly provide the number of regular
+shipouts as publicly a accessible counter, so we define
+\refcmd{mmzRegularPages} as synonymous with their
+\refcmd{ReadonlyShipoutCounter} and \refcmd{realpageno}.  In \hologo{plainTeX}, we
+have to hijack the \refcmd{shipout} control sequence and count regular shipouts
+ourselves; as we have to hijack it while it still refers to the
+\refcmd{shipout} primitive, this format provides another reason for preferring
+Memoize to be loaded early.
+
+
+\subsection{Automemoization}
+\label{sec:tut:automemoization-details}
+
+Automemoization is a mechanism that automatically memoizes the result of the
+compilation of certain commands and environments.  Writing Memoize, I went to
+great lengths to make it flexible, yet easy to use.  This resulted in
+automemoization deploying two specifically developed auxiliary packages:
+package Advice, which provides a generic framework for extending the
+functionality of selected commands and environments, and package CollArgs,
+which provides a command for collection of the arguments conforming to the
+given (slightly extended) \pkg{xparse} argument specification.
+
+This section lists the considerations which went into designing the system,
+followed by short tutorials on both auxiliary packages, which include several
+examples of how Memoize uses the underlying advising framework.
+
+\paragraph{(De)activation}
+Ideally, all commands and environments where memoization makes sense would
+support Memoize (or Memoize would support them) and nothing would ever go
+wrong.  In this dream world, memoization would be completely transparent to the
+author.  However, things will go wrong, so at the very least, we need to
+offer the author a \emph{simple} way to \emph{selectively} switch automemoization
+on and off.  This is achieved by keys \refmmz{activate} and
+\refmmz{deactivate}.
+
+\paragraph{Submission}
+Of course, there will be commands without official support by either Memoize or
+the package which defines them; clearly, at the moment when I write this, all
+commands but \cs{tikz}, \env{tikzpicture} and \env{forest} are such.  Or, the
+author might want to automemoize his or her own command.  Ideally, submitting a
+new command to automemoization would be as simple as
+|memoize=|{\meta{command}}, and for environments, this is in fact achievable,
+although the actual interface is
+\refmmz{auto}|=|\braces{\meta{environment}}\braces{\refmmzauto{memoize}}.  But
+simply submitting the name cannot work for commands, because commands are where
+we encounter the major \hologo{TeX}nical problem with automemoization: we need
+to somehow collect the arguments of the command --- without executing the
+command itself.
+
+\paragraph{Argument collection using CollArgs}
+\hologo{TeX} being \hologo{TeX}, automatically determining the scope of a
+command in general is just plain impossible.  Note that inspecting the
+|\meaning| is not enough in general, because the ``real'' and the formal
+arguments of a command can, and quite often do, differ wildly.  The author (or the
+package writer) will need to tell Memoize about the argument structure of the
+command.  And as there is already a nice and general argument specification on
+the market --- I'm obviously referring to the argument specification of package
+\pkg{xparse}, which was recently even integrated into the core \hologo{LaTeX}
+--- why not use that?  Memoize comes with an auxiliary package CollArgs, which
+(given the slightly extended \pkg{xparse}-style argument specification)
+collects the arguments of a command into a single entity.  All the user needs
+to write to enable automemoization for a command is thus
+\refmmz{auto}|=|\meta{command}\braces{\refmmzauto{memoize},
+  \refmmzauto{args}|=|\braces{\meta{argument specification}}}.  Even simpler,
+when it comes to commands defined by \pkg{xparse}'s \refcmd{NewDocumentCommand}
+or friends, writing \refmmz{auto}|=|\meta{command}\braces{\refmmzauto{memoize}}
+will suffice, as the argument specification of these commands can be retrieved
+by \refcmd{GetDocumentCommandArgSpec}.
+
+\paragraph{Weird commands}
+Not every argument structure can be described using \pkg{xparse}'s argument
+specification, a case in point being \refcmd{tikz} with its totally
+idiosyncratic syntax --- and if Memoize won't support \cs{tikz}, why have it at
+all?  The interface to automemoization must be flexible enough to cover even
+the craziest commands, and this is why Memoize allows for arbitrary argument
+collectors.  These are defined by the advanced user or package writer and then
+declared to be used for parsing the argument structure of a command by writing
+\code{\refmmz{auto}=\marg{command}\bracestt{...,\refmmzauto{collector}=\meta{argument
+      collector}}}.
+
+\paragraph{Over and above automemoization: handlers}
+The framework facilitating automemoization must cover more than just that.  For
+one, it sometimes makes sense to automatically \emph{prevent} memoization
+during the execution of certain commands (as in the \refmmzauto{nomemoize}
+example in section~\ref{sec:tut:redefinitions}).  It follows that the action
+performed to an invocation of a command should not be fixed.  In the advising
+framework, implemented by the auxiliary package Advice, we assign each
+advised command a handler --- a command which does the real work of
+memoizing or whatever.  Crucially, the handler and the collector are
+independent of each other, allowing a single memoization handler to handle
+commands with both standard and non-standard argument structure, and allowing a
+single collector to serve either the memoization or the no-memoization handler.
+
+\paragraph{Over and above automemoization: the outer and the inner handler}
+Second, unlike the memoization handler set by \refmmzauto{memoize}, not all
+handlers work with the entire argument list of the advised command.  Some
+handlers don't care about the arguments of the advised command at all:
+\refmmzauto{abort} simply aborts memoization whenever the advised command is
+executed.  Other handlers are only intended to advise a single command or a
+small family of commands, and need to inspect specific arguments of the advised
+command: for example, \refmmzauto{ref} needs to append the internal
+cross-reference macro to the context, and it of course constructs the name of
+this macro from the reference key.  For all such handlers, it would be plain
+wasteful to first collect the arguments and then tear them apart to inspect
+them (or not).  The advising framework therefore recognizes two kinds of
+handlers.  The abortion and the cross-reference handler are examples of an
+\emph{outer} handler, which is simply placed in front of the arguments of the
+handled command as they are, without invoking the collector.  The memoization
+handler, on the other hand, is an example of an \emph{inner} handler, which
+receives the entire argument list from the collector (as a single argument) ---
+or more precisely, even \refmmzauto{memoize} sets up an outer handler, but this
+outer handler doesn't do much more than invoke the collector, which in turn
+invokes the inner handler.
+
+\paragraph*{Run conditions} are another, if minor, lego piece of the
+advising framework.  Using key \refmmzauto{run conditions}, the user can set the
+conditions under which the (outer) handler is executed; for example,
+cross-reference commands are only advised when memoization is underway.  And
+the same goes for \refcmd{label}, and for the \refmmzauto{replicate}d
+\refcmd{index}, and for \refcmd{savepos}, upon which memoization must be
+aborted.  The bottom-line is that run conditions repeat across handlers, so
+it makes sense to separate them out as an independent component of the
+framework, with the added bonus that the system can make sure that an
+invocation of a advised command which does not satisfy the run conditions
+will incur as litte overhead as possible.
+
+\paragraph{Bailout handler}
+An automemoized command applies the next-options (set by \refcmd{mmznext}), but
+what happens when the run conditions are not satisfied?  If nothing happened,
+the existing next-options might apply to the next instance of
+(auto)memoization, which would not be what the author intended.  This is why
+Advice introduces the bailout handler, a piece of code executed before the
+original command when the run conditions are not met.  Obviously, the bailout
+handler for memoization clears out the next-options (and does not process
+them).
+
+\paragraph{The structure of advice}
+Together, the components mentioned above form a piece of \emph{advice}:
+
+\begin{center}
+  \begin{forest}
+    /tikz/edge node/.style={midway, font=\scriptsize, yshift=0.5ex},
+    for tree={l sep=5ex, % manual, to avoid a page break
+      child anchor=north, s sep+=2em},
+    [activated?
+      [\refmmzauto{run conditions}?,
+        edge=dashed, edge label={node[edge node, left]{yes}}
+        [\refmmzauto{outer handler}\meta{args},
+          edge=->, edge label={node[edge node, left]{yes}},
+          [default:,
+            edge=dashed,
+            [\refmmzauto{collector}\meta{args}, edge=->,
+              [\refmmzauto{inner handler}
+                \textcolor{red}{\bracestt{\textcolor{black}{\meta{args}}}},
+                edge=->
+              ]
+            ]
+          ]
+          [other:\\whatever\rlap\footnotemark,
+            align=center, edge=dashed]
+        ]
+        [\refmmzauto{bailout handler},
+          edge=->, edge label={node[edge node, right]{no}},
+          [\meta{original command}\meta{args}, edge=->]
+        ]
+      ]
+      [\meta{original command}\meta{args},
+        edge=dashed, edge label={node[edge node, right]{no}},
+      ]
+    ]
+  \end{forest}%
+  \footnotetext{The handler may do whatever as long as it consumes all and
+    only the arguments of the original command.}
+\end{center}
+
+
+
+\paragraph{Deferred activation}
+Memoize needs to be loaded early, but activation should take place late, so
+that it can surely override the submitted commands; a case in point,
+\pkg{hyperref} redefines \refcmd{ref} very late.  To address the issue, the
+advising framework implements the deferred \refmmz{activation} regime, under
+which (de)activation commands are not executed but collected in a special
+style, \refmmz{activate deferred}.  Memoize deploys the deferred activation
+regime throughout the preamble, and executes \refmmz{activate deferred} at the
+latest possible \docref{hook:begindocument} hook; as a bonus, it also offers
+the author a way to avoid automatic activation completely by invoking key
+\refmmz{manual}.
+
+
+\paragraph{Install anywhere}
+Once all this machinery is developed, why not offer it to others as well?
+
+Once I decided to offer Advice (at the time, still called Auto) as a standalone
+package (and I freely admit that the framework got much cleaner once I
+separated its code out of Memoize) it became immediately clear that if it is
+to serve as a generic framework, it should be possible for multiple packages to
+use it without interfering with each other.  The package thus allows any number
+of installations into different namespaces, each namespace a \pkg{pgfkeys}
+keypath.  The installation is a breeze:
+\cs{pgfkeys}\bracestt{\meta{namespace}/\refkey{/handlers/.install advice}}.
+
+
+\subsubsection{Using package Advice}
+\label{sec:advice}
+
+In this section, we will provide some examples of handler declarations, mainly
+based on how Memoize deploys the advising framework.
+
+\paragraph{\refmmzauto[show keypath]{memoize}}
+
+In section~\ref{sec:tut:automemoization}, the author was instructed to submit a
+command to automemoization by writing
+\code{\refmmz{auto}=\meta{command}\bracestt{\refmmzauto{memoize},...}}.  The
+auto-key \refmmzauto{memoize} is a style (defined by Memoize rather than
+Advice) which sets the appropriate components of the automemoization advice.
+Residing in keypath \refkeypath{/mmz/auto}, it is effectively defined as
+follows:
+
+\begin{tcblisting}{listing only}
+\mmzset{
+  auto/memoize/.style={
+    run if memoization is possible,
+    bailout handler=\mmz at auto@bailout,
+    outer handler=\mmz at auto@outer,
+    inner handler=\mmz at auto@memoize
+  }
+}
+\end{tcblisting}
+
+The heart of this advice is its inner handler, which actually triggers
+memoization by executing \refcmd{Memoize}.  Remember that the first argument of
+\refcmd{Memoize} is the code which the md5sum is computed off of.  This
+argument must therefore be identical to the author's invocation of the
+automemoized command or environment.  Given what Advice offers, this is easy to
+construct: \refcmd{AdviceReplaced} holds the code replaced by the advice, and
+the \meta{arguments} of the automemoized command are waiting for us in |#1|.
+The second argument of \refcmd{Memoize} will be similar, but as this is the
+code which will get compiled, we have to execute the original definition of the
+command, followed by the (unbraced!) \meta{arguments} as |#1|; this is a job
+for \refcmd{AdviceOriginal}.  (Note that \emph{executing}
+\refcmd{AdviceReplaced} would run the auto-handler again, resulting in an
+infinite loop! Or at least a pile of errors.)
+
+However, the overly simplistic approach shown below won't necessarily work.
+The issue is that the arguments of \refcmd{Memoize} contain
+\refcmd{AdviceReplaced} and \refcmd{AdviceOriginal} themselves, instead of their
+contents, i.e.\ (first) expansions.
+
+\begin{tcblisting}{listing only, bad}
+\long\def\mmz at auto@memoize#1{%
+  \Memoize{\AdviceReplaced#1}{\AdviceOriginal#1}%
+}
+\end{tcblisting}
+
+Regarding the first argument, the problem is that the code md5sum will be
+computed off of the token list \refcmd{AdviceReplaced}\meta{arguments} ---
+exactly as you see it.\footnote{If you inspected a c-memo, you would find
+  \refcmd{AdviceReplaced}\meta{arguments} in the \refcmd{mmzSource} section.}
+This implies that two commands sharing exactly the same \meta{arguments} will
+receive the same (c-)memo.  For example, if you automemoized first
+|\textit{foo}| and then |\textbf{foo}|, both would come out as a bold ``foo''
+upon utilization.
+
+The second argument illustrates a general issue about the lifespan of
+\refcmd{AdviceOriginal} and other |\Advice...| commands.\footnote{The list of
+  all commands available only within the handler can be found in the
+  documentation of key \refmmzauto{outer handler} in
+  section~\ref{sec:ref:advice}.}  By executing \refcmd{Memoize}, we leave the
+advice and thereby cannot be sure that when expanded, \refcmd{AdviceOriginal}
+will mean what it means at the moment.  In general, another piece of advice might be
+triggered until its expansion, or the group might be closed, etc.  For example,
+the author may have issued \refcmd{mmznext}\bracestt{\refmmz{at begin
+    memoization}=\cs{label}\marg{key}}, and as the pre-memoization code is
+executed before the memoization driver, the \cs{label}, which is submitted to
+Advice so that any \cs{label}s inside the memoized code ``just work'', would
+execute another piece of advice, redefining \refcmd{AdviceOriginal} and friends.
+Effectively, you'd end up memoizing an invocation of the \cs{label} command.
+
+The bottom line is that while the code following the above template
+\emph{might} sometimes work, Advice offers no guarantees that it will, so I
+advise against using it.  The actual definition of the memoization inner
+handler is shown below.  In this definition, we expand \refcmd{AdviceReplaced}
+and \refcmd{AdviceOriginal} --- exactly once! --- into the respective arguments
+of \refcmd{Memoize}; of course, as the entire invocation of \refcmd{Memoize} is
+expanded, we have to guard against expanding the collected arguments (|#1|) and
+\refcmd{Memoize} itself.\footnote{As the final touch, the handler also contains
+  \refcmd{ignorespaces} after the invocation of \refcmd{Memoize}, if this was
+  requested using \refmmz{ignore spaces}.  Note that this could not be done
+  without pre-expanding the \cs{ifmmz at ignorespaces} conditional, as
+  \refcmd{Memoize} closes the group in which the auto- and the next-options are
+  applied.}  The result of the expansion is shown under the code: the first and
+the second line assume we are automemoizing command |\foo| and environment
+|bar|, respectively.  Note that \refcmd{AdviceOriginal} expands into an
+invocation of \refcmd{AdviceGetOriginal}, a command which may be safely used
+outside the advice; the first argument of this command is the auto-namespace
+(in our case, \refkeypath{/mmz}), and the second argument is the advised
+command.  For a \hologo{LaTeX} environment, the advised command is actually
+\refcmd{begin}, and this is why the call of \refcmd{AdviceGetOriginal} is of
+course followed by the environment name.
+
+\makeexcerpt{_auto-memoize-inner}
+\tcbinputexample[.tex][.excerpt]{%
+  listing and comment, one file, no attachment,
+  title={The implementation of the \refmmzauto{inner handler}
+    for automemoization},
+  comment={%
+    $\rightarrow$ \refcmd{Memoize}\braces{\cs{foo}\Arg1}%
+    \braces{\refcmd{AdviceGetOriginal}\bracestt{/mmz}\bracestt{\cs{foo}}\Arg1}\\
+    $\rightarrow$ \refcmd{Memoize}\braces{\cs{begin}\bracestt{bar}\Arg1}%
+    \braces{\refcmd{AdviceGetOriginal}%
+      \bracestt{/mmz}\bracestt{\cs{begin}}\bracestt{bar}\Arg1}
+  }
+}
+
+Let us now move backwards in time and look at the outer handler installed by
+\refmmzauto{memoize}.  It is very simple, but performs an important function of
+applying the auto- and the next-options (in this order), which also
+necessitates opening a group (closed by \refcmd{Memoize}).  The final line
+invokes the argument collector, which then calls the inner handler; remember
+that the invocation of \refcmd{AdviceCollector} is the sole function of the
+default outer handler.
+
+\makeexcerpt{_auto-memoize-outer}
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file, no attachment,
+  title={The implementation of the \refmmzauto{outer handler}
+    for automemoization},
+}
+
+Moving even further back in time, we arrive at the run conditions.  The
+\refmmzauto{memoize} style invokes \refmmzauto{run if memoization is possible},
+defined as \code{run conditions=\cs{mmz at auto@rc at if@memoization at possible}}, with
+the installed macro as shown below.  Indeed, memoization only makes when
+Memoize is \refmmz{enable}d (which we test using \refcmd{ifmemoize}), but we're
+not already ``inside \refcmd{Memoize}'' (which we test using
+\refcmd{ifinmemoize}).  The latter condition is true when we're either
+memoizing or regularly compiling some code submitted to memoization (see the
+diagram in section~\ref{sec:Memoize}).  Note that it is not necessary to invoke
+\refcmd{AdviceRunfalse} in branches where the run conditions are not satisfied.
+
+\makeexcerpt{_auto-run-if-memoization-is-possible}
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file, no attachment,
+  title={The implementation of 
+    \refmmzauto{run if memoization is possible}},
+}
+
+While it is clear that double memoization is a no-no, why should we avoid
+memoizing inside a regular compilation?  Imagine that Memoize decides not to
+memoize a Forest tree, perhaps because \refmmz{readonly} is in effect.  Under
+the hood, Forest creates many \env{tikzpicture}s.  Should all of them be
+(auto)memoized now? Certainly not.
+
+Finally, what happens when the run conditions are not met?  Not much, but
+something important nevertheless: by consuming the next-options, the
+\refmmzauto{bailout handler} makes sure they will not erroneously apply to the
+next instance of (auto)memoization.
+
+\makeexcerpt{_auto-memoize-bailout}
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file, no attachment,
+  title={The implementation of the \refmmzauto{bailout handler}
+    for automemoization},
+}
+
+The only component of the automemoization advice not determined by style
+\refmmzauto{memoize} is the argument collector, which allows the user to submit
+a command with a weird argument structure to automemoization simply by setting
+key \refmmzauto{collector} in addition to executing \refmmzauto{memoize}.  For
+example, Memoize submits \refcmd{tikz} to automemoization by loading
+\reffile{advice-tikz.code.tex}, which contains Advice's definition of the
+\cs{tikz} collector \refcmd{AdviceCollectTikZArguments}, and issuing the
+following declaration.
+
+\makeexcerpt{_auto-tikz-collector}
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file, no attachment,
+  title={Declaring automemoization of command \cs{tikz}},
+}
+
+\paragraph{\refmmzauto[show keypath]{ref}}
+
+The cross-reference advice presents an example of an outer handler radically
+different from the default outer handler.  This outer handler does not invoke
+the collector at all.  As shown below, it grabs the argument of \refcmd{ref} (or
+whichever cross-referencing command) on its own --- remember that the outer
+handler receives the arguments of the handled command ``as they are,'' i.e.\
+uncollected.  It then asks \refcmd{mmzNoRef} to do the real job of getting the
+reference key into the context, and finally executes the original \cs{ref}.
+
+\ExampleName{_auto-ref}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{%
+  listing only, no attachment,
+  title={\hypercolor{link}{white}A simplified\footnotemark{} definition
+    of \refmmzauto{ref}},
+  % This only works if there is a single footnote in the memoized code.
+  /mmz/context/.expanded={footnote=\numexpr\thefootnote-1},
+}\footnotetext{The real outer handler allows for arbitrary optional arguments of
+  the cross-referencing command, and shares code with \refmmzauto{force
+    ref}.}
+
+The run conditions of this style are agonizingly simple: \refmmzauto{run if
+  memoizing} sets \refmmzauto{run conditions} to a macro defined as
+\refcmd{ifmemoizing}\hyp\refcmd{AdviceRuntrue}\hyp\cs{fi}.
+
+\paragraph{\refmmzauto[show keypath]{abort}}
+
+The advice for aborting memoization is very simple --- it merely executes
+\refcmd{mmzAbort} --- but also very sneaky.  Here, the \refmmzauto{run
+  conditions} do the real work of aborting memoization, while the ``real,''
+i.e.\ outer handler, never even gets executed; note the absence of
+\refcmd{AdviceRuntrue}, which implies \refcmd{AdviceRunfalse}, which triggers
+the execution of the original command after the run conditions are ``checked.''
+
+\makeexcerpt{_auto-abort}
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file, no attachment,
+  title={The definition of \refmmzauto{abort}},
+}
+
+The point here is that executing \refcmd{mmzAbort} (itself a single-liner
+setting an internal conditional) is cheaper than testing for the real run
+conditions (\refmmzauto{run if memoizing}) and aborting only if they are
+satisfied.  Of course, the trick only works because (i) the advice doesn't
+need to inspect any arguments of advised command, and because (ii) setting the
+internal abortion conditional outside memoization does no damage.
+
+\paragraph{Advice in chains}
+
+A command may be submitted to several instances of the advising framework,
+i.e.\ instances installed under different keypaths.  In the example below, we
+submit |\foo| both to the instance of Advice installed in keypath |/one| and to
+the one installed in keypath |/two|.  Under |/one|, the result of |\foo{...}|
+will be boxed (|\fboxWrap|); under |/two|, in will be parenthesized
+(|\parenWrap|).  The order in which this happens depends on the order in which
+|\foo| was activated under different keypaths.  If we first activate it under
+|/one| with the boxing effect and then under two with the parenthesizing
+effect, the box will appear within parenthesis; if we reverse the activation
+order, the parenthesis will appear inside the box.
+
+\ExampleName{chained-advice}
+\makeexample{\examplename.tex.c1 N=2}
+\tcbinputexample{comment=\input{\examplepath.tex.c2}}
+
+First of all, looking at the code above, you have probably noticed the absence
+of key \refmmz{auto}.  This is because by default, \refkey{/handlers/.install
+  advice} defines the \emph{setup key} to be |advice| --- Memoize overrides
+this default by installing the framework with \refkey{/handlers/.install
+  advice}|=|\bracestt{\refkey{/advice/install/setup key}=auto, ...}.
+
+Next, |advice'| is a variant of |advice| which prevents automatic activation
+upon setup (and the same holds for |auto'| vs.\ |auto| in Memoize).  We have
+used the bar variant above to make it clear that it is the order of activation,
+rather than declaration by |advice|\slash \refmmz{auto}, which matters in
+determining which handler is applied first.
+
+Finally, note that the deactivation order must be the reverse of the activation
+order.  So if we activate |\foo| first in |/one| and then in |/two|, we should
+deactivate it in |/two| first and in |/one| next, otherwise Advice will
+complain.
+
+
+\paragraph{A simple collector}
+
+Let us implement a collector for a command which accepts one (standard
+\hologo{LaTeX}) optional argument and one mandatory argument; in \pkg{xparse}
+terms, a command with argument specification |om|.
+
+Using \cs{NewDocumentCommand}, such a collector is very easy to implement.  We
+simply define a command with signature |om| and distinguish two possibilities
+regarding the presence of the optional argument, which we test using
+\cs{IfValueTF}.  If the true branch, we pass a \emph{braced} |[#1]{#2}| to the
+inner handler, which we invoke by \refcmd{AdviceInnerHandler}; in the false
+branch, we omit the optional argument, passing it an (additionally) braced
+|{#2}|.
+
+\ExampleName{om-collector-NewDocumentCommand}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{listing only}
+
+Defining a functionally equivalent collector using \cs{newcommand} would be a
+bit more involved, as \hologo{LaTeX2e} does not offer a standardized way to
+test for the \emph{presence} of the optional argument.  Consider the following
+collector, whose optional argument has the same default value as the advised
+command.  Is it functionally equivalent to the one above?
+
+\ExampleName{om-collector-newcommand}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{listing only}
+
+While there will be no visual difference, there is a difference under the hood.
+If you compile both documents, you will see that the first one creates three
+memos\slash externs, while the second one only creates two: |\foo{...}| does
+not have its own memo anymore, but creates and uses the same memo as
+|\foo[green]{...}|.
+
+While the second version might sometimes be preferred, perhaps even in the
+context of memoization, the initial collector, which deploys command
+\refcmd{CollectArguments}, behaves like the \cs{NewDocumentCommand}-defined
+collector above,\footnote{In fact, there is a slight difference after all.
+  While the above-defined collector won't distinguish between the single-token
+  mandatory argument given with or without braces, \refcmd{CollectArguments}
+  will again faithfully replicate the original argument tokens.} as it attempts
+to perfectly replicate the command invocation.  Furthermore, this behaviour
+makes it unnecessary for the author to provide the default values of optional
+arguments (and even allows them to replace |O{default}| in the argument
+specification by \docref{xparse:o}).
+
+We now turn to the package CollArgs, which implements the actual argument
+collection; we'll revisit the initial collector of Advice at the end of the
+following subsection.
+
+
+
+\subsubsection{Using package CollArgs}
+\label{sec:collargs}
+
+Automemoization is implemented on top of the framework offered by package
+Advice, and that package in turn couldn't really work as intended without
+package CollArgs.  A regular user of Memoize shouldn't need to know anything
+about CollArgs, but a package writer wanting to support Memoize might have to.
+
+The package provides two public commands, \refcmd{CollectArguments} and
+\refcmd{CollectArgumentsRaw}; we'll focus on the former first.
+\refcmd{CollectArguments} takes three arguments: optional \meta{options} in the
+form of a \pkg{pgfkeys} keylist; a mandatory \meta{argument specification} in a
+(slightly extended) \pkg{xparse} format; and the \meta{next-code}:
+\begin{center}
+  \refcmd{CollectArguments}\oarg{options}\marg{argument specification}\marg{next-code}%
+  \textcolor{gray}{\meta{tokens}}
+\end{center}
+Following the three formal arguments of \refcmd{CollectArguments} are some
+\meta{tokens} --- the rest of the document, really --- and the job of
+\refcmd{CollectArguments} is to figure out the extent to which these
+\meta{tokens} conform to the given \meta{argument specification}.  In other
+words, \refcmd{CollectArguments} will consume as many of the \meta{tokens} as a
+\meta{command} defined by \refcmd{NewDocumentCommand}\meta{command}\marg{argument
+  specification}\bracestt{...} would.  Once these \meta{argument tokens} are
+collected, \refcmd{CollectArguments} executes the \meta{next-code} with the
+\meta{argument tokens} given as a single, braced argument (clearly, the
+\meta{rest} of the \meta{tokens}, i.e.\ the non-consumed tokens, will follow):
+\begin{center}
+  \meta{next-code}\marg{argument tokens}\textcolor{gray}{\meta{rest}}
+\end{center}
+
+In the example below, we define macro |\PrintAndDo|, which takes two arguments,
+a command and the collected arguments of that command, prints out which command
+we're about to execute and with what arguments, and then executes that command
+with those arguments --- |#1#2| at the end of the definition.  Note that |#2|
+immediately following |#1| is not braced, so
+|\PrintAndDo\makebox{[5em][r]{text}}| executes |\makebox[5em][r]{text}|.
+
+{\tolerance 1000 Executing |\PrintAndDo\makebox{[5em][r]{text}}| directly would
+  thus yield the first line of the result below --- and in fact, this is
+  precisely what gets executed to yield that line, but in a roundabout fashion.
+  Given the argument specification |oom| (two optional arguments followed by a
+  mandatory argument), \refcmd{CollectArguments} figures out how many tokens
+  following its formal arguments conform to this argument specification ---
+  below, these would be |[5em][r]{text}| following
+  \refcmd{CollectArguments}\hyp|{oom}{\PrintAndDo\makebox}|--- and puts them,
+  braced, behind its \meta{next-code} argument, |\PrintAndDo\makebox|, yielding
+  |\PrintAndDo|\hyp|\makebox{[5em][r]{text}}|.\par}
+
+\ExampleName{collargs-makebox}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{listing and compile}
+
+Seeing the arguments of |\makebox| without the immediately preceding |\makebox|
+might seem strange, but remember that \refcmd{CollectArguments} is about the
+arguments of a command, not about the command's control sequence.  It doesn't
+know or care which command the argument tokens ``belong'' to, as long as they
+conform to the given specification.  In the example above, it is only in |#1#2|
+of |\PrintAndDo| that |\makebox| is ``reunited'' with its arguments, but note
+that the reunion is far from obligatory.
+
+CollArgs supports all the argument types (and modifiers) that \pkg{xparse}
+does, including the environment type \docref{xparse:b}, as exemplified below.
+Again, the code below might seem strange, as it features an |\end{minipage}|
+without the matching |\begin{minipage}|, but the logic is similar as for
+  commands: just as \refcmd{CollectArguments} occurs in front of the command
+  arguments, without the command itself, so it occurs in front of the
+  environment body, without the opening of that body.  However, while
+  \refcmd{CollectArguments} never needs to know the command name, we need to
+  inform it of the environment name, so that it can find the end of the
+  environment.  This can be achieved as shown below, using key
+  \refcollargs{environment} in the optional argument of the command, or by our
+  extension to the \pkg{xparse} argument specification, where the environment
+  argument type \docref{xparse:b} may be followed by a braced environment name.
+  In the example below, we could therefore also invoke argument collection by
+  \refcmd{CollectArguments}\braces
+  {\docref{xparse:+}\docref{xparse:b}\braces{\env{minipage}}} (we have preceded
+  \docref{xparse:b} with a \docref{xparse:+} to allow for an environment body
+  containing paragraph tokens).\footnote{CollArgs automatically adapts to the
+    format, i.e.\ it knows that environments are tagged by \cs{}\meta{name} and
+    \cs{end}\meta{name} in \hologo{plainTeX} and by \cs{start}\meta{name} and
+    \cs{stop}\meta{name} in \hologo{ConTeXt}.}
+
+\ExampleName{collargs-minipage}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{comment=\input{\examplepath.tex.c1}}
+
+You might wonder why didn't we provide \refcmd{CollectArguments} in the
+previous example with argument specification |omb| --- after all, the
+\env{minipage} environment takes an optional and a mandatory argument.  While that
+would work, and produce the same result,\footnote{Unless argument processing
+  was in effect; see section~\ref{sec:ref:collargs} for details.} note that
+\refcmd{CollectArguments} is only interested in finding the scope of the
+arguments, and grabbing everything until |\end{minipage}| is the same as first
+grabbing the optional argument, maybe, then the mandatory argument, and finally
+the argument body.
+
+\refcmd{CollectArguments} not only supports \pkg{xparse}'s verbatim argument
+type \docref{xparse:v}, it can grab an argument of \emph{any} type in the
+verbatim mode, triggered by option \refcollargs{verbatim}.\footnote{We refer to
+  the verbatim mode triggered by \refcollargs{verbatim} as the full verbatim
+  mode, where all characters are of category ``other''.  There is also the
+  partial verbatim mode, triggered by \refcollargs{verb}, where braces retain
+  their normal category codes.} We illustrate this key below, where we also use
+option \refcollargs{tags}, which makes CollArgs automatically surround the
+grabbed environment body with the begin tag \refcmd{begin}\marg{environment
+  name} and the end tag \cs{end}\marg{environment name}, and use
+\refcmd{scantokens} to execute the grabbed environment.  Consult
+section~\ref{sec:ref:collargs} for the full reference on the verbatim mode and
+its limitations.
+
+% A harmless warning: 
+% Missing character: There is no ^M (U+000D) in font [lmmono10-regular]:!
+% because \texttt in the example is fed a (verbatim) carriage return
+\ExampleName{collargs-verbatim}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{listing and compile}
+
+Finally, CollArgs extends the \pkg{xparse} specification by modifier
+\docref{xparse:amp}, which allows the user to specify options which apply only
+to the following argument, as opposed to the options given as the optional
+argument of \refcmd{CollectArguments}, which apply to all the arguments.  A
+third way to invoke the environment body collection in the above example is
+thus \refcmd{CollectArguments}%
+\bracestt{\docref{xparse:amp}\bracestt{\refcollargs{environment}=minipage}+b}.
+
+Both the single-argument and the common options can be given not only as
+\pkg{pgfkeys} keys, but also in the raw, ``programmer's interface'' format.
+Every option key has a corresponding macro; for example, key
+\refcollargs{environment} is matched by macro \refcmd{collargsEnvironment}.
+The macros are listed alongside their corresponding keys in the reference
+section~\ref{sec:ref:collargs}; here, we merely learn how to use them.
+
+To use raw options for a single argument, double the ampersand in the argument
+specification.  Therefore, the fourth way to specify the environment name is
+\code{\docref{xparse:amp}\docref{xparse:amp}\bracestt{%
+    \refcmd{collargsEnvironment}\bracestt{minipage}}\docref{xparse:+}\docref{xparse:b}}.
+
+To set the raw options for all arguments, use \refcmd{CollectArgumentsRaw}, the
+second public command of the package.  This command is exactly like
+\refcmd{CollectArguments}, excepts that it expects the options in the raw
+format and as a \emph{mandatory} argument:
+
+\begin{center}
+  \refcmd{CollectArgumentsRaw}\marg{raw options}\marg{argument specification}%
+  \marg{next-code}\textcolor{gray}{\meta{tokens}}
+\end{center}
+
+This leads us to the fifth way to set the environment name (an overkill, I
+know): \refcmd{CollectArgumentsRaw}\hyp
+\bracestt{\refcmd{collargsEnvironment}\bracestt{minipage}}\bracestt{+b}\marg{next-code}.
+Furthermore, you can use a mixture of raw and key--value options: the raw
+option commands include \refcmd{collargsSet}, which applies the given option
+keylist.  The idea here (incarnated by both Auto and Memoize) is that the
+package will provide CollArgs with the raw options, for speed, while the
+author can supplement them in the friendly keylist format --- and this leads
+us to the sixth, and thankfully final way to set the environment name:
+\refcmd{CollectArgumentsRaw}\bracestt{\refcmd{collargsSet}%
+  \bracestt{\refcollargs{environment}=minipage}}\bracestt{+b}\marg{next-code}.
+
+
+\paragraph{The initial collector}
+
+As the final example, let us study Advice's initial collector; this is a macro
+which is used as the collector when key \refmmzauto{collector} is not given.
+This macro is not really \refcmd{CollectArguments}, as we sometimes state to
+simplify matters, but a macro which acts as the ``bridge'' between Advice and
+CollArgs, by compiling an invocation of \refcmd{CollectArgumentsRaw} from the
+given advice setup, and executing it.
+
+The bridge macro is shown below in its full glory, but it is really less
+complicated than it might appear at first sight.  In line~2, we use
+\refcmd{AdviceIfArgs} to see whether the argument structure of the handled
+command was given by the user.  If it wasn't, we assume that the handled
+command was defined using \cs{NewDocumentCommand} or similar, and use
+\refcmd{GetDocumentCommandArgSpec} to retrieve it (line~3; note that
+\refcmd{AdviceName} holds the handled control sequence) and store it into
+\refcmd{AdviceArgs} (line~4), which also receives the argument specification
+when given by the user via key \refmmzauto{args}.
+
+\makeexcerpt{_advice-CollectArgumentsRaw}(../../advice.edtx)
+\tcbinputexample[.tex][.excerpt]{%
+  listing only, one file, no attachment,
+  listing options app={numbers=left, numberstyle=\tiny, numbersep=0.5em},
+  title={The definition of the initial collector},
+}
+
+Lines~6--17 are somewhat of an expansion mess, because we have to construct the
+invocation of the CollArgs' collector from the advice setup stored in various
+macros.  But once we think away all the (non-)expansion commands, we're left
+with \refcmd{CollectArgumentsRaw} plus the following three arguments:
+\begin{enumerate}
+\item The raw options (lines 8--11):
+  \begin{enumerate}
+  \item In line 8, the advised command's control sequence is designated as the
+    \refcollargs{caller}.  The effect is that if the given arguments don't
+    conform to the specification, the error thrown seems to come from the
+    advised command rather than some internal CollArgs macro.  The author will
+    be grateful for this little detail.
+  \item In line 9, we add any \refmmzauto{raw collector options} set by Advice
+    (plus the package deploying Advice, like Memoize); user-given options are of
+    course possible, but not really expected here, because:
+  \item In lines 10--11, we add the user-given \refmmzauto{collector options},
+    if there are any, embedded under \refcmd{collargsSet}.
+  \end{enumerate}
+\item The argument specification (line 14).
+\item The \refmmzauto{inner handler} (line 15).
+\end{enumerate}
+
+
+
+\section{Reference}
+\label{sec:reference}
+
+In this section, the extra information about keys, offered at the right of a
+key in parenthesis, may contain the initial value of a key, and also a default
+value of a key.  In this context, the terms ``initial'' and ``default'' have
+the meaning employed by the \pkg{pgfkeys} utility.  Initial value refers to the
+value that is set by the package.  More often, we would call this the default
+or the package-default value, but in the \pkg{pgfkeys} parlance, the default value
+refers to the value that is passed to the key in the absence of the argument.
+Honestly, I only kept to this convention in the reference section; elsewhere,
+I often say ``default'' or ``package-default'' and mean the initial value.
+
+Another convention I kept to in this section is the color-coding of the keys
+and commands.  Green background indicates a basic key or command, which any
+user might want to know about.  Red background indicates other, more or less
+advanced keys and commands.
+
+
+\subsection{Loading}
+\label{sec:ref:loading}
+\paragraph{\hologo{LaTeX}}
+
+Load Memoize by \cs{usepackage}\braces{\docaux{package}{memoize}} or
+\cs{usepackage}\oarg{options}\bracestt{memoize}.  The latter form functions
+almost identically to the former followed by
+\refcmd{mmzset}\bracestt{\meta{options}}, with two exceptions.
+
+First, the \meta{options} as package options may not contain spaces.  This is a
+constraint imposed by \hologo{LaTeX} itself.  To avoid it for a particular key,
+define a spaceless variant of the key in \reffile{memoize.cfg}.  For example,
+to use \refmmz{memo dir} as a package option, put
+\refcmd{mmzset}|{memodir/.style={|\refmmz{memo dir}|={#1}}}| into that file.
+
+Second, key \refmmz{extract} only make senses as a package option, or within
+\reffile{memoize.cfg}.  Internal extern extraction can only be performed before
+the output PDF is opened, and to maximize chances of that, Memoize is designed
+to extract as soon as it can: while it is being loaded.  Consequently, changing
+the extraction method in the document preamble has no effect.
+
+The necessity of performing extraction before the output PDF is opened is also
+why Memoize prefers to be loaded early with respect to other packages.  In
+particular, it must be loaded before \PGF library |fadings| (see
+section~\ref{sec:fadings-problem}) and before the \pkg{beamer} class (see
+section~\ref{sec:tut:beamer}).
+
+If you're familiar with the \TikZ externalization library, you might wonder
+whether Memoize has an equivalent of the \refcmd{tikzexternalize} command.  It
+doesn't.  Memoize assumes that if you loaded it, you want to use it --- but you
+can always disable it using key \refmmz{disable}, or even by loading package
+\refpkg{nomemoize} in its stead.
+
+In \hologo{LaTeX}, initialization and finalization are completely automatic.
+Memoize defines several initialization and finalization styles ---
+\docaux{key}{begindocument/before}, \docaux{key}{begindocument},
+\docaux{key}{begindocument/end} and \docaux{key}{enddocument/afterlastpage}
+---and executes them at the cognominal \hologo{LaTeX} hooks.
+
+\paragraph{\hologo{plainTeX}}{}
+
+Load Memoize by |\input memoize|.  As package options cannot be provided in
+\hologo{plainTeX}, the author must trigger extraction from \refcmd{mmzset}
+using key \refmmz{extract}; I recommend doing this immediately after loading
+the package.  This key may be invoked with or without a value.  In the latter
+case, Memoize will extract using the package default method
+\refmmz{extract=perl}, unless its has been overriden from
+\reffile{memoize.cfg}.
+
+Furthermore, as \hologo{plainTeX} has no concept of a document body, the text
+must be manually enclosed in \refcmd{mmzset}\bracestt{\docaux{key}{begin
+    document}} and \refcmd{mmzset}\bracestt{\docaux{key}{end document}}; this
+is where the initialization and finalization hooks described above will be
+executed.  Note that \refmmz{extract}, when used, must precede this enclosure.
+
+Finally, \hologo{plainTeX} has another reason for preferring the early loading
+of the package.  In this format, Memoize must redefine \refcmd{shipout}, at a
+time the meaning of this control sequence is still primitive.  In particular,
+this means that Memoize must be loaded before \pkg{atbegshi}.
+
+\begin{tcboxedraster}[raster column skip=1cm]{blankest}
+  \ExampleName{plainTeX}%
+  \makeexample{\examplename.tex.c1}%
+  \tcbinputexample{listing only, title=A minimal \hologo{plainTeX} example}
+  %
+  \ExampleName{ConTeXt}%
+  \makeexample{\examplename.tex.c1}%
+  \tcbinputexample{listing only, title=A minimal \hologo{ConTeXt} example}
+\end{tcboxedraster}
+
+\paragraph{\hologo{ConTeXt}}{}
+
+Load Memoize by \cs{usemodule}\bracketstt{memoize} or
+\cs{usemodule}\bracketstt{memoize}\oarg{options}.  Unlike in \hologo{LaTeX},
+spaces are allowed in \meta{options}; the remarks on key \refmmz{extract} and
+loading order are the same as for \hologo{LaTeX}.
+
+In \hologo{LaTeX}, Memoize automatically executes its initialization and
+finalization code when at the beginning and the end of the document body.  Due
+to my very limited experience with \hologo{ConTeXt}, and its project structure
+in particular, I don't know what the appropriate place for initialization and
+finalization would be in \hologo{ConTeXt}.  I therefore provisionally leave it
+to the author to execute \refcmd{mmzset}\bracestt{\refmmz{begin document}} and
+\refcmd{mmzset}\bracestt{\refmmz{end document}} manually, and hope for advice
+on how to handle this properly.
+
+
+\paragraph{Auxiliary packages}
+
+\begin{doc}{package={name=nomemoize}}
+  Loading this package instead of Memoize completely disables memoization, but
+  does not require removing any Memoize commands from the document (they all
+  become no-ops).
+\end{doc}
+
+\begin{doc}{package={name=memoizable}}
+  This package is a programmer's stub: if Memoize is loaded, it does nothing;
+  otherwise, it provides the no-op variants Memoize commands.  See
+  section~\ref{sec:loading-memoize} for details.
+\end{doc}
+
+
+\subsection{Configuration}
+\label{sec:ref:configuration}
+
+
+\begin{doc}{easy,cmd={name=mmzset, par=\marg{options}}}
+  
+  Update the Memoize configuration.
+
+  The \meta{options} are a comma-separated list of \meta{key}|=|\meta{value}
+  pairs.  They are processed using the \pkg{pgfkeys} utility of PGF/\TikZ (see
+  \PGFmanual{87}), with the default path set to \docaux{key path}{mmz}.
+
+  The changes are local to the current \hologo{TeX} group, except for keys
+  where explicitly noted otherwise.
+\end{doc}
+
+\begin{doc}{easy,
+    cmd={name=mmznext, par=\marg{options}},
+  }
+
+  This command accepts the same \meta{options} as \refcmd{mmzset}, but
+  interprets them as \emph{next-options} --- options which will be applied to
+  the next, and only the next, \emph{auto}memoized command or environment.
+  (Remember that a command or environment is submitted to automemoization by
+  \refmmz{auto}|=|\marg{command or
+    environment}\bracestt{\refmmzauto{memoize},...}; see
+  sections~\ref{sec:tut:automemoization}, \ref{sec:tut:working-on-a-picture}
+  and \ref{sec:ref:advicememoization} for details.)
+
+  Remarks for the author:
+
+  \begin{itemize}
+  \item Key \refmmz{enable} has no effect inside \refcmd{mmznext}.
+  \item If \refcmd{mmznext} is used more than once preceding an automemoized
+    command, only the final invocation takes effect.
+  \item The next-options also apply to commands and environments for which
+    memoization is autodisabled via \refmmz{auto}|=|\marg{command or
+      environment}\bracestt{\refmmzauto{nomemoize},...}.
+  \item It is safe to set the next-options in front of a command submitted to
+    automemoization which does not actually undergo memoization in this
+    particular instance.  In other words, the absence of memoization will not
+    cause the next-options to ``leak'' to the next automemoized command.
+  \item Only the linear (execution) order of \refcmd{mmznext} and the
+    automemoized command matters.  Key \refcmd{mmznext} will correctly apply to
+    a single following automemoized command even if it occurs outside the group
+    which that command is executed from; and it will apply to the following
+    automemoized command even if it is called within a group closed before that
+    command is executed.
+  \end{itemize}
+
+  Remarks for the programmer:
+  \begin{itemize}
+  \item The next-options are set globally.
+  \item The effect of \refcmd{mmznext} is \emph{not} cumulative.  Consequently,
+    \refcmd{mmznext}\braces{} clears the next-options.
+  \item The next-options are applied by executing \refcmd{mmzAutoInit} within
+    the advice.  Any piece of advice applying the next options should also clear them
+    when the \refmmzauto{run conditions} are not met.  This is streamlined by
+    style \refmmzauto{apply options}, intended for use within \refmmz{auto}
+    declarations.  Out of the box, this style is deployed by
+    \refmmzauto{memoize}, \refmmzauto{nomemoize} and \refmmzauto{noop}, but it
+    may be used by any piece of advice.  Note that the \refmmzauto{outer handler}
+    declared by this style opens a group (to apply the options in) but leaves
+    it to the (undeclared) \refmmzauto{inner handler} to close that group.
+  \item Key \refmmz{enable} has no effect inside \refcmd{mmznext} because when
+    Memoize is disabled upon encountering an automemoized command, the advice
+    bails out without ever applying the next-options.  More generally, this
+    applies to any advised command whose run conditions require
+    \refcmd{ifmemoize} to be true.  Key \refmmz{disable}, on the other hand,
+    takes effect, because \refcmd{ifmemoize} is checked within \refcmd{Memoize}
+    as well.
+  \end{itemize}
+\end{doc}
+
+\begin{doc}{easy,file={name=memoize.cfg, desc=file}}
+  The configuration file, loaded just before processing the package options.
+  It will typically contain a \refcmd{mmzset} command, but it may contain any
+  \hologo{TeX} code.
+
+  As for any other file loaded by \hologo{TeX}, the location of the file
+  determines whether it applies system-wide, user-wide or directory-wide.
+
+  This file is also loaded by package \refpkg{nomemoize}, on the off chance it
+  defines some commands other than \refkeypath{/mmz} keys.  (It is not loaded
+  by package \refpkg{memoizable}, though).
+\end{doc}
+
+\begin{doc}{cmd={name=nommzkeys, par=\marg{key}}}
+  In package \refpkg{memoize}, this command is a no-op; in packages
+  \refpkg{nomemoize} and \refpkg{memoizable}, it defines key
+  \refkeypath{/mmz}|/|\meta{key} as a no-op.
+
+  As explained in section~\ref{sec:tut:final}, use this command to declare any
+  \refkeypath{/mmz} keys you have used outside \refcmd{mmzset} when switching
+  to package \refpkg{nomemoize}.
+\end{doc}
+
+
+\subsection{Memoization}
+\label{sec:ref:memoization}
+
+\subsubsection{Manual memoization commands}
+\label{sec:ref:memoization:manual}
+
+\begin{doc}{easy,
+    cmd={name=mmz, par=\oarg{options}\marg{code}},
+    env={name=memoize, par=\oarg{options}},
+  }
+  Submit \meta{code} or \meta{environment body} to memoization.
+
+  Prior to memoization, the configuration is locally updated by executing
+  \meta{options} given as the optional argument to this command, i.e.\ the
+  given options take precedence to options previously set via \refcmd{mmzset}.
+  Note that next-options, set by \refcmd{mmznext}, are not applied.
+
+  The effect of the macro and of the environment version of this command is the
+  same, except that the command version memoizes \meta{code} exactly as-is,
+  while the environment version trims away any spaces at the beginning and the
+  end of the code.\footnote{What actually happens is that at the beginning of
+    the environment body, all space tokens will be discarded.  At the end of
+    the body, no spaces are actually discarded; Memoize simply issues an
+    \refcmd{unskip}.  This should not matter to a regular user who simply
+    writes down the environment.} The space-trimming feature of the environment
+  ensures that you can write |\begin{memoize}| and |\end{memoize}| in separate
+  lines (as shown above), but no extra space will creep into the extern.
+
+  The space-trimming feature of the environment, which trims spaces at the
+  beginning and at the end of the \meta{environment body}, should not be
+  confused with the effect of \refmmz{ignore spaces}, which ignores spaces
+  following the environment end-tag (in \hologo{LaTeX}, |\end{...}|) --- and
+  which does not apply to manual memoization at all!
+
+  The argument of \refcmd{mmz} \emph{must} be enclosed in braces.
+\end{doc}
+
+\begin{doc}{easy,
+    cmd={name=nommz, par=\oarg{options}\marg{code}},
+    env={name=nomemoize, par=\oarg{options}},
+  }
+  Disable Memoize for the span of the compilation of \meta{code} or
+  \meta{environment body}.
+  
+  This command consumes the \meta{options} in the same way as
+  \refcmd{mmz}\slash \refenv{memoize} described above.  The macro and the
+  environment version of the command exhibit the same space-trimming behaviour
+  as their \refcmd{mmz}\slash \refenv{memoize} counterparts, and the argument
+  of \refcmd{nommz} \emph{must} be enclosed in braces.
+\end{doc}
+
+
+\subsubsection{Basic configuration}
+\label{sec:ref:memoization:basic}
+
+\begin{doc}{easy,
+    key={name=enable},
+    key={name=disable},
+  }
+  Enable or disable the functionality of the package.
+
+  What happens when Memoize is enabled depends on the memoization mode
+  (\refmmz{normal}, \refmmz{readonly}, \refmmz{recompile}) and many other
+  factors.  When the package is disabled, it neither creates new memos and
+  externs, nor uses the existing ones; this applies to both manual and
+  automatic memoization. The effect is close to not having Memoize loaded, or
+  to loading NoMemoize, but it is not completely the same; for example, the
+  record file (\dmmz) \emph{is} updated while Memoize is disabled, reflecting
+  the fact that nothing was memoized (or utilized) in the disabled
+  state.\footnote{Cleaning the folder (\S\ref{sec:cleanup-scripts}) after
+    disabling the package for the entire document is thus a bad idea.}
+
+  If these keys are used in the preamble, their effect is delayed until the
+  beginning of the document, to ensure that Memoize is never enabled in the
+  preamble.  Other than that, all these keys do is set the \hologo{TeX}
+  conditional \refcmd{ifmemoize}, which you may use in your code to test
+  whether Memoize is enabled.  You may also use \refcmd{memoizetrue} and
+  \refcmd{memoizefalse}, as long as you never enable the package in the
+  preamble.
+
+  Key \refmmz{enable} cannot be applied to automemoized commands via
+  \refcmd{mmznext}.  It will take effect for manual memoization, though, and
+  key \refmmz{disable} will work for both, as expected.
+\end{doc}
+
+\begin{doc}{easy,
+    key={name=normal, desc=the default mode},
+    key={name=readonly},
+    key={name=recompile},
+  }
+
+  Select the memoization mode.
+    
+  Each piece of code submitted to (either manual or automatic) memoization is
+  associated to several files: one c-memo, one cc-memo, and some externs (zero
+  or more, typically one).  When Memoize encounters a piece of code submitted
+  to memoization, it takes one of the following actions:
+    
+  \begin{description}
+  \item[memoization] The code is compiled in a special way which produces the
+    associated memos and externs.
+  \item[utilization] The code is not compiled.  Its effect is replicated by
+    processing the cc-memo; typically, this includes the single extern into the
+    document.
+  \item[regular compilation] The code is compiled as if Memoize was absent or
+    disabled (the memos and externs are neither utilized nor produced).
+  \end{description}
+
+  \begin{minipage}[t]{0.48\linewidth}
+    The action taken depends on the memoization mode and on whether all the
+    memos and externs associated with the code exist, as shown in the table on
+    the right.  Note that a single missing memo or extern implies the ``no''
+    column of the table, and that memoization will create \emph{all} the
+    associated memos and externs, even those which already exist.
+  \end{minipage}
+  \hfill
+  \begin{tabular}[t]{@{}lll@{}}
+    \toprule
+    &\multicolumn{2}{c}{Do the memos and externs exist?}\\
+    \cmidrule{2-3}
+    mode&yes&no\\
+    \midrule
+    normal&utilization&memoization\\
+    readonly&utilization&regular compilation\\
+    recompile&memoization&memoization\\
+    \bottomrule
+  \end{tabular}
+
+  The memoization mode only has effect when Memoize is \refmmz{enable}d.  Mode
+  selection is orthogonal to enabling\slash disabling the package; for example,
+  if you switch to a new mode while the package is disabled, the new mode will
+  be in effect once the package is enabled.
+\end{doc}
+
+
+\begin{doc}{easy,
+    desc={style},
+    key={name=verbatim},
+    key={name=verb},
+    key={name=no verbatim},
+  }
+  When \refmmz{verbatim} or \refmmz{verb} is in effect, the code submitted to
+  memoization is read verbatim; \refmmz{no verbatim} reverts to the normal,
+  non-verbatim collection of the code.  This applies to both manual and
+  automatic memoization.
+  
+  The long version, \refmmz{verbatim}, switches to the full verbatim mode,
+  where all characters are assigned category code 12 (other).  With the short
+  version, \refmmz{verb}, the braces, |{| and |}|, retain category codes 1 and
+  2, which can be useful for verbatim collection of optional arguments.  For
+  details, see the documentation of CollArgs' \refcollargs{verbatim} in
+  section~\ref{sec:ref:collargs}.
+
+  Under the hood, these keys have two effects. First, they are passed on to the
+  argument collector (typically, \refcmd{CollectArguments} of the auxiliary
+  package CollArgs; for details, see section~\ref{sec:ref:advicememoization}),
+  instructing it to collect the code in the specified fashion, as described
+  above.  Second, if the collected verbatim code is eventually compiled (either
+  regularly, or memoized), Memoize first rescans it using \refcmd{scantokens}.
+\end{doc}
+
+\begin{doc}{easy,
+    key={name=padding left, par=\meta{dimension},
+      desc={no default, initially |1| |in|}},
+    key={name=padding right, par=\meta{dimension},
+      desc={no default, initially |1| |in|}},
+    key={name=padding top, par=\meta{dimension},
+      desc={no default, initially |1| |in|}},
+    key={name=padding bottom, par=\meta{dimension},
+      desc={no default, initially |1| |in|}},
+  }
+  Set the left/right/top/bottom padding of the extern in the extern PDF.
+
+  Without padding, the (PDF) page holding the extern would tightly fit the
+  bounding box of the extern.  These keys enlarge the extern page by the given
+  amounts, so that any parts of the extern lying outside the bounding box will
+  be correctly included when using the extern.  See
+  section~\ref{sec:tut:padding} for details.
+
+  \meta{dimension} is evaluated with \hologo{eTeX}'s |\dimexpr|, and may
+  contain control sequences \docaux{cmd}{width}, \docaux{cmd}{height} and
+  \docaux{cmd}{depth}, which will refer to the dimensions of the extern.
+  \refcmd{width} and friends behave like dimension registers, so it is ok to write
+  e.g.\ \refmmz{padding right}|=0.5\width|.
+
+  The default padding is what \hologo{pdfTeX} puts around the page anyway, 1
+  inch, but we use |1 in| rather than |1 true in|, which is the true default
+  value of PDF registers \docref{pdfvar:horigin} and \docref{pdfvar:vorigin},
+  as we want the padding to adjust with \refcmd{mag}nification.
+\end{doc}
+
+\begin{doc}{easy,key={name=padding, par=\meta{dimension}, desc={style, no default}}}
+  Set all the above |padding| keys to the given value.
+\end{doc}
+
+\begin{doc}{
+    easy,
+    key={name=context, par=\meta{tokens}, desc={cumulative, no default,
+        initially set by \refmmz{padding to context}}},
+    key={name=clear context},
+  }
+  These keys append the given \meta{tokens} to the \emph{context expression},
+  or clear this expression.  Memoized code gets recompiled whenever the
+  expansion of the context expression changes.
+
+  The \meta{tokens} must be fully expandable (modulo protection); in
+  \hologo{LaTeX}, they will be expanded by |\protected at edef| when calculating
+  the md5sum of the context.
+
+  The context expression is evaluated at the end of the memoization, and at
+  utilization attempts after inputting the c-memo (note that the c-memo
+  contains any additions to the context expression accumulated during
+  memoization).  At evaluation, the given context expression is fully expanded,
+  yielding the \emph{context value}, whose md5 sum forms the \meta{context md5
+    sum} part of the filename of the cc-memo and the extern.
+
+  These keys may be used both prior to the memoization process, or during
+  memoization.  In the former case, their effect is local to the current group;
+  in the latter case, the effect is global, so that the changes surely survive
+  until the end of memoization, when the c-memo, where the context expression
+  is stored, is written into a file.
+
+  Under the hood, these keys manipulate token registers
+  \docaux{cmd}{mmzContext} and \docaux{cmd}{mmzContextExtra}, changing the
+  contents of the former while not memoizing, and the contents of the latter
+  during memoization.  These token registers may also be manipulated directly
+  by the user, as long as one keeps to the convention of adjusting
+  \refcmd{mmzContext} locally and only while not memoizing, and adjusting
+  \refcmd{mmzContextExtra} globally and only during memoization.
+\end{doc}
+
+\begin{doc}{
+    key={easy, name=meaning to context,
+      par=\marg{comma-separated list of commands and environment names}},
+    key={name=csname meaning to context, par=\marg{control sequence name}},
+    key={name=key meaning to context,
+      par=\marg{full path to a pgfkeys command key}},
+    key={name=key value to context,
+      par=\marg{full path to a pgfkeys value key}},
+  }
+  These keys append the definition of the given construct to the context.
+
+  Essentially, the ``meaning'' keys append \cs{meaning}\meta{control sequence}
+  to the context, for the appropriate \meta{control sequence}.  For example,
+  \refmmz{meaning to context} appends \cs{meaning}\cs{foo} when given \cs{foo}
+  as in item in the list, and it appends the internal environment macros
+  appropriate to the format when given an environment name.  Similarly,
+  \refmmz{key meaning to context} resolves \meta{control sequence} to the
+  internal macro holding the key command.
+
+  Key \refmmz{key value to context} should be used on keys which store values,
+  e.g.\ keys initialized by \pkg{pgfkeys} handler \code{.initial}; see
+  \PGFmanual{87.3.4 and \S87.4.5}.
+
+  All the keys prefix the meaning\slash value by the name of the command\slash
+  environment\slash key, in order to prevent ambiguous contexts, see
+  section~\ref{sec:cross-referencing} for details.  Furthermore, they all
+  operate through \code{\cs{csname}...\cs{endcsname}} construct, allowing one
+  to safely add internal commands to the context.
+\end{doc}
+
+\begin{doc}{
+    keypath={/handlers},
+    key={easy, name=.meaning to context},
+    key={name=.value to context},
+  }
+  These are the handler variants of \refmmz{key meaning to context} and
+  \refmmz{key value to context}.
+\end{doc}
+
+
+\begin{doc}{key={name=padding to context,desc=style}}
+  This key appends the values of the \refmmz{padding} keys to the context,
+  causing the memoized code to be recompiled whenever the padding values are
+  changed.  This key is used to initialize \refmmz{context}, so the author
+  normally shouldn't have to use this key.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzNoRef, par=\marg{reference key}, desc=\hologo{LaTeX} only},
+    cmd={name=mmzForceNoRef, par=\marg{reference key}, desc=\hologo{LaTeX} only},
+  }
+  These macros append the current value of the \meta{reference key} to the
+  context,\footnote{More precisely, it is \meta{reference key}|=|\marg{current
+      value} which is appended.}  causing the memoized code to be recompiled
+  when the reference changes.
+
+  If the reference key is undefined, \refcmd{mmzNoRef} aborts memoization,
+  while \refcmd{mmzForceNoRef} uses \cs{relax} as the reference string.
+
+  These commands are deployed in the implementation of \refmmzauto[show
+    keypath]{ref}, \refmmzauto{force ref} and friends.  If the
+  cross-referencing commands you are using are advised by these keys, you most
+  likely have no need of these macros.
+\end{doc}
+
+\begin{doc}{easy, key={name=per overlay,desc=style}}
+  This key is only defined in the Beamer class.  When in effect, the memoized
+  code will produce a cc-memo (and extern) for each overlay of the frame.  For
+  implementation, see section~\ref{sec:per-overlay}.
+\end{doc}
+
+\begin{doc}{
+    key={name=capture, par=\docAux{of=key:/mmz/capture, value={name=hbox}, text=\alt,
+      value={name=vbox,of=key:/mmz/capture}},
+      desc={no default, initially \refmmz{capture=hbox}}}
+  }
+  Select the capture mode.  This setting only applies to the default
+  memoization \refmmz{driver}.
+
+  By default, it is assumed that the memoized code should be executed in the
+  horizontal mode, so the default memoization driver captures the output of the
+  memoized code in a \refcmd{hbox} --- and also issues a \refcmd{quitvmode}
+  (both in the document and in the cc-memo), just in case the memoized code
+  occurs at the start of the paragraph.
+
+  Use \refmmz{capture}|=|\refmmz{capture=vbox} to execute the memoized code in
+  the vertical mode: Memoize will capture the output of the memoized code in a
+  \refcmd{vbox}, and avoid issuing \refcmd{quitvmode}.  For example, this
+  capture mode is necessary to memoize a \refenv{verbatim} environment.
+\end{doc}
+
+
+\subsubsection{Inside the memoization process}
+\label{sec:ref:memoization:process}
+
+\begin{doc}{easy, cmd={name=mmzAbort}}
+  This command aborts the ongoing memoization.
+
+  The memoization will proceed as usual (i.e.\ the extern boxes and the cc-memo
+  code will be produced), but at the end of this process, no memos will be
+  produced, no externs shipped out to extern pages, and no record files
+  updated.
+\end{doc}
+
+\begin{doc}{easy, cmd={name=mmzUnmemoizable}}
+  This command aborts the ongoing memoization, and marks the submitted code as
+  unmemoizable.
+
+  The ongoing memoization produces a c-memo setting conditional
+  \docaux{cmd}{ifmmzUnmemoizable} to true.  Upon utilizing this c-memo, the
+  system switches to regular compilation.
+
+  For example, if you are automemoizing |tcolorbox|es of package
+  \pkg{tcolorbox}, you will want to refrain from memoizing boxes marked as
+  |breakable| or |float|ing.  Simply aborting the memoization cannot do the
+  trick here, as memoization compiles the submitted code in a \hologo{TeX} box.
+  Marking a |breakable| or |float|ing |tcolorbox| as unmemoizable (either
+  manually using this macro, or automatically using \refmmz{auto key}) makes
+  sure that after the first compilation when memoization is attempted, the box
+  will be compiled regularly, and will have the intended ability to break
+  across pages, or float.
+\end{doc}
+
+
+\begin{doc}{
+    cmd={name=Memoize, par=\marg{key}\marg{code}},
+  }
+  Depending on various factors, this command either memoizes \meta{code} under
+  key \meta{key}, utilizes the results of a previous memoization, or performs a
+  regular compilation of \meta{code}.
+
+  The outcome of executing this command --- memoization, utilization or regular
+  compilation --- depends upon the Memoize's state (\refcmd{ifmemoize},
+  \refcmd{ifmemoizing}) and mode (\refmmz{normal}, \refmmz{readonly},
+  \refmmz{recompile}), and the existence of the relevant memos and externs.
+  The decision process is depicted in section~\ref{sec:Memoize}.
+
+  This command expects to be executed in a dedicated group, which it will close
+  itself.
+
+  Invoking memoization through \refcmd{Memoize} might be useful for packages
+  which want to save the results of intensive computations, regardless of
+  whether the author loads (and enables) memoization or not.  However, this
+  usage is not yet officially allowed, because there is currently no way to
+  load the core memoization routines without loading the entire package,
+  thereby forcing the author to use Memoize.
+\end{doc}
+
+\begin{doc}{
+    key={
+      name=driver, par=\marg{code},
+      desc={no default, initially \refcmd{mmzSingleExternDriver}}
+    },
+  }
+  This key sets \meta{code} as the memoization driver.
+
+  Given some code submitted to memoization, the memoization driver should
+  produce the memos and externs which will replicate the effect of that code
+  (while retaining its regular effect).  For details, see
+  section~\ref{sec:memoization-drivers}.
+
+  Typically, the \meta{code} argument of this key will consist of a single
+  control sequence (the driver control sequence), but any amount of tokens is
+  allowed.  Memoize executes the driver followed by the code which it is
+  supposed to memoize, in braces, and only cares that the driver consumes that
+  code.
+\end{doc}
+
+
+\begin{doc}{
+    key={name=at begin memoization, par=\meta{code}, desc={cumulative, initially empty}},
+    key={name=at end memoization, par=\meta{code}, desc={cumulative, initially empty}},
+    key={name=after memoization, par=\meta{code}, desc={cumulative, initially empty}},
+  }
+  Use these keys to set up memoization hooks.
+
+  These keys may be used both prior to the memoization process, or during
+  memoization.  In the former case, their effect is local to the current group;
+  in the latter case, the code given to \refmmz{at begin memoization} is
+  executed immediately, while the assignment performed by the other two keys is
+  global, so that the changes surely survive until the end of memoization.
+
+  The code given to hook \refmmz{at begin memoization} is kept in macro
+  \docaux{cmd}{mmzAtBeginMemoization}, while the content of the other two hooks
+  resides in two macros per hook: \docaux{cmd}{mmzAtEndMemoization} and
+  \docaux{cmd}{mmzAtEndMemoizationExtra}, and \docaux{cmd}{mmzAfterMemoization}
+  and \docaux{cmd}{mmzAfterMemoizationExtra}. All these macros may be
+  manipulated directly by the user,\footnote{Use \cs{appto}, \cs{eappto},
+    \cs{gappto} and \cs{xappto} of package \pkg{etoolbox} (loaded by Memoize)
+    to easily append code to these macros.} as long as one keeps to the
+  convention of adjusting the macros without ``\texttt{Extra}'' locally and
+  only while not memoizing, and adjusting the macros with ``\texttt{Extra}''
+  globally and only during memoization.  The ``\texttt{Extra}'' macros require
+  global assignments as they might be manipulated by code residing within a
+  \hologo{TeX} group of any depth.
+
+  These complications explained, let us take a look at how memoization proceeds
+  to learn when the hooks are used:
+  \begin{enumerate}
+  \item Initialize various conditionals, macros and token registers.  (Here is
+    where the ``\texttt{Extra}'' hooks are cleared.)  Remember that at this
+    point, we're inside a group opened by \refcmd{Memoize}.
+  \item Execute \refmmz{at begin memoization} hook, i.e.\ the contents of
+    macro \refcmd{mmzAtBeginMemoization}.
+  \item Execute the memoization \refmmz{driver}.
+  \item Execute \refmmz{at end memoization} hook, i.e.\ the contents of macros
+    \refcmd{mmzAtEndMemoization} and \refcmd{mmzAtEndMemoizationExtra} (in this
+    order).
+  \item Write out the memos and ship out the externs to extern pages (unless
+    memoization was aborted).
+  \item Close the memoization group.
+  \item Execute \refmmz{after memoization} hook, i.e.\ the contents of
+    macros \refcmd{mmzAfterMemoization} and \refcmd{mmzAfterMemoizationExtra}
+    (in this order).
+  \end{enumerate}
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzCMemo, desc={token register, global, empty at the start of memoization}},
+  }
+  This token register mediates the construction of the c-memo.  During
+  memoization (and only during memoization), arbitrary code may be added to
+  this register; at the end of memoization, Memoize writes out its contents to
+  the free-form part of the c-memo.
+
+  All assignments to this register should be global.  Use \refcmd{gtoksapp} and
+  \refcmd{xtoksapp} to easily append tokens to the register.
+\end{doc}
+
+
+\begin{doc}{
+    cmd={name=mmzCCMemo, desc={token register, global, empty at the start of memoization}},
+  }
+  This token register mediates the construction of the cc-memo.  During
+  memoization, the memoization driver should append cc-memo code to
+  \refcmd{mmzCCMemo}; at the end of memoization, Memoize writes out its
+  contents to the cc-memo (preceded by the list of produced externs).
+
+  All assignments to this register should be global.  Local assignments would
+  not work, because the memoized code may contain commands, like \cs{label} and
+  \cs{ref}, which contribute content to cc-memo as well, but these commands may
+  appear within a \hologo{TeX} group of any depth.
+
+  Use \refcmd{gtoksapp} and \refcmd{xtoksapp} to easily append tokens to the
+  register.
+\end{doc}
+
+\begin{doc}{
+    par=\meta{token register}\marg{tokens},
+    cmd={name=toksapp},
+    cmd={name=gtoksapp},
+    cmd={name=etoksapp},
+    cmd={name=xtoksapp},
+  }
+  These commands append the given \meta{tokens} to the \meta{token register}.
+  \refcmd{etoksapp} and \refcmd{xtoksapp} expand the \meta{tokens} before
+  appending them; \refcmd{gtoksapp} and \refcmd{xtoksapp} perform a global
+  assignment.
+
+  These commands are actually provided by CollArgs, and they are defined only
+  if they don't already exist; in particular, note that \hologo{LuaTeX}
+  provides them as primitives.
+
+  Unlike the \hologo{LuaTeX} primitive variant, these commands require the
+  \meta{token register} to be given by a (|\toksdef|fed) control sequence; it
+  cannot be given as |\toks|\meta{number}.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=ifmemoize},
+    cmd={name=memoizetrue},
+    cmd={name=memoizefalse},
+  }
+  Use the \hologo{TeX}-style conditional \refcmd{ifmemoize} to test whether
+  Memoize is currently enabled.  Within the document body, the conditional may
+  be set using \refcmd{memoizetrue} and \refcmd{memoizefalse}, which are then
+  functionally equivalent to \refmmz{enable} and \refmmz{disable}.  Do not set
+  the conditional in the preamble of the document (unless you really know what
+  you are doing).
+\end{doc}
+
+\begin{doc}{
+    cmd={name=ifmemoizing,desc={readonly}},
+  }
+  Use this \hologo{TeX}-style conditional to test whether Memoize is currently
+  memoizing.  It may be only inspected; you should \emph{never} set this
+  conditional yourself.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=ifinmemoize,desc={readonly}},
+  }
+  Use this \hologo{TeX}-style conditional to test whether Memoize is currently
+  active, in the sense of either memoizing or regularly compiling some code ---
+  so inside a call to \refcmd{Memoize}.  The conditional may be only inspected;
+  you should \emph{never} set it yourself.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzSingleExternDriver, par=\marg{code}},
+  }
+  This is the default memoization \refmmz{driver}, producing exactly one extern
+  containing whatever is typeset by the submitted \meta{code}.
+
+  The \meta{code} is compiled either within a horizontal or vertical box,
+  depending on the value of key \refmmz{capture}.  In the case of a horizontal
+  capture, the driver makes sure that the horizontal mode is entered prior to
+  both typesetting the resulting box in the document, or utilizing the extern.
+
+  For the implementational details, see
+  section~\ref{sec:memoization-driver-default}.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzExternalizeBox, par=\marg{box}\marg{token register}},
+  }
+  This macro is indended to be called by memoization drivers to produce an
+  extern page.  The given \meta{box} is dumped into the document as a separate
+  extern page, while the \meta{token register} receives the cc-memo extern
+  inclusion code.
+
+  The \meta{box} may be given either as a control sequence (declared via
+  |\newbox|), or as box number.  The resulting extern page will contain a
+  \emph{copy} of the given box, padded by the \refmmz{padding} values in effect
+  at the time of invocation of \refcmd{mmzExternalizeBox}.
+
+  An implementation detail is that \refcmd{mmzExternalizeBox} does not ship out
+  the extern page immediately.  This action is delayed until the end of the
+  memoization process; more precisely, it is carried out (in tandem with
+  writing out the c-memo and the cc-memo) between execution of hooks \refmmz{at
+    end memoization} and \refmmz{after memoization}.  This delay guarantees
+  that no extern pages are produced in the event of aborting memoization, even
+  if the abortion is triggered after executing \refcmd{mmzExternalizeBox}.
+  
+  The \meta{token register} may be given either as a control sequence (declared
+  via |\newtoks|) or as control sequence |\toks| followed by the register
+  number.  The register will receive the code, which, when executed from the
+  cc-memo, includes the extern file into the main document.  This code consists
+  of a single invocation of \refcmd{mmzIncludeExtern}.  It is the
+  responsibility of the driver to include the code received by \meta{token
+    register} in the register \refcmd{mmzMemo}, whose contents are, unless
+  memoization is aborted, written into the cc-memo.  (See
+  \refcmd{ifmmzkeepexterns} and \refmmz{after memoization} to learn about
+  another way to use the code received by \meta{token register}.)
+
+  The invocation of \refcmd{mmzIncludeExtern} in the produced extern-inclusion
+  code is adapted to the type of the box (horizontal or vertical), which is
+  detected automatically --- the memoization driver does not need to inform
+  \refcmd{mmzExternalizeBox} about this type explicitly.\footnote{This does not
+    negate the need for key \refmmz{capture}, which applies to the default ---
+    and therefore generic --- memoization driver.  This driver cannot know
+    whether the memoized code would prefer to be compiled in a horizontal or
+    vertical box.  It is precisely key \refmmz{capture} which gives the user an
+    opportunity to inform Memoize about this preference.  Only once the
+    memoized code is compiled into a box of the appropriate type, it is trivial
+    to detect the type of that box.}
+\end{doc}
+
+\begin{doc}{
+    cmd={name=ifmmzkeepexterns, desc={initially \cs{iffalse}}},
+    cmd={name=mmzkeepexternstrue},
+    cmd={name=mmzkeepexternsfalse},
+  }
+  Setting this conditional to true makes Memoize keep the extern boxes in the
+  global temporary storage even after shipping them out as extern pages.  (The
+  temporary storage is emptied at the start of the next memoization.)
+  
+  The extern inclusion code received by the \refcmd{mmzCCMemo} when executing
+  \refcmd{mmzExternalizeBox} is primarily meant to be executed by inputting the
+  cc-memo file; i.e.\ when the cc-memo is input, \refcmd{mmzIncludeExtern} is
+  defined to include the extern file into the document.  However, it sometimes
+  makes sense to execute the cc-memo contents immediately after memoization;
+  for example, if memoization produces several externs, intricately integrated
+  into the surrouding environment, it might be cumbersome to replicate their
+  typesetting both in the memoizing compilation and in the cc-memo code ---
+  easier to build up the cc-memo code and execute it right after memoization.
+  This is why Memoize, just before executing the contents of \refmmz{after
+    memoization} hook, redefines \refcmd{mmzIncludeExtern} to include externs
+  from the temporary storage rather than from (at that point still
+  non-existing) extern files.  However, as this mechanism requires Memoize to
+  keep the externs around even after memoization, it is not enabled by default:
+  it must be enabled by setting conditional \refcmd{ifmmzkeepexterns} to true.
+\end{doc}
+
+\begin{doc}{
+    key={keypath=/mmz/auto, name=integrated driver, par=\marg{name}}
+  }
+  Use this key to easily setup a memoization driver which is integrated into
+  the command itself.
+
+  \begin{tcolorbox}[warning]
+    This is an auto-key residing in keypath \refkeypath{/mmz/auto}.
+  \end{tcolorbox}
+
+  An integrated driver must have a way of telling whether it is memoizing or
+  regularly compiling the code.  This key declares a driver-specific
+  conditional which may be inspected, using \refcmd{IfMemoizing}, to determine
+  this.  The conditional is set to true by the formal driver of the command
+  (set up by the invocation of this key), executed at the start of memoization;
+  it should never be set elsewhere.  See
+  section~\ref{sec:memoization-multiple-externs} for details and an example.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=IfMemoizing, par=\oarg{offset}\marg{name}\marg{true code}\marg{false code}}
+  }
+  This \hologo{LaTeX}-style conditional is meant to be used by the
+  \refmmzauto{integrated driver} with the given \meta{name}.  It tests whether
+  this particular driver is currently memoizing some code.
+
+  Potentially recursive commands are supported via the optional argument
+  \meta{offset}.  If given, the conditional will only execute the \meta{true
+    code} when the current \hologo{TeX} group level matches the \hologo{TeX}
+  group level at the time of the invocation of the formal driver (held in
+  \refcmd{memoizinggrouplevel}), plus the \meta{offset}.  In effect, the inner
+  invocation of the integrated driver will perform a regular compilation.  For
+  details, see section~\ref{sec:memoization-complex-single-driver}.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=memoizinggrouplevel,desc={readonly}},
+  }
+  During memoization, this macro holds the \hologo{TeX} group level in effect
+  at the start of the memoization.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzRegularPages, desc=readonly counter},
+  }
+  This counter holds the number of pages shipped out (so far) by the format's
+  regular shipout routine.  \emph{Do not change its value!}
+
+  In \hologo{LaTeX}, this counter is synonymous with
+  \refcmd{ReadonlyShipoutCounter}, and in \hologo{ConTeXt}, it is synonymous
+  with \refcmd{realpageno}.  Memoize does not touch its value.
+
+  In \hologo{plainTeX}, Memoize hijacks the \refcmd{shipout} control sequence
+  to count (and only to count) regular shipouts.  In order for its value to be
+  realistic, Memoize should be loaded before other packages which hack
+  \cs{shipout} --- in particular, before \pkg{atbegshi}.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzExternPages, desc=readonly counter},
+  }
+  This counter holds the number of extern pages Memoize has shipped out (so
+  far).  \emph{Do not change its value!}
+
+  A third-party tool may inspect this counter to have a realistic count of
+  shipped-out pages.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzExtraPages, desc=counter},
+  }
+  This counter holds the number of pages shipped out (so far) in a way not
+  tracked by either \refcmd{mmzRegularPages} or \refcmd{mmzExternPages}.  It
+  \emph{should} be advanced by any code which performs such shipouts, or
+  Memoize won't work correctly.
+\end{doc}
+
+
+\subsubsection{Tracing}
+\label{sec:ref:memoization:tracing}
+
+\begin{doc}{
+    key={name=trace, conditional=false},
+  }
+  When tracing is on, Memoize shows information about its decision processes on
+  the terminal.  You can learn whether the memoized code is being memoized,
+  utilized or regularly compiled; find out the md5sum of the code and which
+  input line it comes from; etc.
+
+  This key has the syntax of a conditional, but there is no underlying
+  \hologo{TeX} conditional.  The low-level interface for switching the tracing
+  on and off consists of macros \docaux{cmd}{mmzTracingOn} and
+  \docaux{cmd}{mmzTracingOff}.
+
+  To learn about tracing the ``auto'' part of the automemoization process, also
+  \refcmd{AdviceTracingOn}.
+\end{doc}
+
+\begin{doc}{
+    key={name=include source in cmemo, conditional=true},
+  }
+    
+  As a courtesy towards a curious user and a debugging aid, Memoize can include
+  a copy of the memo source in the c-memo.  This feature is switched on by
+  default, but as the package itself never uses that information, it can be
+  safely switched off at any time.
+\end{doc}
+
+\begin{doc}{
+    key={name=include context in ccmemo, conditional=false},
+  }
+  When this key is in effect, the expanded context expression is appended to
+  the cc-memo, behind the \docaux{cmd}{mmzThisContext} marker.
+
+  Memoize never uses the context information from the cc-memo; this information
+  is only for tracing purposes.
+\end{doc}
+
+\begin{doc}{
+    key={name=direct ccmemo input, conditional=false},
+  }
+  When this key is set to false, a cc-memo is processed indirectly: it is first
+  read into a token register, and it is the contents of this register which are
+  executed.  When the key is set to true, the cc-memo is simply |\input|ted.
+  
+  The indirect execution is implemented to facilitate inverse search.  Under
+  the direct cc-memo input, inverse search pointed at an included extern will
+  visit the cc-memo, which is not practical; under the indirect regime, the
+  inverse search will work as expected, and this is why the indirect cc-memo
+  input is the default.
+
+  The overhead produced by the default indirect input method seems negligible,
+  but there are other factors which might make the user switch to the direct
+  input.  For one, a cc-memo changing some category codes will require direct
+  input (no such cc-memos are ever produced out of the box).  Less crucially,
+  sometimes one would like to use the inverse search to figure whether a part
+  of the document was produced by regular compilation or utilization, and which
+  memos\slash externs were utilized if the latter.  Figuring this out under the
+  indirect input regime is harder: (i) reading the tracing information shown by
+  \refmmz{trace} is the surest way to learn what's going on, although (ii)
+  visual inspection of the externs and (iii) grepping through the |.memo.dir|
+  folder for particular code often help, as well.
+
+  Both input methods use the same cc-memos; there is no need to
+  \refmmz{recompile} the memos when switching the cc-memo input method.  Note
+  that the default indirect input method crucially relies on cc-memos ending
+  with \refcmd{mmzEndMemo}; this macro should not appear in the cc-memo itself.
+\end{doc}
+
+
+
+\subsubsection{Internal memo commands}
+\label{sec:ref:memoization:internal}
+
+The end-user should never have to use these commands.  They are not formally
+marked as internal by a |@| in their name only because doing so would
+complicate |\input|ting the memos due to the category code changes it would
+require.
+
+\begin{doc}{
+    cmd={name=mmzMemo},
+  }
+  This macro marks the beginning of a c-memo and a cc-memo core.  Without it,
+  utilization of a memo will not work.
+\end{doc}
+
+\begin{doc}{cmd={name=mmzSource}}
+  This macro marks the beginning of the memoized source in the c-memo.  That
+  source is not used by Memoize in any way.  It's inclusion into the c-memo may
+  be switched off by \refmmz{include source in cmemo}|=false|.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzResource, par=\marg{filename}},
+  }
+  This is an internal command, which only occurs in a cc-memo.  It checks
+  whether file \meta{filename} exists and is non-empty, and triggers
+  recompilation of the memoized code if the check fails.
+\end{doc}
+
+\begin{doc}{
+    cmd={
+      name=mmzIncludeExtern,
+      par=\marg{seq}\braces{\refcmd{hbox}\alt\refcmd{vbox}}%
+      \marg{expected width}\marg{expected height}\marg{expected depth}%
+      \marg{padding left}\marg{padding bottom}\marg{padding right}\marg{padding top},
+    }
+  }
+  
+  This is an internal command, which only occurs in a cc-memo.  It includes the
+  extern identified by the sequential number \meta{seq} into the document as a
+  box of the specified type (horizontal or vertical).  The extern is trimmed by
+  the given padding values.  After trimming, the command checks whether the
+  size of the resulting box matches the given expectations; if it doesn't, a
+  warning is yielded.
+
+  Before this command is executed, the externs should be listed by a sequence
+  of \refcmd{mmzResource} commands; \meta{seq} refers to the sequential number
+  of an extern in this sequence.
+  
+  This command may also be executed by executing the entire contents of
+  \refcmd{mmzCCMemo} after memoization.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzLabel, par=\marg{label key}\marg{label value}}
+  }
+  This is an internal command written into the cc-memo by the auto-handler of
+  \refcmd{label}.  It temporarily stores \meta{label value} into
+  \refcmd{@currentlabel} and then executes \cs{label}\marg{label name}.
+\end{doc}
+
+\begin{doc}{
+    cmd={name=mmzEndMemo},
+  }
+  This macro marks the end of a cc-memo.  It is used to grab the cc-memo core
+  (everything between \refcmd{mmzMemo} and \refcmd{mmzEndMemo}) under the
+  indirect cc-memo input regime, i.e.\ when \refmmz{direct ccmemo input} is not
+  in effect.
+\end{doc}
+
+
+\subsection{Location of memos and externs}
+\label{sec:ref:dirs}
+
+\begin{doc}{easy,
+    key={name=memo dir,par=\meta{name}, desc={style, default \texttt{\string\jobname}}},
+  }
+  A convenient way to store memos and externs in a dedicated directory (and
+  create this directory in case it does not exist).  Without an argument, this
+  key places these files in subdirectory \meta{document name}|.memo.dir| of the
+  current directory.  See section~\ref{sec:tut:memodir} for the tutorial.
+
+  This key sets \refmmzpath{relative} to |false|, \refmmzpath{dir} to
+  \meta{name}|.memo.dir|, \refmmzpath{prefix} to empty and \refmmz{mkdir} to
+  |true|.  In effect, memos and externs are placed in the subdirectory
+  \meta{name}|.memo.dir| of the directory containing the document; their
+  filenames contain no \meta{name} prefix, as \meta{name} already occurs in the
+  directory name.  The latter feature also makes it easy for projects (or parts
+  of a project) to share memos and externs; see section~\ref{sec:tut:multifile}
+  for a typical usage case.
+\end{doc}
+
+\begin{doc}{easy,key={name=no memo dir,desc=style}}
+  A convenient way to undo the effect of \refmmz{memo dir} and revert to the
+  initial settings where memos and externs are located in the current
+  directory.  See section~\ref{sec:tut:memodir} for the tutorial.
+  
+  This key resets the subkeys of \refmmz{path} to their initial values, and
+  sets \refmmz{mkdir} to |false|.
+\end{doc}
+
+\begin{doc}{
+    key={name=path, par=\meta{keylist}, desc=style},
+  }
+
+  Set the \emph{path prefix} to memo and extern files by executing the given
+  \meta{keylist} in keypath \docaux{key path}{mmz/path}.
+
+  The path prefix contains both the location of the memo\slash extern files
+  (set by \refmmzpath{relative} and \refmmzpath{dir}) and the initial,
+  fixed part of their filenames (set by \refmmzpath{prefix}):
+  \begin{center}
+    \meta{path prefix}=[|./|]\meta{directory}|/|\meta{prefix}
+  \end{center}
+  where ``|./|'' is only present when \refmmzpath{relative} is in effect.
+  Given the \meta{path prefix}, this is how the paths to memos and externs are
+  constructed:
+  \begin{center}
+    \begin{tabular}{r@{ }l}
+      c-memo:&\meta{path prefix}\meta{code md5 sum}|.memo|\\
+      cc-memo:&\meta{path prefix}\meta{code md5 sum}|-|\meta{context md5 sum}|.memo|\\
+      extern:&\meta{path prefix}\meta{code md5 sum}|-|\meta{context md5 sum}-$N$|.pdf|\\
+      &(where ``-$N$'' is only present when $N\neq 0$, i.e.\ for non-first externs)\\
+    \end{tabular}
+  \end{center}
+
+  For example, the default \refmmz{no memo dir} \meta{path prefix} equals
+  \meta{jobname}|.| (note the dot), and after issuing \refmmz{memo dir}, the
+  \meta{path prefix} is \meta{jobname}|.memo.dir|.  Executing
+  \refmmz{path}|=|\bracestt{\refmmzpath{dir}=project-memo-dir,
+    \refmmzpath{prefix}=\string\jobname.} would set the memo prefix to
+  |./project-memo-dir/|\meta{jobname}|.|, allowing the author to keep the memo
+  files of all documents compiled from the project directory in the same place.
+  
+  The following keys may occur in the \meta{keylist}:
+  \yadocset{keypath=/mmz/path}
+
+  \begin{doc}{
+      key={name=relative, conditional=true},
+    }
+    
+    This key determines whether the location is relative to the current
+    directory, i.e.\ the directory where \hologo{TeX} is executed from;
+    usually, this will be the directory where the compiled |.tex| file resides.
+    When set to |true| (the default), the directory set by \refmmzpath{dir}
+    is prefixed by ``|./|''.
+
+    You will probably need to set |openout_any=a| in \reffile{texmf.cnf}
+    to allow writing to an arbitrary directory --- but remember, this might be
+    dangerous!
+  \end{doc}
+  
+  \begin{doc}{
+      key={name=dir, par=\meta{name}, desc={no default, initially empty}},
+    }
+    
+    Set the \meta{directory} where Memoize will search for memos and externs
+    and\slash or create them in.
+
+    Unless \refmmzpath{relative} is set to |false|, this location is
+    relative to the current directory.  Given the empty default, memos and
+    externs are therefore created in the directory holding the source file by
+    default.
+
+    In principle, the given memo directory must already exist, but see
+    \refmmz{mkdir}.
+  \end{doc}
+
+  \begin{doc}{
+      key={name=prefix, par=\meta{name},
+        desc={no default, initially \texttt{\string\jobname.}}},
+    }
+
+    Set the \meta{prefix}, i.e.\ the initial part of the memo\slash extern
+    filename.  Initially, it is set to the document name.
+  \end{doc}
+
+  After processing the \meta{keylist}, \refmmz{path} records the new path
+  prefix by invoking \refmmz{record/record type/prefix}, which typically results
+  in a \refcmd{mmzPrefix} entry in the \dmmz file, and attempts to create the
+  \meta{directory} is \refmmz{mkdir} is in effect --- except when \refmmz{path}
+  is executed in the document preamble: then, these actions are only carried
+  out at the beginning of the document, for the final value of the keys.
+\end{doc}
+
+\begin{doc}{key={name=mkdir, conditional=false}}
+  When this key is set to true, Memoize will attempt to create the directory
+  set by \refmmz{path} if it does not yet exist.  The directory creation takes
+  place at the beginning of the document and at every subsequent invocation of
+  key \refmmz{path}, using the system command specified by \refmmz{mkdir
+    command}.
+\end{doc}
+
+\begin{doc}{
+    key={name=mkdir command, par=\meta{system command invocation},
+      desc={no default, initially |mkdir "\#1"|}},
+  }
+  Sets the command used to create \refmmzpath{dir} when \refmmz{mkdir} is in effect.
+
+  This is a system command, so an appropriate shell escape mode must be in
+  effect to execute it successfully.
+
+  The default should work on Linux, MacOS and Windows.  On Linux systems, it
+  makes sense to change the default (using \reffile{memoize.cfg}) to |mkdir
+  -p "#1"|, which can create parent folders as necessary.
+
+  Note that extraction methods \refmmz{extract=perl} and
+  \refmmz{extract=python} set \refmmz{mkdir command} to
+  \refscript{memoize-extract.pl} \refscript{memoize-extract.pl--mkdir} and
+  \refscript{memoize-extract.py} \refscript{memoize-extract.pl--mkdir},
+  respectively.  Unlike system |mkdir|, these commands are safe in the sense
+  that they conform to the paranoid openout regime (|openout_any=p|).
+\end{doc}
+
+\begin{doc}{
+    key={name=output-directory, par=\meta{directory},
+      desc={no default, initially undefined, as package option only}},
+    cmd={name=mmzOutputDirectory, par=\meta{directory}, desc={pre-defineable}}
+  }
+  If the \hologo{TeX} binary was invoked with option |-output-directory|, one
+  should use this key or define this macro to inform Memoize this, as there is
+  no way to learn about it automatically.
+
+  The given \meta{directory} must end with a slash (|/|).
+
+  The key is only allowed as a package option.  But I imagine that defining the
+  macro from the command line, prior to inputting the document source, will be
+  more common:
+  \begin{center}
+    |pdftex -output-directory somedir '\def\mmzOutputDirectory{somedir/}\input doc'|
+  \end{center}
+\end{doc}
+
+
+\subsection{Extern extraction}
+\label{sec:ref:externs}
+
+\begin{doc}{easy,
+    key={name=extract,par=\marg{extraction method},
+      desc={preamble-only, initially \refmmz{extract=perl}, default: see below}},
+  }
+  This key selects or executes the extern \meta{extraction method}, i.e. the
+  method which Memoize will use to extract the extern pages out of the document
+  PDF.
+
+  Out of the box, Memoize recognizes the following \meta{extraction method}
+  keywords: \docAux{easy, of=key:/mmz/extract, value={name=perl}, comma,
+    value={name=python}, comma, value={name=tex}, and, value={name=no}}.  The final
+  keyword (not available in \hologo{plainTeX}) instructs Memoize to \emph{not}
+  perform to extraction; it should be used when extraction is performed
+  externally (for details, see section~\ref{sec:setup}).  Additional methods
+  may be installed by defining key \docaux{key
+    path}{mmz/extract}|/|\meta{extraction method}.
+  
+  When invoked from \reffile{memoize.cfg} or used as a package option, this key
+  \emph{selects} the extraction method.  In this case, the key has no default
+  value, i.e.\ it is illegal to use it without an argument.  The method
+  selected by the package option overrides the method selected in
+  \reffile{memoize.cfg}, which in turn overrides the package-initial value
+  \refmmz{extract=perl}.
+
+  In \hologo{LaTeX} and \hologo{ConTeXt}, the selected method is executed at
+  the end of loading the package.  Afterwards, the key is disabled.  If you
+  really need to invoke extraction in the preamble, or again, write
+  \refmmz{extract}|/|\meta{method}.
+
+  When invoked from a \refcmd{mmzset} in the document preamble, this key
+  immediately \emph{executes} the given extraction method.  In the preamble
+  incarnation, the key may be invoked without a value to execute the previously
+  selected method.
+
+  As we want to allow a \hologo{plainTeX} author to override the extraction
+  method specified by the package (\refmmz{extract=perl}) or in
+  \reffile{memoize.cfg}, Memoize does \emph{not} perform extern extraction
+  while loading the package in this format.  In \hologo{plainTeX}, internal
+  extraction can only be triggered by an explicit invocation of
+  \refmmz{extract} in the ``document preamble'' --- i.e.\ between |\input
+  memoize| and \refcmd{mmzset}\braces{\refmmz{begin document}}.  In this case,
+  the key does not require an argument; invoking it without the argument will
+  execute either the package-default, \refmmz{extract=perl}, or whatever the
+  user had selected in \reffile{memoize.cfg}.
+
+  Executing extraction method \refmmz{extract=perl} or \refmmz{extract=python}
+  has an additional effect of setting the \refmmz{mkdir command} to the
+  extraction script with option \refscript{memoize-extract.pl--mkdir}.  This
+  obviates the need to include |mkdir| among the restricted shell commands if
+  one is using the restricted shell mode.
+\end{doc}
+
+\subsubsection{Perl- and Python-based extraction}
+\label{sec:ref:extraction-perl-python}
+
+\begin{doc}{
+    key={name=perl extraction command, par=\meta{system command},
+      desc={no default, initially \refscript{memoize-extract.pl}}},
+    key={name=perl extraction options, par=\meta{options},
+      desc={no default, initially: see below}},
+    key={name=python extraction command, par=\meta{system command},
+      desc={no default, initially \refscript{memoize-extract.py}}},
+    key={name=python extraction options, par=\meta{options},
+      desc={no default, initially: see below}},
+  }
+  These keys determine the system calls used for invoking the extraction
+  scripts \refscript{memoize-extract.pl} and \refscript{memoize-extract.py}.
+  All the details below apply both to the Perl and the Python version.
+
+  Use |perl|\slash|python extraction command| to set the name of the extraction
+  script.  If necessary, include the full path to the scrip, or |perl|\slash
+  |python| plus the path to the script.  Whatever you set here must be allowed
+  by the shell escape mode.
+
+  Use |perl|\slash|python extraction options| to set the options that the
+  script will receive; consult the documentation of
+  \refscript{memoize-extract.pl} for their meaning.
+
+  The initial value of \refmmz{perl extraction options}, shown below, (i) sets
+  embedded mode, which prefixes each output line with the script name, (ii)
+  requests a log file named \meta{jobname}|.mmz.log| (|-l|; |\input|ting the
+  log after extraction informs Memoize, and the author, whether extraction was
+  successful), and (iii) sets the warning template suitable for the format
+  (|-w|; this way, any warning messages issued by the script can be reissued by
+  the compilation of the document).
+  
+  These keys were initialized using \pkg{pgfkeys} handler |.initial|, so their
+  values may be modified by handlers |.prefix|, |.append|, etc.  During the
+  execution of the system call, their values are fully expanded --- thus the
+  |\string|s in the initial options value below.  The guards
+  (|%<latex>| etc.) make sure that
+  each format asks for a warning message it understands (the code shown below
+  is an excerpt from the |.dtx| file; ultimately, each format receives a single
+  of the three guarded lines).
+
+  \makeexcerpt{perl-extraction-options}
+  \tcbinputexample[.tex][.excerpt]{listing only, one file, no attachment,
+    title={The initial value of \refmmz{perl extraction
+        options}}, full width, left=-2mm, right=0mm, listing options app={
+      morecomment={[s]{\%<}>} }, }
+\end{doc}
+
+\begin{doc}{
+    script={name=memoize-extract.pl, par=[\meta{options}] \meta{name}\texttt{.mmz}},
+    script={name=memoize-extract.py, par=[\meta{options}] \meta{name}\texttt{.mmz}},
+  }
+  These scripts extract the new externs recorded in \meta{name}\dmmz from
+  \meta{name}|.pdf|.  Memoize invokes them when loaded with package option
+  \refmmz{extract}|=|\refmmz{extract=perl} (the default) or
+  \refmmz{extract}|=|\refmmz{extract=python}.
+
+  The script inspects the given record file, \meta{name}\dmmz, for lines of
+  form \refcmd{mmzNewExtern}\marg{extern filename}\marg{extern page
+    number}\braces{\meta{expected width}\texttt{pt}}\braces{\meta{expected
+      height}\texttt{pt}}.  For each such line, page number
+  \meta{extern page number} is extracted from \meta{name}|.pdf| into
+  \meta{extern filename}. Other lines are ignored (and so are commented
+  invocations of \refcmd{mmzNewExtern}).
+
+  The \meta{extern filename} may contain a (relative or absolute) path to the
+  new extern file.  The relative paths are relative to the location of the
+  \dmmz file, even when the script is invoked from some other directory.
+
+  To guard against extracting a wrong page, the script checks whether the size
+  of each extracted page matches the \meta{expected width} and \meta{expected
+    height}.\footnote{\label{fn:tolerance}To avoid false positives, the match
+    need not be exact, a difference up to |0.01pt| is tolerated.  Some PDF
+    tools, notably the |PDF::API2| library deployed by the Perl version of the
+    script, round the dimensions of a PDF page, recorded in |/MediaBox|, to two
+    digits.}  If it does not, the script refuses to extract the page, yields a
+  warning and even removes the extern file if it exist.
+
+  The extraction script's paranoia extends further.  It will refuse to extract
+  the page, yielding a warning, if a (c)c-memo associated to the extern does
+  not exist.  And it will refuse (yielding a runtime error) to write to any
+  file whose absolute path does not occur under the current directory or the
+  directory set by \docref{TEXMFOUTPUT} (in \reffile{texmf.cnf} or as an
+  environment variable); \docref{TEXMFOUTPUT} is also not allowed to point to
+  the root directory, except on Windows, where it can only point to a drive
+  root.
+    
+  \yadocset{
+    of=script:memoize-extract.pl,
+    override/.style={
+      index annotation={option of {%
+          \hypercolor{link}{gray}%
+          \hyperref[script:memoize-extract.pl]{\texttt{memoize-extract}}%
+        }},
+    },
+  }
+  \begin{doc}{
+      option={name=pdf, short name=P, par=\meta{pdf}}
+    }
+    Extract the externs from the given \meta{pdf} instead of the default
+    \meta{name}\texttt{.mmz}.  Note that file \meta{pdf}, despite the different
+    name, should be produced by the same compilation that produced
+    \meta{name}\dmmz, otherwise wrong pages might be extracted.
+  \end{doc}
+  \begin{doc}{
+      option={name=prune, short name=p}
+    }
+    After extraction, remove the extracted extern pages from the document PDF.
+  \end{doc}
+  \begin{doc}{
+      option={name=keep, short name=k}
+    }
+    By default, the script comments out the \refcmd{mmzNewExtern} lines in the
+    \dmmz file, to prevent multiple extractions.  Specifying this option
+    prevents this behaviour.
+  \end{doc}
+  \begin{doc}{
+      option={name=log, short name=l, parameters=\meta{filename}}
+    }
+    When given this option, the script creates a log file with the given name.
+    The log will receive any warnings yielded by the script, see also
+    \refscript{memoize-extract.pl--warning-template}.  A well-formed log ends
+    with |\endinput|, indicating that the \dmmz file was completely processed.
+    
+    In absence of this option, the warnings are printed to the standard error.
+  \end{doc}
+  \begin{doc}{
+      option={name=warning-template, short name=w, parameters=\meta{template}}, 
+    }
+    When this option is given, a warning message is not logged (or printed to
+    standard error) as-is; it is wrapped by the template given as the argument
+    of this option.  More precisely, the script will log the given
+    \meta{template}, with all occurrences of \docaux{cmd}{warningtext}
+    substituted by the actual warning message.
+
+    The option can be used to propagate warnings to the upstream compilation,
+    simply by setting this option appropriately (see the initial value of
+    \refmmz{python extraction options}) and |\input|ting the log after
+    extraction.
+  \end{doc}
+  \begin{doc}{
+      option={name=force, short name=f}
+    }
+    Force extern extraction even if the size-check fails.  The failure will
+    still be logged.
+  \end{doc}
+  \begin{doc}{
+      option={name=quiet, short name=q}
+    }
+    Normally, the script prints what it is doing to the standard output; in
+    particular, it prints out the page number and the filename of each extern
+    it is extracting.  This option disables this behaviour.
+  \end{doc}
+  \begin{doc}{
+      option={name=embedded, short name=e}
+    }
+    When given this option, everything printed to the standard output is
+    prefixed by the script name.  The idea is to use this option when calling
+    the script from the \hologo{TeX} compilation, as it makes it easy to
+    identify the output of the script.
+  \end{doc}
+  \begin{doc}{
+      option={name=mkdir, short name=m}
+    }
+    When given this option, the extraction script transforms into a paranoid
+    |mkdir| (|-p|).  Argument \meta{name}|.mmz| is interpreted as a path to the
+    directory to create; all other options are ignored.
+
+    The ancestors of the directory are created as needed.  The script will
+    refuse to create any directory whose absolute path does not occur under the
+    current directory or a directory listed in \docref{TEXMFOUTPUT} (set in
+    \reffile{texmf.cnf} or as an environment variable).
+
+    This option exists so that the author using the restricted shell mode does
+    not have to list |mkdir| among the restricted shell mode commands (and it
+    is also safer than a plain |mkdir|).
+
+    Memoize automatically uses this script to create the memo directory when
+    option \refmmz{extract} is given value \refmmz{extract=perl} or
+    \refmmz{extract=python}.
+  \end{doc}
+  \begin{doc}{
+      option={name=help, short name=h}
+    }
+    Show help.
+  \end{doc}
+  \begin{doc}{
+      option={name=version, short name=V}
+    }
+    Show Memoize version.
+  \end{doc}
+
+  Functionally, the Perl (|.pl|) and the Python (|.py|) version of the script
+  are almost equivalent.  The minor differences, listed below, are mostly due
+  to the underlying PDF-processing library:
+  \hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2} in Perl, and
+  \hreftt{https://pypi.org/project/pdfrw2/}{pdfrw2} in Python.
+  \begin{itemize}
+  \item The Python script is about twice as fast as the Perl script.  However,
+    both scripts are very fast compared to the \hologo{TeX}-based extraction.
+    On my computer, extracting 160 externs out of a 400-page book takes 1.4s
+    with Python, 3.7s with Perl, and 65s with \hologo{TeX}.  But even when
+    using \hologo{TeX}-based extraction, externalization using Memoize is
+    extremely fast compared to the \TikZ's externalization library.  Adding
+    the regular compilation time of one minute to the above numbers, we arrive
+    at the maximum externalization time of about two minues, whereas my
+    estimate for the production of all 160 externs using \TikZ's
+    externalization would be an \emph{hour} or more.
+  \item The Python script cannot extract externs out of PDFs created without
+    stream compression, i.e.\ with \refcmd{pdfvariable}
+    \docref{pdfvar:compresslevel} set to |0|.
+  \item Occasionally, the Perl script crashes during extraction externs; see
+    section~\ref{sec:troubleshooting} for details.
+  \end{itemize}
+\end{doc}
+
+\subsubsection{\texorpdfstring{\hologo{TeX}}{TeX}-based extraction}
+\label{sec:ref:extraction-tex}
+
+\begin{doc}{
+    key={name=tex extraction command, par=\meta{system command},
+      desc={no default, initially |pdftex|}},
+    key={name=tex extraction options, par=\meta{options},
+      desc={no default, initially: see below}},
+    key={name=tex extraction script, par=\meta{\hologo{TeX} code},
+      desc={no default, initially: see below}},
+  }
+  \yadocset{
+    before/.style={label prefix=cmd:te},
+    index annotation={defined at \hologo{TeX} extraction}, 
+  }
+  
+  Together, these keys determine the system call used for invoking the
+  \hologo{TeX}-based extraction script, \refscript{memoize-extract-one.tex}.
+  (They were initialized using \pkg{pgfkeys} handler |.initial|, so their
+  values may be modified by handlers |.prefix|, |.append|, etc.)
+
+  Memoize uses the resulting system call string at the following occasions.
+  First, it executes it, once for each new extern in the \dmmz file, during the
+  internal extraction, i.e.\ when it is loaded with package option
+  \refmmz{extract}|=|\refmmz{extract=tex}.  Second, it uses it to construct
+  record files of types \refmmz{record=sh}, \refmmz{record=bat} and
+  \refmmz{record=makefile} when recording of these types is requested.
+  
+  Key \refmmz{tex extraction command} sets the \hologo{TeX} binary used for
+  \hologo{TeX}-based internal extraction.  By default, the \hologo{pdfTeX}
+  engine |pdftex| is used; other sensible values for this key are |luatex| and
+  |xetex|, or the program name including the path.  Note that shell escape mode
+  must be configured appropriately, and that
+  \refscript{memoize-extract-one.tex} must be compiled with the
+  \hologo{plainTeX} format.
+
+  The value of key \refmmz{tex extraction options} is passed as options to the
+  \hologo{plainTeX} binary.  As shown in the initial value in the frame below,
+  it may use the temporary macro \docaux{cmd}{externbasepath}, which expands to
+  the path to the extern without the |.pdf| suffix.  This macro is available
+  during internal \hologo{TeX}-based extraction and during the execution of
+  \refmmz[show keypath]{record/record type/new extern} key for and \meta{record
+    type}.
+
+  \makeexcerpt{tex-extraction-options}
+  \tcbinputexample[.tex][.excerpt]{%
+    listing only, one file, no attachment, title={The initial value of
+      \refmmz{tex extraction options}},
+  }
+
+  Key \refmmz{tex extraction script} defines the command-line script executed
+  to extract the extern.  The default value, shown in the frame below, invokes
+  \refscript{memoize-extract-one.tex} after setting its parameter macros.
+  Temporary macros \docAux{cmd={name=pagenumber}, comma, cmd={name=expectedwidth},
+    and, cmd={name={expectedheight}}} are defined at the same occasions as
+  \refcmd{te:externbasepath} above, i.e.\ during internal \hologo{TeX}-based
+  extraction and during the execution of a \refmmz{record/record type/new
+    extern} key.    The initial value requests the extern to be of the same version as
+  the main document, if possible;\footnote{As far as I know, it is impossible
+    to access the version of the PDF being produced in \hologo{XeTeX}, i.e.\
+    there are no registers \docref{reg:pdfmajorversion} and
+    \docref{reg:pdfminorversion}.  To request production of a specific version of
+    PDF, \hologo{XeTeX} must be invoked by with command-line option
+    \code{-output-driver 'xdvipdfmx -V $N$'}.} note that Memoize defines
+  \docref{reg:pdfmajorversion} and \docref{reg:pdfminorversion} in \hologo{LuaTeX}.
+
+  \makeexcerpt{tex-extraction-script}
+  \tcbinputexample[.tex][.excerpt]{%
+    listing only, one file, title=The initial value of \refmmz{tex extraction
+      script}, no attachment}
+
+  As the value of \refmmz{tex extraction script} is fully expanded when used,
+  the initial value shown above must prevent the expansion of much code.
+  Furthermore, the initial value varies with the \hologo{TeX} format, as
+  indicated by the |.dtx| guards in the definition of
+  \refcmd{meo:warningtemplate}.
+\end{doc}
+
+\begin{doc}{
+    script={
+      head prefix={%
+        (\texttt{pdf}\alt\texttt{lua}\alt\texttt{xe})\texttt{tex -jobname}
+        \meta{extern filename}
+        \texttt{"}\meta{parameters}
+        \cs{input}\texttt{\textbraceleft}
+      },
+      name=memoize-extract-one.tex,
+      head infix=\texttt{\textbraceright"},
+    },
+  }
+  Compiling \refscript{memoize-extract-one.tex} with \hologo{plainTeX}
+  produces an extern file containing a single (extern) page extracted from the
+  document PDF.
+
+  Memoize invokes this script, once for each new extern appearing in the \dmmz
+  file, when loaded with package option
+  \refmmz{extract}|=|\refmmz{extract=tex}.
+  
+  The desired \meta{extern filename} is given as the value of option |-jobname|
+  of the \hologo{TeX} binary.  To set the extraction \meta{parameters}, define
+  the following macros before |\input|ting the file:
+  \yadocset{
+    index annotation=option of \texttt{memoize-extract-one.tex},
+    before/.style={head prefix=\cs{def}, label prefix=cmd:meo},
+  }
+  \begin{doc}{cmd={name=fromdocument, parameters=\marg{document pdf filename}}}
+    Defining this macro sets the filename of the PDF which the externs will be
+    extracted from.  The filename is relative to the working directory.
+  \end{doc}
+  \begin{doc}{cmd={name=pagenumber, parameters=\marg{number}}}
+    Defining this macro sets the number of the page to extract.  The first page
+    has number 1.
+  \end{doc}
+  \begin{doc}{
+      cmd={name=expectedwidth, parameters=\marg{dimension}, desc=optional},
+      cmd={name=expectedheight, parameters=\marg{dimension}, desc=optional},
+    }
+    Defining these macros sets the expected width and height of the extracted
+    page.
+
+    To guard against extracting a wrong page, the dimensions of the extracted
+    page are compared against the expected width and height.  If the size check
+    fails,\footnote{The match need not be exact, see
+      footnote~\ref{fn:tolerance}.} the resulting extern PDF is empty (which
+    counts as non-existent when Memoize checks for its presence when it
+    attempts to utilize it), and a warning message (formatted via
+    \refcmd{meo:warningtemplate}) is printed to the log file, if logging was
+    requested via \refcmd{meo:logfile}.
+    
+    If any of these macros is undefined, the size check will be skipped.
+  \end{doc}
+  \begin{doc}{cmd={name=logfile, parameters=\marg{filename}, desc=optional}}
+    Defining this macro sets the name of the log file.  If not defined, no log
+    file will be produced.
+
+    The log file is intended to be used when the script is invoked from an
+    outer \hologo{TeX} compilation.  In particular, it is intended to be
+    |\input| by that compilation to see whether the extraction was successful.
+    Upon a failed size check, it will contain a warning (formatted by
+    \refcmd{meo:warningtemplate}, if that macro is defined).  The log file ends
+    with |\endinput| to signal that extraction actually took place.
+  \end{doc}
+  \begin{doc}{cmd={name=warningtemplate, parameters=\marg{code}, desc=optional}}
+    Defining this macro determines how to log the warning message in the case
+    of a failed size check.  The macro should expand to a \hologo{TeX}
+    format-specific warning message code containing the warning text given in
+    \docAux{cmd={name=warningtext, label prefix=cmd:meo, into
+        index=false}}.\footnote{Macro \refcmd{meo:warningtemplate} is passed
+      the warning text by a macro rather than a formal parameter to avoid
+      category code problems with the parameter character when setting key
+      \refmmz{tex extraction script}.}
+
+    While the script formats the warning message \emph{text} on its own (``I
+    refuse to extract page \dots''), the warning message is not written into
+    the log unadorned.  The log file is intended to be \cs{input} by the outer
+    \hologo{TeX} compilation, and the idea is that inputting it should yield a
+    warning in that compilation (in the case of a failed size
+    check). Therefore, the content of the log file must contain an invocation
+    of the command used to produce warning messages in the \hologo{TeX} format
+    used by the outer compilation.
+
+    For example, when this script is invoked from within a \hologo{LaTeX}
+    compilation, it makes sense to define something like
+    |\def\warningtemplate{\PackageWarning{memoize}{\warningtext}}|.
+  \end{doc}
+  \begin{doc}{cmd={name=force,
+        parameters=\bracestt{\texttt{true}\Alt\texttt{false}}, desc=optional}}
+    If this macro is defined to |true|, extern extraction will be carried out
+    even if the size-check fails.  The failure will still be logged.
+  \end{doc}
+  \begin{doc}{
+      cmd={name=mmzpdfmajorversion, parameters=\marg{number}, desc=optional},
+      cmd={name=mmzpdfminorversion, parameters=\marg{number}, desc=optional},
+    }
+    Defining (one or both of) these macros requests that the extern PDF be
+    produced with the given major\slash minor PDF version, i.e.\ the extraction
+    script will set registers \docref{reg:pdfmajorversion} and
+    \docref{reg:pdfminorversion}.
+  \end{doc}
+  
+  After extracting the extern, the script will end the compilation, i.e.\
+  intentionally, only one page documents can be produced.
+\end{doc}
+
+\subsubsection{The clean-up scripts}
+\label{sec:cleanup-scripts}
+
+\begin{doc}{
+    script={name=memoize-clean.pl, par=[\meta{options}] [\meta{name}\texttt{.mmz} \dots]},
+    script={name=memoize-clean.py, par=[\meta{options}] [\meta{name}\texttt{.mmz} \dots]},
+  }
+  This script removes memo and extern files whose filenames start with
+  \meta{path prefix}es mentioned in the given \dmmz files or by the
+  \refscript{memoize-clean.pl--prefix} option.  Unless option
+  \refscript{memoize-clean.pl--all} is given, the script only deletes the
+  \emph{stale} files, i.e.\ the files not mentioned in any of the given \dmmz
+  files.
+
+  A \meta{path prefix} of a memo or an extern is what was set by key
+  \refmmz{path}, or more commonly, one of the shortcut keys \refmmz{memo dir}
+  and \refmmz{no memo dir}; see section~\ref{sec:ref:dirs} for details on the
+  form of a memo/extern filename.
+
+  In detail, the script scans the given \dmmz files for occurrences of
+  \refcmd{mmzPrefix}, and adds their \meta{path prefix} arguments to the list
+  of prefixes given on the command line by option
+  \refscript{memoize-clean.pl--prefix}; a \meta{path prefix} occurring in some
+  \dmmz file is interpreted relatively to the location of the \dmmz file.  The
+  script removes all files whose full pathname (relative to the current
+  directory) matches pattern \meta{path
+    prefix}\meta{md5sum}(|-|\meta{md5sum})(|.memo|\alt(|-|$N$)|.pdf|\alt|.log|),%
+  \footnote{The |.log| files are produced by the \hologo{TeX}-based extraction
+    script.}  except those which occur as the \meta{filename} argument to one
+  of \refcmd{mmzUsedCMemo}, \refcmd{mmzUsedCCMemo}, \refcmd{mmzUsedExtern},
+  \refcmd{mmzNewCMemo}, \refcmd{mmzNewCCMemo} and \refcmd{mmzNewExtern} in one
+  of the \dmmz files.
+
+  The script is fairly paranoid.  It refuses to delete anything if a \dmmz file
+  is malformed in any way (but not if it doesn't exist or is completely empty,
+  which facilitates its usage in clean-up scripts), or if it would remove a
+  file not residing under the current directory.  Before removing the files, it
+  lists the files to be removed and asks for confirmation.
+
+  Functionally, the Perl (|.pl|) and the Python (|.py|) version are completely
+  equivalent.
+  
+  \yadocset{
+    of=script:memoize-clean.pl,
+    override/.style={
+      index annotation={option of {%
+          \hypercolor{link}{gray}%
+         \hyperref[script:memoize-clean.pl]{\texttt{memoize-clean}}%
+        }},
+    },
+  }
+  \begin{doc}{
+      option={name=prefix, short name=p, par=\meta{path prefix}}
+    }
+    Add \meta{path prefix} to the list of prefixes; the given prefix is
+    relative to the current directory.  This option may be given multiple
+    times.
+  \end{doc}
+  \begin{doc}{
+      option={name=all, short name=a}
+    }
+    When given this option, the script removes \emph{all} memos and externs
+    belonging to the document, not just the stale ones, i.e.\ it effectively
+    ignores the occurences of \refcmd{mmzUsedCMemo} and friends in the \dmmz
+    file.
+  \end{doc}
+  \begin{doc}{
+      option={name=yes, short name=y}
+    }
+    When given this option, the script does not ask for confirmation before
+    removing the files.
+  \end{doc}
+  \begin{doc}{
+      option={name=quiet, short name=q}
+    }
+    Normally, the script prints what it is doing to the standard output; in
+    particular, it prints out the filename of each file as it is deleting it.
+    This option disables this behaviour.
+  \end{doc}
+  \begin{doc}{
+      option={name=help, short name=h}
+    }
+    Show help.
+  \end{doc}
+  \begin{doc}{
+      option={name=version, short name=V}
+    }
+    Show Memoize version.
+  \end{doc}
+\end{doc}
+
+\subsubsection{Record files}
+\label{sec:ref:record-files}
+
+\begin{doc}{
+    key={name=record, par=\marg{record type},
+      desc={cumulative, initially \refmmz{record=mmz}, no default}},
+    key={name=no record},
+  }
+  Memoize records which externs were produced and used in the compilation,
+  producing a record file of every type found in the record-type list.  These
+  keys add \meta{record type} to the record-type list, or clear this list.  See
+  section~\ref{sec:record-files} for details.
+
+  Note that passing an undefined \meta{record type} to this key will not yield
+  an error.
+
+  Out of the box, the following \meta{record type}s are recognized:
+  \yadocset{of=key:/mmz/record}
+  \begin{doc}{value={name=mmz}}
+    This record type produces a \dmmz file recording new/used
+    externs/c-memos/cc-memos and changes in the \refmmz{path} prefix to these
+    files; see section~\ref{sec:.mmz} for details.
+
+    The produced file is named \docAux{file={name=mmz,
+        name prefix=\meta{jobname}.,
+        ref prefix=.,
+        index prefix=.,
+      }}. This name cannot be changed.
+
+    The \dmmz file is a \hologo{TeX} file, but uses only a simple subset of
+    the \hologo{TeX} syntax, to be easily parsable by the external scripts such
+    as \refscript{memoize-extract.pl}.  Each line of the file consists of a
+    (possibly commented) invocation of one of the commands listed below; the
+    final line is |\endinput|.  The \meta{path prefix} below consists of the
+    path to memos/externs and the immutable \refmmzpath{prefix} of their filename.
+    \begin{doc}{
+        cmd={name=mmzUsedCMemo, par=\marg{filename}},
+        cmd={name=mmzUsedCCMemo, par=\marg{filename}},
+        cmd={name=mmzUsedExtern, par=\marg{filename}},
+      }
+      Record that the (c)c-memo or extern residing in file \meta{filename} was
+      utilized.
+    \end{doc}
+    \begin{doc}{
+        cmd={name=mmzNewCMemo, par=\marg{filename}},
+        cmd={name=mmzNewCCMemo, par=\marg{filename}},
+      }
+      Record that a new (c)c-memo residing in file \meta{filename} was
+      produced.
+    \end{doc}
+    \begin{doc}{cmd={name=mmzNewExtern, par=\marg{filename}\marg{page number}%
+          \marg{expected width}\marg{expected height}}}
+      Record that a new extern was produced and dumped as page \meta{page
+        number} into the document, that it should be extracted into file
+      \meta{filename}, and that it should be \meta{expected width} wide and
+      \meta{expected height} high (modulo tolerance of |0.01pt|, see
+      footnote~\ref{fn:tolerance}), where the height is the total height
+      comprising both \hologo{TeX} height and depth.
+    \end{doc}
+    \begin{doc}{cmd={name=mmzPrefix, par=\marg{path prefix}}}
+      Record that the \refmmz{path} prefix of memo and extern files was
+      changed.
+    \end{doc}
+  \end{doc}
+  \begin{doc}{value={name=makefile}}
+    This record type produces a makefile which, when processed by the |make|
+    utility, triggers \hologo{TeX}-based extraction of the new externs.
+    \begin{doc}{
+        key={name=makefile, par=\marg{filename}, desc={no default,
+            initially \texttt{memoize-extract.\jobname.makefile}}}
+      }
+      Use this key to change the filename of the produced makefile.
+    \end{doc}
+  \end{doc}
+  \begin{doc}{value={name=sh}, value={name=bat}}
+    These record types produce a shell script which, when executed, triggers
+    \hologo{TeX}-based extraction of the new externs.
+
+    Use \refmmz{record=sh} on Unix-like systems, and \refmmz{record=bat} on
+    Windows.
+    
+    \begin{doc}{
+        key={name=sh, par=\marg{filename}, desc={no default,
+            initially \texttt{memoize-extract.\jobname.sh}}},
+        key={name=bat, par=\marg{filename}, desc={no default,
+            initially \texttt{memoize-extract.\jobname.bat}}}
+      }
+      Use these keys to change the filename of the produced shell script.
+    \end{doc}
+  \end{doc}
+\end{doc}
+
+\begin{doc}{
+    desc=definable,
+    keypath=/mmz/record/\meta{record type},
+    keypath label=/mmz/record/record type,
+    name prefix={\meta{record type}/}, ref prefix=,
+    index annotation={key in \texttt{/mmz/\meta{record type}}},
+    key={name=begin},
+    key={name=prefix, par=\marg{path prefix}},
+    key={name=new extern, par=\marg{filename}},
+    key={name=new cmemo, par=\marg{filename}},
+    key={name=new ccmemo, par=\marg{filename}},
+    key={name=used extern, par=\marg{filename}},
+    key={name=used cmemo, par=\marg{filename}},
+    key={name=used ccmemo, par=\marg{filename}},
+    key={name=end},
+  }
+  A new record type can be implemented by defining these keys in keypath
+  \docAux{key path={name=mmz/record/\meta{record type}, label=mmz/record/record
+      type}} (using the standard \pkg{pgfkeys} handlers such as |.code| and
+  |.style|).  The keys are invoked by Memoize where appropriate if recording
+  for the defined type is activated by \refmmz{record}|=|\meta{record type},
+  just as for the predefined types.  Only those keys which are required for
+  implementing the desired functionality need to be defined.
+
+  The following macros are available during the execution of key
+  \refmmz{record/record type/new extern}:
+  \yadocset{before/.style={label prefix=cmd:ne},
+    index annotation=defined at \refmmz{record/record type/new extern}}
+  \begin{doc}{cmd={name=pagenumber}}
+    This macro holds the number of the extern page.
+  \end{doc}
+  \begin{doc}{
+      cmd={name=expectedwidth},
+      cmd={name=expectedheight},
+    }
+    These macros hold the width and the height of the extern page.
+  \end{doc}
+  \begin{doc}{cmd={name=externbasepath}}
+    This macro holds the filename of the extern, minus the |.pdf| suffix (but
+    including the path leading to the extern).
+  \end{doc}
+\end{doc}
+
+
+
+\subsection{Automemoization}
+\label{sec:ref:advicememoization}
+
+
+\subsubsection{Package Advice}
+\label{sec:ref:advice}
+
+Package Advice is a namesake of \Emacs's Advice.  As such, it implements a
+generic framework for extending the functionality of selected commands and
+environments.  Each \emph{advised} command and environment is assigned a piece
+of \emph{advice} --- a command which is executed instead of the advised command
+and environment, and which may, or may not, invoke the original command or
+environment during its execution.  The package offers an elegant way of
+declaring advice, setting up the conditions upon which the advised command will
+actually be replaced by the advice, collecting the arguments of the advised
+command and invoking it, and (de)activating the advice.
+
+Before the advising framework can be used, it must be installed into a selected
+\pkg{pgfkeys} keypath (multiple installations into different keypaths are
+allowed, even if they handle the same commands).  Memoize installs the
+framework into keypath \refkeypath{/mmz} and (primarily) uses it to
+automatically memoize the results of compilation of selected commands and
+environments.
+
+\begin{doc}{
+    keypath={/handlers},
+    key={name=.install advice,
+      sort index=install advice,
+      par=\marg{configuration keylist},
+    },
+  }
+  This key is a \pkg{pgfkeys} key handler (see \PGFmanual{87.3.5}) which
+  installs the advising framework into the keypath which it was invoked from
+  --- henceforth, the \meta{namespace}.
+
+  For example, \code{\cs{pgfkeys}\bracestt{/my/\refkey{/handlers/.install
+        advice}}} installs the framework into keypath |/my|.
+
+  Argument \meta{configuration keylist} may contain the following keys:
+  \yadocset{keypath=/advice/install}
+  \begin{doc}{key={
+        name=setup key,
+        parameters=\marg{name},
+        description={no default, initially \texttt{advice}}},
+    }
+    This key determines the names of the user-interface keys used to setup
+    advice for commands and environments in \meta{namespace}.
+
+    The keys whose names are determined by this key are the following:
+    \meta{name}, \code{\meta{name} csname}, \code{\meta{name} key},
+    \code{\meta{name}'}, \code{\meta{name} csname'} and \code{\meta{name}
+      key'}.  Memoize sets \refkey{/advice/install/setup key}|=auto|, and
+    thereby defines \refmmz{auto}, \refmmz{auto csname}, \refmmz{auto key},
+    \refmmz{auto'}, \refmmz{auto csname'} and \refmmz{auto key'}.
+  \end{doc}
+  \begin{doc}{key={
+        name=activation,
+        par=\meta{initial activation type},
+        desc={no default, initially \texttt{immediate}}
+      },
+    }
+    This key sets the \meta{initial activation type} for \meta{namespace}.
+
+    At the end of the installation, the system will execute
+    \meta{namespace}|/|\refmmz{activation}|=|\meta{initial activation type};
+    consequently, \meta{initial activation type} must be one of
+    \refmmz{activation=immediate} and \refmmz{activation=deferred}.  In
+    Memoize, the \meta{initial activation type} is
+    \refmmz{activation=deferred}.
+
+    Setting the \refmmz{activation} type during the installation only matters
+    in \hologo{LaTeX}, where the installation ends by advising \refcmd{begin}
+    to implement advising of environments.
+  \end{doc}
+
+  \begin{tcolorbox}[warning]
+    Writing the documentation for Advice, I was faced with a dilemma.  Should
+    the documentation reflect the fact that the full names of keys defined by
+    the package depend on the installed instance of the framework, in
+    particular on \meta{namespace} and \meta{setup key}?  For example, should
+    the reference headers contain things like \meta{namespace}|/activate| and
+    \meta{namespace}|/|\meta{setup key} |csname|?  In my opinion, this would
+    make the reference hard to read, so I decided to have the reference headers
+    refer to the Advice keys of the Memoize installation, where
+    \meta{namespace}=|/mmz| and \meta{setup key}=|auto|, resulting in
+    friendlier headers such as \refkeypath{/mmz}|/|\refmmz{activate} and
+    \refkeypath{/mmz}|/|\refmmz{auto csname}.  (Consequently, it also made
+    sense to document Advice within the Memoize documentation.)
+
+    The bottomline: if you're reading this section with a non-Memoize
+    installation in mind, you have to mentally replace any \refkeypath{/mmz}
+    and \refmmz{auto} in the reference headers with the \meta{namespace} and
+    the \meta{setup key} selected by that installation.
+    (Section~\ref{sec:ref:advice:memoization} is another matter.  Keys
+    described there are only available in Memoize.)
+  \end{tcolorbox}
+  
+  In more detail, key handler \refkey{/handlers/.install advice} performs the
+  following actions (as explained in the box above, we assume that the
+  advising framework was installed into keypath \refkeypath{/mmz} with the
+  setup key named |auto|):
+  \begin{itemize}
+  \item \edef\origtolerance{\the\tolerance}\tolerance=1000
+    It defines the following keys in keypath \refkeypath{/mmz}:
+    \refmmz{auto},
+    \refmmz{auto csname},
+    \refmmz{auto key},
+    \refmmz{auto'},
+    \refmmz{auto csname'},
+    \refmmz{auto key'},
+    \refmmz{activation},
+    \refmmz{activate deferred},
+    \refmmz{activate},
+    \refmmz{deactivate},
+    \refmmz{activate csname},
+    \refmmz{deactivate csname}.
+    \refmmz{activate key},
+    \refmmz{deactivate key}.
+    \refmmz{force activate},
+    \refmmz{try activate}.
+  \item
+    It defines the following keys in keypath \refkeypath{/mmz/auto}:
+    \refmmzauto{run conditions},
+    \refmmzauto{outer handler},
+    \refmmzauto{bailout handler},
+    \refmmzauto{collector},
+    \refmmzauto{args},
+    \refmmzauto{collector options},
+    \refmmzauto{clear collector options},
+    \refmmzauto{raw collector options},
+    \refmmzauto{clear raw collector options},
+    \refmmzauto{inner handler},
+    \refmmzauto{options},
+    \refmmzauto{clear options},
+    \refmmzauto{reset}.
+  \item \tolerance\origtolerance\relax
+    It defines the |.unknown| key handler for \refkeypath{/mmz/auto}.
+    This handler appends any unknown keys (and their values) to
+    \refmmzauto{options}.
+  \item It executes \refmmz[show keypath]{activation}|=|\meta{initial
+      activation type}.
+  \item In \hologo{LaTeX}, it submits \refcmd{begin} to advising, thereby
+    enabling environment support in this format.  Consequently, advising of
+    environments can switched off by writing \refmmz{deactivate}|=\begin|.
+  \end{itemize}
+\end{doc}
+
+\paragraph*{The keys installed into keypath \metabf{namespace}} are used to
+declare and (de)activate advice.  In the documentation in this subsection,
+we assume that \meta{namespace}=\refkeypath{/mmz} and that \meta{setup
+  key}=\refmmz{auto}.  In particular, this also applies to the reference
+headers.
+
+\begin{doc}{
+    key={name=activation, par=\docAux{of=key:/mmz/activation, value={name=immediate},
+        text=\Alt, value={name=deferred}}, desc={style, no default}},
+    key={name=activate deferred, desc={style}},
+  }
+  Key \refmmz{activation} selects the activation regime.  Under the
+  \refmmz{activation=immediate} regime, keys \refmmz{activate},
+  \refmmz{deactivate}, \refmmz{force activate} and \refmmz{try activate} behave
+  as described in their documentation below.  Under the
+  \refmmz{activation=deferred} regime, however, those keys are not executed;
+  rather, their invocations are appended to style \refmmz{activate deferred}.
+  For example, writing \refmmz{activate}|=\foo| in the deferred activation
+  regime appends \refmmz{activate}|=\foo| to \refmmz{activate deferred}.  It is
+  up to the user if and when to execute the keys collected in \refmmz{activate
+    deferred}; see the documentation of \refmmz{manual} to learn what Memoize
+  does with the contents of this style.
+\end{doc}
+
+
+\begin{doc}{easy,
+    par=\marg{list of commands and/or environments},
+    desc={style},
+    key={name=activate},
+    key={name=deactivate},
+  }
+  These keys activate or deactivate the advice for the given commands and
+  environments.  When the advice is activated, it replaces the advised command;
+  when it is deactivated, the command is reverted to its original definition.
+
+  In Memoize, these keys are most commonly used to activate or deactivate
+  automemoization for the given commands or environments.  For example, write
+  \refmmz{deactivate}|={\tikz,tikzpicture}| to deactivate automemoization of
+  \TikZ pictures (which is declared and active by default).  The curly braces
+  may be omitted if the list contains a single command or environment, e.g.\
+  \refmmz{deactivate}|=\tikz| or \refmmz{deactivate}|=tikzpicture|.
+
+  (De)activation of a piece of advice is completely orthogonal to its declaration with
+  \refmmz{auto}.  For example, there is no need to deactivate a command before
+  redeclaring its advice, and reactivate it afterwards.  A command may be
+  activated even before declaring its advice --- however, the command itself
+  must be defined at the time of activation.
+  
+  As the advice is normally automatically activated upon declaration with
+  \refmmz{auto}, explicit activation is rarely needed, but see \refmmz{auto'}.
+  The effect of these keys under the deffered activation regime is described in
+  \refmmz{activation}.
+
+  Note that I sometimes speak of (de)activating a command, and sometimes of
+  (de)activating its advice.  I mean the same thing.
+\end{doc}
+
+\begin{doc}{
+    par=\marg{control sequence name},
+    desc={style},
+    key={name=activate csname},
+    key={name=deactivate csname},
+  }
+  These keys activate and deactivate a command given by its \meta{control
+    sequence name}; for example, \refmmz{activate csname}|=foo| is equivalent
+  to \refmmz{activate}|=\foo|.  Note that unlike the regular \refmmz{activate}
+  and \refmmz{deactivate}, their |csname| variants only accept a single command
+  at a time (otherwise, including a comma in the command name would be
+  impossible).
+\end{doc}
+
+\begin{doc}{
+    par=\marg{list of full key names},
+    desc={style},
+    key={name=activate key},
+    key={name=deactivate key},
+  }
+  These keys activate and deactivate |pgfkeys| keys.  Note that \emph{full} key
+  names must be given, i.e.\ the names must include the keypath.
+
+  Under the hood, these keys merely execute \refmmz{activate} and
+  \refmmz{deactivate} on the internal macros corresponding to the given keys.
+\end{doc}
+
+\begin{doc}{
+    key={name=try activate, conditional=false},
+  }
+  When this conditional is set to true, \refmmz{activate} will not yield an
+  error if the advice is already activated, and \refmmz{deactivate} will not
+  yield an error if the advice is not yet activated.
+
+  This key applies to the next, and only to the next, invocation of key
+  \refmmz{activate} or \refmmz{deactivate}, i.e.\ it is reset back to |false|
+  after invoking \refmmz{activate} or \refmmz{deactivate}.
+\end{doc}
+
+\begin{doc}{
+    key={name=force activate, conditional=false},
+  }
+  When this conditional is set to true, \refmmz{activate} will activate even a
+  previously activated command, provided that, additionally, the command has
+  been redefined since the prior activation.
+
+  In more detail, the original definition of the advised command is saved upon
+  activation (to provide the possibility of both deactivation and the usage of
+  the original command by the handler).  Consequently, activation of an already
+  activated command would result in the saved original definition being
+  overwritten by the redefinition made during the first activation.  However,
+  if the handled command was meanwhile redefined by a third party, reactivation
+  makes sense, under the assumption that the former original definition is
+  obsolete and should be replaced by the (third party) redefinition.  As a
+  safeguard, however, \refmmz{activate} requires such reactivation to be
+  explicitly requested using conditional \refmmz{force activate}.\footnote{A
+    potential problem, not (yet) addressed, is that the third party might be
+    another incarnation of the advising framework.  In this case, forced
+    reactivation will result in the loss of the original command and a circular
+    dependency between the two pieces of advice.}
+  
+  This key applies to the next, and only to the next, invocation of key
+  \refmmz{activate}, i.e.\ it is reset back to |false| after invoking
+  \refmmz{activate}.  This key does not apply to \refmmz{deactivate}.
+\end{doc}
+
+\begin{doc}{easy,
+    key={name=auto, par=\marg{command or environment}{\marg{keylist}}, desc=style}}
+  
+  This key sets up the advice for the given command or environment, or updates
+  the configuration of an existing piece of advice.
+
+  In Memoize, this key is most commonly used to submit a command or environment
+  to automemoization.  For an environment (say, |bar|), it suffices to write
+  \refmmz{auto}|=|\bracestt{bar}\bracestt{\refmmzauto{memoize}}; for a command,
+  we usually need to include its argument specification:
+  \refmmz{auto}|=\foo|\bracestt{\refmmzauto{memoize},
+    \refmmzauto{args}=\bracestt{...}}.  Another common usage is to prevent
+  memoization during the execution of a command or environment:
+  \refmmz{auto}|=|\bracestt{bar}\bracestt{\refmmzauto{nomemoize}}.  For
+  details, see sections~\ref{sec:tut:automemoization},
+  \ref{sec:tut:working-on-a-picture} and~\ref{sec:tut:verbatim}.
+
+  The advice is configured by the given \meta{keylist}, which is executed with
+  the default keypath set to \docaux{key path}{mmz/auto}.  Any unknown keys in
+  \meta{keylist} are passed on to key \refmmzauto{options}; for example, a
+  plain \refmmz{verbatim} or \refmmz{padding}|=2in| have the same effect as
+  \refmmzauto{options}|=|\refmmz{verbatim} or
+  \code{\refmmzauto{options}=\braces{\refmmz{padding}=2in}}.
+
+  This key automatically activates the declared advice, unless it is already
+  activated; under the deferred activation regime, the automatic activation is
+  deferred as well. Use variant \refmmz{auto'} when you don't want to
+  automatically activate the advice.
+
+  When this key is used on a command or environment with an existing piece of advice,
+  the advice is merely updated.  This makes it easy to, for example,
+  temporarily switch to verbatim collection of an environment in Memoize:
+  \refmmz{auto}|=|\bracestt{tcolorbox}\braces{\refmmz{verbatim}}.  Use key
+  \refmmzauto{reset} to setup the advice from scratch:
+  \refmmz{auto}|=|\bracestt{...}\bracestt{\refmmzauto{reset}, ...}.
+  
+  A piece of advice consists of several interlocked components, declared by keys
+  residing in path \refkeypath{/mmz/auto}: \refmmzauto{run conditions},
+  \refmmzauto{bailout handler}, \refmmzauto{outer handler},
+  \refmmzauto{collector} and \refmmzauto{inner handler}.  During the execution
+  of the advice, these components are available through the following macros:
+  \refcmd{AdviceRunConditions}, \refcmd{AdviceBailoutHandler},
+  \refcmd{AdviceOuterHandler}, \refcmd{AdviceCollector} and
+  \refcmd{AdviceInnerHandler}.  These macros are also defined during setup, and
+  it is possible to change the configuration by modifying them directly; in
+  that case, it likely also makes sense to use the low-level variant of this
+  key, macro \refcmd{AdviceSetup}.
+
+  Control sequences used in the advice components do not need to be defined at
+  the time of invoking key \refmmz{auto}, or activating the advice; they must
+  only be defined at the time the advice is actually executed.  It is thus
+  perfectly fine to declare \refmmzauto{inner handler}|=\myinnerhandler| before
+  defining |\myinnerhandler|, or to redefine |\myinnerhandler| between the
+  invocations of the advised command.
+
+  This key configures not only the components, but also the options of the
+  advice.  These options are set by keys \refmmzauto{args},
+  \refmmzauto{collector options}, \refmmzauto{raw collector options} and
+  \refmmzauto{options}.  Whether these options are used or not depends on the
+  advice components.  (Same as the components, the options have their
+  corresponding low-level macros: \refcmd{AdviceArgs},
+  \refcmd{AdviceCollectorOptions}, \refcmd{AdviceRawCollectorOptions} and
+  \refcmd{AdviceOptions}.)
+
+  Parameter symbols (i.e.\ |#|) are not allowed in advice settings.
+
+  A command or environment may be submitted to several instances of the
+  advising framework, i.e.\ instances installed under different keypaths.  The
+  effect of such chained advice depends on the order of activation.  If advice
+  $A$ is activated before advice $B$, it will also be applied before $B$.
+
+  The advice setup takes place in a group.  Use key \refmmzauto{after setup} to
+  execute code outside this group.
+ 
+  In general, the name of this key equals whatever was submitted to
+  \refkey{/advice/install/setup key} during the installation of the advising
+  framework via \refkey{/handlers/.install advice}.
+\end{doc}
+
+\begin{doc}{
+    key={name=auto csname, par=\marg{control sequence name}{\marg{keylist}}, desc=style}
+  }
+  This key is a variant of \refmmz{auto}, but with the command of the first
+  argument given as a control sequence name, i.e.\ \refmmz{auto
+    csname}|={foo}{...}| is equivalent to \refmmz{auto}|=\foo{...}|.
+\end{doc}
+
+\begin{doc}{
+    key={name=auto key, par=\marg{full key}{\marg{keylist}}, desc=style},
+  }
+  This key is a variant of \refmmz{auto}, but it works with \pkg{pgfkeys} keys.
+  The first argument should be a \meta{full key} like |/tcb/float|, i.e.\ it
+  must consist of both the keypath and the keyname.
+
+  This key sets up advice for the internal command corresponding to the given
+  \meta{full key}, and also properly initializes the collector, so that
+  \refmmzauto{inner handler} will ``just work.''
+\end{doc}
+
+\begin{doc}{
+    key={name=auto', par=\marg{command or environment}{\marg{keylist}}, desc=style},
+    key={name=auto csname', par=\marg{control sequence name}{\marg{keylist}}, desc=style},
+    key={name=auto key', par=\marg{full key}{\marg{keylist}}, desc=style},
+  }
+  These keys are variants of \refmmz{auto}, \refmmz{auto csname} and
+  \refmmz{auto key} which do not attempt to activate the command after setting
+  it up.
+\end{doc}
+
+\begin{doc}{
+    cmd={
+      name=AdviceSetup,
+      par=\marg{namespace}\marg{command or environment}{\marg{setup code}}
+    }}
+  This macro is the low-level variant of key \refmmz{auto}.  The differences
+  between the two are the following:
+  \begin{itemize}
+  \item An invocation of the macro must provide the namespace (i.e.\ the
+    installation keypath) as the first argument.
+  \item There is no automatic activation at the end of the setup.
+  \item The final argument should not be a keylist (of keys belonging to
+    \refkeypath{/mmz/auto}) but \hologo{TeX} code adjusting the contents of the
+    settings macros \refcmd{AdviceRunConditions}, \refcmd{AdviceBailoutHandler},
+    \refcmd{AdviceOuterHandler}, etc.  For the full list of available macros, see
+    the documentation of their corresponding keys below; the setting macros are
+    mentioned at the end of each entry.
+  \end{itemize}
+\end{doc}
+
+\begin{doc}{
+    cmd={name=AdviceTracingOn},
+    cmd={name=AdviceTracingOff},
+  }
+  Advice tracing is initially off. When it is on, Advice will show (on the
+  terminal and in the |.log| file) which advice components are executed, and
+  what arguments and options they have received.
+\end{doc}
+
+\paragraph*{The keys installed into keypath \metabf{namespace}\texttt{/}\metabf{setup key}}
+are used to configure advice.  They may only occur within the second
+argument of the setup key.  In the documentation in this subsection, we assume
+that \meta{namespace}=\refkeypath{/mmz} and that \meta{setup
+  key}=\refmmz{auto}.  In particular, this also applies to the reference
+headers.
+
+\begingroup
+\yadocset{keypath=/mmz/auto}
+
+\begin{doc}{%
+    key={name=run conditions, par=\meta{\hologo{TeX} code},
+      desc=initially and default: \refcmd{AdviceRuntrue}},
+  }
+  
+  This key declares the \meta{control sequence} as the run conditions component
+  of the advice.
+
+  The run conditions macro is executed at the very start of the advice.  Its
+  function is to decide whether we should proceed to advise the command by
+  executing the outer handler, or execute the original command (after invoking
+  the bailout handler).
+
+  The run conditions macro should take no arguments.  If it determines that the
+  run conditions are satisfied, it should set the \hologo{TeX} conditional
+  \docaux{cmd}{ifAdviceRun} to true by executing \docaux{cmd}{AdviceRuntrue}.
+  There is no need to execute \docaux{cmd}{AdviceRunfalse} when the run
+  conditions are not satisfied.
+
+  Initially, the run conditions are set to \refcmd{AdviceRuntrue}, translating to
+  ``always run.''  For two non-trivial examples, see \refmmzauto{run if
+    memoization is possible} and \refmmzauto{run if memoizing}.  Executing this
+  key without a value restores it to the initial value.
+
+  During advising and advice setup, the run conditions of the advised command
+  are accessible through \docaux{cmd}{AdviceRunConditions}, a parameterless
+  macro expanding to the given \meta{\hologo{TeX} code}.
+\end{doc}
+
+\begin{doc}{%
+    key={name=bailout handler, par=\meta{\hologo{TeX} code},
+      desc=initially and default: \cs{relax}},
+  }
+  
+  This key declares the \meta{\hologo{TeX} code} as the bailout handler
+  component of the advice.
+
+  The bailout handler is executed when the run conditions are not met, just prior
+  to executing the original definition of the advised command.  The bailout
+  handler should take no arguments.
+
+  The initial bailout handler, |\relax|, does nothing.  Memoize defines and
+  uses a bailout handler which clears the next-options.  Executing this key
+  without a value restores it to the initial value.
+
+  During advising and advice setup, the bailout handler of the handled command is
+  accessible through \docaux{cmd}{AdviceBailoutHandler}, a parameterless macro
+  expanding to the given \meta{\hologo{TeX} code}.
+\end{doc}
+
+\begin{doc}{
+    key={name=outer handler,par=\meta{\hologo{TeX} code},
+      desc=initially and default: see below},
+  }
+
+  This key declares the \meta{\hologo{TeX} code} as the outer handler component
+  of the advice.
+
+  The outer handler can be safely imagined as the command which replaces the
+  handled command.  This also holds for handled environments, but with a
+  caveat: for a \hologo{plainTeX} or \hologo{ConTeXt} environment |foo|, the
+  outer handler replaces |\foo| and |\startfoo|, respectively; in the case of a
+  \hologo{LaTeX} environment, it replaces |\begin{foo}|.%]
+  
+  The outer handler is the first component which has the opportunity to inspect
+  the arguments given to the handled command.  It is invoked just in front of
+  these arguments (which are, in case \hologo{TeX} hasn't seen them yet,
+  untokenized), and while it is expected that the advice will consume
+  the same arguments as the advised command itself would, how precisely that
+  happens may vary from situation to situation.  In particular, the argument
+  structure of the outer handler is not prescribed.
+  
+  In fact, the outer handler has complete control over the remainder of the
+  advising process.  In situations where advising requires knowledge of the
+  advised command's arguments as a whole, the outer handler executes the
+  collector, which in turn invokes the inner handler, which does the real work;
+  see \refmmzauto{memoize} for the usage case which inspired this design.
+  Sometimes, however, it is the outer handler which does the real work (and
+  there is thus no inner handler).  This is the case in situations when the
+  arguments of the handled command are irrelevant for the functioning of the
+  advice, or when the advice needs to inspect some individual argument of the
+  handled command; for examples of such situations, see \refmmzauto{abort} and
+  \refmmzauto{ref}.
+
+  To reiterate the argument situation of the outer handler, it sees the
+  arguments of the handled command as they were given.  The arguments are
+  \emph{not} collected before invoking the outer handler --- in fact, avoiding
+  the argument collection is the raison d'être of the outer handler!  (In the case
+  of an advised environment, the environment body can be seen as an argument of
+  \pkg{xparse} type \docref{xparse:+}\docref{xparse:b}.)
+  
+  The outer handler (and any other component of the advice it invokes) has
+  access to the following auxiliary macros, defined by the framework:
+  \begin{itemize}
+  \item \tolerance 1000 the macros holding the configuration of the advised
+    command, as set up by \refmmz{auto}: \refcmd{AdviceRunConditions},
+    \refcmd{AdviceBailoutHandler} and \refcmd{AdviceOuterHandler} are probably
+    useless, as they refer to components already invoked, but the remaining
+    components (\refcmd{AdviceCollector} and \refcmd{AdviceInnerHandler}) and
+    their options (\refcmd{AdviceArgs}, \refcmd{AdviceCollectorOptions},
+    \refcmd{AdviceRawCollectorOptions} and \refcmd{AdviceOptions}) should be
+    commonly used.
+  \item the macros holding information about the namespace and the advised
+    command or environment: \refcmd{AdviceNamespace}, \refcmd{AdviceName},
+    \refcmd{AdviceReplaced} and \refcmd{AdviceOriginal}.  (Command
+    \refcmd{AdviceGetOriginal} might also be useful, although using
+    \refcmd{AdviceOriginal} will likely be more practical.)
+  \end{itemize}
+
+  This key is initially set to an internal control sequence which merely
+  invokes the collector by executing \refcmd{AdviceCollector}; in other words,
+  the initial outer handler leaves all the work to the collector and the inner
+  handler.  There is no need to specifically set up the outer handler when
+  using the inner handler. Executing this key without a value restores it to
+  the initial value.
+
+  During advising and advice setup, the outer handler of the advised command is
+  accessible through \docaux{cmd}{AdviceOuterHandler}, a parameterless macro
+  expanding to the given \meta{\hologo{TeX} code}.
+\end{doc}
+
+\begin{doc}{
+    key={name=collector,par=\meta{\hologo{TeX} code},
+      desc=initially and default: see below},
+  }
+
+  This key declares the \meta{\hologo{TeX} code} as the collector component of
+  the advice.
+  
+  The collector, if used, is invoked by the outer handler.  It is invoked
+  immediately in front of the advised command's arguments (which are, in case
+  \hologo{TeX} hasn't seen them yet, untokenized), and its function is to
+  collect these arguments and pass them on, as a single argument, to the inner
+  handler.
+
+  While this manual occasionally states that the initial argument collector is
+  \refcmd{CollectArguments} of package CollArgs, this is, if we're precise,
+  incorrect on two counts.  For one, the initial collector is not a CollArgs
+  command, but a macro which acts as the ``bridge'' between Advice
+  and CollArgs. Second, the initial collector does not really invoke
+  \refcmd{CollectArguments}, but its cousin, \refcmd{CollectArgumentsRaw},
+  which allows Advice (and Memoize) to fine tune its behaviour
+  using the fast low-level (``programmer interface'') commands rather than the
+  slower \pkg{pgfkeys} interface; clearly, the latter point also provides
+  raison d'être for \refmmzauto{raw collector options}.  Summing up, this key
+  is initially set to an internal control sequence which compiles the settings
+  provided by \refmmzauto{args}, \refmmzauto{collector options} and
+  \refmmzauto{raw collector options} into an invocation of
+  \refcmd{CollectArgumentsRaw} of package CollArgs.\footnote{The initial
+    collector also sets the CollArgs' option \refcollargs{caller} to the
+    name of the advised command or environment.}  Executing this key without a
+  value restores it to the initial value.
+
+  The above-mentioned collector settings were clearly tailored to suit
+  \refcmd{CollectArgumentsRaw}.  In general, a collector might or might not use
+  them, and if it does, it may interpret them in any way.  For example, Advice
+  ships with a \refcmd{tikz} collector, \docaux{cmd}{mmzCollectTikZArguments}, which
+  ignores them completely, as it knows everything about the idiosyncrasies of
+  that command anyway.  Incidentally, \refcmd{mmzCollectTikZArguments} becomes
+  available upon loading \reffile{advice-tikz.code.tex} (which Memoize does
+  automatically in the presence of \TikZ).
+
+  The collector has access to the same auxiliary macros as the outer handler.
+  In particular, it will \emph{have} to use \refcmd{AdviceInnerHandler} (followed
+  by the braced collected arguments) to invoke the inner handler.
+  
+  During advising and advice setup, the collector of the advised command is
+  accessible through \docaux{cmd}{AdviceCollector}, a parameterless macro
+  expanding to the given \meta{\hologo{TeX} code}.
+\end{doc}
+
+\begin{doc}{easy,
+    key={name=args,par=\meta{argument specification}, desc=initially and default: unset},
+  }
+
+  This key describes the \meta{argument specification} of the advised command.
+
+  Assuming that the initial value of \refmmzauto{collector} has not been
+  modified, the given \meta{argument specification} is eventually interpreted
+  by command \refcmd{CollectArguments} of package CollArgs, which expects an
+  argument specification in the format specified by package \pkg{xparse}; the
+  format is summarized in the frame below for convenience, for details, see the
+  \pkg{xparse} manual.  If the specification is not given, the initial collector
+  assumes that the advised command was defined using \refcmd{NewDocumentCommand}
+  (or similar) of package \pkg{xparse}, and will attempt to retrieve the argument
+  specification automatically via \refcmd{GetDocumentCommandArgSpec}.
+  
+  \begin{tcolorbox}[float, before float=\hfill,
+      title={The {\pkg[white]{xparse}} argument specification
+        (as understood by \refcmd[link color=white]{CollectArguments})}]
+    \begin{tabularx}{\linewidth}{>{\tt}lX}
+      \multicolumn{2}{l}{\rm\textbf{Mandatory argument types}}\\
+      m&standard (a single token or multiple tokens in braces)\\
+      r\meta{token$_1$}\meta{token$_2$}&delimited by 
+                                         \meta{token$_1$} and \meta{token$_2$} \\
+      v&verbatim, in the style of \cs{verb}\\
+      b&the body of an environment\\
+      [1ex]\multicolumn{2}{l}{\rm\textbf{Optional argument types}}\\
+      o&in square brackets\\
+      d\meta{token$_1$}\meta{token$_2$}&delimited by
+                                         \meta{token$_1$} and \meta{token$_2$}\\
+      s&an optional star\\
+      t\meta{token}&an optional \meta{token}\\
+      e\marg{tokens}&a set of embellishments\\
+      [1ex]\multicolumn{2}{l}{\rm\textbf{Weird argument types}}\\
+      l&a mandatory argument until the first begin-group token\\
+      u\marg{tokens}&\hologo{TeX}'s delimited argument\\
+      g&an optional argument inside braces\\
+      [1ex]\multicolumn{2}{l}{\rm\textbf{Modifiers}}\\
+      +&allow the next argument to be long\\
+      !&disallow spaces before arguments of type \docref{xparse:d} and \docref{xparse:t}\\
+      >\marg{processor}&process the next argument\\
+      [1ex]\multicolumn{2}{l}{\rm\textbf{CollArgs extensions}}\\
+      \docref{xparse:b}\marg{name}&set the environment name for this environment\\
+      \docref{xparse:amp}\marg{options}&apply CollArgs options to the next argument\\
+      \docref{xparse:amp}\docref{xparse:amp}\marg{raw options}&apply raw CollArgs options to the next argument\\
+    \end{tabularx}
+
+    \smallskip
+    
+    \refcmd{CollectArguments} can grab an argument of any type in the
+    \refcollargs{verbatim} mode.
+    
+    As \refcmd{CollectArguments} does not use the arguments but only collects
+    them, it does not care about the default values of optional arguments.
+    Therefore, argument types with defaults (\docref{xparse:O},
+    \docref{xparse:D} and \docref{xparse:R}) may be substituted by their
+    \texttt{-NoValue-} counterparts (\docref{xparse:o}, \docref{xparse:d} and
+    \docref{xparse:r}) and are therefore not included in the above table.
+  \end{tcolorbox}
+
+  In general, however, an argument collector may this interpret this setting it
+  in any way it sees fit --- or not at all.  For example, in Memoize the value
+  of \refmmzauto{args} is ignored for command \refcmd{tikz}, which requires a special
+  collector (\refcmd{mmzCollectTikZArguments}).
+  
+  When setting up advice for a \emph{command}, this key is initially
+  ``unset,'' i.e.\ it holds a special value indicating that the argument
+  specification is not provided.  Note that this special value is not an empty
+  string --- \refmmzauto{args}|={}|, or simply \refmmzauto{args}|=|, indicates
+  a command which takes no arguments.  During the execution of the advice, one
+  may use the \hologo{LaTeX}-style conditional
+  \docaux{cmd}{AdviceIfArgs}\marg{true branch}\marg{false branch} to test
+  whether the argument specification was provided.  Executing this key without
+  a value restores it to the initial, unset value.
+  
+  When setting up the advice of an \emph{environment}, this key is
+  initialized to \docref{xparse:+}\docref{xparse:b} (a long environment body),
+  making it unnecessary to specify this value manually.  Note that this holds
+  even for environments with arguments other that the environment body
+  ``argument'': those arguments will be caught as the start of the body even if
+  not explicitly specified.
+  
+  During advising and advice setup, the argument specification of the advised
+  command is accessible through \docaux{cmd}{AdviceArgs}, a parameterless macro
+  expanding to the given \meta{argument specification}.
+\end{doc}
+
+
+\begin{doc}{
+    key={name=collector options, par=\marg{keylist},
+      desc={cumulative, initially empty, value required}},
+    key={name=raw collector options, par=\marg{code}, 
+      desc={cumulative, initially empty, value required}},
+  }
+  These keys append the given value to the list of user-friendly and raw
+  collector options, respectively.  A comma is prefixed to the user-friendly
+  \meta{keylist} before appending it.
+
+  Both kinds of collector options are intended to be used by the collector,
+  which may interpret them in any way it sees fit --- or not at all.  The
+  initial collector, which invokes \refcmd{CollectArgumentsRaw} of package
+  CollArgs, passes both lists to this command, which interprets
+  \refmmzauto{collector options} as a user-friendly \pkg{pgfkeys} keylist
+  (which therefore requires a bit of processing) and \refmmzauto{raw collector
+    options} as plain \hologo{TeX} code (expecting it to contain only the
+  allowed, ``programmer's interface'' macros).\footnote{Clearly,
+    \refmmzauto{raw collector options} are why Advice deploys
+    \refcmd{CollectArgumentsRaw} rather than \refcmd{CollectArguments}.  But
+    how does it then pass the user-friendly \refmmzauto{collector options} to
+    that command? It embeds them in \refcmd{collargsSet}.}  The raw variant is
+  used internally by both Advice and Memoize, and may be used by a package
+  deploying the advising framework which wants to save a few processing cycles.
+  In CollArgs, the two kinds of options are functionally equivalent; both are
+  documented in section~\ref{sec:ref:collargs}.
+
+  Initially, the list of collector options is empty, and for commands, so is
+  the list of raw collector options.  For environments, however, the latter
+  list is initialized to set (the raw equivalent of) \refcollargs{environment}
+  to the environment name, and \refcollargs{end tag} to true.  The rationale
+  for the latter is that the environment body containing the end tag (e.g.\
+  |\end{foo}|) is nicely compatible with \refcmd{AdviceReplaced} (which equals
+the begin tag, e.g.\ |\begin{foo}|) and \refcmd{AdviceOriginal} (which executes
+  the original definition of e.g.\ |\begin{foo}|).  For example, thanks to
+    \refcollargs{end tag}, writing \refcmd{AdviceOriginal}|#1| in the inner
+    handler executes the original environment.  Importantly, the original
+    environment can be executed without explicitly referring to the
+    environment's name, and with code that works not only for environments of
+    any \hologo{TeX} format, but is actually the same as the code which invokes
+    an original \emph{command}.  Consequently, the same inner handler works for
+    both commands and environments, and in all \hologo{TeX} formats.
+
+    Furthermore, the initial collector also sets option \refcollargs{caller}
+    to the name of the advised command or environment (however,
+    \refcollargs{caller} never appears in any of the collector options
+    lists; it is simply prefixed to them while constructing the invocation of
+    \refcmd{CollectArgumentsRaw}).  And in Memoize, using keys
+    \refmmz{verbatim}, \refmmz{verb} or \refmmz{no verbatim} triggers the
+    addition of the cognominal \refcollargs{verbatim}, \refcollargs{verb}
+    or \refcollargs{no verbatim} among the collector options.
+    
+    Precious few CollArgs' options thus remain to be set by the author.  For
+    memoization, the most likely candidates are \refcollargs{ignore nesting}
+    and \refcollargs{ignore other tags}, which could help deal with unusual
+    environments.  Overriding the initial \refcollargs{end tag} by
+    \refcollargs{begin tag}, \refcollargs{end tag} and/or \refcollargs{tags}
+    might also be useful on occasion.
+    
+    During advising and advice setup, the \pkg{pgfkeys} and the raw collector
+    options of the advised command are accessible through
+    \docaux{cmd}{AdviceCollectorOptions} and
+    \docaux{cmd}{AdviceRawCollectorOptions}, both a parameterless macro expanding
+    to the given \meta{keylist} and \meta{code}, respectively.
+\end{doc}
+
+\begin{doc}{
+    key={name=clear collector options},
+    key={name=clear raw collector options},
+  }
+  These keys empty the list of user-friendly and raw collector options,
+  respectively.
+\end{doc}
+
+\begin{doc}{
+    key={name=inner handler, par=\meta{\hologo{TeX} code}, long description=0.5,
+      desc=initially and default: see below},
+  }
+
+  This key declares the \meta{\hologo{TeX} code} as the inner handler component
+  of the advice.
+
+  The inner handler is intended to be used in situations which require
+  knowledge of the advised command's arguments as a whole.  In such situations,
+  the outer handler will normally invoke the collector, which will in turn
+  execute the inner handler and provide it with a single (braced) argument,
+  containing the collected arguments of the advised command.  See
+  \refmmzauto{memoize} for the usage case which inspired this design.
+
+  The simplest example of an inner handler is a (single-parameter) macro which
+  does nothing.  Surprisingly enough, such an inner handler could be useful.
+  Defining |\def\Gobble#1{}| and setting
+  \code{\refmmz{auto}=\cs{foo}\bracestt{\refmmzauto{inner handler}=\cs{Gobble},
+      \refmmzauto{args}=\bracestt{...}}} with the argument structure
+  appropriate for |\foo| could be used to eradicate all invocations of |\foo|
+  from the document.
+
+  The inner handler has access to all the macros available to the outer
+  handler, but given that most of them have already fulfilled their function,
+  only the following will likely be useful in the inner handler:
+  \refcmd{AdviceNamespace}, \refcmd{AdviceName}, \refcmd{AdviceReplaced},
+  \refcmd{AdviceOriginal}, and \refcmd{AdviceOptions}.
+
+  Because there is clearly no reasonable default for the inner handler, this key
+  is initially set to an internal control sequence producing an ``undefined
+  inner handler'' error.  Note that it is not necessary to define a dummy inner
+  handler when handling is entirely performed by the outer handler, i.e.\ in
+  cases when the inner handler is not invoked.  Executing this key without a
+  value restores it to the initial value.
+  
+  During advising and advice setup, the inner handler of the advised command is
+  accessible through \docaux{cmd}{AdviceInnerHandler}, a parameterless macro
+  expanding to the given \meta{\hologo{TeX} code}.
+\end{doc}
+
+\begin{doc}{easy,
+    key={name=options,par=\marg{keylist},
+      desc={cumulative, initially empty, value required}},
+    key={name=clear options},
+  }
+
+  The first key appends the given \meta{keylist} to the list of advice options
+  (after prefixing it by a comma), and the second one empties this list.  For a
+  \meta{key} undefined in keypath \refkeypath{/mmz/auto},
+  \meta{key}|=|\meta{value} has the same effect as
+  \refmmzauto{options}|=|\bracestt{\meta{key}=\meta{value}}.
+
+  In Memoize, the options set by this key are known as
+  \emph{auto-options} --- options which are applied (using \refcmd{mmzset}) at
+  every invocation of the advised command or environment.  For example, the
+  \env{tcolorbox} environment of package \pkg{tcolorbox} is used extensively
+  for typesetting this manual, and I have submitted this environment to
+  automemoization.  However, the \env{tcolorbox}es in this manual often include
+  code listings.  To memoize such environments successfully, their bodies must
+  be grabbed verbatim.  I have therefore submitted the \env{tcolorbox}
+  environment to automemoization like this:
+  \refmmz{auto}|={tcolorbox}|\bracestt{\refmmzauto{memoize},
+    \refmmzauto{options}=\refmmz{verbatim}}; the simpler
+  \refmmz{auto}|={tcolorbox}|\bracestt{\refmmzauto{memoize}, \refmmz{verbatim}}
+  would work as well.
+
+  In general, whether to use the options set by this key, and how, remains at
+  the sole discretion of the advice.  Note that they might be used by either
+  the outer or the inner handler, or perhaps even the collector.
+  
+  During advising and advice setup, the options of the advised command are
+  accessible through \docaux{cmd}{AdviceOptions}, a parameterless macro expanding
+  to the given \meta{keylist}.
+\end{doc}
+
+\begin{doc}{key={name=reset, desc=style}}
+  Executing this key restores all \refmmz{auto} keys to their initial values.
+
+  Invoking \refmmz{auto} on the same command or environment again
+  \emph{updates} the advice configuration.  Use this key to start from scratch.
+\end{doc}
+
+\begin{doc}{key={name=after setup, desc={initially empty, cumulative}}}
+  The code given to this key will be executed after exiting the group opened by
+  \refmmz{auto}.  The same effect may be achieved by appending to macro
+  \docaux{cmd}{AdviceAfterSetup}.
+
+  For example, \refmmzauto{integrated driver} uses this key to declare a new
+  conditional.
+\end{doc}
+
+\paragraph{Commands available during the execution of advice}
+
+With the exception of \refcmd{AdviceGetOriginal}, the commands listed below
+only become available in the outer handler, and if that handler does nothing
+funky, they should be available in the collector and the inner handler, as
+well.  However, once the advice yields control to foreign code, these macros
+are not guaranteed to hold the expected values anymore, because the foreign
+code might trigger another piece of advice.  Consequently, these macros
+should be expanded, once, before integrating them into arbitrary (non-advice)
+code; in particular, this applies to \refcmd{AdviceOriginal}.
+
+\begin{doc}{cmd={name=AdviceNamespace}}
+  This macro holds the \meta{namespace}, i.e.\ the keypath which this instance
+  of the advising framework was installed into.
+\end{doc}
+
+\begin{doc}{cmd={name=AdviceName}}
+  This macro holds the name of the advised command or environment, i.e.\ the
+  name which was used as the first argument to \refmmz{auto}.  For a command,
+  this will be a control sequence, e.g.\ |\foo|; for environments (in any
+  \hologo{TeX} format), their name, e.g.\ |foo|.
+\end{doc}
+
+\begin{doc}{cmd={name=AdviceReplaced}}
+  This macro holds the code which was replaced by the outer handler.  For
+  commands, this will be the command itself, e.g.\ |\foo|, so
+  \refcmd{AdviceReplaced} will equal \refcmd{AdviceName}.  For an environment
+  |foo|, \refcmd{AdviceReplaced} is set to |\begin{foo}| in \hologo{LaTeX},
+  |\foo| in \hologo{plainTeX} and |\startfoo| in \hologo{ConTeXt}.
+\end{doc}
+
+\begin{doc}{cmd={name=AdviceOriginal}}
+  This macro executes the original code of the advised command.
+
+  This macro is defined as \refcmd{AdviceGetOriginal}\marg{namespace}\marg{name},
+  and therefore acts as a shortcut for an explicit invocation of
+  \refcmd{AdviceGetOriginal}.  When executing the original command directly from
+  the advice, one may safely write \refcmd{AdviceOriginal}.  However, whenever
+  \refcmd{AdviceOriginal} is embedded in code which might contain other advised
+  commands, it should be pre-expanded, exactly once.
+\end{doc}
+
+\begin{doc}{cmd={name=AdviceGetOriginal, par=\marg{namespace}\marg{control sequence}}}
+  This command invokes the original definition of the \meta{control sequence}
+  advised by the \meta{namespace} instantiation of Advice.  It may be safely
+  used outside the advice, even if the advised command is not activated.
+
+  For example, upon executing key |/ns/|\refmmz{auto}|=\foo{...}|,
+  |\AdviceGetOriginal{/ns}{\foo}| will recall the original definition of |\foo|
+  if |\foo| is activated, and simply execute |\foo| otherwise.
+
+  The second argument of this command should \emph{not} be an environment name.
+  To execute the original environment |foo| in \hologo{TeX} or
+  \hologo{ConTeXt}, use \refcmd{AdviceGetOriginal} with the appropriate macro:
+  |\AdviceGetOriginal{/ns}{\foo}| or |\AdviceGetOriginal{/ns}{\startfoo}|.  In
+  \hologo{LaTeX}, one should use |\AdviceGetOriginal{/ns}{\begin}{foo}|, which
+    executes the original \refcmd{begin} and provides it with the environment name.
+
+  Within the advice, you will probably never have to use this command directly,
+  but will rather rely on the (plain or pre-expanded) \refcmd{AdviceOriginal}.
+  However, outside the advice, this command provides the only means to
+  access the original definition of an advised command.  (Unlike the
+  commands described above, this command is available throughout the
+  document.)
+  
+  \begin{tcolorbox}[warning]
+    A typo in the invocation of this command may result in an infinite loop.
+    Assume that the advice for |\foo|, declared in namespace \refkeypath{/mmz},
+    executes \refcmd{AdviceGetOriginal}|{/zzm}{\foo}|, which incorrectly refers
+    to the non-existing namespace |/zzm|, and that command |\foo| is activated.
+    Executing |\foo| will eventually execute
+    \refcmd{AdviceGetOriginal}|{/zzm}{\foo}|, which won't find the original
+    definition of |\foo| in the non-existing namespace |/zzm| and will thus
+    execute macro |\foo| (again), which, being advised, will lead to another
+    \refcmd{AdviceGetOriginal}|{/zzm}{\foo}|, etc.  My advice is to define an
+    abbreviation like |\def\mmzAdviceGetOriginal{\AdviceGetOriginal{/mmz}}|.
+    And note that the name\-space is a full keypath, which begins with a slash
+    (|/|), but has no slash at the end.
+  \end{tcolorbox}  
+\end{doc}
+    
+\paragraph{Support for specific packages}
+At the moment, Advice only implements specific support for \TikZ, by defining a
+\refmmzauto{collector} for command \refcmd{tikz}.
+
+\begin{doc}{
+    cmd={name=AdviceCollectTikZArguments},
+  }
+  This command collects the arguments in the format expected by \refcmd{tikz}, and
+  executes macro \refcmd{AdviceInnerHandler} with the collected arguments given
+  as a single braced argument.  The collector supports both the group and the
+  semicolor invocation of |\tikz|, i.e.\ both |\tikz{...}| and |\tikz...;|.
+
+  This command is only available upon |\input|ting file
+  \docaux{file}{advice-tikz.code.tex}.
+\end{doc}
+
+\endgroup % keypath = /mmz/auto
+
+\subsubsection{Memoization-related additions to the advising framework}
+\label{sec:ref:advice:memoization}
+
+In section~\ref{sec:ref:advice}, we have seen that Memoize installs the
+advising framework into keypath \refkeypath{/mmz}, with setup key name
+\refmmz{auto}.  This populates keypaths \refkeypath{/mmz} and
+\refkeypath{/mmz/auto} with various generic advice keys.  However, Memoize
+installs further advice\slash automemoization-related keys into these keypaths.
+It is these keys which are described in this section.\footnote{One such key,
+  \refmmzauto{integrated driver}, is actually documented in
+  section~\ref{sec:ref:memoization}.}
+
+Therefore, in contrast to section~\ref{sec:ref:advice}, \refkeypath{/mmz} and
+\refmmz{auto} have no secret generic meaning here, i.e.\ they should \emph{not}
+be generalized to \meta{namespace} and \meta{setup key} of
+\refkey{/handlers/.install advice}.
+
+\paragraph{Keys residing in \refkeypath{/mmz}}
+
+\begingroup
+\setlength\textfloatsep{20pt plus 2pt minus 4pt}% back to the default
+
+\begin{doc}{easy,
+    key={name=manual, description={preamble-only,{ }}, conditional=false},
+  }
+  When this conditional is set to true, no commands are \refmmz{activate}d at
+  the beginning of the document.  The list of commands and environments advised
+  and activated out of the box can be found in Table~\ref{tab:advised-commands}.
+
+  The auto-framework allows the activation to be deferred (see
+  \refmmz{activation} and \refkey{/handlers/.install advice}) but leaves it
+  open to the specific instance of the framework to use the deferred activation
+  commands as it sees fit.  Normally, Memoize switches to immediate activation
+  at the end of the preamble (hook \refmmz{begindocument/before}) and issues
+  \refmmz{activate deferred} at the beginning of the document, more precisely
+  in hook \refmmz{begindocument/end} (afterwards, \refmmz{activate deferred} is
+  emptied).  However, when \refmmz{manual} is in effect, the deferred
+  activation is suppressed (though it may be still carried out by the user by
+  executing \refmmz{activate deferred}).
+
+  In \hologo{LaTeX}, \refmmz{manual} affects the (internal) activation of
+  \refcmd{begin} as well, which effectively deactivates handling of all environments.
+\end{doc}
+
+\begin{table}
+  \centering
+  \begin{tabularx}{\linewidth}{llX}
+    \toprule
+    command/environment&handler&notes\\
+    \midrule
+    \refcmd{begin}&custom&Only in \hologo{LaTeX}; declared by Advice.\\
+    \refcmd{errmessage}&\refmmzauto{abort}&Not available in \hologo{LuaTeX},
+                                            where better error-detection is implemented.\\
+    \refenv{forest}&\refmmzauto{memoize}\\
+    \refcmd{Forest}&\refmmzauto{memoize}\\
+    \refcmd{index}&\refmmzauto{replicate}&The argument is expanded prior to replication.\\
+    \refcmd{label}&custom&Globally appends \refcmd{mmzLabel}\marg{label key}\marg{current label}
+                           to register \refcmd{mmzCCMemo}; \refmmzauto{run if memoizing}.\\
+    \refcmd{pageref}&\refmmzauto{ref}\\
+    \refcmd[into index=false]{pdfsavepos}&\refmmzauto{abort}&Not available in \hologo{LuaTeX}.\\
+    \refcmd{pgfsys at getposition}&\refmmzauto{abort}&Available only in \TikZ is
+                                                    loaded, it aborts memoization of a picture which gets accidentally marked as
+                                                    ``remembered''.\\
+    \refcmd{ref}&\refmmzauto{ref}\\
+    \refcmd[short]{savepos}&\refmmzauto{abort}&Available only in \hologo{LuaTeX}.\\
+    \refcmd{tikz}&\refmmzauto{memoize}\\
+    \refenv{tikzpicture}&\refmmzauto{memoize}\\
+    \bottomrule
+  \end{tabularx}
+  \caption{Commands advised by Memoize}
+  \label{tab:advised-commands}
+\end{table}
+
+\begin{doc}{easy, 
+    key={name=ignore spaces, conditional=false},
+  }
+  Ignore any spaces following \emph{auto}memoized code.  This key has no effect
+  for manual memoization, i.e.\ command \refcmd{mmz} and environment
+  \refenv{memoize}.
+
+  It is common practice to conclude the definition of a command by \hologo{TeX}
+  primitive \refcmd{ignorespaces}, which consumes any following spaces, to
+  prevent unintended blank space after the command's invocation.  Automemoizing
+  such a command disrupts this behaviour.\footnote{It is clear that
+    \refcmd{ignorespaces} is disrupted during utilization; in this case, the
+    original command, including the concluding \cs{ignorespaces}, is never even
+    executed.  However, the disruption also occurs during memoization, and even
+    during regular compilation.  In both cases, the memoized code is embedded
+    in some internal Memoize code.  Therefore, the original \cs{ignorespaces}
+    does not occur directly in front of the rest of the document.} The
+  workaround is to use this key, normally as an option in the \refmmz{auto}
+  declaration; it will work both for automemoized macros and environments.
+\end{doc}
+
+\paragraph{Keys residing in \refkeypath{/mmz/auto}}
+
+\begingroup
+\yadocset{keypath=/mmz/auto}
+
+\begin{doc}{easy,key={name=memoize, desc=style}}
+  This key sets up advice which triggers memoization of the command or
+  environment whenever it is encountered; we often refer to such a command as
+  ``automemoized,'' or say that it was ``submitted to automemoization.''
+
+  An automemoized command will consume the next-options, whether memoization
+  actually occurs or not.
+
+  Under the hood, this key declares both an \refmmzauto{outer handler} and an
+  \refmmzauto{inner handler}.  The outer handler opens the memoization group
+  (so that options can be applied locally), applies the auto-options (given by
+  \refmmzauto{options} within \refmmz{auto}) and the next-options (given by
+  \refcmd{mmznext}) by executing \refmmzauto{apply options}, and appends the
+  verbatim keys to \refmmzauto{collector options} if necessary.  The inner
+  handler invokes \refcmd{Memoize} (which closes the group opened by the outer
+  handler): the first argument is \refcmd{AdviceReplaced}, expanded once and
+  followed by the arguments of the handled command; the second argument is
+  \refcmd{AdviceOriginal}, also expanded once and followed by the arguments of
+  the handled command.  The inner handler also makes sure that \refmmz{ignore
+    spaces} is respected.
+\end{doc}
+
+\begin{doc}{easy,key={name=nomemoize,desc=style}}
+  This key installs advice which disables memoization for the space of the
+  command or environment; we sometimes refer to such commands as
+  ``autodisabled.''
+
+  This key is merely an abbreviation for \refmmzauto{noop}|,|
+  \refmmzauto{options}|=|\refmmz{disable}.  See the documentation of
+  \refmmzauto{noop} for further details.
+\end{doc}
+
+\begin{doc}{key={name=noop,desc=style}}
+  This key sets up advice which does nothing.
+
+  Ok, not nothing at all.  The installed handler applies the auto-options and
+  the next-options by executing \refmmzauto{apply options}, and makes sure that
+  \refmmz{verbatim} and \refmmz{ignore spaces} are respected.
+
+  For commands and non-\hologo{LaTeX} environments, this key declares the same
+  outer handler as \refmmzauto{memoize}, while the inner handler merely
+  executes the original command (respecting the potential verbatim mode),
+  closes the group opened by the outer handler, and makes sure that
+  \refmmz{ignore spaces} is respected.
+
+  For \hologo{LaTeX} environments, which open the group necessary for the local
+  application of options themselves, this key declares an outer handler which
+  adds the relevant code into the next hook |env/|\meta{environment
+    name}|/begin|.  There is no need to open a group, collect the environment
+  body, or make special provisions for the verbatim mode.
+\end{doc}
+
+
+\begin{doc}{key={name=apply options,desc=style}}
+  This style, used by \refmmzauto{memoize}, \refmmzauto{nomemoize} and
+  \refmmzauto{noop} described above, installs two handlers:
+  \begin{itemize}
+  \item an outer handler which opens a group, applies auto-options and
+    next-options by executing \refcmd{mmzAutoInit}, and executes the collector;
+    and
+  \item a bailout handler which clears the next-options.
+  \end{itemize}
+\end{doc}
+
+
+\begin{doc}{cmd={name=mmzAutoInit}}
+  This macro applies the auto-options and the next-options.
+
+  Additionally, if \refmmz{verbatim}, \refmmz{verb} or \refmmz{no verbatim} was
+  previously executed, this style appends the corresponding CollArgs key
+  (\refcollargs{verbatim}, \refcollargs{verb} or \refcollargs{no
+    verbatim}) to \refcmd{AdviceRawCollectorOptions}.  In case several of the
+  verbatim keys were executed, the final one takes effect.
+\end{doc}
+
+
+\begin{doc}{easy, key={name=abort,desc=style}}
+  This key sets up advice which aborts any ongoing memoization.
+
+  Under the hood, the advice merely executes \refcmd{mmzAbort} followed by
+  \refcmd{AdviceOriginal}.  The advised command does \emph{not} consume the
+  next-options.  Out of the box, we submit two control sequences to this
+  handler:
+  \begin{itemize}
+  \item \refcmd{errmessage}: this allows us to detect and abort upon at least some
+    errors.
+  \item \refcmd[into index=false]{pdfsavepos} (in \hologo{LuaTeX},
+    \refcmd[short]{savepos}): one common effect is that memoization of any
+    \TikZ picture with \refkey{/tikz/remember picture} set is aborted.
+  \end{itemize}
+\end{doc}
+
+
+\begin{doc}{key={name=unmemoizable,desc=style}}
+  This key sets up advice which aborts the ongoing memoization and marks the
+  automemoized code as unmemoizable, so that it will be henceforth compiled
+  regularly.
+
+  Under the hood, the advice merely executes \refcmd{mmzUnmemoizable} followed
+  by \refcmd{AdviceOriginal}.  The advised command does \emph{not} consume the
+  next-options.
+
+  Out of the box, we submit no control sequences to this advice, but it might
+  make sense to submit \refcmd[into index=false]{pdfsavepos}\slash
+  \refcmd[short]{savepos}.  Keys \refmmzauto{abort}|=|\refcmd[short]{savepos}
+  and \refmmzauto{unmemoizable}|=|\refcmd[short]{savepos} will most often have
+  the same effect, as far as the author is concerned; the former was chosen as
+  the default because it does not produce a c-memo; see
+  \refcmd{mmzUnmemoizable} for a situation where \refmmzauto{unmemoizable} is
+  preferred.
+\end{doc}
+
+
+\begin{doc}{easy, 
+    key={name=ref,desc=style},
+    key={name=force ref,desc=style},
+  }
+
+  These keys set up advice which adds the reference key to the context
+  expression.  They are intended to be used with cross-referencing commands
+  such as \refcmd{ref} and \refcmd{pageref}.
+
+  Indeed, \refcmd{ref} and \refcmd{pageref} are submitted to this advice by
+  Memoize, with the effect that standard cross-referencing inside memoized code
+  ``just works.''  Note that the stabilization of the document after changing
+  the reference takes three compilation cycles, i.e.\ one cycle more than
+  without memoization.
+
+  The advice set up by \refmmzauto{ref} aborts memoization if the reference
+  key is undefined, the rationale being that the produced memo and extern would
+  most often be useless, and could even obscure an undefined reference.  The
+  \refmmzauto{force ref} handler produces the memo and the extern even when the
+  reference is undefined.
+
+  The reference produced by the advised command should be fully expandable
+  (because it will be expanded as a part of the context expression).
+  
+  Typically, a \refcmd{ref} command takes a single argument, the reference key.
+  However, some packages may define a reference command which takes optional
+  arguments, as well; in particular, the \pkg{hyperref}'s incarnation of \refcmd{ref}
+  takes an optional star.  This advice does not care: it will accept any number
+  of any kind of optional arguments, as long as the reference key is the first
+  braced argument following the advised command; for example, |\ref*{key}|,
+  |\ref[opt]{key}|, |\ref*[opt]{key}| etc.\ will all be handled correctly,
+  while |\ref{mand}{key}| will not work.  Effectively, it is as if we had set
+  \refmmzauto{args}|=lm| --- and with the same downside, namely that an
+  unlikely unbraced single-token reference key, like |\ref k|, will not work.
+
+  Under the hood, these two pieces of advice pass the reference key to macros
+  \refcmd{mmzNoRef} and \refcmd{mmzForceNoRef}, and it is these commands ---
+  which may also be used in user-defined advice or the document itself ---
+  which actually add the reference key to the context expression.
+\end{doc}
+
+\begin{doc}{easy, 
+    key={name=refrange,desc=style},
+    key={name=force refrange,desc=style},
+  }
+  These keys have the same function as \refmmzauto{ref} and \refmmzauto{force
+    ref}, but they operate on reference-range commands, such as \pkg{cleveref}'s
+  \refcmd{crefrange}, which take two arguments (the starting and the ending reference
+  key).
+\end{doc}
+
+\begin{doc}{easy, 
+    key={name=multiref,desc=style},
+    key={name=force multiref,desc=style},
+  }
+  These keys have the same function as \refmmzauto{ref} and \refmmzauto{force
+    ref}, but they operate on ``multireference'' commands, such as
+  \pkg{cleveref}'s \refcmd{cref}, which allow the author to list several
+  comma-separated reference keys in a single argument.
+\end{doc}
+
+\begin{doc}{
+    key={name=replicate, desc=style}
+  }
+  This key sets up advice which replicates the invocation of the command in
+  the cc-memo during memoization.
+
+  When using this key, it is necessary to set \refmmzauto{args} as well.  For
+  \refcmd{index}, Memoize executes
+  \refmmz{auto}|=\index|\bracestt{\refmmzauto{args}=m, \refmmzauto{replicate}}.
+
+  This key takes an auto-option, \docAux{keypath=/mmz/auto/replicate,
+    key={name=expanded}}.\footnote{This option is unrelated to Memoize's options,
+    settable by \refcmd{mmzset}.} If given, the collected arguments will be
+  expanded before replicating them in the cc-memo; in \hologo{LaTeX}, this
+  expansion is |\protect|ed.
+
+  In \hologo{LaTeX}, Memoize submits \refcmd{index} to this handler (with
+  expansion).  Therefore, any |\index{key}| in the memoized code gets copied
+  into the cc-memo.  Effectively, indexing from within the memoized code ``just
+  works.''
+
+  Note that \refcmd{label}, despite essentially requiring replication, cannot
+  use this advice, because it needs to replicate not only the label key but
+  \refcmd{@currentlabel} as well.
+\end{doc}
+
+\begin{doc}{key={name=run if memoization is possible, desc=style}}
+  Under the run conditions installed by this key, a command is only advised if
+  Memoize is enabled but we're not already ``within Memoize,'' i.e.\ memoizing
+  or normally compiling some code submitted to memoization.  In code:
+  \refcmd{ifmemoize}\refcmd{ifinmemoize}|\else|\refcmd{AdviceRuntrue}|\fi\fi|.
+
+  Internally, this key is used by \refmmzauto{memoize} and \refmmzauto{noop}.
+\end{doc}
+
+\begin{doc}{key={name=run if memoizing, desc=style}}
+  Under the run conditions installed by this key, a command is only advised
+  during memoization.  In code:
+  \refcmd{ifmemoize}\refcmd{ifmemoizing}\refcmd{AdviceRuntrue}|\fi\fi|.
+  
+  Internally, this key is used by \refmmzauto{abort}, \refmmzauto{replicate},
+  and \refmmzauto{ref} and friends.
+\end{doc}
+
+\endgroup % keypath = /mmz/auto
+\endgroup
+
+
+
+\subsubsection{Package CollArgs}
+\label{sec:ref:collargs}
+
+\begingroup
+\yadocset{keypath=/collargs}
+
+\begin{doc}{cmd={
+      name=CollectArguments,
+      par=\oarg{options}\marg{argument specification}\marg{next-code}%
+      \textcolor{gray}{\meta{tokens}}}}
+  
+  This command determines the extent to which the \meta{tokens} following the
+  the three formal arguments of the command conform to the given \meta{argument
+    specification}, effectively splitting \meta{tokens} into \meta{argument
+    tokens} and the \meta{rest} of the tokens, and then executes
+  \meta{next-code} with the \meta{argument tokens} provided as a single, braced
+  argument:
+  \begin{center}
+    \meta{next-code}\marg{argument tokens}\textcolor{gray}{\meta{rest}}
+  \end{center}
+  If the initial part of \meta{tokens} does not conform to \meta{argument
+    specification}, \refcmd{CollectArguments} throws an error.  (In this case,
+  \meta{next-code} is not executed, and the \meta{tokens} collected until the
+  error are thrown away.)
+
+  The optional \meta{options} are processed using the \pkg{pgfkeys} utility of
+  PGF/\TikZ (see \PGFmanual{87}), with the default path set to
+  \docaux{key path}{collargs}.  The given options apply to all the arguments in
+  \meta{argument specification}.  The recognized keys are listed in the rest of
+  the section.
+  
+  The \meta{argument specification} should be given in the \pkg{xparse} format
+  (we summarize this format in the documentation for \refmmzauto{args} in
+  section~\ref{sec:ref:advice}), with several extensions:\footnote{Collargs
+    internally uses a dot (|.|) to delimit the argument specification from the
+    following argument tokens.  Therefore, the dot really counts as an extra
+    argument type, in the sense that Collargs will stop working if the dot
+    becomes an argument type or a modifier in some future release of
+    \pkg{xparse}.}
+  \begin{itemize}
+  \item We introduce modifier \docAux{xparse modifier={name=\&,label=amp,index
+        annotation/.prefix={additional\ }, index annotation/.append={\
+          (options)} }} taking a mandatory argument specifying the options to
+    apply to the following argument in the specification.  Options given here
+    override the \meta{options} given as the optional argument.
+  \item The environment body type \docAux{xparse type={name=b,index
+        annotation/.append={\ (environment body)}}} may be followed by an optional
+    \emph{braced} argument providing the name of the environment to collect.
+    The name given here overrides the name given by the
+    \refcollargs{environment} option.
+  \item The number of collected ``arguments'' is unlimited.
+  \end{itemize}
+
+  Also note that the effect of \docref{xparse:O}\marg{default} is the same as
+  the effect of \docref{xparse:o}, and similarly for other pairs of types with
+  and without defaults (\docref{xparse:R} and \docref{xparse:r},
+  \docref{xparse:D} and \docref{xparse:d}, and \docref{xparse:E} and
+  \docref{xparse:e}).  CollArgs is dedicated to collecting the argument tokens
+  precisely as they are given: if an optional argument is missing, its default
+  value is \emph{not} inserted among the collected arguments --- consequently,
+  \refcmd{CollectArguments} is utterly uninterested in the default value.
+
+  Collection of environments automatically adapts to the format, i.e.\ given
+  environment body name |foo|, \refcmd{CollectArguments} knows to search for
+  \refcmd{begin}\bracestt{foo} |...| \refcmd{end}\bracestt{foo} in
+  \hologo{LaTeX}, \cs{foo} |...| \cs{endfoo} in \hologo{plainTeX}, and
+  \cs{startfoo} |...| \cs{stopfoo} in \hologo{ConTeXt}.  For further
+  information on environment collection, see keys \refcollargs{ignore
+    nesting} and \refcollargs{tags}.
+\end{doc}
+
+\begin{doc}{cmd={
+      name=CollectArgumentsRaw,
+      par=\marg{option-setting code}\marg{argument specification}\marg{next-code}%
+      \textcolor{gray}{\meta{tokens}}}}
+    
+  This command is the programmer's interface to CollArgs, intended to be used
+  instead of \refcmd{CollectArguments} when compilation speed is an issue.  The
+  two commands only differ in how they deal with options.
+
+  One difference is that for \refcmd{CollectArgumentsRaw}, the options form a
+  mandatory rather than an optional argument.  More importantly, however, they
+  do not take the form of a keylist, but should be composed out of low-level
+  option-setting commands.  Each key documented in this section has a
+  corresponding low-level macro; these macros are listed in footnotes alongside
+  the keys.  The name of the macro starts with |\collargs| and continues with
+  the name of the key, without spaces, each word capitalized; if the key is
+  boolean, this convention applies to the base of the \hologo{TeX}
+  conditional. For example,
+  \begin{tcblisting}{listing only, listing options app={escapechar=|}}
+\CollectArguments[caller=\foo, tags, verbatim]|\marg{argument specification}\marg{next-code}|
+  \end{tcblisting}
+  is equivalent to
+  \begin{tcblisting}{listing only, listing options app={escapechar=|}}
+\CollectArgumentsRaw{%
+  \collargsCaller{\foo}%
+  \collargsBeginTagtrue\collargsEndTagtrue
+  \collargsVerbatim
+}|\marg{argument specification}\marg{next-code}|
+  \end{tcblisting}
+  
+  Withing the option-setting code, the programmer may also deploy macro
+  \docaux{cmd}{collargsSet}, which processes the \meta{options} in the keylist
+  format.  One idea could be to execute this macro at the end of the low-level
+  options; this would set the ``defaults'' using the fast programmer's
+  interface, but still allow for user customization.
+\end{doc}
+
+
+\begin{doc}[
+    pi={\docaux{cmd}{collargsCaller}},
+  ]{
+    key={name=caller, par=\meta{control sequence (name)},
+      desc={no default, initially \cs{CollectArguments}}},
+  }
+  Set the control sequence to refer to in error messages.
+  
+  If \meta{tokens} do not match the \meta{argument specification},
+  \refcmd{CollectArguments} throws an error.  By default, the error message
+  contains a reference to \refcmd{CollectArguments} itself, for example %
+  |! Argument of \CollectArguments has an extra }.| However, this might not be
+very informative to the author.  When \refcollargs{caller}|=\cs| is in effect,
+the error messages will refer to the given |\cs| instead.
+
+If the value of this key is not a control sequence, it is assumed to be an
+environment name, but as the caller must be a macro, this name will be
+converted into a control sequence.  Setting \refcollargs{caller}|=foo| will
+result in error messages referencing |\foo| in \hologo{plainTeX}, |\startfoo|
+in \hologo{ConTeXt} and |\begin{foo}| (a single control sequence!) in
+  \hologo{LaTeX}.
+\end{doc}
+
+\begin{doc}[
+    pi=\docaux{cmd}{collargsEnvironment},
+  ]{key={name=environment, par=\meta{environment name},
+      desc={applicable to type \docref{xparse:b}, no default, initially empty}}
+  }
+
+  Set the name of the environment collected by argument type
+  \docref{xparse:b}.
+\end{doc}
+
+\begin{doc}[
+    pi={\docaux{cmd}{ifcollargsBeginTag}, \docaux{cmd}{ifcollargsEndTag};
+        \refcollargs{tags} has no corresponding low-level command}
+    ]{
+      key={name=begin tag, desc={applicable to type \docref{xparse:b},{ }}, conditional=false},
+      key={name=end tag, desc={applicable to type \docref{xparse:b},{ }}, conditional=false},
+      key={name=tags, par=\meta{boolean}, % not a conditional
+        desc={applicable to type \docref{xparse:b}, style, default |true|}},
+    }
+
+  When \refcollargs{begin tag}\slash \refcollargs{end tag} is in effect, the
+  begin\slash end tag will be will be prepended/appended to the collected
+  environment body. Style \refcollargs{tags} is a shortcut for setting
+  \refcollargs{begin tag} and \refcollargs{end tag} simultaneously.
+
+  In \hologo{LaTeX}, using \refcollargs{tags} will thus dress up the
+  collected body in a pair or \refcmd{begin}\marg{environment name} and
+  \refcmd{end}\marg{environment name}.  CollArgs will automatically use the tags
+  appropriate to the format.
+
+  In the verbatim modes, the added tags are verbatim as well, with the detail
+  that in \hologo{LaTeX}, there is a slight difference between the full
+  \refcollargs{verbatim} and the partial \refcollargs{verb} mode.  In the
+  full verbatim mode, the braces surrounding the environment name are verbatim
+  (the characters used as braces are actually determined by key
+  \refcollargs{braces}).  In the partial verbatim, as well as the
+  non-verbatim mode, the environment name is surrounded by a pair of actual
+  braces of category 1 and 2, regardless of which characters are of these
+  categories in the calling code.
+\end{doc}
+
+\begin{doc}[
+    pi=\docaux{cmd}{ifcollargsIgnoreNesting},
+  ]{
+    key={name=ignore nesting, desc={applicable to type \docref{xparse:b},{ }},
+      conditional=false},
+  }
+  When this key is \emph{not} in effect, CollArgs respects the hierarchical
+  structure created by tag pairs such as \refcmd{begin}\bracestt{foo} and
+  \refcmd{end}\bracestt{foo}.  Given the situation below on the
+  left, argument type |b{foo}| will collect everything up until the
+  \emph{second} |\end{foo}|.  Now this is what we usually want, because
+\hologo{LaTeX} keeps track of environment embedding as well.  However, all
+\emph{verbatim} environments I know of, starting with the standard
+\hologo{LaTeX} \refenv{verbatim}, will ignore the nesting and simply scoop up
+everything up to the first \cs{end}|{verbatim}|.  In CollArgs, we can replicate
+their behaviour by setting \refcollargs{ignore nesting}, as shown below on the
+right.  (Of course we also need to set \refcollargs{verbatim} if we want to
+grab the environment body in the verbatim mode.)
+
+  \begin{tcbraster}[raster columns=2]
+    \begin{tcblisting}{listing only, mark region={1}{5},
+      example title=\texttt{ignore nesting=false}}
+  ...
+  \begin{foo}
+    ...
+  \end{foo}
+  ...
+\end{foo}
+    \end{tcblisting}
+    \ExampleName{_collargs-verbatim}
+    \makeexample{\examplename.tex.c1}
+    \tcbinputexample{listing only, no attachment, mark region={1}{3}, 
+        example title=\texttt{ignore nesting=true}}
+  \end{tcbraster}
+
+  This key applies not only to argument type \docref{xparse:b} (in either
+  normal or verbatim mode), but also to the verbatim argument type
+  \docref{xparse:v} and to argument types \docref{xparse:m} and
+  \docref{xparse:g} in the \refcollargs{verbatim} (but not normal, or
+  \refcollargs{verb}) mode.  With these keys, the relevant structure markers
+  are braces, |{| and |}|.
+\end{doc}
+
+\begin{doc}[
+    pi=\docaux{cmd}{ifcollargsIgnoreOtherTags},
+  ]{
+    key={name=ignore other tags, desc={applicable to type \docref{xparse:b},{ }},
+      conditional=false},
+  }
+  In \hologo{LaTeX}, the environment tags, \refcmd{begin}\marg{name} and
+  \refcmd{end}\marg{name}, contain braces, which retain their usual category codes
+  in the non-verbatim and in the partial verbatim mode.  Consequently, CollArgs
+  cannot easily search for the full tags to delimit the
+  environment.
+
+  When this key is \emph{not} in effect, CollArgs takes the easy path, and
+  determines the end of the environment only by inspection of \cs{begin}s and
+    \cs{end}s, without reference to what \meta{name} they begin or end.  Only
+  when this key \emph{is} in effect does CollArgs inspect these \meta{name}s,
+  effectively ignoring any \cs{begin}s and \cs{end}s not followed by the name of
+  environment being collected.  The effect of absence vs.\ presence of this key
+  is shown below, where the shaded area marks the code collected into
+  environment |foo|.
+
+  \begin{tcbraster}
+    \ExampleName{_collargs-ignore-other-tags}
+    \makeexample{\examplename.tex.c1 N=2}
+    \tcbinputexample{listing only, no attachment, mark region={3}{3},
+      example title=\texttt{ignore other tags=false}}
+    \tcbinputexample[.tex][.c2]{listing only, no attachment, mark region={3}{5},
+      example title=\texttt{ignore other tags=true}}
+  \end{tcbraster}
+
+  This key does not have any effect the full verbatim mode, which always
+  behaves as if this key was set to true, because braces are of category
+  ``other'' as well.  Similarly, it is as if this key was always true in
+  \hologo{plainTeX} and \hologo{ConTeXt}, simply because environment tags in
+  these formats don't contain braces.
+\end{doc}
+
+\begin{doc}[
+    pi={\raggedright
+      \docaux{cmd}{collargsAppendPreprocessor},
+      \docaux{cmd}{collargsPrependPreprocessor},
+      \docaux{cmd}{collargsAppendPostprocessor},
+      \docaux{cmd}{collargsPrependPostprocessor}},
+  ]{
+    key={name=append preprocessor, par=\meta{code}, desc={no default}},
+    key={name=prepend preprocessor, par=\meta{code}, desc={no default}},
+    key={name=append postprocessor, par=\meta{code}, desc={no default}},
+    key={name=prepend postprocessor, par=\meta{code}, desc={no default}},
+  }
+  These keys declare processors which will transform the collected argument
+  before appending it to the argument list.
+  
+  A collected argument undergoes the following transformations:
+  \begin{itemize}
+  \item First, the argument is processed by any \emph{pre}processors, in the
+    order indicated by |append| and |prepend|.
+  \item Next, the processed argument is dressed up in the delimiters according
+    to its type.  For example, an optional argument of type \docref{xparse:o}
+    will be surrounded by square brackets.
+  \item Finally, the delimited argument is processed by any
+    \emph{post}processors, again in the order indicated by |append| and
+    |prepend|.
+  \end{itemize}
+
+  \meta{code} will typically consist of a single control sequence pointing to a
+  one-argument macro, which will receive the collected argument (possibly
+  modified by the processors already applied).  In general, however, the value
+  of this key may be any code; Collargs will execute \meta{code}\marg{collected
+    argument}.
+
+  The processed argument should be returned by storing it into token register
+  \docaux{cmd}{collargsArg}.
+
+  The following example illustrates how one could go about reimplementing Bruno
+  Le Floch ingenious package \pkg{cprotect}.\footnote{This example is merely a
+    proof of concept.  For the bells and whistles which would make it useful in
+    real life, see the documentation of \pkg{cprotect}.} We define processor
+  |\writetofile| which dumps the argument into a file, replacing it with the
+  |\input| statement.  (Of course, to allow for verbatim content in the
+  footnote, we also have to mark the argument as \refcollargs{verbatim}.
+  And we use \refcollargs{no delimiters} to get rid of the braces around the
+  footnote text.)
+  
+  \ExampleName{collargs-processor}
+  \makeexample{\examplename.tex.c1}
+  \tcbinputexample{listing and text, listing file=\examplepath.tex.c1}
+\end{doc}
+
+\begin{doc}[
+    pi={\docaux{cmd}{collargsClearPreprocessors},
+      \docaux{cmd}{collargsClearPostprocessors}},
+  ]{
+    key={name=clear preprocessors},
+    key={name=clear postprocessors},
+  }
+  Clear the list of pre- or post-processors.
+\end{doc}
+
+\begin{doc}[
+    pi={\docaux{cmd}{collargsAppendExpandablePreprocessor},
+      \docaux{cmd}{collargsPrependExpandablePreprocessor},
+      \docaux{cmd}{collargsAppendExpandablePostprocessor},
+      \docaux{cmd}{collargsPrependExpandablePostprocessor}
+    },
+  ]{
+    key={name=append expandable preprocessor, par=\meta{code}, desc={no default}},
+    key={name=prepend expandable preprocessor, par=\meta{code}, desc={no default}},
+    key={name=append expandable postprocessor, par=\meta{code}, desc={no default}},
+    key={name=prepend expandable postprocessor, par=\meta{code}, desc={no default}},
+  }
+  These keys may be used to add fully expandable processors.  A processor added
+  with one of these keys will end up among the processors declared by
+  \refcollargs{append preprocessor} et al.
+
+  A processor declared by one of these keys will define the processed argument
+  as the full expansion (|\edef|) of \meta{code}\marg{collected argument}.
+  \meta{code} will typically consist of a single control sequence pointing to a
+  fully expandable one-argument macro.
+
+  For example, |\trim at spaces@noexp| from package \pkg{trimspaces} could be used
+  as an expandable processor of environment body to remove the spaces around
+  the grabbed environment body.
+\end{doc}
+
+\begin{doc}[
+    pi={\docaux{cmd}{collargsAppendPrewrap},
+      \docaux{cmd}{collargsPrependPrewrap},
+      \docaux{cmd}{collargsAppendPostwrap},
+      \docaux{cmd}{collargsPrependPostwrap}},
+  ]{
+    key={name=append prewrap, par=\meta{macro definition}, desc={no default}},
+    key={name=prepend prewrap, par=\meta{macro definition}, desc={no default}},
+    key={name=append postwrap, par=\meta{macro definition}, desc={no default}},
+    key={name=prepend postwrap, par=\meta{macro definition}, desc={no default}},
+  }
+  These keys add processors which transform the collected argument in a single
+  expansion.
+
+  The declared processor will use \meta{macro definition} to define a temporary
+  one-argument \meta{macro}, and then set the \meta{processed argument} to be
+  the single expansion of \meta{macro}\marg{collected argument}.
+
+  For example, to add quotes around the collected argument, write
+  \refcollargs{append prewrap}|={``#1''}| (doubling the hash when executing
+  \refcmd{CollectArguments} from a macro, of course).  Or, perhaps more
+  usefully, \refcollargs{append prewrap}|={\scantokens{#1}}| can be used to
+  retokenize a verbatim argument (during the execution of the
+  \meta{next-code}).
+\end{doc}
+
+
+\begin{doc}[
+    pi=\docaux{cmd}{ifcollargsNoDelimiters}
+  ]{
+    key={name=no delimiters, conditional=false},
+  }
+  When this key is in effect, the collected argument will not be dressed up
+  into delimiters that it was dressed up in \meta{argument tokens}.  For
+  example, an optional argument, encountered as [\meta{argument}] inside
+  \meta{argument tokens}, will be spit out simply as \meta{argument}.
+
+  Any user-specified pre- or post-processing will still be applied.
+  \ExampleName{collargs-nodelimiters}
+  \makeexample{\examplename.tex.c1}
+  \tcbinputexample{comment=\input{\examplepath.tex.c1}}
+\end{doc}
+
+
+\begin{doc}[
+    pi={\docaux{cmd}{collargsVerbatim},
+      \docaux{cmd}{collargsVerb},
+      \docaux{cmd}{collargsNoVerbatim}.
+      To ensure the same effect as with the keys,
+      place these macros at the end of the option code},
+  ]{
+    key={name=verbatim, desc=style},
+    key={name=verb, desc=style},
+    key={name=no verbatim, desc=style},
+  }
+  Select the full verbatim, the partial verbatim, or the non-verbatim mode of
+  argument collection.
+  
+  In the full \refcollargs{verbatim} mode, the arguments are collected under
+  a category code regime in which all characters are of category 12, ``other''.
+  The same goes for the partial \refcollargs{verb} mode, except that in this
+  case, the grouping characters --- usually the braces |{| and |}| --- retain
+  their usual category codes 1 and 2.  Key \refcollargs{no verbatim} selects
+  the normal, non-verbatim mode.
+
+  The partial \refcollargs{verb} mode can be useful for verbatim collection
+  of an optional argument.  To pass |]| as an optional argument to command
+|\foo|, we normally enclose it in braces: ˇ\foo[{~]~}]ˇ.  However, if we try to
+collect |[{]}]| with \refcmd{CollectArguments}|[|\refmmz{verbatim}|]{o}|, we
+will get |{| (and most likely an error, as well), because in the
+  \refmmz{verbatim} mode, braces do not have their grouping function.  Using
+  the \refmmz{verb} mode solves the problem: occuring within braces, the first
+  |]| is ``invisible'' to \refcmd{CollectArguments}|[|\refmmz{verb}|]|, so the
+optional argument is correctly recognized as ending at the second |]|.
+
+The partial \refcollargs{verb} mode is also useful for collecting the bodies
+of \emph{\hologo{LaTeX}} environments.  The full \refcollargs{verbatim} mode
+will only correctly collect these bodies when the relevant \refcmd{begin}
+and\slash or \refcmd{end} control sequences are followed by the grouped
+environment name without any intervening spaces.  The partial
+\refcollargs{verb} mode has no such restriction.
+
+In the verbatim modes, modifier \docref{xparse:+} has no effect.  The arguments
+are always collected as if they were long.
+
+To correctly collect arguments in the verbatim modes, CollArgs has to mimic the
+many details of \hologo{TeX}'s tokenization and argument delineation.  These
+details depend on the category code regime, and CollArgs automatically adapts
+to the ``outside'' category code regime, i.e.\ the regime in effect at the time
+of invoking \refcmd{CollectArguments}.  In particular, CollArgs remembers which
+characters were of category codes 0, 1, 2, 5, 10 and 11, and adapts the
+argument collection accordingly.  For example, it will correctly pick up a
+control sequence as a single-token \docref{xparse:m}-type (\hologo{TeX}'s undelimited)
+argument even when it begins with a non-standard character of category code 0.
+The single caveat is that only a single pair of characters can function as the
+grouping characters in the full verbatim mode; to compensate for the
+deficiency, this character pair is customizable via key
+\refcollargs{braces}.
+\end{doc}
+
+\begin{doc}[
+    pi={\docaux{cmd}{collargsFixFromVerbatim},
+      \docaux{cmd}{collargsFixFromVerb},
+      \docaux{cmd}{collargsFixFromNoVerbatim}},
+  ]{
+    key={name=fix from verbatim, desc=style},
+    key={name=fix from verb, desc=style},
+    key={name=fix from no verbatim, desc=style},
+  }
+  Key \refcollargs{fix from no verbatim} should be used when the first
+  argument should be collected in a verbatim mode, but the outside code has
+  already tokenized the first character of the subsequent input stream (most
+  probably by a |\futurelet|) in the non-verbatim category code regime.  Using
+  this key will trigger a CollArgs' ``mode transition'' (described below) which
+  will fix the situation.  (This key is used in the implementation of
+  \refcmd{mmz}.)
+
+  The other two keys should be used in the unlikely reverse situation, where
+  the outside code has tokenized the following character in a verb(atim) mode,
+  while CollArgs is requested to collect the first argument in the non-verbatim
+  mode.
+\end{doc}
+
+\begin{doc}[
+    pi=\docaux{cmd}{collargsBraces}
+  ]{
+    key={name=braces, par={\meta{begin-group char}\meta{end-group char}},
+      desc={no default, for details see below}},
+  }% here
+  This key sets the verbatim begin-group and end-group characters.  The setting
+  affects collection of argument types \docref{xparse:m}, \docref{xparse:g},
+  \docref{xparse:v}, \docref{xparse:l}, \docref{xparse:e} and (in
+  \hologo{LaTeX}) \docref{xparse:b} in the \emph{full} verbatim
+  mode.\footnote{The choice of the verbatim grouping characters also affects
+    the effect of \refcollargs{begin tag} and\slash or \refcollargs{end tag};
+    see the documentation of these keys for details.}
+
+  For example, in the non-verbatim and the partial verbatim mode, an
+  \docref{xparse:m}-type argument may be delimited by any characters of
+  category code 1 (``begin-group'') and 2 (``end-group'').  In the full
+  verbatim mode, there are of course no characters of these categories, so
+  CollArgs internally assigns the grouping function to some pair of characters.
+  When entering the full verbatim mode, CollArgs automatically sets the
+  verbatim grouping characters to characters which were of categories 1 and 2
+  in the ``outside'' category code regime, i.e.\ the regime in effect at the
+  time of invoking \refcmd{CollectArguments}.  However, in contrast to
+  \hologo{TeX}'s internal argument parser, only one pair of characters may
+  serve as the begin-group and the end-group character in CollArgs' full
+  verbatim mode.  In case multiple characters were of category 1 or 2 on the
+  outside, CollArgs therefore has to make a choice, and it chooses the
+  candidate with the lowest character code.  This choice may be overridden by
+  the user by invoking key \refcollargs{braces}; the user may even choose
+  characters which did not belong to categories 1 and 2 in the outside regime.
+
+  When \meta{begin-group char} and \meta{end-group char} are of categories 1
+  and 2 in the outside category regime, they must be enclosed in a triple
+  group.  For example, if both |()| and |{}| have the grouping function on the
+  outside, and the user wants to select |{}| as the verbatim grouping
+  characters (CollArgs would go for |()|, as this pair has lower character
+  codes), the correct way to invoke this key is |braces={{{{}}}}| or
+  |braces=((({})))|.  \footnote{This complication is due to the details of
+    \pkg{pgfkeys}' keylist processing, and does not apply to
+    \refcmd{collargsBraces}.}
+\end{doc}
+
+\begin{doc}[
+    pi=\docaux{cmd}{collargsVerbatimRanges}
+  ]{
+    key={name=verbatim ranges,
+      par={\bracestt{\meta{from}\texttt{-}\meta{to}(\texttt{,} \meta{from}\texttt{-}\meta{to})*}},
+      desc={no default, initially \texttt{0-255}}},
+  }
+  If run under the \hologo{pdfTeX} or \hologo{XeTeX} engine, this key
+  determines which characters will be assigned category code 12 in the verbatim
+  mode.  In \hologo{pdfTeX}, the range should remain at the initial |0-255|,
+  but in \hologo{XeTeX}, some rare situations might require extending this
+  range (don't attempt to set the full range of |0-1114111|, as this would be
+  very slow and you would most likely run out of save stack).
+
+  In \hologo{LuaTeX}, we switch the category code regime using category code
+  tables, so this key has another meaning: it determines the range in which
+  CollArgs will scan for characters of category codes 1, 2 and 14, whose
+  identity it needs to know, for internal reasons.
+\end{doc}
+
+
+
+\paragraph{Mode transition limitations}
+
+\refcmd{CollectArguments} has some minor limitations regarding the transition
+from a verbatim into non-verbatim mode, or vice versa.  The gist of the issue
+is best illustrated with the optional argument type \docref{xparse:o} collected
+in the verbatim mode.  CollArgs determines whether an argument of this type is
+present by peeking ahead (using \hologo{TeX}'s |\futurelet| primitive) into the
+input stream.  If the argument is present (i.e.\ if the input stream continues
+with an open bracket, |[|%]
+), all is well.  But when the optional argument is absent, the peek-ahead will
+tokenize the following character, which presents a problem when no more
+arguments are present in the input stream, like in the example below, where the
+verbatim \docref{xparse:o} is the (only and) final type in the argument
+specification.  In this case, the peek-ahead ``incorrectly'' assigns category
+code 12 (``other'') to the first |$|.  %$
+This character was intended to be tokenized as the math shift character of
+category 3, to start the math mode after \refcmd{CollectArguments} is finished,
+but having been assigned category code 12, it cannot perform this function,
+resulting in error |! Missing $ inserted| %$
+once \hologo{TeX} encounters the superscript character |^|.
+
+\ExampleName{collargs-transition-ok}
+\makeexample{\examplename.tex.c1}
+\tcbinputexample{sidebyside, lefthand ratio=0.6,
+  comment=\input{\examplepath.tex.c1}}
+
+Well --- this is what \emph{would} happen if CollArgs didn't address the
+transition issue described above.  In fact, the above example compiles just
+fine, because CollArgs \emph{does} address this issue, but unfortunately,
+certain transition problems simply cannot be resolved --- read on to learn what
+can go wrong.
+
+For example, you can typeset the name of the document author via
+\hologo{LaTeX}'s internal command |\@author|, but to use this command in the
+document, you have to precede it by |\makeatletter|.  As shown by the first
+line of the example below, this works rather nicely: |\makeatletter| sets the
+category code of |@| to 11 (``letter''), so |@| may help form the control word
+|\@author| --- importantly, |\makeatletter| sets the category code of |@|
+\emph{before} control sequence |\@author| is constructed, even if it precedes
+it immediately.
+
+\ExampleName{collargs-transition-cs}
+\makeexample{\examplename.tex.c1}
+\long\def\ShowArgs#1{Collected: ``{\color{red}\tt\detokenize{#1}}''}
+\tcbinputexample{comment=\input{\examplepath.tex.c1}}
+
+In the second line of the example, our clever invocation of |\@author| is
+immediately preceded by a call to \refcmd{CollectArguments}, which tries to
+collect a verbatim argument of type \docref{xparse:o}.  It doesn't find it, which results in
+the wrong, verbatim tokenization of the escape character of |\makeletter|.
+CollArgs realizes the problem and tries to fix it.  But while it is searching
+for the end of control sequence |\makeletter| (which it successfully
+constructs), it triggers the tokenization of what follows --- which, as |@| is
+at that point of category 12 (``other''), yields the control symbol |\@| (later
+followed by word ``author'', typeset in the example).
+
+In short, the solution has created another, delayed instance of the problem ---
+an instance which cannot be addressed any further.  But we're nevertheless
+better off, as this particular issue will bite only in the case when the
+``corrupted'' control sequence immediately following the invocation
+\refcmd{CollectArguments} changes category codes in a way that affects the
+tokenization of what immediately follows it.
+
+This was an example of what can go wrong in the transition from the
+\meta{argument tokens} to the \meta{rest} of the tokens following an invocation
+of \refcmd{CollectArguments}.  As the ``outside world'' is non-verbatim, this
+transition can only be problematic if the argument which corrupted the first of
+the \meta{rest} tokens was verbatim, so if the transition was from the verbatim
+to the non-verbatim mode.  Such a transition can also occur within the
+\meta{argument tokens}, but the good news here is that CollArgs successfully
+solves any problems that occur there, so you should only worry about the
+end-of-arguments situation.
+
+The other direction of the transition, from the non-verbatim to the verbatim
+mode, however, can affect both the internal and the external transitions.  Let
+us illustrate the problem with the internal transition.  Say you want to
+collect an optional argument (\docref{xparse:o}) in the non-verbatim mode, and
+then a mandatory argument (\docref{xparse:m}) in (either full or partial)
+verbatim mode.  In the first invocation of \refcmd{CollectArguments} below, the
+optional argument is present, and we get what we expect: the percent sign is
+collected, verbatim, into the mandatory argument.  In the second invocation,
+however, the percent character retains its usual commenting function ---
+despite the fact that we have requested verbatim mode for the mandatory
+argument --- which results in the group in the second line being picked up as
+the mandatory argument.  Again, this happens because CollArgs has to peek ahead
+in the input stream when determining whether the optional argument is present.
+Having requested non-verbatim mode for the optional argument, the peeking is
+performed in the non-verbatim mode, and as the optional argument is not
+present, it finds the comment character, which fulfills its regular function of
+disappearing along with the rest of the line.  Once CollArgs sets to find the
+(verbatim) mandatory argument, the rest of the line is already gone, so it
+searches for, and finds, this argument in the next line.
+
+\ExampleName{collargs-transition-comment}
+\makeexample{\examplename.tex.c1}
+\long\def\ShowArgs#1{Collected: ``{\color{red}\tt\detokenize{#1}}''}
+\tcbinputexample{listing and text}
+
+Nothing can be done here --- commenting deletes information, irrevocably ---
+and in a similar fashion, nothing can be done to catch a verbatim end-of-line
+character when preceded by an absent optional argument in the non-verbatim mode
+(because it was already tokenized into a space token).
+
+Finally, the transition issues are not limited to transits from argument type
+\docref{xparse:o}.  The full list of argument types which give rise to
+transition problems (when transiting \emph{from} arguments of these types) is
+as follows: \docref{xparse:o}, \docref{xparse:d}, \docref{xparse:s},
+\docref{xparse:t}, \docref{xparse:g}, \docref{xparse:e}.
+
+
+\endgroup % /collargs
+
+
+\section{Varia}
+
+\subsectionclearpagefalse
+
+\subsection{Known issues}
+\label{sec:known-issues}
+
+\paragraph*{Bitmap graphics export} is coming up in the next release of the
+package.
+
+
+\paragraph{Disappearing errors}
+If a non-fatal internal \hologo{TeX} error occurs during memoization, the memos
+and externs may be nevertheless produced and utilized in subsequent
+compilations.  In such a case, the erroneous code won't be compiled again, and
+therefore won't yield any errors, giving the mistaken impression that the code
+is error-free.
+
+This problem does not apply to errors which trigger \refcmd{errmessage},
+because that control sequence is advised by \refmmzauto{abort}.
+Note that internal \hologo{TeX} errors like |Undefined control sequence| are
+\emph{not} reported through \refcmd{errmessage}, and will therefore cause the
+issue.
+
+This problem does not affect \hologo{LuaTeX}, because this engine allows
+Memoize to detect errors and abort memoization if it encounters any.
+
+
+\paragraph{A minimal issue with \hologo{XeLaTeX}}
+If the very first page of a document of class |minimal|, compiled by
+\hologo{XeLaTeX}, happens to be an extern page, we have a problem: all the
+regular pages of the document will be of the same size as that extern page.
+\hologo{pdfLaTeX} and \hologo{LuaLaTeX} do not exhibit this behaviour, nor do
+\hologo{LaTeX} classes other than |minimal|, even when compiled with
+\hologo{XeLaTeX}.
+
+
+\paragraph{CollArgs}
+
+Due to an unfortunate design decision, CollArgs does not accept a dot |.| as
+the \meta{token} argument of types, \docref{xparse:r}, \docref{xparse:R},
+\docref{xparse:d}, \docref{xparse:D}, and \docref{xparse:t}.  Furthermore,
+\refcollargs{append prewrap} and friends (and their macro counterparts) do not
+accept a parameter symbol consistently.  These issues will be fixed in the next
+release.
+
+
+\subsection{Troubleshooting}
+\label{sec:troubleshooting}
+
+\paragraph{Extern extraction does not work}
+\label{sec:fadings-problem}
+\label{sec:loading-order}
+
+If the internal extern extraction does not work, you should have gotten one of
+the following warnings:
+\begin{enumerate}
+\item \code{Package memoize Warning: Extraction of externs from document
+    "\meta{jobname}.pdf" using method "perl" was unsuccessful. Have you set the
+    shell escape mode as suggested in chapter 1 of the manual?}
+  
+  This warning is thrown when the extraction log \meta{jobname}|.mmz.log|,
+  which should be produced by the extraction script, is incomplete, i.e.\ it
+  does not finish by |\endinput|.\footnote{The extraction log will never be
+    absent, because Memoize clears it before executing the extraction script
+    --- and clearing it creates it if it doesn't exist.}  The most likely
+  reason is that the script was not executed at all, so the question asked in
+  the warning message is pertinent.  However, if all is well with the
+  shell-mode, you have a mystery at your hands.  To gather information, I
+  suggest inspecting:
+  \begin{itemize}
+  \item \meta{jobname}|.log| --- search for \code{runsystem(memoize-extract.pl
+      ...)}, it will tell you whether the script was executed;
+  \item the terminal output --- if the script was executed, it should've
+    announced itself by \code{Extracting externs from \meta{jobname}.pdf}; are
+    there any further messages between this header and the warning message?
+  \item \meta{the path to the extern}|.log|, if you are using the
+    \hologo{TeX}-based extraction (\code{\refmmz{extract}=\refmmz{extract=tex}}).
+  \end{itemize}
+  \hologo{TeX}-based extraction will yield this error even in the case of a
+  missing or corrupted PDF, i.e.\ in
+  case~\ref{item:warning:extract:cannot-read} below.
+
+\item\label{item:warning:extract:cannot-read}
+  \code{Package memoize (perl-based extraction) Warning: Cannot read file
+    "\meta{jobname}.pdf". Perhaps you have to load Memoize earlier in the
+    preamble?}
+
+  Embedded extern extraction requires an intact document PDF from the previous
+  compilation, so Memoize must be loaded before the document PDF is opened for
+  writing the results of the ongoing compilation.  In particular, the PDF is
+  opened by \PGF library |fadings|, included by \TikZ's libraries |fadings|
+  and |shadows|, so Memoize must be loaded before any of these libraries.
+
+  With \pkg{beamer}, the problem is particularly acute because the PDF is
+  opened while loading the class.  In this case, simply moving
+  |\usepackage{memoize}| up the preamble, as suggested, won't help: you have to
+  write |\RequirePackage{memoize}| \emph{before} |\documentclass{beamer}|!
+
+\item\label{item:warning:extract:unexpected-size} \code{Package memoize
+    (perl-based extraction) Warning: I refuse to extract page $n$ from
+    "\meta{jobname}.pdf", because its size ($\meta{width}\times\meta{height}$)
+    is not what I expected\\ ($\meta{expected width}\times\meta{expected
+      height}$)}
+
+  If the compilation which produced the offending extern pages yielded any
+  errors, you should probably disregard this warning, fix the errors, and
+  compile again.  Otherwise, you have somehow winded up with mismatched
+  \meta{jobname}|.pdf| and \meta{jobname}\dmmz (the latter file contains
+  instructions on which pages to extract, complete with the expected
+  dimensions).  Are you sure that they were produced by the same compilation,
+  and have remained untouched since?  Are you perhaps trying to perform the
+  extraction the second time, after the first extraction
+  \refscript{memoize-extract.pl--prune}d the PDF?
+
+  If the warning stubbornly persists, but you are sure that the page the script
+  is refusing to extract is correct, you can force the extraction by adding
+  option \refscript{memoize-extract.pl--force} to the script invocation, which
+  can be set by \refmmz{perl extraction options}.  However, as such a situation
+  probably indicates a bug in Memoize, please let me know about it.
+\item\code{\myfontexpansionon Invalid dictionary key at
+    /.../perl5/site\_perl/PDF/API2/Basic/PDF/File.pm line $N$\myfontexpansionoff}
+
+  This can sometimes happen when extracting with the Perl-based script.  The
+  issue might be related to PDF version --- by default, \hologo{TeX} produces
+  PDFs of version 1.5, while the PDF library
+  \hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2} officially only
+  supports versions up to 1.4 --- but I'm afraid I haven't identified the exact
+  circumstances yet.  Possibly, the externalizing a picture containing an
+  embedded PDF file might be the culprit.  The workaround is to use Python- or
+  \hologo{TeX}-based extraction, i.e.\ load Memoize with package option
+  \refmmz{extract}|=|\refmmz{extract=python} or
+  \refmmz{extract}|=|\refmmz{extract=tex}.
+\end{enumerate}
+
+The failure to extract externs intentionally doesn't result in an error,
+because what if you deleted the document PDF on purpose?  At any rate, the
+compilation will succeed, it's just that as Memoize cannot extract the externs,
+they will be produced, and dumped into your document, at each and every
+compilation.
+
+\paragraph{An extern won't be included}
+
+Did you receive a warning or error message?
+\begin{enumerate}
+\item \code{Package memoize Warning: Unexpected size of extern "\meta{extern
+      path}.pdf"; expected\\ $\meta{expected width}\times\meta{expected
+      height}$, got $\meta{width}\times\meta{height}$}
+
+  This warning is related to warning~\ref{item:warning:extract:unexpected-size}
+  above, only that it occurs once the extern is extracted.  The same
+  investigative methods apply.
+\item \code{!pdfTeX error: pdflatex (file \meta{extern path}.pdf): reading
+    image file failed}
+
+  This is a fatal error.  The extern file got corrupted, somehow ---
+  inexistent, or even empty, extern files merely trigger recompilation.
+\end{enumerate}
+
+If there was no warning or error --- are you certain that Memoize is
+\refmmz{enable}d, and that it is not in the \refmmz{recompile} mode?  Remember
+that these settings can also apply only to a part of the document; search for
+any stray \refcmd{mmzset} or \refcmd{mmznext} commands.
+
+
+\paragraph*{Warnings about duplicate labels, indices, etc.} may be safely
+disregarded.
+
+Externalization causes any (non-immediate) |\write| commands in the extern to
+be executed twice, once upon the shipout of the regular page, and once upon the
+shipout of the extern page.  This results in warnings about doubly defined
+labels, hyperreferences, indices, etc.  For example, you might get
+\texttt{LaTeX Warning: Label `<name>' multiply defined} or \texttt{warning (pdf
+  backend): ignoring duplicate destination with the name '<name>'}.  You can
+safely disregard these warnings; they will disappear once the extern is
+utilized.
+
+
+\paragraph{Memoization was aborted}
+
+This warning means that either:
+\begin{itemize}
+\item you are trying to (auto)memoize a \refenv{tikzpicture} with
+  \refkey{/tikz/remember picture} set, or more generally, some code which
+  contains \refcmd{savepos} --- this can't be done, see
+  section~\ref{sec:tut:good-to-know}; or
+\item an error occurred during memoization --- in this case, Memoize cowardly
+  refuses to proceed with memoization, see section~\ref{sec:known-issues} for
+  details.
+\end{itemize}
+
+
+\subsection{License}
+
+Copyright \textcopyright\ 2020- Sašo Živanović.
+
+This work may be distributed and/or modified under the conditions of the
+\hologo{LaTeX} Project Public License, either version 1.3c of this license or
+(at your option) any later version.  The latest version of this license is
+in \url{https://www.latex-project.org/lppl.txt} and version 1.3 or later is
+part of all distributions of \hologo{LaTeX} version 2008 or later.
+
+This work comprises of the sources, generated files, accompanying scripts,
+auxiliary files and scripts, documentation, documentation sources, examples and
+example sources of packages |memoize|, |nomemoize|, |memoizable|, |auto| and
+|collargs|.  The files belonging to this work and covered by LPPL are listed in
+\meta{texmf}|/doc/generic/memoize/FILES|.
+
+This work has the LPPL maintenance status `maintained.' The Current Maintainer
+of this work is Sašo Živanović.  The work is available on CTAN
+at \url{https://ctan.org/pkg/memoize} and on GitHub
+at \url{https://github.com/sasozivanovic/memoize}.
+
+
+\subsection{Changelog}
+
+\newcommand\githubrelease[2]{%
+  \href{https://github.com/sasozivanovic/memoize/releases/tag/#2}{#1 #2}%
+}
+\begin{description}
+\item[\githubrelease{2020/07/17}{v0.1}]
+  The proof-of-concept, available only at GitHub.
+\item[\githubrelease{2023/10/10}{v1.0.0}]
+  A complete, fully documented reimplementation.
+\end{description}
+
+\subsection{Acknowledgments}
+
+First and foremost, my gratitude goes to Stefan Müller of Language Science
+Press for his encouragement and patience --- without him, this package might've
+remained an idea forever!
+
+But there were others as well.  Shunsaku Hirata of the \hologo{XeTeX} team
+promptly resolved an issue with forward references in |xdvipdfmx|, and thereby
+made Memoize work with \hologo{XeTeX}.  Joseph Wright kindly didn't object to
+me misappropriating \pkg{etoolbox} for other formats.  Petra Rübe-Pugliese
+(CTAN) and Karl Berry (\hologo{TeX}Live) offered good advice on packaging the
+package; I would never get to call Advice Advice without their advice.  Karl
+also performed a security review of the extraction scripts, providing some very
+useful comments along the way, and agreed to include the scripts among the
+shell escape commands allowed in \hologo{TeX}Live.
+
+Thank you all!
+
+
+\printindex
+
+\end{document}
+
+
+% Local Variables:
+% TeX-engine: luatex
+% TeX-master: t
+% End:


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/memoize.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/generic/memoize/yadoc.sty
===================================================================
--- trunk/Master/texmf-dist/doc/generic/memoize/yadoc.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/generic/memoize/yadoc.sty	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,491 @@
+%% yadoc.sty
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%% 
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+
+\RequirePackage{tcolorbox}
+%\tcbuselibrary{listings,documentation,xparse,raster,hooks,breakable}
+\tcbuselibrary{raster,skins}
+
+\RequirePackage{etoolbox}
+
+\newif\ifyadoc at into@index
+\newif\ifyadoc at index@gather
+\newif\ifyadoc at index@colorize at names
+\newif\ifyadoc at ref@page
+\newif\ifyadoc at show@keypath
+
+\newcommand\yadocset[1]{\pgfqkeys{/yadoc}{#1}\ignorespaces}
+
+\yadocset{
+  cmd item/.style={
+    name prefix=\textbackslash,
+    label prefix=cmd,
+  },
+  key item/.style={
+    name prefix={\ifdefempty{\yadoc at keypath}{}{%
+        \ifyadoc at show@keypath
+          \textcolor
+          {\yadoc at name@color!\yadoc at keypath@color at opacity}%
+          {\yadoc at keypath/}%
+        \fi
+      }%
+    },
+    ref prefix={\protect\ifyadoc at show@keypath\yadoc at keypath/\protect\fi},
+    index prefix=,
+    parameters prefix={\texttt{=}},
+    label prefix:=key:\yadoc at keypath@label/,
+    index annotation={key\ifdefempty{\yadoc at keypath}{}{ in \texttt{\yadoc at keypath}}},
+  },
+  env item/.style={
+    head prefix={\texttt{\cs{begin}\{}},
+    head infix={\}},
+    head suffix={%
+      \par\strut{\ttfamily\nobreakspace\nobreakspace}\meta{environment body}%
+      \par\strut\texttt{\cs{end}\{\yadoc at do@name\}}},
+    index annotation=environment,
+    label prefix=env,
+  },
+  register item/.style={
+    name prefix=\textbackslash,
+    label prefix=reg,
+    index annotation=register,
+  },
+  file item/.style={
+    index annotation=file,
+    label prefix=file,
+  },
+  value item/.style={
+    index annotation={value of
+      {\docref[show keypath,into index=false,link color=gray]{\yadoc at of}}},
+    label prefix:={\yadoc at of=},
+  },
+  scope/.code={%
+    \begingroup
+    \pgfkeysalso{#1}%
+    \endgroup
+  },
+  generic item/.style={
+    label prefix:=,
+  },
+  %
+  raster options/.style={},
+  before body/.store in=\yadoc at before@body,
+  after body/.store in=\yadoc at after@body,
+  left/.dimstore in=\yadoc at left,
+  right/.dimstore in=\yadoc at right,
+  left indent/.dimstore in=\kvtcb at doc@indentleft,
+  right indent/.dimstore in=\kvtcb at doc@indentright,
+  name/.store in=\yadoc at name,
+  name/.append style={label={#1}, index={#1}, sort index={#1}},
+  parameters/.store in=\yadoc at parameters,
+  description/.store in=\yadoc at description,
+  label/.store in=\yadoc at label,
+  label prefix:/.store in=\yadoc at label@prefix,
+  label prefix/.style={label prefix:={#1:}},
+  name font/.store in=\yadoc at name@font,
+  name color/.store in=\yadoc at name@color,
+  name prefix/.store in=\yadoc at name@prefix,
+  name suffix/.store in=\yadoc at name@suffix,
+  name prefix/.append style={index prefix={#1}, ref prefix={#1}},
+  name suffix/.append style={index suffix={#1}, ref suffix={#1}},
+  parameters font/.store in=\yadoc at parameters@font,
+  parameters prefix/.store in=\yadoc at parameters@prefix,
+  parameters suffix/.store in=\yadoc at parameters@suffix,
+  keypath/.store in=\yadoc at keypath,
+  keypath label/.store in=\yadoc at keypath@label,
+  keypath/.append style={keypath label={#1}},
+  keypath color opacity/.store in=\yadoc at keypath@color at opacity,
+  show keypath/.is if=yadoc at show@keypath,
+  index/.store in=\yadoc at index,
+  index prefix/.store in=\yadoc at index@prefix,
+  index suffix/.store in=\yadoc at index@suffix,
+  index annotation/.initial=,
+  index font/.store in=\yadoc at index@font,
+  index annotation font/.store in=\yadoc at index@annotation at font,
+  sort index/.store in=\yadoc at sort@index,
+  index colorize names/.is if=yadoc at index@colorize at names,
+  index page number format/.store in=\yadoc at index@page at number@format,
+  index gather/.is if=yadoc at index@gather,
+  index command/.store in=\yadoc at index@command,
+  index actual/.store in=\yadoc at index@actual,
+  index quote/.store in=\yadoc at index@quote,
+  index level/.store in=\yadoc at index@level,
+  index encapsulator/.store in=\yadoc at index@encapsulator,
+  see/.initial=,
+  ref font/.store in=\yadoc at ref@font,
+  ref prefix/.store in=\yadoc at ref@prefix,
+  ref suffix/.store in=\yadoc at ref@suffix,
+  head prefix/.store in=\yadoc at head@prefix,
+  head infix/.store in=\yadoc at head@infix,
+  head suffix/.store in=\yadoc at head@suffix,
+  phrases/.code={\pgfqkeys{/yadoc/phrases}{#1}},
+  phrases/.unknown/.code={\csdef{yadoc at phrases@\pgfkeyscurrentname}{#1}},
+  ref page/.is if=yadoc at ref@page,
+  of/.store in=\yadoc at of,  
+  link color/.code={\hypercolor{link}{#1}},
+  long description/.style={% for do/def
+    head/.append style={
+      sidebyside gap=1em,
+      lefthand ratio=#1,
+    },
+  },
+  long description/.default=0.6,
+  %
+  .unknown/.code={%
+    \pgfkeysifdefined{/yadoc/\pgfkeyscurrentname\space item/. at cmd}{%
+      \begingroup
+      \expandafter\pgfkeysalso\expandafter{%
+        \pgfkeyscurrentname\space item,
+        before,#1,after,
+        do
+      }%
+      \endgroup
+    }{%
+      \PackageError{yadoc}{Unknown item "\pgfkeyscurrentname"}%
+      {Perhaps you have misspelled an option name?}%
+    }%
+  },
+  before/.code={},
+  after/.code={},
+  do/.is choice,
+  ref options/.style={
+    show keypath=false,
+  },
+  def options/.style={
+    show keypath,
+  },
+  aux options/.style={
+    show keypath=false,
+  },
+  foreign options/.style={
+    show keypath=false,
+    cmd item/.append style={index annotation=command},
+  },
+  index options/.code=,
+  into index/.is if=yadoc at into@index,
+  print/.is if=yadoc at printref,
+}
+
+\NewDocumentEnvironment{doc}{O{}m}{%
+  \begin{list}{}{%
+      \setlength{\leftmargin}{\yadoc at left}%
+      \setlength{\itemindent}{0pt}%
+      \setlength{\itemsep}{0pt}%
+      \setlength{\parsep}{0pt}%
+      \setlength{\rightmargin}{\yadoc at right}%
+    }%
+  \item
+    \begin{tcboxedraster}[
+        raster columns=1,
+        raster row skip=0pt,
+        raster before skip=0pt,
+        raster after skip=0pt,
+        raster force size=false,
+        /yadoc/raster options
+      ]{blankest,
+        before skip=1\baselineskip plus 6\baselineskip minus .5\baselineskip,
+        after skip=0pt plus 2pt minus .5\baselineskip,%
+        #1%
+      }%
+      \yadocset{do/.default=def,def options,#2}%
+    \end{tcboxedraster}
+    \nopagebreak
+    \yadoc at before@body\relax
+    \nopagebreak
+    \ignorespaces
+}{%
+    \ifvmode\else\unskip\fi
+    \yadoc at after@body\relax
+  \end{list}%
+}
+
+\newcommand\docaux[2]{%
+  \begingroup
+  \yadocset{do/.default=aux,aux options,#1={name={#2}}}%
+  \endgroup
+}
+
+\newcommand\docAux[1]{%
+  \begingroup
+  \yadocset{do/.default=aux,aux options,#1}%
+  \endgroup
+}
+
+\newcommand\docForeign[1]{%
+  \begingroup
+  \yadoc at hyperreffalse
+  \yadocset{do/.default=foreign,foreign options,#1}%
+  \endgroup
+}
+
+\newcommand\docindex[1]{%
+  \begingroup
+  \yadoc at hyperreffalse
+  \yadocset{do/.default=index,index options,#1}%
+  \endgroup
+}
+
+\yadocset{
+  do/def/.code={%
+    \begin{tcolorbox}[%
+        blank,
+        colback=white, colframe=white,
+        code={%
+          \tcbdimto\tcb at temp@grow at left{\yadoc at left}%
+          \tcbdimto\tcb at temp@grow at right{\yadoc at right}%
+        },
+        grow to left by=\tcb at temp@grow at left,
+        grow to right by=\tcb at temp@grow at right,
+        sidebyside, sidebyside align=top, sidebyside gap=-\tcb at w@upper at real,
+        force nobeforeafter,
+        phantom=\phantomsection,
+        /yadoc/head,
+      ]%
+      \yadoc at head@prefix
+      \yadoc at do@name
+      \yadoc at do@index
+      \yadoc at do@label
+      \yadoc at head@infix
+      \yadoc at do@parameters
+      \yadoc at head@suffix
+      \yadoc at do@description
+    \end{tcolorbox}
+    \nopagebreak
+  },
+  do/aux/.code={%
+    \yadoc at do@name
+    \yadoc at do@index
+    \yadoc at do@label  
+  },
+  do/foreign/.code={%
+    \yadoc at do@label
+  },
+  do/index/.code={%
+    \yadoc at do@label
+    \yadoc at do@index
+  },
+}
+
+\def\yadoc at do@name{%
+  \begingroup
+  \yadoc at name@colorize{%
+    \yadoc at name@font
+    \strut\yadoc at name@prefix\yadoc at name\yadoc at name@suffix\strut
+  }%
+  \endgroup
+}
+
+\def\yadoc at do@index{%
+  \ifyadoc at into@index
+    \yadoc at index@command{%
+      \yadoc at sort@index
+      \yadoc at index@actual
+      \yadoc at format@index
+    }%
+    \ifyadoc at index@gather
+      \yadoc at index@command{%
+        \yadoc at phrases@Commands
+        \yadoc at index@level
+        \yadoc at sort@index
+        \yadoc at index@actual
+        \yadoc at format@index
+      }%
+    \fi
+  \fi
+}
+
+\def\yadoc at name@colorize{%
+  \ifdefempty\yadoc at name@color{}{%
+    \textcolor{\yadoc at name@color}%
+  }%
+}
+
+\def\yadoc at format@index{%
+  {%
+    \ifyadoc at index@colorize at names\yadoc at name@colorize\fi
+    \yadoc at index@font
+    \yadoc at index@prefix\yadoc at index\yadoc at index@suffix
+  }%
+  {%
+    \ifkeyempty{/yadoc/index annotation}{}{%
+      \space\yadoc at index@annotation at font\pgfkeysvalueof{/yadoc/index annotation}%
+    }%
+  }%
+  \ifdefempty\yadoc at index@page at number@format{}{%
+    \yadoc at index@encapsulator
+    \yadoc at index@page at number@format
+  }%
+  \ifkeyempty{/yadoc/see}{}{%
+    \yadoc at index@encapsulator
+    see{\pgfkeysvalueof{/yadoc/see}}%
+  }%
+}
+
+\def\yadoc at do@label{%
+  \ifdefempty{\yadoc at label}{}{%
+    \begingroup
+    \yadocset{ref options}%
+    \protected at edef\@currentlabel{%
+      \protect\ifyadoc at setupref
+        \ifyadoc at hyperref
+          \protect\yadoc at hyperreftrue
+        \else
+          \protect\yadoc at hyperreffalse
+        \fi
+      \protect\fi
+      \protect\ifyadoc at printref
+        \yadoc at ref@font
+        \yadoc at ref@prefix\yadoc at name\yadoc at ref@suffix
+      \protect\fi
+      \protect\ifyadoc at into@index
+        \yadoc at do@index
+      \protect\fi
+    }%
+    \label{\yadoc at label@prefix\yadoc at label}%
+    \endgroup
+  }%
+}
+
+\def\yadoc at do@parameters{%
+  \ifdefempty\yadoc at parameters{}{%
+    \begingroup
+    \yadoc at parameters@font
+    \yadoc at parameters@prefix\yadoc at parameters\yadoc at parameters@suffix
+    \endgroup
+  }%
+}
+
+\def\yadoc at do@description{%
+  \ifdefempty{\yadoc at description}{}{%
+    \tcblower
+    \raggedleft
+    \strut
+    (\yadoc at description)%
+    \strut
+  }%
+}
+
+% ref
+
+\newif\ifyadoc at setupref
+\newif\ifyadoc at printref
+\newif\ifyadoc at hyperref
+\yadoc at printreftrue
+\yadoc at hyperreftrue
+\DeclareRobustCommand\docref[2][]{%
+  \quitvmode % otherwise, extra vertical space if this begins an \item !?!
+  \begingroup
+  \yadocset{ref options,#1}%
+  \ifcsname r@#2\endcsname
+    \expanded{%
+      \noexpand\yadoc at setupreftrue
+      \ifyadoc at printref\noexpand\yadoc at printreffalse\fi
+      \ifyadoc at into@index\noexpand\yadoc at into@indexfalse\fi
+      \ifmemoize\noexpand\memoizefalse\fi
+      \ref*{#2}%
+      \noexpand\yadoc at setupreffalse
+      \ifyadoc at printref\noexpand\yadoc at printreftrue\fi
+      \ifyadoc at into@index\noexpand\yadoc at into@indextrue\fi
+      \ifmemoize\noexpand\memoizetrue\fi
+    }%
+  \fi
+  \ifyadoc at printref\else\yadoc at hyperreffalse\fi
+  \ifyadoc at hyperref
+    \ifnum\getpagerefnumber{#2}=\thepage\relax
+      \yadoc at into@indexfalse
+    \fi
+    \hyperref[#2]{%
+      \ref*{#2}%
+      \ifyadoc at printref
+        \ifyadoc at ref@page\yadoc at ref@pagenumber{#2}\fi
+      \fi
+    }%
+  \else
+    \ref*{#2}%
+    \ifyadoc at printref
+      \ifyadoc at ref@page\yadoc at ref@pagenumber{#2}\fi
+    \fi
+  \fi
+  \endgroup
+}
+\def\yadoc at ref@pagenumber#1{%
+  \ifnum\getpagerefnumber{#1}=\thepage\relax
+  \else%
+    \textsuperscript{%
+      {\fontfamily{pzd}\fontencoding{U}\fontseries{m}\fontshape{n}%
+        \selectfont\char213}%
+      \,\yadoc at phrases@pageshort\,\pageref*{#1}}%
+  \fi
+}
+
+
+\yadocset{
+  before body=,
+  after body=,
+  left=2em,
+  right=0pt,
+  left indent=-2em,
+  right indent=0pt,
+  name=,
+  name font=\ttfamily\bfseries,
+  index font=\ttfamily,
+  ref font=\ttfamily,
+  index annotation font=,
+  name color=black,
+  name prefix=,
+  name suffix=,
+  label=,
+  label prefix=,
+  parameters=,
+  parameters font=,
+  parameters prefix=,
+  parameters suffix=,
+  keypath=,
+  keypath color opacity=30,
+  description=,
+  into index=true,
+  index colorize names=false,
+  index page number format=,
+  index command=\index,
+  index gather=false,
+  index actual={@},
+  index quote={"},
+  index level={!},
+  index encapsulator={|},
+  head prefix=,
+  head infix=,
+  head suffix=,
+  ref page=false,
+  phrases={
+    index=Index,
+    pageshort=P.,
+    Commands=Commands,
+  },
+  text/.code={#1},
+  comma/.code={,\ },
+  and/.code={\ and\ },
+}
+
+\def\ifkeyempty#1{\ifcsempty{pgfk@#1}}
+
+\AddToHook{begindocument}{%
+  \robustify\index
+  \robustify\hypersetup
+}


Property changes on: trunk/Master/texmf-dist/doc/generic/memoize/yadoc.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-clean.1	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-clean.1	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,72 @@
+.\" Automatically generated by Pandoc 3.0.1
+.\"
+.\" Define V font for inline verbatim, using C font in formats
+.\" that render this, and otherwise B font.
+.ie "\f[CB]x\f[]"x" \{\
+. ftr V B
+. ftr VI BI
+. ftr VB B
+. ftr VBI BI
+.\}
+.el \{\
+. ftr V CR
+. ftr VI CI
+. ftr VB CB
+. ftr VBI CBI
+.\}
+.TH "memoize-clean" "1" "October 10, 2023" "memoize-clean of Memoize v1.0.0" "User Manual"
+.nh
+.SH NAME
+.PP
+memoize-clean.pl, memoize-clean.py - Remove (stale) memo and extern
+files
+.SH SYNOPSIS
+.PP
+\f[B]memoize-clean.pl\f[R] [\f[I]OPTIONS\f[R]] [\f[I]document1.mmz\f[R]
+\&...]
+.PP
+\f[B]memoize-clean.py\f[R] [\f[I]OPTIONS\f[R]] [\f[I]document1.mmz\f[R]
+\&...]
+.SH DESCRIPTION
+.PP
+\f[B]memoize-clean\f[R] is a script accompanying Memoize, a TeX package
+which allows the author to reuse the results of compilation-intensive
+code such as TikZ pictures.
+.PP
+By default, this script removes stale memo and extern files.
+A stale memo or extern is an extern produced during a compilation of a
+previous version of the document which was neither used nor produced
+during the last compilation of the document.
+Typically, stale files arise when we change the memoized code (or its
+context).
+.PP
+\f[B]memoize-clean.pl\f[R] removes all memo and extern files with
+prefixes mentioned in the listed \f[B].mmz\f[R] files and by options
+\f[B]--prefix\f[R] which are not explicitly mentioned in the
+\f[B].mmz\f[R] files.
+.PP
+Before deleting anything, \f[B]memoize-clean.pl\f[R] lists all the files
+it would delete and asks for confirmation.
+.SH OPTIONS
+.TP
+\f[B]-p, --prefix\f[R]
+Add a memo/extern prefix for cleaning.
+This option may be given multiple times.
+.TP
+\f[B]-a, --all\f[R]
+Remove all memos and externs, rather than only the stale ones.
+.TP
+\f[B]-y, --yes\f[R]
+Do not ask for confirmation.
+.TP
+\f[B]-q, --quiet\f[R]
+Don\[cq]t describe what\[cq]s happening.
+.TP
+\f[B]-h, --help\f[R]
+Show help.
+.TP
+\f[B]-V, --version\f[R]
+Show the Memoize version number and exit.
+.SH SEE ALSO
+.PP
+Memoize manual (https://ctan.org/pkg/memoize), section 6.6.3.


Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.man1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.man1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-clean.man1.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-clean.man1.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.man1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.1	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.1	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+.so man1/doc/memoize-clean.1


Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.man1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.man1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.man1.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.man1.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.pl.man1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.1	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.1	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+.so man1/doc/memoize-clean.1


Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.man1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.man1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.man1.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.man1.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-clean.py.man1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-extract.1	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-extract.1	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,111 @@
+.\" Automatically generated by Pandoc 3.0.1
+.\"
+.\" Define V font for inline verbatim, using C font in formats
+.\" that render this, and otherwise B font.
+.ie "\f[CB]x\f[]"x" \{\
+. ftr V B
+. ftr VI BI
+. ftr VB B
+. ftr VBI BI
+.\}
+.el \{\
+. ftr V CR
+. ftr VI CI
+. ftr VB CB
+. ftr VBI CBI
+.\}
+.TH "memoize-extract" "1" "October 10, 2023" "memoize-extract of Memoize v1.0.0" "User Manual"
+.nh
+.SH NAME
+.PP
+memoize-extract.pl, memoize-extract.py - Extract extern pages out of the
+PDF
+.SH SYNOPSIS
+.PP
+\f[B]memoize-extract.pl\f[R] [\f[I]OPTIONS\f[R]] \f[I]document.mmz\f[R]
+.PP
+\f[B]memoize-extract.py\f[R] [\f[I]OPTIONS\f[R]] \f[I]document.mmz\f[R]
+.SH DESCRIPTION
+.PP
+\f[B]memoize-extract\f[R] is a script accompanying Memoize, a TeX
+package which allows the author to reuse the results of
+compilation-intensive code such as TikZ pictures.
+.PP
+Memoize dumps the created externs (boxes containing the typeset material
+to be reused) onto their own pages in the produced PDF file.
+It is the job of \f[B]memoize-extract\f[R] to extract these extern pages
+into separate PDF files.
+At subsequent compilations, Memoize will include those extern files into
+the document, without compiling their source again.
+.PP
+Memoize communicates with \f[B]memoize-extract\f[R] through file
+\f[I]document.mmz\f[R].
+When \f[I]document.tex\f[R] is compiled to produce
+\f[I]document.pdf\f[R], Memoize produces \f[I]document.mmz\f[R], which
+records which pages in the produced document are extern pages and to
+which extern files they should be extracted.
+Therefore, after compiling \f[I]document.tex\f[R], the externs should be
+extracted by \f[B]memoize-extract\f[R] \f[I]document.mmz\f[R].
+.PP
+\f[I]document.mmz\f[R] also records the expected width and height of
+each extern.
+In case of a mismatch, \f[B]memoize-extract\f[R] refuses to extract the
+page and removes the extern file if it already exist, and prints a
+warning message to the standard error.
+The script furthermore refuses to extract the page if a (c)c-memo
+associated to the extern does not exist, and to write to any file whose
+absolute path does not occur under the current directory or the
+directory set by TEXMFOUTPUT (in \f[I]texmf.cnf\f[R] or as an
+environment variable); TEXMFOUTPUT is also not allowed to point to the
+root directory, except on Windows, where it can only point to a drive
+root.
+.PP
+The Perl (.pl) and the Python (.py) version of the script are
+functionally equivalent.
+The Perl script requires library
+PDF::API2 (https://metacpan.org/pod/PDF::API2), and the Python script
+requires library pdfrw2 (https://pypi.org/project/pdfrw2).
+.SH OPTIONS
+.TP
+\f[B]-P, --pdf\f[R] \f[I]filename.pdf\f[R]
+The externs will be extracted from \f[I]filename.pdf\f[R].
+By default, they are extracted from \f[I]document.pdf\f[R].
+.TP
+\f[B]-p, --prune\f[R]
+Remove the extern pages from the PDF after extraction.
+.TP
+\f[B]-k, --keep\f[R]
+Do not modify the \f[I]document.mmz\f[R] to mark the externs as
+extracted.
+By default, they are commented out to prevent double extraction.
+.TP
+\f[B]-f, --force\f[R]
+Extract the extern even if the size-check fails.
+.TP
+\f[B]-l, --log\f[R] \f[I]filename\f[R]
+Log size mismatches to \f[I]filename\f[R] rather than to the standard
+error.
+.TP
+\f[B]-w, --warning-template\f[R] \f[I]string\f[R]
+Wrap the size mismatch warning text into the given template:
+\[rs]warningtext in the template will be replaced by the warning text.
+.TP
+\f[B]-q, --quiet\f[R]
+Don\[cq]t describe what\[cq]s happening.
+.TP
+\f[B]-e, --embedded\f[R]
+Prefix all messages to the standard output with the script name.
+.TP
+\f[B]-m, --mkdir\f[R]
+A paranoid \f[I]mkdir -p\f[R].
+(No extraction occurs, \f[I]document.mmz\f[R] is interpreted as a
+directory name.)
+.TP
+\f[B]-h, --help\f[R]
+Show help and exit.
+.TP
+\f[B]-V, --version\f[R]
+Show the Memoize version number and exit.
+.SH SEE ALSO
+.PP
+Memoize manual (https://ctan.org/pkg/memoize), section 6.6.1.


Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.man1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.man1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-extract.man1.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-extract.man1.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.man1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.1	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.1	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+.so man1/doc/memoize-extract.1


Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.man1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.man1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.man1.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.man1.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.pl.man1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.1	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.1	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1 @@
+.so man1/doc/memoize-extract.1


Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.man1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.man1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.man1.pdf	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.man1.pdf	2023-10-11 20:46:52 UTC (rev 68515)

Property changes on: trunk/Master/texmf-dist/doc/man/man1/memoize-extract.py.man1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/memoize/memoize-clean.pl
===================================================================
--- trunk/Master/texmf-dist/scripts/memoize/memoize-clean.pl	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/memoize/memoize-clean.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,163 @@
+#!/usr/bin/env perl
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+use strict;
+use Getopt::Long;
+# I intend to rewrite this script using Path::Class.
+use Cwd 'realpath';
+use File::Spec;
+use File::Basename;
+
+my $VERSION = '2023/10/10 v1.0.0';
+
+my $usage = "usage: memoize-clean.py [-h] [--yes] [--all] [--quiet] [--prefix PREFIX] [mmz ...]\n";
+my $Help = <<END;
+Remove (stale) memo and extern files.
+
+positional arguments:
+  mmz                   .mmz record files
+
+options:
+  -h, --help            show this help message and exit
+  --version, -V         show version and exit
+  --yes, -y             Do not ask for confirmation.
+  --all, -a             Remove *all* memos and externs.
+  --quiet, -q
+  --prefix PREFIX, -p PREFIX
+                        A path prefix to clean; this option can be specified multiple times.
+
+For details, see the man page or the Memoize documentation.
+END
+
+my ($yes, $all, @prefixes, $quiet, $help, $print_version);
+GetOptions(
+    "yes|y"   => \$yes,
+    "all|a"   => \$all,
+    "prefix|p=s" => \@prefixes,
+    "quiet|q|?" => \$quiet,
+    "help|h|?" => \$help,
+    "version|V"  => \$print_version,
+    ) or die $usage;
+$help and die "$usage\n$Help";
+if ($print_version) { print("memoize-clean.pl of Memoize $VERSION\n"); exit 0 }
+
+my (%keep, %prefixes);
+
+my $curdir = Cwd::getcwd();
+
+for my $prefix (@prefixes) {
+    $prefixes{Cwd::realpath(File::Spec->catfile(($curdir), $prefix))} = '';
+}
+
+my @mmzs = @ARGV;
+
+for my $mmz (@mmzs) {
+    my ($mmz_filename, $mmz_dir) = File::Basename::fileparse($mmz);
+    @ARGV = ($mmz);
+    my $endinput = 0;
+    my $empty = -1;
+    my $prefix = "";
+    while (<>) {
+	if (/^ *$/) {
+	} elsif ($endinput) {
+	    die "Bailing out, \\endinput is not the last line of file $mmz.\n";
+	} elsif (/^ *\\mmzPrefix *{(.*?)}/) {
+	    $prefix = $1;
+	    $prefixes{Cwd::realpath(File::Spec->catfile(($curdir,$mmz_dir), $prefix))} = '';
+	    $empty = 1 if $empty == -1;
+	} elsif (/^%? *\\mmz(?:New|Used)(?:CC?Memo|Extern) *{(.*?)}/) {
+	    my $fn = $1;
+	    if ($prefix eq '') {
+		die "Bailing out, no prefix announced before file $fn.\n";
+	    }
+	    $keep{Cwd::realpath(File::Spec->catfile(($mmz_dir), $fn))} = 1;
+	    $empty = 0;
+	    if (rindex($fn, $prefix, 0) != 0) {
+		die "Bailing out, prefix of file $fn does not match " .
+		    "the last announced prefix ($prefix).\n";
+	    }
+	} elsif (/^ *\\endinput *$/) {
+	    $endinput = 1;
+	} else {
+	    die "Bailing out, file $mmz contains an unrecognized line: $_\n";
+	}
+    }
+    die "Bailing out, file $mmz is empty.\n" if $empty && !$all;
+    die "Bailing out, file $mmz does not end with \\endinput; this could mean that " .
+	"the compilation did not finish properly. You can only clean with --all.\n"
+	if $endinput == 0 && !$all;
+}
+
+my @tbdeleted;
+sub populate_tbdeleted {
+    my ($basename_prefix, $dir, $suffix_dummy) = @_;
+    opendir(MD, $dir) or die "Cannot open directory '$dir'";
+    while( (my $fn = readdir(MD)) ) {
+	my $path = File::Spec->catfile(($dir),$fn);
+	if ($fn =~ /\Q$basename_prefix\E[0-9A-F]{32}(?:-[0-9A-F]{32})?(?:-[0-9]+)?(\.memo|(?:-[0-9]+)?\.pdf|\.log)/ and ($all || !exists($keep{$path}))) {
+	    push @tbdeleted, $path;
+	}
+    }
+    closedir(MD);
+}
+for my $prefix (keys %prefixes) {
+    my ($basename_prefix, $dir, $suffix);
+    if (-d $prefix) {
+	populate_tbdeleted('', $prefix, '');
+    }
+    populate_tbdeleted(File::Basename::fileparse($prefix));
+}
+ at tbdeleted = sort(@tbdeleted);
+
+my @allowed_dirs = ($curdir);
+my @deletion_not_allowed;
+for my $f (@tbdeleted) {
+    my $f_allowed = 0;
+    for my $dir (@allowed_dirs) {
+	if ($f =~ /^\Q$dir\E/) {
+	    $f_allowed = 1;
+	    last;
+	}
+    }
+    push(@deletion_not_allowed, $f) if ! $f_allowed;
+}
+die "Bailing out, I was asked to delete these files outside the current directory:\n" .
+    join("\n", @deletion_not_allowed) if (@deletion_not_allowed);
+
+if (scalar(@tbdeleted) != 0) {
+    my $a;
+    unless ($yes) {
+	print("I will delete the following files:\n" .
+	      join("\n", at tbdeleted) . "\n" .
+	      "Proceed (y/n)? ");
+	$a = lc(<>);
+	chomp $a;
+    }
+    if ($yes || $a eq 'y' || $a eq 'yes') {
+	foreach my $fn (@tbdeleted) {
+	    print "Deleting ", $fn, "\n" unless $quiet;
+	    unlink $fn;
+	}
+    } else {
+	die "Bailing out.\n";
+    }
+} elsif (!$quiet) {
+    print "Nothing to do, the directory seems clean.\n";
+}


Property changes on: trunk/Master/texmf-dist/scripts/memoize/memoize-clean.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/memoize/memoize-clean.py
===================================================================
--- trunk/Master/texmf-dist/scripts/memoize/memoize-clean.py	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/memoize/memoize-clean.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+__version__ = '2023/10/10 v1.0.0'
+
+import argparse, re, sys, pathlib, os
+
+parser = argparse.ArgumentParser(
+    description="Remove (stale) memo and extern files.",
+    epilog = "For details, see the man page or the Memoize documentation."
+)
+parser.add_argument('--yes', '-y', action = 'store_true',
+                    help = 'Do not ask for confirmation.')
+parser.add_argument('--all', '-a', action = 'store_true',
+                    help = 'Remove *all* memos and externs.')
+parser.add_argument('--quiet', '-q', action = 'store_true')
+parser.add_argument('--prefix', '-p', action = 'append', default = [],
+    help = 'A path prefix to clean; this option can be specified multiple times.')
+parser.add_argument('mmz', nargs= '*', help='.mmz record files')
+parser.add_argument('--version', '-V', action = 'version',
+                    version = f"%(prog)s of Memoize " + __version__)
+args = parser.parse_args()
+
+re_prefix = re.compile(r'\\mmzPrefix *{(.*?)}')
+re_memo = re.compile(r'%? *\\mmz(?:New|Used)(?:CC?Memo|Extern) *{(.*?)}')
+re_endinput = re.compile(r' *\\endinput *$')
+
+prefixes = set(pathlib.Path(prefix).resolve() for prefix in args.prefix)
+keep = set()
+
+# We loop through the given .mmz files, adding prefixes to whatever manually
+# specified by the user, and collecting the files to keep.
+for mmz_fn in args.mmz:
+    mmz = pathlib.Path(mmz_fn)
+    mmz_parent = mmz.parent.resolve()
+    try:
+        with open(mmz) as mmz_fh:
+            prefix = ''
+            endinput = False
+            empty = None
+            for line in mmz_fh:
+                line = line.strip()
+                
+                if not line:
+                    pass
+                
+                elif endinput:
+                    raise RuntimeError(
+                        r'Bailing out, \endinput is not the last line of file $mmz_fn.')
+                
+                elif m := re_prefix.match(line):
+                    prefix = m[1]
+                    prefixes.add( (mmz_parent/prefix).resolve() )
+                    if empty is None:
+                        empty = True
+
+                elif m := re_memo.match(line):
+                    if not prefix:
+                        raise RuntimeError(
+                            f'Bailing out, no prefix announced before file "{m[1]}".')
+                    if not m[1].startswith(prefix):
+                        raise RuntimeError(
+                            f'Bailing out, prefix of file "{m[1]}" does not match '
+                            f'the last announced prefix ({prefix}).')
+                    keep.add((mmz_parent / m[1]))
+                    empty = False
+
+                elif re_endinput.match(line):
+                    endinput = True
+                    continue
+
+                else:
+                    raise RuntimeError(fr"Bailing out, "
+                        fr"file {mmz_fn} contains an unrecognized line: {line}")
+            
+        if empty and not args.all:
+            raise RuntimeError(fr'Bailing out, file {mmz_fn} is empty.')
+
+        if not endinput and empty is not None and not args.all:
+            raise RuntimeError(
+                fr'Bailing out, file {mmz_fn} does not end with \endinput; '
+                fr'this could mean that the compilation did not finish properly. '
+                fr'You can only clean with --all.'
+            )
+        
+    # It is not an error if the file doesn't exist.
+    # Otherwise, cleaning from scripts would be cumbersome.
+    except FileNotFoundError:
+        pass
+
+tbdeleted = []
+def populate_tbdeleted(folder, basename_prefix):
+    re_aux = re.compile(
+        re.escape(basename_prefix) + 
+        '[0-9A-F]{32}(?:-[0-9A-F]{32})?(?:-[0-9]+)?(?:\.memo|(?:-[0-9]+)?\.pdf|\.log)$')
+    try:
+        for f in folder.iterdir():
+            if re_aux.match(f.name) and (args.all or f not in keep):
+                tbdeleted.append(f)
+    except FileNotFoundError:
+        pass
+
+for prefix in prefixes:
+    # "prefix" is interpreted both as a directory (if it exists) and a basename prefix.
+    if prefix.is_dir():
+        populate_tbdeleted(prefix, '')
+    populate_tbdeleted(prefix.parent, prefix.name)
+
+allowed_dirs = [pathlib.Path().absolute()] # todo: output directory
+deletion_not_allowed = [f for f in tbdeleted if not f.is_relative_to(*allowed_dirs)]
+if deletion_not_allowed:
+    raise RuntimeError("Bailing out, "
+        "I was asked to delete these files outside the current directory:\n" +
+        "\n".join(str(f) for f in deletion_not_allowed))
+        
+_cwd_absolute = pathlib.Path().absolute()
+def relativize(path):
+    try:
+        return path.relative_to(_cwd_absolute)
+    except ValueError:
+        return path
+
+if tbdeleted:
+    tbdeleted.sort()
+    if not args.yes:
+        print('I will delete the following files:')
+        for f in tbdeleted:
+            print(relativize(f))
+        print("Proceed (y/n)? ")
+        a = input()
+    if args.yes or a == 'y' or a == 'yes':
+        for f in tbdeleted:
+            if not args.quiet:
+                print("Deleting", relativize(f))
+            try:
+                f.unlink()
+            except FileNotFoundError:
+                print(f"Cannot delete {f}")
+    else:
+        print("Bailing out.")
+elif not args.quiet:
+    print('Nothing to do, the directory seems clean.')


Property changes on: trunk/Master/texmf-dist/scripts/memoize/memoize-clean.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/memoize/memoize-extract.pl
===================================================================
--- trunk/Master/texmf-dist/scripts/memoize/memoize-extract.pl	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/memoize/memoize-extract.pl	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,205 @@
+#!/usr/bin/env perl
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+use strict;
+use Getopt::Long;
+use Path::Class;
+use File::Spec;
+use File::Basename;
+use PDF::API2;
+
+my $VERSION = '2023/10/10 v1.0.0';
+
+my $usage = "usage: memoize-extract.pl [-h] [--pdf PDF] [--prune] [--keep] [--force] [--log LOG] [--warning-template WARNING_TEMPLATE] [--quiet] [--mkdir] mmz\n";
+my $Help = <<END;
+Extract extern pages out of the document PDF.
+
+positional arguments:
+  mmz                   the record file produced by Memoize: doc.mmz when compiling doc.tex
+
+options:
+  --help, -h            show this help message and exit
+  --version, -V         show version and exit
+  --pdf PDF, -P PDF     extract from file PDF
+  --prune, -p           remove the extern pages after extraction
+  --keep, -k            do not mark externs as extracted
+  --force, -f           extract even if the size-check fails
+  --log LOG, -l LOG     the log file
+  --warning-template WARNING_TEMPLATE, -w WARNING_TEMPLATE
+                        \warningtext in the template will be replaced by the warning message
+  --quiet, -q           don't describe what's happening
+  --embedded, -e        prefix all messages to the standard output with the script name
+  --mkdir, -m           create a directory (and exit)
+
+For details, see the man page or the Memoize documentation.
+END
+
+my ($pdf_arg, $prune, $keep, $log, $quiet, $embedded, $force, $mkdir, $help, $print_version);
+my $warning_template = '\warningtext';
+Getopt::Long::Configure ("bundling");
+GetOptions(
+    "pdf|P=s"   => \$pdf_arg,
+    "keep|k"    => \$keep,
+    "prune|p"   => \$prune,
+    "log|l=s"   => \$log,
+    "quiet|q" => \$quiet,
+    "embedded|e" => \$embedded,
+    "force|f" => \$force,
+    "warning-template|w=s" => \$warning_template,
+    "mkdir|m"   => \$mkdir,
+    "help|h|?"  => \$help,
+    "version|V"  => \$print_version,
+    ) or die $usage;
+if ($help) {print("$usage\n$Help"); exit 0}
+if ($print_version) { print("memoize-extract.pl of Memoize $VERSION\n"); exit 0 }
+die $usage unless @ARGV == 1;
+
+my $message_prefix = $embedded ? basename($0) . ': ' : '';
+print("\n") if ($embedded);
+
+my @output_paths = (dir()->absolute->resolve);
+my $texmfoutput = `kpsewhich --var-value=TEXMFOUTPUT`;
+$texmfoutput =~ s/^\s+|\s+$//g;
+if ($texmfoutput) {
+    my $texmfoutput_dir = dir($texmfoutput)->absolute->resolve;
+    push(@output_paths, $texmfoutput_dir) unless $texmfoutput_dir->dir_list == 1 && ! $texmfoutput_dir->volume;
+}
+
+sub paranoia {
+    my $file = $_[0];
+    die "${message_prefix}Cannot create a hidden file or dir: $file"
+	if $file->basename =~ /^\./;
+    my $parent = $file->parent->absolute->resolve;
+    die "${message_prefix}Cannot write outside the current working or output directory tree: $file"
+	unless grep($_->contains($parent), @output_paths);
+}
+
+my $mmz_arg = $ARGV[0];
+my $mmz_file = file($mmz_arg);
+my $mmz_dir = $mmz_file->parent;
+
+if ($mkdir) {
+    my $dir = dir($mmz_arg)->cleanup;
+    my $current = dir(File::Spec->catpath($dir->volume,
+					  $dir->is_absolute ? File::Spec->rootdir : File::Spec->curdir,
+					  ''))->absolute;
+    for my $c ($dir->components) {
+	$current = $current->subdir($c);
+	if (-d $current) {
+	    $current = $current->resolve;
+	} else {
+	    paranoia($current);
+	    mkdir($current);
+	    print("${message_prefix}Created directory $current\n") unless $quiet;
+	}
+    }
+    exit;
+} else {
+    die "${message_prefix}The 'mmz' argument should be a file with suffix '.mmz', not '$mmz_file'\n" unless $mmz_file->basename =~ /\.mmz$/;
+}
+
+# Enable in-place editing (of the .mmz file).
+paranoia($mmz_file) unless $keep;
+$^I = "" unless $keep;
+
+my $pdf_file = $pdf_arg ? file($pdf_arg) : $mmz_dir->file($mmz_file->basename =~ s/\.mmz$/\.pdf/r)->cleanup;
+paranoia($pdf_file) if $prune;
+
+if ($log) {
+    paranoia(file($log));
+    open LOG, ">$log";
+} else {
+    *LOG = *STDERR;
+}
+
+my ($pdf, %extern_pages);
+print "${message_prefix}Extracting externs from $pdf_file:\n" unless $quiet;
+
+my $tolerance = 0.01;
+my $done_message = "${message_prefix}Done (there was nothing to extract).\n";
+    
+while (<>) {
+    if (/^\\mmzNewExtern *{(?P<extern_path>(?P<prefix>.*?)(?P<code_md5sum>[0-9A-F]{32})-(?P<context_md5sum>[0-9A-F]{32})(?:-[0-9]+)?.pdf)}{(?P<page_n>[0-9]+)}{(?P<expected_width>[0-9.]*)pt}{(?P<expected_height>[0-9.]*)pt}/) {
+	my $extern_file = file($+{extern_path});
+	if (! $extern_file->is_absolute) {
+	    $extern_file = $mmz_dir->file($+{extern_path});
+	}
+	paranoia($extern_file);
+	my $page = $+{page_n};
+	my $expected_width_pt = $+{expected_width};
+	my $expected_height_pt = $+{expected_height};
+	my $c_memo_file = $mmz_dir->file($+{prefix} . $+{code_md5sum} . '.memo');
+	my $cc_memo_file = $mmz_dir->file($+{prefix} . $+{code_md5sum} . '-' . $+{context_md5sum} . '.memo');
+	if (!(-e $c_memo_file && -e $cc_memo_file)) {
+	    print LOG ($warning_template =~ s/\\warningtext/Not extracting page $page into extern $extern_file, because the associated (c)c-memo does not exist/gr), "\n\\endinput\n";
+	    last;
+	}
+	eval { $pdf = PDF::API2->open($pdf_file->stringify) unless $pdf; };
+	if ($@) {
+	    print LOG ($warning_template =~ s/\\warningtext/Cannot read file "$pdf_file". Perhaps you have to load Memoize earlier in the preamble?/gr), "\n\\endinput\n";
+	    close LOG;
+	    die "${message_prefix}File '$pdf_file' cannot be read, bailing out.\n";
+	}
+	my $extern = PDF::API2->new();
+	$extern->version($pdf->version);
+	$extern->import_page($pdf, $page);
+	my $extern_page = $extern->open_page(1);
+	my ($x0, $y0, $x1, $y1) = $extern_page->get_mediabox();
+	my $width_pt = ($x1 - $x0) / 72 * 72.27;
+	my $height_pt = ($y1 - $y0) / 72 * 72.27;
+	my $warning = '';
+	if (abs($width_pt - $expected_width_pt) > $tolerance
+	    || abs($height_pt - $expected_height_pt) > $tolerance)
+	{
+	    $warning = "I refuse to extract page $page from $pdf_file, because its size (${width_pt}pt x ${height_pt}pt) is not what I expected (${expected_width_pt}pt x ${expected_height_pt}pt)";
+	    print LOG ($warning_template =~ s/\\warningtext/$warning/gr), "\n";
+	}
+	if ($warning && !$force) {
+	    unlink $extern_file;
+	} else {
+	    $extern->saveas($extern_file->stringify);
+	    $done_message = "${message_prefix}Done.\n";
+	    print STDOUT "${message_prefix}  Page $page --> $extern_file\n" unless $quiet;
+	    $extern_pages{$page} = 1 if $prune;
+	    print("%") unless $keep;
+	}
+    }
+    print unless $keep;
+}
+
+print $done_message unless $quiet;
+
+if ($pdf and $prune) {
+    paranoia($pdf_file);
+    my $pruned_pdf = PDF::API2->new();
+    for (my $n = 1; $n <= $pdf->page_count(); $n++) {
+	if (! $extern_pages{$n}) {
+	    $pruned_pdf->import_page($pdf, $n);
+	}
+    }
+    $pruned_pdf->save($pdf_file->stringify);
+    print("${message_prefix}The following extern pages were pruned out of the PDF: ",
+	  join(",", sort(keys(%extern_pages))) . "\n") unless $quiet;
+}
+
+if ($log) {
+    print LOG "\\endinput\n";
+    close LOG;
+}


Property changes on: trunk/Master/texmf-dist/scripts/memoize/memoize-extract.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/memoize/memoize-extract.py
===================================================================
--- trunk/Master/texmf-dist/scripts/memoize/memoize-extract.py	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/memoize/memoize-extract.py	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,183 @@
+#!/usr/bin/env python3
+
+# This file is a part of Memoize, a TeX package for externalization of
+# graphics and memoization of compilation results in general, available at
+# https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+#
+# Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+#
+# This work may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3c of this license or (at
+# your option) any later version.  The latest version of this license is in
+# https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+# all distributions of LaTeX version 2008 or later.
+#
+# This work has the LPPL maintenance status `maintained'.
+# The Current Maintainer of this work is Saso Zivanovic.
+# 
+# The files belonging to this work and covered by LPPL are listed in
+# <texmf>/doc/generic/memoize/FILES.
+
+__version__ = '2023/10/10 v1.0.0'
+
+import argparse, re, sys, os, pdfrw, subprocess, itertools
+from pathlib import Path
+
+parser = argparse.ArgumentParser(
+    description = "Extract extern pages out of the document PDF.",
+    epilog = "For details, see the man page or the Memoize documentation.",
+    prog = 'memoize-extract.py',
+)
+parser.add_argument('--pdf', '-P', help = 'extract from file PDF')
+parser.add_argument('--prune', '-p', action = 'store_true',
+    help = 'remove the extern pages after extraction')
+parser.add_argument('--keep', '-k', action = 'store_true',
+    help = 'do not mark externs as extracted')
+parser.add_argument('--force', '-f', action = 'store_true',
+    help = 'extract even if the size-check fails')
+parser.add_argument('--log', '-l', default = os.devnull, help = 'the log file')
+parser.add_argument('--warning-template', '-w', default = '\warningtext',
+    help = '\warningtext in the template will be replaced by the warning message')
+parser.add_argument('--quiet', '-q', action = 'store_true',
+    help = "describe what's happening")
+parser.add_argument('--embedded', '-e', action = 'store_true',
+    help = "prefix all messages to the standard output with the script name")
+parser.add_argument('--mkdir', '-m', action = 'store_true',
+    help = 'create a directory (and exit)')
+parser.add_argument('mmz',
+    help = 'the record file produced by Memoize: doc.mmz when compiling doc.tex')
+parser.add_argument('--version', '-V', action = 'version',
+                    version = f"%(prog)s of Memoize " + __version__)
+
+args = parser.parse_args()
+
+message_prefix = parser.prog + ': ' if args.embedded else ''
+if args.embedded:
+    print()
+
+# Even a bit more paranoid than required:
+# (a) disallowing TEXMFOUTPUT=/ (while allowing C:\ on Windows)
+# (b) waiting for access to '-output-directory'.
+output_paths = [Path.cwd()]
+if texmfoutput := subprocess.run(
+        ['kpsewhich', '--var-value=TEXMFOUTPUT'],
+        capture_output = True).stdout.decode().strip():
+    texmfoutput_dir = Path(texmfoutput).resolve()
+    if len(texmfoutput_dir.parts) != 1 or texmfoutput_dir.drive:
+        output_paths.append(texmfoutput_dir)
+
+def paranoia(f):
+    p = Path(f).resolve()
+    if p.stem.startswith('.'):
+        raise RuntimeError(f"{message_prefix}Cannot create a hidden file or dir: {f}")
+    if not any(p.is_relative_to(op) for op in output_paths):
+        raise RuntimeError(f"{message_prefix}Cannot write outside the current working or output directory tree: {f}")
+
+mmz_file = Path(args.mmz)
+    
+if args.mkdir: # Here, argument "mmz" is interpreted as the directory to create.
+    # We cannot simply say
+    # paranoia(mmz_file)
+    # mmz_file.mkdir(parents = True, exist_ok = True)
+    # because have be paranoid about the intermediate directories as well:
+    # memoize-extract.py -m a/../../BAD/../<cwd-name>/b
+    # Note that paranoia might kick in only after a part of the given path was
+    # already created.  This is in accord to how "mkdir" behaves wrt existing
+    # files.
+    for folder in itertools.chain(reversed(mmz_file.parents), (mmz_file,)):
+        if not folder.is_dir():
+            paranoia(folder)
+            folder.mkdir(exist_ok = True)
+            if not args.quiet:
+                print(f"{message_prefix}Created directory {folder}")
+    sys.exit()
+elif mmz_file.suffix != '.mmz':
+    raise RuntimeError(f"{message_prefix}The 'mmz' argument should be a file with suffix '.mmz', not '{mmz_file}'")
+
+mmz_dir = mmz_file.parent
+pdf_file = Path(args.pdf) if args.pdf else mmz_file.with_suffix('.pdf')
+paranoia(pdf_file)
+pdf = None
+extern_pages = []
+new_mmz = []
+args.log is os.devnull or paranoia(Path(args.log))
+re_newextern = re.compile(r'\\mmzNewExtern *{(?P<extern_fn>(?P<prefix>.*?)(?P<code_md5sum>[0-9A-F]{32})-(?P<context_md5sum>[0-9A-F]{32})(?:-[0-9]+)?.pdf)}{(?P<page_n>[0-9]+)}{(?P<expected_width>[0-9.]*)pt}{(?P<expected_height>[0-9.]*)pt}')
+tolerance = 0.01
+done_message = f"{message_prefix}Done (there was nothing to extract)."
+
+# Complication: I want to use 'with', but don't have to open stderr.
+with open(args.log, 'w') as log:
+    log = sys.stderr if args.log is os.devnull else log
+    try:
+        mmz = mmz_file.open()
+    except FileNotFoundError:
+        print(f'''{message_prefix}File "{mmz_file}" does not exist, assuming there's nothing to do.''',
+              file = sys.stderr)
+    else:
+        if not args.quiet:
+            print(f"{message_prefix}Extracting externs from {pdf_file}")
+        for line in mmz:
+            if m := re_newextern.match(line):
+                extern_file = mmz_dir / m['extern_fn']
+                paranoia(extern_file)
+                page_n = int(m['page_n'])-1
+                c_memo = mmz_dir / (m['prefix'] + m['code_md5sum'] + '.memo')
+                cc_memo = mmz_dir / (m['prefix'] + m['code_md5sum'] + '-' + m['context_md5sum'] + '.memo')
+                if not (c_memo.exists() and cc_memo.exists()):
+                    print(args.warning_template.replace('\warningtext', f'Not extracting page {page_n} into extern {extern_file}, because the associated (c)c-memo does not exist'), file = log)
+                    continue
+                if not pdf:
+                    try:
+                        pdf = pdfrw.PdfReader(pdf_file)
+                    except pdfrw.errors.PdfParseError:
+                        print(f'{message_prefix}File "{pdf_file}" cannot be read, bailing out.', file = sys.stderr)
+                        print(args.warning_template.replace('\warningtext', f'Cannot read file "{pdf_file}". Perhaps you have to load Memoize earlier in the preamble?'), file = log)
+                        args.keep = True
+                        break
+                extern = pdfrw.PdfWriter(extern_file)
+                page = pdf.pages[page_n]
+                expected_width_pt, expected_height_pt = float(m['expected_width']), float(m['expected_height'])
+                mb = page['/MediaBox']
+                width_bp, height_bp = float(mb[2]) - float(mb[0]), float(mb[3]) - float(mb[1])
+                width_pt = width_bp / 72 * 72.27
+                height_pt = height_bp / 72 * 72.27
+                warning = None
+                if abs(width_pt - expected_width_pt) > tolerance \
+                   or abs(height_pt - expected_height_pt) > tolerance:
+                    warning = (
+                        f'I refuse to extract page {page_n+1} from "{pdf_file}", '
+                        f'because its size ({width_pt}pt x {height_pt}pt) is not '
+                        f'what I expected ({expected_width_pt}pt x {expected_height_pt}pt)')
+                    print(args.warning_template.replace('\warningtext', warning), file = log)
+                if warning and not args.force:
+                    extern_file.unlink(missing_ok = True)
+                else:
+                    extern.addpage(page)
+                    if not args.quiet:
+                        print(f"{message_prefix}  Page {page_n+1} --> {extern_file}", file = sys.__stdout__)
+                    extern.write()
+                    done_message = f"{message_prefix}Done."
+                    if args.prune:
+                        extern_pages.append(page_n)
+                    if not args.keep:
+                        line = '%' + line
+            if not args.keep:
+                new_mmz.append(line)
+        mmz.close()
+        if not args.quiet:
+            print(done_message)
+        if not args.keep:
+            paranoia(mmz_file)
+            with open(mmz_file, 'w') as mmz:
+                for line in new_mmz:
+                    print(line, file = mmz, end = '')
+        if args.prune and extern_pages:
+            pruned_pdf = pdfrw.PdfWriter(pdf_file)
+            pruned_pdf.addpages(
+                page for n, page in enumerate(pdf.pages) if n not in extern_pages)
+            pruned_pdf.write()
+            if not args.quiet:
+                print(f"{message_prefix}The following extern pages were pruned out of the PDF:",
+                      ",".join(str(page+1) for page in extern_pages))
+    if args.log is not os.devnull:
+        print(r'\endinput', file = log)


Property changes on: trunk/Master/texmf-dist/scripts/memoize/memoize-extract.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/generic/memoize/Makefile
===================================================================
--- trunk/Master/texmf-dist/source/generic/memoize/Makefile	                        (rev 0)
+++ trunk/Master/texmf-dist/source/generic/memoize/Makefile	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,139 @@
+# Prepare the CTAN submission for all three packages.
+
+PACKAGES = memoize advice collargs
+
+all: ctan/memoize.zip
+	$(MAKE) -f Makefile.advice ctan/advice.zip
+	$(MAKE) -f Makefile.collargs ctan/collargs.zip
+
+# Prepare the CTAN submission.
+
+PACKAGE = memoize
+VERSION = 1.0.0
+YEAR = 2023
+MONTH = 10
+DAY = 10
+
+FORMAT = generic
+
+COMMON = memoize nomemoize memoizable
+PLAIN = memoize-extract-one.tex
+SOURCE = memoize.edtx memoize.ins # $(makefiles)
+
+SCRIPTS := memoize-extract memoize-clean
+man-src := $(SCRIPTS:%=doc/%.1.md)
+MAN := $(SCRIPTS:%=%.1) $(SCRIPTS:%=%.pl.1) $(SCRIPTS:%=%.py.1)
+MAN := $(MAN:%=doc/%)
+SCRIPTS := $(SCRIPTS:%=%.pl) $(SCRIPTS:%=%.py)
+
+%.pl.1: %.1
+	echo .so man1/$*.1 > $@     # link to .1 man page
+%.py.1: %.1
+	echo .so man1/$*.1 > $@     # link to .1 man page
+
+.PHONY: runtime
+runtime: $(RUNTIME)
+
+README = doc/README.memoize.md
+INSTALL = INSTALL.md
+MAKEFILE = Makefile
+LICENCE = LICENCE
+
+makefiles = Makefile.package Makefile.runtimes Makefile.advice Makefile.collargs 
+
+codedoc-source = memoize-code.tex \
+                 memoize-code.sty memoize-doc-common.sty
+
+manual-source = memoize.tex \
+                memoize-doc.sty memoize-doc-common.sty yadoc.sty \
+		memoize.mst
+
+PDF = memoize.pdf memoize-code.pdf
+
+codedoc-source := $(codedoc-source:%=doc/%)
+manual-source := $(manual-source:%=doc/%)
+pdf := $(PDF:%=doc/%)
+DOC = $(sort $(codedoc-source) $(manual-source)) $(pdf) $(man-src)
+
+examples-src := Makefile ins.begin ins.mid ins.end
+examples-src := $(examples-src:%=doc/examples/%)
+#examples-src += $(shell git ls-files | grep ^doc/examples/.*dtx$)
+examples-src += $(shell find doc/examples -name '*.dtx')
+
+# doc/attachments.lst is produced by compiling memoize.tex (without memoization).
+# doc-examples will hold soft links to the relevant generated example files.
+doc-examples := $(shell sed 's/^.* \(.*\) ##.*$$/\1/' doc/attachments.lst)
+doc-examples := $(doc-examples:%=doc/examples/%)
+
+ctan/$(PACKAGE).zip:
+	$(TDS-BEGIN)
+#	Check for duplicate filenames:
+	echo $(doc-examples) | tr ' ' '\n' | uniq -d | ifne false
+	cd doc && zip ../$(TDS-DOC-DIR)/examples-src.zip $(examples-src:doc/%=%)
+#	For each line ($1 $2) in attachments.lst, link $1 to $2 ...
+	cd doc/examples && sed 's!^examples/!ln -sfr !' ../attachments.lst | sh
+#	... and zip those links.
+	cd doc && zip -r ../$(TDS-DOC-DIR)/examples.zip $(doc-examples:doc/%=%)
+	$(TDS-END)
+	$(CTAN-BEGIN)
+	ln -sr $(TDS-DOC-DIR)/examples-src.zip $(CTAN-DIR)/doc
+	ln -sr $(TDS-DOC-DIR)/examples.zip $(CTAN-DIR)/doc
+	$(CTAN-END)
+
+
+
+doc/memoize-code.pdf: $(SOURCE) $(codedoc-source)
+
+doc/memoize.pdf: $(manual-source) $(examples-src)
+
+%.pdf: %.tex
+	latexmk -cd -lualatex -bibtex- $<  && touch $@
+
+
+
+# Maintanence
+
+test.tex = $(wildcard test*.tex)
+
+.PHONY: all runtime force clean versions-show
+
+.PRECIOUS: %.1
+
+clean: # clean this directory
+	memoize-clean.py -a $(test.tex:%.tex=-p %.) $(test.tex:%.tex=-p %.memo.dir/)
+	latexmk -C -f $(test.tex) _region_
+
+version:
+	$(MAKE) -f Makefile.collargs version
+	$(MAKE) -f Makefile.advice version
+	$(call EDIT-VERSION-LATEX,memoize.edtx,memoize)
+	$(call EDIT-VERSION-LATEX,memoize.edtx,nomemoize)
+	$(call EDIT-VERSION-LATEX,memoize.edtx,memoizable)
+	$(call EDIT-VERSION-CONTEXT,memoize.edtx)
+	$(call EDIT-VERSION-PLAIN,memoize.edtx,memoize)
+	$(call EDIT-VERSION-PLAIN,memoize.edtx,nomemoize)
+	$(call EDIT-VERSION-PLAIN,memoize.edtx,memoizable)
+	$(call EDIT-VERSION-PERL,memoize-extract.pl)
+	$(call EDIT-VERSION-PERL,memoize-clean.pl)
+	$(call EDIT-VERSION-PYTHON,memoize-extract.py)
+	$(call EDIT-VERSION-PYTHON,memoize-clean.py)
+	$(call EDIT-VERSION-MAN,doc/memoize-extract.1.md)
+	$(call EDIT-VERSION-MAN,doc/memoize-clean.1.md)
+# Change the date of the latest release (identified by the version).
+	sed -Ei 's!^\\item\[\\githubrelease\{[0-9]{4}/[0-9]{2}/[0-9]{2}\}\{v$(VERSION)\}\] *$$!\\item\[\\githubrelease\{$(YEAR)/$(MONTH)/$(DAY)\}\{v$(VERSION)\}\]!' doc/memoize.tex
+
+define COLOR_VERSION
+grep -E --color '[0-9]{4}[/-][0-9]{2}[/-][0-9]{2}|v?[0-9]\.[0-9]\.[0-9]|(January|February|March|April|May|June|July|August|September|October|November|December) [0-9]+, [0-9]{4}'
+endef
+
+versions-show:
+	@grep -E '%<latex>\\ProvidesPackage|^%<context>%D\s*(version|date)=' $(PACKAGES:%=%.edtx) | ${COLOR_VERSION}
+	@grep __version__ *.py | ${COLOR_VERSION}
+	@grep VERSION *.pl | ${COLOR_VERSION}
+	@grep -E '^(footer|date):' doc/memoize-*.md | ${COLOR_VERSION}
+	@grep -E 'githubrelease' doc/memoize.tex | ${COLOR_VERSION}
+
+include Makefile.package
+include Makefile.runtimes
+
+VERSION-MAN = of Memoize v$(VERSION)


Property changes on: trunk/Master/texmf-dist/source/generic/memoize/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/generic/memoize/memoize.edtx
===================================================================
--- trunk/Master/texmf-dist/source/generic/memoize/memoize.edtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/generic/memoize/memoize.edtx	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,3597 @@
+% \iffalse
+% 
+% memoize.edtx (this is not a .dtx file; to produce a .dtx, process it with edtx2dtx)
+% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%% 
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+% 
+% \fi
+% 
+%    \begin{macrocode}
+% 
+% \relax
+% 
+% This file contains the documented source code of
+% package \href{https://ctan.org/pkg/memoize}{Memoize} and, somewhat
+% unconventionally, its two independently distributed auxiliary
+% packages \href{https://ctan.org/pkg/advice}{Advice}
+% and \href{https://ctan.org/pkg/collargs}{CollArgs}.
+% 
+% The source code of the \hologo{TeX} parts of the package resides in
+% |memoize.edtx|, |advice.edtx| and |collargs.edtx|.  These files are written
+% in \href{https://ctan.org/pkg/easydtx}{EasyDTX}, a format of my own invention
+% which is almost like the DTX format but eliminates the need for all those
+% pesky |macrocode| environments: Any line introduced by a single comment
+% counts as documentation, and to top it off, documentation lines may be
+% indented.  An |.edtx| file is converted to a |.dtx| by a little Perl script
+% called |edtx2dtx|; there is also a rudimentary Emacs mode, implemented in
+% |easydoctex-mode.el|, which takes care of fontification, indentation, and
+% forward and inverse search.
+% 
+% The |.edtx| files contain the code for all three formats supported by the
+% three packages --- \hologo{LaTeX} (guard |latex|), \hologo{plainTeX} (guard
+% |plain|) and \hologo{ConTeXt} (guard |context|) --- but upon reading the
+% code, it will quickly become clear that Memoize was first developed for
+% \hologo{LaTeX}.  In \S\ref{sec:code:identification}, we manually define
+% whatever \hologo{LaTeX} tools are ``missing'' in \hologo{plainTeX} and
+% \hologo{ConTeXt}.  Even worse, \hologo{ConTeXt} code is often just the same
+% as \hologo{plainTeX} code, even in cases where I'm sure \hologo{ConTeXt}
+% offers the relevant tools.  This nicely proves that I have no clue about
+% \hologo{ConTeXt}.  If you are willing to \hologo{ConTeXt}-ualize my code ---
+% please do so, your help is welcome!
+% 
+% The runtimes of Memoize (and also Advice) comprise of more than just the main
+% runtime for each format.  Memoize ships with two additional stub packages,
+% |nomemoize| and |memoizable|, and a \hologo{TeX}-based extraction script
+% |memoize-extract-one|; Advice optionally offers a \TikZ; support defined in
+% |advice-tikz.code.tex|.  For the relation between guards and runtimes,
+% consult the core of the |.ins| files below.
+% 
+% \tcbset{ins listing/.style={listing only, fonttitle=\ttfamily\footnotesize,
+% leftupper=-1.5mm, lefttitle=2mm, right=0mm, top=2mm, bottom=2.65mm,
+% listing options app={basicstyle=\ttfamily\scriptsize}}}
+% 
+% \begin{tcbraster}[raster columns=100]
+%   \tcbinputlisting{raster multicolumn=55, ins listing, top=1mm, bottom=1mm, title=memoize.ins,listing file=../memoize.ins, linerange={27-38}, leftupper=1mm}
+%   \begin{tcboxedraster}[raster columns=1]{blankest, raster multicolumn=45}
+%     \tcbinputlisting{ins listing, title=advice.ins, listing file=../advice.ins, linerange=28-31}
+%     \tcbinputlisting{ins listing, title=collar\raisebox{0pt}[\height][0pt]{g}s.ins, listing file=../collargs.ins, linerange=29-31}
+%   \end{tcboxedraster}
+% \end{tcbraster}
+% 
+% Memoize also contains two scripts, |memoize-extract| and |memoize-clean|.
+% Both come in two functionally equivalent implementations: Perl (|.pl|) and a
+% Python (|.py|).  The code is listed in \S\ref{sec:code:scripts}, I believe it
+% is self-explanatory enough to lack more than a occasional comment.
+% 
+% 
+% \thispagestyle{empty}
+% \clearpage
+% \tableofcontents
+% \clearpage
+%
+% \newgeometry{left=4cm,right=1cm,top=1cm,bottom=1cm,
+% marginparwidth=3cm,marginparsep=0pt,nohead,includefoot}
+% \settowidth\marginparsep{\ }
+% 
+% \section{First things first}
+% \label{sec:code:identification}
+% 
+% \paragraph{Identification} of |memoize|, |memoizable| and |nomemoize|.
+%<*mmz>
+%<latex>\ProvidesPackage{memoize}[2023/10/10 v1.0.0 Fast and flexible externalization]
+%<context>%D \module[
+%<context>%D         file=t-memoize.tex,
+%<context>%D      version=1.0.0,
+%<context>%D        title=Memoize,
+%<context>%D     subtitle=Fast and flexible externalization,
+%<context>%D       author=Saso Zivanovic,
+%<context>%D         date=2023-10-10,
+%<context>%D    copyright=Saso Zivanovic,
+%<context>%D      license=LPPL,
+%<context>%D ]
+%<context>\writestatus{loading}{ConTeXt User Module / memoize}
+%<context>\unprotect
+%<context>\startmodule[memoize]
+%<plain>% Package memoize 2023/10/10 v1.0.0
+%</mmz>
+%<*mmzable>
+%<latex>\ProvidesPackage{memoizable}[2023/10/10 v1.0.0 A programmer's stub for Memoize]
+%<context>%D \module[
+%<context>%D         file=t-memoizable.tex,
+%<context>%D      version=1.0.0,
+%<context>%D        title=Memoizable,
+%<context>%D     subtitle=A programmer's stub for Memoize,
+%<context>%D       author=Saso Zivanovic,
+%<context>%D         date=2023-10-10,
+%<context>%D    copyright=Saso Zivanovic,
+%<context>%D      license=LPPL,
+%<context>%D ]
+%<context>\writestatus{loading}{ConTeXt User Module / memoizable}
+%<context>\unprotect
+%<context>\startmodule[memoizable]
+%<plain>% Package memoizable 2023/10/10 v1.0.0
+%</mmzable>
+%<*nommz>
+%<latex>\ProvidesPackage{nomemoize}[2023/10/10 v1.0.0 A no-op stub for Memoize]
+%<context>%D \module[
+%<context>%D         file=t-nomemoize.tex,
+%<context>%D      version=1.0.0,
+%<context>%D        title=Memoize,
+%<context>%D     subtitle=A no-op stub for Memoize,
+%<context>%D       author=Saso Zivanovic,
+%<context>%D         date=2023-10-10,
+%<context>%D    copyright=Saso Zivanovic,
+%<context>%D      license=LPPL,
+%<context>%D ]
+%<context>\writestatus{loading}{ConTeXt User Module / nomemoize}
+%<context>\unprotect
+%<context>\startmodule[nomemoize]
+%<mmz>% Package nomemoize 2023/10/10 v1.0.0
+%</nommz>
+% 
+% \paragraph{Required packages} and \hologo{LaTeX}ization of \hologo{plainTeX}
+% and \hologo{ConTeXt}.
+%<*(mmz,mmzable,nommz)&(plain,context)>
+\input miniltx
+%</(mmz,mmzable,nommz)&(plain,context)>
+% Some stuff which is ``missing'' in |miniltx|, copied here from |latex.ltx|.
+%<*mmz&(plain,context)>
+\def\PackageWarning#1#2{{%
+    \newlinechar`\^^J\def\MessageBreak{^^J\space\space#1: }%
+    \message{#1: #2}}}
+%</mmz&(plain,context)>
+% Same as the official definition, but without |\outer|.  Needed for record
+% file declarations.
+%<*mmz&plain>
+\def\newtoks{\alloc at 5\toks\toksdef\@cclvi}
+\def\newwrite{\alloc at 7\write\chardef\sixt@@n}
+%</mmz&plain>
+% |Nomemoize| has to load |pgfopts| as well, and process package options (right
+% away, why not), otherwise \hologo{LaTeX} will complain.
+%<*latex>
+%<mmz,nommz>\RequirePackage{pgfopts}  % pgfkeys-based package options
+%<nommz>\pgfkeys{/memoize/package options/.unknown/.code={}}
+%<nommz>\ProcessPgfPackageOptions{/memoize/package options}
+%</latex>
+% I can't really write any code without |etoolbox| \dots
+%<*mmz>
+%<latex>\RequirePackage{etoolbox}
+%<plain,context>\input etoolbox-generic
+% Setup the |memoize| namespace in \hologo{LuaTeX}.
+\ifdefined\luatexversion
+  \directlua{memoize = {}}
+\fi
+% |pdftexcmds.sty| eases access to some PDF primitives, but I cannot manage to
+% load it in \hologo{ConTeXt}, even if it's supposed to be a generic
+% package. So let's load |pdftexcmds.lua| and copy--paste what we need from
+% |pdftexcmds.sty|.
+%<latex>\RequirePackage{pdftexcmds}
+%<plain>\input pdftexcmds.sty
+%<*context>
+\directlua{%
+  require("pdftexcmds")
+  tex.enableprimitives('pdf@', {'draftmode'})
+}
+\long\def\pdf at mdfivesum#1{%
+  \directlua{%
+    oberdiek.pdftexcmds.mdfivesum("\luaescapestring{#1}", "byte")%
+  }%
+}%
+\def\pdf at system#1{%
+  \directlua{%
+    oberdiek.pdftexcmds.system("\luaescapestring{#1}")%
+  }%
+}
+\let\pdf at primitive\primitive
+% Lua function |oberdiek.pdftexcmds.filesize| requires the |kpse| library,
+% which is not loaded in \hologo{ConTeXt},
+% see \url(https://){github.com/latex3/lua-uni-algos/issues/3}, so we define our
+% own filesize function.
+\directlua{%
+  function memoize.filesize(filename)
+    local filehandle = io.open(filename, "r")
+    % We can't easily use |~=|, as |~| is an active character, so the |else|
+    % workaround.
+    if filehandle == nil then
+    else
+      tex.write(filehandle:seek("end"))
+      io.close(filehandle)
+    end
+  end
+}%
+\def\pdf at filesize#1{%
+  \directlua{memoize.filesize("\luaescapestring{#1}")}%
+}
+%</context>
+% Take care of some further differences between the engines.
+\ifdef\pdftexversion{%
+}{%
+  \def\pdfhorigin{1true in}%
+  \def\pdfvorigin{1true in}%
+  \ifdef\XeTeXversion{%
+    \let\quitvmode\leavevmode
+  }{%
+    \ifdef\luatexversion{%
+      \let\pdfpagewidth\pagewidth
+      \let\pdfpageheight\pageheight
+      \def\pdfmajorversion{\pdfvariable majorversion}%
+      \def\pdfminorversion{\pdfvariable minorversion}%
+    }{%
+      \PackageError{memoize}{Support for this TeX engine is not implemented}{}%
+    }%
+  }%
+}
+% 
+% In \hologo{ConTeXt}, |\unexpanded| means |\protected|, and the usual
+% |\unexpanded| is available as |\normalunexpanded|.  Option one: use dtx
+% guards to produce the correct control sequence.  I tried this option.  I find
+% it ugly, and I keep forgetting to guard.  Option two: |\let| an internal
+% control sequence, like |\mmz at unexpanded|, to the correct thing, and use that
+% all the time.  I never tried this, but I find it ugly, too, and I guess I
+% would forget to use the new control sequence, anyway.  Option three: use
+% |\unexpanded| in the |.dtx|, and |sed| through the generated \hologo{ConTeXt}
+% files to replace all its occurrences by |\normalunexpanded|.  Oh yeah!
+% 
+% 
+% \paragraph.{Shipout}
+% We will next load our own auxiliary package, CollArgs, but before we do
+% that, we need to grab |\shipout| in \hologo{plainTeX}.  The problem is,
+% Memoize needs to hack into the shipout routine, but it has best chances
+% of working as intended if it redefines the \emph{primitive} |\shipout|.
+% However, CollArgs loads |pgfkeys|, which in turn (and perhaps with no for
+% reason) loads |atbegshi|, which redefines |\shipout|.  For details, see
+% section~\ref{sec:code:extern}.  Below, we first check that the current
+% meaning of |\shipout| is primitive, and then redefine it.
+% 
+%<*plain>
+\def\mmz at regular@shipout{%
+  \global\advance\mmzRegularPages1\relax
+  \mmz at primitive@shipout
+}
+\edef\mmz at temp{\string\shipout}%
+\edef\mmz at tempa{\meaning\shipout}%
+\ifx\mmz at temp\mmz at tempa
+  \let\mmz at primitive@shipout\shipout      
+  \let\shipout\mmz at regular@shipout
+\else
+  \PackageError{memoize}{Cannot grab \string\shipout, it is already redefined}{}%
+\fi
+%</plain>
+% Our auxiliary package (\MS\ref{sec:ref:collargs}, \S\ref{sec:code:collargs}).
+% We also need it in |nomemoize|, to collect manual environments.
+%<latex>\RequirePackage{advice}
+%<plain>\input advice
+%<context>\input t-advice
+%</mmz>
+% 
+% \paragraph.{Loading order} |memoize| and |nomemoize| are mutually exclusive,
+% and |memoizable| must be loaded before either of them.  |\mmz at loadstatus|: 1
+% = memoize, 2 = memoizable, 3 = nomemoize.
+%<*(plain,context)&(mmz,nommz,mmzable)>
+\def\ifmmz at loadstatus#1{%
+  \ifnum#1=0\csname mmz at loadstatus\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+%</(plain,context)&(mmz,nommz,mmzable)>
+%<*mmz>
+%<latex>\@ifpackageloaded{nomemoize}%
+%<plain,context>\ifmmz at loadstatus{3}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "nomemoize" is already
+    loaded. Memoization will NOT be in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+  %<latex>\pgfkeys{/memoize/package options/.unknown/.code={}}
+  %<latex>\ProcessPgfPackageOptions{/memoize/package options}
+    \endinput
+}{}%
+%<latex>\@ifpackageloaded{memoizable}%
+%<plain,context>\ifmmz at loadstatus{2}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded "memoizable";
+    please move
+    %<latex>"\string\usepackage{memoize}"
+    %<plain>"\string\input memoize"
+    %<context>"\string\usemodule[memoize]"
+    before the
+    %<latex>"\string\usepackage"
+    %<plain>"\string\input"
+    %<context>"\string\usemodule"
+    of that package.}%
+    %<latex>\pgfkeys{/memoize/package options/.unknown/.code={}}
+    %<latex>\ProcessPgfPackageOptions{/memoize/package options}
+  \endinput
+}{}%
+%<plain,context>\ifmmz at loadstatus{1}{\endinput}{}%
+%<plain,context>\def\mmz at loadstatus{1}%
+%</mmz>
+%<*mmzable>
+%<latex>\@ifpackageloaded{memoize}%
+%<plain,context>\ifmmz at loadstatus{1}%
+{\endinput}{}
+%<latex>\@ifpackageloaded{nomemoize}%
+%<plain,context>\ifmmz at loadstatus{3}%
+{\endinput}{}%
+%<plain,context>\ifmmz at loadstatus{2}{\endinput}{}%
+%<plain,context>\def\mmz at loadstatus{2}%
+%</mmzable>
+%<*nommz>
+%<latex>\@ifpackageloaded{memoize}
+%<plain,context>\ifmmz at loadstatus{1}%
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoize" is already
+    loaded; memoization will remain in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+  \endinput }{}%
+%<latex>\@ifpackageloaded{memoizable}%
+%<plain,context>\ifmmz at loadstatus{2}%
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  (No)Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded
+    "memoizable"; please move
+    %<latex>"\string\usepackage{nomemoize}"
+    %<plain>"\string\input memoize"
+    %<context>"\string\usemodule[memoize]"
+    before the
+    %<latex>"\string\usepackage"
+    %<plain>"\string\input"
+    %<context>"\string\usemodule"
+    of that package.}%
+  \endinput
+}{}%
+%<plain,context>\ifmmz at loadstatus{3}{\endinput}{}%
+%<plain,context>\def\mmz at loadstatus{3}%
+%</nommz>
+% 
+%<*mmz>
+% 
+% \begin{macro}{\filetotoks}
+%   Read \hologo{TeX} file |#2| into token register |#1| (under the current
+%   category code regime); |\toksapp| is defined in CollArgs.
+\def\filetotoks#1#2{%
+  \immediate\openin0{#2}%
+  #1={}%
+  \loop
+  \unless\ifeof0
+    \read0 to \totoks at temp
+    % We need the |\expandafter|s for our |\toksapp| macro.
+    \expandafter\toksapp\expandafter#1\expandafter{\totoks at temp}%
+  \repeat
+  \immediate\closein0
+}
+% \end{macro}
+% 
+% \paragraph{Other} little things.
+\newif\ifmmz at temp
+\newtoks\mmz at temptoks
+\newbox\mmz at box
+\newwrite\mmz at out
+% 
+% \section{The basic configuration}
+% \label{sec:code:configuration}
+% 
+% \begin{macro}{\mmzset}
+%   The user primarily interacts with |Memoize| through the |pgfkeys|-based
+%   configuration macro |\mmzset|, which executes keys in path |/mmz|.  In
+%   |nomemoize| and |memoizable|, is exists as a no-op.
+\def\mmzset#1{\pgfqkeys{/mmz}{#1}\ignorespaces}
+%</mmz>
+%<nommz,mmzable>\def\mmzset#1{\ignorespaces}
+% \end{macro}
+% 
+% \begin{macro}{\mmzset}
+%   Any |/mmz| keys used outside of |\mmzset| must be declared by this macro
+%   for |nomemoize| package to work.
+%<mmz>\def\nommzkeys#1{}
+%<*nommz,mmzable>
+\def\nommzkeys{\pgfqkeys{/mmz}}
+\pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}}
+%</nommz,mmzable>
+% \end{macro}
+% 
+% \begin{key}{enable, disable}
+% \begin{macro}{\ifmemoize}
+%   These keys set \hologo{TeX}-style conditional \cs{ifmemoize}, used as the
+%   central on/off switch for the functionality of the package --- it is
+%   inspected in |\Memoize| and by run conditions of automemoization handlers.
+%   
+%   If used in the preamble, the effect of these keys is delayed until the
+%   beginning of the document.  The delay is implemented through a special
+%   style, |begindocument|, which is executed at |begindocument| hook in
+%   \hologo{LaTeX}; in other formats, the user must invoke it manually
+%   (\MS\ref{sec:ref:loading}).
+%
+%   |Nomemoize| does not need the keys themselves, but it does need the
+%   underlying conditional --- which will be always false.
+%<mmz,nommz,mmzable>\newif\ifmemoize
+%<*mmz>
+\mmzset{%
+  enable/.style={begindocument/.append code=\memoizetrue},
+  disable/.style={begindocument/.append code=\memoizefalse},
+  begindocument/.append style={
+    enable/.code=\memoizetrue,
+    disable/.code=\memoizefalse,
+  },
+  % Memoize is enabled at the beginning of the document, unless explicitly
+  % disabled by the user in the preamble.
+  enable,
+}
+% \end{macro}
+% \end{key}
+% 
+% \begin{key}{normal,readonly,recompile}
+%   When Memoize is enabled, it can be in one of three modes
+%   (\MS\ref{sec:tut:working-on-a-picture}): normal, readonly, and recompile.
+%   The numeric constants are defined below.  The mode is stored in
+%   |\mmz at mode|, and only matters in |\Memoize| (and
+%   |\mmz at process@ccmemo|).\footnote{In fact, this code treats anything but 1
+%   and 2 as normal.}
+\def\mmz at mode@normal{0}
+\def\mmz at mode@readonly{1}
+\def\mmz at mode@recompile{2}
+\let\mmz at mode\mmz at mode@normal
+\mmzset{%
+  normal/.code={\let\mmz at mode\mmz at mode@normal},
+  readonly/.code={\let\mmz at mode\mmz at mode@readonly},
+  recompile/.code={\let\mmz at mode\mmz at mode@recompile},
+}
+% \end{key}
+% 
+% \begin{key}{path, path/relative, path/dir, path/prefix}
+%   Key |path| executes the given keylist in path |/mmz/path|, to determine the
+%   full \emph{path prefix} to memo and extern files
+%   (\MS\ref{sec:tut:memodir},\ref{sec:memos}): |relative|, true by default,
+%   determines whether the location of these files is relative to the current
+%   directory; |dir| sets their directory; and |prefix| sets the first, fixed
+%   part of their basename; the second part containing the MD5 sum(s) is not
+%   under user control, and neither is the suffix.  These subkeys will be
+%   initialized a bit later, via |no memo dir|.
+\mmzset{%
+  path/.code={\pgfqkeys{/mmz/path}{#1}},
+  path/.cd,
+  relative/.is if=mmz at relativepath,
+  dir/.store in=\mmz at dir,
+  dir/.value required,
+  prefix/.store in=\mmz at prefix,
+  prefix/.value required,
+}
+\newif\ifmmz at relativepath
+% Key |path| concludes by performing two post-path-setting actions: creating
+% the given directory if |mkdir| is in effect, and noting the new path prefix
+% in record files (by eventually executing |record/prefix|, which typically
+% puts a |\mmzPrefix| line in the |.mmz| file).  These actions are the reason
+% for having the path setting keys grouped under |path| --- we don't want them
+% to be triggered by changes of the individual components of the path.
+% Similarly, we don't want them triggered by multiple invocations of |path| in
+% the preamble; only the final setting matters, so |path| is only equipped with
+% the action-triggering code at the beginning of the document.
+\mmzset{%
+  begindocument/.append style={
+    path/.append code=\mmz at maybe@mkmemodir\mmz at record@prefix,
+  },
+  % Consequently, the post-path-setting actions must be triggered manually at
+  % the beginning of the document.  Below, we trigger directory creation;
+  % |record/prefix| will be called from |record/begin|, which is executed at
+  % the beginning of the document, so it shouldn't be mentioned here.
+  begindocument/.append code=\mmz at maybe@mkmemodir,
+}
+% Define the paths to the memo directory and the prefix.
+\def\mmz at dir@path{\ifmmz at relativepath.\fi/\mmz at dir}
+\def\mmz at prefix@path{\mmz at dir@path/\mmz at prefix}
+% \end{key}
+% 
+% \begin{key}{mkdir, mkdir command}
+%   Should we create the memo/extern directory if it doesn't exist?  And which
+%   command should we use to create it?  Of course, shell escape must be
+%   properly configured for this to work (\MS\ref{sec:shell-escape}).
+%   ^^A todo: What about quoting the paths containing spaces on Windows? Will this work?
+\mmzset{
+  mkdir/.is if=mmz at mkdir,
+  mkdir command/.code={\def\mmz at mkdir@command##1{#1}},
+  mkdir command={mkdir "#1"},
+}
+% The underlying conditional \cs{ifmmz at mkdir} is only ever used in
+% |\mmz at maybe@mkmemodir| below, which is itself only executed at the end of
+% |path| and in |begindocument|.
+\newif\ifmmz at mkdir
+\def\mmz at maybe@mkmemodir{%
+  \ifmmz at mkdir
+    \pdf at system{\mmz at mkdir@command{\mmzOutputDirectory\mmz at dir@path}}%
+  \fi
+}
+% \end{key}
+% 
+% \begin{key}{memo dir, no memo dir}
+%   Shortcuts for two common settings of |path| keys.  The default |no memo
+%   dir| will place the memos and externs in the current directory, prefixed
+%   with |#1.|, where |#1| defaults to (unquoted) |\jobname|.  Key |memo dir|
+%   places the memos and externs in a dedicated directory, |#1.memo.dir|; the
+%   filenames themselves have no prefix.  Furthermore, |memo dir| triggers the
+%   creation of the directory.
+\mmzset{%
+  memo dir/.style={
+    mkdir,
+    path={
+      relative,
+      dir={#1.memo.dir},
+      prefix={},
+    },
+  },
+  memo dir/.default=\mmzUnquote\jobname,
+  no memo dir/.style={
+    mkdir=false,
+    path={
+      relative,
+      dir={},
+      prefix={#1.},
+    },
+  },
+  no memo dir/.default=\mmzUnquote\jobname,
+  no memo dir,
+}
+% \end{key}
+%   
+% \begin{macro}{\mmzUnquote}
+%   If the expanded argument is surrounded by double quotes, remove them. This
+%   relies on |#1| containing no quotes other than the potential surrounding
+%   quotes, which should be the case when applying the macro to |\jobname|.  An
+%   empty |#1| is dealt with correctly, even if |\jobname| can hardly ever be
+%   empty (needs |openout_any=a|).
+% 
+%   We use this macro when we are passing a filename constructed from
+%   |\jobname| to external programs.
+\def\mmzUnquote#1{\expanded{\noexpand\mmz at unquote#1}\mmz at unquote@end}
+\def\mmz at unquote#1{%
+  \ifx\mmz at unquote@end#1%
+  \else
+    \ifx"#1%
+      \expandafter\expandafter\expandafter\mmz at unquote@quotes
+    \else
+      \expandafter\expandafter\expandafter\mmz at unquote@noquotes
+      \expandafter\expandafter\expandafter#1%
+    \fi
+  \fi
+}
+\def\mmz at unquote@quotes#1"\mmz at unquote@end{#1}
+\def\mmz at unquote@noquotes#1\mmz at unquote@end{#1}
+% \end{macro}
+% 
+% \begin{key}{ignore spaces}
+%   The underlying conditional will be inspected by automemoization handlers,
+%   to maybe put |\ignorespaces| after the invocation of the handler.
+\newif\ifmmz at ignorespaces
+\mmzset{
+  ignore spaces/.is if=mmz at ignorespaces,
+}
+% \end{key}
+% 
+% \begin{key}{verbatim, verb, no verbatim}
+%   These keys are tricky.  For one, there's |verbatim|, which sets all
+%   characters' category codes to other, and there's |verb|, which leaves
+%   braces untouched (well, honestly, it redefines them).  But Memoize itself
+%   doesn't really care about this detail --- it only uses the underlying
+%   conditional \cs{ifmmz at verbatim}.  It is CollArgs which cares about the
+%   difference between the ``long'' and the ``short'' verbatim, so we need to
+%   tell it about it.  That's why the verbatim options ``append themselves'' to
+%   |\mmzRawCollectorOptions|, which is later passed on to
+%   |\CollectArgumentsRaw| as a part of its optional argument.
+\newif\ifmmz at verbatim
+\def\mmzRawCollectorOptions{}
+\mmzset{
+  verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerbatim}%
+    \mmz at verbatimtrue
+  },
+  verb/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerb}%
+    \mmz at verbatimtrue
+  },
+  no verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsNoVerbatim}%
+    \mmz at verbatimfalse
+  },
+}
+% \end{key}
+% \section{Memoization}
+% \label{sec:code:memoization}
+% 
+% \subsection{Manual memoization}
+% \label{sec:code:memoization:manual}
+% 
+% \begin{macro}{\mmz}
+%   The core of this macro will be a simple invocation of |\Memoize|, but to
+%   get there, we have to collect the optional argument carefully, because we
+%   might have to collect the memoized code verbatim.
+\protected\def\mmz{\futurelet\mmz at temp\mmz at i}
+\def\mmz at i{%
+  % Anyone who wants to call |\Memoize| must open a group, because |\Memoize|
+  % will close a group.
+  \begingroup
+  % As the optional argument occurs after a control sequence (|\mmz|), any
+  % spaces were consumed and we can immediately test for the opening bracket.
+  \ifx\mmz at temp[%]
+    \def\mmz at verbatim@fix{}%
+    \expandafter\mmz at ii
+  \else
+    % If there was no optional argument, the opening brace (or the unlikely
+    % single token) of our mandatory argument is already tokenized.  If we are
+    % requested to memoize in a verbatim mode, this non-verbatim tokenization
+    % was wrong, so we will use option |\collargsFixFromNoVerbatim| to ask
+    % CollArgs to fix the situation.  (|\mmz at verbatim@fix| will only be used in
+    % the verbatim mode.)
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+    % No optional argument, so we can skip |\mmz at ii|.
+    \expandafter\mmz at iii
+  \fi
+}
+\def\mmz at ii[#1]{%
+  % Apply the options given in the optional argument.
+  \mmzset{#1}%
+  \mmz at iii
+}
+\def\mmz at iii{%
+  % In the non-verbatim mode, we avoid collecting the single mandatory argument
+  % using |\CollectArguments|.
+  \ifmmz at verbatim
+    \expandafter\mmz at do@verbatim
+  \else
+    \expandafter\mmz at do
+  \fi
+}
+% This macro grabs the mandatory argument of |\mmz| and calls |\Memoize|.
+\long\def\mmz at do#1{%
+  \Memoize{#1}{#1}%
+}%
+% 
+% The following macro uses |\CollectArgumentsRaw| of package CollArgs
+% (\S\ref{sec:code:collargs}) to grab the argument verbatim; the appropriate
+% verbatim mode triggering raw option was put in |\mmzRawCollectorOptions| by
+% key |verb(atim)|.  The macro also |\mmz at verbatim@fix| contains the potential
+% request for a category code fix (\S\ref{sec:code:collargs:fix}).
+\def\mmz at do@verbatim#1{%
+  \expanded{%
+    \noexpand\CollectArgumentsRaw{%
+      \noexpand\collargsCaller{\noexpand\mmz}%
+      \expandonce\mmzRawCollectorOptions
+      \mmz at verbatim@fix
+    }%
+  }{+m}\mmz at do
+}
+% \end{macro}
+% 
+% \begin{environment}{memoize}
+%   The definition of the manual memoization environment proceeds along the
+%   same lines as the definition of |\mmz|, except that we also have to
+%   implement space-trimming, and that we will collect the environment using
+%   |\CollectArguments| in both the verbatim and the non-verbatim and mode.
+% 
+%   We define the \hologo{LaTeX}, \hologo{plainTeX} and \hologo{ConTeXt}
+%   environments in parallel.  The definition of the \hologo{plainTeX} and
+%   \hologo{ConTeXt} version is complicated by the fact that space-trimming is
+%   affected by the presence vs.\ absence of the optional argument (for
+%   purposes of space-trimming, it counts as present even if it is empty).
+%<*latex>
+% We define the \hologo{LaTeX} environment using |\newenvironment|, which
+% kindly grabs any spaces in front of the optional argument, if it exists ---
+% and if doesn't, we want to trim spaces at the beginning of the environment
+% body anyway.
+\newenvironment{memoize}[1][\mmz at noarg]{%
+  % We close the environment right away.  We'll collect the environment body,
+  % complete with the end-tag, so we have to reintroduce the end-tag somewhere.
+  % Another place would be after the invocation of |\Memoize|, but that would
+  % put memoization into a double group and |\mmzAfterMemoization| would not work.
+  \end{memoize}%
+  % % We open the group which will be closed by |\Memoize|.
+  \begingroup
+  % As with |\mmz| above, if there was no optional argument, we have to ask
+  % Collargs for a fix.  The difference is that, as we have collected the
+  % optional argument via |\newcommand|, we have to test for its presence in a
+  % roundabout way.
+  \def\mmz at temp{#1}%
+  \ifx\mmz at temp\mmz at noarg
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+  \else
+    \def\mmz at verbatim@fix{}%
+    \mmzset{#1}%
+  \fi
+  \mmz at env@iii
+}{}
+\def\mmz at noarg{\mmz at noarg}
+%</latex>
+%<plain>\def\memoize{%
+%<context>\def\startmemoize{%
+%<*plain,context>
+  \begingroup
+  % In \hologo{plainTeX} and \hologo{ConTeXt}, we don't have to worry about any
+  % spaces in front of the optional argument, as the environments are opened by
+  % a control sequence.
+  \futurelet\mmz at temp\mmz at env@i
+}
+\def\mmz at env@i{%
+  \ifx\mmz at temp[%]
+    \def\mmz at verbatim@fix{}%
+    \expandafter\mmz at env@ii
+  \else
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+    \expandafter\mmz at env@iii
+  \fi
+}
+\def\mmz at env@ii[#1]{%
+  \mmzset{#1}%
+  \mmz at env@iii
+}
+%</plain,context>
+\def\mmz at env@iii{%
+  \long\edef\mmz at do##1{%
+    % |\unskip| will ``trim'' spaces at the end of the environment body.
+    \noexpand\Memoize{##1}{##1\unskip}%
+  }%
+  \expanded{%
+    \noexpand\CollectArgumentsRaw{%
+      % |\CollectArgumentsRaw| will adapt the caller to the format automatically.
+      \noexpand\collargsCaller{memoize}%
+      % |verb(atim)| is in here if it was requested.
+      \expandonce\mmzRawCollectorOptions
+      % The category code fix, if needed.
+      \ifmmz at verbatim\mmz at verbatim@fix\fi
+    }%
+    % Spaces at the beginning of the environment body are trimmed by setting
+    % the first argument to |!t<space>| and disappearing it with
+    % |\collargsAppendPostwrap{}|; note that this removes any number of space
+    % tokens.  |\CollectArgumentsRaw| automatically adapts the argument type
+    % |b| to the format.
+    % 
+  }{&&{\collargsAppendPostwrap{}}!t{ }+b{memoize}}{\mmz at do}%
+}%
+%</mmz>
+% \end{environment}
+% 
+% \begin{macro}{\nommz}
+%   We throw away the optional argument if present, and replace the opening
+%   brace with begin-group plus |\memoizefalse|.  This way, the ``argument'' of
+%   |\nommz| will be processed in a group (with Memoize disabled) and even the
+%   verbatim code will work because the ``argument'' will not have been
+%   tokenized.
+% 
+%   As a user command, |\nommz| has to make it into package |nomemoize| as
+%   well, and we'll |\let| |\mmz| equal it there; it is not needed in
+%   |mmzable|.
+%<*mmz,nommz>
+\protected\def\nommz#1#{%
+  \afterassignment\nommz at i
+  \let\mmz at temp
+}
+\def\nommz at i{%
+  \bgroup
+  \memoizefalse
+}
+%<nommz>\let\mmz\nommz
+% \end{macro}
+% 
+% \begin{environment}{nomemoize}
+%   We throw away the optional argument and take care of the spaces at the
+%   beginning and at the end of the body.
+%<*latex>
+\newenvironment{nomemoize}[1][]{%
+  \memoizefalse
+  \ignorespaces
+}{%
+  \unskip
+}
+%</latex>
+%<*plain,context>
+%<plain>\def\nomemoize{%
+%<context>\def\startnomemoize{%
+% Start a group to delimit |\memoizefalse|.
+  \begingroup
+  \memoizefalse
+  \futurelet\mmz at temp\nommz at env@i
+}
+\def\nommz at env@i{%
+  \ifx\mmz at temp[%]
+    \expandafter\nommz at env@ii
+    % No optional argument, no problems with spaces.
+  \fi
+}
+\def\nommz at env@ii[#1]{%
+  \ignorespaces
+}
+%<plain>\def\endnomemoize{%
+%<context>\def\stopnomemoize{%
+  \endgroup
+  \unskip
+}
+%</plain,context>
+%<*nommz>
+%<plain,latex>\let\memoize\nomemoize
+%<plain,latex>\let\endmemoize\endnomemoize
+%<context>\let\startmemoize\startnomemoize
+%<context>\let\stopmemoize\stopnomemoize
+%</nommz>
+% \end{environment}
+% 
+% \subsection{The memoization process}
+% \label{sec:code:memoization-process}
+% 
+% \begin{macro}{\ifmemoizing}
+%     This conditional is set to true when we start memoization (but not when
+%     we start regular compilation or utilization); it should never be set
+%     anywhere else.  It is checked by |\Memoize| to prevent nested
+%     memoizations, deployed in advice run conditions set by |run only if
+%     memoizing|, etc.
+\newif\ifmemoizing
+% \end{macro}
+% 
+% \begin{macro}{\ifinmemoize}
+%     This conditional is set to true when we start either memoization or
+%     regular compilation (but not when we start utilization); it should never
+%     be set anywhere else.  It is deployed in the default advice run conditions,
+%     making sure that automemoized commands are not handled even when we're
+%     regularly compiling some code submitted to memoization.
+\newif\ifinmemoize
+% \end{macro}
+%
+% \begin{macro}{\mmz at maybe@scantokens}
+%   An auxiliary macro which rescans the given
+%   code using |\scantokens| if the verbatim mode is active.  We also need it
+%   in NoMemoize, to properly grab verbatim manually memoized code.
+%</mmz,nommz>
+%<*mmz>
+\def\mmz at maybe@scantokens{%
+  \ifmmz at verbatim
+    \expandafter\mmz at scantokens
+  \else
+    \expandafter\@firstofone
+  \fi
+}
+% Without |\newlinechar=13|, |\scantokens| would see receive the entire
+% argument as one long line --- but it would not \emph{see} the entire
+% argument, but only up to the first newline character, effectively losing most
+% of the tokens.  (We need to manually save and restore |\newlinechar| because
+% we don't want to execute the memoized code in yet another group.)
+\long\def\mmz at scantokens#1{%
+  \expanded{%
+    \newlinechar=13
+    \unexpanded{\scantokens{#1\endinput}}%
+    \newlinechar=\the\newlinechar
+  }%
+}
+% \end{macro}
+% 
+% \begin{macro}{\Memoize}
+%   Memoization is invoked by executing |\Memoize|.  This macro is a decision
+%   hub.  It test for the existence of the memos and externs associated with
+%   the memoized code, and takes the appropriate action (memoization:
+%   |\mmz at memoize|; regular compilation: |\mmz at compile|, utilization:
+%   |\mmz at process@cmemo| plus |\mmz at process@ccmemo| plus further complications)
+%   depending on the memoization mode (normal, readonly, recompile).  Note that
+%   one should open a \hologo{TeX} group prior to executing |\Memoize|, because
+%   |\Memoize| will close a group (\MS\ref{sec:Memoize}).
+% 
+%   |\Memoize| takes two arguments, which contain two potentially different
+%   versions of the code submitted to memoization: |#1| contains the code which
+%   \meta{code MD5 sum} is computed off of, while |#2| contains the code which
+%   is actually executed during memoization and regular compilation.  The
+%   arguments will contain the same code in the case of manual memoization, but
+%   they will differ in the case of automemoization, where the executable code
+%   will typically prefixed by |\AdviceOriginal|.  As the two
+%   codes will be used not only by |\Memoize| but also by macros called from
+%   |\Memoize|, |\Memoize| stores them into dedicated toks registers, declared
+%   below.
+\newtoks\mmz at mdfive@source
+\newtoks\mmz at exec@source
+% Finally, the definition of the macro.  In package NoMemoize, we should simply
+% execute the code in the second argument.  But in Memoize, we have work to do.
+\let\Memoize\@secondoftwo
+\long\def\Memoize#1#2{%
+  % We store the first argument into token register |\mmz at mdfive@source|
+  % because we might have to include it in tracing info (when |trace| is in
+  % effect), or paste it into the c-memo (depending on |include source in
+  % cmemo|).
+  \mmz at mdfive@source{#1}%
+  % We store the executable code in |\mmz at exec@source|.  In the verbatim mode,
+  % the code will have to be rescanned.  This is implemented by
+  % |\mmz at maybe@scantokens|, and we wrap the code into this macro right away,
+  % once and for all.  Even more, we pre-expand |\mmz at maybe@scantokens| (three
+  % times), effectively applying the current \cs{ifmmz at verbatim} and
+  % eliminating the need to save and restore this conditional in
+  % |\mmz at compile|, which (regularly) compiles the code \emph{after} closing
+  % the |\Memoize| group --- after this pre-expansion, |\mmz at exec@source| will
+  % contain either |\mmz at scantokens{...}| or |\@firstofone{...}|.
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  \mmz at exec@source
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  {%
+    \mmz at maybe@scantokens{#2}%
+  }%
+  \mmz at trace@Memoize
+  % In most branches below, we end up with regular compilation, so let this be
+  % the default action.
+  \let\mmz at action\mmz at compile
+  % If Memoize is disabled, or if memoization is currently taking place, we
+  % will perform a regular compilation.
+  \ifmemoizing
+  \else
+    \ifmemoize
+      % Compute \meta{code md5sum} off of the first argument, and globally
+      % store it into |\mmz at code@mdfivesum| --- globally, because we need it in
+      % utilization to include externs, but the |\Memoize| group is closed (by
+      % |\mmzMemo|) while inputting the cc-memo.  
+      \xdef\mmz at code@mdfivesum{\pdf at mdfivesum{\the\mmz at mdfive@source}}%
+      \mmz at trace@code at mdfive
+      % Recompile mode forces memoization.
+      \ifnum\mmz at mode=\mmz at mode@recompile\relax
+        \ifnum\pdf at draftmode=0
+          \let\mmz at action\mmz at memoize
+        \fi
+      \else
+        % In the normal and the readonly mode, we try to utilize the memos. The
+        % c-memo comes first.  If the c-memo does not exist (or if something is
+        % wrong with it), |\mmz at process@cmemo| (defined in
+        % \S\ref{sec:code:c-memo}) will set |\ifmmz at abort| to true.  It might
+        %   also set |\ifmmzUnmemoizable| which means we should compile normally
+        %     regardless of the mode.
+        \mmz at process@cmemo
+        \ifmmzUnmemoizable
+          \mmz at trace@cmemo at unmemoizable
+        \else
+          \ifmmz at abort
+            % If there is no c-memo, or it is invalid, we memoize, unless the
+            % read-only mode is in effect.
+            \mmz at trace@process at cmemo@fail
+            \ifnum\mmz at mode=\mmz at mode@readonly\relax
+            \else
+              \ifnum\pdf at draftmode=0
+                \let\mmz at action\mmz at memoize
+              \fi
+            \fi
+          \else
+            \mmz at trace@process at cmemo@ok
+            % If the c-memo was fine, the formal action decided upon is to try
+            % utilizing the cc-memo.  If it exists and everything is fine with
+            % it, |\mmz at process@ccmemo| (defined in
+            % section~\ref{sec:code:cc-memo}) will utilize it, i.e.\ the core
+            % of the cc-memo (the part following |\mmzMemo|) will be executed
+            % (typically including the single extern).  Otherwise,
+            % |\mmz at process@ccmemo| will trigger either memoization (in the
+            % normal mode) or regular compilation (in the readonly mode).  This
+            % final decision is left to |\mmz at process@ccmemo| because if we
+            % made it here, the code would get complicated, as the cc-memo must
+            % be processed outside the |\Memoize| group and all the
+            % conditionals in this macro.
+            \let\mmz at action\mmz at process@ccmemo
+          \fi
+        \fi
+      \fi
+    \fi
+  \fi
+  \mmz at action
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmz at compile}
+%   This macro performs regular compilation --- this is signalled to the
+%   memoized code and the memoization driver by setting \cs{ifinmemoize} to
+%   true for the duration of the compilation; \cs{ifmemoizing} is not touched.
+%   The group opened prior to the invocation of |\Memoize| is closed before
+%   executing the code in |\mmz at exec@source|, so that compiling the code has
+%   the same local effect as if was not submitted to memoization; it is closing
+%   this group early which complicates the restoration of \cs{ifinmemoize} at
+%   the end of compilation.  Note that |\mmz at exec@source| is already set to
+%   properly deal with the current verbatim mode, so any further inspection of
+%   \cs{ifmmz at verbatim} is unnecessary; the same goes for
+%   \cs{ifmmz at ignorespaces}, which was (or at least should be) taken care of by
+%   whoever called |\Memoize|.
+\def\mmz at compile{%
+  \mmz at trace@compile
+  \expanded{%
+    \endgroup
+    \noexpand\inmemoizetrue
+    \the\mmz at exec@source
+    \ifinmemoize\noexpand\inmemoizetrue\else\noexpand\inmemoizefalse\fi
+  }%
+}
+% \end{macro}
+% \begin{luafun}{abortOnError}
+%   \begin{macro}{\mmz at lua@atbeginmemoization,\mmz at lua@atendmemoization}
+%     In \hologo{LuaTeX}, we can whether an error occurred during memoization,
+%     and abort if it did.  (We're going through |memoize.abort|, because
+%     |tex.print| does not seem to work during error handling.)  We omit all
+%     this in \hologo{ConTeXt}, as it appears to stop on any error?
+%<*!context>
+\ifdefined\luatexversion
+  \directlua{%
+    luatexbase.add_to_callback(
+      "show_error_message",
+      function()
+        memoize.abort = true
+        texio.write_nl(status.lasterrorstring)
+      end,
+      "Abort memoization on error"
+    )
+  }%
+  \def\mmz at lua@atbeginmemoization{%
+    \directlua{memoize.abort = false}%
+  }%
+  \def\mmz at lua@atendmemoization{%
+    \directlua{%
+      if memoize.abort then
+        tex.print("\noexpand\\mmzAbort")
+      end
+    }%
+  }%
+\else
+%</!context>
+  \let\mmz at lua@atbeginmemoization\relax
+  \let\mmz at lua@atendmemoization\relax
+%<!context>\fi
+%   \end{macro}
+% \end{luafun}
+% \begin{macro}{\mmz at memoize}
+%   This macro performs memoization --- this is signalled to the memoized code
+%   and the memoization driver by setting both \cs{ifinmemoize} and
+%   \cs{ifinmemoizing} to true.
+\def\mmz at memoize{%
+  \mmz at trace@memoize
+  \memoizingtrue
+  \inmemoizetrue
+  % Initialize the various macros and registers used in memoization (to be
+  % described below, or later).  Note that most of these are global, as they
+  % might be adjusted arbitrarily deep within the memoized code.
+  \edef\memoizinggrouplevel{\the\currentgrouplevel}%
+  \global\mmz at abortfalse
+  \global\mmzUnmemoizablefalse
+  \global\mmz at seq 0
+  \global\setbox\mmz at tbe@box\vbox{}%
+  \global\mmz at ccmemo@resources{}%
+  \global\mmzCMemo{}%
+  \global\mmzCCMemo{}%
+  \global\mmzContextExtra{}%
+  \gdef\mmzAtEndMemoizationExtra{}%
+  \gdef\mmzAfterMemoizationExtra{}%
+  \mmz at lua@atbeginmemoization
+  % Execute the pre-memoization hook, the memoized code (wrapped in the
+  % driver), and the post-memoization hook.
+  \mmzAtBeginMemoization
+  \mmzDriver{\the\mmz at exec@source}%
+  \mmzAtEndMemoization
+  \mmzAtEndMemoizationExtra
+  \mmz at lua@atendmemoization
+  \ifmmzUnmemoizable
+    % To permanently prevent memoization, we have to write down the c-memo
+    % (containing |\mmzUnmemoizabletrue|).  We don't need the extra context in
+    % this case.
+    \global\mmzContextExtra{}%
+    \gtoksapp\mmzCMemo{\global\mmzUnmemoizabletrue}%
+    \mmz at write@cmemo
+    \mmz at trace@endmemoize at unmemoizable
+    \PackageWarning{memoize}{Marking this code as unmemoizable}%
+  \else
+    \ifmmz at abort
+      % If memoization was aborted, we create an empty c-memo, to make sure that
+      % no leftover c-memo tricks Memoize into thinking that the code was
+      % successfully memoized.
+      \mmz at trace@endmemoize at aborted
+      \PackageWarning{memoize}{Memoization was aborted}%
+      \mmz at write@empty at cmemo
+    \else
+      % If memoization was not aborted, we compute the \meta{context md5sum},
+      % open and write out the memos, and shipout the externs (as pages into the
+      % document).
+      \mmz at compute@context at mdfivesum
+      \mmz at write@cmemo
+      \mmz at write@ccmemo
+      \mmz at shipout@externs
+      \mmz at trace@endmemoize at ok
+    \fi
+  \fi
+  % After closing the group, we execute the final, after-memoization hook (we
+  % pre-expand the regular macro; the extra macro was assigned to globally). In
+  % the after-memoization code, |\mmzIncludeExtern| points to a macro which can
+  % include the extern from |\mmz at tbe@box|, which makes it possible to typeset
+  % the extern by dropping the contents of |\mmzCCMemo| into this hook --- but
+  % note that this will only work if |\ifmmzkeepexterns| was in effect at the
+  %   end of memoization.
+  \expandafter\endgroup
+  \expandafter\let
+    \expandafter\mmzIncludeExtern\expandafter\mmz at include@extern at from@tbe at box
+  \mmzAfterMemoization
+  \mmzAfterMemoizationExtra
+}
+% \end{macro}
+% 
+% \begin{macro}{\memoizinggrouplevel}
+%   This macro stores the group level at the beginning of memoization.  It is
+%   deployed by |\IfMemoizing|, normally used by integrated drivers.
+\def\memoizinggrouplevel{-1}%
+% \end{macro}
+% 
+% \begin{macro}{\mmzAbort}
+% Memoized code may execute this macro to abort memoization.
+\def\mmzAbort{\global\mmz at aborttrue}
+% \end{macro}
+% 
+% \begin{macro}{\ifmmz at abort}
+%     This conditional serves as a signal that something went wrong during
+%     memoization (where it is set to true by |\mmzAbort|), or c(c)-memo
+%     processing.  The assignment to this conditional should always be global
+%     (because it may be set during memoization).
+\newif\ifmmz at abort
+% \end{macro}
+% 
+% \begin{macro}{\mmzUnmemoizable}
+%   Memoized code may execute |\mmzUnmemoizable| to abort memoization and mark
+%   (in the c-memo) that memoization should never be attempted again.  The
+%   c-memo is composed by |\mmz at memoize|.
+\def\mmzUnmemoizable{\global\mmzUnmemoizabletrue}
+% \end{macro}
+% 
+% \begin{macro}{\ifmmzUnmemoizable}
+%     This conditional serves as a signal that the code should never be
+%     memoized.  It can be set (a) during memoization (that's why it should be
+%     assigned globally), after which it is inspected by |\mmz at memoize|, and
+%     (b) from the c-memo, in which case it is inspected by |\Memoize|.
+\newif\ifmmzUnmemoizable
+% \end{macro}
+% 
+% \begin{macro}{\mmzAtBeginMemoization,\mmzAtEndMemoization,\mmzAfterMemoization}
+%   \begin{key}{at begin memoization, at end memoization, after memoization}
+%     The memoization hooks and their keys.  The hook macros may be set either
+%     before or during memoization.  In the former case, one should modify the
+%     primary macro (|\mmzAtBeginMemoization|, |\mmzAtEndMemoization|,
+%     |\mmzAfterMemoization|), and the assignment should be local.  In the
+%     latter case, one should modify the extra macro
+%     (|\mmzAtEndMemoizationExtra|, |\mmzAfterMemoizationExtra|; there is no
+%     |\mmzAtBeginMemoizationExtra|), and the assignment should be global.  The
+%     keys automatically adapt to the situation, by appending either to the
+%     primary or the the extra macro; if |at begin memoization| is used during
+%     memoization, the given code is executed immediately.  We will use this
+%     ``extra'' approach and the auto-adapting keys for other options, like
+%     |context|, as well.
+\def\mmzAtBeginMemoization{}
+\def\mmzAtEndMemoization{}
+\def\mmzAfterMemoization{}
+\mmzset{
+  at begin memoization/.code={%
+    \ifmemoizing
+      \expandafter\@firstofone
+    \else
+      \expandafter\appto\expandafter\mmzAtBeginMemoization
+    \fi
+    {#1}%
+  },
+  at end memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAtEndMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAtEndMemoization
+    \fi
+    {#1}%
+  },
+  after memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAfterMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAfterMemoization
+    \fi
+    {#1}%
+  },
+}
+% \end{key}
+% \end{macro}
+%
+% \begin{key}{driver}
+%   This key sets the (formal) memoization driver.  The function of the driver
+%   is to produce the memos and externs while executing the submitted code.
+\mmzset{
+  driver/.store in=\mmzDriver,
+  driver=\mmzSingleExternDriver,
+}
+% \end{key}
+% 
+% \begin{macro}{\ifmmzkeepexterns}
+%     This conditional causes Memoize not to empty out |\mmz at tbe@box|, holding
+%     the externs collected during memoization, while shipping them out.
+\newif\ifmmzkeepexterns
+% \end{macro}
+% 
+% \begin{macro}{\mmzSingleExternDriver}
+%   The default memoization driver externalizes the submitted code.  It always
+%   produces exactly one extern, and including the extern will be the only
+%   effect of inputting the cc-memo (unless the memoized code contained some
+%   commands, like |\label|, which added extra instructions to the cc-memo.)
+%   The macro (i) adds |\quitvmode| to the cc-memo, if we're capturing into a
+%   horizontal box, and it puts it to the very front, so that it comes before
+%   any |\label| and |\index| replications, guaranteeing (hopefully) that they
+%   refer to the correct page; (ii) takes the code and typesets it in a box
+%   (|\mmz at box|); (iii) submits the box for externalization; (iv) adds the
+%   extern-inclusion code to the cc-memo, and (v) puts the box into the
+%   document (again prefixing it with |\quitvmode| if necessary).  (The listing
+%   region markers help us present this code in the manual.)
+%   \begin{listingregion}{single-extern-driver.tex}
+\long\def\mmzSingleExternDriver#1{%
+  \xtoksapp\mmzCCMemo{\mmz at maybe@quitvmode}%
+  \setbox\mmz at box\mmz at capture{#1}%
+  \mmzExternalizeBox\mmz at box\mmz at temptoks
+  \xtoksapp\mmzCCMemo{\the\mmz at temptoks}%
+  \mmz at maybe@quitvmode\box\mmz at box
+}
+%   \end{listingregion}
+% \end{macro}
+% 
+% \begin{key}{capture}
+%   The default memoization driver uses |\mmz at capture| and
+%   |\mmz at maybe@quitvmode|, which are set by this key.  |\mmz at maybe@quitvmode|
+%   will be expanded, but for \hologo{XeTeX}, we have defined |\quitvmode| as a
+%   synonym for |\leavevmode|, which is a macro rather than a primitive, so we
+%   have to prevent its expansion in that case.  It is easiest to just add
+%   |\noexpand|, regardless of the engine used.
+\mmzset{
+  capture/.is choice,
+  capture/hbox/.code={%
+    \let\mmz at capture\hbox
+    \def\mmz at maybe@quitvmode{\noexpand\quitvmode}%
+  },
+  capture/vbox/.code={%
+    \let\mmz at capture\vbox
+    \def\mmz at maybe@quitvmode{}%
+  },
+  capture=hbox,
+}
+% \end{key}
+% The memoized code may be memoization-aware; in such a case, we say that the
+% driver is \emph{integrated} into the code.  Code containing an integrated
+% driver must take care to execute it only when memoizing, and not during a
+% regular compilation.  The following key and macro can help here, see
+% \MS\ref{sec:memoization-complex-single-driver} for details.
+% 
+% \begin{mmzautokey}{integrated driver}
+%   This is an advice key, residing in |/mmz/auto|.  Given \meta{suffix} as the
+%   only argument, it declares conditional \cs{ifmemoizing}\meta{suffix}, and
+%   sets the driver for the automemoized command to a macro which sets this
+%   conditional to true.  The declared conditional is \emph{internal} and
+%   should not be used directly, but only via |\IfMemoizing| --- because it
+%   will not be declared when package NoMemoize or only Memoizable is loaded.
+\mmzset{
+  auto/integrated driver/.style={
+    after setup={\expandafter\newif\csname ifmmz at memoizing#1\endcsname},
+    driver/.expand once={%
+      \csname mmz at memoizing#1true\endcsname
+      % Without this, we would introduce an extra group around the memoized
+      % code.
+      \@firstofone
+    }%
+  },
+}
+% \end{mmzautokey}
+% 
+% \begin{macro}{\IfMemoizing}
+%   Without the optional argument, the condition is satisfied when the internal
+%   conditional \cs{ifmemoizing}\meta{suffix}, declared by |integrated driver|,
+%   is true.  With the optional argument \meta{offset}, the current group level
+%   must additionally match the memoizing group level, modulo \meta{offset} ---
+%   this makes sure that the conditional comes out as false in a regular
+%   compilation embedded in a memoization.
+\newcommand\IfMemoizing[2][\mmz at Ifmemoizing@nogrouplevel]{%>\fi
+\csname ifmmz at memoizing#2\endcsname%>\if
+  % One |\relax| is for the |\numexpr|, another for |\ifnum|.  Complications
+  %   arise when |#1| is the optional argument default (defined below).  In
+  %   that case, the content of |\mmz at Ifmemoizing@nogrouplevel| closes off the
+  %   |\ifnum| conditional (with both the true and the false branch empty), and
+  %     opens up a new one, |\iftrue|.  Effectively, we're not testing for the
+  %       group level match.
+  \ifnum\currentgrouplevel=\the\numexpr\memoizinggrouplevel+#1\relax\relax
+    \expandafter\expandafter\expandafter\@firstoftwo
+  \else
+    \expandafter\expandafter\expandafter\@secondoftwo
+  \fi
+\else
+  \expandafter\@secondoftwo
+\fi
+}
+\def\mmz at Ifmemoizing@nogrouplevel{0\relax\relax\fi\iftrue}
+% \end{macro}
+% 
+% \paragraph.{Tracing} We populate the hooks which send the tracing info to the
+% terminal.
+\def\mmz at trace#1{\immediate\write16{[tracing memoize] #1}}
+\def\mmz at trace@context{\mmz at trace{\space\space
+    Context: "\expandonce{\mmz at context@key}" --> \mmz at context@mdfivesum}}
+\def\mmz at trace@Memoize at on{%
+  \mmz at trace{%
+    Entering \noexpand\Memoize (%
+    \ifmemoize enabled\else disabled\fi,
+    \ifnum\mmz at mode=\mmz at mode@recompile recompile\fi
+    \ifnum\mmz at mode=\mmz at mode@readonly readonly\fi
+    \ifnum\mmz at mode=\mmz at mode@normal normal\fi
+    \space mode) on line \the\inputlineno
+  }%
+  \mmz at trace{\space\space Code: \the\mmz at mdfive@source}%
+}
+\def\mmz at trace@code at mdfive@on{\mmz at trace{\space\space
+    Code md5sum: \mmz at code@mdfivesum}}
+\def\mmz at trace@compile at on{\mmz at trace{\space\space Compiling}}
+\def\mmz at trace@memoize at on{\mmz at trace{\space\space Memoizing}}
+\def\mmz at trace@endmemoize at ok@on{\mmz at trace{\space\space
+    Memoization completed}}%
+\def\mmz at trace@endmemoize at aborted@on{\mmz at trace{\space\space
+    Memoization was aborted}}
+\def\mmz at trace@endmemoize at unmemoizable@on{\mmz at trace{\space\space
+    Marking this code as unmemoizable}}
+% No need for |\mmz at trace@endmemoize at fail|, as abortion results in a package
+% warning anyway.
+\def\mmz at trace@process at cmemo@on{\mmz at trace{\space\space
+    Attempting to utilize c-memo \mmz at cmemo@path}}
+\def\mmz at trace@process at no@cmemo at on{\mmz at trace{\space\space
+    C-memo does not exist}}
+\def\mmz at trace@process at cmemo@ok at on{\mmz at trace{\space\space
+    C-memo was processed successfully}\mmz at trace@context}
+\def\mmz at trace@process at cmemo@fail at on{\mmz at trace{\space\space
+    C-memo input failed}}
+\def\mmz at trace@cmemo at unmemoizable@on{\mmz at trace{\space\space
+    This code was marked as unmemoizable}}
+\def\mmz at trace@process at ccmemo@on{\mmz at trace{\space\space
+    Attempting to utilize cc-memo \mmz at ccmemo@path\space
+    (\ifmmz at direct@ccmemo at input\else in\fi direct input)}}
+\def\mmz at trace@resource at on#1{\mmz at trace{\space\space
+    Extern file does not exist: #1}}
+\def\mmz at trace@process at ccmemo@ok at on{%
+  \mmz at trace{\space\space Utilization successful}}
+\def\mmz at trace@process at no@ccmemo at on{%
+  \mmz at trace{\space\space CC-memo does not exist}}
+\def\mmz at trace@process at ccmemo@fail at on{%
+  \mmz at trace{\space\space Cc-memo input failed}}
+% 
+% \begin{key}{tracing}
+%   \begin{macro}{\mmzTracingOn,\mmzTracingOff}
+%     The user interface for switching the tracing on and off; initially, it is
+%     off.  Note that there is no underlying conditional.  The off version
+%     simply |\let|s all the tracing hooks to |\relax|, so that the overhead of
+%     having the tracing functionality available is negligible.
+\mmzset{%
+  trace/.is choice,
+  trace/.default=true,
+  trace/true/.code=\mmzTracingOn,
+  trace/false/.code=\mmzTracingOff,
+}
+\def\mmzTracingOn{%
+  \let\mmz at trace@Memoize\mmz at trace@Memoize at on
+  \let\mmz at trace@code at mdfive\mmz at trace@code at mdfive@on
+  \let\mmz at trace@compile\mmz at trace@compile at on
+  \let\mmz at trace@memoize\mmz at trace@memoize at on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@endmemoize at ok\mmz at trace@endmemoize at ok@on
+  \let\mmz at trace@endmemoize at unmemoizable\mmz at trace@endmemoize at unmemoizable@on
+  \let\mmz at trace@endmemoize at aborted\mmz at trace@endmemoize at aborted@on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@process at cmemo@ok\mmz at trace@process at cmemo@ok at on
+  \let\mmz at trace@process at no@cmemo\mmz at trace@process at no@cmemo at on
+  \let\mmz at trace@process at cmemo@fail\mmz at trace@process at cmemo@fail at on
+  \let\mmz at trace@cmemo at unmemoizable\mmz at trace@cmemo at unmemoizable@on
+  \let\mmz at trace@process at ccmemo\mmz at trace@process at ccmemo@on
+  \let\mmz at trace@resource\mmz at trace@resource at on
+  \let\mmz at trace@process at ccmemo@ok\mmz at trace@process at ccmemo@ok at on
+  \let\mmz at trace@process at no@ccmemo\mmz at trace@process at no@ccmemo at on
+  \let\mmz at trace@process at ccmemo@fail\mmz at trace@process at ccmemo@fail at on
+}
+\def\mmzTracingOff{%
+  \let\mmz at trace@Memoize\relax
+  \let\mmz at trace@code at mdfive\relax
+  \let\mmz at trace@compile\relax
+  \let\mmz at trace@memoize\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@endmemoize at ok\relax
+  \let\mmz at trace@endmemoize at unmemoizable\relax
+  \let\mmz at trace@endmemoize at aborted\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@process at cmemo@ok\relax
+  \let\mmz at trace@process at no@cmemo\relax
+  \let\mmz at trace@process at cmemo@fail\relax
+  \let\mmz at trace@cmemo at unmemoizable\relax
+  \let\mmz at trace@process at ccmemo\relax
+  \let\mmz at trace@resource\@gobble
+  \let\mmz at trace@process at ccmemo@ok\relax
+  \let\mmz at trace@process at no@ccmemo\relax
+  \let\mmz at trace@process at ccmemo@fail\relax
+}
+\mmzTracingOff
+% \end{macro}
+% \end{key}
+% 
+%</mmz>
+%<nommz,mmzable>\newcommand\IfMemoizing[2][]{\@secondoftwo}
+%<*mmz>
+% 
+% \subsection{Context}
+% \label{sec:code:context}
+%
+% \begin{macro}{\mmzContext,\mmzContextExtra}
+%   The context expression is stored in two token registers.  Outside
+%   memoization, we will locally assign to |\mmzContext|; during memoization,
+%   we will globally assign to |\mmzContextExtra|.
+\newtoks\mmzContext
+\newtoks\mmzContextExtra
+% \end{macro}
+% \begin{key}{context, clear context}
+%   The user interface keys for context manipulation hide the complexity
+%   underlying the context storage from the user.
+\mmzset{%
+  context/.code={%
+    \ifmemoizing
+      \expandafter\gtoksapp\expandafter\mmzContextExtra
+    \else
+      \expandafter\toksapp\expandafter\mmzContext
+    \fi
+    % We append a comma to the given context chunk, for disambiguation.
+    {#1,}%
+  },
+  clear context/.code={%
+    \ifmemoizing
+      \expandafter\global\expandafter\mmzContextExtra
+    \else
+      \expandafter\mmzContext
+    \fi
+    {}%
+  },
+  clear context/.value forbidden,
+  % \end{key}
+  % \begin{key}{meaning to context, csname meaning to context, key meaning to
+  %   context, key value to context, /handlers/.meaning to context,
+  %   /handlers/.value to context}
+  %   Utilities to put the meaning of various stuff into |context|.
+  meaning to context/.code={\forcsvlist\mmz at mtoc{#1}},
+  csname meaning to context/.code={\mmz at mtoc@cs{#1}},
+  key meaning to context/.code={\forcsvlist\mmz at mtoc\mmz at mtoc@keycmd{#1}},
+  key value to context/.code={\forcsvlist\mmz at mtoc@key{#1}},
+  /handlers/.meaning to context/.code={%
+    \expanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath/. at cmd}}},
+  /handlers/.value to context/.code={%
+    \expanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath}}},
+}
+\def\mmz at mtoc#1{%
+  \collargs at cs@cases{#1}%
+    {\mmz at mtoc@cmd{#1}}%
+    {\mmz at mtoc@error at notcsorenv{#1}}%
+    {%
+      \mmz at mtoc@cs{%
+        %<context>start%
+        #1}%
+      \mmz at mtoc@cs{%
+        %<latex,plain>end%
+        %<context>stop%
+        #1}%
+    }%
+}
+\def\mmz at mtoc@cmd#1{%
+  \begingroup
+  \escapechar=-1
+  \expandafter\endgroup
+  \expandafter\mmz at mtoc@cs\expandafter{\string#1}%
+}
+\def\mmz at mtoc@cs#1{%
+  \pgfkeysvalueof{/mmz/context/. at cmd}%
+  \expandafter\string\csname#1\endcsname={\expandafter\meaning\csname#1\endcsname}%
+  \pgfeov  
+}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1}}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1/. at cmd}}
+\def\mmz at mtoc@error at notcsorenv#1{%
+  \PackageError{memoize}{'\detokenize{#1}' passed to key 'meaning to context' is neither a command nor an environment}{}%
+}
+% \end{key}
+% 
+% 
+% \subsection{C-memos}
+% \label{sec:code:c-memo}
+% 
+% \paragraph{The path} to a c-memo consists of the path prefix, the MD5 sum of
+% the memoized code, and suffix |.memo|.
+\def\mmz at cmemo@path{\mmz at prefix@path\mmz at code@mdfivesum.memo}
+% \begin{macro}{\mmzCMemo}
+%   The additional, free-form content of the c-memo is collected in this token
+%   register.
+\newtoks\mmzCMemo
+% \end{macro}
+% 
+% \begin{key}{include source in cmemo}
+%   \begin{macro}{\ifmmz at include@source}
+%       Should we include the memoized code in
+%       the c-memo?  By default, yes. \bigskip
+\mmzset{%
+  include source in cmemo/.is if=mmz at include@source,
+}
+\newif\ifmmz at include@source
+\mmz at include@sourcetrue
+% \end{macro}
+% \end{key}
+% 
+% \begin{macro}{\mmz at write@cmemo}
+%   This macro creates the c-memo from the contents of |\mmzContextExtra| and
+%   |\mmzCMemo|.
+\def\mmz at write@cmemo{%
+  % Open the file for writing.
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  % The memo starts with the |\mmzMemo| marker (a signal that the memo is valid).
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  % We store the content of |\mmzContextExtra| by writing out a command that
+  % will (globally) assign its content back into this register.
+  \immediate\write\mmz at out{%
+    \global\mmzContextExtra{\the\mmzContextExtra}\collargs at percentchar
+  }%
+  % Write out the free-form part of the c-memo.
+  \immediate\write\mmz at out{\the\mmzCMemo\collargs at percentchar}%
+  % When |include source in cmemo| is in effect, add the memoized code, hiding
+  % it behind the |\mmzSource| marker.
+  \ifmmz at include@source
+    \immediate\write\mmz at out{\noexpand\mmzSource}%
+    \immediate\write\mmz at out{\the\mmz at mdfive@source}%
+  \fi
+  % Close the file.
+  \immediate\closeout\mmz at out
+  % Record that we wrote a new c-memo.
+  \pgfkeysalso{/mmz/record/new cmemo={\mmz at cmemo@path}}%
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmz at write@empty at cmemo}
+%   This macro is used to create an empty c-memo on aborted memoization, to
+%   make sure that no leftover c-memo tricks Memoize into thinking that the
+%   code was successfully memoized.
+\def\mmz at write@empty at cmemo{%
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  \immediate\closeout\mmz at out
+}
+% \end{macro}
+% 
+% 
+% \begin{macro}{\mmzSource}
+%   The c-memo memoized code marker. This macro is synonymous with |\endinput|,
+%   so the source following it is ignored when inputting the c-memo.
+\let\mmzSource\endinput
+% \end{macro}
+% 
+% \begin{macro}{\mmz at process@cmemo}
+%   This macro inputs the c-memo, which will update the context code, which we
+%   can then compute the MD5 sum of.
+\def\mmz at process@cmemo{%
+  \mmz at trace@process at cmemo
+  % |\ifmmz at abort| serves as a signal that the c-memo exists and is of correct
+  %   form.
+  \global\mmz at aborttrue
+  % If c-memo sets |\ifmmzUnmemoizable|, we will compile regularly.
+  \global\mmzUnmemoizablefalse
+  \def\mmzMemo{\global\mmz at abortfalse}%
+  % Just a safeguard \dots\ c-memo assigns to |\mmzContextExtra| anyway.
+  \global\mmzContextExtra{}%
+  % Input the c-memo, if it exists, and record that we have used it.
+  \IfFileExists{\mmz at cmemo@path}{%
+    \input{\mmz at cmemo@path}%
+    \pgfkeysalso{/mmz/record/used cmemo={\mmz at cmemo@path}}%
+  }{%
+    \mmz at trace@process at no@cmemo
+  }%
+  % Compute the context MD5 sum.
+  \mmz at compute@context at mdfivesum
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmz at compute@context at mdfivesum}
+%   This macro computes the MD5 sum of the concatenation of |\mmzContext| and
+%   |\mmzContextExtra|, and writes out the tracing info when |trace context| is
+%   in effect.  The argument is the tracing note.
+% \end{macro}
+\def\mmz at compute@context at mdfivesum{%
+  \xdef\mmz at context@key{\the\mmzContext\the\mmzContextExtra}%
+  % A special provision for padding, which occurs in the context by default,
+  % and may contain otherwise undefined macros referring to the extern
+  % dimensions.  We make sure that when we expand the context key,
+  % |\mmz at paddings| contains the stringified |\width| etc., while these macros
+  % (which may be employed by the end user in the context expression), are
+  % returned to their original definitions.
+  \begingroup
+  \begingroup
+  \def\width{\string\width}%
+  \def\height{\string\height}%
+  \def\depth{\string\depth}%
+  \edef\mmz at paddings{\mmz at paddings}%
+  \expandafter\endgroup
+  \expandafter\def\expandafter\mmz at paddings\expandafter{\mmz at paddings}%
+  % We pre-expand the concatenated context, for tracing\slash inclusion in the
+  % cc-memo.  In \hologo{LaTeX}, we protect the expansion, as the context
+  % expression may contain whatever.
+  %<latex>\protected at xdef
+  %<!latex>\xdef
+  \mmz at context@key{\mmz at context@key}%
+  \endgroup
+  % Compute the MD5 sum.  We have to assign globally, because this macro is (also)
+  % called after inputting the c-memo, while the resulting MD5 sum is used to
+  % input the cc-memo, which happens outside the |\Memoize| group.
+  % |\mmz at context@mdfivesum|.
+  \xdef\mmz at context@mdfivesum{\pdf at mdfivesum{\expandonce\mmz at context@key}}%
+}
+%
+%
+% \subsection{Cc-memos}
+% \label{sec:code:cc-memo}
+%
+% \paragraph{The path} to a cc-memo consists of the path prefix, the
+% hyphen-separated MD5 sums of the memoized code and the (evaluated) context,
+% and suffix |.memo|.
+\def\mmz at ccmemo@path{%
+  \mmz at prefix@path\mmz at code@mdfivesum-\mmz at context@mdfivesum.memo}
+% 
+% \paragraph{The structure} of a cc-memo:
+% \begin{itemize}
+% \item the list of resources consisting of calls to |\mmzResource|;
+% \item the core memo code (which includes the externs when executed),
+%   introduced by marker |\mmzMemo|; and,
+% \item optionally, the context expansion, introduced by marker
+%   |\mmzThisContext|.
+% \end{itemize}
+% 
+% We begin the cc-memo with a list of extern files included by the core memo
+% code so that we can check whether these files exist prior to executing the
+% core memo code.  Checking this on the fly, while executing the core memo
+% code, would be too late, as that code is arbitrary (and also executed outside
+% the |\Memoize| group).
+% 
+% \begin{macro}{\mmzCCMemo}
+%   During memoization, the core content of the cc-memo is collected into this
+%   token register.
+\newtoks\mmzCCMemo
+% \end{macro}
+% 
+% \begin{key}{include context in ccmemo}
+%   \begin{macro}{\ifmmz at include@context}
+%       Should we include the context expansion in the cc-memo?  By default, no.
+%       \bigskip
+\newif\ifmmz at include@context
+\mmzset{%
+  include context in ccmemo/.is if=mmz at include@context,
+}
+% \end{macro}
+% \end{key}
+% 
+% \begin{key}{direct ccmemo input}
+%   \begin{macro}{\ifmmz at direct@ccmemo at input}
+%       When this conditional is false, the
+%         cc-memo is read indirectly, via a token register, to facilitate
+%         inverse search.  \bigskip
+\newif\ifmmz at direct@ccmemo at input
+\mmzset{%
+  direct ccmemo input/.is if=mmz at direct@ccmemo at input,
+}
+% \end{macro}
+% \end{key}
+% 
+% \begin{macro}{\mmz at write@ccmemo}
+%   This macro creates the cc-memo from the list of resources in
+%   |\mmz at ccmemo@resources| and the contents of |\mmzCCMemo|.
+\def\mmz at write@ccmemo{%
+  % Open the cc-memo file for writing.  Note that the filename contains the
+  % context MD5 sum, which can only be computed after memoization, as the
+  % memoized code can update the context.  This is one of the two reasons why
+  % we couldn't write the cc-memo directly into the file, but had to collect
+  % its contents into token register |\mmzCCMemo|.
+  \immediate\openout\mmz at out{\mmz at ccmemo@path}%
+  % Token register |\mmz at ccmemo@resources| consists of calls to
+  % |\mmz at ccmemo@append at resource|, so the following code writes down the list
+  % of created externs into the cc-memo.  Wanting to have this list at the top
+  % of the cc-memo is the other reason for the roundabout creation of the
+  % cc-memo --- the resources become known only during memoization, as well.
+  \begingroup
+  \the\mmz at ccmemo@resources
+  \endgroup
+  % Write down the content of |\mmzMemo|, but first introduce it by the
+  % |\mmzMemo| marker.
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  \immediate\write\mmz at out{\the\mmzCCMemo\collargs at percentchar}%
+  % Write down the context tracing info when |include context in ccmemo| is in
+  % effect.
+  \ifmmz at include@context
+    \immediate\write\mmz at out{\noexpand\mmzThisContext}%
+    \immediate\write\mmz at out{\expandonce{\mmz at context@key}}%
+  \fi
+  % Insert the end-of-file marker and close the file.
+  \immediate\write\mmz at out{\noexpand\mmzEndMemo}%
+  \immediate\closeout\mmz at out
+  % Record that we wrote a new cc-memo.
+  \pgfkeysalso{/mmz/record/new ccmemo={\mmz at ccmemo@path}}%
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmz at ccmemo@append at resource}
+%   Append the resource to the cc-memo (we are nice to external utilities and
+%   put each resource on its own line).  |#1| is the sequential number of the
+%   extern belonging to the memoized code; below, we assign it to |\mmz at seq|,
+%   which appears in |\mmz at extern@name|.  Note that |\mmz at extern@name| only
+%   contains the extern filename --- without the path, so that externs can be
+%   used by several projects, or copied around.
+\def\mmz at ccmemo@append at resource#1{%
+  \mmz at seq=#1\relax
+  \immediate\write\mmz at out{%
+    \string\mmzResource{\mmz at extern@name}\collargs at percentchar}%
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmzResource}
+%   A list of these macros is located at the top of a cc-memo.  The macro
+%   checks for the existence of the extern file, given as |#1|.  If the extern
+%   does not exist, we redefine |\mmzMemo| to |\endinput|, so that the core
+%   content of the cc-memo is never executed; see also |\mmz at process@ccmemo|
+%   above.
+\def\mmzResource#1{%
+  % We check for existence using |\pdffilesize|, because an empty PDF, which
+  % might be produced by a failed \hologo{TeX}-based extraction, should count
+  % as no file.  The |0| behind |\ifnum| is there because |\pdffilesize|
+  %   returns an empty string when the file does not exist.
+  \ifnum0\pdf at filesize{\mmz at dir@path/#1}=0
+    \ifmmz at direct@ccmemo at input
+      \let\mmzMemo\endinput
+    \else
+      % With indirect cc-memo input, we simulate end-of-input by grabbing
+      % everything up to the end-of-memo marker.  In the indirect cc-memo
+      % input, a |\par| token shows up after |\mmzEndMemo|, I'm not sure why
+      % (|\everyeof={}| does not help).
+      \long\def\mmzMemo##1\mmzEndMemo\par{}%
+    \fi
+    \mmz at trace@resource{#1}%
+  \fi
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmz at process@ccmemo,\mmzThisContext,\mmzEndMemo}
+%   This macro processes the cc-memo.
+\def\mmz at process@ccmemo{%
+  \mmz at trace@process at ccmemo
+  % The following conditional signals whether cc-memo was successfully
+  % utilized.  If the cc-memo file does not exist, |\ifmmz at abort| will remain
+  %   true.  If it exists, it is headed by the list of resources.  If a
+  %   resource check fails, |\mmzMemo| (which follows the list of resources) is
+  %   redefined to |\endinput|, so |\ifmmz at abort| remains true.  However, if
+  %     all resource checks are successful, |\mmzMemo| marker is reached with
+  %     the below definition in effect, so |\ifmmz at abort| becomes false.  Note
+  %       that this marker also closes the |\Memoize| group, so that the core
+  %       cc-memo content is executed in the original group --- and that this
+  %       does not happen if anything goes wrong!
+  \global\mmz at aborttrue
+  % Note that |\mmzMemo| may be redefined by |\mmzResource| upon an unavailable
+  % extern file.
+  \def\mmzMemo{%
+    \endgroup
+    \global\mmz at abortfalse
+    % We |\let| the control sequence used for extern inclusion in the cc-memo to
+    % the macro which includes the extern from the extern file.
+    \let\mmzIncludeExtern\mmz at include@extern
+  }%
+  % Define |\mmzEndMemo| wrt |\ifmmz at direct@ccmemo at input|, whose value will be
+  %   lost soon because |\mmMemo| will close the group --- that's also why this
+  %   definition is global.
+  \xdef\mmzEndMemo{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      % In the indirect cc-memo input, a |\par| token shows up after
+      % |\mmzEndMemo|, I'm not sure why (|\everyeof={}| does not help).
+      \unexpanded{%
+        \def\mmz at temp\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  % The cc-memo context marker, again wrt |\ifmmz at direct@ccmemo at input| and
+  %   globally.  With direct cc-memo input, this macro is synonymous with
+  %   |\endinput|, so the (expanded) context following it is ignored when
+  %   inputting the cc-memo.  With indirect input, we simulate end-of-input by
+  %   grabbing everything up to the end-of-memo marker (plus gobble the |\par|
+  %   mentioned above).
+  \xdef\mmzThisContext{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      \unexpanded{%
+        \long\def\mmz at temp##1\mmzEndMemo\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  % Input the cc-memo if it exists.
+  \IfFileExists{\mmz at ccmemo@path}{%
+    \ifmmz at direct@ccmemo at input
+      \input{\mmz at ccmemo@path}%
+    \else
+      % Indirect cc-memo input reads the cc-memo into a token register and
+      % executes the contents of this register.
+      \filetotoks\toks@{\mmz at ccmemo@path}%
+      \the\toks@
+    \fi
+    % Record that we have used the cc-memo.
+    \pgfkeysalso{/mmz/record/used ccmemo={\mmz at ccmemo@path}}%
+  }{%
+    \mmz at trace@process at no@ccmemo
+  }%
+  \ifmmz at abort
+    % The cc-memo doesn't exist, or some of the resources don't.  We need to
+    % memoize, but we'll do it only if |readonly| is not in effect, otherwise
+    % we'll perform a regular compilation. (Note that we are still in the group
+    % opened prior to executing |\Memoize|.)
+    \mmz at trace@process at ccmemo@fail
+    \ifnum\mmz at mode=\mmz at mode@readonly\relax
+      \expandafter\expandafter\expandafter\mmz at compile
+    \else
+      \expandafter\expandafter\expandafter\mmz at memoize
+    \fi
+  \else
+    \mmz at trace@process at ccmemo@ok
+  \fi
+}
+% \end{macro}
+% 
+% \subsection{The externs}
+% \label{sec:code:extern}
+% 
+% \paragraph{The path} to an extern is like the path to a cc-memo, modulo
+% suffix |.pdf|, of course.  However, in case memoization of a chunk produces
+% more than one extern, the filename of any non-first extern includes
+% |\mmz at seq|, the sequential number of the extern as well (we start the
+% numbering at $0$).  We will have need for several parts of the full path to
+% an extern: the basename, the filename, the path without the suffix, and the
+% full path.
+\newcount\mmz at seq
+\def\mmz at extern@basename{%
+  \mmz at prefix\mmz at code@mdfivesum-\mmz at context@mdfivesum
+  \ifnum\mmz at seq>0 -\the\mmz at seq\fi
+}
+\def\mmz at extern@name{\mmz at extern@basename.pdf}
+\def\mmz at extern@basepath{\mmz at dir@path/\mmz at extern@basename}
+\def\mmz at extern@path{\mmz at extern@basepath.pdf}
+% 
+% \begin{key}{padding left, padding right, padding top, padding bottom}
+%   These options set the amount of space surrounding the bounding box of the
+%   externalized graphics in the resulting PDF, i.e.\ in the extern file.  This
+%   allows the user to deal with \TikZ; overlays, |\rlap| and |\llap|, etc.
+\mmzset{
+  padding left/.store in=\mmz at padding@left,
+  padding right/.store in=\mmz at padding@right,
+  padding top/.store in=\mmz at padding@top,
+  padding bottom/.store in=\mmz at padding@bottom,
+% \end{key}
+% 
+% \begin{key}{padding}
+%   A shortcut for setting all four paddings at once.
+  padding/.style={
+    padding left=#1, padding right=#1,
+    padding top=#1, padding bottom=#1
+  },
+  % The default padding is what \hologo{pdfTeX} puts around the page anyway, 1
+  % inch, but we'll use |1 in| rather than |1 true in|, which is the true
+  % default value of |\pdfhorigin| and |\pdfvorigin|, as we want the padding to
+  % adjust with magnification.
+  padding=1in,
+% \end{key}
+% 
+  % \begin{key}{padding to context}
+  %   This key adds padding to the context.  Note that we add the padding
+  %   expression (|\mmz at paddings|, defined below, refers to all the individual
+  %   padding macros), not the actual value (at the time of expansion).  This
+  %   is so because |\width|, |\height| and |\depth| are not defined outside
+  %   extern shipout routines, and the context is evaluated elsewhere.
+  padding to context/.style={
+    context={padding=(\mmz at paddings)},
+  },
+  % \end{key}
+  % 
+  % Padding nearly always belongs into the context --- the exception being
+  % memoized code which produces no externs (\MS\ref{sec:pure-memoization}) ---
+  % so we execute this key immediately.
+  padding to context,
+}
+\def\mmz at paddings{%
+  \mmz at padding@left,\mmz at padding@bottom,\mmz at padding@right,\mmz at padding@top
+}
+% 
+% \begin{macro}{\mmzExternalizeBox}
+%   This macro is the public interface to externalization.  In Memoize itself,
+%   it is called from the default memoization driver, |\mmzSingleExternDriver|,
+%   but it should be called by any driver that wishes to produce an extern, see
+%   \MS\ref{sec:memoization-drivers} for details.  It takes two arguments:
+% \begin{enumerate}[\tt\#1]
+% \item The box that we want to externalize.  It's content will remain intact.
+%   The box may be given either as a control sequence, declared via |\newbox|,
+%   or as box number (say, 0).
+% \item The token register which will receive the code that includes the extern
+%   into the document; it is the responsibility of the memoization driver to
+%   (globally) include the contents of the register in the cc-memo, i.e.\ in
+%   token register |\mmzCCMemo|.  This argument may be either a control
+%   sequence, declared via |\newtoks|, or a |\toks|\meta{token register
+%   number}.
+% \end{enumerate}
+\def\mmzExternalizeBox#1#2{%
+  \begingroup
+  % A courtesy to the user, so they can define padding in terms of the size of
+  % the externalized graphics.
+  \def\width{\wd#1 }%
+  \def\height{\ht#1 }%
+  \def\depth{\dp#1 }%
+  % Store the extern-inclusion code in a temporary macro, which will be
+  % smuggled out of the group.
+  \xdef\mmz at global@temp{%
+    % Executing |\mmzIncludeExtern| from the cc-memo will include the extern
+    % into the document.
+    \noexpand\mmzIncludeExtern
+    % |\mmzIncludeExtern| identifies the extern by its sequence number,
+    % |\mmz at seq|.
+      {\the\mmz at seq}%
+      % What kind of box? We |\noexpand| the answer just in case someone
+      % redefined them.
+      \ifhbox#1\noexpand\hbox\else\noexpand\vbox\fi
+      % The dimensions of the extern.
+      {\the\wd#1}%
+      {\the\ht#1}%
+      {\the\dp#1}%
+      % The padding values.
+      {\the\dimexpr\mmz at padding@left}%
+      {\the\dimexpr\mmz at padding@bottom}%
+      {\the\dimexpr\mmz at padding@right}%
+      {\the\dimexpr\mmz at padding@top}%
+  }%
+  % Prepend the new extern box into the global extern box where we collect all
+  % the externs of this memo.  Note that we |\copy| the extern box, retaining
+  % its content --- we will also want to place the extern box in its regular
+  % place in the document.
+  \global\setbox\mmz at tbe@box\vbox{\copy#1\unvbox\mmz at tbe@box}%
+  % Add the extern to the list of resources, which will be included at the top
+  % of the cc-memo, to check whether the extern files exists at the time the
+  % cc-memo is utilized.  In the cc-memo, the list will contain full extern
+  % filenames, which are currently unknown, but no matter; right now, providing
+  % the extern sequence number suffices, the full extern filename will be
+  % produced at the end of memoization, once the context MD5 sum is known.
+  \xtoksapp\mmz at ccmemo@resources{%
+    \noexpand\mmz at ccmemo@append at resource{\the\mmz at seq}%
+  }%
+  % Increment the counter containing the sequence number of the extern within
+  % this memo.
+  \global\advance\mmz at seq1
+  % Assign the extern-including code into the token register given in |#2|.
+  % This register may be given either as a control sequence or as
+  % |\toks|\meta{token register number}, and this is why we have temporarily
+  % stored the code (into |\mmz at global@temp|) globally: a local storage with
+  % |\expandafter\endgroup\expandafter| here would fail with the receiving
+  % token register given as |\toks|\meta{token register number}.
+  \endgroup
+  #2\expandafter{\mmz at global@temp}%
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmz at ccmemo@resources}
+%   This token register, populated by |\mmz at externalize@box| and used by
+%   |\mmz at write@ccmemo|, holds the list of externs produced by memoization of
+%   the current chunk.
+\newtoks\mmz at ccmemo@resources
+% \end{macro}
+% 
+% \begin{macro}{\mmz at tbe@box}
+%   |\mmz at externalize@box| does not directly dump the extern into the document
+%   (as a special page).  Rather, the externs are collected into
+%   |\mmz at tbe@box|, whose contents are dumped into the document at the end of
+%   memoization of the current chunk.  In this way, we guarantee that aborted
+%   memoization does not pollute the document.
+\newbox\mmz at tbe@box
+% \end{macro}
+% 
+% \begin{macro}{\mmz at shipout@externs}
+%   This macro is executed at the end of
+%   memoization, when the externs are waiting for us in |\mmz at tbe@box| and need
+%   to be dumped into the document.  It loops through the contents of
+%   |\mmz at tbe@box|,\footnote{The looping code is based on TeX.SE
+%   answer \url(https://){tex.stackexchange.com/a/25142/16819} by Bruno Le
+%   Floch.}, putting each extern into |\mmz at box| and calling
+%   |\mmz at shipout@extern|.  Note that the latter macro is executed within the
+%   group opened by |\vbox| below.
+\def\mmz at shipout@externs{%
+  \global\mmz at seq 0
+  \setbox\mmz at box\vbox{%
+    % Set the macros below to the dimensions of the extern box, so that the
+    % user can refer to them in the padding specification (which is in turn
+    % used in the page setup in |\mmz at shipout@extern|).
+    \def\width{\wd\mmz at box}%
+    \def\height{\ht\mmz at box}%
+    \def\depth{\dp\mmz at box}%    
+    \vskip1pt
+    \ifmmzkeepexterns\expandafter\unvcopy\else\expandafter\unvbox\fi\mmz at tbe@box
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox\mmz at box\lastbox
+      \mmz at shipout@extern
+    }%
+  }%
+}
+% \end{macro}
+%
+% \begin{macro}{\mmz at shipout@extern}
+%   This macro ships out a single extern, which
+%   resides in |\mmz at box|, and records the creation of the new extern.
+\def\mmz at shipout@extern{%
+  % Calculate the expected width and height. We have to do this now, before we
+  % potentially adjust the box size and paddings for magnification.
+  \edef\expectedwidth{\the\dimexpr
+    (\mmz at padding@left) + \wd\mmz at box + (\mmz at padding@right)}%
+  \edef\expectedheight{\the\dimexpr
+    (\mmz at padding@top) + \ht\mmz at box + \dp\mmz at box + (\mmz at padding@bottom)}%
+  % Apply the inverse magnification, if |\mag| is not at the default
+  % value. We'll do this in a group, which will last until shipout.
+  \begingroup
+  \ifnum\mag=1000
+  \else
+    \mmz at shipout@mag
+  \fi
+  % Setup the geometry of the extern page.  In \hologo{plainTeX} and
+  % \hologo{LaTeX}, setting |\pdfpagewidth| and |\pdfpageheight| seems to do
+  % the trick of setting the extern page dimensions.  In \hologo{ConTeXt},
+  % however, the resulting extern page ends up with the PDF |/CropBox|
+  % specification of the current regular page, which is then used (ignoring our
+  % |mediabox| requirement) when we're including the extern into the document
+  % by |\mmzIncludeExtern|.  Typically, this results in a page-sized extern.
+  % I'm not sure how to deal with this correctly.  In the workaround below, we
+  % use Lua function |backends.codeinjections.setupcanvas| to set up page
+  % dimensions: we first remember the current page dimensions
+  % (|\edef\mmz at temp|), then set up the extern page dimensions
+  % (|\expanded{...}|), and finally, after shipping
+  % out the extern page, revert to the current page dimensions by executing
+  % |\mmz at temp| at the very end of this macro.
+  %<*plain,latex>
+  \pdfpagewidth\dimexpr
+    (\mmz at padding@left) + \wd\mmz at box + (\mmz at padding@right)\relax
+  \pdfpageheight\dimexpr
+    (\mmz at padding@top) + \ht\mmz at box + \dp\mmz at box+ (\mmz at padding@bottom)\relax
+  %</plain,latex>
+  %<*context>
+  \edef\mmz at temp{%
+    \noexpand\directlua{
+      backends.codeinjections.setupcanvas({
+        paperwidth=\the\numexpr\pagewidth,
+        paperheight=\the\numexpr\pageheight
+      })
+    }%
+  }%
+  \expanded{%
+    \noexpand\directlua{
+      backends.codeinjections.setupcanvas({
+        paperwidth=\the\numexpr\dimexpr
+          \mmz at padding@left + \wd\mmz at box + \mmz at padding@right\relax,
+        paperheight=\the\numexpr\dimexpr
+          \mmz at padding@top + \ht\mmz at box + \dp\mmz at box+ \mmz at padding@bottom\relax
+      })
+    }%
+  }%
+  %</context>
+  % 
+  % We complete the page setup by setting the content offset.
+  \hoffset\dimexpr\mmz at padding@left - \pdfhorigin\relax
+  \voffset\dimexpr\mmz at padding@top - \pdfvorigin\relax
+  % We shipout the extern page using the |\shipout| primitive, so that the
+  % extern page is not modified, or even registered, by the shipout code of the
+  % format or some package.  I can't imagine those shipout routines ever
+  % needing to know about the extern page.  In fact, most often knowing about
+  % it would be undesirable.  For example, \hologo{LaTeX} and \hologo{ConTeXt}
+  % count the ``real'' pages, but usually to know whether they are shipping out
+  % an odd or an even page, or to make the total number of pages available to
+  % subsequent compilations.  Taking the extern pages into account would
+  % disrupt these mechanisms.
+  % 
+  % Another thing: delayed |\write|s.  We have to make sure that any
+  % \hologo{LaTeX}-style protected stuff in those is not expanded. We don't
+  % bother introducing a special group, as we'll close the |\mag| group right
+  % after the shipout anyway.
+  %<latex>\let\protect\noexpand
+  \pdf at primitive\shipout\box\mmz at box
+  %<context>\mmz at temp
+  \endgroup
+  % Advance the counter of shipped-out externs.  We do this before preparing
+  % the recording information below, because the extern extraction tools expect
+  % the extern page numbering to start with $1$.
+  \global\advance\mmzExternPages1
+  % Prepare the macros which may be used in |record/<type>/new extern| code.
+  \edef\externbasepath{\mmz at extern@basepath}%
+  % Adding up the counters below should result in the real page number of the
+  % extern.  Macro |\mmzRegularPages| holds the number of pages which were
+  % shipped out so far using the regular shipout routine of the format;
+  % |\mmzExternPages| holds the number of shipped-out extern pages; and
+  % |\mmzExtraPages| holds, or at least should hold, the number of pages
+  % shipped out using any other means.
+  \edef\pagenumber{\the\numexpr\mmzRegularPages
+    % In \hologo{LaTeX}, the |\mmzRegularPages| holds to number of pages
+    % already shipped out.  In \hologo{ConTeXt}, the counter is already
+    % increased while processing the page, so we need to subtract $1$.
+%<context>    -1%
+    +\mmzExternPages+\mmzExtraPages}%
+  % Record the creation of the new extern.  We do this after shipping out the
+  % extern page, so that the recording mechanism can serve as an after-shipout
+  % hook, for the unlikely situation that some package really needs to do
+  % something when our shipout happens.  Note that we absolutely refuse to
+  % provide a before-shipout hook, because we can't allow anyone messing with
+  % our extern, and that using this after-shipout ``hook'' is unnecessary for
+  % counting extern shipouts, as we already provide this information in the
+  % public counter |\mmzExternPages|.
+  \mmzset{record/new extern/.expanded=\mmz at extern@path}%
+  % Advance the sequential number of the extern, in the context of the current
+  % memoized code chunk.  This extern numbering starts at 0, so we only do this
+  % after we wrote the cc-memo and called |record/new extern|.
+  \global\advance\mmz at seq1
+}
+% \end{macro}
+%
+% \begin{macro}{\mmz at shipout@mag}
+%   This macro applies the inverse magnification, so that the extern ends up
+%   with its natural size on the extern page.
+\def\mmz at shipout@mag{%
+  % We scale the extern box using the PDF primitives: |q| and |Q| save and
+  % restore the current graphics state; |cm| applies the given coordinate
+  % transformation matrix. ($a$ $b$ $c$ $d$ $e$ $f$ |cm| transforms $(x,y)$
+  % into $(ax+cy+e,bx+dy+f)$.)
+  \setbox\mmz at box\hbox{%
+    \pdfliteral{q \mmz at inverse@mag\space 0 0 \mmz at inverse@mag\space 0 0 cm}%
+    \copy\mmz at box\relax
+    \pdfliteral{Q}%
+  }%
+  % We first have to scale the paddings, as they might refer to the |\width|
+  % etc.\ of the extern.
+  \dimen0=\dimexpr\mmz at padding@left\relax
+  \edef\mmz at padding@left{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@bottom\relax
+  \edef\mmz at padding@bottom{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@right\relax
+  \edef\mmz at padding@right{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@top\relax
+  \edef\mmz at padding@top{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  % Scale the extern box.
+  \wd\mmz at box=\mmz at inverse@mag\wd\mmz at box\relax
+  \ht\mmz at box=\mmz at inverse@mag\ht\mmz at box\relax
+  \dp\mmz at box=\mmz at inverse@mag\dp\mmz at box\relax
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmz at inverse@mag}
+%   The inverse magnification factor, i.e.\ the number we have to multiply the
+%   extern dimensions with so that they will end up in their natural size.  We
+%   compute it, once and for all, at the beginning of the document.  To do
+%   that, we borrow the little macro |\Pgf at geT| from |pgfutil-common| (but
+%   rename it).
+{\catcode`\p=12\catcode`\t=12\gdef\mmz at Pgf@geT#1pt{#1}}
+\mmzset{begindocument/.append code={%
+    \edef\mmz at inverse@mag{\expandafter\mmz at Pgf@geT\the\dimexpr 1000pt/\mag}%
+  }}
+% \end{macro}
+% 
+% \begin{macro}{\mmzRegularPages}
+%   This counter holds the number of pages shipped out by the format's shipout
+%   routine.  \hologo{LaTeX} and \hologo{ConTeXt} keep track of this in
+%   dedicated counters, so we simply use those.  In \hologo{plainTeX}, we have
+%   to hack the |\shipout| macro to install our own counter.  In fact, we
+%   already did this while loading the required packages, in order to avoid it
+%   being redefined by |atbegshi| first.  All that is left to do here is to
+%   declare the counter.
+%<latex>\let\mmzRegularPages\ReadonlyShipoutCounter
+%<context>\let\mmzRegularPages\realpageno
+%<plain>\newcount\mmzRegularPages
+% \end{macro}
+% 
+% \begin{macro}{\mmzExternPages}
+%   This counter holds the number of extern pages shipped out so far.
+\newcount\mmzExternPages
+% \end{macro}
+% 
+% The total number of new externs is announced at the end of the compilation,
+% so that \hologo{TeX} editors, |latexmk| and such can propose recompilation.
+\mmzset{
+  enddocument/afterlastpage/.append code={%
+    \ifnum\mmzExternPages>0
+      \PackageWarning{memoize}{The compilation produced \the\mmzExternPages\space
+        new extern\ifnum\mmzExternPages>1 s\fi.}%
+    \fi
+  },
+}
+% 
+% \begin{macro}{\mmzExtraPages}
+%   This counter will probably remain at zero forever.  It should be advanced by
+%   any package which (like Memoize) ships out pages bypassing the regular
+%   shipout routine of the format.
+\newcount\mmzExtraPages
+% \end{macro}
+% 
+% \begin{macro}{\mmz at include@extern}
+%   This macro, called from cc-memos as |\mmzIncludeExtern|, inserts an extern
+%   file into the document.  |#1| is the sequential number, |#2| is either
+%   |\hbox| or |\vbox|, |#3|, |#4| and |#5| are the (expected) width, height
+%   and the depth of the externalized box; |#6|--|#9| are the paddings (left,
+%   bottom, right, and top).
+\def\mmz at include@extern#1#2#3#4#5#6#7#8#9{%
+  % Set the extern sequential number, so that we open the correct extern file
+  % (|\mmz at extern@basename|).
+  \mmz at seq=#1\relax
+  % Use the primitive PDF graphics inclusion commands to include the extern
+  % file.  Set the correct depth or the resulting box, and shift it as
+  % specified by the padding.
+  \setbox\mmz at box=#2{%
+    \setbox0=\hbox{%
+      \lower\dimexpr #5+#7\relax\hbox{%
+        \hskip -#6\relax
+        \setbox0=\hbox{%
+          \mmz at insertpdfpage{\mmz at extern@path}{1}%
+        }%
+        \unhbox0
+      }%
+    }%
+    \wd0 \dimexpr\wd0-#8\relax
+    \ht0 \dimexpr\ht0-#9\relax
+    \dp0 #5\relax
+    \box0
+  }%
+  % Check whether the size of the included extern is as expected.  There is no
+  % need to check |\dp|, we have just set it.  (|\mmz at if@roughly at equal| is
+  % defined in section~\ref{sec:code:extract:tex}.)
+  \mmz at tempfalse
+  \mmz at if@roughly at equal{\mmz at tolerance}{#3}{\wd\mmz at box}{%
+    \mmz at if@roughly at equal{\mmz at tolerance}{#4}{\ht\mmz at box}{%
+      \mmz at temptrue
+    }{}}{}%
+  \ifmmz at temp
+  \else
+    \mmz at use@memo at warning{\mmz at extern@path}{#3}{#4}{#5}%
+  \fi
+  % Use the extern box, with the precise size as remembered at memoization.
+  \wd\mmz at box=#3\relax
+  \ht\mmz at box=#4\relax
+  \box\mmz at box
+  % Record that we have used this extern.
+  \pgfkeysalso{/mmz/record/used extern={\mmz at extern@path}}%
+}
+% \end{macro}
+\def\mmz at use@memo at warning#1#2#3#4{%
+  \PackageWarning{memoize}{Unexpected size of extern "#1";
+    expected #2\space x \the\dimexpr #3+#4\relax,
+    got \the\wd\mmz at box\space x \the\dimexpr\the\ht\mmz at box+\the\dp\mmz at box\relax}%
+}
+% \begin{macro}{\mmz at insertpdfpage}
+%   This macro inserts a page from the PDF into the document.  We define it
+%   according to which engine is being used.  Note that \hologo{ConTeXt} always
+%   uses \hologo{LuaTeX}.
+%<latex,plain>\ifdef\luatexversion{%
+  \def\mmz at insertpdfpage#1#2{% #1 = filename, #2 = page number
+    \saveimageresource page #2 mediabox {#1}%
+    \useimageresource\lastsavedimageresourceindex
+  }%
+%<*latex,plain>
+}{%
+  \ifdef\XeTeXversion{%
+    \def\mmz at insertpdfpage#1#2{%
+      \XeTeXpdffile #1 page #2 media 
+    }%
+  }{% pdfLaTeX
+    \def\mmz at insertpdfpage#1#2{%
+      \pdfximage page #2 mediabox {#1}%
+      \pdfrefximage\pdflastximage
+    }%
+  }%
+}
+%</latex,plain>
+% \end{macro}
+%
+% \begin{macro}{\mmz at include@extern at from@tbe at box}
+%   Include the extern number |#1| residing in |\mmz at tbe@box| into the
+%   document.  This helper macro makes it possible for a complex memoization
+%   driver to process the cc-memo right after memoization --- by using the
+%   |\mmzkeepexternstrue\xtoksapp\mmzAfterMemoizationExtra{\the\mmzCCMemo}|
+%   trick --- to ensure that the result of the memoizing compilation matches
+%   the result of inputting the cc-memo.  The rest of the arguments are
+%   gobbled, as we don't have to do any size adjustment or checking here, and
+%   the box is of the correct type.
+\def\mmz at include@extern at from@tbe at box#1#2#3#4#5#6#7#8#9{%
+  \setbox0\vbox{%
+    \@tempcnta#1\relax
+    \vskip1pt
+    \unvcopy\mmz at tbe@box
+    \@whilenum\@tempcnta>0\do{%
+      \setbox0\lastbox
+      \advance\@tempcnta-1\relax
+    }%
+    \global\setbox1\lastbox
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox0\lastbox
+    }%
+    \box\mmz at box
+  }%
+  \box1
+}
+% \end{macro}
+%
+% \section{Extraction}
+% \label{sec:code:extract}
+%
+% \subsection{Extraction mode and method}
+% \label{sec:code:extraction-mode-method}
+% 
+% \begin{key}{extract}
+%   This key selects the extraction mode and method.  It normally occurs in the
+%   package options list, less commonly in the preamble, and never in the
+%   document body.
+\def\mmzvalueof#1{\pgfkeysvalueof{/mmz/#1}}
+\mmzset{
+  extract/.estore in=\mmz at extraction@method,
+  extract/.value required,
+  begindocument/.append style={extract/.code=\mmz at preamble@only at warning},
+  % \end{key}
+  % 
+  % \begin{key}{extract/perl, extract/python}
+  %   Any other value will select internal extraction with the given method.
+  %   Memoize ships with two extraction scripts, a Perl script and a Python
+  %   script, which are selected by |extract=perl| (the default) and
+  %   |extract=python|, respectively.  We run the scripts in verbose mode
+  %   (without |-q|), and keep the |.mmz| file as is, i.e.\ we're not commenting
+  %   out the |\mmzNewExtern| lines, because we're about to overwrite it
+  %   anyway.  We also request the log file, which will contain
+  %   |\mmzExtractionSuccessful| if extraction was successful.
+  extract/perl/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{perl extraction command}\space
+      \mmzvalueof{perl extraction options}%
+    }%
+    \mmz at check@extraction at log{perl}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{perl extraction command}\space --mkdir "##1"}%
+  },
+  perl extraction command/.initial=memoize-extract.pl,
+  perl extraction options/.initial={%
+%     \begin{listingregion}{perl-extraction-options.tex}
+    -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+    %<latex>"\string\PackageWarning{memoize (perl-based extraction)}{\string\warningtext}"
+    %<plain>"\string\warning{memoize (perl-based extraction): \string\warningtext}"
+    %<context>"\string\warning{memoize (perl-based extraction): \string\warningtext}"
+    "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+%     \end{listingregion}
+  },
+  extract=perl,
+  extract/python/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{python extraction command}\space
+      \mmzvalueof{python extraction options}%
+    }%
+    \mmz at check@extraction at log{python}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{python extraction command}\space --mkdir "##1"}%
+  },
+  python extraction command/.initial=memoize-extract.py,
+  python extraction options/.initial={%
+  -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+  %<latex>"\string\PackageWarning{memoize (python-based extraction)}{\string\warningtext}"
+  %<plain>"\string\warning{memoize (python-based extraction): \string\warningtext}"
+  %<context>"\string\warning{memoize (python-based extraction): \string\warningtext}"
+  "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+  },
+}
+\def\mmz at preamble@only at warning{%
+  \PackageWarning{memoize}{%
+    Ignoring the invocation of "\pgfkeyscurrentkey".
+    This key may only be executed in the preamble}%
+}
+% \end{key}
+% 
+% \paragraph*{The extraction log}
+% As we cannot access the exit status of a system command in \hologo{TeX}, we
+% communicate with the system command via the ``extraction log file,'' produced
+% by both \hologo{TeX}-based extraction and the Perl and Python extraction
+% script.  This file signals whether the embedded extraction was successful ---
+% if it is, the file contains |\mmzExtractionSuccessful| --- and also contains
+% any size-mismatch warnings (these are currently only thrown by the
+% \hologo{TeX}-based extraction).  As the log is really a \hologo{TeX} file,
+% the idea is to simply input it after extracting each extern (for
+% \hologo{TeX}-based extraction) or after the extraction of all externs (for
+% the external scripts).
+\def\mmz at clear@extraction at log{%
+  \begingroup
+  \immediate\openout0{\mmzUnquote\jobname.mmz.log"}%
+  \immediate\closeout0
+  \endgroup
+}
+% |#1| is the extraction method.
+\def\mmz at check@extraction at log#1{%
+  \begingroup \def\extractionmethod{#1}%
+  \mmz at tempfalse \let\mmz at orig@endinput\endinput
+  \def\endinput{\mmz at temptrue\mmz at orig@endinput}%
+  \@input{\jobname.mmz.log}%
+  \ifmmz at temp \else \mmz at extraction@error \fi \endgroup }
+\def\mmz at extraction@error{%
+  \PackageWarning{memoize}{Extraction of externs from document "\mmzUnquote\jobname.pdf"
+    using method "\extractionmethod" was unsuccessful. Have you set the
+    shell escape mode as suggested in chapter 1 of the manual?}{}}
+%
+% \subsection{The record files}
+% \label{sec:code:record}
+%
+% \begin{key}{record}
+%   This key activates a record \meta{type}: the hooks defined by that record
+%   \meta{type} will henceforth be executed at the appropriate places.
+%   
+%   A \meta{hook} of a particular \meta{type} resides in |pgfkeys| path
+%   |/mmz/record/|\meta{type}|/|\meta{hook}, and is invoked via
+%   |/mmz/record/|\meta{hook}.  Record type activation thus appends a call of
+%   the former to the latter.  It does so using handler |.try|, so that
+%   unneeded hooks may be left undefined.
+% 
+\mmzset{
+  record/.style={%
+    record/begin/.append style={
+      /mmz/record/#1/begin/.try,
+      % The |begin| hook also executes the |prefix| hook, so that |\mmzPrefix|
+      % surely occurs at the top of the |.mmz| file.  Listing each prefix type
+      % separately in this hook ensures that |prefix| of a certain type is
+      % executed after that type's |begin|.
+      /mmz/record/#1/prefix/.try/.expanded=\mmz at prefix@path,
+    },
+    record/prefix/.append style={/mmz/record/#1/prefix/.try={##1}},
+    record/new extern/.append style={/mmz/record/#1/new extern/.try={##1}},
+    record/used extern/.append style={/mmz/record/#1/used extern/.try={##1}},
+    record/new cmemo/.append style={/mmz/record/#1/new cmemo/.try={##1}},
+    record/new ccmemo/.append style={/mmz/record/#1/new ccmemo/.try={##1}},
+    record/used cmemo/.append style={/mmz/record/#1/used cmemo/.try={##1}},
+    record/used ccmemo/.append style={/mmz/record/#1/used ccmemo/.try={##1}},
+    record/end/.append style={/mmz/record/#1/end/.try},
+  },
+}
+% \end{key}
+% 
+% \begin{key}{no record}
+%   This key deactivates all record types.  Below, we use it to initialize the
+%   relevant keys; in the user code, it may be used to deactivate the
+%   preactivated |mmz| record type.
+\mmzset{
+  no record/.style={%
+    % The |begin| hook clears itself after invocation, to prevent double
+    % execution.  Consequently, |record/begin| may be executed by the user in
+    % the preamble, without any ill effects.
+    record/begin/.style={record/begin/.style={}},
+    % The |prefix| key invokes itself again when the group closes.  This way,
+    % we can correctly track the path prefix changes in the |.mmz| even if
+    % |path| is executed in a group.
+    record/prefix/.code={\aftergroup\mmz at record@prefix},
+    record/new extern/.code={},
+    record/used extern/.code={},
+    record/new cmemo/.code={},
+    record/new ccmemo/.code={},
+    record/used cmemo/.code={},
+    record/used ccmemo/.code={},
+    % The |end| hook clears itself after invocation, to prevent double
+    % execution.  Consequently, |record/end| may be executed by the user before
+    % the end of the document, without any ill effects.
+    record/end/.style={record/end/.code={}},
+  }
+}
+% \end{key}
+% We define this macro because |\aftergroup|, used in |record/prefix|, only
+% accepts a token.
+\def\mmz at record@prefix{%
+  \mmzset{/mmz/record/prefix/.expanded=\mmz at prefix@path}%
+}
+% \paragraph{Initialize} the hook keys, preactivate |mmz| record type, and
+% execute hooks |begin| and |end| at the edges of the document.
+\mmzset{
+  no record,
+  record=mmz,
+  begindocument/.append style={record/begin},
+  enddocument/afterlastpage/.append style={record/end},
+}
+% 
+% \subsubsection{The \texttt{.mmz} file}
+% \label{sec:code:record:mmz}
+% 
+% Think of the |.mmz| record file as a \hologo{TeX}-readable log file, which
+% lets the extraction procedure know what happened in the previous compilation.
+% The file is in \hologo{TeX} format, so that we can trigger internal
+% \hologo{TeX}-based extraction by simply inputting it.  The commands it
+% contains are intentionally as simple as possible (just a macro plus braced
+% arguments), to facilitate parsing by the external scripts.
+% 
+% These hooks simply put the calls of the corresponding macros into the file.
+% All but hooks but |begin| and |end| receive the full path to the relevant
+% file as the only argument (ok, |prefix| receives the full path prefix, as set
+% by key |path|).
+% 
+% \begin{key}{record/mmz/...}
+\mmzset{
+  record/mmz/begin/.code={%
+    \newwrite\mmz at mmzout
+    % The record file has a fixed name (the jobname plus the |.mmz| suffix) and
+    % location (the current directory, i.e.\ the directory where \hologo{TeX}
+    % is executed from; usually, this will be the directory containing the
+    % \hologo{TeX} source).
+    \immediate\openout\mmz at mmzout{\jobname.mmz}%
+  },
+  % The |\mmzPrefix| is used by the clean-up script, which will remove all
+  % files with the given path prefix but (unless called with |--all|) those
+  % mentioned in the |.mmz|.  Now this script could in principle figure out
+  % what to remove by inspecting the paths to utilized\slash created
+  % memos\slash externs in the |.mmz| file, but this method could lead to
+  % problems in case of an incomplete (perhaps empty) |.mmz| file created by a
+  % failed compilation.  Recording the path prefix in the |.mmz| radically
+  % increases the chances of a successful clean-up, which is doubly important,
+  % because a clean-up is sometimes precisely what we need to do to recover
+  % after a failed compilation.
+  record/mmz/prefix/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzPrefix{#1}}%
+  },
+  record/mmz/new extern/.code={%
+    % While this key receives a single formal argument, Memoize also prepares
+    % macros |\externbasepath| (|#1| without the |.pdf| suffix), |\pagenumber|
+    % (of the extern page in the document PDF), and |\expectedwidth| and
+    % |\expectedheight| (of the extern page).
+    \immediate\write\mmz at mmzout{%
+      \noexpand\mmzNewExtern{#1}{\pagenumber}{\expectedwidth}{\expectedheight}%
+    }%
+  },
+  record/mmz/new cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCMemo{#1}}%
+  },
+  record/mmz/new ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCCMemo{#1}}%
+  },
+  record/mmz/used extern/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedExtern{#1}}%
+  },
+  record/mmz/used cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCMemo{#1}}%
+  },
+  record/mmz/used ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCCMemo{#1}}%
+  },
+  record/mmz/end/.code={%
+    % Add the |\endinput| marker to signal that the file is complete.
+    \immediate\write\mmz at mmzout{\noexpand\endinput}%
+    \immediate\closeout\mmz at mmzout
+  },
+  % 
+  % \end{key}
+  % \subsubsection{The shell scripts}
+% 
+% We define two shell script record types: |sh| for Linux, and |bat| for
+% Windows.
+%
+% \begin{key}{sh, bat}
+%   These keys set the shell script filenames.
+%   \bigskip
+  sh/.store in=\mmz at shname,
+  sh=memoize-extract.\jobname.sh,
+  bat/.store in=\mmz at batname,
+  bat=memoize-extract.\jobname.bat,
+% \end{key}
+%   
+% \begin{key}{record/sh/...} Define the Linux shell script record type.
+  record/sh/begin/.code={%
+    \newwrite\mmz at shout
+    \immediate\openout\mmz at shout{\mmz at shname}%
+  },
+  record/sh/new extern/.code={%
+    \begingroup
+    % Macro |\mmz at tex@extraction at systemcall| is customizable through |tex
+    % extraction command|, |tex extraction options| and |tex extraction
+    % script|.
+    \immediate\write\mmz at shout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/sh/end/.code={%
+    \immediate\closeout\mmz at shout
+  },
+% \end{key}
+% 
+% \begin{key}{record/bat/...}
+%   Rinse and repeat for Windows.
+  record/bat/begin/.code={%
+    \newwrite\mmz at batout
+    \immediate\openout\mmz at batout{\mmz at batname}%
+  },
+  record/bat/new extern/.code={%
+    \begingroup
+    \immediate\write\mmz at batout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/bat/end/.code={%
+    \immediate\closeout\mmz at batout
+  },
+% \end{key}
+%
+% \subsubsection{The Makefile} 
+% 
+% The implementation of the Makefile record type is the most complex so far, as
+% we need to keep track of the targets.
+% 
+% \begin{key}{makefile}
+%   This key sets the makefile filename.
+  makefile/.store in=\mmz at makefilename,
+  makefile=memoize-extract.\jobname.makefile,
+}
+% \end{key}
+% 
+% We need to define a macro which expands to the tab character of catcode
+% ``other'', to use as the recipe prefix.
+\begingroup
+\catcode`\^^I=12
+\gdef\mmz at makefile@recipe at prefix{^^I}%
+\endgroup
+% \begin{key}{record/makefile/...}
+%   Define the Makefile record type.
+\mmzset{
+  record/makefile/begin/.code={%
+    % We initialize the record type by opening the file and setting makefile
+    % variables |.DEFAULT_GOAL| and |.PHONY|.
+    \newwrite\mmz at makefileout
+    \newtoks\mmz at makefile@externs
+    \immediate\openout\mmz at makefileout{\mmz at makefilename}%
+    \immediate\write\mmz at makefileout{.DEFAULT_GOAL = externs}%
+    \immediate\write\mmz at makefileout{.PHONY: externs}%
+  },
+  % The crucial part, writing out the extraction rule. The target comes first,
+  % then the recipe, which is whatever the user has set by |tex extraction
+  % command|, |tex extraction options| and |tex extraction script|.
+  record/makefile/new extern/.code={%
+    % The target extern file:
+    \immediate\write\mmz at makefileout{#1:}%
+    \begingroup
+    % The recipe is whatever the user set by |tex extraction
+    % command|, |tex extraction options| and |tex extraction script|.
+    \immediate\write\mmz at makefileout{%
+      \mmz at makefile@recipe at prefix\mmz at tex@extraction at systemcall}%
+    \endgroup
+    % Append the extern file to list of targets.
+    \xtoksapp\mmz at makefile@externs{#1\space}%
+  },
+  record/makefile/end/.code={%
+    % Before closing the file, we list the extern files as the prerequisites of
+    % our phony default target, |externs|.
+    \immediate\write\mmz at makefileout{externs: \the\mmz at makefile@externs}%
+    \immediate\closeout\mmz at makefileout
+  },
+}
+% \end{key}
+% 
+% 
+% \subsection{\hologo{TeX}-based extraction}
+% \label{sec:code:extract:tex}
+% 
+% \begin{key}{extract/tex}
+%   We trigger the \hologo{TeX}-based extraction by inputting the |.mmz| record
+%   file.
+\mmzset{
+  extract/tex/.code={%
+    \begingroup
+    \@input{\jobname.mmz}%
+    \endgroup
+  },
+}
+% \end{key}
+%
+% \begingroup
+% \setlength\MacroIndent{2em}
+% \begin{macro}{\mmzUsedCMemo,\mmzUsedCCMemo,\mmzUsedExtern,\mmzNewCMemo,\mmzNewCCMemo,\mmzPrefix}
+%   We can ignore everything but |\mmzNewExtern|s.  All these macros receive a
+%   single argument.
+\def\mmzUsedCMemo#1{}
+\def\mmzUsedCCMemo#1{}
+\def\mmzUsedExtern#1{}
+\def\mmzNewCMemo#1{}
+\def\mmzNewCCMemo#1{}
+\def\mmzPrefix#1{}
+% \end{macro}
+% \endgroup
+% 
+% \begin{macro}{\mmzNewExtern}
+%   Command |\mmzNewExtern| takes four arguments.  It instructs us to extract
+%   page |#2| of document |\jobname.pdf| to file |#1|.  During the extraction,
+%   we will check whether the size of the extern matches the given expected
+%   width (|#3|) and total height (|#4|).
+% 
+%   We perform the extraction by an embedded \hologo{TeX} call.  The system
+%   command that gets executed is stored in |\mmz at tex@extraction at systemcall|,
+%   which is set by |tex extraction command| and friends; by default, we
+%   execute |pdftex|.
+% 
+\def\mmzNewExtern#1{%
+  % The \hologo{TeX} executable expects the basename as the argument, so we
+  % strip away the |.pdf| suffix.
+  \mmz at new@extern at i#1\mmz at temp
+}
+\def\mmz at new@extern at i#1.pdf\mmz at temp#2#3#4{%
+  \begingroup
+  % Define the macros used in |\mmz at tex@extraction at systemcall|.
+  \def\externbasepath{#1}%
+  \def\pagenumber{#2}%
+  \def\expectedwidth{#3}%
+  \def\expectedheight{#4}%
+  % Empty out the extraction log.
+  \mmz at clear@extraction at log
+  % Extract.
+  \pdf at system{\mmz at tex@extraction at systemcall}%
+  % Was the extraction successful?  We temporarily redefine the extraction
+  % error message macro (suited for the external extraction scripts, which
+  % extract all externs in one go) to report the exact problematic extern page.
+  \let\mmz at extraction@error\mmz at pageextraction@error
+  \mmz at check@extraction at log{tex}%
+  \endgroup
+}
+% \end{macro}
+\def\mmz at pageextraction@error{%
+  \PackageError{memoize}{Extraction of extern page \pagenumber\space from
+    document "\mmzUnquote\jobname.pdf" using method "\extractionmethod" was unsuccessful.
+    Have you set the shell escape mode as suggested in chapter 1 of the
+    manual?}{If "\mmzvalueof{tex extraction command}" was executed,
+    shell escape mode is not the problem, and inspecting "\externbasepath.log"
+    might give you a clue what's wrong}}
+% 
+% \begin{key}{tex extraction command, tex extraction options, tex extraction script}
+%   Using these keys, we set the system call
+%   which will be invoked for each extern page.  The value of this key is
+%   expanded when executing the system command.  The user may deploy the
+%   following macros in the value of these keys:
+% \begin{itemize}
+% \item |\externbasepath|: the extern PDF that should be produced, minus the
+%   |.pdf| suffix;
+% \item |\pagenumber|: the page number to be extracted;
+% \item |\expectedwidth|: the expected width of the extracted page;
+% \item |\expectedheight|: the expected total height of the extracted page;
+% \end{itemize}
+\def\mmz at tex@extraction at systemcall{%
+  \mmzvalueof{tex extraction command}\space
+  \mmzvalueof{tex extraction options}\space
+  "\mmzvalueof{tex extraction script}"%
+}
+% \end{key}
+%
+% \paragraph{The default} system call for \hologo{TeX}-based extern extraction.
+% As this method, despite being \hologo{TeX}-based, shares no code with the
+% document, we're free to implement it with any engine and format we want.  For
+% reasons of speed, we clearly go for the plain \hologo{pdfTeX}.\footnote{I
+% implemented the first version of \hologo{TeX}-based extraction using
+% \hologo{LaTeX} and package \texttt{graphicx}, and it was (running with
+% \hologo{pdfTeX} engine) almost four times slower than the current plain
+% \hologo{TeX} implementation.}  We perform the extraction by a little
+% \hologo{TeX} script, |memoize-extract-one|, inputted at the end of the value
+% given to |tex extraction script|.
+\mmzset{
+  tex extraction command/.initial=pdftex,
+  tex extraction options/.initial={%
+%   \begin{listingregion}{tex-extraction-options.tex}
+    -halt-on-error
+    -interaction=batchmode
+    -jobname "\externbasepath"
+    \ifdefempty\mmzOutputDirectory{}{-output-directory "\mmzOutputDirectory"}
+% \end{listingregion}
+  },
+  tex extraction script/.initial={%
+%   \begin{listingregion}{tex-extraction-script.tex} ^^A todo: context
+    \def\noexpand\fromdocument{"\mmzOutputDirectory"\jobname.pdf}%
+    \def\noexpand\pagenumber{\pagenumber}%
+    \def\noexpand\expectedwidth{\expectedwidth}%
+    \def\noexpand\expectedheight{\expectedheight}%
+    \def\noexpand\logfile{\jobname.mmz.log}%
+    \unexpanded{%
+      \def\warningtemplate{%
+        %<latex>\noexpand\PackageWarning{memoize}{\warningtext}%
+        %<plain>\warning{memoize: \warningtext}%
+        %<context>\warning{memoize: \warningtext}%
+      }}%
+    \ifdef\XeTeXversion{}{%
+      \def\noexpand\mmzpdfmajorversion{\the\pdfmajorversion}%
+      \def\noexpand\mmzpdfminorversion{\the\pdfminorversion}%
+    }%
+    \noexpand\input memoize-extract-one
+% \end{listingregion}
+  },
+}
+%</mmz>
+%
+% \subsubsection{\texttt{memoize-extract-one.tex}}
+% 
+% The rest of the code of this section resides in file
+% |memoize-extract-one.tex|.  It is used to extract a single extern page from
+% the document; it also checks whether the extern page dimensions are as
+% expected, and passes a warning to the main job if that is not the case.  For
+% the reason of speed, the extraction script is in \hologo{plainTeX} format.
+% For the same reason, it is compiled by \hologo{pdfTeX} engine by default, but
+% we nevertheless take care that it will work with other (supported) engines as
+% well.
+% 
+%<*extract-one>
+\catcode`\@11\relax
+\def\@firstoftwo#1#2{#1}
+\def\@secondoftwo#1#2{#2}
+% 
+% Set the PDF version (maybe) passed to the script via |\mmzpdfmajorversion|
+% and |\mmzpdfminorversion|.
+\ifdefined\XeTeXversion
+\else
+  \ifdefined\luatexversion
+    \def\pdfmajorversion{\pdfvariable majorversion}%
+    \def\pdfminorversion{\pdfvariable minorversion}%
+  \fi
+  \ifdefined\mmzpdfmajorversion
+    \pdfmajorversion\mmzpdfmajorversion\relax
+  \fi
+  \ifdefined\mmzpdfminorversion
+    \pdfminorversion\mmzpdfminorversion\relax    
+  \fi
+\fi
+% Allocate a new output stream, always --- |\newwrite| is |\outer| and thus
+% cannot appear in a conditional.
+\newwrite\extractionlog
+% Are we requested to produce a log file?
+\ifdefined\logfile
+  \immediate\openout\extractionlog{\logfile}%
+  % Define a macro which both outputs the warning message and writes it to the
+  % extraction log.
+  \def\doublewarning#1{%
+    \message{#1}%
+    \def\warningtext{#1}%
+    % This script will be called from different formats, so it is up to the
+    % main job to tell us, by defining macro |\warningtemplate|, how to throw a
+    % warning in the log file.
+    \immediate\write\extractionlog{%
+      \ifdefined\warningtemplate\warningtemplate\else\warningtext\fi
+    }%
+  }%
+\else
+  \let\doublewarning\message
+\fi
+\newif\ifforce
+\ifdefined\force
+  \csname force\force\endcsname
+\fi
+% \begin{macro}{\mmz at if@roughly at equal}
+%   This macro checks whether the given dimensions (|#2| and |#3|) are equal
+%   within the tolerance given by |#1|.  We use the macro both in the
+%   extraction script and in the main package.  (We don't use |\ifpdfabsdim|,
+%     because it is unavailable in \hologo{XeTeX}.)
+%</extract-one>
+%<*mmz,extract-one>
+\def\mmz at tolerance{0.01pt}
+\def\mmz at if@roughly at equal#1#2#3{%
+  \dimen0=\dimexpr#2-#3\relax
+  \ifdim\dimen0<0pt
+    \dimen0=-\dimen0\relax
+  \fi
+  \ifdim\dimen0>#1\relax
+    \expandafter\@secondoftwo
+  \else
+    % The exact tolerated difference is, well, tolerated.  This is a must to
+    % support |tolerance=0pt|.
+    \expandafter\@firstoftwo
+  \fi
+}%
+%</mmz,extract-one>
+%<*extract-one>
+% Grab the extern page from the document and put it in a box.
+\ifdefined\XeTeXversion
+  \setbox0=\hbox{\XeTeXpdffile \fromdocument\space page \pagenumber media}%
+\else
+  \ifdefined\luatexversion
+    \saveimageresource page \pagenumber mediabox {\fromdocument}%
+    \setbox0=\hbox{\useimageresource\lastsavedimageresourceindex}%
+  \else
+    \pdfximage page \pagenumber mediabox {\fromdocument}%
+    \setbox0=\hbox{\pdfrefximage\pdflastximage}%
+  \fi
+\fi
+% Check whether the extern page is of the expected size.
+\newif\ifbaddimensions
+\ifdefined\expectedwidth
+  \ifdefined\expectedheight
+    \mmz at if@roughly at equal{\mmz at tolerance}{\wd0}{\expectedwidth}{%
+      \mmz at if@roughly at equal{\mmz at tolerance}{\ht0}{\expectedheight}%
+        {}%
+        {\baddimensionstrue}%
+    }{\baddimensionstrue}%
+  \fi
+\fi
+% We'll setup the page geometry of the extern file and shipout the extern ---
+% if all is well, or we're forced to do it.
+\ifdefined\luatexversion
+  \let\pdfpagewidth\pagewidth
+  \let\pdfpageheight\pageheight
+  \def\pdfhorigin{\pdfvariable horigin}%
+  \def\pdfvorigin{\pdfvariable vorigin}%
+\fi
+\def\do at shipout{%
+  \pdfpagewidth=\wd0
+  \pdfpageheight=\ht0
+  \ifdefined\XeTeXversion
+    \hoffset -1 true in
+    \voffset -1 true in
+  \else
+    \pdfhorigin=0pt
+    \pdfvorigin=0pt
+  \fi
+  \shipout\box0
+}
+\ifbaddimensions
+  \doublewarning{I refuse to extract page \pagenumber\space from
+    "\fromdocument", because its size (\the\wd0 \space x \the\ht0) is not
+    what I expected (\expectedwidth\space x \expectedheight)}%
+  \ifforce\do at shipout\fi
+\else
+  \do at shipout
+\fi
+% If logging is in effect and the extern dimensions were not what we expected,
+% write a warning into the log.
+\ifdefined\logfile
+  \immediate\write\extractionlog{\noexpand\endinput}%
+  \immediate\closeout\extractionlog
+\fi
+\bye
+%</extract-one>
+% \end{macro}
+% 
+% \section{Automemoization}
+% \label{sec:code:automemoization}
+% 
+% \paragraph{Install} the advising framework implemented by our auxiliary
+% package Advice, which automemoization depends on.  This will define keys
+% |auto|, |activate| etc.\ in our keypath.
+%<*mmz>
+\mmzset{
+  .install advice={setup key=auto, activation=deferred},
+  % We switch to the immediate activation at the end of the preamble.
+  begindocument/before/.append style={activation=immediate},
+}
+% 
+% \begin{key}{manual}
+%   Unless the user switched on |manual|, we perform the deferred
+%   (de)activations at the beginning of the document (and then clear the style,
+%   so that any further deferred activations will start with a clean slate).
+%   In \hologo{LaTeX}, we will use the latest possible hook,
+%   |begindocument/end|, as we want to hack into commands defined by other
+%   packages.  (The \hologo{TeX} conditional needs to be defined before using
+%   it in |.append code| below.
+\newif\ifmmz at manual
+\mmzset{
+  manual/.is if=mmz at manual,
+  begindocument/end/.append code={%
+    \ifmmz at manual
+    \else
+      \pgfkeysalso{activate deferred,activate deferred/.code={}}%
+    \fi
+  },
+% \end{key}
+% 
+% \paragraph{Announce} Memoize's run conditions and handlers.
+  auto/.cd,
+  run if memoization is possible/.style={
+    run conditions=\mmz at auto@rc at if@memoization at possible
+  },
+  run if memoizing/.style={run conditions=\mmz at auto@rc at if@memoizing},
+  apply options/.style={
+    bailout handler=\mmz at auto@bailout,
+    outer handler=\mmz at auto@outer,
+  },
+  memoize/.style={
+    run if memoization is possible,
+    apply options,
+    inner handler=\mmz at auto@memoize
+  },
+  %<*latex>
+  noop/.style={run if memoization is possible, noop \AdviceType},
+  noop command/.style={apply options, inner handler=\mmz at auto@noop},
+  noop environment/.style={
+    outer handler=\mmz at auto@noop at env, bailout handler=\mmz at auto@bailout},
+  %</latex>
+  %<plain,context>noop/.style={inner handler=\mmz at auto@noop},
+  nomemoize/.style={noop, options=disable},
+  replicate/.style={run if memoizing, inner handler=\mmz at auto@replicate},
+}
+%
+% \paragraph{Abortion}
+% We cheat and let the |run conditions| do the work --- it is cheaper to just
+% always abort than to invoke the outer handler.  (As we don't set
+% |\AdviceRuntrue|, the run conditions will never be satisfied.)
+% \begin{listingregion}{_auto-abort.tex}
+\mmzset{
+  auto/abort/.style={run conditions=\mmzAbort},
+}
+% \end{listingregion}
+% And the same for |unmemoizable|:
+\mmzset{
+  auto/unmemoizable/.style={run conditions=\mmzUnmemoizable},
+}
+% For one, we abort upon |\pdfsavepos| (called |\savepos| in \hologo{LuaTeX}).
+% Second, unless in \hologo{LuaTeX}, we submit |\errmessage|, which allows us
+% to detect at least some errors --- in \hologo{LuaTeX}, we have a more
+% bullet-proof system of detecting errors, see |\mmz at memoize| in
+% \S\ref{sec:code:memoization-process}.
+\ifdef\luatexversion{%
+  \mmzset{auto=\savepos{abort}}
+}{%
+  \mmzset{
+    auto=\pdfsavepos{abort},
+    auto=\errmessage{abort},
+  }
+}
+% 
+% \begin{mmzautokey}{run if memoization is possible}
+%   \begin{macro}{\mmz at auto@rc at if@memoization at possible}
+%     These run conditions are used by |memoize| and |noop|: Memoize should be
+%     enabled, but we should not be already within Memoize, i.e.\ memoizing or
+%     normally compiling some code submitted to memoization.
+%     \begin{listingregion}{_auto-run-if-memoization-is-possible.tex}
+\def\mmz at auto@rc at if@memoization at possible{%
+  \ifmemoize
+    \ifinmemoize
+    \else
+      \AdviceRuntrue
+    \fi
+  \fi
+}
+% \end{listingregion}
+% \end{macro}
+% \end{mmzautokey}
+% 
+% \begin{mmzautokey}{run if memoizing}
+%   \begin{macro}{\mmz at auto@rc at if@memoizing}
+%     These run conditions are used by |\label| and |\ref|: they should
+%     be handled only during memoization (which implies that Memoize is enabled).
+\def\mmz at auto@rc at if@memoizing{%
+  \ifmemoizing\AdviceRuntrue\fi
+}
+% \end{macro}
+% \end{mmzautokey}
+%
+% \begin{macro}{\mmznext}
+%   The next-options, set by this macro, will be applied to the next, and only
+%   next instance of automemoization.  We set the next-options globally, so
+%   that only the linear order of the invocation matters. Note that |\mmznext|,
+%   being a user command, must also be defined in package |nomemoize|.
+%</mmz>
+%<nommz>\def\mmznext#1{\ignorespaces}
+%<*mmz>
+\def\mmznext#1{\gdef\mmz at next{#1}\ignorespaces}
+\mmznext{}%
+% \end{macro}
+% 
+% \begin{mmzautokey}{apply options}
+%   \begin{macro}{\mmz at auto@outer,\mmz at auto@bailout}
+%     The outer and the bailout handler defined here work as a team.  The outer
+%     handler's job is to apply the auto- and the next-options; therefore, the
+%     bailout handler must consume the next-options as well.  To keep the
+%     option application local, the outer handler opens a group, which is
+%     expected to be closed by the inner handler.  This key is used by
+%     |memoize| and |noop command|.
+%     \begin{listingregion}{_auto-memoize-outer.tex}
+\def\mmz at auto@outer{%
+  \begingroup
+  \mmzAutoInit
+  \AdviceCollector
+}
+% \end{listingregion}
+% \begin{listingregion}{_auto-memoize-bailout.tex}
+\def\mmz at auto@bailout{%
+  \mmznext{}%
+}
+% \end{listingregion}
+% \bigskip
+% \end{macro}
+% \end{mmzautokey}
+% 
+% \begin{macro}{\mmzAutoInit}
+%   Apply first the auto-options, and then the next-options (and clear the
+%   latter).  Finally, if we have any extra collector options (set by the
+%   |verbatim| keys), append them to Advice's (raw) collector options.
+\def\mmzAutoInit{%
+  \ifdefempty\AdviceOptions{}{\expandafter\mmzset\expandafter{\AdviceOptions}}%
+  \ifdefempty\mmz at next{}{\expandafter\mmzset\expandafter{\mmz at next}\mmznext{}}%
+  \eappto\AdviceRawCollectorOptions{\expandonce\mmzRawCollectorOptions}%
+}
+% \end{macro}
+% 
+% \begin{mmzautokey}{memoize}
+%   \begin{macro}{\mmz at auto@memoize}
+%     This key installs the inner handler for memoization.  If you compare this
+%     handler to the definition of |\mmz| in
+%     section~\ref{sec:code:memoization:manual}, you will see that the only
+%     thing left to do here is to start memoization with |\Memoize|, everything
+%     else is already done by the advising framework, as customized by Memoize.
+% 
+%     The first argument to |\Memoize| is the memoization key (which the code
+%     md5sum is computed off of); it consists of the handled code (the contents
+%     of |\AdviceReplaced|) and its arguments, which were collected into |##1|.
+%     The second argument is the code which the memoization driver will
+%     execute.  |\AdviceOriginal|, if invoked right away, would execute the
+%     original command; but as this macro is only guaranteed to refer to this
+%     command within the advice handlers, we expand it before calling |\Memoize|.
+%     that command.
+% 
+%     Note that we don't have to define different handlers for commands and
+%     environments, and for different \hologo{TeX} formats.  When memoizing
+%     command |\foo|, |\AdviceReplaced| contains |\foo|.  When memoizing
+%     environment |foo|, |\AdviceReplaced| contains |\begin{foo}|, |\foo| or
+%       |\startfoo|, depending on the format, while the closing tag
+%       (|\end{foo}|, |\endfoo| or |\stopfoo|) occurs at the end of the
+%     collected arguments, because |apply options| appended
+%     |\collargsEndTagtrue| to |raw collector options|.
+% 
+%     This macro has no formal parameters, because the collected arguments will
+%     be grabbed by |\mmz at marshal|, which we have to go through because
+%     executing |\Memoize| closes the memoization group and we lose the current
+%     value of |\ifmmz at ignorespaces|.  (We also can't use |\aftergroup|,
+%       because closing the group is not the final thing |\Memoize| does.)
+%       \begin{listingregion}{_auto-memoize-inner.tex}
+\long\def\mmz at auto@memoize#1{%
+  \expanded{%
+    \noexpand\Memoize
+      {\expandonce\AdviceReplaced\unexpanded{#1}}%
+      {\expandonce\AdviceOriginal\unexpanded{#1}}%
+    \ifmmz at ignorespaces\ignorespaces\fi
+  }%
+}
+% \end{listingregion}
+% \end{macro}
+% \end{mmzautokey}
+%
+% \begin{mmzautokey}{noop}
+%   \begin{macro}{\mmz at auto@noop,\mmz at auto@noop at env}
+%     The no-operation handler can be used to apply certain options for the
+%     span of the execution of the handled command or environment.  This is
+%     exploited by |auto/nomemoize|, which sets |disable| as an auto-option.
+% 
+%     The handler for commands and non-\hologo{LaTeX} environments is
+%     implemented as an inner handler.  On its own, it does nothing except
+%     honor |verbatim| and |ignore spaces| (only takes care of |verbatim| and
+%     |ignore spaces| (in the same way as the memoization handler above), but
+%     it is intended to be used alongside the default outer handler, which
+%     applies the auto- and the next-options.  As that handler opens a group
+%     (and this handler closes it), we have effectively delimited the effect of
+%     those options to this invocation of the handled command or environment.
+\long\def\mmz at auto@noop#1{%
+  \expandafter\mmz at maybe@scantokens\expandafter{\AdviceOriginal#1}%
+  \expandafter\endgroup
+  \ifmmz at ignorespaces\ignorespaces\fi
+}
+% In \hologo{LaTeX}, and only there, commands and environments need separate
+% treatment.  As \hologo{LaTeX} environments introduce a group of their own, we
+% can simply hook our initialization into the beginning of the environment (as
+% a one-time hook).  Consequently, we don't need to collect the environment
+% body, so this can be an outer handler.
+%<*latex>
+\def\mmz at auto@noop at env{%
+  \AddToHookNext{env/\AdviceName/begin}{%
+    \mmzAutoInit
+    \ifmmz at ignorespaces\ignorespacesafterend\fi
+  }%
+  \AdviceOriginal
+}
+%</latex>
+% \end{macro}
+% \end{mmzautokey}
+%
+% \begin{mmzautokey}{replicate}
+%   \begin{macro}{\mmz at auto@replicate}
+%     This inner handler writes a copy of the handled command or environment's
+%     invocation into the cc-memo (and then executes it).  As it is used
+%     alongside |run if memoizing|, the replicated command in the cc-memo will
+%     always execute the original command.  The system works even if
+%     replication is off when the cc-memo is input; in that case, the control
+%     sequence in the cc-memo directly executes the original command.
+% 
+%     This handler takes an option, |expanded| --- if given, the collected
+%     arguments will be expanded (under protection) before being written into
+%     the cc-memo.
+\def\mmz at auto@replicate#1{%
+  \begingroup
+  \let\mmz at auto@replicate at expansion\unexpanded
+  \expandafter\pgfqkeys\expanded{{/mmz/auto/replicate}{\AdviceOptions}}%
+  %<latex>\let\protect\noexpand
+  \expanded{%
+    \endgroup
+    \noexpand\gtoksapp\noexpand\mmzCCMemo{%
+      \expandonce\AdviceReplaced\mmz at auto@replicate at expansion{#1}}%
+    \expandonce\AdviceOriginal\unexpanded{#1}%
+  }%
+}
+\pgfqkeys{/mmz/auto/replicate}{
+  expanded/.code={\let\mmz at auto@replicate at expansion\@firstofone},
+}
+% \end{macro}
+% \end{mmzautokey}
+% 
+% \subsection{\hologo{LaTeX}-specific handlers}
+%
+% We handle cross-referencing (both the |\label| and the |\ref| side) and
+% indexing.  Note that the latter is a straightforward instance of replication.
+% 
+%<*latex>
+% \begin{listingregion}{_auto-memoize-ref.tex}
+\mmzset{
+  auto/.cd,
+  ref/.style={outer handler=\mmz at auto@ref\mmzNoRef, run if memoizing},
+  force ref/.style={outer handler=\mmz at auto@ref\mmzForceNoRef, run if memoizing},
+}
+% \end{listingregion}
+\mmzset{
+  auto=\ref{ref},
+  auto=\pageref{ref},
+  auto=\label{run if memoizing, outer handler=\mmz at auto@label},
+  auto=\index{replicate, args=m, expanded},
+}
+% 
+% \begin{mmzautokey}{ref, force ref}
+%   \begin{macro}{\mmz at auto@ref}
+%   These keys install an outer handler which appends a cross-reference to the
+%   context.  |force ref| does this even if the reference key is undefined,
+%   while |ref| aborts memoization in such a case --- the idea is that it makes
+%   no sense to memoize when we expect the context to change in the next
+%   compilation anyway.
+% 
+%   Any command taking a mandatory braced reference key argument potentially
+%   preceded by optional arguments of (almost) any kind may be submitted to
+%   these keys. This follows from the parameter list of |\mmz at auto@ref at i|,
+%   where |#2| grabs everything up to the first opening brace.  The downside of
+%   the flexibility regarding the optional arguments is that unbraced
+%   single-token reference keys will cause an error, but as such usages of
+%   |\ref| and friends should be virtually inexistent, we let the bug stay.
+% 
+%   |#1| should be either |\mmzNoRef| or |\mmzForceNoRef|. |#2| will receive
+%   any optional arguments of |\ref| (or |\pageref|, or whatever), and |#3| in
+%   |\mmz at auto@ref at i| is the cross-reference key.
+%   \begin{listingregion}{_auto-memoize-ref.tex}
+\def\mmz at auto@ref#1#2#{\mmz at auto@ref at i#1{#2}}
+\def\mmz at auto@ref at i#1#2#3{%
+  #1{#3}%
+  \AdviceOriginal#2{#3}%
+}
+% \end{listingregion}
+% \end{macro}
+% \end{mmzautokey}
+% 
+% \begin{macro}{\mmzForceNoRef,\mmzNoRef}
+%   These macros do the real job in the outer handlers for cross-referencing,
+%   but it might be useful to have them publicly available.  |\mmzForceNoRef|
+%   appends the reference key to the context.  |\mmzNoRef| only does that if
+%   the reference is defined, otherwise it aborts the memoization.
+\def\mmzForceNoRef#1{%
+  \ifmemoizing
+    \expandafter\gtoksapp\expandafter\mmzContextExtra
+  \else
+    \expandafter\toksapp\expandafter\mmzContext
+  \fi
+  {r@#1={\csname r@#1\endcsname}}%
+  \ignorespaces
+}
+\def\mmzNoRef#1{%
+  \ifcsundef{r@#1}{\mmzAbort}{\mmzForceNoRef{#1}}%
+  \ignorespaces
+}
+% \end{macro}
+%
+% \begin{mmzautokey}{refrange, force refrange}
+%   \begin{macro}{\mmz at auto@refrange}
+%     Let's rinse and repeat for reference ranges. The code is virtually the
+%     same as above, but we grab two reference key arguments (|#3| and |#4|) in
+%     the final macro.\indentmacrocode
+\mmzset{
+  auto/.cd,
+  refrange/.style={outer handler=\mmz at auto@refrange\mmzNoRef,
+    bailout handler=\relax, run if memoizing},
+  force refrange/.style={outer handler=\mmz at auto@refrange\mmzForceNoRef,
+    bailout handler=\relax, run if memoizing},
+}
+% \noindentmacrocode
+\def\mmz at auto@refrange#1#2#{\mmz at auto@refrange at i#1{#2}}
+\def\mmz at auto@refrange at i#1#2#3#4{%
+  #1{#3}%
+  #1{#4}%
+  \AdviceOriginal#2{#3}{#4}%
+}
+% \end{macro}
+% \end{mmzautokey}
+% 
+% \begin{mmzautokey}{multiref, force multiref}
+%   \begin{macro}{\mmz at auto@multiref}
+%     And one final time, for ``multi-references'', such as |cleveref|'s
+%     |\cref|, which can take a comma-separated list of reference keys in the
+%     sole argument.  Again, only the final macro is any different, this time
+%     distributing |#1| (|\mmzNoRef| or |\mmzForceNoRef|) over |#3| by
+%     |\forcsvlist|.
+\mmzset{
+  auto/.cd,
+  multiref/.style={outer handler=\mmz at auto@multiref\mmzNoRef,
+    bailout handler=\relax, run if memoizing},
+  force multiref/.style={outer handler=\mmz at auto@multiref\mmzForceNoRef,
+    bailout handler=\relax, run if memoizing},
+}
+\def\mmz at auto@multiref#1#2#{\mmz at auto@multiref at i#1{#2}}
+\def\mmz at auto@multiref at i#1#2#3{%
+  \forcsvlist{#1}{#3}%
+  \AdviceOriginal#2{#3}%
+}
+%   \end{macro}
+% \end{mmzautokey}
+% 
+% \begin{macro}{\mmz at auto@label}
+%   The outer handler for \cs{label} must be defined specifically for this
+%   command.  The generic replicating handler is not enough here, as we need to
+%   replicate both the invocation of |\label| and the definition of
+%   |\@currentlabel|.
+\def\mmz at auto@label#1{%
+  \xtoksapp\mmzCCMemo{%
+    \noexpand\mmzLabel{#1}{\expandonce\@currentlabel}%
+  }%
+  \AdviceOriginal{#1}%
+}
+% \end{macro}
+% 
+% \begin{macro}{\mmzLabel}
+%   This is the macro that |\label|'s handler writes into the cc-memo.  The
+%   first argument is the reference key; the second argument is the value of
+%   |\@currentlabel| at the time of invocation |\label| during memoization,
+%   which this macro temporarily restores.
+\def\mmzLabel#1#2{%
+  \begingroup
+  \def\@currentlabel{#2}%
+  \label{#1}%
+  \endgroup  
+}
+%</latex>
+%</mmz>
+%   
+% \end{macro}
+% 
+% \section{Support for various classes and packages}
+% 
+% \subsection{\TikZ;}
+% \label{sec:code:mmz:tikz}
+%
+% In this section, we activate \TikZ; support (the collector is defined by
+% Advice).  All the action happens at the end of the preamble, so that we can
+% detect whether \TikZ; was loaded (regardless of whether Memoize was loaded
+% before \TikZ;, or vice versa), but still input the definitions.
+%<*mmz>
+\mmzset{
+  begindocument/before/.append code={%
+    %<latex>\@ifpackageloaded{tikz}{%
+    %<plain,context>\ifdefined\tikz
+      \input advice-tikz.code.tex
+    %<latex>}{}%
+    %<plain,context>\fi
+    % We define and activate the automemoization handlers for the \TikZ; command
+    % and environment.
+    \mmzset{%
+      % \begin{listingregion}{_auto-tikz-collector.tex}
+      auto=\tikz{memoize, collector=\AdviceCollectTikZArguments},
+      % \end{listingregion}
+      %/utils/exec={\tracingall},
+      auto={tikzpicture}{memoize},
+      % A hack to prevent memoizing pictures which are accidentally marked as
+      % remembered --- accidentally in the sense that because the document
+      % changed, the |.aux| file contains a |\pgfsyspdfmark| command which
+      % erroneously refers to the picture being memoized.  We know that
+      % memoizing a remembered picture can't be right, as we always abort on
+      % |\pdfsavepos|.  This is implemented by hacking into PGF's
+      % |\pgfsys at getposition|, and aborting memoization if the mark does not
+      % equal |\relax|.  (We have to duplicate |#| because of |.append code|.)
+      auto=\pgfsys at getposition{
+        run if memoizing, outer handler=\mmz at pgfsys@getposition},
+    }%    
+    \def\mmz at pgfsys@getposition##1{%
+      \expandafter\ifx\csname pgf at sys@pdf at mark@pos@##1\endcsname\relax
+      \else
+        \mmzAbort
+      \fi
+      \AdviceOriginal{##1}%
+    }%
+  },
+}
+%</mmz>
+% 
+%
+% \subsection{Forest}
+% \label{sec:code:forest}
+%
+% Forest will soon feature extensive memoization support, but for now, let's
+% just enable the basic, single extern externalization.
+%<*mmz>
+%<*latex>
+\mmzset{
+  begindocument/before/.append code={%
+    \@ifpackageloaded{forest}{%
+      \mmzset{
+        auto={forest}{memoize},
+% Yes, |\Forest| is defined using |xparse|.
+        auto=\Forest{memoize},
+      }%
+    }{}%
+  },
+}
+%</latex>
+% 
+% \subsection{Beamer}
+% \label{sec:code:beamer}
+%
+% The Beamer code is explained in \MS\ref{sec:per-overlay}.
+% 
+%<*latex>
+\AddToHook{begindocument/before}{\@ifclassloaded{beamer}{%
+  % \begin{listingregion}{per-overlay.tex}
+  \mmzset{per overlay/.style={
+    /mmz/context={%
+      overlay=\csname beamer at overlaynumber\endcsname,
+      pauses=\ifmemoizing
+               \mmzBeamerPauses
+             \else
+               \expandafter\the\csname c at beamerpauses\endcsname
+             \fi
+    },
+    /mmz/at begin memoization={%
+      \xdef\mmzBeamerPauses{\the\c at beamerpauses}%
+      \xtoksapp\mmzCMemo{%
+        \noexpand\mmzSetBeamerOverlays{\mmzBeamerPauses}{\beamer at overlaynumber}}%
+      \gtoksapp\mmzCCMemo{%
+        \only<\mmzBeamerOverlays>{}}%
+    },
+    /mmz/at end memoization={%
+      \xtoksapp\mmzCCMemo{%
+        \noexpand\setcounter{beamerpauses}{\the\c at beamerpauses}}%
+    },
+    /mmz/per overlay/.code={},
+  }}
+  \def\mmzSetBeamerOverlays#1#2{%
+    \ifnum\c at beamerpauses=#1\relax
+      \gdef\mmzBeamerOverlays{#2}%
+      \ifnum\beamer at overlaynumber<#2\relax \mmz at temptrue \else \mmz at tempfalse \fi
+    \else
+      \mmz at temptrue
+    \fi
+    \ifmmz at temp
+      \appto\mmzAtBeginMemoization{%
+        \gtoksapp\mmzCMemo{\mmzSetBeamerOverlays{#1}{#2}}}%
+    \fi
+  }%
+  % \end{listingregion}
+}{}}
+%</latex>
+%
+%
+% \section{Initialization}
+% \label{sec:code:initialization}
+%
+% \begin{key}{begindocument/before, begindocument, begindocument/end,
+%   enddocument/afterlastpage}
+%   These styles contain the initialization
+%   and the finalization code.  They were populated throughout the source.
+%   Hook |begindocument/before| contains the package support code, which must
+%   be loaded while still in the preamble.  Hook |begindocument| contains the
+%   initialization code whose execution doesn't require any particular timing,
+%   as long as it happens at the beginning of the document.  Hook
+%   |begindocument/end| is where the commands are activated; this must
+%   crucially happen as late as possible, so that we successfully override
+%   foreign commands (like |hyperref|'s definitions).  In \hologo{LaTeX}, we
+%   can automatically execute these hooks at appropriate places:
+%<*latex>
+\AddToHook{begindocument/before}{\mmzset{begindocument/before}}
+\AddToHook{begindocument}{\mmzset{begindocument}}
+\AddToHook{begindocument/end}{\mmzset{begindocument/end}}
+\AddToHook{enddocument/afterlastpage}{\mmzset{enddocument/afterlastpage}}
+%</latex>
+% In \hologo{plainTeX}, the user must execute these hooks manually; but at
+% least we can group them together and given them nice names.  Provisionally,
+% manual execution is required in \hologo{ConTeXt} as well, as I'm not sure
+% where to execute them --- please help!
+%<*plain,context>
+\mmzset{
+  begin document/.style={begindocument/before, begindocument, begindocument/end},
+  end document/.style={enddocument/afterlastpage},
+}
+%</plain,context>
+% \end{key}
+% 
+% \paragraph{\texttt{memoize.cfg}} Load the configuration file.  Note that
+% |nomemoize| must input this file as well, because any special
+% memoization-related macros defined by the user should be available; for
+% example, my |memoize.cfg| defines |\ifregion| (see
+%   \MS\ref{sec:tut:multifile}).
+%</mmz>
+%<mmz,nommz>\InputIfFileExists{memoize.cfg}{}{}
+%<*mmz>
+%
+% Formats other than \hologo{plainTeX} need a way to prevent extraction during
+% package-loading.
+\mmzset{
+  %<!plain>extract/no/.code={},
+% \begin{key}{output directory}
+%   \begin{macro}{mmzOutputDirectory}
+%     Set the |-output-directory| --- manually, as there is no other way.
+% \indentmacrocode
+  output-directory/.store in=\mmzOutputDirectory,
+}
+%   \end{macro}
+% \end{key}
+% 
+% \paragraph{Process} the package options (except in \hologo{plainTeX}).
+%<latex>\ProcessPgfPackageOptions{/mmz}
+%<context>\expandafter\mmzset\expandafter{\currentmoduleparameters}
+% 
+% Define |\mmzOutputDirectory| if |output-directory| was not given.
+\ifdefined\mmzOutputDirectory
+\else
+  \def\mmzOutputDirectory{}%
+\fi
+\mmzset{output directory/.code={\PackageError{memoize}{Key "output-directory"
+      may only be used as a package option}{}}}
+\mmzset{
+  % \paragraph{Extract} the externs using the method given by |memoize.cfg| or
+  % the package options --- unless we're running \hologo{plainTeX}.
+  %<*!plain>
+  extract/\mmz at extraction@method,
+  % In non-\hologo{plainTeX} formats, also disable |extract| in the preamble.
+  extract/.code={\PackageError{memoize}{Key "extract" is only allowed as a
+      package option.}{If you really want to extract in the preamble, execute
+      "extract/<method>".}},
+  %</!plain>
+  %<*plain>
+  % In \hologo{plainTeX}, where extraction must be invoked after
+  % loading the package, we now have to redefine |extract|, so that it will
+  % immediately trigger extraction.  
+  extract/.is choice,
+  extract/.default=\mmz at extraction@method,
+  % But only once:
+  extract/.append style={
+    extract/.code={\PackageError{memoize}{Key "extract" is only allowed to
+        be used once.}{If you really want to extract again, execute
+        "extract/<method>".}},
+  },
+  %</plain>
+}
+% 
+% Memoize was not really born for the draft mode, as it cannot produce new
+% externs there.  But we don't want to disable the package, as utilization is
+% still perfectly valid in this mode, so let's just warn the user.
+\ifnum\pdf at draftmode=1
+  \PackageWarning{memoize}{No memoization will be performed in the draft mode}%
+\fi
+%</mmz>
+% 
+% \paragraph{The end} of |memoize|, |nomemoize| and |memoizable|.
+%<*mmz,nommz,mmzable>
+%<plain>\resetatcatcode
+%<context>\stopmodule
+%<context>\protect
+%</mmz,nommz,mmzable>
+% That's all, folks!
+% 
+%    \end{macrocode}
+% 
+% \endinput
+% 
+% Local Variables:
+% TeX-engine: luatex
+% TeX-master: "doc/memoize-code.tex"
+% TeX-auto-save: nil
+% End:
\ No newline at end of file

Added: trunk/Master/texmf-dist/source/generic/memoize/memoize.ins
===================================================================
--- trunk/Master/texmf-dist/source/generic/memoize/memoize.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/generic/memoize/memoize.ins	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,39 @@
+%% memoize.ins
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%% 
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+%% 
+\input docstrip.tex
+\keepsilent
+\preamble
+\endpreamble
+\askforoverwritefalse
+\generate{%
+  \file{memoize.sty}{\from{memoize.dtx}{mmz,latex}}%
+  \file{memoize.tex}{\from{memoize.dtx}{mmz,plain}}%
+  \file{t-memoize.tex}{\from{memoize.dtx}{mmz,context}}%
+  \file{nomemoize.sty}{\from{memoize.dtx}{nommz,latex}}%
+  \file{nomemoize.tex}{\from{memoize.dtx}{nommz,plain}}%
+  \file{t-nomemoize.tex}{\from{memoize.dtx}{nommz,context}}%
+  \file{memoizable.sty}{\from{memoize.dtx}{mmzable,latex}}%
+  \file{memoizable.tex}{\from{memoize.dtx}{mmzable,plain}}%
+  \file{t-memoizable.tex}{\from{memoize.dtx}{mmzable,context}}%  
+  \file{memoize-extract-one.tex}{\from{memoize.dtx}{extract-one}}%
+}
+\endbatchfile

Added: trunk/Master/texmf-dist/tex/context/memoize/t-memoizable.tex
===================================================================
--- trunk/Master/texmf-dist/tex/context/memoize/t-memoizable.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/memoize/t-memoizable.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,63 @@
+%%
+%% This is file `t-memoizable.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `mmzable,context')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+%D \module[
+%D         file=t-memoizable.tex,
+%D      version=1.0.0,
+%D        title=Memoizable,
+%D     subtitle=A programmer's stub for Memoize,
+%D       author=Saso Zivanovic,
+%D         date=2023-10-10,
+%D    copyright=Saso Zivanovic,
+%D      license=LPPL,
+%D ]
+\writestatus{loading}{ConTeXt User Module / memoizable}
+\unprotect
+\startmodule[memoizable]
+\input miniltx
+\def\ifmmz at loadstatus#1{%
+  \ifnum#1=0\csname mmz at loadstatus\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+\ifmmz at loadstatus{1}%
+{\endinput}{}
+\ifmmz at loadstatus{3}%
+{\endinput}{}%
+\ifmmz at loadstatus{2}{\endinput}{}%
+\def\mmz at loadstatus{2}%
+\def\mmzset#1{\ignorespaces}
+\def\nommzkeys{\pgfqkeys{/mmz}}
+\pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}}
+\newif\ifmemoize
+\newcommand\IfMemoizing[2][]{\@secondoftwo}
+\stopmodule
+\protect
+\endinput
+%%
+%% End of file `t-memoizable.tex'.


Property changes on: trunk/Master/texmf-dist/tex/context/memoize/t-memoizable.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/context/memoize/t-memoize.tex
===================================================================
--- trunk/Master/texmf-dist/tex/context/memoize/t-memoize.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/memoize/t-memoize.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,1431 @@
+%%
+%% This is file `t-memoize.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `mmz,context')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+%D \module[
+%D         file=t-memoize.tex,
+%D      version=1.0.0,
+%D        title=Memoize,
+%D     subtitle=Fast and flexible externalization,
+%D       author=Saso Zivanovic,
+%D         date=2023-10-10,
+%D    copyright=Saso Zivanovic,
+%D      license=LPPL,
+%D ]
+\writestatus{loading}{ConTeXt User Module / memoize}
+\unprotect
+\startmodule[memoize]
+\input miniltx
+\def\PackageWarning#1#2{{%
+    \newlinechar`\^^J\def\MessageBreak{^^J\space\space#1: }%
+    \message{#1: #2}}}
+\input etoolbox-generic
+\ifdefined\luatexversion
+  \directlua{memoize = {}}
+\fi
+\directlua{%
+  require("pdftexcmds")
+  tex.enableprimitives('pdf@', {'draftmode'})
+}
+\long\def\pdf at mdfivesum#1{%
+  \directlua{%
+    oberdiek.pdftexcmds.mdfivesum("\luaescapestring{#1}", "byte")%
+  }%
+}%
+\def\pdf at system#1{%
+  \directlua{%
+    oberdiek.pdftexcmds.system("\luaescapestring{#1}")%
+  }%
+}
+\let\pdf at primitive\primitive
+\directlua{%
+  function memoize.filesize(filename)
+    local filehandle = io.open(filename, "r")
+    if filehandle == nil then
+    else
+      tex.write(filehandle:seek("end"))
+      io.close(filehandle)
+    end
+  end
+}%
+\def\pdf at filesize#1{%
+  \directlua{memoize.filesize("\luaescapestring{#1}")}%
+}
+\ifdef\pdftexversion{%
+}{%
+  \def\pdfhorigin{1true in}%
+  \def\pdfvorigin{1true in}%
+  \ifdef\XeTeXversion{%
+    \let\quitvmode\leavevmode
+  }{%
+    \ifdef\luatexversion{%
+      \let\pdfpagewidth\pagewidth
+      \let\pdfpageheight\pageheight
+      \def\pdfmajorversion{\pdfvariable majorversion}%
+      \def\pdfminorversion{\pdfvariable minorversion}%
+    }{%
+      \PackageError{memoize}{Support for this TeX engine is not implemented}{}%
+    }%
+  }%
+}
+\input t-advice
+\def\ifmmz at loadstatus#1{%
+  \ifnum#1=0\csname mmz at loadstatus\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+\ifmmz at loadstatus{3}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "nomemoize" is already
+    loaded. Memoization will NOT be in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+    \endinput
+}{}%
+\ifmmz at loadstatus{2}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded "memoizable";
+    please move
+    "\string\usemodule[memoize]"
+    before the
+    "\string\usemodule"
+    of that package.}%
+  \endinput
+}{}%
+\ifmmz at loadstatus{1}{\endinput}{}%
+\def\mmz at loadstatus{1}%
+\def\filetotoks#1#2{%
+  \immediate\openin0{#2}%
+  #1={}%
+  \loop
+  \unless\ifeof0
+    \read0 to \totoks at temp
+    \expandafter\toksapp\expandafter#1\expandafter{\totoks at temp}%
+  \repeat
+  \immediate\closein0
+}
+\newif\ifmmz at temp
+\newtoks\mmz at temptoks
+\newbox\mmz at box
+\newwrite\mmz at out
+\def\mmzset#1{\pgfqkeys{/mmz}{#1}\ignorespaces}
+\def\nommzkeys#1{}
+\newif\ifmemoize
+\mmzset{%
+  enable/.style={begindocument/.append code=\memoizetrue},
+  disable/.style={begindocument/.append code=\memoizefalse},
+  begindocument/.append style={
+    enable/.code=\memoizetrue,
+    disable/.code=\memoizefalse,
+  },
+  enable,
+}
+\def\mmz at mode@normal{0}
+\def\mmz at mode@readonly{1}
+\def\mmz at mode@recompile{2}
+\let\mmz at mode\mmz at mode@normal
+\mmzset{%
+  normal/.code={\let\mmz at mode\mmz at mode@normal},
+  readonly/.code={\let\mmz at mode\mmz at mode@readonly},
+  recompile/.code={\let\mmz at mode\mmz at mode@recompile},
+}
+\mmzset{%
+  path/.code={\pgfqkeys{/mmz/path}{#1}},
+  path/.cd,
+  relative/.is if=mmz at relativepath,
+  dir/.store in=\mmz at dir,
+  dir/.value required,
+  prefix/.store in=\mmz at prefix,
+  prefix/.value required,
+}
+\newif\ifmmz at relativepath
+\mmzset{%
+  begindocument/.append style={
+    path/.append code=\mmz at maybe@mkmemodir\mmz at record@prefix,
+  },
+  begindocument/.append code=\mmz at maybe@mkmemodir,
+}
+\def\mmz at dir@path{\ifmmz at relativepath.\fi/\mmz at dir}
+\def\mmz at prefix@path{\mmz at dir@path/\mmz at prefix}
+\mmzset{
+  mkdir/.is if=mmz at mkdir,
+  mkdir command/.code={\def\mmz at mkdir@command##1{#1}},
+  mkdir command={mkdir "#1"},
+}
+\newif\ifmmz at mkdir
+\def\mmz at maybe@mkmemodir{%
+  \ifmmz at mkdir
+    \pdf at system{\mmz at mkdir@command{\mmzOutputDirectory\mmz at dir@path}}%
+  \fi
+}
+\mmzset{%
+  memo dir/.style={
+    mkdir,
+    path={
+      relative,
+      dir={#1.memo.dir},
+      prefix={},
+    },
+  },
+  memo dir/.default=\mmzUnquote\jobname,
+  no memo dir/.style={
+    mkdir=false,
+    path={
+      relative,
+      dir={},
+      prefix={#1.},
+    },
+  },
+  no memo dir/.default=\mmzUnquote\jobname,
+  no memo dir,
+}
+\def\mmzUnquote#1{\normalexpanded{\noexpand\mmz at unquote#1}\mmz at unquote@end}
+\def\mmz at unquote#1{%
+  \ifx\mmz at unquote@end#1%
+  \else
+    \ifx"#1%
+      \expandafter\expandafter\expandafter\mmz at unquote@quotes
+    \else
+      \expandafter\expandafter\expandafter\mmz at unquote@noquotes
+      \expandafter\expandafter\expandafter#1%
+    \fi
+  \fi
+}
+\def\mmz at unquote@quotes#1"\mmz at unquote@end{#1}
+\def\mmz at unquote@noquotes#1\mmz at unquote@end{#1}
+\newif\ifmmz at ignorespaces
+\mmzset{
+  ignore spaces/.is if=mmz at ignorespaces,
+}
+\newif\ifmmz at verbatim
+\def\mmzRawCollectorOptions{}
+\mmzset{
+  verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerbatim}%
+    \mmz at verbatimtrue
+  },
+  verb/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerb}%
+    \mmz at verbatimtrue
+  },
+  no verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsNoVerbatim}%
+    \mmz at verbatimfalse
+  },
+}
+\protected\def\mmz{\futurelet\mmz at temp\mmz at i}
+\def\mmz at i{%
+  \begingroup
+  \ifx\mmz at temp[%]
+    \def\mmz at verbatim@fix{}%
+    \expandafter\mmz at ii
+  \else
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+    \expandafter\mmz at iii
+  \fi
+}
+\def\mmz at ii[#1]{%
+  \mmzset{#1}%
+  \mmz at iii
+}
+\def\mmz at iii{%
+  \ifmmz at verbatim
+    \expandafter\mmz at do@verbatim
+  \else
+    \expandafter\mmz at do
+  \fi
+}
+\long\def\mmz at do#1{%
+  \Memoize{#1}{#1}%
+}%
+\def\mmz at do@verbatim#1{%
+  \normalexpanded{%
+    \noexpand\CollectArgumentsRaw{%
+      \noexpand\collargsCaller{\noexpand\mmz}%
+      \expandonce\mmzRawCollectorOptions
+      \mmz at verbatim@fix
+    }%
+  }{+m}\mmz at do
+}
+\def\startmemoize{%
+  \begingroup
+  \futurelet\mmz at temp\mmz at env@i
+}
+\def\mmz at env@i{%
+  \ifx\mmz at temp[%]
+    \def\mmz at verbatim@fix{}%
+    \expandafter\mmz at env@ii
+  \else
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+    \expandafter\mmz at env@iii
+  \fi
+}
+\def\mmz at env@ii[#1]{%
+  \mmzset{#1}%
+  \mmz at env@iii
+}
+\def\mmz at env@iii{%
+  \long\edef\mmz at do##1{%
+    \noexpand\Memoize{##1}{##1\unskip}%
+  }%
+  \normalexpanded{%
+    \noexpand\CollectArgumentsRaw{%
+      \noexpand\collargsCaller{memoize}%
+      \expandonce\mmzRawCollectorOptions
+      \ifmmz at verbatim\mmz at verbatim@fix\fi
+    }%
+  }{&&{\collargsAppendPostwrap{}}!t{ }+b{memoize}}{\mmz at do}%
+}%
+\protected\def\nommz#1#{%
+  \afterassignment\nommz at i
+  \let\mmz at temp
+}
+\def\nommz at i{%
+  \bgroup
+  \memoizefalse
+}
+\def\startnomemoize{%
+  \begingroup
+  \memoizefalse
+  \futurelet\mmz at temp\nommz at env@i
+}
+\def\nommz at env@i{%
+  \ifx\mmz at temp[%]
+    \expandafter\nommz at env@ii
+  \fi
+}
+\def\nommz at env@ii[#1]{%
+  \ignorespaces
+}
+\def\stopnomemoize{%
+  \endgroup
+  \unskip
+}
+\newif\ifmemoizing
+\newif\ifinmemoize
+\def\mmz at maybe@scantokens{%
+  \ifmmz at verbatim
+    \expandafter\mmz at scantokens
+  \else
+    \expandafter\@firstofone
+  \fi
+}
+\long\def\mmz at scantokens#1{%
+  \normalexpanded{%
+    \newlinechar=13
+    \normalunexpanded{\scantokens{#1\endinput}}%
+    \newlinechar=\the\newlinechar
+  }%
+}
+\newtoks\mmz at mdfive@source
+\newtoks\mmz at exec@source
+\let\Memoize\@secondoftwo
+\long\def\Memoize#1#2{%
+  \mmz at mdfive@source{#1}%
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  \mmz at exec@source
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  {%
+    \mmz at maybe@scantokens{#2}%
+  }%
+  \mmz at trace@Memoize
+  \let\mmz at action\mmz at compile
+  \ifmemoizing
+  \else
+    \ifmemoize
+      \xdef\mmz at code@mdfivesum{\pdf at mdfivesum{\the\mmz at mdfive@source}}%
+      \mmz at trace@code at mdfive
+      \ifnum\mmz at mode=\mmz at mode@recompile\relax
+        \ifnum\pdf at draftmode=0
+          \let\mmz at action\mmz at memoize
+        \fi
+      \else
+        \mmz at process@cmemo
+        \ifmmzUnmemoizable
+          \mmz at trace@cmemo at unmemoizable
+        \else
+          \ifmmz at abort
+            \mmz at trace@process at cmemo@fail
+            \ifnum\mmz at mode=\mmz at mode@readonly\relax
+            \else
+              \ifnum\pdf at draftmode=0
+                \let\mmz at action\mmz at memoize
+              \fi
+            \fi
+          \else
+            \mmz at trace@process at cmemo@ok
+            \let\mmz at action\mmz at process@ccmemo
+          \fi
+        \fi
+      \fi
+    \fi
+  \fi
+  \mmz at action
+}
+\def\mmz at compile{%
+  \mmz at trace@compile
+  \normalexpanded{%
+    \endgroup
+    \noexpand\inmemoizetrue
+    \the\mmz at exec@source
+    \ifinmemoize\noexpand\inmemoizetrue\else\noexpand\inmemoizefalse\fi
+  }%
+}
+  \let\mmz at lua@atbeginmemoization\relax
+  \let\mmz at lua@atendmemoization\relax
+\def\mmz at memoize{%
+  \mmz at trace@memoize
+  \memoizingtrue
+  \inmemoizetrue
+  \edef\memoizinggrouplevel{\the\currentgrouplevel}%
+  \global\mmz at abortfalse
+  \global\mmzUnmemoizablefalse
+  \global\mmz at seq 0
+  \global\setbox\mmz at tbe@box\vbox{}%
+  \global\mmz at ccmemo@resources{}%
+  \global\mmzCMemo{}%
+  \global\mmzCCMemo{}%
+  \global\mmzContextExtra{}%
+  \gdef\mmzAtEndMemoizationExtra{}%
+  \gdef\mmzAfterMemoizationExtra{}%
+  \mmz at lua@atbeginmemoization
+  \mmzAtBeginMemoization
+  \mmzDriver{\the\mmz at exec@source}%
+  \mmzAtEndMemoization
+  \mmzAtEndMemoizationExtra
+  \mmz at lua@atendmemoization
+  \ifmmzUnmemoizable
+    \global\mmzContextExtra{}%
+    \gtoksapp\mmzCMemo{\global\mmzUnmemoizabletrue}%
+    \mmz at write@cmemo
+    \mmz at trace@endmemoize at unmemoizable
+    \PackageWarning{memoize}{Marking this code as unmemoizable}%
+  \else
+    \ifmmz at abort
+      \mmz at trace@endmemoize at aborted
+      \PackageWarning{memoize}{Memoization was aborted}%
+      \mmz at write@empty at cmemo
+    \else
+      \mmz at compute@context at mdfivesum
+      \mmz at write@cmemo
+      \mmz at write@ccmemo
+      \mmz at shipout@externs
+      \mmz at trace@endmemoize at ok
+    \fi
+  \fi
+  \expandafter\endgroup
+  \expandafter\let
+    \expandafter\mmzIncludeExtern\expandafter\mmz at include@extern at from@tbe at box
+  \mmzAfterMemoization
+  \mmzAfterMemoizationExtra
+}
+\def\memoizinggrouplevel{-1}%
+\def\mmzAbort{\global\mmz at aborttrue}
+\newif\ifmmz at abort
+\def\mmzUnmemoizable{\global\mmzUnmemoizabletrue}
+\newif\ifmmzUnmemoizable
+\def\mmzAtBeginMemoization{}
+\def\mmzAtEndMemoization{}
+\def\mmzAfterMemoization{}
+\mmzset{
+  at begin memoization/.code={%
+    \ifmemoizing
+      \expandafter\@firstofone
+    \else
+      \expandafter\appto\expandafter\mmzAtBeginMemoization
+    \fi
+    {#1}%
+  },
+  at end memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAtEndMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAtEndMemoization
+    \fi
+    {#1}%
+  },
+  after memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAfterMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAfterMemoization
+    \fi
+    {#1}%
+  },
+}
+\mmzset{
+  driver/.store in=\mmzDriver,
+  driver=\mmzSingleExternDriver,
+}
+\newif\ifmmzkeepexterns
+\long\def\mmzSingleExternDriver#1{%
+  \xtoksapp\mmzCCMemo{\mmz at maybe@quitvmode}%
+  \setbox\mmz at box\mmz at capture{#1}%
+  \mmzExternalizeBox\mmz at box\mmz at temptoks
+  \xtoksapp\mmzCCMemo{\the\mmz at temptoks}%
+  \mmz at maybe@quitvmode\box\mmz at box
+}
+\mmzset{
+  capture/.is choice,
+  capture/hbox/.code={%
+    \let\mmz at capture\hbox
+    \def\mmz at maybe@quitvmode{\noexpand\quitvmode}%
+  },
+  capture/vbox/.code={%
+    \let\mmz at capture\vbox
+    \def\mmz at maybe@quitvmode{}%
+  },
+  capture=hbox,
+}
+\mmzset{
+  auto/integrated driver/.style={
+    after setup={\expandafter\newif\csname ifmmz at memoizing#1\endcsname},
+    driver/.expand once={%
+      \csname mmz at memoizing#1true\endcsname
+      \@firstofone
+    }%
+  },
+}
+\newcommand\IfMemoizing[2][\mmz at Ifmemoizing@nogrouplevel]{%>\fi
+\csname ifmmz at memoizing#2\endcsname%>\if
+  \ifnum\currentgrouplevel=\the\numexpr\memoizinggrouplevel+#1\relax\relax
+    \expandafter\expandafter\expandafter\@firstoftwo
+  \else
+    \expandafter\expandafter\expandafter\@secondoftwo
+  \fi
+\else
+  \expandafter\@secondoftwo
+\fi
+}
+\def\mmz at Ifmemoizing@nogrouplevel{0\relax\relax\fi\iftrue}
+\def\mmz at trace#1{\immediate\write16{[tracing memoize] #1}}
+\def\mmz at trace@context{\mmz at trace{\space\space
+    Context: "\expandonce{\mmz at context@key}" --> \mmz at context@mdfivesum}}
+\def\mmz at trace@Memoize at on{%
+  \mmz at trace{%
+    Entering \noexpand\Memoize (%
+    \ifmemoize enabled\else disabled\fi,
+    \ifnum\mmz at mode=\mmz at mode@recompile recompile\fi
+    \ifnum\mmz at mode=\mmz at mode@readonly readonly\fi
+    \ifnum\mmz at mode=\mmz at mode@normal normal\fi
+    \space mode) on line \the\inputlineno
+  }%
+  \mmz at trace{\space\space Code: \the\mmz at mdfive@source}%
+}
+\def\mmz at trace@code at mdfive@on{\mmz at trace{\space\space
+    Code md5sum: \mmz at code@mdfivesum}}
+\def\mmz at trace@compile at on{\mmz at trace{\space\space Compiling}}
+\def\mmz at trace@memoize at on{\mmz at trace{\space\space Memoizing}}
+\def\mmz at trace@endmemoize at ok@on{\mmz at trace{\space\space
+    Memoization completed}}%
+\def\mmz at trace@endmemoize at aborted@on{\mmz at trace{\space\space
+    Memoization was aborted}}
+\def\mmz at trace@endmemoize at unmemoizable@on{\mmz at trace{\space\space
+    Marking this code as unmemoizable}}
+\def\mmz at trace@process at cmemo@on{\mmz at trace{\space\space
+    Attempting to utilize c-memo \mmz at cmemo@path}}
+\def\mmz at trace@process at no@cmemo at on{\mmz at trace{\space\space
+    C-memo does not exist}}
+\def\mmz at trace@process at cmemo@ok at on{\mmz at trace{\space\space
+    C-memo was processed successfully}\mmz at trace@context}
+\def\mmz at trace@process at cmemo@fail at on{\mmz at trace{\space\space
+    C-memo input failed}}
+\def\mmz at trace@cmemo at unmemoizable@on{\mmz at trace{\space\space
+    This code was marked as unmemoizable}}
+\def\mmz at trace@process at ccmemo@on{\mmz at trace{\space\space
+    Attempting to utilize cc-memo \mmz at ccmemo@path\space
+    (\ifmmz at direct@ccmemo at input\else in\fi direct input)}}
+\def\mmz at trace@resource at on#1{\mmz at trace{\space\space
+    Extern file does not exist: #1}}
+\def\mmz at trace@process at ccmemo@ok at on{%
+  \mmz at trace{\space\space Utilization successful}}
+\def\mmz at trace@process at no@ccmemo at on{%
+  \mmz at trace{\space\space CC-memo does not exist}}
+\def\mmz at trace@process at ccmemo@fail at on{%
+  \mmz at trace{\space\space Cc-memo input failed}}
+\mmzset{%
+  trace/.is choice,
+  trace/.default=true,
+  trace/true/.code=\mmzTracingOn,
+  trace/false/.code=\mmzTracingOff,
+}
+\def\mmzTracingOn{%
+  \let\mmz at trace@Memoize\mmz at trace@Memoize at on
+  \let\mmz at trace@code at mdfive\mmz at trace@code at mdfive@on
+  \let\mmz at trace@compile\mmz at trace@compile at on
+  \let\mmz at trace@memoize\mmz at trace@memoize at on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@endmemoize at ok\mmz at trace@endmemoize at ok@on
+  \let\mmz at trace@endmemoize at unmemoizable\mmz at trace@endmemoize at unmemoizable@on
+  \let\mmz at trace@endmemoize at aborted\mmz at trace@endmemoize at aborted@on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@process at cmemo@ok\mmz at trace@process at cmemo@ok at on
+  \let\mmz at trace@process at no@cmemo\mmz at trace@process at no@cmemo at on
+  \let\mmz at trace@process at cmemo@fail\mmz at trace@process at cmemo@fail at on
+  \let\mmz at trace@cmemo at unmemoizable\mmz at trace@cmemo at unmemoizable@on
+  \let\mmz at trace@process at ccmemo\mmz at trace@process at ccmemo@on
+  \let\mmz at trace@resource\mmz at trace@resource at on
+  \let\mmz at trace@process at ccmemo@ok\mmz at trace@process at ccmemo@ok at on
+  \let\mmz at trace@process at no@ccmemo\mmz at trace@process at no@ccmemo at on
+  \let\mmz at trace@process at ccmemo@fail\mmz at trace@process at ccmemo@fail at on
+}
+\def\mmzTracingOff{%
+  \let\mmz at trace@Memoize\relax
+  \let\mmz at trace@code at mdfive\relax
+  \let\mmz at trace@compile\relax
+  \let\mmz at trace@memoize\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@endmemoize at ok\relax
+  \let\mmz at trace@endmemoize at unmemoizable\relax
+  \let\mmz at trace@endmemoize at aborted\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@process at cmemo@ok\relax
+  \let\mmz at trace@process at no@cmemo\relax
+  \let\mmz at trace@process at cmemo@fail\relax
+  \let\mmz at trace@cmemo at unmemoizable\relax
+  \let\mmz at trace@process at ccmemo\relax
+  \let\mmz at trace@resource\@gobble
+  \let\mmz at trace@process at ccmemo@ok\relax
+  \let\mmz at trace@process at no@ccmemo\relax
+  \let\mmz at trace@process at ccmemo@fail\relax
+}
+\mmzTracingOff
+\newtoks\mmzContext
+\newtoks\mmzContextExtra
+\mmzset{%
+  context/.code={%
+    \ifmemoizing
+      \expandafter\gtoksapp\expandafter\mmzContextExtra
+    \else
+      \expandafter\toksapp\expandafter\mmzContext
+    \fi
+    {#1,}%
+  },
+  clear context/.code={%
+    \ifmemoizing
+      \expandafter\global\expandafter\mmzContextExtra
+    \else
+      \expandafter\mmzContext
+    \fi
+    {}%
+  },
+  clear context/.value forbidden,
+  meaning to context/.code={\forcsvlist\mmz at mtoc{#1}},
+  csname meaning to context/.code={\mmz at mtoc@cs{#1}},
+  key meaning to context/.code={\forcsvlist\mmz at mtoc\mmz at mtoc@keycmd{#1}},
+  key value to context/.code={\forcsvlist\mmz at mtoc@key{#1}},
+  /handlers/.meaning to context/.code={%
+    \normalexpanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath/. at cmd}}},
+  /handlers/.value to context/.code={%
+    \normalexpanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath}}},
+}
+\def\mmz at mtoc#1{%
+  \collargs at cs@cases{#1}%
+    {\mmz at mtoc@cmd{#1}}%
+    {\mmz at mtoc@error at notcsorenv{#1}}%
+    {%
+      \mmz at mtoc@cs{%
+        start%
+        #1}%
+      \mmz at mtoc@cs{%
+        stop%
+        #1}%
+    }%
+}
+\def\mmz at mtoc@cmd#1{%
+  \begingroup
+  \escapechar=-1
+  \expandafter\endgroup
+  \expandafter\mmz at mtoc@cs\expandafter{\string#1}%
+}
+\def\mmz at mtoc@cs#1{%
+  \pgfkeysvalueof{/mmz/context/. at cmd}%
+  \expandafter\string\csname#1\endcsname={\expandafter\meaning\csname#1\endcsname}%
+  \pgfeov
+}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1}}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1/. at cmd}}
+\def\mmz at mtoc@error at notcsorenv#1{%
+  \PackageError{memoize}{'\detokenize{#1}' passed to key 'meaning to context' is neither a command nor an environment}{}%
+}
+\def\mmz at cmemo@path{\mmz at prefix@path\mmz at code@mdfivesum.memo}
+\newtoks\mmzCMemo
+\mmzset{%
+  include source in cmemo/.is if=mmz at include@source,
+}
+\newif\ifmmz at include@source
+\mmz at include@sourcetrue
+\def\mmz at write@cmemo{%
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  \immediate\write\mmz at out{%
+    \global\mmzContextExtra{\the\mmzContextExtra}\collargs at percentchar
+  }%
+  \immediate\write\mmz at out{\the\mmzCMemo\collargs at percentchar}%
+  \ifmmz at include@source
+    \immediate\write\mmz at out{\noexpand\mmzSource}%
+    \immediate\write\mmz at out{\the\mmz at mdfive@source}%
+  \fi
+  \immediate\closeout\mmz at out
+  \pgfkeysalso{/mmz/record/new cmemo={\mmz at cmemo@path}}%
+}
+\def\mmz at write@empty at cmemo{%
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  \immediate\closeout\mmz at out
+}
+\let\mmzSource\endinput
+\def\mmz at process@cmemo{%
+  \mmz at trace@process at cmemo
+  \global\mmz at aborttrue
+  \global\mmzUnmemoizablefalse
+  \def\mmzMemo{\global\mmz at abortfalse}%
+  \global\mmzContextExtra{}%
+  \IfFileExists{\mmz at cmemo@path}{%
+    \input{\mmz at cmemo@path}%
+    \pgfkeysalso{/mmz/record/used cmemo={\mmz at cmemo@path}}%
+  }{%
+    \mmz at trace@process at no@cmemo
+  }%
+  \mmz at compute@context at mdfivesum
+}
+\def\mmz at compute@context at mdfivesum{%
+  \xdef\mmz at context@key{\the\mmzContext\the\mmzContextExtra}%
+  \begingroup
+  \begingroup
+  \def\width{\string\width}%
+  \def\height{\string\height}%
+  \def\depth{\string\depth}%
+  \edef\mmz at paddings{\mmz at paddings}%
+  \expandafter\endgroup
+  \expandafter\def\expandafter\mmz at paddings\expandafter{\mmz at paddings}%
+  \xdef
+  \mmz at context@key{\mmz at context@key}%
+  \endgroup
+  \xdef\mmz at context@mdfivesum{\pdf at mdfivesum{\expandonce\mmz at context@key}}%
+}
+\def\mmz at ccmemo@path{%
+  \mmz at prefix@path\mmz at code@mdfivesum-\mmz at context@mdfivesum.memo}
+\newtoks\mmzCCMemo
+\newif\ifmmz at include@context
+\mmzset{%
+  include context in ccmemo/.is if=mmz at include@context,
+}
+\newif\ifmmz at direct@ccmemo at input
+\mmzset{%
+  direct ccmemo input/.is if=mmz at direct@ccmemo at input,
+}
+\def\mmz at write@ccmemo{%
+  \immediate\openout\mmz at out{\mmz at ccmemo@path}%
+  \begingroup
+  \the\mmz at ccmemo@resources
+  \endgroup
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  \immediate\write\mmz at out{\the\mmzCCMemo\collargs at percentchar}%
+  \ifmmz at include@context
+    \immediate\write\mmz at out{\noexpand\mmzThisContext}%
+    \immediate\write\mmz at out{\expandonce{\mmz at context@key}}%
+  \fi
+  \immediate\write\mmz at out{\noexpand\mmzEndMemo}%
+  \immediate\closeout\mmz at out
+  \pgfkeysalso{/mmz/record/new ccmemo={\mmz at ccmemo@path}}%
+}
+\def\mmz at ccmemo@append at resource#1{%
+  \mmz at seq=#1\relax
+  \immediate\write\mmz at out{%
+    \string\mmzResource{\mmz at extern@name}\collargs at percentchar}%
+}
+\def\mmzResource#1{%
+  \ifnum0\pdf at filesize{\mmz at dir@path/#1}=0
+    \ifmmz at direct@ccmemo at input
+      \let\mmzMemo\endinput
+    \else
+      \long\def\mmzMemo##1\mmzEndMemo\par{}%
+    \fi
+    \mmz at trace@resource{#1}%
+  \fi
+}
+\def\mmz at process@ccmemo{%
+  \mmz at trace@process at ccmemo
+  \global\mmz at aborttrue
+  \def\mmzMemo{%
+    \endgroup
+    \global\mmz at abortfalse
+    \let\mmzIncludeExtern\mmz at include@extern
+  }%
+  \xdef\mmzEndMemo{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      \normalunexpanded{%
+        \def\mmz at temp\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  \xdef\mmzThisContext{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      \normalunexpanded{%
+        \long\def\mmz at temp##1\mmzEndMemo\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  \IfFileExists{\mmz at ccmemo@path}{%
+    \ifmmz at direct@ccmemo at input
+      \input{\mmz at ccmemo@path}%
+    \else
+      \filetotoks\toks@{\mmz at ccmemo@path}%
+      \the\toks@
+    \fi
+    \pgfkeysalso{/mmz/record/used ccmemo={\mmz at ccmemo@path}}%
+  }{%
+    \mmz at trace@process at no@ccmemo
+  }%
+  \ifmmz at abort
+    \mmz at trace@process at ccmemo@fail
+    \ifnum\mmz at mode=\mmz at mode@readonly\relax
+      \expandafter\expandafter\expandafter\mmz at compile
+    \else
+      \expandafter\expandafter\expandafter\mmz at memoize
+    \fi
+  \else
+    \mmz at trace@process at ccmemo@ok
+  \fi
+}
+\newcount\mmz at seq
+\def\mmz at extern@basename{%
+  \mmz at prefix\mmz at code@mdfivesum-\mmz at context@mdfivesum
+  \ifnum\mmz at seq>0 -\the\mmz at seq\fi
+}
+\def\mmz at extern@name{\mmz at extern@basename.pdf}
+\def\mmz at extern@basepath{\mmz at dir@path/\mmz at extern@basename}
+\def\mmz at extern@path{\mmz at extern@basepath.pdf}
+\mmzset{
+  padding left/.store in=\mmz at padding@left,
+  padding right/.store in=\mmz at padding@right,
+  padding top/.store in=\mmz at padding@top,
+  padding bottom/.store in=\mmz at padding@bottom,
+  padding/.style={
+    padding left=#1, padding right=#1,
+    padding top=#1, padding bottom=#1
+  },
+  padding=1in,
+  padding to context/.style={
+    context={padding=(\mmz at paddings)},
+  },
+  padding to context,
+}
+\def\mmz at paddings{%
+  \mmz at padding@left,\mmz at padding@bottom,\mmz at padding@right,\mmz at padding@top
+}
+\def\mmzExternalizeBox#1#2{%
+  \begingroup
+  \def\width{\wd#1 }%
+  \def\height{\ht#1 }%
+  \def\depth{\dp#1 }%
+  \xdef\mmz at global@temp{%
+    \noexpand\mmzIncludeExtern
+      {\the\mmz at seq}%
+      \ifhbox#1\noexpand\hbox\else\noexpand\vbox\fi
+      {\the\wd#1}%
+      {\the\ht#1}%
+      {\the\dp#1}%
+      {\the\dimexpr\mmz at padding@left}%
+      {\the\dimexpr\mmz at padding@bottom}%
+      {\the\dimexpr\mmz at padding@right}%
+      {\the\dimexpr\mmz at padding@top}%
+  }%
+  \global\setbox\mmz at tbe@box\vbox{\copy#1\unvbox\mmz at tbe@box}%
+  \xtoksapp\mmz at ccmemo@resources{%
+    \noexpand\mmz at ccmemo@append at resource{\the\mmz at seq}%
+  }%
+  \global\advance\mmz at seq1
+  \endgroup
+  #2\expandafter{\mmz at global@temp}%
+}
+\newtoks\mmz at ccmemo@resources
+\newbox\mmz at tbe@box
+\def\mmz at shipout@externs{%
+  \global\mmz at seq 0
+  \setbox\mmz at box\vbox{%
+    \def\width{\wd\mmz at box}%
+    \def\height{\ht\mmz at box}%
+    \def\depth{\dp\mmz at box}%
+    \vskip1pt
+    \ifmmzkeepexterns\expandafter\unvcopy\else\expandafter\unvbox\fi\mmz at tbe@box
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox\mmz at box\lastbox
+      \mmz at shipout@extern
+    }%
+  }%
+}
+\def\mmz at shipout@extern{%
+  \edef\expectedwidth{\the\dimexpr
+    (\mmz at padding@left) + \wd\mmz at box + (\mmz at padding@right)}%
+  \edef\expectedheight{\the\dimexpr
+    (\mmz at padding@top) + \ht\mmz at box + \dp\mmz at box + (\mmz at padding@bottom)}%
+  \begingroup
+  \ifnum\mag=1000
+  \else
+    \mmz at shipout@mag
+  \fi
+  \edef\mmz at temp{%
+    \noexpand\directlua{
+      backends.codeinjections.setupcanvas({
+        paperwidth=\the\numexpr\pagewidth,
+        paperheight=\the\numexpr\pageheight
+      })
+    }%
+  }%
+  \normalexpanded{%
+    \noexpand\directlua{
+      backends.codeinjections.setupcanvas({
+        paperwidth=\the\numexpr\dimexpr
+          \mmz at padding@left + \wd\mmz at box + \mmz at padding@right\relax,
+        paperheight=\the\numexpr\dimexpr
+          \mmz at padding@top + \ht\mmz at box + \dp\mmz at box+ \mmz at padding@bottom\relax
+      })
+    }%
+  }%
+  \hoffset\dimexpr\mmz at padding@left - \pdfhorigin\relax
+  \voffset\dimexpr\mmz at padding@top - \pdfvorigin\relax
+  \pdf at primitive\shipout\box\mmz at box
+  \mmz at temp
+  \endgroup
+  \global\advance\mmzExternPages1
+  \edef\externbasepath{\mmz at extern@basepath}%
+  \edef\pagenumber{\the\numexpr\mmzRegularPages
+    -1%
+    +\mmzExternPages+\mmzExtraPages}%
+  \mmzset{record/new extern/.expanded=\mmz at extern@path}%
+  \global\advance\mmz at seq1
+}
+\def\mmz at shipout@mag{%
+  \setbox\mmz at box\hbox{%
+    \pdfliteral{q \mmz at inverse@mag\space 0 0 \mmz at inverse@mag\space 0 0 cm}%
+    \copy\mmz at box\relax
+    \pdfliteral{Q}%
+  }%
+  \dimen0=\dimexpr\mmz at padding@left\relax
+  \edef\mmz at padding@left{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@bottom\relax
+  \edef\mmz at padding@bottom{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@right\relax
+  \edef\mmz at padding@right{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@top\relax
+  \edef\mmz at padding@top{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \wd\mmz at box=\mmz at inverse@mag\wd\mmz at box\relax
+  \ht\mmz at box=\mmz at inverse@mag\ht\mmz at box\relax
+  \dp\mmz at box=\mmz at inverse@mag\dp\mmz at box\relax
+}
+{\catcode`\p=12\catcode`\t=12\gdef\mmz at Pgf@geT#1pt{#1}}
+\mmzset{begindocument/.append code={%
+    \edef\mmz at inverse@mag{\expandafter\mmz at Pgf@geT\the\dimexpr 1000pt/\mag}%
+  }}
+\let\mmzRegularPages\realpageno
+\newcount\mmzExternPages
+\mmzset{
+  enddocument/afterlastpage/.append code={%
+    \ifnum\mmzExternPages>0
+      \PackageWarning{memoize}{The compilation produced \the\mmzExternPages\space
+        new extern\ifnum\mmzExternPages>1 s\fi.}%
+    \fi
+  },
+}
+\newcount\mmzExtraPages
+\def\mmz at include@extern#1#2#3#4#5#6#7#8#9{%
+  \mmz at seq=#1\relax
+  \setbox\mmz at box=#2{%
+    \setbox0=\hbox{%
+      \lower\dimexpr #5+#7\relax\hbox{%
+        \hskip -#6\relax
+        \setbox0=\hbox{%
+          \mmz at insertpdfpage{\mmz at extern@path}{1}%
+        }%
+        \unhbox0
+      }%
+    }%
+    \wd0 \dimexpr\wd0-#8\relax
+    \ht0 \dimexpr\ht0-#9\relax
+    \dp0 #5\relax
+    \box0
+  }%
+  \mmz at tempfalse
+  \mmz at if@roughly at equal{\mmz at tolerance}{#3}{\wd\mmz at box}{%
+    \mmz at if@roughly at equal{\mmz at tolerance}{#4}{\ht\mmz at box}{%
+      \mmz at temptrue
+    }{}}{}%
+  \ifmmz at temp
+  \else
+    \mmz at use@memo at warning{\mmz at extern@path}{#3}{#4}{#5}%
+  \fi
+  \wd\mmz at box=#3\relax
+  \ht\mmz at box=#4\relax
+  \box\mmz at box
+  \pgfkeysalso{/mmz/record/used extern={\mmz at extern@path}}%
+}
+\def\mmz at use@memo at warning#1#2#3#4{%
+  \PackageWarning{memoize}{Unexpected size of extern "#1";
+    expected #2\space x \the\dimexpr #3+#4\relax,
+    got \the\wd\mmz at box\space x \the\dimexpr\the\ht\mmz at box+\the\dp\mmz at box\relax}%
+}
+  \def\mmz at insertpdfpage#1#2{% #1 = filename, #2 = page number
+    \saveimageresource page #2 mediabox {#1}%
+    \useimageresource\lastsavedimageresourceindex
+  }%
+\def\mmz at include@extern at from@tbe at box#1#2#3#4#5#6#7#8#9{%
+  \setbox0\vbox{%
+    \@tempcnta#1\relax
+    \vskip1pt
+    \unvcopy\mmz at tbe@box
+    \@whilenum\@tempcnta>0\do{%
+      \setbox0\lastbox
+      \advance\@tempcnta-1\relax
+    }%
+    \global\setbox1\lastbox
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox0\lastbox
+    }%
+    \box\mmz at box
+  }%
+  \box1
+}
+\def\mmzvalueof#1{\pgfkeysvalueof{/mmz/#1}}
+\mmzset{
+  extract/.estore in=\mmz at extraction@method,
+  extract/.value required,
+  begindocument/.append style={extract/.code=\mmz at preamble@only at warning},
+  extract/perl/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{perl extraction command}\space
+      \mmzvalueof{perl extraction options}%
+    }%
+    \mmz at check@extraction at log{perl}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{perl extraction command}\space --mkdir "##1"}%
+  },
+  perl extraction command/.initial=memoize-extract.pl,
+  perl extraction options/.initial={%
+    -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+    "\string\warning{memoize (perl-based extraction): \string\warningtext}"
+    "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+  },
+  extract=perl,
+  extract/python/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{python extraction command}\space
+      \mmzvalueof{python extraction options}%
+    }%
+    \mmz at check@extraction at log{python}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{python extraction command}\space --mkdir "##1"}%
+  },
+  python extraction command/.initial=memoize-extract.py,
+  python extraction options/.initial={%
+  -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+  "\string\warning{memoize (python-based extraction): \string\warningtext}"
+  "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+  },
+}
+\def\mmz at preamble@only at warning{%
+  \PackageWarning{memoize}{%
+    Ignoring the invocation of "\pgfkeyscurrentkey".
+    This key may only be executed in the preamble}%
+}
+\def\mmz at clear@extraction at log{%
+  \begingroup
+  \immediate\openout0{\mmzUnquote\jobname.mmz.log"}%
+  \immediate\closeout0
+  \endgroup
+}
+\def\mmz at check@extraction at log#1{%
+  \begingroup \def\extractionmethod{#1}%
+  \mmz at tempfalse \let\mmz at orig@endinput\endinput
+  \def\endinput{\mmz at temptrue\mmz at orig@endinput}%
+  \@input{\jobname.mmz.log}%
+  \ifmmz at temp \else \mmz at extraction@error \fi \endgroup }
+\def\mmz at extraction@error{%
+  \PackageWarning{memoize}{Extraction of externs from document "\mmzUnquote\jobname.pdf"
+    using method "\extractionmethod" was unsuccessful. Have you set the
+    shell escape mode as suggested in chapter 1 of the manual?}{}}
+\mmzset{
+  record/.style={%
+    record/begin/.append style={
+      /mmz/record/#1/begin/.try,
+      /mmz/record/#1/prefix/.try/.expanded=\mmz at prefix@path,
+    },
+    record/prefix/.append style={/mmz/record/#1/prefix/.try={##1}},
+    record/new extern/.append style={/mmz/record/#1/new extern/.try={##1}},
+    record/used extern/.append style={/mmz/record/#1/used extern/.try={##1}},
+    record/new cmemo/.append style={/mmz/record/#1/new cmemo/.try={##1}},
+    record/new ccmemo/.append style={/mmz/record/#1/new ccmemo/.try={##1}},
+    record/used cmemo/.append style={/mmz/record/#1/used cmemo/.try={##1}},
+    record/used ccmemo/.append style={/mmz/record/#1/used ccmemo/.try={##1}},
+    record/end/.append style={/mmz/record/#1/end/.try},
+  },
+}
+\mmzset{
+  no record/.style={%
+    record/begin/.style={record/begin/.style={}},
+    record/prefix/.code={\aftergroup\mmz at record@prefix},
+    record/new extern/.code={},
+    record/used extern/.code={},
+    record/new cmemo/.code={},
+    record/new ccmemo/.code={},
+    record/used cmemo/.code={},
+    record/used ccmemo/.code={},
+    record/end/.style={record/end/.code={}},
+  }
+}
+\def\mmz at record@prefix{%
+  \mmzset{/mmz/record/prefix/.expanded=\mmz at prefix@path}%
+}
+\mmzset{
+  no record,
+  record=mmz,
+  begindocument/.append style={record/begin},
+  enddocument/afterlastpage/.append style={record/end},
+}
+\mmzset{
+  record/mmz/begin/.code={%
+    \newwrite\mmz at mmzout
+    \immediate\openout\mmz at mmzout{\jobname.mmz}%
+  },
+  record/mmz/prefix/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzPrefix{#1}}%
+  },
+  record/mmz/new extern/.code={%
+    \immediate\write\mmz at mmzout{%
+      \noexpand\mmzNewExtern{#1}{\pagenumber}{\expectedwidth}{\expectedheight}%
+    }%
+  },
+  record/mmz/new cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCMemo{#1}}%
+  },
+  record/mmz/new ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCCMemo{#1}}%
+  },
+  record/mmz/used extern/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedExtern{#1}}%
+  },
+  record/mmz/used cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCMemo{#1}}%
+  },
+  record/mmz/used ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCCMemo{#1}}%
+  },
+  record/mmz/end/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\endinput}%
+    \immediate\closeout\mmz at mmzout
+  },
+  sh/.store in=\mmz at shname,
+  sh=memoize-extract.\jobname.sh,
+  bat/.store in=\mmz at batname,
+  bat=memoize-extract.\jobname.bat,
+  record/sh/begin/.code={%
+    \newwrite\mmz at shout
+    \immediate\openout\mmz at shout{\mmz at shname}%
+  },
+  record/sh/new extern/.code={%
+    \begingroup
+    \immediate\write\mmz at shout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/sh/end/.code={%
+    \immediate\closeout\mmz at shout
+  },
+  record/bat/begin/.code={%
+    \newwrite\mmz at batout
+    \immediate\openout\mmz at batout{\mmz at batname}%
+  },
+  record/bat/new extern/.code={%
+    \begingroup
+    \immediate\write\mmz at batout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/bat/end/.code={%
+    \immediate\closeout\mmz at batout
+  },
+  makefile/.store in=\mmz at makefilename,
+  makefile=memoize-extract.\jobname.makefile,
+}
+\begingroup
+\catcode`\^^I=12
+\gdef\mmz at makefile@recipe at prefix{^^I}%
+\endgroup
+\mmzset{
+  record/makefile/begin/.code={%
+    \newwrite\mmz at makefileout
+    \newtoks\mmz at makefile@externs
+    \immediate\openout\mmz at makefileout{\mmz at makefilename}%
+    \immediate\write\mmz at makefileout{.DEFAULT_GOAL = externs}%
+    \immediate\write\mmz at makefileout{.PHONY: externs}%
+  },
+  record/makefile/new extern/.code={%
+    \immediate\write\mmz at makefileout{#1:}%
+    \begingroup
+    \immediate\write\mmz at makefileout{%
+      \mmz at makefile@recipe at prefix\mmz at tex@extraction at systemcall}%
+    \endgroup
+    \xtoksapp\mmz at makefile@externs{#1\space}%
+  },
+  record/makefile/end/.code={%
+    \immediate\write\mmz at makefileout{externs: \the\mmz at makefile@externs}%
+    \immediate\closeout\mmz at makefileout
+  },
+}
+\mmzset{
+  extract/tex/.code={%
+    \begingroup
+    \@input{\jobname.mmz}%
+    \endgroup
+  },
+}
+\def\mmzUsedCMemo#1{}
+\def\mmzUsedCCMemo#1{}
+\def\mmzUsedExtern#1{}
+\def\mmzNewCMemo#1{}
+\def\mmzNewCCMemo#1{}
+\def\mmzPrefix#1{}
+\def\mmzNewExtern#1{%
+  \mmz at new@extern at i#1\mmz at temp
+}
+\def\mmz at new@extern at i#1.pdf\mmz at temp#2#3#4{%
+  \begingroup
+  \def\externbasepath{#1}%
+  \def\pagenumber{#2}%
+  \def\expectedwidth{#3}%
+  \def\expectedheight{#4}%
+  \mmz at clear@extraction at log
+  \pdf at system{\mmz at tex@extraction at systemcall}%
+  \let\mmz at extraction@error\mmz at pageextraction@error
+  \mmz at check@extraction at log{tex}%
+  \endgroup
+}
+\def\mmz at pageextraction@error{%
+  \PackageError{memoize}{Extraction of extern page \pagenumber\space from
+    document "\mmzUnquote\jobname.pdf" using method "\extractionmethod" was unsuccessful.
+    Have you set the shell escape mode as suggested in chapter 1 of the
+    manual?}{If "\mmzvalueof{tex extraction command}" was executed,
+    shell escape mode is not the problem, and inspecting "\externbasepath.log"
+    might give you a clue what's wrong}}
+\def\mmz at tex@extraction at systemcall{%
+  \mmzvalueof{tex extraction command}\space
+  \mmzvalueof{tex extraction options}\space
+  "\mmzvalueof{tex extraction script}"%
+}
+\mmzset{
+  tex extraction command/.initial=pdftex,
+  tex extraction options/.initial={%
+    -halt-on-error
+    -interaction=batchmode
+    -jobname "\externbasepath"
+    \ifdefempty\mmzOutputDirectory{}{-output-directory "\mmzOutputDirectory"}
+  },
+  tex extraction script/.initial={%
+    \def\noexpand\fromdocument{"\mmzOutputDirectory"\jobname.pdf}%
+    \def\noexpand\pagenumber{\pagenumber}%
+    \def\noexpand\expectedwidth{\expectedwidth}%
+    \def\noexpand\expectedheight{\expectedheight}%
+    \def\noexpand\logfile{\jobname.mmz.log}%
+    \normalunexpanded{%
+      \def\warningtemplate{%
+        \warning{memoize: \warningtext}%
+      }}%
+    \ifdef\XeTeXversion{}{%
+      \def\noexpand\mmzpdfmajorversion{\the\pdfmajorversion}%
+      \def\noexpand\mmzpdfminorversion{\the\pdfminorversion}%
+    }%
+    \noexpand\input memoize-extract-one
+  },
+}
+\def\mmz at tolerance{0.01pt}
+\def\mmz at if@roughly at equal#1#2#3{%
+  \dimen0=\dimexpr#2-#3\relax
+  \ifdim\dimen0<0pt
+    \dimen0=-\dimen0\relax
+  \fi
+  \ifdim\dimen0>#1\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi
+}%
+\mmzset{
+  .install advice={setup key=auto, activation=deferred},
+  begindocument/before/.append style={activation=immediate},
+}
+\newif\ifmmz at manual
+\mmzset{
+  manual/.is if=mmz at manual,
+  begindocument/end/.append code={%
+    \ifmmz at manual
+    \else
+      \pgfkeysalso{activate deferred,activate deferred/.code={}}%
+    \fi
+  },
+  auto/.cd,
+  run if memoization is possible/.style={
+    run conditions=\mmz at auto@rc at if@memoization at possible
+  },
+  run if memoizing/.style={run conditions=\mmz at auto@rc at if@memoizing},
+  apply options/.style={
+    bailout handler=\mmz at auto@bailout,
+    outer handler=\mmz at auto@outer,
+  },
+  memoize/.style={
+    run if memoization is possible,
+    apply options,
+    inner handler=\mmz at auto@memoize
+  },
+  noop/.style={inner handler=\mmz at auto@noop},
+  nomemoize/.style={noop, options=disable},
+  replicate/.style={run if memoizing, inner handler=\mmz at auto@replicate},
+}
+\mmzset{
+  auto/abort/.style={run conditions=\mmzAbort},
+}
+\mmzset{
+  auto/unmemoizable/.style={run conditions=\mmzUnmemoizable},
+}
+\ifdef\luatexversion{%
+  \mmzset{auto=\savepos{abort}}
+}{%
+  \mmzset{
+    auto=\pdfsavepos{abort},
+    auto=\errmessage{abort},
+  }
+}
+\def\mmz at auto@rc at if@memoization at possible{%
+  \ifmemoize
+    \ifinmemoize
+    \else
+      \AdviceRuntrue
+    \fi
+  \fi
+}
+\def\mmz at auto@rc at if@memoizing{%
+  \ifmemoizing\AdviceRuntrue\fi
+}
+\def\mmznext#1{\gdef\mmz at next{#1}\ignorespaces}
+\mmznext{}%
+\def\mmz at auto@outer{%
+  \begingroup
+  \mmzAutoInit
+  \AdviceCollector
+}
+\def\mmz at auto@bailout{%
+  \mmznext{}%
+}
+\def\mmzAutoInit{%
+  \ifdefempty\AdviceOptions{}{\expandafter\mmzset\expandafter{\AdviceOptions}}%
+  \ifdefempty\mmz at next{}{\expandafter\mmzset\expandafter{\mmz at next}\mmznext{}}%
+  \eappto\AdviceRawCollectorOptions{\expandonce\mmzRawCollectorOptions}%
+}
+\long\def\mmz at auto@memoize#1{%
+  \normalexpanded{%
+    \noexpand\Memoize
+      {\expandonce\AdviceReplaced\normalunexpanded{#1}}%
+      {\expandonce\AdviceOriginal\normalunexpanded{#1}}%
+    \ifmmz at ignorespaces\ignorespaces\fi
+  }%
+}
+\long\def\mmz at auto@noop#1{%
+  \expandafter\mmz at maybe@scantokens\expandafter{\AdviceOriginal#1}%
+  \expandafter\endgroup
+  \ifmmz at ignorespaces\ignorespaces\fi
+}
+\def\mmz at auto@replicate#1{%
+  \begingroup
+  \let\mmz at auto@replicate at expansion\normalunexpanded
+  \expandafter\pgfqkeys\normalexpanded{{/mmz/auto/replicate}{\AdviceOptions}}%
+  \normalexpanded{%
+    \endgroup
+    \noexpand\gtoksapp\noexpand\mmzCCMemo{%
+      \expandonce\AdviceReplaced\mmz at auto@replicate at expansion{#1}}%
+    \expandonce\AdviceOriginal\normalunexpanded{#1}%
+  }%
+}
+\pgfqkeys{/mmz/auto/replicate}{
+  expanded/.code={\let\mmz at auto@replicate at expansion\@firstofone},
+}
+\mmzset{
+  begindocument/before/.append code={%
+    \ifdefined\tikz
+      \input advice-tikz.code.tex
+    \fi
+    \mmzset{%
+      auto=\tikz{memoize, collector=\AdviceCollectTikZArguments},
+      auto={tikzpicture}{memoize},
+      auto=\pgfsys at getposition{
+        run if memoizing, outer handler=\mmz at pgfsys@getposition},
+    }%
+    \def\mmz at pgfsys@getposition##1{%
+      \expandafter\ifx\csname pgf at sys@pdf at mark@pos@##1\endcsname\relax
+      \else
+        \mmzAbort
+      \fi
+      \AdviceOriginal{##1}%
+    }%
+  },
+}
+\mmzset{
+  begin document/.style={begindocument/before, begindocument, begindocument/end},
+  end document/.style={enddocument/afterlastpage},
+}
+\InputIfFileExists{memoize.cfg}{}{}
+\mmzset{
+  extract/no/.code={},
+  output-directory/.store in=\mmzOutputDirectory,
+}
+\expandafter\mmzset\expandafter{\currentmoduleparameters}
+\ifdefined\mmzOutputDirectory
+\else
+  \def\mmzOutputDirectory{}%
+\fi
+\mmzset{output directory/.code={\PackageError{memoize}{Key "output-directory"
+      may only be used as a package option}{}}}
+\mmzset{
+  extract/\mmz at extraction@method,
+  extract/.code={\PackageError{memoize}{Key "extract" is only allowed as a
+      package option.}{If you really want to extract in the preamble, execute
+      "extract/<method>".}},
+}
+\ifnum\pdf at draftmode=1
+  \PackageWarning{memoize}{No memoization will be performed in the draft mode}%
+\fi
+\stopmodule
+\protect
+\endinput
+%%
+%% End of file `t-memoize.tex'.


Property changes on: trunk/Master/texmf-dist/tex/context/memoize/t-memoize.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/context/memoize/t-nomemoize.tex
===================================================================
--- trunk/Master/texmf-dist/tex/context/memoize/t-nomemoize.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/memoize/t-nomemoize.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,110 @@
+%%
+%% This is file `t-nomemoize.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `nommz,context')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+%D \module[
+%D         file=t-nomemoize.tex,
+%D      version=1.0.0,
+%D        title=Memoize,
+%D     subtitle=A no-op stub for Memoize,
+%D       author=Saso Zivanovic,
+%D         date=2023-10-10,
+%D    copyright=Saso Zivanovic,
+%D      license=LPPL,
+%D ]
+\writestatus{loading}{ConTeXt User Module / nomemoize}
+\unprotect
+\startmodule[nomemoize]
+\input miniltx
+\def\ifmmz at loadstatus#1{%
+  \ifnum#1=0\csname mmz at loadstatus\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+\ifmmz at loadstatus{1}%
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoize" is already
+    loaded; memoization will remain in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+  \endinput }{}%
+\ifmmz at loadstatus{2}%
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  (No)Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded
+    "memoizable"; please move
+    "\string\usemodule[memoize]"
+    before the
+    "\string\usemodule"
+    of that package.}%
+  \endinput
+}{}%
+\ifmmz at loadstatus{3}{\endinput}{}%
+\def\mmz at loadstatus{3}%
+\def\mmzset#1{\ignorespaces}
+\def\nommzkeys{\pgfqkeys{/mmz}}
+\pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}}
+\newif\ifmemoize
+\protected\def\nommz#1#{%
+  \afterassignment\nommz at i
+  \let\mmz at temp
+}
+\def\nommz at i{%
+  \bgroup
+  \memoizefalse
+}
+\let\mmz\nommz
+\def\startnomemoize{%
+  \begingroup
+  \memoizefalse
+  \futurelet\mmz at temp\nommz at env@i
+}
+\def\nommz at env@i{%
+  \ifx\mmz at temp[%]
+    \expandafter\nommz at env@ii
+  \fi
+}
+\def\nommz at env@ii[#1]{%
+  \ignorespaces
+}
+\def\stopnomemoize{%
+  \endgroup
+  \unskip
+}
+\let\startmemoize\startnomemoize
+\let\stopmemoize\stopnomemoize
+\newif\ifmemoizing
+\newif\ifinmemoize
+\newcommand\IfMemoizing[2][]{\@secondoftwo}
+\def\mmznext#1{\ignorespaces}
+\InputIfFileExists{memoize.cfg}{}{}
+\stopmodule
+\protect
+\endinput
+%%
+%% End of file `t-nomemoize.tex'.


Property changes on: trunk/Master/texmf-dist/tex/context/memoize/t-nomemoize.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/memoize/memoizable.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/memoize/memoizable.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/memoize/memoizable.sty	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,39 @@
+%%
+%% This is file `memoizable.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `mmzable,latex')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+\ProvidesPackage{memoizable}[2023/10/10 v1.0.0 A programmer's stub for Memoize]
+\@ifpackageloaded{memoize}%
+{\endinput}{}
+\@ifpackageloaded{nomemoize}%
+{\endinput}{}%
+\def\mmzset#1{\ignorespaces}
+\def\nommzkeys{\pgfqkeys{/mmz}}
+\pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}}
+\newif\ifmemoize
+\newcommand\IfMemoizing[2][]{\@secondoftwo}
+\endinput
+%%
+%% End of file `memoizable.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/memoize/memoizable.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/memoize/memoize.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/memoize/memoize.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/memoize/memoize.sty	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,1510 @@
+%%
+%% This is file `memoize.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `mmz,latex')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+\ProvidesPackage{memoize}[2023/10/10 v1.0.0 Fast and flexible externalization]
+\RequirePackage{pgfopts}  % pgfkeys-based package options
+\RequirePackage{etoolbox}
+\ifdefined\luatexversion
+  \directlua{memoize = {}}
+\fi
+\RequirePackage{pdftexcmds}
+\ifdef\pdftexversion{%
+}{%
+  \def\pdfhorigin{1true in}%
+  \def\pdfvorigin{1true in}%
+  \ifdef\XeTeXversion{%
+    \let\quitvmode\leavevmode
+  }{%
+    \ifdef\luatexversion{%
+      \let\pdfpagewidth\pagewidth
+      \let\pdfpageheight\pageheight
+      \def\pdfmajorversion{\pdfvariable majorversion}%
+      \def\pdfminorversion{\pdfvariable minorversion}%
+    }{%
+      \PackageError{memoize}{Support for this TeX engine is not implemented}{}%
+    }%
+  }%
+}
+\RequirePackage{advice}
+\@ifpackageloaded{nomemoize}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "nomemoize" is already
+    loaded. Memoization will NOT be in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+  \pgfkeys{/memoize/package options/.unknown/.code={}}
+  \ProcessPgfPackageOptions{/memoize/package options}
+    \endinput
+}{}%
+\@ifpackageloaded{memoizable}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded "memoizable";
+    please move
+    "\string\usepackage{memoize}"
+    before the
+    "\string\usepackage"
+    of that package.}%
+    \pgfkeys{/memoize/package options/.unknown/.code={}}
+    \ProcessPgfPackageOptions{/memoize/package options}
+  \endinput
+}{}%
+\def\filetotoks#1#2{%
+  \immediate\openin0{#2}%
+  #1={}%
+  \loop
+  \unless\ifeof0
+    \read0 to \totoks at temp
+    \expandafter\toksapp\expandafter#1\expandafter{\totoks at temp}%
+  \repeat
+  \immediate\closein0
+}
+\newif\ifmmz at temp
+\newtoks\mmz at temptoks
+\newbox\mmz at box
+\newwrite\mmz at out
+\def\mmzset#1{\pgfqkeys{/mmz}{#1}\ignorespaces}
+\def\nommzkeys#1{}
+\newif\ifmemoize
+\mmzset{%
+  enable/.style={begindocument/.append code=\memoizetrue},
+  disable/.style={begindocument/.append code=\memoizefalse},
+  begindocument/.append style={
+    enable/.code=\memoizetrue,
+    disable/.code=\memoizefalse,
+  },
+  enable,
+}
+\def\mmz at mode@normal{0}
+\def\mmz at mode@readonly{1}
+\def\mmz at mode@recompile{2}
+\let\mmz at mode\mmz at mode@normal
+\mmzset{%
+  normal/.code={\let\mmz at mode\mmz at mode@normal},
+  readonly/.code={\let\mmz at mode\mmz at mode@readonly},
+  recompile/.code={\let\mmz at mode\mmz at mode@recompile},
+}
+\mmzset{%
+  path/.code={\pgfqkeys{/mmz/path}{#1}},
+  path/.cd,
+  relative/.is if=mmz at relativepath,
+  dir/.store in=\mmz at dir,
+  dir/.value required,
+  prefix/.store in=\mmz at prefix,
+  prefix/.value required,
+}
+\newif\ifmmz at relativepath
+\mmzset{%
+  begindocument/.append style={
+    path/.append code=\mmz at maybe@mkmemodir\mmz at record@prefix,
+  },
+  begindocument/.append code=\mmz at maybe@mkmemodir,
+}
+\def\mmz at dir@path{\ifmmz at relativepath.\fi/\mmz at dir}
+\def\mmz at prefix@path{\mmz at dir@path/\mmz at prefix}
+\mmzset{
+  mkdir/.is if=mmz at mkdir,
+  mkdir command/.code={\def\mmz at mkdir@command##1{#1}},
+  mkdir command={mkdir "#1"},
+}
+\newif\ifmmz at mkdir
+\def\mmz at maybe@mkmemodir{%
+  \ifmmz at mkdir
+    \pdf at system{\mmz at mkdir@command{\mmzOutputDirectory\mmz at dir@path}}%
+  \fi
+}
+\mmzset{%
+  memo dir/.style={
+    mkdir,
+    path={
+      relative,
+      dir={#1.memo.dir},
+      prefix={},
+    },
+  },
+  memo dir/.default=\mmzUnquote\jobname,
+  no memo dir/.style={
+    mkdir=false,
+    path={
+      relative,
+      dir={},
+      prefix={#1.},
+    },
+  },
+  no memo dir/.default=\mmzUnquote\jobname,
+  no memo dir,
+}
+\def\mmzUnquote#1{\expanded{\noexpand\mmz at unquote#1}\mmz at unquote@end}
+\def\mmz at unquote#1{%
+  \ifx\mmz at unquote@end#1%
+  \else
+    \ifx"#1%
+      \expandafter\expandafter\expandafter\mmz at unquote@quotes
+    \else
+      \expandafter\expandafter\expandafter\mmz at unquote@noquotes
+      \expandafter\expandafter\expandafter#1%
+    \fi
+  \fi
+}
+\def\mmz at unquote@quotes#1"\mmz at unquote@end{#1}
+\def\mmz at unquote@noquotes#1\mmz at unquote@end{#1}
+\newif\ifmmz at ignorespaces
+\mmzset{
+  ignore spaces/.is if=mmz at ignorespaces,
+}
+\newif\ifmmz at verbatim
+\def\mmzRawCollectorOptions{}
+\mmzset{
+  verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerbatim}%
+    \mmz at verbatimtrue
+  },
+  verb/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerb}%
+    \mmz at verbatimtrue
+  },
+  no verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsNoVerbatim}%
+    \mmz at verbatimfalse
+  },
+}
+\protected\def\mmz{\futurelet\mmz at temp\mmz at i}
+\def\mmz at i{%
+  \begingroup
+  \ifx\mmz at temp[%]
+    \def\mmz at verbatim@fix{}%
+    \expandafter\mmz at ii
+  \else
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+    \expandafter\mmz at iii
+  \fi
+}
+\def\mmz at ii[#1]{%
+  \mmzset{#1}%
+  \mmz at iii
+}
+\def\mmz at iii{%
+  \ifmmz at verbatim
+    \expandafter\mmz at do@verbatim
+  \else
+    \expandafter\mmz at do
+  \fi
+}
+\long\def\mmz at do#1{%
+  \Memoize{#1}{#1}%
+}%
+\def\mmz at do@verbatim#1{%
+  \expanded{%
+    \noexpand\CollectArgumentsRaw{%
+      \noexpand\collargsCaller{\noexpand\mmz}%
+      \expandonce\mmzRawCollectorOptions
+      \mmz at verbatim@fix
+    }%
+  }{+m}\mmz at do
+}
+\newenvironment{memoize}[1][\mmz at noarg]{%
+  \end{memoize}%
+  \begingroup
+  \def\mmz at temp{#1}%
+  \ifx\mmz at temp\mmz at noarg
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+  \else
+    \def\mmz at verbatim@fix{}%
+    \mmzset{#1}%
+  \fi
+  \mmz at env@iii
+}{}
+\def\mmz at noarg{\mmz at noarg}
+\def\mmz at env@iii{%
+  \long\edef\mmz at do##1{%
+    \noexpand\Memoize{##1}{##1\unskip}%
+  }%
+  \expanded{%
+    \noexpand\CollectArgumentsRaw{%
+      \noexpand\collargsCaller{memoize}%
+      \expandonce\mmzRawCollectorOptions
+      \ifmmz at verbatim\mmz at verbatim@fix\fi
+    }%
+  }{&&{\collargsAppendPostwrap{}}!t{ }+b{memoize}}{\mmz at do}%
+}%
+\protected\def\nommz#1#{%
+  \afterassignment\nommz at i
+  \let\mmz at temp
+}
+\def\nommz at i{%
+  \bgroup
+  \memoizefalse
+}
+\newenvironment{nomemoize}[1][]{%
+  \memoizefalse
+  \ignorespaces
+}{%
+  \unskip
+}
+\newif\ifmemoizing
+\newif\ifinmemoize
+\def\mmz at maybe@scantokens{%
+  \ifmmz at verbatim
+    \expandafter\mmz at scantokens
+  \else
+    \expandafter\@firstofone
+  \fi
+}
+\long\def\mmz at scantokens#1{%
+  \expanded{%
+    \newlinechar=13
+    \unexpanded{\scantokens{#1\endinput}}%
+    \newlinechar=\the\newlinechar
+  }%
+}
+\newtoks\mmz at mdfive@source
+\newtoks\mmz at exec@source
+\let\Memoize\@secondoftwo
+\long\def\Memoize#1#2{%
+  \mmz at mdfive@source{#1}%
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  \mmz at exec@source
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  {%
+    \mmz at maybe@scantokens{#2}%
+  }%
+  \mmz at trace@Memoize
+  \let\mmz at action\mmz at compile
+  \ifmemoizing
+  \else
+    \ifmemoize
+      \xdef\mmz at code@mdfivesum{\pdf at mdfivesum{\the\mmz at mdfive@source}}%
+      \mmz at trace@code at mdfive
+      \ifnum\mmz at mode=\mmz at mode@recompile\relax
+        \ifnum\pdf at draftmode=0
+          \let\mmz at action\mmz at memoize
+        \fi
+      \else
+        \mmz at process@cmemo
+        \ifmmzUnmemoizable
+          \mmz at trace@cmemo at unmemoizable
+        \else
+          \ifmmz at abort
+            \mmz at trace@process at cmemo@fail
+            \ifnum\mmz at mode=\mmz at mode@readonly\relax
+            \else
+              \ifnum\pdf at draftmode=0
+                \let\mmz at action\mmz at memoize
+              \fi
+            \fi
+          \else
+            \mmz at trace@process at cmemo@ok
+            \let\mmz at action\mmz at process@ccmemo
+          \fi
+        \fi
+      \fi
+    \fi
+  \fi
+  \mmz at action
+}
+\def\mmz at compile{%
+  \mmz at trace@compile
+  \expanded{%
+    \endgroup
+    \noexpand\inmemoizetrue
+    \the\mmz at exec@source
+    \ifinmemoize\noexpand\inmemoizetrue\else\noexpand\inmemoizefalse\fi
+  }%
+}
+\ifdefined\luatexversion
+  \directlua{%
+    luatexbase.add_to_callback(
+      "show_error_message",
+      function()
+        memoize.abort = true
+        texio.write_nl(status.lasterrorstring)
+      end,
+      "Abort memoization on error"
+    )
+  }%
+  \def\mmz at lua@atbeginmemoization{%
+    \directlua{memoize.abort = false}%
+  }%
+  \def\mmz at lua@atendmemoization{%
+    \directlua{%
+      if memoize.abort then
+        tex.print("\noexpand\\mmzAbort")
+      end
+    }%
+  }%
+\else
+  \let\mmz at lua@atbeginmemoization\relax
+  \let\mmz at lua@atendmemoization\relax
+\fi
+\def\mmz at memoize{%
+  \mmz at trace@memoize
+  \memoizingtrue
+  \inmemoizetrue
+  \edef\memoizinggrouplevel{\the\currentgrouplevel}%
+  \global\mmz at abortfalse
+  \global\mmzUnmemoizablefalse
+  \global\mmz at seq 0
+  \global\setbox\mmz at tbe@box\vbox{}%
+  \global\mmz at ccmemo@resources{}%
+  \global\mmzCMemo{}%
+  \global\mmzCCMemo{}%
+  \global\mmzContextExtra{}%
+  \gdef\mmzAtEndMemoizationExtra{}%
+  \gdef\mmzAfterMemoizationExtra{}%
+  \mmz at lua@atbeginmemoization
+  \mmzAtBeginMemoization
+  \mmzDriver{\the\mmz at exec@source}%
+  \mmzAtEndMemoization
+  \mmzAtEndMemoizationExtra
+  \mmz at lua@atendmemoization
+  \ifmmzUnmemoizable
+    \global\mmzContextExtra{}%
+    \gtoksapp\mmzCMemo{\global\mmzUnmemoizabletrue}%
+    \mmz at write@cmemo
+    \mmz at trace@endmemoize at unmemoizable
+    \PackageWarning{memoize}{Marking this code as unmemoizable}%
+  \else
+    \ifmmz at abort
+      \mmz at trace@endmemoize at aborted
+      \PackageWarning{memoize}{Memoization was aborted}%
+      \mmz at write@empty at cmemo
+    \else
+      \mmz at compute@context at mdfivesum
+      \mmz at write@cmemo
+      \mmz at write@ccmemo
+      \mmz at shipout@externs
+      \mmz at trace@endmemoize at ok
+    \fi
+  \fi
+  \expandafter\endgroup
+  \expandafter\let
+    \expandafter\mmzIncludeExtern\expandafter\mmz at include@extern at from@tbe at box
+  \mmzAfterMemoization
+  \mmzAfterMemoizationExtra
+}
+\def\memoizinggrouplevel{-1}%
+\def\mmzAbort{\global\mmz at aborttrue}
+\newif\ifmmz at abort
+\def\mmzUnmemoizable{\global\mmzUnmemoizabletrue}
+\newif\ifmmzUnmemoizable
+\def\mmzAtBeginMemoization{}
+\def\mmzAtEndMemoization{}
+\def\mmzAfterMemoization{}
+\mmzset{
+  at begin memoization/.code={%
+    \ifmemoizing
+      \expandafter\@firstofone
+    \else
+      \expandafter\appto\expandafter\mmzAtBeginMemoization
+    \fi
+    {#1}%
+  },
+  at end memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAtEndMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAtEndMemoization
+    \fi
+    {#1}%
+  },
+  after memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAfterMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAfterMemoization
+    \fi
+    {#1}%
+  },
+}
+\mmzset{
+  driver/.store in=\mmzDriver,
+  driver=\mmzSingleExternDriver,
+}
+\newif\ifmmzkeepexterns
+\long\def\mmzSingleExternDriver#1{%
+  \xtoksapp\mmzCCMemo{\mmz at maybe@quitvmode}%
+  \setbox\mmz at box\mmz at capture{#1}%
+  \mmzExternalizeBox\mmz at box\mmz at temptoks
+  \xtoksapp\mmzCCMemo{\the\mmz at temptoks}%
+  \mmz at maybe@quitvmode\box\mmz at box
+}
+\mmzset{
+  capture/.is choice,
+  capture/hbox/.code={%
+    \let\mmz at capture\hbox
+    \def\mmz at maybe@quitvmode{\noexpand\quitvmode}%
+  },
+  capture/vbox/.code={%
+    \let\mmz at capture\vbox
+    \def\mmz at maybe@quitvmode{}%
+  },
+  capture=hbox,
+}
+\mmzset{
+  auto/integrated driver/.style={
+    after setup={\expandafter\newif\csname ifmmz at memoizing#1\endcsname},
+    driver/.expand once={%
+      \csname mmz at memoizing#1true\endcsname
+      \@firstofone
+    }%
+  },
+}
+\newcommand\IfMemoizing[2][\mmz at Ifmemoizing@nogrouplevel]{%>\fi
+\csname ifmmz at memoizing#2\endcsname%>\if
+  \ifnum\currentgrouplevel=\the\numexpr\memoizinggrouplevel+#1\relax\relax
+    \expandafter\expandafter\expandafter\@firstoftwo
+  \else
+    \expandafter\expandafter\expandafter\@secondoftwo
+  \fi
+\else
+  \expandafter\@secondoftwo
+\fi
+}
+\def\mmz at Ifmemoizing@nogrouplevel{0\relax\relax\fi\iftrue}
+\def\mmz at trace#1{\immediate\write16{[tracing memoize] #1}}
+\def\mmz at trace@context{\mmz at trace{\space\space
+    Context: "\expandonce{\mmz at context@key}" --> \mmz at context@mdfivesum}}
+\def\mmz at trace@Memoize at on{%
+  \mmz at trace{%
+    Entering \noexpand\Memoize (%
+    \ifmemoize enabled\else disabled\fi,
+    \ifnum\mmz at mode=\mmz at mode@recompile recompile\fi
+    \ifnum\mmz at mode=\mmz at mode@readonly readonly\fi
+    \ifnum\mmz at mode=\mmz at mode@normal normal\fi
+    \space mode) on line \the\inputlineno
+  }%
+  \mmz at trace{\space\space Code: \the\mmz at mdfive@source}%
+}
+\def\mmz at trace@code at mdfive@on{\mmz at trace{\space\space
+    Code md5sum: \mmz at code@mdfivesum}}
+\def\mmz at trace@compile at on{\mmz at trace{\space\space Compiling}}
+\def\mmz at trace@memoize at on{\mmz at trace{\space\space Memoizing}}
+\def\mmz at trace@endmemoize at ok@on{\mmz at trace{\space\space
+    Memoization completed}}%
+\def\mmz at trace@endmemoize at aborted@on{\mmz at trace{\space\space
+    Memoization was aborted}}
+\def\mmz at trace@endmemoize at unmemoizable@on{\mmz at trace{\space\space
+    Marking this code as unmemoizable}}
+\def\mmz at trace@process at cmemo@on{\mmz at trace{\space\space
+    Attempting to utilize c-memo \mmz at cmemo@path}}
+\def\mmz at trace@process at no@cmemo at on{\mmz at trace{\space\space
+    C-memo does not exist}}
+\def\mmz at trace@process at cmemo@ok at on{\mmz at trace{\space\space
+    C-memo was processed successfully}\mmz at trace@context}
+\def\mmz at trace@process at cmemo@fail at on{\mmz at trace{\space\space
+    C-memo input failed}}
+\def\mmz at trace@cmemo at unmemoizable@on{\mmz at trace{\space\space
+    This code was marked as unmemoizable}}
+\def\mmz at trace@process at ccmemo@on{\mmz at trace{\space\space
+    Attempting to utilize cc-memo \mmz at ccmemo@path\space
+    (\ifmmz at direct@ccmemo at input\else in\fi direct input)}}
+\def\mmz at trace@resource at on#1{\mmz at trace{\space\space
+    Extern file does not exist: #1}}
+\def\mmz at trace@process at ccmemo@ok at on{%
+  \mmz at trace{\space\space Utilization successful}}
+\def\mmz at trace@process at no@ccmemo at on{%
+  \mmz at trace{\space\space CC-memo does not exist}}
+\def\mmz at trace@process at ccmemo@fail at on{%
+  \mmz at trace{\space\space Cc-memo input failed}}
+\mmzset{%
+  trace/.is choice,
+  trace/.default=true,
+  trace/true/.code=\mmzTracingOn,
+  trace/false/.code=\mmzTracingOff,
+}
+\def\mmzTracingOn{%
+  \let\mmz at trace@Memoize\mmz at trace@Memoize at on
+  \let\mmz at trace@code at mdfive\mmz at trace@code at mdfive@on
+  \let\mmz at trace@compile\mmz at trace@compile at on
+  \let\mmz at trace@memoize\mmz at trace@memoize at on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@endmemoize at ok\mmz at trace@endmemoize at ok@on
+  \let\mmz at trace@endmemoize at unmemoizable\mmz at trace@endmemoize at unmemoizable@on
+  \let\mmz at trace@endmemoize at aborted\mmz at trace@endmemoize at aborted@on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@process at cmemo@ok\mmz at trace@process at cmemo@ok at on
+  \let\mmz at trace@process at no@cmemo\mmz at trace@process at no@cmemo at on
+  \let\mmz at trace@process at cmemo@fail\mmz at trace@process at cmemo@fail at on
+  \let\mmz at trace@cmemo at unmemoizable\mmz at trace@cmemo at unmemoizable@on
+  \let\mmz at trace@process at ccmemo\mmz at trace@process at ccmemo@on
+  \let\mmz at trace@resource\mmz at trace@resource at on
+  \let\mmz at trace@process at ccmemo@ok\mmz at trace@process at ccmemo@ok at on
+  \let\mmz at trace@process at no@ccmemo\mmz at trace@process at no@ccmemo at on
+  \let\mmz at trace@process at ccmemo@fail\mmz at trace@process at ccmemo@fail at on
+}
+\def\mmzTracingOff{%
+  \let\mmz at trace@Memoize\relax
+  \let\mmz at trace@code at mdfive\relax
+  \let\mmz at trace@compile\relax
+  \let\mmz at trace@memoize\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@endmemoize at ok\relax
+  \let\mmz at trace@endmemoize at unmemoizable\relax
+  \let\mmz at trace@endmemoize at aborted\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@process at cmemo@ok\relax
+  \let\mmz at trace@process at no@cmemo\relax
+  \let\mmz at trace@process at cmemo@fail\relax
+  \let\mmz at trace@cmemo at unmemoizable\relax
+  \let\mmz at trace@process at ccmemo\relax
+  \let\mmz at trace@resource\@gobble
+  \let\mmz at trace@process at ccmemo@ok\relax
+  \let\mmz at trace@process at no@ccmemo\relax
+  \let\mmz at trace@process at ccmemo@fail\relax
+}
+\mmzTracingOff
+\newtoks\mmzContext
+\newtoks\mmzContextExtra
+\mmzset{%
+  context/.code={%
+    \ifmemoizing
+      \expandafter\gtoksapp\expandafter\mmzContextExtra
+    \else
+      \expandafter\toksapp\expandafter\mmzContext
+    \fi
+    {#1,}%
+  },
+  clear context/.code={%
+    \ifmemoizing
+      \expandafter\global\expandafter\mmzContextExtra
+    \else
+      \expandafter\mmzContext
+    \fi
+    {}%
+  },
+  clear context/.value forbidden,
+  meaning to context/.code={\forcsvlist\mmz at mtoc{#1}},
+  csname meaning to context/.code={\mmz at mtoc@cs{#1}},
+  key meaning to context/.code={\forcsvlist\mmz at mtoc\mmz at mtoc@keycmd{#1}},
+  key value to context/.code={\forcsvlist\mmz at mtoc@key{#1}},
+  /handlers/.meaning to context/.code={%
+    \expanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath/. at cmd}}},
+  /handlers/.value to context/.code={%
+    \expanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath}}},
+}
+\def\mmz at mtoc#1{%
+  \collargs at cs@cases{#1}%
+    {\mmz at mtoc@cmd{#1}}%
+    {\mmz at mtoc@error at notcsorenv{#1}}%
+    {%
+      \mmz at mtoc@cs{%
+        #1}%
+      \mmz at mtoc@cs{%
+        end%
+        #1}%
+    }%
+}
+\def\mmz at mtoc@cmd#1{%
+  \begingroup
+  \escapechar=-1
+  \expandafter\endgroup
+  \expandafter\mmz at mtoc@cs\expandafter{\string#1}%
+}
+\def\mmz at mtoc@cs#1{%
+  \pgfkeysvalueof{/mmz/context/. at cmd}%
+  \expandafter\string\csname#1\endcsname={\expandafter\meaning\csname#1\endcsname}%
+  \pgfeov
+}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1}}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1/. at cmd}}
+\def\mmz at mtoc@error at notcsorenv#1{%
+  \PackageError{memoize}{'\detokenize{#1}' passed to key 'meaning to context' is neither a command nor an environment}{}%
+}
+\def\mmz at cmemo@path{\mmz at prefix@path\mmz at code@mdfivesum.memo}
+\newtoks\mmzCMemo
+\mmzset{%
+  include source in cmemo/.is if=mmz at include@source,
+}
+\newif\ifmmz at include@source
+\mmz at include@sourcetrue
+\def\mmz at write@cmemo{%
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  \immediate\write\mmz at out{%
+    \global\mmzContextExtra{\the\mmzContextExtra}\collargs at percentchar
+  }%
+  \immediate\write\mmz at out{\the\mmzCMemo\collargs at percentchar}%
+  \ifmmz at include@source
+    \immediate\write\mmz at out{\noexpand\mmzSource}%
+    \immediate\write\mmz at out{\the\mmz at mdfive@source}%
+  \fi
+  \immediate\closeout\mmz at out
+  \pgfkeysalso{/mmz/record/new cmemo={\mmz at cmemo@path}}%
+}
+\def\mmz at write@empty at cmemo{%
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  \immediate\closeout\mmz at out
+}
+\let\mmzSource\endinput
+\def\mmz at process@cmemo{%
+  \mmz at trace@process at cmemo
+  \global\mmz at aborttrue
+  \global\mmzUnmemoizablefalse
+  \def\mmzMemo{\global\mmz at abortfalse}%
+  \global\mmzContextExtra{}%
+  \IfFileExists{\mmz at cmemo@path}{%
+    \input{\mmz at cmemo@path}%
+    \pgfkeysalso{/mmz/record/used cmemo={\mmz at cmemo@path}}%
+  }{%
+    \mmz at trace@process at no@cmemo
+  }%
+  \mmz at compute@context at mdfivesum
+}
+\def\mmz at compute@context at mdfivesum{%
+  \xdef\mmz at context@key{\the\mmzContext\the\mmzContextExtra}%
+  \begingroup
+  \begingroup
+  \def\width{\string\width}%
+  \def\height{\string\height}%
+  \def\depth{\string\depth}%
+  \edef\mmz at paddings{\mmz at paddings}%
+  \expandafter\endgroup
+  \expandafter\def\expandafter\mmz at paddings\expandafter{\mmz at paddings}%
+  \protected at xdef
+  \mmz at context@key{\mmz at context@key}%
+  \endgroup
+  \xdef\mmz at context@mdfivesum{\pdf at mdfivesum{\expandonce\mmz at context@key}}%
+}
+\def\mmz at ccmemo@path{%
+  \mmz at prefix@path\mmz at code@mdfivesum-\mmz at context@mdfivesum.memo}
+\newtoks\mmzCCMemo
+\newif\ifmmz at include@context
+\mmzset{%
+  include context in ccmemo/.is if=mmz at include@context,
+}
+\newif\ifmmz at direct@ccmemo at input
+\mmzset{%
+  direct ccmemo input/.is if=mmz at direct@ccmemo at input,
+}
+\def\mmz at write@ccmemo{%
+  \immediate\openout\mmz at out{\mmz at ccmemo@path}%
+  \begingroup
+  \the\mmz at ccmemo@resources
+  \endgroup
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  \immediate\write\mmz at out{\the\mmzCCMemo\collargs at percentchar}%
+  \ifmmz at include@context
+    \immediate\write\mmz at out{\noexpand\mmzThisContext}%
+    \immediate\write\mmz at out{\expandonce{\mmz at context@key}}%
+  \fi
+  \immediate\write\mmz at out{\noexpand\mmzEndMemo}%
+  \immediate\closeout\mmz at out
+  \pgfkeysalso{/mmz/record/new ccmemo={\mmz at ccmemo@path}}%
+}
+\def\mmz at ccmemo@append at resource#1{%
+  \mmz at seq=#1\relax
+  \immediate\write\mmz at out{%
+    \string\mmzResource{\mmz at extern@name}\collargs at percentchar}%
+}
+\def\mmzResource#1{%
+  \ifnum0\pdf at filesize{\mmz at dir@path/#1}=0
+    \ifmmz at direct@ccmemo at input
+      \let\mmzMemo\endinput
+    \else
+      \long\def\mmzMemo##1\mmzEndMemo\par{}%
+    \fi
+    \mmz at trace@resource{#1}%
+  \fi
+}
+\def\mmz at process@ccmemo{%
+  \mmz at trace@process at ccmemo
+  \global\mmz at aborttrue
+  \def\mmzMemo{%
+    \endgroup
+    \global\mmz at abortfalse
+    \let\mmzIncludeExtern\mmz at include@extern
+  }%
+  \xdef\mmzEndMemo{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      \unexpanded{%
+        \def\mmz at temp\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  \xdef\mmzThisContext{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      \unexpanded{%
+        \long\def\mmz at temp##1\mmzEndMemo\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  \IfFileExists{\mmz at ccmemo@path}{%
+    \ifmmz at direct@ccmemo at input
+      \input{\mmz at ccmemo@path}%
+    \else
+      \filetotoks\toks@{\mmz at ccmemo@path}%
+      \the\toks@
+    \fi
+    \pgfkeysalso{/mmz/record/used ccmemo={\mmz at ccmemo@path}}%
+  }{%
+    \mmz at trace@process at no@ccmemo
+  }%
+  \ifmmz at abort
+    \mmz at trace@process at ccmemo@fail
+    \ifnum\mmz at mode=\mmz at mode@readonly\relax
+      \expandafter\expandafter\expandafter\mmz at compile
+    \else
+      \expandafter\expandafter\expandafter\mmz at memoize
+    \fi
+  \else
+    \mmz at trace@process at ccmemo@ok
+  \fi
+}
+\newcount\mmz at seq
+\def\mmz at extern@basename{%
+  \mmz at prefix\mmz at code@mdfivesum-\mmz at context@mdfivesum
+  \ifnum\mmz at seq>0 -\the\mmz at seq\fi
+}
+\def\mmz at extern@name{\mmz at extern@basename.pdf}
+\def\mmz at extern@basepath{\mmz at dir@path/\mmz at extern@basename}
+\def\mmz at extern@path{\mmz at extern@basepath.pdf}
+\mmzset{
+  padding left/.store in=\mmz at padding@left,
+  padding right/.store in=\mmz at padding@right,
+  padding top/.store in=\mmz at padding@top,
+  padding bottom/.store in=\mmz at padding@bottom,
+  padding/.style={
+    padding left=#1, padding right=#1,
+    padding top=#1, padding bottom=#1
+  },
+  padding=1in,
+  padding to context/.style={
+    context={padding=(\mmz at paddings)},
+  },
+  padding to context,
+}
+\def\mmz at paddings{%
+  \mmz at padding@left,\mmz at padding@bottom,\mmz at padding@right,\mmz at padding@top
+}
+\def\mmzExternalizeBox#1#2{%
+  \begingroup
+  \def\width{\wd#1 }%
+  \def\height{\ht#1 }%
+  \def\depth{\dp#1 }%
+  \xdef\mmz at global@temp{%
+    \noexpand\mmzIncludeExtern
+      {\the\mmz at seq}%
+      \ifhbox#1\noexpand\hbox\else\noexpand\vbox\fi
+      {\the\wd#1}%
+      {\the\ht#1}%
+      {\the\dp#1}%
+      {\the\dimexpr\mmz at padding@left}%
+      {\the\dimexpr\mmz at padding@bottom}%
+      {\the\dimexpr\mmz at padding@right}%
+      {\the\dimexpr\mmz at padding@top}%
+  }%
+  \global\setbox\mmz at tbe@box\vbox{\copy#1\unvbox\mmz at tbe@box}%
+  \xtoksapp\mmz at ccmemo@resources{%
+    \noexpand\mmz at ccmemo@append at resource{\the\mmz at seq}%
+  }%
+  \global\advance\mmz at seq1
+  \endgroup
+  #2\expandafter{\mmz at global@temp}%
+}
+\newtoks\mmz at ccmemo@resources
+\newbox\mmz at tbe@box
+\def\mmz at shipout@externs{%
+  \global\mmz at seq 0
+  \setbox\mmz at box\vbox{%
+    \def\width{\wd\mmz at box}%
+    \def\height{\ht\mmz at box}%
+    \def\depth{\dp\mmz at box}%
+    \vskip1pt
+    \ifmmzkeepexterns\expandafter\unvcopy\else\expandafter\unvbox\fi\mmz at tbe@box
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox\mmz at box\lastbox
+      \mmz at shipout@extern
+    }%
+  }%
+}
+\def\mmz at shipout@extern{%
+  \edef\expectedwidth{\the\dimexpr
+    (\mmz at padding@left) + \wd\mmz at box + (\mmz at padding@right)}%
+  \edef\expectedheight{\the\dimexpr
+    (\mmz at padding@top) + \ht\mmz at box + \dp\mmz at box + (\mmz at padding@bottom)}%
+  \begingroup
+  \ifnum\mag=1000
+  \else
+    \mmz at shipout@mag
+  \fi
+  \pdfpagewidth\dimexpr
+    (\mmz at padding@left) + \wd\mmz at box + (\mmz at padding@right)\relax
+  \pdfpageheight\dimexpr
+    (\mmz at padding@top) + \ht\mmz at box + \dp\mmz at box+ (\mmz at padding@bottom)\relax
+  \hoffset\dimexpr\mmz at padding@left - \pdfhorigin\relax
+  \voffset\dimexpr\mmz at padding@top - \pdfvorigin\relax
+  \let\protect\noexpand
+  \pdf at primitive\shipout\box\mmz at box
+  \endgroup
+  \global\advance\mmzExternPages1
+  \edef\externbasepath{\mmz at extern@basepath}%
+  \edef\pagenumber{\the\numexpr\mmzRegularPages
+    +\mmzExternPages+\mmzExtraPages}%
+  \mmzset{record/new extern/.expanded=\mmz at extern@path}%
+  \global\advance\mmz at seq1
+}
+\def\mmz at shipout@mag{%
+  \setbox\mmz at box\hbox{%
+    \pdfliteral{q \mmz at inverse@mag\space 0 0 \mmz at inverse@mag\space 0 0 cm}%
+    \copy\mmz at box\relax
+    \pdfliteral{Q}%
+  }%
+  \dimen0=\dimexpr\mmz at padding@left\relax
+  \edef\mmz at padding@left{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@bottom\relax
+  \edef\mmz at padding@bottom{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@right\relax
+  \edef\mmz at padding@right{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@top\relax
+  \edef\mmz at padding@top{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \wd\mmz at box=\mmz at inverse@mag\wd\mmz at box\relax
+  \ht\mmz at box=\mmz at inverse@mag\ht\mmz at box\relax
+  \dp\mmz at box=\mmz at inverse@mag\dp\mmz at box\relax
+}
+{\catcode`\p=12\catcode`\t=12\gdef\mmz at Pgf@geT#1pt{#1}}
+\mmzset{begindocument/.append code={%
+    \edef\mmz at inverse@mag{\expandafter\mmz at Pgf@geT\the\dimexpr 1000pt/\mag}%
+  }}
+\let\mmzRegularPages\ReadonlyShipoutCounter
+\newcount\mmzExternPages
+\mmzset{
+  enddocument/afterlastpage/.append code={%
+    \ifnum\mmzExternPages>0
+      \PackageWarning{memoize}{The compilation produced \the\mmzExternPages\space
+        new extern\ifnum\mmzExternPages>1 s\fi.}%
+    \fi
+  },
+}
+\newcount\mmzExtraPages
+\def\mmz at include@extern#1#2#3#4#5#6#7#8#9{%
+  \mmz at seq=#1\relax
+  \setbox\mmz at box=#2{%
+    \setbox0=\hbox{%
+      \lower\dimexpr #5+#7\relax\hbox{%
+        \hskip -#6\relax
+        \setbox0=\hbox{%
+          \mmz at insertpdfpage{\mmz at extern@path}{1}%
+        }%
+        \unhbox0
+      }%
+    }%
+    \wd0 \dimexpr\wd0-#8\relax
+    \ht0 \dimexpr\ht0-#9\relax
+    \dp0 #5\relax
+    \box0
+  }%
+  \mmz at tempfalse
+  \mmz at if@roughly at equal{\mmz at tolerance}{#3}{\wd\mmz at box}{%
+    \mmz at if@roughly at equal{\mmz at tolerance}{#4}{\ht\mmz at box}{%
+      \mmz at temptrue
+    }{}}{}%
+  \ifmmz at temp
+  \else
+    \mmz at use@memo at warning{\mmz at extern@path}{#3}{#4}{#5}%
+  \fi
+  \wd\mmz at box=#3\relax
+  \ht\mmz at box=#4\relax
+  \box\mmz at box
+  \pgfkeysalso{/mmz/record/used extern={\mmz at extern@path}}%
+}
+\def\mmz at use@memo at warning#1#2#3#4{%
+  \PackageWarning{memoize}{Unexpected size of extern "#1";
+    expected #2\space x \the\dimexpr #3+#4\relax,
+    got \the\wd\mmz at box\space x \the\dimexpr\the\ht\mmz at box+\the\dp\mmz at box\relax}%
+}
+\ifdef\luatexversion{%
+  \def\mmz at insertpdfpage#1#2{% #1 = filename, #2 = page number
+    \saveimageresource page #2 mediabox {#1}%
+    \useimageresource\lastsavedimageresourceindex
+  }%
+}{%
+  \ifdef\XeTeXversion{%
+    \def\mmz at insertpdfpage#1#2{%
+      \XeTeXpdffile #1 page #2 media
+    }%
+  }{% pdfLaTeX
+    \def\mmz at insertpdfpage#1#2{%
+      \pdfximage page #2 mediabox {#1}%
+      \pdfrefximage\pdflastximage
+    }%
+  }%
+}
+\def\mmz at include@extern at from@tbe at box#1#2#3#4#5#6#7#8#9{%
+  \setbox0\vbox{%
+    \@tempcnta#1\relax
+    \vskip1pt
+    \unvcopy\mmz at tbe@box
+    \@whilenum\@tempcnta>0\do{%
+      \setbox0\lastbox
+      \advance\@tempcnta-1\relax
+    }%
+    \global\setbox1\lastbox
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox0\lastbox
+    }%
+    \box\mmz at box
+  }%
+  \box1
+}
+\def\mmzvalueof#1{\pgfkeysvalueof{/mmz/#1}}
+\mmzset{
+  extract/.estore in=\mmz at extraction@method,
+  extract/.value required,
+  begindocument/.append style={extract/.code=\mmz at preamble@only at warning},
+  extract/perl/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{perl extraction command}\space
+      \mmzvalueof{perl extraction options}%
+    }%
+    \mmz at check@extraction at log{perl}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{perl extraction command}\space --mkdir "##1"}%
+  },
+  perl extraction command/.initial=memoize-extract.pl,
+  perl extraction options/.initial={%
+    -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+    "\string\PackageWarning{memoize (perl-based extraction)}{\string\warningtext}"
+    "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+  },
+  extract=perl,
+  extract/python/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{python extraction command}\space
+      \mmzvalueof{python extraction options}%
+    }%
+    \mmz at check@extraction at log{python}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{python extraction command}\space --mkdir "##1"}%
+  },
+  python extraction command/.initial=memoize-extract.py,
+  python extraction options/.initial={%
+  -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+  "\string\PackageWarning{memoize (python-based extraction)}{\string\warningtext}"
+  "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+  },
+}
+\def\mmz at preamble@only at warning{%
+  \PackageWarning{memoize}{%
+    Ignoring the invocation of "\pgfkeyscurrentkey".
+    This key may only be executed in the preamble}%
+}
+\def\mmz at clear@extraction at log{%
+  \begingroup
+  \immediate\openout0{\mmzUnquote\jobname.mmz.log"}%
+  \immediate\closeout0
+  \endgroup
+}
+\def\mmz at check@extraction at log#1{%
+  \begingroup \def\extractionmethod{#1}%
+  \mmz at tempfalse \let\mmz at orig@endinput\endinput
+  \def\endinput{\mmz at temptrue\mmz at orig@endinput}%
+  \@input{\jobname.mmz.log}%
+  \ifmmz at temp \else \mmz at extraction@error \fi \endgroup }
+\def\mmz at extraction@error{%
+  \PackageWarning{memoize}{Extraction of externs from document "\mmzUnquote\jobname.pdf"
+    using method "\extractionmethod" was unsuccessful. Have you set the
+    shell escape mode as suggested in chapter 1 of the manual?}{}}
+\mmzset{
+  record/.style={%
+    record/begin/.append style={
+      /mmz/record/#1/begin/.try,
+      /mmz/record/#1/prefix/.try/.expanded=\mmz at prefix@path,
+    },
+    record/prefix/.append style={/mmz/record/#1/prefix/.try={##1}},
+    record/new extern/.append style={/mmz/record/#1/new extern/.try={##1}},
+    record/used extern/.append style={/mmz/record/#1/used extern/.try={##1}},
+    record/new cmemo/.append style={/mmz/record/#1/new cmemo/.try={##1}},
+    record/new ccmemo/.append style={/mmz/record/#1/new ccmemo/.try={##1}},
+    record/used cmemo/.append style={/mmz/record/#1/used cmemo/.try={##1}},
+    record/used ccmemo/.append style={/mmz/record/#1/used ccmemo/.try={##1}},
+    record/end/.append style={/mmz/record/#1/end/.try},
+  },
+}
+\mmzset{
+  no record/.style={%
+    record/begin/.style={record/begin/.style={}},
+    record/prefix/.code={\aftergroup\mmz at record@prefix},
+    record/new extern/.code={},
+    record/used extern/.code={},
+    record/new cmemo/.code={},
+    record/new ccmemo/.code={},
+    record/used cmemo/.code={},
+    record/used ccmemo/.code={},
+    record/end/.style={record/end/.code={}},
+  }
+}
+\def\mmz at record@prefix{%
+  \mmzset{/mmz/record/prefix/.expanded=\mmz at prefix@path}%
+}
+\mmzset{
+  no record,
+  record=mmz,
+  begindocument/.append style={record/begin},
+  enddocument/afterlastpage/.append style={record/end},
+}
+\mmzset{
+  record/mmz/begin/.code={%
+    \newwrite\mmz at mmzout
+    \immediate\openout\mmz at mmzout{\jobname.mmz}%
+  },
+  record/mmz/prefix/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzPrefix{#1}}%
+  },
+  record/mmz/new extern/.code={%
+    \immediate\write\mmz at mmzout{%
+      \noexpand\mmzNewExtern{#1}{\pagenumber}{\expectedwidth}{\expectedheight}%
+    }%
+  },
+  record/mmz/new cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCMemo{#1}}%
+  },
+  record/mmz/new ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCCMemo{#1}}%
+  },
+  record/mmz/used extern/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedExtern{#1}}%
+  },
+  record/mmz/used cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCMemo{#1}}%
+  },
+  record/mmz/used ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCCMemo{#1}}%
+  },
+  record/mmz/end/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\endinput}%
+    \immediate\closeout\mmz at mmzout
+  },
+  sh/.store in=\mmz at shname,
+  sh=memoize-extract.\jobname.sh,
+  bat/.store in=\mmz at batname,
+  bat=memoize-extract.\jobname.bat,
+  record/sh/begin/.code={%
+    \newwrite\mmz at shout
+    \immediate\openout\mmz at shout{\mmz at shname}%
+  },
+  record/sh/new extern/.code={%
+    \begingroup
+    \immediate\write\mmz at shout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/sh/end/.code={%
+    \immediate\closeout\mmz at shout
+  },
+  record/bat/begin/.code={%
+    \newwrite\mmz at batout
+    \immediate\openout\mmz at batout{\mmz at batname}%
+  },
+  record/bat/new extern/.code={%
+    \begingroup
+    \immediate\write\mmz at batout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/bat/end/.code={%
+    \immediate\closeout\mmz at batout
+  },
+  makefile/.store in=\mmz at makefilename,
+  makefile=memoize-extract.\jobname.makefile,
+}
+\begingroup
+\catcode`\^^I=12
+\gdef\mmz at makefile@recipe at prefix{^^I}%
+\endgroup
+\mmzset{
+  record/makefile/begin/.code={%
+    \newwrite\mmz at makefileout
+    \newtoks\mmz at makefile@externs
+    \immediate\openout\mmz at makefileout{\mmz at makefilename}%
+    \immediate\write\mmz at makefileout{.DEFAULT_GOAL = externs}%
+    \immediate\write\mmz at makefileout{.PHONY: externs}%
+  },
+  record/makefile/new extern/.code={%
+    \immediate\write\mmz at makefileout{#1:}%
+    \begingroup
+    \immediate\write\mmz at makefileout{%
+      \mmz at makefile@recipe at prefix\mmz at tex@extraction at systemcall}%
+    \endgroup
+    \xtoksapp\mmz at makefile@externs{#1\space}%
+  },
+  record/makefile/end/.code={%
+    \immediate\write\mmz at makefileout{externs: \the\mmz at makefile@externs}%
+    \immediate\closeout\mmz at makefileout
+  },
+}
+\mmzset{
+  extract/tex/.code={%
+    \begingroup
+    \@input{\jobname.mmz}%
+    \endgroup
+  },
+}
+\def\mmzUsedCMemo#1{}
+\def\mmzUsedCCMemo#1{}
+\def\mmzUsedExtern#1{}
+\def\mmzNewCMemo#1{}
+\def\mmzNewCCMemo#1{}
+\def\mmzPrefix#1{}
+\def\mmzNewExtern#1{%
+  \mmz at new@extern at i#1\mmz at temp
+}
+\def\mmz at new@extern at i#1.pdf\mmz at temp#2#3#4{%
+  \begingroup
+  \def\externbasepath{#1}%
+  \def\pagenumber{#2}%
+  \def\expectedwidth{#3}%
+  \def\expectedheight{#4}%
+  \mmz at clear@extraction at log
+  \pdf at system{\mmz at tex@extraction at systemcall}%
+  \let\mmz at extraction@error\mmz at pageextraction@error
+  \mmz at check@extraction at log{tex}%
+  \endgroup
+}
+\def\mmz at pageextraction@error{%
+  \PackageError{memoize}{Extraction of extern page \pagenumber\space from
+    document "\mmzUnquote\jobname.pdf" using method "\extractionmethod" was unsuccessful.
+    Have you set the shell escape mode as suggested in chapter 1 of the
+    manual?}{If "\mmzvalueof{tex extraction command}" was executed,
+    shell escape mode is not the problem, and inspecting "\externbasepath.log"
+    might give you a clue what's wrong}}
+\def\mmz at tex@extraction at systemcall{%
+  \mmzvalueof{tex extraction command}\space
+  \mmzvalueof{tex extraction options}\space
+  "\mmzvalueof{tex extraction script}"%
+}
+\mmzset{
+  tex extraction command/.initial=pdftex,
+  tex extraction options/.initial={%
+    -halt-on-error
+    -interaction=batchmode
+    -jobname "\externbasepath"
+    \ifdefempty\mmzOutputDirectory{}{-output-directory "\mmzOutputDirectory"}
+  },
+  tex extraction script/.initial={%
+    \def\noexpand\fromdocument{"\mmzOutputDirectory"\jobname.pdf}%
+    \def\noexpand\pagenumber{\pagenumber}%
+    \def\noexpand\expectedwidth{\expectedwidth}%
+    \def\noexpand\expectedheight{\expectedheight}%
+    \def\noexpand\logfile{\jobname.mmz.log}%
+    \unexpanded{%
+      \def\warningtemplate{%
+        \noexpand\PackageWarning{memoize}{\warningtext}%
+      }}%
+    \ifdef\XeTeXversion{}{%
+      \def\noexpand\mmzpdfmajorversion{\the\pdfmajorversion}%
+      \def\noexpand\mmzpdfminorversion{\the\pdfminorversion}%
+    }%
+    \noexpand\input memoize-extract-one
+  },
+}
+\def\mmz at tolerance{0.01pt}
+\def\mmz at if@roughly at equal#1#2#3{%
+  \dimen0=\dimexpr#2-#3\relax
+  \ifdim\dimen0<0pt
+    \dimen0=-\dimen0\relax
+  \fi
+  \ifdim\dimen0>#1\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi
+}%
+\mmzset{
+  .install advice={setup key=auto, activation=deferred},
+  begindocument/before/.append style={activation=immediate},
+}
+\newif\ifmmz at manual
+\mmzset{
+  manual/.is if=mmz at manual,
+  begindocument/end/.append code={%
+    \ifmmz at manual
+    \else
+      \pgfkeysalso{activate deferred,activate deferred/.code={}}%
+    \fi
+  },
+  auto/.cd,
+  run if memoization is possible/.style={
+    run conditions=\mmz at auto@rc at if@memoization at possible
+  },
+  run if memoizing/.style={run conditions=\mmz at auto@rc at if@memoizing},
+  apply options/.style={
+    bailout handler=\mmz at auto@bailout,
+    outer handler=\mmz at auto@outer,
+  },
+  memoize/.style={
+    run if memoization is possible,
+    apply options,
+    inner handler=\mmz at auto@memoize
+  },
+  noop/.style={run if memoization is possible, noop \AdviceType},
+  noop command/.style={apply options, inner handler=\mmz at auto@noop},
+  noop environment/.style={
+    outer handler=\mmz at auto@noop at env, bailout handler=\mmz at auto@bailout},
+  nomemoize/.style={noop, options=disable},
+  replicate/.style={run if memoizing, inner handler=\mmz at auto@replicate},
+}
+\mmzset{
+  auto/abort/.style={run conditions=\mmzAbort},
+}
+\mmzset{
+  auto/unmemoizable/.style={run conditions=\mmzUnmemoizable},
+}
+\ifdef\luatexversion{%
+  \mmzset{auto=\savepos{abort}}
+}{%
+  \mmzset{
+    auto=\pdfsavepos{abort},
+    auto=\errmessage{abort},
+  }
+}
+\def\mmz at auto@rc at if@memoization at possible{%
+  \ifmemoize
+    \ifinmemoize
+    \else
+      \AdviceRuntrue
+    \fi
+  \fi
+}
+\def\mmz at auto@rc at if@memoizing{%
+  \ifmemoizing\AdviceRuntrue\fi
+}
+\def\mmznext#1{\gdef\mmz at next{#1}\ignorespaces}
+\mmznext{}%
+\def\mmz at auto@outer{%
+  \begingroup
+  \mmzAutoInit
+  \AdviceCollector
+}
+\def\mmz at auto@bailout{%
+  \mmznext{}%
+}
+\def\mmzAutoInit{%
+  \ifdefempty\AdviceOptions{}{\expandafter\mmzset\expandafter{\AdviceOptions}}%
+  \ifdefempty\mmz at next{}{\expandafter\mmzset\expandafter{\mmz at next}\mmznext{}}%
+  \eappto\AdviceRawCollectorOptions{\expandonce\mmzRawCollectorOptions}%
+}
+\long\def\mmz at auto@memoize#1{%
+  \expanded{%
+    \noexpand\Memoize
+      {\expandonce\AdviceReplaced\unexpanded{#1}}%
+      {\expandonce\AdviceOriginal\unexpanded{#1}}%
+    \ifmmz at ignorespaces\ignorespaces\fi
+  }%
+}
+\long\def\mmz at auto@noop#1{%
+  \expandafter\mmz at maybe@scantokens\expandafter{\AdviceOriginal#1}%
+  \expandafter\endgroup
+  \ifmmz at ignorespaces\ignorespaces\fi
+}
+\def\mmz at auto@noop at env{%
+  \AddToHookNext{env/\AdviceName/begin}{%
+    \mmzAutoInit
+    \ifmmz at ignorespaces\ignorespacesafterend\fi
+  }%
+  \AdviceOriginal
+}
+\def\mmz at auto@replicate#1{%
+  \begingroup
+  \let\mmz at auto@replicate at expansion\unexpanded
+  \expandafter\pgfqkeys\expanded{{/mmz/auto/replicate}{\AdviceOptions}}%
+  \let\protect\noexpand
+  \expanded{%
+    \endgroup
+    \noexpand\gtoksapp\noexpand\mmzCCMemo{%
+      \expandonce\AdviceReplaced\mmz at auto@replicate at expansion{#1}}%
+    \expandonce\AdviceOriginal\unexpanded{#1}%
+  }%
+}
+\pgfqkeys{/mmz/auto/replicate}{
+  expanded/.code={\let\mmz at auto@replicate at expansion\@firstofone},
+}
+\mmzset{
+  auto/.cd,
+  ref/.style={outer handler=\mmz at auto@ref\mmzNoRef, run if memoizing},
+  force ref/.style={outer handler=\mmz at auto@ref\mmzForceNoRef, run if memoizing},
+}
+\mmzset{
+  auto=\ref{ref},
+  auto=\pageref{ref},
+  auto=\label{run if memoizing, outer handler=\mmz at auto@label},
+  auto=\index{replicate, args=m, expanded},
+}
+\def\mmz at auto@ref#1#2#{\mmz at auto@ref at i#1{#2}}
+\def\mmz at auto@ref at i#1#2#3{%
+  #1{#3}%
+  \AdviceOriginal#2{#3}%
+}
+\def\mmzForceNoRef#1{%
+  \ifmemoizing
+    \expandafter\gtoksapp\expandafter\mmzContextExtra
+  \else
+    \expandafter\toksapp\expandafter\mmzContext
+  \fi
+  {r@#1={\csname r@#1\endcsname}}%
+  \ignorespaces
+}
+\def\mmzNoRef#1{%
+  \ifcsundef{r@#1}{\mmzAbort}{\mmzForceNoRef{#1}}%
+  \ignorespaces
+}
+\mmzset{
+  auto/.cd,
+  refrange/.style={outer handler=\mmz at auto@refrange\mmzNoRef,
+    bailout handler=\relax, run if memoizing},
+  force refrange/.style={outer handler=\mmz at auto@refrange\mmzForceNoRef,
+    bailout handler=\relax, run if memoizing},
+}
+\def\mmz at auto@refrange#1#2#{\mmz at auto@refrange at i#1{#2}}
+\def\mmz at auto@refrange at i#1#2#3#4{%
+  #1{#3}%
+  #1{#4}%
+  \AdviceOriginal#2{#3}{#4}%
+}
+\mmzset{
+  auto/.cd,
+  multiref/.style={outer handler=\mmz at auto@multiref\mmzNoRef,
+    bailout handler=\relax, run if memoizing},
+  force multiref/.style={outer handler=\mmz at auto@multiref\mmzForceNoRef,
+    bailout handler=\relax, run if memoizing},
+}
+\def\mmz at auto@multiref#1#2#{\mmz at auto@multiref at i#1{#2}}
+\def\mmz at auto@multiref at i#1#2#3{%
+  \forcsvlist{#1}{#3}%
+  \AdviceOriginal#2{#3}%
+}
+\def\mmz at auto@label#1{%
+  \xtoksapp\mmzCCMemo{%
+    \noexpand\mmzLabel{#1}{\expandonce\@currentlabel}%
+  }%
+  \AdviceOriginal{#1}%
+}
+\def\mmzLabel#1#2{%
+  \begingroup
+  \def\@currentlabel{#2}%
+  \label{#1}%
+  \endgroup
+}
+\mmzset{
+  begindocument/before/.append code={%
+    \@ifpackageloaded{tikz}{%
+      \input advice-tikz.code.tex
+    }{}%
+    \mmzset{%
+      auto=\tikz{memoize, collector=\AdviceCollectTikZArguments},
+      auto={tikzpicture}{memoize},
+      auto=\pgfsys at getposition{
+        run if memoizing, outer handler=\mmz at pgfsys@getposition},
+    }%
+    \def\mmz at pgfsys@getposition##1{%
+      \expandafter\ifx\csname pgf at sys@pdf at mark@pos@##1\endcsname\relax
+      \else
+        \mmzAbort
+      \fi
+      \AdviceOriginal{##1}%
+    }%
+  },
+}
+\mmzset{
+  begindocument/before/.append code={%
+    \@ifpackageloaded{forest}{%
+      \mmzset{
+        auto={forest}{memoize},
+        auto=\Forest{memoize},
+      }%
+    }{}%
+  },
+}
+\AddToHook{begindocument/before}{\@ifclassloaded{beamer}{%
+  \mmzset{per overlay/.style={
+    /mmz/context={%
+      overlay=\csname beamer at overlaynumber\endcsname,
+      pauses=\ifmemoizing
+               \mmzBeamerPauses
+             \else
+               \expandafter\the\csname c at beamerpauses\endcsname
+             \fi
+    },
+    /mmz/at begin memoization={%
+      \xdef\mmzBeamerPauses{\the\c at beamerpauses}%
+      \xtoksapp\mmzCMemo{%
+        \noexpand\mmzSetBeamerOverlays{\mmzBeamerPauses}{\beamer at overlaynumber}}%
+      \gtoksapp\mmzCCMemo{%
+        \only<\mmzBeamerOverlays>{}}%
+    },
+    /mmz/at end memoization={%
+      \xtoksapp\mmzCCMemo{%
+        \noexpand\setcounter{beamerpauses}{\the\c at beamerpauses}}%
+    },
+    /mmz/per overlay/.code={},
+  }}
+  \def\mmzSetBeamerOverlays#1#2{%
+    \ifnum\c at beamerpauses=#1\relax
+      \gdef\mmzBeamerOverlays{#2}%
+      \ifnum\beamer at overlaynumber<#2\relax \mmz at temptrue \else \mmz at tempfalse \fi
+    \else
+      \mmz at temptrue
+    \fi
+    \ifmmz at temp
+      \appto\mmzAtBeginMemoization{%
+        \gtoksapp\mmzCMemo{\mmzSetBeamerOverlays{#1}{#2}}}%
+    \fi
+  }%
+}{}}
+\AddToHook{begindocument/before}{\mmzset{begindocument/before}}
+\AddToHook{begindocument}{\mmzset{begindocument}}
+\AddToHook{begindocument/end}{\mmzset{begindocument/end}}
+\AddToHook{enddocument/afterlastpage}{\mmzset{enddocument/afterlastpage}}
+\InputIfFileExists{memoize.cfg}{}{}
+\mmzset{
+  extract/no/.code={},
+  output-directory/.store in=\mmzOutputDirectory,
+}
+\ProcessPgfPackageOptions{/mmz}
+\ifdefined\mmzOutputDirectory
+\else
+  \def\mmzOutputDirectory{}%
+\fi
+\mmzset{output directory/.code={\PackageError{memoize}{Key "output-directory"
+      may only be used as a package option}{}}}
+\mmzset{
+  extract/\mmz at extraction@method,
+  extract/.code={\PackageError{memoize}{Key "extract" is only allowed as a
+      package option.}{If you really want to extract in the preamble, execute
+      "extract/<method>".}},
+}
+\ifnum\pdf at draftmode=1
+  \PackageWarning{memoize}{No memoization will be performed in the draft mode}%
+\fi
+\endinput
+%%
+%% End of file `memoize.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/memoize/memoize.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/memoize/nomemoize.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/memoize/nomemoize.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/memoize/nomemoize.sty	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,78 @@
+%%
+%% This is file `nomemoize.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `nommz,latex')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+\ProvidesPackage{nomemoize}[2023/10/10 v1.0.0 A no-op stub for Memoize]
+\RequirePackage{pgfopts}  % pgfkeys-based package options
+\pgfkeys{/memoize/package options/.unknown/.code={}}
+\ProcessPgfPackageOptions{/memoize/package options}
+\@ifpackageloaded{memoize}
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoize" is already
+    loaded; memoization will remain in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+  \endinput }{}%
+\@ifpackageloaded{memoizable}%
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  (No)Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded
+    "memoizable"; please move
+    "\string\usepackage{nomemoize}"
+    before the
+    "\string\usepackage"
+    of that package.}%
+  \endinput
+}{}%
+\def\mmzset#1{\ignorespaces}
+\def\nommzkeys{\pgfqkeys{/mmz}}
+\pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}}
+\newif\ifmemoize
+\protected\def\nommz#1#{%
+  \afterassignment\nommz at i
+  \let\mmz at temp
+}
+\def\nommz at i{%
+  \bgroup
+  \memoizefalse
+}
+\let\mmz\nommz
+\newenvironment{nomemoize}[1][]{%
+  \memoizefalse
+  \ignorespaces
+}{%
+  \unskip
+}
+\let\memoize\nomemoize
+\let\endmemoize\endnomemoize
+\newif\ifmemoizing
+\newif\ifinmemoize
+\newcommand\IfMemoizing[2][]{\@secondoftwo}
+\def\mmznext#1{\ignorespaces}
+\InputIfFileExists{memoize.cfg}{}{}
+\endinput
+%%
+%% End of file `nomemoize.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/memoize/nomemoize.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/plain/memoize/memoizable.tex
===================================================================
--- trunk/Master/texmf-dist/tex/plain/memoize/memoizable.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/plain/memoize/memoizable.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,50 @@
+%%
+%% This is file `memoizable.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `mmzable,plain')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+% Package memoizable 2023/10/10 v1.0.0
+\input miniltx
+\def\ifmmz at loadstatus#1{%
+  \ifnum#1=0\csname mmz at loadstatus\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+\ifmmz at loadstatus{1}%
+{\endinput}{}
+\ifmmz at loadstatus{3}%
+{\endinput}{}%
+\ifmmz at loadstatus{2}{\endinput}{}%
+\def\mmz at loadstatus{2}%
+\def\mmzset#1{\ignorespaces}
+\def\nommzkeys{\pgfqkeys{/mmz}}
+\pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}}
+\newif\ifmemoize
+\newcommand\IfMemoizing[2][]{\@secondoftwo}
+\resetatcatcode
+\endinput
+%%
+%% End of file `memoizable.tex'.


Property changes on: trunk/Master/texmf-dist/tex/plain/memoize/memoizable.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/plain/memoize/memoize-extract-one.tex
===================================================================
--- trunk/Master/texmf-dist/tex/plain/memoize/memoize-extract-one.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/plain/memoize/memoize-extract-one.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,126 @@
+%%
+%% This is file `memoize-extract-one.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `extract-one')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+\catcode`\@11\relax
+\def\@firstoftwo#1#2{#1}
+\def\@secondoftwo#1#2{#2}
+\ifdefined\XeTeXversion
+\else
+  \ifdefined\luatexversion
+    \def\pdfmajorversion{\pdfvariable majorversion}%
+    \def\pdfminorversion{\pdfvariable minorversion}%
+  \fi
+  \ifdefined\mmzpdfmajorversion
+    \pdfmajorversion\mmzpdfmajorversion\relax
+  \fi
+  \ifdefined\mmzpdfminorversion
+    \pdfminorversion\mmzpdfminorversion\relax
+  \fi
+\fi
+\newwrite\extractionlog
+\ifdefined\logfile
+  \immediate\openout\extractionlog{\logfile}%
+  \def\doublewarning#1{%
+    \message{#1}%
+    \def\warningtext{#1}%
+    \immediate\write\extractionlog{%
+      \ifdefined\warningtemplate\warningtemplate\else\warningtext\fi
+    }%
+  }%
+\else
+  \let\doublewarning\message
+\fi
+\newif\ifforce
+\ifdefined\force
+  \csname force\force\endcsname
+\fi
+\def\mmz at tolerance{0.01pt}
+\def\mmz at if@roughly at equal#1#2#3{%
+  \dimen0=\dimexpr#2-#3\relax
+  \ifdim\dimen0<0pt
+    \dimen0=-\dimen0\relax
+  \fi
+  \ifdim\dimen0>#1\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi
+}%
+\ifdefined\XeTeXversion
+  \setbox0=\hbox{\XeTeXpdffile \fromdocument\space page \pagenumber media}%
+\else
+  \ifdefined\luatexversion
+    \saveimageresource page \pagenumber mediabox {\fromdocument}%
+    \setbox0=\hbox{\useimageresource\lastsavedimageresourceindex}%
+  \else
+    \pdfximage page \pagenumber mediabox {\fromdocument}%
+    \setbox0=\hbox{\pdfrefximage\pdflastximage}%
+  \fi
+\fi
+\newif\ifbaddimensions
+\ifdefined\expectedwidth
+  \ifdefined\expectedheight
+    \mmz at if@roughly at equal{\mmz at tolerance}{\wd0}{\expectedwidth}{%
+      \mmz at if@roughly at equal{\mmz at tolerance}{\ht0}{\expectedheight}%
+        {}%
+        {\baddimensionstrue}%
+    }{\baddimensionstrue}%
+  \fi
+\fi
+\ifdefined\luatexversion
+  \let\pdfpagewidth\pagewidth
+  \let\pdfpageheight\pageheight
+  \def\pdfhorigin{\pdfvariable horigin}%
+  \def\pdfvorigin{\pdfvariable vorigin}%
+\fi
+\def\do at shipout{%
+  \pdfpagewidth=\wd0
+  \pdfpageheight=\ht0
+  \ifdefined\XeTeXversion
+    \hoffset -1 true in
+    \voffset -1 true in
+  \else
+    \pdfhorigin=0pt
+    \pdfvorigin=0pt
+  \fi
+  \shipout\box0
+}
+\ifbaddimensions
+  \doublewarning{I refuse to extract page \pagenumber\space from
+    "\fromdocument", because its size (\the\wd0 \space x \the\ht0) is not
+    what I expected (\expectedwidth\space x \expectedheight)}%
+  \ifforce\do at shipout\fi
+\else
+  \do at shipout
+\fi
+\ifdefined\logfile
+  \immediate\write\extractionlog{\noexpand\endinput}%
+  \immediate\closeout\extractionlog
+\fi
+\bye
+\endinput
+%%
+%% End of file `memoize-extract-one.tex'.


Property changes on: trunk/Master/texmf-dist/tex/plain/memoize/memoize-extract-one.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/plain/memoize/memoize.tex
===================================================================
--- trunk/Master/texmf-dist/tex/plain/memoize/memoize.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/plain/memoize/memoize.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,1425 @@
+%%
+%% This is file `memoize.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `mmz,plain')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+% Package memoize 2023/10/10 v1.0.0
+\input miniltx
+\def\PackageWarning#1#2{{%
+    \newlinechar`\^^J\def\MessageBreak{^^J\space\space#1: }%
+    \message{#1: #2}}}
+\def\newtoks{\alloc at 5\toks\toksdef\@cclvi}
+\def\newwrite{\alloc at 7\write\chardef\sixt@@n}
+\input etoolbox-generic
+\ifdefined\luatexversion
+  \directlua{memoize = {}}
+\fi
+\input pdftexcmds.sty
+\ifdef\pdftexversion{%
+}{%
+  \def\pdfhorigin{1true in}%
+  \def\pdfvorigin{1true in}%
+  \ifdef\XeTeXversion{%
+    \let\quitvmode\leavevmode
+  }{%
+    \ifdef\luatexversion{%
+      \let\pdfpagewidth\pagewidth
+      \let\pdfpageheight\pageheight
+      \def\pdfmajorversion{\pdfvariable majorversion}%
+      \def\pdfminorversion{\pdfvariable minorversion}%
+    }{%
+      \PackageError{memoize}{Support for this TeX engine is not implemented}{}%
+    }%
+  }%
+}
+\def\mmz at regular@shipout{%
+  \global\advance\mmzRegularPages1\relax
+  \mmz at primitive@shipout
+}
+\edef\mmz at temp{\string\shipout}%
+\edef\mmz at tempa{\meaning\shipout}%
+\ifx\mmz at temp\mmz at tempa
+  \let\mmz at primitive@shipout\shipout
+  \let\shipout\mmz at regular@shipout
+\else
+  \PackageError{memoize}{Cannot grab \string\shipout, it is already redefined}{}%
+\fi
+\input advice
+\def\ifmmz at loadstatus#1{%
+  \ifnum#1=0\csname mmz at loadstatus\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+\ifmmz at loadstatus{3}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "nomemoize" is already
+    loaded. Memoization will NOT be in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+    \endinput
+}{}%
+\ifmmz at loadstatus{2}%
+{%
+  \PackageError{memoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded "memoizable";
+    please move
+    "\string\input memoize"
+    before the
+    "\string\input"
+    of that package.}%
+  \endinput
+}{}%
+\ifmmz at loadstatus{1}{\endinput}{}%
+\def\mmz at loadstatus{1}%
+\def\filetotoks#1#2{%
+  \immediate\openin0{#2}%
+  #1={}%
+  \loop
+  \unless\ifeof0
+    \read0 to \totoks at temp
+    \expandafter\toksapp\expandafter#1\expandafter{\totoks at temp}%
+  \repeat
+  \immediate\closein0
+}
+\newif\ifmmz at temp
+\newtoks\mmz at temptoks
+\newbox\mmz at box
+\newwrite\mmz at out
+\def\mmzset#1{\pgfqkeys{/mmz}{#1}\ignorespaces}
+\def\nommzkeys#1{}
+\newif\ifmemoize
+\mmzset{%
+  enable/.style={begindocument/.append code=\memoizetrue},
+  disable/.style={begindocument/.append code=\memoizefalse},
+  begindocument/.append style={
+    enable/.code=\memoizetrue,
+    disable/.code=\memoizefalse,
+  },
+  enable,
+}
+\def\mmz at mode@normal{0}
+\def\mmz at mode@readonly{1}
+\def\mmz at mode@recompile{2}
+\let\mmz at mode\mmz at mode@normal
+\mmzset{%
+  normal/.code={\let\mmz at mode\mmz at mode@normal},
+  readonly/.code={\let\mmz at mode\mmz at mode@readonly},
+  recompile/.code={\let\mmz at mode\mmz at mode@recompile},
+}
+\mmzset{%
+  path/.code={\pgfqkeys{/mmz/path}{#1}},
+  path/.cd,
+  relative/.is if=mmz at relativepath,
+  dir/.store in=\mmz at dir,
+  dir/.value required,
+  prefix/.store in=\mmz at prefix,
+  prefix/.value required,
+}
+\newif\ifmmz at relativepath
+\mmzset{%
+  begindocument/.append style={
+    path/.append code=\mmz at maybe@mkmemodir\mmz at record@prefix,
+  },
+  begindocument/.append code=\mmz at maybe@mkmemodir,
+}
+\def\mmz at dir@path{\ifmmz at relativepath.\fi/\mmz at dir}
+\def\mmz at prefix@path{\mmz at dir@path/\mmz at prefix}
+\mmzset{
+  mkdir/.is if=mmz at mkdir,
+  mkdir command/.code={\def\mmz at mkdir@command##1{#1}},
+  mkdir command={mkdir "#1"},
+}
+\newif\ifmmz at mkdir
+\def\mmz at maybe@mkmemodir{%
+  \ifmmz at mkdir
+    \pdf at system{\mmz at mkdir@command{\mmzOutputDirectory\mmz at dir@path}}%
+  \fi
+}
+\mmzset{%
+  memo dir/.style={
+    mkdir,
+    path={
+      relative,
+      dir={#1.memo.dir},
+      prefix={},
+    },
+  },
+  memo dir/.default=\mmzUnquote\jobname,
+  no memo dir/.style={
+    mkdir=false,
+    path={
+      relative,
+      dir={},
+      prefix={#1.},
+    },
+  },
+  no memo dir/.default=\mmzUnquote\jobname,
+  no memo dir,
+}
+\def\mmzUnquote#1{\expanded{\noexpand\mmz at unquote#1}\mmz at unquote@end}
+\def\mmz at unquote#1{%
+  \ifx\mmz at unquote@end#1%
+  \else
+    \ifx"#1%
+      \expandafter\expandafter\expandafter\mmz at unquote@quotes
+    \else
+      \expandafter\expandafter\expandafter\mmz at unquote@noquotes
+      \expandafter\expandafter\expandafter#1%
+    \fi
+  \fi
+}
+\def\mmz at unquote@quotes#1"\mmz at unquote@end{#1}
+\def\mmz at unquote@noquotes#1\mmz at unquote@end{#1}
+\newif\ifmmz at ignorespaces
+\mmzset{
+  ignore spaces/.is if=mmz at ignorespaces,
+}
+\newif\ifmmz at verbatim
+\def\mmzRawCollectorOptions{}
+\mmzset{
+  verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerbatim}%
+    \mmz at verbatimtrue
+  },
+  verb/.code={%
+    \def\mmzRawCollectorOptions{\collargsVerb}%
+    \mmz at verbatimtrue
+  },
+  no verbatim/.code={%
+    \def\mmzRawCollectorOptions{\collargsNoVerbatim}%
+    \mmz at verbatimfalse
+  },
+}
+\protected\def\mmz{\futurelet\mmz at temp\mmz at i}
+\def\mmz at i{%
+  \begingroup
+  \ifx\mmz at temp[%]
+    \def\mmz at verbatim@fix{}%
+    \expandafter\mmz at ii
+  \else
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+    \expandafter\mmz at iii
+  \fi
+}
+\def\mmz at ii[#1]{%
+  \mmzset{#1}%
+  \mmz at iii
+}
+\def\mmz at iii{%
+  \ifmmz at verbatim
+    \expandafter\mmz at do@verbatim
+  \else
+    \expandafter\mmz at do
+  \fi
+}
+\long\def\mmz at do#1{%
+  \Memoize{#1}{#1}%
+}%
+\def\mmz at do@verbatim#1{%
+  \expanded{%
+    \noexpand\CollectArgumentsRaw{%
+      \noexpand\collargsCaller{\noexpand\mmz}%
+      \expandonce\mmzRawCollectorOptions
+      \mmz at verbatim@fix
+    }%
+  }{+m}\mmz at do
+}
+\def\memoize{%
+  \begingroup
+  \futurelet\mmz at temp\mmz at env@i
+}
+\def\mmz at env@i{%
+  \ifx\mmz at temp[%]
+    \def\mmz at verbatim@fix{}%
+    \expandafter\mmz at env@ii
+  \else
+    \def\mmz at verbatim@fix{\noexpand\collargsFixFromNoVerbatim}%
+    \expandafter\mmz at env@iii
+  \fi
+}
+\def\mmz at env@ii[#1]{%
+  \mmzset{#1}%
+  \mmz at env@iii
+}
+\def\mmz at env@iii{%
+  \long\edef\mmz at do##1{%
+    \noexpand\Memoize{##1}{##1\unskip}%
+  }%
+  \expanded{%
+    \noexpand\CollectArgumentsRaw{%
+      \noexpand\collargsCaller{memoize}%
+      \expandonce\mmzRawCollectorOptions
+      \ifmmz at verbatim\mmz at verbatim@fix\fi
+    }%
+  }{&&{\collargsAppendPostwrap{}}!t{ }+b{memoize}}{\mmz at do}%
+}%
+\protected\def\nommz#1#{%
+  \afterassignment\nommz at i
+  \let\mmz at temp
+}
+\def\nommz at i{%
+  \bgroup
+  \memoizefalse
+}
+\def\nomemoize{%
+  \begingroup
+  \memoizefalse
+  \futurelet\mmz at temp\nommz at env@i
+}
+\def\nommz at env@i{%
+  \ifx\mmz at temp[%]
+    \expandafter\nommz at env@ii
+  \fi
+}
+\def\nommz at env@ii[#1]{%
+  \ignorespaces
+}
+\def\endnomemoize{%
+  \endgroup
+  \unskip
+}
+\newif\ifmemoizing
+\newif\ifinmemoize
+\def\mmz at maybe@scantokens{%
+  \ifmmz at verbatim
+    \expandafter\mmz at scantokens
+  \else
+    \expandafter\@firstofone
+  \fi
+}
+\long\def\mmz at scantokens#1{%
+  \expanded{%
+    \newlinechar=13
+    \unexpanded{\scantokens{#1\endinput}}%
+    \newlinechar=\the\newlinechar
+  }%
+}
+\newtoks\mmz at mdfive@source
+\newtoks\mmz at exec@source
+\let\Memoize\@secondoftwo
+\long\def\Memoize#1#2{%
+  \mmz at mdfive@source{#1}%
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  \mmz at exec@source
+  \expandafter\expandafter\expandafter\expandafter
+  \expandafter\expandafter\expandafter
+  {%
+    \mmz at maybe@scantokens{#2}%
+  }%
+  \mmz at trace@Memoize
+  \let\mmz at action\mmz at compile
+  \ifmemoizing
+  \else
+    \ifmemoize
+      \xdef\mmz at code@mdfivesum{\pdf at mdfivesum{\the\mmz at mdfive@source}}%
+      \mmz at trace@code at mdfive
+      \ifnum\mmz at mode=\mmz at mode@recompile\relax
+        \ifnum\pdf at draftmode=0
+          \let\mmz at action\mmz at memoize
+        \fi
+      \else
+        \mmz at process@cmemo
+        \ifmmzUnmemoizable
+          \mmz at trace@cmemo at unmemoizable
+        \else
+          \ifmmz at abort
+            \mmz at trace@process at cmemo@fail
+            \ifnum\mmz at mode=\mmz at mode@readonly\relax
+            \else
+              \ifnum\pdf at draftmode=0
+                \let\mmz at action\mmz at memoize
+              \fi
+            \fi
+          \else
+            \mmz at trace@process at cmemo@ok
+            \let\mmz at action\mmz at process@ccmemo
+          \fi
+        \fi
+      \fi
+    \fi
+  \fi
+  \mmz at action
+}
+\def\mmz at compile{%
+  \mmz at trace@compile
+  \expanded{%
+    \endgroup
+    \noexpand\inmemoizetrue
+    \the\mmz at exec@source
+    \ifinmemoize\noexpand\inmemoizetrue\else\noexpand\inmemoizefalse\fi
+  }%
+}
+\ifdefined\luatexversion
+  \directlua{%
+    luatexbase.add_to_callback(
+      "show_error_message",
+      function()
+        memoize.abort = true
+        texio.write_nl(status.lasterrorstring)
+      end,
+      "Abort memoization on error"
+    )
+  }%
+  \def\mmz at lua@atbeginmemoization{%
+    \directlua{memoize.abort = false}%
+  }%
+  \def\mmz at lua@atendmemoization{%
+    \directlua{%
+      if memoize.abort then
+        tex.print("\noexpand\\mmzAbort")
+      end
+    }%
+  }%
+\else
+  \let\mmz at lua@atbeginmemoization\relax
+  \let\mmz at lua@atendmemoization\relax
+\fi
+\def\mmz at memoize{%
+  \mmz at trace@memoize
+  \memoizingtrue
+  \inmemoizetrue
+  \edef\memoizinggrouplevel{\the\currentgrouplevel}%
+  \global\mmz at abortfalse
+  \global\mmzUnmemoizablefalse
+  \global\mmz at seq 0
+  \global\setbox\mmz at tbe@box\vbox{}%
+  \global\mmz at ccmemo@resources{}%
+  \global\mmzCMemo{}%
+  \global\mmzCCMemo{}%
+  \global\mmzContextExtra{}%
+  \gdef\mmzAtEndMemoizationExtra{}%
+  \gdef\mmzAfterMemoizationExtra{}%
+  \mmz at lua@atbeginmemoization
+  \mmzAtBeginMemoization
+  \mmzDriver{\the\mmz at exec@source}%
+  \mmzAtEndMemoization
+  \mmzAtEndMemoizationExtra
+  \mmz at lua@atendmemoization
+  \ifmmzUnmemoizable
+    \global\mmzContextExtra{}%
+    \gtoksapp\mmzCMemo{\global\mmzUnmemoizabletrue}%
+    \mmz at write@cmemo
+    \mmz at trace@endmemoize at unmemoizable
+    \PackageWarning{memoize}{Marking this code as unmemoizable}%
+  \else
+    \ifmmz at abort
+      \mmz at trace@endmemoize at aborted
+      \PackageWarning{memoize}{Memoization was aborted}%
+      \mmz at write@empty at cmemo
+    \else
+      \mmz at compute@context at mdfivesum
+      \mmz at write@cmemo
+      \mmz at write@ccmemo
+      \mmz at shipout@externs
+      \mmz at trace@endmemoize at ok
+    \fi
+  \fi
+  \expandafter\endgroup
+  \expandafter\let
+    \expandafter\mmzIncludeExtern\expandafter\mmz at include@extern at from@tbe at box
+  \mmzAfterMemoization
+  \mmzAfterMemoizationExtra
+}
+\def\memoizinggrouplevel{-1}%
+\def\mmzAbort{\global\mmz at aborttrue}
+\newif\ifmmz at abort
+\def\mmzUnmemoizable{\global\mmzUnmemoizabletrue}
+\newif\ifmmzUnmemoizable
+\def\mmzAtBeginMemoization{}
+\def\mmzAtEndMemoization{}
+\def\mmzAfterMemoization{}
+\mmzset{
+  at begin memoization/.code={%
+    \ifmemoizing
+      \expandafter\@firstofone
+    \else
+      \expandafter\appto\expandafter\mmzAtBeginMemoization
+    \fi
+    {#1}%
+  },
+  at end memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAtEndMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAtEndMemoization
+    \fi
+    {#1}%
+  },
+  after memoization/.code={%
+    \ifmemoizing
+      \expandafter\gappto\expandafter\mmzAfterMemoizationExtra
+    \else
+      \expandafter\appto\expandafter\mmzAfterMemoization
+    \fi
+    {#1}%
+  },
+}
+\mmzset{
+  driver/.store in=\mmzDriver,
+  driver=\mmzSingleExternDriver,
+}
+\newif\ifmmzkeepexterns
+\long\def\mmzSingleExternDriver#1{%
+  \xtoksapp\mmzCCMemo{\mmz at maybe@quitvmode}%
+  \setbox\mmz at box\mmz at capture{#1}%
+  \mmzExternalizeBox\mmz at box\mmz at temptoks
+  \xtoksapp\mmzCCMemo{\the\mmz at temptoks}%
+  \mmz at maybe@quitvmode\box\mmz at box
+}
+\mmzset{
+  capture/.is choice,
+  capture/hbox/.code={%
+    \let\mmz at capture\hbox
+    \def\mmz at maybe@quitvmode{\noexpand\quitvmode}%
+  },
+  capture/vbox/.code={%
+    \let\mmz at capture\vbox
+    \def\mmz at maybe@quitvmode{}%
+  },
+  capture=hbox,
+}
+\mmzset{
+  auto/integrated driver/.style={
+    after setup={\expandafter\newif\csname ifmmz at memoizing#1\endcsname},
+    driver/.expand once={%
+      \csname mmz at memoizing#1true\endcsname
+      \@firstofone
+    }%
+  },
+}
+\newcommand\IfMemoizing[2][\mmz at Ifmemoizing@nogrouplevel]{%>\fi
+\csname ifmmz at memoizing#2\endcsname%>\if
+  \ifnum\currentgrouplevel=\the\numexpr\memoizinggrouplevel+#1\relax\relax
+    \expandafter\expandafter\expandafter\@firstoftwo
+  \else
+    \expandafter\expandafter\expandafter\@secondoftwo
+  \fi
+\else
+  \expandafter\@secondoftwo
+\fi
+}
+\def\mmz at Ifmemoizing@nogrouplevel{0\relax\relax\fi\iftrue}
+\def\mmz at trace#1{\immediate\write16{[tracing memoize] #1}}
+\def\mmz at trace@context{\mmz at trace{\space\space
+    Context: "\expandonce{\mmz at context@key}" --> \mmz at context@mdfivesum}}
+\def\mmz at trace@Memoize at on{%
+  \mmz at trace{%
+    Entering \noexpand\Memoize (%
+    \ifmemoize enabled\else disabled\fi,
+    \ifnum\mmz at mode=\mmz at mode@recompile recompile\fi
+    \ifnum\mmz at mode=\mmz at mode@readonly readonly\fi
+    \ifnum\mmz at mode=\mmz at mode@normal normal\fi
+    \space mode) on line \the\inputlineno
+  }%
+  \mmz at trace{\space\space Code: \the\mmz at mdfive@source}%
+}
+\def\mmz at trace@code at mdfive@on{\mmz at trace{\space\space
+    Code md5sum: \mmz at code@mdfivesum}}
+\def\mmz at trace@compile at on{\mmz at trace{\space\space Compiling}}
+\def\mmz at trace@memoize at on{\mmz at trace{\space\space Memoizing}}
+\def\mmz at trace@endmemoize at ok@on{\mmz at trace{\space\space
+    Memoization completed}}%
+\def\mmz at trace@endmemoize at aborted@on{\mmz at trace{\space\space
+    Memoization was aborted}}
+\def\mmz at trace@endmemoize at unmemoizable@on{\mmz at trace{\space\space
+    Marking this code as unmemoizable}}
+\def\mmz at trace@process at cmemo@on{\mmz at trace{\space\space
+    Attempting to utilize c-memo \mmz at cmemo@path}}
+\def\mmz at trace@process at no@cmemo at on{\mmz at trace{\space\space
+    C-memo does not exist}}
+\def\mmz at trace@process at cmemo@ok at on{\mmz at trace{\space\space
+    C-memo was processed successfully}\mmz at trace@context}
+\def\mmz at trace@process at cmemo@fail at on{\mmz at trace{\space\space
+    C-memo input failed}}
+\def\mmz at trace@cmemo at unmemoizable@on{\mmz at trace{\space\space
+    This code was marked as unmemoizable}}
+\def\mmz at trace@process at ccmemo@on{\mmz at trace{\space\space
+    Attempting to utilize cc-memo \mmz at ccmemo@path\space
+    (\ifmmz at direct@ccmemo at input\else in\fi direct input)}}
+\def\mmz at trace@resource at on#1{\mmz at trace{\space\space
+    Extern file does not exist: #1}}
+\def\mmz at trace@process at ccmemo@ok at on{%
+  \mmz at trace{\space\space Utilization successful}}
+\def\mmz at trace@process at no@ccmemo at on{%
+  \mmz at trace{\space\space CC-memo does not exist}}
+\def\mmz at trace@process at ccmemo@fail at on{%
+  \mmz at trace{\space\space Cc-memo input failed}}
+\mmzset{%
+  trace/.is choice,
+  trace/.default=true,
+  trace/true/.code=\mmzTracingOn,
+  trace/false/.code=\mmzTracingOff,
+}
+\def\mmzTracingOn{%
+  \let\mmz at trace@Memoize\mmz at trace@Memoize at on
+  \let\mmz at trace@code at mdfive\mmz at trace@code at mdfive@on
+  \let\mmz at trace@compile\mmz at trace@compile at on
+  \let\mmz at trace@memoize\mmz at trace@memoize at on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@endmemoize at ok\mmz at trace@endmemoize at ok@on
+  \let\mmz at trace@endmemoize at unmemoizable\mmz at trace@endmemoize at unmemoizable@on
+  \let\mmz at trace@endmemoize at aborted\mmz at trace@endmemoize at aborted@on
+  \let\mmz at trace@process at cmemo\mmz at trace@process at cmemo@on
+  \let\mmz at trace@process at cmemo@ok\mmz at trace@process at cmemo@ok at on
+  \let\mmz at trace@process at no@cmemo\mmz at trace@process at no@cmemo at on
+  \let\mmz at trace@process at cmemo@fail\mmz at trace@process at cmemo@fail at on
+  \let\mmz at trace@cmemo at unmemoizable\mmz at trace@cmemo at unmemoizable@on
+  \let\mmz at trace@process at ccmemo\mmz at trace@process at ccmemo@on
+  \let\mmz at trace@resource\mmz at trace@resource at on
+  \let\mmz at trace@process at ccmemo@ok\mmz at trace@process at ccmemo@ok at on
+  \let\mmz at trace@process at no@ccmemo\mmz at trace@process at no@ccmemo at on
+  \let\mmz at trace@process at ccmemo@fail\mmz at trace@process at ccmemo@fail at on
+}
+\def\mmzTracingOff{%
+  \let\mmz at trace@Memoize\relax
+  \let\mmz at trace@code at mdfive\relax
+  \let\mmz at trace@compile\relax
+  \let\mmz at trace@memoize\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@endmemoize at ok\relax
+  \let\mmz at trace@endmemoize at unmemoizable\relax
+  \let\mmz at trace@endmemoize at aborted\relax
+  \let\mmz at trace@process at cmemo\relax
+  \let\mmz at trace@process at cmemo@ok\relax
+  \let\mmz at trace@process at no@cmemo\relax
+  \let\mmz at trace@process at cmemo@fail\relax
+  \let\mmz at trace@cmemo at unmemoizable\relax
+  \let\mmz at trace@process at ccmemo\relax
+  \let\mmz at trace@resource\@gobble
+  \let\mmz at trace@process at ccmemo@ok\relax
+  \let\mmz at trace@process at no@ccmemo\relax
+  \let\mmz at trace@process at ccmemo@fail\relax
+}
+\mmzTracingOff
+\newtoks\mmzContext
+\newtoks\mmzContextExtra
+\mmzset{%
+  context/.code={%
+    \ifmemoizing
+      \expandafter\gtoksapp\expandafter\mmzContextExtra
+    \else
+      \expandafter\toksapp\expandafter\mmzContext
+    \fi
+    {#1,}%
+  },
+  clear context/.code={%
+    \ifmemoizing
+      \expandafter\global\expandafter\mmzContextExtra
+    \else
+      \expandafter\mmzContext
+    \fi
+    {}%
+  },
+  clear context/.value forbidden,
+  meaning to context/.code={\forcsvlist\mmz at mtoc{#1}},
+  csname meaning to context/.code={\mmz at mtoc@cs{#1}},
+  key meaning to context/.code={\forcsvlist\mmz at mtoc\mmz at mtoc@keycmd{#1}},
+  key value to context/.code={\forcsvlist\mmz at mtoc@key{#1}},
+  /handlers/.meaning to context/.code={%
+    \expanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath/. at cmd}}},
+  /handlers/.value to context/.code={%
+    \expanded{\noexpand\mmz at mtoc@cs{pgfk@\pgfkeyscurrentpath}}},
+}
+\def\mmz at mtoc#1{%
+  \collargs at cs@cases{#1}%
+    {\mmz at mtoc@cmd{#1}}%
+    {\mmz at mtoc@error at notcsorenv{#1}}%
+    {%
+      \mmz at mtoc@cs{%
+        #1}%
+      \mmz at mtoc@cs{%
+        end%
+        #1}%
+    }%
+}
+\def\mmz at mtoc@cmd#1{%
+  \begingroup
+  \escapechar=-1
+  \expandafter\endgroup
+  \expandafter\mmz at mtoc@cs\expandafter{\string#1}%
+}
+\def\mmz at mtoc@cs#1{%
+  \pgfkeysvalueof{/mmz/context/. at cmd}%
+  \expandafter\string\csname#1\endcsname={\expandafter\meaning\csname#1\endcsname}%
+  \pgfeov
+}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1}}
+\def\mmz at mtoc@key#1{\mmz at mtoc@cs{pgfk@#1/. at cmd}}
+\def\mmz at mtoc@error at notcsorenv#1{%
+  \PackageError{memoize}{'\detokenize{#1}' passed to key 'meaning to context' is neither a command nor an environment}{}%
+}
+\def\mmz at cmemo@path{\mmz at prefix@path\mmz at code@mdfivesum.memo}
+\newtoks\mmzCMemo
+\mmzset{%
+  include source in cmemo/.is if=mmz at include@source,
+}
+\newif\ifmmz at include@source
+\mmz at include@sourcetrue
+\def\mmz at write@cmemo{%
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  \immediate\write\mmz at out{%
+    \global\mmzContextExtra{\the\mmzContextExtra}\collargs at percentchar
+  }%
+  \immediate\write\mmz at out{\the\mmzCMemo\collargs at percentchar}%
+  \ifmmz at include@source
+    \immediate\write\mmz at out{\noexpand\mmzSource}%
+    \immediate\write\mmz at out{\the\mmz at mdfive@source}%
+  \fi
+  \immediate\closeout\mmz at out
+  \pgfkeysalso{/mmz/record/new cmemo={\mmz at cmemo@path}}%
+}
+\def\mmz at write@empty at cmemo{%
+  \immediate\openout\mmz at out{\mmz at cmemo@path}%
+  \immediate\closeout\mmz at out
+}
+\let\mmzSource\endinput
+\def\mmz at process@cmemo{%
+  \mmz at trace@process at cmemo
+  \global\mmz at aborttrue
+  \global\mmzUnmemoizablefalse
+  \def\mmzMemo{\global\mmz at abortfalse}%
+  \global\mmzContextExtra{}%
+  \IfFileExists{\mmz at cmemo@path}{%
+    \input{\mmz at cmemo@path}%
+    \pgfkeysalso{/mmz/record/used cmemo={\mmz at cmemo@path}}%
+  }{%
+    \mmz at trace@process at no@cmemo
+  }%
+  \mmz at compute@context at mdfivesum
+}
+\def\mmz at compute@context at mdfivesum{%
+  \xdef\mmz at context@key{\the\mmzContext\the\mmzContextExtra}%
+  \begingroup
+  \begingroup
+  \def\width{\string\width}%
+  \def\height{\string\height}%
+  \def\depth{\string\depth}%
+  \edef\mmz at paddings{\mmz at paddings}%
+  \expandafter\endgroup
+  \expandafter\def\expandafter\mmz at paddings\expandafter{\mmz at paddings}%
+  \xdef
+  \mmz at context@key{\mmz at context@key}%
+  \endgroup
+  \xdef\mmz at context@mdfivesum{\pdf at mdfivesum{\expandonce\mmz at context@key}}%
+}
+\def\mmz at ccmemo@path{%
+  \mmz at prefix@path\mmz at code@mdfivesum-\mmz at context@mdfivesum.memo}
+\newtoks\mmzCCMemo
+\newif\ifmmz at include@context
+\mmzset{%
+  include context in ccmemo/.is if=mmz at include@context,
+}
+\newif\ifmmz at direct@ccmemo at input
+\mmzset{%
+  direct ccmemo input/.is if=mmz at direct@ccmemo at input,
+}
+\def\mmz at write@ccmemo{%
+  \immediate\openout\mmz at out{\mmz at ccmemo@path}%
+  \begingroup
+  \the\mmz at ccmemo@resources
+  \endgroup
+  \immediate\write\mmz at out{\noexpand\mmzMemo}%
+  \immediate\write\mmz at out{\the\mmzCCMemo\collargs at percentchar}%
+  \ifmmz at include@context
+    \immediate\write\mmz at out{\noexpand\mmzThisContext}%
+    \immediate\write\mmz at out{\expandonce{\mmz at context@key}}%
+  \fi
+  \immediate\write\mmz at out{\noexpand\mmzEndMemo}%
+  \immediate\closeout\mmz at out
+  \pgfkeysalso{/mmz/record/new ccmemo={\mmz at ccmemo@path}}%
+}
+\def\mmz at ccmemo@append at resource#1{%
+  \mmz at seq=#1\relax
+  \immediate\write\mmz at out{%
+    \string\mmzResource{\mmz at extern@name}\collargs at percentchar}%
+}
+\def\mmzResource#1{%
+  \ifnum0\pdf at filesize{\mmz at dir@path/#1}=0
+    \ifmmz at direct@ccmemo at input
+      \let\mmzMemo\endinput
+    \else
+      \long\def\mmzMemo##1\mmzEndMemo\par{}%
+    \fi
+    \mmz at trace@resource{#1}%
+  \fi
+}
+\def\mmz at process@ccmemo{%
+  \mmz at trace@process at ccmemo
+  \global\mmz at aborttrue
+  \def\mmzMemo{%
+    \endgroup
+    \global\mmz at abortfalse
+    \let\mmzIncludeExtern\mmz at include@extern
+  }%
+  \xdef\mmzEndMemo{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      \unexpanded{%
+        \def\mmz at temp\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  \xdef\mmzThisContext{%
+    \ifmmz at direct@ccmemo at input
+      \noexpand\endinput
+    \else
+      \unexpanded{%
+        \long\def\mmz at temp##1\mmzEndMemo\par{}%
+        \mmz at temp
+      }%
+    \fi
+  }%
+  \IfFileExists{\mmz at ccmemo@path}{%
+    \ifmmz at direct@ccmemo at input
+      \input{\mmz at ccmemo@path}%
+    \else
+      \filetotoks\toks@{\mmz at ccmemo@path}%
+      \the\toks@
+    \fi
+    \pgfkeysalso{/mmz/record/used ccmemo={\mmz at ccmemo@path}}%
+  }{%
+    \mmz at trace@process at no@ccmemo
+  }%
+  \ifmmz at abort
+    \mmz at trace@process at ccmemo@fail
+    \ifnum\mmz at mode=\mmz at mode@readonly\relax
+      \expandafter\expandafter\expandafter\mmz at compile
+    \else
+      \expandafter\expandafter\expandafter\mmz at memoize
+    \fi
+  \else
+    \mmz at trace@process at ccmemo@ok
+  \fi
+}
+\newcount\mmz at seq
+\def\mmz at extern@basename{%
+  \mmz at prefix\mmz at code@mdfivesum-\mmz at context@mdfivesum
+  \ifnum\mmz at seq>0 -\the\mmz at seq\fi
+}
+\def\mmz at extern@name{\mmz at extern@basename.pdf}
+\def\mmz at extern@basepath{\mmz at dir@path/\mmz at extern@basename}
+\def\mmz at extern@path{\mmz at extern@basepath.pdf}
+\mmzset{
+  padding left/.store in=\mmz at padding@left,
+  padding right/.store in=\mmz at padding@right,
+  padding top/.store in=\mmz at padding@top,
+  padding bottom/.store in=\mmz at padding@bottom,
+  padding/.style={
+    padding left=#1, padding right=#1,
+    padding top=#1, padding bottom=#1
+  },
+  padding=1in,
+  padding to context/.style={
+    context={padding=(\mmz at paddings)},
+  },
+  padding to context,
+}
+\def\mmz at paddings{%
+  \mmz at padding@left,\mmz at padding@bottom,\mmz at padding@right,\mmz at padding@top
+}
+\def\mmzExternalizeBox#1#2{%
+  \begingroup
+  \def\width{\wd#1 }%
+  \def\height{\ht#1 }%
+  \def\depth{\dp#1 }%
+  \xdef\mmz at global@temp{%
+    \noexpand\mmzIncludeExtern
+      {\the\mmz at seq}%
+      \ifhbox#1\noexpand\hbox\else\noexpand\vbox\fi
+      {\the\wd#1}%
+      {\the\ht#1}%
+      {\the\dp#1}%
+      {\the\dimexpr\mmz at padding@left}%
+      {\the\dimexpr\mmz at padding@bottom}%
+      {\the\dimexpr\mmz at padding@right}%
+      {\the\dimexpr\mmz at padding@top}%
+  }%
+  \global\setbox\mmz at tbe@box\vbox{\copy#1\unvbox\mmz at tbe@box}%
+  \xtoksapp\mmz at ccmemo@resources{%
+    \noexpand\mmz at ccmemo@append at resource{\the\mmz at seq}%
+  }%
+  \global\advance\mmz at seq1
+  \endgroup
+  #2\expandafter{\mmz at global@temp}%
+}
+\newtoks\mmz at ccmemo@resources
+\newbox\mmz at tbe@box
+\def\mmz at shipout@externs{%
+  \global\mmz at seq 0
+  \setbox\mmz at box\vbox{%
+    \def\width{\wd\mmz at box}%
+    \def\height{\ht\mmz at box}%
+    \def\depth{\dp\mmz at box}%
+    \vskip1pt
+    \ifmmzkeepexterns\expandafter\unvcopy\else\expandafter\unvbox\fi\mmz at tbe@box
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox\mmz at box\lastbox
+      \mmz at shipout@extern
+    }%
+  }%
+}
+\def\mmz at shipout@extern{%
+  \edef\expectedwidth{\the\dimexpr
+    (\mmz at padding@left) + \wd\mmz at box + (\mmz at padding@right)}%
+  \edef\expectedheight{\the\dimexpr
+    (\mmz at padding@top) + \ht\mmz at box + \dp\mmz at box + (\mmz at padding@bottom)}%
+  \begingroup
+  \ifnum\mag=1000
+  \else
+    \mmz at shipout@mag
+  \fi
+  \pdfpagewidth\dimexpr
+    (\mmz at padding@left) + \wd\mmz at box + (\mmz at padding@right)\relax
+  \pdfpageheight\dimexpr
+    (\mmz at padding@top) + \ht\mmz at box + \dp\mmz at box+ (\mmz at padding@bottom)\relax
+  \hoffset\dimexpr\mmz at padding@left - \pdfhorigin\relax
+  \voffset\dimexpr\mmz at padding@top - \pdfvorigin\relax
+  \pdf at primitive\shipout\box\mmz at box
+  \endgroup
+  \global\advance\mmzExternPages1
+  \edef\externbasepath{\mmz at extern@basepath}%
+  \edef\pagenumber{\the\numexpr\mmzRegularPages
+    +\mmzExternPages+\mmzExtraPages}%
+  \mmzset{record/new extern/.expanded=\mmz at extern@path}%
+  \global\advance\mmz at seq1
+}
+\def\mmz at shipout@mag{%
+  \setbox\mmz at box\hbox{%
+    \pdfliteral{q \mmz at inverse@mag\space 0 0 \mmz at inverse@mag\space 0 0 cm}%
+    \copy\mmz at box\relax
+    \pdfliteral{Q}%
+  }%
+  \dimen0=\dimexpr\mmz at padding@left\relax
+  \edef\mmz at padding@left{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@bottom\relax
+  \edef\mmz at padding@bottom{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@right\relax
+  \edef\mmz at padding@right{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \dimen0=\dimexpr\mmz at padding@top\relax
+  \edef\mmz at padding@top{\the\dimexpr\mmz at inverse@mag\dimen0}%
+  \wd\mmz at box=\mmz at inverse@mag\wd\mmz at box\relax
+  \ht\mmz at box=\mmz at inverse@mag\ht\mmz at box\relax
+  \dp\mmz at box=\mmz at inverse@mag\dp\mmz at box\relax
+}
+{\catcode`\p=12\catcode`\t=12\gdef\mmz at Pgf@geT#1pt{#1}}
+\mmzset{begindocument/.append code={%
+    \edef\mmz at inverse@mag{\expandafter\mmz at Pgf@geT\the\dimexpr 1000pt/\mag}%
+  }}
+\newcount\mmzRegularPages
+\newcount\mmzExternPages
+\mmzset{
+  enddocument/afterlastpage/.append code={%
+    \ifnum\mmzExternPages>0
+      \PackageWarning{memoize}{The compilation produced \the\mmzExternPages\space
+        new extern\ifnum\mmzExternPages>1 s\fi.}%
+    \fi
+  },
+}
+\newcount\mmzExtraPages
+\def\mmz at include@extern#1#2#3#4#5#6#7#8#9{%
+  \mmz at seq=#1\relax
+  \setbox\mmz at box=#2{%
+    \setbox0=\hbox{%
+      \lower\dimexpr #5+#7\relax\hbox{%
+        \hskip -#6\relax
+        \setbox0=\hbox{%
+          \mmz at insertpdfpage{\mmz at extern@path}{1}%
+        }%
+        \unhbox0
+      }%
+    }%
+    \wd0 \dimexpr\wd0-#8\relax
+    \ht0 \dimexpr\ht0-#9\relax
+    \dp0 #5\relax
+    \box0
+  }%
+  \mmz at tempfalse
+  \mmz at if@roughly at equal{\mmz at tolerance}{#3}{\wd\mmz at box}{%
+    \mmz at if@roughly at equal{\mmz at tolerance}{#4}{\ht\mmz at box}{%
+      \mmz at temptrue
+    }{}}{}%
+  \ifmmz at temp
+  \else
+    \mmz at use@memo at warning{\mmz at extern@path}{#3}{#4}{#5}%
+  \fi
+  \wd\mmz at box=#3\relax
+  \ht\mmz at box=#4\relax
+  \box\mmz at box
+  \pgfkeysalso{/mmz/record/used extern={\mmz at extern@path}}%
+}
+\def\mmz at use@memo at warning#1#2#3#4{%
+  \PackageWarning{memoize}{Unexpected size of extern "#1";
+    expected #2\space x \the\dimexpr #3+#4\relax,
+    got \the\wd\mmz at box\space x \the\dimexpr\the\ht\mmz at box+\the\dp\mmz at box\relax}%
+}
+\ifdef\luatexversion{%
+  \def\mmz at insertpdfpage#1#2{% #1 = filename, #2 = page number
+    \saveimageresource page #2 mediabox {#1}%
+    \useimageresource\lastsavedimageresourceindex
+  }%
+}{%
+  \ifdef\XeTeXversion{%
+    \def\mmz at insertpdfpage#1#2{%
+      \XeTeXpdffile #1 page #2 media
+    }%
+  }{% pdfLaTeX
+    \def\mmz at insertpdfpage#1#2{%
+      \pdfximage page #2 mediabox {#1}%
+      \pdfrefximage\pdflastximage
+    }%
+  }%
+}
+\def\mmz at include@extern at from@tbe at box#1#2#3#4#5#6#7#8#9{%
+  \setbox0\vbox{%
+    \@tempcnta#1\relax
+    \vskip1pt
+    \unvcopy\mmz at tbe@box
+    \@whilenum\@tempcnta>0\do{%
+      \setbox0\lastbox
+      \advance\@tempcnta-1\relax
+    }%
+    \global\setbox1\lastbox
+    \@whilesw\ifdim0pt=\lastskip\fi{%
+      \setbox0\lastbox
+    }%
+    \box\mmz at box
+  }%
+  \box1
+}
+\def\mmzvalueof#1{\pgfkeysvalueof{/mmz/#1}}
+\mmzset{
+  extract/.estore in=\mmz at extraction@method,
+  extract/.value required,
+  begindocument/.append style={extract/.code=\mmz at preamble@only at warning},
+  extract/perl/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{perl extraction command}\space
+      \mmzvalueof{perl extraction options}%
+    }%
+    \mmz at check@extraction at log{perl}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{perl extraction command}\space --mkdir "##1"}%
+  },
+  perl extraction command/.initial=memoize-extract.pl,
+  perl extraction options/.initial={%
+    -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+    "\string\warning{memoize (perl-based extraction): \string\warningtext}"
+    "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+  },
+  extract=perl,
+  extract/python/.code={%
+    \mmz at clear@extraction at log
+    \pdf at system{%
+      \mmzvalueof{python extraction command}\space
+      \mmzvalueof{python extraction options}%
+    }%
+    \mmz at check@extraction at log{python}%
+    \def\mmz at mkdir@command##1{\mmzvalueof{python extraction command}\space --mkdir "##1"}%
+  },
+  python extraction command/.initial=memoize-extract.py,
+  python extraction options/.initial={%
+  -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w
+  "\string\warning{memoize (python-based extraction): \string\warningtext}"
+  "\mmzOutputDirectory\mmzUnquote\jobname.mmz"
+  },
+}
+\def\mmz at preamble@only at warning{%
+  \PackageWarning{memoize}{%
+    Ignoring the invocation of "\pgfkeyscurrentkey".
+    This key may only be executed in the preamble}%
+}
+\def\mmz at clear@extraction at log{%
+  \begingroup
+  \immediate\openout0{\mmzUnquote\jobname.mmz.log"}%
+  \immediate\closeout0
+  \endgroup
+}
+\def\mmz at check@extraction at log#1{%
+  \begingroup \def\extractionmethod{#1}%
+  \mmz at tempfalse \let\mmz at orig@endinput\endinput
+  \def\endinput{\mmz at temptrue\mmz at orig@endinput}%
+  \@input{\jobname.mmz.log}%
+  \ifmmz at temp \else \mmz at extraction@error \fi \endgroup }
+\def\mmz at extraction@error{%
+  \PackageWarning{memoize}{Extraction of externs from document "\mmzUnquote\jobname.pdf"
+    using method "\extractionmethod" was unsuccessful. Have you set the
+    shell escape mode as suggested in chapter 1 of the manual?}{}}
+\mmzset{
+  record/.style={%
+    record/begin/.append style={
+      /mmz/record/#1/begin/.try,
+      /mmz/record/#1/prefix/.try/.expanded=\mmz at prefix@path,
+    },
+    record/prefix/.append style={/mmz/record/#1/prefix/.try={##1}},
+    record/new extern/.append style={/mmz/record/#1/new extern/.try={##1}},
+    record/used extern/.append style={/mmz/record/#1/used extern/.try={##1}},
+    record/new cmemo/.append style={/mmz/record/#1/new cmemo/.try={##1}},
+    record/new ccmemo/.append style={/mmz/record/#1/new ccmemo/.try={##1}},
+    record/used cmemo/.append style={/mmz/record/#1/used cmemo/.try={##1}},
+    record/used ccmemo/.append style={/mmz/record/#1/used ccmemo/.try={##1}},
+    record/end/.append style={/mmz/record/#1/end/.try},
+  },
+}
+\mmzset{
+  no record/.style={%
+    record/begin/.style={record/begin/.style={}},
+    record/prefix/.code={\aftergroup\mmz at record@prefix},
+    record/new extern/.code={},
+    record/used extern/.code={},
+    record/new cmemo/.code={},
+    record/new ccmemo/.code={},
+    record/used cmemo/.code={},
+    record/used ccmemo/.code={},
+    record/end/.style={record/end/.code={}},
+  }
+}
+\def\mmz at record@prefix{%
+  \mmzset{/mmz/record/prefix/.expanded=\mmz at prefix@path}%
+}
+\mmzset{
+  no record,
+  record=mmz,
+  begindocument/.append style={record/begin},
+  enddocument/afterlastpage/.append style={record/end},
+}
+\mmzset{
+  record/mmz/begin/.code={%
+    \newwrite\mmz at mmzout
+    \immediate\openout\mmz at mmzout{\jobname.mmz}%
+  },
+  record/mmz/prefix/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzPrefix{#1}}%
+  },
+  record/mmz/new extern/.code={%
+    \immediate\write\mmz at mmzout{%
+      \noexpand\mmzNewExtern{#1}{\pagenumber}{\expectedwidth}{\expectedheight}%
+    }%
+  },
+  record/mmz/new cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCMemo{#1}}%
+  },
+  record/mmz/new ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzNewCCMemo{#1}}%
+  },
+  record/mmz/used extern/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedExtern{#1}}%
+  },
+  record/mmz/used cmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCMemo{#1}}%
+  },
+  record/mmz/used ccmemo/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\mmzUsedCCMemo{#1}}%
+  },
+  record/mmz/end/.code={%
+    \immediate\write\mmz at mmzout{\noexpand\endinput}%
+    \immediate\closeout\mmz at mmzout
+  },
+  sh/.store in=\mmz at shname,
+  sh=memoize-extract.\jobname.sh,
+  bat/.store in=\mmz at batname,
+  bat=memoize-extract.\jobname.bat,
+  record/sh/begin/.code={%
+    \newwrite\mmz at shout
+    \immediate\openout\mmz at shout{\mmz at shname}%
+  },
+  record/sh/new extern/.code={%
+    \begingroup
+    \immediate\write\mmz at shout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/sh/end/.code={%
+    \immediate\closeout\mmz at shout
+  },
+  record/bat/begin/.code={%
+    \newwrite\mmz at batout
+    \immediate\openout\mmz at batout{\mmz at batname}%
+  },
+  record/bat/new extern/.code={%
+    \begingroup
+    \immediate\write\mmz at batout{\mmz at tex@extraction at systemcall}%
+    \endgroup
+  },
+  record/bat/end/.code={%
+    \immediate\closeout\mmz at batout
+  },
+  makefile/.store in=\mmz at makefilename,
+  makefile=memoize-extract.\jobname.makefile,
+}
+\begingroup
+\catcode`\^^I=12
+\gdef\mmz at makefile@recipe at prefix{^^I}%
+\endgroup
+\mmzset{
+  record/makefile/begin/.code={%
+    \newwrite\mmz at makefileout
+    \newtoks\mmz at makefile@externs
+    \immediate\openout\mmz at makefileout{\mmz at makefilename}%
+    \immediate\write\mmz at makefileout{.DEFAULT_GOAL = externs}%
+    \immediate\write\mmz at makefileout{.PHONY: externs}%
+  },
+  record/makefile/new extern/.code={%
+    \immediate\write\mmz at makefileout{#1:}%
+    \begingroup
+    \immediate\write\mmz at makefileout{%
+      \mmz at makefile@recipe at prefix\mmz at tex@extraction at systemcall}%
+    \endgroup
+    \xtoksapp\mmz at makefile@externs{#1\space}%
+  },
+  record/makefile/end/.code={%
+    \immediate\write\mmz at makefileout{externs: \the\mmz at makefile@externs}%
+    \immediate\closeout\mmz at makefileout
+  },
+}
+\mmzset{
+  extract/tex/.code={%
+    \begingroup
+    \@input{\jobname.mmz}%
+    \endgroup
+  },
+}
+\def\mmzUsedCMemo#1{}
+\def\mmzUsedCCMemo#1{}
+\def\mmzUsedExtern#1{}
+\def\mmzNewCMemo#1{}
+\def\mmzNewCCMemo#1{}
+\def\mmzPrefix#1{}
+\def\mmzNewExtern#1{%
+  \mmz at new@extern at i#1\mmz at temp
+}
+\def\mmz at new@extern at i#1.pdf\mmz at temp#2#3#4{%
+  \begingroup
+  \def\externbasepath{#1}%
+  \def\pagenumber{#2}%
+  \def\expectedwidth{#3}%
+  \def\expectedheight{#4}%
+  \mmz at clear@extraction at log
+  \pdf at system{\mmz at tex@extraction at systemcall}%
+  \let\mmz at extraction@error\mmz at pageextraction@error
+  \mmz at check@extraction at log{tex}%
+  \endgroup
+}
+\def\mmz at pageextraction@error{%
+  \PackageError{memoize}{Extraction of extern page \pagenumber\space from
+    document "\mmzUnquote\jobname.pdf" using method "\extractionmethod" was unsuccessful.
+    Have you set the shell escape mode as suggested in chapter 1 of the
+    manual?}{If "\mmzvalueof{tex extraction command}" was executed,
+    shell escape mode is not the problem, and inspecting "\externbasepath.log"
+    might give you a clue what's wrong}}
+\def\mmz at tex@extraction at systemcall{%
+  \mmzvalueof{tex extraction command}\space
+  \mmzvalueof{tex extraction options}\space
+  "\mmzvalueof{tex extraction script}"%
+}
+\mmzset{
+  tex extraction command/.initial=pdftex,
+  tex extraction options/.initial={%
+    -halt-on-error
+    -interaction=batchmode
+    -jobname "\externbasepath"
+    \ifdefempty\mmzOutputDirectory{}{-output-directory "\mmzOutputDirectory"}
+  },
+  tex extraction script/.initial={%
+    \def\noexpand\fromdocument{"\mmzOutputDirectory"\jobname.pdf}%
+    \def\noexpand\pagenumber{\pagenumber}%
+    \def\noexpand\expectedwidth{\expectedwidth}%
+    \def\noexpand\expectedheight{\expectedheight}%
+    \def\noexpand\logfile{\jobname.mmz.log}%
+    \unexpanded{%
+      \def\warningtemplate{%
+        \warning{memoize: \warningtext}%
+      }}%
+    \ifdef\XeTeXversion{}{%
+      \def\noexpand\mmzpdfmajorversion{\the\pdfmajorversion}%
+      \def\noexpand\mmzpdfminorversion{\the\pdfminorversion}%
+    }%
+    \noexpand\input memoize-extract-one
+  },
+}
+\def\mmz at tolerance{0.01pt}
+\def\mmz at if@roughly at equal#1#2#3{%
+  \dimen0=\dimexpr#2-#3\relax
+  \ifdim\dimen0<0pt
+    \dimen0=-\dimen0\relax
+  \fi
+  \ifdim\dimen0>#1\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi
+}%
+\mmzset{
+  .install advice={setup key=auto, activation=deferred},
+  begindocument/before/.append style={activation=immediate},
+}
+\newif\ifmmz at manual
+\mmzset{
+  manual/.is if=mmz at manual,
+  begindocument/end/.append code={%
+    \ifmmz at manual
+    \else
+      \pgfkeysalso{activate deferred,activate deferred/.code={}}%
+    \fi
+  },
+  auto/.cd,
+  run if memoization is possible/.style={
+    run conditions=\mmz at auto@rc at if@memoization at possible
+  },
+  run if memoizing/.style={run conditions=\mmz at auto@rc at if@memoizing},
+  apply options/.style={
+    bailout handler=\mmz at auto@bailout,
+    outer handler=\mmz at auto@outer,
+  },
+  memoize/.style={
+    run if memoization is possible,
+    apply options,
+    inner handler=\mmz at auto@memoize
+  },
+  noop/.style={inner handler=\mmz at auto@noop},
+  nomemoize/.style={noop, options=disable},
+  replicate/.style={run if memoizing, inner handler=\mmz at auto@replicate},
+}
+\mmzset{
+  auto/abort/.style={run conditions=\mmzAbort},
+}
+\mmzset{
+  auto/unmemoizable/.style={run conditions=\mmzUnmemoizable},
+}
+\ifdef\luatexversion{%
+  \mmzset{auto=\savepos{abort}}
+}{%
+  \mmzset{
+    auto=\pdfsavepos{abort},
+    auto=\errmessage{abort},
+  }
+}
+\def\mmz at auto@rc at if@memoization at possible{%
+  \ifmemoize
+    \ifinmemoize
+    \else
+      \AdviceRuntrue
+    \fi
+  \fi
+}
+\def\mmz at auto@rc at if@memoizing{%
+  \ifmemoizing\AdviceRuntrue\fi
+}
+\def\mmznext#1{\gdef\mmz at next{#1}\ignorespaces}
+\mmznext{}%
+\def\mmz at auto@outer{%
+  \begingroup
+  \mmzAutoInit
+  \AdviceCollector
+}
+\def\mmz at auto@bailout{%
+  \mmznext{}%
+}
+\def\mmzAutoInit{%
+  \ifdefempty\AdviceOptions{}{\expandafter\mmzset\expandafter{\AdviceOptions}}%
+  \ifdefempty\mmz at next{}{\expandafter\mmzset\expandafter{\mmz at next}\mmznext{}}%
+  \eappto\AdviceRawCollectorOptions{\expandonce\mmzRawCollectorOptions}%
+}
+\long\def\mmz at auto@memoize#1{%
+  \expanded{%
+    \noexpand\Memoize
+      {\expandonce\AdviceReplaced\unexpanded{#1}}%
+      {\expandonce\AdviceOriginal\unexpanded{#1}}%
+    \ifmmz at ignorespaces\ignorespaces\fi
+  }%
+}
+\long\def\mmz at auto@noop#1{%
+  \expandafter\mmz at maybe@scantokens\expandafter{\AdviceOriginal#1}%
+  \expandafter\endgroup
+  \ifmmz at ignorespaces\ignorespaces\fi
+}
+\def\mmz at auto@replicate#1{%
+  \begingroup
+  \let\mmz at auto@replicate at expansion\unexpanded
+  \expandafter\pgfqkeys\expanded{{/mmz/auto/replicate}{\AdviceOptions}}%
+  \expanded{%
+    \endgroup
+    \noexpand\gtoksapp\noexpand\mmzCCMemo{%
+      \expandonce\AdviceReplaced\mmz at auto@replicate at expansion{#1}}%
+    \expandonce\AdviceOriginal\unexpanded{#1}%
+  }%
+}
+\pgfqkeys{/mmz/auto/replicate}{
+  expanded/.code={\let\mmz at auto@replicate at expansion\@firstofone},
+}
+\mmzset{
+  begindocument/before/.append code={%
+    \ifdefined\tikz
+      \input advice-tikz.code.tex
+    \fi
+    \mmzset{%
+      auto=\tikz{memoize, collector=\AdviceCollectTikZArguments},
+      auto={tikzpicture}{memoize},
+      auto=\pgfsys at getposition{
+        run if memoizing, outer handler=\mmz at pgfsys@getposition},
+    }%
+    \def\mmz at pgfsys@getposition##1{%
+      \expandafter\ifx\csname pgf at sys@pdf at mark@pos@##1\endcsname\relax
+      \else
+        \mmzAbort
+      \fi
+      \AdviceOriginal{##1}%
+    }%
+  },
+}
+\mmzset{
+  begin document/.style={begindocument/before, begindocument, begindocument/end},
+  end document/.style={enddocument/afterlastpage},
+}
+\InputIfFileExists{memoize.cfg}{}{}
+\mmzset{
+  output-directory/.store in=\mmzOutputDirectory,
+}
+\ifdefined\mmzOutputDirectory
+\else
+  \def\mmzOutputDirectory{}%
+\fi
+\mmzset{output directory/.code={\PackageError{memoize}{Key "output-directory"
+      may only be used as a package option}{}}}
+\mmzset{
+  extract/.is choice,
+  extract/.default=\mmz at extraction@method,
+  extract/.append style={
+    extract/.code={\PackageError{memoize}{Key "extract" is only allowed to
+        be used once.}{If you really want to extract again, execute
+        "extract/<method>".}},
+  },
+}
+\ifnum\pdf at draftmode=1
+  \PackageWarning{memoize}{No memoization will be performed in the draft mode}%
+\fi
+\resetatcatcode
+\endinput
+%%
+%% End of file `memoize.tex'.


Property changes on: trunk/Master/texmf-dist/tex/plain/memoize/memoize.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/plain/memoize/nomemoize.tex
===================================================================
--- trunk/Master/texmf-dist/tex/plain/memoize/nomemoize.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/plain/memoize/nomemoize.tex	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,96 @@
+%%
+%% This is file `nomemoize.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% memoize.dtx  (with options: `nommz,plain')
+%% 
+%% This file is a part of Memoize, a TeX package for externalization of
+%% graphics and memoization of compilation results in general, available at
+%% https://ctan.org/pkg/memoize and https://github.com/sasozivanovic/memoize.
+%%
+%% Copyright (c) 2020- Saso Zivanovic <saso.zivanovic at guest.arnes.si>
+%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version.  The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
+%% all distributions of LaTeX version 2008 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Saso Zivanovic.
+%%
+%% The files belonging to this work and covered by LPPL are listed in
+%% (<texmf>/doc/generic/memoize/)FILES.
+\input miniltx
+\def\ifmmz at loadstatus#1{%
+  \ifnum#1=0\csname mmz at loadstatus\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+\ifmmz at loadstatus{1}%
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoize" is already
+    loaded; memoization will remain in effect}{Packages "memoize" and
+    "nomemoize" are mutually exclusive, please load either one or the other.}%
+  \endinput }{}%
+\ifmmz at loadstatus{2}%
+{%
+  \PackageError{nomemoize}{Cannot load the package, as "memoizable" is already
+    loaded}{Package "memoizable" is loaded by packages which support
+    memoization.  (No)Memoize must be loaded before all such packages.  The
+    compilation log can help you figure out which package loaded
+    "memoizable"; please move
+    "\string\input memoize"
+    before the
+    "\string\input"
+    of that package.}%
+  \endinput
+}{}%
+\ifmmz at loadstatus{3}{\endinput}{}%
+\def\mmz at loadstatus{3}%
+\def\mmzset#1{\ignorespaces}
+\def\nommzkeys{\pgfqkeys{/mmz}}
+\pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}}
+\newif\ifmemoize
+\protected\def\nommz#1#{%
+  \afterassignment\nommz at i
+  \let\mmz at temp
+}
+\def\nommz at i{%
+  \bgroup
+  \memoizefalse
+}
+\let\mmz\nommz
+\def\nomemoize{%
+  \begingroup
+  \memoizefalse
+  \futurelet\mmz at temp\nommz at env@i
+}
+\def\nommz at env@i{%
+  \ifx\mmz at temp[%]
+    \expandafter\nommz at env@ii
+  \fi
+}
+\def\nommz at env@ii[#1]{%
+  \ignorespaces
+}
+\def\endnomemoize{%
+  \endgroup
+  \unskip
+}
+\let\memoize\nomemoize
+\let\endmemoize\endnomemoize
+\newif\ifmemoizing
+\newif\ifinmemoize
+\newcommand\IfMemoizing[2][]{\@secondoftwo}
+\def\mmznext#1{\ignorespaces}
+\InputIfFileExists{memoize.cfg}{}{}
+\resetatcatcode
+\endinput
+%%
+%% End of file `nomemoize.tex'.


Property changes on: trunk/Master/texmf-dist/tex/plain/memoize/nomemoize.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2023-10-11 20:46:52 UTC (rev 68515)
@@ -552,7 +552,7 @@
     mcaption mceinleger mcexam mcf2graph mcite mciteplus mcmthesis
     mdframed mdputu mdsymbol mdwtools mecaso media4svg media9 medstarbeamer
     meetingmins membranecomputing memdesign memexsupp
-    memoir memoirchapterstyles memory memorygraphs mendex-doc mentis
+    memoir memoirchapterstyles memoize memory memorygraphs mendex-doc mentis
     mensa-tex menu menucard menukeys mercatormap merriweather
     messagepassing
     metafont-beginners metago metalogo metalogox metanorma metaobj metaplot

Modified: trunk/Master/tlpkg/libexec/ctan2tds
===================================================================
--- trunk/Master/tlpkg/libexec/ctan2tds	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/tlpkg/libexec/ctan2tds	2023-10-11 20:46:52 UTC (rev 68515)
@@ -1773,6 +1773,7 @@
  'm-tx'			=> '&POSTmtx',
  'match_parens'		=> '&POST_do_man',
  'mathdesign'		=> '&POSTmathdesign',
+ 'memoize'		=> '&POST_do_man',
  'mflogo'		=> '&POST_rmsymlink',
  'mitthesis'		=> '&POSTmitthesis',
  'moderncv'		=> '&POST_deref_symlink',
@@ -3733,6 +3734,7 @@
  'makedtx'		=> '^makedtx\.pl$',
  'match_parens'         => '^match_parens$',
  'mathspic'             => '^mathspic\.pl$',
+ 'memoize'		=> '\.p[ly]$',
  'multibibliography'    => '\.pl$',
  'mf2pt1'               => '\.pl$',
  'mkgrkindex'           => 'mkgrkindex$',
@@ -4662,9 +4664,19 @@
   # 
   my $build_tldir = "texk/texlive";
   chomp (my @platforms = `cd $Master/bin && ls | grep -vw man`);
+  print  " linking in platforms: @platforms\n";
   #
   for my $s (@scripts) {
     (my $linkname = $s) =~ s/\..*$//;
+    print  " beginning linking script $s to $linkname\n";
+    
+    if ($package =~ /^(memoize|listings-ext)$/) {
+      # memoize requires preserving the .pl/.py extensions,
+      # ditto listings-ext.sh.
+      $linkname = $s;
+      print "  package $package special case: linking to $linkname\n";
+    }
+    
     for my $p (@platforms) {
       my $platdir = "$TOPDEST/bin/$p";
       &xmkdir ($platdir);

Modified: trunk/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc	2023-10-11 20:32:41 UTC (rev 68514)
+++ trunk/Master/tlpkg/tlpsrc/collection-pictures.tlpsrc	2023-10-11 20:46:52 UTC (rev 68515)
@@ -94,6 +94,7 @@
 depend maker
 depend makeshape
 depend mathspic
+depend memoize
 depend mercatormap
 depend milsymb
 depend miniplot

Added: trunk/Master/tlpkg/tlpsrc/memoize.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/memoize.tlpsrc	                        (rev 0)
+++ trunk/Master/tlpkg/tlpsrc/memoize.tlpsrc	2023-10-11 20:46:52 UTC (rev 68515)
@@ -0,0 +1,2 @@
+binpattern f bin/${ARCH}/${PKGNAME}-*
+docpattern +f texmf-dist/doc/man/man1/${PKGNAME}*



More information about the tex-live-commits mailing list.