Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Программы » SciTE - Open Source Text Editor for Windows & Linux

Модерирует : gyra, Maz

Widok (23-11-2010 11:23): Лимит страниц. Продолжаем здесь  Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

   

BioInfo

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Код:
-- Форматер кода для LUA
-- Автор: Маслов Дмитрий
--
-- Принцип действия:
-- Текст разбивается на лексемы (слова)
-- Лексемы выстраивыаются нужным образом
--
-- В планах развития:
-- 1. Формирование вертикальных блоков функции и условий при достижении правой границы
-- 2. Отступы между блоками функций
-- 3. Установка второго стиля кода, когда начало блока не отделяется новой строкой
-- 4. Портировать форматер на лексер С++
-- 5. Не разворачивать блоки if exp then param end, если блок из одного параметра
-- .. Добавить кучу настроек под нужды общества
---------------------------------------------------------------------------------------
 
-- Стиль для блоков
--
-- Стиль № 0
--* имя блока
--* do
--*   ...
--* end
--
-- Стиль № 1
--* имя блока do
--*   ...
--* end
local block_style = 0;
 
---------------------------------------------------------------------------------------
 
local function GetEOL()
   
local eol = "\r\n"
   
if editor.EOLMode == SC_EOL_CR then
       
eol = "\r"
   
elseif editor.EOLMode == SC_EOL_LF then
       
eol = "\n"
   
end
    return
eol
end
 
-- возвражает количество слов найденных в тексте и таблицу с ними
local function GetLexemas( text )
   
local result = {};
   
local count = 0;
   
local pos = 0;
   
local text_len = string.len( text );
   
while true
    do
       
-- убираем пробелы в начале
       
while ( pos < text_len )
       
do
            local
char = string.char( text:byte( pos+1 ) );
           
if ( char == " " or char == "\t" or char == "\r" or char == "\n" )
           
then
               
pos = pos + 1;
           
else
                break
;
           
end
        end
       
-- проверка на конец
       
if ( pos == text_len ) then break; end
       
-- собираем лексему
       
local one_word = string.char( text:byte( pos + 1 ) );
       
local double_word = one_word..string.char( text:byte( pos + 2 ) );
       
local threed_word = double_word..string.char( text:byte( pos + 3 ) );
       
local q_word = threed_word..string.char( text:byte( pos + 4 ) );
       
-- 1. Проверяем трех составные слова: ...
       
if ( threed_word == '...' )
       
then
           
-- сохраняем слово в таблицу
           
count = count + 1;
           
result[ count ] = threed_word;
           
pos = pos + 3;
       
else
           
-- 2. Проверяем двусоставные слова: .. | <= | >= | == | ~=  
           
if ( double_word == '..' or
                 
double_word == '<=' or
                 
double_word == '>=' or
                 
double_word == '==' or
                 
double_word == '~=' )
           
then
               
-- сохраняем слово в таблицу
               
count = count + 1;
               
result[ count ] = double_word;
               
pos = pos + 2;
           
else
               
