summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Build/source/texk/texlive/linked_scripts/Makefile.am1
-rw-r--r--Build/source/texk/texlive/linked_scripts/Makefile.in1
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl495
-rw-r--r--Build/source/texk/texlive/linked_scripts/scripts.lst1
l---------Master/bin/amd64-freebsd/ctan-o-mat1
l---------Master/bin/amd64-netbsd/ctan-o-mat1
l---------Master/bin/armel-linux/ctan-o-mat1
l---------Master/bin/armhf-linux/ctan-o-mat1
l---------Master/bin/i386-cygwin/ctan-o-mat1
l---------Master/bin/i386-darwin/ctan-o-mat1
l---------Master/bin/i386-freebsd/ctan-o-mat1
l---------Master/bin/i386-linux/ctan-o-mat1
l---------Master/bin/i386-netbsd/ctan-o-mat1
l---------Master/bin/i386-solaris/ctan-o-mat1
l---------Master/bin/powerpc-darwin/ctan-o-mat1
l---------Master/bin/powerpc-linux/ctan-o-mat1
l---------Master/bin/sparc-solaris/ctan-o-mat1
-rwxr-xr-xMaster/bin/win32/ctan-o-mat.exebin0 -> 1536 bytes
l---------Master/bin/x86_64-cygwin/ctan-o-mat1
l---------Master/bin/x86_64-darwin/ctan-o-mat1
l---------Master/bin/x86_64-darwinlegacy/ctan-o-mat1
l---------Master/bin/x86_64-linux/ctan-o-mat1
l---------Master/bin/x86_64-solaris/ctan-o-mat1
-rw-r--r--Master/texmf-dist/doc/man/man1/ctan-o-mat.1238
-rw-r--r--Master/texmf-dist/doc/man/man1/ctan-o-mat.man1.pdfbin0 -> 18850 bytes
-rw-r--r--Master/texmf-dist/doc/support/ctan-o-mat/LICENSE27
-rw-r--r--Master/texmf-dist/doc/support/ctan-o-mat/README.md136
-rwxr-xr-xMaster/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat21
-rw-r--r--Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat.pkg131
-rwxr-xr-xMaster/texmf-dist/doc/support/ctan-o-mat/lib/md2ltx.pl146
-rw-r--r--Master/texmf-dist/doc/support/ctan-o-mat/makefile32
-rwxr-xr-xMaster/texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl495
-rwxr-xr-xMaster/texmf-dist/source/support/ctan-o-mat/ctan-o-mat.bat21
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds10
-rw-r--r--Master/tlpkg/tlpsrc/collection-binextra.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/ctan-o-mat.tlpsrc2
37 files changed, 1776 insertions, 2 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.am b/Build/source/texk/texlive/linked_scripts/Makefile.am
index 32804d0c3a8..535a94a2021 100644
--- a/Build/source/texk/texlive/linked_scripts/Makefile.am
+++ b/Build/source/texk/texlive/linked_scripts/Makefile.am
@@ -105,6 +105,7 @@ texmf_other_scripts = \
crossrefware/bibmradd.pl \
crossrefware/bibzbladd.pl \
crossrefware/ltx2crossrefxml.pl \
+ ctan-o-mat/ctan-o-mat.pl \
ctanify/ctanify \
ctanupload/ctanupload.pl \
de-macro/de-macro \
diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.in b/Build/source/texk/texlive/linked_scripts/Makefile.in
index 5274a34bb18..f54f0939482 100644
--- a/Build/source/texk/texlive/linked_scripts/Makefile.in
+++ b/Build/source/texk/texlive/linked_scripts/Makefile.in
@@ -319,6 +319,7 @@ texmf_other_scripts = \
crossrefware/bibmradd.pl \
crossrefware/bibzbladd.pl \
crossrefware/ltx2crossrefxml.pl \
+ ctan-o-mat/ctan-o-mat.pl \
ctanify/ctanify \
ctanupload/ctanupload.pl \
de-macro/de-macro \
diff --git a/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl b/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl
new file mode 100755
index 00000000000..1463743432b
--- /dev/null
+++ b/Build/source/texk/texlive/linked_scripts/ctan-o-mat/ctan-o-mat.pl
@@ -0,0 +1,495 @@
+#!/usr/bin/perl -w
+##-----------------------------------------------------------------------------
+## This file is part of ctan-o-mat.
+## This program is distributed under BSD-like license. See file LICENSE
+##
+## (c) 2016-2017 Gerd Neugebauer
+##
+## Net: gene@gerd-neugebauer.de
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of a 3-clause BSD-like license as stated in the file
+## LICENSE contained in this distribution.
+##
+## You should have received a copy of the LICENSE along with this program; if
+## not, see the repository under https://github.com/ge-ne/ctan-o-mat.
+##
+##-----------------------------------------------------------------------------
+
+=head1 NAME
+
+ctan-o-mat - Upload or validate a package for CTAN
+
+=head1 SYNOPSIS
+
+ctan-o-mat [options] [<package configuration>]
+
+=head1 DESCRIPTION
+
+This program can be used to automate the upload of a package to CTAN
+(https://www.ctan.org). The description of the package is contained in
+a configuration file. Thus it can be updated easily without the need
+to fill a Web form with the same old information.
+
+The provided information is validated in any case. If the validation
+succeeds and not only the validation is requested then the provided
+archive file is placed in the incoming area of the CTAN for further
+processing by the CTAN team.
+
+In any case any finding during the validation is reported at the end
+of the processing. Note that the validation is the default and a
+official submission has to be requested by the an appropriate command
+line option.
+
+B<ctan-o-mat> requires an Internet connection to the CTAN server. Even the
+validation retrieves the known attributes and the basic constraints
+from the server.
+
+
+=head1 CONFIGURATION
+
+The default configuration is read from a file with the same name as
+the current directory an the extension .pkg. This file name can be
+overwritten on the command line.
+
+The configuration depends on the features supported by the CTAN server.
+Since these features can change over time the configuration is not
+hard-coded in B<ctan-o-mat>. You can request a template of the
+configuration via the command line parameter C<-init>.
+
+
+=head1 OPTIONS
+
+=over 4
+
+=item -h
+
+=item --help
+
+Print this short summary about the usage and exit the program.
+
+=item --validate
+
+=item -n
+
+=item --noaction
+
+Do not perform the final upload. The package is validated and the
+resulting messages are printed.
+
+=item -i
+
+=item --init
+
+Create an empty template for a configuration.
+
+=item -s
+
+=item --submit
+
+Upload the submission, validate it and officially submit it to CTAN it the
+validation succeeds.
+
+=item -v
+
+=item --verbose
+
+Print some more information during the processing (verbose mode).
+
+=item --version
+
+Print the version number of this program and exit.
+
+=item --validate
+
+Print some additional debugging information.
+
+=item <package>
+
+This parameter is the name of a package configuration
+(see section CONFIGURATION) contained in a file.
+
+=back
+
+=head1 CONNECTING VIA PROXIES
+
+If you need to connect to the Internet via a proxy then this can be achieved
+by setting some environment variables before running B<ctan-o-mat>.
+To redirect the request via the proxy simply define an environment variable
+C<http_proxy> to point to the proxy host -- including protocol and port as
+required. Note that the name of the environment variable is supposed to be in
+B<lower> case.
+
+
+=head1 AUTHOR
+
+Gerd Neugebauer (gene@gerd-neugebauer.de)
+
+=head1 BUGS
+
+=over 4
+
+=item *
+
+The program can not be used without a working connection to the
+Internet.
+
+=back
+
+=cut
+
+use strict;
+use FileHandle;
+use File::Basename;
+use Cwd;
+
+use LWP::UserAgent;
+use LWP::Protocol::https;
+use HTTP::Request::Common;
+
+use constant VERSION => '1.0';
+
+use constant NEW_CONFIG => 0;
+use constant UPLOAD => 1;
+use constant VALIDATE => 2;
+use constant INCREMENT => 3;
+
+my $CTAN_URL = 'http://localhost:8080/submit/';
+
+#------------------------------------------------------------------------------
+# Function: usage
+# Arguments: none
+# Returns: nothing
+# Description: Print the POD to stderr and exit
+#
+sub usage {
+ use Pod::Text;
+ Pod::Text->new()
+ ->parse_from_filehandle( new FileHandle( $0, 'r' ), \*STDERR );
+ exit(0);
+}
+
+#------------------------------------------------------------------------------
+# Variable: $verbose
+# Description: The verbosity indicator.
+#
+my $verbose = 0;
+
+#------------------------------------------------------------------------------
+# Variable: $method
+# Description: The validation or submit indicator.
+#
+my $method = VALIDATE;
+
+#------------------------------------------------------------------------------
+# Variable: $debug
+# Description: The debug indicator.
+#
+my $debug = 0;
+
+#------------------------------------------------------------------------------
+# Variable: $config
+# Description: The name of the configuration file.
+#
+my $config = undef;
+
+#------------------------------------------------------------------------------
+# Variable: @fields
+# Description:
+#
+my %fields = ();
+
+#------------------------------------------------------------------------------
+# Variable: @parameter
+# Description: The list of fields
+#
+my @parameter = ();
+
+use Getopt::Long;
+GetOptions(
+ "config=s" => \$config,
+ "pkg=s" => \$config,
+ "package=s" => \$config,
+ "debug" => \$debug,
+ "h|help" => \&usage,
+ "increment" => sub { $method = INCREMENT },
+ "init" => sub { $method = NEW_CONFIG },
+ "n|noaction" => sub { $method = VALIDATE; },
+ "submit" => sub { $method = UPLOAD; },
+ "v|verbose" => \$verbose,
+ "version" => sub { print STDOUT VERSION,"\n"; exit(0); },
+ "validate" => sub { $method = VALIDATE; },
+);
+
+my $UPLOAD_URL = $CTAN_URL . 'upload';
+my $VALIDATE_URL = $CTAN_URL . 'validate';
+my $FIELDS_URL = $CTAN_URL . 'fields';
+
+$config = $ARGV[0] if defined $ARGV[0];
+if ( not defined $config ) {
+ $config = cwd();
+ $config =~ s|.*[/\\]||;
+ $config = $config . '.pkg';
+}
+
+fields();
+
+if ( $method == NEW_CONFIG ) {
+ new_config();
+} elsif ( $method == INCREMENT ) {
+ increment_config();
+} else {
+ upload( read_config() );
+}
+
+#------------------------------------------------------------------------------
+# Function: upload
+# Arguments: none
+# Description:
+#
+sub upload {
+ my $f = shift;
+
+ print STDERR "Uploading to CTAN..." if $verbose;
+ my $service_url = $UPLOAD_URL;
+ $service_url = $VALIDATE_URL if $method == VALIDATE;
+ my $ua = LWP::UserAgent->new();
+ my $request = POST $service_url,
+ Content_Type => 'multipart/form-data',
+ Content => $f;
+ print STDERR "done\n" if $verbose;
+ my $response = $ua->request($request);
+
+ die format_errors( $response->decoded_content, $response->status_line ),
+ "\n"
+ if not $response->is_success;
+
+ if ( $method == VALIDATE and $response->decoded_content eq '[]' ) {
+ print "ok\n";
+ }
+ else {
+ print format_errors( $response->decoded_content, 'ok' ), "\n"
+ }
+}
+
+#------------------------------------------------------------------------------
+# Function: format_errors
+# Arguments:
+# $json the JSON list with the messages
+# $fallback the fallback message if the first parameter is empty
+# Description:
+#
+sub format_errors {
+ local $_ = shift;
+ if ( $_ eq '' ) {
+ return shift;
+ }
+ s/^\[*\"//g;
+ s/\]$//g;
+ my @a = map {
+ s/^ERROR\",\"/*** ERROR: /g;
+ s/^WARNING\",\"/+++ WARNING: /g;
+ s/^INFO\",\"/--- INFO: /g;
+ s/\",\"/ /g;
+ s/\"\]$//g;
+ $_
+ } split /\"\],\[\"/;
+ return join( "\n", @a );
+}
+
+#------------------------------------------------------------------------------
+# Function: fields
+# Arguments: none
+# Description:
+#
+sub fields {
+ print STDERR "Retrieving fields from CTAN..." if $verbose;
+ print STDERR $FIELDS_URL if $debug;
+ my $response;
+ eval {
+ my $ua = LWP::UserAgent->new();
+ my $request = GET $FIELDS_URL;
+ print STDERR "done\n" if $verbose;
+ $response = $ua->request($request);
+ };
+
+ die format_errors( $response->decoded_content, $response->status_line ),
+ "\n"
+ if not $response->is_success;
+
+ local $_ = $response->decoded_content;
+ print STDERR $response->decoded_content, "\n\n" if $debug;
+ while (m/\"([a-z0-9]+)\":\{([^{}]*)\}/i) {
+ my $f = $1;
+ my %a = ();
+ $_ = $';
+ my $attr = $2;
+ while ( $attr =~ m/\"([a-z0-9]+)\":([a-z0-9]+|"[^"]*")/i ) {
+ $attr = $';
+ $a{$1} = $2;
+ $a{$1} =~ s/(^"|"$)//g;
+ }
+ $fields{$f} = \%a;
+ push @parameter, $f;
+ }
+}
+
+#------------------------------------------------------------------------------
+# Function: read_config
+# Arguments:
+# Description:
+#
+sub read_config {
+ my %cfg = ();
+ my $fd = new FileHandle($config)
+ || die "*** Configuration file `$config' could not be read.\n";
+ my $slurp = undef;
+ local $_;
+
+ while (<$fd>) {
+ s/^[ \t]*%.*//;
+ s/([^\\])%.*/$1/;
+ while (m/\\([a-z]+)/i) {
+ $_ = $';
+ if ( $1 eq 'begin' ) {
+ die "$config: missing {environment} instead of $_\n"
+ if not m/^[ \t]*\{([a-z]*)\}/i;
+ my $tag = $1;
+ my $val = '';
+ $_ = $';
+ while ( not m/\\end\{$tag\}/ ) {
+ $val .= $_;
+ $_ = <$fd>;
+ die "$config: unexpected end of file while searching end of $tag\n"
+ if not defined $_;
+ }
+ $val .= $`;
+ $val =~ s/^[ \t\n\r]*//m;
+ $val =~ s/[ \t\n\r]*$//m;
+ $cfg{$tag} = $val;
+ $_ = $';
+ }
+ elsif ( $1 eq 'endinput' ) {
+ last;
+ }
+ elsif ( defined $fields{$1} ) {
+ my $key = $1;
+ die "$config: missing {environment} instead of $_\n"
+ if not m/^[ \t]*\{([^{}]*)\}/i;
+
+ if ( $key eq 'file' ) {
+ $cfg{$key} = [$1];
+ }
+ else { $cfg{$key} = $1; }
+ $_ = $';
+ }
+ else {
+ die "$config: undefined keyword $&\n";
+ }
+ s/^[ \t]*%.*//;
+ }
+ }
+ $fd->close();
+ return \%cfg;
+}
+
+#------------------------------------------------------------------------------
+# Function: increment_config
+# Arguments: none
+# Description:
+#
+sub increment_config {
+
+ my $modified = undef;
+ my $fd = new FileHandle($config)
+ || die "*** Configuration file `$config' could not be read.\n";
+ local $_;
+ my $content = '';
+
+ while (<$fd>) {
+ if (m/^[ \t]*%/) {
+ $content .= $_;
+ next;
+ }
+ if (m/\\version{([^}]*[^}0-9]*)([0-9]+)}/) {
+ $content .= $` . "\\version{$1" . ($2 + 1) . "}" . $';
+ $modified = 1;
+ next;
+ } else {
+ $content .= $_;
+ }
+ }
+ $fd->close();
+
+ if ($modified) {
+ rename $config, $config.'.bak';
+ $fd = new FileHandle($config,'w');
+ print $fd $content;
+ $fd->close();
+ }
+}
+
+#------------------------------------------------------------------------------
+# Function: new_config
+# Arguments: none
+# Description:
+#
+sub new_config {
+
+ print <<__EOF__;
+% This is a description file for ctan-o-mat.
+% It manages uploads of a package to
+% CTAN -- the Comprehensive TeX Archive Network.
+%
+% The syntax is roughly oriented towards (La)TeX.
+% Two form of the macros are used. The simple macros take one argument
+% in braces. Here the argument may not contain embedded macros.
+%
+% The second form uses an environment enclosed in \\begin{}/\\end{}.
+% In the long text fields logo macros can be used.
+%
+% You should enter your values between the begin and the end of the
+% named type.
+__EOF__
+ local $_;
+ foreach ( @parameter ) {
+ print <<__EOF__;
+% -------------------------------------------------------------------------
+% This field contains the $fields{$_}->{'text'}.
+__EOF__
+ if ( defined $fields{$_}->{'nullable'} ) {
+ print "% The value is optional.\n";
+ }
+ if ( defined $fields{$_}->{'url'} ) {
+ print "% The value is a URL.\n";
+ }
+ if ( defined $fields{$_}->{'email'} ) {
+ print "% The value is an email address.\n";
+ }
+ if ( defined $fields{$_}->{'file'} ) {
+ print
+ "% The value is the file name of the archive to be uploaded.\n";
+ print "% It may have a relative or absolute directory.\n";
+ }
+ if ( defined $fields{$_}->{'maxsize'} ) {
+ print "% The value is restricted to $fields{$_}->{'maxsize'} characters.\n";
+ }
+ if ( defined $fields{$_}->{'list'} ) {
+ print "% Multiple values are allowed.\n\\$_\{}\n";
+ }
+ elsif ( defined $fields{$_}->{'maxsize'}
+ and $fields{$_}->{'maxsize'} ne 'null'
+ and $fields{$_}->{'maxsize'} < 256 )
+ {
+ print "\\$_\{}\n";
+ }
+ else {
+ print "\\begin{$_}\\end{$_}\n";
+ }
+ }
+}
+
+#------------------------------------------------------------------------------
+# Local Variables:
+# mode: perl
+# End:
diff --git a/Build/source/texk/texlive/linked_scripts/scripts.lst b/Build/source/texk/texlive/linked_scripts/scripts.lst
index b10451b30e8..f500c48d4c1 100644
--- a/Build/source/texk/texlive/linked_scripts/scripts.lst
+++ b/Build/source/texk/texlive/linked_scripts/scripts.lst
@@ -49,6 +49,7 @@ crossrefware/bibdoiadd.pl
crossrefware/bibmradd.pl
crossrefware/bibzbladd.pl
crossrefware/ltx2crossrefxml.pl
+ctan-o-mat/ctan-o-mat.pl
ctanify/ctanify
ctanupload/ctanupload.pl
de-macro/de-macro
diff --git a/Master/bin/amd64-freebsd/ctan-o-mat b/Master/bin/amd64-freebsd/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/amd64-freebsd/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/amd64-netbsd/ctan-o-mat b/Master/bin/amd64-netbsd/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/amd64-netbsd/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/armel-linux/ctan-o-mat b/Master/bin/armel-linux/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/armel-linux/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/armhf-linux/ctan-o-mat b/Master/bin/armhf-linux/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/armhf-linux/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/i386-cygwin/ctan-o-mat b/Master/bin/i386-cygwin/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/i386-cygwin/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/i386-darwin/ctan-o-mat b/Master/bin/i386-darwin/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/i386-darwin/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/i386-freebsd/ctan-o-mat b/Master/bin/i386-freebsd/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/i386-freebsd/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/i386-linux/ctan-o-mat b/Master/bin/i386-linux/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/i386-linux/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/i386-netbsd/ctan-o-mat b/Master/bin/i386-netbsd/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/i386-netbsd/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/i386-solaris/ctan-o-mat b/Master/bin/i386-solaris/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/i386-solaris/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/powerpc-darwin/ctan-o-mat b/Master/bin/powerpc-darwin/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/powerpc-darwin/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/powerpc-linux/ctan-o-mat b/Master/bin/powerpc-linux/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/powerpc-linux/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/sparc-solaris/ctan-o-mat b/Master/bin/sparc-solaris/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/sparc-solaris/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/win32/ctan-o-mat.exe b/Master/bin/win32/ctan-o-mat.exe
new file mode 100755
index 00000000000..5777d90a17a
--- /dev/null
+++ b/Master/bin/win32/ctan-o-mat.exe
Binary files differ
diff --git a/Master/bin/x86_64-cygwin/ctan-o-mat b/Master/bin/x86_64-cygwin/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/x86_64-cygwin/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/x86_64-darwin/ctan-o-mat b/Master/bin/x86_64-darwin/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/x86_64-darwin/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/x86_64-darwinlegacy/ctan-o-mat b/Master/bin/x86_64-darwinlegacy/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/x86_64-darwinlegacy/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/x86_64-linux/ctan-o-mat b/Master/bin/x86_64-linux/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/x86_64-linux/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/bin/x86_64-solaris/ctan-o-mat b/Master/bin/x86_64-solaris/ctan-o-mat
new file mode 120000
index 00000000000..ed6a2d963c2
--- /dev/null
+++ b/Master/bin/x86_64-solaris/ctan-o-mat
@@ -0,0 +1 @@
+../../texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl \ No newline at end of file
diff --git a/Master/texmf-dist/doc/man/man1/ctan-o-mat.1 b/Master/texmf-dist/doc/man/man1/ctan-o-mat.1
new file mode 100644
index 00000000000..db9f74aa7a6
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/ctan-o-mat.1
@@ -0,0 +1,238 @@
+.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "CTAN-O-MAT 1"
+.TH CTAN-O-MAT 1 "2017-10-20" "ctan-o-mat" "Gerd Neugebauer"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+ctan\-o\-mat \- Upload or validate a package for CTAN
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+ctan-o-mat [options] [<package configuration>]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This program can be used to automate the upload of a package to \s-1CTAN\s0
+(https://www.ctan.org). The description of the package is contained in
+a configuration file. Thus it can be updated easily without the need
+to fill a Web form with the same old information.
+.PP
+The provided information is validated in any case. If the validation
+succeeds and not only the validation is requested then the provided
+archive file is placed in the incoming area of the \s-1CTAN\s0 for further
+processing by the \s-1CTAN\s0 team.
+.PP
+In any case any finding during the validation is reported at the end
+of the processing. Note that the validation is the default and a
+official submission has to be requested by the an appropriate command
+line option.
+.PP
+\&\fBctan-o-mat\fR requires an Internet connection to the \s-1CTAN\s0 server. Even the
+validation retrieves the known attributes and the basic constraints
+from the server.
+.SH "CONFIGURATION"
+.IX Header "CONFIGURATION"
+The default configuration is read from a file with the same name as
+the current directory an the extension .pkg. This file name can be
+overwritten on the command line.
+.PP
+The configuration depends on the features supported by the \s-1CTAN\s0 server.
+Since these features can change over time the configuration is not
+hard-coded in \fBctan-o-mat\fR. You can request a template of the
+configuration via the command line parameter \f(CW\*(C`\-init\*(C'\fR.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\-h" 4
+.IX Item "-h"
+.PD 0
+.IP "\-\-help" 4
+.IX Item "--help"
+.PD
+Print this short summary about the usage and exit the program.
+.IP "\-\-validate" 4
+.IX Item "--validate"
+.PD 0
+.IP "\-n" 4
+.IX Item "-n"
+.IP "\-\-noaction" 4
+.IX Item "--noaction"
+.PD
+Do not perform the final upload. The package is validated and the
+resulting messages are printed.
+.IP "\-i" 4
+.IX Item "-i"
+.PD 0
+.IP "\-\-init" 4
+.IX Item "--init"
+.PD
+Create an empty template for a configuration.
+.IP "\-s" 4
+.IX Item "-s"
+.PD 0
+.IP "\-\-submit" 4
+.IX Item "--submit"
+.PD
+Upload the submission, validate it and officially submit it to \s-1CTAN\s0 it the
+validation succeeds.
+.IP "\-v" 4
+.IX Item "-v"
+.PD 0
+.IP "\-\-verbose" 4
+.IX Item "--verbose"
+.PD
+Print some more information during the processing (verbose mode).
+.IP "\-\-version" 4
+.IX Item "--version"
+Print the version number of this program and exit.
+.IP "\-\-validate" 4
+.IX Item "--validate"
+Print some additional debugging information.
+.IP "<package>" 4
+.IX Item "<package>"
+This parameter is the name of a package configuration
+(see section \s-1CONFIGURATION\s0) contained in a file.
+.SH "CONNECTING VIA PROXIES"
+.IX Header "CONNECTING VIA PROXIES"
+If you need to connect to the Internet via a proxy then this can be achieved
+by setting some environment variables before running \fBctan-o-mat\fR.
+To redirect the request via the proxy simply define an environment variable
+\&\f(CW\*(C`http_proxy\*(C'\fR to point to the proxy host \*(-- including protocol and port as
+required. Note that the name of the environment variable is supposed to be in
+\&\fBlower\fR case.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Gerd Neugebauer (gene@gerd\-neugebauer.de)
+.SH "BUGS"
+.IX Header "BUGS"
+.IP "\(bu" 4
+The program can not be used without a working connection to the
+Internet.
diff --git a/Master/texmf-dist/doc/man/man1/ctan-o-mat.man1.pdf b/Master/texmf-dist/doc/man/man1/ctan-o-mat.man1.pdf
new file mode 100644
index 00000000000..44974f9e388
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/ctan-o-mat.man1.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/LICENSE b/Master/texmf-dist/doc/support/ctan-o-mat/LICENSE
new file mode 100644
index 00000000000..f2b8136dbec
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2016-2017, Gerd Neugebauer
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of ctan-o-mat nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/README.md b/Master/texmf-dist/doc/support/ctan-o-mat/README.md
new file mode 100644
index 00000000000..964d1690ac2
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/README.md
@@ -0,0 +1,136 @@
+# ctan-o-mat - Upload or validate a package for CTAN
+
+## SYNOPSIS
+
+```
+ctan-o-mat [options] [<package configuration>]
+```
+
+## DESCRIPTION
+
+This program can be used to automate the upload of a package to CTAN
+(https://www.ctan.org). The description of the package is contained in
+a configuration file. Thus it can be updated easily without the need
+to fill a Web form with the same old information.
+
+The provided information is validated in any case. If the validation
+succeeds and not only the validation is requested then the provided
+archive file is placed in the incoming area of the CTAN for further
+processing by the CTAN team.
+
+In any case any finding during the validation is reported at the end
+of the processing. Note that the validation is the default and a
+official submission has to be requested by the an appropriate command
+line option.
+
+*ctan-o-mat* requires an Internet connection to the CTAN server. Even the
+validation retrieves the known attributes and the basic constraints
+from the server.
+
+
+## CONFIGURATION
+
+The default configuration is read from a file with the same name as
+the current directory an the extension `.pkg`. This file name can be
+overwritten on the command line.
+
+The configuration depends on the features supported by the CTAN server.
+Since these features can change over time the configuration is not
+hard-coded in *ctan-o-mat*. You can request a template of the
+configuration via the command line parameter `-init`.
+
+
+## OPTIONS
+
+<dl>
+ <dt><code>-h</code></dt>
+ <dt><code>--help</code></dt>
+ <dd>
+ Print this short summary about the usage and exit the program.
+ </dd>
+
+ <dt><code>--validate</code></dt>
+ <dt><code>-n</code></dt>
+ <dt><code>--noaction</code></dt>
+ <dd>
+ Do not perform the final upload. The package is validated and the
+ resulting messages are printed.
+ </dd>
+
+ <dt><code>-i</code></dt>
+ <dt><code>--init</code></dt>
+ <dd>
+ Create an empty template for a configuration.
+ </dd>
+
+ <dt><code>-s</code></dt>
+ <dt><code>--submit</code></dt>
+ <dd>
+ Upload the submission, validate it and officially submit it to
+ CTAN it the validation succeeds.
+ </dd>
+
+ <dt><code>-v</code></dt>
+ <dt><code>--verbose</code></dt>
+ <dd>
+ Print some more information during the processing (verbose mode).
+ </dd>
+
+ <dt><code>--version</code></dt>
+ <dd>
+ Print the version number of this program and exit.
+ </dd>
+
+ <dt><code>--validate</code></dt>
+ <dd>
+ Print some additional debugging information.
+ </dd>
+
+ <dt>&lt;package&gt;</dt>
+ <dd>
+ This parameter is the name of a package configuration
+ (see section CONFIGURATION) contained in a file.
+ </dd>
+</dl>
+
+## CONNECTING VIA PROXIES
+
+If you need to connect to the Internet via a proxy then this can be achieved
+by setting some environment variables before running *ctan-o-mat*.
+To redirect the request via the proxy simply define an environment variable
+`http_proxy` to point to the proxy host -- including protocol and port as
+required. Note that the name of the environment variable is supposed to be in *lower* case.
+
+
+## INSTALLATION
+
+### PREREQUISITE: PERL
+
+*ctan-o-mat* is written in Perl. Thus a Perl interpreter has to be installed,
+at least in version 5. It is assumed that the Perl interpreter is reachable
+under the name `perl` on the program path.
+
+
+### PREREQUISITE: LWP
+
+*ctan-o-mat* uses the LWP bundle to connect to the remote server and such.
+Thus it has to be installed. With the help of Perl you can install it with
+the following command line:
+
+```
+perl -MCPAN -e 'install Bundle::LWP'
+```
+
+You might want to check whether LWP can be installed with your package manager. In this case this is the preferred way.
+
+### INSTALLATION STEPS
+
+The installation is straight forward. Just put the file `ctan-o-mat.pl` and one of `ctan-o-mat` or `ctan-o-mat.bat` on your path.
+
+Make sure that these files are executable (if required). Now you are done.
+
+
+## AUTHOR
+
+[Gerd Neugebauer](mailto:gene@gerd-neugebauer.de)
+
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat b/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat
new file mode 100755
index 00000000000..664abc2d647
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat
@@ -0,0 +1,21 @@
+#/bin/sh
+##-----------------------------------------------------------------------------
+## This file is part of ctan-o-mat.
+## This program is distributed under BSD-like license. See file LICENSE
+##
+## (c) 2016-2017 Gerd Neugebauer
+##
+## Net: gene@gerd-neugebauer.de
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of a 3-clause BSD-like license as stated in the
+## file LICENSE contained in this distribution.
+##
+## You should have received a copy of the LICENSE along with this
+## program; if not, see the repository under http://***.
+##
+##-----------------------------------------------------------------------------
+
+exec perl $0.pl $*
+
+# \ No newline at end of file
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat.pkg b/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat.pkg
new file mode 100644
index 00000000000..16353d467e0
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat.pkg
@@ -0,0 +1,131 @@
+% This is a description file for ctan-o-mat.
+% It manages uploads of a package to
+% CTAN -- the Comprehensive TeX Archive Network.
+%
+% The syntax is roughly oriented towards (La)TeX.
+% Two form of the macros are used. The simple macros take one argument
+% in braces. Here the argument may not contain embedded macros.
+%
+% The second form uses an environment enclosed in \begin{}/\end{}.
+% In the long text fields logo macros can be used.
+%
+% You should enter your values between the begin and the end of the
+% named type.
+% -------------------------------------------------------------------------
+% This field contains the CTAN id of the package.
+% The value is optional.
+% The value is restricted to 32 characters.
+\pkg{ctan-o-mat}
+% -------------------------------------------------------------------------
+% This field contains the version of the package.
+% The value is optional.
+% The value is restricted to 32 characters.
+\version{1.0}
+% -------------------------------------------------------------------------
+% This field contains the name of the author(s).
+% The value is optional.
+% The value is restricted to 128 characters.
+\author{Gerd Neugebauer}
+% -------------------------------------------------------------------------
+% This field contains the email address of the uploader.
+% The value is an email address.
+% The value is restricted to 255 characters.
+\email{gene@gerd-neugebauer.de}
+% -------------------------------------------------------------------------
+% This field contains the name of the uploader.
+% The value is restricted to 255 characters.
+\uploader{Gerd Neugebauer}
+% -------------------------------------------------------------------------
+% This field contains the directory on CTAN.
+% The value is optional.
+% The value is restricted to 255 characters.
+\ctanPath{/support/ctan-o-mat}
+% -------------------------------------------------------------------------
+% This field contains the license.
+% The value is optional.
+% The value is restricted to 2048 characters.
+% Multiple values are allowed.
+\license{bsd3}
+% -------------------------------------------------------------------------
+% This field contains the URL of the home page.
+% The value is optional.
+% The value is a URL.
+% The value is restricted to 255 characters.
+% Multiple values are allowed.
+\home{https://github.com/ge-ne/ctan-o-mat}
+% -------------------------------------------------------------------------
+% This field contains the URL of the bug tracker.
+% The value is optional.
+% The value is a URL.
+% The value is restricted to 255 characters.
+% Multiple values are allowed.
+\bugtracker{https://github.com/ge-ne/ctan-o-mat/issues}
+% -------------------------------------------------------------------------
+% This field contains the support channel.
+% The value is optional.
+% The value is a URL.
+% The value is restricted to 255 characters.
+% Multiple values are allowed.
+\support{}
+% -------------------------------------------------------------------------
+% This field contains the version management.
+% The value is optional.
+% The value is a URL.
+% The value is restricted to 255 characters.
+% Multiple values are allowed.
+\repository{https://github.com/ge-ne/ctan-o-mat}
+% -------------------------------------------------------------------------
+% This field contains the developer's channel.
+% The value is optional.
+% The value is a URL.
+% The value is restricted to 255 characters.
+% Multiple values are allowed.
+\development{}
+% -------------------------------------------------------------------------
+% This field contains the update indicator; true for update.
+% The value is optional.
+% The value is restricted to 8 characters.
+\update{false}
+% -------------------------------------------------------------------------
+% This field contains the topics id.
+% The value is optional.
+% The value is restricted to 1024 characters.
+% Multiple values are allowed.
+\topic{ctan}
+% -------------------------------------------------------------------------
+% This field contains the text for the mail announcement.
+% The value is optional.
+% The value is restricted to 8192 characters.
+\begin{announcement}
+This program can be used to automate the upload of a package to CTAN.
+The description of the package is contained in a configuration file.
+
+The provided information is validated in any case. If the validation
+succeeds and not only the validation is requested then the provided
+archive file is placed in the incoming area of the CTAN for further
+processing by the CTAN team.
+
+In any case any finding during the validation is reported at the end
+of the processing. Note that the validation is the default and a
+official submission has to be requested by the an appropriate command
+line option.
+
+ctan-o-mat requires an Internet connection to the CTAN server. Even the
+validation retrieves the known attributes and the basic constraints
+from the server.
+\end{announcement}
+% -------------------------------------------------------------------------
+% This field contains the one-liner for the package.
+% The value is optional.
+% The value is restricted to 4096 characters.
+\begin{description}Upload or validate a package for CTAN\end{description}
+% -------------------------------------------------------------------------
+% This field contains the note to the CTAN upload managers.
+% The value is optional.
+% The value is restricted to 2048 characters.
+\begin{note}\end{note}
+% -------------------------------------------------------------------------
+% This field contains the archive file.
+% The value is the file name of the archive to be uploaded.
+% It may have a relative or absolute directory.
+\file{ctan-o-mat.zip}
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/lib/md2ltx.pl b/Master/texmf-dist/doc/support/ctan-o-mat/lib/md2ltx.pl
new file mode 100755
index 00000000000..53b4cffa17b
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/lib/md2ltx.pl
@@ -0,0 +1,146 @@
+#!/usr/bin/perl -w
+##-----------------------------------------------------------------------------
+## This file is part of ctan-o-mat.
+## This program is distributed under BSD-like license. See file LICENSE
+##
+## (c) 2016-2017 Gerd Neugebauer
+##
+## Net: gene@gerd-neugebauer.de
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of a 3-clause BSD-like license as stated in the file
+## LICENSE contained in this distribution.
+##
+## You should have received a copy of the LICENSE along with this program; if
+## not, see the repository under https://github.com/ge-ne/ctan-o-mat.
+##
+##-----------------------------------------------------------------------------
+
+use strict;
+
+use constant MODE_NORMAL => 0;
+use constant MODE_PRE => 1;
+use constant MODE_AUTHOR => 10;
+
+#------------------------------------------------------------------------------
+# Function: usage
+# Arguments: none
+# Returns: nothing
+# Description: Print the POD to stderr and exit
+#
+sub usage {
+ use Pod::Text;
+ Pod::Text->new()
+ ->parse_from_filehandle( new FileHandle( $0, 'r' ), \*STDERR );
+ exit(0);
+}
+
+#------------------------------------------------------------------------------
+# Variable: $verbose
+# Description: The verbosity indicator.
+#
+my $verbose = 0;
+
+my $version = '';
+
+use Getopt::Long;
+GetOptions(
+ "h|help" => \&usage,
+ "version=s" => \$version,
+ "v|verbose" => \$verbose,
+);
+
+my $mode = MODE_NORMAL;
+my $body = '';
+my $author = '';
+my $title = '';
+
+
+while(<>) {
+ if (m/## AUTHOR/) {
+ $mode = MODE_AUTHOR;
+ next;
+ }
+ if ($mode == MODE_AUTHOR) {
+
+ if (m/^##/) {
+ $mode = MODE_NORMAL;
+ } else {
+ $author .= $_;
+ next;
+ }
+ }
+ next if m|</dd>|;
+ if (m/^```/) {
+ if ($mode == MODE_NORMAL) {
+ $mode = MODE_PRE;
+ $body .= "\\begin{verbatim}\n";
+ } else {
+ $mode = MODE_NORMAL;
+ $body .= "\\end{verbatim}\n";
+ }
+ next
+ }
+ $_ = "\\subsection*{".ucfirst(lc($1))."}\\label{$1}" if m/^### (.*)/;
+ $_ = "\\section*{".ucfirst(lc($1))."}\\label{$1}" if m/^## (.*)/;
+ if (m/^# (.*)/) {
+ $title = $1;
+ $title =~ s/--/\\\\/;
+ next;
+ }
+ $_ = "$`see section~\\ref{$1}$'" if m/see section ([a-z0-9]*)/i;
+ while (m/`([^`]+)`/) {
+ $_ = "$`\\texttt{$1}$'";
+ }
+ while (m/\*([^*]+)\*/) {
+ $_ = "$`\\textbf{$1}$'";
+ }
+ s/<dl>/\\begin{description}/;
+ s/<\/dl>/\\end{description}/;
+ s/<code>(.*)<\/code>/\\texttt{$1}/;
+ s/<dt>(.*)<\/dt>/\\item[$1]/;
+ s/<dd>/\\ \\\\/;
+ s/ - / -- /;
+ s/&gt;/\\(>\\)/;
+ s/&lt;/\\(<\\)/;
+ s/_/\\_/g;
+ s|https?://[.a-z\/]*|\\url{$&}|;
+ $body .= $_;
+}
+
+my $author_long = '';
+my $subject = '';
+if ($title =~ m/ +-+ +/) {
+ $title = $`;
+ $subject = $';
+}
+if ($author =~ m/\[([a-z0-9.,:; ]*)\]\(([^()]*)\)/i) {
+ $author = $1;
+ $author_long = "$1 ($2)";
+}
+
+print <<__EOF__;
+\\documentclass[a4paper,12pt]{scrartcl}
+\\usepackage[urlcolor=blue,urlbordercolor={.85 .85 1}]{hyperref}
+\\date{}
+\\hypersetup{
+ pdfinfo={
+ Title={$title},
+ Subject={$subject},
+ Author={$author}
+ }
+}
+
+\\author{$author_long}
+\\title{$title\\thanks{This document describes \textbf{$title} version $version}\\\\$subject}
+\\begin{document}
+\\maketitle
+
+$body
+\\end{document}
+__EOF__
+
+#------------------------------------------------------------------------------
+# Local Variables:
+# mode: perl
+# End:
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/makefile b/Master/texmf-dist/doc/support/ctan-o-mat/makefile
new file mode 100644
index 00000000000..cabe9d8d145
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/makefile
@@ -0,0 +1,32 @@
+#******************************************************************************
+#* (c) 2017 Gerd Neugebauer
+#*=============================================================================
+
+FILES = ctan-o-mat \
+ ctan-o-mat.bat \
+ ctan-o-mat.pl \
+ ctan-o-mat.pkg \
+ LICENSE \
+ README.md \
+ makefile \
+ ctan-o-mat.pdf \
+ lib/md2ltx.pl
+
+VERSION = `ctan-o-mat --version`
+
+all:
+
+clean:
+ $(RM) -f *~ *.out *.log *.aux ctan-o-mat.ltx
+
+ctan-o-mat.pdf: README.md makefile lib/md2ltx.pl
+ @perl lib/md2ltx.pl --version "$(VERSION)" README.md > ctan-o-mat.ltx
+ @xelatex -interaction=batchmode ctan-o-mat.ltx > /dev/null
+ @xelatex -interaction=batchmode ctan-o-mat.ltx
+ @$(RM) ctan-o-mat.out ctan-o-mat.aux ctan-o-mat.log
+
+dist ctan-o-mat.zip: $(FILES)
+ $(RM) ctan-o-mat.zip
+ (cd ..; zip ctan-o-mat/ctan-o-mat.zip $(addprefix ctan-o-mat/,$(FILES)))
+
+#
diff --git a/Master/texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl b/Master/texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl
new file mode 100755
index 00000000000..1463743432b
--- /dev/null
+++ b/Master/texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl
@@ -0,0 +1,495 @@
+#!/usr/bin/perl -w
+##-----------------------------------------------------------------------------
+## This file is part of ctan-o-mat.
+## This program is distributed under BSD-like license. See file LICENSE
+##
+## (c) 2016-2017 Gerd Neugebauer
+##
+## Net: gene@gerd-neugebauer.de
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of a 3-clause BSD-like license as stated in the file
+## LICENSE contained in this distribution.
+##
+## You should have received a copy of the LICENSE along with this program; if
+## not, see the repository under https://github.com/ge-ne/ctan-o-mat.
+##
+##-----------------------------------------------------------------------------
+
+=head1 NAME
+
+ctan-o-mat - Upload or validate a package for CTAN
+
+=head1 SYNOPSIS
+
+ctan-o-mat [options] [<package configuration>]
+
+=head1 DESCRIPTION
+
+This program can be used to automate the upload of a package to CTAN
+(https://www.ctan.org). The description of the package is contained in
+a configuration file. Thus it can be updated easily without the need
+to fill a Web form with the same old information.
+
+The provided information is validated in any case. If the validation
+succeeds and not only the validation is requested then the provided
+archive file is placed in the incoming area of the CTAN for further
+processing by the CTAN team.
+
+In any case any finding during the validation is reported at the end
+of the processing. Note that the validation is the default and a
+official submission has to be requested by the an appropriate command
+line option.
+
+B<ctan-o-mat> requires an Internet connection to the CTAN server. Even the
+validation retrieves the known attributes and the basic constraints
+from the server.
+
+
+=head1 CONFIGURATION
+
+The default configuration is read from a file with the same name as
+the current directory an the extension .pkg. This file name can be
+overwritten on the command line.
+
+The configuration depends on the features supported by the CTAN server.
+Since these features can change over time the configuration is not
+hard-coded in B<ctan-o-mat>. You can request a template of the
+configuration via the command line parameter C<-init>.
+
+
+=head1 OPTIONS
+
+=over 4
+
+=item -h
+
+=item --help
+
+Print this short summary about the usage and exit the program.
+
+=item --validate
+
+=item -n
+
+=item --noaction
+
+Do not perform the final upload. The package is validated and the
+resulting messages are printed.
+
+=item -i
+
+=item --init
+
+Create an empty template for a configuration.
+
+=item -s
+
+=item --submit
+
+Upload the submission, validate it and officially submit it to CTAN it the
+validation succeeds.
+
+=item -v
+
+=item --verbose
+
+Print some more information during the processing (verbose mode).
+
+=item --version
+
+Print the version number of this program and exit.
+
+=item --validate
+
+Print some additional debugging information.
+
+=item <package>
+
+This parameter is the name of a package configuration
+(see section CONFIGURATION) contained in a file.
+
+=back
+
+=head1 CONNECTING VIA PROXIES
+
+If you need to connect to the Internet via a proxy then this can be achieved
+by setting some environment variables before running B<ctan-o-mat>.
+To redirect the request via the proxy simply define an environment variable
+C<http_proxy> to point to the proxy host -- including protocol and port as
+required. Note that the name of the environment variable is supposed to be in
+B<lower> case.
+
+
+=head1 AUTHOR
+
+Gerd Neugebauer (gene@gerd-neugebauer.de)
+
+=head1 BUGS
+
+=over 4
+
+=item *
+
+The program can not be used without a working connection to the
+Internet.
+
+=back
+
+=cut
+
+use strict;
+use FileHandle;
+use File::Basename;
+use Cwd;
+
+use LWP::UserAgent;
+use LWP::Protocol::https;
+use HTTP::Request::Common;
+
+use constant VERSION => '1.0';
+
+use constant NEW_CONFIG => 0;
+use constant UPLOAD => 1;
+use constant VALIDATE => 2;
+use constant INCREMENT => 3;
+
+my $CTAN_URL = 'http://localhost:8080/submit/';
+
+#------------------------------------------------------------------------------
+# Function: usage
+# Arguments: none
+# Returns: nothing
+# Description: Print the POD to stderr and exit
+#
+sub usage {
+ use Pod::Text;
+ Pod::Text->new()
+ ->parse_from_filehandle( new FileHandle( $0, 'r' ), \*STDERR );
+ exit(0);
+}
+
+#------------------------------------------------------------------------------
+# Variable: $verbose
+# Description: The verbosity indicator.
+#
+my $verbose = 0;
+
+#------------------------------------------------------------------------------
+# Variable: $method
+# Description: The validation or submit indicator.
+#
+my $method = VALIDATE;
+
+#------------------------------------------------------------------------------
+# Variable: $debug
+# Description: The debug indicator.
+#
+my $debug = 0;
+
+#------------------------------------------------------------------------------
+# Variable: $config
+# Description: The name of the configuration file.
+#
+my $config = undef;
+
+#------------------------------------------------------------------------------
+# Variable: @fields
+# Description:
+#
+my %fields = ();
+
+#------------------------------------------------------------------------------
+# Variable: @parameter
+# Description: The list of fields
+#
+my @parameter = ();
+
+use Getopt::Long;
+GetOptions(
+ "config=s" => \$config,
+ "pkg=s" => \$config,
+ "package=s" => \$config,
+ "debug" => \$debug,
+ "h|help" => \&usage,
+ "increment" => sub { $method = INCREMENT },
+ "init" => sub { $method = NEW_CONFIG },
+ "n|noaction" => sub { $method = VALIDATE; },
+ "submit" => sub { $method = UPLOAD; },
+ "v|verbose" => \$verbose,
+ "version" => sub { print STDOUT VERSION,"\n"; exit(0); },
+ "validate" => sub { $method = VALIDATE; },
+);
+
+my $UPLOAD_URL = $CTAN_URL . 'upload';
+my $VALIDATE_URL = $CTAN_URL . 'validate';
+my $FIELDS_URL = $CTAN_URL . 'fields';
+
+$config = $ARGV[0] if defined $ARGV[0];
+if ( not defined $config ) {
+ $config = cwd();
+ $config =~ s|.*[/\\]||;
+ $config = $config . '.pkg';
+}
+
+fields();
+
+if ( $method == NEW_CONFIG ) {
+ new_config();
+} elsif ( $method == INCREMENT ) {
+ increment_config();
+} else {
+ upload( read_config() );
+}
+
+#------------------------------------------------------------------------------
+# Function: upload
+# Arguments: none
+# Description:
+#
+sub upload {
+ my $f = shift;
+
+ print STDERR "Uploading to CTAN..." if $verbose;
+ my $service_url = $UPLOAD_URL;
+ $service_url = $VALIDATE_URL if $method == VALIDATE;
+ my $ua = LWP::UserAgent->new();
+ my $request = POST $service_url,
+ Content_Type => 'multipart/form-data',
+ Content => $f;
+ print STDERR "done\n" if $verbose;
+ my $response = $ua->request($request);
+
+ die format_errors( $response->decoded_content, $response->status_line ),
+ "\n"
+ if not $response->is_success;
+
+ if ( $method == VALIDATE and $response->decoded_content eq '[]' ) {
+ print "ok\n";
+ }
+ else {
+ print format_errors( $response->decoded_content, 'ok' ), "\n"
+ }
+}
+
+#------------------------------------------------------------------------------
+# Function: format_errors
+# Arguments:
+# $json the JSON list with the messages
+# $fallback the fallback message if the first parameter is empty
+# Description:
+#
+sub format_errors {
+ local $_ = shift;
+ if ( $_ eq '' ) {
+ return shift;
+ }
+ s/^\[*\"//g;
+ s/\]$//g;
+ my @a = map {
+ s/^ERROR\",\"/*** ERROR: /g;
+ s/^WARNING\",\"/+++ WARNING: /g;
+ s/^INFO\",\"/--- INFO: /g;
+ s/\",\"/ /g;
+ s/\"\]$//g;
+ $_
+ } split /\"\],\[\"/;
+ return join( "\n", @a );
+}
+
+#------------------------------------------------------------------------------
+# Function: fields
+# Arguments: none
+# Description:
+#
+sub fields {
+ print STDERR "Retrieving fields from CTAN..." if $verbose;
+ print STDERR $FIELDS_URL if $debug;
+ my $response;
+ eval {
+ my $ua = LWP::UserAgent->new();
+ my $request = GET $FIELDS_URL;
+ print STDERR "done\n" if $verbose;
+ $response = $ua->request($request);
+ };
+
+ die format_errors( $response->decoded_content, $response->status_line ),
+ "\n"
+ if not $response->is_success;
+
+ local $_ = $response->decoded_content;
+ print STDERR $response->decoded_content, "\n\n" if $debug;
+ while (m/\"([a-z0-9]+)\":\{([^{}]*)\}/i) {
+ my $f = $1;
+ my %a = ();
+ $_ = $';
+ my $attr = $2;
+ while ( $attr =~ m/\"([a-z0-9]+)\":([a-z0-9]+|"[^"]*")/i ) {
+ $attr = $';
+ $a{$1} = $2;
+ $a{$1} =~ s/(^"|"$)//g;
+ }
+ $fields{$f} = \%a;
+ push @parameter, $f;
+ }
+}
+
+#------------------------------------------------------------------------------
+# Function: read_config
+# Arguments:
+# Description:
+#
+sub read_config {
+ my %cfg = ();
+ my $fd = new FileHandle($config)
+ || die "*** Configuration file `$config' could not be read.\n";
+ my $slurp = undef;
+ local $_;
+
+ while (<$fd>) {
+ s/^[ \t]*%.*//;
+ s/([^\\])%.*/$1/;
+ while (m/\\([a-z]+)/i) {
+ $_ = $';
+ if ( $1 eq 'begin' ) {
+ die "$config: missing {environment} instead of $_\n"
+ if not m/^[ \t]*\{([a-z]*)\}/i;
+ my $tag = $1;
+ my $val = '';
+ $_ = $';
+ while ( not m/\\end\{$tag\}/ ) {
+ $val .= $_;
+ $_ = <$fd>;
+ die "$config: unexpected end of file while searching end of $tag\n"
+ if not defined $_;
+ }
+ $val .= $`;
+ $val =~ s/^[ \t\n\r]*//m;
+ $val =~ s/[ \t\n\r]*$//m;
+ $cfg{$tag} = $val;
+ $_ = $';
+ }
+ elsif ( $1 eq 'endinput' ) {
+ last;
+ }
+ elsif ( defined $fields{$1} ) {
+ my $key = $1;
+ die "$config: missing {environment} instead of $_\n"
+ if not m/^[ \t]*\{([^{}]*)\}/i;
+
+ if ( $key eq 'file' ) {
+ $cfg{$key} = [$1];
+ }
+ else { $cfg{$key} = $1; }
+ $_ = $';
+ }
+ else {
+ die "$config: undefined keyword $&\n";
+ }
+ s/^[ \t]*%.*//;
+ }
+ }
+ $fd->close();
+ return \%cfg;
+}
+
+#------------------------------------------------------------------------------
+# Function: increment_config
+# Arguments: none
+# Description:
+#
+sub increment_config {
+
+ my $modified = undef;
+ my $fd = new FileHandle($config)
+ || die "*** Configuration file `$config' could not be read.\n";
+ local $_;
+ my $content = '';
+
+ while (<$fd>) {
+ if (m/^[ \t]*%/) {
+ $content .= $_;
+ next;
+ }
+ if (m/\\version{([^}]*[^}0-9]*)([0-9]+)}/) {
+ $content .= $` . "\\version{$1" . ($2 + 1) . "}" . $';
+ $modified = 1;
+ next;
+ } else {
+ $content .= $_;
+ }
+ }
+ $fd->close();
+
+ if ($modified) {
+ rename $config, $config.'.bak';
+ $fd = new FileHandle($config,'w');
+ print $fd $content;
+ $fd->close();
+ }
+}
+
+#------------------------------------------------------------------------------
+# Function: new_config
+# Arguments: none
+# Description:
+#
+sub new_config {
+
+ print <<__EOF__;
+% This is a description file for ctan-o-mat.
+% It manages uploads of a package to
+% CTAN -- the Comprehensive TeX Archive Network.
+%
+% The syntax is roughly oriented towards (La)TeX.
+% Two form of the macros are used. The simple macros take one argument
+% in braces. Here the argument may not contain embedded macros.
+%
+% The second form uses an environment enclosed in \\begin{}/\\end{}.
+% In the long text fields logo macros can be used.
+%
+% You should enter your values between the begin and the end of the
+% named type.
+__EOF__
+ local $_;
+ foreach ( @parameter ) {
+ print <<__EOF__;
+% -------------------------------------------------------------------------
+% This field contains the $fields{$_}->{'text'}.
+__EOF__
+ if ( defined $fields{$_}->{'nullable'} ) {
+ print "% The value is optional.\n";
+ }
+ if ( defined $fields{$_}->{'url'} ) {
+ print "% The value is a URL.\n";
+ }
+ if ( defined $fields{$_}->{'email'} ) {
+ print "% The value is an email address.\n";
+ }
+ if ( defined $fields{$_}->{'file'} ) {
+ print
+ "% The value is the file name of the archive to be uploaded.\n";
+ print "% It may have a relative or absolute directory.\n";
+ }
+ if ( defined $fields{$_}->{'maxsize'} ) {
+ print "% The value is restricted to $fields{$_}->{'maxsize'} characters.\n";
+ }
+ if ( defined $fields{$_}->{'list'} ) {
+ print "% Multiple values are allowed.\n\\$_\{}\n";
+ }
+ elsif ( defined $fields{$_}->{'maxsize'}
+ and $fields{$_}->{'maxsize'} ne 'null'
+ and $fields{$_}->{'maxsize'} < 256 )
+ {
+ print "\\$_\{}\n";
+ }
+ else {
+ print "\\begin{$_}\\end{$_}\n";
+ }
+ }
+}
+
+#------------------------------------------------------------------------------
+# Local Variables:
+# mode: perl
+# End:
diff --git a/Master/texmf-dist/source/support/ctan-o-mat/ctan-o-mat.bat b/Master/texmf-dist/source/support/ctan-o-mat/ctan-o-mat.bat
new file mode 100755
index 00000000000..14aa5ff188b
--- /dev/null
+++ b/Master/texmf-dist/source/support/ctan-o-mat/ctan-o-mat.bat
@@ -0,0 +1,21 @@
+@echo off
+@rem --------------------------------------------------------------------------
+@rem This file is part of ctan-o-mat.
+@rem This program is distributed under BSD-like license. See file LICENSE
+@rem
+@rem (c) 2016-2017 Gerd Neugebauer
+@rem
+@rem Net: gene@gerd-neugebauer.de
+@rem
+@rem This program is free software; you can redistribute it and/or modify
+@rem it under the terms of a 3-clause BSD-like license as stated in the
+@rem file LICENSE contained in this distribution.
+@rem
+@rem You should have received a copy of the LICENSE along with this
+@rem program; if not, see the repository under http://***.
+@rem
+@rem --------------------------------------------------------------------------
+
+"perl ctan-o-mat.pl %*"
+
+@rem --------------------------------------------------------------------------
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index fa3ffb976f5..f724bdaf42b 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -185,7 +185,7 @@ my @TLP_working = qw(
cryptocode cryst
cs csbulletin cslatex csplain csquotes csquotes-de
css-colors cstypo csvsimple cstex
- ctan_chk ctanify ctanupload ctable ctablestack ctex ctex-faq
+ ctan-o-mat ctan_chk ctanify ctanupload ctable ctablestack ctex ctex-faq
cursolatex cuisine
currency currfile currvita curve curve2e curves
custom-bib cutwin cv cv4tw cweb-latex
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index 51b00a40dca..8e28cf2a4d3 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -1252,6 +1252,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`);
'cm-super' => '&PREHOOK_cm_super',
'cmextra' => '&PREHOOK_cmextra',
'concrete' => '&PREHOOK_concrete',
+ 'ctan-o-mat' => '&PREHOOK_ctan_o_mat',
'download' => '&PREHOOK_savepdf',
'dynblocks' => '&PREHOOK_flatten1',
'enctex' => '&PREHOOK_flatten1',
@@ -1401,7 +1402,6 @@ chomp ($Build = `cd $Master/../Build/source && pwd`);
%specialdest = (
- 'hyphenex', 'texmf-dist',
);
$standarddest = "texmf-dist";
@@ -2820,6 +2820,7 @@ $standardttf = '\.ttf|\.TTC';
'cjk-gs-integrate' => '\.pl$',
'convbkmk' => '\.rb$',
'crossrefware' => '\.pl$',
+ 'ctan-o-mat' => '\.pl$',
'ctanify' => '^ctanify$',
'ctanupload' => '\.pl$',
'de-macro' => 'de-macro',
@@ -2929,6 +2930,7 @@ $standardttf = '\.ttf|\.TTC';
%specialmans = (
'bundledoc' => '\.1$',
'crossrefware' => '\.1$',
+ 'ctan-o-mat' => '\.1$',
'ctanify' => '\.1$',
'dosepsbin' => 'dosepsbin.man',
'epstopdf' => 'r?epstopdf.1|epstopdf.man1.pdf', # don't keep pdf
@@ -5223,6 +5225,12 @@ sub PREHOOK_concrete {
# symlinks will get removed afterward by MAKEflatten.
}
+sub PREHOOK_ctan_o_mat {
+ print "PREHOOK_$package - make .1 with pod2man\n";
+ &prehook_pod2man ("Gerd Neugebauer", "$package.pl");
+ &SYSTEM ("$RM $package.pdf");
+}
+
sub PREHOOK_enctex {
print "PREHOOK_$package - up a level\n";
&SYSTEM ("$MV enctex/* .");
diff --git a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
index e28b4fcdfe5..acf9ca3ef9a 100644
--- a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
@@ -15,6 +15,7 @@ depend bibtexu
depend bundledoc
depend checklistings
depend chktex
+depend ctan-o-mat
depend ctan_chk
depend ctanify
depend ctanupload
diff --git a/Master/tlpkg/tlpsrc/ctan-o-mat.tlpsrc b/Master/tlpkg/tlpsrc/ctan-o-mat.tlpsrc
new file mode 100644
index 00000000000..745e64e018f
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/ctan-o-mat.tlpsrc
@@ -0,0 +1,2 @@
+binpattern f bin/${ARCH}/${PKGNAME}
+docpattern +f texmf-dist/doc/man/man1/${PKGNAME}.*