texlive[59817] trunk: optexcount (2jul21)

commits+karl at tug.org commits+karl at tug.org
Sat Jul 3 19:10:35 CEST 2021


Revision: 59817
          http://tug.org/svn/texlive?view=revision&revision=59817
Author:   karl
Date:     2021-07-03 19:10:35 +0200 (Sat, 03 Jul 2021)
Log Message:
-----------
optexcount (2jul21)

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

Added Paths:
-----------
    trunk/Build/source/texk/texlive/linked_scripts/optexcount/
    trunk/Build/source/texk/texlive/linked_scripts/optexcount/optexcount
    trunk/Master/bin/aarch64-linux/optexcount
    trunk/Master/bin/amd64-freebsd/optexcount
    trunk/Master/bin/amd64-netbsd/optexcount
    trunk/Master/bin/armhf-linux/optexcount
    trunk/Master/bin/i386-cygwin/optexcount
    trunk/Master/bin/i386-freebsd/optexcount
    trunk/Master/bin/i386-linux/optexcount
    trunk/Master/bin/i386-netbsd/optexcount
    trunk/Master/bin/i386-solaris/optexcount
    trunk/Master/bin/universal-darwin/optexcount
    trunk/Master/bin/win32/optexcount.exe
    trunk/Master/bin/x86_64-cygwin/optexcount
    trunk/Master/bin/x86_64-darwinlegacy/optexcount
    trunk/Master/bin/x86_64-linux/optexcount
    trunk/Master/bin/x86_64-linuxmusl/optexcount
    trunk/Master/bin/x86_64-solaris/optexcount
    trunk/Master/texmf-dist/doc/support/optexcount/
    trunk/Master/texmf-dist/doc/support/optexcount/LICENSE
    trunk/Master/texmf-dist/doc/support/optexcount/README.md
    trunk/Master/texmf-dist/doc/support/optexcount/example_01.tex
    trunk/Master/texmf-dist/doc/support/optexcount/final_bird.png
    trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.pdf
    trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.tex
    trunk/Master/texmf-dist/scripts/optexcount/
    trunk/Master/texmf-dist/scripts/optexcount/optexcount
    trunk/Master/texmf-dist/source/support/optexcount/
    trunk/Master/texmf-dist/source/support/optexcount/color_print.py
    trunk/Master/texmf-dist/source/support/optexcount/counter.py
    trunk/Master/texmf-dist/source/support/optexcount/header.py
    trunk/Master/texmf-dist/source/support/optexcount/install.sh
    trunk/Master/texmf-dist/source/support/optexcount/keywords.py
    trunk/Master/texmf-dist/source/support/optexcount/optexcount.py
    trunk/Master/texmf-dist/source/support/optexcount/word_iterator.py
    trunk/Master/tlpkg/tlpsrc/optexcount.tlpsrc

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.am
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2021-07-03 17:10:35 UTC (rev 59817)
@@ -179,6 +179,7 @@
 	multibibliography/multibibliography.pl \
 	musixtex/musixflx.lua \
 	musixtex/musixtex.lua \
+	optexcount/optexcount \
 	pax/pdfannotextractor.pl \
 	pdfcrop/pdfcrop.pl \
 	pdflatexpicscale/pdflatexpicscale.pl \

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.in
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2021-07-03 17:10:35 UTC (rev 59817)
@@ -228,7 +228,6 @@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -393,6 +392,7 @@
 	multibibliography/multibibliography.pl \
 	musixtex/musixflx.lua \
 	musixtex/musixtex.lua \
+	optexcount/optexcount \
 	pax/pdfannotextractor.pl \
 	pdfcrop/pdfcrop.pl \
 	pdflatexpicscale/pdflatexpicscale.pl \

Added: trunk/Build/source/texk/texlive/linked_scripts/optexcount/optexcount
===================================================================
(Binary files differ)

Index: trunk/Build/source/texk/texlive/linked_scripts/optexcount/optexcount
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/optexcount/optexcount	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Build/source/texk/texlive/linked_scripts/optexcount/optexcount	2021-07-03 17:10:35 UTC (rev 59817)

Property changes on: trunk/Build/source/texk/texlive/linked_scripts/optexcount/optexcount
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Modified: trunk/Build/source/texk/texlive/linked_scripts/scripts.lst
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2021-07-03 17:10:35 UTC (rev 59817)
@@ -121,6 +121,7 @@
 multibibliography/multibibliography.pl
 musixtex/musixflx.lua
 musixtex/musixtex.lua
+optexcount/optexcount
 pax/pdfannotextractor.pl
 pdfcrop/pdfcrop.pl
 pdflatexpicscale/pdflatexpicscale.pl

Added: trunk/Master/bin/aarch64-linux/optexcount
===================================================================
--- trunk/Master/bin/aarch64-linux/optexcount	                        (rev 0)
+++ trunk/Master/bin/aarch64-linux/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/aarch64-linux/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-freebsd/optexcount
===================================================================
--- trunk/Master/bin/amd64-freebsd/optexcount	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-netbsd/optexcount
===================================================================
--- trunk/Master/bin/amd64-netbsd/optexcount	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armhf-linux/optexcount
===================================================================
--- trunk/Master/bin/armhf-linux/optexcount	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-cygwin/optexcount
===================================================================
--- trunk/Master/bin/i386-cygwin/optexcount	                        (rev 0)
+++ trunk/Master/bin/i386-cygwin/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-cygwin/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-freebsd/optexcount
===================================================================
--- trunk/Master/bin/i386-freebsd/optexcount	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-linux/optexcount
===================================================================
--- trunk/Master/bin/i386-linux/optexcount	                        (rev 0)
+++ trunk/Master/bin/i386-linux/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-netbsd/optexcount
===================================================================
--- trunk/Master/bin/i386-netbsd/optexcount	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-solaris/optexcount
===================================================================
--- trunk/Master/bin/i386-solaris/optexcount	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/universal-darwin/optexcount
===================================================================
--- trunk/Master/bin/universal-darwin/optexcount	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


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

Index: trunk/Master/bin/win32/optexcount.exe
===================================================================
--- trunk/Master/bin/win32/optexcount.exe	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Master/bin/win32/optexcount.exe	2021-07-03 17:10:35 UTC (rev 59817)

