Zum Inhalt springen

Modul:Expr

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 26. Mai 2013 um 20:37 Uhr durch PerfektesChaos (Diskussion | Beiträge) (Setup). Sie kann sich erheblich von der aktuellen Version unterscheiden.
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Vorlagenprogrammierung Diskussionen Lua Test Unterseiten
Modul Deutsch English

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus

Dies ist die (produktive) Mutterversion eines global benutzten Lua-Moduls.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Versionsbezeichnung auf WikiData: 2022-09-12

PARKEN IM MODUL-NAMENSRAUM AUS SICHTUNGSGRÜNDEN Ein optionaler Parameter erlaubt unterschiedliche Interpretation eines Eingabewerts.

  • Vorgabe ist . mit der Bedeutung „Computer-Format“.
  • „Computer-Format“ bedeutet: . als Dezimaltrennzeichen, Minuszeichen in ASCII, keine Zifferngruppierung („Tausender“). Alternativ kommt die Exponential-Notation mit E in Frage.

Das erlaubte Eingabeformat, falls angegeben, besteht aus ein bis drei Codes mgd mit den Komponenten:

  • d – Pflichtangabe wenn verwendet: Dezimaltrennzeichen. Zulässige Werte: . oder , (nur an letzter Stelle).
  • m – Minuszeichen ist „typografisch“ (Unicode U+2212) erlaubt bei - (nur an erster Stelle).
  • g – Zifferngruppierung („Tausender“, auch Nachkommastellen) erlaubt gemäß nachfolgender Tabelle (optional).
Codes für Ziffergruppierung
g Bedeutung
, Komma, passend zum angloamerikanischen „Computer-Format“.
. Punkt; Standardformatierung in der deutschsprachigen Wikipedia
' ASCII-Hochkomma/Apostroph; üblich mit Bezug zur Schweiz
', ASCII-Hochkomma/Apostroph oder Komma
'. ASCII-Hochkomma/Apostroph oder Punkt
U+20 ASCII-Leerzeichen
Nicht als Zahlenformat geeignet, aber zur Analyse und für qualifizierte Fehlermeldungen
U+A0 Geschütztes Leerzeichen
U+202F Schmales geschütztes Leerzeichen
%s Einfaches oder (auch schmales) geschütztes Leerzeichen
.%s Punkt oder einfaches oder (auch schmales) geschütztes Leerzeichen
'%s ASCII-Hochkomma/Apostroph oder einfaches oder (auch schmales) geschütztes Leerzeichen
'.%s Punkt oder ASCII-Hochkomma/Apostroph oder einfaches oder (auch schmales) geschütztes Leerzeichen

Bei der Eingabe können für die Zifferngruppierung alternativ auch HTML-Entities benutzt werden.

  • Wissenschaftliche oder Exponential-Darstellung erfordert immer das „Computer-Format“; e oder E, Exponent ganzzahlig, + kann der Mantisse und dem Exponent vorangestellt werden.

Beispiele:

  • -., – Format für deutschsprachige Wikis, entsprechend lokalem Wert der Parserfunktion formatnum – Komma als Dezimaltrennzeichen, Punkt als Tausendertrennzeichen, typografisches Minuszeichen erlaubt
  • ,. – klassisches US-Format
  • -'.%s, – breiteste Akzeptanz deutschsprachiger Formate, typografisches Minuszeichen möglich

--[=[ 2013-05-25
Expr
* max
* min
* TemplateMax
* TemplateMin
]=]



local messagePrefix = "lua-module-Expr-"
local l10nDef = {}
l10nDef[ "en" ] = {
    ErrorExpr  = "Error in mathematical expression, function#parameter"
}
l10nDef[ "de" ]  = {
    ErrorExpr  = "Fehler in mathematischem Ausdruck, Funktion#Parameter"
}



local function factory( say )
    -- Retrieve localized message string in content language
    -- Precondition:
    --     say  -- string; message ID
    -- Postcondition:
    --     Return some message string
    -- Uses:
    --     >  messagePrefix
    --     >  l10nDef
    --     mw.language.getContentLanguage()
    --     mw.message.new()
    local c = mw.language.getContentLanguage():getCode()
    local m = mw.message.new( messagePrefix .. say )
    local r = false
    if m:isBlank() then
        local l10n = l10nDef[ c ]
        if not l10n then
            l10n = l10nDef[ "en" ]
        end
        r = l10n[ say ]
    else
        m:inLanguage( c )
        r = m:plain()
    end
    if not r then
        r = "(((".. say .. ")))"
    end
    return r
end -- factory()



local function eval( source, frame )
    -- Evaluate expression
    -- Precondition:
    --     source  -- string; mathematical expression
    --     frame   -- object
    return frame:callParserFunction( "#expr", source )
end -- eval()



local function expr( source, frame, show )
    -- Safe evaluation of presumable expression
    -- Precondition:
    --     source  -- string; mathematical expression
    --     frame   -- object
    --     show    -- string; details about source
    -- Postcondition:
    --     throws error, if expression failed
    --     returns number with resulting figure
    -- Uses:
    --     factory()
    local lucky, r = pcall( eval, source, frame )
    local n = tonumber( r, 10 )
    if not lucky or n == nil then
        r = r .. " " .. factory( "ErrorExpr" )
            .. " ''" .. show .. "'' (" .. source .. ")"
        error( r, 0 )
    else
        r = n
    end
    return r
end -- expr()



local function minmax( params, frame, low, lazy  )
    -- Find extremum of unnamed params values
    -- Precondition:
    --     params  -- table; like args
    --                       .minus
    --                       .zeroBlank
    --     frame   -- object
    --     low     -- true: minimum;  false: maximum
    --     lazy    -- true: try numeric result;  false: return string
    -- Postcondition:
    --     throws error, if expression failed
    --     returns number, or
    --             string if formatting required, or
    --             false if no data provided
    -- Uses:
    --     expr()
    local k, v, n, scope
    local light  = ( params.minus ~= "-" )
    local luxury = ( params.minus and light )
    local c      = mw.ustring.char( 8722 )    -- minus
    local scan   = "^%s*%-?[0-9]*%.?[0-9]*%s*$"
    local r      = false
    for k, v in pairs( params ) do
        if type( k ) == "number" then
            scope  = type( v )
            if scope == "string" then
                if v:match( "^%s*$" ) then
                    n = false
                else
                    if mw.ustring.match( v, c ) then
                        luxury = light
                        v      = mw.ustring.gsub( v, c, "-" )
                    end
                    if not mw.ustring.match( v, scan ) then
                        if low then
                            scope = "min()#"
                        else
                            scope = "max()#"
                        end
                        scope = scope .. tostring( k )
                        v     = expr( v, frame, scope )
                    end
                    n = tonumber( v )
                end
            elseif scope == "number" then
                n = v
            end
            if n then
                if r then
                    if low then
                        if n < r then
                            r = n
                        end
                    else
                        if n > r then
                            r = n
                        end
                    end
                else
                    r = n
                end
            end
        end
    end -- for k, v
    if r then
        if luxury and r < 0 then
            r = c .. tostring( -1 * r )
        elseif not lazy then
            if r == 0 then
                if params.zeroBlank then
                    r = ""
                else
                    r = "0"
                end
            else
                r = tostring( r )
            end
        end
    end
    return r
end -- minmax()



-- Export
local p = {}

function p.max( frame )
    local lucky, r = pcall( minmax, frame.args, frame, false, false )
    return r or ""
end

function p.min( frame )
    local lucky, r = pcall( minmax, frame.args, frame, true, false )
    return r or ""
end

function p.TemplateMax( frame )
    return p.max( frame:getParent() )
end

function p.TemplateMin( frame )
    return p.min( frame:getParent() )
end

function p.Expr( f, a )
    local frame = mw.getCurrentFrame()
    local r = false
    if f == "min"  or  f == "max" then
        local lucky
        local low = ( f == "min" )
        lucky, r = pcall( minmax, a, frame, low, true )
    end
    return r
end -- .Expr()

return p -- Expr