#!/bin/bash if [[ "$#" -ne 2 ]]; then echo "Please pass exactly 2 parameters: the .po and the language" exit 1 fi LANGUAGE="${2}" WORKDIR="/tmp/thea2/${LANGUAGE}" PO="${1}" FINALDIR="$(pwd)/Translation/${LANGUAGE}/game_files/Modules/" TXT=$(basename "${PO%%.po}.txt") TXT="${FINALDIR}/${TXT}" dos2unix "${PO}" &> /dev/null # Initialization mkdir -p "${WORKDIR}" mkdir -p "${FINALDIR}" truncate -s 0 "${TXT}" readarray -t FILE < "${PO}" declare -A eventArray=() declare -A translationArray=() # First thing first, let's anonymize the po and delete all email references sed -i 's/[A-Za-z0-9._%+-]\+@[A-Za-z0-9.-]\+\.[A-Za-z]\{2,6\}//' "${PO}" function extract_translation { key="${line}" # We need to escape special char for regex: [ + and ( key="${key//[/\\\\[}" key="${key//+/\\\\\+}" key="${key//(/\\\\\(}" # We search for the exact key in the po file until we get a blank line, to get the full msgstr and the msgid tempPO=$(awk -v key="${key}" '{pat="#. "key"$"} !NF{s=0}s;$0 ~ pat{ print $0; s=1 }' "${PO}") # Extract msgstr and merge all lines into one tempMsgstr=$(awk '!NF{s=0}s;/msgstr/{ print $0; s=1 }' <<< "${tempPO}" | sed -e 's/^"//' -e 's/"$//' -e 's/^msgstr "//') msgstr=$(awk 'NR{printf "%s",$0;next;}1' <<< ${tempMsgstr}) # Extract msgid and merge all lines into one tempMsgid="$(awk '/msgid/{ s=1 }s;/msgstr/{ s=0 }' <<< \"${tempPO}\" |grep -v "msgstr" | sed -e 's/^"//' -e 's/"$//' -e 's/^msgid "//')" msgid="$(awk 'NR{printf "%s",$0;next;}1' <<< ${tempMsgid})" # Escape special char causing problem in with sed and xml msgstr=${msgstr//'&'/'\&'} msgid=${msgid//'&'/'\&'} if [[ "${msgstr}" == "" ]]; then # if the msgstr is empty, then it's not translated yet, we use original string translation=${msgid} else translation=${msgstr} fi # Using printf is more consistent then echo, here it transforms \n in real newline 😄 printf "${translation}" } function rebuild_txt { ## We need to recurse on all event, then getting all node and their content for each event ## # In order to recurse properly, we need to sort the translationArray # To sort we use a new sorted array which contains all keys sorted following "Version style" order # eg: 0.2.story is before 0.2.1 and 0.2.1 is before 0.11.1 sorted=() while IFS= read -rd '' key; do sorted+=( "$key" ) done < <(printf '%s\0' "${!translationArray[@]}" | sort -zV) sortedEvent=() while IFS= read -rd '' key; do sortedEvent+=( "$key" ) done < <(printf '%s\0' "${!eventArray[@]}" | sort -zV) currentEvent="" currentNode="" isEmpty=0 for index in "${sortedEvent[@]}"; do # If currentEvent is different than our index, then we just changed event and need to close the precedent # We also closed the next event in line if [[ ${currentEvent} != ${index} && "${currentEvent}" != "" && "${isEmpty}" != "1" ]]; then echo "[/NODE]" >> "${TXT}" echo >> "${TXT}" echo "[/EVENT]" >> "${TXT}" echo >> "${TXT}" fi echo "${eventArray[${index}]%EMPTY}" >> "${TXT}" # If the Event contains EMPTY then it's a special empty event, we need to close it without le [/NODE] # Then we pass directly to the next event if [[ ${eventArray[${index}]} == *"EMPTY"* ]]; then echo "[/EVENT]" >> "${TXT}" echo >> "${TXT}" isEmpty=1 currentEvent=${index} continue fi isEmpty=0 for key in "${sorted[@]}"; do # We work only on key related to our current event # We need to compare key to the event id in index, ie the first part of the key (see #7) if [[ "${key/.*/}" == "${index}" ]]; then eventID="${index}" nodeID="$(awk -F'.' '{print $2}' <<< ${key})" type="$(awk -F'.' '{print $3}' <<< ${key})" # If nodeID is different than currentNodeID, then we just changed the node and need to close the node # We do this only when we are in the same event and not for the first iteration if [[ "${currentNodeID}" != "${nodeID}" && ${currentEvent} == ${index} && "${currentNodeID}" != "" ]]; then echo "[/NODE]" >> "${TXT}" echo >> "${TXT}" fi # Here type is a story or an out if [[ "${type}" == "story" ]]; then echo "+[NODE]${nodeID}" >> "${TXT}" echo "[STORY]" >> "${TXT}" echo "${translationArray[${key}]}" >> "${TXT}" echo "[/STORY]" >> "${TXT}" currentNodeID=${nodeID} currentEvent=${index} else echo "[OUT]${translationArray[${key}]}" >> "${TXT}" fi fi done done # At the end of last event, we go outside the loop so we need to close remaining node and event echo "[/NODE]" >> "${TXT}" echo >> "${TXT}" echo "[/EVENT]" >> "${TXT}" echo >> "${TXT}" } for index in "${!FILE[@]}"; do line="${FILE[${index}]}" line=${line##\#. } # If the line contains an event, we need to init variables for following compute if [[ ${line} == *"[EVENT]"* ]]; then event="$(awk -F'@@' '{print $1}' <<< ${line})" eventID="$(awk -F'(' '{print $2}' <<< ${event})" eventID="${eventID%%\)}" node="$(awk -F'@@' '{print $2}' <<< ${line})" nodeID="$(awk -F']' '{print $2}' <<< ${node})" eventArray[${eventID}]="${event}" fi if [[ ${line} == *"[STORY]"* ]]; then translation=$(extract_translation "${line}") translationArray["${eventID}.${nodeID}.story"]="${translation}" elif [[ ${line} == *"[OUT]"* ]]; then out="$(awk -F'@@' '{print $3}' <<< ${line})" outID=$(awk -F']' '{print $2}' <<< ${out}) translation=$(extract_translation "${line}") translationArray["${eventID}.${nodeID}.${outID}"]="${translation}" fi done # Now we have 2 arrays: one with all event name, and one with all translation. We can rebuild the original file rebuild_txt