Property changes on: trunk/Master/bin/win32/optexcount.exe
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/bin/x86_64-cygwin/optexcount
===================================================================
--- trunk/Master/bin/x86_64-cygwin/optexcount	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-darwinlegacy/optexcount
===================================================================
--- trunk/Master/bin/x86_64-darwinlegacy/optexcount	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwinlegacy/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwinlegacy/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linux/optexcount
===================================================================
--- trunk/Master/bin/x86_64-linux/optexcount	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linuxmusl/optexcount
===================================================================
--- trunk/Master/bin/x86_64-linuxmusl/optexcount	                        (rev 0)
+++ trunk/Master/bin/x86_64-linuxmusl/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linuxmusl/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-solaris/optexcount
===================================================================
--- trunk/Master/bin/x86_64-solaris/optexcount	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/optexcount	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/optexcount/optexcount
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/optexcount
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/optexcount/LICENSE
===================================================================
--- trunk/Master/texmf-dist/doc/support/optexcount/LICENSE	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/optexcount/LICENSE	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Richard Hartmann
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

Added: trunk/Master/texmf-dist/doc/support/optexcount/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/support/optexcount/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/optexcount/README.md	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,7 @@
+# OpTeXcount
+
+What is OpTeXcount? It is a basic python script that analyzes OpTeX source code and counts words in specific categories. For more information about this tool read `optexcount-doc.pdf`.
+### How to install OpTeXcount?
+Run: `sudo ./install.sh`
+### Usage
+Run: `optexcount [-h] [-v] [-s SET_VERBCHAR] [--version] filename`, where `filename` is the name of our OpTeX code file. What does the optional argument `-v/--verbose`? It prints the entire source code with colored words according to their categories. `-s SET_VERBCHAR` or `--set-verbchar SET_VERBCHAR` sets the implicit inline verbatim character to `SET_VERBCHAR` character.


