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;
|
||||
}
|
||||
|
||||
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 () {
|
||||
if (Blocks.empty()) return;
|
||||
Text.clear();
|
||||
|
|
|
@ -204,8 +204,6 @@ public:
|
|||
/// @param callback The callback function to call per tag parameter
|
||||
/// @param userData User data to pass to callback function
|
||||
void ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData=NULL);
|
||||
/// Convert ASS tags to SRT tags
|
||||
void ConvertTagsToSRT();
|
||||
/// Strip all ASS tags from the text
|
||||
void StripTags();
|
||||
/// Strip a specific ASS tag from the text
|
||||
|
|
|
@ -199,19 +199,22 @@ void SubtitleFormat::SortLines() {
|
|||
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) {
|
||||
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*cur)) {
|
||||
// Strip tags
|
||||
if (format == 1) current->StripTags();
|
||||
else if (format == 2) current->ConvertTagsToSRT();
|
||||
current->StripTags();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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("\\n", lineEnd);
|
||||
current->Text.Replace("\\N", lineEnd);
|
||||
current->Text.Replace("\\n", newline);
|
||||
current->Text.Replace("\\N", newline);
|
||||
if (mergeLineBreaks) {
|
||||
while (current->Text.Replace(lineEnd+lineEnd, lineEnd));
|
||||
while (current->Text.Replace(newline+newline, newline));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,11 +82,12 @@ protected:
|
|||
void ClearCopy();
|
||||
/// Sort the lines by start time
|
||||
void SortLines();
|
||||
/// Strip tags or convert them to SRT
|
||||
/// @param format 1: strip tags 2: SRT
|
||||
/// @param lineEnd Newline character(s)
|
||||
/// Strip override tags
|
||||
void StripTags();
|
||||
/// Convert newlines to the specified character(s)
|
||||
/// @param lineEnd newline character(s)
|
||||
/// @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
|
||||
void StripComments();
|
||||
/// Remove everything but the dialogue lines
|
||||
|
|
|
@ -64,7 +64,8 @@ void EncoreSubtitleFormat::WriteFile(wxString const& filename, wxString const& e
|
|||
StripComments();
|
||||
RecombineOverlaps();
|
||||
MergeIdentical();
|
||||
ConvertTags(1, "\r\n");
|
||||
StripTags();
|
||||
ConvertNewlines("\r\n");
|
||||
|
||||
// Write lines
|
||||
int i = 0;
|
||||
|
|
|
@ -149,7 +149,8 @@ void MicroDVDSubtitleFormat::WriteFile(wxString const& filename, wxString const&
|
|||
StripComments();
|
||||
RecombineOverlaps();
|
||||
MergeIdentical();
|
||||
ConvertTags(1, "|");
|
||||
StripTags();
|
||||
ConvertNewlines("|");
|
||||
|
||||
TextFileWriter file(filename, encoding);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_file.h"
|
||||
#include "ass_override.h"
|
||||
#include "ass_style.h"
|
||||
#include "colorspace.h"
|
||||
#include "compat.h"
|
||||
|
@ -519,26 +520,66 @@ void SRTSubtitleFormat::WriteFile(wxString const& filename, wxString const& enco
|
|||
CreateCopy();
|
||||
SortLines();
|
||||
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();
|
||||
MergeIdentical();
|
||||
// And finally convert linebreaks
|
||||
ConvertTags(0,"\r\n",false);
|
||||
// Otherwise unclosed overrides might affect lines they shouldn't, see bug #809 for example
|
||||
ConvertNewlines("\r\n", false);
|
||||
|
||||
// Write lines
|
||||
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)) {
|
||||
file.WriteLineToFile(wxString::Format("%d", i++));
|
||||
file.WriteLineToFile(WriteSRTTime(current->Start) + " --> " + WriteSRTTime(current->End));
|
||||
file.WriteLineToFile(current->Text);
|
||||
file.WriteLineToFile(ConvertTags(current));
|
||||
file.WriteLineToFile("");
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
class SRTSubtitleFormat : public SubtitleFormat {
|
||||
wxString ConvertTags(AssDialogue *diag);
|
||||
public:
|
||||
SRTSubtitleFormat();
|
||||
wxArrayString GetReadWildcards() const;
|
||||
|
|
|
@ -282,7 +282,8 @@ void TTXTSubtitleFormat::ConvertToTTXT () {
|
|||
StripComments();
|
||||
RecombineOverlaps();
|
||||
MergeIdentical();
|
||||
ConvertTags(1, "\r\n");
|
||||
StripTags();
|
||||
ConvertNewlines("\r\n");
|
||||
|
||||
// Find last line
|
||||
AssTime lastTime;
|
||||
|
|
Loading…
Reference in a new issue