%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \magstep {Macros from plain TeX <2022-10-11>} % preloaded in format

   \_doc -----------------------------
   The \`\dospecials` works like in plain TeX but does nothing with `_`.
   If you need to do the same with this character, you can re-define:
   \begtt
   \addto \dospecials{\do\_}
   \endtt
   \`\active` is character constant 13, we can use it in the context
   \code{\\catcode`}<character>\code{=\\active}.
   \_cod -----------------------------

\_def\_dospecials {\do\ \do\\\do\{\do\}\do\$\do\&%
  \do\#\do\^\do\^^K\do\^^A\do\%\do\~}
\_chardef\_active = 13

\_public \dospecials \active ;

   \_doc -----------------------------
   The shortcuts `\chardef\@one` is not defined in \OpTeX/. Use normal
   numbers instead of such obscurities.
   \nl
   The \`\magstep` and \`\magstephalf` are
   defined with `\space`, (no `\relax`), in order to be expandable.
   \_cod -----------------------------

\_def \_magstephalf{1095 }
\_def \_magstep#1{\_ifcase#1 1000\_or 1200\_or 1440\_or 1728\_or 2074\_or 2488\_fi\_space}
\_public \magstephalf \magstep ;

   \_doc -----------------------------
   Plain \TeX/ basic macros and control sequences.
   \`\endgraf`, \`\endline`.
   The `^^L` is not defined in \OpTeX/ because it is obsolete.
   \_cod -----------------------------

\_def\^^M{\ } % control <return> = control <space>
\_def\^^I{\ } % same for <tab>

\_def\lq{`} \def\rq{'}
\_def\lbrack{[} \_def\rbrack{]} % They are only public versions.
% \catcode`\^^L=\active \outer\def^^L{\par} % ascii form-feed is "\outer\par" % obsolete

\_let\_endgraf=\_par \_let\_endline=\_cr
\_public \endgraf \endline ;

   \_doc -----------------------------
   Plain \TeX/ classical \`\obeylines` and \`\obeyspaces`.
   \_cod -----------------------------

% In \obeylines, we say `\let^^M=\_par' instead of `\def^^M{\_par}'
% since this allows, for example, `\let\_par=\cr \obeylines \halign{...'
{\_catcode`\^^M=13 % these lines must end with %
  \_gdef\_obeylines{\_catcode`\^^M=13\_let^^M\_par}%
  \_glet^^M=\_par} % this is in case ^^M appears in a \write
\_def\_obeyspaces{\_catcode`\ =13 }
{\_obeyspaces\_glet =\_space}
\_public \obeylines \obeyspaces ;

   \_doc -----------------------------
   Spaces.
   \`\thinspace`, \`\negthinspace`, \`\enspace`, \`\enskip`,
   \`\quad`, \`\qquad`, \`\smallskip`,
   \`\medskip`, \`\bigskip`, \`\nointerlineskip`, \`\offinterlineskip`,
   \`\topglue`, \`\vglue`, \`\hglue`, \`\slash`.
   \_cod -----------------------------

\_protected\_def\_thinspace {\_kern .16667em }
\_protected\_def\_negthinspace {\_kern-.16667em }
\_protected\_def\_enspace {\_kern.5em }
\_protected\_def\_enskip {\_hskip.5em\_relax}
\_protected\_def\_quad {\_hskip1em\_relax}
\_protected\_def\_qquad {\_hskip2em\_relax}
\_protected\_def\_smallskip {\_vskip\_smallskipamount}
\_protected\_def\_medskip {\_vskip\_medskipamount}
\_protected\_def\_bigskip {\_vskip\_bigskipamount}
\_def\_nointerlineskip {\_prevdepth=-1000pt }
\_def\_offinterlineskip {\_baselineskip=-1000pt \_lineskip=0pt \_lineskiplimit=\_maxdimen}

\_public \thinspace \negthinspace \enspace \enskip \quad \qquad \smallskip
   \medskip \bigskip \nointerlineskip \offinterlineskip ;

\_def\_topglue {\_nointerlineskip\_vglue-\_topskip\_vglue} % for top of page
\_def\_vglue {\_afterassignment\_vglA \_skip0=}
\_def\_vglA {\_par \_dimen0=\_prevdepth \_hrule height0pt
  \_nobreak\_vskip\_skip0 \_prevdepth=\_dimen0 }
\_def\_hglue {\_afterassignment\_hglA \_skip0=}
\_def\_hglA {\_leavevmode \_count255=\_spacefactor \_vrule width0pt
  \_nobreak\_hskip\_skip0 \_spacefactor=\_count255 }
\_protected\_def~{\_penalty10000 \ } % tie
\_protected\_def\_slash {/\_penalty\_exhyphenpenalty} % a `/' that acts like a `-'

\_public \topglue \vglue \hglue \slash ;

   \_doc -----------------------------
   Penalties macros:
   \`\break`, \`\nobreak`, \`\allowbreak`, \`\filbreak`, \`\goodbreak`,
   \`\eject`, \`\supereject`, \`\dosupereject`,
   \`\removelastskip`, \`\smallbreak`, \`\medbreak`, \`\bigbreak`.
   \_cod -----------------------------

\_protected\_def \_break {\_penalty-10000 }
\_protected\_def \_nobreak {\_penalty10000 }
\_protected\_def \_allowbreak {\_penalty0 }
\_protected\_def \_filbreak {\_par\_vfil\_penalty-200\_vfilneg}
\_protected\_def \_goodbreak {\_par\_penalty-500 }
\_protected\_def \_eject {\_par\_break}
\_protected\_def \_supereject {\_par\_penalty-20000 }
\_protected\_def \_dosupereject {\_ifnum \_insertpenalties>0 % something is being held over
  \_line{}\_kern-\_topskip \_nobreak \_vfill \_supereject \_fi}
\_def \_removelastskip {\_ifdim\_lastskip=\_zo \_else \_vskip-\_lastskip \_fi}
\_def \_smallbreak {\_par\_ifdim\_lastskip<\_smallskipamount
  \_removelastskip \_penalty-50 \_smallskip \_fi}
\_def \_medbreak {\_par\_ifdim\_lastskip<\_medskipamount
  \_removelastskip \_penalty-100 \_medskip \_fi}
\_def \_bigbreak {\_par\_ifdim\_lastskip<\_bigskipamount
  \_removelastskip \_penalty-200 \_bigskip \_fi}

\_public \break \nobreak \allowbreak \filbreak \goodbreak \eject \supereject \dosupereject
   \removelastskip \smallbreak \medbreak \bigbreak ;

   \_doc -----------------------------
   Boxes.
   \`\line`, \`\leftline`, \`\rightline`, \`\centerline`, \`\rlap`, \`\llap`,
   \`\underbar`.
   \_cod -----------------------------

\_def \_line {\_hbox to\_hsize}
\_def \_leftline #1{\_line{#1\_hss}}
\_def \_rightline #1{\_line{\_hss#1}}
\_def \_centerline #1{\_line{\_hss#1\_hss}}
\_def \_rlap #1{\_hbox to\_zo{#1\_hss}}
\_def \_llap #1{\_hbox to\_zo{\_hss#1}}
\_def\_underbar #1{$\_setbox0=\_hbox{#1}\_dp0=\_zo \_math \_underline{\_box0}$}

\_public \line \leftline \rightline \centerline \rlap \llap \underbar ;

   \_doc -----------------------------
   The \`\strutbox` is declared as 10pt size dependent (like in plain \TeX), but
   the macro `\_setbaselineskip` (from `fonts-opmac.opm`) redefines it.
   The `\strut` macro puts the \^`\strutbox`.
   \_cod -----------------------------

\_newbox\_strutbox
\_setbox\_strutbox=\_hbox{\_vrule height8.5pt depth3.5pt width0pt}
\_def \_strut {\_relax\_ifmmode\_copy\_strutbox\_else\_unhcopy\_strutbox\_fi}

\_public \strutbox \strut ;

   \_doc -----------------------------
   Alignment. \`\hidewidth` \`\ialign` \`\multispan`.
   \_cod -----------------------------

\_def \_hidewidth {\_hskip\_hideskip} % for alignment entries that can stick out
\_def \_ialign{\_everycr={}\_tabskip=\_zoskip \_halign} % initialized \halign
\_newcount\_mscount
\_def \_multispan #1{\_omit \_mscount=#1\_relax
   \_loop \_ifnum\_mscount>1 \_spanA \_repeat}
\_def \_spanA {\_span\_omit \_advance\_mscount by-1 }

\_public \hidewidth \ialign \multispan ;

   \_doc -----------------------------
   Tabbing macros are omitted because they are obsolete.
   \nl
   Indentation and similar macros are defined here: \`\hang`, \`\textindent`,
   \`\item`, \`\itemitem`, \`\narrower`, \`\raggedright`, \`\ttraggedright`, \`\leavevmode`.
   \_cod -----------------------------

\_def \_hang {\_hangindent\_parindent}
\_def \_textindent #1{\_indent\_llap{#1\_enspace}\_ignorespaces}
\_def \_item {\_par\_hang\_textindent}
\_def \_itemitem {\_par\_indent \_hangindent2\_parindent \_textindent}
\_def \_narrower {\_advance\_leftskip\_parindent
   \_advance\_rightskip\_parindent}
\_def \_raggedright {\_rightskip=0pt plus2em
   \_spaceskip=.3333em \_xspaceskip=.5em\_relax}
\_def \_ttraggedright {\_tt \_rightskip=0pt plus2em\_relax} % for use with \tt only
\_def \_leavevmode {\_unhbox\_voidbox} % begins a paragraph, if necessary

\_public \hang \textindent \item \itemitem \narrower \raggedright \ttraggedright \leavevmode ;

   \_doc -----------------------------
   Few character codes are set for backward compatibility. But old obscurities
   (from plain \TeX) based on \`\mathhexbox`
   are not supported -- an error message and recommendation
   to directly using the desired character is implemented by the
   \`\_usedirectly` macro).
   The user can re-define these control sequences of course.
   \_cod -----------------------------

