forked from mia/Aegisub
Move ASS -> SRT tag conversion to the SRT subtitle format from AssDialogue
Originally committed to SVN as r5911.
This commit is contained in:
parent
0992a839cc
commit
56e6f7d5b2
9 changed files with 73 additions and 123 deletions
|
@ -360,103 +360,6 @@ void AssDialogue::StripTag (wxString tagName) {
|
||||||
Text = final;
|
Text = final;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssDialogue::ConvertTagsToSRT () {
|
|
||||||
using std::list;
|
|
||||||
using std::vector;
|
|
||||||
AssDialogueBlockOverride* curBlock;
|
|
||||||
AssDialogueBlockPlain *curPlain;
|
|
||||||
AssOverrideTag* curTag;
|
|
||||||
wxString final = "";
|
|
||||||
bool isItalic=false,isBold=false,isUnder=false,isStrike=false;
|
|
||||||
bool temp;
|
|
||||||
|
|
||||||
// Iterate through blocks
|
|
||||||
ParseASSTags();
|
|
||||||
for (size_t i=0;i<Blocks.size();i++) {
|
|
||||||
curBlock = dynamic_cast<AssDialogueBlockOverride*>(Blocks.at(i));
|
|
||||||
if (curBlock) {
|
|
||||||
// Iterate through overrides
|
|
||||||
for (size_t j=0;j<curBlock->Tags.size();j++) {
|
|
||||||
curTag = curBlock->Tags.at(j);
|
|
||||||
if (curTag->IsValid()) {
|
|
||||||
// Italics
|
|
||||||
if (curTag->Name == "\\i") {
|
|
||||||
temp = curTag->Params.at(0)->Get<bool>();
|
|
||||||
if (temp && !isItalic) {
|
|
||||||
isItalic = true;
|
|
||||||
final += "<i>";
|
|
||||||
}
|
|
||||||
if (!temp && isItalic) {
|
|
||||||
isItalic = false;
|
|
||||||
final += "</i>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Underline
|
|
||||||
if (curTag->Name == "\\u") {
|
|
||||||
temp = curTag->Params.at(0)->Get<bool>();
|
|
||||||
if (temp && !isUnder) {
|
|
||||||
isUnder = true;
|
|
||||||
final += "<u>";
|
|
||||||
}
|
|
||||||
if (!temp && isUnder) {
|
|
||||||
isUnder = false;
|
|
||||||
final += "</u>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strikeout
|
|
||||||
if (curTag->Name == "\\s") {
|
|
||||||
temp = curTag->Params.at(0)->Get<bool>();
|
|
||||||
if (temp && !isStrike) {
|
|
||||||
isStrike = true;
|
|
||||||
final += "<s>";
|
|
||||||
}
|
|
||||||
if (!temp && isStrike) {
|
|
||||||
isStrike = false;
|
|
||||||
final += "</s>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bold
|
|
||||||
if (curTag->Name == "\\b") {
|
|
||||||
temp = curTag->Params.at(0)->Get<bool>();
|
|
||||||
if (temp && !isBold) {
|
|
||||||
isBold = true;
|
|
||||||
final += "<b>";
|
|
||||||
}
|
|
||||||
if (!temp && isBold) {
|
|
||||||
isBold = false;
|
|
||||||
final += "</b>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plain text
|
|
||||||
else {
|
|
||||||
curPlain = dynamic_cast<AssDialogueBlockPlain*>(Blocks.at(i));
|
|
||||||
if (curPlain) {
|
|
||||||
final += curPlain->GetText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure all tags are closed
|
|
||||||
if (isBold)
|
|
||||||
final += "</b>";
|
|
||||||
if (isItalic)
|
|
||||||
final += "</i>";
|
|
||||||
if (isUnder)
|
|
||||||
final += "</u>";
|
|
||||||
if (isStrike)
|
|
||||||
final += "</s>";
|
|
||||||
|
|
||||||
Text = final;
|
|
||||||
ClearBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssDialogue::UpdateText () {
|
void AssDialogue::UpdateText () {
|
||||||
if (Blocks.empty()) return;
|
if (Blocks.empty()) return;
|
||||||
Text.clear();
|
Text.clear();
|
||||||
|
|
|
@ -204,8 +204,6 @@ public:
|
||||||
/// @param callback The callback function to call per tag parameter
|
/// @param callback The callback function to call per tag parameter
|
||||||
/// @param userData User data to pass to callback function
|
/// @param userData User data to pass to callback function
|
||||||
void ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData=NULL);
|
void ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData=NULL);
|
||||||
/// Convert ASS tags to SRT tags
|
|
||||||
void ConvertTagsToSRT();
|
|
||||||
/// Strip all ASS tags from the text
|
/// Strip all ASS tags from the text
|
||||||
void StripTags();
|
void StripTags();
|
||||||
/// Strip a specific ASS tag from the text
|
/// Strip a specific ASS tag from the text
|
||||||
|
|
|
@ -199,19 +199,22 @@ void SubtitleFormat::SortLines() {
|
||||||
AssFile::Sort(*Line);
|
AssFile::Sort(*Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubtitleFormat::ConvertTags(int format, const wxString &lineEnd, bool mergeLineBreaks) {
|
void SubtitleFormat::StripTags() {
|
||||||
for (std::list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); ++cur) {
|
for (std::list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); ++cur) {
|
||||||
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*cur)) {
|
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*cur)) {
|
||||||
// Strip tags
|
current->StripTags();
|
||||||
if (format == 1) current->StripTags();
|
}
|
||||||
else if (format == 2) current->ConvertTagsToSRT();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Replace line breaks
|
void SubtitleFormat::ConvertNewlines(wxString const& newline, bool mergeLineBreaks) {
|
||||||
|
for (std::list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); ++cur) {
|
||||||
|
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*cur)) {
|
||||||
current->Text.Replace("\\h", " ");
|
current->Text.Replace("\\h", " ");
|
||||||
current->Text.Replace("\\n", lineEnd);
|
current->Text.Replace("\\n", newline);
|
||||||
current->Text.Replace("\\N", lineEnd);
|
current->Text.Replace("\\N", newline);
|
||||||
if (mergeLineBreaks) {
|
if (mergeLineBreaks) {
|
||||||
while (current->Text.Replace(lineEnd+lineEnd, lineEnd));
|
while (current->Text.Replace(newline+newline, newline));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,11 +82,12 @@ protected:
|
||||||
void ClearCopy();
|
void ClearCopy();
|
||||||
/// Sort the lines by start time
|
/// Sort the lines by start time
|
||||||
void SortLines();
|
void SortLines();
|
||||||
/// Strip tags or convert them to SRT
|
/// Strip override tags
|
||||||
/// @param format 1: strip tags 2: SRT
|
void StripTags();
|
||||||
/// @param lineEnd Newline character(s)
|
/// Convert newlines to the specified character(s)
|
||||||
|
/// @param lineEnd newline character(s)
|
||||||
/// @param mergeLineBreaks Should multiple consecutive line breaks be merged into one?
|
/// @param mergeLineBreaks Should multiple consecutive line breaks be merged into one?
|
||||||
void ConvertTags(int format, const wxString &lineEnd, bool mergeLineBreaks=true);
|
void ConvertNewlines(wxString const& newline, bool mergeLineBreaks = true);
|
||||||
/// Remove All commented and empty lines
|
/// Remove All commented and empty lines
|
||||||
void StripComments();
|
void StripComments();
|
||||||
/// Remove everything but the dialogue lines
|
/// Remove everything but the dialogue lines
|
||||||
|
|
|
@ -64,7 +64,8 @@ void EncoreSubtitleFormat::WriteFile(wxString const& filename, wxString const& e
|
||||||
StripComments();
|
StripComments();
|
||||||
RecombineOverlaps();
|
RecombineOverlaps();
|
||||||
MergeIdentical();
|
MergeIdentical();
|
||||||
ConvertTags(1, "\r\n");
|
StripTags();
|
||||||
|
ConvertNewlines("\r\n");
|
||||||
|
|
||||||
// Write lines
|
// Write lines
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
|
@ -149,7 +149,8 @@ void MicroDVDSubtitleFormat::WriteFile(wxString const& filename, wxString const&
|
||||||
StripComments();
|
StripComments();
|
||||||
RecombineOverlaps();
|
RecombineOverlaps();
|
||||||
MergeIdentical();
|
MergeIdentical();
|
||||||
ConvertTags(1, "|");
|
StripTags();
|
||||||
|
ConvertNewlines("|");
|
||||||
|
|
||||||
TextFileWriter file(filename, encoding);
|
TextFileWriter file(filename, encoding);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
|
#include "ass_override.h"
|
||||||
#include "ass_style.h"
|
#include "ass_style.h"
|
||||||
#include "colorspace.h"
|
#include "colorspace.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
@ -519,26 +520,66 @@ void SRTSubtitleFormat::WriteFile(wxString const& filename, wxString const& enco
|
||||||
CreateCopy();
|
CreateCopy();
|
||||||
SortLines();
|
SortLines();
|
||||||
StripComments();
|
StripComments();
|
||||||
// Tags must be converted in two passes
|
|
||||||
// First ASS style overrides are converted to SRT but linebreaks are kept
|
|
||||||
ConvertTags(2,"\\N",false);
|
|
||||||
// Then we can recombine overlaps, this requires ASS style linebreaks
|
|
||||||
RecombineOverlaps();
|
RecombineOverlaps();
|
||||||
MergeIdentical();
|
MergeIdentical();
|
||||||
// And finally convert linebreaks
|
ConvertNewlines("\r\n", false);
|
||||||
ConvertTags(0,"\r\n",false);
|
|
||||||
// Otherwise unclosed overrides might affect lines they shouldn't, see bug #809 for example
|
|
||||||
|
|
||||||
// Write lines
|
// Write lines
|
||||||
int i=1;
|
int i=1;
|
||||||
for (std::list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
|
for (std::list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); ++cur) {
|
||||||
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*cur)) {
|
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*cur)) {
|
||||||
file.WriteLineToFile(wxString::Format("%d", i++));
|
file.WriteLineToFile(wxString::Format("%d", i++));
|
||||||
file.WriteLineToFile(WriteSRTTime(current->Start) + " --> " + WriteSRTTime(current->End));
|
file.WriteLineToFile(WriteSRTTime(current->Start) + " --> " + WriteSRTTime(current->End));
|
||||||
file.WriteLineToFile(current->Text);
|
file.WriteLineToFile(ConvertTags(current));
|
||||||
file.WriteLineToFile("");
|
file.WriteLineToFile("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearCopy();
|
ClearCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString SRTSubtitleFormat::ConvertTags(AssDialogue *diag) {
|
||||||
|
wxString final;
|
||||||
|
std::map<char, bool> tag_states;
|
||||||
|
tag_states['i'] = false;
|
||||||
|
tag_states['b'] = false;
|
||||||
|
tag_states['u'] = false;
|
||||||
|
tag_states['s'] = false;
|
||||||
|
|
||||||
|
diag->ParseASSTags();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < diag->Blocks.size(); ++i) {
|
||||||
|
if (AssDialogueBlockOverride* block = dynamic_cast<AssDialogueBlockOverride*>(diag->Blocks[i])) {
|
||||||
|
// Iterate through overrides
|
||||||
|
for (size_t j = 0; j < block->Tags.size(); j++) {
|
||||||
|
AssOverrideTag *tag = block->Tags[j];
|
||||||
|
if (tag->IsValid()) {
|
||||||
|
std::map<char, bool>::iterator it = tag_states.find(tag->Name[1]);
|
||||||
|
if (it != tag_states.end()) {
|
||||||
|
bool temp = tag->Params[0]->Get<bool>();
|
||||||
|
if (temp && !it->second)
|
||||||
|
final += wxString::Format("<%c>", it->first);
|
||||||
|
if (!temp && it->second)
|
||||||
|
final += wxString::Format("</%c>", it->first);
|
||||||
|
it->second = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Plain text
|
||||||
|
else if (AssDialogueBlockPlain *plain = dynamic_cast<AssDialogueBlockPlain*>(diag->Blocks[i])) {
|
||||||
|
final += plain->GetText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all tags are closed
|
||||||
|
// Otherwise unclosed overrides might affect lines they shouldn't, see bug #809 for example
|
||||||
|
for (std::map<char, bool>::iterator it = tag_states.begin(); it != tag_states.end(); ++it) {
|
||||||
|
if (it->second)
|
||||||
|
final += wxString::Format("</%c>", it->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
diag->ClearBlocks();
|
||||||
|
|
||||||
|
return final;
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class SRTSubtitleFormat : public SubtitleFormat {
|
class SRTSubtitleFormat : public SubtitleFormat {
|
||||||
|
wxString ConvertTags(AssDialogue *diag);
|
||||||
public:
|
public:
|
||||||
SRTSubtitleFormat();
|
SRTSubtitleFormat();
|
||||||
wxArrayString GetReadWildcards() const;
|
wxArrayString GetReadWildcards() const;
|
||||||
|
|
|
@ -282,7 +282,8 @@ void TTXTSubtitleFormat::ConvertToTTXT () {
|
||||||
StripComments();
|
StripComments();
|
||||||
RecombineOverlaps();
|
RecombineOverlaps();
|
||||||
MergeIdentical();
|
MergeIdentical();
|
||||||
ConvertTags(1, "\r\n");
|
StripTags();
|
||||||
|
ConvertNewlines("\r\n");
|
||||||
|
|
||||||
// Find last line
|
// Find last line
|
||||||
AssTime lastTime;
|
AssTime lastTime;
|
||||||
|
|
Loading…
Reference in a new issue