From 49ed0551adb5b1034942db4286bbcfb6ebe18674 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sat, 24 Nov 2012 13:58:24 -0800 Subject: [PATCH] Consolidate all entries of each group when there are duplicate sections Dealing with multiple instances of each section makes the code significantly more complicated, and in most cases Aegisub doesn't actually bother to handle it correctly. --- aegisub/src/ass_parser.cpp | 31 +++++++++++++++++-------------- aegisub/src/ass_parser.h | 7 ++++++- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/aegisub/src/ass_parser.cpp b/aegisub/src/ass_parser.cpp index 5a27a2027..25e5ce55e 100644 --- a/aegisub/src/ass_parser.cpp +++ b/aegisub/src/ass_parser.cpp @@ -51,7 +51,7 @@ void AssParser::ParseAttachmentLine(wxString const& data) { // Data is over, add attachment to the file if (!valid_data || is_filename) { attach->Finish(); - target->Line.push_back(*attach.release()); + InsertLine(attach.release()); AddLine(data); } else { @@ -60,7 +60,7 @@ void AssParser::ParseAttachmentLine(wxString const& data) { // Done building if (data.Length() < 80) { attach->Finish(); - target->Line.push_back(*attach.release()); + InsertLine(attach.release()); } } } @@ -87,33 +87,27 @@ void AssParser::ParseScriptInfoLine(wxString const& data) { } } - target->Line.push_back(*new AssEntry(data, "[Script Info]")); + InsertLine(new AssEntry(data, "[Script Info]")); } void AssParser::ParseEventLine(wxString const& data) { if (data.StartsWith("Dialogue:") || data.StartsWith("Comment:")) - target->Line.push_back(*new AssDialogue(data)); + InsertLine(new AssDialogue(data)); } void AssParser::ParseStyleLine(wxString const& data) { if (data.StartsWith("Style:")) - target->Line.push_back(*new AssStyle(data, version)); + InsertLine(new AssStyle(data, version)); } void AssParser::ParseFontLine(wxString const& data) { - if (data.StartsWith("fontname: ")) { + if (data.StartsWith("fontname: ")) attach.reset(new AssAttachment(data.Mid(10), "[Fonts]")); - } } void AssParser::ParseGraphicsLine(wxString const& data) { - if (data.StartsWith("filename: ")) { + if (data.StartsWith("filename: ")) attach.reset(new AssAttachment(data.Mid(10), "[Graphics]")); - } -} - -void AssParser::AppendUnknownLine(wxString const& data) { - target->Line.push_back(*new AssEntry(data, target->Line.back().group)); } void AssParser::AddLine(wxString const& data) { @@ -151,9 +145,18 @@ void AssParser::AddLine(wxString const& data) { else if (low == "[fonts]") state = &AssParser::ParseFontLine; else - state = &AssParser::AppendUnknownLine; + state = &AssParser::UnknownLine; return; } (this->*state)(data); } + +void AssParser::InsertLine(AssEntry *entry) { + auto it = insertion_positions.find(entry->group); + if (it == insertion_positions.end()) + target->Line.push_back(*entry); + else + target->Line.insert(++target->Line.iterator_to(*it->second), *entry); + insertion_positions[entry->group] = entry; +} diff --git a/aegisub/src/ass_parser.h b/aegisub/src/ass_parser.h index 7c920eaae..3e3aeeb11 100644 --- a/aegisub/src/ass_parser.h +++ b/aegisub/src/ass_parser.h @@ -13,12 +13,14 @@ // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef AGI_PRE +#include #include #include #endif class AssAttachment; +class AssEntry; class AssFile; class AssParser { @@ -26,6 +28,9 @@ class AssParser { int version; std::unique_ptr attach; void (AssParser::*state)(wxString const&); + std::map insertion_positions; + + void InsertLine(AssEntry *entry); void ParseAttachmentLine(wxString const& data); void ParseEventLine(wxString const& data); @@ -33,7 +38,7 @@ class AssParser { void ParseScriptInfoLine(wxString const& data); void ParseFontLine(wxString const& data); void ParseGraphicsLine(wxString const& data); - void AppendUnknownLine(wxString const& data); + void UnknownLine(wxString const&) { } public: AssParser(AssFile *target, int version); ~AssParser();