summaryrefslogtreecommitdiff
path: root/macros/optex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-08-27 03:00:41 +0000
committerNorbert Preining <norbert@preining.info>2021-08-27 03:00:41 +0000
commiteb339ffb650bb61b1080d7cef2cc187f09508fe0 (patch)
tree9dab49ba37836bc36796ba4a9f87fc6cbdbeb3b3 /macros/optex
parent059cab71c68a3fbee36f60e8208d4a47d11c6b60 (diff)
CTAN sync 202108270300
Diffstat (limited to 'macros/optex')
-rw-r--r--macros/optex/README12
-rw-r--r--macros/optex/base/basic-macros.opm24
-rw-r--r--macros/optex/base/colors.opm215
-rw-r--r--macros/optex/base/doc.opm6
-rw-r--r--macros/optex/base/fonts-select.opm30
-rw-r--r--macros/optex/base/graphics.opm75
-rw-r--r--macros/optex/base/hi-syntax.opm122
-rw-r--r--macros/optex/base/hisyntax-python.opm4
-rw-r--r--macros/optex/base/if-macros.opm7
-rw-r--r--macros/optex/base/makeindex.opm8
-rw-r--r--macros/optex/base/maketoc.opm6
-rw-r--r--macros/optex/base/math-macros.opm7
-rw-r--r--macros/optex/base/math-unicode.opm48
-rw-r--r--macros/optex/base/optex.ini6
-rw-r--r--macros/optex/base/optex.lua268
-rw-r--r--macros/optex/base/others.opm4
-rw-r--r--macros/optex/base/output.opm51
-rw-r--r--macros/optex/base/parameters.opm26
-rw-r--r--macros/optex/base/prefixed.opm12
-rw-r--r--macros/optex/base/ref-file.opm135
-rw-r--r--macros/optex/base/references.opm6
-rw-r--r--macros/optex/base/slides.opm19
-rw-r--r--macros/optex/base/table.opm125
-rw-r--r--macros/optex/doc/omls.tex3
-rw-r--r--macros/optex/doc/optex-doc.pdfbin1383214 -> 1387160 bytes
-rw-r--r--macros/optex/doc/optex-doc.tex2
-rw-r--r--macros/optex/doc/optex-math.tex7
-rw-r--r--macros/optex/doc/optex-techdoc.tex4
-rw-r--r--macros/optex/doc/optex-userdoc.tex36
-rw-r--r--macros/optex/pkg/tikz.opm39
30 files changed, 848 insertions, 459 deletions
diff --git a/macros/optex/README b/macros/optex/README
index 61c4698328..ac77358913 100644
--- a/macros/optex/README
+++ b/macros/optex/README
@@ -17,6 +17,16 @@ pkg/ ... external macros. Maybe, they can be created by other authors if
in the OpTeX documentation.
doc/ ... PDF version of the OpTeX documentation and sources.
+History:
+
+<1.04> Aug. 2021:
+ Color handling reimplemented, LuaTeX's attributes are used now.
+ Loading Unicode math fonts reimplemented, (s)script size given by font.
+ Better compatibility with TikZ using tikz.opm package.
+ .ref file: consistency checking added.
+ Versions of .opm files printed only to .log.
+ \tracingmacros=3 or 4 enabled.
+ Bugs fixing.
<1.03> Jun. 2021:
mte: Package for MicroTypographic Extensions released.
Erewhon: font family support added.
@@ -31,7 +41,7 @@ doc/ ... PDF version of the OpTeX documentation and sources.
Microtypography support added.
Various colors for links can be declared by \def\_<type>linkolor.
unimath-codes: \nabla math-code set similar as \Delta.
- Actual version of UnicodeData.txt read during format generation.
+ Up to date version of UnicodeData.txt read during format generation.
Reading mathclacss.opm improved.
slides: hyperlink destinations allowed in \slideshow mode too.
\bibpart allows to create independent bib-lists in single document.
diff --git a/macros/optex/base/basic-macros.opm b/macros/optex/base/basic-macros.opm
index 57393fc323..912be5e036 100644
--- a/macros/optex/base/basic-macros.opm
+++ b/macros/optex/base/basic-macros.opm
@@ -1,9 +1,9 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \sdef {Basic macros for OpTeX <2021-05-16>} % preloaded in format
+\_codedecl \sdef {Basic macros for OpTeX <2021-07-20>} % preloaded in format
\_doc ------------------------------
- \`\bgroup`, \`\egroup`, \`\empty`, \`\space`, \`\null` and \`\wlog`
+ \`\bgroup`, \`\egroup`, \`\empty`, \`\space`, and \`\null`
are classical macros from plain \TeX/.
\_cod ------------------------------
@@ -11,8 +11,7 @@
\_def \_empty {}
\_def \_space { }
\_def \_null {\_hbox{}}
-\_def \_wlog {\_immediate\_write-1 } % write on log file (only)
-\_public \bgroup \egroup \empty \space \null \wlog ;
+\_public \bgroup \egroup \empty \space \null ;
\_doc ------------------------------
\`\ignoreit` ignores next token or `{<text>}`,
@@ -107,25 +106,32 @@
\_cod ------------------------------
\_def\_loggingall{\_tracingcommands=3 \_tracingstats=2 \_tracingpages=1
- \_tracingoutput=1 \_tracinglostchars=1 \_tracingmacros=2
+ \_tracingoutput=1 \_tracinglostchars=1 \_tracingmacros=3
\_tracingparagraphs=1 \_tracingrestores=1 \_tracingscantokens=1
\_tracingifs=1 \_tracinggroups=1 \_tracingassigns=1 }
\_def\_tracingall{\_tracingonline=1 \_loggingall}
\_public \loggingall \tracingall ;
\_doc ------------------------------
- Write a warning if the user did not load a Unicode Font {\em or}
- if there were unresolved references. \`\_byehook` is used in the \^`\bye` macro.
+ \`\_byehook` is used in the \^`\bye` macro.
+ Write a warning if the user did not load a Unicode Font.
+ Write a \"rerun" warning if the `.ref` file was newly created or it was
+ changed (compared to the previous TeX run).
\_cod ------------------------------
\_def\_byehook{%
\_ifx\_initunifonts\_relax \_relax\_else \_opwarning{Unicode font was not loaded}\_fi
- \_ifnum\_unresolvedrefs>0 \_opwarning{Try to rerun to get references right}\_fi
+ \_immediate\_closeout\_reffile
+ \_edef\_tmp{\_mdfive{\_jobname.ref}}%
+ \_ifx\_tmp\_prevrefhash\_else \_opwarning{Try to rerun,
+ \_jobname.ref file was \_ifx\_prevrefhash\_empty created\_else changed\_fi}\_fi
}
\_endcode % -------------------------------------
-2021-05-16: \slet reimplemnted (to allow \slet{foo}{undefined}).
+2021-07-20: \_unresovedrefs removed from \_byehook
+2021-07-18: \_byehook: checking `ref` file consistency added.
+2021-05-16: \slet reimplemented (to allow \slet{foo}{undefined}).
2021-02-03: \useit defined.
2021-01-22: \trycs: \ea added in order to be able to use cs with parameters
2021-01-08: \opwarning format changed (secondly, hope that conclusively)
diff --git a/macros/optex/base/colors.opm b/macros/optex/base/colors.opm
index 23ec22dd9f..6ef8fc9dcf 100644
--- a/macros/optex/base/colors.opm
+++ b/macros/optex/base/colors.opm
@@ -1,16 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \colordef {Colors <2021-05-28>} % preloaded in format
-
- \_doc -----------------------------
- We declare internal boolean value \`\_iflocalcolor` ad do
- \`\localcolor` as default.
- \_cod -----------------------------
-
-\_newifi \_iflocalcolor \_localcolortrue
-\_protected\_def \_localcolor {\_localcolortrue}
-\_protected\_def \_nolocalcolor {\_localcolorfalse}
-\_public \localcolor \nolocalcolor ;
+\_codedecl \colordef {Colors <2021-07-16>} % preloaded in format
\_doc -----------------------------
The basic colors in CMYK
@@ -21,103 +11,101 @@
\_def\Blue {\_setcmykcolor{1 1 0 0}}
\_def\Red {\_setcmykcolor{0 1 1 0}}
-\_def\Brown {\_setcmykcolor{0 0.67 0.67 0.5}}
+\_def\Brown {\_setcmykcolor{0 .67 .67 .5}}
\_def\Green {\_setcmykcolor{1 0 1 0}}
\_def\Yellow {\_setcmykcolor{0 0 1 0}}
\_def\Cyan {\_setcmykcolor{1 0 0 0}}
\_def\Magenta {\_setcmykcolor{0 1 0 0}}
-\_def\Grey {\_setcmykcolor{0 0 0 0.5}}
-\_def\LightGrey {\_setcmykcolor{0 0 0 0.2}}
+\_def\Grey {\_setcmykcolor{0 0 0 .5}}
+\_def\LightGrey {\_setcmykcolor{0 0 0 .2}}
\_def\White {\_setgreycolor{1}}
\_def\Black {\_setgreycolor{0}}
\_doc -----------------------------
By default, the \`\setcmykcolor` \`\setrgbcolor` and \`\setgreycolor`
macros with `{<componetns>}` parameter
- expand to `\_setcolor{<pdf-primitive>}` using \`\_formatcmyk`
- or \`\_formatrgb` or \`\_formatgrey` expandable macros.
- For example `\setrgbcolor{1 0 0}` expands to `\_setcolor{1 0 0 rg 1 0 0 RG}`.\nl
- We set both types of colors (for lines (`K` or `RG` or `G`) and for fills
- (`r` or `rg` or `g`) together in the <pdf-primitive> command.
- This is the reason why the \`\_fillstroke` uses both its parameters.
- If only fills are needed you can do `\def\_fillstroke#1#2{#1}`.
- If only strokes are needed you can do `\def\_fillstroke#1#2{#2}`.
+ expand to \^`\_setcolor``{<color-data>}{<fill-op>}{<stroke-op>}` where
+ <color-data> is <R> <G> <B> or <C> <M> <Y> <K> or <G> and
+ <fill-op> is color operator for filling, <stroke-op> is color operator
+ for stroking.
\_cod -----------------------------
-\_def\_setcmykcolor#1{\_setcolor{\_formatcmyk{#1}}}
-\_def\_setrgbcolor#1{\_setcolor{\_formatrgb{#1}}}
-\_def\_setgreycolor#1{\_setcolor{\_formatgrey{#1}}}
-\_def\_formatcmyk#1{\_fillstroke{#1 k}{#1 K}}
-\_def\_formatrgb#1{\_fillstroke{#1 rg}{#1 RG}}
-\_def\_formatgrey#1{\_fillstroke{#1 g}{#1 G}}
-\_def\_fillstroke#1#2{#1 #2}
+\_def\_setcmykcolor#1{\_setcolor{#1}kK}
+\_def\_setrgbcolor#1{\_setcolor{#1}{rg}{RG}}
+\_def\_setgreycolor#1{\_setcolor{#1}gG}
\_public \setcmykcolor \setrgbcolor \setgreycolor ;
\_doc -----------------------------
- The \`\onlyrgb` declaration redefines \^`\_formatcmyk` in order it expands
- to its conversion to RGB <pdf-primitive>. This conversion is done by
- the \^`\_cmyktorgb` macro. Moreover, `\onlyrgb` re-defines three basic RGB
+ The \`\onlyrgb` declaration redefines \^`\setcmykcolor` to do conversion
+ to RGB just before \^`\_setcolor` is used.
+ The \`\onlycmyk` declaration redefines \^`\setrgbcolor` to do conversion
+ to CMYK just before \^`\_setcolor` is used.
+ Moreover, \^`\onlyrgb` re-defines three basic RGB
colors for RGB color space and re-declares \^`\colordef` as \^`\rgbcolordef`.
- The \hbox{\`\onlycmyk`} macro does similar work, it re-defines \^`\_formatrgb`
- macro. The Grey color space is unchanged and works in both main
- settings (RGB or CMYK) without collisions.
\_cod -----------------------------
\_def\_onlyrgb{\_def\Red{\_setrgbcolor{1 0 0}}%
\_def\Green{\_setrgbcolor{0 1 0}}\_def\Blue{\_setrgbcolor{0 0 1}}%
\_let\_colordef=\_rgbcolordef
- \_def\_formatrgb##1{\_fillstroke{##1 rg}{##1 RG}}%
- \_def\_formatcmyk##1{\_fillstroke{\_cmyktorgb ##1 ; rg}{\_cmyktorgb ##1 ; RG}}}
-\_def\_onlycmyk{\_def\_formatcmyk##1{\_fillstroke{##1 k}{##1 K}}%
- \_def\_formatrgb##1{\_fillstroke{\_rgbtocmyk ##1 ; k}{\_rgbtocmyk ##1 ; K}}}
+ \_def\_setrgbcolor##1{\_setcolor{##1}{rg}{RG}}%
+ \_def\_setcmykcolor##1{\_ea\_setcolor\_ea{\_expanded{\_cmyktorgb ##1 ;}}{rg}{RG}}%
+ \_public \colordef \setrgbcolor \setcmykcolor ;}
+\_def\_onlycmyk{%
+ \_let\_colordef=\_cmykcolordef
+ \_def\_setrgbcolor##1{\_ea\_setcolor\_ea{\_expanded{\_rgbtocmyk ##1 ;}}kK}%
+ \_def\_setcmykcolor##1{\_setcolor{##1}kK}%
+ \_public \colordef \setrgbcolor \setcmykcolor ;}
\_public \onlyrgb \onlycmyk ;
\_doc -----------------------------
- The \`\_setcolor` macro redefines empty `\_ensureblack` macro (used in
- output routine for headers and footers) to `\_ensureblackA` which sets
- Black at the start of its parameter and returns to the current color at the
- end of its parameter.
-
- The current color is saved into `\_currentcolor` macro and colorstack is pushed.
- Finally, the `\_colorstackpop` is initialized by `\aftergroup` if
- `\localcolor` is declared.
-
- You can save the current color to your macro by `\let\yourmacro=\_currentcolor`
- and you can return to this color by the command `\_setcolor\yourmacro`.
+ The \`\_colorattr` for coloring is allocated and
+ \`\_setcolor``{<color-data>}{<fill-op>}{<stroke-op>}` is defined here.
+ This macro does `\_colorattr=`\`\_colorcnt` if the <color data> was not used
+ before and prepare mapping from this integer value to the <color data>
+ and increments \^`\_colorcnt`.
+ If the <color data> were used already, then \^`\_setcolor`
+ does `\_colorattr=<stored-value>`.
+ This work is done by the \`\_translatecolor` macro. The following mapping
+ macros are created:
+ \begtt \catcode`<=13
+ \_color::<data> <fill-op> ... expands to used <attribute-value>
+ \_color:<attribute-value> ... expands to <data> <fill-op>
+ \_color-s:<attribute-value> ... expands to <data> <stroke-op>
+ \endtt
+ The \`\_resetcolor` un-sets the color attribute, it means that default
+ color (black) shall be used.
\_cod -----------------------------
-\_protected\_def \_setcolor #1{\_global\_let\_ensureblack=\_ensureblackA
- \_iflocalcolor \_edef\_currentcolor{#1}\_colorstackpush\_currentcolor
- \_aftergroup\_colorstackpop
- \_else \_xdef\_currentcolor{#1}\_colorstackset\_currentcolor \_fi
+\_newattribute \_colorattr
+\_newcount \_colorcnt \_colorcnt=1 % allocations start at 1
+\_protected\_def\_setcolor{\_colorprefix\_colorattr=\_translatecolor}
+\_def\_resetcolor{\_colorattr=-"7FFFFFFF }
+\_def\_translatecolor#1#2#3{\_ifcsname _color::#1 #2\_endcsname\_lastnamedcs\_relax
+ \_else
+ \_colorcnt
+ \_sxdef{_color::#1 #2}{\_the\_colorcnt}%
+ \_sxdef{_color:\_the\_colorcnt}{#1 #2}%
+ \_sxdef{_color-s:\_the\_colorcnt}{#1 #3}%
+ \_incr \_colorcnt
+ \_fi
}
-\_def\_pdfblackcolor{0 g 0 G}
-\_edef\_currentcolor{\_pdfblackcolor}
-\_def\_ensureblackA#1{\_global\_let\_openfnotestack=\_openfnotestackA
- \_colorstackpush\_pdfblackcolor #1\_colorstackpop}
-
- \_doc -----------------------------
- The colorstack is initialized here and the basic macros
- \`\_colorstackpush`, \`\_colorstackpop` and \`\_colorstackset`
- are defined here.
- \_cod -----------------------------
-
-\_mathchardef\_colorstackcnt=0 % Implicit stack usage
-\_def\_colorstackpush#1{\_pdfcolorstack\_colorstackcnt push{#1}}
-\_def\_colorstackpop{\_pdfcolorstack\_colorstackcnt pop}
-\_def\_colorstackset#1{\_pdfcolorstack\_colorstackcnt set{#1}}
+% Black is the default color.
+\_sdef{_color::0 g}{0}
+\_sdef{_color:0}{0 g}
+\_sdef{_color-s:0}{0 G}
\_doc -----------------------------
- We need to open a special color stack for footnotes because footnotes
- can follow on the next pages and their colors are independent of colors
- used in the main page-body. The \`\_openfnotestack` is defined as
- \`\_openfnotestackA` when the \^`\_setcolor` is used first.
- The \`\_fnotestack` is initialized in in `\everyjob` because the
- initialization is not saved to the format.
+ We support concept of non-local color, i.e. all changes of the color
+ attribute are global by setting \`\_colorprefix` to `\global`.
+ \`\localcolor` is the default, i.e.\ \^`\_colorprefix` is `\relax`.\nl
+ You can write `\global\Red` if you want to have global setting of the
+ color.
\_cod -----------------------------
-%\_mathchardef\_fnotestack=\_pdfcolorstackinit page {0 g 0 G} % must be in \everyjob
-\_def \_openfnotestackA {\_pdfcolorstack\_fnotestack current}
+\_protected\_def \_localcolor {\_let\_colorprefix=\_relax}
+\_protected\_def \_nolocalcolor {\_let\_colorprefix=\_global}
+\_public \localcolor \nolocalcolor ;
+\_localcolor
\_doc -----------------------------
We use Lua codes for RGB to CMYK or CMYK to RGB conversions and for
@@ -297,7 +285,7 @@
\begtt
\def\vr{\vrule height10pt depth2pt width20pt}
\def\_showcolor{\hbox{\tt\_bslash\_tmpb: \csname\_tmpb\endcsname \vr}\space\space}
- \begmulti 4 \typosize[11/14]
+ \begmulti 4 \typosize[10/14]
\morecolors
\endmulti
\endtt
@@ -319,35 +307,49 @@
\_endcode % -------------------------------------
-The colors have different behavior than fonts. Marks (whatsits) with color
-information are stored into PDF output and \TeX/ doesn't interpret them.
-The PDF viewer (or PDF interpreter in a printer) reads these marks
-and switches colors according to them. This
-is independent of \TeX/ group mechanism. You can declare
-`\nolocalcolor` at the beginning of the document, if you want this behavior.
-In this case, if you set a color then you must return to the black color
-using `\Black` manually.
-
-By default, \OpTeX/ sets `\localcolor`. It means that the typesetting
-returns to a previous color at the end of the current group, so you cannot
-write `\Black` explicitly. This is implemented using the `\aftergroup` feature.
-There is a limitation of this feature: when a color selector is used in a
-group of a box, which is saved by `\setbox`, then the activity or
-reconstruction of the previous color is processed at `\setbox` time, no in the
-box itself. You must correct it by double group:
-\begtt
-\setbox0=\hbox{\Red text} % bad: \Black is done after \setbox
-\setbox0=\hbox{{\Red text}} % good: \Black is done after group inside the box
-\endtt
-
-The implementation of colors is based on colorstack, so the current color
-can follow across more pages. It is not so obvious because PDF viewer (or PDF
-interpreter) manipulates with colors locally at each PDF page and it
-initializes each PDF page with black on white color.
+\secc Basic concept
+
+Setting of color in PDF is handled by graphics operators which change the
+graphics context. Colors for fills/strokes are distinguished, but apart from
+that, only one color is active at time and is used for all material drawn by
+following graphics operators, until next color is set. Each PDF content (e.g.
+page or form XObject) has its own graphics context, that is initialized from
+zero. Hence we have different concept of selecting fonts in \TeX/ (it
+depends on \TeX/ groups but does not depends on pages) and color handling in
+PDF.
+
+\TeX/ itself has no concept of colors. Colors have always been handled by
+inserting whatsits (either using `\special` for DVI or using
+`\pdfliteral`/`\pdfcolorstack` for PDF). It is very efficient and \TeX/ doesn't
+even have to know anything about colors, but it is also problematic in many
+ways.
+
+That is the reason why we decided to change color handling from
+`\pdfcolorstack` to \LuaTeX/ attributes in version 1.04 of \OpTeX. Using
+attributes, the color setting behaves exactly like font selection from \TeX/
+point of view: it respects \TeX/ groups, colors can span more pages,
+independent colors can be set for `\insert`s, etc. Moreover, once a material is
+created (using `\setbox` for example) then it has its fonts and its colors
+frozen and you can rely on it when you are using e.g. `\unhbox`. There are no
+internal whatsits for colors which can interfere with other typesetting
+material. In the end something like setting text to red (`{\Red text}`) should
+have the same nice behavior like setting text to bold (`{\bf text}`).
+
+\LuaTeX/ attributes can be set like count register -- one attribute holds one
+number at a time. But the value of attribute is propagated to each created
+typesetting element until the attribute is unset or set to another value. Very
+much like the font property. We use one attribute \^`\_colorattr` for storing
+the currently selected color (in number form).
Macros \^`\setcmykcolor``{<C> <M> <Y> <K>}` or \^`\setrgbcolor``{<R> <G> <B>}`
-or\nl \^`\setgreycolor``{<Grey>}` should be used in color selectors or user can
-specify these macros explicitly.
+or\nl \^`\setgreycolor``{<Grey>}` are used in color selectors. These
+macros expand to internal \^`\_setcolor` macro which sets the \^`\_colorattr`
+attribute to an integer value and prepares mapping between this value and the real
+color data. This mapping is used just before each `\shipout` in output routine.
+The \^`\_preshipout` pseudo-primitive is used here, it converts attribute
+values to internal PDF commands for selecting colors.
+
+\secc Color mixing
The color mixing processed by the \^`\colordef` is done in the subtractive color
model CMYK. If the result has a component greater than 1 then all
@@ -405,8 +407,11 @@ and it is used in \^`\colordef` or if it is printed when \^`\onlycmyk` is declar
The CMYK to RGB conversion is invoked when a color is declared using \^`\setcmykcolor`
and it is used in \^`\rgbcolordef` or if it is printed when \^`\onlyrgb` is declared.
+\secc Implementation
+
\_endinput
+2021-07-16 colors reimplemented, now they are based on attributes
2021-05-28 \rgbcmykmap introduced
2020-04-22 \replstring\tmpb{+ }{+}, {- }{-} added in \colordef, bug fixed
2020-03-18 introduced
diff --git a/macros/optex/base/doc.opm b/macros/optex/base/doc.opm
index 643a283e7c..34a00dc1e9 100644
--- a/macros/optex/base/doc.opm
+++ b/macros/optex/base/doc.opm
@@ -127,7 +127,7 @@
The lines in the listing mode have a yellow background.
\_cod -----------------------------
-\_def\Yellow{\_setcmykcolor{0.0 0.0 0.3 0.03}}
+\_def\Yellow{\_setcmykcolor{0 0 .3 .03}}
\_def\_printcodeline#1{\_advance \_maxlines by-1
\_ifnum \_maxlines<0 \_ea \_endverbprinting \_fi
@@ -137,7 +137,7 @@
\_indent \_printverblinenum #1\par}
\_def\_printfilename{\_hbox to0pt{%
- \_hskip\_hsize\vbox to0pt{\_vss\_llap{\Brown\docfile}\_kern7.5pt}\_hss}%
+ \_hskip\_hsize\_vbox to0pt{\_vss\_llap{\Brown\docfile}\_kern7.5pt}\_hss}%
\_let\_printfilename=\_relax
}
\_everytt={\_let\_printverblinenum=\_relax}
@@ -153,7 +153,7 @@
\_def\docfile{}
\_def\_printdoc #1 {\_par \_def\docfile{#1}%
\_everytt={\_ttshift=-15pt \_let\_printverblinenum=\_relax}%
- \_ea\_cod \input #1
+ \_ea\_cod \_input #1
\_everytt={\_let\_printverblinenum=\_relax}%
\_def\docfile{}%
}
diff --git a/macros/optex/base/fonts-select.opm b/macros/optex/base/fonts-select.opm
index 5dab510453..355a71a191 100644
--- a/macros/optex/base/fonts-select.opm
+++ b/macros/optex/base/fonts-select.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \fontfam {Fonts selection system <2021-05-23>} % preloaded in format
+\_codedecl \fontfam {Fonts selection system <2021-07-16>} % preloaded in format
\_doc -----------------------------
The variant selectors \^`\rm`, \^`\bf`, \^`\it`, \^`\bi`, \^`\tt`
@@ -16,7 +16,7 @@
`\_tryloadbf \_tenbf`. If the font context (font family, font size, features)
is not changed, then `\_tryloadbf` is `\relax` and `\_tenbf` font switcher selects
given font. If the font context is changed, then `\_tryloadbf` is re-defined (see
- \^`\_reloading` macro) to load new bold varinat of the font using \^`\_resizefont`
+ \^`\_reloading` macro) to load new bold variant of the font using \^`\_resizefont`
The loaded font is saved to `\_tenbf` switcher and `\_tryloadbf` returns
back to the `\relax` meaning. So, `\bf` macro loads
new font with current font context and then selects it by `\_tenbf`
@@ -31,8 +31,8 @@
family independence for `\tt` macro, see section~\ref[tt].
So, `\_tryloadtt` is defined constantly as \"loading `\tt` font" and it is
not re-defined to `\relax`. On the other hand, `\_tryloadtt` is
- re-defined in the \^`\initunifonts` macro or when used
- \~`\famvardef``\tt`.
+ re-defined in the \^`\initunifonts` macro or when
+ \~`\famvardef``\tt` is used.
\_cod -----------------------------
\_def\_reloading{\_loadf{rm}\_tenrm \_loadf{bf}\_tenbf \_loadf{it}\_tenit \_loadf{bi}\_tenbi}
@@ -46,8 +46,8 @@
\_doc ----------------------------
The Font Selection system allows to use \`\currvar`
- instead explicitly specified variant selector. The current variant
- is extracted from `\the\font` output which could be `\_ten<XX>` control
+ instead of an explicitly specified variant selector. The current variant
+ is extracted from `\the\font` output which could be the `\_ten<XX>` control
sequence. Then `\currvar` expands to `\_rm` or `\_it` etc.
\_cod ----------------------------
@@ -66,7 +66,7 @@
The <variant-name> is `rm` or `bf` or `it` or `bi` or `tt`.
The new <font-switch> is declared (roughly speaking) by:
\begtt \catcode`<=13
- \_font <font switch> = <fontname of>\_ten<variant-name> \_sizepec % in TFM mode
+ \_font <font switch> = <fontname of>\_ten<variant-name> \_sizespec % in TFM mode
\_font <font switch> = {\_fontnamegen} \_sizespec % in OTF mode
\endtt
The font is loaded by \`\_doresizefont``<font switch>`. This macro has
@@ -121,7 +121,7 @@
typesetting then it is set to a positive value.\nl
The `\_newfontloaded` should be defined for micro-typographic configuration of
fonts, for example. See
- \ulink[http://petr.olsak.net/optex/optex-tricks.html\#fontexpand]{OpTeX/ trick 0058}.
+ \ulink[http://petr.olsak.net/optex/optex-tricks.html\#fontexpand]{\OpTeX/ trick 0058}.
\_cod -----------------------------
\_def\_fontloaded #1{\_ifnum\_skewchar#1=-1 \_skewchar#1=-2 \_newfontloaded#1\_fi}
@@ -130,7 +130,7 @@
\_doc -----------------------------
\`\initunifonts` macro extends \LuaTeX's font capabalities,
in order to be able to load Unicode fonts. Unfortunately, this part of
- \OpTeX/ depends on `luaotfload` package, which adapts Con\TeX/t's generic
+ \OpTeX/ depends on the `luaotfload` package, which adapts Con\TeX/t's generic
font loader for plain \TeX/ and \LaTeX. `luaotfload` uses Lua functions
from \LaTeX's `luatexbase` namespace, we provide our own replacements.
Moreover, `\initunifont` switches with
@@ -146,6 +146,7 @@
\_directlua{%
require('luaotfload-main')
luaotfload.main()
+ optex_hook_into_luaotfload()
}%
\_gdef\_rfskipatX ##1" ##2\_relax{"##1"}%
\_global\_let \_doresizefont=\_doresizeunifont
@@ -169,7 +170,7 @@
be in the right font family context. The `\_currfamily` is set to the
`<Famselector>` by the `\<Famselector>` too, because `\<Famselector>`
must set the right font family context. The font family context is given by the current
- `\_currfamily` value and by the actual meaning of the \^`\_fontnamegen` macro.
+ `\_currfamily` value and by the current meaning of the \^`\_fontnamegen` macro.
The \`\_mathfaminfo` is saved for usage in the catalog.
\_cod -----------------------------
@@ -585,7 +586,7 @@ We distinguish between
In addition, \OpTeX/ defines \~`\tt` as variant selector
independent of chosen font family. It selects typewriter-like font.
* {\em font modifiers} are declared in a family (`\cond`, `\caps`) or are
- \"build in" (\^`\setfontsize``{<size spec>}`, \~`\setff{<features>}`).
+ \"built-in" (\^`\setfontsize``{<size spec>}`, \~`\setff{<features>}`).
They do appropriate change in the {\em font context} but do not select
the font.
* {\em family selectors} (for example `\Termes`, `\LMfonts`),
@@ -701,10 +702,10 @@ family selectors and defined font macros doing something with fonts.
variant selectors can be declared by \~`\famvardef` command. They select a
font dependent on the current font context, see section~\ref[famvardef].
The `\tt` selector is documented in section~\ref[tt].
-* Font modifiers are \"build in" or declared by \~`\moddef` command.
+* Font modifiers are \"built-in" or declared by \~`\moddef` command.
They do modifications in the font context but don't select any font.
\begitems
- * \"build-in" font modifiers are \^`\setfontsize` (see
+ * \"built-in" font modifiers are \^`\setfontsize` (see
section~\ref[setfontsize]), \~`\setff` (see section~\ref[setff]),
\~`\setfontcolor`, \~`\setletterspace` and \~`\setwordspace`
(see section~\ref[specff]). They are independent of font family.
@@ -995,7 +996,7 @@ all possibilities of extended `\font` primitive.
The \OpTeX/ format is initialized by `luatex` engine by default but
you can initialize it by `luahbtex` engine too. Then the harfbuzz library is
-ready to use for font rendering as an alternative to build-in font renderer
+ready to use for font rendering as an alternative to built-in font renderer
from Luaotfload. The harfbuzz library gives more features for rendering
Indic and Arabic scripts. But it is not used as default, you need to specify
`mode=harf` in the fontfeatures field when `\font` is used. Moreover, when
@@ -1010,6 +1011,7 @@ Luaotfload documentation for more information.
\endinput
+2021-07-16 \initunifonts: optex_hook_into_luaotfload added.
2021-05-23 concept of \_fontfeatures macro re-implemented
2021-05-02 simpler \_resizefont, better concept of doc, moving parts from fonts-resize
2021-04-22 \_ffonum introduced
diff --git a/macros/optex/base/graphics.opm b/macros/optex/base/graphics.opm
index 1adb444b4e..4c72528e48 100644
--- a/macros/optex/base/graphics.opm
+++ b/macros/optex/base/graphics.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \inspic {Graphics <2021-03-19>} % preloaded in format
+\_codedecl \inspic {Graphics <2021-07-16>} % preloaded in format
\_doc -----------------------------
\`\inspic` accepts old syntax `\inspic <filename><space>`
@@ -231,8 +231,8 @@
are parameters, they can be set by user in optional brackets `[...]`.
For example `\fcolor=\Red` does `\_let\_fcolorvalue=\Red` and it means
filling color.\nl
- The \`\_setflcolor` uses the \^`\_fillstroke` macro to separate filling
- color and drawing color.
+ The \`\_setflcolors` uses the \^`\_setcolor` macro to separate filling (non-stroking)
+ color and stroking color.
\_cod -----------------------------
\_newdimen \_lwidth
@@ -245,10 +245,9 @@
\_def\_touppervalue#1{\_ifx#1n\_let#1=N\_fi}
\_def\_setflcolors#1{% use only in a group
- \_def\_setcolor##1{##1}%
- \_def\_fillstroke##1##2{##1}%
+ \_def\_setcolor##1##2##3{##1 ##2}%
\_edef#1{\_fcolorvalue}%
- \_def\_fillstroke##1##2{##2}%
+ \_def\_setcolor##1##2##3{##1 ##3}%
\_edef#1{#1\_space\_lcolorvalue\_space}%
}
\_optdef\_inoval[]{\_vbox\_bgroup
@@ -260,9 +259,7 @@
\_advance\_hsize by-2\_hhkern \_advance\_hsize by-2\_roundness \_fi
\_setbox0=\_hbox\_bgroup\_bgroup \_aftergroup\_inovalA \_kern\_hhkern \_let\_next=%
}
-\_def\_inovalA{\_isnextchar\_colorstackpop\_inovalB\_inovalC}
-\_def\_inovalB#1{#1\_isnextchar\_colorstackpop\_inovalB\_inovalC}
-\_def\_inovalC{\_egroup % of \setbox0=\hbox\bgroup
+\_def\_inovalA{\_egroup % of \setbox0=\hbox\bgroup
\_ifdim\_vvkern=\_zo \_else \_ht0=\_dimexpr\_ht0+\_vvkern \_relax
\_dp0=\_dimexpr\_dp0+\_vvkern \_relax \_fi
\_ifdim\_hhkern=\_zo \_else \_wd0=\_dimexpr\_wd0+\_hhkern \_relax \_fi
@@ -290,9 +287,7 @@
\_touppervalue\_overlapmarginsvalue \_touppervalue\_shadowvalue
\_setbox0=\_hbox\_bgroup\_bgroup \_aftergroup\_incircleA \_kern\_hhkern \_let\_next=%
}
-\_def\_incircleA {\_isnextchar\_colorstackpop\_incircleB\_incircleC}
-\_def\_incircleB #1{#1\_isnextchar\_colorstackpop\_incircleB\_incircleC}
-\_def\_incircleC {\_egroup % of \setbox0=\hbox\bgroup
+\_def\_incircleA {\_egroup % of \setbox0=\hbox\bgroup
\_wd0=\_dimexpr \_wd0+\_hhkern \_relax
\_ht0=\_dimexpr \_ht0+\_vvkern \_relax \_dp0=\_dimexpr \_dp0+\_vvkern \_relax
\_ifdim \_ratiovalue\_dimexpr \_ht0+\_dp0 > \_wd0
@@ -319,6 +314,39 @@
\_public \inoval \incircle \ratio \lwidth \fcolor \lcolor \shadow \overlapmargins ;
\_doc -----------------------------
+ Just before defining shadows, which require special graphics states, we
+ define means for managing these graphics states. This is important, because
+ otherwise our use of `\pdfpageresources` register might clash with other
+ packages (TikZ) or even with our other usage (slides).
+
+ The macro \`\addextgstate``<PDF name> <PDF dictionary>` shall be used for
+ adding more graphics states. It must be used {\em after} `\dump`. First use
+ of it detects PGF/TikZ and either uses its mechanism or defines our own. Our
+ mechanism is very similar though -- use single `/ExtGState` dictionary for all
+ pages (`\pdfpageresources` just points to it).
+ \_cod -----------------------------
+
+\_def\_initpageresources{%
+ \_glet\_initpageresources=\_relax
+ \_ifcsname pgf@sys@addpdfresource@extgs@plain\_endcsname
+ % TikZ loaded
+ \_global\_slet{_addextgstate}{pgf@sys@addpdfresource@extgs@plain}%
+ \_else
+ % TikZ not loaded
+ \_pdfobj reserveobjnum% not to be used in iniTeX
+ \_xdef\_extgstatesobj{\_the\_pdflastobj}%
+ \_expanded{\_global\_pdfpageresources={/ExtGState \_extgstatesobj\_space 0 R}}%
+ \_global\_addto\_byehook{\_immediate\_pdfobj useobjnum\_extgstatesobj {<<\_extgstates>>}}%
+ \_gdef\_extgstates{}%
+ \_gdef\_addextgstate##1{\_xdef\_extgstates{\_extgstates\_space##1}}%
+ \_fi
+}
+% first initialize page resources, then execute new meaning of itself
+\_def\_addextgstate#1{\_initpageresources \_addextgstate{#1}}
+
+\_public \addextgstate ;
+
+ \_doc -----------------------------
A shadow effect is implemented here. The shadow is equal to the
silhouette of the given path in a gray-transparent color shifted by
\`\_shadowmoveto` vector and with blurred boundary.
@@ -333,27 +361,11 @@
\_def\_shadowmoveto{1.8 -2.5} % vector defines shifting layer (in bp)
\_def\_shadowb{1} % 2*shadowb = blurring area thickness
- \_doc -----------------------------
- The `\_pdfpageresources` primitive is used to define transparency.
- It does not work when used in a box. So, we use it at the beginning of
- the output routine. The modification of the output routine is done
- using \`\_insertshadowresources` only once when the shadow effect is used first.
- \_cod -----------------------------
-
\_def\_insertshadowresources{%
- \_global\_addto\_begoutput{\_setshadowresources}%
- \_xdef\_setshadowresources{%
- \_pdfpageresources{/ExtGState
- <<
- /op1 <</Type /ExtGState /ca \_shadowdarknessA>>
- /op2 <</Type /ExtGState /ca \_shadowdarknessB>>
- \_morepgresources
- >>
- }%
- }%
- \_global\_let\_insertshadowresources=\_relax
+ \_addextgstate{/op1 <</ca \_shadowdarknessA>>}%
+ \_addextgstate{/op2 <</ca \_shadowdarknessB>>}%
+ \_glet\_insertshadowresources=\_relax
}
-\_def\_morepgresources{}
\_doc -----------------------------
The \`\_doshadow``{<curve>}` does the shadow effect.
@@ -441,6 +453,7 @@ the \^`\transformbox{<transformation>}{\copy\mypic}`.
\_endinput
+2021-07-16: \inoval, \incircle are more simple, using attribitecolor features
2021-03-19: \inkinspic: pictures in subdirectories, bug fixed
2020-12-21: \puttext: \box0 in goup, bugfix
2020-04-12: \_public \clipinoval \clipincircle ; added, bug fixed
diff --git a/macros/optex/base/hi-syntax.opm b/macros/optex/base/hi-syntax.opm
index eb6d747914..040390db51 100644
--- a/macros/optex/base/hi-syntax.opm
+++ b/macros/optex/base/hi-syntax.opm
@@ -1,28 +1,27 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \hisyntax {Syntax highlithing of verbatim listings <2020-04-04>} % preloaded in format
+\_codedecl \hisyntax {Syntax highlighting of verbatim listings <2020-04-04>} % preloaded in format
\_doc -----------------------------
- The following macros `\replfromto` and `\replthis` manipulate with the
- verbatim text which has been read already and stored in the `\_tmpb` macro.
-
- The \`\replfromto` `{<from>}{<to>}{<what>}` finds first `<from>` then the
- first `<to>` following by `<from>` pattern and the
- `<text>` between them is packed to `#1`.
- Then `<from><text><to>` is replaced by `<what>`. The `<what>` parameter
- can use `#1` which is replaced by the `<text>`.
-
- The `\replfromto` continues by finding next `<from>`, then, next `<to>`
- repeatedly over the whole verbatim text. If the verbatim text is ended by
- opened `<from>` but not closing by `<to>` then `<to>` is appended to the
+ The macros `\replfromto` and `\replthis` manipulate the
+ verbatim text that is already stored in the `\_tmpb` macro.
+
+ \`\replfromto` `{<from>}{<to>}{<replacement>}` finds the first
+ occurrence of `<from>` and the first occurrence of `<to>` following it. The
+ `<text>` between them is packed into `#1` and available to `<replacement>`
+ which ultimately replaces `<text>`.
+
+ `\replfromto` continues by finding next `<from>`, then, next `<to>`
+ repeatedly over the whole verbatim text. If the verbatim text ends with
+ opening `<from>` but has no closing `<to>`, then `<to>` is appended to the
verbatim text automatically and the last part of the verbatim text is replaced too.
- First two parameters are expanded before usage of `\replfromto`. You can
+ The first two parameters are expanded before use of `\replfromto`. You can
use `\csstring\%` or something else here.
\_cod -----------------------------
\_def\_replfromto #1#2{\_edef\_tmpa{{#1}{#2}}\_ea\_replfromtoE\_tmpa}
-\_def\_replfromtoE#1#2#3{% #1=from #2=to #3=what to replace
+\_def\_replfromtoE#1#2#3{% #1=from #2=to #3=replacement
\_def\_replfrom##1#1##2{\_addto\_tmpb{##1}%
\_ifx\_end##2\_ea\_replstop \_else \_afterfi{\_replto##2}\_fi}%
\_def\_replto##1#2##2{%
@@ -36,7 +35,8 @@
\_def\_finrepl{}
\_doc -----------------------------
- The \`\replthis` `{<pattern>}{<what>}` replaces each `<pattern>` by `<what>`.
+ The \`\replthis` `{<pattern>}{<replacement>}` replaces each `<pattern>`
+ by `<replacement>`.
Both parameters of `\replthis` are expanded first.
\_cod -----------------------------
@@ -46,18 +46,18 @@
\_doc -----------------------------
The patterns `<from>`, `<to>` and `<pattern>` are not found when they are
- hidden in braces `{...}`. Example:
+ hidden in braces `{...}`. E.g.
\begtt
\replfromto{/*}{*/}{\x C{/*#1/*}}
\endtt
replaces all C comments by `\x C{...}`. The patterns inside `{...}` are
not used by next usage of `\replfromto` or `\replthis` macros.
- The \`\_xscan` macro does replacing `\x` by `\z` in the post-processing
- phase. The `\x <letter>{<text>}` expands to `\_xscan {<letter>}<text>^^J^`.
+ The \`\_xscan` macro replaces occurrences of `\x` by `\z` in the post-processing
+ phase. The construct `\x <letter>{<text>}` expands to `\_xscan {<letter>}<text>^^J^`.
If `#3` is `\_end` then it signals that something wrong happens, the
`<from>` was not terminated by legal `<to>` when `\replfromto` did work.
- We must to fix it by the \`\_xscanR` macro.
+ We must to fix this by using the \`\_xscanR` macro.
\_cod -----------------------------
\_def\_xscan#1#2^^J#3{\_ifx\_end#3 \_ea\_xscanR\_fi
@@ -66,7 +66,7 @@
\_def\_xscanR#1\_fi#2^{^^J}
\_doc -----------------------------
- The \`\hicolor` `<letter> <color>` defines `\_z<letter>{<text>}`
+ The \`\hicolor` `<letter> <color>` defines `\_z:<letter>{<text>}`
as `{<color><text>}`. It should be used in the context of
`\x <letter>{<text>}` macros.
\_cod -----------------------------
@@ -74,13 +74,13 @@
\_def\_hicolor #1#2{\_sdef{_z:#1}##1{{#2##1}}}
\_doc -----------------------------
- The \`\hisyntax``{<name>}` re-defines default \^`\_prepareverbdata``<macro><verbtext>`
- in order to it does more things:
+ \`\hisyntax``{<name>}` re-defines default \^`\_prepareverbdata``<macro><verbtext>`,
+ but in order to do it does more things:
It saves `<verbtext>` to `\_tmpb`, appends `\n` around spaces and
- `^^J` characters in pre-processing phase, it opens `hisyntax-<name>.opm`
- file if `\_hisyntax<name>` is not defined. Then `\_the\_isyntax<name>`
+ `^^J` characters in pre-processing phase, opens `hisyntax-<name>.opm`
+ file if `\_hisyntax<name>` is not defined. Then `\_the\_hisyntax<name>`
is processed. Finally, the post-processing phase is realized by setting
- appropriate values to `\x` and `\y` macros and doing
+ appropriate values to the `\x` and `\y` macros and doing
`\_edef\_tmpb{\_tmpb}`.
\_cod -----------------------------
@@ -132,15 +132,15 @@
The user can write
\begtt \adef/{\_csstring\\}
-\begtt \hisytnax{C}
+\begtt \hisyntax{C}
...
/endtt
\endtt
-and the code is colorized by C syntax.
-The user can write `\everytt={\hisyntax{C}}` and all verbatim listings are
+to colorize the code using C syntax.
+The user can also write `\everytt={\hisyntax{C}}` to have all verbatim listings
colorized.
-The \^`\hisyntax``{<name>}` reads the file `hisyntax-<name>.opm` where the
+\^`\hisyntax``{<name>}` reads the file `hisyntax-<name>.opm` where the
colorization is declared. The parameter `<name>` is case insensitive and the
file name must include it in lowercase letters. For example, the file
`hisyntax-c.opm` looks like this:
@@ -150,40 +150,40 @@ file name must include it in lowercase letters. For example, the file
\OpTeX/ provides `hisyntax-{c,python,tex,html}.opm` files.
You can take inspiration from these files and declare more languages.
-User can re-declare colors by `\hicolors={...}` This value has precedence
-before `\_hicolors<name>` values declared in the `hicolors-<name>.opm` file.
-What exactly to do: copy `\_hicolors<name>={...}`
+Users can re-declare colors by `\hicolors={...}` This value has precedence
+over `\_hicolors<name>` values declared in the `hicolors-<name>.opm` file.
+The steps are: copy `\_hicolors<name>={...}`
from `hicolors-<name>.opm` to your document,
-rename it as `\hicolors={...}` and do you own colors modifications.
+rename it to `\hicolors={...}` and do your own colors modifications.
Another way to set non-default colors is to declare
-`\newtoks\hicolors<name>` (without the `_` prefix) and set the colors palette here.
+`\newtoks\hicolors<name>` (without the `_` prefix) and set the color palette there.
It has precedence before `\_hicolors<name>` (with the `_` prefix) declared in
the `hicolors-<name>.opm` file.
This is useful when there are more hi-syntax languages used in one document.
\secl4 Notes for hi-syntax macro writers
-The file `hisyntax-<name>.opm` is read only once in the \TeX/ group.
+The file `hisyntax-<name>.opm` is read only once and in a \TeX/ group.
If there are definitions then they must be declared as global.
-The `hisyntax-<name>.opm` file must (globally) declare `\_hisyntax<name>` tokens string
-where the action over verbatim text is declared typically by `\replfromto` or
+The file `hisyntax-<name>.opm` must (globally) declare `\_hisyntax<name>` token list
+where the action over verbatim text is declared typically by using the `\replfromto` or
`\replthis` macros.
-The verbatim text is prepared by {\em pre-processing phase}, then the
-`\_hisyntax<name>` is applied and then {\em post-processing phase} does final
+The verbatim text is prepared by the {\em pre-processing phase}, then
+`\_hisyntax<name>` is applied and then the {\em post-processing phase} does final
corrections. Finally, the verbatim text is printed line by line.
The pre-processing phase does:
\begitems
-* Each space is replaced by {\visiblesp`\n\ \n`}, so `\n<word>\n` should be a pattern to
- finding whole words (no subwords). The `\n` control sequence is removed in
+* Each space is replaced by {\visiblesp`\n\ \n`}, so `\n<word>\n` is the pattern for
+ matching whole words (no subwords). The `\n` control sequence is removed in
the post-processing phase.
* Each end of line is represented by `\n^^J\n`.
* The `\_start` control sequence is added before the verbatim text and the `\_end` control
- sequence is appended to the end of the verbatim text. These control
- sequences are removed in the post-processing phase.
+ sequence is appended to the end of the verbatim text. Both are removed
+ in the post-processing phase.
\enditems
Special macros are working only in a group when processing the verbatim
@@ -191,33 +191,35 @@ text.
\begitems
-* `\n` means noting but it should be used as a boundary of words as mentioned above.
-* `\t` means a tabulator. It is prepared as `\n\t\n` because it can be at
- the boundary of a word.
-* `\x <letter>{<text>}` can be used as replacing text. Suppose the example
+* `\n` represents nothing but it should be used as a boundary of words as mentioned above.
+* `\t` represents a tabulator. It is prepared as `\n\t\n` because it can be at
+ the boundary word boundary.
+* `\x <letter>{<text>}` can be used as replacing text. Consider the example
\begtt
\replfromto{/*}{*/}{\x C{/*#1*/}}
\endtt
- This replaces all C comments `/*...*/` by `\x C{/*...*/}`. But the
- C comments may span more lines, i.e. the `^^J` should be inside it.
+ This replaces all C comments `/*...*/` by `\x C{/*...*/}`. But
+ C comments may span multiple lines, i.e. the `^^J` should be inside it.
- The macro `\x <letter>{<text>}` is replaced by one or more
- `\z <letter>{<text>}` in post-processing phase where each parameter `<text>` of
- `\z` keeps inside one line. Inside-line parameters are represented
- by `\x C{<text>}` and they are replaced to `\z C{<text>}` without any change.
+ The macro `\x <letter>{<text>}` is replaced by one or more occurrences of
+ `\z <letter>{<text>}` in the post-processing phase, each parameter `<text>` of
+ `\z` is from from a single line. Parameters not crossing line boundary are represented
+ by `\x C{<text>}` and replaced by `\z C{<text>}` without any change.
But:
\begtt \catcode`\<=13
- \x C{<text1>^^J<text3>^^J<text3>}
+ \x C{<text1>^^J<text2>^^J<text3>}
+ \endtt
is replaced by
+ \begtt \catcode`\<=13
\z C{<text1>}^^J\z C{<text2>}^^J\z C{<text3>}
\endtt
- The `\z <letter>{<text>}` is expanded to `\_z:<letter>{<text>}` and if
+ `\z <letter>{<text>}` is expanded to `\_z:<letter>{<text>}` and if
`\hicolor <letter> <color>` is declared then
`\_z:<letter>{<text>}` expands to `{<color><text>}`. So, required color is
- activated at all lines (separately) where C comment spans.
-* `\y {<text>}` is replaced by `\<text>` in the post processing phase. It should
- be used for macros without a parameter. You cannot use unprotected macros
+ activated for each line separately (e.g. for C comments spanning multiple lines).
+* `\y {<text>}` is replaced by `\<text>` in the post-processing phase. It should
+ be used for macros without a parameters. You cannot use unprotected macros
as replacement text before the post-processing phase, because the post-processing
- phase is based on expansion whole verbatim text.
+ phase is based on the expansion of the whole verbatim text.
\enditems
diff --git a/macros/optex/base/hisyntax-python.opm b/macros/optex/base/hisyntax-python.opm
index 6250eed0e3..12f7ebeeb4 100644
--- a/macros/optex/base/hisyntax-python.opm
+++ b/macros/optex/base/hisyntax-python.opm
@@ -69,8 +69,8 @@
}
\_gdef\_hipystrpre#1\x#2{\x#2{#1}\x#2}
-\_ifx\LightBlue\_undefined \_gdef\LightBlue {\_setcmykcolor{1 0.43 0 0}}\_fi
-\_ifx\Orange\_undefined \_gdef\Orange {\_setcmykcolor{0 0.64 1 0}}\_fi
+\_ifx\LightBlue\_undefined \_gdef\LightBlue {\_setcmykcolor{1 .43 0 0}}\_fi
+\_ifx\Orange\_undefined \_gdef\Orange {\_setcmykcolor{0 .64 1 0}}\_fi
\_endcode %------------------------------------------------
diff --git a/macros/optex/base/if-macros.opm b/macros/optex/base/if-macros.opm
index 462e496017..6c6318b841 100644
--- a/macros/optex/base/if-macros.opm
+++ b/macros/optex/base/if-macros.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \newif {Special if-macros, is-macros and loops <2021-02-03>} % preloaded in format
+\_codedecl \newif {Special if-macros, is-macros and loops <2021-08-02>} % preloaded in format
\_doc ----------------------------
\secc Classical \code{\\newif}
@@ -118,9 +118,9 @@
\_ea\_fornumB\_ea{\_the\_numexpr#3\_ea}\_ea{\_the\_numexpr#1}%
}
\_def\_fornumB #1#2{\_ifnum#1\_ifnum#2>0<\_else>\_fi \_frnum \_getforstack
- \_else \_ea\_fbody\_ea{\_the\_frnum}%
+ \_else \_afterfi{\_ea\_fbody\_ea{\_the\_frnum}%
\_immediateassignment\_global\_advance\_frnum by#2
- \_afterfi{\_fornumB{#1}{#2}}\_fi
+ \_fornumB{#1}{#2}}\_fi
}
\_def\fornum#1..#2\do{\_fornumstep 1:#1..#2\_do}
\_def\fornumstep#1:#2..#3\do{\_fornumstep #1:#2..#3\_do}
@@ -304,6 +304,7 @@
\_endcode
+2021-08-02 more robust \fornum: \fi moved by \afterfi
2021-02-03 public version of \loop and \foreach are \long
2020-05-22 \foreach, \fornum: all settings are global, independent on TeX group
2020-05-06 \isnextchar: \let\tmp=#1 -> \let\tmp= #1 (bug fix, #1 should be space)
diff --git a/macros/optex/base/makeindex.opm b/macros/optex/base/makeindex.opm
index 64ff2ca228..4de0d815fd 100644
--- a/macros/optex/base/makeindex.opm
+++ b/macros/optex/base/makeindex.opm
@@ -245,10 +245,10 @@
be whatever. It does not influence the sorting. \OpTeX/ uses comma at
this place for sorting indexes: `\,<word1> \,<word2> \,<word3> ...`.
- The actual language (chosen for hyphenation patterns) is used for
- sorting data. If the `\_sortinglang` macro
- is defined as `<iso-code>`(for example `\def\sortinglang{de}`)
- then this has precedence and actual language is not used.
+ The current language (chosen for hyphenation patterns) is used for
+ sorting data. If the macro \`\_sortinglang`
+ is defined as `<iso-code>` (for example `\def\sortinglang{de}`)
+ then this has precedence and current language is not used.
Moreover, if you specify \`\_asciisortingtrue` then ASCII
sorting will be processed and all language sorting data will be ignored.
\_cod -----------------------------
diff --git a/macros/optex/base/maketoc.opm b/macros/optex/base/maketoc.opm
index 8dfd821640..928618db6b 100644
--- a/macros/optex/base/maketoc.opm
+++ b/macros/optex/base/maketoc.opm
@@ -1,6 +1,6 @@
% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \maketoc {Macros for maketoc <2020-02-09>} % preloaded in format
+\_codedecl \maketoc {Macros for maketoc <2021-07-18>} % preloaded in format
\_doc ------------------------------------
\`\_Xtoc` `{<level>}{<type>}{<number>}{<o-title>}<title>` (in `.ref` file) reads
@@ -73,7 +73,8 @@
Parameters are `{<number>}{<title>}{<pageno>}`.
\_cod -----------------------------------
-\_sdef{_tocl:1}#1#2#3{\_nofirst\_bigskip \_bf\_llaptoclink{#1}{#2}\_hfill \_pgn{#3}\_tocpar}
+\_sdef{_tocl:1}#1#2#3{\_nofirst\_bigskip
+ \_bf\_llaptoclink{#1}{#2}\_nobreak\_hfill \_pgn{#3}\_tocpar}
\_sdef{_tocl:2}#1#2#3{\_llaptoclink{#1}{#2}\_tocdotfill \_pgn{#3}\_tocpar}
\_sdef{_tocl:3}#1#2#3{\_advance\_leftskip by\_iindent \_cs{_tocl:2}{#1}{#2}{#3}}
@@ -148,6 +149,7 @@
\_endcode
+2021-07-18 _tocl:1, \nobreak added, bug fixed
2021-02-09 \thisoutline implemented
2020-04-23 \_tocpar introduced (incompatible change)
2020-04-22 \_pg -> \_pgn (incompatible change)
diff --git a/macros/optex/base/math-macros.opm b/macros/optex/base/math-macros.opm
index 8a956ee2d0..83d3c5ab51 100644
--- a/macros/optex/base/math-macros.opm
+++ b/macros/optex/base/math-macros.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \sin {Math macros plus mathchardefs <2021-04-25>} % preloaded in format
+\_codedecl \sin {Math macros plus mathchardefs <2021-08-02>} % preloaded in format
\_doc -----------------------------
The category code of the character `_` remains as the letter (11) and the mathocode
@@ -1059,14 +1059,15 @@
\_def\_mathbox#1{{\_mathstyles{\_hbox{%
\_ifnum\_stylenum<2 \_everymath{\_currstyle}%
\_else
- \_ifnum\_stylenum=2 \_def\_textmff{+ssty=0;}\_fi
- \_ifnum\_stylenum=3 \_def\_textmff{+ssty=1;}\_def\_scriptmff{+ssty=1;}\_fi
+ \_ifnum\_stylenum=2 \_def\_textmff{ssty=1;}\_fi
+ \_ifnum\_stylenum=3 \_def\_textmff{ssty=2;}\_def\_scriptmff{ssty=2;}\_fi
\_typoscale[\_dobystyle{}{}{700}{500}/]\_fi #1}}}%
}
\_public \mathbox ;
\_endcode %---------------------------------------------------
+2021-08-02 ssty fontfeatures rewritten
2021-04-25 \triangleright: typo fixed
2021-03-22 \(l)eqalignno: \hbox instead \llap, \rlap (\par error suppressed)
2021-03-19 allow text mode \{ and \}
diff --git a/macros/optex/base/math-unicode.opm b/macros/optex/base/math-unicode.opm
index e9ec87f30f..eaa0e72fbf 100644
--- a/macros/optex/base/math-unicode.opm
+++ b/macros/optex/base/math-unicode.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \loadmath {Unicode Math fonts <2021-04-05>} % preloaded in format
+\_codedecl \loadmath {Unicode Math fonts <2021-08-16>} % preloaded in format
\_doc -----------------------------
\`\loadmath` `{<Unicode-math font>}` loads the given font. It does:
@@ -85,9 +85,8 @@
\_setunimathdimens
}%
\_def\_setunimathdimens{% PlainTeX sets these dimens for 10pt size only:
- \_delimitershortfall=0.5\_fontdimen6\_textfont3
- \_nulldelimiterspace=0.12\_fontdimen6\_textfont3
- \_scriptspace=0.05\_fontdimen6\_textfont3
+ \_delimitershortfall=0.5\_fontdimen6\_textfont1
+ \_nulldelimiterspace=0.12\_fontdimen6\_textfont1
\_setbox0=\_hbox{\_everymath{}$\_fam1\_displaystyle{0\_atop0}$}%
\_Umathfractiondelsize\_displaystyle = \_dimexpr(\_ht0-\_Umathaxis\_displaystyle)*2\_relax
\_setbox0=\_box\_voidbox
@@ -111,18 +110,21 @@
\endtt
\`\_loadumathfamily` `<number> {<font>}{<font features>}`
- loads the given Unicode-math fonts in three sizes given by the
- \^`\setmathsizes` macro and sets it as the math family `<number>`.
+ loads the given Unicode-math fonts in three sizes
+ using single <font> with different `mathsize=1,2,3` font features.
+ The math font family is set with given `<number>`.
The `<font features>` are added to the default
- \`\_mfontfeatures` and to the size-dependent features `+ssty=0`
- if script size is asked or `+ssty=1` if scriptscriptsize is asked.
- If the math family 1 is loaded then the family 2 and 3 are set by the same
- font because \TeX/ needs to read dimension information about generating
- math formulae from these three math families. All information needed by
- \TeX/ is collected in single Unicode-math font.\nl
+ \`\_mfontfeatures` and to the size-dependent features `ssty=1`
+ if script size is asked or `ssty=2` if scriptscriptsize is asked.\nl
+ \`\_mparams``<number>` inserts additional font feature `nomathparam`
+ if the <number> of the family is greater than 3. Lua\TeX/ sets math
+ parameters (thickness of fraction rules etc., see section 7.4 in Lua\TeX/
+ documentation) repeatedly from loaded math
+ fonts if `nomathparam` is not given. We want to load these parameters only
+ from fonts at families 0--3 (and actually we are using only family 1 as main math font).\nl
The \^`\_corrmsize` `<factor><space>` can be used just before
`\_loadumathfamily`, see section~\ref[math-preload] for more information.\nl
- The \`\_textmff`, \`\_scriptmff` and \`\_sscriptmff` are additional font
+ The \`\_textmff`, \`\_scriptmff` and \`\_sscriptmff` are font
features for text, script and sscript sizes respectively. They are
locally re-defined in \^`\mathbox` macro.
\_cod -----------------------------
@@ -131,16 +133,15 @@
\_def\_mfontfeatures{mode=base;script=math;}
\_def\_loadumathfamily #1 #2#3 {%
- \_edef\_optsizesave{\_the\_optsize}%
- \_optsize=\_sizemtext \_font\_mF=\_umathname{#2}{\_textmff #3} at\_optsize
- \_textfont#1=\_mF \_ifnum#1=1 \_textfont2=\_mF \_textfont3=\_mF \_fi
- \_optsize=\_sizemscript \_font\_mF=\_umathname{#2}{\_scriptmff #3} at\_optsize
- \_scriptfont#1=\_mF \_ifnum#1=1 \_scriptfont2=\_mF \_scriptfont3=\_mF \_fi
- \_optsize=\_sizemsscript \_font\_mF=\_umathname{#2}{\_sscriptmff #3} at\_optsize
- \_scriptscriptfont#1=\_mF \_ifnum#1=1 \_scriptscriptfont2=\_mF \_scriptscriptfont3=\_mF \_fi
- \_optsize=\_optsizesave \_ptmunit=\_ptunit
+ \_font\_mF=\_umathname{#2}{\_textmff \_mparams{#1}#3} at\_sizemtext \_textfont #1=\_mF
+ \_font\_mF=\_umathname{#2}{\_scriptmff \_mparams{#1}#3} at\_sizemtext \_scriptfont #1=\_mF
+ \_font\_mF=\_umathname{#2}{\_sscriptmff\_mparams{#1}#3} at\_sizemtext \_scriptscriptfont#1=\_mF
+ \_ptmunit=\_ptunit
}
-\_def\_textmff{} \_def\_scriptmff{+ssty=0;} \_def\_sscriptmff{+ssty=1;}
+\_def\_textmff {ssty=0;mathsize=1;}
+\_def\_scriptmff {ssty=1;mathsize=2;}
+\_def\_sscriptmff{ssty=2;mathsize=3;}
+\_def\_mparams#1{\_ifnum#1>3 nomathparam;\_fi}
\_doc -----------------------------
Unicode math font includes all typical math alphabets together, user needs not to
@@ -258,6 +259,9 @@ the section~\ref[math-macros].
\_endinput
+2021-08-16 \_loadumathfamily simplified, used mathsize= font feature.
+2021-08-16 nomathparam font feature used for families > 3 (bug fixed).
+2021-08-02 ssty fontfeatures rewritten; fam2, fam3 unused, \scriptspace not set
2021-04-04 \_setunimathdimens: \setbox0=\box\voidbox added
2021-03-09 \_setunimathdimes: \_begin/end/group instead {}, bug fixed
2021-02-15 \_textmff, \_scriptmff and \_sscriptmff introduced
diff --git a/macros/optex/base/optex.ini b/macros/optex/base/optex.ini
index be081adac8..e51a8824df 100644
--- a/macros/optex/base/optex.ini
+++ b/macros/optex/base/optex.ini
@@ -21,7 +21,7 @@
% OpTeX version
-\def\optexversion{1.03 Jun.2021}
+\def\optexversion{1.04 Aug.2021}
\def\fmtname{OpTeX}
\let\fmtversion=\optexversion
@@ -95,13 +95,13 @@
\_everyjob = {%
\_message{This is OpTeX (Olsak's Plain TeX), version <\optexversion>^^J}%
- \_mathchardef\_fnotestack=\_pdfcolorstackinit page {0 g 0 G}%
\_directlua{lua.bytecode[1]()}% load OpTeX's Lua code
\_mathsbon % replaces \int_a^b to \int _a^b
\_inputref % inputs \jobname.ref if exists
}
-\_dump
+\dump % You can redefine \dump if additional macros are needed. Example:
+ % \let\dump=\relax \input optex.ini \input mymacros \_dump
\_endcode % ------------------------------
diff --git a/macros/optex/base/optex.lua b/macros/optex/base/optex.lua
index 3738acaefb..5114ea21e9 100644
--- a/macros/optex/base/optex.lua
+++ b/macros/optex/base/optex.lua
@@ -2,7 +2,11 @@
-- The basic lua functions and declarations used in \OpTeX/ are here
--- GENERAL
+-- \medskip\secc General^^M
+--
+-- Define namespace where some \OpTeX/ functions will be added.
+
+optex = optex or {}
-- Error function used by following functions for critical errors.
local function err(message)
@@ -15,7 +19,17 @@ function registernumber(name)
return token.create(name).index
end
--
--- ALLOCATORS
+-- MD5 hash of given file.
+function mdfive(file)
+ local fh = io.open(file, "rb")
+ if fh then
+ local data = fh:read("*a")
+ fh:close()
+ tex.print(md5.sumhexa(data))
+ end
+end
+--
+-- \medskip\secc[lua-alloc] Allocators^^M
alloc = alloc or {}
--
-- An attribute allocator in Lua that cooperates with normal \OpTeX/ allocator.
@@ -32,10 +46,20 @@ function alloc.new_attribute(name)
end
end
--
+-- Allocator for Lua functions ("pseudoprimitives"). It passes variadic
+-- arguments (\"`...`") like `"global"` to `token.set_lua`.
+local function_table = lua.get_functions_table()
+local luafnalloc = 0
+function define_lua_command(csname, fn, ...)
+ luafnalloc = luafnalloc + 1
+ token.set_lua(csname, luafnalloc, ...) -- WARNING: needs LuaTeX 1.08 (2019) or newer
+ function_table[luafnalloc] = fn
+end
+--
-- `provides_module` is needed by older version of luaotfload
provides_module = function() end
--
--- CALLBACKS
+-- \medskip\secc[callbacks] Callbacks^^M
callback = callback or {}
--
-- Save `callback.register` function for internal use.
@@ -181,6 +205,7 @@ end
-- callbacks, that are called manually by user using `call_callback` or for
-- standard callbacks that have default functions -- like `mlist_to_hlist` (see
-- below).
+local call_callback
function callback.add_to_callback(name, fn, description)
if user_callbacks[name] or callback_functions[name] or default_functions[name] then
-- either:
@@ -193,9 +218,9 @@ function callback.add_to_callback(name, fn, description)
-- register a proxy function as a real callback. Assert, so we know
-- when things break, like when callbacks get redefined by future
-- luatex.
- assert(callback_register(name, function(...)
- return callback.call_callback(name, ...)
- end))
+ callback_register(name, function(...)
+ return call_callback(name, ...)
+ end)
else
err("cannot add to callback '"..name.."' - no such callback exists")
end
@@ -307,6 +332,7 @@ function callback.call_callback(name, ...)
end
return not changed or head
end
+call_callback = callback.call_callback
--
-- Create \"virtual" callbacks `pre/post_mlist_to_hlist_filter` by setting
-- `mlist_to_hlist` callback. The default behaviour of `mlist_to_hlist` is kept by
@@ -317,7 +343,7 @@ callback.create_callback("pre_mlist_to_hlist_filter", "list")
callback.create_callback("post_mlist_to_hlist_filter", "reverselist")
callback_register("mlist_to_hlist", function(head, ...)
-- pre_mlist_to_hlist_filter
- local new_head = callback.call_callback("pre_mlist_to_hlist_filter", head, ...)
+ local new_head = call_callback("pre_mlist_to_hlist_filter", head, ...)
if new_head == false then
node.flush_list(head)
return nil
@@ -326,9 +352,9 @@ callback_register("mlist_to_hlist", function(head, ...)
end
-- mlist_to_hlist means either added functions or standard luatex behavior
-- of node.mlist_to_hlist (handled by default function)
- head = callback.call_callback("mlist_to_hlist", head, ...)
+ head = call_callback("mlist_to_hlist", head, ...)
-- post_mlist_to_hlist_filter
- new_head = callback.call_callback("post_mlist_to_hlist_filter", head, ...)
+ new_head = call_callback("post_mlist_to_hlist_filter", head, ...)
if new_head == false then
node.flush_list(head)
return nil
@@ -338,6 +364,27 @@ callback_register("mlist_to_hlist", function(head, ...)
return head
end)
--
+-- For preprocessing boxes just before shipout we define custom callback. This
+-- is used for coloring based on attributes.
+-- There is however a challenge - how to call this callback? We could redefine
+-- `\shipout` and `\pdfxform` (which both run `ship_out` procedure internally),
+-- but they would lose their primtive meaning – i.e. `\immediate` wouldn't work
+-- with `\pdfxform`. The compromise is to require anyone to run
+-- \`\_preshipout``<destination box number><box specification>` just before
+-- `\shipout` or `\pdfxform` if they want to call `pre_shipout_filter` (and
+-- achieve colors and possibly more).
+callback.create_callback("pre_shipout_filter", "list")
+
+local tex_setbox = tex.setbox
+local token_scanint = token.scan_int
+local token_scanlist = token.scan_list
+define_lua_command("_preshipout", function()
+ local boxnum = token_scanint()
+ local head = token_scanlist()
+ head = call_callback("pre_shipout_filter", head)
+ tex_setbox(boxnum, head)
+end)
+--
-- Compatibility with \LaTeX/ through luatexbase namespace. Needed for
-- luaotfload.
luatexbase = {
@@ -352,3 +399,206 @@ luatexbase = {
call_callback = callback.call_callback,
callbacktypes = {}
}
+--
+-- `\tracingmacros` callback registered.
+-- Use `\tracingmacros=3` or `\tracingmacros=4` if you want to see the result.
+callback.add_to_callback("input_level_string", function(n)
+ if tex.tracingmacros > 3 then
+ return "[" .. n .. "] "
+ elseif tex.tracingmacros > 2 then
+ return "~" .. string.rep(".",n)
+ else
+ return ""
+ end
+end, "_tracingmacros")
+--
+-- \medskip\secc[lua-colors] Handling of colors using attributes^^M
+--
+-- Because \LuaTeX/ doesn't do anything with attributes, we have to add meaning
+-- to them. We do this by intercepting \TeX/ just before it ships out a page and
+-- inject PDF literals according to attributes.
+--
+local node_id = node.id
+local glyph_id = node_id("glyph")
+local rule_id = node_id("rule")
+local glue_id = node_id("glue")
+local hlist_id = node_id("hlist")
+local vlist_id = node_id("vlist")
+local disc_id = node_id("disc")
+local token_getmacro = token.get_macro
+
+local direct = node.direct
+local todirect = direct.todirect
+local tonode = direct.tonode
+local getfield = direct.getfield
+local setfield = direct.setfield
+local getwhd = direct.getwhd
+local getid = direct.getid
+local getlist = direct.getlist
+local setlist = direct.setlist
+local getleader = direct.getleader
+local getattribute = direct.get_attribute
+local insertbefore = direct.insert_before
+local copy = direct.copy
+local traverse = direct.traverse
+local one_bp = tex.sp("1bp")
+local string_format = string.format
+--
+-- The attribute for coloring is allocated in `colors.opm`
+local color_attribute = registernumber("_colorattr")
+--
+-- Now we define function which creates whatsit nodes with PDF literals. We do
+-- this by creating a base literal, which we then copy and customize.
+--
+local pdf_base_literal = direct.new("whatsit", "pdf_literal")
+setfield(pdf_base_literal, "mode", 2) -- direct mode
+local function pdfliteral(str)
+ local literal = copy(pdf_base_literal)
+ setfield(literal, "data", str)
+ return literal
+end
+optex.directpdfliteral = pdfliteral
+--
+-- The function {\Red`colorize`}`(head, current, current_stroke)` goes through
+-- a node list and injects PDF literals according to attributes.
+-- Its arguments are the head of the list to be colored and the current color
+-- for fills and strokes. It is a recursive function – nested
+-- horizontal and vertical lists are handled in the same way. Only the
+-- attributes of “content” nodes (glyphs, rules, etc.) matter. Users drawing
+-- with PDF literals have to set color themselves.
+--
+-- Whatsit node with color setting PDF literal is injected only when a
+-- different color is needed. Our injection does not care about boxing levels,
+-- but this isn't a problem, since PDF literal whatsits just instruct the
+-- `\shipout` related procedures to emit the literal.
+--
+-- We also set the stroke and non-stroke colors separately. This is because
+-- stroke color is not always needed – \LuaTeX/ itself only uses it for rules
+-- whose one dimension is less than or equal to 1 bp and for fonts whose `mode`
+-- is set to 1 (outline) or 2 (outline and fill). Catching these cases is a
+-- little bit involved. For example rules are problematic, because at this
+-- point their dimensions can still be running ($-2^{30}$) – they may or may
+-- not be below the one big point limit. Also the text direction is involved.
+-- Because of the negative value for running dimensions the simplistic check,
+-- while not fully correct, should produce the right results. We currently
+-- don't check for the font mode at all.
+--
+-- Leaders (represented by glue nodes with leader field) are not handled fully.
+-- They are problematic, because their content is repeated more times and it
+-- would have to be ensured that the coloring would be right even for e.g.
+-- leaders that start and end on a different color. We came to conclusion that
+-- this is not worth, hence leaders are handled just opaquely and only the
+-- attribute of the glue node itself is checked. For setting different colors
+-- inside leaders, raw PDF literals have to be used.
+--
+-- We use the `node.direct` way of working with nodes. This is less safe, and
+-- certainly not idiomatic Lua, but faster and codewise more close to the way
+-- \TeX/ works with nodes.
+local function is_color_needed(head, n, id, subtype) -- returns non-stroke, stroke color needed
+ if id == glyph_id then
+ return true, false
+ elseif id == glue_id then
+ n = getleader(n)
+ if n then
+ id = getid(n)
+ if id == hlist_id or id == vlist_id then
+ -- leaders with hlist/vlist get single color
+ return true, false
+ else -- rule
+ -- stretchy leaders with rules are tricky,
+ -- just set both colors for safety
+ return true, true
+ end
+ end
+ elseif id == rule_id then
+ local width, height, depth = getwhd(n)
+ if width <= one_bp or height + depth <= one_bp then
+ -- running (-2^30) may need both
+ return true, true
+ end
+ return true, false
+ end
+ return false, false
+end
+
+local function colorize(head, current, current_stroke)
+ for n, id, subtype in traverse(head) do
+ if id == hlist_id or id == vlist_id then
+ -- nested list, just recurse
+ local list = getlist(n)
+ list, current, current_stroke = colorize(list, current, current_stroke)
+ setlist(n, list)
+ elseif id == disc_id then
+ -- at this point only no-break (replace) list is of any interest
+ local replace = getfield(n, "replace")
+ if replace then
+ replace, current, current_stroke = colorize(replace, current, current_stroke)
+ setfield(n, "replace", replace)
+ end
+ else
+ local nonstroke_needed, stroke_needed = is_color_needed(head, n, id, subtype)
+ local new = getattribute(n, color_attribute) or 0
+ local newcolor = nil
+ if current ~= new and nonstroke_needed then
+ newcolor = token_getmacro("_color:"..new)
+ current = new
+ end
+ if current_stroke ~= new and stroke_needed then
+ local stroke_color = token_getmacro("_color-s:"..current)
+ if stroke_color then
+ if newcolor then
+ newcolor = string_format("%s %s", newcolor, stroke_color)
+ else
+ newcolor = stroke_color
+ end
+ current_stroke = new
+ end
+ end
+ if newcolor then
+ head = insertbefore(head, n, pdfliteral(newcolor))
+ end
+ end
+ end
+ return head, current, current_stroke
+end
+--
+-- Colorization should be run just before shipout. We use our custom callback
+-- for this. See the definition of `pre_shipout_filter` for details on
+-- limitations.
+callback.add_to_callback("pre_shipout_filter", function(list)
+ -- By setting initial color to -1 we force initial setting of color on
+ -- every page. This is useful for transparently supporting other default
+ -- colors than black (although it has a price for each normal document).
+ local list = colorize(todirect(list), -1, -1)
+ return tonode(list)
+end, "_colors")
+--
+-- We also hook into `luaotfload`'s handling of color. Instead of the default
+-- behavior (inserting colorstack whatsits) we set our own attribute. The hook
+-- has to be registered {\em after} `luaotfload` is loaded.
+function optex_hook_into_luaotfload()
+ if not luaotfload.set_colorhandler then
+ return -- old luaotfload, colored fonts will be broken
+ end
+ local setattribute = direct.set_attribute
+ local token_setmacro = token.set_macro
+ local color_count = registernumber("_colorcnt")
+ local tex_getcount, tex_setcount = tex.getcount, tex.setcount
+ luaotfload.set_colorhandler(function(head, n, rgbcolor) -- rgbcolor = "1 0 0 rg"
+ local attr = tonumber(token_getmacro("_color::"..rgbcolor))
+ if not attr then
+ attr = tex_getcount(color_count)
+ tex_setcount(color_count, attr + 1)
+ local strattr = tostring(attr)
+ token_setmacro("_color::"..rgbcolor, strattr)
+ token_setmacro("_color:"..strattr, rgbcolor)
+ -- no stroke color set
+ end
+ setattribute(n, color_attribute, attr)
+ return head, n
+ end)
+end
+
+ -- History:
+ -- 2021-07-16 support for colors via attributes added
+ -- 2020-11-11 optex.lua released
diff --git a/macros/optex/base/others.opm b/macros/optex/base/others.opm
index 6ff15d4332..a6dc2064eb 100644
--- a/macros/optex/base/others.opm
+++ b/macros/optex/base/others.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \uv {Miscenaleous <2020-05-22>} % preloaded in format
+\_codedecl \uv {Miscenaleous <2020-08-02>} % preloaded in format
\_doc ----------------------------
\`\useOpTeX` and \`\useoptex` are declared as `\relax`.
@@ -92,6 +92,7 @@
\_def\_lipsumload{{%
\_setbox0=\_vbox{\_tmpnum=0 % vertical mode during \input lipsum.ltd.tex
\_def\ProvidesFile##1[##2]{}%
+ \_def\SetLipsumLanguage##1{}%
\_def\NewLipsumPar{\_incr\_tmpnum \_sxdef{_lip:\_the\_tmpnum}}%
\_opinput {lipsum.ltd.tex}%
\_global\_let\_lipsumload=\_empty
@@ -101,6 +102,7 @@
\_endcode
+2021-08-02 \SetLipsumLanguage added, fix for new lipusm version
2021-01-04 \lipsumtext introduced
2020-05-22 \lipsum uses \fornum (expandable after first usage)
2020-04-02 released
diff --git a/macros/optex/base/output.opm b/macros/optex/base/output.opm
index 5bb93c2477..ffe41c5387 100644
--- a/macros/optex/base/output.opm
+++ b/macros/optex/base/output.opm
@@ -1,13 +1,17 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \nopagenumbers {Output routine <2021-02-25>} % preloaded in format
+\_codedecl \nopagenumbers {Output routine <2021-07-16>} % preloaded in format
\_doc -----------------------------
- \`\_optexoutput` is the default output routine. You can create another...
+ \`\_optexoutput` is the default output routine. You can create another...\nl
+ The \^`\_preshipout``<destination box number><box specification>` used
+ here behaves similarly like `\setbox` but it does not only copy the box
+ contents but adds the color literals depending on used attributes.
+ It is defined using lua code, see section~\ref[lua].
\_cod -----------------------------
\_output={\_optexoutput}
-\_def \_optexoutput{\_begoutput \_shipout\_completepage \_endoutput}
+\_def \_optexoutput{\_begoutput \_preshipout0\_completepage \_shipout\_box0 \_endoutput}
\_doc -----------------------------
Default \`\_begoutput` and \`\_endoutput` is defined.
@@ -58,24 +62,19 @@
The \`\_completepage` is similar to what plain \TeX/ does in its output routine.
New is only \`\_backgroundbox`. It is `\vbox` with zero height with its
contents (from \^`\pgbackground`) extended down. It is shifted directly to the
- left-upper corner of the paper.
-
- The \`\_ensureblack` sets the typesetting of its parameter locally to `\Black`
- color. We needn't do this if colors are never used in the document. So,
- the default value of the `\_ensureblack` macro is empty. But the first usage of
- color macros in the document re-defines `\_ensureblack`.
- See the section~\ref[colors] for more details.
+ left-upper corner of the paper.\nl
+ The \^`\_resetcolor` used here means that all newly created texts in
+ output routine (texts used in headline, footline) have default color.
\_cod -----------------------------
\_def\_completepage{\_vbox{%
+ \_resetcolor
\_istoksempty \_pgbackground
- \_iffalse \_ensureblack{\_backgroundbox{\_the\_pgbackground}}\_nointerlineskip \_fi
- \_ensureblack{\_makeheadline}%
+ \_iffalse \_backgroundbox{\_the\_pgbackground}\_nointerlineskip \_fi
+ \_makeheadline
\_vbox to\_vsize {\_boxmaxdepth=\_maxdepth \_pagecontents}% \pagebody in plainTeX
- \_ensureblack{\_makefootline}}%
+ \_makefootline}%
}
-\_def \_ensureblack #1{#1} % will be re-defined by color macros
-\_let \_openfnotestack = \_relax % will be re-defined by color macros
\_def \_backgroundbox #1{\_moveleft\_hoffset\_vbox to\_zo{\_kern-\_voffset #1\_vss}}
\_doc -----------------------------
@@ -102,17 +101,16 @@
\_doc -----------------------------
The \`\_pagecontents` is similar as in plain \TeX/. The only differnece is
- that the \`\_pagedest` is inserted at the top of `\_pagecontents` and
- \^`\_ensureblack` is applied to the \^`\topins` and \^`\footins` material.\nl
+ that the \`\_pagedest` is inserted at the top of `\_pagecontents`.\nl
The \`\_footnoterule` is defined here.
\_cod -----------------------------
\_def\_pagecontents{\_pagedest % destination of the page
- \_ifvoid\_topins \_else \_ensureblack{\_unvbox\_topins}\_fi
+ \_ifvoid\_topins \_else \_unvbox\_topins\_fi
\_dimen0=\_dp255 \_unvbox255 % open up \box255
\_ifvoid\_footins \_else % footnote info is present
\_vskip\_skip\_footins
- \_ensureblack{\_footnoterule \_openfnotestack \_unvbox\_footins}\_fi
+ \_footnoterule \_unvbox\_footins\_fi
\_kern-\_dimen0 \_vskip \_pgbottomskip
}
\_def \_pagedest {{\_def\_destheight{25pt}\_dest[pg:\_the\_gpageno]}}
@@ -157,7 +155,7 @@
\_def \_opfootnote #1#2{\_insert\_footins\_bgroup
\_interlinepenalty=\_interfootnotelinepenalty
\_leftskip=\_zo \_rightskip=\_zo \_spaceskip=\_zo \_xspaceskip=\_zo \_relax
- \_let\_colorstackcnt=\_fnotestack % special color stack for footnotes
+ \_resetcolor
#1\_relax % local settings used by \fnote macro
\_splittopskip=\_ht\_strutbox % top baseline for broken footnotes
\_splitmaxdepth=\_dp\_strutbox \_floatingpenalty=20000
@@ -165,10 +163,8 @@
\_isnextchar \_bgroup
{\_bgroup \_aftergroup\_vfootA \_afterassignment\_ignorespaces \_let\_next=}{\_vfootB}%
}
-\_def\_vfootA{\_unskip\_strut\_isnextchar\_colorstackpop\_closefncolor\_vfootF}
-\_def\_vfootB #1{#1\_unskip\_strut\_vfootF}
-\_def\_vfootF{\_egroup} % close \_insert\_footins\_bgroup
-\_def\_closefncolor#1{#1\_isnextchar\_colorstackpop\_closefncolor\_vfootF}
+\_def\_vfootA{\_unskip\_strut\_egroup}
+\_def\_vfootB #1{#1\_unskip\_strut\_egroup}
\_def \_footstrut {\_vbox to\_splittopskip{}}
\_skip\_footins=\_bigskipamount % space added when footnote is present
\_count\_footins=1000 % footnote magnification factor (1 to 1)
@@ -190,7 +186,7 @@
\_skip\_topins=\_zoskip % no space added when a topinsert is present
\_count\_topins=1000 % magnification factor (1 to 1)
\_dimen\_topins=\_maxdimen % no limit per page
-\_def \_oins {\_par \_begingroup\_setbox0=\_vbox\_bgroup} % start a \_vbox
+\_def \_oins {\_par \_begingroup\_setbox0=\_vbox\_bgroup\_resetcolor} % start a \_vbox
\_def \_endinsert {\_par\_egroup % finish the \_vbox
\_ifumid \_dimen0=\_ht0 \_advance\_dimen0 by\_dp0 \_advance\_dimen0 by\_baselineskip
\_advance\_dimen0 by\_pagetotal \_advance\_dimen0 by-\_pageshrink
@@ -214,11 +210,11 @@
\_fontdef\_draftfont{\_setfontsize{at10pt}\_bf}%
\_global\_let\_draftfont=\_draftfont
}
-\_def \_draftbox #1{\_setbox0=\_hbox{#1}%
+\_def \_draftbox #1{\_setbox0=\_hbox{\_setgreycolor{.8}#1}%
\_kern.5\_vsize \_kern\_voffset \_kern4.5\_wd0
\_hbox to0pt{\_kern.5\_xhsize \_kern\_hoffset \_kern-2\_wd0
\_pdfsave \_pdfrotate{55}\_pdfscale{10}{10}%
- \_hbox to0pt{\_localcolor\_setgreycolor{.8}\_box0\_hss}%
+ \_hbox to0pt{\_box0\_hss}%
\_pdfrestore
\_hss}%
}
@@ -261,6 +257,7 @@ The output routine \^`\_optexoutput` is similar as in plain \TeX. It does:
\_endinput
+2021-07-16 output routine supports colors via attributes
2021-02-25 \_draftbox improved
2021-02-15 \_advance -> \_decr
2020-05-12 \vfootB: \uskip -> \unskip bug fixed
diff --git a/macros/optex/base/parameters.opm b/macros/optex/base/parameters.opm
index e03bef6ef3..5379617d6c 100644
--- a/macros/optex/base/parameters.opm
+++ b/macros/optex/base/parameters.opm
@@ -58,7 +58,7 @@
\_doc -----------------------------
\secc Plain \TeX/ registers
- Declared registers used in plain \TeX/
+ Allocate registers that are used just like in plain \TeX/.
\_cod -----------------------------
% We also define special registers that function like parameters:
@@ -100,14 +100,14 @@
\_normalbaselines % baseline setting, 10 pt font size
\_doc -----------------------------
- Different values than in plain \TeX/ have the following primitive registers.
+ The following primitive registers have different values than in plain \TeX/.
We prohibit orphans, set more information for tracing boxes, set page origin
to the upper left corner of the paper (no at 1\,in, 1\,in coordinates)
- and set default page dimensions as A4, no letter.
+ and set default page dimensions as A4, not letter.
\_cod -----------------------------
-\_emergencystretch=20pt % we want to use third pass of paragraph building algoritmh
- % we need not keep the compatibility with old documents
+\_emergencystretch=20pt % we want to use third pass of paragraph building algorithm
+ % we don't need compatibility with old documents
\_clubpenalty=10000 % after first line of paragraph
\_widowpenalty=10000 % before last line of paragraph
@@ -115,10 +115,10 @@
\_showboxbreadth=150 % for tracing boxes
\_showboxdepth=7
\_errorcontextlines=15
-\_tracinglostchars=2 % missing chracter warnings on terminal too
+\_tracinglostchars=2 % missing character warnings on terminal too
-\_outputmode=1 % PDF ouput
-\_pdfvorigin=0pt % orgin is exatly at left upper corner
+\_outputmode=1 % PDF output
+\_pdfvorigin=0pt % origin is exactly at upper left corner
\_pdfhorigin=0pt
\_hoffset=25mm % margins are 2.5cm, no 1in
\_voffset=25mm
@@ -374,7 +374,7 @@
\_newtoks\_everymnote
\_newdimen\_mnotesize \_mnotesize=20mm % the width of the mnote paragraph
-\_newdimen\_mnoteindent \_mnoteindent=10pt % ditance between mnote and text
+\_newdimen\_mnoteindent \_mnoteindent=10pt % distance between mnote and text
\_public \everymnote \mnotesize \mnoteindent ;
\_doc -----------------------------
@@ -428,8 +428,8 @@
\_doc -----------------------------
The \^`\eqalign` macro can be configured by \`\eqlines` and \`\eqstyle`
- tokens lists. The default values are set in order these macro beahaves
- as in Plain \TeX. The \`\eqspace` is horizontal space put
+ tokens lists. The default values are set in order these macro behaves
+ like in Plain \TeX. The \`\eqspace` is horizontal space put
between equation systems if more columns in \^`\eqalign` are used.
\_cod -----------------------------
@@ -447,8 +447,8 @@
\_public \lmfil ;
\_doc -----------------------------
- The output routine uses token list \`\headline` and \`\footline` in the
- same sense as in plain \TeX/. If they are non-empty then `\hfil` or `\hss`
+ The output routine uses token lists \`\headline` and \`\footline` in the
+ same sense as plain \TeX/ does. If they are non-empty then `\hfil` or `\hss`
must be here because they are used inside `\hbox to\hsize`.
Assume that page-body text can be typeset in different sizes and
diff --git a/macros/optex/base/prefixed.opm b/macros/optex/base/prefixed.opm
index f8edf5d135..6dec64c7e5 100644
--- a/macros/optex/base/prefixed.opm
+++ b/macros/optex/base/prefixed.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \public {Prefixing and code syntax <2020-02-25>} % preloaded in format
+\_codedecl \public {Prefixing and code syntax <2021-08-16>} % preloaded in format
\_doc ---------
All \TeX/ primitives have alternative control sequence `\_hbox` `\_string`, ...
@@ -61,17 +61,18 @@
such file more than once. Else the <info> is printed to the terminal
and the file is read.\nl
The {\`\_endcode`} is defined as `\endinput` in the `optex.ini` file.
- \`\wterm` `{<text>}` prints `<text>`
- to the terminal and to the `.log` file (as in plain \TeX/).
+ \`\wterm` `{<text>}` prints the `<text>` to the terminal and to the `.log` file,
+ \`\wlog` `{<text>}` prints the `<text>` only to the `.log` file (as in plain \TeX)
\_cod -----------------------
\_def \_codedecl #1#2{%
- \_ifx #1\_undefined \_wterm{#2}%
+ \_ifx #1\_undefined \_wlog{#2}%
\_else \_ea \_endinput \_fi
}
\_def \_wterm {\_immediate \_write16 }
+\_def \_wlog {\_immediate\_write-1 } % write on log file (only)
-\_public \wterm ;
+\_public \wterm \wlog ;
\_doc ------------------------
The `\optexversion` and `\fmtname` are defined in the `optex.ini` file.
@@ -314,6 +315,7 @@ can look like.
\endinput
+2021-08-16 \_wlog moved from basic macros, \_codedecl uses \_wlog only.
2021-04-25 \_checkexists introduced
2021-02-15 \_expandafter -> \_ea in \_codedecl
2020-02-14 released
diff --git a/macros/optex/base/ref-file.opm b/macros/optex/base/ref-file.opm
index 8c459f7de5..95e960bc12 100644
--- a/macros/optex/base/ref-file.opm
+++ b/macros/optex/base/ref-file.opm
@@ -1,85 +1,97 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \openref {File for references <2021-04-13>} % preloaded in format
+\_codedecl \openref {File for references <2021-07-19>} % preloaded in format
\_doc --------------------------
- The \`\_inputref` macro is used in `\everyjob`. It reads `\jobname.ref` file
- if it exists. After the file is read then it is removed and opened to write
- a new contents to this file.
+ The \`\_inputref` macro is executed in `\everyjob`. It reads the
+ `\jobname.ref` file, if it exists. After the file is read then it is removed
+ and opened for writing.
\_cod --------------------------
\_newwrite\_reffile
\_def\_inputref {%
\_isfile{\_jobname.ref}\_iftrue
- \_input {\_jobname.ref}
+ \_input {\_jobname.ref}%
+ \_edef\_prevrefhash{\_mdfive{\_jobname.ref}}%
\_gfnotenum=0 \_lfnotenum=0 \_mnotenum=0
- \_openrefA{\_string\_inputref}%
+ \_openref
\_fi
}
\_doc --------------------------
- If the file does not exist then it is not created by default. It means that if you
+ \`\_mdfive``{<file>}` expands to the MD5 hash of a given file.
+ We use it to do consistency checking of the `.ref` file. First, we read the MD5 hash
+ of `.ref` file from previous \TeX/ run before it is removed and opened for
+ writing again in the \^`\_inputref` macro. The hash is saved to \`\_prevrefhash`.
+ Second, we read the MD5 hash in the \^`\_byehook` macro again and if
+ these hashes differ, warning that \"ref file has changed" is
+ printed. Try running `optex op-demo` twice to see the effect.
+ \_cod --------------------------
+
+\_def\_mdfive#1{\_directlua{mdfive("#1")}}
+\_def\_prevrefhash{}
+
+ \_doc --------------------------
+ If the `.ref` file does not exist, then it is not created by default. This means that if you
process a document without any forward references then no `\jobname.ref`
- file is created because it is unusable. The \^`\_wref` macro is a dummy in
- this case.
+ file is created (it would be unusable). The \^`\_wref` macro is a dummy in
+ that case.
\_cod --------------------------
\_def\_wrefrelax#1#2{}
\_let\_wref=\_wrefrelax
\_doc ---------------------
- If a macro needs to create and to use `.ref` file then such macro must use
- \`\openref`. When the file is created (using internal \`\_openrefA`) then
- the \`\_wref` `\<macro>{<data>}` is redefined in order to
- save the line `\<macro><data>` to the `.ref` file using asynchronous
- `\write` primitive. Finally, the `\_openref` destroys itself, because we
- need not open the file again.\nl
- The `\_wref``<csname>{<params>}` does exactly `\write\_reffile{\string<csname><params>}`
- in this case and \`\_ewref``<csname>{<params>}` does
+ If a macro needs to create and use the `.ref` file, then such macro must
+ first use \`\openref`. It creates the file and redefines
+ \`\_wref` `\<macro>{<data>}` so that it
+ saves the line `\<macro><data>` to the `.ref` file using the asynchronous
+ `\write` primitive. Finally, `\_openref` destroys itself, because we
+ don't need to open the file again.\nl
+ `\_wref``<csname>{<params>}` in fact does `\write\_reffile{\string<csname><params>}`
+ and similarly \`\_ewref``<csname>{<params>}` does
`\write\_reffile{\string<csname><expanded-params>}`.
\_cod ---------------------
\_def\_openref {%
- \_ifx \_wref\_wrefrelax \_openrefA{\_string\openref}\_fi
- \_gdef\_openref{}%
-}
-\_def\_openrefA #1{%
\_immediate\_openout\_reffile="\_jobname.ref"\_relax
\_gdef\_wref ##1##2{\_write\_reffile{\_bslash\_csstring##1##2}}%
- \_immediate\_write\_reffile {\_pcent\_pcent\_space OPTeX <\_optexversion> - REF file (#1)}%
+ \_immediate\_write\_reffile {\_pcent\_pcent\_space OpTeX <\_optexversion> - REF file}%
\_immediate\_wref \Xrefversion{{\_REFversion}}%
+ \_gdef\_openref{}%
}
\_def\_ewref #1#2{\_edef\_ewrefA{#2}\_ea\_wref\_ea#1\_ea{\_ewrefA}}
\_def\openref{\_openref}
\_doc ----------------------
We are using the convention that the macros used in `.ref` file are named
- `\_X<foo>`. If there is a new version of \OpTeX/ with a different collection
- of such macros then we don't want to read the `.ref` files produced by an
- old version of \OpTeX/ or by OPmac. So the first line of `.ref` file is in
- the form
+ `\_X<foo>`.
+ We don't want to read `.ref` files from old, incompatible versions of
+ \OpTeX/ (and OPmac). This is ensured by using a version number and the
+ \`\Xrefversion` macro at the beginning of the `.ref` file:
\begtt \catcode`\<=13
\Xrefversion{<version>}
\endtt
- We can check the version compatibility by this macro.
+ The macro checks the version compatibility.
Because OPmac does not understand `\_Xrefversion` we use
- \`\Xrefversion` (with a different number of `<version>` form OPmac) here.
- The result: OPmac skips the `.ref` files produced by \OpTeX/ and vice
+ `\Xrefversion` (with a different number of `<version>` than OPmac) here.
+ The result: OPmac skips `.ref` files produced by \OpTeX/ and vice
versa.
\_cod ----------------------
-\_def\_REFversion{6} % actual version of .ref files in OpTeX
+\_def\_REFversion{6} % current version of .ref files in OpTeX
\_def\_Xrefversion#1{\_ifnum #1=\_REFversion\_relax \_else \_endinput \_fi}
\_public \Xrefversion ; % we want to ignore .ref files generated by OPmac
\_doc -----------------------
- You cannot define your special `.ref` macros before `.ref` file is read
- because it is read in `\everyjob`. But you can define such macros using
+ You cannot define your own `.ref` macros before `.ref` file is read
+ because it is read in `\everyjob`. But you can define such macros by using
\`\refdecl``{<definitions of your ref macros>}`.
- This command sends to `.ref` file your `<definitions of your ref macros>`
- immediately. Next lines in `.ref` file should include our macros. Example
- from CTUstyle2:
+ This command immediately writes `<definitions of your ref macros>` to the
+ `.ref` file. Then the next lines written to the `.ref` file can include
+ your macros.
+ An example from CTUstyle2:
\begtt
\refdecl{%
\def\totlist{} \def\toflist{}^^J
@@ -87,8 +99,8 @@
\def\Xfig#1#2#3{\addto\toflist{\tofline{#1}{#2}{#3}}}
}
\endtt
- We must read `<definition of your ref macros>` when the catcode of `#` is 12
- because we needn't duplicate each `#` in the `.ref` file.
+ We must read `<definitions of your ref macros>` while `#` has the catcode 12,
+ because we don't want to duplicate each `#` in the `.ref` file.
\_cod \_fin -----------------
\_def\_refdecl{\_bgroup \_catcode`\#=12 \_refdeclA}
@@ -100,13 +112,11 @@
\_endcode % ================================================
-
-The `.ref` file has the name `\jobname.ref` and
-it saves information about references, TOC lines, etc.
-All data needed in next \TeX/ run are saved here.
-\OpTeX/ reads this file at the beginning of the document
-(using `\everyjob`) if such file exists.
-The `.ref` file looks like:
+A so called `.ref` (`\jobname.ref`) file is used to store data that will be
+needed in the next \TeX/ run (information about references, TOC lines, etc.).
+If it exists it is read by `\everyjob`, when processing of the document starts,
+but it is not created at all if the document doesn't need any forward
+references. Here are the typical contents of a `.ref` file:
\begtt \catcode`\<=13
\Xrefversion{<ref-version>}
@@ -119,29 +129,28 @@ The `.ref` file looks like:
\_Xlabel{<label>}{<text>}
...
\endtt
-%
-where <gpageno> is internal page number globally numbered from one and
-`<pageno>` is a page number (`\the\pageno`) used in pagination (they may differ).
-Each page begins with \^`\_Xpage`.
-The `<label>` is a label used by user in `\label[<label>]` and `<text>` is a
-text which should be referenced (the number of section or table, for
-example `2.3.14`). The `<title>` is the title of the chapter (`<level>`=1,
-`<type>`=`chap`), section (`<level>`=2, `<type>`=`sec`), subsection
-(`<level>`=3, `<type>`=`secc`). The \^`\_Xpage` is written at the beginning of each
-page, the `\_Xtoc` is written when chapter or section or subsection title
-exists on the page and `\_Xlabel` when labeled object prefixed by
-`\label[<label>]` exists on the page.
-
-The `.ref` file is read when the processing of the document starts using
-`\everyjob`. It is read, removed, and opened to writing immediately.
-But the `.ref` file should be missing. If none forward references are needed
-in the document then `.ref` file is not created. For example, you only want
-to test a simple plain \TeX/ macro, you create `test.tex` file, you do
-`optex test` and you don't need to see an empty `test.ref` file in your directory.
+
+\begitems
+* \^`\_Xpage` corresponds to the beginning of a page. <gpageno> is an internal
+page number, globally numbered from one. `<pageno>` is the page number
+(`\the\pageno`) used in pagination (they may differ).
+
+* \^`\_Xtoc` corresponds to a chapter, section or subsection title on a page.
+`<title>` is the title of the chapter (`<level>`=1, `<type>`=`chap`), section
+(`<level>`=2, `<type>`=`sec`) or subsection (`<level>`=3, `<type>`=`secc`).
+
+* \^`\_Xlabel` corresponds to a labelled object on a page. `<label>` is the
+label provided by the user in \^`\label[<label>]`, while `<text>` is the text
+which should be used for the reference (section or table number, for example
+`2.3.14`).
+\enditems
+
\_endinput
History:
+2021-07-19 \openrefA merged to \openref
+2021-07-18 ref file consistency checking added
2021-04-13 \Xrefversion incremented (6), new format of \_Xbib
2021-02-05 \_ewref introduced
2020-02-14 released
diff --git a/macros/optex/base/references.opm b/macros/optex/base/references.opm
index a4c2e694db..eb884c4f1d 100644
--- a/macros/optex/base/references.opm
+++ b/macros/optex/base/references.opm
@@ -11,6 +11,12 @@
\_doc ----------------------------
Counter for the number of unresolved references \`\_unresolvedrefs`.
+ It is set but unused in OpTeX versions 1.04+. You can add the report, for
+ example:
+ \begtt
+ \_addto\_byehook{\_ifnum\_unresolvedrefs>0 \_opwarning
+ {There are \_the\_unresolvedrefs\_space unresolved references}\_fi}
+ \endtt
\_cod ----------------------------
\_newcount\_unresolvedrefs
diff --git a/macros/optex/base/slides.opm b/macros/optex/base/slides.opm
index a491d1f5ad..0fed12ac7f 100644
--- a/macros/optex/base/slides.opm
+++ b/macros/optex/base/slides.opm
@@ -53,19 +53,20 @@
\_doc -----------------------------
The \`\pshow``<num>` prints the text in invisible
(transparent) font when \^`\layernum`\code{<}`<num>`.
- The transparency is set by `\pdfpageresoyrces` primitive.
+ For transparency we need to define special graphics states.
\_cod -----------------------------
-\pdfpageresources{/ExtGState << /Invisible << /Type /ExtGState /ca 0 /CA 0 >>
- /Visible << /Type /ExtGState /ca 1 /CA 1 >> >>}
-\addto\_morepgresources{/Invisible << /Type /ExtGState /ca 0 /CA 0 >>
- /Visible << /Type /ExtGState /ca 1 /CA 1 >>}
-\def\Invisible {\_pdfliteral{/Invisible gs}}
-\def\Visible {\_pdfliteral{/Visible gs}}
-\def\Transparent {\Invisible \_aftergroup \Visible}
+\_addextgstate{/Invisible <</ca 0 /CA 0>>}
+\_addextgstate {/Visible <</ca 1 /CA 1>>}
+
+\_def\_Invisible {\_pdfliteral{/Invisible gs}}
+\_def\_Visible {\_pdfliteral{/Visible gs}}
+\_def\_Transparent {\_Invisible \_aftergroup \_Visible}
+
+\_public \Invisible \Visible \Transparent ;
\_def\_use#1#2{\_ifnum\_layernum#1\_relax#2\_fi}
-\_def\_pshow#1{\_use{=#1}\Red \_use{<#1}\Transparent \_ignorespaces}
+\_def\_pshow#1{\_use{=#1}\Red \_use{<#1}\_Transparent \_ignorespaces}
\_doc -----------------------------
The main level list of items is activated here. The `\_item:X` and
diff --git a/macros/optex/base/table.opm b/macros/optex/base/table.opm
index b29aabbf4a..d10e916bbe 100644
--- a/macros/optex/base/table.opm
+++ b/macros/optex/base/table.opm
@@ -1,6 +1,6 @@
%% This is part of the OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \table {Basic macros for OpTeX <2021-06-03>} % preloaded in format
+\_codedecl \table {Basic macros for OpTeX <2021-08-04>} % preloaded in format
\_doc -----------------------------
The result of the \`\table``{<declaration>}{<data>}` macro is inserted into
@@ -84,16 +84,6 @@
If no `pxto` keyword was used, then we print the table using `\halign`
directly. The \^`\_tablew` macro is nonempty if the `to` keyword was used.
- Because the color selector with `\aftergroup` can be used inside the
- table item, we must create the second real group for each table item.
- This is reason why we start `<converted declaration>` by `\bgroup` and we
- end it by `\egroup` in the \`\_tableC` macro. Each `&` character
- is stored as `\egroup&\bgroup` in `<converted declaration>`. The
- `\halign\_tablew\_tableC` really does:
- \begtt \catcode`\<=13
- \halign\_tablew{\bgroup<converted declaration>\egroup\tabskip=\tabskipr \cr<data>\crcr}
- \endtt
- \relax
The <data> are re-tokenized by `\_scantextokens` in order to be more
robust to catcode changing inside the <data>. But inline verbatim cannot
work in special cases here like \code{`\{`} for example.
@@ -116,8 +106,7 @@
\_halign\_tablew \_tableC
\_fi \_egroup
}
-\_def\_tableC{\_ea{\_ea\_bgroup\_the\_tabdata\_egroup\_tabskip=\_tabskipr\_cr
- \_scantextokens\_ea{\_tmpb\_crcr}}}
+\_def\_tableC{\_ea{\_the\_tabdata\_tabskip=\_tabskipr\_cr \_scantextokens\_ea{\_tmpb\_crcr}}}
\_doc -----------------------------
\`\_tabreplstrings` replaces each `\crl` etc. to `\crcr\crl`.
@@ -143,11 +132,11 @@
For example, the
following result is generated when `<declaration>=|cr||cl|`.
\begtt
- tabdata: \_vrule\_the\_tabiteml\_hfil#\_unsskip\_hfil\_the\_tabitemr\_tabstrutA
- &\_the\_tabiteml\_hfil#\_unsskip\_the\_tabitemr
+ tabdata: \_vrule\_the\_tabiteml{\_hfil#\_unsskip\_hfil}\_the\_tabitemr\_tabstrutA
+ &\_the\_tabiteml{\_hfil#\_unsskip}\_the\_tabitemr
\_vrule\_kern\_vvkern\_vrule\_tabstrutA
- &\_the\_tabiteml\_hfil#\_unsskip\_hfil\_the\_tabitemr\_tabstrutA
- &\_the\_tabiteml#\_unsskip\_hfil\_the\_tabitemr\_vrule\_tabstrutA
+ &\_the\_tabiteml{\_hfil#\_unsskip\_hfil}\_the\_tabitemr\_tabstrutA
+ &\_the\_tabiteml{\_relax#\_unsskip\_hfil}\_the\_tabitemr\_vrule\_tabstrutA
ddlinedata: &\_dditem &\_dditem\_vvitem &\_dditem &\_dditem
\endtt
The second result in the \`\_ddlinedata` macro is a template of one row of the table
@@ -200,7 +189,7 @@
\_public \colnum ;
\_def\_addtabitemx{\_ifnum\_colnum>0
- \_addtabdata{\_egroup &\_bgroup}\_addto\_ddlinedata{&\_dditem}\_fi
+ \_addtabdata{&}\_addto\_ddlinedata{&\_dditem}\_fi
\_advance\_colnum by1 \_let\_tmpa=\_relax
\_ifnum\_colnum>1 \_ea\_addtabdata\_ea{\_ea\_colnum\_the\_colnum\_relax}\_fi}
\_def\_addtabdata#1{\_tabdata\_ea{\_the\_tabdata#1}}
@@ -222,44 +211,67 @@
\_doc -----------------------------
The default \"declaration letters" `c`, `l`, `r` and `p` are declared
by setting \`\_tabdeclarec`, \`\_tabdeclarel`, \`\_tabdeclarer` and
- \`\_paramtabdeclarep` macros. In general, define
+ \^`\_paramtabdeclarep` macros. In general, define
`\def\_tabdeclare<letter>{...}` for a non-parametric
letter and `\def\_paramtabdeclare<letter>{...}` for a letter with a parameter.
The double hash `##` must be in the definition, it is replaced by a real table item data.
You can declare more such \"declaration letters" if you want.
+
+ Note, that the `##` with fills are in group. The reason can be explained
+ by following example:
+ \begtt
+ \table{|c|c|}{\crl \Red A & B \crl}
+ \endtt
+ We don't want vertical line after red A to be in red.
\_cod -----------------------------
-\_def\_tabdeclarec{\_the\_tabiteml\_hfil##\_unsskip\_hfil\_the\_tabitemr}
-\_def\_tabdeclarel{\_the\_tabiteml\_relax##\_unsskip\_hfil\_the\_tabitemr}
-\_def\_tabdeclarer{\_the\_tabiteml\_hfil##\_unsskip\_the\_tabitemr}
-\_def\_paramtabdeclarep#1{\_the\_tabiteml\_vtop{\_hsize=#1\_relax \_partabitem{##}}\_the\_tabitemr}
+\_def\_tabdeclarec{\_the\_tabiteml{\_hfil##\_unsskip\_hfil}\_the\_tabitemr}
+\_def\_tabdeclarel{\_the\_tabiteml{\_relax##\_unsskip\_hfil}\_the\_tabitemr}
+\_def\_tabdeclarer{\_the\_tabiteml{\_hfil##\_unsskip}\_the\_tabitemr}
\_doc -----------------------------
- \`\_partabitem``{<data>}` prints the table item in a paragraph format.
- This macro solves two things. Fist, the setting of parameters for the
- paragraph formatting. The `\hsize` and parameters from macros
- \^`\fC`, \^`\fR` etc. are set already.\nl
- Second thing: if the `\hsize` is negative then first pass of `pxto` table is processed.
- We print nothing in such case but we advance the \`\_tsizesum`.
+ The \`\_paramtabdeclarep``{<data>}` is invoked when `p{<data>}`
+ declarator is used. First, it saves the `\hsize` value
+ and then it runs \`\_tablepar`.
+ The \^`\_tablepar` macro behaves like \`\_tableparbox` (which is `\vtop`) in normal cases.
+ But there is a special case: if the first pass of `pxto` table is
+ processed then `\hsize` is negative. We print nothing in this case, i.e.\
+ \^`\_tableparbox` is \^`\ignoreit` and we advance the \`\_tsizesum`.
The auxiliary macro \`\_tsizelast` is used to do advancing
only in the first row of the table.
- \^`\_tsizesum` and \^`\_tsizelast` are initialized in the \^`\_tableB` macro.\nl
- \`\_partabitemA``{<data>}` only copies <data>, but it is redefined by \^`\fS`.
+ \^`\_tsizesum` and \^`\_tsizelast` are initialized in the \^`\_tableB` macro.
\_cod -----------------------------
-\_newdimen \_tsizesum
-\_def \_tsizelast{0}
-\_long\_def\_partabitem#1{%
+\_def\_paramtabdeclarep#1{\_hsize=#1\_relax
+ \_the\_tabiteml \_tablepar{\_tableparB ##\_tableparC}\_the\_tabitemr
+}
+\_def\_tablepar{%
\_ifdim\_hsize<0pt
\_ifnum\_tsizelast<\_colnum \_global\_advance\_tsizesum by-\_hsize
\_xdef\_tsizelast{\_the\_colnum}\_fi
- \_else
- \_baselineskip=\_normalbaselineskip
- \_lineskiplimit=\_zo \_noindent \_hskip\_zo \_relax \_partabitemA{#1}\_unsskip
- \_ifvmode\_vskip\_dp\_tstrutbox \_else\_lower\_dp\_tstrutbox\_hbox{}\_fi
+ \_let\_tableparbox=\_ignoreit
\_fi
+ \_tableparA \_tableparbox
+}
+\_let \_tableparbox=\_vtop
+\_let \_tableparA=\_empty
+\_newdimen \_tsizesum
+\_def \_tsizelast{0}
+
+ \_doc -----------------------------
+ The \`\_tableparB` initializes the paragraphs inside the table item and
+ \`\_tableparC` closes them. They are used in the \^`\_paramtabdeclarep` macro.
+ The first paragraph is no indented.
+ \_cod -----------------------------
+
+\_def\_tableparB{%
+ \_baselineskip=\_normalbaselineskip \_lineskiplimit=\_zo \_noindent
+ \_raise\_ht\_tstrutbox\_null \_hskip\_zo \_relax
+}
+\_def\_tableparC{%
+ \_unsskip
+ \_ifvmode\_vskip\_dp\_tstrutbox \_else\_lower\_dp\_tstrutbox\_null\_fi
}
-\_let\_partabitemA=\_useit
\_doc -----------------------------
Users put optional spaces around the table item typically, i.e.\ they write
@@ -274,19 +286,33 @@
\_doc -----------------------------
The \`\fL`, \`\fR`, \`\fC` and \`\fX` macros only do special parameters settings
- for paragraph building algorithm. The \`\fS` prints the paragraph into
- box 0 first, measures the number of lines by the `\prevgraf` primitive
- and use (or don't use) `\hfil` (for centering) before the first line.
- \_cod -----------------------------
+ for paragraph building algorithm.
+ \_cod
\_let\_fL=\_raggedright
\_def\_fR{\_leftskip=0pt plus 1fill \_relax}
\_def\_fC{\_leftskip=0pt plus1fill \_rightskip=0pt plus 1fill \_relax}
\_def\_fX{\_leftskip=0pt plus1fil \_rightskip=0pt plus-1fil \_parfillskip=0pt plus2fil \_relax}
-\_def\_fS{\_long\_def\_partabitemA##1{%
- \_setbox0=\_vbox{\_noindent ##1\_endgraf \_ea}\_ifnum\_prevgraf=1 \_hfil \_fi ##1%
-}}
-\_public \fL \fR \fC \fX \fS ;
+\_public \fL \fR \fC \fX ;
+
+ \_doc -----------------------------
+ The \`\fS` macro is more tricky. The \^`\_tableparbox` isn't printed
+ immediatelly, but `\setbox2=` is prefixed by the macro \`\_tableparA`,
+ which is empty by default (used in \^`\_tablepar`). The \`\_tableparD`
+ is processed after the box is set: it checks if there is only one line
+ and prints `\hbox to\hsize{\hfil<this line>\hfil}` in this case. In other
+ cases, the box2 is printed.
+ \_cod -----------------------------
+
+\_def\_fS{\_relax
+ \_ifdim\_hsize<0pt \_else \_def\_tableparA{\_setbox2=}\_fi
+ \_addto\_tableparC{\_aftergroup\_tableparD}%
+}
+\_def\_tableparD{\_setbox0=\_vbox{\_unvcopy2 \_unskip \_global\_setbox1=\_lastbox}%
+ \_ifdim\_ht0>0pt \_box2 \_setbox0=\_box1
+ \_else \_hbox to\_hsize{\_hfil \_unhbox1\_unskip\_unskip\_hfil}\_setbox0=\_box2 \_fi
+}
+\_public \fS ;
\_doc -----------------------------
The family of `\_cr*` macros
@@ -334,7 +360,7 @@
\_def\_mspan{\_omit \_afterassignment\_mspanA \_mscount=}
\_def\_mspanA[#1]#2{\_loop \_ifnum\_mscount>1 \_cs{_span}\_omit \_advance\_mscount-1 \_repeat
\_count1=\_colnum \_colnum=0 \_def\_tmpa{}\_tabdata={}\_scantabdata#1\_relax
- \_colnum=\_count1 \_setbox0=\_vbox{\_halign\_ea{\_ea\_bgroup\_the\_tabdata\_egroup\_cr#2\_cr}%
+ \_colnum=\_count1 \_setbox0=\_vbox{\_halign\_ea{\_the\_tabdata\_cr#2\_cr}%
\_global\_setbox8=\_lastbox}%
\_setbox0=\_hbox{\_unhbox8 \_unskip \_global\_setbox8=\_lastbox}%
\_unhbox8 \_ignorespaces}
@@ -557,6 +583,9 @@ after the second one.
\_endinput
+2021-08-04 \_patamtabdeclarep reimplemented.
+2021-07-16 grouping based on colors via attributes.
+2021-06-03 \scantextokens added to \_partabitem, bug fixed.
2021-06-03 \fS corrected, re-implemented.
2021-06-02 \table in \table allowed, bug fixed.
2021-06-01 pxto: sum of \tsize's allowed different than 1
diff --git a/macros/optex/doc/omls.tex b/macros/optex/doc/omls.tex
index 0f42e4b3c0..5c21fd5671 100644
--- a/macros/optex/doc/omls.tex
+++ b/macros/optex/doc/omls.tex
@@ -509,7 +509,8 @@ output of the \LaTeX/ source file.
italic, \.`\bf` selects upright bold font, \.`\bi` selects bold italic and
\.`\tt` selects a monospaced font, \.`\em` select italic (if upright is current) or upright
(if italic is current). The font sizes or other font features are typically ignored
-by cnv-programs. The actual font selection is closed at the end of the current group.
+by cnv-programs. Selection of font is local to a group (i.e. should be reverted
+at the end of the current group).
The groups are given:
\begitems
* explicitly by `{` and `}` characters (which are not delimiters of
diff --git a/macros/optex/doc/optex-doc.pdf b/macros/optex/doc/optex-doc.pdf
index 3bcf1a843e..910019b5d9 100644
--- a/macros/optex/doc/optex-doc.pdf
+++ b/macros/optex/doc/optex-doc.pdf
Binary files differ
diff --git a/macros/optex/doc/optex-doc.tex b/macros/optex/doc/optex-doc.tex
index 8d056698f4..f8cb192d86 100644
--- a/macros/optex/doc/optex-doc.tex
+++ b/macros/optex/doc/optex-doc.tex
@@ -21,7 +21,7 @@
\tit Format Based on Plain \TeX/ and OPmac\fnotemark1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\hfill Version 1.03
+\hfill Version 1.04
\centerline{\it Petr Olšák, 2020, 2021}
diff --git a/macros/optex/doc/optex-math.tex b/macros/optex/doc/optex-math.tex
index 57afd22334..5f590d5b25 100644
--- a/macros/optex/doc/optex-math.tex
+++ b/macros/optex/doc/optex-math.tex
@@ -954,6 +954,7 @@ should be at baseline if the repeating symbol is at baseline. Or they should be
at the math axis if the repeating symbol is at the math axis. We have to use \x`\cdots` instead
`\dots` in the second case. Example:
$$
+ \addto\_ttfont{\thefontsize[9.5]}
`a_1, a_2, \dots, a_n, \quad a_1 + a_2 + \cdots + a_n` \qquad
a_1, a_2, \dots, a_n, \quad a_1 + a_2 + \cdots + a_n
$$
@@ -1576,8 +1577,7 @@ We can re-define the `\_normalmath` macro by:
\begtt \typosize[10/12]
\addto\_normalmath {\_loadmathfamily 5 bbold }
-\_regtfm bbold 0 bbold5 5.5 bbold6 6.5 bbold7 7.5 bbold8 8.5 bbold9
- 9.5 bbold10 11.1 bbold12 15 bbold17 * % using all bbold*.tfm
+\_regtfm bbold 0 bbold5 6 bbold7 8.5 bbold10 * % using all bbold*.pfb
\_normalmath % reload the math fonts collection
\endtt
%
@@ -1585,8 +1585,7 @@ The string \"`bbold`" is declared by `\_regtfm` as a collection of all
`bbold*.tfm` fonts, the optical sizes are supported.
\addto\_normalmath {\_loadmathfamily 5 bbold }
-\_regtfm bbold 0 bbold5 5.5 bbold6 6.5 bbold7 7.5 bbold8 8.5 bbold9
- 9.5 bbold10 11.1 bbold12 15 bbold17 * % using all bbold*.tfm
+\_regtfm bbold 0 bbold5 6 bbold7 8.5 bbold10 * % using all bbold*.pfb
\_normalmath
\Umathchardef \bbplus 2 5 "2B
\Umathchardef \bble 3 5 "3C
diff --git a/macros/optex/doc/optex-techdoc.tex b/macros/optex/doc/optex-techdoc.tex
index 31f789d56c..4f94e8be70 100644
--- a/macros/optex/doc/optex-techdoc.tex
+++ b/macros/optex/doc/optex-techdoc.tex
@@ -269,6 +269,10 @@ allocators, and callback management. Callback management is a nice extension
and is actually used in \OpTeX/. Other functions are defined more or less just
to suit luaotfload's use.
+The allocations are declared in subsection~\ref[lua-alloc], calbacks are
+implemented in subsection~\ref[callbacks] and handling with colors can be
+found in the subsection~\ref[lua-colors].
+
\newtoks \_hisyntaxlua
\_hisyntaxlua={%
\_hicolor C \Green
diff --git a/macros/optex/doc/optex-userdoc.tex b/macros/optex/doc/optex-userdoc.tex
index 93dad28377..16fd468c1f 100644
--- a/macros/optex/doc/optex-userdoc.tex
+++ b/macros/optex/doc/optex-userdoc.tex
@@ -1349,14 +1349,16 @@ using this empty internal name.
{`\White`},
{\Grey `\Grey`},
{\LightGrey `\LightGrey`} and
-`\Black`. User can define more
-such selectors by setting four CMYK components
-\new
-or three RGB components. For example
+`\Black`. More
+such selectors can be defined
+by setting four CMYK components (using \^`\setcmykcolor`),
+or three RGB components (using \^`\setrgbcolor`)
+or one grey component (using \^`\setgreycolor`). For example
\begtt
\def \Orange {\setcmykcolor{0 0.5 1 0}}
\def \Purple {\setrgbcolor{1 0 1}}
+\def \DarkGrey {\setgreycolor{.1}}
\endtt
\new
@@ -1368,7 +1370,7 @@ name, then the letters B, C, etc. are appended to the name in \OpTeX/. For examp
`\Chocolate` is Chocolate1, `\ChocolateB` is Chocolate2 etc.
\new
-The color selectors work locally in groups by default but with limitations. See
+The color selectors work locally in groups by default. See
the technical documentation, section~\ref[colors] for more information.
The basic colors \^`\Blue`, \^`\Red`, \^`\Cyan`, \^`\Yellow` etc.\ are defined
@@ -1405,23 +1407,24 @@ If a convex linear combination (as in the last example above) is used then it
emulates color behavior on a painter's palette.
You can use \^`\rgbcolordef` instead of \^`\colordef` if you want to mix colors
in the additive RGB color space.
+If \^`\onlyrgb` is set then \^`\colordef` works like \^`\rgbcolordef`.
\def\coloron#1#2#3{%
- \setbox0=\hbox{{#2#3}}\leavevmode
- \localcolor \rlap{#1\strut \vrule width\wd0}\box0
+ \setbox0=\hbox{#2#3}\leavevmode
+ \rlap{#1\strut \vrule width\wd0}\box0
}
-The following example defines the macro for the
-\coloron\Yellow\Brown{colored text on the colored background}. Usage:
+The following example defines the macro for
+\coloron\Yellow\Brown{colored text on colored background}. Usage:
`\coloron<background><foreground>{<text>}`
-The `\coloron` can be defined as follows:
+The `\coloron` macro can be defined as follows:
\begtt
\def\coloron#1#2#3{%
- \setbox0=\hbox{{#2#3}}%
+ \setbox0=\hbox{#2#3}%
\leavevmode \rlap{#1\strut \vrule width\wd0}\box0
}
-\coloron\Yellow\Brown{The brown text on the yellow background}
+\coloron\Yellow\Brown{Brown text on yellow background}
\endtt
\secc Images
@@ -1718,12 +1721,12 @@ temporarily standard category codes during loading and it tries to
load `<filename>.opm` or `<filename>.tex` or `<filename>`, the first occurence
wins. Example:
\begtt
-\load [qrcode, tikz]
+\load [qrcode, scanbase]
\endtt
%
-does `\input qrcode.opm` \,and `\input tikz.tex` \,and it saves
-local information about the fact that these file names
-`qrcode` and `tikz` were already used, i.\,e. next \^`\load` will skip them.
+does `\input qrcode.opm` \,and \,and `\input scanbase.tex`.
+It saves local information about the fact that these file names
+(`qrcode`, `scanbase`) were loaded, i.e.\ next \^`\load` will skip them.
It is strongly recommended to use the `\load` macro for loading external
macros if you need them. On the other hand, if your source document is structured
@@ -1733,6 +1736,7 @@ The macro packages intended to \OpTeX/ have the name `*.opm`.
The following packages are distributed as part of \OpTeX/:
\begitems
* `qrcode.opm` enables to create QR codes.
+* `tikz.opm` does `\input tikz.tex`, i.e.\ loads Ti{\it k\/}Z. It adds \OpTeX/-specific code.
* \ulink[http://petr.olsak.net/ftp/olsak/optex/mte-doc.pdf]{\tt mte.opm}
includes settings for microtypographic extensions (protrusions+expanding fonts).
* `vlna.opm` enables to protect of one-letter prepositions and more things automatically.
diff --git a/macros/optex/pkg/tikz.opm b/macros/optex/pkg/tikz.opm
new file mode 100644
index 0000000000..da2657d5fc
--- /dev/null
+++ b/macros/optex/pkg/tikz.opm
@@ -0,0 +1,39 @@
+% This is macro package used by OpTeX, see http://petr.olsak.net/optex
+
+\_codedecl \tikzpicture {TikZ for OpTeX <2021-07-15>}
+
+ \_doc
+ This package is \OpTeX/'s compatibility layer for PGF/TikZ. When users do
+ `\load[tikz]` they expect `tikz.tex` to be loaded, but this file gets loaded
+ instead. It does load `tikz.tex`, but also does fixups.
+
+ First we load TikZ itself.
+
+ \_cod
+
+\_input tikz.tex
+
+ \_doc
+ PGF's `\pgfutil@everybye` hooks into `\end`, but normally \OpTeX/ uses the
+ prefixed `\_end`. Here we make it hook into `\_byehook` which should
+ hopefully be preserved by all \OpTeX/ macro writers.
+ \_cod
+
+\_addto\_byehook{\_the\_cs{pgfutil@everybye}}
+
+ \_doc
+ There is a general disagreement about the use/meaning of `\hoffset` and
+ `\voffset` -- \LaTeX/, the \LaTeX/ `crop`
+ package\fnote{\url{https://www.ctan.org/pkg/crop}}, TikZ, and \OpTeX/ all
+ try to use the values differently. Unfortunately this means a broken
+ behaviour observed by end users in
+ \OpTeX/\fnote{\url{https://github.com/pgf-tikz/pgf/issues/983}}.
+
+ The problem at hand is that PGF nowadays sets the page origin to include
+ `\hoffset` and `\voffset`. We instead set it to the origin (i.e. the point
+ $(0, 0)$).
+ \_cod
+
+\_sdef{pgf@sys@pdf@mark@pos@pgfpageorigin}{\pgfpointorigin}
+
+\_endcode