Browse Source

Update subtatiles translation extraction

pull/8394/head
Yuri Pourre 3 months ago
parent
commit
cd015f2d34
  1. 17
      Source/translation_dummy.cpp
  2. 5
      Source/utils/srt_parser.cpp
  3. 72
      tools/extract_translation_data.py

17
Source/translation_dummy.cpp

@ -1041,5 +1041,22 @@ const char *SPELL_RUNE_OF_LIGHT_NAME = P_("spell", "Rune of Light");
const char *SPELL_RUNE_OF_NOVA_NAME = P_("spell", "Rune of Nova");
const char *SPELL_RUNE_OF_IMMOLATION_NAME = P_("spell", "Rune of Immolation");
const char *SPELL_RUNE_OF_STONE_NAME = P_("spell", "Rune of Stone");
const char *SUBTITLE_DIABEND_0 = N_("The Soulstone burns with hellfire as an eerie");
const char *SUBTITLE_DIABEND_1 = N_("red glow blurs your vision.");
const char *SUBTITLE_DIABEND_2 = N_("Fresh blood flows into your eyes and you");
const char *SUBTITLE_DIABEND_3 = N_("begin to hear the tormented whispers of the damned.");
const char *SUBTITLE_DIABEND_4 = N_("You have done what you knew must be done.");
const char *SUBTITLE_DIABEND_5 = N_("The essence of Diablo is contained.");
const char *SUBTITLE_DIABEND_6 = N_("For now.");
const char *SUBTITLE_DIABEND_7 = N_("You pray that you have become strong enough");
const char *SUBTITLE_DIABEND_8 = N_("to contain the demon and keep him at bay.");
const char *SUBTITLE_DIABEND_9 = N_("Although you have been fortified by your quest,");
const char *SUBTITLE_DIABEND_10 = N_("you can still feel him, clawing his way");
const char *SUBTITLE_DIABEND_11 = N_("up from the dark recesses of your soul.");
const char *SUBTITLE_DIABEND_12 = N_("Fighting to retain control, your thoughts turn toward");
const char *SUBTITLE_DIABEND_13 = N_("the ancient, mystic lands of the Far East.");
const char *SUBTITLE_DIABEND_14 = N_("Perhaps there, beyond the desolate wastes of Aranak,");
const char *SUBTITLE_DIABEND_15 = N_("you will find an answer.");
const char *SUBTITLE_DIABEND_16 = N_("Or perhaps, salvation.");
} // namespace

5
Source/utils/srt_parser.cpp

@ -7,6 +7,7 @@
#include <string>
#include "engine/assets.hpp"
#include "utils/language.h"
namespace devilution {
@ -85,7 +86,9 @@ std::string GetSubtitleAtTime(const std::vector<SubtitleEntry> &subtitles, uint6
{
for (const auto &entry : subtitles) {
if (videoTimeMs >= entry.startTimeMs && videoTimeMs < entry.endTimeMs) {
return entry.text;
// Translate the subtitle text
std::string_view translated = LanguageTranslate(entry.text);
return std::string(translated);
}
}
return "";

72
tools/extract_translation_data.py

@ -49,6 +49,68 @@ replacement_table = str.maketrans(
def create_identifier(value, prefix = '', suffix = ''):
return prefix + value.upper().translate(replacement_table) + suffix
def escape_cpp_string(s):
"""Escape a string for use in a C++ string literal."""
return s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n')
def process_srt_file(srt_path, temp_source, prefix="SUBTITLE"):
"""Parse an SRT file and extract subtitle text for translation."""
if not srt_path.exists():
return
try:
with open(srt_path, 'r', encoding='utf-8') as f:
content = f.read()
except Exception:
return
lines = content.split('\n')
text = ""
subtitle_index = 0
i = 0
while i < len(lines):
line = lines[i]
# Remove \r if present (matching C++ parser behavior)
if line and line.endswith('\r'):
line = line[:-1]
# Skip empty lines (end of subtitle block)
if not line:
if text:
# Remove trailing newline from text
text = text.rstrip('\n')
if text:
var_name = f'{prefix}_{subtitle_index}'
escaped_text = escape_cpp_string(text)
write_entry(temp_source, var_name, "subtitle", escaped_text, False)
subtitle_index += 1
text = ""
i += 1
continue
# Check if line is a number (subtitle index) - skip it
if line.strip().isdigit():
i += 1
continue
# Check if line contains --> (timestamp line) - skip it
if '-->' in line:
i += 1
continue
# Otherwise it's subtitle text
if text:
text += "\n"
text += line
i += 1
# Handle last subtitle if file doesn't end with blank line
if text:
text = text.rstrip('\n')
if text:
var_name = f'{prefix}_{subtitle_index}'
escaped_text = escape_cpp_string(text)
write_entry(temp_source, var_name, "subtitle", escaped_text, False)
def process_files(paths, temp_source):
# Classes
if "classdat" in paths:
@ -140,4 +202,14 @@ with open(translation_dummy_path, 'w') as temp_source:
process_files(base_paths, temp_source)
process_files(hf_paths, temp_source)
# Process SRT subtitle files
srt_files = [
root.joinpath("assets/gendata/diabend.srt"),
]
for srt_file in srt_files:
# Extract filename without extension and convert to uppercase for prefix
filename = srt_file.stem.upper()
prefix = f"SUBTITLE_{filename}"
process_srt_file(srt_file, temp_source, prefix)
temp_source.write(f'\n}} // namespace\n')

Loading…
Cancel
Save