% language=uk

\startcomponent cld-specialcommands

\environment cld-environment

\startchapter[title=Special commands]

\index{tracing}

\startsection[title=Tracing]

There are a few functions in the \type {context} namespace that are no
macros at the \TEX\ end.

\starttyping
context.runfile("somefile.cld")
\stoptyping

Another useful command is:

\starttyping
context.settracing(true)
\stoptyping

There are a few tracing options that you can set at the \TEX\ end:

\starttyping
\enabletrackers[context.files]
\enabletrackers[context.trace]
\stoptyping

\stopsection

\startsection[title=Overloads]

A few macros have special functions (overloads) at the \LUA\ end. One of them is
\type {\char}. The function makes sure that the characters ends up right. The
same is true for \type {\chardef}. So, you don't need to mess around with \type
{\relax} or trailing spaces as you would do at the \TEX\ end in order to tell the
scanner to stop looking ahead.

\starttyping
context.char(123)
\stoptyping

Other examples of macros that have optimized functions are \type {\par},
\type{\bgroup} and \type {\egroup}. Or take this:

\startbuffer
1: \ctxlua{commands.doif(true)}{one}
2: \cldcommand{doif("a","a","two")}
3: \ctxcommand{doif(true)}{three}
\stopbuffer

\typebuffer

\startlines
\getbuffer
\stoplines

\stopsection

\startsection[title=Steps]

% added and extended in sync with an article about a generic 'execute'
% feature

We already mentioned the stepper as a very special trick so let's give
some more explanation here. When you run the following code:

\setbox0\emptybox

\starttyping
\startluacode
  context.startitemize()
    context.startitem()
      context("BEFORE 1")
    context.stopitem()
    context("\\setbox0\\hbox{!!!!}")
    context.startitem()
      context("%p",tex.getbox(0).width)
    context.stopitem()
  context.stopitemize()
\stopluacode
\stoptyping

You get a message like:

\starttyping
[ctxlua]:8: attempt to index a nil value
...
10             context("\\setbox0\\hbox{!!!!}")
11             context.startitem()
12 >>              context("%p",tex.getbox(0).width)
...
\stoptyping

due to the fact that the box is still void. All that the \CONTEXT\ commands feed
into \TEX\ happens when the code snippet has finished. You can however run a
snippet of code the following way:

\startbuffer
\startluacode
  context.stepwise (function()
    context.startitemize()
      context.startitem()
        context.step("BEFORE 1")
      context.stopitem()
      context.step("\\setbox0\\hbox{!!!!}")
      context.startitem()
        context.step("%p",tex.getbox(0).width)
      context.stopitem()
    context.stopitemize()
  end)
\stopluacode
\stopbuffer

\typebuffer

and get:

\getbuffer

A more extensive example is:

\startbuffer
\startluacode
  context.stepwise (function()
    context.startitemize()
      context.startitem()
        context.step("BEFORE 1")
      context.stopitem()
      context.step("\\setbox0\\hbox{!!!!}")
      context.startitem()
        context.step("%p",tex.getbox(0).width)
      context.stopitem()
      context.startitem()
        context.step("BEFORE 2")
      context.stopitem()
      context.step("\\setbox2\\hbox{????}")
      context.startitem()
        context.step("%p",tex.getbox(2).width)
      context.startitem()
        context.step("BEFORE 3")
      context.stopitem()
      context.startitem()
        context.step("\\copy0\\copy2")
      context.stopitem()
      context.startitem()
        context.step("BEFORE 4")
        context.startitemize()
          context.stepwise (function()
            context.step("\\bgroup")
            context.step("\\setbox0\\hbox{>>>>}")
            context.startitem()
              context.step("%p",tex.getbox(0).width)
            context.stopitem()
            context.step("\\setbox2\\hbox{<<<<}")
            context.startitem()
              context.step("%p",tex.getbox(2).width)
            context.stopitem()
            context.startitem()
              context.step("\\copy0\\copy2")
            context.stopitem()
            context.startitem()
              context.step("\\copy0\\copy2")
            context.stopitem()
            context.step("\\egroup")
          end)
        context.stopitemize()
      context.stopitem()
      context.startitem()
        context.step("AFTER 1\\par")
      context.stopitem()
      context.startitem()
        context.step("\\copy0\\copy2\\par")
      context.stopitem()
      context.startitem()
        context.step("\\copy0\\copy2\\par")
      context.stopitem()
      context.startitem()
        context.step("AFTER 2\\par")
      context.stopitem()
      context.startitem()
        context.step("\\copy0\\copy2\\par")
      context.stopitem()
      context.startitem()
        context.step("\\copy0\\copy2\\par")
      context.stopitem()
    context.stopitemize()
  end)
\stopluacode
\stopbuffer

\typebuffer

which gives:

\getbuffer

A step returns control to \TEX\ immediately and after the \TEX\ code that it
feeds back is expanded, returns to \LUA. There are some limitations due to the
input stack but normally that is no real issue.

You can run the following code:

\starttyping
\definenumber[LineCounter][way=bypage]
\starttext
\startluacode
for i=1,2000 do
    context.incrementnumber { "LineCounter" }
    context.getnumber { "LineCounter" }
    context.par()
end
\stopluacode
\stoptext
\stoptyping

You will notice however that the number is not right on each page. This is
because \TEX\ doesn't know yet that there is no room on the page. The next will
work better:

\starttyping
\definenumber[LineCounter][way=bypage]
\starttext
\startluacode
context.stepwise(function()
    for i=1,2000 do
        context.testpage { 0 }
        context.incrementnumber { "LineCounter" }
        context.getnumber { "LineCounter" }
        context.par()
        context.step()
    end
end)
\stopluacode
\stoptext
\stoptyping

Instead of the \type {testpage} function you can also play directly with
registers, like:

\starttyping
if tex.pagegtotal + tex.count.lineheight > tex.pagetotal then
\stoptyping

but often an already defined helper does a better job. Of course you will
probably never need this kind of hacks anyway, if only because much more is going
on and there are better ways then.

\stopsection

\stopchapter

\stopcomponent
