%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 / Hans Hagen \& Ton Otten}] %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}{1.001} \unprotect %D Version checking: \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. %newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}} \newlinechar=10 \edef\outputnewlinechar{^^J} \edef\operatingsystem {\ctxlua{tex.write(os.platform)}} \def\jobfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.jobfilename or "")}} \def\jobfilesuffix {\ctxlua{tex.sprint(tex.texcatcodes,environment.jobfilesuffix or "")}} \def\inputfilebarename{\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilebarename or "")}} \def\inputfilesuffix {\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilesuffix or "")}} \def\inputfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilename or "")}} \def\outputfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.outputfilename or "")}} \def\initializenewlinechar {\bgroup\newlinechar=10\xdef\outputnewlinechar{^^J}\egroup} \newtoks \everysetupsystem \unexpanded\def\setupsystem {\dosingleargument\dosetupsystem} \def\dosetupsystem[#1]% {\getparameters[\??sv][#1]% \the\everysetupsystem} \appendtoks \edef\outputresolution{\@@svresolution}% \to \everysetupsystem \appendtoks \ifcase\@@svn % % 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 \appendtoks \edef\outputfilename{\@@svfile}% \edef\inputfilename {\@@svinputfile}% \to \everysetupsystem \let\@@jobsuffix\s!unknown \appendtoks \resetsystemmode{suffix-\@@jobsuffix}% \edef\@@jobsuffix{\jobsuffix}% \setsystemmode{suffix-\@@jobsuffix}% \to \everysetupsystem \appendtoks \ctxlua {commands.updatefilenames("\inputfilename","\outputfilename")}% \to \everysetupsystem % 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} \def\setjobfullname#1% #1 = default if not given {\doifelsenothing\jobfilename {\let\jobfullname\empty} {\doif\jobfilesuffix\c!tex{\edef\jobfullname{\jobfilename.#1}}}} \let\systemendofline\outputnewlinechar % will become obsolete \def\systemparameter#1{\executeifdefined{\??sv#1}\empty} %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 %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} {\bgroup % 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!systems{randomseed: \the\scratchcounter}% \egroup}} \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. \def\dostartglobaldefs#1#2% {\edef\!!stringa{\the\globaldefs}% \ifnum\globaldefs#10 \globaldefs-\globaldefs \fi \advance\globaldefs #21 \setevalue{@gd@\the\globaldefs}{\!!stringa}} \def\dostopglobaldefs {\doifdefinedelse{@gd@\the\globaldefs} {\globaldefs\getvalue{@gd@\the\globaldefs}\relax} {\globaldefs\zerocount}} \unexpanded\def\startlocal {\dostartglobaldefs>-} \unexpanded\def\stoplocal {\dostopglobaldefs} \unexpanded\def\startglobal {\dostartglobaldefs<+} \unexpanded\def\stopglobal {\dostopglobaldefs} \def\complexstart[#1]{\bgroup\getvalue{\e!start#1}} \def\complexstop [#1]{\getvalue{\e!stop #1}\egroup} \let\simplestart\bgroup \let\simplestop \egroup \definecomplexorsimple\start \definecomplexorsimple\stop \def\dododefinestartstop[#1][#2]% todo: use indirect commands {\getparameters [\??be#1] [\c!before=, \c!after=, \c!inbetween=, \c!commands=, \c!style=, #2]% \setuvalue{#1}% {\groupedcommand {\getvalue{\??be#1\c!commands}% \dostartattributes{\??be#1}\c!style\c!color} {\dostopattributes \getvalue{\??be#1\c!inbetween}}}% \setvalue{\e!start#1}% {\getvalue{\??be#1\c!before}% \bgroup \getvalue{\??be#1\c!commands}% \dostartattributes{\??be#1}\c!style\c!color\empty}% \setvalue{\e!stop#1}% {\dostopattributes \egroup \getvalue{\??be#1\c!after}}} \def\dodefinestartstop[#1][#2]% {\def\docommand##1{\dododefinestartstop[##1][#2]}% \processcommalist[#1]\docommand} \unexpanded\def\definestartstop {\dodoubleargument\dodefinestartstop} \def\dosetupstartstop[#1][#2]% {\def\docommand##1{\getparameters[\??be##1][#2]}% \processcommalist[#1]\docommand} \unexpanded\def\setupstartstop {\dodoubleargument\dosetupstartstop} % \docommand kan niet worden gebruikt omdat deze macro % soms lokaal wordt gebruikt % te zijner tijd: % % \definevariable {pc} % ProtectedCommand % % \def\executeprotected#1% % {\csname\??pc\string#1\endcsname} % % \unexpanded\def\defineprotected#1#2% % {\expandafter\def\csname\??pc\string#2\endcsname} % % \unexpanded\def\defineunprotected#1% % {\def#1} % % \def\doprotected% % {\ifx\next\define % \let\next=\defineprotected % \else % \let\next=\executeprotected % \fi % \next} % % \def\unexpanded% % {\futurelet\next\doprotected} % % \unexpanded\define\ziezo{ziezo} % % \unexpanded\ziezo \def\complexdefine[#1]#2#3% {\ifx#2\undefined \else \showmessage\m!systems4{\string#2}% \fi \ifcase0#1\def#2{#3}% \or\def#2##1{#3}% \or\def#2##1##2{#3}% \or\def#2##1##2##3{#3}% \or\def#2##1##2##3##4{#3}% \or\def#2##1##2##3##4##5{#3}% \or\def#2##1##2##3##4##5##6{#3}% \or\def#2##1##2##3##4##5##6##7{#3}% \or\def#2##1##2##3##4##5##6##7##8{#3}% \or\def#2##1##2##3##4##5##6##7##8##9{#3}% \else\def#2{#3}% \fi} \definecomplexorsimpleempty\define % \startluacode % local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes % local format, match, gmatch, rep = string.format, 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 % texsprint(ctxcatcodes,format("\\unexpanded\\def\\%s",cmd)) % if #a > 0 then % texsprint(ctxcatcodes,format("{\\do%sempty\\do%s}",empty[#a],cmd)) % texsprint(ctxcatcodes,format("\\def\\do%s",cmd)) % for i=1,#a do % texsprint(ctxcatcodes,"[#",i,"]") % end % texsprint(ctxcatcodes,"{") % for i=#a,1,-1 do % texsprint(ctxcatcodes,format("\\if%sargument",check[i])) % texsprint(ctxcatcodes,format("\\def\\next{\\dodo%s",cmd)) % for j=1,#a-i do % texsprint(ctxcatcodes,format("[%s]",a[j])) % end % for j=1,i do % texsprint(ctxcatcodes,format("[#%s]",j)) % end % texsprint(ctxcatcodes,"}") % if i == 1 then % texsprint(ctxcatcodes,rep("\\fi",#a)) % else % texsprint(ctxcatcodes,"\\else") % end % end % texsprint(ctxcatcodes,"\\next}") % texsprint(ctxcatcodes,format("\\def\\dodo%s",cmd)) % for i=1,#a do % texsprint(ctxcatcodes,"[#",i,"]") % end % end % for i=1,n do % texsprint(ctxcatcodes,"#",#a+i) % end % end % \stopluacode % % \unexpanded\def\define#1#{\ctxlua{commands.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} % \stoptext \unexpanded\def\macroname#1% brrr {\executeifdefined{#1}\empty} \def\usecommands#1% {\bgroup \def\docommand##1{\setbox0\hbox{\getvalue{\string##1}##1}}% \processcommalist[#1]\docommand \egroup} \newif\ifforcefileexpansion % handy for document level overload %D The next implementation is about 4 times as faster than a %D processaction alternative on an string of average length. %D Since this feature is used in XML processing, it made sense %D to support this faster alternative. It's installable as well. %D %D We keep this around for \MKII\ \XML\ but it's not used in \MKIV\ %D code as expansion is controlled in another way there. \def\installexpander#1#2#3% changed, no longer \convert..\to... {\setvalue{\s!do\c!expansion#1l}{#2}% \setvalue{\s!do\c!expansion#1g}{#3}}% % \convertexpanded is obsolete \long\def\doconvertexpanded#1#2#3% #4 % [l|g] \cs {kind} {data} {\csname % that we assign all exp a value \s!do\c!expansion \ifforcefileexpansion \v!yes \else\ifcsname\s!do\c!expansion#3#1\endcsname #3% \else \s!default \fi\fi #1% \endcsname#2}% #3 \long\def\defconvertexpanded {\doconvertexpanded l} \long\def\gdefconvertexpanded{\doconvertexpanded g} \installexpander\v!command \defconvertedcommand \gdefconvertedcommand \installexpander\s!default \defconvertedargument \gdefconvertedargument \installexpander\empty \defconvertedargument \gdefconvertedargument \installexpander\v!no \defconvertedargument \gdefconvertedargument \installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning \installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning \installexpander\v!strict \defreducedargument \gdefreducedargument \installexpander {utf} \defreducedtoutf \gdefreducedtoutf \def\dodefconvertedmeaning#1#2#3% watch the double expansion ! {\bgroup \xdef\@@globalexpanded{#3}% \xdef\@@globalexpanded{\@@globalexpanded}% \egroup #1#2\@@globalexpanded} \def\defconvertedmeaning {\dodefconvertedmeaning\defconvertedcommand} \def\gdefconvertedmeaning{\dodefconvertedmeaning\gdefconvertedcommand} \def\dodefreducedargument#1#2#3% {\begingroup \reducetocoding[raw]% \edef\ascii{#3}% \expandafter\endgroup\expandafter#1\expandafter#2\expandafter{\ascii}} \def\defreducedargument {\dodefreducedargument\edef} \def\gdefreducedargument{\dodefreducedargument\xdef} \protect \endinput