Dear list,

I am trying to define a command which behaves like an internal register
using the `token` library.  However, there are some complications.  For
example a register has to be settable using both

   \register=<number>
   \register<number>

Additionally, if no number is given it should raise a “cannot be used in
vmode” error or similar.  Also it has to be possible to get the value
using `\the`.  Below you can find a minimal example where I have already
achieved some of these things but others fail miserably.

Cheers, Henri

P.S.: I have also attached a much more complex example, so you can see
that I actually want to emulate pdfTeX's \pdfadjustinterwordglue.

---

\directlua{
local value = 0
%
function register()
    local str = token.scan_string()
    %
    if str then
        local int = string.gsub(str,"=","")
        value = tonumber(int)
    else
        tex.sprint([[\numexpr]] .. value .. [[\relax]])
    end
end
}

\protected\def\register{\directlua{register()}}

\register=1
\register=12
\register=123

\register1
\register12
\register123

\the\register
\the\register
\the\register

\bye
\ifdefined\directlua

\csname newcount\endcsname\pdfadjustinterwordglue

\begingroup
\catcode`\^^M=12
\directlua{
local subtypes = node.subtypes("glue")

local knbscode = {}

function add_knbscode(field)
    local fid = token.scan_int()
    local chr = token.scan_int()
    local str = token.scan_string()

    knbscode[fid] = knbscode[fid] or {}
    knbscode[fid][chr] = knbscode[fid][chr] or {}
    if str then
        local int = string.gsub(str,"=","")
        knbscode[fid][chr][field] = tonumber(int)
    else
        tex.sprint([[\numexpr]] .. (knbscode[fid][chr][field] or 0) .. [[\relax]])
    end
end

local microtype_spacing = function(head, tail)
    head, tail, success = node.kerning(head, tail)
    if tex.count.pdfadjustinterwordglue > 0 then
        for space in node.traverse_id(node.id("glue"), head) do
            if subtypes[space.subtype] == "spaceskip" then
                local prev = node.prev(space)
                if prev.id == node.id("glyph") then
                    local knbs = knbscode[prev.font]
                    if knbs and knbs[prev.char] then
                        local f = font.getfont(prev.font)
                        local em = f.parameters.quad

                        local width = knbs[prev.char].width or 0
                        local stretch = knbs[prev.char].stretch or 0
                        local shrink = knbs[prev.char].shrink or 0

                        local glue = node.new(node.id("glue"))
                        glue.width = width*em/1000
                        glue.stretch = stretch*em/1000
                        glue.shrink = shrink*em/1000

                        head = node.insert_before(head, space, glue)
                    end
                end
            end
        end
    end
end

callback.register("kerning", microtype_spacing, "microtype_spacing")
}%
\endgroup

\protected\def\knbscode{\directlua{add_knbscode("width")}\fontid}
\protected\def\stbscode{\directlua{add_knbscode("stretch")}\fontid}
\protected\def\shbscode{\directlua{add_knbscode("shrink")}\fontid}

\fi

\pdfadjustinterwordglue=1

\knbscode\font`r=1100
\stbscode\font`r=10
\shbscode\font`r=10

\knbscode\font`r 1100
\stbscode\font`r 10
\shbscode\font`r 10

\the\knbscode\font`r
\the\stbscode\font`r
\the\shbscode\font`r

\input lorem

\bye

Reply via email to