summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2017-11-16 22:15:27 +0000
committerKarl Berry <karl@freefriends.org>2017-11-16 22:15:27 +0000
commit26bbe6fbf6f01b0ad3162a5d7c2cc0a6fbaafc13 (patch)
tree062a4755a4137f13acd90b525b6cc5415f2e328a /Master
parentbdb7ac9c2d3d7ef690d7499162aa15f0b8e51d21 (diff)
ctan-o-mat (16nov17)
git-svn-id: svn://tug.org/texlive/trunk@45834 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/man/man1/ctan-o-mat.158
-rw-r--r--Master/texmf-dist/doc/man/man1/ctan-o-mat.man1.pdfbin18850 -> 21363 bytes
-rw-r--r--Master/texmf-dist/doc/support/ctan-o-mat/README.md113
-rwxr-xr-xMaster/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat2
-rw-r--r--Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat.pkg35
-rwxr-xr-xMaster/texmf-dist/doc/support/ctan-o-mat/lib/md2ltx.pl27
-rw-r--r--Master/texmf-dist/doc/support/ctan-o-mat/makefile34
-rwxr-xr-xMaster/texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl574
-rwxr-xr-xMaster/texmf-dist/source/support/ctan-o-mat/ctan-o-mat.bat42
9 files changed, 575 insertions, 310 deletions
diff --git a/Master/texmf-dist/doc/man/man1/ctan-o-mat.1 b/Master/texmf-dist/doc/man/man1/ctan-o-mat.1
index db9f74aa7a6..30dff2d7c45 100644
--- a/Master/texmf-dist/doc/man/man1/ctan-o-mat.1
+++ b/Master/texmf-dist/doc/man/man1/ctan-o-mat.1
@@ -129,22 +129,23 @@
.\" ========================================================================
.\"
.IX Title "CTAN-O-MAT 1"
-.TH CTAN-O-MAT 1 "2017-10-20" "ctan-o-mat" "Gerd Neugebauer"
+.TH CTAN-O-MAT 1 "2017-11-16" "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
+ctan\-o\-mat \- Validate and upload 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.
+This program can be used to automate the upload of a package to the
+Comprehensive TeX Archive Network (https://www.ctan.org). The description
+of the package is taken from a configuration file. Thus it can be updated
+easily without the need to fill a Web form with the same old information
+again and again.
.PP
The provided information is validated in any case. If the validation
succeeds and not only the validation is requested then the provided
@@ -165,10 +166,11 @@ 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.
+The configuration depends on the features currently 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.
+hard-coded in \fBctan-o-mat\fR. You can request an empty template of the
+configuration via the command line parameter \f(CW\*(C`\-\-init\*(C'\fR.
.SH "OPTIONS"
.IX Header "OPTIONS"
.IP "\-h" 4
@@ -178,16 +180,6 @@ configuration via the command line parameter \f(CW\*(C`\-init\*(C'\fR.
.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
@@ -195,6 +187,15 @@ resulting messages are printed.
.IX Item "--init"
.PD
Create an empty template for a configuration.
+.IP "\-\-config <package configuration>" 4
+.IX Item "--config <package configuration>"
+.PD 0
+.IP "\-\-pkg <package configuration>" 4
+.IX Item "--pkg <package configuration>"
+.IP "\-\-package <package configuration>" 4
+.IX Item "--package <package configuration>"
+.PD
+Set the package configuration file.
.IP "\-s" 4
.IX Item "-s"
.PD 0
@@ -215,11 +216,28 @@ Print some more information during the processing (verbose mode).
Print the version number of this program and exit.
.IP "\-\-validate" 4
.IX Item "--validate"
-Print some additional debugging information.
+.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 "<package>" 4
.IX Item "<package>"
This parameter is the name of a package configuration
(see section \s-1CONFIGURATION\s0) contained in a file.
+If not set otherwise the package configuration defaults to the
+name of the current directory with \f(CW\*(C`.pkg\*(C'\fR appended.
+.SH "ENVIRONMENT"
+.IX Header "ENVIRONMENT"
+The following environment variables are recognized by \fBctan-o-mat\fR.
+.IP "\s-1CTAN_O_MAT_URL\s0" 4
+.IX Item "CTAN_O_MAT_URL"
+The value is the \s-1URL\s0 prefix for the \s-1CTAN\s0 server to be contacted. The default
+is \f(CW\*(C`https://ctan.org/submit\*(C'\fR. The complete \s-1URL\s0 is constructed by appending
+\&\f(CW\*(C`validate\*(C'\fR, \f(CW\*(C`upload\*(C'\fR, or \f(CW\*(C`fields\*(C'\fR to use the respective \s-1CTAN REST API.\s0
.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
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
index 44974f9e388..6efe50fd344 100644
--- 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 differ
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/README.md b/Master/texmf-dist/doc/support/ctan-o-mat/README.md
index 964d1690ac2..08b44507d4d 100644
--- a/Master/texmf-dist/doc/support/ctan-o-mat/README.md
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/README.md
@@ -1,4 +1,4 @@
-# ctan-o-mat - Upload or validate a package for CTAN
+# ctan-o-mat - Validate and upload a package for CTAN
## SYNOPSIS
@@ -8,10 +8,11 @@ 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.
+This program can be used to automate the upload of a package to the
+Comprehensive TeX Archive Network (https://www.ctan.org). The
+description of the package is taken from a configuration file. Thus it
+can be updated easily without the need to fill a Web form with the
+same old information again and again.
The provided information is validated in any case. If the validation
succeeds and not only the validation is requested then the provided
@@ -23,9 +24,9 @@ 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.
+*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
@@ -34,10 +35,10 @@ 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`.
+The configuration depends on the features currently 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 an empty template of the
+configuration via the command line parameter `--init`.
## OPTIONS
@@ -49,21 +50,11 @@ configuration via the command line parameter `-init`.
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
@@ -76,39 +67,62 @@ configuration via the command line parameter `-init`.
Print some more information during the processing (verbose mode).
</dd>
- <dt><code>--version</code></dt>
+ <dt><code>--validate</code></dt>
<dd>
- Print the version number of this program and exit.
- </dd>
+ Do not perform the final upload. The package is validated and the
+ resulting messages are printed. This is the default.
+ </dd>
- <dt><code>--validate</code></dt>
+ <dt><code>--verbose</code></dt>
<dd>
Print some additional debugging information.
</dd>
- <dt>&lt;package&gt;</dt>
+ <dt><code>--version</code></dt>
+ <dd>
+ Print the version number of this program and exit.
+ </dd>
+
+ <dt><code>&lt;package&gt;</code></dt>
<dd>
This parameter is the name of a package configuration
(see section CONFIGURATION) contained in a file.
+ If not set otherwise the package configuration defaults to the
+ name of the current directory with <code>.pkg</code> appended.
+ </dd>
+</dl>
+
+## ENVIRONMENT
+
+The following environment variables are recognized by B<ctan-o-mat>.
+
+<dl>
+ <dt>CTAN_O_MAT_URL</dt>
+ <dd>
+ The value is the URL prefix for the CTAN server to be contacted. The
+ default is `https://ctan.org/submit`. The complete URL is constructed
+ by appending `validate`, `upload`, or `fields` to use the respective
+ CTAN REST API.
</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.
+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.
+*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
@@ -121,14 +135,37 @@ 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.
+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.
+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.
+
+### CREATING THE DOCUMENTATION
+
+The PDF documentation is generated from the file `README.md`. This can
+be done with the following command:
+
+```
+make ctan-o-mat.pdf
+```
+
+It requires Perl and a TeX distribution to be installed and on the
+path.
+
+
+## REPOSITORY
-Make sure that these files are executable (if required). Now you are done.
+*ctan-o-mat* lives in a public repository at GitHub. It can be found under the
+URL https://github.com/ge-ne/ctan-o-mat.
+*ctan-o-mat* can be found on CTAN under the URL https://www.ctan.org/pkg/ctan-o-mat.
## AUTHOR
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
index 664abc2d647..3041dc07ad3 100755
--- a/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/ctan-o-mat
@@ -16,6 +16,6 @@
##
##-----------------------------------------------------------------------------
-exec perl $0.pl $*
+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
index 16353d467e0..83d70a22c21 100644
--- 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
@@ -20,7 +20,7 @@
% This field contains the version of the package.
% The value is optional.
% The value is restricted to 32 characters.
-\version{1.0}
+\version{1.1}
% -------------------------------------------------------------------------
% This field contains the name of the author(s).
% The value is optional.
@@ -85,7 +85,7 @@
% This field contains the update indicator; true for update.
% The value is optional.
% The value is restricted to 8 characters.
-\update{false}
+\update{true}
% -------------------------------------------------------------------------
% This field contains the topics id.
% The value is optional.
@@ -100,6 +100,25 @@
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.
+Changes:
+
+- Handling of directories with spaces improved.
+- Error messages improved.
+- Wrong version on CTAN fixed
+\end{announcement}
+% -------------------------------------------------------------------------
+% This field contains the one-liner for the package.
+% The value is optional.
+% The value is restricted to 128 characters.
+\summary{Upload or validate a package for CTAN}
+% -------------------------------------------------------------------------
+% This field contains the descriptive abstract for the package.
+% The value is optional.
+% The value is restricted to 4096 characters.
+\begin{description}
+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
@@ -113,17 +132,15 @@ 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}
+\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}
+\begin{note}
+Sorry, the wrong zip has made it to CTAN.
+This gives me the chance to publish a few minor problems too.
+\end{note}
% -------------------------------------------------------------------------
% This field contains the archive file.
% The value is the file name of the archive to be uploaded.
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
index 53b4cffa17b..e3ca5666c8e 100755
--- a/Master/texmf-dist/doc/support/ctan-o-mat/lib/md2ltx.pl
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/lib/md2ltx.pl
@@ -55,7 +55,6 @@ my $body = '';
my $author = '';
my $title = '';
-
while(<>) {
if (m/## AUTHOR/) {
$mode = MODE_AUTHOR;
@@ -81,6 +80,10 @@ while(<>) {
}
next
}
+ if ($mode == MODE_PRE) {
+ $body .= $_;
+ next;
+ }
$_ = "\\subsection*{".ucfirst(lc($1))."}\\label{$1}" if m/^### (.*)/;
$_ = "\\section*{".ucfirst(lc($1))."}\\label{$1}" if m/^## (.*)/;
if (m/^# (.*)/) {
@@ -98,13 +101,16 @@ while(<>) {
s/<dl>/\\begin{description}/;
s/<\/dl>/\\end{description}/;
s/<code>(.*)<\/code>/\\texttt{$1}/;
- s/<dt>(.*)<\/dt>/\\item[$1]/;
+ s/<dt>/\\item[/;
+ s/<\/dt>/]/;
s/<dd>/\\ \\\\/;
s/ - / -- /;
- s/&gt;/\\(>\\)/;
- s/&lt;/\\(<\\)/;
+ s/TeX /\\TeX{} /;
+ s/(&gt;|>)/\$>\$/;
+ s/(&lt;|<)/\$<\$/;
s/_/\\_/g;
- s|https?://[.a-z\/]*|\\url{$&}|;
+ s|https?://[.a-z\/-]*[a-z\/]|\\url{$&}|;
+ s|mailto:([\@a-z-]*)|\\href{$&}{$1}|;
$body .= $_;
}
@@ -114,14 +120,18 @@ if ($title =~ m/ +-+ +/) {
$title = $`;
$subject = $';
}
-if ($author =~ m/\[([a-z0-9.,:; ]*)\]\(([^()]*)\)/i) {
+if ($author =~ m/\[([a-z0-9.,:; ]*)\]\(mailto:([^()]*)\)/i) {
+ $author = $1;
+ $author_long = "$1 (\\href{mailto:$2}{$2})";
+} elsif ($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}
+\\usepackage[colorlinks=true,urlcolor=blue]{hyperref}
\\date{}
\\hypersetup{
pdfinfo={
@@ -132,7 +142,8 @@ print <<__EOF__;
}
\\author{$author_long}
-\\title{$title\\thanks{This document describes \textbf{$title} version $version}\\\\$subject}
+\\title{$title\\thanks{This document describes \\textbf{$title} version $version}}
+\\subtitle{$subject}
\\begin{document}
\\maketitle
diff --git a/Master/texmf-dist/doc/support/ctan-o-mat/makefile b/Master/texmf-dist/doc/support/ctan-o-mat/makefile
index cabe9d8d145..eebb703f99c 100644
--- a/Master/texmf-dist/doc/support/ctan-o-mat/makefile
+++ b/Master/texmf-dist/doc/support/ctan-o-mat/makefile
@@ -1,6 +1,19 @@
-#******************************************************************************
-#* (c) 2017 Gerd Neugebauer
-#*=============================================================================
+##-----------------------------------------------------------------------------
+## 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.
+##
+##-----------------------------------------------------------------------------
FILES = ctan-o-mat \
ctan-o-mat.bat \
@@ -13,17 +26,20 @@ FILES = ctan-o-mat \
lib/md2ltx.pl
VERSION = `ctan-o-mat --version`
+LATEX = xelatex
+
+#------------------------------------------------------------------------------
all:
-clean:
+clean distclean:
$(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
+pdf doc ctan-o-mat.pdf: README.md makefile lib/md2ltx.pl
+ @perl lib/md2ltx.pl --version "$(VERSION)" README.md > ctan-o-mat.latex
+ @$(LATEX) -interaction=batchmode ctan-o-mat.latex > /dev/null
+ @$(LATEX) -interaction=batchmode ctan-o-mat.latex
+ @$(RM) ctan-o-mat.out ctan-o-mat.aux ctan-o-mat.log ctan-o-mat.latex
dist ctan-o-mat.zip: $(FILES)
$(RM) ctan-o-mat.zip
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
index 1463743432b..73faab8578e 100755
--- a/Master/texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl
+++ b/Master/texmf-dist/scripts/ctan-o-mat/ctan-o-mat.pl
@@ -18,7 +18,7 @@
=head1 NAME
-ctan-o-mat - Upload or validate a package for CTAN
+ctan-o-mat - Validate and upload a package for CTAN
=head1 SYNOPSIS
@@ -26,10 +26,11 @@ 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.
+This program can be used to automate the upload of a package to the
+Comprehensive TeX Archive Network (https://www.ctan.org). The description
+of the package is taken from a configuration file. Thus it can be updated
+easily without the need to fill a Web form with the same old information
+again and again.
The provided information is validated in any case. If the validation
succeeds and not only the validation is requested then the provided
@@ -52,10 +53,11 @@ 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.
+The configuration depends on the features currently 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>.
+hard-coded in B<ctan-o-mat>. You can request an empty template of the
+configuration via the command line parameter C<--init>.
=head1 OPTIONS
@@ -68,20 +70,19 @@ configuration via the command line parameter C<-init>.
Print this short summary about the usage and exit the program.
-=item --validate
+=item -i
-=item -n
+=item --init
-=item --noaction
+Create an empty template for a configuration.
-Do not perform the final upload. The package is validated and the
-resulting messages are printed.
+=item --config <package configuration>
-=item -i
+=item --pkg <package configuration>
-=item --init
+=item --package <package configuration>
-Create an empty template for a configuration.
+Set the package configuration file.
=item -s
@@ -102,15 +103,38 @@ Print the version number of this program and exit.
=item --validate
-Print some additional debugging information.
+=item -n
+
+=item --noaction
+
+Do not perform the final upload. The package is validated and the
+resulting messages are printed.
=item <package>
This parameter is the name of a package configuration
(see section CONFIGURATION) contained in a file.
+If not set otherwise the package configuration defaults to the
+name of the current directory with C<.pkg> appended.
+
+=back
+
+
+=head1 ENVIRONMENT
+
+The following environment variables are recognized by B<ctan-o-mat>.
+
+=over 4
+
+=item CTAN_O_MAT_URL
+
+The value is the URL prefix for the CTAN server to be contacted. The default
+is C<https://ctan.org/submit>. The complete URL is constructed by appending
+C<validate>, C<upload>, or C<fields> to use the respective CTAN REST API.
=back
+
=head1 CONNECTING VIA PROXIES
If you need to connect to the Internet via a proxy then this can be achieved
@@ -143,23 +167,12 @@ 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/';
+use constant VERSION => '1.1';
#------------------------------------------------------------------------------
-# Function: usage
+# Function: usage
# Arguments: none
-# Returns: nothing
+# Returns: nothing
# Description: Print the POD to stderr and exit
#
sub usage {
@@ -170,151 +183,125 @@ sub usage {
}
#------------------------------------------------------------------------------
-# Variable: $verbose
+# Variable: $verbose
# Description: The verbosity indicator.
#
my $verbose = 0;
#------------------------------------------------------------------------------
-# Variable: $method
-# Description: The validation or submit indicator.
-#
-my $method = VALIDATE;
-
-#------------------------------------------------------------------------------
-# Variable: $debug
+# Variable: $debug
# Description: The debug indicator.
#
my $debug = 0;
#------------------------------------------------------------------------------
-# Variable: $config
-# Description: The name of the configuration file.
+# Variable: $submit
+# Description: The validation or submit indicator.
#
-my $config = undef;
+my $submit = undef;
#------------------------------------------------------------------------------
-# Variable: @fields
-# Description:
+# Variable: $cfg
+# Description: The name of the configuration file.
#
-my %fields = ();
+my $cfg = undef;
#------------------------------------------------------------------------------
-# Variable: @parameter
-# Description: The list of fields
+# Variable: $CTAN_URL
+# Description: The base URL for requesting information from the CTAN server.
#
-my @parameter = ();
+my $CTAN_URL = $ENV{'CTAN_O_MAT_URL'} || 'https://ctan.org';
+$CTAN_URL .= '/' if not $CTAN_URL =~ m/\/$/;
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; },
+ "config=s" => \$cfg,
+ "pkg=s" => \$cfg,
+ "package=s" => \$cfg,
+ "debug" => \$debug,
+ "h|help" => \&usage,
+ "i|init:s" => sub { local $_ = pkg_name_or_fallback($_[1], '');
+ (new CTAN::Pkg())
+ ->add(pkg => $_)
+ ->write(new CTAN::Upload::Fields());
+ exit(0);
+ },
+ "n|noaction" => sub { $submit = undef; },
+ "submit|upload" => sub { $submit = 1; },
+ "v|verbose" => \$verbose,
+ "validate" => sub { $submit = undef; },
+ "version" => sub { print STDOUT VERSION, "\n"; exit(0); },
);
-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();
+(new CTAN::Pkg())
+ ->read(pkg_name_or_fallback($ARGV[0] || $cfg, '.pkg'))
+ ->upload($submit);
-if ( $method == NEW_CONFIG ) {
- new_config();
-} elsif ( $method == INCREMENT ) {
- increment_config();
-} else {
- upload( read_config() );
-}
#------------------------------------------------------------------------------
-# Function: upload
-# Arguments: none
-# Description:
+# Function: pkg_name_or_fallback
+# Arguments: $value the value
+# $ext the extension to append
+# Description: Construct a fallback from the current directory if $value is
+# not defined.
#
-sub upload {
- my $f = shift;
+sub pkg_name_or_fallback {
+ my ($value, $ext) = @_;
+ if ( not defined $value or $value eq '') {
+ $value = cwd();
+ $value =~ s|.*[/\\]||;
+ $value = $value . $ext;
+ }
+ return $value;
+}
- 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);
+###############################################################################
+package CTAN::Upload::Fields;
- die format_errors( $response->decoded_content, $response->status_line ),
- "\n"
- if not $response->is_success;
+use LWP::UserAgent;
+use LWP::Protocol::https;
+use HTTP::Request::Common;
- if ( $method == VALIDATE and $response->decoded_content eq '[]' ) {
- print "ok\n";
- }
- else {
- print format_errors( $response->decoded_content, 'ok' ), "\n"
- }
-}
+#------------------------------------------------------------------------------
+# Variable: @parameter
+# Description: The list of fields.
+#
+my @parameter = ();
#------------------------------------------------------------------------------
-# Function: format_errors
-# Arguments:
-# $json the JSON list with the messages
-# $fallback the fallback message if the first parameter is empty
-# Description:
+# Constructor: new
+# Description: This is the constructor
#
-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 );
+sub new
+{ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $this = {};
+ bless $this,$class;
+ return $this->load();
}
#------------------------------------------------------------------------------
-# Function: fields
+# Method: load
# Arguments: none
-# Description:
+# Description: Retrieve a list of currently supported fields from the
+# CTAN server.
#
-sub fields {
- print STDERR "Retrieving fields from CTAN..." if $verbose;
- print STDERR $FIELDS_URL if $debug;
+sub load {
+ my $this = shift;
+ my $url = $CTAN_URL . 'submit/fields';
+
+ print STDERR "Retrieving fields from CTAN..." if $::verbose;
+ print STDERR $url,"\n" if $debug;
my $response;
eval {
my $ua = LWP::UserAgent->new();
- my $request = GET $FIELDS_URL;
- print STDERR "done\n" if $verbose;
+ my $request = GET $url;
+ print STDERR "done\n" if $::verbose;
$response = $ua->request($request);
};
- die format_errors( $response->decoded_content, $response->status_line ),
- "\n"
+ die CTAN::ErrorHandler::format( $response->decoded_content,
+ $response->status_line ), "\n"
if not $response->is_success;
local $_ = $response->decoded_content;
@@ -329,21 +316,88 @@ sub fields {
$a{$1} = $2;
$a{$1} =~ s/(^"|"$)//g;
}
- $fields{$f} = \%a;
- push @parameter, $f;
+ $this->{$f} = \%a;
+ push @CTAN::Upload::Fields::parameter, $f;
}
+ return $this;
}
+
+###############################################################################
+package CTAN::ErrorHandler;
+
#------------------------------------------------------------------------------
-# Function: read_config
+# Method: format
# Arguments:
+# $json the JSON list with the messages
+# $fallback the fallback message if the first parameter is empty
+# Description:
+#
+sub format{
+ local $_ = shift;
+ if ( $_ eq '' ) {
+ return shift;
+ }
+ if (m/^(<!DOCTYPE html>|<html)/i) {
+ return "Unexpected HTML response found under $CTAN_URL";
+ }
+
+ my $json = (new JSON::Parser())->parse($_);
+ return join("\n", map { join(': ', @$_ )} @$json);
+}
+
+
+###############################################################################
+package CTAN::Pkg;
+
+use LWP::UserAgent;
+use LWP::Protocol::https;
+use HTTP::Request::Common;
+
+#------------------------------------------------------------------------------
+# Constructor: new
+# Description: This is the constructor
+#
+sub new
+{ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $this = [];
+ return bless $this,$class;
+}
+
+#------------------------------------------------------------------------------
+# Method: add
+# Arguments: arbitrary many key/value pairs
+# Description:
+# This function adds a key/value pair to the object.
+#
+sub add {
+ my $this = shift;
+ my ($key, $val);
+ $key = shift;
+ $val = shift;
+ while (defined $key and defined $val) {
+ push @$this, $key => $val;
+ $key = shift;
+ $val = shift;
+ }
+ return $this;
+}
+
+#------------------------------------------------------------------------------
+# Method: read
+# Arguments: $file the file name to be read
# Description:
+# This function parses a configuration file in (La)TeX form and returns
+# it as hash-like list.
#
-sub read_config {
- my %cfg = ();
- my $fd = new FileHandle($config)
- || die "*** Configuration file `$config' could not be read.\n";
- my $slurp = undef;
+sub read {
+ my ($this, $file) = @_;
+ die "*** Configuration file missing.\n" if not defined $file;
+
+ my $fields = new CTAN::Upload::Fields();
+ my $fd = new FileHandle($file)
+ || die "*** Configuration file `$file' could not be read.\n";
local $_;
while (<$fd>) {
@@ -351,8 +405,9 @@ sub read_config {
s/([^\\])%.*/$1/;
while (m/\\([a-z]+)/i) {
$_ = $';
- if ( $1 eq 'begin' ) {
- die "$config: missing {environment} instead of $_\n"
+ my $keyword = $1;
+ if ( $keyword eq 'begin' ) {
+ die "$file:$.: missing {environment} instead of $_\n"
if not m/^[ \t]*\{([a-z]*)\}/i;
my $tag = $1;
my $val = '';
@@ -360,81 +415,86 @@ sub read_config {
while ( not m/\\end\{$tag\}/ ) {
$val .= $_;
$_ = <$fd>;
- die "$config: unexpected end of file while searching end of $tag\n"
+ die "$file:$.: "
+ . "unexpected end of file while searching end of $tag\n"
if not defined $_;
}
+ m/\\end\{$tag\}/;
+ $_ = $';
$val .= $`;
$val =~ s/^[ \t\n\r]*//m;
$val =~ s/[ \t\n\r]*$//m;
- $cfg{$tag} = $val;
- $_ = $';
+ push @$this, $tag => $val;
}
- elsif ( $1 eq 'endinput' ) {
+ elsif ( $keyword eq 'endinput' ) {
last;
}
- elsif ( defined $fields{$1} ) {
- my $key = $1;
- die "$config: missing {environment} instead of $_\n"
+ elsif ( defined $fields->{$keyword} ) {
+ die "$file:$.: missing {environment} instead of $_\n"
if not m/^[ \t]*\{([^{}]*)\}/i;
- if ( $key eq 'file' ) {
- $cfg{$key} = [$1];
- }
- else { $cfg{$key} = $1; }
+ if ( $keyword eq 'file' ) { push @$this, $keyword => [$1];
+ } else { push @$this, $keyword => $1; }
$_ = $';
}
else {
- die "$config: undefined keyword $&\n";
+ die "$file:$.: undefined keyword $keyword\n";
}
s/^[ \t]*%.*//;
}
}
$fd->close();
- return \%cfg;
+ return $this;
}
#------------------------------------------------------------------------------
-# Function: increment_config
-# Arguments: none
-# Description:
+# Method: upload
+# Arguments: ...
+# Description: Connect to the CTAN server to upload or validate the package.
#
-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 .= $_;
- }
+sub upload {
+ my $this = shift;
+ my $submit = shift;
+
+ print STDERR "Uploading to CTAN..." if $verbose;
+ my $service_url;
+ if ($submit) {
+ $service_url = $CTAN_URL . 'submit/upload';
+ } else {
+ $service_url = $CTAN_URL . 'submit/validate';
}
- $fd->close();
-
- if ($modified) {
- rename $config, $config.'.bak';
- $fd = new FileHandle($config,'w');
- print $fd $content;
- $fd->close();
+ my $ua = LWP::UserAgent->new();
+ my $request = POST ($service_url,
+ 'Content_Type' => 'multipart/form-data',
+ 'Content' => $this);
+
+ print STDERR "done\n" if $verbose;
+ my $response = $ua->request($request);
+
+ die CTAN::ErrorHandler::format($response->decoded_content,
+ $response->status_line),
+ "\n"
+ if not $response->is_success;
+
+ if ( not $submit and $response->decoded_content eq '[]' ) {
+ print "ok\n";
+ }
+ else {
+ print CTAN::ErrorHandler::format( $response->decoded_content, 'ok' ),
+ "\n";
}
+ return $this;
}
#------------------------------------------------------------------------------
-# Function: new_config
+# Method: write
# Arguments: none
-# Description:
+# Description: Write a new configuration to stdout.
#
-sub new_config {
+sub write {
+ my $this = shift;
+ my %this = @$this;
+ my $fields = shift;
print <<__EOF__;
% This is a description file for ctan-o-mat.
@@ -452,41 +512,147 @@ sub new_config {
% named type.
__EOF__
local $_;
- foreach ( @parameter ) {
+ foreach (@CTAN::Upload::Fields::parameter) {
print <<__EOF__;
% -------------------------------------------------------------------------
-% This field contains the $fields{$_}->{'text'}.
+% This field contains the $fields->{$_}->{'text'}.
__EOF__
- if ( defined $fields{$_}->{'nullable'} ) {
+ if ( defined $fields->{$_}->{'nullable'} ) {
print "% The value is optional.\n";
}
- if ( defined $fields{$_}->{'url'} ) {
+ if ( defined $fields->{$_}->{'url'} ) {
print "% The value is a URL.\n";
}
- if ( defined $fields{$_}->{'email'} ) {
+ if ( defined $fields->{$_}->{'email'} ) {
print "% The value is an email address.\n";
}
- if ( defined $fields{$_}->{'file'} ) {
+ 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->{$_}->{'maxsize'} ) {
+ print
+"% The value is restricted to $fields->{$_}->{'maxsize'} characters.\n";
}
- if ( defined $fields{$_}->{'list'} ) {
+ 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";
+ elsif ( defined $fields->{$_}->{'maxsize'}
+ and $fields->{$_}->{'maxsize'} ne 'null'
+ and $fields->{$_}->{'maxsize'} < 256 )
+ { my $v = $this{$_};
+ $v = '' if not defined $v;
+ print "\\$_\{$v\}\n";
}
else {
- print "\\begin{$_}\\end{$_}\n";
+ my $v = $this{$_};
+ if (defined $v) {
+ $v = "\n " + $v + "\n";
+ } else {
+ $v = '';
+ }
+
+ print "\\begin{$_}$v\\end{$_}\n";
+ }
+ }
+}
+
+###############################################################################
+
+package JSON::Parser;
+#------------------------------------------------------------------------------
+# Constructor: new
+# Description: This is the constructor
+#
+sub new
+{ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $this = {};
+ return bless $this,$class;
+}
+
+#------------------------------------------------------------------------------
+# Method: parse
+# Arguments:
+# $json the JSON list with the messages
+# Description: Parse the input string for a JSON object and retrun the Perl
+# representation of it.
+#
+sub parse {
+ my ($this, $json) = @_;
+ my ( $result, $remainder ) = $this->scan($json);
+ chomp $remainder;
+ if ($remainder ne '' ) {
+ die "Unprocessed JSON: $remainder\n";
+ }
+ return $result;
+}
+
+#------------------------------------------------------------------------------
+# Method: scan
+# Arguments:
+# $json the JSON list with the messages
+# Description: Scan the input string for the next token
+#
+sub scan {
+ my ($this, $json) = @_;
+ local $_;
+ $json =~ s/^\s+//;
+ if ($json =~ m/^\[\s*/) {
+ my @a = ();
+ $json = $';
+ while ( not $json =~ m/^\]/ ) {
+ my ($el, $remainder) = $this->scan($json);
+ push @a, $el;
+ $json = $remainder;
+ if ($json =~ m/^\s*,/) {
+ $json = $';
+ }
+ }
+ $json = substr($json, 1);
+ return ( \@a, $json );
+ }
+ elsif ($json =~ m/^"/) {
+ $json = $';
+ my $s = '';
+ while ($json =~ m/(\\.|")/) {
+ $s .= $`;
+ $json = $';
+ if ( $& eq '"' ) {
+ return ($s, $json);
+ }
+ if ( $& eq '\\n' ) {
+ $s .= "\n";
+ }
+ elsif ( $& eq '\\"' ) {
+ $s .= '"';
+ }
+ elsif ( $& eq '\\t' ) {
+ $s .= "\t";
+ }
+ elsif ( $& eq '\\\\' ) {
+ $s .= "\\";
+ }
+ elsif ( $& eq '\\r' ) {
+ $s .= "\r";
+ }
+ elsif ( $& eq '\\b' ) {
+ $s .= "\b";
+ }
+ else {
+ $s .= "\\";
+ }
}
+ die "missing end of string\n";
}
+ elsif ($json =~ m/^([0-9]+|[a-z]+)/i) {
+ $json = $';
+ $_ = $&;
+ return ( $_, $json );
+ }
+
+ die "Parse error at: $json\n";
}
#------------------------------------------------------------------------------
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
index 14aa5ff188b..88db0ddb149 100755
--- 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
@@ -1,21 +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 --------------------------------------------------------------------------
+@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 --------------------------------------------------------------------------