Property changes on: trunk/Master/texmf-dist/doc/support/optexcount/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/optexcount/example_01.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/optexcount/example_01.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/optexcount/example_01.tex	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,146 @@
+% This optex source code is partialy copied from http://petr.olsak.net/tat/priklad-optex.tex
+% text words:  221
+% header words: 15
+% caption words: 14
+
+
+\chyph                      % české vzory dělení slov
+\fontfam[Schola]            % fontová rodina TeXGyre Schola
+\margins/1 a4 (3,3,3,3)cm   % okraje 3cm ze všech stran pro stranu A4
+\typosize[11/13]            % velikost písma 11pt na 13pt řádkování
+\activettchar"              % znak " bude ohraničovat řádkový verbatim
+\hyperlinks\Blue\Green      % interní odkazy modré, webové odkazy zelené
+\outlines0                  % klikací obsah po straně PDF prohlížeče
+
+\def\center{\noindent\hfil} % zkratka pro centrování
+
+\tit Ukázka \OpTeX u
+
+\sec Základní struktura
+
+Dokument se skládá z odstavců (ve zdrojovém textu jsou odděleny prázdnými řádky)
+a dále z kapitol, sekcí a podsekcí.
+
+\secc Výčty
+
+V textu můžeme používat výčty:
+
+\begitems
+* první
+* druhý
+\enditems
+
+
+Někdy mohou být výčty vnořeny:
+
+\begitems
+* První
+* Druhý.
+  \begitems \style a
+  * Podproblém,
+  * ještě jeden podproblém,
+  * poslední podproblém.
+  \enditems
+* Třetí.
+* Poslední.
+\enditems
+ 
+
+\secc Vyznačování
+
+Text můžeme zdůraznit {\it kurzívou}, nebo {\bf tučně}. 
+
+\secc[poznamky]  Poznámky
+
+Poznámka pod čarou\fnote{Vypadá takto.} je automaticky číslovaná.
+Může jich být více\fnote{Druhá poznámka.}.
+
+
+\sec[dalsi] Další sekce
+
+\secc Verbatim text
+
+Vložíme {\it verbatim text}, tedy text \uv{tak jak je} bez interpretace
+\TeX{}em:
+
+Výčet:
+\begtt
+\begitems
+* První
+* Druhý.
+\enditems
+\endtt
+
+Kromě toho je možné psát "#kusy {kódů}" přímo v textu odstavce.
+
+\secc Obrázky
+
+Obrázky se do odborného textu obvykle vkládají včetně popisku.
+
+\midinsert \label[ptacek]
+  \center \picw=7cm \inspic final_bird.png
+  \medskip
+  \caption/f Hlavní textura hry Flappy Bird
+\endinsert
+
+
+\secc Odkazy
+
+Na automaticky číslované objekty je možné odkazovat. Ve zdrojovém dokumentu
+je třeba použít {\it lejblík} v místě cíle a stejný lejblík v místě odkazu.
+Odkazy vypadají například takto: viz sekci~\ref[dalsi] na
+straně~\pgref[dalsi], dále v podsekci~\ref[poznamky] je zmínka o poznámkách
+pod čarou a rovnice~\ref[rce] na straně~\pgref[rce] uvádí zajímavou
+matematickou myšlenku. Každý jistě poznal, že na obrázku~\ref[ptacek] se
+nachází karikatura ptáčka.
+
+Vnější odkazy směřují obvykle na webové stránky, 
+např.~\url{http://petr.olsak.net/opmac.html}.
+
+\secc Tabulky
+
+Na tabulky se používá "\hbox" / "\vbox" aritmetika.
+
+\bigskip
+\center\table{||l|cc||}{\crl \tskip.5ex
+           & \multispan2 \hfil počet \qquad\hfil\vrule\kern\vvkern\vrule\strut\cr
+   makro             & řádků kódu & stran dokumentace \crli \tskip.5ex
+   plain             &    1241 & 100 \cr
+   OPmac             &    1600 &  19 \crli \tskip.5ex
+   \LaTeX{} (jádro)  &    8000 & 240 \cr
+   hyperref          &   24773 & 423 \cr
+   color + graphics  &    2469 &  81 \crli \tskip.5ex
+   Ti{\it k}Z        & 1\,634\,882 & 726 \crli \tskip.5ex
+   Con\TeX{}t        & 1\,155\,673 & 547 \crl
+ } 
+\nobreak\medskip
+\caption/t Makra a jejich rámcový rozsah
+\bigskip
+
+V tabulce ve zdrojovém textu je jednak záhlaví s pravidlem, jak mají být
+formátována jednotlivá pole tabulky, a dále data oddělená od sebe smluvenými
+oddělovači.
+
+\secc Matematika
+
+V řádku se píše matematika mezi dolary: $a^2+b^2=c^2$. Nebo je možno sestavit
+samostatnou rovnici obklopenou dvojicí dolarů:
+
+\label[rce]
+$$
+  \int x^\alpha {\rm d}x = \cases {
+     x^{\alpha+1} \over \alpha+1 & pro $\alpha\not=-1$ \cr \noalign{\medskip}
+     \ln x                       & pro $\alpha=-1 $
+  }
+  \eqmark
+$$ 
+Vzorce se zapisují zhruba tak, jak bychom je anglicky přečetli.
+
+
+
+$$
+  {\bbchar A} = \pmatrix{ a & b & c \cr d & e & f \cr g & h & i}.
+$$
+Toť na úvod vše.
+
+\bye


Property changes on: trunk/Master/texmf-dist/doc/support/optexcount/example_01.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/optexcount/final_bird.png
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/support/optexcount/final_bird.png
===================================================================
--- trunk/Master/texmf-dist/doc/support/optexcount/final_bird.png	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Master/texmf-dist/doc/support/optexcount/final_bird.png	2021-07-03 17:10:35 UTC (rev 59817)

Property changes on: trunk/Master/texmf-dist/doc/support/optexcount/final_bird.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.pdf	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.pdf	2021-07-03 17:10:35 UTC (rev 59817)

Property changes on: trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/optexcount/optexcount-doc.tex	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,97 @@
+
+\fontfam[Termes]
+\margins/1 a4 (3,3,3,3)cm
+\typosize[11/13.5]
+\verbchar`
+
+\def\title{\OpTeX count}
+\def\desc{Python script for counting words in \OpTeX/ documents}
+\def\version{Version 1.1}
+\def\author{Richard Hartmann}
+
+\def\maketitle {\vbox to 9\baselineskip{
+    \parindent=0pt
+    \leftskip=0pt plus 1fill \rightskip=0pt plus 1fill
+    {\parskip=14pt \typoscale[2000/]\bf \title \par}
+    {\parskip=19pt \typoscale[1200/]\desc \par}
+    {\parskip=10pt \version \par}
+    {\parskip=10pt \it \author \par}
+    {\parskip=8pt \the\day.\,\the\month.\,\the\year \par}
+}}
+
+\maketitle
+
+
+\sec Functionality and Usage
+
+\OpTeX count is a basic python utility that analyzes \OpTeX source code. It is inspired by already existing \TeX count for \LaTeX. The functionality is really lightweight and basic.
+It counts words and other elements of \OpTeX/ document and sorts them out into individual categories. These categories are inspired by \TeX count.
+
+\begitems
+\typosize[11.5/16]
+\style N \bf
+* Regular text words count
+* Header words count
+* Caption words count
+* Header count
+* Figures/Tables count
+* Inline formulae
+* Displayed math formulae
+\enditems
+
+Regular text words are words that occur in the main text.
+Header words are introduced using these particular keywords: {\Blue `\tit`}, {\Blue `\chap`}, {\Blue `\sec`} and {\Blue `\secc`}.
+Caption words take into account captions of tables and figures, i.e., {\Blue `\caption/t`} and {\Blue `\caption/f`}, footnotes({\Blue `\fnote`} or {\Blue `\fnotetext`}) and marginal notes({\Blue `\mnote`}).
+Header count is the number of all headers in our document.
+Figures/Tables count counts all tables and figures which occur in the document.
+Inline formulae are introduced using {\Blue `$`\dots`$`} and displayed formulae are introduced using {\Blue `$$`\dots`$$`}.
+
+If there is a verbatim text in some category, its words are counted too.
+
+Alongside above mentioned statistics, all individual sections are printed separately with particular word counts.
+
+To get this utility running, you need to install it using basic bash script.
+Use command {\Blue `sudo ./install.sh`}.
+Installation requires `python3` and `zip` utility running.
+Then user can run this utility by command:
+
+\begtt
+optexcount [-h] [-v] [-s SET_VERBCHAR] [--version] filename
+\endtt
+
+Use {\Blue `-h`} or {\Blue `--help`} specifier for the help message.
+User can also use two optional specifiers: {\Blue `-v`}~/~{\Blue `--verbose`} and {\Blue -s SET_VERBCHAR}~/~{\Blue --set-verbchar SET_VERBCHAR}.
+When the utility is ran in verbose mode, it prints the source code on the screen with colored words, so user can easily see, what is considered as text word, header word, caption word or keyword.
+Character {\Blue `SET_VERBCHAR`} sets implicit verbatim inline character.
+This can be useful when the specific verbatim character is used in the file but not explicitely set in the file.
+The situation may occur for example when user wants to count words in file, that is read by different main file.
+The verbatim character is set in the main file, but not in the file we want to analyze.
+
+In case you don't want to install this software you can run python script {\Blue `src/optexcount.py`} with {\Blue `python3`} command explicitly.
+
+\sec A Brief Implementation Description
+
+\OpTeX count uses regular expressions to separate individual words, to identify keywords, brackets, math formulae etc.
+These preprocessed words are sequentially loaded into counter that decides how to treat with the word.
+
+If some specific keyword occurs, that is not known by this utility, it is skipped.
+Problem may occur, if an unknown keyword has got some arguments, the utility could count these arguments as individual words.
+Therefore, most common keywords with arguments are listed in `src/keywords.py`, so the utility can load successfully these arguments.
+If there is some important keyword missing, feel free to modify this file, to add this keyword\dots
+
+In case of some keyword, that is important for the utility to identify, for example {\Blue `\sec`} or {\Blue `\fnote`}, special handler routine is ran, to manage this particular keyword.
+The place, from which we process the word also determines the category of the word, in what color should be this word highlighted in verbose mode etc.
+
+
+\sec Utility Limitations
+
+The results are pretty precise when the most basic \OpTeX/ constructions are used.
+As It has been already mentioned above, it is really basic and lightweight utility.
+When user uses some more advanced \TeX/ constructions, problems may occur, and the counts may be imprecise.
+It doesn't take into account macro expansion, self defined rules etc\dots When using this utility, a valid \OpTeX/ source code should be passed.
+If the file contains some errors(for example unterminated inline verbatim), utility terminates the process and won't provide much information about the problem.
+This utility only works with one particular file so it doesn't count included files as well.
+
+Beside above mentioned limitations of this utility, it could be very useful for the analysis of basic \OpTeX/ documents(such as the exemplary document {\Blue `examples/example_01.tex`}).
+
+\bye


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

Index: trunk/Master/texmf-dist/scripts/optexcount/optexcount
===================================================================
--- trunk/Master/texmf-dist/scripts/optexcount/optexcount	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Master/texmf-dist/scripts/optexcount/optexcount	2021-07-03 17:10:35 UTC (rev 59817)

Property changes on: trunk/Master/texmf-dist/scripts/optexcount/optexcount
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/optexcount/color_print.py
===================================================================
--- trunk/Master/texmf-dist/source/support/optexcount/color_print.py	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/optexcount/color_print.py	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,29 @@
+class Printer:
+    """
+    Class for printing string with specific color
+    Color list: blue, green, cyan, red, white
+    """
+    def __init__(self):
+        self.__BLUE = '\033[1;34;48m'
+        self.__GREEN = '\033[1;32;48m'
+        self.__CYAN = '\033[1;36;48m'
+        self.__RED = '\033[1;31;48m'
+        self.__TERM = '\033[1;37;0m'
+
+    def print_c(self, text, color):
+        print(color + text + self.__TERM, end='')
+
+    def blue(self, text):
+        self.print_c(text, self.__BLUE)
+
+    def green(self, text):
+        self.print_c(text, self.__GREEN)
+
+    def cyan(self, text):
+        self.print_c(text, self.__CYAN)
+
+    def red(self, text):
+        self.print_c(text, self.__RED)
+
+    def white(self, text):
+        print(text, end='')


Property changes on: trunk/Master/texmf-dist/source/support/optexcount/color_print.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/optexcount/counter.py
===================================================================
--- trunk/Master/texmf-dist/source/support/optexcount/counter.py	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/optexcount/counter.py	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,466 @@
+import keywords as kw
+import word_iterator as wi
+import header as hd
+import color_print as cp
+
+
+class Counter:
+    """
+    Class that analyzes a source code and counts word counts
+    """
+
+    def __init__(self, filename, color_print=False, verb_char=None):
+        self.word_iter = wi.WordIterator(filename)  # source of words that will be analyzed
+        if verb_char is not None:
+            self.word_iter.add_separator(verb_char)
+        self.verb_char = verb_char  # used for inline verbatim text
+        self.color_print = color_print  # input text will be printed(with colors)
+        self.printer = cp.Printer()
+        self.regular_words_count = 0
+        self.header_words_count = 0
+        self.caption_words_count = 0
+        self.figure_float_count = 0
+        self.math_inline_count = 0
+        self.math_count = 0
+        self.all_headers = []
+        """
+        Three possible types of __context:
+        1) regular-text (implicit)
+        2) headers
+        3) captions
+        """
+        self.__context = "regular-text"
+
+    def run(self):
+        """
+        Main method of the class
+        Loads all words and initializes the analysis
+        """
+        pair = self.word_iter.read()
+        while pair is not None and pair[0] != "\\bye":
+            self.__process_word(pair)
+            pair = self.word_iter.read()
+        if pair is not None:
+            self.print_keyword(pair)
+            self.print_irrelevant_word(("", "\n"))
+
+    def print_result(self):
+        """
+        Generates formatted output of the counter
+        """
+        print("Text words summary: " + str(self.regular_words_count))
+        print("Header words summary: " + str(self.header_words_count))
+        print("Caption and notes words summary: " + str(self.caption_words_count))
+        print("Headers summary: " + str(len(self.all_headers)))
+        print("Figure/float count: " + str(self.figure_float_count))
+        print("Inline math formulae count: " + str(self.math_inline_count))
+        print("Math formulae count: " + str(self.math_count))
+        print("Subcounts: (header-words-count + text-words-count + caption-words-count)")
+        for header in self.all_headers:
+            print(header)
+
+    def print_counted_word(self, pair):
+        """
+        Prints word that was counted. The color depends on category of the word.
+        """
+        if not self.color_print:
+            return
+        if self.__context == "regular-text":
+            self.printer.blue(pair[0]+pair[1])
+        elif self.__context == "header":
+            self.printer.cyan(pair[0]+pair[1])
+        elif self.__context == "caption":
+            self.printer.green(pair[0]+pair[1])
+
+    def print_keyword(self, pair):
+        """
+        Prints keyword - word with red color
+        """
+        if not self.color_print:
+            return
+        self.printer.red(pair[0]+pair[1])
+
+    def print_irrelevant_word(self, pair):
+        """
+        Prints words that wasn't counted and are not important for our functionality, like commentary words etc...
+        """
+        if not self.color_print:
+            return
+        self.printer.white(pair[0]+pair[1])
+
+    def __process_word(self, pair):
+        """
+        Decides how to treat with word from argument
+        """
+        if len(pair[0]) == 0 or pair[0] == "\n":  # empty word or newline
+            self.print_irrelevant_word(pair)
+        elif pair[0] == "%":
+            self.print_irrelevant_word(pair)
+            self.__skip_commentary()
+        elif pair[0] == "{":
+            self.print_irrelevant_word(pair)
+            self.__load_curly_brackets()
+        elif pair[0] == "$":
+            self.print_keyword(pair)
+            self.__load_inline_formulae()
+        elif pair[0] == "$$":
+            self.print_keyword(pair)
+            self.__load_formulae()
+        elif self.verb_char is not None and pair[0] == self.verb_char:
+            self.print_keyword(pair)
+            self.__load_verbatim(self.verb_char)
+        elif self.__is_keyword(pair[0]):
+            self.__process_keyword(pair)
+        else:
+            self.__process_text_word(pair)
+
+    def __process_keyword(self, pair):
+        """
+        Treats with keywords.
+        Calls action on known keywords that are important for the counter
+        If keyword is unknown it is skipped
+        """
+        word, arg = self.__split_keyword(pair[0])
+        self.print_keyword((word, ''))
+        if arg is None:
+            self.print_irrelevant_word(('', pair[1]))
+        else:
+            self.print_irrelevant_word((arg, pair[1]))
+        if word == '\\tit':
+            self.all_headers.append(hd.Header("title"))
+            self.__load_header()
+        elif word == '\\chap':
+            self.all_headers.append(hd.Header("chapter"))
+            self.__skip_brackets("[", "]")
+            self.__load_header()
+        elif word == '\\sec':
+            self.all_headers.append(hd.Header("section"))
+            self.__skip_brackets("[", "]")
+            self.__load_header()
+        elif word == '\\secc':
+            self.all_headers.append(hd.Header("subsection"))
+            self.__skip_brackets("[", "]")
+            self.__load_header()
+        elif word == '\\begitems':
+            self.__load_list()
+        elif word == '\\caption':
+            self.__skip_brackets("[", "]")
+            self.__load_caption()
+        elif word == '\\fnote' or word == '\\fnotetext' or word == '\\mnote':
+            self.__load_footnote()
+        elif word in kw.keywords_list:
+            if word in kw.floats_keywords:
+                self.figure_float_count += 1
+            self.__read_arguments(word)
+        elif word == '\\begtt':
+            self.__skip_commentary()
+            self.__load_verbatim()
+        elif word == '\\verbchar' or word == '\\activettchar':  # keywords with same functionality
+            self.__set_verb_char(word, arg, pair[1])
+        elif word == '\\code':
+            self.__load_code_verbatim()
+        elif word in kw.logos:
+            self.__load_logo(word, arg, pair[1])
+        else:
+            pass  # skip unknown keywords
+
+    def __process_text_word(self, pair):
+        """
+        Increases word counts based on the word location - word context
+        """
+        # word with only one character that is not alphanumeric won't be counted as word
+        if len(pair[0]) == 0:
+            self.print_irrelevant_word(pair)
+        elif len(pair[0]) == 1 and not pair[0].isalnum():
+            self.print_irrelevant_word(pair)
+        elif self.__context == "regular-text":
+            self.print_counted_word(pair)
+            self.regular_words_count += 1
+            if len(self.all_headers):
+                self.all_headers[-1].add_text_word()
+        elif self.__context == "header":
+            self.print_counted_word(pair)
+            self.header_words_count += 1
+            self.all_headers[-1].add_header_word(pair[0])
+        elif self.__context == "caption":
+            self.print_counted_word(pair)
+            self.caption_words_count += 1
+            if len(self.all_headers):
+                self.all_headers[-1].add_caption_word()
+
+    @staticmethod
+    def __is_keyword(word):
+        """
+        Decides whether word is keyword or not
+        """
+        if len(word) >= 3:
+            if word[0] == '\\' and word[1].isalpha() and word[2].isalpha():
+                return True
+        return False
+
+    @staticmethod
+    def __split_keyword(word):
+        """
+        Splits word to two part - keyword and its argument
+        For example:
+        '\verbchar"' will be splitted into pair: '\verbchar', '"'
+        """
+        for i in range(1, len(word)):
+            if not word[i].isalpha():
+                return word[:i], word[i:]
+        return word, None
+
+    def __load_header(self):
+        """
+        Loads header
+        It reads the source code until new line occurs.
+        In case of ^^J at the end of the line it reads until next new line occurs.
+        """
+        orig_context = self.__context
+        self.__context = 'header'
+        pair = self.word_iter.read()
+        skip_new_line = False
+        while pair is not None and pair[0] != "\\bye":
+            if not len(pair[0]):
+                self.print_irrelevant_word(pair)
+            elif pair[0] == "\n":
+                self.print_irrelevant_word(pair)
+                if not skip_new_line:
+                    self.__context = orig_context
+                    return
+                skip_new_line = False
+            elif pair[0] == "^^J":
+                self.print_irrelevant_word(pair)
+                skip_new_line = True
+            else:
+                self.__process_word(pair)
+                skip_new_line = False
+            pair = self.word_iter.read()
+        self.__context = orig_context
+        if pair is not None:
+            self.__process_keyword(pair)
+
+    def __load_list(self):
+        """
+        Loads list - words that are surrounded by '\begitems' and '\enditems'
+        """
+        pair = self.word_iter.read()
+        while pair is not None and pair[0] != "\\enditems":
+            if pair[0] != "*":
+                self.__process_word(pair)
+            else:
+                self.print_irrelevant_word(pair)
+            pair = self.word_iter.read()
+        if pair is None:
+            raise Exception("No list ending found - \\enditems")
+        else:
+            self.print_keyword(pair)
+
+    def __load_caption(self):
+        """
+        Loads caption - words until EOL
+        """
+        orig_context = self.__context
+        self.__context = 'caption'
+        pair = self.word_iter.read()
+        while pair is not None and pair[0] != "\\bye":
+            if pair[0] == "\n":
+                self.print_irrelevant_word(pair)
+                self.__context = orig_context
+                return
+            else:
+                self.__process_word(pair)
+            pair = self.word_iter.read()
+        self.__context = orig_context
+        if pair is not None:
+            self.print_keyword(pair)
+
+    def __load_footnote(self):
+        """
+        Loads footnote(block in curly brackets)
+        """
+        orig_context = self.__context
+        self.__context = 'caption'
+        pair = self.word_iter.read()
+        if pair is None:
+            raise Exception("No opening curly bracket found!")
+        while len(pair[0]) == 0 or pair[0].isspace():
+            self.print_irrelevant_word(pair)
+            pair = self.word_iter.read()
+        if pair[0] != "{":
+            self.__context = orig_context
+            self.word_iter.push_back(pair)
+            return
+        self.print_irrelevant_word(pair)
+        self.__load_curly_brackets()
+        self.__context = orig_context
+
+    def __load_formulae(self):
+        """
+        Loads math formulae($$ as separator)
+        """
+        pair = self.word_iter.read()
+        while pair is not None and pair[0] != "$$":
+            self.print_irrelevant_word(pair)
+            pair = self.word_iter.read()
+        if pair is None:
+            raise Exception("No end of math formulae found!")
+        else:
+            self.print_keyword(pair)
+        self.math_count += 1
+
+    def __load_inline_formulae(self):
+        """
+        Loads inline math formulae($ as separator)
+        """
+        pair = self.word_iter.read()
+        while pair is not None and pair[0] != "$":
+            self.print_irrelevant_word(pair)
+            pair = self.word_iter.read()
+        self.math_inline_count += 1
+        if pair is None:
+            raise Exception("No end of inline math formulae found!")
+        else:
+            self.print_keyword(pair)
+
+    def __load_verbatim(self, ending="\\endtt", keyword_print=True):
+        """
+        Reads words until ending(param) word occurs.
+        These words are processed as regular word(not keywords etc...)
+        """
+        pair = self.word_iter.read()
+        while pair is not None and ending != pair[0]:
+            self.__process_text_word(pair)
+            pair = self.word_iter.read()
+        if pair is None:
+            raise Exception("Verbatim text not terminated!")
+        else:
+            if keyword_print:
+                self.print_keyword(pair)
+            else:
+                self.print_irrelevant_word(pair)
+
+    def __load_code_verbatim(self):
+        """
+        In case of verbatim using "\code" keyword
+        """
+        pair = self.word_iter.read()
+        while len(pair[0]) == 0 or pair[0].isspace():
+            self.print_irrelevant_word(pair)
+            pair = self.word_iter.read()
+        if pair[0] != "{":
+            raise Exception("\\Code must be followed be opening curly bracket('{')!")
+        self.print_irrelevant_word(pair)
+        self.__load_verbatim("}", False)
+
+    def __load_logo(self, logo, arg, sep):
+        """
+        Checks whether logo keyword is followed by slash etc...
+        """
+        if arg != '/' or len(sep) > 0:
+            pass
+        elif self.__context == "regular-text":
+            self.regular_words_count += 1
+            if len(self.all_headers):
+                self.all_headers[-1].add_text_word()
+        elif self.__context == "header":
+            self.header_words_count += 1
+            self.all_headers[-1].add_header_word(logo)
+        elif self.__context == "caption":
+            self.caption_words_count += 1
+            if len(self.all_headers):
+                self.all_headers[-1].add_caption_word()
+
+    def __set_verb_char(self, word, arg, sep):
+        """
+        Loads new character for inline verbatim
+        """
+        if arg is not None and len(arg) == 1:
+            self.verb_char = arg
+            self.word_iter.add_separator(arg)
+        elif arg is None and sep == '':
+            pair = self.word_iter.read()
+            if len(pair[0]) != 1:
+                raise Exception("Invalid use of " + word)
+            else:
+                self.print_irrelevant_word(pair)
+                self.verb_char = pair[0]
+                self.word_iter.add_separator(pair[0])
+        else:
+            raise Exception("Invalid use of " + word)
+
+    def __read_arguments(self, word):
+        """
+        Loads from keywords file what arguments has got particular keyword from argument
+        These arguments are skipped - not important for our purpose
+        """
+        params = kw.keywords_list[word]
+        for p in params:
+            if p == "O":
+                pass  # this case is managed by '__process_keyword' method
+            elif p == "W":
+                self.__obligatory_argument()
+            elif p == "S":
+                self.__skip_brackets("[", "]")
+            elif p == "P":
+                self.__skip_brackets("(", ")")
+            elif p == "C":
+                self.__skip_brackets("{", "}")
+            else:  # unknown specifier - no argument expected
+                pass
+
+    def __obligatory_argument(self):
+        """
+        Just reads another word. In case of the end of source file Exception is thrown
+        """
+        pair = self.word_iter.read()
+        if pair is None or pair[0] == "\\bye":
+            raise Exception("No obligatory argument found")
+        self.print_irrelevant_word(pair)
+        return pair
+
+    def __load_curly_brackets(self):
+        """
+        Loads block of source code in curly brackets
+        """
+        pair = self.word_iter.read()
+        while pair is not None and pair[0] != "}":
+            self.__process_word(pair)
+            pair = self.word_iter.read()
+        if pair is None:
+            raise Exception("No closing bracket ('}') found.")
+        else:
+            self.print_irrelevant_word(pair)
+
+    def __skip_brackets(self, opening, closing):
+        """
+        Skips block of source code in brackets opening-closing
+        """
+        pair = self.word_iter.read()
+        bracket_count = 0
+        while True:
+            if pair is None:
+                raise Exception("No closing bracket ('" + closing + "') found.")
+            elif pair[0] == opening:
+                bracket_count += 1
+                self.print_irrelevant_word(pair)
+            elif pair[0] == closing:
+                bracket_count -= 1
+                self.print_irrelevant_word(pair)
+            if bracket_count <= 0:
+                if pair[0] != closing:
+                    self.word_iter.push_back(pair)
+                break
+            elif pair[0] != opening and pair[0] != closing:
+                self.print_irrelevant_word(pair)
+            pair = self.word_iter.read()
+
+    def __skip_commentary(self):
+        """
+        Skips entire line
+        """
+        pair = self.word_iter.read()
+        while pair is not None and pair[0] != "\n":
+            self.print_irrelevant_word(pair)
+            pair = self.word_iter.read()
+        self.print_irrelevant_word(pair)


Property changes on: trunk/Master/texmf-dist/source/support/optexcount/counter.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/optexcount/header.py
===================================================================
--- trunk/Master/texmf-dist/source/support/optexcount/header.py	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/optexcount/header.py	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,27 @@
+class Header:
+    """
+    Class represents header (all types - title, chapter, section, subsection) and its word counts
+    """
+    def __init__(self, header_type):
+        self.type = header_type  # title, chapter, section, subsection
+        self.words = []
+        self.header_count = 0
+        self.text_count = 0
+        self.caption_count = 0
+
+    def add_header_word(self, word):
+        self.words.append(word)
+        self.header_count += 1
+
+    def add_text_word(self):
+        self.text_count += 1
+
+    def add_caption_word(self):
+        self.caption_count += 1
+
+    def __str__(self):
+        result = "  " + self.type + " ("
+        result += str(self.header_count) + " + " + str(self.text_count) + " + " + str(self.caption_count) + ")"
+        for word in self.words:
+            result += " " + word
+        return result


Property changes on: trunk/Master/texmf-dist/source/support/optexcount/header.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/optexcount/install.sh
===================================================================
--- trunk/Master/texmf-dist/source/support/optexcount/install.sh	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/optexcount/install.sh	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+set -e
+cp src/optexcount.py src/__main__.py
+zip -j optexcount.zip src/*.py 1> /dev/null
+echo '#!/usr/bin/env python3' | cat - optexcount.zip > optexcount
+chmod +x optexcount
+rm optexcount.zip src/__main__.py
+mv optexcount /usr/bin/optexcount
+echo 'OpTeXcount successfully installed!'
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/source/support/optexcount/install.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/optexcount/keywords.py
===================================================================
--- trunk/Master/texmf-dist/source/support/optexcount/keywords.py	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/optexcount/keywords.py	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,48 @@
+"""
+List of known keywords that has got some arguments
+"O" - strOke argument
+"W" - argument Without brackets
+"S" - argument in Square brackets
+"P" - argument in Parentheses
+"C" - argument in Curly brackets
+"""
+keywords_list = {
+    "\\ii": ["W", "W"],
+    "\\label": ["S"],
+    "\\ref": ["S"],
+    "\\pgref": ["S"],
+    "\\caption": ["0"],
+    "\\begmulti": ["W"],
+    "\\cite": ["S"],
+    "\\rcite": ["S"],
+    "\\bib": ["S"],
+    "\\usebib": ["O", "P", "W"],
+    "\\load": ["S"],
+    "\\fontfam": ["S"],
+    "\\typosize": ["S"],
+    "\\typoscale": ["S"],
+    "\\thefontsize": ["S"],
+    "\\thefontscale": ["S"],
+    "\\inspic": ["W"],
+    "\\table": ["C", "C"],
+    "\\hyperlinks": ["C", "C"],
+    "\\outlines": ["C"],
+    "\\magscale": ["S"],
+    "\\margins": ["O", "W", "P", "W"],
+    "\\style": ["W"],
+    "\\url": ["C"],
+    "\\loadmath": ["C"],
+    "\\everytt": ["C"],
+    "\\eqmark": ["S"]
+}
+
+"""
+List of keywords that introduce some floats, we want to be counted in section table/floats/figures
+Pay attention! This keyword MUST be introduced in keyword_list too, otherwise it won't count words properly!
+"""
+floats_keywords = ["\\table", "\\inspic"]
+
+"""
+List of keywords of logos
+"""
+logos = ["\\TeX", "\\OpTeX", "\\LuaTeX", "\\XeTeX", "\\OPmac", "\\CS", "\\csplain"]
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/source/support/optexcount/keywords.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/optexcount/optexcount.py
===================================================================
--- trunk/Master/texmf-dist/source/support/optexcount/optexcount.py	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/optexcount/optexcount.py	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+
+"""
+The main file for entire optexcount utility
+Author: Richard Hartmann
+Version: 1.1
+"""
+
+
+import argparse
+import counter
+
+
+def main():
+    parser = argparse.ArgumentParser(description="Word counter of OpTeX documents")
+    parser.add_argument('filename', help='filename of our OpTeX file', type=argparse.FileType('r'))
+    parser.add_argument("-v", "--verbose", help="activate verbose mode", action="store_true")
+    parser.add_argument('-s', '--set-verbchar', help='set implicit inline verbatim character', nargs=1)
+    parser.add_argument('--version', action='version', version='Version 1.1')
+    args = parser.parse_args()
+    if args.set_verbchar:
+        if len(args.set_verbchar[0]) != 1:
+            parser.error("SET_VERBCHAR must be a character")
+            raise argparse.ArgumentTypeError("SET_VERBCHAR must be a character")
+        else:
+            args.set_verbchar = args.set_verbchar[0]
+
+    try:
+        c = counter.Counter(args.filename.name, args.verbose, args.set_verbchar)
+        c.run()
+        c.print_result()
+    except Exception as err:
+        print()
+        print("Problem occurred!")
+        print(err)
+
+
+if __name__ == "__main__":
+    main()


Property changes on: trunk/Master/texmf-dist/source/support/optexcount/optexcount.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/support/optexcount/word_iterator.py
===================================================================
--- trunk/Master/texmf-dist/source/support/optexcount/word_iterator.py	                        (rev 0)
+++ trunk/Master/texmf-dist/source/support/optexcount/word_iterator.py	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1,112 @@
+import re
+
+
+class WordIterator:
+    """
+    A basic wrapper for sequential reading of words from file
+    """
+
+    def __init__(self, filename):
+        self.filename = filename
+        self.word_queue = []
+        self.line_payload = 50  # how many lines will be loaded into the queue at one time
+        self.__lines_count = sum(1 for line in open(filename))
+        self.__load_line = 1  # index of first line which haven't been already loaded into the queue
+        self.__separators = []
+
+    def read(self):
+        """
+        Returns first word from file that wasn't already read by this particular object.
+        Return value format: (word, separator)
+        When all words had been read, it returns None
+        """
+        if len(self.word_queue) == 0:
+            self.__load_payload()
+        if len(self.word_queue) == 0:
+            return None
+        else:
+            return self.word_queue.pop(0)
+
+    def push_back(self, word):
+        """
+        Pushes word from argument into the first position of the queue
+        In case we already read a word but we want to re-read it again
+        """
+        self.word_queue = [word] + self.word_queue
+
+    def add_separator(self, sep):
+        """
+        All words will be separated with sep separator
+        """
+        if sep in self.__separators:
+            return
+        self.__separators.append(sep)
+        new_queue = []
+        regex_arg = re.compile('(' + sep + ')')
+        for word, sep in self.word_queue:
+            new_word = re.sub(regex_arg, r' \1 ', word)
+            new_words = new_word.split(' ')
+            new_queue += self.__make_pairs(word + sep, new_words)
+        self.word_queue = new_queue
+
+    def __load_payload(self):
+        """
+        Loads words from input file into the queue
+        Format of words: (word, separator)
+        """
+        index = 0
+        with open(self.filename, 'r') as file:
+            for line in file:
+                index += 1
+                if index < self.__load_line:
+                    continue
+                elif index < self.__load_line + self.line_payload:
+                    self.word_queue += self.__parse_words(line)
+                    if index >= self.__lines_count:
+                        index += 1
+                else:
+                    break
+        self.__load_line = index
+
+    def __parse_words(self, line):
+        """
+        Parses a line passed by argument using regular expressions.
+        It separates each word on the line and stores it into list.
+        returns list of tuples (word, separator between word and next word)
+        """
+        orig_line = line
+        if line == "\n" or line == "\r\n":
+            return self.__make_pairs(orig_line, [line])
+        # All non escape occurrences of some characters are seperated to be a single 'word'
+        line = re.sub(r'(?<!\\)(?:\\\\)*([{}\[\]()%])', r' \1 ', line)
+        # $$ and $ are separated from the text to be a single 'word'
+        line = re.sub(r'(?<!\\)(?:\\\\)*((\$\$)|(\$))', r' \1 ', line)
+        # All escaped alphabetic characters are separated from the previous word
+        line = re.sub(r'(?<!\\)(\\\\)*(\\)([A-Za-z])', r'\1 \2\3', line)
+        # Non escaped character ~ is replaced with space
+        line = re.sub(r'(?<!\\)(?:\\\\)*(~)', r' \1 ', line)
+        # Iterate through every separator and put spaces around them
+        for sep in self.__separators:
+            line = re.sub('(' + sep + ')', r' \1 ', line)
+        words_on_line = re.split(r'\s+', line)
+        # At the end of every nonempty line newline character is placed
+        words_on_line.append("\n")
+        return self.__make_pairs(orig_line, words_on_line)
+
+    @staticmethod
+    def __make_pairs(orig_line, words):
+        """
+        Generates list of tuples (word, separator between the word and the next word in list)
+        """
+        pairs = []
+        read_index = 0
+        for i in range(len(words)):
+            if i + 1 >= len(words):
+                start = orig_line[read_index:].find(words[i]) + len(words[i]) + read_index
+                pairs.append((words[i], orig_line[start:]))
+            else:
+                start = orig_line[read_index:].find(words[i]) + len(words[i]) + read_index
+                end = orig_line[start:].find(words[i+1]) + start
+                pairs.append((words[i], orig_line[start: end]))
+                read_index = end
+        return pairs


Property changes on: trunk/Master/texmf-dist/source/support/optexcount/word_iterator.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2021-07-03 17:10:35 UTC (rev 59817)
@@ -565,7 +565,7 @@
     ogham oinuit old-arrows oldlatin oldstandard
     oldstyle olsak-misc
     onedown onlyamsmath onrannual opcit opensans oplotsymbl
-    opteng optex optidef optional options
+    opteng optex optexcount optidef optional options
     orcidlink ordinalpt orientation orkhun
     oscola oswald ot-tableau othello othelloboard
     oubraces oup-authoring-template

Modified: trunk/Master/tlpkg/libexec/ctan2tds
===================================================================
--- trunk/Master/tlpkg/libexec/ctan2tds	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Master/tlpkg/libexec/ctan2tds	2021-07-03 17:10:35 UTC (rev 59817)
@@ -973,6 +973,7 @@
  'oops',	"die 'skipping, replaced by ccool'",
  'opacity-pro',	"die 'skipping, adobe required (dps)'",
  'opensans',    "&MAKEcopy",
+ 'optexcount',  "&MAKEflatten",
  'optima',      "die 'skipping, nonfree font'",
  'osa',         "die 'skipping, relies on endfloat.cfg and non-unique filenames'",
  'osmanian',    "die 'skipping, no good license info'",
@@ -1530,6 +1531,7 @@
  'numericplots'		=> '&PREHOOK_flatten1',
  'nwejm'		=> '&PREHOOK_flatten1',
  'optex'		=> '&PREHOOK_optex',
+ 'optexcount'		=> '&PREHOOK_optexcount',
  'pgfornament'		=> '&PREHOOK_flatten1',
  'phonetic'		=> '&PREHOOK_flatten1',
  'pictex'               => '&PREHOOK_pictex',
@@ -2778,6 +2780,7 @@
  'mkjobtexmf',          'Makefile.in|' . $standardsource,
  'mpman-ru',            'NULL', # doc package
  'needspace',           '\.tex|' . $standardsource,
+ 'optexcount',		'\.(py|sh)$|' . $standardsource,
  'ot2cyr',              '\.afm|\.etx|' . $standardsource,
  'patch',               '\.doc',
  'pdfx',                'rvdtx\.sty|' . $standardsource,
@@ -3405,6 +3408,7 @@
  'mkjobtexmf'           => 'mkjobtexmf\.pl$',
  'mkpic'	        => '^mkpic$',
  'musixtex'             => '\.lua$',
+ 'optexcount'           => 'optexcount$',
  'pdfbook2'             => 'pdfbook2$',
  'pdfcrop'              => '\.pl$',             # doscripts() does r*
  'pdfjam'               => 'pdfjam$',
@@ -5925,6 +5929,16 @@
   &SYSTEM ("$MV doc/optex.1 .");
 }
 
+sub PREHOOK_optexcount { # make executable zip, from their install.sh
+  print "PREHOOK_$package - make executable zip\n";
+  &xsystem ("cp src/optexcount.py src/__main__.py");
+  &xsystem ("zip -j tmp.zip src/*.py");
+  &xsystem ("echo '#!/usr/bin/env python3' | cat - tmp.zip >optexcount");
+  chmod (0755, "optexcount") || die "chmod(optexcount) failed: $!";
+  unlink ("tmp.zip");
+  unlink ("src/__main__.py");
+}
+
 sub PREHOOK_pictex {
   print "PREHOOK_$package - rm autoarea\n";
   &SYSTEM ("$RM -rf addon/autoarea*");

Modified: trunk/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc	2021-07-02 23:49:03 UTC (rev 59816)
+++ trunk/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc	2021-07-03 17:10:35 UTC (rev 59817)
@@ -53,18 +53,19 @@
 depend latex2nemeth
 depend latexdiff
 depend latexfileversion
+depend latexindent
 depend latexmk
 depend latexpand
-depend latexindent
+depend light-latex-make
+depend listings-ext
 depend ltxfileinfo
 depend ltximg
-depend light-latex-make
-depend listings-ext
 depend luajittex
 depend make4ht
 depend match_parens
 depend mflua
 depend mkjobtexmf
+depend optexcount
 depend patgen
 depend pdfbook2
 depend pdfcrop

Added: trunk/Master/tlpkg/tlpsrc/optexcount.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/optexcount.tlpsrc	                        (rev 0)
+++ trunk/Master/tlpkg/tlpsrc/optexcount.tlpsrc	2021-07-03 17:10:35 UTC (rev 59817)
@@ -0,0 +1 @@
+binpattern f bin/${ARCH}/${PKGNAME}



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