%D \module
%D   [       file=file-mod, % was core-fil,
%D        version=20110701, % 1997.11.15,
%D          title=\CONTEXT\ File Macros,
%D       subtitle=Module Support,
%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 File Macros / Modules}

\unprotect

\registerctxluafile{file-mod}{1.001}

%D \macros
%D   {usemodule}
%D
%D Most of \CONTEXT is preloaded in the format file. Some very
%D domain specific typesetting topics are however dealt with in
%D separate modules, e.g. typesetting of chemical structure
%D formulas. These modules are loaded by:
%D
%D \showsetup{usemodule}
%D
%D More information on the specific modules can be found in
%D their dedicated manuals. We use \type {\next} so that we
%D can \type {\end} in modules.

\unexpanded\def\usemodules
  {\dotripleempty\strc_modules_use}

\let\usemodule   \usemodules
\let\usetexmodule\usemodules

% \def\strc_modules_use[#category][#name][#parameters]%
%   {\pushmacro\currentmodule
%    \pushmacro\currentmoduleparameters
%    \let\currentmoduleparameters\empty
%    \ifthirdargument
%      \singleexpandafter\strc_modules_use_a
%    \else\ifsecondargument
%      \doubleexpandafter\strc_modules_use_b
%    \else
%      \doubleexpandafter\strc_modules_use_c
%    \fi\fi
%    % here we load
%    \popmacro\currentmoduleparameters
%    \popmacro\currentmodule}
%
% \def\strc_modules_use_a[#category][#name][#parameters]%
%   {\doifsomething{#name}
%      {\def\currentmoduleparameters{#parameters}%
%       \processcommalist[#name]{\strc_modules_use_indeed{#category}}}}
%
% \def\strc_modules_use_b[#category][#name][#parameters]%
%   {\doifsomething{#name}
%      {\doifassignmentelse{#name}
%         {\def\currentmoduleparameters{#name}%
%          \processcommalist[#category]{\strc_modules_use_indeed\empty}}
%         {\processcommalist[#name]{\strc_modules_use_indeed{#category}}}}}
%
% \def\strc_modules_use_c[#category][#name][#parameters]%
%   {\processcommalist[#category]{\strc_modules_use_indeed\empty}}
%
% \def\strc_modules_use_indeed#category#name%
%   {\ctxcommand{usemodules("#category","#name","\truefilename{#name}")}}

\def\strc_modules_use[#category][#name][#parameters]% category=t|m|x|p|...
  {\pushmacro\currentmodule
   \pushmacro\currentmodulecategory
   \pushmacro\currentmoduleparameters
   \ifthirdargument
     \edef\currentmodulecategory  {#category}%
     \edef\currentmodule          {#name}%
     \def \currentmoduleparameters{#parameters}%
   \else\ifsecondargument
     \doifassignmentelse{#name}
       {\let\currentmodulecategory   \empty
        \edef\currentmodule          {#category}%
        \edef\currentmoduleparameters{#name}}
       {\edef\currentmodulecategory  {#category}%
        \edef\currentmodule          {#name}%
        \let \currentmoduleparameters\empty}%
   \else
     \let \currentmodulecategory  \empty
     \edef\currentmodule          {#category}%
     \let \currentmoduleparameters\empty
   \fi\fi
   \processcommacommand[\currentmodule]{\strc_modules_use_indeed\currentmodulecategory}%
   \popmacro\currentmoduleparameters
   \popmacro\currentmodulecategory
   \popmacro\currentmodule}

\def\strc_modules_use_indeed#category#name% truefilename moved to lua end
  {\ctxcommand{usemodules("#category","#name")}} % ,"\truefilename{#name}")}}

\installcorenamespace{module}

\let\currentmoduleparameters\empty
\let\currentmodule          \s!unknown

\unexpanded\def\startmodule
  {\doifnextoptionalelse\syst_modules_start_yes\syst_modules_start_nop}

\def\syst_modules_start_yes[#name]%
  {\pushmacro\currentmodule
   \pushmacro\currentmoduleparameters
   \def\currentmodule{#name}}

\def\syst_modules_start_nop#name %
  {\syst_modules_start_yes[#name]}

\unexpanded\def\stopmodule
  {\popmacro\currentmoduleparameters
   \popmacro\currentmodule}

\unexpanded\def\setupmodule
  {\dodoubleempty\syst_modules_setup}

\def\syst_modules_setup[#name][#parameters]%
  {\scratchtoks\expandafter{\currentmoduleparameters}%
   \ifsecondargument
     \getparameters[\??module#name:][#parameters]% internal (defaults)
     \normalexpanded{\getparameters[\??module#name:][\the\scratchtoks]}% loadtime (user)
   \else
     \getparameters[\??module\currentmodule:][#name]% internal (defaults)
     \normalexpanded{\getparameters[\??module\currentmodule:][\the\scratchtoks]}% loadtime (user)
   \fi
   \let\currentmoduleparameters\empty}

% to be tested:
%
% \def\syst_modules_setup[#name][#parameters]%
%   {\ifsecondargument
%      \getparameters[\??module#name:][#parameters]% internal (defaults)
%      \normalexpanded{\getparameters[\??module#name:][\normalunexpanded\expandafter{\currentmoduleparameters}]}% loadtime (user)
%    \else
%      \getparameters[\??module\currentmodule:][#name]% internal (defaults)
%      \normalexpanded{\getparameters[\??module\currentmodule:][\normalunexpanded\expandafter{\currentmoduleparameters}]}% loadtime (user)
%    \fi
%    \let\currentmoduleparameters\empty}

\def\moduleparameter#name#parameter%
  {\csname\??module
     \ifcsname\??module#name:#parameter\endcsname#name:#parameter\fi
   \endcsname}

\letvalue\??module\empty % so we default to empty as with all parameters

\def\currentmoduleparameter{\moduleparameter\currentmodule} % no need for inlining

\unexpanded\def\useluamodule  [#name]{\ctxlua{dofile(resolvers.findctxfile("#name"))}}
\unexpanded\def\luaenvironment #name {\ctxlua{dofile(resolvers.findctxfile("#name"))}}

% \usemodule[newmml]
% \usemodule[newmml][a=b]
% \usemodule[x][newmml]
% \usemodule[x][newmml][a=b]
%
% \startmodule [mathml]
%   \setupmodule[a=c] \relax [\currentmoduleparameter{a}] % user vars will be set afterwards
%   \setupmodule[a=c] \relax [\currentmoduleparameter{a}] % user vars are now forgotten
% \stopmodule

% one can introduce test sections with:
%
% \enablemode[newmml:test:\currentmoduleparameter{test}]
% \startmode[newmml:test:yes} ... \stopmode
%
% these will be ignored unless test=yes
%
% however, a better way is:

\unexpanded\def\startmoduletestsection
  {\begingroup
   \setupmodule % we need to make sure that the vars are set
   \doifelse{\currentmoduleparameter\v!test}\v!yes
     {\endgroup
      \writestatus\currentmodule{loading experimental code}}
     {\endgroup
      \writestatus\currentmodule{skipping experimental code}%
      \gobbleuntil\stopmoduletestsection}}

\let\stopmoduletestsection\donothing

% will become file-run

%D To save memory, we implement some seldomly used commands in a lazy way. Nota
%D bene: such runtime definitions are to be defined global.
%D
%D \starttyping
%D \fetchruntimecommand\showaccents{\f!colorprefix ...}
%D \stoptyping

\installcorenamespace{runtimeloaded}

\unexpanded\def\fetchruntimecommand#1#2%
  {\unexpanded\def#1{\dofetchruntimecommand#1{#2}}}

\def\dofetchruntimecommand#1#2% actually a test on #1 being define would be ok as well
  {\ifcsname\??runtimeloaded#2\endcsname
     % already loaded
   \else
     \global\let#1\undefined
     \startreadingfile
     \startnointerference % \bgroup
     \cleanupfeatures % better \setnormalcatcodes / test first
     \readfile{#2.\mksuffix}\donothing\donothing
     \stopnointerference  % \egroup
     \stopreadingfile
     \letgvalue{\??runtimeloaded#2}\empty
   \fi
   \ifx#1\undefined
     \writestatus\m!system{command \string#1 not found in file #2}%
     \unexpanded\gdef#1{{\infofont[unknown command \string#1]}}%
   \fi
   #1}

%D \macros
%D   {doifolderversionelse}
%D
%D We start with a macro specially for Aditya who wants to be able
%D to use development versions of \MKIV\ for real documents.
%D
%D \starttyping
%D \doifolderversionelse\contextversion{1010.10.10} {OLDER} {OKAY} => OLDER
%D \doifolderversionelse\contextversion{2020.20.20} {OLDER} {OKAY} => OKAY
%D \doifolderversionelse\contextversion{2020}       {OLDER} {OKAY} => OKAY
%D \stoptyping
%D
%D The version pattern is \type {yyyy.mm.dd} (with mm and dd being optional).

\unexpanded\def\doifolderversionelse#parent#child{\ctxcommand{doifolderversionelse("#parent","#child")}}
\unexpanded\def\doifoldercontextelse       #child{\ctxcommand{doifolderversionelse("#child")}}

% obsolete
%
% \def\documentresources{\@@erurl}
%
% \unexpanded\def\setupexternalresources
%   {\dodoubleargument\getparameters[\??er]}
%
% \setupexternalresources
%   [url=]

% new:

\unexpanded\def\useluamodule[#1]{\ctxcommand{useluamodule("#1")}}

\protect \endinput
