%D \module
%D   [       file=spac-pas,
%D        version=2023.06.10,
%D          title=\CONTEXT\ Spacing Macros,
%D       subtitle=Passes,
%D         author=Hans Hagen & Mikael Sundqvist,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Spacing Macros / Passes}

\registerctxluafile{spac-pas}{autosuffix}

%D Here we set up some nano typography features. We have moved the penalties
%D that deal with par building here. We also separated them from the page
%D builder related ones.

\unprotect

% \resetpenalties\orphanpenalties

%integerdef\unknownparpassclass     "000
\integerdef\verylooseparpassclass   "001
\integerdef\looseparpassclass       "002
\integerdef\almostlooseparpassclass "004
\integerdef\barelylooseparpassclass "008
\integerdef\decentparpassclass      "010
\integerdef\barelytightparpassclass "020
\integerdef\almosttightparpassclass "040
\integerdef\tightparpassclass       "080
\integerdef\verytightparpassclass   "100

%  \fitnessdemerits \numexpr \verylooseparpassclass + \almostlooseparpassclass \relax % 5 default

% \integerdef\indecentparpassclasses\numexpr
%       \verylooseparpassclass
%     + \looseparpassclass
%     + \almostlooseparpassclass
%     + \barelylooseparpassclass
%     % \decentparpassclass
%     + \barelytightparpassclass
%     + \almosttightparpassclass
%     + \tightparpassclass
%     + \verytightparpassclass
% \relax

\integerdef\allparpassclasses "FFFF

\integerdef\indecentparpassclasses\numexpr
    \allparpassclasses
  - \decentparpassclass
\relax

\integerdef\almostdecentparpassclasses\numexpr
      \verylooseparpassclass
    + \looseparpassclass
    + \almostlooseparpassclass
    % \decentparpassclass
    + \almosttightparpassclass
    + \tightparpassclass
    + \verytightparpassclass
\relax

\integerdef\looseparpassclasses\numexpr
      \verylooseparpassclass
    + \looseparpassclass
    % \decentparpassclass
    + \almostlooseparpassclass
    + \barelylooseparpassclass
\relax

\integerdef\tightparpassclasses\numexpr
      \verytightparpassclass
    + \tightparpassclass
    % \decentparpassclass
    + \almosttightparpassclass
    + \barelytightparpassclass
\relax

\appendtoks
    \ifcase\linebreakpasses\else
        \linebreakpasses\zerocount
        % maybe always:
        \pretolerance   \plushundred
        \tolerance      \plustwohundred
    \fi
\to \everyforgetall

\startsetups align:pass:none
    \pretolerance   \plushundred
    \tolerance      \plustwohundred
    \parpasses      \zerocount
    \linebreakpasses\zerocount
  % \lettonothing\currentalignpass
\stopsetups

% see spac-pas-imp-tests.mkxl

\lettonothing\currentalignpass

\permanent\def\synchronizealignpass
  {\ifcsname\currentalignpass parpasses\endcsname
     \lastnamedcs % wins
   \else
     \fastsetup\currentalignpass\relax
   \fi}


\permanent\protected\def\setupalignpass[#1]%
  {\cdef\tempstring{align:pass:#1}%
   \ifx\tempstring\currentalignpass\else
     \linebreakpasses\plusone % none will reset this
     \let\currentalignpass\tempstring
     \synchronizealignpass
   \fi}

\appendtoks
    \ifcase\linebreakpasses\orelse\ifempty\currentalignpass\else
      % This is needed just in case we have some dimensions hard coded in a pass
      % although ... we can actually have a state parameter that keeps track of
      % that.
      \synchronizealignpass
    \fi
\to \everybodyfont

%D This sort of belongs here:

\permanent\protected\def\optionalword#1%
  {\removeunwantedspaces\wordboundary\discretionary{}{}{#1}}

%D \starttyping
%D \dostepwiserecurse{80}{100}{1}{\hsize #1mm
%D     Many readers will skim over formulas on their first reading
%D     of your exposition. Therefore, your sentences should flow
%D     smoothly when all but the simplest formulas are replaced by
%D     \quotation {blah} or some other \optionalword {grunting }noise.
%D     \page
%D }
%D \stoptyping

% Musical timestamp: Archive's Call to Arms & Angels (and Super8) in loop mode
% (June 2023, weirdly I had missed those releases in 2022).

% \dorecurse{41}{line #1\par}
% here \singlelinepenalty20000 \updateparagraphpenalties here here

%D Todo:

% \specificationdef \parpassonemoreline \parpasses 3
%     looseness    1
%     tolerance  100
% next
%     tolerance 200
%     hyphenation  1
% next
%     demerits 1
%     emergencystretch 4em
%
% \specificationdef \parpasstwomorelines \parpasses 3
%     looseness    2
%     tolerance  100
% next
%     tolerance  200
%     hyphenation  1
% next
%     demerits 1
%     emergencystretch 8em
%
% \permanent\protected\def\onemoreline {\parpassesexception\parpassonemoreline }
% \permanent\protected\def\twomorelines{\parpassesexception\parpasstwomorelines}

% \startsetups align:pass:default
%     \parpasses 2
%         classes \indecentparpassclasses
%         fitnessdemerits \zerocount
%         next
%         quit
%     \relax
%   % \linebreakpasses\plusone
% \stopsetups

\setnewconstant\c_parpass_granular\parpassidentifier{granular}
\setnewconstant\c_parpass_decent  \parpassidentifier{decent}
\setnewconstant\c_parpass_quality \parpassidentifier{quality}
\setnewconstant\c_parpass_mathbook\parpassidentifier{mathbook}

\specificationdef\granularparpasses
    \parpasses 2 options \constantspecificationoptioncode
        identifier      \c_parpass_granular
        classes         \indecentparpassclasses
        fitnessclasses  \granularfitnessclasses
      next
      quit
    \relax

% \specificationdef\decentparpasses
%     %pretolerance          50
%     %tolerance            150
%     \parpasses    2
%         identifier             \c_parpass_decent
%         threshold              0.05pt
%         tolerance            200
%       next
%         threshold              0.05pt
%         tolerance            500
%         adjustspacing          3
%         adjustspacingstep      1
%         adjustspacingshrink   20
%         adjustspacingstretch  40
%     \relax

\specificationdef\decentparpasses
    %pretolerance          50
    %tolerance            150
    \parpasses 3 options \constantspecificationoptioncode
        identifier             \c_parpass_decent
        tolerance             50
        hyphenation            0
      next
        hyphenation            1
        emergencyfactor        0
        threshold              0.05pt
        tolerance            200
      next
        threshold              0.05pt
        tolerance            500
        adjustspacing          3
        adjustspacingstep      1
        adjustspacingshrink   20
        adjustspacingstretch  40
    \relax

% \specificationdef\qualityparpasses
%     %pretolerance          50
%     %tolerance            150
%     \parpasses    4
%         identifier             \c_parpass_quality
%       % classes                \indecentparpassclasses
%         threshold              0.025pt
%         tolerance            175
%       next
%         threshold              0.025pt
%         tolerance            200
%       next
%         threshold              0.025pt
%         tolerance            250
%       next
%         threshold              0.025pt
%         tolerance            250
%         adjustspacing          3
%         adjustspacingstep      1
%         adjustspacingshrink   20
%         adjustspacingstretch  40
%     \relax

\specificationdef\qualityparpasses
    %pretolerance          50
    %tolerance            150
    \parpasses 5 options \constantspecificationoptioncode
        identifier             \c_parpass_quality
      % classes                \indecentparpassclasses
        threshold              0.025pt
        tolerance             50
        hyphenation            0
      next
        tolerance            175
        hyphenation            1
      next
        threshold              0.025pt
        tolerance            200
      next
        threshold              0.025pt
        tolerance            250
      next
        threshold              0.025pt
        tolerance            250
        adjustspacing          3
        adjustspacingstep      1
        adjustspacingshrink   20
        adjustspacingstretch  40
    \relax

\specificationdef\mathbookparpasses
    \parpasses 5 options \constantspecificationoptioncode
        identifier              \c_parpass_mathbook
        emergencyunit           \userunitcode fs
        tolerance             100
        adjustspacing           0
        emergencyfactor         0
        hyphenation             0
        mathpenaltyfactor   20000
        orphanlinefactors       4 100 250 500 1000
        toddlerpenalties        1 options 2 200 50
      next
        tolerance             200
        adjustspacing           3
        adjustspacingstep       1
        adjustspacingshrink     5
        adjustspacingstretch   10
      next
        tolerance             200
        adjustspacing           3
        adjustspacingshrink    20
        adjustspacingstretch   40
      next
        tolerance             200
        hyphenation             1
        extrahyphenpenalty    200
        adjustspacingshrink    25
        adjustspacingstretch   50
        emergencyfactor       500
        mathpenaltyfactor    1000
      next
        tolerance             300
        extrahyphenpenalty    100
        adjustspacingshrink    30
        adjustspacingstretch   60
        emergencyfactor      1000
    \relax

\installaligncommand{granularpasses}  {\linebreakpasses\plusone\granularparpasses}
\installaligncommand{decentpasses}    {\linebreakpasses\plusone\decentparpasses  }
\installaligncommand{qualitypasses}   {\linebreakpasses\plusone\qualityparpasses }
\installaligncommand{mathbookpasses}  {\linebreakpasses\plusone\mathbookparpasses}

% for old times sake

% \startsetups align:pass:granular
%     \granularparpasses
% \stopsetups
%
% \startsetups align:pass:decent
%     \decentparpasses
% \stopsetups
%
% \startsetups align:pass:quality
%     \qualityparpasses
% \stopsetups
%
% \startsetups align:pass:mathbook
%     \mathbookparpasses
% \stopsetups

\permanent\protected\def\optional#1#2%
  {\optionalboundary#1\wordboundary#2\wordboundary\optionalboundary\zerocount}

\protect
