模組:藏語/轉

維基詞典,自由的多語言詞典
local str = {}
 
function str.extract( frame )
    local new_args = str._getParameters( frame.args, {'source', 'target', 'num', 'plain', 'start1', 'start2', 'start3', 'start4', 'start5', 'start6', 'comp', 'comp1', 'comp2', 'comp3', 'comp4', 'comp5', 'comp6' } ); 
    local source_str = new_args['source'] or '';
    local pattern = new_args['target'] or '';
    local start_pos = tonumber(new_args['start']) or 1;
    local start_pos2 = tonumber(new_args['start2']) or 1;
    local start_pos3 = tonumber(new_args['start3']) or 1;
    local start_pos4 = tonumber(new_args['start4']) or 1;
    local start_pos5 = tonumber(new_args['start5']) or 1;
    local start_pos6 = tonumber(new_args['start6']) or 1;
    local comp = new_args['comp'] or '';
    local comp1 = new_args['comp1'] or '';
    local comp2 = new_args['comp2'] or '';
    local comp3 = new_args['comp3'] or '';
    local comp4 = new_args['comp4'] or '';
    local comp5 = new_args['comp5'] or '';
    local comp6 = new_args['comp6'] or '';
    local num = tonumber(new_args['num']) or 1;
    local plain = new_args['plain'] or true;
 
    if source_str == '' or pattern == '' then
        return 0;
    end    
    
    source_str = mw.ustring.sub(source_str,1,mw.ustring.len(source_str))
 
    plain = str._getBoolean( plain );
 
    local start1 = mw.ustring.find( source_str, pattern, start_pos, plain )
    if start1 == nil then
        start1 = 0
    end
 
    if start1 > 0 then
        start_pos2 = start1 + 1;
    end
 
    local start2 = mw.ustring.find( source_str, pattern, start_pos2, plain )
    if start2 == nil then
        start2 = 0
    end
 
    if start2 == 0 then
        start_pos3 = start2
        else start_pos3 = start2 + 1;
    end
 
    local start3 = mw.ustring.find( source_str, pattern, start_pos3, plain )
    if start3 == nil then
        start3 = 0
    end
    if start_pos3 == 0 then start3 = 0 end
 
    if start3 == 0 then
        start_pos4 = start3
        else start_pos4 = start3 + 1;
    end
 
    local start4 = mw.ustring.find( source_str, pattern, start_pos4, plain )
 
    if start4 == nil then
        start4 = 0
    end
    if start_pos4 == 0 then start4 = 0 end
 
    if start4 == 0 then
        start_pos5 = start4
        else start_pos5 = start4 + 1;
    end
 
    local start5 = mw.ustring.find( source_str, pattern, start_pos5, plain )
    if start5 == nil then
        start5 = 0
    end
    if start_pos5 == 0 then start5 = 0 end
 
    if start5 == 0 then
        start_pos6 = start5
        else start_pos6 = start5 + 1;
    end
 
    local start6 = mw.ustring.find( source_str, pattern, start_pos6, plain )
    if start6 == nil then
        start6 = 0
    end
    if start_pos6 == 0 then start6 = 0 end
 
    if start1 > 0 then
        comp1 = mw.ustring.sub( source_str, 1, start1-1)
    end
 
    if start2 > 0 then
        comp2 = mw.ustring.sub( source_str, start1+1, start2-1)
    end
 
    if start3 > 0 then
        comp3 = mw.ustring.sub( source_str, start2+1, start3-1)
    end
 
    if start4 > 0 then
        comp4 = mw.ustring.sub( source_str, start3+1, start4-1)
    end
 
    if start5 > 0 then
        comp5 = mw.ustring.sub( source_str, start4+1, start5-1)
    end
 
    if start6 > 0 then
        comp6 = mw.ustring.sub( source_str, start5+1, start6-1)
    end
 
    if num == 1 then
        comp = comp1
    end
 
    if num == 2 then
        comp = comp2
    end
 
    if num == 3 then
        comp = comp3
    end
 
    if num == 4 then
        comp = comp4
    end
 
    if num == 5 then
        comp = comp5
    end
 
    if num == 6 then
        comp = comp6
    end
 
    return comp
end
 
function str.len( frame )
    local new_args = str._getParameters( frame.args, {'s'} );
    local s = new_args['s'] or '';
    return mw.ustring.len( s )
end
 
function str.sub( frame )
    local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
    local s = new_args['s'] or '';
    local i = tonumber( new_args['i'] ) or 1;
    local j = tonumber( new_args['j'] ) or -1;
 
    local len = mw.ustring.len( s );
 
    -- Convert negatives for range checking
    if i < 0 then
        i = len + i + 1;
    end
    if j < 0 then
        j = len + j + 1;
    end
 
    if i > len or j > len or i < 1 or j < 1 then
        return str._error( 'String subset index out of range' );
    end
    if j < i then
        return str._error( 'String subset indices out of order' );
    end
 
    return mw.ustring.sub( s, i, j )
end
 
