diff options
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 Binary files differnew file mode 100755 index 00000000000..5777d90a17a --- /dev/null +++ b/Master/bin/win32/ctan-o-mat.exe 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 Binary files differnew file mode 100644 index 00000000000..44974f9e388 --- /dev/null +++ b/Master/texmf-dist/doc/man/man1/ctan-o-mat.man1.pdf 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><package></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/>/\\(>\\)/; + s/</\\(<\\)/; + 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}.* |