STD to Penlight Migration - sile-typesetter/sile GitHub Wiki
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.
- For deep cloning structures, instead of
std.tree.clone
, usepl.tablex.deepcopy
.¹ - For shallow cloning structures, instead of
std.table.clone
, usepl.tablex.copy
.¹ - To add a table to a table, instead of our hacked
table.append
, usepl.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 builtinpl.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 bySU.flip_in_place
. - To turn a table into a string (for hashability or debugging), instead of
std.string.pickle(t)
, usepl.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)
).
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
(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 renamedgetTargetLength