%\chardef\%=`\%
\_let\% = \_pcent  % more natural, can be used in lua codes.
\_chardef\&=`\&
\_chardef\#=`\#
\_chardef\$=`\$
\_chardef\ss="FF
\_chardef\ae="E6
\_chardef\oe="F7
\_chardef\o="F8
\_chardef\AE="C6
\_chardef\OE="D7
\_chardef\O="D8
\_chardef\i="19 \chardef\j="1A % dotless letters
\_chardef\aa="E5
\_chardef\AA="C5
\_chardef\S="9F
\_def\l{\_errmessage{\_usedirectly ł}}
\_def\L{\_errmessage{\_usedirectly Ł}}
%\def\_{\_ifmmode \kern.06em \vbox{\hrule width.3em}\else _\fi} % obsolete
\_protected\_def\_{\_relax \_ifmmode \_hbox{_}\_else _\_fi}
\_def\dag{\_errmessage{\_usedirectly †}}
\_def\ddag{\_errmessage{\_usedirectly ‡}}
\_def\copyright{\_errmessage{\_usedirectly ©}}
%\_def\Orb{\_mathhexbox20D} % obsolete (part of Copyright)
%\_def\P{\_mathhexbox27B}   % obsolete

\_def \_usedirectly #1{Load Unicoded font by \string\fontfam\space and use directly #1}
\_def \_mathhexbox #1#2#3{\_leavevmode \_hbox{$\_math \_mathchar"#1#2#3$}}
\_public \mathhexbox ;

   \_doc -----------------------------
   The \`\_unichars` macro is run when Unicode font family is loaded,
   Unicodes are used instead old plain \TeX/ settings.
   \_cod -----------------------------

