Skip to content

Instantly share code, notes, and snippets.

@qgustavor
Created May 14, 2020 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qgustavor/a1359f474ec388dd2bc5e7368a132375 to your computer and use it in GitHub Desktop.
Save qgustavor/a1359f474ec388dd2bc5e7368a132375 to your computer and use it in GitHub Desktop.
Replace text in ASS subtitles ignoring formatting
function replaceAssText (source, replacerFn) {
// Detect all non-dialogue tokens and mark those with null characters
const lines = source.replace(/\0/g, '').split('\n')
const nonReplaceableTokens = []
const replaceableTokens = []
let nonTextAccumulator = ''
for (let line of lines) {
if (!line.startsWith('Dialogue: ')) {
nonTextAccumulator += line + '\n'
continue
}
const lineParts = line.split(',')
const nonTextLine = lineParts.slice(0, 9).join(',')
nonTextAccumulator += nonTextLine + ','
nonReplaceableTokens.push(nonTextAccumulator)
nonTextAccumulator = ''
const dialogueText = lineParts.slice(9).join(',')
const nonTextTokens = dialogueText.match(/\{.*?\}|\\N/g)
const textTokens = dialogueText.split(/\{.*?\}|\\N/g)
if (nonTextTokens) {
for (let token of textTokens) replaceableTokens.push(token)
for (let token of nonTextTokens) nonReplaceableTokens.push(token)
} else {
replaceableTokens.push(dialogueText)
}
replaceableTokens[replaceableTokens.length - 1] += '\n'
}
nonReplaceableTokens.push(nonTextAccumulator)
replaceableText = '\0' + replaceableTokens.join('\0') + '\0'
// Replace text with null characters using the replacer function
replaceableText = replacerFn(replaceableText)
// Place back the non-dialogue tokens
let replaceIndex = 0
return replaceableText.replace(/\0/g, () => nonReplaceableTokens[replaceIndex++])
}
// Function usage
const result = replaceAssText(assText, (text) => text.replace(/"([\s\S]*?)"/g, '“$1”'))
console.log(result)
@qgustavor
Copy link
Author

Important: the replacer function must not add or remove null characters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment