diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2011-05-04 10:15:57 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2011-05-04 10:15:57 +0000 |
commit | 088b61d350fba63ae429a3c79fe765e4b4b9cc7b (patch) | |
tree | f228e4a69be7a6f6ab25409a191d183c77973611 /Build/source/utils/vlna/vlna-1.5 | |
parent | bc4eca8d682e6e8c0f05ffcab3d38d3030782cd2 (diff) |
reorganize: vlna-1.5 plus vlna-1.5-PATCHES
git-svn-id: svn://tug.org/texlive/trunk@22301 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/vlna/vlna-1.5')
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/ChangeLog | 53 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/Makefile.am | 36 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/README | 76 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/README.en | 66 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/configure.ac | 31 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/csmac.tex | 63 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/vlna-cz.man | 131 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/vlna.man | 163 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/vlna.txt | 131 | ||||
-rw-r--r-- | Build/source/utils/vlna/vlna-1.5/vlna.w | 1070 |
10 files changed, 1820 insertions, 0 deletions
diff --git a/Build/source/utils/vlna/vlna-1.5/ChangeLog b/Build/source/utils/vlna/vlna-1.5/ChangeLog new file mode 100644 index 00000000000..8d058e8e23e --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/ChangeLog @@ -0,0 +1,53 @@ +2010-02-01 Petr Olsak <petr@olsak.net> + + * Buffer overflow problem corrected + * vlna.w: BANNER: version 1.4 -> version 1.5 + +2009-04-30 Petr Olsak <petr@olsak.net> + + * vlna.w: program is able to process utf16 input by following way: + it ignores zero bytes while searching patterns but it stores + all bytes from input to output. + * vlna.w, vlna.man: The -u changed to -x option. + * vlna.man, vlna-cz.man: English man page is created. + +2009-04-26 Petr Olsak <petr@olsak.net> + + * vlna.w, vlna.man: new parameter -u. You can set another code + to be inserted instead a tie. Example: vlna -u C2A0 . + * vlna.w: BANNER: version 1.3 -> version 1.4 + +2009-04-20 Petr Olsak <petr@olsak.net> + + * README.en: the stupid sequence about "selling" of the program + and its modifications is removed from "Program distribution" + paragraph. The Czech README file never included the translation of + this sentecne; it means the inconsistency was there. + +2008-07-18 Petr Olsak <petr@olsak.net> + + * vlna.w: BANNER: vlna, version 1.2 -> vlna, version 1.3 + * vlna.tex, vlna.dvi, vlna.c: dtto + * README, README.en: Acknowledgement added. + +2008-07-04 Peter Breitenlohner <peb@mppmu.mpg.de> + + * vlna.idx, vlna.scn (new): Add these files required to build + vlna.dvi. + * Makefile.am: Rules to (re-)build vlna.idx and vlna.scn. + +2008-07-01 Peter Breitenlohner <peb@mppmu.mpg.de> + + * vlna.dvi: new version from Zdenek, keep it here because it is + required for 'make dist (copy in Master/texmf/doc/vlna/). + +2008-06-26 Peter Breitenlohner <peb@mppmu.mpg.de> + + * README.en (new): from Zdenek Wagner, fixed a few typos. + * vlna.w: Ensure charset parameter for '-v'. + +2008-06-25 Peter Breitenlohner <peb@mppmu.mpg.de> + + Autoconfiscated vlna-1.2, imported from + ftp://math.feld.cvut.cz/pub/olsak/vlna. + diff --git a/Build/source/utils/vlna/vlna-1.5/Makefile.am b/Build/source/utils/vlna/vlna-1.5/Makefile.am new file mode 100644 index 00000000000..2de8c38680c --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/Makefile.am @@ -0,0 +1,36 @@ +# Makefile.am -- Peter Breitenlohner <peb@mppmu.mpg.de> -- Public domain. + +bin_PROGRAMS = vlna +dist_man1_MANS = vlna.man + +CWEB_SRC = vlna.w +CSMAC = csmac.tex +CWEB_TEX = vlna.tex vlna.idx vlna.scn +CWEB_DVI = vlna.dvi + +DOCS = README README.en vlna.txt + +EXTRA_DIST = $(CWEB_SRC) $(CSMAC) $(CWEB_TEX) $(CWEB_DVI) $(DOCS) + +CLEANFILES = vlna.log vlna.toc + +vlna.dvi: vlna.tex vlna.idx vlna.scn + TEXINPUTS=.:$(srcdir):$$TEXINPUTS $(CSPLAIN) vlna.tex + +# Running cweave in order to create vlna.tex generates in addition +# vlna.idx and vlna.scn; we must rerun cweave when they are not +# up to date (even if vlna.tex is up to date). Thus the sub-make. +# +vlna.tex vlna.idx vlna.scn: vlna.w + $(MAKE) do-cweave +do-cweave: vlna.w .FORCE + $(CWEAVE) $< +.PHONY: do-cweave .FORCE + +if MAINTAINER_MODE +all-local: vlna.dvi +vlna.c: vlna.w + $(CTANGLE) $< +else +all-local: +endif diff --git a/Build/source/utils/vlna/vlna-1.5/README b/Build/source/utils/vlna/vlna-1.5/README new file mode 100644 index 00000000000..5c4e09d1f02 --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/README @@ -0,0 +1,76 @@ + +VLNA v1.3 +========= + +Program vlna přidává vlnky (místo původních mezer) za neslabičné předložky +ve vstupních souborech pro TeX. To zabrání zlomu řádku v nežádoucím místě. + +Obsah distribuce: +----------------- + +README ... tento soubor (formát UNIX, ISO 8859-2), +vlna.txt ... manuál k programu (formát UNIX, ISO 8859-2), +Makefile ... soubor pro program make +vlna.w ... zdrojový text programu v jazyce CWEB (formát UNIX, ISO 8859-2), +vlna.c ... výstup z ctangle vlna (program v jazyce C), +vlna.dvi ... listing programu (vyžaduje csfonty), + listing je vytvořen takto: + cweave vlna + csplain vlna +vlna.man ... kostra manuálové stránky +csmac.tex ... makra potřebná při zpracování dokumentace (formát ISO 8859-2). +vlna.exe ... už zkompilovaný program pro DOS + +Instalace v DOSu: +----------------- + +1) Převedení textových souborů z ISO 8859-2 do použitého kódování + (například programem cstocs). +2) Je možné přímo použít připravený program vlna.exe. +3) S vhodným překladačem a při troše štěstí lze též kompilovat program + jako ze zdrojových textů (například s gcc a několika UNIXovými + utilitami). + +Instalace v UNIXu: +------------------ + +1) Případná úprava Makefile pro přizpůsobení překladu a instalace + na cílovému systému. +2) Překlad a instalace: + make + su + make install + +Šíření programu: +---------------- + +Program poskytuji k veřejnému použití. Pokud někdo udělá užitečné +změny ve zdrojovém textu CWEB, chtěl bych být o tom informován. Bez +souhlasu autora nemůže být změněný program šířen pod stejným názvem. + +Nedávám žádnou záruku, že program nepoškodí mnohahodinovou práci, +kterou uživatelé editovali. Program sice vytváří zálohové soubory, ale +ty se při dalším použití programu mažou. + +Poděkování: +----------- + +Děkuji panu Rudolfu Čejkovi za vytvoření Makefile a manuálové stranky +k programu. Rovněž mu děkuji za odstranění drobných chyb programu, které +se vyskytly ve verzi 1.0. + +Děkuji pánům Peteru Breitenlohnerovi a Zdeňku Wagnerovi za úpravu +nástojů k sestavení programu a za další dokumentaci, což pomohlo zařadit +program do TexLive. + +18. 7. 2008 Petr Olšák + + +verze 1.3 (18. 7. 2008): + viz Changelog +verze 1.2 (20. 5. 2002): + oprava chyby "v<space><cr>lese" -> "v~~lese" + a přidání patternu pro "\uv{v lese}" -> "\uv{v~lese}". +(23. 2. 2004): + v README v odstavci "Šíření programu" zrušena věta + "Program ani jeho modifikace se nesmí prodávat". diff --git a/Build/source/utils/vlna/vlna-1.5/README.en b/Build/source/utils/vlna/vlna-1.5/README.en new file mode 100644 index 00000000000..81ae74d20b7 --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/README.en @@ -0,0 +1,66 @@ + +VLNA v1.3 +========= + +Program vlna adds ties (Czech vlna or vlnka) after nonsyllabic prepositions +(instead of spaces) in the TeX source files. This prevents line breaks +at undesirable spaces. + +Contents of the distribution +---------------------------- + +README ... manual in Czech (format UNIX, ISO 8859-2), +README.en ... translation into English +vlna.txt ... Czech manual to the program (format UNIX, ISO 8859-2), +Makefile ... file for make +vlna.w ... CWEB source code (format UNIX, ISO 8859-2), +vlna.c ... output of ctangle vlna (program in C), +vlna.dvi ... program listing (requires csfonts) + listing was created by + cweave vlna + csplain vlna +vlna.man ... Czech man page +csmac.tex ... Macros required for printing the documentation (encoding ISO 8859-2). +vlna.exe ... DOS executable + +Installation in UNIX: +--------------------- + +1) Modification of the Makefile (optional) +2) Compilation and installation: + make + su + make install + +Program distribution: +--------------------- + +The program may be freely used. If somebody makes useful changes +in the CWEB source code, I want to be informed about it. The +modified version must not be distributed under the same name +without author's consent. + +The author gives no warranty that the program will not damage your +file that you have been editing for many hours. Although the program +creates backup files, these files are deleted after subsequent use +of the program. + +Acknowledgement: +---------------- + +The author thanks to Rudolf Cejka for creation of the man page +as well as for fixing small bugs that ocurred in version 1.0. + +Thanks to Peter Breitenlohner and Zdenek Wagner for updating building +tools and documentation of the program in order to merging it to +TeXLive. + +20 Apr. 2009 Petr Olsak + +version 1.3 (18. Jul 2008) + see Changelog + +version 1.2 (20. May 2002): + bug fix "v<space><cr>lese" -> "v~~lese" + added pattern for "\uv{v lese}" -> "\uv{v~lese}". + diff --git a/Build/source/utils/vlna/vlna-1.5/configure.ac b/Build/source/utils/vlna/vlna-1.5/configure.ac new file mode 100644 index 00000000000..750d233936d --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/configure.ac @@ -0,0 +1,31 @@ +dnl configure.ac -- Peter Breitenlohner <peb@mppmu.mpg.de> -- Public domain. + +AC_PREREQ(2.60) +AC_INIT([vlna], [1.3], [tex-live@tug.org]) +AC_CONFIG_SRCDIR([vlna.w]) + +AM_INIT_AUTOMAKE([foreign no-define])dnl using automake + +# Checks for programs. +AC_PROG_CC +AC_PROG_MAKE_SET +AC_PROG_INSTALL + +dnl Maintainer mode requires ctangle, cweave, and csplain +AC_CHECK_PROGS([CTANGLE], [ctangle], [none]) +AC_CHECK_PROGS([CWEAVE], [cweave], [none]) +AC_CHECK_PROGS([CSPLAIN], [csplain], [none]) + +if test x"$enable_maintainer_mode" = xyes; then + case :$CTANGLE:$CWEAVE:$CSPLAIN: in + *:none:*) + AC_MSG_WARN([Maintainer mode disabled -- requires ctangle, cweave, and csplain.]) + enable_maintainer_mode=no + ;; + esac +fi + +AM_MAINTAINER_MODE[]dnl maintainer mode only if requested + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/Build/source/utils/vlna/vlna-1.5/csmac.tex b/Build/source/utils/vlna/vlna-1.5/csmac.tex new file mode 100644 index 00000000000..0860a70f4f0 --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/csmac.tex @@ -0,0 +1,63 @@ +\chyph +\font\ninerm=csr9 +\font\eightrm=csr8 +\let\sc=\eightrm % small caps (NOT a caps-and-small-caps font) +\font\titlefont=csr7 scaled\magstep4 % title on the contents page +\font\ttitlefont=cstt10 scaled\magstep2 % typewriter type in title +\def\postATL#1 #2 {\bf písmeno \\{\uppercase{\char"#1}} + v~.c kódu jako \tentex "#2"\egroup\par} +\def\ATH{\X\kern-.5em:Definice pro preprocesor\X} +\def\A{\note{Viz také sekci}} % xref for doubly defined section name +\def\As{\note{Viz také sekce}} % xref for multiply defined section name +\def\ET{ a~} % conjunction between two section numbers +\def\ETs{ a~} % conjunction between the last two of several section numbers +\def\Q{\note{Tento kód je citován v~sekci}} % xref for mention of a section +\def\Qs{\note{Tento kód je citován v~sekcích}} % xref for mentions of a section +\def\U{\note{Tento kód je použit v~sekci}} % xref for use of a section +\def\Us{\note{Tento kód je použit v~sekcích}} % xref for uses of a section +\def\ch{\note{Následující sekce byly změněny prostřednictvím změnového + souboru:} \let\*=\relax} +\def\fin{\par\vfill\eject % this is done when we are ending the index + \ifpagesaved\null\vfill\eject\fi % output a null index column + \if L\lr\else\null\vfill\eject\fi % finish the current page + \parfillskip 0pt plus 1fil + \def\grouptitle{NÁZVY SEKCÍ} + \let\topsecno=\nullsec + \message{Section names:} + \output={\normaloutput\page\lheader\rheader} + \setpage + \def\note##1##2.{\quad{\eightrm##1~##2.}} + \def\Q{\note{Citováno v~sekci}} % crossref for mention of a section + \def\Qs{\note{Citováno v~sekcích}} % crossref for mentions of a section + \def\U{\note{Použito v~sekci}} % crossref for use of a section + \def\Us{\note{Použito v~sekcích}} % crossref for uses of a section + \def\I{\par\hangindent 2em}\let\*=* + \readsections} +\def\contentsline#1#2#3#4{\ifnum#2=0 \smallbreak\fi + \line{\consetup{#2}#1 + \rm\leaders\hbox to .5em{.\hfil}\hfil\ #3\hbox to4em{\hss#4}}} +\def\con{\par\vfill\eject % finish the section names +% \ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers + \rightskip 0pt \hyphenpenalty 50 \tolerance 200 + \setpage \output={\normaloutput\page\lheader\rheader} + \titletrue % prepare to output the table of contents + \pageno=\contentspagenumber + \def\grouptitle{OBSAH} + \message{Table of contents:} + \topofcontents + \line{\hfil Sekce\hbox to4em{\hss Strana}} + \let\ZZ=\contentsline + \readcontents\relax % read the contents info + \botofcontents \end} % print the contents page(s) and terminate +\def\today{\number\day.~\ifcase\month\or ledna\or února\or března\or + dubna\or května\or června\or července\or srpna\or září\or října\or + listopadu\or prosince\fi \space\number\year} +\def\datethis{\def\startsection{\leftline{\sc\today\ v~\hours}\bigskip + \let\startsection=\stsec\stsec}} +\def\datecontentspage{% + \def\topofcontents{\leftline{\sc\today\ v~\hours}\bigskip + \centerline{\titlefont\title}\vfill}} % timestamps the contents page + +\def\allowhyphens{\nobreak\hskip0pt\relax} +\def \uv#1{\char254 \allowhyphens#1\allowhyphens\char255 } + diff --git a/Build/source/utils/vlna/vlna-1.5/vlna-cz.man b/Build/source/utils/vlna/vlna-1.5/vlna-cz.man new file mode 100644 index 00000000000..334b683572b --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/vlna-cz.man @@ -0,0 +1,131 @@ +.\" $Id$ +.TH VLNA 1 "4. unora 1998" +.nh +.SH NAZEV +vlna \- pridani vlnek za neslabicne predlozky v TeXu +.SH POUZITI +.B vlna +[\fIvolby\fP] +[\fIsoubory\fP] +.SH POPIS +Program +.B vlna +pridava vlnky (misto puvodnich mezer) za neslabicne predlozky +ve vstupnich souborech pro TeX, coz zabrani zlomu radku v nezadoucich mistech. +.PP +Veskere aktivity programu je mozne vypnout sekvenci \fB%~-\fP a zapnout +sekvenci \fB%~+\fP (mezi uvedenymi znaky muze byt libovolne mnozstvi mezer). +.PP +Pred predlozkou se muze nachazet libovolne mnozstvi oteviracich zavorek, +pred kterymi se musi nachazet mezera nebo zacatek radku. Pred +oteviraci svorkou muze byt take misto mezery TeXova +\(lq\\sekvence\(rq (od verze 1.2). +Napr. za \(lq([{(V\(rq na pocatku radku bude vlnka pridana. +Stejne tak se text \(lq\\uv{V lese}\(rq promeni na +\(lq\\uv{V~lese}\(rq. +.PP +Program kontroluje konzistenci matematickych prostredi (neni-li uveden +parametr \fB\-m\fP). +Vstup do \fIdisplay\fP rezimu (\fB$$\fP) uvnitr \fItext\fP rezimu (\fB$\fP) +(napr. \fB$\fP...\fB$$\fP...\fB$\fP) znamena varovani a prechod do +\fIdisplay\fP. +Podobne prazdny radek uvnitr \fItext\fP nebo \fIdisplay\fP rezimu znamena +vypis varovani a prechod do nematematickeho (standardniho) rezimu. +Uvnitr rezimu \fIdisplay\fP se ignoruji vyskyty samostatneho znaku \fB$\fP, +jelikoz byva vetsinou soucasti konstrukce \fB\\hbox\fP. +.PP +Program kontroluje konzistenci verbatim rezimu na konci souboru. +Nebyl-li ukoncen, vypise se varovani. +Kontrola se neprovadi, pokud je pouzita volba \fB\-n\fP nebo \fB\-w\fP. +.PP +Program nedoplnuje vlnky za samostatna pismena, ktera jako predlozky vypadaji, +ale nasleduji bezprostredne za sekvencemi \fB\\TeX\fP nebo \fB\\LaTeX\fP. +Napr. do textu \(lq\fBVlastnosti \\TeX u jsou\fP\(rq nebude zadna vlnka +doplnena. +.SH VOLBY +Volby jsou nepovinne a mohou byt uvedeny v libovolnem poradi, ale nemohou +byt spojovany. +.TP +.B \-f +Filtr. Jmena souboru jsou interpretovana takto: +.RS +.TP 4 +.B vlna \-f \fIsoubor1 soubor2\fP +Vstup je \fIsoubor1\fP, vystup \fIsoubor2\fP. +.TP 4 +.B vlna \-f \fIsoubor1\fP +Vstup je \fIsoubor1\fP, vystup \fIstdout\fP. +.TP 4 +.B vlna \-f +Vstup je \fIstdin\fP, vystup \fIstdout\fP. +.TP 4 +\fBvlna\fP \fIsoubor1\fP [\fIsoubor2\fP [\fIsoubor3\fP ...]] +Neni-li uveden parametr \fB\-f\fP, kazdy soubor je zpracovavan samostatne. +.RE +.TP +.B \-s +Tichy rezim. Program potlaci vypis uvodni zpravy, varovnych zprav a +statistik o zmenach v souborech +(bez uvedeni parametru jsou zpravy vypisovany na \fIstderr\fP). +V tichem rezimu se vypise jen chyba, ktera predcasne ukonci +cinnost programu. +.TP +.B \-r +Nevytvaret (mazat) zalohy. +Parametr \fB\-r\fP nema vliv, pokud je uveden spolu s \fB\-f\fP. +V opacnem pripade se ke kazdemu souboru vytvari zaloha s vlnkou na konci jmena +a parametr \fB\-r\fP zpusobi, ze na konci zpracovani jsou tyto zalohy mazany. +.TP +.B \-v \fIznaky\fP +Znaky povazovane za neslabicne predlozky, za ktere ma byt pridavana +vlnka. Implicitni hodnota je \fB\-v\ KkSsVvZzOoUuAI\fP. (Mezi +\fB\-v\fP a skupinou znaku musi byt mezera.) +.TP +.B \-x \fIkod\fP +vymezuje string (kod je hexadecimalni zapis stringu), +ktery bude vkladan misto implicitni vlnky na vyhledana mista. +Priklad \fB\-x C2A0\fP vymezuje dvouznakovy string: misto kazde vlnky budou +vlozeny dva byty, prvni s kodem C2 a druhy s kodem A0. Podle unicodove tabulky +tento priklad tedy zpusobi nahrazovani znakem NO-BREAK SPACE pri kodovani UTF8. +Jine priklady: \fB\-x 00A0\fP nahrazovani znakem NO-BREAK SPACE pri +kodovani UTF16, \fB\-x 41484F4A\fP nahrazovani textem AHOJ. +Mezi \fB\-x\fP a kodem musi byt mezera. +.TP +.B \-m +Ignorovani prechodu do matematickych prostredi +(\fB$\fP...\fB$\fP a \fB$$\fP...\fB$$\fP). +Parametr \fB\-m\fP zpusobi vlnkovani i v matematickych prostredich, ktera +se implicitne vynechavaji. +.TP +.B \-n +Ignorovani verbatim rezimu (\fB\\verb\fP\fI<znak>\fP...\fI<znak>\fP, +\fB\\begtt\fP...\fB\\endtt\fP). +Parametr \fB\-n\fP zpusobi vlnkovani i ve verbatim rezimu, ktery se +implicitne vynechava. +.TP +.B \-l +LaTeX. Pro rozpoznani matematickeho rezimu jsou pridana prostredi +\fB\\begin{display}\fP...\fB\\end{display}\fP a +\fB\\begin{equation}\fP...\fB\\end{equation}\fP. +Pro rozpoznani verbatim rezimu je pridano LaTeXove prostredi +\fB\\begin{verbatim}\fP...\fB\\end{verbatim}\fP. +.TP +.B \-w +Web. Pro rozpoznani verbatim rezimu jsou pridany sekvence +\fB@<\fP, \fB@d\fP...\fB@*\fP, \fB@\fP\fImezera\fP nebo \fB@>|\fP. +Ve zdrojovem kodu se tedy nevlnkuje program, ale jen komentare. +.SH PRIKLADY +.TP +.B vlna \-m \-n \-s \-r \fIsoubor\fP +Volani priblizne odpovida volani puvodniho programu \fBvlnka\fP. +(Navic se neprovadi vlnkovani za sekvencemi \fB\\TeX\fP a \fB\\LaTeX\fP.) +.TP +.B vlna *.tex +Vlnkovani vsech souboru s priponou \fBtex\fP. +(Pouze na UNIXu.) +.TP +.B vlna \-f soubor > /dev/null +Test konzistence matematickeho a verbatim rezimu bez provedeni zmen. +(Pouze na UNIXu.) +.SH AUTOR +Petr Olsak <olsak@math.feld.cvut.cz>. Manualovou stranku a Makefile vytvoril Rulolf Cejka diff --git a/Build/source/utils/vlna/vlna-1.5/vlna.man b/Build/source/utils/vlna/vlna-1.5/vlna.man new file mode 100644 index 00000000000..691b3cb7128 --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/vlna.man @@ -0,0 +1,163 @@ +.\" $Id$ +.TH VLNA 1 "March 30 2009" +.nh +.SH NAME +vlna \- adds tilde after each non-syllabic preposition +.SH USAGE +.B vlna +[\fIoptions\fP] +[\fIfilenames\fP] +.SH PREFACE +There exists a special Czech and Slovak typographical rule: you cannot +leave the non-syllabic preposition on the end of one line and continue +writting text on next line. For example, +you cannot write down the text "v lese" (in a forest) like +"v<new-line>lese". The program vlna adds the asciitilde +between such preposition and the next word and removes the space(s) in +this place. It means, the program converts "v lese" to "v~lese". You +can use this program as a preporcessor before TeXing. Moreower, you +can set another sequence to store instead asciitilte (see the +\fB\-x\fP option). +.SH DESCRIPTION +The program +.B vlna +processes one or more files, searches the non-syllabic prepositions +followed by space(s) in these files and converts this/these space(s) +to asciitilde for each such occurrence. +.PP +In the processed file, the activity of the program can be blocked by +\fB%~-\fP sequence and the activity can be restored again by the +\fB%~+\fP sequence. These sequences can include spaces, it means that +\fB% ~-\fP is a correct sequence too. +.PP +The rule to recognize a preposition follows: +The arbitrary number of opening parentheses can be written before the +preposition and before these (optional) parentheses must be the space, +tabelator or new-line. The preposition itself is one-letter word, the letters +have to be from this set: {KkSsVvZzOoUuAI}. See the \fB\-v\fP option if you +want to change this set of letters. From version 1.2, the TeX sequence +can be written before preposition and before the brace. Example: +"<new-line>([V lese" is converted to "<new-line>([V~lese". +Another example: "\\uv{V lese}" is converted to "\\uv{V~lese}". +.PP +One or more blank-spaces have to be included after preposition +before next word. The blank-space means space or tabelator. +One <new-line> can be here too. +All these characters are removed and replaced by asciitilde (or by +another string, see \fB\-x\fP option). If <new-line> is deleted, another +<new-line> is created before preposition (and before optional parentheses) +in order to the number of lines is kept unchanged. +Example: "... V<new-line><tabelator>lese" is converted to +"...<new-line>V~lese". +.PP +The program checks the consintence of TeX's math environments +(if \fB\-m\fP option isn't used). For example the "$...$$...$" sequence +(it means the display mode switch inside the text-math mode) +generates a warning. Empty line inside display mode generates +a warning too and the program processes next text like +in normal (non-math) mode. The existence of the "$" inside display mode +are accepted because the constructions like +$$..\\hbox{..$..$}..$$ are allowed and common. +.PP +The consistence of verbatim mode is checked on the end of the file. +If the file ends but the verbatim mode does not end the warning is printed. +This behavior can be switched off by \fB\-n\fP or \fB\-w\fP options. +.PP +The program suppresses the tilde changing after letters like prepositions +but they are not prepositions because the \fB\\TeX\fP or \fB\\LaTeX\fP +sequence precedes. Example: "vlastnosti \\TeX u jsou" is not converted to +"vlastnosti \\TeX u~jsou", because this text is printed (after TeX +processing) like "vlastnosti TeXu jsou". The letter "u" is a suffix here, +no preposition. +.SH OPTIONS +The options are optional and can be written in arbitrarty order separated +by space. +.TP +.B \-f +Filter. The [\fIfilenames\fP] are treated as follows: +.RS +.TP 4 +.B vlna \-f \fIfilename1 filename2\fP +Input is \fIfilename1\fP, output is \fIfilename2\fP. +.TP 4 +.B vlna \-f \fIfilename1\fP +Input is \fIfilename1\fP, output is \fIstdout\fP. +.TP 4 +.B vlna \-f +Input is \fIstdin\fP, output is \fIstdout\fP. +.TP 4 +\fBvlna\fP \fIfilename1\fP [\fIfilename2\fP [\fIfilename3\fP ...]] +If the \fB\-f\fP option is omitted then each file is processed +independently and it is re-written. +.RE +.TP +.B \-s +The silent mode. No messages, warnings, statistics are printed. +Only errors which terminates the program untimely are printed. +If this parameter is omitted then banner, warnings and statistics +are printed to \fIstderr\fP. +.TP +.B \-r +Do not create the backups. The option \fB\-r\fP is irrelevant if +the \fB\-f\fP option is used. If the \fB\-f\fP and \fB\-r\fP options +aren't used then each re-written file is stored with its original contents +to a backup file (the name of backup file is the same as filename, only +the tilde is used instead of the last character). +.TP +.B \-v \fIcharacters\fP +The set of characters treated as non-syllabic prepositions is declared +by this option. Default: \fB\-v\ KkSsVvZzOoUuAI\fP. +The space between \fB\-v\fP and \fIcharacters\fP is required. +.TP +.B \-x \fIcode\fP +The \fIcode\fP is a string written in hexadecimal notation +(even hexa digits is required). This string will be saved after prepositions +instead asciitilde which is default. +The example: \fB\-x C2A0\fP two bytes are stored after each +non-syllabic preposition, first byte has C2 code and second byte +has A0 code. This example means that +NO-BREAK SPACE in UTF8 encoding will be used after prepositions. +Another example: \fB\-x 00A0\fP the NO-BREAK SPACE in UTF16 encoding. +Another example: \fB\-x 48454C4C4F\fP the string HELLO will be used. +The space between \fB\-x\fP and \fIcode\fP is required. +.TP +.B \-m +The math-modes (\fB$\fP...\fB$\fP and \fB$$\fP...\fB$$\fP) are ignored. +It means that non-syllabic prepositions is searched in math-mode too. +Default (without \fB\-m\fP option): no changes in math modes are done +because (for example) "v" is variable in math-mode, no preposition. +.TP +.B \-n +The verbatim mode (\fB\\verb\fP\fI<char>\fP...\fI<char>\fP, +\fB\\begtt\fP...\fB\\endtt\fP) is ignored, it means the program can +do a changes in verbatim environment. +Default (without \fB\-n\fP option): no changes in verbatim mode are done. +.TP +.B \-l +The LaTeX mode. The following environments are treated as display mode: +\fB\\begin{display}\fP...\fB\\end{display}\fP and +\fB\\begin{equation}\fP...\fB\\end{equation}\fP and the following +environment is treated as verbatim mode: +\fB\\begin{verbatim}\fP...\fB\\end{verbatim}\fP. +.TP +.B \-w +The web mode (Knuth's web, no www:-). The following sequences are +treated as verbatim: +\fB@<\fP, \fB@d\fP...\fB@*\fP, \fB@\fP\fIspace\fP or \fB@>|\fP. +It means program code is unchanged in *.w or *.web files, only +web-comments are processed. +.SH EXAMPLES +.TP +.B vlna \-m \-n \-s \-r \fIfile\fP +The program has a behavior similar to the old \fBvlnka\fP program. +.TP +.B vlna *.tex +All files with .tex suffix in current directory will be processed +(and possibly changed). (The "*" is UNIX-shell feautre). +.TP +.B vlna \-f file > /dev/null +Only the consistence checking of math and verbatim modes is processed. +No changes are done. +.SH AUTHORS +Petr Olsak <olsak@math.feld.cvut.cz>. +Man page (Czech original) and Makefile is created by Rulolf Cejka diff --git a/Build/source/utils/vlna/vlna-1.5/vlna.txt b/Build/source/utils/vlna/vlna-1.5/vlna.txt new file mode 100644 index 00000000000..0546f828207 --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/vlna.txt @@ -0,0 +1,131 @@ + + Program VLNA + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + verze 1.4 Petr Olšák + +Program vlna přidává vlnky (místo původních mezer) za neslabičné předložky +ve vstupních souborech pro TeX. To zabrání zlomu řádku v nežádoucím místě. + +Není použit název "vlnka", abychom odlišili původní program vlnka +(autoři O. Ulrych, Š. Kasal) od tohoto programu vlna. Jedná se o +vylepšenou a zcela nově napsanou verzi, která není důsledně zpětně +kompatibilní s původním programem vlnka. + +POUŽITÍ: +-------- + +vlna [opt] [jména souborů] + +[opt] jsou nepovinné přepínače, které musí být odděleny mezerou a uvozeny +znakem "-". Mohou být uvedeny v libovolném pořadí. + +PŘEPÍNAČE: +---------- + +-f : Režim "filtr". V tomto režimu jsou jména souborů interpretována takto: + vlna -f soubor1 soubor2 ... soubor1 -> soubor2 (musí: in!=out) + vlna -f soubor1 ... soubor1 -> stdout + vlna -f ... stdin -> stdout + Není-li program v režimu filtr, pak jsou jména souborů interpretována + takto: + vlna soubor1 [soubor2 [soubor3...]] + Zde je každý soubor "ovlnkován" samostatně, tj. soubory jsou měněny. + Není-li uveden parametr -r, jsou vytvářeny zálohy k souborům + s vlnkou na konci jména. +-s : Tichý režim. Program nevypisuje úvodní zprávu, varovné zprávy a + statistiky o změnách v souborech. Tyto texty se vypisují do stderr, + takže v režimu filtr není nutné -s zapínat, pokud umíme oddělit stderr + od stdout. V tichém režimu se vypíše jen chyba, která předčasně ukončí + činnost programu. +-r : Nevytvářet (mazat) zálohy. Není-li program v režimu filtr, pak se ke + každému souboru vytváří záloha s vlnkou na konci jména. Takové soubory + se interně vytvářejí vždy při běhu programu v režimu ne-filtr. Je-li + uveden parametr -r, jsou na konci zpracování tyto zálohy mazány. + V režimu filtr nemá -r žádný vliv. +-v znaky : Definice znaků, které budeme považovat za neslabičné předložky, + tj. k ovlnkování. Implicitní hodnota -v KkSsVvZzOoUuAI je použitím + tohoto parametru přepsána. Mezi -v a skupinou znaků musí být mezera. +-x kód : Vyhledané místo se implicitně nahrazuje vlnkou. Místo toho jej + můžete nechat nahrazovat libovolným stringem. Kód za parametrem + -x je hexadecimálně vyjádřený string, nula je ve stringu + povoleným znakem. Takže -x C2A0 vymezuje dvouznakový string: + místo každé vlnky budou vloženy dva byty, první s kódem C2 a + druhý s kódem A0. Podle unicodové tabulky tento pžíklad tedy + způsobí nahrazování znakem NO-BREAK SPACE při kódování UTF8. + Jine příklady: -x 00A0 nahrazování znakem NO-BREAK SPACE při + kódování UTF16, -x 41484F4A nahrazování textem AHOJ. Mezi -x a + kódem musí být mezera. +-m : Ignoruje přechody do matematického režimu ($...$ a $$...$$) a vlnkuje + i v těchto prostředích. Imlicitně v matematických prostředích nevlnkuje. +-n : Ignoruje přechody do verbatim režimu (\verb<zn>...<zn>, \begtt...\endtt) + a vlnkuje i v těchto prostředích. +-l : LaTeX mód. K výše uvedeným sekvencím ohraničující display math + mód je přidáno \begin{display}...\end{display} a + \begin{equation}...\end{equation}. K sekvencím ohraničující + verbatim mód je přidáno \begin{verbatim}...\end{verbatim} +-w : web mód. K sekvencím ohraničujícím verbatim mód je přidáno + @< nebo @d ... @* nebo @mezera nebo @>| . To způsobí, že není + provlnkovaný kód programu ve web souborech, ale jenom komentáře. + +POZNÁMKY: +--------- + +* Před předložkou může být libovolné množství otevíracích závorek, + před kterými musí být mezera nebo začátek řádku. Před otevírací + svorkou může také být místo mezery TeXova "\sekvence" (od verze 1.2). + Např. ([{(V tomto případě bude vlnka za V. Stejně tak + se vlnka objeví \boldfont{V tomto případě}. +* Veškeré aktivity programu je možné vypnout sekvencí %~- a zapnout + sekvencí %~+ (mezi uvedenými znaky může být libovoné množství mezer) +* Program kontroluje konzistenci matematických režimů. Dá varování + v těchto případech: + Vstup do display uvnitř t-math (např. $ ...$$... $). -- přejde do display. + Prázdný řádek uvnitř t-math nebo display -- přejde do standardního režimu. + Poznamenejme, že uvnitř display se ignorují výskyty jednoho dolaru + naprosto bez varování, protože ty většinou mohou být součástí \hbox-u. + Při -m není konzistence math. módů kontrolována. +* Program kontroluje konzistenci verbatim módů na konci souboru. + Nebyl-li verbatim mód ukončen, objeví se varování. Tento test + neprobíhá, pokud je nastaven přepínač -n nebo -w. +* Program nedoplňuje vlnky za písmena, která vypadají "jako" + předložky, ale následují bezprostředně za sekvencemi \TeX nebo + \LaTeX, tj. např. v textu "Vlastnosti \TeX u jsou" nepřidá vlnku + mezi u a j. Sekvence \TeX a \LaTeX jsou zatím natvrdo implementovány + do programu. Otázka čtení množiny takových sekvencí z konf. souboru + (nebo odjinud) bude (možná) zahrnuta v další verzi. + +TIPY K POUŽITÍ PROGRAMU: +------------------------ + +vlna -m -n -s -r soubor ... odpovídá zhruba volání původního vlnka. +Není to zcela přesné, protože program navíc nevlnkuje za slovy \TeX a +\LaTeX a to se nedá vypnout. + +vlna *.tex ... provlnkuje všechny soubory s příponou .tex. +Pracuje pouze na UNIXu. + +vlna -f soubor > /dev/null ... provede test konzistence math a +verbatim módů a neudělá žádnou změnu. + +HISTORIE TOHOTO PRODUKTU: +------------------------- + +Původní verzi programu vlnka vytvořil zhruba v roce 1990 Oldřich Ulrych +v Pascalu. Další vylepšení v Pascalském programu udělal Štěpán Kasal. +Tento Pascalský program je šířen v balíku CSTeX. + +Zde uvedená varianta programu (vlna) byla napsána v únoru 1995 pro +použití v UNIXových prostředích, a proto v jazyce C. Přesněji byl +použit prostředek CWEB, který umožňuje snadno číst zdrojový text a +snadno jej modifikovat. Program byl zcela přepracován (z původního +Pascalského kódu nebylo použito vůbec nic) a byl do něj implementován +algoritmus rozpoznávání tzv. patternů (jednoduchých regulárních +výrazů). + +Tato varianta programu byla testována na SUN OS a na MS DOS. + +V únoru 1998 mi poslal pan Rudof Čejka Makefile a manuálovou stránku +k programu a ve zdrojovém kódu poravil drobné chyby. + +23.2.1995 Petr Olšák. + diff --git a/Build/source/utils/vlna/vlna-1.5/vlna.w b/Build/source/utils/vlna/vlna-1.5/vlna.w new file mode 100644 index 00000000000..08a7588ecc6 --- /dev/null +++ b/Build/source/utils/vlna/vlna-1.5/vlna.w @@ -0,0 +1,1070 @@ + +\input csmac % Makra pro češtinu +\pageheight=9.5in \fullpageheight=9.8in \setpage +%\nocon % omit table of contents +\datethis % print date on listing + +\def\begitems{\medskip\bgroup\catcode`\*=13 \narrower\narrower} +\def\enditems{\par\egroup\medskip} +{\catcode`\*=13 \gdef*{\par\noindent\llap{$\bullet$\ }\ignorespaces}} + + +@* PROGRAM VLNA. +Program čte vstupní textový soubor a nahrazuje za specifikovanými +jednopísmennými slovy (např.~v, k, u) mezery symbolem \uv{\.{\char126}}. To +zabrání při následném zpracování \TeX{}em zlomit řádek na nevhodných +místech, která jsou v rozporu s typografickou normou. + +Program sestává z těchto hlavních celků: +@c +@<Hlavičkové soubory k načtení@>@/ +@<Globální deklarace@>@/ +@<Pomocné funkce@>@/ +@<Vlnkovací funkce |tie|@>@/ +@<Hlavní program@> + +@ Definujeme |BANNER|, což je text, který se objevi při startu +programu a obsahuje číslo verze programu. +Zde je názorně vidět, že míchání dvou jazyků se nevyhneme. Při tisku +textů na terminál nesmíme předpokládat, že tam budou české fonty. +V~této dokumentaci se setkáme se třemi jazyky: angličtinou (většinou +v~kódu programu, cestinou v~/* komentářích */ a češtinou jinde. +Tu cestinu si vynutil fakt, že DOS-ovská varianta \.{tangle} a +\.{weave} se nesnáší s~akcentovanými písmeny v~/* komentářích */. +A~nyní už slíbený (vícejazyčný) |BANNER|. +@d BANNER "This is program vlna, version 1.5, (c) 1995, 2002, 2009, 2010 Petr Olsak\n" + +@ V programu jsou použity knihovní funkce, jejíchž prototypy jsou +definovány ve třech standardních hlavičkových souborech. +@<Hlavičkové ...@>= +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +@ Definujeme konstanty pro návratový kód. |OK| pro úspěšný běh, +|WARNING| při výskytu aspoň jedné varovné zprávy, |IO_ERR| pro chybu +v~přístupu ke vtupním nebo výstupním souborům, |BAD_OPTIONS| pro +syntaktickou chybu na příkazové řádce a |BAD_PROGRAM| pro případ +havárie programu. Ta by neměla nikdy nastat. Proměnná |status| bude +obsahovat návratový kód a proměnná |prog_name| bude ukazovat na text +nultého parametru příkazové řádky. +@d OK 0 +@d WARNING 1 +@d IO_ERR 2 +@d BAD_OPTIONS 3 +@d BAD_PROGRAM 4 +@<Globální deklarace@>= +char *prog_name; +int status; + +@ Základní rozvržení funkce |main|. +@<Hlavní program@>= +int main (int argc, char **argv) +{ + @<Lokální proměnné funkce |main|@>; + prog_name=argv[0]; status = OK; + @<Načtení parametrů příkazového řádku@>; + if (!silent) fprintf (stderr, BANNER); + @<Inicializace datových struktur@>; + @<Zpracování souborů@>; + return status; +} + +@* Parametry příkazového řádku. +Program čte z~příkazového řádku postupně (nepovinné) parametry, +které začínají znakem \uv{\.{-}}. Pak následují jména vstupních a výstupních +souborů. +\begitems +* \.{-f} \dots\ program pracuje jako filtr (viz sekce |@<Zpracování + souborů@>|). Není-li tento parametr použit, program pracuje v tzv. + standardním režimu, kdy jednotlivé soubory jsou vstupní i výstupní. +* \.{-s} \dots\ program nevypíše |BANNER|, ani sumarizaci, ani varování, + při nichž není program předčasně ukončen. Všechny tyto výpisy + směřují do |stderr|, takže pokud program pracuje v režimu \uv{filtr}, + není nutné tento parametr použít. +* \.{-r} \dots\ program maže pracovní soubor (soubory), které vytváří + ve standardním režimu (tj. není použit \.{-f}). V reřimu filter nemá + tento parametr vliv. +* \.{-v} \dots\ parametr definuje skupinu písmen, které budou + interpretovány jako neslabičné předložky. + Např. \.{-v KkSsVvZzOoUuAI}. Pokud není parametr uveden, je použita + skupina uvedená v tomto příkladě. +* \.{-x} \dots\ parametr vymezuje pomocí hexadecimálního zápisu string, + který program vkládá na vyhledaná místa. Implicitně vkládá vlnku. + Například \.{-x C2A0} způsobí, že program bude vkládat místo vlnky dva byty, + první s kódem \.{C2} a druhý s kódem \.{A0}. +* \.{-m} \dots\ program neprovádí kontrolu math/text módů, tj. vlnkuje i + uvnitř matematického módu \TeX{}u. (Implicite tam nevlnkuje). +* \.{-n} \dots\ prorgram neprovádí kontrolu verbatim módu, tj. vlnkuje i + uvnitř verbatim módu definovaném běžnými prostředími. Imlicite ve + verbatim prostředí nevlnkuje. +* \.{-l} \dots\ La\TeX{} režim. Při kontrole text-math-verbatim módů jsou + brány v úvahu další sekvence, obvyklé v La\TeX{}ových dokumentech. +* \.{-w} \dots\ WEB režim. Ohraničení verbatim módu je doplněno znaky + používanými v dokumentech WEB (např. tento dokument). Důsledek: program + vlnkuje dokumentační část každé sekce, ale nikoli kód. +\enditems + +Definujeme funkci |printusage|, která tiskne (při chybě) stručný přehled +možných parametrů. Nepodařilo se mi zjistit, jak se ve WEBu napíše +kulturně dlouhý string obsahující \.{\char92n} s formátovacími +požadavky. Byl jsem nucen to takto nehezky zapsat. +@<Pomocné funkce@>= +static void printusage (void) +{ + fprintf(stderr, + "usage: vlna [opt] [filenames]\n" + " opt -f : filter mode: file1 file2 ... file1->file2\n" + " file1 ... file1->stdout\n" + " ... stdin->stdout\n" + " nofilter: file1 [file2 file3 ...] all are in/out\n" + " -s : silent: no messages to stderr\n" + " -r : rmbackup: if nofilter, removes temporary files\n" + " -v charset : set of lettres to add tie, default: KkSsVvZzOoUuAI\n" + " -x code : code for tie symbol, default: 7E, example -x C2A0\n" + " -m : nomath: ignores math modes\n" + " -n : noverb: ignores verbatim modes\n" + " -l : LaTeX mode\n" + " -w : web mode\n"); +} + +@ Proměnné |isfilter|, |silent|, |rmbackup|, |nomath|, |noverb|, +|latex|, resp. |web| říkají, že je nastaven parametr \.{-f}, \.{-s}, +\.{-r}, \.{-m}, \.{-n}, \.{-l}, resp. \.{-w}. Proměnná |charset| +ukazuje buď na implicitní skupinu znaků |charsetdefault|, nebo (při +použití parametru \.{-v}) na text uvedený v příkazovém řádku. +@<Globální deklarace@>= +int isfilter=0, silent=0, rmbackup=0, nomath=0, noverb=0, web=0, latex=0; +char charsetdefault[]="KkSsVvZzOoUuAI"; +char *charset=charsetdefault; + +@ String |tiestr| obsahuje string, kterým se má nahradit vyhledané +místo. Pokud není použit parametr \.{-u}, je tento string jadnoznakový +a obsahuje vlnku. Jinak obsahuje string konvertovaný z parametru \.{-u}. +String má délku |tiestrlen| bez ohledu na to, zda obsahuje nebo +neobsahuje nulové znaky (C-čková konvence pro stringy není použita). +@<Globální deklarace@>= +unsigned char tiestr[MAXLEN]; +int tiestrlen; + +@ @<Načtení parametrů ...@>= +tiestr[0] = '~'; +tiestrlen = 1; +while (argc>1 && argv[1][0] == '-') { + if (argv[1][2] != 0) printusage (), exit (BAD_OPTIONS); + switch(argv[1][1]) { + case 'f': isfilter = 1; break; + case 's': silent = 1; break; + case 'r': rmbackup = 1; break; + case 'v': if (argc<2) printusage (), exit (BAD_OPTIONS); + argv++; argc--; charset = argv[1]; break; + case 'x': if (argc<2) printusage (), exit (BAD_OPTIONS); + argv++; argc--; settiestr(argv[1]); break; + case 'm': nomath = 1; break; + case 'n': noverb = 1; break; + case 'l': latex = 1; break; + case 'w': web = 1; break; + default: printusage (), exit (BAD_OPTIONS); + /* nezn\'am\'y parametr */ + } + argc--; argv++; +} + +@ Vyřešíme konverzi kódu zapsaného za parametrem \.{-x} na string |tiestr|. +@<Pomocné funkce@>= +static unsigned char hexnum(char c) { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + printusage (), exit (BAD_OPTIONS); +} +static void settiestr(char *s) { + int i, j; + i = strlen(s); + if ((i > 2*MAXLEN) || i%2 == 1) printusage (), exit (BAD_OPTIONS); + tiestrlen = i/2; + j = 0; + for (i=0; i<tiestrlen; i++) { + tiestr[i] = hexnum(s[j++]) << 4; + tiestr[i] += hexnum(s[j++]); + } +} + +@* Zpracování souborů. Parametr |MAXLEN| definuje maximální možnou +délku jména souboru, který vytvoříme jako přechodný, nebo zálohový. +Dále deklarujeme proměnné typu \uv{stream}. +@d MAXLEN 120 +@<Lokální proměnné funkce...@>= +FILE *infile, *outfile; +char backup[MAXLEN]; +int j; + +@ Definujeme funkci pro výpis chybového hlášení při neúspěšném otevření +souboru. +@<Pomocné funkce@>= +static void ioerr (char *f) +{ + fprintf(stderr, "%s: cannot open file %s\n", prog_name, f); +} + +@ Způsob zpracování souborů rozlišíme podle režimu daným přepínačem \.{-f}. +@<Zpracování souborů@>= +if (isfilter) @<Zpracování v režimu filter@> @/ +else @<Zpracování všech souborů příkazové řádky@> + +@ V režimu |isfilter==1| je další zpracování závislé na počtu souborů v +příkazové řádce: +\begitems +* nula souborů -- vstup je |stdin| a výstup je |stdout|, +* jeden soubor -- je vstupní, výstup je |stdout|, +* dva soubory -- první je vstupní, druhý výstupní, +* více souborů -- program skončí s chybou. +\enditems +@<Zpracování v režimu filter@>= +{ + if (argc > 3) printusage (), exit (BAD_OPTIONS) ; + infile = stdin; outfile = stdout; + if (argc >= 2) infile = fopen (argv[1], "r"); + if (infile == NULL) ioerr (argv[1]), exit (IO_ERR); + if (argc == 3) outfile = fopen(argv[2], "w"); + if (outfile == NULL) ioerr (argv[2]), exit (IO_ERR); + if (argc >= 2) filename = argv[1]; + else filename = NULL; + tie (infile, outfile); + if (outfile != stdout) fclose (outfile); + if (infile != stdin) fclose (infile); +} + +@ V~režimu |isfilter==0| jsou jednotlivé soubory v~příkazovém řádku +interpretovány jako vstupní i výstupní. Více souborů v~příkazovém řádku má +stejný efekt, jako opakované volání programu na jednotlivé soubory. +V~\UNIX/u lze tedy např. napsat \.{\jobname\ *.tex} a program doplní vlnky do +všech souborů s~příponou~\.{tex}. Toto neplatí v~DOSu, protože interpretace +masky je v~\UNIX/u starostí shellu a nikoli programu samotného. Náš program +masku nebude interpretovat. Je-li v~tomto režimu nulový počet souborů, +program se ukončí s~chybou. +@<Zpracování všech souborů příkazové řádky@>= +{ + if (argc==1) printusage (), exit(BAD_OPTIONS); + while (argc>1) { + argc--; argv++; + @<Přejmenuj vstup |argv[0]| na |backup| a otevři jej jako |infile|@>; + if (infile == NULL) { + ioerr (argv[0]); continue; + } + outfile = fopen (argv[0], "w"); + if (outfile == NULL) { + ioerr (argv[0]); + rename (backup, argv[0]); + status = WARNING; + continue; + } + filename = argv[0]; + tie (infile, outfile); + fclose (outfile), fclose (infile); + if (rmbackup) remove (backup); + } +} + +@ Při |isfilter==0| program přejmenuje každý zpracovávaný soubor tak, že +změní poslední písmeno názvu souboru na znak \.{\char126}. Tento +přejmenovaný soubor bude otevřen jako vstupní a výstupem bude původní +soubor. Vstupní soubor při |rmbackup==0| zůstane zachován jako záloha. + +Proč vlnku nepřidáváme na konec názvu souboru, ale měníme ji za poslední +znak souboru? Protože chceme, aby program fungoval i v tak nemožných +systémech, jako je DOS. +@<Přejmenuj vstup...@>= +infile = NULL; +j = strlen (argv[0]) - 1; +if (j >= MAXLEN || argv[0][j] == '~') { + if (!silent) fprintf (stderr, "%s: the conflict of file name %s\n", + prog_name, argv[0]); +} +else { + strcpy (backup, argv[0]); + backup[j] = '~'; + remove (backup); + j = rename (argv[0], backup); + if (j == 0) infile = fopen (backup, "r"); +} + +@* Patterny. Abychom mohli účelně definovat chování programu +v~různých situacích, zavedeme datovou strukturu |PATTERN|. Zhruba +řečeno, budeme sledovat vstup znak po znaku a pokud bude část vstupu +souhlasit s~definovaným patternem, provedeme námi požadovanou +akci. Například nejčastější aktivitu, přidání vlnky uvnitř řádku, +spustíme v~okamžiku, kdy vstupní text odpovídá patternu \uv{\.{\ (v\ +p}}, kde \uv{\.{\ }} znamená jedna nebo více mezer a tabelátorů, +\uv{\.{(}} je nula nebo více otevíracích závorek všeho druhu, +\uv{\.{v}} znamená jedno písmeno z~množiny předložek (viz |charset|) a +\uv{\.{p}} zde znamená libovolné písmeno. Příklad zde není zcela přesný. +Přesně jsou všechny patterny pro náš program definovány v~závěrečných +sekcích tohoto povídání. + +Pattern bude znamenat konečnou sekvenci tzv. pozic patternu (|PATITEM|). +Cykly uvnitř pozic pro jednoduchost nepřipustíme. Každá pozice obsahuje +řetězec znaků, uvažovaný pro danou pozici (v~příkladu pozice~\uv{\.{\ }} by +obsahovala mezeru a tabelátor, zatímco pozice \.{v} odpovídá |charset|). +Každá pozice má svůj přepínač (|flag|), který obsahuje informaci o~tom, +zda shodu testovaného znaku s~některým prvkem v~množině znaků +budeme považovat za úspěch či neúspěch a zda pozice se ve zkoumaném +řetězci může vyskytovat právě jednou nebo opakovaně. Jako druhý případ +stačí implementovat \uv{nula nebo více} protože \uv{jedna nebo více} lze +popsat pomocí dvou pozic, první \uv{právě jednou} a následující \uv{nula +nebo více}. Jednotlivé pozice jsou zřetězeny ukazatelem |next|, poslední +pozice má |next==NULL|. Stejně tak jednotlivé patterny budeme +sestavovat do seznamů a budou rovněž zřetězeny ukazatelem |next|. + +Pattern kromě řetězu pozic obsahuje ukazatel na funkci (proceduru) |proc|, +která se má vykonat v~případě, že testovaný řetězec vyhovuje patternu. + +@d ONE 1 /* flag: prave jeden vyskyt */ +@d ANY 2 /* flag: nula nebo vice */ +@d ONE_NOT -1 /* flag: prave jednou, znak nesmi byt v mnozine */ +@d ANY_NOT -2 /* flag: nula nebo vice, znak nesmi byt v mnozine */ + +@<Globální deklarace@>= +typedef struct PATITEM { /* jedna pozice patternu */ + char *str; /* seznam znaku na teto pozici */ + int flag; /* vyznam seznamu znaku */ + struct PATITEM *next ; /* nasledujici pozice patternu */ +} PATITEM; +typedef struct PATTERN { /* jeden pattern */ + PATITEM *patt; /* ukazatel na prvni pozici */ + void (*proc)(void); /* procedura spustena pri souhlasu patternu */ + struct PATTERN *next ; /* nasledujici v seznamu vsech patternu */ +} PATTERN; + +@ Deklarujeme některé globální proměnné pro práci s~patterny. |lapi| je pole +obsahující ukazatele na aktuální pozice v~otevřených patternech. Říkáme, +že \uv{pattern je otevřen}, pokud zkoumaný řetězec s~ním {\it začíná\/} +souhlasit. Pattern se uzavře, pokud nastane jedna ze dvou možností: +zkoumaný řetězec s~mím souhlasí až do konce (v~takovém případě se provede +procedura |proc|), nebo při vyšetřování dalších znaků ze zkoumaného +řetězce přestane řetězec s~patternem souhlasit. + +V~dané chvíli může být pattern otevřen několikrát. Např. pattern \.{abac} +je při stringu \.{aba} při výskytu druhého \.{a} otevřen podruhé. Proto +pole obsahuje ukazatele na právě aktuální pozici patternu a nikoli na +pattern jako takový. + +V~poli |lapi| budou na počátku samá |NULL| (to se při překladu inicializuje +samo) a přemazání ukazatele na pozici konstantou |NULL| budeme považovat +za zavření patternu. Vedle pole |lapi| souměrně udržujeme pole |lapt|, +do něhož budeme ukládat ukazatele na odpovídající otevřený pattern. Tuto +informaci použijeme v~případě, že potřebujeme např, znát |proc| +patternu. + +|listpatt| bude ukazovat na začátek aktuálního seznamu patternů. Seznamy +budeme mít dva. Jeden se použije, nacházíme-li se mimo komentář a druhý +v~případě, že se nacházíme v~prostoru \TeX{}ovského komentáře (tj. za +procentem). Starty těchto seznamů patternů jsou |normallist| a +|commentlist| a aktivní |listpatt| má vždy jednu z~těchto dvou hodnot. + +Proměnné |lastpt| a |lastpi| použijeme pro budování řetězové struktury +patternů. + +Proměnná |c| obsahuje právě testovaný znak ze vstupu (který se rovněž +přepíše do bufferu |buff|). Z~bufferu občas ukládáme data do výstupního +proudu. Děláme to ale vždy jen v~okamžiku, kdy není otevřen žádný +pattern. Tehdy totiž \uv{nehrozí} situace, že by nějaká procedura vyvolaná +souhlasem patternu požadovala v~tomto bufferu nějaké změny se zpětnou +platností. O~vyprázdnění bufferu se začneme zajímat až v~okamžiku, kdy je +zaplněn aspoň na hodnotu |BUFI|, abychom proceduru přepisu bufferu do +výstupního proudu neaktivovali zbytečně často. +@d MAXPATT 200 /* maximalni pocet patternu */ +@d MAXBUFF 500 /* velikost bufferu pro operace */ +@d BUFI 300 /* velikost stredniho zaplneni */ +@<Globální deklarace@>= +PATITEM *lapi[MAXPATT]; /* pole ukazatelu na aktualni pozice */ +PATTERN *lapt[MAXPATT]; /* pole odpovidajicich ukazatelu na patterny */ +PATTERN *listpatt, *normallist, *commentlist, *pt, *lastpt=NULL; +PATITEM *lastpi=NULL; +char c; /* zrovna nacetny znak */ +char buff[MAXBUFF]; /* prechodny buffer */ +int ind; /* aktualni pozice prechodneho bufferu */ + +@ Dne 30. 4. 2009 jsem přidal možnost čtení vstupu, který obsahuje nulové byty. +Takové nuly se přepisují do výstupu, ale program si jich nevšímá při +procházení patternů. Tím je možno program použít na soubory kódované +v UTF16, ačkoli patterny obsahují jen jednobytové ASCII znaky. +Buffer |buff| může obsahovat i nulové byty, které je třeba přepsat do výstupu. +Na druhé straně buffer |buffnz| obsahuje jen nenulové byty, na které se +někdy ptáme při pohledu dozadu. Nejdelší pohled dozadu je o čtyři byty. +Udělám tedy |buffnz| osmibytový, začnu jej plnit od |buffnz|[4] +a kdykoli je buffer zcela zaplněn, přesunu horní čtyři byty na spodní a dále +pokračuji v plnění bufferu od pozice |buffnz|[4]. +@<Globální deklarace@>= +char buffnz[8]; +int inz; + +@ Nyní definujeme pomocné funkce |setpattern|, |setpi| a |normalpattern|. +Tyto funkce alokují paměť pomocí standardní funkce |malloc|. Abychom mohli +ohlídat případnou chybu při alokaci, budeme allokovat paměť zprostředkovaně +pomocí funkce |myalloc|. +@<Pomocné funkce@>= +static void *myalloc (int size) +{ + void *p; + p = malloc (size); + if (p == NULL) + { + fprintf (stderr, "%s, no memory, malloc failed\n", prog_name); + exit (BAD_PROGRAM) ; + } + return p; +} + +@ Funkce |setpattern| alokuje paměťové místo struktury |PATTERN| a napojí +ji pomocí proměnné |lastpt| na už alokovaný řetěz patternů. +Vrátí ukazatel na nově alokované místo. Jednotlivé pozice patternu se musí +následovně alokovat pomocí |setpi|. +@<Pomocné funkce@>= +static PATTERN *setpattern (void (*proc)(void)) +{ + PATTERN *pp; + pp = myalloc (sizeof (PATTERN)); + pp->proc = proc; + pp->next = NULL; + pp->patt = NULL; + if (lastpt != NULL) lastpt->next = pp; + lastpt = pp; + lastpi = NULL; + return pp; +} + +@ Funkce |setpi| alokuje paměťové místo pro jednu pozici patternu. Provede +zřetězení tak, aby první pozice řetězu pozic byla zaznamenána v položce +|patt| ve struktuře |PATTERN| a další byly provázány položkou |next| ve +struktuře |PATITEM|. Poslední pozice má |next==NULL|. +@<Pomocné funkce@>= +static void setpi (char *str, int flag) +{ + PATITEM* p; + p = myalloc (sizeof (PATITEM)); + p->str = str; p->flag = flag; + p->next = NULL; + if (lastpi == NULL) lastpt->patt = p; + else lastpi->next = p; + lastpi = p; +} + +@ Připravme si půdu pro funkci |normalpattern|. Tato funkce alokuje +strukturu pro jeden pattern včetně pozic patternu na základě vstupního +stringu. Každá pozice patternu obsahuje v~množině znaků jediný znak a má +|flag=ONE|. Znaky ve vstupním stringu odpovídají po řadě jednotlivým +pozicím. Vytvoří se vlastně jakýsi absolutní pattern, tj. testovaný řetězec +se musí přesně shodovat s~uvedeným stringem. Výjimku tvoří znak |"."|, +který se interpretuje jako nula nebo více mezer. Chceme-li tečku +vnutit do patternu, napíšeme dvě tečky za sebou. + +Nejdříve deklarujeme pole všech možných jednopísmenných stringů. +@<Globální deklarace@>= +char strings[512]; +int i; + +@ Inicializujeme toto pole (znak, nula, znak, nula, atd...). +@<Inicializace datových struktur@>= +for (i=0; i<256; i++) { + strings[2*i] = (char) i; strings[2*i+1] = 0; +} + +@ Definujme funkci |normalpattern|. +@<Pomocné funkce@>= +static PATTERN *normalpattern (void (*proc)(void), const char *str) +{ + PATTERN *pp; + int j=0; + pp = setpattern (proc); + while (str[j]) { + if (str[j]=='.') { + j++; + if (str[j]!='.') { + setpi (blankscr, ANY); + continue; + } + } + setpi (&strings[(unsigned char)str[j]*2], ONE); + j++; + } + return pp; +} + +@ Funkce |match|. Definujeme funkci, která na základě hodnoty znaku |c| +(proměnná |c| je definována jako globální), a pozice patternu |p| (parametr +funkce) vrátí informaci o tom, zda znak souhlasí s patternem. Záporná čísla +|FOUND|, resp. |NOFOUND| znamenají, že je třeba uzavřít pattern s tím, že +vzor odpovídá, resp. neodpovídá patternu. Nezáporné číslo vrátí v případě, +že zkoumaný vstup stále souhlasí s patternem, ale není ještě +rozhodnuto. Velikost návratové hodnoty v takovém případě udává, o kolik +pozic je třeba se posunout v patternu, abychom měli ukazatel na pozici +patternu v souhlase s novou situací, způsobenou znakem |c|. + +Pokud je |c| v množině znaků pro danou pozici |p->str|, bude |m==1|, jinak +je |m==-1|. Pokud tímto číslem pronásobíme hodnotu |p->flag|, nemusíme +větvení podle |p->flag| programovat dvakrát. Hodnoty |flag| jsou totiž +symetrické podle nuly, např. |ANY==-ANY_NOT|. +@d FOUND -1 +@d NOFOUND -2 +@<Pomocné funkce@>= +static int match (PATITEM *p) +{ + int m; + if (strchr (p->str, c) != NULL) m = 1; /* Znak nalezen */ + else m = -1; /* Znak nenalezen */ + switch (m * p->flag) { + case ANY: return 0; /* Souhas, neni nutny posun */ + case ONE: if (p->next == NULL) return FOUND; + return 1; /* Souhas, nutny posun o 1 */ + case ONE_NOT: return NOFOUND; /* Nesouhlas */ + case ANY_NOT: @<Vrať hodnotu podle následující...@>; + } + return 0; /* Tady bychom nikdy nemeli byt, return pro potlaceni varovani */ +} + +@ O kolik pozic je třeba se posunout a s jakým výsledkem zjistíme +rekurzivním voláním funkce |match|. +@<Vrať hodnotu podle následující pozice patternu@>= +switch (m = match (p->next)) { +case NOFOUND: return NOFOUND; +case FOUND: return FOUND; +default: return 1 + m; +} + +@* Vlnkovací funkce. +Nejprve připravíme globální deklarace pro \uv{vlnkovací} funkci |tie|. +Funkce |tie| \uv{ovlnkuje} vstupní soubor |infile| a vytvoří soubor +|outfile|. Při |silent=0| tiskne závěrečnou zprávu o zpracování. V této +zprávě se objeví jméno souboru, které se funkce \uv{dozví} prostřednictvím +globální proměnné |filename|. Proměnná |numline| počítá řádky, proměnná +|numchanges| sčítá změny, tj. počet doplněných vlnek. +Proměnná |mode| nabývý některé z hodnot |TEXTMODE|, |MATHMODE|, +|DISPLAYMODE| a |VERBMODE| podle stavu ve čteném textu. +@d TEXTMODE 0 +@d MATHMODE 1 +@d DISPLAYMODE 2 +@d VERBMODE 3 +@<Globální deklarace@>= +char *filename; /* jmeno zpracovavaneho souboru */ +long int numline, numchanges; /* pro zaverecnou statistiku */ +int mode; + +@ Nyní definujeme vlnkovací funkci |tie|. Veškerá činnost se opírá o +strukturu patternů. Výhodné je (z důvodu rychlosti) \uv{natvrdo} zde +implementovat jen přepínání mezi stavem čtení z oblasti komentáře +(|listpatt==commentlist|) a mimo komentář (|listpatt==normallist|); +@<Vlnkovací funkce |tie|@>= +static void tie (FILE *input, FILE *output) +{ + int ap; /* ap je pocet otevrenych patternu */ + register int k, m, n; + int ic; + PATTERN *pp; + PATITEM *pi; + + @<Inicializace proměnných při startu funkce |tie|@>; + + while (!feof(input)) { + if (ap == 0 && ind > BUFI && c !='\\') @<Vyprázdni buffer@>; + @<Otevři nové patterny@>; /* 1. 2. 2010: prohozene poradi */ + if (ind >= MAXBUFF) { + fprintf (stderr, "Operating buffer overflow, is anything wrong?\n"); + exit (BAD_PROGRAM); + } + if ((ic = getc(input)) == EOF) /* opravil Cejka Rudolf */ + break; + buff[ind++] = c = ic; + if (c == 0) continue; /* 30. 4. 2009 */ + if (inz>=8) { + for (inz=0; inz<4; inz++) buffnz[inz] = buffnz[inz+4]; + inz=4; + } + buffnz[inz++] = c; + if (c == '\n') numline++, listpatt = normallist; + if (c == '%' && mode!=VERBMODE && buffnz[inz-2] != '\\') listpatt = commentlist; + @<Projdi otevřené patterny@>; + } + @<Vyprázdni buffer@>; + if (!web) checkmode (); /* zaverecna kontrola modu */ + if (!silent) @<Tiskni závěrečnou zprávu@>; +} + +@ @<Inicializace proměnných při ...@>= +for (k=0; k<MAXPATT; k++) lapi[k] = NULL; +c = '\n'; +buff[0] = 1; mode = ap = 0; ind = 1; +for(inz=0; inz<4; inz++) buffnz[inz] = 0; +inz = 4; +numline = 1; numchanges = 0; +mode = TEXTMODE; + +@ Při manipulaci s bufferem byl použit jeden trik. Veškeré načtené znaky +začínají až od |buff[1]|, zatímco |buff[0]| je rovno nule. Je to proto, že +některé algoritmy se vrací o jeden znak zpět za svůj pattern, aby zjistily, +zda tam není symbol \uv{\.{\char92}} (například na výskyt sekvence +\.{\char92\char37} je třeba reagovat jinak, než na výskyt obyčejného +procenta). Kdybychm zazačali od |buff[0]|, v některých situacích +bychom se ptali, zda |buff[-1]=='\\'|, tj. sahali bychom na neošetřené +místo v paměti. Od 30. 4. 2009 tento problém pominul, protože se ptáme dozadu pouze +v~|buffnz|, ale vlastnost dříve implementovanou v |buff| jsem ponechal beze změny. +@<Vyprázdni buffer@>= +{ + fwrite (&buff[1], ind-1, 1, output); + ind = 1; +} + +@ Při procházení otevřenými patterny posunujeme v poli |lapi| pozice +jednotlivých patternů podle pokynů funkce |match|, případně pattern zavřeme +a případně vyvoláme proceduru patternu. + +Některé patterny v poli |lapi| už mohou být zavřeny, takže je nutno s tímto +polem pracovat jako s jakýmsi děravým sýrem. +@<Projdi otevřené patterny@>= +n = ap; k = 0; +while (n) { + while (lapi[k]==NULL) k++; /* zastav se na prvnim ukazateli na pattern */ + switch (m = match (lapi[k])) { + case FOUND: (*lapt[k]->proc)(); /* Pattern nalezen, spustit proceduru */ + case NOFOUND: lapi[k] = NULL; /* Deaktivace patternu */ + ap--; break; + default: while (m--) lapi[k] = lapi[k]->next; /* dalsi pozice patternu */ + } + k++; n--; +} + +@ Při otevírání nových patternů, které nejsou v tuto chvíli zablokovány, +se hned vypořádáme s takovými patterny, které nám dávají rovnou odpověď +typu |FOUND| nebo |NOFOUND|. V takových případech ani nezanášíme ukazatel +na pozici do pole |lapi|. +@<Otevři nové patterny@>= +pp = listpatt; +if (c) while (pp != NULL) { + switch (m = match (pp->patt)) { + case FOUND: (*pp->proc)(); /* spustit proceduru */ + case NOFOUND: break; + default: @<Vytvoř ukazatel na nový pattern a |break|@>; + } + pp=pp->next; +} + +@ Není-li hned známa odpověď, zda pattern vyhovuje či nikoli, +překontrolujeme nejdříve, zda už není pattern ve stejné pozici otevřený. +Pak najdeme první \uv{díru} v tabulce |lapi| a tam uhnízdíme nový ukazatel +na pozici v patternu. +@<Vytvoř ukazatel na nový pattern...@>= +pi = pp->patt; +while (m--) pi = pi->next; +n = ap; k = 0; +while (n) { + if (lapi[k]==pi) break; + if (lapi[k++] != NULL) n--; +} +if (!n) { + k = 0; + while (lapi[k] != NULL) k++; + if (k >= MAXPATT) { + fprintf (stderr, "I cannot allocate pp, is anything wrong?\n"); + exit (BAD_PROGRAM); + } + lapt[k] = pp; lapi[k] = pi; ap++; +} + +@ Poslední věcí ve funci |tie| je tisk závěrečné statistiky zpracování. +@<Tiskni závěrečnou zprávu@>= +fprintf (stderr, "~~~ file: %s\t lines: %ld, changes: %ld\n", + filename, numline, numchanges); + +@* Inicializace patternů. +Po vytvoření předchozího kódu opírajícího se o~patterny máme nyní v~ruce +poměrně silný nástroj na definování různých činností programu prostým +vytvořením patternu a příslušné jeho procedury. Pokud budeme chtít +v~budoucnu nějaký rys programu přidat, pravděpodobně to bude snadné. + +Nejprve deklarujeme některé často používané skupiny znaků v~patternech. + +@<Globální deklarace@>= +char tblanks[] = " ~\t"; +char blanks[] = " \t"; +char blankscr[] = " \t\n"; +char tblankscr[] = " ~\t\n"; +char nochar[] = "%~\n"; +char cr[] = "\n"; +char prefixes[] = "[({~"; +char dolar[] = "$"; +char backslash[] = "\\"; +char openbrace[] = "{"; +char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +PATTERN *vlnkalist, *mathlist, *parcheck, *verblist ; + +@ Začneme definicí nejčastěji používaného patternu na vlnkování uvnitř +řádku. Připomeňme, že opakované volání funkce |setpattern| vytváří interně +seznam patternů, přičemž o~jejich propojení se nemusíme starat. Vyzvedneme +si z~návratového kódu funkce pouze ukazatel na první položku seznamu +|normallist|. Stejně tak opakované volání funkce |setpi| vytváří seznam +pozic pro naposledy deklarovaný pattern. +@<Inicializace datových struktur@>= +vlnkalist = setpattern (vlnkain); +setpi (tblankscr, ONE); +setpi (tblanks, ANY); +setpi (prefixes, ANY); +setpi (charset, ONE); +setpi (blanks, ONE); +setpi (blanks, ANY); +setpi (nochar, ONE_NOT); + +@ @<Inicializace proměnných při ...@>= +listpatt = normallist = vlnkalist; + +@ Vložení vlnky znamená vykonat následující práci: Zapamatovat si znak za skupinou mezer +(do proměnné |p|). Pokud před tímto znakem předchází nulový byte, použijeme ho později, proto +si jej uložíme do proměnné |z|. Dále se posuneme v bufferu vlevo přes všechny mezery, tabelátory +(přesněji |blanks|) a přeskakujeme přitom všechny nulové byty. Index |ind| se zastaví +na předložce. Posuneme jej doprava za předložku (++|ind|) a pokud tam je nulový byte a první znak +|tiestr| není nulový, posuneme se až za tento nulový byte. Dále vložíme string |tiestr|, +neboli vlnku. Nakonec připojíme zapamatovaný znak |p|, ovšem pokud před ním byla nula, +vložíme ji ještě před znak |p|. +@<Pomocné funkce@>= +static void vlnkain(void) +{ + int i; + char p, z; + ind--; + p = buff[ind--]; + z = buff[ind]; + while (!buff[ind] || (strchr(blanks, buff[ind]) !=NULL)) ind--; + if (!buff[++ind] && tiestr[0]) ind++; + for (i=0; i<tiestrlen; i++) buff[ind++] = tiestr[i]; + i = tiestrlen; /* nulu pred p vlozime, pokud je z==0 a */ + if (!tiestr[0]) i--; /* pocet vlozenych znaku z tiestr */ + if (!z && (i%2)) buff[ind++] = 0; /* je sudy */ + buff[ind++] = p; + numchanges++; +} + +@ Podobně pro tvorbu vlnky \uv{přes řádek} vytvoříme pattern a kód +procedury. +@<Inicializace dat...@>= +setpattern (vlnkacr); +setpi (tblankscr, ONE); +setpi (tblanks, ANY); +setpi (prefixes, ANY); +setpi (charset, ONE); +setpi (blanks, ANY); +setpi (cr, ONE); +setpi (blanks, ANY); +setpi (nochar, ONE_NOT); + +@ V proceduře k tomuto patternu musíme ošetřit případ typu +\uv{\.{a\char126v\char92np}}, +kdy nelze prostě přehodit \uv{\.{\char92n}} za \uv{\.{v}}, protože +bychom roztrhli +mezeru svázanou vlnkou už dříve. Proto musíme vyhledat vhodné místo pro +roztržení řádku, které bude až {\it před\/} znakem \uv{\.{a}}. Při důsledném +ošetření tohoto fenoménu můžeme dokonce narazit na situaci +\uv{\.{\char92n\ v\char126v\char126v\char92np}}, kde nemůžeme vložit +\uv{\.{\char92n}} před první výskyt \uv{\.{v}}, protože bychom dostali +\uv{\.{\char92n\char92n}}, tedy prázdný +řádek. Ten je v \TeX{}u interperetován odlišně. V této výjimečné +situaci pouze zrušíme stávající (v pořadí druhé) \uv{\.{\char92n}} a +nebudeme vytvářet nové. Na výstupu bude soubor o jeden řádek kratší. +@<Pomocné funkce@>= +static void vlnkacr(void) +{ + char p, z; + int i, j; + ind--; + p = buff[ind--]; + z = buff[ind]; + while (!buff[ind] || (strchr(blankscr, buff[ind]) !=NULL)) ind--; + i = ind; /* misto predlozky, kterou chceme vazat */ + while (i >= 0 && (strchr(blankscr, buff[i]) == NULL)) i--; + j = i; + while (i >= 0 && (!buff[ind] || (strchr(blanks, buff[i]) != NULL))) i--; + if (i >= 0 && buff[i] == '\n') j = -1; + if (j >= 0) buff[j] = '\n'; + else numline--; + if (!buff[++ind] && tiestr[0]) ind++; + for (i=0; i<tiestrlen; i++) buff[ind++] = tiestr[i]; + i = tiestrlen; + if (!tiestr[0]) i--; + if (!z && (i%2)) buff[ind++] = 0; + buff[ind++] = p; + numchanges++; +} + +@ Nyní vytvoříme patterny pro případy typu \.{\char92uv\char`\{v lese\char`\}}. +@<Inicializace dat...@>= +setpattern (vlnkain); /* na radku */ +setpi (tblankscr, ONE); +setpi (backslash, ONE); +setpi (letters, ONE); +setpi (letters, ANY); +setpi (openbrace, ONE); +setpi (prefixes, ANY); +setpi (charset, ONE); +setpi (blanks, ONE); +setpi (blanks, ANY); +setpi (nochar, ONE_NOT); + +setpattern (vlnkacr); /* pres radek */ +setpi (tblankscr, ONE); +setpi (backslash, ONE); +setpi (letters, ONE); +setpi (letters, ANY); +setpi (openbrace, ONE); +setpi (prefixes, ANY); +setpi (charset, ONE); +setpi (blanks, ANY); +setpi (cr, ONE); +setpi (blanks, ANY); +setpi (nochar, ONE_NOT); + + + +@ Vytvoříme patterny a proceduru pro potlatčení tvorby vlnky u písmen těsně +následujících sekvence \.{\char92TeX} a \.{\char92LaTeX}. Tj. nechceme, aby +např z textu \uv{\.{Vlastnosti~\char92TeX~u~jsou...}} jsme dostali text +s nesprávně vázaným písmenem +\uv{\.{Vlastnosti~\char92TeX~u\char126jsou...}}. +@<Inicializace dat...@>= +normalpattern (tielock, "\\TeX"); +setpi (blankscr, ONE); +normalpattern (tielock, "\\LaTeX"); +setpi (blankscr, ONE); + +@ Procedura |tielock| obsahuje nečistý trik. Při provádění procedury je +právě načten znak z |blankscr| a je uložen do |buff|. Testy na otevírání +nových patternů pro tento znak teprve budou následovat a testují se na +hodnotu proměnné |c|. Stačí tedy změnit hodnotu |c| a vlnkovací patterny se +neotevřou. +@<Pomocné funkce@>= +static void tielock (void) +{ + c = 1; +} + +@ Ošetříme nyní přechod do/z matematického režimu \TeX{}u. Uvnitř math +módu vlnky neděláme. Při zjištěném nesouladu v přechodech mezi +math-módy spustíme následující proceduru. +@<Pomocné funkce@>= +static void printwarning (void) +{ + if (!silent) + fprintf (stderr, + "~!~ warning: text/math/verb mode mismatch, file: %s, line: %ld\n", + filename, numline - (c=='\n'?1:0)); + status = WARNING; +} + +@ Začneme patterny pro přechod do/z matematického režimu, ohraničeného +jedním dolarem, nebo v La\TeX{}u příslušnými sekvencemi. Sekvence +La\TeX{}u \.{\char92(} a \.{\char92)} nejsou zahrnuty, protože bývají +často předefinovány k jiným užitečnějším věcem. +@<Inicializace datových ...@>= +if (!nomath) { + mathlist = setpattern (onedollar); + setpi (dolar, ONE); + setpi (dolar, ONE_NOT); + if (latex) { + normalpattern (mathin, "\\begin.{math}"); + normalpattern (mathout, "\\end.{math}"); + } +} + +@ @<Pomocné funkce@>= +static void mathin (void) +{ + if (mode!=TEXTMODE) printwarning (); + mode = MATHMODE; + normallist = listpatt = mathlist; +} +static void mathout (void) +{ + if (mode!=MATHMODE) printwarning (); + mode = TEXTMODE; + normallist = listpatt = vlnkalist; +} + +@ Při programování procedury |onedollar| nesmíme zapomenout na výskyt +sekvence \.{\char92\$}. V tom případě akci ignorujeme. Podobně u sekvence +\.{\$\$} souhlasí ten druhý dolar s naším patternem, ale to už jsme uvnitř +display módu. V takovém případě také nic neděláme. +@<Pomocné funkce@>= +static void onedollar (void) +{ + if (buffnz[inz-3]=='\\' || (buffnz[inz-3]=='$' && buffnz[inz-4]!='\\')) return; + if (mode==DISPLAYMODE) printwarning (); + else { + if (mode==TEXTMODE) mathin(); + else mathout(); + } +} + +@ Pokud najdeme prázdný řádek, překontrolujeme, zda náhodou nejsme v +math-módu. Pokud ano, vypíšeme varování a přejdeme do textového módu. +@<Inicializace dat...@>= +parcheck = setpattern (checkmode); +setpi (cr, ONE); +setpi (blanks, ANY); +setpi (cr, ONE); + +@ @<Pomocné funkce@>= +static void checkmode (void) +{ + if (mode!=TEXTMODE) { + printwarning (); + mode = TEXTMODE; + normallist = listpatt = vlnkalist; + } +} + +@ Nyní ošetříme výskyt dvou dolarů, tj. vstup do/z display módu. +Rovněž mysleme na La\TeX{}isty a jejich prostředí pro display-mód. Protože +je možná alternativa s hvězdičkou na konci názvu prostředí, raději už +uzavírací závorku do patternu nezahrnujeme. + +@<Inicializace dat...@>= +if (!nomath) { + normalpattern (twodollars, "$$"); + if (latex) { + normalpattern (displayin, "\\begin.{displaymath"); + normalpattern (displayin, "\\begin.{equation"); + normalpattern (displayout, "\\end.{displaymath"); + normalpattern (displayout, "\\end.{equation"); + } +} + +@ @<Pomocné funkce@>= +static void displayin (void) +{ + if (mode!=TEXTMODE) printwarning (); + mode = DISPLAYMODE; normallist = listpatt = parcheck; +} +static void displayout (void) +{ + if (mode!=DISPLAYMODE) printwarning(); + mode = TEXTMODE; normallist = listpatt = vlnkalist; +} +static void twodollars (void) +{ + if (buffnz[inz-3]=='\\') return; + if (mode==DISPLAYMODE) displayout (); + else displayin (); +} + +@ Následuje ošetření tzv. verbatim módu. Pro plain i La\TeX{} jsou nejčastější +závorky pro verbatim mod tyto (variantu s \.{\char92begtt} používám +s oblibou já). +@<Inicializace dat...@>= +if (!noverb) { + verblist = normalpattern (verbinchar, "\\verb"); + setpi (blankscr, ANY); + setpi (blankscr, ONE_NOT); + normalpattern (verbin, "\\begtt"); + if (latex) normalpattern (verbin, "\\begin.{verbatim"); +} +if (web) { + normalpattern (verbin, "@@<"); + normalpattern (verbin, "@@d"); +} +if (!noverb) { + verboutlist[0] = setpattern (verbout); + setpi (verbchar, ONE); + verboutlist[1] = normalpattern (verbout, "\\endtt"); + if (latex) verboutlist[2] = normalpattern (verbout, "\\end{verbatim"); +} +if (web) { + verboutlist[3] = normalpattern (verbout, "@@ "); + normalpattern (verbout, "@@*"); + normalpattern (verbout, "@@>|"); +} + + +@ Procedura |verbinchar| se od \uv{společné} procedury |verbin| liší v +tom, že zavede do stringu |verbchar| momentální hodnotu proměnné |c|. +Proto druhý výskyt této hodnoty verbatim režim ukončí. +@<Pomocné funkce@>= +int prevmode; +PATTERN *prevlist, *verboutlist[4]; +char verbchar[2]; +static void verbinchar (void) +{ + prevmode = mode; + verbchar[0] = c; + c = 1; + listpatt = normallist = verboutlist[0]; + prevlist = listpatt->next; + listpatt->next = NULL; + mode = VERBMODE; +} + +@ Při programování \uv{obecné} funkce |verbin| musíme dbát na to, aby +zůstal aktivní pouze odpovídající \uv{výstupní} pattern k danému +vstupnímu. Také si zapamatujeme mód, ze kterého jsme do verbatim +oblasti vstoupili, abychom se k němu mohli vrátit (např. uvnitř +math. módu může být +\.{\char92hbox} a v něm lokálně verbatim konstrukce). +@<Pomocné funkce@>= +static void verbin (void) +{ + int i; + i = 0; + prevmode = mode; + switch (c) { + case 't': i = 1; break; + case 'm': i = 2; break; + case '<': ; + case 'd': i = 3; + if (buffnz[inz-3]=='@@') return; /* dvojity @@ ignorovat */ + break; + } + listpatt = normallist = verboutlist[i]; + prevlist = listpatt->next; + if (c != '<' && c != 'd') listpatt->next = NULL; + mode = VERBMODE; +} + +@ @<Pomocné funkce@>= +static void verbout (void) +{ + if (mode!=VERBMODE) return; + if (web && buffnz[inz-2] == '@@' && buffnz[inz-3] == '@@') return; + mode = prevmode; + normallist->next = prevlist; + switch (mode) { + case DISPLAYMODE: normallist = listpatt = parcheck; break; + case MATHMODE: normallist = listpatt = mathlist; break ; + case TEXTMODE: normallist = listpatt = vlnkalist; break; + } +} + +@ Nyní implementujeme vlastnost dříve používaného programu vlnka, tj. že +lze jeho činnost vypnout a opět zapnout v komentářích. Vytváříme druhý +nezávislý seznam patternů a proto nejprve pronulujeme |lastpt|. +@<Inicializace dat...@>= +lastpt = 0; +commentlist = normalpattern (tieoff, "%.~.-"); +normalpattern (tieon, "%.~.+"); + +@ @<Pomocné funkce@>= +static void tieoff (void) +{ + normallist = NULL; +} +static void tieon (void) +{ + normallist = vlnkalist; +} + +@ Další plánovaná vylepšení. Program by mohl číst definici svého chování +nejen z~příkazové řádky, ale v~mnohem kompletnější podobě, včetně +uživatelsky definovaných patternů, z komentářové oblasti ve čteném souboru. +Parametry zde uvedené by mohly mít vyšší prioritu, než parametry +z~příkazové řádky a mohl by se třeba rozšiřovat seznam sekvencí, za nimiž +písmena nemají být vázana vlnkou (zatím je implemenováno na pevno jen +\.{\char92TeX} a \.{\char92LaTeX}). + +@* Rejstřík. + + |