summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-02-16 22:14:11 +0000
committerKarl Berry <karl@freefriends.org>2015-02-16 22:14:11 +0000
commitc8388f2f2a7db78c1cb5f9d4f3c8fbde11067285 (patch)
treeed4fa6f421e4b3350f5d55b826c667a8c8cedb76 /Master
parent44af66510a720d5a38a1779b8f1d08e6135a3692 (diff)
ctan_chk (16feb15)
git-svn-id: svn://tug.org/texlive/trunk@36299 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/support/ctan_chk/README36
-rw-r--r--Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk227
-rw-r--r--Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdfbin0 -> 215201 bytes
-rw-r--r--Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w648
-rwxr-xr-xMaster/texmf-dist/doc/support/ctan_chk/ctan_chk_bash28
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/collection-binextra.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/ctan_chk.tlpsrc0
8 files changed, 941 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/support/ctan_chk/README b/Master/texmf-dist/doc/support/ctan_chk/README
new file mode 100644
index 00000000000..30620a61d6d
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan_chk/README
@@ -0,0 +1,36 @@
+
+Project: Ctan guidelines verifier and corrector program for uploading projects
+Distributed under license: GNU General Public License (version 3).
+Distribution Date: 15 Feb. 2015
+Distribution version: 1.0
+Comments: Currently for the Unix flavoured Platforms running Gawk
+Author: Dave Bone
+
+Contributors list:
+ Dave Bone
+
+
+Basic Gawk program that uses Ctan's published guidelines for authors to help eliminate slopiness in uploaded files/project.
+It is completely open for users to program additional guidelines and Ctan's future adjustments.
+The program came about when I first attempted to upload ``Yacco2'' for Ctan consideration.
+As Yacco2 was quite large, it took me 3 attempts to clean up my project.
+Depending on how u develop your project, in my case the Yacco2 project for Ctan upload is a subset of the complete system
+and so each uplift required the guideline assessment/purging process.
+
+This is my attempt to help both the author in getting the new system in shape for Ctan uplift
+and to lower the Ctan volanteers interaction to aid in publishing on their servers.
+It is my thank you to these volanteers / Ctan.
+
+1) License.
+ctan_chk's distributed source code is subject to the terms of the GNU General Public License (version 3).
+If a copy of the MPL was not distributed with this file, you can obtain one at https://gnu.org/licenses/gpl.html.
+
+2) Ctan_chk reference.
+Unzip the ctan_chk.zip file.
+Please read ctan_chk.pdf document. It instructs one in ``how to'' use the gawk ctan_chk.gawk program.
+
+3) Literate Programming.
+ctan_chk.pdf is generated by Cweb system. Please consider using Cweb and to join
+``www.tug.org''.
+
+
diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk
new file mode 100644
index 00000000000..805f5ab82bb
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk
@@ -0,0 +1,227 @@
+# section no34:*/
+# section no12:*/
+#
+# Program: ctan_chk.gawk
+#
+# Author: Dave Bone
+#
+# License:
+# This Source Code Form is subject to the terms of the GNU General Public License (version 3).
+# If a copy of the MPL was not distributed with this file,
+# You can obtain one at: "https://gnu.org/licenses/gpl.html".
+#
+# Purpose: Implementation of some suggested CTAN guidelines that an upload project should respect.
+# Correction functions help u cleanup the droppings.
+# See www.ctan.org website for "upload guideline" document
+# Read ctan_chk.pdf document describing the program with various run scenarios.
+#
+#
+# section no:12*/
+# section no14:*/
+function is_file_a_directory(filename,filetype)
+{
+x= "file \"%s\"";
+y= sprintf(x,filename);
+y|getline a;
+close(y);
+split(a,parts);
+filetype[1]= parts[2];
+xx= parts[2];
+str= "^directory$";
+if(xx~str){
+return 1;
+}
+return 0;
+}
+# section no:14*/
+# section no15:*/
+function is_file_an_executable(filename,filetype)
+{
+x= "file %s";
+y= sprintf(x,filename);
+y|getline a;
+close(y);
+split(a,parts);
+filetype[1]= parts[2];
+xx= parts[2];
+str= "(executable|POSIX|Mach-O|ELF)$";
+if(xx~str){
+return 1;
+}
+return 0;
+}
+# section no:15*/
+# section no17:*/
+function chk_auxiliary_files(filename)
+{
+if(is_file_a_directory(filename)==1)
+return 0;
+str= "\\.(ps|gitignore|git|aux|log|bbl|bcf|blg|brf|ilg|ind|idx|glo|loa|lof|lot|nav|out|snm|vrb|toc|dvi|glg|gls|tmp|o|bak|mpx|scn|toc)$";
+if(filename~str){
+a= "\"%s\" 'Auxilary file to be deleted'";
+b= sprintf(a,filename);
+print b;
+#delete_file(filename);
+return 1;
+}
+return 0;
+}
+# section no:17*/
+# section no25:*/
+function remove_file_s_extended_attributes(filename,message)
+{
+x= "echo %s\";xattr -c %s";
+y= sprintf(x,message,filename);
+print y;
+#y|getline a;
+#close(y);
+}
+# section no:25*/
+# section no21:*/
+function chk_file_permissions(filename)
+{
+filetype[1]= "";
+if(is_file_a_directory(filename,filetype)==1)
+return 0;
+if(is_file_an_executable(filename,filetype)==1)
+return 0;
+x= "ls -al \"%s\"";
+y= sprintf(x,filename);
+y|getline a;
+close(y);
+number_fields= split(a,parts);
+str= "x";
+if(parts[1]~str){
+a= "\"%s\" 'Write permissions %s to possibly delete file type: %s'";
+b= sprintf(a,filename,parts[1],filetype[1]);
+print b;
+return 1;
+}
+return 0;
+}
+# section no:21*/
+# section no18:*/
+function chk_extended_file_attributes(filename)
+{
+x= "ls -al \"%s\"";
+y= sprintf(x,filename);
+y|getline a;
+close(y);
+number_of_fields= split(a,parts);
+if(number_of_fields<9)
+return 0;
+xx= parts[1];
+str= "(@|+)$";
+if(xx!~str){
+return 0;
+}
+a= "\"%s\" 'Extended attributes %s'";
+b= sprintf(a,filename,parts[1]);
+print b;
+#remove_file_s_extended_attributes(filename,b);
+return 1;
+}
+# section no:18*/
+# section no19:*/
+function chk_empty_files(filename)
+{
+if(is_file_a_directory(filename)==1)
+return 0;
+x= "ls -al \"%s\"";
+y= sprintf(x,filename);
+y|getline a;
+close(y);
+number_of_fields= split(a,parts);
+if(number_of_fields<9)
+{
+print"ERROR ===> ls -al should be 9 fields and it isn't: "a" no fields: "number_of_fields;
+return 0;
+}
+i= strtonum(parts[5]);
+if(i> 0){
+return 0;
+}
+a= "\"%s\" 'Empty file to be deleted'";
+b= sprintf(a,filename);
+print b;
+#delete_file(filename);
+return 1;
+}
+# section no:19*/
+# section no20:*/
+function chk_empty_directory(filename)
+{
+if(is_file_a_directory(filename)==0)
+return 0;
+x= "du -sk \"%s\"";
+y= sprintf(x,filename);
+y|getline a;
+close(y);
+number_of_fields= split(a,parts);
+i= strtonum(parts[1]);
+if(i> 0)
+return 0;
+a= "\"%s\" 'Empty directory to be deleted or needs to add info.txt file inside it'";
+b= sprintf(a,filename);
+print b;
+return 1;
+}
+# section no:20*/
+# section no26:*/
+function delete_file(filename)
+{
+x= "rm -i \"%s\"";
+y= sprintf(x,filename);
+y|getline a;
+close(y);
+}
+# section no:26*/
+# section no22:*/
+function chk_file_to_bypass_in_zip(filename)
+{
+str= ".(DS_Store|.nbattrs)$";
+if(filename~str){
+a= "\"%s\" 'Bypass file in zip'";
+b= sprintf(a,filename);
+print b;
+return 1;
+}
+return 0;
+}
+# section no:22*/
+# section no28:*/
+function pass1_guidelines_verify(filename)
+{
+chk_auxiliary_files(filename);
+chk_extended_file_attributes(filename);
+chk_empty_files(filename);
+chk_empty_directory(filename);
+chk_file_permissions(filename);
+chk_file_to_bypass_in_zip(filename);
+}
+# section no:28*/
+# section no29:*/
+function pass2_correct(filename,message)
+{
+#remove_file_s_execute_attribute(filename,message);
+#remove_file_s_extended_attributes(filename,message);
+#delete_file(filename);
+}
+# section no:29*/
+# section no31:*/
+BEGIN{
+rec_cnt= 0;
+}
+# section no:31*/
+# section no32:*/
+{
+pass1_guidelines_verify($1);
+#pass2_correct($1,$2);
+}
+# section no:32*/
+# section no33:*/
+END{
+#print "no records read: " NR;
+}
+# section no:33*/
+# section no:34*/
diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdf b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdf
new file mode 100644
index 00000000000..e99c6671bcf
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w
new file mode 100644
index 00000000000..b00475c73d6
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w
@@ -0,0 +1,648 @@
+% file: ctan_chk.w
+%
+\def\Tex{\TeX}
+\def\cweb{\Cweb}
+\def\Cweb{{\prgstyle Cweb}}
+\def\prgstyle{\tt \sl }
+\def\NOsign{
+ {\tt{\char`\#}}
+}
+\def\Verticalbar{{\tt \char`|}}
+\def\GTsign{
+\ifmmode
+ >
+\else
+$>$
+\fi
+}
+\def\Arrow{$\Rightarrow$}
+\def\prtobrace{$\{$}
+\def\prtcbrace{$\}$}
+\def\Backslash{
+{\tt\char`\\}
+}
+
+\def\printlistinglineno{\hskip .7 in \llap{\the\lineno:\quad}}
+\def\ptindent#1{\line{\hskip.5in{#1}\hfill}}
+\def\Yacco2{Ya$c_2o_2$}
+\def\yacco2{\Yacco2}
+\def\O2{$O_2$}
+\def\o2{\O2}
+\def\Cpp{C\kern-.25em \raise.25ex\hbox{\tt $+\kern-0.2ex+$}}
+\def\Olinker{$O_{2}^{linker}$}
+\def\olinker{$O_{2}^{linker}$}
+\def\TILDE{\catcode`\~=11{}~}
+\def\INDENT#1#2{\line{\hskip#1{#2}\hfill}}
+\def\fbreak{\hfill\break}
+
+
+@* Gawk program |ctan_chk.gawk|.\fbreak
+Basic Gawk program that uses Ctan's published guidelines for authors to help eliminate slopiness in uploaded files/project.
+It is completely open for users to program additional guidelines and Ctan's future adjustments.
+The program came about when I first attempted to upload ``Yacco2'' for Ctan consideration.
+As Yacco2 was quite large, it took me 3 attempts to clean up my project.
+Depending on how u develop your project, in my case the Yacco2 project for Ctan upload is a subset of the complete system
+and so each uplift required the guideline assessment/purging process.
+
+This is my attempt to help both the author in getting the new system in shape for Ctan uplift
+and to lower the Ctan volanteers interaction to aid for publishing on their servers.
+It is my thank you to these volanteers / Ctan.
+\fbreak
+\fbreak
+This |gawk| program verifies whether an upload project for CTAN
+follows its published guidelines on their website:\fbreak
+\ptindent{http://ctan.org/upload/}
+\fbreak
+Here is the link to the awk/gawk reference manual for people needing a refresher to its programming statements:\fbreak
+\ptindent{https://www.gnu.org/software/gawk/manual/gawk.html\#Reading-Files}
+
+@*1 License.\fbreak
+ctan\_chk's distributed source code is subject to the terms of the GNU General Public License (version 3).
+If a copy of the MPL was not distributed with this file, you can obtain one at https://gnu.org/licenses/gpl.html.
+\fbreak
+\fbreak
+\ptindent{Project: ctan guidelines verifier and corrector program for uploading projects}
+\ptindent{Distributed under license: GNU General Public License (version 3).}
+\ptindent{Distribution Date: \today}
+\ptindent{Distribution version: 1.0}
+\ptindent{Comments: Currently for the Unix flavoured Platforms running Gawk}
+\ptindent{Author: Dave Bone}
+\fbreak
+\ptindent{Contributors list:}
+\ptindent{ Dave Bone}
+
+@*2 |Ctan_chk| reference.\fbreak
+Unzip the |ctan_chk.zip| file.
+Please read |ctan_chk.pdf| document. It instructs one in ``how to'' use the gawk |ctan_chk.gawk| program.
+
+@*2 Literate Programming genre.\fbreak
+|ctan_chk.pdf| user manual and |ctan_chk.gawk| program are generated by the Cweb system's
+{\it{cweave}} and {\it{ctangle}} programs along with the {\it{pdftex}}.
+The |ctan_chk_bash| script does it all for u; have a read it doesn't bite.
+Please consider using Cweb and joining
+``www.tug.org'' where u'll find the Cweb system.
+
+@*1 Comments on program's functions.\fbreak
+Normally u edit the |ctan_chk.gawk| file (using gawk comments) as to what "verification function" is called to check out your project's files.
+Here is a list of the verification functions to call:\fbreak
+Helper functions:\fbreak
+\ptindent{|is_file_a_directory| --- is file a directory type rather than a data type?}
+\ptindent{|is_file_an_executable| --- Maybe too platform dependent: is it an executable}
+\fbreak
+Verification functions:\fbreak
+\ptindent{|chk_auxiliary_files| --- files that should be removed / deleted}
+\ptindent{|chk_file_permissions| --- file execute permissions check}
+\ptindent{|chk_extended_file_attributes| --- does file have extended attribute like @@}
+\ptindent{|chk_empty_files| --- zero byte size file?}
+\ptindent{|chk_empty_directory| --- empty folder}
+\ptindent{|chk_file_to_bypass_in_zip| --- file to bypass by zip using its -x option}
+\fbreak
+Correction functions:\fbreak
+\ptindent{|remove_file_s_execute_attribute| --- Read ``Remove file's execute attribute'' section for details}
+\ptindent{|delete_file| --- interacts with user. Used by itself or from other functions like |chk_auxiliary_files|}
+\ptindent{|remove_file_s_extended_attributes| --- Remove extended attribute from file (platform dependent)}
+
+@*2 Running Gawk program has 2 run/pass attitude.\fbreak
+U run this program twice with appropriate editing sessions inbetween the run passes:\fbreak
+\ptindent{run Pass 1 function where your edited functions to call and capturing output with {\it{tee}} utility}
+\ptindent{\Arrow{} pass 1's input file is an absolute pathed files list. See |How to use this gawk program| section}
+\ptindent{\Arrow{} assess the messages outputted as to what guidelines need to be corrected}
+\ptindent{\Arrow{} outputted messages have 2 parts: part 1 the filename and part 2 the quoted message}
+\fbreak
+\ptindent{run Pass 2 function where u comment out pass 1 call and uncomment pass 2 function call}
+\ptindent{\Arrow{} inside the |pass2_correct| function, uncomment the appropriate correction function to call}
+\ptindent{\Arrow{} the captured messages from {\it{tee}} of pass 1 is its inputted file}
+\ptindent{\Arrow{} in awk/gawk terms this |gawk|'s record is composed of fields where the field separator is space}
+\ptindent{\Arrow{} so the 2nd pass receives the 2 fields filename, and message}
+\fbreak
+\fbreak
+Output example of guideline violations from Pass 1:\fbreak
+\ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Extended attributes -rwxr-xr-x@@'}
+\ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: data'}
+\ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Bypass file in zip'}
+\ptindent{\Arrow{} "/yacco2/.gitignore" 'Auxilary file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/.nbattrs" 'Extended attributes -rwxr-xr-x+'}
+\ptindent{\Arrow{} "/yacco2/.nbattrs" 'Write permissions -rwxr-xr-x+ to possibly delete file type: XML'}
+\ptindent{\Arrow{} "/yacco2/.nbattrs" 'Bypass file in zip'}
+\ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Extended attributes -rwxr-xr-x@@'}
+\ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: data'}
+\ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Bypass file in zip'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Auxilary file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Empty file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrtracings.log" 'Auxilary file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrtracings.log" 'Empty file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/o2.man" 'Extended attributes -rw-r--r--@@'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/o2linker.man" 'Extended attributes -rw-r--r--@@'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2.man" 'Extended attributes -rw-r--r--@@'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2cmd.tmp" 'Auxilary file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2cmd.tmp" 'Empty file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/bld\_bash\_APPLE" 'Extended attributes -rwxr-xr-x@@'}
+\ptindent{\Arrow{} "/yacco2/bld\_bash\_APPLE" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: ASCII'}
+\ptindent{\Arrow{} "/yacco2/book/appendix\_a.aux" 'Auxilary file to be deleted'}
+\ptindent{\Arrow{} "/yacco2/book/ch\_fsm.tex" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: LaTeX'}
+\fbreak
+Running the initial program could potentially output the above sampling.
+If there are just 1 message type outputted then u would just focus on ``pass 2'' to correct it.
+Having a mix of messages means ``pass 1'' should be edited to just deal with the 1 message type
+ at a time. This allows the homogenous output to be captured and edit the removal of files to bypass.
+Now the program can be edited to support the message type action correcting the violation
+and rerun.
+Each listed guideline type would go thru this edit behaviour: ``pass 1'' to see the violations, analyse its outcome,
+re-edit program, and then run the correction.
+
+@*2 Anatomy of this |gawk| program.\fbreak
+It contains 3 |gawk| actions: BEGIN, Body, and END.
+This program's BEGIN and END actions are just read record stats.
+U can add your own code as this program is open to your creativity.
+The action Body contains the 2 passes: |pass1_guidelines_verify| and |pass2_correct|.
+To comment out a function call, add a \NOsign{} at the beginning of its line.
+To activate a commented out function call, just remove its |gawk|'s comment character: \NOsign.
+
+@*2 How to generate the pdf document and this gawk program.\fbreak
+The \Cweb{} ``literate programming'' framework is used to generate
+its pdf document and its gawk program from |ctan_chk.w|.
+Though Cweb emits a ``c'' type code, gawk code is very similar to ``c''.\fbreak
+0) Run from a terminal using bash.\fbreak
+\ptindent{{\bf{. ctan\_chk\_bash}}}
+\ptindent{\Arrow{} The various utilities used are outputed on the terminal}
+
+U are open to add your own code to the |ctan_chk.w| program and rerun the above script.
+If u do not have the \Cweb{} framework installed, u can
+add the code to the |ctan_chk.gawk| file.
+
+@*2 How to use this gawk program.\fbreak
+0) Run from a terminal using bash.\fbreak
+1) Generate a file containing your project's files whose path is absolute\fbreak
+\ptindent{{\bf{find /absolute path of your project \GTsign{} xxx}}}
+\ptindent{\Arrow{} xxx is a holding file containing your project's files}
+\ptindent{\Arrow{} example of an absolute path: {\bf {/usr/local/yacco2}}}
+2) Edit |ctan_chk.gawk| to what function calls u want to use inside |pass1_guidelines_verify|\fbreak
+3) Run gawk ctan\_chk program verifying your project\fbreak
+\ptindent{{\bf{gawk -f ctan\_chk.gawk xxx}} \NOsign xxx is the file read containing the files to assess}\fbreak
+\ptindent{\Arrow{} it outputs files to correct on the terminal with appropriate guideline message}
+\ptindent{\Arrow{} no outputted messages means your project passed with flying colours :\prtcbrace}
+\fbreak
+\ptindent{\Arrow{} To capture the verification output:}
+\ptindent{{\bf{gawk -f ctan\_chk.gawk xxx\Verticalbar{}tee yyy}}}\fbreak
+\ptindent{\Arrow{} Use of {\it{tee}} utility to capture the output into yyy file}
+
+@*3 Example: Checking auxilary files to delete.\fbreak
+Here are the steps to see whether there are files to remove/delete.
+File xxx contains the files to verify as exampled earlier in this document.\fbreak
+1) {\bf{gawk -f ctan\_chk.gawk xxx}}\fbreak
+\fbreak
+2) Its output should have messages similar to this:\fbreak
+\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Auxilary file to be deleted'}
+\fbreak
+3) Rerun {\bf{gawk -f ctan\_chk.gawk xxx\Verticalbar{}tee yyy}} where the output messages are put in {\bf{yyy}} file.\fbreak
+\break
+4) Edit: comment out pass1\_guidelines\_verify and uncomment \#pass2\_correct in Body action code:\fbreak
+The gened |ctan_chk.gawk| program could have different commented ``section no:'' used in the below
+edit session. What is important are function names referenced: for example, |pass1_guidelines_verify| which
+you'll find in your |ctan_chk.gawk| program. Same comments apply against the other pieces of code being edited.\fbreak
+\ptindent{\# section no:22*/}
+\ptindent{\# section no28:*/}
+\ptindent{\prtobrace}
+\ptindent{ pass1\_guidelines\_verify(\$1);}
+\ptindent{ \#pass2\_correct(\$1,\$2);}
+\ptindent{\prtcbrace}
+to\fbreak
+\ptindent{\# section no:22*/}
+\ptindent{\# section no28:*/}
+\ptindent{\prtobrace}
+\ptindent{ \#pass1\_guidelines\_verify(\$1);}
+\ptindent{ pass2\_correct(\$1,\$2);}
+\ptindent{\prtcbrace}
+\fbreak
+5) Edit: uncomment out \#delete\_file in pass2\_correct:\fbreak
+\ptindent{\# section no:28*/}
+\ptindent{\# section no29:*/}
+\ptindent{function pass2\_correct(filename,message)}
+\ptindent{\prtobrace}
+\ptindent{ \#remove\_file\_s\_execute\_attribute(filename,message);}
+\ptindent{ \#remove\_file\_s\_extended\_attributes(filename,message);}
+\ptindent{ \#delete\_file(filename);}
+\ptindent{\prtcbrace}
+to\break
+\ptindent{\# section no:28*/}
+\ptindent{\# section no29:*/}
+\ptindent{function pass2\_correct(filename,message)}
+\ptindent{\prtobrace}
+\ptindent{ \#remove\_file\_s\_execute\_attribute(filename,message);}
+\ptindent{ \#remove\_file\_s\_extended\_attributes(filename,message);}
+\ptindent{ delete\_file(filename);}
+\ptindent{\prtcbrace}
+\fbreak
+\fbreak
+\fbreak
+\fbreak
+\fbreak
+\fbreak
+6) Save edited |ctan_chk.gawk| program and rerun with {\bf{yyy}}:\fbreak
+\ptindent{\Arrow{} {\bf {gawk -f ctan\_chk.gawk yyy}}}
+Each file being deleted is questioned and allows u to bypass it.\fbreak
+This is due to the {\bf{-i}} option used in {\it{rm -i file-to-delete}}\fbreak
+\fbreak
+Other guideline contraints would follow the same run / edit / rerun template above adjusting
+the program accordingly.\fbreak
+\ptindent{\Arrow{} {\bf{Just remember to reset the program back to its initial setting.}}}
+As an aside comment, u could have uncommented the |delete_file| call inside the
+|chk_auxiliary_files| function and do the correction while in the ``assess guideline'' pass.
+So why did u not express this before :\prtobrace?
+Well the normal correction pattern is see what guidelines are violated by ``pass 1', edit the program,
+and then rerun against ``pass 2'' correction.
+Once u are familiar with the program throw out my patterns and jig your own :\prtcbrace.
+@* Function code sections.
+@*2 ctan gawk's comments --- author, license etc.
+@<Emit gawk comments@>=
+#
+# Program: ctan_chk.gawk
+#
+# Author: Dave Bone
+#
+# License:
+# This Source Code Form is subject to the terms of the GNU General Public License (version 3).
+# If a copy of the MPL was not distributed with this file,
+# You can obtain one at: "https://gnu.org/licenses/gpl.html".
+#
+# Purpose: Implementation of some suggested CTAN guidelines that an upload project should respect.
+# Correction functions help u cleanup the droppings.
+# See www.ctan.org website for "upload guideline" document
+# Read ctan_chk.pdf document describing the program with various run scenarios.
+#
+#
+
+@*1 Helper functions.
+@*2 Is file a directory.\fbreak
+Directory found returns 1.
+@<|is_file_a_directory|@>=
+function is_file_a_directory(filename, filetype)@\
+{
+ x="file \"%s\"";
+ y=sprintf(x,filename);
+ y|getline a;
+ close(y);
+ split(a,parts);
+ filetype[1] = parts[2];
+ xx = parts[2];
+ str= "^directory$";
+ if (xx ~ str) {
+ return 1;
+ }
+ return 0;
+}
+
+@*2 Is file an executable.\fbreak
+This function {\bf{might be too platform dependent}}.\fbreak
+If so then don't call it or find an alternative.\fbreak
+A return 1 means it's an executable.
+@<|is_file_an_executable|@>=
+function is_file_an_executable(filename, filetype)@\
+{
+ x="file %s";
+ y=sprintf(x,filename);
+ y|getline a;
+ close(y);
+ split(a,parts);
+ filetype[1] = parts[2];
+ xx = parts[2];
+ str= "(executable|POSIX|Mach-O|ELF)$";
+ if (xx ~ str) {
+ return 1;
+ }
+ return 0;
+}
+
+@*1 Guideline assessment functions.
+@*2 Check for auxiliary type files.\fbreak
+``str'' contains a regular expression of file extensions to search for starting with a ``.'' followed by
+the round bracket expression of extensions to search on ending by the end-of-string regular expression indicator: \$.
+Inside the rounded bracket expression is the choice of extensions separated by \Verticalbar{}
+which is the ``or'' operator of a regular expression.\fbreak
+\fbreak
+The double \Backslash{} in str is due to how gawk parses the program code:
+it does a double pass:\fbreak
+\ptindent{1) on the string: str}
+\ptindent{2) on the regular expression called}
+Just having a ``.'' at the start of regular expression means it is a single ``wild character'' to accept.
+To accept a period ``.'' that starts the file extension, u have to escape it.
+Pass 1 for the literal string is the first escape sequence on \Backslash{} the 2nd backslash.
+In pass 2 for the regular expession called, the \Backslash{} escapes the ``.'' to not interpret
+as the regular expression wild character.\fbreak
+\fbreak
+str can be added to. Make sure u include the added extension started with the \Verticalbar{} when appended to before
+the closing off rounded bracked ``)''. \fbreak
+\fbreak
+|chk_auxiliary_files| outputs a 2 part message: file name and message it considers as an auxiliary file to be deleted.
+Calling |delete_file| interacts with the user whether to delete it or not.
+It is commented out so that the messages can saved and reviewed before the correction pass takes place:
+See |Pass 2 --- correct violated guidelines| section providing more information.
+U can uncomment the |delete_file| statement below if u prefer to delete the file in the assessment pass
+rather than the correction pass. Your call and temperment.
+@<|chk_auxiliary_files|@>=
+function chk_auxiliary_files(filename)@\
+{
+ if (is_file_a_directory(filename) == 1)
+ return 0;
+
+ str= "\\.(ps|gitignore|git|aux|log|bbl|bcf|blg|brf|ilg|ind|idx|glo|loa|lof|lot|nav|out|snm|vrb|toc|dvi|glg|gls|tmp|o|bak|mpx|scn|toc)$";
+ if (filename ~ str) {
+ a= "\"%s\" 'Auxilary file to be deleted'";
+ b= sprintf(a,filename);
+ print b;
+ #delete_file(filename);
+ return 1;
+ }
+ return 0;
+}
+
+@*2 Check for extended attributes.\fbreak
+Basicly looks at the output from the ``ls -al'' of a file.
+If there are extended attributes it will be displayed at the end of the first field as ``@@'' or ``+''.
+It outputs the filename and message to the terminal.
+Return 1 if found.
+@<|chk_extended_file_attributes|@>=
+function chk_extended_file_attributes(filename)@\
+{
+ x="ls -al \"%s\"";
+ y=sprintf(x,filename);
+ y|getline a;
+ close(y);
+ number_of_fields = split(a,parts);
+ if (number_of_fields < 9)
+ return 0;
+
+ xx=parts[1];
+ str= "(@@|+)$";
+ if (xx !~ str) {
+ return 0;
+ }
+
+ a="\"%s\" 'Extended attributes %s'";
+ b=sprintf(a,filename,parts[1]);
+ print b;
+ #remove_file_s_extended_attributes(filename,b);
+ return 1;
+}
+@*2 Check for empty files.\fbreak
+Uncomment out the |delete_file| statement below if u want to remove it in the assessment phase.
+Asks whether to delete the zero sized file and returns 1.
+@<|chk_empty_files|@>=
+function chk_empty_files(filename)@\
+{
+ if (is_file_a_directory(filename) == 1)
+ return 0;
+
+ x="ls -al \"%s\"";
+ y=sprintf(x,filename);
+ y|getline a;
+ close(y);
+ number_of_fields = split(a,parts);
+ if (number_of_fields < 9)@\
+ {
+ print "ERROR ===> ls -al should be 9 fields and it isn't: " a " no fields: " number_of_fields;
+ return 0;
+ }
+ i=strtonum(parts[5]);
+ if (i > 0){
+ return 0;
+ }
+ a="\"%s\" 'Empty file to be deleted'";
+
+ b=sprintf(a,filename);
+ print b;
+ #delete_file(filename);
+ return 1;
+}
+
+@*2 Check for empty directory.\fbreak
+Empty directory found returns a 1.\fbreak
+This check requires u to assess what u want to do: delete it, or add an ``info.txt'' file inside it.
+For example in the ``Yacco2'' project, it is a full
+development framework of a compiler/compile, and its API library.
+It has empty Debug folders. Its Release folders contained content.
+Depending on what the user wanted to debug and link against, the empty Debug folder
+provided consistency to the framework and hence it was needed. So an ``info.txt'' file
+was created inside each Debug folder expressing their intent/use to the developer.
+
+@<|chk_empty_directory|@>=
+function chk_empty_directory(filename)@\
+{
+ if (is_file_a_directory(filename) == 0)
+ return 0;
+
+ x="du -sk \"%s\"";
+ y=sprintf(x,filename);
+ y|getline a;
+ close(y);
+ number_of_fields = split(a,parts);
+
+ i=strtonum(parts[1]);
+ if (i > 0)
+ return 0;
+
+ a="\"%s\" 'Empty directory to be deleted or needs to add info.txt file inside it'";
+
+ b=sprintf(a,filename);
+ print b;
+ return 1;
+}
+
+
+@*2 Check file permissions.\fbreak
+Bypass a directory.
+If the file does not have an executable attribute then exit stage gracefully.
+
+@<|chk_file_permissions|@>=
+function chk_file_permissions(filename)@\
+{
+ filetype[1]="";
+ if (is_file_a_directory(filename, filetype) == 1)
+ return 0;
+ if (is_file_an_executable(filename,filetype) == 1)
+ return 0;
+
+ x="ls -al \"%s\"";
+ y=sprintf(x,filename);
+ y|getline a;
+ close(y);
+
+ number_fields = split(a,parts);
+
+ str= "x";
+ if (parts[1] ~ str) {
+ a="\"%s\" 'Write permissions %s to possibly delete file type: %s'";
+ b=sprintf(a,filename,parts[1],filetype[1]);
+ print b;
+ return 1;
+ }
+ return 0;
+}
+
+@*2 Check file to bypass in zip.\fbreak
+This is just a check function that lists files to bypass in the zip file creation process.\fbreak
+An example of creating a zip file:\fbreak
+\ptindent{{\bf{zip -r -ll yacco2.zip yacco2 -x '*DS\_Store' -x '*.nbattrs'}}}
+\ptindent{\Arrow{} -r recurse through the folder getting all its subfolders and their contents}
+\ptindent{\Arrow{} -ll parameter reduces carriage return/line feed combo to line feed}
+\ptindent{\Arrow{} -x parameter lists by regular expression the file(s) to bypass}
+\ptindent{\Arrow{} The bypassed exampled files are Apple OSX specific}
+
+@<|chk_file_to_bypass_in_zip|@>=
+function chk_file_to_bypass_in_zip(filename)
+{
+ str= ".(DS_Store|.nbattrs)$";
+ if (filename ~ str) {
+ a="\"%s\" 'Bypass file in zip'";
+ b=sprintf(a,filename);
+ print b;
+ return 1;
+ }
+ return 0;
+}
+
+
+@*1 Correct guideline violations.
+@*2 Remove file's execute attribute.\fbreak
+Due to security reasons, u cannot have an indirect bash script run against a list of files
+to change their ownership attributes.
+It will run but nothing will be changed.\fbreak
+So what to do?\fbreak
+\ptindent{\Arrow{} gawk -f |ctan_chk.gawk| xxx \Verticalbar{}tee yyy}
+\ptindent{\Arrow{} \ \ \ \ u can use your own temporary file name instead of yyy}
+\ptindent{\Arrow{} \ \ \ \ just remember to substitute your file name in place of yyy}
+\ptindent{\Arrow{} where the |chk_file_permissions| function is the only function run}
+\ptindent{\Arrow{} and the other functions have been commented out}
+\fbreak
+\ptindent{Edit yyy file containing the list of potential files, removing files keeping their execute attribute.}
+\break
+\ptindent{Run this below gawk script interactively from your bash terminal}
+\ptindent{\Arrow{} This means copy the below script line and paste it in the bash terminal}
+\ptindent{\ \ \ \ \ gawk '\prtobrace x="chmod a-x \%s;";y=sprint(x,\$1);system(y);\prtcbrace' yyy}
+\fbreak
+Some comments on the above interactive |gawk| program:\fbreak
+1) It reads the yyy file where each line read contains 2 fields: filename, and message separated by a space\fbreak
+2) It runs the {\it{chmod}} utility by the {\bf{system}} statement\fbreak
+3) Not sure about {\bf{chmod}} utility, do a ``man chmod'' on your bash terminal for more information\fbreak
+4) If u boobooed on a file and removed the execute attribute, here is a correction:\fbreak
+\ptindent{\Arrow{} {\bf{chmod a+x file-to-reimplement}}}
+
+@<|remove_file_s_execute_attribute|@>=
+function remove_file_s_execute_attribute(filename, message)@\
+{
+ print "Please read |ctan_chk.pdf| to find instructions on how remove execute attribute from a file";
+}
+
+@*2 Remove file's with extended attributes.\fbreak
+This function is platform dependent.
+The {\it{xattr}} is the utility to run on Apple's OSx platform to remove the extension.
+@<|remove_file_s_extended_attributes|@>=
+function remove_file_s_extended_attributes(filename, message)@\
+{
+ x="echo %s\";xattr -c %s";
+ y=sprintf(x,message,filename);
+ print y;
+ #y|getline a;
+ #close(y);
+}
+
+@*2 Delete file.\fbreak
+The file name passed to it is displayed and asks whether it should be deleted.
+@<|delete_file|@>=
+function delete_file(filename)@\
+{
+ x="rm -i \"%s\"";
+ y=sprintf(x,filename);
+ y|getline a;
+ close(y);
+}
+
+
+@* Pass 1 / 2 guidelines assessment and correction.\fbreak
+@*2 Pass 1 --- guidelines assessment.\fbreak
+Using a text editor (un)comment out the appropriate function calls in |ctan_chk.gawk| that u'd like to verify.
+For example checking just the files to be deleted, comment out all the below functions except
+|chk_auxiliary_files|.
+
+U can run pass 1 as is to see whether any of your files for upload do not
+pass the guidelines.
+From there u can adjust what function to deal with by commenting out the others fuctions
+and teeing out its found infidelities for pass 2 correction.
+
+@<pass 1 guidelines verify@>=
+function pass1_guidelines_verify(filename)
+{
+ chk_auxiliary_files(filename);
+ chk_extended_file_attributes(filename);
+ chk_empty_files(filename);
+ chk_empty_directory(filename);
+ chk_file_permissions(filename);
+ chk_file_to_bypass_in_zip(filename);
+}
+
+@*2 Pass 2 --- correct violated guidelines.\fbreak
+There are 3 functions whereby 2 of them do usefull things.\fbreak
+\ptindent{|delete_file| function asks whether its passed file should be deleted}
+\ptindent{\Arrow{} Remove the -i in {\bf{rm -i}} statement if u don't want the interactive question}
+\fbreak
+\ptindent{|remove_file_s_extended_attributes| function is tailored to the Apple platform}
+\ptindent{\Arrow{} Other platforms should have an equivalent {\it{xattr -c}} utility}
+\ptindent{\Arrow{} {\bf{Caveat:}} know what utility to use and adjust accordingly to remove the extension attribute}
+\ptindent{\Arrow{} Have a read at https://en.wikipedia.org/wiki/Extended\_file\_attributes\#cite\_note-14}
+\fbreak
+\ptindent{|remove_file_s_execute_attribute| tells u to read the {\bf{ctan\_chk.pdf}} document}
+\ptindent{\Arrow{} on ``how to remove'' the execute attribute from a file}
+\fbreak
+Uncomment the appropriate below function to call.
+And comment out |pass1_guidelines_verify| statement, and uncomment |pass2_correct| statement
+in |Body| action before reruning this program.
+@<pass 2 guidelines correction@>=
+function pass2_correct(filename, message)
+{
+ #remove_file_s_execute_attribute(filename,message);
+ #remove_file_s_extended_attributes(filename,message);
+ #delete_file(filename);
+}
+
+@* Gawk Begin, Body, End actions.
+@*2 Begin.
+@<|BEGIN|@>=
+BEGIN{
+rec_cnt = 0;
+}
+
+@*2 Body.
+@<|Body|@>=
+{
+ pass1_guidelines_verify($1);
+ #pass2_correct($1,$2);
+}
+
+@*2 END.
+@<|END|@>=
+END{
+#print "no records read: " NR;
+}
+
+
+
+@ Write out gawk program.
+@(ctan_chk.gawk@>=
+@<Emit gawk comments@>;
+@<|is_file_a_directory|@>;
+@<|is_file_an_executable|@>;
+@<|chk_auxiliary_files|@>;
+@<|remove_file_s_extended_attributes|@>;
+@<|chk_file_permissions|@>;
+@<|chk_extended_file_attributes|@>;
+@<|chk_empty_files|@>;
+@<|chk_empty_directory|@>;
+@<|delete_file|@>;
+@<|chk_file_to_bypass_in_zip|@>;
+@<pass 1 guidelines verify@>;
+@<pass 2 guidelines correction@>;
+@<|BEGIN|@>;
+@<|Body|@>;
+@<|END|@>;
+
+@** Index.
diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk_bash b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk_bash
new file mode 100755
index 00000000000..79e3a3486e2
--- /dev/null
+++ b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk_bash
@@ -0,0 +1,28 @@
+#! /bin/sh
+# File: ctan_chk_bash
+# Why: Creates the ctan_chk.gawk and ctan_chk.pdf from the ctan_chk.w ``literate program''
+# How to run: from bash command-terminal
+# . ctan_chk_bash
+#
+echo "----------->ctan_chk_bash script<-----------"
+echo "----------->cweave create the pdf doc of ctan_chk<-----------"
+cweave ctan_chk
+pdftex ctan_chk
+echo "----------->ctangle create ctan_chk.gawk program<-----------"
+ctangle -l +e ctan_chk.w
+echo "----------->sed - change section no into a gawk comment<-----------"
+sed 's/^\/\*/# section no/' ctan_chk.gawk>ctan_chk.tmp
+echo "----------->gawk --- remove empty lines and #line lines<-----------"
+gawk -e '{r=length($0);if(r==0) next; match($0,/^(\#line|;)/);if (RLENGTH > 0) next; print $0;}' ctan_chk.tmp > ctan_chk.tm1
+echo "----------->cp --- create the gawk edited program<-----------"
+cp ctan_chk.tm1 ctan_chk.gawk
+echo "----------->remove temporary files<-----------"
+rm ctan_chk.tmp
+rm ctan_chk.tm1
+rm *.idx
+rm *.scn
+rm *.toc
+rm *.tex
+rm *.log
+rm *.c
+
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 20eca3b90ce..a2758ba39fc 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -155,7 +155,7 @@ my @TLP_working = qw(
cprotect
crbox crop crossreference crossrefware crossword crosswrd cryst
cs csbulletin cslatex csplain csquotes csquotes-de csvsimple csvtools cstex
- ctanify ctanupload ctable ctex ctex-faq
+ ctan_chk ctanify ctanupload ctable ctex ctex-faq
cursolatex cuisine
currfile currvita curve curve2e curves
custom-bib cutwin cv cv4tw cweb-latex cyklop cyrillic cyrplain
diff --git a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
index 9ee425e4177..36a49152d86 100644
--- a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
@@ -14,6 +14,7 @@ depend bibtex8
depend bibtexu
depend bundledoc
depend chktex
+depend ctan_chk
depend ctanify
depend ctanupload
depend ctie
diff --git a/Master/tlpkg/tlpsrc/ctan_chk.tlpsrc b/Master/tlpkg/tlpsrc/ctan_chk.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/ctan_chk.tlpsrc