add missing files
parent
f5148da326
commit
36b9bae647
|
@ -0,0 +1,180 @@
|
||||||
|
function translation_file(translations; interpolation = false)
|
||||||
|
interpolate = "String fill(List<Object> params) => localizeFill(this, params);"
|
||||||
|
"""import 'package:i18n_extension/i18n_extension.dart';
|
||||||
|
|
||||||
|
extension Localization on String {
|
||||||
|
|
||||||
|
static var _t = Translations.byLocale("en_us") +
|
||||||
|
{
|
||||||
|
$(translations)
|
||||||
|
};
|
||||||
|
$(interpolation ? interpolate : "")
|
||||||
|
String get i18n => localize(this, _t);
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
placeholder(n; place = "STRING") = string(place, "#", string(n, pad=20))
|
||||||
|
function extract(regex, content)
|
||||||
|
placeholders = Dict()
|
||||||
|
for (idx, interp) in enumerate(eachmatch(regex, content))
|
||||||
|
holder = placeholder(idx, place = "INTERPOLATION")
|
||||||
|
placeholders[holder] = interp.match
|
||||||
|
end
|
||||||
|
placeholders
|
||||||
|
end
|
||||||
|
|
||||||
|
function replace_extracted(content, placeholders)
|
||||||
|
inv = Dict(map((p) -> p[2] => p[1], collect(placeholders)))
|
||||||
|
# for placeholder in keys(placeholder)
|
||||||
|
for key in keys(inv)
|
||||||
|
content = replace(content, key => inv[key])
|
||||||
|
end
|
||||||
|
content
|
||||||
|
end
|
||||||
|
|
||||||
|
function find_all_strings(basepath, filepath)
|
||||||
|
content = read(joinpath(basepath, filepath), String)
|
||||||
|
# String interpolation ${} can contain anything (including unescaped strings)
|
||||||
|
# So it's better to extract it before doing anything
|
||||||
|
# Replace them with identifiers
|
||||||
|
placeholders = extract(r"(\$\{.*?\}|\$[A-Za-z][A-Za-z0-9]*)", content)
|
||||||
|
content = replace_extracted(content, placeholders)
|
||||||
|
# interpolations = replace(content, r"${.*}" => )
|
||||||
|
matches =
|
||||||
|
eachmatch(r"""(?P<quote>'''|'|")(?P<string>.+?)(?<!\\)\k<quote>(?P<i18n>\.i18n)?"""s, content)
|
||||||
|
# long_lines = [
|
||||||
|
# placeholder(i, place = "LONGDESCRIPTION") => a for (i, a) in
|
||||||
|
# filter(m -> occursin("\n", m.match), collect(matches)) |> enumerate
|
||||||
|
# ] |> Dict
|
||||||
|
# Now we need to find the lines of the matches.
|
||||||
|
(placeholders = placeholders,
|
||||||
|
matches = collect(matches),
|
||||||
|
content = content)
|
||||||
|
end
|
||||||
|
|
||||||
|
# function find_all_strings(basepath, filepath; i18n = true)
|
||||||
|
# content = read(joinpath(basepath, filepath), String)
|
||||||
|
# # Remove comments
|
||||||
|
# content = replace(content, r"""///?.*"""m => "")
|
||||||
|
# content = replace(content, r"""/\*.*?\*/"""s => "")
|
||||||
|
# # Remove imports/export
|
||||||
|
# content = replace(content, r"""(import|export|part) .*"""m => "")
|
||||||
|
# # Mark new lines to extract string positions
|
||||||
|
# lines = findall(x -> x == '\n', collect(content))
|
||||||
|
# # Find all types of strings
|
||||||
|
# # ? EXCLUDE PRINT?
|
||||||
|
# strings = eachmatch(r"""(['"])(.*?)\1(\.i18n)?""", content)
|
||||||
|
# out = []
|
||||||
|
# for string in strings
|
||||||
|
# (i18n && isnothing(string[3])) && continue
|
||||||
|
# # TODO: Interactively modify the source code to:
|
||||||
|
# # 1. Add the .i18n
|
||||||
|
# # 2. Include the file
|
||||||
|
# # Get the line of the match
|
||||||
|
# line = findfirst(line -> line >= string.offset, lines)
|
||||||
|
# push!(out, (file = filepath, line = line, strid = string[2]))
|
||||||
|
# end
|
||||||
|
# out
|
||||||
|
# end
|
||||||
|
|
||||||
|
dartfiles(files) = filter(f -> endswith(f, ".dart"), files)
|
||||||
|
function find_dart_files(path)
|
||||||
|
out = []
|
||||||
|
for (root, dirs, files) in walkdir(path)
|
||||||
|
for file in dartfiles(files)
|
||||||
|
push!(out, joinpath(root, file))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
out
|
||||||
|
end
|
||||||
|
|
||||||
|
function find_all_strings(path)
|
||||||
|
no_i18n(files) = filter(f -> !endswith(f, "i18n.dart"), files)
|
||||||
|
excluded(files) = filter(f -> !(f in exclude), files)
|
||||||
|
path = realpath(path)
|
||||||
|
files = find_dart_files(path) |> no_i18n
|
||||||
|
find_all_strings.(Ref(path), files)
|
||||||
|
end
|
||||||
|
|
||||||
|
read_dart_project(path; exclude = []) = find_all_strings(path, exclude = exclude, i18n = true)
|
||||||
|
|
||||||
|
function i18n_project(path)
|
||||||
|
exc = ".i18n-excluded"
|
||||||
|
ign = ".i18n-ignored"
|
||||||
|
splitter = "\0¤\0"
|
||||||
|
ignored = isfile(ign) ? map(l -> split(l, splitter), readlines(ign)) : []
|
||||||
|
new_excludes = []
|
||||||
|
edits = []
|
||||||
|
adds = []
|
||||||
|
cd(path) do
|
||||||
|
exclude = isfile(exc) ? readlines(exc) : []
|
||||||
|
strings = vcat(find_all_strings(path; exclude = exclude, i18n = false)...)
|
||||||
|
files = map(s -> s.file, strings) |> unique
|
||||||
|
@info "You have a total of $(length(strings)) strings in $(length(files)) files"
|
||||||
|
@warn "!!!Remember to git commit before running this!!!"
|
||||||
|
for file in files
|
||||||
|
content = readlines(file)
|
||||||
|
@info "Inspecting file $(file)?"
|
||||||
|
for str in filter(s -> s.file == file, strings)
|
||||||
|
if !isnothing(findfirst(i -> i[1] == str.file &&
|
||||||
|
i[2] == string(str.line) &&
|
||||||
|
i[3] == str.strid, ignored))
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
println("Line $(str.line): >$(str.strid)< ")
|
||||||
|
println(content[str.line])
|
||||||
|
println("[e]xclude, [a]dd, [c]hange, [i]gnore")
|
||||||
|
resp = ' '
|
||||||
|
while !(resp in ["e", "a", "c", "i"])
|
||||||
|
resp = readline(stdin)
|
||||||
|
end
|
||||||
|
if resp == "e"
|
||||||
|
push!(new_excludes, file)
|
||||||
|
break
|
||||||
|
elseif resp == "a"
|
||||||
|
push!(adds, str)
|
||||||
|
continue
|
||||||
|
elseif resp == "c"
|
||||||
|
push!(edits, str => readline(stdin))
|
||||||
|
elseif resp == "i"
|
||||||
|
open(ign, "a+") do f
|
||||||
|
println(f, join([str.file, str.line, str.strid], splitter))
|
||||||
|
end
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
@error "Unknown problem"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
## Process changes
|
||||||
|
@warn "Applying changes in 3s... last chance to interrupt (Ctrl-C)"
|
||||||
|
sleep(3)
|
||||||
|
open(exc, "a+") do f
|
||||||
|
write(f, join(new_excludes, "\n"))
|
||||||
|
end
|
||||||
|
edits, adds
|
||||||
|
end
|
||||||
|
|
||||||
|
struct Translation
|
||||||
|
lang::String
|
||||||
|
msgstr::String
|
||||||
|
end
|
||||||
|
|
||||||
|
struct Translatable
|
||||||
|
msgid::String
|
||||||
|
translations::Array{Translation}
|
||||||
|
file::Union{String,Nothing}
|
||||||
|
line::Union{UInt,Nothing}
|
||||||
|
end
|
||||||
|
|
||||||
|
function dart_to_pot(path)
|
||||||
|
files = find_all_strings(path)
|
||||||
|
for file in files
|
||||||
|
i18n_s = filter(!isnothing, map(m -> m["i18n"], file.matches))
|
||||||
|
length(i18n_s) == 0 && continue
|
||||||
|
@show i18n_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Pot import/export functions
|
||||||
|
|
||||||
|
is_comment(line; char = r"#") = startswith(line, char)
|
||||||
|
|
||||||
|
function readpot(path, lang, name = "base")
|
||||||
|
lines = readlines(joinpath(path, lang, "LC_MESSAGES", string(name, ".pot")))
|
||||||
|
filter!(x -> !is_comment(x, char = r"#(?!:)"), lines)
|
||||||
|
filter!(!isempty, lines)
|
||||||
|
lines = lines[3:end]
|
||||||
|
@assert length(lines) % 3 == 0
|
||||||
|
output = []
|
||||||
|
for l in 1:3:length(lines)
|
||||||
|
ref = split(lines[l], "#: ")
|
||||||
|
msgid = split(lines[l+1], "msgid ")
|
||||||
|
msgstr = split(lines[l+2], "msgstr ")
|
||||||
|
@assert length(ref) == 2
|
||||||
|
@assert length(msgid) == 2
|
||||||
|
@assert length(msgstr) == 2
|
||||||
|
id = split(msgid[2], '"')
|
||||||
|
str = split(msgstr[2], '"')
|
||||||
|
if length(id) != 3 && l != 1
|
||||||
|
@warn "Problems with $msgstr $msgid"
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
if isempty(str[2])
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
push!(output, (lang, id[2], str[2], split(ref[2], ":")[1]))
|
||||||
|
end
|
||||||
|
output
|
||||||
|
end
|
||||||
|
|
||||||
|
function pot_to_jl(lang, id)
|
||||||
|
"""@translate "$lang" "$(id[2])" "$(str[2])" """
|
||||||
|
end
|
||||||
|
|
||||||
|
function pot_to_jl(srcpath, destpath, filename, basename)
|
||||||
|
langs = readdir(srcpath)
|
||||||
|
content = join([join(readpot(srcpath, lang, basename), "\n")
|
||||||
|
for lang in langs], "\n\n")
|
||||||
|
write(joinpath(destpath, string(filename, ".jl")), content)
|
||||||
|
end
|
|
@ -0,0 +1,6 @@
|
||||||
|
struct Translatable
|
||||||
|
string::AbastractString
|
||||||
|
file::String
|
||||||
|
line::Int
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue