mirror of https://github.com/odrling/Aegisub
Move ASS parsing to its own class
This commit is contained in:
parent
c7fd04a739
commit
7e1bb8348a
|
@ -361,6 +361,14 @@
|
|||
RelativePath="..\..\src\ass_override.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ass_parser.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ass_parser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ass_style.cpp"
|
||||
>
|
||||
|
|
|
@ -131,6 +131,7 @@ SRC += \
|
|||
ass_file.cpp \
|
||||
ass_karaoke.cpp \
|
||||
ass_override.cpp \
|
||||
ass_parser.cpp \
|
||||
ass_style.cpp \
|
||||
ass_style_storage.cpp \
|
||||
ass_time.cpp \
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ass_parser.h"
|
||||
|
||||
#include "ass_attachment.h"
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_file.h"
|
||||
#include "ass_style.h"
|
||||
|
||||
AssParser::AssParser(AssFile *target, int version)
|
||||
: target(target)
|
||||
, version(version)
|
||||
, attach(0)
|
||||
{
|
||||
}
|
||||
|
||||
AssParser::~AssParser() {
|
||||
}
|
||||
|
||||
void AssParser::AddLine(wxString const& data) {
|
||||
// Is this line an attachment filename?
|
||||
bool isFilename = data.StartsWith("fontname: ") || data.StartsWith("filename: ");
|
||||
|
||||
// If there's an attachment in progress, deal with it first as an
|
||||
// attachment data line can appear to be other things
|
||||
if (attach.get()) {
|
||||
// Check if it's valid data
|
||||
bool validData = data.size() > 0 && data.size() <= 80;
|
||||
for (size_t i = 0; i < data.size(); ++i) {
|
||||
if (data[i] < 33 || data[i] >= 97) {
|
||||
validData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Data is over, add attachment to the file
|
||||
if (!validData || isFilename) {
|
||||
attach->Finish();
|
||||
target->Line.push_back(attach.release());
|
||||
}
|
||||
else {
|
||||
// Insert data
|
||||
attach->AddData(data);
|
||||
|
||||
// Done building
|
||||
if (data.Length() < 80) {
|
||||
attach->Finish();
|
||||
target->Line.push_back(attach.release());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.empty()) return;
|
||||
|
||||
// Section header
|
||||
if (data[0] == '[' && data.Last() == ']') {
|
||||
// Ugly hacks to allow intermixed v4 and v4+ style sections
|
||||
const wxString low = data.Lower();
|
||||
wxString header = data;
|
||||
if (low == "[v4 styles]") {
|
||||
header = "[V4+ Styles]";
|
||||
version = 0;
|
||||
}
|
||||
else if (low == "[v4+ styles]") {
|
||||
header = "[V4+ Styles]";
|
||||
version = 1;
|
||||
}
|
||||
|
||||
target->Line.push_back(new AssEntry(header, header));
|
||||
return;
|
||||
}
|
||||
|
||||
// If the first nonblank line isn't a header pretend it starts with [Script Info]
|
||||
if (target->Line.empty())
|
||||
target->Line.push_back(new AssEntry("[Script Info]", "[Script Info]"));
|
||||
|
||||
wxString group = target->Line.back()->group;
|
||||
wxString lowGroup = group.Lower();
|
||||
|
||||
// Attachment
|
||||
if (lowGroup == "[fonts]" || lowGroup == "[graphics]") {
|
||||
if (isFilename) {
|
||||
attach.reset(new AssAttachment(data.Mid(10), group));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Dialogue
|
||||
if (lowGroup == "[events]") {
|
||||
if (data.StartsWith("Dialogue:") || data.StartsWith("Comment:"))
|
||||
target->Line.push_back(new AssDialogue(data));
|
||||
else if (data.StartsWith("Format:"))
|
||||
target->Line.push_back(new AssEntry("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text", group));
|
||||
return;
|
||||
}
|
||||
|
||||
// Style
|
||||
if (lowGroup == "[v4+ styles]") {
|
||||
if (data.StartsWith("Style:"))
|
||||
target->Line.push_back(new AssStyle(data, version));
|
||||
else if (data.StartsWith("Format:"))
|
||||
target->Line.push_back(new AssEntry("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding", group));
|
||||
return;
|
||||
}
|
||||
|
||||
// Script info
|
||||
if (lowGroup == "[script info]") {
|
||||
// Comment
|
||||
if (data.StartsWith(";")) {
|
||||
// Skip stupid comments added by other programs
|
||||
// Of course, we'll add our own in place later... ;)
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.StartsWith("ScriptType:")) {
|
||||
wxString versionString = data.Mid(11).Trim(true).Trim(false).Lower();
|
||||
int trueVersion;
|
||||
if (versionString == "v4.00")
|
||||
trueVersion = 0;
|
||||
else if (versionString == "v4.00+")
|
||||
trueVersion = 1;
|
||||
else
|
||||
throw "Unknown SSA file format version";
|
||||
if (trueVersion != version) {
|
||||
wxLogMessage("Warning: File has the wrong extension.");
|
||||
version = trueVersion;
|
||||
}
|
||||
}
|
||||
|
||||
target->Line.push_back(new AssEntry(data, group));
|
||||
return;
|
||||
}
|
||||
|
||||
// Unrecognized group
|
||||
target->Line.push_back(new AssEntry(data, group));
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#ifndef AGI_PRE
|
||||
#include <memory>
|
||||
|
||||
#include <wx/string.h>
|
||||
#endif
|
||||
|
||||
class AssAttachment;
|
||||
class AssFile;
|
||||
|
||||
class AssParser {
|
||||
AssFile *target;
|
||||
int version;
|
||||
std::auto_ptr<AssAttachment> attach;
|
||||
public:
|
||||
AssParser(AssFile *target, int version);
|
||||
~AssParser();
|
||||
void AddLine(wxString const& data);
|
||||
};
|
|
@ -52,11 +52,11 @@
|
|||
#include "mkv_wrap.h"
|
||||
|
||||
#include "ass_file.h"
|
||||
#include "ass_parser.h"
|
||||
#include "ass_time.h"
|
||||
#include "compat.h"
|
||||
#include "dialog_progress.h"
|
||||
#include "MatroskaParser.h"
|
||||
#include "subtitle_format_ass.h"
|
||||
|
||||
class MkvStdIO : public InputStream {
|
||||
public:
|
||||
|
@ -135,10 +135,9 @@ static void read_subtitles(agi::ProgressSink *ps, MatroskaFile *file, MkvStdIO *
|
|||
delete[] readBuf;
|
||||
|
||||
// Insert into file
|
||||
int version = ssa;
|
||||
AssAttachment *attach = 0;
|
||||
AssParser parser(target, ssa);
|
||||
for (std::map<int, wxString>::iterator it = subList.begin(); it != subList.end(); ++it) {
|
||||
AssSubtitleFormat::AddLine(target, it->second, &version, &attach);
|
||||
parser.AddLine(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,11 +204,10 @@ void MatroskaWrapper::GetSubtitles(wxString const& filename, AssFile *target) {
|
|||
wxString privString((const char *)trackInfo->CodecPrivate, wxConvUTF8, trackInfo->CodecPrivateSize);
|
||||
|
||||
// Load into file
|
||||
int version = !ssa;
|
||||
AssAttachment *attach = 0;
|
||||
AssParser parser(target, !ssa);
|
||||
wxStringTokenizer token(privString, "\r\n", wxTOKEN_STRTOK);
|
||||
while (token.HasMoreTokens())
|
||||
AssSubtitleFormat::AddLine(target, token.GetNextToken(), &version, &attach);
|
||||
parser.AddLine(token.GetNextToken());
|
||||
}
|
||||
// Load default if it's SRT
|
||||
else {
|
||||
|
|
|
@ -38,10 +38,9 @@
|
|||
|
||||
#include "subtitle_format_ass.h"
|
||||
|
||||
#include "ass_attachment.h"
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_entry.h"
|
||||
#include "ass_file.h"
|
||||
#include "ass_style.h"
|
||||
#include "ass_parser.h"
|
||||
#include "compat.h"
|
||||
#include "text_file_reader.h"
|
||||
#include "text_file_writer.h"
|
||||
|
@ -72,12 +71,12 @@ void AssSubtitleFormat::ReadFile(AssFile *target, wxString const& filename, wxSt
|
|||
|
||||
TextFileReader file(filename, encoding);
|
||||
int version = filename.Right(4).Lower() != ".ssa";
|
||||
AssAttachment *attach = 0;
|
||||
AssParser parser(target, version);
|
||||
|
||||
while (file.HasMoreLines()) {
|
||||
wxString line = file.ReadLineFromFile();
|
||||
try {
|
||||
AddLine(target, line, &version, &attach);
|
||||
parser.AddLine(line);
|
||||
}
|
||||
catch (const char *err) {
|
||||
target->Clear();
|
||||
|
@ -101,118 +100,3 @@ void AssSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
|
|||
file.WriteLineToFile(ssa ? (*cur)->GetSSAText() : (*cur)->GetEntryData(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void AssSubtitleFormat::AddLine(AssFile *target, wxString data, int *version, AssAttachment **attach) {
|
||||
// Is this line an attachment filename?
|
||||
bool isFilename = data.StartsWith("fontname: ") || data.StartsWith("filename: ");
|
||||
|
||||
// If there's an attachment in progress, deal with it first as an
|
||||
// attachment data line can appear to be other things
|
||||
if (*attach) {
|
||||
// Check if it's valid data
|
||||
bool validData = data.size() > 0 && data.size() <= 80;
|
||||
for (size_t i = 0; i < data.size(); ++i) {
|
||||
if (data[i] < 33 || data[i] >= 97) {
|
||||
validData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Data is over, add attachment to the file
|
||||
if (!validData || isFilename) {
|
||||
(*attach)->Finish();
|
||||
target->Line.push_back(*attach);
|
||||
*attach = NULL;
|
||||
}
|
||||
else {
|
||||
// Insert data
|
||||
(*attach)->AddData(data);
|
||||
|
||||
// Done building
|
||||
if (data.Length() < 80) {
|
||||
(*attach)->Finish();
|
||||
target->Line.push_back(*attach);
|
||||
*attach = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.empty()) return;
|
||||
|
||||
// Section header
|
||||
if (data[0] == '[' && data.Last() == ']') {
|
||||
// Ugly hacks to allow intermixed v4 and v4+ style sections
|
||||
wxString low = data.Lower();
|
||||
if (low == "[v4 styles]") {
|
||||
data = "[V4+ Styles]";
|
||||
*version = 0;
|
||||
}
|
||||
else if (low == "[v4+ styles]") {
|
||||
data = "[V4+ Styles]";
|
||||
*version = 1;
|
||||
}
|
||||
|
||||
target->Line.push_back(new AssEntry(data, data));
|
||||
return;
|
||||
}
|
||||
|
||||
// If the first nonblank line isn't a header pretend it starts with [Script Info]
|
||||
if (target->Line.empty())
|
||||
target->Line.push_back(new AssEntry("[Script Info]", "[Script Info]"));
|
||||
|
||||
wxString group = target->Line.back()->group;
|
||||
wxString lowGroup = group.Lower();
|
||||
|
||||
// Attachment
|
||||
if (lowGroup == "[fonts]" || lowGroup == "[graphics]") {
|
||||
if (isFilename) {
|
||||
*attach = new AssAttachment(data.Mid(10), group);
|
||||
}
|
||||
}
|
||||
// Dialogue
|
||||
else if (lowGroup == "[events]") {
|
||||
if (data.StartsWith("Dialogue:") || data.StartsWith("Comment:"))
|
||||
target->Line.push_back(new AssDialogue(data));
|
||||
else if (data.StartsWith("Format:"))
|
||||
target->Line.push_back(new AssEntry("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text", group));
|
||||
}
|
||||
// Style
|
||||
else if (lowGroup == "[v4+ styles]") {
|
||||
if (data.StartsWith("Style:"))
|
||||
target->Line.push_back(new AssStyle(data, *version));
|
||||
else if (data.StartsWith("Format:"))
|
||||
target->Line.push_back(new AssEntry("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding", group));
|
||||
}
|
||||
// Script info
|
||||
else if (lowGroup == "[script info]") {
|
||||
// Comment
|
||||
if (data.StartsWith(";")) {
|
||||
// Skip stupid comments added by other programs
|
||||
// Of course, we'll add our own in place later... ;)
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.StartsWith("ScriptType:")) {
|
||||
wxString versionString = data.Mid(11).Trim(true).Trim(false).Lower();
|
||||
int trueVersion;
|
||||
if (versionString == "v4.00")
|
||||
trueVersion = 0;
|
||||
else if (versionString == "v4.00+")
|
||||
trueVersion = 1;
|
||||
else
|
||||
throw "Unknown SSA file format version";
|
||||
if (trueVersion != *version) {
|
||||
wxLogMessage("Warning: File has the wrong extension.");
|
||||
*version = trueVersion;
|
||||
}
|
||||
}
|
||||
|
||||
// Everything
|
||||
target->Line.push_back(new AssEntry(data, group));
|
||||
}
|
||||
// Unrecognized group
|
||||
else {
|
||||
target->Line.push_back(new AssEntry(data, group));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
#include "subtitle_format.h"
|
||||
|
||||
class AssAttachment;
|
||||
|
||||
/// DOCME
|
||||
/// @class ASSSubtitleFormat
|
||||
/// @brief DOCME
|
||||
|
@ -55,6 +53,4 @@ public:
|
|||
|
||||
void ReadFile(AssFile *target, wxString const& filename, wxString const& forceEncoding) const;
|
||||
void WriteFile(const AssFile *src, wxString const& filename, wxString const& encoding) const;
|
||||
|
||||
static void AddLine(AssFile *target, wxString data, int *version, AssAttachment **attach);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue