po2tr.lua 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/env luajit
  2. -- Convert regular Gettext PO files to Minetest-specific TR files. If there is
  3. -- already a TR file with the same name of the PO file except the file suffix
  4. -- bneing .tr (or .TR) instead of .po (or .PO) then THIS FILE WILL BE
  5. -- OVERWRITTEN WITHOUT INFORMATION OR A WAY TO RECOVER THE PREVIOUS FILE!
  6. --
  7. --
  8. -- ▄██▄
  9. -- ▀███
  10. -- █
  11. -- ▄▄▄▄▄ █
  12. -- ▀▄ ▀▄ █ BACKUP
  13. -- ▄▀▀▀▄ █▄▄▄▄█▄▄ ▄▀▀▀▄ █
  14. -- █ ▄ █ █ ▄ █ █
  15. -- ▀▄ ▄▀ ▀▄ ▄▀ █
  16. -- █▀▀▀ ▀▀▀ █ █
  17. -- █ █ █ ALL
  18. -- ▄▀▄▄▀▄ █ ▄█▀█▀█▀█▀█▀█▄ █ █
  19. -- █▒▒▒▒█ █ █████████████▄ █ █
  20. -- █▒▒▒▒█ █ ██████████████▄ █ █
  21. -- █▒▒▒▒█ █ ██████████████▄ █ █
  22. -- █▒▒▒▒█ █ ██████████████ █ █
  23. -- █▒▒▒▒█ █ ██████████████▀ █ █ THE
  24. -- █▒▒▒▒█ ██ ██████████████ █ █
  25. -- ▀████▀ ██▀█ █████████████▀ █▄█
  26. -- ██ ██ ▀█ █▄█▄█▄█▄█▄█▀ ▄█▀
  27. -- ██ ██ ▀█ ▄▀▓█
  28. -- ██ ██ ▀█▀▄▄▄▄▄▄▄▄▄▀▀▓▓▓█
  29. -- ████ █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█
  30. -- ███ █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█ THINGS
  31. -- ██ █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█
  32. -- ██ █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█
  33. -- ██ ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█
  34. -- ██ ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█
  35. -- ██ ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▌ !!!
  36. -- ██ ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▌
  37. -- ██ ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▌
  38. -- ██ ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▌
  39. --
  40. --
  41. -- The syntax of TR files according to the introducing forum post is:
  42. --
  43. -- # textdomain: namespace
  44. -- original 1 = translation 1
  45. -- original 2 = translation 2
  46. -- original 3 = tralslation 3
  47. -- original N = translation N
  48. --
  49. -- Where namespace should be the name of the mod. Following strings have to be
  50. -- escaped using @.
  51. --
  52. -- String | Escape
  53. -- -------+--------
  54. -- `@` |`@@`
  55. -- `=` |`@=`
  56. -- `\n` |`@\n`
  57. --
  58. -- See https://forum.minetest.net/viewtopic.php?t=18349 for details.
  59. -- Preparation
  60. if arg[1] == nil or arg[2] == nil then
  61. print('Provide the namesspace as first parameter')
  62. print('Provide the path to the source PO file as second parameter')
  63. print('Example: '..arg[0]..' mymod path/to/my/source.po')
  64. return
  65. end
  66. local SEP = package.path:match('(%p)%?%.') or '/' -- wonky but hey ... :)
  67. -- Assign parameters to local variables
  68. local namespace = arg[1]
  69. local po_file = arg[2]
  70. local tr_file = arg[2]:gsub('po$', 'tr'):gsub('PO$', 'TR')
  71. -- Get the translations through crude plaintext file parsing
  72. local file_contents = {}
  73. local translations = {}
  74. local po_file_handle = io.open(po_file, 'rb')
  75. if po_file_handle == nil then print('No base file found') return end
  76. for line in po_file_handle:lines() do
  77. if line:match('^msgid') or line:match('^msgstr') then
  78. table.insert(file_contents, line)
  79. end
  80. end
  81. local escape_string = function (s)
  82. s = s:gsub('@([^%d])', '@@%1') -- All @ not followed by a number become @@
  83. s = s:gsub('([^@]@)$', '%1@') -- An @ at the end of the string become @@
  84. s = s:gsub('=', '@=') -- All = become @=
  85. return s
  86. end
  87. for number,line_content in pairs(file_contents) do
  88. if line_content:match('^msgid') then
  89. local o = line_content:gsub('^msgid "(.+)"$', '%1')
  90. local t = file_contents[number + 1]:gsub('^msgstr "(.+)"$', '%1')
  91. if o ~= 'msgid = ""' and t ~= 'msgstr ""' then
  92. table.insert(translations, escape_string(o)..'='..escape_string(t))
  93. end
  94. end
  95. end
  96. print(number)
  97. po_file_handle:close()
  98. -- Write translation to file
  99. local tr_file_handle = io.open(tr_file, 'w+')
  100. if tr_file_handle == nil then print('Could not open target file') return end
  101. tr_file_handle:write('# textdomain: '..namespace, "\n")
  102. for _,line in pairs(translations) do tr_file_handle:write(line, "\n") end
  103. tr_file_handle:close()