%D \module
%D   [       file=spac-prf,
%D        version=2015.11.16, % moved from test module mathplus
%D          title=\CONTEXT\ Spacing Macros,
%D       subtitle=Profiling,
%D         author=Hans Hagen,
%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 / Profiling}

%D This is experimental code that we need for a project. The interface and details
%D can change. I moved it into the core because that way we can use it on servers.

% framed: first reflow then profile

\unprotect

\registerctxluafile{spac-prf}{autosuffix}

\definesystemattribute[profilemethod][public]

\installcorenamespace {profile}
\installcorenamespace {profiles}

\installcommandhandler \??profile {profile} \??profile

\setupprofile
  [\c!height=\strutht,
   \c!depth=\strutdp,
   \c!distance=\normallineskip,
   \c!lines=\zerocount,
   \c!factor=\plusone]

\defineprofile
  [\v!strict]
  [\c!method=\v!strict]

\defineprofile
  [\v!fixed]
  [\c!method=\v!fixed]

\defineprofile
  [\v!none]
  [\c!method=\v!none,
   \c!height=\zeropoint,
   \c!depth=\zeropoint,
   \c!distance=\zeropoint,
   \c!factor=\plusone]

\appendtoks
    \ifcstok{\profileparameter\c!define}\v!yes
        \frozen\protected\edefcsname\e!start\currentprofile\endcsname{\spac_profile_start{\currentprofile}}%
        \frozen\protected\defcsname \e!stop \currentprofile\endcsname{\spac_profile_stop}%
    \fi
\to \everydefineprofile

\def\spac_profile_set
  {\clf_setprofile
      name      {\currentprofile}%
      height    \dimexpr\profileparameter\c!height\relax
      depth     \dimexpr\profileparameter\c!depth\relax
      distance  \dimexpr\profileparameter\c!distance\relax
      factor    \numexpr\profileparameter\c!factor\relax
      lines     \numexpr\profileparameter\c!lines\relax
      method    {\profileparameter\c!method}%
   \relax}

\tolerant\protected\def\spac_profile_start#profile#spacer[#S#settings]%
  {\begingroup
   \ifparameter#settings\or
     \cdef\currentprofile{#profile}%
     \setupcurrentprofile[#settings]%
   \orelse\ifhastok={#profile}%
      \let\currentprofile\v!none
      \setupcurrentprofile[#profile]%
   \else
      \cdef\currentprofile{#profile}%
   \fi
   \spac_profile_set
   \profileparameter\c!before}

\protected\def\spac_profile_stop
  {\par % otherwise not applied
   \profileparameter\c!after
   \endgroup}

\permanent\protected\def\startprofile[#S#profile]%
  {\spac_profile_start{#profile}}

\permanent\protected\def\stopprofile
  {\spac_profile_stop}

\permanent\protected\def\setprofile[#profile]%
  {\cdef\currentprofile{#profile}%
   \spac_profile_set}

\permanent\protected\def\resetprofile
  {\c_attr_profilemethod\attributeunsetvalue}

\permanent\protected\def\useprofileparameter#getparameter%
  {\edef\m_spac_profile_asked{#getparameter\c!profile}%
   \ifempty\m_spac_profile_asked
     \resetprofile
   \else
     \setprofile[\m_spac_profile_asked]%
   \fi}

\permanent\tolerant\protected\def\profiledbox[#S#profile]#spacer[#S#settings]%
  {\vbox\bgroup
   \ifparameter#settings\or
     \cdef\currentprofile{#profile}%
     \setupcurrentprofile[#settings]%
   \orelse\ifhastok={#profile}%
      \let\currentprofile\v!none
      \setupcurrentprofile[#profile]%
   \else
      \cdef\currentprofile{#profile}%
   \fi
   \dowithnextbox
     {\profilegivenbox\currentprofile\nextbox
      \unvbox\nextbox
      \egroup}%
     \vbox}

\permanent\protected\def\profilegivenbox#profile#box%
  {\begingroup
   \cdef\currentprofile{#profile}%
   \clf_profilebox
      box      \numexpr#box\relax
      height   \dimexpr\profileparameter\c!height\relax
      depth    \dimexpr\profileparameter\c!depth\relax
      distance \dimexpr\profileparameter\c!distance\relax
      factor   \numexpr\profileparameter\c!factor\relax
      lines    \numexpr\profileparameter\c!lines\relax
      method   {\profileparameter\c!method}%
    \relax
    \endgroup}

\defineprofile[halffixed]   [\v!fixed][\c!factor=\plustwo]
\defineprofile[quarterfixed][\v!fixed][\c!factor=\plusfour]
\defineprofile[eightsfixed] [\v!fixed][\c!factor=\pluseight]

% Finally some follow up on this experiment:

\definesystemattribute[lineprofile]  [public]

\installcorenamespace {lineprofile}

\installcommandhandler \??lineprofile {lineprofile} \??lineprofile

\setuplineprofile
  [\c!method=\v!a,
   \c!step=.5\emwidth, % maybe 2pt
   \c!paragraph=\v!no,
   \c!factor=.125]     % maybe 0.250

\def\spac_line_profile_set
  {\clf_setlineprofile
      name      {\currentlineprofile}%
      step      \dimexpr\lineprofileparameter\c!step\relax
      factor    {\lineprofileparameter\c!factor}%
      method    {\lineprofileparameter\c!method}%
      paragraph {\lineprofileparameter\c!paragraph}%
   \relax}

\permanent\tolerant\protected\def\setlineprofile[#profile]%
  {\cdef\currentlineprofile{#profile}%
   \spac_line_profile_set}

\permanent\protected\def\resetlineprofile
  {\c_attr_lineprofile\attributeunsetvalue}

\permanent\protected\def\setmainlineprofile
  {\lettonothing\currentlineprofile
   \spac_line_profile_set}

\appendtoks
    \c_attr_lineprofile\attributeunsetvalue % or in general resetter
\to \everyforgetall

\protect \endinput

