Skip to content

STD to Penlight Migration

Caleb Maclennan edited this page Jan 4, 2020 · 2 revisions

Up until v0.9.5.1, SILE used the std lua package for inheritance, object modelling, tree cloning and so on. After that build, we moved to penlight (pl). If you are used to the std ways to do things, here is what you need to do to upgrade your code to penlight.

Utility functions

  • For deep cloning structures, instead of std.tree.clone, use pl.tablex.deepcopy
  • For shallow cloning structures, instead of std.table.clone, use pl.tablex.copy
  • To add a table to a table, instead of our hacked table.append, use pl.tablex.insertvalues.
  • To count the number of items in a table (as opposed to the highest index in the table), instead of our table.nitems, use the penlight builtin pl.tablex.size.
  • To find the numerically highest key in a table, use math.max(table.unpack(pl.tablex.keys(items)))
  • To reverse a table in place, our old table.flip has been replaced by SU.flip_in_place.
  • To turn a table into a string (for hashability or debugging), instead of std.string.pickle(t), use pl.pretty.write(t, '').

¹ Note: Don't copy the table structures of anything created with Penlight classes, the result is a mess. Use new instances instead. For SILE specific APIs you can copy an object my passing it as an initialization parameter to it's class (.e.g. newlen = SILE.length(oldlen)).

Object model

To create a new base class:

local objectRepresentingClass = pl.class({
    _init = function (self, stuff) ... end,
    method = function (self, stuff) .. end
})

local instance = objectRepresentingClass(initialisationParameters)

Note that unlike std, the object representing a class is not itself an instance: it is a true class, not a prototype object. Hence you need to instantiate it with objectRepresentingClass() before calling methods.

Overloads such as __tostring, __add etc. work as normal.

To create a new class with inheritance:

local objectRepresentingClass = pl.class({
    _base = objectRepresentingBaseClass,
    ...
})

prototype/is_a/type

Other core changes

(Should be later reflected in the documentation.)

  • To instantiate a length, you can say:

    -- any of:
    l = SILE.length({ length = 1, stretch = 2, shrink = 3 })
    l = SILE.length(1, 2, 3)
    l = SILE.length("1 plus 2 minus 3")

    All parameters are optional and will default to zero if not specified.

    SILE.length.new(), .make(), and .parse() (which essentially did the same thing) will soon be deprecated.

  • Names of types in settings (SILE.settings.declare({ type = "xxx", ...})) are now all lower-case.

  • pageTarget has been renamed getTargetLength

Clone this wiki locally