function str.sublength( frame )
    local i = tonumber( frame.args.i ) or 0
    local len = tonumber( frame.args.len )
    return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
 
function str.match( frame )
    local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
    local s = new_args['s'] or '';
    local start = tonumber( new_args['start'] ) or 1;
    local plain_flag = str._getBoolean( new_args['plain'] or false );
    local pattern = new_args['pattern'] or '';
    local match_index = math.floor( tonumber(new_args['match']) or 1 );
    local nomatch = new_args['nomatch'];
 
    if s == '' then
        return str._error( 'Target string is empty' );
    end
    if pattern == '' then
        return str._error( 'Pattern string is empty' );
    end
    if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
        return str._error( 'Requested start is out of range' );
    end
    if match_index == 0 then
        return str._error( 'Match index is out of range' );
    end
    if plain_flag then
        pattern = str._escapePattern( pattern );
    end
 
    local result
    if match_index == 1 then
        -- Find first match is simple case
        result = mw.ustring.match( s, pattern, start )
    else
        if start > 1 then
            s = mw.ustring.sub( s, start );
        end
 
        local iterator = mw.ustring.gmatch(s, pattern);
        if match_index > 0 then
            -- Forward search
            for w in iterator do
                match_index = match_index - 1;
                if match_index == 0 then
                    result = w;
                    break;
                end
            end    
        else
            -- Reverse search
            local result_table = {};
            local count = 1;
            for w in iterator do
                result_table[count] = w;
                count = count + 1;
            end
 
            result = result_table[ count + match_index ];            
        end
    end        
 
    if result == nil then
        if nomatch == nil then
            return str._error( 'Match not found' );
        else
            return nomatch;
        end
    else
        return result;
    end
end
 
function str.pos( frame )
    local new_args = str._getParameters( frame.args, {'target', 'pos'} );
    local target_str = new_args['target'] or '';
    local pos = tonumber( new_args['pos'] ) or 0;
 
    return mw.ustring.sub( target_str, pos, pos );
end
 
function str.str_find( frame )
    local new_args = str._getParameters( frame.args, {'source', 'target'} );
    local source_str = new_args['source'] or '';
    local target_str = new_args['target'] or '';
 
    if target_str == '' then
        return 1;
    end    
 
    local start = mw.ustring.find( source_str, target_str, 1, true )
    if start == nil then
        start = -1
    end
 
    return start
end
 
function str.find( frame )
    local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); 
    local source_str = new_args['source'] or '';
    local pattern = new_args['target'] or '';
    local start_pos = tonumber(new_args['start']) or 1;
    local plain = new_args['plain'] or true;
 
    if source_str == '' or pattern == '' then
        return 0;
    end    
 
    plain = str._getBoolean( plain );
 
    local start = mw.ustring.find( source_str, pattern, start_pos, plain )
    if start == nil then
        start = 0
    end
 
    return start
end
 
function str.replace( frame )
    local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ); 
    local source_str = new_args['source'] or '';
    local pattern = new_args['pattern'] or '';
    local replace = new_args['replace'] or '';
    local count = tonumber( new_args['count'] );
    local plain = new_args['plain'] or true;
 
    if source_str == '' or pattern == '' then
        return source_str;
    end    
    plain = str._getBoolean( plain );
 
    if plain then
        pattern = str._escapePattern( pattern );
        replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences.
    end
 
    local result;
 
    if count ~= nil then
        result = mw.ustring.gsub( source_str, pattern, replace, count );
    else
        result = mw.ustring.gsub( source_str, pattern, replace );
    end        
 
    return result;
end
 
function str._getParameters( frame_args, arg_list )
    local new_args = {};
    local index = 1;
    local value;
 
    for i,arg in ipairs( arg_list ) do
        value = frame_args[arg]
        if value == nil then
            value = frame_args[index];
            index = index + 1;
        end
        new_args[arg] = value;
    end
 
    return new_args;
end        
 
function str._error( error_str )
    local frame = mw.getCurrentFrame();
    local error_category = frame.args.error_category or 'Errors reported by Module String';
    local ignore_errors = frame.args.ignore_errors or false;
    local no_category = frame.args.no_category or false;
 
    if str._getBoolean(ignore_errors) then
        return '';
    end
 
    local error_str = '<strong class="error">String Module Error: ' .. error_str .. '</strong>';
    if error_category ~= '' and not str._getBoolean( no_category ) then
        error_str = '[[Category:' .. error_category .. ']]' .. error_str;
    end        
 
    return error_str;
end
 
function str._getBoolean( boolean_str )
    local boolean_value;
 
    if type( boolean_str ) == 'string' then
        boolean_str = boolean_str:lower();
        if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' 
                or boolean_str == '' then
            boolean_value = false;
        else
            boolean_value = true;
        end    
    elseif type( boolean_str ) == 'boolean' then
        boolean_value = boolean_str;
    else
        error( 'No boolean value found' );
    end    
    return boolean_value
end
 
function str._escapePattern( pattern_str )
    return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end
 
return str