%D \module %D [ file=core-fil, %D version=1997.11.15, %D title=\CONTEXT\ Core Macros, %D subtitle=File 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 Core Macros / File Support} \unprotect %D Files registered as temporary files will be deleted after a %D run by texexec: % \starttext % \immediate\openout\scratchwrite=oeps.tmp % \immediate\write\scratchwrite{oeps} % \immediate\closeout\scratchwrite % \registertempfile{oeps.tmp} % \typefile{oeps.tmp} % \stoptext \let\usedtempfile\gobbleoneargument \def\registertempfile#1{\immediatewriteutility{f t {#1}}} %D \macros %D {definefilesynonym} %D %D One of the problems with loading files is that their names %D can depend on the interface language. We therefore need a %D method to define filesynonyms. The actual synonyms are %D defined elsewhere, but look like: %D %D \starttyping %D \definefilesynonym [chemic] [chemie] %D \definefilesynonym [einheit] [unit] %D \definefilesynonym [unit] [unit] %D \stoptyping %D %D So we can say in english: %D %D \starttyping %D \usemodules[pictex,chemic,unit] %D \stoptyping %D %D and in dutch: %D %D \starttyping %D \usemodules[pictex,chemie,unit] %D \stoptyping % will be redone in mkiv \def\definefilesynonym {\dodoubleempty\dodefinefilesynonym} \def\dodefinefilesynonym[#1][#2]% {\ifundefined{\??fs#1}\else \doifnotvalue{\??fs#1}{#2}{\showmessage\m!files1{#1 (#2),\getvalue{\??fs#1}}}% \fi \doifelse{#1}{#2}{\letbeundefined{\??fs#1}{#2}}{\setevalue{\??fs#1}{#2}}} %D \macros %D {definefilefallback} \def\definefilefallback {\dodoubleargument\dodefinefilefallback} \def\dodefinefilefallback[#1][#2]% {\doifnotfile{#1} {\def\docommand##1{\doiffile{##1}{\definefilesynonym[#1][##1]\quitcommalist}}% \processcommalist[#2]\docommand}} %D \macros %D {truefilename} %D %D At the system level such a filename can be called upon by %D saying: %D %D \starttyping %D \truefilename{filename/filesynonym} %D \stoptyping %D %D The implementation shows that nesting is supported. \def\truefilename#1% {\ifundefined{\??fs#1}#1\else\truefilename{\csname\??fs#1\endcsname}\fi} %D \macros %D {makeshortfilename} %D %D To prevent cross platform problems with filenames, we %D lowercase them as well as only use the first 8~characters. %D %D \starttyping %D \def\domakeshortfilename[#1#2#3#4#5#6#7#8#9]% %D {\lowercase{\edef\shortfilename{#1#2#3#4#5#6#7#8.}}% %D \expandafter\beforesplitstring\shortfilename\at.\to\shortfilename} %D %D \def\makeshortfilename[#1]% %D {\edef\fullfilename{#1.........}% %D \expanded{\domakeshortfilename[\fullfilename]}} %D \stoptyping %D %D In 2005 there is no need for the 8~character limit any more, so: \def\makeshortfilename[#1]% no need for further cleanup and shortening {\lowercase{\edef\shortfilename{#1.}}% \expandafter\beforesplitstring\shortfilename\at.\to\shortfilename} %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. %D %D In \MKIV\ we load the \type {mkiv} file when there is a \type %D {tex} file on the same path but in \MKII\ we start with the \type %D {tex} file as in many cases a \type {mkii} will be the same as an %D (old) \type {tex} one simply because we don't update drastically %D (or load a mark file indirectly). \newconditional\moduleisloaded \def\dododousemodules#1#2% no \unprotect/\protect when loading, {\relax % since we need to use ? ! unprotected \ifconditional\moduleisloaded % sometimes (see xtag-map) \let\next\relax % or: \expandafter\gobbleoneargument \else \makeshortfilename[#1\truefilename{#2}]% beware: *- is not part of syn \doifelseflagged\shortfilename {\showmessage\m!systems7{#2 (line \number\inputlineno)}% \settrue\moduleisloaded \let\next\relax} {\doglobal\setflag\shortfilename \def\next {\startreadingfile \readsysfile\shortfilename {\showmessage\m!systems5{#2}\settrue\moduleisloaded} {\readsysfile{\shortfilename.\mksuffix} % new {\showmessage\m!systems5{#2 (\mksuffix)}\settrue\moduleisloaded} \donothing}% \stopreadingfile}}% \fi \next} \def\dodousemodules#1#2% {\setfalse\moduleisloaded \doifelsenothing{#1} {\dododousemodules\f!moduleprefix {#2}% \dododousemodules\f!privateprefix{#2}% \dododousemodules\f!styleprefix {#2}% \dododousemodules\f!xstyleprefix {#2}% \dododousemodules\f!thirdprefix {#2}% \dododousemodules\empty {#2}}% new, fall back on raw name {\dododousemodules{#1-}{#2}}% \ifconditional\moduleisloaded\else \showmessage\m!systems6{#2}% \appendtoks\showmessage\m!systems6{#2}\to\everynotabene \fi} % \def\usemodules % {\dodoubleempty\dousemodules} % % \def\dousemodules[#1][#2]% % {\ifsecondargument % \doifelsenothing{#2} % {\let\next\relax} % {\def\next{\processcommalist[#2]{\dodousemodules{#1}}}}% % \else % \def\next{\usemodules[][#1]}% % \fi % \next} % % \let\usemodule\usemodules \def\usemodules {\dotripleempty\dousemodules} \def\dousemodules[#1][#2][#3]% {\pushmacro\currentmodule \pushmacro\currentmoduleparameters \let\currentmoduleparameters\empty \ifthirdargument \doifelsenothing{#2} {\let\next\relax} {\def\currentmoduleparameters{#3}% \def\next{\processcommalist[#2]{\dodousemodules{#1}}}}% \else\ifsecondargument \doifelsenothing{#2} {\let\next\relax} {\doifassignmentelse{#2} {\def\currentmoduleparameters{#2}% \def\next{\processcommalist[#1]{\dodousemodules{}}}} {\def\next{\processcommalist[#2]{\dodousemodules{#1}}}}}% \else \def\next{\processcommalist[#1]{\dodousemodules{}}}% \fi\fi \next \popmacro\currentmoduleparameters \popmacro\currentmodule} \let\currentmoduleparameters\empty \let\currentmodule \s!unknown \def\startmodule {\doifnextoptionalelse\dostartmodule\nostartmodule} \def\nostartmodule #1 % {\dostartmodule[#1]} \def\dostartmodule[#1]% {\pushmacro\currentmodule \pushmacro\currentmoduleparameters \def\currentmodule{#1}} \def\stopmodule {\popmacro\currentmoduleparameters \popmacro\currentmodule} \def\setupmodule {\dodoubleempty\dosetupmodule} \def\dosetupmodule[#1][#2]% {\scratchtoks\expandafter{\currentmoduleparameters}% \ifsecondargument \getparameters[\??md:#1:][#2]% \expanded{\getparameters[\??md:#1:][\the\scratchtoks]}% \else \getparameters[\??md:\currentmodule:][#1]% \expanded{\getparameters[\??md:\currentmodule:][\the\scratchtoks]}% \fi \let\currentmoduleparameters\empty} \def\moduleparameter #1#2{\executeifdefined{\??md:#1:#2}\s!empty} \def\currentmoduleparameter#1{\executeifdefined{\??md:\currentmodule:#1}\s!empty} % \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: \let\stopmoduletestsection\donothing \def\startmoduletestsection {\bgroup \setupmodule % we need to make sure that the vars are set \doifelse{\currentmoduleparameter\v!test}\v!yes {\egroup \writestatus{\currentmodule}{loading experimental code}} {\egroup \writestatus{\currentmodule}{skipping experimental code}% \gobbleuntil\stopmoduletestsection}} %D We also support a singular call, which saves us for %D frustrations when we do a typo. \let\usemodule=\usemodules % %D The definition shows that the language specific settings % %D are activated after loading all the modules specified. %D \macros %D {ifprotectbuffers, bufferprefix, %D TEXbufferfile, MPgraphicfile} %D %D The next switch enables protection of temporary filenames, %D which is needed when we process more files on one path at %D the same time. \newif\ifprotectbuffers \def\bufferprefix{\ifprotectbuffers\jobname-\fi} % The following filenames are defined here: \def\TEXbufferfile #1{\bufferprefix#1.\f!temporaryextension} \def\MPgraphicfile {\bufferprefix mp\ifMPrun run\else graph\fi} % not needed in luatex \def\convertMPcolorfile{\bufferprefix metacmyk.tmp} %D To save memory, we implement some seldomly used commands %D in a lazy way. Nota bene: such runtime definitions are %D global. %D %D \starttyping %D \fetchruntimecommand\showaccents{\f!encodingprefix ...} %D \stoptyping \def\fetchruntimecommand#1#2% {\def#1{\dofetchruntimecommand#1{#2}}} \def\dofetchruntimecommand#1#2% {\doifnotflagged{#2} {\let#1\undefined \startreadingfile \startnointerference % \bgroup \cleanupfeatures % better \setnormalcatcodes / test first \readfile{#2.\mksuffix}\donothing\donothing \stopnointerference % \egroup \stopreadingfile \doglobal\setflag{#2}}% \ifx#1\undefined \writestatus\m!systems{command \string#1 not found in file #2}% \def#1{{\infofont[unknown command \string#1]}}% \fi #1} %D Experimental: \let\checkpreprocessor\relax %D To be documented and probably moved \def\documentresources{\@@erurl} \def\setupexternalresources {\dodoubleargument\getparameters[\??er]} \setupexternalresources [url=] %D Goodie: \unexpanded\def\continueifinputfile#1{\doifnotfile{#1}{\endinput}} %D This module will be perfected / changed / weeded. \protect \endinput