% language=uk

\startcomponent hybrid-bibtex

\environment hybrid-environment

\startchapter[title={Upto \ConTeXt\ MkVI}]

\startsection [title={Introduction}]

No, this is not a typo: \MKVI\ is the name of upcoming
functionality but with an experimental character. It is
also a playground. Therefore this is not the final story.

\stopsection

\startsection [title={Defining macros}]

When you define macros in \TEX, you use the \type {#} to indicate
variables. So, you code can end up with the following:

\startbuffer
\def\MyTest#1#2#3#4%
  {\dontleavehmode
   \dostepwiserecurse{#1}{#2}{#3}
     {\ifnum\recurselevel>#1 \space,\fi
      \recurselevel: #4\space}%
   .\par}
\stopbuffer

\typebuffer

This macro is called with 4 arguments:

\starttyping
\MyTest{3}{8}{1}{Hi}
\stoptyping

However, using numbers as variable identifiers might not have your
preference. It makes perfect sense if you keep in mind that \TEX\
supports delimited arguments using arbitrary characters. But in
practice, and especially in \CONTEXT\ we use only a few well
defined variants. \ This is why you can also imagine:

\startbuffer
\def\MyTest#first#last#step#text%
  {\dontleavehmode
   \dostepwiserecurse{#first}{#last}{#step}
     {\ifnum\recurselevel>#first \space,\fi
      \recurselevel: #text}%
   .\par}
\stopbuffer

\typebuffer

In order for this to work, you need to give your file the
suffix \type {mkvi} or you need to put a directive on the
first line:

\starttyping
% macros=mkvi
\stoptyping

You can of course use delimited arguments as well, given that
the delimiters are not letters.

\startbuffer
\def\TestOne[#1]%
  {this is: #1}

\def\TestTwo#some%
  {this is: #some}

\def\TestThree[#whatever][#more]%
  {this is: #more and #whatever}

\def\TestFour[#one]#two%
  {\def\TestFive[#alpha][#one]%
     {#one, #two, #alpha}}
\stopbuffer

\typebuffer \mkvibuffer

You can also use the following variant which is already present
for a while but not that much advertised. This method ignores all
spaces in definitions so if you need one, you have to use \type
{\space}.

\startbuffer
\starttexdefinition TestSix #oeps

  here: #oeps

\stoptexdefinition
\stopbuffer

\typebuffer \mkvibuffer

These commands work as expected:

\startbuffer
\startlines
  \TestOne  [one]
  \TestTwo  {one}
  \TestThree[one][two]
  \TestFour [one]{two}
  \TestFive [one][two]
  \TestSix  {one}
\stoplines
\stopbuffer

\typebuffer

% We need to obey catcode changes (we can use \getbuffer
% instead).

\getbuffer

You can use buffers to collect definitions. In that case you can force
preprocessing of the buffer with \type {\mkvibuffer[name]}.

\stopsection

\startsection[title={Implementation}]

This functionality is not hard codes in the \LUATEX\ engine as
this is not needed at all. We just preprocess the file before it
gets loaded and this is something that is relatively easy to
implement. Already early in the development of \LUATEX\ we have
decided that instead of hard coding solutions, opening up makes
more sense.

One of the first mechanisms that were opened up was
file IO. This means that when a file is opened, you can decide
to intercept lines and process them before passing them to the
traditional built in input parser. The user can be completely
unaware of this. In fact, as \LUATEX\ only accepts \UTF-8
preprocessing will likely happen already when other input
encodings are used.

The following helper functions are available:

\starttyping
local result = resolvers.macros.preprocessed(str)
\stoptyping

This function returns a string with all named parameters
replaced.

\starttyping
resolvers.macros.convertfile(oldname,newname)
\stoptyping

This function converts a file into a new one.

\starttyping
local result = resolvers.macros.processmkvi(str,filename)
\stoptyping

This function converts the string but only if the suffix
of the filename is \type {mkvi} or when the first line of
the string is a comment line containing \type {macros=mkvi}.
Otherwise the original string is returned. The filename
is optional.

\stopsection

\startsection[title=A few details]

Imagine that you want to do this:

\starttyping
\def\test#1{before#1after}
\stoptyping

When we use names this could look like:

\starttyping
\def\test#inbetween{before#inbetweenafter}
\stoptyping

and that is not going to work out well. We could be more liberal
with spaces, like

\starttyping
\def\test #inbetween {before #inbetween after}
\stoptyping

but then getting spaces in the output before or after variables
would get more complex. However, there is a way out:

\starttyping
\def\test#inbetween{before#{inbetween}after}
\stoptyping

As the sequence \type +#{+ has a rather low probablility of
showing up in a \TEX\ source file, this kind of escaping is part
of the game. So, all the following cases are valid:

\starttyping
\def\test#oeps{... #oeps ...}
\def\test#oeps{... #{oeps} ...}
\def\test#{main:oeps}{... #{main:oeps} ...}
\def\test#{oeps:1}{... #{oeps:1} ...}
\def\test#{oeps}{... #oeps ...}
\stoptyping

When you use the braced variant, all characters except braces
are acceptable as name, optherwise only lowercase and uppercase
characters are permitted.

Normally \TEX\ uses a couple of special tokens like \type {^}
and \type {_}. In a macro definition file you can avoid these
by using primitives:

\starttabulate[|cT|lT|]
\NC \letterampersand           \NC \tex{aligntab}          \NC \NR
\NC \letterhash                \NC \tex{alignmark}         \NC \NR
\NC \letterhat                 \NC \tex{Usuperscript}      \NC \NR
\NC \letterunderscore          \NC \tex{Usubscript}        \NC \NR
\NC \letterdollar              \NC \tex{Ustartmath}        \NC \NR
\NC \letterdollar              \NC \tex{Ustopmath}         \NC \NR
\NC \letterdollar\letterdollar \NC \tex{Ustartdisplaymath} \NC \NR
\NC \letterdollar\letterdollar \NC \tex{Ustopdisplaymath}  \NC \NR
\stoptabulate

Especially the \type {aligntab} is worth noticing: using that
one directly in a macro definition can result in unwanted
replacements, depending whether a match can be found. In practice
the following works out well

\starttyping
\def\test#oeps{test:#oeps \halign{##\cr #oeps\cr}}
\stoptyping

You can use \UTF-8\ characters as well. For practical reasons this
is only possible with the braced variant.

\starttyping
\def\blä#{blá}{blà:#{blá}}
\stoptyping

There will probably be more features in future versions but each
of them needs careful consideration in order to prevent
interferences.

\stopsection

\startsection[title=Utilities]

There is currently one utility (or in fact an option to an existing
utility):

\starttyping
mtxrun --script interface --preprocess whatever.mkvi
\stoptyping

This will convert the given file(s) to new ones, with the default
suffix \type{tex}. Existing files will not be overwritten unless
\type {---force} is given. You can also force another suffix:

\starttyping
mtxrun --script interface --preprocess whatever.mkvi --suffix=mkiv
\stoptyping

A rather plain module \type {luatex-preprocessor.lua} is provided for
other usage. That variant provides a somewhat simplified version.

Given that you have a \type {luatex-plain} format you can run:

\starttyping
luatex --fmt=luatex-plain luatex-preprocessor-test.tex
\stoptyping

Such a plain format can be made with:

\starttyping
luatex --ini luatex-plain
\stoptyping

You probably need to move the format to a proper location in your
\TEX\ tree.

\stopsection

\stopchapter

\stopcomponent
