User:Lilyuserin/Lua
Allgemeines
[edit]Substitution und Transclusion sind mächtige Werkzeuge innerhalb der Wiki-Software MediaWiki. Diesen fehlt jedoch eine wichtige Funktionalität, die in jeder Programmiersprache enthalten ist, die Möglichkeit, Vorgänge in Schleifen zu wiederholen. Es gibt zwar Parserfunktionen und eine Menge nützlicher Erweiterungen, mit deren Hilfe logische Entscheidungen getroffen werden können, doch muss jeder mögliche Fall explizit vorgesehen werden.
Beispielsweise kann ich keine Tabelle erzeugen, deren Zeilenzahl von einem Parameter abhängt. Zumindest gibt es keinen einfachen Weg dafür, es müsste für jeden möglichen Fall eine eigene Vorlage mit entsprechender Benennung angelegt werden, also eine Vorlage mit einer Zeile, eine Vorlage mit zwei Zeilen, eine Vorlage mit drei Zeilen usw.
Diesem Umstand schafft die Scriptsprache Lua Abhilfe. Im folgenden gebe ich einen Überblick über die wichtigsten Elemente dieser Sprache, deren Kenntnis für das Programmieren von Scripten innerhalb eines Wikis erforderlich ist.
Links
[edit]Lua Programmierung
[edit]- Lua Manual
- Lua Manual deutsche Übersetzung
- Erweiterte Backus-Naur-Form (für die Verständlichkeit des deutschsprachigen Manuals)
- Lua Wiki
- Lua auf Wikibooks.de
- Lua Programmierung (englisches Wikibook)
- Programmieren mit Lua
- Lua für Anfänger
- Lua lernen Teil 1; es gibt keinen weiteren Teil
- Patterns Tutorial
Lua in der Wikipedia und in MediaWiki-Software
[edit]- Lua Hilfe
- Lua Referenz auf Mediawiki.org
- Zeichen Mengen in Lua
- Wiktionary: Scribunto
- Wiktionary:Scribunto/Converting templates
- Wikipedia:Comparable Lua functions to wikitext
- Lua-Tutorial auf MediaWiki
- Lua Module in der englischsprachigen Wikipedia
- Lua Module in der deutschsprachigen Wikipedia
- Lua Module auf Commons
- Lua Module auf MediaWiki
- Lua Module auf Mediawiki durchsuchen
- Lua Module auf Commons durchsuchen
- Lua Module in der deutschsprachigen Wikipedia durchsuchen
- Lua Module in der englischsprachigen Wikipedia durchsuchen
Beispielmodule
[edit]Erweiterungen für Lua
[edit]- Scribunto: bindet Lua in das Wiki ein
- Code Editor: praktisch zum Editieren von Lua, fügt z.B. Zeilennummern ein
- Lua-Zugriff auf die Datenbank
Scribunto läuft nicht
[edit]- Error after update
- Cannot create process: proc_open(/dev/null) der Webstpace-Provider lässt proc_open nicht zu, Lua ist daher zu vergessen
- Mit folgenden Erweiterungen können in Vorlagen Schleifen programmiert werden:
Zusatzinfos
[edit]Datentypen
[edit]Es gibt in Lua acht Datentypen, von denen für Scribunto sechs relevant sind.
nil, boolean, number, string,userdata, function,thread, table
Eine Variable kann jeden Datentyp aufnehmen, type(varname)
liefert den derzeit aktuellen Datentyp des Inhalts als String.
Nil
[edit]Nichts, undefiniert, leer: wenn eine Variable nicht definiert ist, enthält sie nil
, sie kann durch Zuweisen von nil
auf undefiniert gesetzt werden.
Boolean
[edit]Logischer Datentyp, true
oder false
, alle Inhalte außer false
und nil
sind true
.
Number
[edit]Zahlen, mit denen gerechnet werden kann. Integer (eigener Subtyp seit Lua 5.3), Dezimalzahl, Exponentialzahl oder Hexadezimalzahl.
String
[edit]Eine Folge von Zeichen. Ein String wird entweder von doppelten oder einfachen Anführungszeichen eingeschlossen. Escape sequence
ist der Backslash \
, damit können Zeilenumbrüche, Tabulatoren und Ascii-Zeichen durch Angabe des Hexadezimalcodes innerhalb des Strings angegeben werden sowie Anführungszeichen und der Backslash selber.
Eine Besonderheit von Lua ist die Angabe von Strings durch long brackets
, die nichts anders sind als doppelte eckige Klammern, damit können Strings erzeugt werden, die sich über mehrere Zeilen erstrecken. Ein Zeilenwechsel, der unmittelbar auf die öffnende Klammer folgt, wird ignoriert.
Mit dem unary length operator #
kann die Länge des Strings ermittelt werden.
#("This is a string") --> 16
Strings werden durch zwei aufeinanderfolgende Punkte ..
miteinander verkettet.
"This is" .. " a string" --> "This is a string"
Zeichenfolge | Bedeutung |
---|---|
\a | bell |
\b | back space |
\f | form feed |
\n | newline |
\r | carriage return |
\t | horizontal tab |
\v | vertical tab |
\\ | backslash |
\" | double quote |
\' | single quote |
\[ | left square bracket |
\] | right square bracket |
Variable
[edit]Sämtliche Bezeichnungen und Namen sind case-sensitive, d.h. Groß- und Kleinbuchstabenschreibweise wird unterschieden. Variablennamen dürfen nicht mit einer Zahl beginnen und dürfen nur Buchstaben, Ziffern sowie das Sonderzeichen _
enthalten. Zu vermeiden sind Namen, die mit einem Unterstrich beginnen und ausschließlich Großbuchstaben enthalten.
Folgende Wörter sind Schlüsselwörter und können nicht als Variablennamen verwendet werden
and break do else elseif end false for function goto if in local nil not or repeat return then true until while
Tabellen
[edit]Tabellen sind ein Feature von Lua, das diese Sprache am meisten von allen anderen Programmiersprachen unterscheidet.
Einerseits können Tabellen wie gewöhnliche Arrays verwendet werden, die wir aus anderen Programmiersprachen kennen. Zu beachten ist, dass der erste Index immer 1 ist, nicht 0 wie in vielen anderen Programmiersprachen. Andererseits können Tabellenelemente benannt werden, entweder mit Namen oder mit Stringkombination, Funktionen etc, praktisch alles kann ein Tabellenplatzbezeichner sein. Hat das Tabellenelement einen Namen, der als Variablennamen zulässig ist, kann es durch Qualifizierung oder Einfügen des Namens in eckige Klammern angesprochen werden, andere Bezeichner müssen in eckige Klammern unter Hochkomma gesetzt werden. Indizes stehen in eckigen Klammern. In einer Tabelle können indizierte und benannte Elemente parallel nebeneinander verwendet werden.
Dies entspricht den unbenannten und benannten Parametern in Vorlagen.
Definiert werden Tabellen mit geschweiften Klammer:
mytab = { }
definiert eine leere Tabelle.
Es gibt mehrere Möglichkeiten, einer Tabelle Werte zuzuweisen.
mymonat = { "Jänner", "Februar", "März" }
mydatum = { monat="Jänner", jahr="2012", tag="11" }
myops = { ["!"]="Rufzeichen", ["*"]="Stern", ["µ"]="mü" }
mytables = { mymonat, mydatum, myops }
Tabellenelemente können durch Punkte oder Strichpunkte voneinander getrennt werden, auch am Ende darf ein Trennzeichen stehen. Dadurch braucht das Ende einer Tabelle nicht besonders behandelt zu werden.
Referenziert werden die Tabellenelemente folgendermaßen:
mymonat[2] --> Februar
mydatum.monat --> Jänner
myops["*"] --> Stern
mytables.mydatum.jahr --> 2012
Für das effiziente Suchen in einer Tabelle ist es praktisch, die Umkehrung zu erzeugen, also Werte und Indizes zu vertauschen.
revmonat = {}
for i,v in ipairs(mymonat) do
revmonat [v] = i
end
Alle Tabelleneinträge abarbeiten
[edit]Mit pairs()
und ipairs()
können alle Elemente einer Tabelle in einer Schleife abgearbeitet werden.
tab = {erster, zweiter, dritter, zahl=5, obst = 'Äpfel'}
for k, v in pairs(tab) do
-- irgendwas wo k und v vorkommt; k ist der Index, v der Inhalt
-- k=1, v="erster"
-- k=2, v="zweiter" ...
-- k=zahl, v=5
-- k=obst, v="Äpfel"
end
Die Reihenfolge der Abarbeitung ist willkürlich und kann nicht vorhergesehen werden, ipairs()
arbeitet die Parameter in der Reihenfolge der Indizes ab, allerdings nur bis zur ersten Lücke in der Numerierung, die benannten Tabelleneinträge werden daher von der Schleife nicht erfasst.
Tabellenelemente zusammenhängen table.concat
[edit]Diese Funktion verbindet alle Elemente einer Tabellen zu einem String, für Debugzwecke nützlich. Allerdings werden nur Elemente mit Indizes erfasst, benannte Elemente können derart nicht verkettet werden, da die vordefinierte Ordnung fehlt.
tab = {erster, zweiter, dritter, zahl=5, obst = 'Äpfel'}
table.concat(tab, ", ") --> "erster, zweiter, dritter"
Es gibt auch eine Wikimedia-eigene Funktion mw.text.listToText, die eine Tabelle verkettet, aber das vorletzte und das letzte Element mittes eines Verbindungsstrings verbindet. Das Default-Trennzeichen ist das Standard-Komma, das Verbindungszeichen das Standard „und“
Tabelle entpacken unpack
[edit]Ordnet die Elemente einer Tabelle einer Variablenliste zu
unpack (tabelle [, i [, j]])
local feld = {11, 8, 5}
local x, y, z = table.unpack(feld)
--> x=11, y=8, z=5
i ist der Startwert, j die Anzahl der Elemente, i ist per Default 1, j die Zahl der Elemente der Tabelle #
Text in eine Tabelle aufteilen
[edit]mw.text.split teilt einen Text nach einem vorgegebenen Muster in eine Tabelle bzw. Array.
Mehrfache Zuordnungen
[edit]Eines der besonderen Features von Lua ist die Möglichkeit, einer Liste von Variablen eine Liste von Werten in einem Statement zuzuweisen.
a, b, c = 0, 1 --> a: 0; b: 1; c: nil
Vor einer Zuweisung werden alle Variablen auf der rechten Seite ausgewertet, daher kann z.B. ein Tausch des Inhalts zweier Variablen einfach durchgeführt werden:
a, b = b, a --> a: b; b: a
Funktionen
[edit]Eine Funktion kann eine beliebige Zahl an Parametern aufnehmen und eine beliebige Zahl an Rückgabewerten liefern. Wird die Funktion mit mehr Parametern aufgerufen als im Kopf definiert sind, werden die überflüssigen Parameter verworfen. Fehlende Parameter werden mit nil
aufgefüllt.
Des weiteren kann eine Funktion mehrere Ergebnisse gleichzeitig liefern, die dann einer Variablenliste zugeordnet werden sollten (sonst würde es keinen Sinn haben, da die restlichen Werte ohnehin verworfen würden).
Eine Funktion, die als Ergebnis das Maximum einer Tabelle sowie den Index des Maximums liefert:
function max (tab)
local index=1 -- Index
local xam=tab(1) -- Wert des Maximums
for i,val in ipairs(tab) do
if val > xam then
index = i
xam = val
end
end -- for
return xam, index
end
a, b = max ( { 10, 20, 5, 5, 100, 99 }]
a --> 100
b --> 5
Eine Besonderheit ist der Aufruf mit einer variablen Anzahl von Parametern, die durch die Zeichenfolge ...
, genannt vararg expression
symbolisiert werden. Zu beachten ist, dass ...
innerhalb der Funktion keine table, sondern eine Liste von Werten darstellt, die zur weiteren Bearbeitung mit {...}
in eine table umgewandelt werden muss.
function variableParameterzahl (...)
local tab = {...}
for k, v in pairs(tab ) do
-- irgendwelche Aktionen
end
end
Man kann auch eine Parameterliste mit einer vararg expression
kombinieren, diese muss am Ende der Parameterliste stehen. Derartige Funktionen heißen variadic functions
function variableParameterzahl (para1, para2, ...)
local tab = {...}
for k, v in pairs(tab ) do
-- irgendwelche Aktionen
end
end
Lua und MediaWiki Software
[edit]Lua erfordert die Installation der Erweiterung Scribunto.
Beim Provider nachfragen, ob proc_open() möglich ist.
Jeder Lua-Modul ist eingekapselt und kann aus Sicherheitsgründen mit dem System ausschließlich über den Rückgabewert interagieren.
Jeder Lua-Modul liefert als Rückgabewert einen Textstring, der an der Stelle des Aufrufs in die aufrufende Seite eingebettet wird. Zum Zeitpunkt des Lua-Funktionsaufrufs hat der Parser etliche Schritte wie Vorlagenauswertung, Auswertung von Extension-Tags
(categorytree ce <charinsert> chem gallery graph hiero imagemap includeonly inputbox maplink math noinclude <nowiki> onlyinclude poem <pre> ref references score einbinden#section section (source) syntaxhighlight templatedata TemplateStyles timeline)
bereits durchgeführt. Das bedeutet, dass Vorlagen nicht mehr ausgewertet werden, wenn sie als Rückgabewert eines Lua-Moduls erscheinen, dieses Verhalten wird hier beschrieben. Vorlage können jedoch mit den Funktionen frame:expandTemplate
und frame:preprocess
zur Zeit der Durchführung des Moduls ausgewertet werden
Der Text {{Meine Vorlage}}
im Rückgabestring wird daher nicht mehr ausgewertet, sondern als {{Meine Vorlage}}
in der Wikiseite dargestellt.
Sonstige Tipps
[edit]Die Erweiterung Code Editor vereinfacht das Editieren erheblich, indem sie Zeilennummern hinzufügt und den Code farblich gestaltet. Konfigurationstexte zum Copy&Paste gibt es hier.
Ein einfacher Lua-Modul
[edit]local p = {} -- p stands for package
function p.mehrfach(frame)
local w, count, vorlage="", frame.args.count, frame.args.vorlage or "2x"
if count == nil then count = 1 end
--[[
Die Vorlage [[:Template:Vorlage]] hat beispielsweise die Parameter
p, q und r. Die Werte von n Parametersätzen
p1, q1, r1, p2 ... werden an den Modul übergeben.
Wenn der Parameter p[j] existiert, wird die Vorlage [[:Template:Meine Vorlage]]
mit den Paramtern p[j], q[j] und r[j] aufgerufen, ggfs. werden Defaultwerte für
q und r eingesetzt. Diese Defaultwerte könnten z.B. als weitere benannte Parameter
übergeben werden.
--]]
if not mw.title.new("template:" .. vorlage).exists then return "Vorlage " .. vorlage .. " existiert nicht" end
for i = 1,count do
local j = tostring(i)
local p = frame.args["p" .. j]
if p then
local q = frame.args["q" .. j] or "default-q"
local r = frame.args["r" .. j] or "default-r"
w = w .. frame:expandTemplate{ title = vorlage, args = { p, q, r } }
end
end
return w
end
function p.main(frame)
local titel = frame.args.name or "Hauptseite"
if mw.title.new(titel).exists then return "Seite " .. titel .. " existiert"
else return "Seite " .. titel .. " existiert nicht " end
end
function p.vorlage(frame)
local titel = frame.args.name or "2x"
if mw.title.new("template:" .. titel).exists then return "Vorlage " .. titel .. " existiert"
else return "Vorlage " .. titel .. " existiert nicht " end
end
function p.datei(frame)
local titel = frame.args.name or "Info_Icon.png"
if mw.title.new("File:" .. titel).exists then return "Datei " .. titel .. " existiert"
else return "Datei " .. titel .. " existiert nicht " end
end
function p.namespace(frame)
return mw.site.namespaces.template.id .. mw.site.namespaces.template.name
end
function p.zerlegen(frame)
local was, _ = {}, ""
local i = 1
local param = frame.args.param
for _ in string.gmatch(param,"([%w!§&=%$%(%)%%%[%]%*%+%-%?]+),") do
was[i] = _
i = i+1
end
return #was .. " -- " .. table.concat( was, ", ")
end
function p.split(frame)
--[[
Diese Funktion teilt einen String durch Trennzeichen auf und erzeugt eine Tabelle
nicht nur eine Tabelle, sondern sogar eine Sequence, d.h. die Elemente sind mit natürlich Zahlen
indiziert
--]]
local was, _ = {}, ""
local param = frame.args.param
was = mw.text.split( param, '[%,%s]')
return #was .. " -- " .. table.concat( was, ", ")
end
return p
Dokumentation
[edit]Das umfangreiche System von Dokumentationsvorlagen soll durch einen einzigen Lua-Modul ersetzt werden.
Unterseiten