\def\_unichars{% Plain TeX character sequences with different codes in Unicode:
   \_chardef\ss=`ß
   \_chardef\ae=`æ \_chardef\AE=`Æ
   \_chardef\oe=`œ \_chardef\OE=`Œ
   \_chardef\o=`ø  \_chardef\O=`Ø
   \_chardef\aa=`å \_chardef\AA=`Å
   \_chardef\l=`ł  \_chardef\L=`Ł
   \_chardef\i=`ı  \_chardef\j=`ȷ
   \_chardef\S=`§  \_chardef\P=`¶
   \_chardef\dag`†
   \_chardef\ddag`‡
   \_chardef\copyright`©
}

   \_doc -----------------------------
   Accents.
   The macros \`\ooalign`, \`\d`, \`\b`, \`\c`, \`\dots`,
   are defined for backward compatibility.
   \_cod -----------------------------

\_def \_oalign #1{\_leavevmode\_vtop{\_baselineskip=\_zo \_lineskip=.25ex
   \_ialign{##\_crcr#1\_crcr}}}
\_def \_oalignA {\_lineskiplimit=\_zo \_oalign}
\_def \_ooalign {\_lineskiplimit=-\_maxdimen \_oalign} % chars over each other
\_def \_shiftx #1{\_dimen0=#1\_kern\_ea\_ignorept \_the\_fontdimen1\_font
   \_dimen0 } % kern by #1 times the current slant
