Files

78 lines
2.3 KiB
Python
Executable File

#!/usr/bin/env python3
import ast
import struct
import sys
from pathlib import Path
def read_po(path):
messages = {}
current = None
buffers = {"msgid": [], "msgstr": []}
def flush():
if buffers["msgid"] or buffers["msgstr"]:
messages["".join(buffers["msgid"])] = "".join(buffers["msgstr"])
buffers["msgid"] = []
buffers["msgstr"] = []
for raw_line in path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line or line.startswith("#"):
continue
if line.startswith("msgid "):
flush()
current = "msgid"
buffers[current].append(ast.literal_eval(line[6:].strip()))
continue
if line.startswith("msgstr "):
current = "msgstr"
buffers[current].append(ast.literal_eval(line[7:].strip()))
continue
if line.startswith('"') and current:
buffers[current].append(ast.literal_eval(line))
flush()
return messages
def write_mo(messages, path):
keys = sorted(messages)
ids = b"\x00".join(key.encode("utf-8") for key in keys) + b"\x00"
strs = b"\x00".join(messages[key].encode("utf-8") for key in keys) + b"\x00"
keystart = 7 * 4 + len(keys) * 16
valuestart = keystart + len(ids)
koffsets = []
voffsets = []
offset = keystart
for key in keys:
encoded = key.encode("utf-8")
koffsets.append((len(encoded), offset))
offset += len(encoded) + 1
offset = valuestart
for key in keys:
encoded = messages[key].encode("utf-8")
voffsets.append((len(encoded), offset))
offset += len(encoded) + 1
output = [
struct.pack("Iiiiiii", 0x950412DE, 0, len(keys), 7 * 4, 7 * 4 + len(keys) * 8, 0, 0)
]
output.extend(struct.pack("ii", length, offset) for length, offset in koffsets)
output.extend(struct.pack("ii", length, offset) for length, offset in voffsets)
output.append(ids)
output.append(strs)
path.write_bytes(b"".join(output))
def main():
root = Path(sys.argv[1] if len(sys.argv) > 1 else "locale")
for po in root.glob("*/LC_MESSAGES/*.po"):
mo = po.with_suffix(".mo")
write_mo(read_po(po), mo)
print(mo)
if __name__ == "__main__":
main()