% language=uk engine=luatex
%
% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa

\usemodule[abr-02]

\startbuffer[definitions]
    \def\lua{\directlua\zerocount} % the zero instance
\stopbuffer

\getbuffer
  [definitions]

\setuplayout
  [height=middle,
   width=middle,
   backspace=2cm,
   topspace=2cm]

\setuppagenumbering
  [alternative=doublesided]

\setupwhitespace
  [big]

\preloadtypescripts

\startmode[atpragma]

    \usetypescriptfile[type-ghz]

    \definetypeface[mainfacenormal]  [ss][sans] [optima-nova] [default]
    \definetypeface[mainfacenormal]  [rm][serif][palatino]    [default]
    \definetypeface[mainfacenormal]  [tt][mono] [modern]      [default][rscale=1.1]
    \definetypeface[mainfacenormal]  [mm][math] [palatino]    [default][encoding=default]

    \definetypeface[mainfacemedium]  [ss][sans] [optima-nova] [default]
    \definetypeface[mainfacenormal]  [rm][serif][palatino]    [default]
    \definetypeface[mainfacemedium]  [tt][mono] [modern]      [default][rscale=1.1]
    \definetypeface[mainfacemedium]  [mm][math] [palatino]    [default][encoding=default]

    \definetypeface[mainfacenarrowtt][tt][mono] [modern-cond] [default][rscale=1.1]

\stopmode

\startnotmode[atpragma]

    \definetypeface[mainfacenormal]  [ss][sans] [iwona]       [default]
    \definetypeface[mainfacenormal]  [rm][serif][palatino]    [default]
    \definetypeface[mainfacenormal]  [tt][mono] [modern]      [default][rscale=1.1]
    \definetypeface[mainfacenormal]  [mm][math] [iwona]       [default][encoding=default]

    \definetypeface[mainfacemedium]  [ss][sans] [iwona-medium][default]
    \definetypeface[mainfacenormal]  [rm][serif][palatino]    [default]
    \definetypeface[mainfacemedium]  [tt][mono] [modern]      [default][rscale=1.1]
    \definetypeface[mainfacemedium]  [mm][math] [iwona-medium][default][encoding=default]

    \definetypeface[mainfacenarrowtt][tt][mono] [modern-cond] [default][rscale=1.1]

\stopnotmode

\setupbodyfont[mainfacenormal,11pt]

\definehead
  [remark]
  [subsubsubject]

\setuphead [chapter]      [style=\mainfacemedium\bfd,color=blue]
\setuphead [section]      [style=\mainfacemedium\bfc,color=blue]
\setuphead [subsection]   [style=\mainfacemedium\bfb,color=blue]
\setuphead [subsubsection][style=\mainfacemedium\bfa,color=blue]

\setupheadertexts
  []

\setupcolors
  [state=start]

\setuptyping
  [color=blue,
   style=\mainfacenarrowtt]

\setuptype
  [color=blue,
   style=\mainfacenarrowtt]

\definecolor[blue] [b=.5]
\definecolor[red]  [b=.5]
\definecolor[green][g=.5]

\starttext

\startuseMPgraphic{lualogo}
    color   luaplanetcolor ; luaplanetcolor := .5blue  ;
    color   luaholecolor   ; luaholecolor   :=   white ;
    numeric luaextraangle  ; luaextraangle  := 0 ;

    vardef lualogo = image (
        % Graphic design by A. Nakonechnyj. Copyright (c) 1998, All rights reserved.

        save luaorbitcolor, d, r, p ; color luaorbitcolor ; numeric d, r, p ;

        luaorbitcolor := .5luaholecolor ; d := sqrt(2)/4 ; r := 1/4 ; p := r/8 ;

        fill fullcircle scaled 1 withcolor luaplanetcolor ;
        draw fullcircle rotated 40.5 scaled (1+r) dashed evenly scaled p withpen pencircle scaled (p/2) withcolor luaorbitcolor ;
        fill fullcircle scaled r shifted (d+1/8,d+1/8) rotated luaextraangle withcolor luaplanetcolor ;
        fill fullcircle scaled r shifted (d-1/8,d-1/8) withcolor luaholecolor   ;
    )  enddef ;

\stopuseMPgraphic

\startuseMPgraphic{luapage}
    \includeMPgraphic{lualogo}

    StartPage ;

        fill Page withcolor (white-luaplanetcolor) ;

        picture p ; p := lualogo xsized (3PaperWidth/5) ;
        draw p shifted center Page shifted (0,-ypart center ulcorner p) ;

    StopPage ;
\stopuseMPgraphic

\startuseMPgraphic{luanumber}
    \includeMPgraphic{lualogo}
%     luaextraangle := \realfolio*360/\lastpage ;
    luaextraangle := (\realfolio-2)*360/(\lastpage-2) ;
    picture p ; p := lualogo ;
    setbounds p to boundingbox fullcircle ;
    draw p ysized 1cm ;
\stopuseMPgraphic

\definelayer
  [page]
  [width=\paperwidth,
   height=\paperheight]

\setupbackgrounds
  [leftpage]
  [background=page]

\setupbackgrounds
  [rightpage]
  [background=page]

\startsetups pagenumber:right
  \setlayerframed
    [page]
    [preset=rightbottom,offset=1cm]
    [frame=off,height=1cm,offset=overlay]
    {\useMPgraphic{luanumber}}
  \setlayerframed
    [page]
    [preset=rightbottom,offset=1cm,x=1.5cm]
    [frame=off,height=1cm,width=1cm,offset=overlay]
    {\pagenumber}
  \setlayerframed
    [page]
    [preset=rightbottom,offset=1cm,x=2.5cm]
    [frame=off,height=1cm,offset=overlay]
    {Lua Enhanced TEX}
\stopsetups

\startsetups pagenumber:left
  \setlayerframed
    [page]
    [preset=leftbottom,offset=1cm,x=2.5cm]
    [frame=off,height=1cm,offset=overlay]
    {Lua Enhanced TEX}
  \setlayerframed
    [page]
    [preset=leftbottom,offset=1cm,x=1.5cm]
    [frame=off,height=1cm,width=1cm,offset=overlay]
    {\pagenumber}
  \setlayerframed
    [page]
    [preset=leftbottom,offset=1cm]
    [frame=off,height=1cm,offset=overlay]
    {\useMPgraphic{luanumber}}
\stopsetups

\startstandardmakeup % \startTEXpage

    \switchtobodyfont[mainfacemedium]
    \definedfont[Bold at .1\paperheight] \setupinterlinespace

    \setlayer[page]{\useMPgraphic{luapage}}

    \setlayerframed
      [page]
      [preset=middletop,
       voffset=.05\paperheight]
      [align=middle,
       foregroundcolor=blue,
       frame=off]
      {LUA\\ENHANCED\\TEX}

    % \tightlayer[page]

\stopstandardmakeup % \stopTEXpage

\setupbackgrounds
  [leftpage]
  [setups=pagenumber:left]

\setupbackgrounds
  [rightpage]
  [setups=pagenumber:right]

\title{Contents}

\placecontent[criterium=text]

\title{Introduction}

I started thinking about a \LUA\ extended version of \TEX\ when I
played with \LUA\ in the Scite editor (spell checking and such).
After some emailing Hartmut Henkel took the challenge and within a
few days had the first version of such an integration running.
After some experiments, the time was there to involve Taco
Hoekwater and interfacing to \TEX's internals started taking
shape. It will take some time for the interface to mature, and we
should take that time. The \type {\lua} primitive is just a start,
because in the end we want to interface to \TEX's internals.

Part of the game is to provide a plug||in interface so that we can
talk with the (more or less independent) paragraph and page
builders that Karl Skoup\'y is experimenting with and showed at
\TEX\ conferences.

The project started as a branch of \PDFTEX\ but in the end it will
end up in the main version of \THANH's the original. Given the small
footprint of \LUA, users who don't use it will not suffer from it.

This manual is a kind of diary, where I keep track of new things
and ideas. In the process I will provide:

\startitemize[packed]
\item a basic macro set for (plain) \TEX
\item an extended macro set for \CONTEXT
\item general purpose \LUA\ libraries
\stopitemize

This manual is dedicated to Hartmut, Taco, Thanh and Karl, my personal
heros of extending and reimplementing \TEX\ who are never tired to try
out new things, no matter what weird things I come up with.

\blank[2*big]

\startlines
Hans Hagen
Pragma ADE
Hasselt NL
August 2005
\stoplines

\chapter{Definitions}

Before we start playing with \LUA, we define a few auxiliary
macros. They permits us to write a bit more readable code.

\typebuffer[definitions]

The \type {\lua} command is simply a shortcut for using the
zero \LUA\ instance, our scratch instance.

\startbuffer
I wonder for how long we can use \lua { tex.print("Hello World") }
as an example, since it assumes that there is a world left.
\stopbuffer

\typebuffer

This piece of source code results in: \getbuffer.

The \type {tex} table |<|tables are one of \LUA's core
mechanisms|>| contains a predefined \type {print} function and
that one can be used to feed back results into the tex input
stream.