-- 3. Проверяем комментарий: --[[ | --
               
local isComment = false;
               
local comment_end = '';
               
if ( q_word == '--[[' ) -- потоковй комментарий
               
then
                   
isComment = true;
                   
comment_end = ']]';
               
elseif ( double_word == '--' ) -- строчный комментарий
               
then
                   
isComment = true;
               
end
                if
( isComment == true )
               
then
                   
-- отделяем комментарий
                   
local comment = '';
                   
if ( comment_end:len() == 0 ) -- по концу строки
                   
then
                        while true
                        do
                           
pos = pos + 1;
                           
if ( pos == text_len ) then break; end
                            local
char = string.char( text:byte( pos ) )
                           
if ( char == "\n" or char == "\r" ) then break; end
                           
comment = comment..char;
                       
end
                    else
                        while true
                        do
                           
pos = pos + 1;
                           
if ( pos == text_len ) then break; end
                            local
char1 = string.char( text:byte( pos ) )
                           
local char2 = string.char( text:byte( pos + 1 ) )
                           
comment = comment..char1;
                           
if ( comment_end == char1..char2 )
                           
then
                               
comment = comment..char2;
                               
pos = pos + 1;
                               
break;
                           
end
                        end
                    end
                   
-- сохраняем слово в таблицу
                   
count = count + 1;
                   
result[ count ] = comment;
               
else
                   
-- 4. Проверяем текстовое поле: " | '
                   
local text_end = '';
                   
if ( one_word == '\'' ) then text_end = '\''; end
                    if
( one_word == '\"' ) then text_end = '\"'; end
                    if
( text_end ~= '' )
                   
then
                        local
text_field='';
                       
while true
                        do
                           
pos = pos + 1;
                           
if ( pos == text_len ) then break; end
                            local
char = string.char( text:byte( pos ) )
                           
local char_prev = string.char( text:byte( pos - 1 ) )
                           
local char_prev_prev = string.char( text:byte( pos - 2 ) )
                           
text_field = text_field..char;
                           
if ( char == text_end and text_field ~= text_end and ( char_prev ~= '\\' or char_prev_prev == '\\' ) ) then break; end
                        end
                       
-- сохраняем слово в таблицу
                       
count = count + 1;
                       
result[ count ] = text_field;
                   
else
                       
-- 5. Проверяем односоставные слова
                       
if ( one_word == '+' or
                             
one_word == '-' or
                             
one_word == '*' or
                             
one_word == '/' or
                             
one_word == '%' or
                             
one_word == '^' or
                             
one_word == '#' or
                             
one_word == ';' or
                             
one_word == ':' or
                             
one_word == ',' or
                             
one_word == '.' or
                             
one_word == '(' or
                             
one_word == ')' or
                             
one_word == '{' or
                             
one_word == '}' or
                             
one_word == '[' or
                             
one_word == ']' or
                             
one_word == '=' or
                             
one_word == '<' or
                             
one_word == '>' )
                       
then
                           
pos = pos + 1;
                           
-- сохраняем слово в таблицу
                           
count = count + 1;
                           
result[ count ] =one_word;
                       
else
                           
-- 6. Проверяем остальные слова
                           
local word = '';
                           
while ( pos < text_len )
                           
do
                                local
char = string.char( text:byte( pos + 1 ) );
                               
if ( char == '+' or
                                     
char == '-' or
                                     
char == '*' or
                                     
char == '/' or
                                     
char == '%' or
                                     
char == '^' or
                                     
char == '#' or
                                     
char == ';' or
                                     
char == ':' or
                                     
char == ',' or
                                     
char == '.' or
                                     
char == '(' or
                                     
char == ')' or
                                     
char == '{' or
                                     
char == '}' or
                                     
char == '[' or
                                     
char == ']' or
                                     
char == '=' or
                                     
char == '<' or
                                     
char == '>' or
                                     
char == ' ' or
                                     
char == '\'' or
                                     
char == '\"' or
                                     
char == '~' or
                                     
char == "\n" or
                                     
char == "\r" )
                               
then
                                    break
;
                               
else
                                   
word = word..char;
                               
end
                               
pos = pos + 1;
                           
end
                           
-- сохраняем слово в таблицу
                           
count = count + 1;
                           
result[ count ] = word;
                       
end
                    end
                end
            end
        end
    end
    return
count, result;
end
 
-- Получить отступ в строке
local function GetLineIndentation( num_line )
   
if ( num_line < 0 ) then num_line = 0 end
    if
( num_line >= editor.LineCount ) then num_line = editor.LineCount - 1 end
    return
( editor.LineIndentation[num_line] / editor.Indent )
end
 
--[lua] Расчет начала блока в lua - блока функции
local isFunctionBlockBeginLua = false;
local lastParamBlockBeginLua = '';
local function IsBlockBeginLua( str )
   
local result = false;
   
if ( str == 'function' ) then isFunctionBlockBeginLua = true; end
    if
( lastParamBlockBeginLua == ')' and str ~= ')' ) then isFunctionBlockBeginLua = false; end
    if
( str == ')' ) then result = isFunctionBlockBeginLua; end
   
lastParamBlockBeginLua = str;
   
return result;
end
 
--[lua] Расчет конца вырожения в lua - может не оканчиватся точкой с запятой
local lastParamNewLineBeforLua = nil;
local function IsNewLineBeforLua( str )
   
local ret = false
    if
( str ~= nil and lastParamNewLineBeforLua ~= nil )
   
then
        if
( str ~= '+' and
             
str ~= ')' and
             
str ~= '}' and
             
str ~= ']' and
             
str ~= '-' and
             
str ~= '*' and
             
str ~= '/' and
             
str ~= '^' and
             
str ~= '%' and
             
str ~= '..' and
             
str ~= '<' and
             
str ~= '<=' and
             
str ~= '>' and
             
str ~= '>=' and
             
str ~= '==' and
             
str ~= '~=' and
             
str ~= '[' and
             
str ~= '{' and
             
str ~= '(' and
             
str ~= ';' and
             
str ~= '.' and
             
str ~= ',' and
             
str ~= ':' and
             
str ~= '=' and
             
str ~= 'do' and
             
str ~= 'else' and
             
str ~= 'repeat' and
             
str ~= 'then' and
             
str ~= 'until' and
             
str ~= 'in' and
             
str ~= 'and' and
             
str ~= 'or' and
             
str ~= '...' ) and
           
( lastParamNewLineBeforLua ~= '+' and
             
lastParamNewLineBeforLua ~= 'do' and
             
lastParamNewLineBeforLua ~= 'else' and
             
lastParamNewLineBeforLua ~= 'elseif' and
             
lastParamNewLineBeforLua ~= 'for' and
             
lastParamNewLineBeforLua ~= 'function' and
             
lastParamNewLineBeforLua ~= 'if' and
             
lastParamNewLineBeforLua ~= 'local' and
             
lastParamNewLineBeforLua ~= 'not' and
             
lastParamNewLineBeforLua ~= 'repeat' and
             
lastParamNewLineBeforLua ~= 'return' and
             
lastParamNewLineBeforLua ~= 'then' and
             
lastParamNewLineBeforLua ~= 'until' and
             
lastParamNewLineBeforLua ~= 'while' and
             
lastParamNewLineBeforLua ~= '-' and
             
lastParamNewLineBeforLua ~= '-' and
             
lastParamNewLineBeforLua ~= '-' and
             
lastParamNewLineBeforLua ~= '*' and
             
lastParamNewLineBeforLua ~= '/' and
             
lastParamNewLineBeforLua ~= '^' and
             
lastParamNewLineBeforLua ~= '%' and
             
lastParamNewLineBeforLua ~= '..' and
             
lastParamNewLineBeforLua ~= '<' and
             
lastParamNewLineBeforLua ~= '<=' and
             
lastParamNewLineBeforLua ~= '>' and
             
lastParamNewLineBeforLua ~= '>=' and
             
lastParamNewLineBeforLua ~= '==' and
             
lastParamNewLineBeforLua ~= '~=' and
             
lastParamNewLineBeforLua ~= '[' and
             
lastParamNewLineBeforLua ~= '{' and
             
lastParamNewLineBeforLua ~= '(' and
             
lastParamNewLineBeforLua ~= ';' and
             
lastParamNewLineBeforLua ~= '.' and
             
lastParamNewLineBeforLua ~= ',' and
             
lastParamNewLineBeforLua ~= ':' and
             
lastParamNewLineBeforLua ~= '=' and
             
lastParamNewLineBeforLua ~= 'in' and
             
lastParamNewLineBeforLua ~= 'and' and
             
lastParamNewLineBeforLua ~= 'or' and
             
lastParamNewLineBeforLua ~= '...' )
       
then
           
ret = true;
       
end
    end
   
lastParamNewLineBeforLua = str;
   
return ret;
end
 
-- начало блока?
local function IsBlockBeginLang( str )
   
return str =='do' or str == 'repeat' or str == 'then' or str == 'else';
end
 
local function
IsBlockBegin( str )
   
return IsBlockBeginLang( str ) or IsBlockBeginLua( str );
end
 
-- конец блока?
local function IsBlockEnd( str )
   
return str == 'end' or str == 'until' or str == 'elseif' or str == 'else';
end
 
-- это комментарий?
local function IsComment( str )
   
return str ~= nil and str:sub( 1, 2 ) == '--';
end
 
-- это вплотную прилигающее слово?
local function IsLeftSidedWord( str )
   
return str == ';' or str == '(' or str == ',' or str == '.' or str == '[' or str == '..' or str == ':';
end
 
-- после этого слова нужно всегда делать отступ?
local function IsLeftNoSidedWord( str )
   
return str == 'or' or str == 'and' or str == 'not' or str == 'for' or str == 'if' or
           
str == 'while' or str == 'return' or str == 'elseif';
end
 
-- после этого слова не нужно делать отступ?
local function IsRightSidedWord( str )
   
return str == '..' or str == '.' or str == ':';
end
 
-- с этого слова начинается строка?
local function IsNewLineBefor( str )
   
return str == 'local' or str == 'for' or str == 'if' or str == 'while' or str == 'function' or
           
str == 'return' or str == 'break' or
           
( block_style == 0 and IsBlockBeginLang( str ) ) or
           
IsBlockEnd( str ) or
           
IsComment( str );
end
 
-- после этого слова начинается строка?
local function IsNewLineAfter( str )
   
return str == ';' or
           
IsBlockBegin( str ) or
           
str == 'end' or
           
IsComment( str );
end
 
-- MAIN --
 
local sel_start = editor.SelectionStart;
local sel_end = editor.SelectionEnd;
local line_start = editor:LineFromPosition( sel_start ) + 1;
local line_indent = GetLineIndentation( line_start );
-- Если ничего не выделено, то берем весь текст
if sel_start == sel_end
then
   
--[[тест]]
   
line_start = 0
   
sel_start = 0
   
sel_end = editor:PositionFromLine( editor.LineCount );
   
line_indent = 0;
end
 
local
line_indent = GetLineIndentation( editor:LineFromPosition( editor.SelectionStart ) );
local text, lenght = editor:GetSelText();
local count, tbl = GetLexemas(text);
local out_text = '';
local curr_line_indent = line_indent;
local in_new_line = true;
for i = 1, count
do
    local
lexBefor = tbl[ i - 1 ];
   
local lexCurr = tbl[ i ];
   
local lexNext = tbl[ i + 1 ];
 
   
-- нужен ли пробел?
   
local word_prefix = ' ';
   
if ( IsLeftSidedWord( lexCurr ) and not IsLeftNoSidedWord( lexBefor ) ) or
       
( in_new_line == true ) or
       
( IsRightSidedWord( lexBefor ) )
   
then
       
word_prefix = '';
   
end
 
   
-- вставлять ли новую строку?
   
local paste_new_line = IsNewLineBeforLua( lexNext ) or
                           
IsNewLineAfter( lexCurr ) or
                           
( not IsNewLineBefor( lexCurr ) and IsNewLineBefor( lexNext ) );
   
if IsBlockBegin( lexCurr ) then curr_line_indent = curr_line_indent + 1; end
    if
IsBlockEnd( lexNext ) and ( curr_line_indent > 0 ) then curr_line_indent = curr_line_indent - 1; end
 
   
out_text = out_text..word_prefix..lexCurr;
   
in_new_line = false;
   
if ( paste_new_line == true )
   
then
       
out_text = out_text..GetEOL()..string.rep( '    ', curr_line_indent );
       
in_new_line = true;
   
end
end
print( out_text );
 

Всего записей: 83 | Зарегистр. 30-04-2007 | Отправлено: 00:44 18-05-2008 | Исправлено: BioInfo, 01:42 18-05-2008
   

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Программы » SciTE - Open Source Text Editor for Windows & Linux
Widok (23-11-2010 11:23): Лимит страниц. Продолжаем здесь


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru