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