In practice there will be more involved than just printing. \LUA\
is pretty well capable of providing \TEX\ some powerful
calculation features.

\starttyping
\lua{a = 1.5 ; b = 1.8 ; c = a*b ; tex.print(c) ;}

\lua {
    a = 1.5
    b = 1.8
    c = a*b
    tex.print(c)
}
\stoptyping

The semicolons are only needed when there can be confusion about
where a statement ends. Even in the first line of this example, no
semicolons are needed, but they make the source a bit more
readable.

Those who know \CONTEXT\ may wonder if we need some way of storing
\LUA\ code in macros with the purpose of recalling them later on,
as we do with \METAPOST\ code. There is no real need for such a
mechanism because \LUA\ has functions and \LUA\ itself can collect
them for us.

\starttyping
\lua {
    function mine.sum(a,b)
        tex.print(a+b)
    end
}
\stoptyping

Also, because we have an interface to \TEX's registers and hash
table, we can ask for any information we want. There is no need
to explicitly pass for instance page numbers to \LUA\ when entering
the page builder, as we do with \METAPOST.

\chapter{Expansion}

You may have noticed by now that the \type {\directlua} command is fully
expandable. Only things that you want to end up in the result will
end up there: no unexpanded bits and pieces, \type {\relax}'s etc.

There are two ways to feed back the result into \TEX: print and write.
The first method makes \TEX\ process the result as if it was entered as
\TEX, i.e.\ the current catcode regime is used. The write method
detokenizes the result, which means as much that you get uninterpreted
results. This is comparable by feeding the result through \type
{\detokenize}: characters with catcodes that identity them as
letters and nothing else. So, a \type {$} is just a dollar, and does
not switch to mathmode.

\startbuffer
\directlua 0 {tex.print("$\string\\sqrt{2} = " .. math.sqrt(2) .. "$")} \blank
\directlua 0 {tex.write("$\string\\sqrt{2} = " .. math.sqrt(2) .. "$")} \blank
\stopbuffer

\typebuffer

This shows up as:

\getbuffer

The \type {..} operator in this example concatenates strings. The
following call would have worked as well:

\starttyping
\directlua 0 {tex.print("$\string\\sqrt{2} = ", math.sqrt(2), "$")} \blank
\directlua 0 {tex.write("$\string\\sqrt{2} = ", math.sqrt(2), "$")} \blank
\stoptyping

Because we want the string \type {\sqrt} in the result, we
duplicate the backslash and prefix it by \type {\string}. We could
redefine \type {\\} just before we invoke \type {\lua}:

\starttyping
\def\\{\string\\}
\stoptyping

but this would spoil its fully expandable character so for the
moment we will let this rest.

The result of the square root calculation is rather precise.
Donald Knuth wrote \TEX\ in such a way that calculations were
platform independent. In \LUA, calculations are done using
floating point arithmics, using standardised protocols. In
practice one will not notice this, since the accuracy is more
than enough for everyday integer calculations.

\chapter{Scripting}

Let's present a more complex example. It is no secret that \TEX\
has no real capabilities to manipulate strings. This is no
surprise because it's main purpose is to typeset documents and
other programs can provide the manipulated input. But what if you
want to do it all (or as much as possible) from within \TEX ?

\starttyping
\lua {
    match = {} ;
    match.expression = "" ;
    match.string = "" ;
    match.result = {} ;
    match.start = 0 ;
    match.length = 0 ;
}

\def\matchstring#1#2{\lua {
    match.expression = "#1" ;
    match.string = "#2" ;
    match.result = {} ;
    match.start, match.length,
        match.result[1], match.result[2], match.result[3],
        match.result[4], match.result[5], match.result[6],
        match.result[7], match.result[8], match.result[9] = string.find(match.string,match.expression) ;
} }

\def\matchresult#1{\lua {
    tex.print(match.result[#1]) ;
} }
\stoptyping

The first call to \type {\lua} initializes some variables. Next we
define two macros, the first one matches an expression with a
string, while the second one gives access to the result. However,
this implementation is not that efficient because each time that
we call \type {\matchstring}, we pass a lot of code to lua. The
next variant is cleaner:

\startbuffer
\lua {
    match = {} ;
    match.expression = "" ;
    match.string = "" ;
    match.result = {} ;
    match.start = 0 ;
    match.length = 0 ;
}

\lua {
    function match.find(expr, str)
        match.expression = expr ;
        match.string = str ;
        match.result = {} ;
        match.start, match.length,
            match.result[1], match.result[2], match.result[3],
            match.result[4], match.result[5], match.result[6],
            match.result[7], match.result[8], match.result[9] = string.find(match.string,match.expression) ;
    end
}

\def\matchstring#1#2{\lua { match.find("#1","#2") }}
\def\matchresult  #1{\lua { tex.print(match.result[#1]) }}
\stopbuffer

\typebuffer \getbuffer

We can use these macros as follows. The \type {\letterpercent}
inserts an percent symbol, which is \LUA's escape character in
regular expressions.

\startbuffer
\matchstring
  {(\letterpercent d+) (\letterpercent d+) (\letterpercent d+)}
  {2005 08 08}

\starttabulate[|l|c|r|]
\NC year  \NC \matchresult{1} \NC \number \matchresult{1} \NC \NR
\NC month \NC \matchresult{2} \NC \number \matchresult{2} \NC \NR
\NC day   \NC \matchresult{3} \NC \number \matchresult{3} \NC \NR
\stoptabulate
\stopbuffer

\typebuffer \getbuffer

In this example the \type {\number} command strips the preceding
zeros from the result. However, in case of a faulty date, where
result returns no number, we run into troubles. Ok, we could add
an redundant zero after the \type {\number} command, but the next
alternative is more in sync with what regular expressions can do.

\startbuffer
\matchstring
  {0*(\letterpercent d+) 0*(\letterpercent d+) 0*(\letterpercent d+)}
  {2005 08 08}

\starttabulate[|l|c|]
\NC year  \NC \matchresult{1} \NC \NR
\NC month \NC \matchresult{2} \NC \NR
\NC day   \NC \matchresult{3} \NC \NR
\stoptabulate
\stopbuffer

\typebuffer \getbuffer

\chapter{Talking to \TeX}

An extension like this gains in power when it can interface to
\TEX's internals. Another benefit is that it provides alternative
ways to store and access information. The next example
demonstrates how we can use \LUA\ to calculate with \TEX\
dimensions. First we define a \quote {namespace} table and within
that another table.

{\em The following examples use a preliminary interface to \TEX's
data structures. This may change.}

\startbuffer
\lua {
    document = { }
    document.widths = { }
}
\stopbuffer

\typebuffer \getbuffer

Next we calculate the widths of characters in the current font and
store them in the table.

\startbuffer
\dostepwiserecurse{`a}{`z}{1} {
    \setbox0\hbox{\char\recurselevel}
    \lua { document.widths[\recurselevel] = tex.wd[0] }
}
\stopbuffer

\typebuffer \getbuffer

We calculate the average width and store that value in a variable
in the \type {document} table.

\startbuffer
\lua {
    local total, n = 0, 0
    for d in pairs(document.widths) do
        total, n = total + document.widths[d], n + 1
    end
    if n>0 then
        document.mean = total/n
    else
        document.mean = 0
    end
}
\stopbuffer

\typebuffer \getbuffer

We can access dimension registers in a similar way as the
dimensions of boxes, as demonstrated a few lines before. Next we
can do things with the calculated mean value.

\startbuffer
\mathematics {
    \lua { tex.dimen[0] = document.mean } \withoutpt \the\dimen0  =
    \lua { tex.print(document.mean/65536) } \approx
    \lua { tex.print(math.ceil(document.mean/65536)) }
}
\stopbuffer

\typebuffer \getbuffer

We need to keep into mind that only \TEX\ knows how to deal with
things meant for \TEX: \LUA\ does not know how to handle control
sequences and special directives in the input stream. Take the
following example.

\startbuffer
\toks0 = {interesting}

\lua {
    tex.toks[0] = string.gsub(tex.toks[0], "(.)", " (\letterpercent1) ")
}

\the\toks0
\stopbuffer

\typebuffer

Here we store a string in a token register. Next we split this
string in characters and put parenthesis around it.

\getbuffer

This goes well for simple strings but imagine that we have the
string

\starttyping
\toks0 = {math f\"ur $\all$}
\stoptyping

\startbuffer
\toks0 = {math f\"ur $\all$}

\lua {
    tex.toks[0] = string.gsub(tex.toks[0], "(.)", " (\letterpercent1) ")
}

\the\toks0
\stopbuffer

This gives:

\getbuffer

and not (m) (a) (t) (h) ( ) (f) (\"u) (r) ($\forall$). Apart from
the fact that lua sees characters and is not aware of the magic
combinations \type {\"u} and \type {$\forall$} it just returns
letters. If we want to manipulate strings in a more clever way, we
need to have access to the internal lists of already typeset
material. But, given some constraints, we can do nice things
anyway. In the next example we use a quote from Hermann Zapf.

\startbuffer
\toks0 = {
    Coming back to the use of typefaces in electronic publishing: many of the
    new typographers receive their knowledge and information about the rules
    of typography from books, from computer magazines or the instruction
    manuals which they get with the purchase of a PC or software. There is
    not so much basic instruction, as of now, as there was in the old days,
    showing the differences between good and bad typographic design. Many people
    are just fascinated by their PC's tricks, and think that a widely||praised
    program, called up on the screen, will make everything automatic from now on.
}

\lua {
    str = tex.toks[0]
    str = string.gsub(str, "\letterpercent w+",
        function(w)
            if str.len(w) > 4 then
                return "\string\\color[red]{" .. w .. "}"
            else
                return "\string\\color[green]{" .. w .. "}"
            end
        end
    )
    tex.toks[0] = str
}

\scantokens\expandafter{\the\toks0}
\stopbuffer

\typebuffer

The compound word marker \type {||} is left untouched and just
treated as normal characters.

\getbuffer

Here is another example of storing and retrieving. This solution
is slower that storing the assignments in a token list registers
and expanding that one each time when needed, but when assignments
take place seldom, it could be an alternative.

\startbuffer
\lua {
    lccodes = { }
}

\dorecurse{255} {
    \lua {
        lccodes[\recurselevel] = \number\lccode\recurselevel ;
    }
}

\luatex {
    for i in pairs(lccodes) do
        tex.print("\string\\lccode" .. i .. "=" .. lccodes[i] .. " ")
    end
}
\stopbuffer

\typebuffer

In this case, the result is just a series of assignments and no text.

In the next example we return to the kind of example code that we
started with: fully expandable definitions.

\startbuffer
\lua {
    interface = {}
    interface.noftests = 0
    function interface.oneoftwo(result)
        interface.noftests = interface.noftests + 1
        if result then
            tex.print("firstoftwoarguments")
        else
            tex.print("secondoftwoarguments")
        end
    end
}
\stopbuffer

\typebuffer \getbuffer

This function returns a string, which one depends on the boolean
(condition) fed into it. The two possible strings reflect macro
names (\CONTEXT\ has a bunch of those):

\starttyping
\long\def\firstoftwoarguments #1#2{#1}
\long\def\secondoftwoarguments#1#2{#2}
\stoptyping

Teh following lines show us what happens:

\startbuffer
\lua { interface.oneoftwo(true)} \& \lua { interface.oneoftwo(false)}
\stopbuffer

\typebuffer

we get: \getbuffer

Now imagine the following definitions:

\startbuffer
\def\DoIfElse#1#2%
  {\csname\lua{interface.oneoftwo("#1"=="#2")}\endcsname}
\stopbuffer

\typebuffer \getbuffer

We feed the string comparison into the function, which returns a
string, which in turn is expanded into a control sequence. Without
any change of interference we also keep track of the number of
tests. We can ask for this number with:

\startbuffer

\def\NOfTests
  {\lua{tex.print(interface.noftests)}}
\stopbuffer

\typebuffer \getbuffer

The following code shows how to use the test. They all return (typeset)
\type {OK}.

\startbuffer
\def\xxx{yyy} \def\yyy{yyy}

\DoIfElse{one}{one}{OK}{NO}
\DoIfElse{two}{one}{NO}{OK}
\DoIfElse\xxx \yyy {OK}{NO}
\stopbuffer

\typebuffer

This gives:

\getbuffer

What goes in gets expanded, but when it enters \LUA\ it has been
turned into a harmless sequence of characters:

\starttyping
\DoIfElse
  {this is a \hbox to \hsize{real} mess}
  {and \rm this is even worse}
  {NO}{OK}
\stoptyping

This test can be used in an \type {\edef} and fed back into \LUA\
if needed.

\starttyping
\edef\zzz{this \DoIfElse{a}{b}{or}{and} that}

\lua{tex.print("\zzz")}
\lua{tex.print("this \DoIfElse{a}{a}{or}{and} that")}
\stoptyping

These examples demonstrate that we can comfortably mix \TEX\ and
\LUA\ and use either of them for what suits them best. Also keep
in mind that nesting \LUA\ calls is no problem either.

\starttyping
\lua{tex.print("this \lua{tex.print("---")} that")}
\stoptyping

Of course we need additional trickery. For instance we need a way
to escape characters before they enter \LUA, for instance the
following will fail:

\starttyping
\DoIfElse{one "two" three}{one 'two' three}{OK}{NO}
\stoptyping

Instead we need something:

\starttyping
\DoIfElse
  {\luaesc{one "two" three}}
  {\luaesc{one 'two' three}}
  {OK}{NO}
\stoptyping

This will comfortably escape the sensitive characters. So, there
is some work left to do.

\stoptext
