]> mj.ucw.cz Git - ucwmac.git/commitdiff
Merge branch 'ucwmac2'
authorMartin Mares <mj@ucw.cz>
Sat, 30 Jun 2018 22:15:32 +0000 (00:15 +0200)
committerMartin Mares <mj@ucw.cz>
Sat, 30 Jun 2018 22:15:32 +0000 (00:15 +0200)
18 files changed:
Makefile
test-labels.tex
test-ref.tex [new file with mode: 0644]
test.tex
ucw-algo.tex [new file with mode: 0644]
ucw-labels.tex
ucw-lang-cs.tex [new file with mode: 0644]
ucw-link.tex [new file with mode: 0644]
ucw-luacsplain.ini [new file with mode: 0644]
ucw-luaofs.tex [new file with mode: 0644]
ucw-ofs.tex
ucw-paper.tex
ucw-pdfmeta.lua [new file with mode: 0644]
ucw-pdfmeta.tex [new file with mode: 0644]
ucw-ref.tex [new file with mode: 0644]
ucw-verb.tex
ucwmac.tex
ucwmac2.tex [new file with mode: 0644]

index 963b7b7f97302b67ec5797da5c02bd6d2de44e50..a67bafaf596a8ab0d0d0782b5769ea997020a781 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,19 +1,44 @@
 VERSION=1.1
 ARCHIVE=ucwmac-$(VERSION).tar.gz
 
-all: test.pdf test-labels.pdf
+all: test.pdf test-labels.pdf test-ref.pdf
 
-%.dvi: %.tex
-       csplain $<
+MACROS=$(wildcard ucw*.tex)
 
-%.ps: %.dvi
-       dvips -D600 -o $@ -t a4 $<
+ifdef USE_LUATEX
 
-%.pdf: %.tex
-       pdfcsplain $<
+LUATEX?=luatex
+export TEXINPUTS=.//:
+export LUAINPUTS=.//:
+
+%.pdf: %.tex $(MACROS) ucw-luacsplain.fmt
+       $(LUATEX) -file-line-error -fmt ucw-luacsplain $<
+       $(LUATEX) -file-line-error -fmt ucw-luacsplain $<
+
+%.fmt: %.ini
+       $(LUATEX) -file-line-error -jobname $* -ini $<
+
+.SECONDARY: ucw-luacsplain.fmt
+
+else ifdef USE_DVI
+
+%.dvi: %.tex $(MACROS)
+       csplain -file-line-error $<
+       csplain -file-line-error $<
+
+%.pdf: %.dvi
+       dvipdfm -r 600 -o $@ -p a4 $<
+
+else
+
+%.pdf: %.tex $(MACROS)
+       pdfcsplain -file-line-error $<
+       pdfcsplain -file-line-error $<
+
+endif
 
 clean:
-       rm -f *~ *.log *.dvi *.ps *.pdf *.aux
+       rm -f *~ *.log *.dvi *.ps *.pdf *.aux *.fmt
 
 release:
        git tag v$(VERSION)
index ceb68b6dd5c4c7c986b95c546e7a32fedeaad119..903569a63d056fc07f49d776b475e6fe7fa741c0 100644 (file)
@@ -1,5 +1,5 @@
-\input ucwmac.tex
-\input ucw-labels.tex
+\input ucwmac2.tex
+\ucwmodule{labels}
 
 \setuplabels{3}{7}
 \labelrulestrue
diff --git a/test-ref.tex b/test-ref.tex
new file mode 100644 (file)
index 0000000..a503c76
--- /dev/null
@@ -0,0 +1,40 @@
+\input ucwmac2.tex
+\ucwmodule{ofs}
+\ucwmodule{ref}
+\ucwmodule{pdfmeta}
+
+% \clickablefalse
+
+\pdfmetainfo{Author}{A. U. Thor}
+\pdfmetainfo{Title}{TeX Caput Regni}
+
+\newcount\chapcount
+\chapcount=0
+\optdef\chapter#1{
+       \vfill\eject
+       \advance\chapcount by 1
+       \addid{chap}{\the\chapcount}
+       \pdfmetaoutline{\the\chapcount}{\currentid}{#1}
+       \leftline{\the\chapcount. #1}
+       \medskip
+}
+
+\def\chapref{\ref{chap}}
+
+\pageid{pri}
+
+\chapter[pri]{Caput prima}
+
+\chapter[sec]{Caput secunda}
+
+\url{http://pruvodce.ucw.cz/errata%21.html}
+
+\linkurl{http://pruvodce.ucw.cz/}{See the web page.}
+
+\chapter[ter]{Caput tertia}
+
+See also chapter~\chapref{pri} at page \ref{page}{pri}.
+
+Hard link to \linkpage{1}{page~1}.
+
+\bye
index 6859be8c8c7ae48c347a16631eda28282b18fa9a..88536a1946c86b414685634819839e6dcd9d24f1 100644 (file)
--- a/test.tex
+++ b/test.tex
@@ -1,6 +1,7 @@
-\input ucwmac.tex
-\input ucw-ofs.tex
-\input ucw-verb.tex
+\input ucwmac2.tex
+\ucwmodule{ofs}
+\ucwmodule{verb}
+\ucwmodule{algo}
 
 \showfonts
 
 
 \noindent An~itemized list:
 
+\list{(g)}
+\:primo
+\:secundo
+\:tertio
+\liststyle{(a)}
+\:quarto
+\liststyle{o}
+\:quinto
+\endlist
+
+\bigskip
+\noindent Backward-compatible lists:
+
 \itemize\ibull
-\:It is an important and popular fact that things are not always what
+\:It is an {\I important and popular fact} that things are not always what
 they seem.  For instance, on the planet Earth, man had always assumed
 that he was more intelligent than dolphins because he had achieved so
-much -- the wheel, New York, wars and so on -- whilst all the dolphins
+much -- the wheel, {\colorlocal\rgb{1 0 0}New York}, wars and so on -- whilst all the dolphins
 had ever done was muck about in the water having a good time.  But
-conversely, the dolphins had always believed that they were far more
+conversely, the \colorpush\rgb{0 0 1}dolphins\colorpop{} had always believed that they were far more
 intelligent than man -- for precisely the same reasons.
 \:Curiously enough, the dolphins had long known of the impending
 destruction of the of the planet Earth and had made many attempts to
@@ -95,11 +109,21 @@ abracadabra {!@#$%^&*()\_}
 
 {\csc Caps And Small Caps}
 
-\loadmathfam \ttfam [/cmtt\fotenc]%
 ${\tt x}\in\fam\bbfam R$
 
 The set{\settextsize{11}text}size macro does not strew spaces.
 
 {\tt Typewriter {\it italic} {\sl slanted.}}
 
+\hd{Algorithms}
+
+\algo{Factorial}\algalias{calculate a~factorial}
+\algin A~non-negative integer~$n$
+\:If $n\ge 1$:  \cmt{Test if something}
+\::Return $n$
+\:Else:
+\::Return $n \cdot \alg{Factorial}(n-1)$
+\algout The factorial of~$n$
+\endalgo
+
 \bye
diff --git a/ucw-algo.tex b/ucw-algo.tex
new file mode 100644 (file)
index 0000000..32f3c30
--- /dev/null
@@ -0,0 +1,94 @@
+% The UCW Macro Collection: Typesetting of algorithms
+% Written by Martin Mares <mj@ucw.cz> in 2018 and placed into public domain
+% -------------------------------------------------------------------------
+
+\ucwdefmodule{algo}
+
+%      \algo{name of the algorithm}\algalias{a longer name}
+%      \algin input description
+%      \:step
+%      \:step  \cmt{comment}
+%      \::[identifier]nested step
+%      \:::yet more nested step
+%      \algout output description
+%      \endalgo
+
+% Localized strings
+\localedef{0}{alg:alg}{Algorithm}
+\localedef{0}{alg:proc}{Procedure}
+\localedef{0}{alg:in}{Input}
+\localedef{0}{alg:out}{Output}
+
+% Item indent
+\newdimen\algoindent
+\algoindent=2em
+
+% Extra indent for nested items
+\newdimen\algonestindent
+\algonestindent=2em
+
+% Width of item label
+\newdimen\algolabelwidth
+\algolabelwidth=0.5em
+
+% Set up spacing (customizable)
+\def\algospacing{
+       \itemnarrow=\itemindent
+       \interitemskip=1pt
+       \preitemizeskip=\bigskipamount
+       \postitemizeskip=\dimexpr \bigskipamount - \parskip \relax
+}
+
+% Set up paragraph mode for a single step of the algorithm (customizable)
+\def\algopar{
+       \par
+       \parindent=\algoindent
+       \hangindent=\algoindent
+       \advance\hangindent by \algolabelwidth
+       \hangafter=1
+       \leavevmode
+}
+
+% Typeset step label (customizable)
+\def\algostep#1{\hbox to \algolabelwidth{\hss #1~~}}
+
+\def\algoinit{
+       \begingroup
+       \algospacing
+       \inititemize
+       \let\:=\algoitem
+       \def\={\leftarrow}
+       \let\cmt=\algcmt
+       \itemcount=0
+}
+
+\def\typedalgo#1#2{\algoinit {\bo #1\/} \alg{#2}}
+\def\algo#1{\typedalgo{\localestr{alg:alg}}{#1}}
+\def\proc#1{\typedalgo{\localestr{alg:proc}}{#1}}
+\def\headlessalgo{\algoinit}
+
+\def\endalgo{\endlist\endgroup}
+\let\endproc=\endalgo
+
+\def\algoitem{%
+       \ifnum\itemcount=0\par\nobreak\smallskip\fi
+       \algopar\advance\itemcount by 1
+       \algostep{\the\itemcount.}%
+       \futurelet\next\algoitemh
+}
+
+\def\algoitemh{\ifx\next:\let\next=\algohang\else\let\next=\algoitemgo\fi\next}
+\def\algohang:{\advance\hangindent by \algonestindent \hskip \algonestindent\futurelet\next\algoitemh}
+\optdef\algoitemgo{\ifx\addid\undefined\else\addid{item}{\the\itemcount}\fi}
+
+\def\algin{\par\nobreak{\it \localestr{alg:in}:\/} }
+\def\algout{\par\nobreak\parindent=0pt{\it \localestr{alg:in}:\/} }
+\def\alginbreak{\hfil\break\hphantom{\it \localestr{alg:out}:\/} }
+\def\algalias#1{ (#1)}
+
+% Algorithm name in text or in a formula
+\protected\def\alg#1{\leavevmode\hbox{\csc #1}}
+
+% Comments
+\def\algcmt#1{\unskip~~\hfill\fullcmt{#1}\ignorespaces}
+\def\fullcmt#1{{$\triangleleft$\hskip0.5em\it #1}}
index f6730b5eb5e990335ab0d5e13bc031b2fded265e..58bf8831b4a8b88e99e9137b5fcfb95caf65d5b1 100644 (file)
@@ -1,5 +1,7 @@
 %% Macros for typesetting of labels
 
+\ucwdefmodule{labels}
+
 % Default page parameters. You can change them before calling \setuplabels.
 \setmargins{0pt}
 \setuppage
diff --git a/ucw-lang-cs.tex b/ucw-lang-cs.tex
new file mode 100644 (file)
index 0000000..2ca2508
--- /dev/null
@@ -0,0 +1,10 @@
+% The UCW Macro Collection: Czech localization
+% Written by Martin Mares <mj@ucw.cz> in 2018 and placed into public domain
+% -------------------------------------------------------------------------
+
+\ucwdefmodule{lang-cs}
+
+\localedef{\czech}{alg:alg}{Algoritmus}
+\localedef{\czech}{alg:proc}{Procedura}
+\localedef{\czech}{alg:in}{Vstup}
+\localedef{\czech}{alg:out}{Výstup}
diff --git a/ucw-link.tex b/ucw-link.tex
new file mode 100644 (file)
index 0000000..58a1c67
--- /dev/null
@@ -0,0 +1,74 @@
+% The UCW Macro Collection: Destinations and links
+% Written by Martin Mares <mj@ucw.cz> in 2018 and placed into public domain
+% -------------------------------------------------------------------------
+
+\ucwdefmodule{link}
+
+% Should clickable links be produced?
+\newif\ifclickable
+\ifpdf
+       \clickabletrue
+\else
+       \clickablefalse
+\fi
+
+% Common style of all clickable links
+\pdflinkmargin=1pt
+\def\commonlinkargs{height \the\dimexpr\ht\strutbox-0.5pt\relax depth \the\dimexpr\dp\strutbox-0.5pt\relax attr {/C [0 0 0.5] /Border [0 0 2]}}
+
+% Define a PDF destination for the current position at the page
+\def\destpos#1{\ifclickable\pdfdest name {#1} xyz\relax\fi}
+
+% Define a PDF destination for the current page
+\def\destpage#1{\ifclickable\pdfdest name {#1} fit\relax\fi}
+
+% Typeset a clickable link to the given destination
+% \link{dest}{text}
+\def\link#1#2{%
+       \ifclickable
+               \pdfstartlink\commonlinkargs goto name {#1}\relax
+               #2%
+               \pdfendlink\relax
+       \else
+               #2%
+       \fi
+}
+
+% Typeset a clickable link to the given page number
+% (This does not use named destinations. We use it in tables of contents and indices,
+% where absolute page numbers are known from other sources.)
+% \linkpage{page}{text}
+\def\linkpage#1#2{\ifclickable\pdfstartlink\commonlinkargs goto page #1 {/Fit}\relax #2\pdfendlink\else #2\fi}
+
+% Typeset a clickable URL
+% \url{http://example.com/}
+\def\url{\begingroup\allowurlchars\urlaux}
+\def\urlaux#1{\linkurlaux{#1}{\displayurl #1^^X}}
+
+% Typeset a clickable link to the given URL
+% \linkurl{http://example.com/}{text}
+\def\linkurl{\begingroup\allowurlchars\linkurlaux}
+\def\linkurlaux#1#2{\endgroup
+       \leavevmode
+       \ifclickable
+               \pdfstartlink\commonlinkargs user {/Subtype/Link /A << /Type/Action /S/URI /URI(#1) >>}\relax
+       \fi
+       #2%
+       \ifclickable
+               \pdfendlink
+       \fi
+}
+
+% Catcode each special character valid in URL to 'other'
+\def\allowurlchars{\catcode`\#=12\catcode`\_=12\catcode`\%=12\catcode`\&=12\catcode`\$=12\catcode`\~=12\relax}
+
+% Style switches and the beginning/end of an URL
+\let\urlprefix\it
+\let\urlsuffix\/
+
+% Kern to place between "//" in an URL
+\newdimen\urlinterslashkern
+\urlinterslashkern=-0.1em
+
+% Internal macro for typesetting of URLs
+\def\displayurl#1:#2#3^^X{{\urlprefix #1:#2\ifx#2/\kern\urlinterslashkern\fi#3\urlsuffix}}
diff --git a/ucw-luacsplain.ini b/ucw-luacsplain.ini
new file mode 100644 (file)
index 0000000..a06af6d
--- /dev/null
@@ -0,0 +1,64 @@
+%% Czech format for LuaTeX + ucwmac
+%%
+%% This is a cousin of Petr Olšák's csplain/luaplain living in LuaTeX land.
+%% It is based on ε-TeX.
+%%
+%% WARNING: This is experimental. We currently depend on internals of csplain
+%% and also on various packages related to LuaTeX, which tend to be rapidly
+%% changing.
+%%
+%% Written by Martin Mareš <mj@ucw.cz> in 2017 and placed into public domain
+
+\catcode`\{=1 \catcode`\}=2  \catcode`\#=6  \catcode9=10
+
+\input luatexiniconfig.tex             % Enable LuaTeX primitives
+
+% We will skip font section of plain.tex, which sets up CM fonts.
+% Later, we will load Unicode LM fonts instead.
+% This hack is inspired by luaplain.ini.
+\let\orifont=\font
+\long\def\font#1\ttfam=\tentt{}
+\let\rm=\relax \let\tenex=\relax
+\def\mit{\fam1 } \def\cal{\fam2 }
+\def\it{\fam\itfam\tenit} \def\sl{\fam\slfam\tensl}
+\def\bf{\fam\bffam\tenbf} \def\tt{\fam\ttfam\tentt}
+\def\oldstyle{\fam1 \the\textfont1 }
+
+% Disarm \outer
+\let\outer=\relax
+
+\input etex.src                                % ε-TeX macros (includes plain.tex)
+
+% Bring \font back and allocate font families
+\let\font=\orifont
+\let\orifont=\undefined
+\newfam\itfam
+\newfam\slfam
+\newfam\bffam
+\newfam\ttfam
+
+\input luatex-unicode-letters.tex      % Set properties of Unicode characters
+% \input ltluatex.tex                  % LuaTeX support for plain TeX
+\input luatex85.sty                    % Backward compatibility with pdfTeX
+\input pdftexconfig.tex                        % Initialize PDF output parameters
+\input pdftexmagfix.tex                        % Fix \magnification
+\input plaina4.tex                     % Set paper size to A4
+\input ucode.tex                       % \uv and similar macros for Czech typesetting
+% \input luaotfload.sty                        % OTF loader
+
+% Ask csplain to load LM fonts
+% (currently disabled, because it is broken in some versions; use ucw-luaofs.tex instead)
+% \def\fontfeatures{mode=base;script=latn;+tlig}
+% \let\luafonts=\relax                 % Avoid inclusion of csplain's luafonts.tex
+% \input lmfonts.tex
+% \let\fontfeatures=\undefined
+
+\everyjob={%
+   \message{Loaded ucw-luacsplain 2018-06}%
+   % These packages do not survive dumping, defer loading to \everyjob
+   \input ltluatex.tex
+   \input ucwmac2.tex
+   \input ucw-luaofs.tex
+}
+
+\dump
diff --git a/ucw-luaofs.tex b/ucw-luaofs.tex
new file mode 100644 (file)
index 0000000..5008bea
--- /dev/null
@@ -0,0 +1,216 @@
+\ucwdefmodule{luaofs}
+\ucwdefmodule{ofs}
+
+\input luaotfload.sty
+\input ofs.tex
+\nofontmessages
+
+\ofsputfamlist{^^JLatinModern:}
+
+\def\LMfeat#1{:mode=base;script=latn;+tlig}
+
+%%% LMRoman %%%
+
+\ofsdeclarefamily [LMRoman] {%
+   \loadtextfam lmr;%
+                lmbx;%
+                lmti;%
+                lmbxti;;%
+   \newvariant 8 \sl   (Slanted)     lmsl;;%
+   \newvariant 9 \bxsl (BoldSlanted) lmbxsl;;%
+   \newvariant a \bo   (BoldNormal)  lmb;;%
+   \newvariant b \bosl (BoldNormalSlanted)  lmbsl;;%
+   \newvariant c \csc  (CapsAndSmallCaps)   lmcsc;;%
+}
+
+\registertfm lmr        -      LMRoman10-Regular\LMfeat{}
+\registertfm lmr     0pt-6pt   LMRoman5-Regular\LMfeat{}
+\registertfm lmr     6pt-7pt   LMRoman6-Regular\LMfeat{}
+\registertfm lmr     7pt-8pt   LMRoman7-Regular\LMfeat{}
+\registertfm lmr     8pt-9pt   LMRoman8-Regular\LMfeat{}
+\registertfm lmr     9pt-10pt  LMRoman9-Regular\LMfeat{}
+\registertfm lmr    10pt-12pt  LMRoman10-Regular\LMfeat{}
+\registertfm lmr    12pt-17pt  LMRoman12-Regular\LMfeat{}
+\registertfm lmr    17pt-*     LMRoman17-Regular\LMfeat{}
+
+\registertfm lmbx       -      LMRoman10-Bold\LMfeat{}
+\registertfm lmbx    0pt-6pt   LMRoman5-Bold\LMfeat{}
+\registertfm lmbx    6pt-7pt   LMRoman6-Bold\LMfeat{}
+\registertfm lmbx    7pt-8pt   LMRoman7-Bold\LMfeat{}
+\registertfm lmbx    8pt-9pt   LMRoman8-Bold\LMfeat{}
+\registertfm lmbx    9pt-10pt  LMRoman9-Bold\LMfeat{}
+\registertfm lmbx   10pt-12pt  LMRoman10-Bold\LMfeat{}
+\registertfm lmbx   12pt-*     LMRoman12-Bold\LMfeat{}
+
+\registertfm lmti       -      LMRoman10-Italic\LMfeat{}
+\registertfm lmti    0pt-8pt   LMRoman7-Italic\LMfeat{}
+\registertfm lmti    8pt-9pt   LMRoman8-Italic\LMfeat{}
+\registertfm lmti    9pt-10pt  LMRoman9-Italic\LMfeat{}
+\registertfm lmti   10pt-12pt  LMRoman10-Italic\LMfeat{}
+\registertfm lmti   12pt-*     LMRoman12-Italic\LMfeat{}
+
+\registertfm lmbxti     -      LMRoman10-BoldItalic\LMfeat{}
+
+\registertfm lmsl       -      LMRomanSlant10-Regular\LMfeat{}
+\registertfm lmsl    0pt-9pt   LMRomanSlant8-Regular\LMfeat{}
+\registertfm lmsl    9pt-10pt  LMRomanSlant9-Regular\LMfeat{}
+\registertfm lmsl   10pt-12pt  LMRomanSlant10-Regular\LMfeat{}
+\registertfm lmsl   12pt-17pt  LMRomanSlant12-Regular\LMfeat{}
+\registertfm lmsl   17pt-*     LMRomanSlant17-Regular\LMfeat{}
+
+\registertfm lmbxsl     -      LMRomanSlant10-Bold\LMfeat{}
+
+\registertfm lmb        -      LMRomanDemi10-Regular\LMfeat{}
+
+\registertfm lmbsl      -      LMRomanDemi10-Oblique\LMfeat{}
+
+\registertfm lmcsc      -      LMRomanCaps10-Regular\LMfeat{}
+
+\setfonts[LMRoman/]
+
+%%% LMSans %%%
+
+\ofsdeclarefamily [LMSans] {%
+   \loadtextfam lmss;%
+                lmssbx;%
+                lmsso;%
+                lmssbo;;%
+}
+
+\registertfm lmss       -      LMSans10-Regular\LMfeat{}
+\registertfm lmss    0pt-9pt   LMSans8-Regular\LMfeat{}
+\registertfm lmss    9pt-10pt  LMSans9-Regular\LMfeat{}
+\registertfm lmss   10pt-12pt  LMSans10-Regular\LMfeat{}
+\registertfm lmss   12pt-17pt  LMSans12-Regular\LMfeat{}
+\registertfm lmss   17pt-*     LMSans17-Regular\LMfeat{}
+
+\registertfm lmssbx     -      LMSans10-Bold\LMfeat{}
+
+\registertfm lmsso      -      LMSans10-Oblique\LMfeat{}
+\registertfm lmsso   0pt-9pt   LMSans8-Oblique\LMfeat{}
+\registertfm lmsso   9pt-10pt  LMSans9-Oblique\LMfeat{}
+\registertfm lmsso  10pt-12pt  LMSans10-Oblique\LMfeat{}
+\registertfm lmsso  12pt-17pt  LMSans12-Oblique\LMfeat{}
+\registertfm lmsso  17pt-*     LMSans17-Oblique\LMfeat{}
+
+\registertfm lmssbo     -      LMSans10-BoldOblique\LMfeat{}
+
+%%% LMSansDC %%%
+
+\ofsdeclarefamily [LMSansDC] {%
+   \loadtextfam lmssdc;%
+                ;%
+                lmssdo;%
+                ;;%
+}
+
+\registertfm lmssdc     -      LMSansDemiCond10-Regular\LMfeat{}
+
+\registertfm lmssdo     -      LMSansDemiCond10-Oblique\LMfeat{}
+
+%%% LMMono %%%
+
+\ofsdeclarefamily [LMMono] {%
+   \loadtextfam lmtt;%
+                lmtk;%
+                lmtti;%
+                ;;%
+   \newvariant 8 \sl   (Slanted)     lmtto;;%
+   \newvariant 9 \bxsl (BoldSlanted) lmtko;;%
+   \newvariant c \csc  (CapsAndSmallCaps)   lmtcsc;;%
+}
+
+\registertfm lmtt       -      LMMono10-Regular\LMfeat{}
+\registertfm lmtt    0pt-9pt   LMMono8-Regular\LMfeat{}
+\registertfm lmtt    9pt-10pt  LMMono9-Regular\LMfeat{}
+\registertfm lmtt   10pt-12pt  LMMono10-Regular\LMfeat{}
+\registertfm lmtt   12pt-*     LMMono12-Regular\LMfeat{}
+
+\registertfm lmtk       -      LMMonoLt10-Bold\LMfeat{}
+
+\registertfm lmtti      -      LMMono10-Italic\LMfeat{}
+
+\registertfm lmtto      -      LMMonoSlant10-Regular\LMfeat{}
+
+\registertfm lmtko      -      LMMonoLt10-BoldOblique\LMfeat{}
+
+\registertfm lmtcsc     -      LMMonoCaps10-Regular\LMfeat{}
+
+\newfam\ttfam
+\loadmathfam\ttfam[/LMMono10-Regular\LMfeat{}]
+
+%%% LMMonoCondensed %%%
+
+\ofsdeclarefamily [LMMonoCondensed] {%
+   \loadtextfam lmtlc;%
+                ;%
+                lmtlco;%
+                ;;%
+}
+
+\registertfm lmtlc      -      LMMonoLtCond10-Regular\LMfeat{}
+
+\registertfm lmtlco     -      LMMonoLtCond10-Oblique\LMfeat{}
+
+%%% UCW extensions %%%
+
+\ofsputfamlist{^^JUCW:}
+
+\ofsdeclarefamily [BlackboardBold] {%
+   \loadtextfam bbm;%
+               ;%
+               ;%
+               ;\defaultextraenc;%
+}
+
+\registertfm bbm     -      bbm10
+\registertfm bbm  0pt-6pt   bbm5
+\registertfm bbm  6pt-7pt   bbm6
+\registertfm bbm  7pt-8pt   bbm7
+\registertfm bbm  8pt-9pt   bbm8
+\registertfm bbm  9pt-10pt  bbm9
+\registertfm bbm  10pt-12pt bbm10
+\registertfm bbm  12pt-17pt bbm12
+\registertfm bbm  17pt-*    bbm17
+
+% \bb - blackboard bold math font
+
+\newfam\bbfam
+\def\bb{\fam\bbfam}
+
+\def\loadbbm{%
+       \loadmathfam\bbfam[/bbm]%
+}
+\loadbbm
+
+%%% Font size switches %%%
+
+% Recalculate line spacing for a given point size of the font (assuming CM-like metrics).
+% Also sets \strut and \topskip.
+\def\setbaselines#1{%
+       \dimen0=1pt
+       \dimen0=#1\dimen0
+       \normalbaselineskip=1.2\dimen0
+       \normallineskip=0.1\dimen0
+       \setbox\strutbox=\hbox{\vrule height 0.85\dimen0 depth 0.35\dimen0 width 0pt}%
+       \topskip=1\dimen0
+       \normalbaselines
+}
+
+% Switch to a specified font size (including math, line spacing etc.)
+\def\settextsize#1{%
+       \def\fomenc{CM}%
+       \setfonts[/#1]%
+       \setmath[//]%
+       \setbaselines{#1}%
+       \loadbbm
+}
+\def\twelvepoint{\settextsize{12}}
+
+%%% Various hacks %%%
+
+% Re-define \tt, so that it works in both text and math mode
+\def\tt{\ifmmode\fam\ttfam\else\setfonts[LMMono/]\fi}
+
+% Re-define ucwmac's \fontfont
+\let\footfont=\tenrm
index 46c816534b7a1ea19a8f8f31b16a706b38692ded..5fae70d599b971cb4f8498099c45c61a55f46e9b 100644 (file)
@@ -2,6 +2,8 @@
 % Written by Martin Mares <mj@ucw.cz> in 2010 and placed into public domain
 % -------------------------------------------------------------------------
 
+\ucwdefmodule{ofs}
+
 \ifx\OFSversion\undefined
 \input ofs.tex
 % \detailfontmessages
@@ -97,4 +99,5 @@
 \def\twelvepoint{\settextsize{12}}
 
 % Re-define \tt, so that it works in both text and math mode
+\loadmathfam\ttfam[/cmtt\fotenc]
 \def\tt{\ifmmode\fam\ttfam\else\setfonts[CMTypewriter/]\fi}
index 242ccf254f32afdf9ff7197f6485fc3fa216da82..9b656f0db56898824bf0b1f6d93f22882141f522 100644 (file)
@@ -1,5 +1,7 @@
 %% ISO 216 paper sizes [ABC]{0..10}
 
+\ucwdefmodule{paper}
+
 \defpaper{a0}{840truemm}{1189truemm}
 \defpaper{a1}{594truemm}{840truemm}
 \defpaper{a2}{420truemm}{594truemm}
diff --git a/ucw-pdfmeta.lua b/ucw-pdfmeta.lua
new file mode 100644 (file)
index 0000000..80e743a
--- /dev/null
@@ -0,0 +1,203 @@
+-- A library for writing PDF metadata
+
+luatexbase.provides_module {
+       name    = 'pdfmeta',
+       version = '0.0',
+       author  = 'Martin Mareš',
+}
+
+pdfmeta = { }
+
+-- Debugging function for dumping a table
+
+local function do_dump_table(t, key, depth)
+       local tmp = string.rep("  ", depth)
+       if key then
+               tmp = tmp .. key .. ": "
+       end
+       if type(t) == "table" then
+               texio.write(tmp .. "{\n")
+               for k, v in pairs(t) do
+                       do_dump_table(v, k, depth+1)
+               end
+               tmp = string.rep("  ", depth) .. "}"
+       elseif type(t) == "number" then
+               tmp = tmp .. tostring(t)
+       elseif type(t) == "string" then
+               tmp = tmp .. string.format("%q", t)
+       else
+               tmp = tmp .. "???"
+       end
+       texio.write(tmp .. "\n")
+end
+
+local function dump_table(t)
+       do_dump_table(t, nil, 0)
+end
+
+-- PDF metadata can be encoded either in an ancient PDFEncoding, which covers
+-- only a small subset of Unicode characters, or in UTF-16-BE. We use the latter
+-- for anything outside basic ASCII. It is tempting to use "lualibs-unicode"
+-- for the conversion, but alas, it is too broken.
+
+local function pdf_string(s)
+       local u16 = {}
+       local str = {}
+       local strok = true
+       table.insert(u16, "<feff")
+       for x in string.utfvalues(s) do
+               if x >= 0x20 and x < 0x7f and x ~= 0x28 and x ~= 0x29 and x ~= 0x5c then
+                       if x == 0x28 or x == 0x29 or x == 0x5c then
+                               table.insert(str, "\\" .. string.char(x))
+                       else
+                               table.insert(str, string.char(x))
+                       end
+               else
+                       strok = false
+               end
+               if x < 0x10000 then
+                       table.insert(u16, string.format("%04x", x))
+               else
+                       local y = x - 0x10000
+                       local h = y/1024 + 0xd800
+                       local l = y%1024 + 0xdc00
+                       table.insert(u16, string.format("%04x%04x", h, l))
+               end
+       end
+
+       if strok then
+               return "(" .. table.concat(str) .. ")"
+       else
+               table.insert(u16, ">")
+               return table.concat(u16)
+       end
+end
+
+local function pdf_encode_dict_body(d)
+       local t = {}
+       for k, v in pairs(d) do
+               table.insert(t, "/" .. k .. " " .. v)
+       end
+       return table.concat(t, "\n")
+end
+
+local function pdf_encode_dict(d)
+       return '<< ' .. pdf_encode_dict_body(d) .. ' >>'
+end
+
+-- Metadata dictionary
+
+pdfmeta.info = { }
+pdfmeta.catalog = { }
+
+function pdfmeta.set_info(key, val)
+       pdfmeta.info[key] = pdf_string(val)
+end
+
+local function write_metas()
+       pdfmeta.make_outline()
+       pdf.setinfo(pdf_encode_dict_body(pdfmeta.info))
+       pdf.setcatalog(pdf_encode_dict_body(pdfmeta.catalog))
+end
+
+luatexbase.add_to_callback('finish_pdffile', write_metas, 'Write all PDF metadata')
+
+-- Document outline
+
+pdfmeta.outline = { children = {} }
+pdfmeta.outline_stack = { pdfmeta.outline }
+
+function pdfmeta.add_outline(key, dest, text)
+       local stk = pdfmeta.outline_stack
+       local level = 1
+       local p, r
+
+       for k in string.gmatch(key, '%.*(%d+)') do
+               level = level+1
+       end
+       while #stk >= level do
+               table.remove(stk)
+       end
+       while #stk < level do
+               p = stk[#stk]
+               r = { children = {} }
+               table.insert(p.children, r)
+               table.insert(stk, r)
+       end
+       r.dest = dest
+       text = string.gsub(text, '~', unicode.utf8.char(160))
+       text = string.gsub(text, '%-%-%-', unicode.utf8.char(8212))
+       text = string.gsub(text, '%-%-', unicode.utf8.char(8211))
+       r.text = text;
+end
+
+local function reserve_objects(r)
+       r.obj = pdf.reserveobj()
+       r.num_descendants = 0
+       for i, child in pairs(r.children) do
+               reserve_objects(child)
+               r.num_descendants = r.num_descendants + child.num_descendants + 1
+       end
+end
+
+local function outline_ref(r)
+       if r then
+               return r.obj .. ' 0 R'
+       else
+               tex.error('Asked to format null reference')
+               return 'nil'
+       end
+end
+
+local function gen_outline(r, parent)
+       d = {}
+       r.dict = d
+
+       if not parent then
+               d.Type = '/Outlines'
+               d.Count = r.num_descendants
+       else
+               d.Parent = outline_ref(parent)
+               d.Count = r.num_descendants
+       end
+
+       if r.text then
+               d.Title = pdf_string(r.text)
+               d.A = '<< /D (' .. r.dest .. ') /S /GoTo >>'
+       end
+
+       if r.children[1] then
+               d.First = outline_ref(r.children[1])
+               d.Last = outline_ref(r.children[#r.children])
+               for i, child in pairs(r.children) do
+                       gen_outline(child, r)
+                       if i>1 then
+                               child.dict.Prev = outline_ref(r.children[i-1])
+                       end
+                       if i<#r.children then
+                               child.dict.Next = outline_ref(r.children[i+1])
+                       end
+               end
+       end
+end
+
+local function write_outline(r)
+       pdf.obj {
+               type = 'raw',
+               immediate = true,
+               objnum = r.obj,
+               string = pdf_encode_dict(r.dict),
+       }
+       for i, child in pairs(r.children) do
+               write_outline(child)
+       end
+end
+
+function pdfmeta.make_outline()
+       local o = pdfmeta.outline
+       reserve_objects(o)
+       gen_outline(o, nil)
+       -- dump_table(o)
+       write_outline(o)
+       pdfmeta.catalog.Outlines = outline_ref(o)
+end
diff --git a/ucw-pdfmeta.tex b/ucw-pdfmeta.tex
new file mode 100644 (file)
index 0000000..31884e1
--- /dev/null
@@ -0,0 +1,22 @@
+% The UCW Macro Collection: PDF meta-data (requires LuaTeX)
+% Written by Martin Mares <mj@ucw.cz> in 2018 and placed into public domain
+% -------------------------------------------------------------------------
+
+\ucwdefmodule{pdfmeta}
+
+\ifx\directlua\undefined
+       \def\pdfmetainfo#1#2{}%
+       \def\pdfmetaoutline#1#2#3{}%
+\endinput\fi
+
+\directlua{require('ucw-pdfmeta.lua')}
+
+% Set entry in Info dictionary (usual keys are Author and Title)
+% \pdfmetainfo{key}{value}
+\def\pdfmetainfo#1#2{\directlua{pdfmeta.set_info('\luaescapestring{#1}', '\luaescapestring{#2}')}}
+
+% Add entry to the document outline
+% \pdfmetaoutline{chapter.section.subsec.etc}{link-destination}{text}
+\def\pdfmetaoutline#1#2#3{%
+       \directlua{pdfmeta.add_outline('\luaescapestring{#1}', '\luaescapestring{#2}', '\luaescapestring{#3}')}%
+}
diff --git a/ucw-ref.tex b/ucw-ref.tex
new file mode 100644 (file)
index 0000000..37f3721
--- /dev/null
@@ -0,0 +1,69 @@
+% The UCW Macro Collection: References
+% Written by Martin Mares <mj@ucw.cz> in 2018 and placed into public domain
+% -------------------------------------------------------------------------
+
+\ucwdefmodule{ref}
+\ucwmodule{link}
+
+% We maintain a collection of objects. Each object has:
+%    - type (namespace -- e.g., chapter)
+%    - identifier (alphanumeric string used to refer to the object in TeX source)
+%    - label (to be typeset in clickable links -- e.g., chapter number)
+%    - location (it is tied to a specific place in the output document)
+
+% Some output formats (e.g., EPUB) have output split to multiple files.
+% We need to keep track of the file name for every object.
+% When producing a PDF, it is always empty.
+\def\refcurrentfile{}
+
+% An auxiliary file to which we write definitions of all identifiers
+\newwrite\ids
+\def\writeid#1#2{\immediate\write\ids{\string\iddef{#1}{#2}{\refcurrentfile}}}
+\def\delayedwriteid#1#2{\write\ids{\string\iddef{#1}{#2}{\refcurrentfile}}}
+
+% Used in auxiliary files
+\def\iddef#1#2#3{\ifcsname id:#1\endcsname\ucwwarn{Identifier #1 re-defined}\else
+\expandafter\def\csname id:#1\endcsname{#2}%
+\expandafter\def\csname ff:#1\endcsname{#3}%
+\fi}
+
+% Read the auxiliary file from the previous run of TeX, create a new one
+\immediate\openin\ids=\jobname.ids.aux
+\ifeof\ids
+\else
+\input \jobname.ids.aux
+\fi
+\immediate\closein\ids
+\immediate\openout\ids=\jobname.ids.aux
+
+% Define an object. It is called from macros with optional arguments
+% as \addid{type}{label}. It defines a new object whose identifier is the
+% optional argument.
+% It sets \currentid to either ID prefixed by its type, or to \relax.
+\def\addid#1#2{%
+       \ifx\optarg\relax
+               \let\currentid\relax
+       \else
+               \edef\currentid{#1\optarg}%
+               \writeid{\currentid}{#2}%
+               \destpos{\currentid}%
+       \fi
+}
+
+% A low-level interface for typesetting references: produces a clickable link
+% to the identifier #2 of type #1 with a label translated by macro #3 (use \relax
+% for no translation).
+\def\reflink#1#2#3{\expandafter\ifx\csname id:#1#2\endcsname\relax
+       {\ifx\bo\undefined\bf\else\bo\fi ??}%
+       \immediate\write16{*** Warning: Reference #1 undefined ***}%
+\else
+       \link{#1#2}{#3{\csname id:#1#2\endcsname}}%
+\fi
+}
+
+% Typeset a link to identifier #2 of type #1
+\def\ref#1#2{\reflink{#1}{#2}\relax}
+
+% Define an identifier of type page pointing to the current page
+\def\pageid#1{\delayedwriteid{page#1}{\the\count0}\destpage{page#1}}
+\def\pageref{\ref{page}}
index 31f2172c54a2412526258dcad2477a61b337d3ce..a7b19730e145cf83893bec492fe74c0b1ec38f70 100644 (file)
@@ -2,6 +2,8 @@
 % Written by Martin Mares <mj@ucw.cz> in 2010 and placed into public domain
 % -------------------------------------------------------------------------
 
+\ucwdefmodule{verb}
+
 % We'll use internal macros of plain TeX
 \catcode`@=11
 
index 86dc5e5cc55840e3fa799645cfb0eef5ef855b72..0d2c9061071c31b735af8156c9489ec30bf791de 100644 (file)
@@ -1,247 +1,6 @@
-% The UCW Macro Collection (a successor of mjmac.tex)
-% Written by Martin Mares <mj@ucw.cz> in 2010--2013 and placed into public domain
-% -------------------------------------------------------------------------------
+% Emulate behavior of historic ucwmac
 
-%%% Prolog %%%
+\input ucwmac2.tex
 
-% We'll use internal macros of plain TeX
-\catcode`@=11
-
-%%% PDF output detection %%%
-
-\newif\ifpdf
-\pdffalse
-
-\ifx\pdfoutput\undefined
-\else\ifnum\pdfoutput>0
-       \pdftrue
-       \pdfpkresolution=600    % Provide a reasonable default
-\fi\fi
-
-%%% Page size and margins %%%
-
-% If you modify these registers, call \setuppage afterwards
-\newdimen\pagewidth
-\newdimen\pageheight
-\newdimen\leftmargin
-\newdimen\rightmargin
-\newdimen\topmargin
-\newdimen\bottommargin
-\newdimen\evenpageshift
-
-\def\setuppage{%
-       \hsize=\pagewidth
-       \advance\hsize by -\leftmargin
-       \advance\hsize by -\rightmargin
-       \vsize=\pageheight
-       \advance\vsize by -\topmargin
-       \advance\vsize by -\bottommargin
-       \hoffset=\leftmargin
-       \advance\hoffset by -1truein
-       \voffset=\topmargin
-       \advance\voffset by -1truein
-       \ifpdf
-               \pdfhorigin=1truein
-               \pdfvorigin=1truein
-               \pdfpagewidth=\pagewidth
-               \pdfpageheight=\pageheight
-       \fi
-}
-
-% Set multiple margins to the same value
-\def\sethmargins#1{\leftmargin=#1\relax\rightmargin=#1\relax\evenpageshift=0pt\relax}
-\def\setvmargins#1{\topmargin=#1\relax\bottommargin=#1\relax}
-\def\setmargins#1{\sethmargins{#1}\setvmargins{#1}}
-
-% Define inner/outer margin instead of left/right
-\def\setinneroutermargin#1#2{\leftmargin#1\relax\rightmargin#2\relax\evenpageshift=\rightmargin\advance\evenpageshift by -\leftmargin}
-
-% Use a predefined paper format, calls \setuppage automagically
-\def\setpaper#1{%
-       \expandafter\let\expandafter\currentpaper\csname paper-#1\endcsname
-       \ifx\currentpaper\relax
-               \errmessage{Undefined paper format #1}
-       \fi
-       \currentpaper
-}
-
-% Switch to landscape orientation, calls \setuppage automagically
-\def\landscape{%
-       \dimen0=\pageheight
-       \pageheight=\pagewidth
-       \pagewidth=\dimen0
-       \setuppage
-}
-
-% Common paper sizes
-\def\defpaper#1#2#3{\expandafter\def\csname paper-#1\endcsname{\pagewidth=#2\pageheight=#3\setuppage}}
-\defpaper{a3}{297truemm}{420truemm}
-\defpaper{a4}{210truemm}{297truemm}
-\defpaper{a5}{148truemm}{210truemm}
-\defpaper{letter}{8.5truein}{11truein}
-\defpaper{legal}{8.5truein}{14truein}
-
-% Default page parameters
-\setmargins{1truein}
-\setpaper{a4}
-
-%%% Placing material at specified coordinates %%%
-
-% Set all dimensions of a given box register to zero
-\def\smashbox#1{\ht#1=0pt \dp#1=0pt \wd#1=0pt}
-\long\def\smashedhbox#1{{\setbox0=\hbox{#1}\smashbox0\box0}}
-\long\def\smashedvbox#1{{\setbox0=\vbox{#1}\smashbox0\box0}}
-
-% Variants of \llap and \rlap working equally on both sides and/or vertically
-\def\hlap#1{\hbox to 0pt{\hss #1\hss}}
-\def\vlap#1{\vbox to 0pt{\vss #1\vss}}
-\def\clap#1{\vlap{\hlap{#1}}}
-
-% \placeat{right}{down}{hmaterial} places <hmaterial>, so that its
-% reference point lies at the given position wrt. the current ref point
-\long\def\placeat#1#2#3{\smashedhbox{\hskip #1\lower #2\hbox{#3}}}
-
-% Like \vbox, but with reference point in the upper left corner
-\long\def\vhang#1{\vtop{\hrule height 0pt\relax #1}}
-
-% Like \vhang, but respecting interline skips
-\long\def\vhanglines#1{\vtop{\hbox to 0pt{}#1}}
-
-% Crosshair with reference point in its center
-\def\crosshair#1{\clap{\vrule height 0.2pt width #1}\clap{\vrule height #1 width 0.2pt}}
-
-%%% Output routine %%%
-
-\newbox\pageunderlays
-\newbox\pageoverlays
-\newbox\commonunderlays
-\newbox\commonoverlays
-
-% In addition to the normal page contents, you can define page overlays
-% and underlays, which are zero-size vboxes positioned absolutely in the
-% front / in the back of the normal material. Also, there are global
-% versions of both which are not reset after every page.
-\def\addlay#1#2{\setbox#1=\vbox{\ifvbox#1\box#1\fi\nointerlineskip\smashedvbox{#2}}}
-\def\pageunderlay{\addlay\pageunderlays}
-\def\pageoverlay{\addlay\pageoverlays}
-\def\commonunderlay{\addlay\commonoverlays}
-\def\commonoverlay{\addlay\commonoverlays}
-
-% Our variation on \plainoutput, which manages inner/outer margins and overlays
-\output{\ucwoutput}
-\newdimen\pagebodydepth
-\def\ucwoutput{\wigglepage\shipout\vbox{%
-       \makeheadline
-       \ifvbox\commonunderlays\copy\commonunderlays\nointerlineskip\fi
-       \ifvbox\pageunderlays\box\pageunderlays\nointerlineskip\fi
-       \pagebody
-       \pagebodydepth=\prevdepth
-       \nointerlineskip
-       \ifvbox\commonoverlays\vbox to 0pt{\vskip -\vsize\copy\commonoverlays\vss}\nointerlineskip\fi
-       \ifvbox\pageoverlays\vbox to 0pt{\vskip -\vsize\box\pageoverlays\vss}\nointerlineskip\fi
-       \prevdepth=\pagebodydepth
-       \makefootline
-}\advancepageno
-\ifnum\outputpenalty>-\@MM \else\dosupereject\fi}
-
-\def\wigglepage{\ifodd\pageno\else\advance\hoffset by \evenpageshift\fi}
-
-% Make it easier to redefine footline font (also, fix it so that OFS won't change it unless asked)
-\let\footfont=\tenrm
-\footline={\hss\footfont\folio\hss}
-
-%%% Itemization %%%
-
-% Default dimensions of itemized lists
-\newdimen\itemindent           \itemindent=0.5in
-\newdimen\itemnarrow           \itemnarrow=0.5in                       % make lines narrower by this amount
-\newskip\itemmarkerskip                \itemmarkerskip=0.4em                   % between marker and the item
-\newskip\preitemizeskip                \preitemizeskip=3pt plus 2pt minus 1pt  % before the list
-\newskip\postitemizeskip       \postitemizeskip=3pt plus 2pt minus 1pt % after the list
-\newskip\interitemskip         \interitemskip=2pt plus 1pt minus 0.5pt % between two items
-
-% Analogues for nested lists
-\newdimen\nesteditemindent     \nesteditemindent=0.25in
-\newdimen\nesteditemnarrow     \nesteditemnarrow=0.25in
-\newskip\prenesteditemizeskip  \prenesteditemizeskip=0pt
-\newskip\postnesteditemizeskip \postnesteditemizeskip=0pt
-
-\newif\ifitems\itemsfalse
-\newbox\itembox
-\newcount\itemcount
-
-\def\preitemize{
-       \ifitems
-               \vskip\prenesteditemizeskip
-               \advance\leftskip by \nesteditemindent
-               \advance\rightskip by \nesteditemnarrow
-       \else
-               \vskip\preitemizeskip
-               \advance\leftskip by \itemindent
-               \advance\rightskip by \itemnarrow
-       \fi
-       \parskip=\interitemskip
-}
-
-\def\postitemize{
-       \ifitems
-               \vskip\postnesteditemizeskip
-       \else
-               \vskip\postitemizeskip
-       \fi
-}
-
-\def\inititemize{\begingroup\preitemize\itemstrue\parindent=0pt}
-
-\def\itemize#1{\inititemize\setbox\itembox\llap{#1\hskip\itemmarkerskip}%
-\let\:=\singleitem}
-
-\def\singleitem{\par\leavevmode\copy\itembox\ignorespaces}
-
-\def\endlist{\par\endgroup\postitemize}
-
-\def\ibull{\raise0.2ex\hbox{$\bullet$}} % Signs frequently used for \itemize
-\def\idot{\raise0.2ex\hbox{$\cdot$}}
-\def\istar{\raise0.2ex\hbox{$\ast$}}
-
-\def\numlist#1{\inititemize\itemcount=0\let\:=\numbereditem
-\let\itemnumbering=#1}
-
-\def\numbereditem{\par\leavevmode\advance\itemcount by 1
-\llap{\itemnumbering\hskip\itemmarkerskip}\ignorespaces}
-
-\def\nnorm{\the\itemcount}
-\def\ndotted{\nnorm.}
-\def\nparen{\nnorm)}
-\def\nroman{\romannumeral\itemcount}
-\def\nromanp{\nroman)}
-\def\nalpha{\count@=96\advance\count@ by\itemcount\char\count@)}
-\def\nAlpha{\count@=64\advance\count@ by\itemcount\char\count@)}
-\def\ngreek{$\ifcase\itemcount\or\alpha\or\beta\or\gamma\or\delta\or\epsilon\or
-\zeta\or\eta\or\theta\or\iota\or\kappa\or\lambda\or\mu\or\nu\or\xi\or\pi\or\rho
-\or\sigma\or\tau\or\upsilon\or\phi\or\chi\or\psi\or\omega\fi$)}
-
-%%% Miscellanea %%%
-
-% {\I italic} with automatic italic correction
-\def\I{\it\aftergroup\/}
-
-% A breakable dash, to be repeated on the next line
-\def\={\discretionary{-}{-}{-}}
-
-% Non-breakable identifiers
-\def\<#1>{\leavevmode\hbox{\I #1}}
-
-% A handy shortcut
-\let\>=\noindent
-
-% Variants of \centerline, \leftline and \rightline, which are compatible with
-% verbatim environments and other catcode hacks
-\def\cline{\bgroup\def\linet@mp{\aftergroup\box\aftergroup0\aftergroup\egroup\hss\bgroup\aftergroup\hss\aftergroup\egroup}\afterassignment\linet@mp\setbox0\hbox to \hsize}
-\def\lline{\bgroup\def\linet@mp{\aftergroup\box\aftergroup0\aftergroup\egroup\bgroup\aftergroup\hss\aftergroup\egroup}\afterassignment\linet@mp\setbox0\hbox to \hsize}
-\def\rline{\bgroup\def\linet@mp{\aftergroup\box\aftergroup0\aftergroup\egroup\hss\bgroup\aftergroup\egroup}\afterassignment\linet@mp\setbox0\hbox to \hsize}
-
-%%% Epilog %%%
-
-% Let's hide all internal macros
-\catcode`@=12
+\preitemizepenalty=0
+\postitemizepenalty=0
diff --git a/ucwmac2.tex b/ucwmac2.tex
new file mode 100644 (file)
index 0000000..6fd3f59
--- /dev/null
@@ -0,0 +1,485 @@
+% The UCW Macro Collection (a successor of mjmac.tex)
+% Written by Martin Mares <mj@ucw.cz> in 2010--2018 and placed into public domain
+% -------------------------------------------------------------------------------
+
+\ifx\ucwmodule\undefined\else\endinput\fi
+
+%%% Prolog %%%
+
+% We'll use internal macros of plain TeX
+\catcode`@=11
+
+\ifx\eTeXversion\undefined
+\errmessage{ucwmac requires the e-TeX engine or its successor}
+\fi
+
+%%% PDF output detection %%%
+
+\newif\ifpdf
+\pdffalse
+
+\ifx\pdfoutput\undefined
+\else\ifnum\pdfoutput>0
+       \pdftrue
+       \pdfpkresolution=600    % Provide a reasonable default
+\fi\fi
+
+\ifx\directlua\undefined\else
+       % In LuaTeX \pdfpkresolution is not enough
+       \directlua{kpse.init_prog("luatex", 600, "ljfour")}
+\fi
+
+%%% Temporary registers %%%
+
+\newcount\tmpcount
+\newdimen\tmpdimen
+
+%%% Auxiliary macros %%%
+
+% Prepend/append #2 to the definition of #1
+\long\def\prependef#1#2{\expandafter\def\expandafter#1\expandafter{#2#1}}
+\long\def\appendef#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
+
+% Variants of \def and \let, where the control sequence name is given as a string
+\def\sdef#1{\expandafter\def\csname#1\endcsname}
+\def\slet#1#2{\expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname}
+
+% Assign a control sequence given as a string, complain if it is not defined.
+\def\sget#1#2{\ifcsname#2\endcsname
+               \expandafter\let\expandafter#1\csname#2\endcsname
+       \else
+               \errmessage{Undefined control sequence #2}%
+               \let#1\relax
+       \fi
+}
+
+% Add \protected to an existing macro
+\def\addprotected#1{\protected\edef#1{\expandafter\unexpanded\expandafter{#1}}}
+
+% Protect ~
+\addprotected~
+
+\def\ucwwarn#1{\immediate\write16{*** UCWmac warning: #1 ***}}
+
+%%% Page size and margins %%%
+
+% If you modify these registers, call \setuppage afterwards
+\ifx\luatexversion\undefined
+       % In LuaTeX, \pagewidth and \pageheight are primitive
+       \newdimen\pagewidth
+       \newdimen\pageheight
+\fi
+\newdimen\leftmargin
+\newdimen\rightmargin
+\newdimen\topmargin
+\newdimen\bottommargin
+\newdimen\evenpageshift
+
+\def\setuppage{%
+       \hsize=\pagewidth
+       \advance\hsize by -\leftmargin
+       \advance\hsize by -\rightmargin
+       \vsize=\pageheight
+       \advance\vsize by -\topmargin
+       \advance\vsize by -\bottommargin
+       \hoffset=\leftmargin
+       \advance\hoffset by -1truein
+       \voffset=\topmargin
+       \advance\voffset by -1truein
+       \ifpdf
+               \pdfhorigin=1truein
+               \pdfvorigin=1truein
+               \ifx\luatexversion\undefined
+                       \pdfpagewidth=\pagewidth
+                       \pdfpageheight=\pageheight
+               \fi
+       \fi
+}
+
+% Set multiple margins to the same value
+\def\sethmargins#1{\leftmargin=#1\relax\rightmargin=#1\relax\evenpageshift=0pt\relax}
+\def\setvmargins#1{\topmargin=#1\relax\bottommargin=#1\relax}
+\def\setmargins#1{\sethmargins{#1}\setvmargins{#1}}
+
+% Define inner/outer margin instead of left/right
+\def\setinneroutermargin#1#2{\leftmargin#1\relax\rightmargin#2\relax\evenpageshift=\rightmargin\advance\evenpageshift by -\leftmargin}
+
+% Use a predefined paper format, calls \setuppage automagically
+\def\setpaper#1{%
+       \expandafter\let\expandafter\currentpaper\csname paper-#1\endcsname
+       \ifx\currentpaper\relax
+               \errmessage{Undefined paper format #1}
+       \fi
+       \currentpaper
+}
+
+% Switch to landscape orientation, calls \setuppage automagically
+\def\landscape{%
+       \dimen0=\pageheight
+       \pageheight=\pagewidth
+       \pagewidth=\dimen0
+       \setuppage
+}
+
+% Common paper sizes
+\def\defpaper#1#2#3{\expandafter\def\csname paper-#1\endcsname{\pagewidth=#2\pageheight=#3\setuppage}}
+\defpaper{a3}{297truemm}{420truemm}
+\defpaper{a4}{210truemm}{297truemm}
+\defpaper{a5}{148truemm}{210truemm}
+\defpaper{letter}{8.5truein}{11truein}
+\defpaper{legal}{8.5truein}{14truein}
+
+% Default page parameters
+\setmargins{1truein}
+\setpaper{a4}
+
+%%% Macros with optional arguments %%%
+
+% After \def\a{\withoptarg\b}, the macro \a behaves in this way:
+%      \a[arg]         does \def\optarg{arg} and then it expands \b
+%      \a              does \let\optarg=\relax and then it expands \b
+\def\withoptarg#1{\let\xoptcall=#1\futurelet\next\xopt}
+\def\xopt{\ifx\next[\expandafter\xoptwith\else\let\optarg=\relax\expandafter\xoptcall\fi}
+\def\xoptwith[#1]{\def\optarg{#1}\xoptcall}
+
+% A shortcut for defining macros with optional arguments:
+% \optdef\macro behaves as \def\domacro, while \macro itself is defined
+% as a wrapper calling \domacro using \withoptarg.
+\def\optdef#1{%
+       \edef\xoptname{\expandafter\eatbackslash\string#1}%
+       \edef#1{\noexpand\withoptarg\csname do\xoptname\endcsname}%
+       \expandafter\def\csname do\xoptname\endcsname
+}
+
+% Trick: \eatbackslash eats the next backslash of category 12
+\begingroup\lccode`\+=`\\
+\lowercase{\endgroup\def\eatbackslash+{}}
+
+% Expand to the optional argument if it exists
+\def\optargorempty{\ifx\optarg\relax\else\optarg\fi}
+
+%%% Placing material at specified coordinates %%%
+
+% Set all dimensions of a given box register to zero
+\def\smashbox#1{\ht#1=0pt \dp#1=0pt \wd#1=0pt}
+\long\def\smashedhbox#1{{\setbox0=\hbox{#1}\smashbox0\box0}}
+\long\def\smashedvbox#1{{\setbox0=\vbox{#1}\smashbox0\box0}}
+
+% Variants of \llap and \rlap working equally on both sides and/or vertically
+\def\hlap#1{\hbox to 0pt{\hss #1\hss}}
+\def\vlap#1{\vbox to 0pt{\vss #1\vss}}
+\def\clap#1{\vlap{\hlap{#1}}}
+
+% \placeat{right}{down}{hmaterial} places <hmaterial>, so that its
+% reference point lies at the given position wrt. the current ref point
+\long\def\placeat#1#2#3{\smashedhbox{\hskip #1\lower #2\hbox{#3}}}
+
+% Like \vbox, but with reference point in the upper left corner
+\long\def\vhang#1{\vtop{\hrule height 0pt\relax #1}}
+
+% Like \vhang, but respecting interline skips
+\long\def\vhanglines#1{\vtop{\hbox to 0pt{}#1}}
+
+% Crosshair with reference point in its center
+\def\crosshair#1{\clap{\vrule height 0.2pt width #1}\clap{\vrule height #1 width 0.2pt}}
+
+%%% Output routine %%%
+
+\newbox\pageunderlays
+\newbox\pageoverlays
+\newbox\commonunderlays
+\newbox\commonoverlays
+
+% In addition to the normal page contents, you can define page overlays
+% and underlays, which are zero-size vboxes positioned absolutely in the
+% front / in the back of the normal material. Also, there are global
+% versions of both which are not reset after every page.
+\def\addlay#1#2{\setbox#1=\vbox{\ifvbox#1\box#1\fi\nointerlineskip\smashedvbox{#2}}}
+\def\pageunderlay{\addlay\pageunderlays}
+\def\pageoverlay{\addlay\pageoverlays}
+\def\commonunderlay{\addlay\commonoverlays}
+\def\commonoverlay{\addlay\commonoverlays}
+
+% Our variation on \plainoutput, which manages inner/outer margins and overlays
+\output{\ucwoutput}
+\newdimen\pagebodydepth
+\def\ucwoutput{\wigglepage\shipout\vbox{%
+       \makeheadline
+       \ifvbox\commonunderlays\copy\commonunderlays\nointerlineskip\fi
+       \ifvbox\pageunderlays\box\pageunderlays\nointerlineskip\fi
+       \pagebody
+       \pagebodydepth=\prevdepth
+       \nointerlineskip
+       \ifvbox\commonoverlays\vbox to 0pt{\vskip -\vsize\copy\commonoverlays\vss}\nointerlineskip\fi
+       \ifvbox\pageoverlays\vbox to 0pt{\vskip -\vsize\box\pageoverlays\vss}\nointerlineskip\fi
+       \prevdepth=\pagebodydepth
+       \makefootline
+}\advancepageno
+\ifnum\outputpenalty>-\@MM \else\dosupereject\fi}
+
+\def\wigglepage{\ifodd\pageno\else\advance\hoffset by \evenpageshift\fi}
+
+% Make it easier to redefine footline font (also, fix it so that OFS won't change it unless asked)
+\let\footfont=\tenrm
+\footline={\hss\footfont\folio\hss}
+
+%%% Itemization %%%
+
+% Usage:
+%
+% \list{style}
+% \:first item
+% \:second item
+% \endlist
+%
+% Available styles (others can be defined by \sdef{item:<style>}{<marker>})
+%
+%      o               % bullet
+%      O               % empty circle
+%      *               % asterisk
+%      -               % en-dash
+%      .               % dot
+%      n               % 1, 2, 3
+%      i               % i, ii, iii
+%      I               % I, II, III
+%      a               % a, b, c
+%      A               % A, B, C
+%      g               % α, β, γ
+%
+% Meta-styles (can be used to modify an arbitrary style, currently hard-wired)
+%
+%      #.              % with a dot behind
+%      #)              % with a parenthesis behind
+%      (#)             % enclosed in parentheses
+%
+% Historic usage:
+%
+% \itemize\ibull       % or other marker
+% \:first item
+% \:second item
+% \endlist
+%
+% \numlist\ndotted     % or other numbering style
+% \:first
+% \:second
+% \endlist
+
+% Default dimensions of itemized lists
+\newdimen\itemindent           \itemindent=0.5in
+\newdimen\itemnarrow           \itemnarrow=0.5in                       % make lines narrower by this amount
+\newskip\itemmarkerskip                \itemmarkerskip=0.4em                   % between marker and the item
+\newskip\preitemizeskip                \preitemizeskip=3pt plus 2pt minus 1pt  % before the list
+\newskip\postitemizeskip       \postitemizeskip=3pt plus 2pt minus 1pt % after the list
+\newskip\interitemskip         \interitemskip=2pt plus 1pt minus 0.5pt % between two items
+
+% Analogues for nested lists
+\newdimen\nesteditemindent     \nesteditemindent=0.25in
+\newdimen\nesteditemnarrow     \nesteditemnarrow=0.25in
+\newskip\prenesteditemizeskip  \prenesteditemizeskip=0pt
+\newskip\postnesteditemizeskip \postnesteditemizeskip=0pt
+
+\newif\ifitems\itemsfalse
+\newbox\itembox
+\newcount\itemcount
+
+% Penalties
+\newcount\preitemizepenalty    \preitemizepenalty=-500
+\newcount\postitemizepenalty   \postitemizepenalty=-500
+
+\def\preitemize{
+       \ifitems
+               \vskip\prenesteditemizeskip
+               \advance\leftskip by \nesteditemindent
+               \advance\rightskip by \nesteditemnarrow
+       \else
+               \ifnum\preitemizepenalty=0\else\penalty\preitemizepenalty\fi
+               \vskip\preitemizeskip
+               \advance\leftskip by \itemindent
+               \advance\rightskip by \itemnarrow
+       \fi
+       \parskip=\interitemskip
+}
+
+\def\postitemize{
+       \ifitems
+               \vskip\postnesteditemizeskip
+       \else
+               \ifnum\postitemizepenalty=0\else\penalty\postitemizepenalty\fi
+               \vskip\postitemizeskip
+       \fi
+}
+
+\def\inititemize{\begingroup\preitemize\itemstrue\parindent=0pt}
+
+\def\list#1{\inititemize\itemcount=0\liststyle{#1}\let\:=\listitem}
+\def\listitem{\par\leavevmode\advance\itemcount by 1
+       \llap{\listmarker\hskip\itemmarkerskip}\ignorespaces}
+
+\def\liststyle#1{%
+       \edef\markertmp{#1}
+       \ifcsname item:\markertmp\endcsname
+               \sget\listmarker{item:\markertmp}%
+       \else
+               \sget\listmarker{metaitem:\markertometa#1^^X}%
+               \sget\markerinner{item:\markertoinner#1^^X}%
+       \fi
+}
+
+\def\markertometa#1{%
+       \ifx#1^^X%
+       \else
+               \ifx#1((%
+               \else\ifx#1))%
+               \else\ifx#1..%
+               \else=%
+               \fi\fi\fi
+               \expandafter\markertometa
+       \fi
+}
+
+\def\markertoinner#1{%
+       \ifx#1^^X%
+       \else
+               \ifx#1(%
+               \else\ifx#1)%
+               \else\ifx#1.%
+               \else#1%
+               \fi\fi\fi
+               \expandafter\markertoinner
+       \fi
+}
+
+\def\endlist{\par\endgroup\postitemize}
+
+% List styles
+\sdef{item:o}{\raise0.2ex\hbox{$\bullet$}}
+\sdef{item:O}{\raise0.2ex\hbox{$\circ$}}
+\sdef{item:*}{\raise0.2ex\hbox{$\ast$}}
+\sdef{item:-}{--}
+\sdef{item:.}{\raise0.2ex\hbox{$\cdot$}}
+\sdef{item:n}{\the\itemcount}
+\sdef{item:i}{\romannumeral\itemcount}
+\sdef{item:I}{\uppercase\expandafter{\romannumeral\itemcount}}
+\sdef{item:a}{\char\numexpr 96+\itemcount\relax}
+\sdef{item:A}{\char\numexpr 64+\itemcount\relax}
+\sdef{item:g}{$\ifcase\itemcount\or\alpha\or\beta\or\gamma\or\delta\or\epsilon\or
+\zeta\or\eta\or\theta\or\iota\or\kappa\or\lambda\or\mu\or\nu\or\xi\or\pi\or\rho
+\or\sigma\or\tau\or\upsilon\or\phi\or\chi\or\psi\or\omega\fi$}
+
+% List meta-styles
+\sdef{metaitem:=.}{\markerinner.}
+\sdef{metaitem:=)}{\markerinner)}
+\sdef{metaitem:(=)}{(\markerinner)}
+
+% Old-style lists
+
+\def\itemize#1{\inititemize\setbox\itembox\llap{#1\hskip\itemmarkerskip}%
+\let\:=\singleitem}
+
+\def\singleitem{\par\leavevmode\copy\itembox\ignorespaces}
+
+\def\numlist#1{\inititemize\itemcount=0\let\:=\numbereditem
+\let\itemnumbering=#1}
+
+\def\numbereditem{\par\leavevmode\advance\itemcount by 1
+\llap{\itemnumbering\hskip\itemmarkerskip}\ignorespaces}
+
+% Old-style markers
+
+\def\ibull{\raise0.2ex\hbox{$\bullet$}}
+\def\idot{\raise0.2ex\hbox{$\cdot$}}
+\def\istar{\raise0.2ex\hbox{$\ast$}}
+
+\def\nnorm{\the\itemcount}
+\def\ndotted{\nnorm.}
+\def\nparen{\nnorm)}
+\def\nparenp{(\nnorm)}
+\def\nroman{\romannumeral\itemcount}
+\def\nromanp{\nroman)}
+\def\nalpha{\count@=96\advance\count@ by\itemcount\char\count@)}
+\def\nAlpha{\count@=64\advance\count@ by\itemcount\char\count@)}
+\def\ngreek{$\ifcase\itemcount\or\alpha\or\beta\or\gamma\or\delta\or\epsilon\or
+\zeta\or\eta\or\theta\or\iota\or\kappa\or\lambda\or\mu\or\nu\or\xi\or\pi\or\rho
+\or\sigma\or\tau\or\upsilon\or\phi\or\chi\or\psi\or\omega\fi$)}
+
+%%% Miscellanea %%%
+
+% {\I italic} with automatic italic correction
+\def\I{\it\aftergroup\/}
+
+% A breakable dash, to be repeated on the next line
+\def\={\discretionary{-}{-}{-}}
+
+% Non-breakable identifiers
+\def\<#1>{\leavevmode\hbox{\I #1}}
+
+% Handy shortcuts
+\let\>=\noindent
+\def\\{\hfil\break}
+
+% Variants of \centerline, \leftline and \rightline, which are compatible with
+% verbatim environments and other catcode hacks
+\def\cline{\bgroup\def\linet@mp{\aftergroup\box\aftergroup0\aftergroup\egroup\hss\bgroup\aftergroup\hss\aftergroup\egroup}\afterassignment\linet@mp\setbox0\hbox to \hsize}
+\def\lline{\bgroup\def\linet@mp{\aftergroup\box\aftergroup0\aftergroup\egroup\bgroup\aftergroup\hss\aftergroup\egroup}\afterassignment\linet@mp\setbox0\hbox to \hsize}
+\def\rline{\bgroup\def\linet@mp{\aftergroup\box\aftergroup0\aftergroup\egroup\hss\bgroup\aftergroup\egroup}\afterassignment\linet@mp\setbox0\hbox to \hsize}
+
+% Insert a PDF picture
+% \putimage{width specification}{file}
+\def\putimage#1#2{\hbox{\pdfximage #1{#2}\pdfrefximage\pdflastximage}}
+
+%%% Colors %%%
+
+% Use of pdfTeX color stack:
+% \colorpush\rgb{1 0 0} puts a new color on the stack
+% \colorset\rgb{1 0 0} replaces the top color on the stack
+% \colorpop pops the top color
+% \colorlocal\rgb{1 0 0} set a color locally until the end of the current group
+\chardef\colorstk=\pdfcolorstackinit page direct{0 g 0 G}
+\def\colorset#1{\pdfcolorstack\colorstk set #1}
+\def\colorpush#1{\pdfcolorstack\colorstk push #1}
+\def\colorpop{\pdfcolorstack\colorstk pop}
+\def\colorlocal{\aftergroup\colorpop\colorpush}
+
+% Different ways of describing colors: \rgb{R G B}, \gray{G}, \cmyk{C M Y K}
+% (all components are real numbers between 0 and 1)
+\def\rgb#1{{#1 rg #1 RG}}
+\def\gray#1{{#1 g #1 G}}
+\def\cmyk#1{{#1 k #1 K}}
+
+%%% Localization %%%
+
+% Define a new localized string: \localedef{language}{identifier}{message}
+% (we use \language codes to identify languages)
+\def\localedef#1#2{\tmpcount=#1\expandafter\def\csname loc:\the\tmpcount:#2\endcsname}
+
+% Expand a localized string in the current language: \localemsg{identifier}
+\def\localestr#1{%
+       \ifcsname loc:\the\language:#1\endcsname
+               \csname loc:\the\language:#1\endcsname
+       \else
+               \ucwwarn{Localized string #1 not defined in language \the\language}%
+               ???%
+       \fi
+}
+
+%%% Modules %%%
+
+% Require a module: load it if it is not already loaded
+\def\ucwmodule#1{
+       \ifcsname ucwmod:#1\endcsname
+       \else
+               \input ucw-#1.tex
+       \fi
+}
+
+% Definition of a new module (to be placed at the beginning of its file)
+% (Also guards against repeated loading if somebody uses \input instead of \ucwmodule.)
+\def\ucwdefmodule#1{
+       \ifcsname ucwmod:#1\endcsname\endinput\fi
+       \expandafter\let\csname ucwmod:#1\endcsname=\relax
+}
+
+%%% Epilog %%%
+
+% Let's hide all internal macros
+\catcode`@=12