%D \module
%D   [       file=core-sys, % moved from main-001
%D        version=1997.03.31,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=System,
%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.

% we need to mkiv-ize this file !

\writestatus{loading}{ConTeXt Core Macros / System}

\registerctxluafile{core-sys}{}

\unprotect

%D Version checking:

\unexpanded\def\newcontextversion#1%
  {\doifelse{#1}\contextversion
      {\let\newcontextversion\gobbleoneargument}
      {\writeline
       \writestatus{Fatal    Error}{Your format does not match the base files!}%
       \writeline
       \writestatus{Format Version}{\contextversion\space\contextmark}%
       \writestatus{Files  Version}{#1}%
       \batchmode
       \normalend}}

%D End of lines to the output. \TEX\ will map this onto the platform specific
%D line ending. I hate this mess.

\let\operatingsystem\clf_operatingsystem

%D The jobname is what gets loaded by the cont-yes stub file. This name
%D also determines the name of tuc etc files.

\let\jobfilefullname\clf_jobfilefullname
\let\jobfilename    \clf_jobfilename
\let\jobfilesuffix  \clf_jobfilesuffix

%D However, that one can itself load another file.

\let\inputfilebarename  \clf_inputfilebarename
\let\inputfilerealsuffix\clf_inputfilerealsuffix
\let\inputfilesuffix    \clf_inputfilesuffix
\let\inputfilename      \clf_inputfilename

%D The output name is only used for some checking.

\let\outputfilename\clf_outputfilename

\installcorenamespace{system}

\installdirectcommandhandler \??system {system}

\appendtoks
%   \edef\outputfilename  {\directsystemparameter\c!file      }%
%   \edef\inputfilename   {\directsystemparameter\c!inputfile }%
\to \everysetupsystem

\appendtoks
    \ifcase\directsystemparameter\c!n\relax
        %                        % 0 : unknown
    \or
        \setsystemmode\v!first   % 1 : first run
    \or
        %                        % 2 : successive run
    \or
        \setsystemmode\v!first   % 3 : first and only run
    \or
        \setsystemmode\v!last    % 4 : (extra) last run
    \fi
\to \everysetupsystem

\let\m_system_job_suffix\s!unknown

\appendtoks
    \resetsystemmode{suffix-\m_system_job_suffix}%
    \edef\m_system_job_suffix{\jobsuffix}%
    \setsystemmode{suffix-\m_system_job_suffix}%
\to \everysetupsystem

% \appendtoks
%     \ctxcommand{updatefilenames("\jobame","\inputfilename","\outputfilename")}%
% \to \everysetupsystem

\newconditional\prerollrun % when true it means that we have a forced number of runs

% Some mechanisms (see x-res-01) use either \jobfilename or
% \jobfilename.somesuffix, in which case we need to use the
% full name if given or a default (like \jobfilename.xml);
% this comes down to replacing the default tex suffix.

\def\jobfullname{\jobfilename.\jobfilesuffix}

\unexpanded\def\setjobfullname#1% #1 = default if not given
  {\doifelsenothing\jobfilename
     {\let\jobfullname\empty}
     {\doif\jobfilesuffix\c!tex{\edef\jobfullname{\jobfilename.#1}}}}

%D There are a couple of system states avaiable:
%D
%D \starttabulate [|T|T|]
%D     \NC \type{\jobname}           \NC \jobname           \NC \NR
%D     \NC \type{\jobfilename}       \NC \jobfilename       \NC \NR
%D     \NC \type{\jobfilesuffix}     \NC \jobfilesuffix     \NC \NR
%D     \NC \type{\inputfilename}     \NC \inputfilename     \NC \NR
%D     \NC \type{\inputfilebarename} \NC \inputfilebarename \NC \NR
%D     \NC \type{\inputfilesuffix}   \NC \inputfilesuffix   \NC \NR
%D     \NC \type{\outputfilename}    \NC \outputfilename    \NC \NR
%D     \NC \type{\operatingsystem}   \NC \operatingsystem   \NC \NR
%D \stoptabulate

\appendtoks
    \edef\outputresolution{\directsystemparameter\c!resolution}%
\to \everysetupsystem

%D The system modes set by the setup command can be used in
%D situations like:
%D
%D \starttyping
%D \startmode[*first]
%D   \executesystemcommand{cleanupxml text.xml clean-text.xml}
%D \stopmode
%D
%D \starttext
%D   \typefile{clean-text.xml}
%D \stoptext
%D \stoptyping

\unexpanded\def\setuprandomize[#1]%
  {\doifsomething{#1}
     {\begingroup
      % tex's time is in minutes
      \scratchcounter\normaltime
      \processaction
        [#1]
        [  \v!small=>\divide\scratchcounter 15, %  900,
          \v!medium=>\divide\scratchcounter 30, % 1800,
             \v!big=>\divide\scratchcounter 60, % 3600,
          \v!normal=>\getnewrandomseed\scratchcounter,
         \s!default=>\getnewrandomseed\scratchcounter,
         \s!unknown=>\scratchcounter#1]%
      \expanded{\setrandomseed{\the\scratchcounter}}%
    % \writestatus\m!system{randomseed: \the\scratchcounter}%
      \endgroup}}

\setupsystem
  [\c!directory=,
   \c!n=0, % 0:unknown 1: one run 2: first 3: successive 4: final run
   \c!resolution=600,% in dpi, no unit in mkiv
 % \c!random=, % obsolete here
 % \c!file=\jobname,
 % \c!inputfile=\outputfilename,
   \c!type=unix, % windows is normally less sensitive to handle
   \c!bodyfont=\normalizedlocalbodyfontsize] % of iets anders

%D Remark: windows programs normally handle \type {cr|lf|crlf} but unix
%D is more picky, so we default to the \type {cr}. I never understood why
%D \type {crlf} was not used in all systems, since it makes most sense.
%D But anyway, in \MKIV\ we avoid most of the complications anyway as we
%D deal with much at the \LUA\ end.

\unexpanded\def\start
  {\dosingleempty\syst_start}

\def\syst_start
  {\bgroup
   \iffirstargument
     \expandafter\syst_start_yes
   \else
     \expandafter\syst_start_nop
   \fi}

\def\syst_start_yes[#1]%
 {\edef\m_syst_start_stop{#1}%
  \ifx\m_syst_start_stop\empty
    \let\syst_stop_indeed\donothing
  \else\ifcsname\e!start\m_syst_start_stop\endcsname
    \expandafter\let\expandafter\syst_stop_indeed\csname\e!stop\m_syst_start_stop\endcsname
    \csname\e!start\m_syst_start_stop\expandafter\expandafter\expandafter\endcsname
  \else
    \let\syst_stop_indeed\donothing
  \fi\fi}

\def\syst_start_nop[#1]%
  {\let\syst_stop_indeed\donothing}

\unexpanded\def\stop
  {\syst_stop_indeed
   \egroup}

% \c!before \c!after \c!inbetween \c!commands \c!style \c!color

\installcorenamespace{startstop}

\installcommandhandler \??startstop {startstop} \??startstop

\appendtoks
    \setuevalue{\e!start\currentstartstop}{\syst_startstop_start {\currentstartstop}}%
    \setuevalue{\e!stop \currentstartstop}{\syst_startstop_stop  {\currentstartstop}}%
    \setuevalue        {\currentstartstop}{\syst_startstop_indeed{\currentstartstop}}%
\to \everydefinestartstop

\ifdefined\dotagconstruct \else \let\dotagconstruct\relax \fi

\unexpanded\def\syst_startstop_start#1%
  {\namedstartstopparameter{#1}\c!before\relax
   \bgroup
   \def\currentstartstop{#1}%
   % we will keep this for a while:
   \startstopparameter\c!commands\relax % obsolete
   % this is the new method:
   \usesetupsparameter\startstopparameter\relax % only in the display version
   \dostarttagged\t!construct\currentstartstop
   \usestartstopstyleandcolor\c!style\c!color
   \dotagconstruct}

\unexpanded\def\syst_startstop_stop#1%
  {\dostoptagged
   \egroup
   \namedstartstopparameter{#1}\c!after\relax}

\unexpanded\def\syst_startstop_indeed#1%
  {\groupedcommand
     {\def\currentstartstop{#1}%
      \startstopparameter\c!commands\relax % better: setups so that will show op soon
      \dostarttagged\t!construct\currentstartstop
      \usestartstopstyleandcolor\c!style\c!color
      \startstopparameter\c!left\relax}
     {\def\currentstartstop{#1}% safeguard, not really needed
      \startstopparameter\c!right\relax
      \dostoptagged
      \startstopparameter\c!inbetween\relax}}

% \definestartstop[tracing][\c!style=\tt]

% \unexpanded\def\ignorestartstop[#1]%
%   {\unexpanded\expandafter\def\csname\e!start#1\expandafter\endcsname\expandafter
%      {\expandafter\gobbleuntil\csname\e!stop#1\endcsname}}
%
% \ignorestartstop[bagger]

\installcorenamespace{highlight}

\installcommandhandler \??highlight {highlight} \??highlight % we could do with less

\setuphighlight
  [\c!command=\v!yes]

\appendtoks
    \edef\p_command{\highlightparameter\c!command}%
    \ifx\p_command\v!yes
        \setuevalue\currenthighlight{\typo_highlights_indeed{\currenthighlight}}%
    \fi
\to \everydefinehighlight

\ifdefined\dotaghighlight \else \let\dotaghighlight\relax \fi

\unexpanded\def\typo_highlights_indeed#1% inline style/color switch
  {\dontleavehmode\groupedcommand % otherwise wrong par number in tags
     {\def\currenthighlight{#1}%
      \dostarttagged\t!highlight\currenthighlight
      \usehighlightstyleandcolor\c!style\c!color
      \dotaghighlight}
     {\dostoptagged}}

\unexpanded\def\highlight[#1]%
  {\typo_highlights_indeed{#1}}

\unexpanded\def\starthighlight[#1]%
  {\begingroup
   \def\currenthighlight{#1}%
   \dostarttagged\t!highlight\currenthighlight
   \usehighlightstyleandcolor\c!style\c!color
   \dotaghighlight}

\unexpanded\def\stophighlight
  {\dostoptagged
   \endgroup}

\let\directhighlight\typo_highlights_indeed

\unexpanded\def\defineexpandable
  {\doifelsenextoptional
     {\syst_basics_define_yes\def}%
     {\syst_basics_define_nop\def}}

\unexpanded\def\define
  {\doifelsenextoptional
     {\syst_basics_define_yes{\unexpanded\def}}%
     {\syst_basics_define_nop{\unexpanded\def}}}

\unexpanded\def\syst_basics_define_yes#1[#2]#3#4%
  {\ifdefined#3%
     \showmessage\m!system4{\string#3}%
   \fi
   \ifcase0#2\relax
     #1#3{#4}\or
     #1#3##1{#4}\or
     #1#3##1##2{#4}\or
     #1#3##1##2##3{#4}\or
     #1#3##1##2##3##4{#4}\or
     #1#3##1##2##3##4##5{#4}\or
     #1#3##1##2##3##4##5##6{#4}\or
     #1#3##1##2##3##4##5##6##7{#4}\or
     #1#3##1##2##3##4##5##6##7##8{#4}\or
     #1#3##1##2##3##4##5##6##7##8##9{#4}\else
     #1#3{#4}\fi}

\unexpanded\def\syst_basics_define_nop#1#2#3%
  {\ifdefined#2%
     \showmessage\m!system4{\string#2}%
   \fi
   #1#2{#3}}

% new:
%
% \checked\def \whatever#alpha#beta{#alpha + #beta}
% \checked\edef\whatever#alpha#beta{#alpha + #beta}

\unexpanded\def\unique#1#2%
  {\ifdefined#2%
     \showmessage\m!system4{\string#2}%
     \expandafter#1\expandafter\gobbleddefinition
   \else
     \expandafter#1%
   \fi#2}

\unexpanded\def\checked#1#2%
  {\ifdefined#2%
     \showmessage\m!system4{\string#2}%
   \fi
   #1#2}

% \startluacode
%     local formatters = string.formatters
%     local contextsprint, ctxcatcodes, prtcatcodes = context.sprint, tex.ctxcatcodes, tex.prtcatcodes
%     local match, gmatch, rep = string.match, string.gmatch, string.rep
%     local empty = {
%         "single",
%         "double",
%         "triple",
%         "quadruple",
%         "quintuple",
%     }
%     local check = {
%         "first",
%         "second",
%         "third",
%         "fourth",
%         "fifth",
%     }
%     function commands.define(str)
%         -- we could store the defaults in lua and call lua instead but why bother
%         local arg, cmd = match(str,"(.*)\\(.-)$")
%         local a = { }
%         for s in gmatch(arg,"%[(.-)%]") do
%             a[#a+1] = s
%         end
%         local n = tonumber(a[#a])
%         if n then
%             a[#a] = nil
%         else
%             n = 0
%         end
%         contextsprint(ctxcatcodes,formatters["\\unexpanded\\def\\%s"](cmd))
%         if #a > 0 then
%             contextsprint(prtcatcodes,formatters["{\\do%sempty\\user_defined_%s}"](empty[#a],cmd))
%             contextsprint(prtcatcodes,formatters["\\def\\user_defined_%s"](cmd))
%             for i=1,#a do
%                 contextsprint(ctxcatcodes,formatters["[#%s]"](i))
%             end
%             contextsprint(ctxcatcodes,"{")
%             for i=#a,1,-1 do
%                 contextsprint(ctxcatcodes,formatters["\\if%sargument"](check[i]))
%                 contextsprint(prtcatcodes,formatters["\\def\\next{\\user_defined_indeed_%s"](cmd))
%                 for j=1,#a-i do
%                     contextsprint(ctxcatcodes,formatters["[%s]"](a[j]))
%                 end
%                 for j=1,i do
%                     contextsprint(ctxcatcodes,formatters["[#%s]"](j))
%                 end
%                 contextsprint(ctxcatcodes,"}")
%                 if i == 1 then
%                     contextsprint(ctxcatcodes,rep("\\fi",#a))
%                 else
%                     contextsprint(ctxcatcodes,"\\else")
%                 end
%             end
%             contextsprint(ctxcatcodes,"\\next}")
%             contextsprint(prtcatcodes,formatters["\\def\\user_defined_indeed_%s"](cmd))
%             for i=1,#a do
%                 contextsprint(ctxcatcodes,formatters["[#%s]"](i))
%             end
%         end
%         for i=1,n do
%             contextsprint(ctxcatcodes,formatters["#%s"](#a+i))
%         end
%     end
% \stopluacode
%
% \unexpanded\def\define#1#{\ctxcommand{define([[\detokenize{#1}]])}}
%
% \starttext
%     \define[2]\whatevera{#1+#2}
%     \whatevera{A}{B}
%     \define[me][too][2]\whateverb{#1+#2+#3+#4}
%     \whateverb[A]{B}{C}
%     \whateverb[A][B]{C}{D}
%     \define[alpha][beta][gamma][delta]\whateverc{#1+#2+#3+#4}
%     \whateverc[P][Q]
% \stoptext

%D This is a checked variant of \type {\getvalue}.

\unexpanded\def\macroname#1% brrr
% {\csname\ifcsname#1\endcsname#1\else\s!empty\fi\endcsname}
  {\begincsname#1\endcsname}

% %D A weird one that I probably needed once, so it might as well become
% %D obsolete.
%
% \unexpanded\def\usecommands#1%
%   {\begingroup
%    \def\docommand##1{\setbox\scratchbox\hbox{\csname\string##1\endcsname##1}}%
%    \processcommalist[#1]\docommand
%    \endgroup}

\unexpanded\def\syst_log_indeed#1#2#3%
  {\ctxcommand{systemlog("#1","#2",\!!bs#3\!!es)}}

\let\systemlog\syst_log_indeed

\unexpanded\def\systemlogfirst
  {\ifcase\directsystemparameter\c!n\relax
     \expandafter\syst_log_indeed
   \or
     \expandafter\syst_log_indeed
   \else
     \expandafter\gobblethreearguments
   \fi}

\unexpanded\def\systemloglast
  {\ifcase\directsystemparameter\c!n\relax
     \expandafter\syst_log_indeed
   \or
      \expandafter\gobblethreearguments
   \or
     \expandafter\gobblethreearguments
   \or
     \expandafter\gobblethreearguments
   \or
     \expandafter\syst_log_indeed
   \fi}

\protect \endinput
