196 lines
6.7 KiB
Plaintext
196 lines
6.7 KiB
Plaintext
# Form String Extractor
|
|
# Extracts user-facing strings from TypeDialog TOML forms for i18n
|
|
# Generates Fluent keys and string catalogs
|
|
|
|
use std
|
|
|
|
# Extract strings from a single TOML form file
|
|
export def extract-form-strings [
|
|
form_path: string
|
|
] {
|
|
let content = (open $form_path)
|
|
|
|
let extracted = (
|
|
if ($content | has "elements") {
|
|
$content.elements | reduce -f [] { |elem, acc|
|
|
let elem_name = ($elem | get name? | default "unknown")
|
|
let prompt_entry = (
|
|
if ($elem | has "prompt") {
|
|
let prompt = ($elem | get prompt)
|
|
if ($prompt != null) and ($prompt != "") {
|
|
[{
|
|
key: $"form-($elem_name)-prompt"
|
|
en: $prompt
|
|
type: "prompt"
|
|
}]
|
|
} else {
|
|
[]
|
|
}
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
let help_entry = (
|
|
if ($elem | has "help") {
|
|
let help = ($elem | get help)
|
|
if ($help != null) and ($help != "") {
|
|
[{
|
|
key: $"form-($elem_name)-help"
|
|
en: $help
|
|
type: "help"
|
|
}]
|
|
} else {
|
|
[]
|
|
}
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
let placeholder_entry = (
|
|
if ($elem | has "placeholder") {
|
|
let placeholder = ($elem | get placeholder)
|
|
if ($placeholder != null) and ($placeholder != "") {
|
|
[{
|
|
key: $"form-($elem_name)-placeholder"
|
|
en: $placeholder
|
|
type: "placeholder"
|
|
}]
|
|
} else {
|
|
[]
|
|
}
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
let options_entries = (
|
|
if ($elem | has "options") and ($elem.type == "select") {
|
|
$elem.options | reduce -f [] { |opt, opts_acc|
|
|
let label_entry = (
|
|
if ($opt | has "label") {
|
|
[{
|
|
key: $"form-($elem_name)-option-($opt.value)"
|
|
en: ($opt | get label)
|
|
type: "option_label"
|
|
}]
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
let desc_entry = (
|
|
if ($opt | has "description") {
|
|
[{
|
|
key: $"form-($elem_name)-desc-($opt.value)"
|
|
en: ($opt | get description)
|
|
type: "option_desc"
|
|
}]
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
$opts_acc | append $label_entry | append $desc_entry | flatten
|
|
}
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
let title_entry = (
|
|
if ($elem | has "title") {
|
|
let title = ($elem | get title)
|
|
if ($title != null) and ($title != "") {
|
|
[{
|
|
key: $"section-($elem_name)-title"
|
|
en: $title
|
|
type: "section_title"
|
|
}]
|
|
} else {
|
|
[]
|
|
}
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
let desc_entry = (
|
|
if ($elem | has "description") and ($elem.type == "section_header") {
|
|
let desc = ($elem | get description)
|
|
if ($desc != null) and ($desc != "") {
|
|
[{
|
|
key: $"section-($elem_name)-desc"
|
|
en: $desc
|
|
type: "section_desc"
|
|
}]
|
|
} else {
|
|
[]
|
|
}
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
$acc
|
|
| append $prompt_entry
|
|
| append $help_entry
|
|
| append $placeholder_entry
|
|
| append $options_entries
|
|
| append $title_entry
|
|
| append $desc_entry
|
|
| flatten
|
|
}
|
|
} else {
|
|
[]
|
|
}
|
|
)
|
|
|
|
# Extract from load_fragments references
|
|
# Note: Fragments are loaded recursively - future enhancement
|
|
|
|
$extracted
|
|
}
|
|
|
|
# Generate Fluent format from string catalog
|
|
export def generate-fluent [
|
|
strings: list
|
|
--language: string = "en-US"
|
|
] {
|
|
let header = $"# Auto-generated Fluent translations\n# Language: ($language)\n# Generated by form_string_extractor.nu\n\n"
|
|
|
|
let fluent_entries = (
|
|
$strings
|
|
| reduce -f [] { |str, acc|
|
|
let source = (if $language == "en-US" { $str.en } else { "TODO" })
|
|
let line = ($str.key + " = " + $source)
|
|
$acc | append $line
|
|
}
|
|
| str join "\n"
|
|
)
|
|
|
|
$header + $fluent_entries + "\n"
|
|
}
|
|
|
|
# Count unique strings across forms
|
|
export def count-strings [
|
|
forms_list: list
|
|
] {
|
|
$forms_list | reduce -f {total: 0, by_type: {}} { |form_path, acc|
|
|
let strings = (extract-form-strings $form_path)
|
|
let new_total = ($acc.total + ($strings | length))
|
|
|
|
let new_by_type = ($strings | reduce -f $acc.by_type { |str, type_acc|
|
|
let type_key = $str.type
|
|
let current_count = (if ($type_acc | has $type_key) { ($type_acc | get $type_key) } else { 0 })
|
|
$type_acc | insert $type_key ($current_count + 1)
|
|
})
|
|
|
|
{
|
|
total: $new_total
|
|
by_type: $new_by_type
|
|
}
|
|
}
|
|
}
|