\_def \_d #1{{\_oalignA{\_relax#1\_crcr\_hidewidth\_shiftx{-1ex}.\_hidewidth}}}
\_def \_b #1{{\_oalignA{\_relax#1\_crcr\_hidewidth\_shiftx{-3ex}%
   \_vbox to.2ex{\_hbox{\_char\_macron}\_vss}\_hidewidth}}}
\_def \_c #1{{\_setbox0=\_hbox{#1}\_ifdim\_ht0=1ex\_accent\_cedilla #1%
   \_else\_ooalign{\_unhbox0\_crcr\_hidewidth\_cedilla\_hidewidth}\_fi}}
\_def\_dots{\_relax\_ifmmode\_ldots\_else$\_math\_ldots\_thinsk$\_fi}
\_public \oalign \ooalign \d \b \c \dots ;

   \_doc -----------------------------
   The accent commands like `\v`, `\.`, `\H`, etc. are not defined. Use the
   accented characters directly -- it is the best solution. But you can use the
   macro \`\oldaccents` which defines accented macros.
   \nl
   Much more usable is to define these control sequences for other purposes.
   \nl
   The \`\_uniaccents` macro redeclares codes for accents and it is run when
   Unicode font family is loaded.
   \_cod -----------------------------

\_def \_oldaccents {%
   \_def\`##1{{\_accent\_tgrave  ##1}}%
   \_def\'##1{{\_accent\_tacute  ##1}}%
   \_def\v##1{{\_accent\_caron  ##1}}%
   \_def\u##1{{\_accent\_tbreve  ##1}}%
   \_def\=##1{{\_accent\_macron ##1}}%
   \_def\^##1{{\_accent\_circumflex ##1}}%
   \_def\.##1{{\_accent\_dotaccent ##1}}%
   \_def\H##1{{\_accent\_hungarumlaut ##1}}%
   \_def\~##1{{\_accent\_ttilde  ##1}}%
   \_def\"##1{{\_accent\_dieresis ##1}}%
   \_def\r##1{{\_accent\_ring   ##1}}%
}
\_public \oldaccents ;

% ec-lmr encoding (will be changed after \fontfam macro):
\_chardef\_tgrave=0
\_chardef\_tacute=1
\_chardef\_circumflex=2
\_chardef\_ttilde=3
\_chardef\_dieresis=4
\_chardef\_hungarumlaut=5
\_chardef\_ring=6
\_chardef\_caron=7
\_chardef\_tbreve=8
\_chardef\_macron=9
\_chardef\_dotaccent=10
\_chardef\_cedilla=11

\_def \_uniaccents {% accents with Unicode
   \_chardef\_tgrave="0060
   \_chardef\_tacute="00B4
   \_chardef\_circumflex="005E
   \_chardef\_ttilde="02DC
   \_chardef\_dieresis="00A8
   \_chardef\_hungarumlaut="02DD
   \_chardef\_ring="02DA
   \_chardef\_caron="02C7
   \_chardef\_tbreve="02D8
   \_chardef\_macron="00AF
   \_chardef\_dotaccent="02D9
   \_chardef\_cedilla="00B8
   \_chardef\_ogonek="02DB
   \_let \_uniaccents=\_relax
}

   \_doc -----------------------------
   The plain \TeX/ macros
   \`\hrulefill`, \`\dotfill`, \`\rightarrowfill`, \`\leftarrowfill`,
   \`\downbracefill`, \`\upbracefill`.
   The last four are used in non-Unicode variants of `\overrightarrow`,
   `\overleftarrow`, `\overbrace` and `\underbrace` macros, see
   section~\ref[math-macros].
   \_cod -----------------------------

\_def \_hrulefill {\_leaders\_hrule\_hfill}
\_def \_dotfill {\_cleaders\_hbox{$\_math \_mkern1.5mu.\_mkern1.5mu$}\_hfill}
\_def \_rightarrowfill {$\_math\_smash-\_mkern-7mu%
  \_cleaders\_hbox{$\_mkern-2mu\_smash-\_mkern-2mu$}\_hfill
  \_mkern-7mu\_mathord\_rightarrow$}
\_def \_leftarrowfill {$\_math\_mathord\_leftarrow\_mkern-7mu%
  \_cleaders\_hbox{$\_mkern-2mu\_smash-\_mkern-2mu$}\_hfill
  \_mkern-7mu\_smash-$}

\_mathchardef \_braceld="37A \_mathchardef \_bracerd="37B
\_mathchardef \_bracelu="37C \_mathchardef \_braceru="37D
\_def \_downbracefill {$\_math \_setbox0=\_hbox{$\_braceld$}%
  \_braceld \_leaders\_vrule height\_ht0 depth\_zo \_hfill \_braceru
  \_bracelu \_leaders\_vrule height\_ht0 depth\_zo \_hfill \_bracerd$}
\_def \_upbracefill {$\_math \_setbox0=\_hbox{$\_braceld$}%
  \_bracelu \_leaders\_vrule height\_ht0 depth\_zo \_hfill \_bracerd
  \_braceld \_leaders\_vrule height\_ht0 depth\_zo \_hfill \_braceru$}

\_public \hrulefill \dotfill
   \rightarrowfill \leftarrowfill \downbracefill \upbracefill ;

   \_doc -----------------------------
   The last part of plain \TeX/ macros: \`\magnification`, \`\showhyphens`, \`\bye`.
   Note that math macros are defined in the `math-macros.opm` file
   (section~\ref[math-macros]).
   \_cod -----------------------------

\_def \_magnification {\_afterassignment \_magA \_count255 }
\_def \_magA {\_mag=\_count255 \_truedimen\_hsize \_truedimen\_vsize
  \_dimen\_footins=8truein
}
% only for backward compatibility, but \margins macro is preferred.
\_public \magnification ;

\_def \_showhyphens #1{\_setbox0=\_vbox{\_parfillskip=0pt \_hsize=\_maxdimen \_tenrm
  \_pretolerance=-1 \tolerance=-1 \hbadness=0 \showboxdepth=0 \ #1}}

\_def \_bye {\_par \_vfill \_supereject \_byehook \_end}
\_public \showhyphens \bye ;

   \_doc -----------------------------
   Plain \TeX/ reads `hyphen.tex` with patterns when \^`\language``=0`. We do the same.
   \_cod -----------------------------

\_lefthyphenmin=2 \_righthyphenmin=3 % disallow x- or -xx breaks
\_input hyphen  % en(USenglish) patterns from TeX82

\_endcode % -------------------------------------

2024-04-28 ... \_ corrected
2022-10-11 ... \_unichars extended
2022-02-19 ... \input hyphen.tex moved here (format file is 80k smaller)
2021-09-24 ... \_unichars introduced
2021-04-09 ... \_public\showhyphens, bug fixed
2020-02-14 ... released
