mki -x pasta arquivo.run (compacta 'pasta' e cria um arquivo auto-extraível arquivo.run)
mki -i pasta instalador.run (cria um instalador auto-extraível, que chama "instalar.sh" após a extração);
mki -o PastaAlvo Nome.run ./inicio.sh (cria instalador que chama "./inicio.sh", assim vc pode personalizar qual scritp será executado após a extração)
mki -h (mostra algumas informações sobre o programa)
local mtar = inclua'pmicrotar'
funcao leia_arquivobin(n)
local a,err = es.abra(n,'leiturabin');
se nao a entao retorne falso, err; fim
local txt = a:leia('*t');
a:feche();
retorne txt;
fim
local dado1 = leia_arquivobin('dados/arq1.txt'); //lemos um arquivo para uma variável string.
local tar,err = mtar.abra("simples.tar",'escrita');//abrimos um arquivo tar para escrita (gravar dados nele)
se nao tar entao imprima('Erro:',err,'\nEnter para sair...'); leia(); sis.saia(1) fim //se der erro o programa imprime e sai.
mtar.escreva_cabecalho_arquivo(tar,"dados/arq1.txt",#dado1);//criamos um cabeçalho com o nome do arquivo (diretório completo)
//note que na função acima é necessário passar o tamanho da string dado '#dado1';
mtar.escreva_dado(tar,dado1)//agora podemos gravar os dados.
//aqui no meio poderia escrever muitos outros arquivos antes de finalizar e fechar.
mtar.finalize(tar);
mtar.feche(tar);
poe('Processo terminado, verifique o arquivo "simples.tar", ENTER para sair...');
leia();
/*
MIT License
Copyright (c) 2018 xiedacon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Biblioteca JSON portada por Rafael Alves Lemos
na madrugada de 16/maio/2019 as 0h as 6h
não tem mudanças significativas em relação a lib json anterior prisma
apenas na identação com opção de escolher os espaços
inclusive portei as funções de cod_arquivo e decod_arquivo
USO:
local json = inclua 'rjson'
local cod = json.cod({
a=verdadeiro,
b=falso,
c='string',
d=1,
[0]={'matriz','de','valores'}
},nulo,4) //<-- o quanto é a tabulação
imprima(cod)
local dec = json.decod(cod)
imprima(tipo(dec))
para i,v em pares(dec) inicio
imprima(i,v)
fim
saida:
{
"d": 1,
"c": "string",
"b": false,
"a": true,
"0": [
"matriz",
"de",
"valores"
]
}
tabela
d 1
c string
b falso
a verdadeiro
0 tabela: 0x1ea14a0
*/
//*****************************Constant
local Constant = {
ESC_MAP = {
["\\"] = [[\]],
["\""] = [[\"]],
["/"] = [[\/]],
["\b"] = [[\b]],
["\f"] = [[\f]],
["\n"] = [[\n]],
["\r"] = [[\r]],
["\t"] = [[\t]],
["\a"] = [[\u0007]],
["\v"] = [[\u000b]]
},
UN_ESC_MAP = {
b = "\b",
f = "\f",
n = "\n",
r = "\r",
t = "\t",
u0007 = "\a",
u000b = "\v"
},
NULL = defmetatabela({}, {
__tostring = funcao() retorne "nulo" fim
})
}
//*****************************Serializer
local NULL = Constant.NULL
local ESC_MAP = Constant.ESC_MAP
local funcao kind_of(obj)
se tipo(obj) ~= "tabela" entao retorne tipo(obj) fim
se obj == NULL entao retorne "nulo" fim
local i = 1
para _ em pares(obj) inicio
se obj[i] ~= nulo entao i = i + 1 senao retorne "tabela" fim
fim
se i == 1 entao
retorne "tabela"
senao
retorne "matriz"
fim
fim
local funcao escape_str(s)
para k, v em pares(ESC_MAP) inicio
s = s:troque(k, v)
fim
retorne s
fim
local Serializer = {
print_address = falso,
max_depth = 100
}
defmetatabela(Serializer, {
__call = funcao(este, opts)
local serializer = {
depth = 0,
max_depth = opts.max_depth,
print_address = opts.print_address,
stream = opts.stream
}
defmetatabela(serializer, { __index = Serializer })
retorne serializer
fim
})
funcao Serializer:space(n)
local stream = este.stream
para i = 1, n ou 0 inicio
stream:write(" ")
fim
retorne este
fim
funcao Serializer:key(key)
local stream = este.stream
local kind = kind_of(key)
se kind == "matriz" entao
erro("Can't encode matriz as key.")
senaose kind == "tabela" entao
erro("Can't encode tabela as key.")
senaose kind == "string" entao
stream:write("\"", escape_str(key), "\"")
senaose kind == "numero" entao
stream:write("\"", convstring(key), "\"")
senaose kind == 'booleano' entao
se key entao
stream:write('true')
senao
stream:write('false')
fim
senaose kind == 'nulo' entao
stream:write('null')
senaose este.print_address entao
stream:write(convstring(key))
senao
erro("Unjsonifiable tipo: " .. kind .. ".")
fim
retorne este
fim
funcao Serializer:matriz(arr, replacer, indent, space)
local stream = este.stream
stream:write("[")
para i, v em ipares(arr) inicio
se replacer entao v = replacer(k, v) fim
stream:write(i == 1 e "" ou ",")
stream:write(space > 0 e "\n" ou "")
este:space(indent)
este:json(v, replacer, indent + space, space)
fim
se #arr > 0 entao
stream:write(space > 0 e "\n" ou "")
este:space(indent - space)
fim
stream:write("]")
retorne este
fim
funcao Serializer:tabela(obj, replacer, indent, space)
local stream = este.stream
stream:write("{")
local len = 0
para k, v em pares(obj) inicio
se replacer entao v = replacer(k, v) fim
se v ~= nulo entao
stream:write(len == 0 e "" ou ",")
stream:write(space > 0 e "\n" ou "")
este:space(indent)
este:key(k)
stream:write(space > 0 e ": " ou ":")
este:json(v, replacer, indent + space, space)
len = len + 1
fim
fim
se len > 0 entao
stream:write(space > 0 e "\n" ou "")
este:space(indent - space)
fim
stream:write("}")
retorne este
fim
funcao Serializer:json(obj, replacer, indent, space)
local stream = este.stream
local kind = kind_of(obj)
este.depth = este.depth + 1
se este.depth > este.max_depth entao erro("Reach max depth: " .. convstring(este.max_depth)) fim
se kind == "matriz" entao
este:matriz(obj, replacer, indent, space)
senaose kind == "tabela" entao
este:tabela(obj, replacer, indent, space)
senaose kind == "string" entao
stream:write("\"", escape_str(obj), "\"")
senaose kind == "numero" entao
stream:write(convstring(obj))
senaose kind == "booleano" entao
se obj entao
stream:write('true')
senao
stream:write('false')
fim
senaose kind == "nulo" entao
stream:write("null")
senaose este.print_address entao
stream:write(convstring(obj))
senao
erro("Unjsonifiable tipo: " .. kind)
fim
retorne este
fim
funcao Serializer:toString()
retorne este.stream:toString()
fim
//*****************************Parser
local NULL = Constant.NULL
local UN_ESC_MAP = Constant.UN_ESC_MAP
local funcao next_char(str, pos)
pos = pos + #str:separe("^%s*", pos)
retorne str:corte(pos, pos), pos
fim
local funcao syntax_error(str, pos)
retorne erro("Sintaxe JSON inválida iniciando em " .. pos .. ": " .. str:corte(pos, pos + 10))
fim
local Parser = {}
defmetatabela(Parser, {
__call = funcao(este, opts)
local parser = {
without_null = opts.without_null
}
defmetatabela(parser, { __index = Parser })
retorne parser
fim
})
funcao Parser:numero(str, pos)
local num = str:separe("^-?%d+%.?%d*[eE]?[+-]?%d*", pos)
local val = convnumero(num)
se nao val entao
syntax_error(str, pos)
senao
retorne val, pos + #num
fim
fim
funcao Parser:string(str, pos)
pos = pos + 1
local i = 1
local chars = {} //tabela.new(#str - pos - 1, 0)
enquanto(pos <= #str) inicio
local c = str:corte(pos, pos)
se c == "\"" entao
retorne tabela.concat(chars, ""), pos + 1
senaose c == "\\" entao
local j = pos + 1
local next_c = str:corte(j, j)
para k, v em pares(UN_ESC_MAP) inicio
se str:corte(j, j + #k - 1) == k entao
next_c = v
j = j + #k - 1
fim
fim
c = next_c
pos = j
fim
chars[i] = c
i = i + 1
pos = pos + 1
fim
syntax_error(str, pos)
fim
funcao Parser:matriz(str, pos)
local arr = {} //tabela.new(10, 0)
local val
local i = 1
local c
pos = pos + 1
enquanto verdadeiro inicio
val, pos = este:json(str, pos)
arr[i] = val
i = i + 1
c, pos = next_char(str, pos)
se (c == ",") entao
pos = pos + 1
senaose (c == "]") entao
retorne arr, pos + 1
senao
syntax_error(str, pos)
fim
fim
retorne arr
fim
funcao Parser:tabela(str, pos)
local obj = {} //tabela.new(0, 10)
local key
local val
local c
pos = pos + 1
enquanto verdadeiro inicio
c, pos = next_char(str, pos)
se c == "}" entao retorne obj, pos + 1
senaose c == "\"" entao key, pos = este:string(str, pos)
senao syntax_error(str, pos) fim
c, pos = next_char(str, pos)
se c ~= ":" entao syntax_error(str, pos) fim
val, pos = este:json(str, pos + 1)
obj[key] = val
c, pos = next_char(str, pos)
se c == "}" entao
retorne obj, pos + 1
senaose c == "," entao
pos = pos + 1
senao
syntax_error(str, pos)
fim
fim
fim
funcao Parser:json(str, pos)
local first = falso
local val
local c
se nao pos ou pos == 1 entao first = verdadeiro fim
pos = pos ou 1
se tipo(str) ~= "string" entao erro("str should be a string")
senaose pos > #str entao erro("Reached unexpected fim of input") fim
c, pos = next_char(str, pos)
se c == "{" entao
val, pos = este:tabela(str, pos)
senaose c == "[" entao
val, pos = este:matriz(str, pos)
senaose c == "\"" entao
val, pos = este:string(str, pos)
senaose c == "-" ou c:procure('%d') entao
val, pos = este:numero(str, pos)
senao
para k, v em pares({ ["true"] = verdadeiro, ["false"] = falso, ["null"] = NULL }) inicio
se (str:corte(pos, pos + #k - 1) == k) entao
val, pos = v, pos + #k
quebre
fim
fim
//se val == nulo entao syntax_error(str, pos) fim
fim
se first e pos <= #str entao syntax_error(str, pos) fim
se este.without_null e val == NULL entao val = nulo fim
retorne val, pos
fim
//************************JSON
local json = {
_VERSION = "0.1",
null = Constant.NULL
}
funcao json.cod(obj, replacer, space, print_address)
se tipo(space) ~= "numero" entao space = 0 fim
retorne Serializer({
print_address = print_address,
stream = {
fragments = {},
write = funcao(este, ...)
para i = 1, #{...} inicio
este.fragments[#este.fragments + 1] = ({...})[i]
fim
fim,
toString = funcao(este)
retorne tabela.concat(este.fragments)
fim
}
}):json(obj, replacer, space, space):toString()
fim
funcao json.decod(str, without_null)
retorne Parser({ without_null = without_null }):json(str, 1)
fim
local es_abra = es.abra;
funcao json.decod_arquivo(arq)
local a, err = es_abra(arq,'leitura');
se nao a entao retorne falso, err fim
local str = a:leia'*t'; //lê todo o arquivo.
a:feche();
retorne json.decod(str); //retorna a tabela.
fim
funcao json.cod_arquivo(arq, tab)
se tipo(tab)<> 'tabela' entao
retorne falso, ('\n\nErro arg #2, espera-se tabela ao invés de ' .. tipo(tab) .. '\n\n');
fim
local str = json.cod(tab);
local a, err = es_abra(arq,'escrita');
se nao a entao retorne falso, err fim
a:escreva(str);
a:feche();
retorne verdadeiro;
fim
retorne json
linux:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
linux:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
execute_arquivo = carreguearquivo ( 'ola.prisma' );
bytes = string.compile(execute_arquivo);
funcao inicio_programa()
//...todo seu código aqui...
fim //inicio_programa
string.compile(inicio_programa);
local json = {}
// Internal functions.
local funcao kind_of(obj)
se tipo(obj) <> 'tabela' entao retorne tipo(obj) fim
local i = 1
para _ em pares(obj) inicio
se obj[i] <> nulo entao i = i + 1 senao retorne 'tabela' fim
fim
se i == 1 entao retorne 'tabela' senao retorne 'array' fim
fim
local funcao escape_str(s)
local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'}
local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'}
para i, c em ipares(in_char) inicio
s = s:troque(c, '\\' .. out_char[i])
fim
retorne s
fim
// Returns pos, did_find; there are two cases:
// 1. Delimiter found: pos = pos after leading space + delim; did_find = verdadeiro.
// 2. Delimiter not found: pos = pos after leading space; did_find = falso.
// This throws an error if err_if_missing is true and the delim is not found.
local funcao skip_delim(str, pos, delim, err_if_missing)
pos = pos + #str:separe('^%s*', pos)
se str:corte(pos, pos) <> delim entao
se err_if_missing entao
retorne falso, ('Esperado ' .. delim .. ' próximo da posição ' .. pos)
fim
retorne pos, falso
fim
retorne pos + 1, verdadeiro
fim
// Expects the given pos to be the first character after the opening quote.
// Returns val, pos; the returned pos is after the closing quote character.
local funcao parse_str_val(str, pos, val)
val = val ou ''
local early_end_error = 'Fim de input encontrado durante a análise da string.'
se pos > #str entao retorne falso, (early_end_error) fim
local c = str:corte(pos, pos)
se c == '"' entao retorne val, pos + 1 fim
se c <> '\\' entao retorne parse_str_val(str, pos + 1, val .. c) fim
// We must have a \ character.
local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
local nextc = str:corte(pos + 1, pos + 1)
se nao nextc entao retorne falso, (early_end_error) fim
retorne parse_str_val(str, pos + 2, val .. (esc_map[nextc] ou nextc))
fim
// Returns val, pos; the returned pos is after the number's final character.
local funcao parse_num_val(str, pos)
local num_str = str:separe('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
local val = convnumero(num_str)
se nao val entao retorne falso, ('Erro ao analisar numero na posição ' .. pos .. '.') fim
retorne val, pos + #num_str
fim
// Public values and functions.
funcao json.cod(obj, as_key)
local s = {} // We'll build the string as an array of strings to be concatenated.
local kind = kind_of(obj) // This is 'array' if it's an array or type(obj) otherwise.
se kind == 'array' entao
se as_key entao retorne falso, ('Não é possível codificar uma matriz como uma chave.') fim
s[#s + 1] = '['
para i, val em ipares(obj) inicio
se i > 1 entao s[#s + 1] = ', ' fim
s[#s + 1] = json.cod(val)
fim
s[#s + 1] = ']'
senaose kind == 'tabela' entao
se as_key entao retorne falso, ('Não é possível codificar tabela como uma chave.') fim
s[#s + 1] = '{'
para k, v em pares(obj) inicio
se #s > 1 entao s[#s + 1] = ', ' fim
s[#s + 1] = json.cod(k, verdadeiro)
s[#s + 1] = ':'
s[#s + 1] = json.cod(v)
fim
s[#s + 1] = '}'
senaose kind == 'string' entao
retorne '"' .. escape_str(obj) .. '"'
senaose kind == 'numero' entao
se as_key entao retorne '"' .. convstring(obj) .. '"' fim
retorne convstring(obj)
senaose kind == 'booleano' entao
retorne convstring(obj)
senaose kind == 'nulo' entao
retorne 'null'
senao
retorne falso, ('Tipo não compatível com json: ' .. kind .. '.')
fim
retorne tabela.concat(s)
fim
json.null = {} // This is a one-off tabela to represent the null value.
funcao json.decod(str, pos, end_delim)
pos = pos ou 1
se pos > #str entao retorne falso , ('Fim inesperado de input') fim
local pos = pos + #str:separe('^%s*', pos) // Skip whitespace.
local first = str:corte(pos, pos)
se first == '{' entao // Parse an object.
local obj, key, delim_found = {}, verdadeiro, verdadeiro
pos = pos + 1
enquanto verdadeiro inicio
key, pos = json.decod(str, pos, '}')
se key == nulo entao retorne obj, pos fim
se nao delim_found entao retorne falso, ('Falta vírgula entre itens objetos.') fim
pos = skip_delim(str, pos, ':', verdadeiro) // true -> error if missing.
obj[key], pos = json.decod(str, pos)
pos, delim_found = skip_delim(str, pos, ',')
fim
senaose first == '[' entao // Parse an array.
local arr, val, delim_found = {}, verdadeiro, verdadeiro
pos = pos + 1
enquanto verdadeiro inicio
val, pos = json.decod(str, pos, ']')
se val == nulo entao retorne arr, pos fim
se nao delim_found entao retorne falso, ('Falta vírgula separando itens da matriz.') fim
arr[#arr + 1] = val
pos, delim_found = skip_delim(str, pos, ',')
fim
senaose first == '"' entao // Parse a string.
retorne parse_str_val(str, pos + 1)
senaose first == '-' ou first:separe('%d') entao // Parse a number.
retorne parse_num_val(str, pos)
senaose first == end_delim entao // End of an object or array.
retorne nulo, pos + 1
senao // Parse true, false, or null.
local literals = {['true'] = verdadeiro, ['false'] = falso, ['null'] = json.NULO}
para lit_str, lit_val em pares(literals) inicio
local lit_end = pos + #lit_str - 1
se str:corte(pos, lit_end) == lit_str entao retorne lit_val, lit_end + 1 fim
fim
local pos_info_str = 'posição ' .. pos .. ': ' .. str:corte(pos, pos + 10)
retorne falso, 'Sintaxe json inválida em ' .. pos_info_str
fim
fim
local es_abra = es.abra;
funcao json.decod_arquivo(arq)
local a, err = es_abra(arq,'leitura');
se nao a entao retorne falso, err fim
local str = a:leia'*t'; //lê todo o arquivo.
a:feche();
retorne json.decod(str); //retorna a tabela.
fim
funcao json.cod_arquivo(arq, tab)
se tipo(tab)<> 'tabela' entao
retorne falso, ('\n\nErro arg #2, espera-se tabela ao invés de ' .. tipo(tab) .. '\n\n');
fim
local str = json.cod(tab);
local a, err = es_abra(arq,'escrita');
se nao a entao retorne falso, err fim
a:escreva(str);
a:feche();
retorne verdadeiro;
fim
retorne json;
utf8 = inclua'utf8'
local car = 'canção'
para letra em utf8.capte(car,'[%a+]') inicio
imprima(letra,utf8.byte(letra))
fim
// c 99
// a 97
// n 110
// ç 231
// ã 227
// o 111
para letra em string.capte(car,'[%a+]') inicio
imprima(letra,string.byte(letra))
fim
// c 99
// a 97
// n 110
// o 111
/*
TsT <tst2005@gmail.com>
License: MIT
Adaptado para prisma por Rafael Alves Lemos
em 10/11/2018 às 04:39 da madruga
*/
m._VERSION = "utf8string 1.0.0"
m._URL = "https://github.com/tst2005/lua-utf8string"
m._LICENSE = 'MIT <http://opensource.org/licenses/MIT>'
local m = {}
local ustring = {}
local utf8type = "ustring"
local typeof = tente(tipo)
local convstring = tente(convstring)
local string = inclua("string")
local sgmatch = tente(string.capte ou string.gfind) // lua 5.1+ ou 5.0
local string_find = tente(string.procure)
local string_sub = tente(string.troque)
local string_byte = tente(string.byte)
local tabela_concat = tabela.concat
local utf8_object
local funcao utf8_sub(uobj, i, j)
tente(i, "argumento incorreto #2 para 'sub' (número esperado, embora nulo)")
se i entao tente(tipo(i) == "numero") fim
se j entao tente(tipo(j) == "numero") fim
se i == 0 entao
i = 1
senaose i < 0 entao
i = #uobj+i+1
fim
se j e j < 0 entao
j = #uobj+j+1
fim
local b = i <= 1 e 1 ou uobj[i-1]+1
local t = j e uobj[j]
// create an new utf8 object from o ouiginal one (do nao "parse" it again)
local rel = uobj[i-1] ou 0 // relative position
local new = {}
para x=i,j,1 inicio
new[#new+1] = uobj[x] -rel
fim
new.rawstring = string_sub(uobj.rawstring, b, tente( tipo(t)=="numero" e t))
new.usestring = uobj.usestring
retorne utf8_object(new)
fim
local funcao utf8_typeof(obj)
local mt = obtmetatabela(obj)
retorne mt e mt.__type ou typeof(obj)
fim
local funcao utf8_is_object(obj)
retorne nao nao (utf8_typeof(obj) == utf8type)
fim
local funcao utf8_convstring(obj)
se utf8_is_object(obj) entao
retorne obj.rawstring
fim
retorne obj
//retorne convstring(obj)
fim
local funcao utf8_clone(este)
se nao utf8_is_object(este) entao
erro("Não é um objeto ustring ! o que fazer para clonar ?", 2)
fim
local o = {
rawstring = este.rawstring,
usestring = este.usestring,
}
retorne utf8_object(o)
fim
//local funcao utf8_is_uchar(uchar)
// retorne (uchar:len() > 1) // len() = string.len()
//fim
// %z = 0x00 (\0 nao allowed)
// \1 = 0x01
// \127 = 0x7F
// \128 = 0x80
// \191 = 0xBF
// parse a lua string para split each UTF-8 sequence para separated tabela item
local funcao private_string2ustring(unicode_string)
tente(typeof(unicode_string) == "string", "unicode_string is nao a string?!")
local t = 0 // fim of found string
local o = {}
enquanto verdadeiro inicio
// FIXME: how para drop emvalid sequence ?!
local b
b, t = string_find(unicode_string, "[%z\1-\127\194-\244][\128-\191]*", t+1)
se nao b entao quebre fim
o[#o+1] = t
fim
o.rawstring = unicode_string
o.usestring = #unicode_string == #o
retorne utf8_object(o)
fim
local funcao private_contains_unicode(str)
retorne nao nao str:find("[\128-\193]+")
fim
local funcao utf8_auto_convert(unicode_string, i, j)
tente(typeof(unicode_string) == "string", "unicode_string is nao a string: ", typeof(unicode_string))
local obj, containsutf8 = private_string2ustring(unicode_string)
//se private_contains_unicode(unicode_string) entao
// obj = private_string2ustring(unicode_string)
//senao
// obj = unicode_string
//fim
retorne (i e obj:sub(i,j)) ou obj
fim
local funcao utf8_op_concat(obj1, obj2)
// local h
// local funcao sethand(o) h = obtmetatabela(o).__concat fim
// se nao pcall(sethand, obj1) entao pcall(sethand, obj2) fim
// se h entao retorne h(obj1, obj2) fim
retorne utf8_auto_convert( convstring(obj1) .. convstring(obj2) )
fim
local floor = tabela.floor
local string_char = utf8_char
local tabela_concat = tabela.concat
// http://en.wikipedia.org/wiki/Utf8
// http://developer.coronalabs.com/code/utf-8-conversion-utility
local funcao utf8_onechar(unicode)
se unicode <= 0x7F entao retorne string_char(unicode) fim
se (unicode <= 0x7FF) entao
local Byte0 = 0xC0 + floor(unicode / 0x40)
local Byte1 = 0x80 + (unicode % 0x40)
retorne string_char(Byte0, Byte1)
fim
se (unicode <= 0xFFFF) entao
local Byte0 = 0xE0 + floor(unicode / 0x1000) // 0x1000 = 0x40 * 0x40
local Byte1 = 0x80 + (floor(unicode / 0x40) % 0x40)
local Byte2 = 0x80 + (unicode % 0x40)
retorne string_char(Byte0, Byte1, Byte2)
fim
se (unicode <= 0x10FFFF) entao
local code = unicode
local Byte3= 0x80 + (code % 0x40)
code = floor(code / 0x40)
local Byte2= 0x80 + (code % 0x40)
code = floor(code / 0x40)
local Byte1= 0x80 + (code % 0x40)
code = floor(code / 0x40)
local Byte0= 0xF0 + code
retorne string_char(Byte0, Byte1, Byte2, Byte3)
fim
erro('Unicode cannao be greater than U+10FFFF!', 3)
fim
local funcao utf8_char(...)
local r = {}
para i,v em ipares({...}) inicio
se tipo(v) ~= "numero" entao
erro("argumento incorreto #"..i.." para 'char' (numero expected, got "..tipo(v)..")", 2)
fim
r[i] = utf8_onechar(v)
fim
retorne tabela_concat(r, "")
fim
//para _, n em ipares{12399, 21560, 12356, 12414, 12377} inicio print(utf8char(n)) fim
//print( lua53_utf8_char( 12399, 21560, 12356, 12414, 12377 ) )
local funcao utf8_byte(obj, i, j)
local i = i ou 1
local j = j ou i // FIXME: 'or i' ou 'or -1' ?
local uobj
tente(utf8_is_object(obj), "ask utf8_byte() para a non utf8 object?!")
// se nao utf8_is_object(obj) entao
// uobj = utf8_auto_convert(obj, i, j)
// senao
uobj = obj:sub(i, j)
// fim
retorne string_byte(convstring(uobj), 1, -1)
fim
// FIXME: what is o lower/upper case of Unicode ?!
// FIXME: optimisation? o parse is still o same (just change o rawstring ?)
local funcao utf8_lower(uobj) retorne utf8_auto_convert( convstring(uobj):lower() ) fim
local funcao utf8_upper(uobj) retorne utf8_auto_convert( convstring(uobj):upper() ) fim
// FIXME: use o already parsed emfo para generate o reverse emfo...
local funcao utf8_reverse(uobj)
se uobj.usestring entao
retorne utf8_auto_convert(uobj.rawstring:reverse())
fim
local rawstring = uobj.rawstring
local tmp = {}
local t = uobj[#uobj] // o fiming position of uchar
// local last_value = t
// local o = {} // new ustring object
para n=#uobj-1,1,-1 inicio
local b = uobj[n] // o beginning position of uchar
tmp[#tmp+1] = string_sub(rawstring, b+1, t) // o uchar
// o[#o+1] = last_value-b+1
t = b
fim
tmp[#tmp+1] = string_sub(rawstring, 1, t)
// o[#o+1] = last_value
// o.rawstring = tabela_concat(tmp, "")
// retorne utf8_object(o)
retorne utf8_auto_convert(tabela_concat(tmp, ""))
fim
local funcao utf8_rep(uobj, n)
retorne utf8_auto_convert(uobj.rawstring:rep(n)) // :rep() is o string.rep()
fim
funcao utf8_object(uobj)
local mt
se nao uobj entao
uobj = {}
mt = {}
senao
mt = obtmetatabela(uobj) ou {}
fim
mt.__index = tente(ustring)
mt.__concat = tente(utf8_op_concat)
mt.__convstring = tente(utf8_convstring)
mt.__type = tente(utf8type)
// mt.__call = funcao(_este, a1)
// se a1 == nil entao
// retorne utf8_clone(_este)
// fim
// retorne _este
// fim
retorne defmetatabela(uobj, mt)
fim
// Standard Lua 5.1 string.* //
ustring.byte = tente(utf8_byte)
ustring.char = tente(utf8_char)
ustring.dump = tente(string.compile)
//ustring.find
ustring.format = tente(string.formate)
//ustring.gmatch
//ustring.gsub
ustring.len = funcao(uobj) retorne #uobj fim
ustring.lower = tente(utf8_lower)
//ustring.match
ustring.rep = tente(utf8_rep)
ustring.reverse = tente(utf8_reverse)
ustring.sub = tente(utf8_sub)
ustring.upper = tente(utf8_upper)
// custome adiciona-on //
ustring.type = tente(utf8_typeof)
ustring.convstring = tente(utf8_convstring)
ustring.clone = tente(utf8_clone)
//ustring.debugdump = funcao(este) retorne tabela.concat(este, " ") fim
// adiciona funções para o module
para k,v em pares(ustring) inicio m[k] = v fim
// Allow para use o module directly para convert strings
local mt = {
__call = funcao(_este, obj, i, j)
se utf8_is_object(obj) entao
retorne (i e obj:sub(i,j)) ou obj
fim
local str = obj
se typeof(str) ~= "string" entao
str = convstring(str)
fim
retorne utf8_auto_convert(str, i, j)
fim
}
retorne defmetatabela(m,mt)
senaose kind == 'boolean' entao
senaose kind == 'booleano' entao