Module:User:ZxxZxxZ/IPA


local export = {}
local m_data = mw.loadData("Module:IPA/data")
local m_debug = require("Module:debug")

local sub = mw.ustring.sub
local gsub = mw.ustring.gsub
local find = mw.ustring.find

-- Used in [[Template:IPA]].
function export.template_IPA(frame)
    local args = frame:getParent().args
    local lang = args["lang"]
    NAMESPACE = mw.title.getCurrentTitle().nsText
    local ret

    ---- Initial link to pronunciation's guide page ----
    -- TODO
    if lang == nil or lang == "" or lang == "en" then
        ret = '[[Appendix:English pronunciation|IPA]]'
    elseif lang == "mul" then
        ret = '[[Wiktionary:IPA pronunciation key|IPA]]'
    else
        ret = '[[Wiktionary:IPA pronunciation key|IPA]]' -- FIXME
    end

    ret = ret .. ': '

    ---- Format the given pronunciation(s) ----
    if args[1] == nil then
        error('No pronunciation given to the parameter #1')
    end

    local i = 1
    while args[i] do
        if args[i] == "" then
            error('No pronunciation given in the paramater #' .. i)
        end

        if i ~= 1 then
            ret = ret .. ', '
        end

        ret = ret .. export.format_IPA(args[i])

        i = i + 1
    end

    return ret
end

-- Takes an IPA pronunciation and formats it.
function export.format_IPA(text)
    local ret
    local categories = {}

    ---- Determine the representation type ----
    local representation

    if sub(text, 1, 1) == '/' and sub(text, -1, -1) == '/' then
        representation = 'phonemic'
        text = sub(text, 2, -2)
    elseif sub(text, 1, 1) == '[' and sub(text, -1, -1) == ']' then
        representation = 'phonetic'
        text = sub(text, 2, -2)
    else -- TODO
        --error('invalid input')
    end

    ---- Check for obsolete and nonstandard symbols ----
    if export.contains_nonstandard(text) then
        table.insert(categories, "Entries using obsolete or nonstandard IPA characters")
    end

    local symbols_data = m_data.symbols

    ---- Check for invalid symbols ----
    -- TODO: check for invalid symbols here and return a script error
    -- NOTE: in many pages " " is used, I think it shouldn't, and even if we are going to make
    -- the spaces non-breakable, we should do that through CSS using the "IPA" class in [[MediaWiki:Common.css]]

    ---- Format the symbols ----
    -- We can make it simpler by using the "]]" and "[[" in our links, but we would have to only link symbols but
    -- not other changes (so in that case we can't tag a symbol with <span> to specify "title" without linking the symbol)

    if find(text, '[«»]') then
        error("The characters '«' and '»' are not allowed in input")
    end

    text = '»' .. text .. '«'

    -- Try to find IPA symbols in the text, format every symbol and tag it with «»
    for i = 6, 1, -1 do
        for symbol, symbol_data in pairs(symbols_data[i]) do
            text = gsub(text,
                '»([^«»]-)' .. symbol,
                '»%1«' .. (export.format_symbol(symbol, symbol_data) or symbol) .. '»')
        end
    end

    -- Remove the added tags
    text = gsub(text, '[«»]', '')

    ---- Format the text ----
    ret = '<span class="IPA" lang="">' .. text .. '</span>'

    if representation == 'phonemic' then
        ret = '<span title="phonemic representation">/</span>'
            .. ret
            .. '<span title="phonemic representation">/</span>'
    elseif representation == 'phonetic' then
        ret = '<span title="phonetic representation">[</span>'
            .. ret
            .. '<span title="phonetic representation">]</span>'
    end

    -- Add the categories
    for key, cat in ipairs(categories) do
        ret = ret .. "[[Category:" .. cat .. "]]"
    end

    return ret
end

-- Takes an IPA symbol and it's data and formats it.
function export.format_symbol(symbol, symbol_data)
    if symbol_data then
        if symbol_data['link'] then
            if symbol_data['title'] then
                return '[[' .. symbol_data['link'] .. '|' .. '<span title="' .. symbol_data['title'] .. '">' .. symbol .. '</span>]]'
            else
                return '[[' .. symbol_data['link'] .. '|' .. symbol .. ']]'
            end
        elseif symbol_data['title'] then
            return '<span title="' .. symbol_data['title'] .. '">' .. symbol .. '</span>'
        else
            return nil
        end
    else
        return nil
    end
end

-- Returns true if the given text contains obolete or nonstandard IPA symbols.
function export.contains_nonstandard(text)
    for i, symbol in ipairs(m_data.nonstandard) do
        if find(text, symbol) then
            return true
        end
    end
end

return export