Scripting tools to interact with Thea 2 The Shattering files in order to translate them easily.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
6.2 KiB

  1. #!/bin/bash
  2. if [[ "$#" -ne 2 ]]; then
  3. echo "Please pass exactly 2 parameters: the .po and the language"
  4. exit 1
  5. fi
  6. LANGUAGE="${2}"
  7. WORKDIR="/tmp/thea2/${LANGUAGE}"
  8. PO="${1}"
  9. FINALDIR="$(pwd)/Translation/${LANGUAGE}/game_files/Modules/"
  10. TXT=$(basename "${PO%%.po}.txt")
  11. TXT="${FINALDIR}/${TXT}"
  12. dos2unix "${PO}" &> /dev/null
  13. # Initialization
  14. mkdir -p "${WORKDIR}"
  15. mkdir -p "${FINALDIR}"
  16. truncate -s 0 "${TXT}"
  17. readarray -t FILE < "${PO}"
  18. declare -A eventArray=()
  19. declare -A translationArray=()
  20. # First thing first, let's anonymize the po and delete all email references
  21. sed -i 's/[A-Za-z0-9._%+-]\+@[A-Za-z0-9.-]\+\.[A-Za-z]\{2,6\}//' "${PO}"
  22. function extract_translation {
  23. key="${line}"
  24. # We need to escape special char for regex: [ + and (
  25. key="${key//[/\\\\[}"
  26. key="${key//+/\\\\\+}"
  27. key="${key//(/\\\\\(}"
  28. # We search for the exact key in the po file until we get a blank line, to get the full msgstr and the msgid
  29. tempPO=$(awk -v key="${key}" '{pat="#. "key"$"} !NF{s=0}s;$0 ~ pat{ print $0; s=1 }' "${PO}")
  30. # Extract msgstr and merge all lines into one
  31. tempMsgstr=$(awk '!NF{s=0}s;/msgstr/{ print $0; s=1 }' <<< "${tempPO}" | sed -e 's/^"//' -e 's/"$//' -e 's/^msgstr "//')
  32. msgstr=$(awk 'NR{printf "%s",$0;next;}1' <<< ${tempMsgstr})
  33. # Extract msgid and merge all lines into one
  34. tempMsgid="$(awk '/msgid/{ s=1 }s;/msgstr/{ s=0 }' <<< \"${tempPO}\" |grep -v "msgstr" | sed -e 's/^"//' -e 's/"$//' -e 's/^msgid "//')"
  35. msgid="$(awk 'NR{printf "%s",$0;next;}1' <<< ${tempMsgid})"
  36. # Escape special char causing problem in with sed and xml
  37. msgstr=${msgstr//'&'/'\&'}
  38. msgid=${msgid//'&'/'\&'}
  39. if [[ "${msgstr}" == "" ]]; then
  40. # if the msgstr is empty, then it's not translated yet, we use original string
  41. translation=${msgid}
  42. else
  43. translation=${msgstr}
  44. fi
  45. # Using printf is more consistent then echo, here it transforms \n in real newline 😄
  46. printf "${translation}"
  47. }
  48. function rebuild_txt {
  49. ## We need to recurse on all event, then getting all node and their content for each event ##
  50. # In order to recurse properly, we need to sort the translationArray
  51. # To sort we use a new sorted array which contains all keys sorted following "Version style" order
  52. # eg: 0.2.story is before 0.2.1 and 0.2.1 is before 0.11.1
  53. sorted=()
  54. while IFS= read -rd '' key; do
  55. sorted+=( "$key" )
  56. done < <(printf '%s\0' "${!translationArray[@]}" | sort -zV)
  57. sortedEvent=()
  58. while IFS= read -rd '' key; do
  59. sortedEvent+=( "$key" )
  60. done < <(printf '%s\0' "${!eventArray[@]}" | sort -zV)
  61. currentEvent=""
  62. currentNode=""
  63. isEmpty=0
  64. for index in "${sortedEvent[@]}"; do
  65. # If currentEvent is different than our index, then we just changed event and need to close the precedent
  66. # We also closed the next event in line
  67. if [[ ${currentEvent} != ${index} && "${currentEvent}" != "" && "${isEmpty}" != "1" ]]; then
  68. echo "[/NODE]" >> "${TXT}"
  69. echo >> "${TXT}"
  70. echo "[/EVENT]" >> "${TXT}"
  71. echo >> "${TXT}"
  72. fi
  73. echo "${eventArray[${index}]%EMPTY}" >> "${TXT}"
  74. # If the Event contains EMPTY then it's a special empty event, we need to close it without le [/NODE]
  75. # Then we pass directly to the next event
  76. if [[ ${eventArray[${index}]} == *"EMPTY"* ]]; then
  77. echo "[/EVENT]" >> "${TXT}"
  78. echo >> "${TXT}"
  79. isEmpty=1
  80. currentEvent=${index}
  81. continue
  82. fi
  83. isEmpty=0
  84. for key in "${sorted[@]}"; do
  85. # We work only on key related to our current event
  86. # We need to compare key to the event id in index, ie the first part of the key (see #7)
  87. if [[ "${key/.*/}" == "${index}" ]]; then
  88. eventID="${index}"
  89. nodeID="$(awk -F'.' '{print $2}' <<< ${key})"
  90. type="$(awk -F'.' '{print $3}' <<< ${key})"
  91. # If nodeID is different than currentNodeID, then we just changed the node and need to close the node
  92. # We do this only when we are in the same event and not for the first iteration
  93. if [[ "${currentNodeID}" != "${nodeID}" && ${currentEvent} == ${index} && "${currentNodeID}" != "" ]]; then
  94. echo "[/NODE]" >> "${TXT}"
  95. echo >> "${TXT}"
  96. fi
  97. # Here type is a story or an out
  98. if [[ "${type}" == "story" ]]; then
  99. echo "+[NODE]${nodeID}" >> "${TXT}"
  100. echo "[STORY]" >> "${TXT}"
  101. echo "${translationArray[${key}]}" >> "${TXT}"
  102. echo "[/STORY]" >> "${TXT}"
  103. currentNodeID=${nodeID}
  104. currentEvent=${index}
  105. else
  106. echo "[OUT]${translationArray[${key}]}" >> "${TXT}"
  107. fi
  108. fi
  109. done
  110. done
  111. # At the end of last event, we go outside the loop so we need to close remaining node and event
  112. echo "[/NODE]" >> "${TXT}"
  113. echo >> "${TXT}"
  114. echo "[/EVENT]" >> "${TXT}"
  115. echo >> "${TXT}"
  116. }
  117. for index in "${!FILE[@]}"; do
  118. line="${FILE[${index}]}"
  119. line=${line##\#. }
  120. # If the line contains an event, we need to init variables for following compute
  121. if [[ ${line} == *"[EVENT]"* ]]; then
  122. event="$(awk -F'@@' '{print $1}' <<< ${line})"
  123. eventID="$(awk -F'(' '{print $2}' <<< ${event})"
  124. eventID="${eventID%%\)}"
  125. node="$(awk -F'@@' '{print $2}' <<< ${line})"
  126. nodeID="$(awk -F']' '{print $2}' <<< ${node})"
  127. eventArray[${eventID}]="${event}"
  128. fi
  129. if [[ ${line} == *"[STORY]"* ]]; then
  130. translation=$(extract_translation "${line}")
  131. translationArray["${eventID}.${nodeID}.story"]="${translation}"
  132. elif [[ ${line} == *"[OUT]"* ]]; then
  133. out="$(awk -F'@@' '{print $3}' <<< ${line})"
  134. outID=$(awk -F']' '{print $2}' <<< ${out})
  135. translation=$(extract_translation "${line}")
  136. translationArray["${eventID}.${nodeID}.${outID}"]="${translation}"
  137. fi
  138. done
  139. # Now we have 2 arrays: one with all event name, and one with all translation. We can rebuild the original file
  140. rebuild_txt