mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2025-01-31 21:11:39 +01:00
Rename method for better readability
This commit is contained in:
parent
124c2d0064
commit
e8e1e55314
@ -1,141 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreLineTabNewLine : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore (line#/tabs/n)"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER\tSTART\tEND\tFILE_NAME"))
|
||||
return false; // SON
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER START END FILE_NAME"))
|
||||
return false; // SON
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!
|
||||
// - Yes, professor.
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "@Italic@");
|
||||
text = text.Replace("</i>", "@Italic@");
|
||||
text = HtmlUtil.RemoveHtmlTags(text, true);
|
||||
if (Utilities.CountTagInText(Environment.NewLine, text) > 1)
|
||||
text = Utilities.AutoBreakLineMoreThanTwoLines(text, Configuration.Settings.General.SubtitleLineMaximumLength, string.Empty);
|
||||
text = text.Replace(Environment.NewLine, Environment.NewLine + "\t\t\t\t");
|
||||
sb.AppendLine(string.Format("{0:0000} {1} {2}\t{3}", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!
|
||||
// - Yes, professor.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line;
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[1];
|
||||
string end = temp[2];
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = s.Remove(0, RegexTimeCodes.Match(s).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
if (text.Contains("@Italic@"))
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (text.Contains("@Italic@"))
|
||||
{
|
||||
var index = text.IndexOf("@Italic@", StringComparison.Ordinal);
|
||||
string italicTag = "<i>";
|
||||
if (italicOn)
|
||||
italicTag = "</i>";
|
||||
text = text.Remove(index, "@Italic@".Length).Insert(index, italicTag);
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
text = HtmlUtil.FixInvalidItalicTags(text);
|
||||
}
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line == "\t\t\t" || line == "\t\t\t\t" || line == "\t\t\t\t\t")
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (line.StartsWith("\t\t\t\t") && p != null)
|
||||
{
|
||||
if (p.Text.Length < 200)
|
||||
p.Text = (p.Text + Environment.NewLine + line.Trim()).Trim();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreLineTabNewLine : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore (line#/tabs/n)"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER\tSTART\tEND\tFILE_NAME"))
|
||||
return false; // SON
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER START END FILE_NAME"))
|
||||
return false; // SON
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!
|
||||
// - Yes, professor.
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "@Italic@");
|
||||
text = text.Replace("</i>", "@Italic@");
|
||||
text = HtmlUtil.RemoveHtmlTags(text, true);
|
||||
if (Utilities.CountTagInText(Environment.NewLine, text) > 1)
|
||||
text = Utilities.AutoBreakLineMoreThanTwoLines(text, Configuration.Settings.General.SubtitleLineMaximumLength, string.Empty);
|
||||
text = text.Replace(Environment.NewLine, Environment.NewLine + "\t\t\t\t");
|
||||
sb.AppendLine(string.Format("{0:0000} {1} {2}\t{3}", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!
|
||||
// - Yes, professor.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line;
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[1];
|
||||
string end = temp[2];
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = s.Remove(0, RegexTimeCodes.Match(s).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
if (text.Contains("@Italic@"))
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (text.Contains("@Italic@"))
|
||||
{
|
||||
var index = text.IndexOf("@Italic@", StringComparison.Ordinal);
|
||||
string italicTag = "<i>";
|
||||
if (italicOn)
|
||||
italicTag = "</i>";
|
||||
text = text.Remove(index, "@Italic@".Length).Insert(index, italicTag);
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
text = HtmlUtil.FixInvalidItalicTags(text);
|
||||
}
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line == "\t\t\t" || line == "\t\t\t\t" || line == "\t\t\t\t\t")
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (line.StartsWith("\t\t\t\t") && p != null)
|
||||
{
|
||||
if (p.Text.Length < 200)
|
||||
p.Text = (p.Text + Environment.NewLine + line.Trim()).Trim();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,131 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreLineTabs : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore (line/tabs)"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER\tSTART\tEND\tFILE_NAME"))
|
||||
return false; // SON
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER START END FILE_NAME"))
|
||||
return false; // SON
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!//- Yes, professor.
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "@Italic@");
|
||||
text = text.Replace("</i>", "@Italic@");
|
||||
text = text.Replace(Environment.NewLine, "//");
|
||||
sb.AppendLine(string.Format("{0:0000}\t{1}\t{2}\t{3}", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(text, true)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!//- Yes, professor.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Replace(" ", "\t");
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split('\t');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[1];
|
||||
string end = temp[2];
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = s.Remove(0, RegexTimeCodes.Match(s).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
if (text.Contains("@Italic@"))
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (text.Contains("@Italic@"))
|
||||
{
|
||||
var index = text.IndexOf("@Italic@", StringComparison.Ordinal);
|
||||
string italicTag = "<i>";
|
||||
if (italicOn)
|
||||
italicTag = "</i>";
|
||||
text = text.Remove(index, "@Italic@".Length).Insert(index, italicTag);
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
text = HtmlUtil.FixInvalidItalicTags(text);
|
||||
}
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreLineTabs : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore (line/tabs)"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER\tSTART\tEND\tFILE_NAME"))
|
||||
return false; // SON
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER START END FILE_NAME"))
|
||||
return false; // SON
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!//- Yes, professor.
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "@Italic@");
|
||||
text = text.Replace("</i>", "@Italic@");
|
||||
text = text.Replace(Environment.NewLine, "//");
|
||||
sb.AppendLine(string.Format("{0:0000}\t{1}\t{2}\t{3}", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(text, true)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0002 00:01:48:22 00:01:52:17 - I need those samples, fast!//- Yes, professor.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Replace(" ", "\t");
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split('\t');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[1];
|
||||
string end = temp[2];
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = s.Remove(0, RegexTimeCodes.Match(s).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
if (text.Contains("@Italic@"))
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (text.Contains("@Italic@"))
|
||||
{
|
||||
var index = text.IndexOf("@Italic@", StringComparison.Ordinal);
|
||||
string italicTag = "<i>";
|
||||
if (italicOn)
|
||||
italicTag = "</i>";
|
||||
text = text.Remove(index, "@Italic@".Length).Insert(index, italicTag);
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
text = HtmlUtil.FixInvalidItalicTags(text);
|
||||
}
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,96 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreTabs : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore (tabs)"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:00:54:08 00:00:58:06 - Saucers... - ... a dry lake bed. (newline is \r)
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text, true).Replace(Environment.NewLine, "\r")));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("\r", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (p.Text.Length < 200)
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreTabs : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore (tabs)"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:00:54:08 00:00:58:06 - Saucers... - ... a dry lake bed. (newline is \r)
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text, true).Replace(Environment.NewLine, "\r")));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("\r", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (p.Text.Length < 200)
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,104 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreWithLineNumbers : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+ \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore w. line#"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains("#INPOINT OUTPOINT PATH"))
|
||||
return false; // Pinnacle Impression
|
||||
if (sb.ToString().StartsWith("{{\\rtf1"))
|
||||
return false;
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
sb.AppendLine(string.Format("{0} {1} {2} {3}", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(line.IndexOf(' ')).Trim();
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreWithLineNumbers : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+ \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore w. line#"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains("#INPOINT OUTPOINT PATH"))
|
||||
return false; // Pinnacle Impression
|
||||
if (sb.ToString().StartsWith("{{\\rtf1"))
|
||||
return false;
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
sb.AppendLine(string.Format("{0} {1} {2} {3}", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(line.IndexOf(' ')).Trim();
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,101 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreWithLineNumbersNtsc : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+ \d\d;\d\d;\d\d;\d\d \d\d;\d\d;\d\d;\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore NTSC"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains("#INPOINT OUTPOINT PATH"))
|
||||
return false; // Pinnacle Impression
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
sb.AppendLine(string.Format("{0} {1} {2} {3}", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00;03;15;22 (last is frame)
|
||||
return string.Format("{0:00};{1:00};{2:00};{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00;03;15;22 00;03;23;10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(line.IndexOf(' ')).Trim();
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AdobeEncoreWithLineNumbersNtsc : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+ \d\d;\d\d;\d\d;\d\d \d\d;\d\d;\d\d;\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Adobe Encore NTSC"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains("#INPOINT OUTPOINT PATH"))
|
||||
return false; // Pinnacle Impression
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
sb.AppendLine(string.Format("{0} {1} {2} {3}", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00;03;15;22 (last is frame)
|
||||
return string.Format("{0:00};{1:00};{2:00};{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00;03;15;22 00;03;23;10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(line.IndexOf(' ')).Trim();
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,130 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AvidCaption : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Avid Caption"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
sb.AppendLine("@ This file written with the Avid Caption plugin, version 1");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("<begin subtitles>");
|
||||
const string writeFormat = "{0} {1}{2}{3}{2}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(writeFormat, p.StartTime.ToHHMMSSFF(), EncodeEndTimeCode(p.EndTime), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
//00:50:34:22 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
index++;
|
||||
}
|
||||
sb.AppendLine("<end subtitles>");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeEndTimeCode(TimeCode time)
|
||||
{
|
||||
//00:50:39:13 (last is frame)
|
||||
|
||||
//Bugfix for Avid - On 23.976 FPS and 24 FPS projects, when the End time of a subtitle ends in 02, 07, 12, 17, 22, 27 frames, the subtitle won't import.
|
||||
if (Math.Abs(Configuration.Settings.General.CurrentFrameRate - 23.976) < 0.01 ||
|
||||
Math.Abs(Configuration.Settings.General.CurrentFrameRate - 24) < 0.01)
|
||||
{
|
||||
var frames = SubtitleFormat.MillisecondsToFramesMaxFrameRate(time.Milliseconds);
|
||||
if (frames == 2 || frames == 7 || frames == 12 || frames == 17 || frames == 22 || frames == 27)
|
||||
frames--;
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, frames);
|
||||
}
|
||||
else
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
bool beginFound = false;
|
||||
bool endFound = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string tline = line.Trim();
|
||||
if (tline.Equals("<begin subtitles>", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
beginFound = true;
|
||||
}
|
||||
else if (tline.Equals("<end subtitles>", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
endFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.IndexOf(':') == 2 && RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (tline.Length == 0 || tline[0] == '@')
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (tline.Length > 0 && p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text.TrimEnd() + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
if (!beginFound)
|
||||
_errorCount++;
|
||||
if (!endFound)
|
||||
_errorCount++;
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AvidCaption : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Avid Caption"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
sb.AppendLine("@ This file written with the Avid Caption plugin, version 1");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("<begin subtitles>");
|
||||
const string writeFormat = "{0} {1}{2}{3}{2}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(writeFormat, p.StartTime.ToHHMMSSFF(), EncodeEndTimeCode(p.EndTime), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
//00:50:34:22 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
index++;
|
||||
}
|
||||
sb.AppendLine("<end subtitles>");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeEndTimeCode(TimeCode time)
|
||||
{
|
||||
//00:50:39:13 (last is frame)
|
||||
|
||||
//Bugfix for Avid - On 23.976 FPS and 24 FPS projects, when the End time of a subtitle ends in 02, 07, 12, 17, 22, 27 frames, the subtitle won't import.
|
||||
if (Math.Abs(Configuration.Settings.General.CurrentFrameRate - 23.976) < 0.01 ||
|
||||
Math.Abs(Configuration.Settings.General.CurrentFrameRate - 24) < 0.01)
|
||||
{
|
||||
var frames = SubtitleFormat.MillisecondsToFramesMaxFrameRate(time.Milliseconds);
|
||||
if (frames == 2 || frames == 7 || frames == 12 || frames == 17 || frames == 22 || frames == 27)
|
||||
frames--;
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, frames);
|
||||
}
|
||||
else
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
bool beginFound = false;
|
||||
bool endFound = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string tline = line.Trim();
|
||||
if (tline.Equals("<begin subtitles>", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
beginFound = true;
|
||||
}
|
||||
else if (tline.Equals("<end subtitles>", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
endFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.IndexOf(':') == 2 && RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (tline.Length == 0 || tline[0] == '@')
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (tline.Length > 0 && p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text.TrimEnd() + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
if (!beginFound)
|
||||
_errorCount++;
|
||||
if (!endFound)
|
||||
_errorCount++;
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,148 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AvidDvd : SubtitleFormat
|
||||
{
|
||||
//25 10:03:20:23 10:03:23:05 some text
|
||||
//I see, on my way.|New line also.
|
||||
//
|
||||
//26 10:03:31:18 10:03:34:00 even more text
|
||||
//Panessa, why didn't they give them
|
||||
//an escape route ?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t.+$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Avid DVD"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (fileName != null && fileName.EndsWith(".dost", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return tc.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
bool italic = false;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = p.Text;
|
||||
if (text.StartsWith('{') && text.Length > 6 && text[6] == '}')
|
||||
text = text.Remove(0, 6);
|
||||
if (text.StartsWith("<i>", StringComparison.Ordinal) && text.EndsWith("</i>", StringComparison.Ordinal))
|
||||
{
|
||||
if (!italic)
|
||||
{
|
||||
italic = true;
|
||||
sb.AppendLine("$Italic = TRUE");
|
||||
}
|
||||
}
|
||||
else if (italic)
|
||||
{
|
||||
italic = false;
|
||||
sb.AppendLine("$Italic = FALSE");
|
||||
}
|
||||
|
||||
text = HtmlUtil.RemoveHtmlTags(text, true);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}\t{3}", count, MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text.Replace(Environment.NewLine, "|")));
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
bool italic = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Replace("|", Environment.NewLine).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb.Clear();
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length >= 3)
|
||||
{
|
||||
string text = s.Remove(0, arr[0].Length + arr[1].Length + arr[2].Length + 2).Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(text.Replace("0", string.Empty).Replace("1", string.Empty).Replace("2", string.Empty).Replace("3", string.Empty).Replace("4", string.Empty).Replace("5", string.Empty).
|
||||
Replace("6", string.Empty).Replace("7", string.Empty).Replace("8", string.Empty).Replace("9", string.Empty).Replace(".", string.Empty).Replace(":", string.Empty).Replace(",", string.Empty)))
|
||||
_errorCount++;
|
||||
if (italic)
|
||||
text = "<i>" + text + "</i>";
|
||||
sb.AppendLine(text);
|
||||
char[] splitChars = { ',', '.', ':' };
|
||||
p = new Paragraph(DecodeTimeCode(arr[1], splitChars), DecodeTimeCode(arr[2], splitChars), string.Empty);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (s.StartsWith('$'))
|
||||
{
|
||||
if (s.Replace(" ", string.Empty).Equals("$italic=true", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
italic = true;
|
||||
}
|
||||
else if (s.Replace(" ", string.Empty).Equals("$italic=false", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
italic = false;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Replace("|", Environment.NewLine).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class AvidDvd : SubtitleFormat
|
||||
{
|
||||
//25 10:03:20:23 10:03:23:05 some text
|
||||
//I see, on my way.|New line also.
|
||||
//
|
||||
//26 10:03:31:18 10:03:34:00 even more text
|
||||
//Panessa, why didn't they give them
|
||||
//an escape route ?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t.+$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Avid DVD"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (fileName != null && fileName.EndsWith(".dost", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return tc.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
bool italic = false;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = p.Text;
|
||||
if (text.StartsWith('{') && text.Length > 6 && text[6] == '}')
|
||||
text = text.Remove(0, 6);
|
||||
if (text.StartsWith("<i>", StringComparison.Ordinal) && text.EndsWith("</i>", StringComparison.Ordinal))
|
||||
{
|
||||
if (!italic)
|
||||
{
|
||||
italic = true;
|
||||
sb.AppendLine("$Italic = TRUE");
|
||||
}
|
||||
}
|
||||
else if (italic)
|
||||
{
|
||||
italic = false;
|
||||
sb.AppendLine("$Italic = FALSE");
|
||||
}
|
||||
|
||||
text = HtmlUtil.RemoveHtmlTags(text, true);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}\t{3}", count, MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text.Replace(Environment.NewLine, "|")));
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
bool italic = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Replace("|", Environment.NewLine).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb.Clear();
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length >= 3)
|
||||
{
|
||||
string text = s.Remove(0, arr[0].Length + arr[1].Length + arr[2].Length + 2).Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(text.Replace("0", string.Empty).Replace("1", string.Empty).Replace("2", string.Empty).Replace("3", string.Empty).Replace("4", string.Empty).Replace("5", string.Empty).
|
||||
Replace("6", string.Empty).Replace("7", string.Empty).Replace("8", string.Empty).Replace("9", string.Empty).Replace(".", string.Empty).Replace(":", string.Empty).Replace(",", string.Empty)))
|
||||
_errorCount++;
|
||||
if (italic)
|
||||
text = "<i>" + text + "</i>";
|
||||
sb.AppendLine(text);
|
||||
char[] splitChars = { ',', '.', ':' };
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[1], splitChars), DecodeTimeCodeFrames(arr[2], splitChars), string.Empty);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (s.StartsWith('$'))
|
||||
{
|
||||
if (s.Replace(" ", string.Empty).Equals("$italic=true", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
italic = true;
|
||||
}
|
||||
else if (s.Replace(" ", string.Empty).Equals("$italic=false", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
italic = false;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Replace("|", Environment.NewLine).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,332 +1,332 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class BelleNuitSubtitler : SubtitleFormat
|
||||
{
|
||||
///tc 00:00:35:09 00:00:38:05
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\/tc \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexFileNum = new Regex(@"^\/file\s+\d+$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".stp"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Belle Nuit Subtitler"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string paragraphWriteFormat = "/tc {0} {1}{2}{3}{2}";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, EncodeText(p.Text)));
|
||||
}
|
||||
|
||||
var doc = new XmlDocument { XmlResolver = null };
|
||||
doc.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine + @"<xmldict>
|
||||
<key>document</key>
|
||||
<dict>
|
||||
<key>creator</key>
|
||||
<string>SICT</string>
|
||||
<key>type</key>
|
||||
<string>STLI</string>
|
||||
<key>version</key>
|
||||
<real>1.4</real>
|
||||
<key>applicationversion</key>
|
||||
<string>Belle Nuit Subtitler 1.7.8</string>
|
||||
<key>creationdate</key>
|
||||
<date>2012-03-13 16:30:32</date>
|
||||
<key>modificationdate</key>
|
||||
<date>2012-03-13 16:30:32</date>
|
||||
</dict>
|
||||
<key>mainleft</key>
|
||||
<integer>40</integer>
|
||||
<key>maintop</key>
|
||||
<integer>48</integer>
|
||||
<key>mainwidth</key>
|
||||
<integer>825</integer>
|
||||
<key>mainheight</key>
|
||||
<integer>886</integer>
|
||||
<key>styledt</key>
|
||||
<false/>
|
||||
<key>exportdt</key>
|
||||
<true/>
|
||||
<key>previewdt</key>
|
||||
<true/>
|
||||
<key>moviedt</key>
|
||||
<true/>
|
||||
<key>exportformat</key>
|
||||
<string>TIFF</string>
|
||||
<key>style</key>
|
||||
<dict>
|
||||
<key>font</key>
|
||||
<string>Geneva</string>
|
||||
<key>size</key>
|
||||
<integer>26</integer>
|
||||
<key>spacing</key>
|
||||
<real>1</real>
|
||||
<key>leading</key>
|
||||
<real>7</real>
|
||||
<key>bold</key>
|
||||
<false/>
|
||||
<key>italic</key>
|
||||
<false/>
|
||||
<key>underline</key>
|
||||
<false/>
|
||||
<key>vertical</key>
|
||||
<integer>486</integer>
|
||||
<key>halin</key>
|
||||
<integer>1</integer>
|
||||
<key>valign</key>
|
||||
<integer>2</integer>
|
||||
<key>standard</key>
|
||||
<string>PAL</string>
|
||||
<key>height</key>
|
||||
<integer>576</integer>
|
||||
<key>width</key>
|
||||
<integer>720</integer>
|
||||
<key>widthreal</key>
|
||||
<integer>768</integer>
|
||||
<key>antialiasing</key>
|
||||
<integer>4</integer>
|
||||
<key>left</key>
|
||||
<integer>40</integer>
|
||||
<key>right</key>
|
||||
<integer>680</integer>
|
||||
<key>wrapmethod</key>
|
||||
<integer>2</integer>
|
||||
<key>interlaced</key>
|
||||
<true/>
|
||||
<key>textcolor</key>
|
||||
<color>#FBFFF2</color>
|
||||
<key>textalpha</key>
|
||||
<real>1</real>
|
||||
<key>textsoft</key>
|
||||
<integer>0</integer>
|
||||
<key>bordercolor</key>
|
||||
<color>#F0F10</color>
|
||||
<key>borderalpha</key>
|
||||
<real>1</real>
|
||||
<key>bordersoft</key>
|
||||
<integer>0</integer>
|
||||
<key>borderwidth</key>
|
||||
<integer>6</integer>
|
||||
<key>rectcolor</key>
|
||||
<color>#0</color>
|
||||
<key>rectalpha</key>
|
||||
<real>0</real>
|
||||
<key>rectsoft</key>
|
||||
<integer>0</integer>
|
||||
<key>rectform</key>
|
||||
<integer>1</integer>
|
||||
<key>shadowcolor</key>
|
||||
<color>#7F7F7F</color>
|
||||
<key>shadowalpha</key>
|
||||
<real>0</real>
|
||||
<key>shadowsoft</key>
|
||||
<integer>0</integer>
|
||||
<key>shadowx</key>
|
||||
<integer>2</integer>
|
||||
<key>shadowy</key>
|
||||
<integer>2</integer>
|
||||
<key>framerate</key>
|
||||
<string>25</string>
|
||||
</dict>
|
||||
<key>folderpath</key>
|
||||
<string></string>
|
||||
<key>prefix</key>
|
||||
<string></string>
|
||||
<key>moviepath</key>
|
||||
<string></string>
|
||||
<key>movieoffset</key>
|
||||
<string>00:00:00:00</string>
|
||||
<key>moviesyncoption</key>
|
||||
<true/>
|
||||
<key>pagesetup</key>
|
||||
<null/>
|
||||
<key>titlelist</key>
|
||||
</xmldict>");
|
||||
XmlNode node = doc.CreateElement("string");
|
||||
node.InnerText = sb.ToString().Trim() + Environment.NewLine + Environment.NewLine;
|
||||
doc.DocumentElement.AppendChild(node);
|
||||
|
||||
return ToUtf8XmlString(doc).Replace("\r\n", "\n");
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
var doc = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
doc.LoadXml(sb.ToString());
|
||||
if (doc.DocumentElement == null || doc.DocumentElement.Name != "xmldict" || doc.DocumentElement.SelectSingleNode("string") == null)
|
||||
return;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
string text = null;
|
||||
string keyName = string.Empty;
|
||||
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
|
||||
{
|
||||
if (node.Name == "key")
|
||||
{
|
||||
keyName = node.InnerText;
|
||||
}
|
||||
else if (node.Name == "string" && keyName == "titlelist")
|
||||
{
|
||||
text = node.InnerText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (text == null)
|
||||
return;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
Paragraph paragraph = null;
|
||||
sb = new StringBuilder();
|
||||
foreach (string line in text.Split(Utilities.NewLineChars))
|
||||
{
|
||||
if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(4, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (paragraph != null && !string.IsNullOrWhiteSpace(sb.ToString()))
|
||||
{
|
||||
paragraph.Text = DecodeText(sb);
|
||||
}
|
||||
|
||||
var start = DecodeTimeCode(parts);
|
||||
parts = line.Substring(16, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
var end = DecodeTimeCode(parts);
|
||||
paragraph = new Paragraph { StartTime = start, EndTime = end };
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
sb.Clear();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RegexFileNum.IsMatch(line))
|
||||
{
|
||||
continue; // skip Belle-Nuit's numbering lines ("/file 0001")
|
||||
}
|
||||
else if (paragraph != null)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrWhiteSpace(sb.ToString()))
|
||||
{
|
||||
paragraph.Text = DecodeText(sb);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeText(string s)
|
||||
{
|
||||
s = HtmlUtil.RemoveOpenCloseTags(s, HtmlUtil.TagBold, HtmlUtil.TagUnderline, HtmlUtil.TagFont);
|
||||
if (s.StartsWith("{\\an3}", StringComparison.Ordinal) || s.StartsWith("{\\an6}", StringComparison.Ordinal))
|
||||
s = "/STYLE RIGHT" + Environment.NewLine + s.Remove(0, 6).Trim();
|
||||
if (s.StartsWith("{\\an1}", StringComparison.Ordinal) || s.StartsWith("{\\an4}", StringComparison.Ordinal))
|
||||
s = "/STYLE LEFT" + Environment.NewLine + s.Remove(0, 6).Trim();
|
||||
if (s.StartsWith("{\\an7}", StringComparison.Ordinal) || s.StartsWith("{\\an8}", StringComparison.Ordinal) || s.StartsWith("{\\an9}", StringComparison.Ordinal))
|
||||
s = "/STYLE VERTICAL(-25)" + Environment.NewLine + s.Remove(0, 6).Trim();
|
||||
if (s.StartsWith("{\\an2}", StringComparison.Ordinal) || s.StartsWith("{\\an5}", StringComparison.Ordinal))
|
||||
s = s.Remove(0, 6).Trim();
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string DecodeText(StringBuilder sb)
|
||||
{
|
||||
var s = sb.ToString().Trim();
|
||||
s = s.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine).Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
|
||||
if (s.StartsWith("/STYLE RIGHT" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an3}" + s.Remove(0, 12).Trim();
|
||||
if (s.StartsWith("/STYLE LEFT" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an1}" + s.Remove(0, 11).Trim();
|
||||
if (s.StartsWith("/STYLE TOP" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 10).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-25)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-24)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-23)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-22)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-21)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-20)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-19)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-18)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-17)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-16)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-15)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-14)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-13)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-12)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-11)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-10)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
s = HtmlUtil.FixInvalidItalicTags(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class BelleNuitSubtitler : SubtitleFormat
|
||||
{
|
||||
///tc 00:00:35:09 00:00:38:05
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\/tc \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexFileNum = new Regex(@"^\/file\s+\d+$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".stp"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Belle Nuit Subtitler"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string paragraphWriteFormat = "/tc {0} {1}{2}{3}{2}";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, EncodeText(p.Text)));
|
||||
}
|
||||
|
||||
var doc = new XmlDocument { XmlResolver = null };
|
||||
doc.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine + @"<xmldict>
|
||||
<key>document</key>
|
||||
<dict>
|
||||
<key>creator</key>
|
||||
<string>SICT</string>
|
||||
<key>type</key>
|
||||
<string>STLI</string>
|
||||
<key>version</key>
|
||||
<real>1.4</real>
|
||||
<key>applicationversion</key>
|
||||
<string>Belle Nuit Subtitler 1.7.8</string>
|
||||
<key>creationdate</key>
|
||||
<date>2012-03-13 16:30:32</date>
|
||||
<key>modificationdate</key>
|
||||
<date>2012-03-13 16:30:32</date>
|
||||
</dict>
|
||||
<key>mainleft</key>
|
||||
<integer>40</integer>
|
||||
<key>maintop</key>
|
||||
<integer>48</integer>
|
||||
<key>mainwidth</key>
|
||||
<integer>825</integer>
|
||||
<key>mainheight</key>
|
||||
<integer>886</integer>
|
||||
<key>styledt</key>
|
||||
<false/>
|
||||
<key>exportdt</key>
|
||||
<true/>
|
||||
<key>previewdt</key>
|
||||
<true/>
|
||||
<key>moviedt</key>
|
||||
<true/>
|
||||
<key>exportformat</key>
|
||||
<string>TIFF</string>
|
||||
<key>style</key>
|
||||
<dict>
|
||||
<key>font</key>
|
||||
<string>Geneva</string>
|
||||
<key>size</key>
|
||||
<integer>26</integer>
|
||||
<key>spacing</key>
|
||||
<real>1</real>
|
||||
<key>leading</key>
|
||||
<real>7</real>
|
||||
<key>bold</key>
|
||||
<false/>
|
||||
<key>italic</key>
|
||||
<false/>
|
||||
<key>underline</key>
|
||||
<false/>
|
||||
<key>vertical</key>
|
||||
<integer>486</integer>
|
||||
<key>halin</key>
|
||||
<integer>1</integer>
|
||||
<key>valign</key>
|
||||
<integer>2</integer>
|
||||
<key>standard</key>
|
||||
<string>PAL</string>
|
||||
<key>height</key>
|
||||
<integer>576</integer>
|
||||
<key>width</key>
|
||||
<integer>720</integer>
|
||||
<key>widthreal</key>
|
||||
<integer>768</integer>
|
||||
<key>antialiasing</key>
|
||||
<integer>4</integer>
|
||||
<key>left</key>
|
||||
<integer>40</integer>
|
||||
<key>right</key>
|
||||
<integer>680</integer>
|
||||
<key>wrapmethod</key>
|
||||
<integer>2</integer>
|
||||
<key>interlaced</key>
|
||||
<true/>
|
||||
<key>textcolor</key>
|
||||
<color>#FBFFF2</color>
|
||||
<key>textalpha</key>
|
||||
<real>1</real>
|
||||
<key>textsoft</key>
|
||||
<integer>0</integer>
|
||||
<key>bordercolor</key>
|
||||
<color>#F0F10</color>
|
||||
<key>borderalpha</key>
|
||||
<real>1</real>
|
||||
<key>bordersoft</key>
|
||||
<integer>0</integer>
|
||||
<key>borderwidth</key>
|
||||
<integer>6</integer>
|
||||
<key>rectcolor</key>
|
||||
<color>#0</color>
|
||||
<key>rectalpha</key>
|
||||
<real>0</real>
|
||||
<key>rectsoft</key>
|
||||
<integer>0</integer>
|
||||
<key>rectform</key>
|
||||
<integer>1</integer>
|
||||
<key>shadowcolor</key>
|
||||
<color>#7F7F7F</color>
|
||||
<key>shadowalpha</key>
|
||||
<real>0</real>
|
||||
<key>shadowsoft</key>
|
||||
<integer>0</integer>
|
||||
<key>shadowx</key>
|
||||
<integer>2</integer>
|
||||
<key>shadowy</key>
|
||||
<integer>2</integer>
|
||||
<key>framerate</key>
|
||||
<string>25</string>
|
||||
</dict>
|
||||
<key>folderpath</key>
|
||||
<string></string>
|
||||
<key>prefix</key>
|
||||
<string></string>
|
||||
<key>moviepath</key>
|
||||
<string></string>
|
||||
<key>movieoffset</key>
|
||||
<string>00:00:00:00</string>
|
||||
<key>moviesyncoption</key>
|
||||
<true/>
|
||||
<key>pagesetup</key>
|
||||
<null/>
|
||||
<key>titlelist</key>
|
||||
</xmldict>");
|
||||
XmlNode node = doc.CreateElement("string");
|
||||
node.InnerText = sb.ToString().Trim() + Environment.NewLine + Environment.NewLine;
|
||||
doc.DocumentElement.AppendChild(node);
|
||||
|
||||
return ToUtf8XmlString(doc).Replace("\r\n", "\n");
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
var doc = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
doc.LoadXml(sb.ToString());
|
||||
if (doc.DocumentElement == null || doc.DocumentElement.Name != "xmldict" || doc.DocumentElement.SelectSingleNode("string") == null)
|
||||
return;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
string text = null;
|
||||
string keyName = string.Empty;
|
||||
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
|
||||
{
|
||||
if (node.Name == "key")
|
||||
{
|
||||
keyName = node.InnerText;
|
||||
}
|
||||
else if (node.Name == "string" && keyName == "titlelist")
|
||||
{
|
||||
text = node.InnerText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (text == null)
|
||||
return;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
Paragraph paragraph = null;
|
||||
sb = new StringBuilder();
|
||||
foreach (string line in text.Split(Utilities.NewLineChars))
|
||||
{
|
||||
if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(4, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (paragraph != null && !string.IsNullOrWhiteSpace(sb.ToString()))
|
||||
{
|
||||
paragraph.Text = DecodeText(sb);
|
||||
}
|
||||
|
||||
var start = DecodeTimeCodeFrames(parts);
|
||||
parts = line.Substring(16, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
var end = DecodeTimeCodeFrames(parts);
|
||||
paragraph = new Paragraph { StartTime = start, EndTime = end };
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
sb.Clear();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RegexFileNum.IsMatch(line))
|
||||
{
|
||||
continue; // skip Belle-Nuit's numbering lines ("/file 0001")
|
||||
}
|
||||
else if (paragraph != null)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrWhiteSpace(sb.ToString()))
|
||||
{
|
||||
paragraph.Text = DecodeText(sb);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeText(string s)
|
||||
{
|
||||
s = HtmlUtil.RemoveOpenCloseTags(s, HtmlUtil.TagBold, HtmlUtil.TagUnderline, HtmlUtil.TagFont);
|
||||
if (s.StartsWith("{\\an3}", StringComparison.Ordinal) || s.StartsWith("{\\an6}", StringComparison.Ordinal))
|
||||
s = "/STYLE RIGHT" + Environment.NewLine + s.Remove(0, 6).Trim();
|
||||
if (s.StartsWith("{\\an1}", StringComparison.Ordinal) || s.StartsWith("{\\an4}", StringComparison.Ordinal))
|
||||
s = "/STYLE LEFT" + Environment.NewLine + s.Remove(0, 6).Trim();
|
||||
if (s.StartsWith("{\\an7}", StringComparison.Ordinal) || s.StartsWith("{\\an8}", StringComparison.Ordinal) || s.StartsWith("{\\an9}", StringComparison.Ordinal))
|
||||
s = "/STYLE VERTICAL(-25)" + Environment.NewLine + s.Remove(0, 6).Trim();
|
||||
if (s.StartsWith("{\\an2}", StringComparison.Ordinal) || s.StartsWith("{\\an5}", StringComparison.Ordinal))
|
||||
s = s.Remove(0, 6).Trim();
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string DecodeText(StringBuilder sb)
|
||||
{
|
||||
var s = sb.ToString().Trim();
|
||||
s = s.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine).Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
|
||||
if (s.StartsWith("/STYLE RIGHT" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an3}" + s.Remove(0, 12).Trim();
|
||||
if (s.StartsWith("/STYLE LEFT" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an1}" + s.Remove(0, 11).Trim();
|
||||
if (s.StartsWith("/STYLE TOP" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 10).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-25)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-24)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-23)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-22)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-21)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-20)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-19)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an8}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-18)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-17)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-16)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-15)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-14)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-13)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-12)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-11)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
if (s.StartsWith("/STYLE VERTICAL(-10)" + Environment.NewLine, StringComparison.Ordinal))
|
||||
s = "{\\an5}" + s.Remove(0, 20).Trim();
|
||||
s = HtmlUtil.FixInvalidItalicTags(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,181 +1,181 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Csv3 : SubtitleFormat
|
||||
{
|
||||
private const string Separator = ",";
|
||||
|
||||
//01:00:10:03,01:00:15:25,"I thought I should let my sister-in-law know.", ""
|
||||
private static readonly Regex CsvLine = new Regex(@"^\d\d:\d\d:\d\d:\d\d" + Separator + @"\d\d:\d\d:\d\d:\d\d" + Separator, RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".csv"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Csv3"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
int fine = 0;
|
||||
int failed = 0;
|
||||
bool continuation = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.StartsWith("$FontName", StringComparison.Ordinal) || line.StartsWith("$ColorIndex1", StringComparison.Ordinal))
|
||||
return false;
|
||||
Match m = null;
|
||||
if (line.Length > 8 && line[2] == ':')
|
||||
m = CsvLine.Match(line);
|
||||
if (m != null && m.Success)
|
||||
{
|
||||
fine++;
|
||||
string s = line.Remove(0, m.Length);
|
||||
continuation = s.StartsWith('"');
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (continuation)
|
||||
continuation = false;
|
||||
else
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
if (failed > 20)
|
||||
return false;
|
||||
|
||||
return fine > failed;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{1}{0}{2}{0}\"{3}\"{0}\"{4}\"";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(string.Format(format, Separator, "Start time (hh:mm:ss:ff)", "End time (hh:mm:ss:ff)", "Line 1", "Line 2"));
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var arr = p.Text.Trim().SplitToLines();
|
||||
if (arr.Length > 3)
|
||||
{
|
||||
string s = Utilities.AutoBreakLine(p.Text);
|
||||
arr = s.Trim().SplitToLines();
|
||||
}
|
||||
string line1 = string.Empty;
|
||||
string line2 = string.Empty;
|
||||
if (arr.Length > 0)
|
||||
line1 = arr[0];
|
||||
if (arr.Length > 1)
|
||||
line2 = arr[1];
|
||||
line1 = line1.Replace("\"", "\"\"");
|
||||
line2 = line2.Replace("\"", "\"\"");
|
||||
sb.AppendLine(string.Format(format, Separator, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), line1, line2));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
Match m = CsvLine.Match(line);
|
||||
if (m.Success)
|
||||
{
|
||||
string[] parts = line.Substring(0, m.Length).Split(Separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 2)
|
||||
try
|
||||
{
|
||||
var start = DecodeTimeCode(parts[0], splitChars);
|
||||
var end = DecodeTimeCode(parts[1], splitChars);
|
||||
string text = ReadText(line.Remove(0, m.Length));
|
||||
var p = new Paragraph(start, end, text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string ReadText(string csv)
|
||||
{
|
||||
if (string.IsNullOrEmpty(csv))
|
||||
return string.Empty;
|
||||
|
||||
csv = csv.Replace("\"\"", "\"");
|
||||
|
||||
var sb = new StringBuilder();
|
||||
csv = csv.Trim();
|
||||
if (csv.StartsWith('"'))
|
||||
csv = csv.Remove(0, 1);
|
||||
if (csv.EndsWith('"'))
|
||||
csv = csv.Remove(csv.Length - 1, 1);
|
||||
bool isBreak = false;
|
||||
for (int i = 0; i < csv.Length; i++)
|
||||
{
|
||||
var s = csv[i];
|
||||
if (s == '"' && csv.Substring(i).StartsWith("\"\""))
|
||||
{
|
||||
sb.Append('"');
|
||||
}
|
||||
else if (s == '"')
|
||||
{
|
||||
if (isBreak)
|
||||
{
|
||||
isBreak = false;
|
||||
}
|
||||
else if (i == 0 || i == csv.Length - 1 || sb.ToString().EndsWith(Environment.NewLine))
|
||||
{
|
||||
sb.Append('"');
|
||||
}
|
||||
else
|
||||
{
|
||||
isBreak = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isBreak && s == ' ')
|
||||
{
|
||||
}
|
||||
else if (isBreak && s == ',')
|
||||
{
|
||||
sb.Append(Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
isBreak = false;
|
||||
sb.Append(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Csv3 : SubtitleFormat
|
||||
{
|
||||
private const string Separator = ",";
|
||||
|
||||
//01:00:10:03,01:00:15:25,"I thought I should let my sister-in-law know.", ""
|
||||
private static readonly Regex CsvLine = new Regex(@"^\d\d:\d\d:\d\d:\d\d" + Separator + @"\d\d:\d\d:\d\d:\d\d" + Separator, RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".csv"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Csv3"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
int fine = 0;
|
||||
int failed = 0;
|
||||
bool continuation = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.StartsWith("$FontName", StringComparison.Ordinal) || line.StartsWith("$ColorIndex1", StringComparison.Ordinal))
|
||||
return false;
|
||||
Match m = null;
|
||||
if (line.Length > 8 && line[2] == ':')
|
||||
m = CsvLine.Match(line);
|
||||
if (m != null && m.Success)
|
||||
{
|
||||
fine++;
|
||||
string s = line.Remove(0, m.Length);
|
||||
continuation = s.StartsWith('"');
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (continuation)
|
||||
continuation = false;
|
||||
else
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
if (failed > 20)
|
||||
return false;
|
||||
|
||||
return fine > failed;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{1}{0}{2}{0}\"{3}\"{0}\"{4}\"";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(string.Format(format, Separator, "Start time (hh:mm:ss:ff)", "End time (hh:mm:ss:ff)", "Line 1", "Line 2"));
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var arr = p.Text.Trim().SplitToLines();
|
||||
if (arr.Length > 3)
|
||||
{
|
||||
string s = Utilities.AutoBreakLine(p.Text);
|
||||
arr = s.Trim().SplitToLines();
|
||||
}
|
||||
string line1 = string.Empty;
|
||||
string line2 = string.Empty;
|
||||
if (arr.Length > 0)
|
||||
line1 = arr[0];
|
||||
if (arr.Length > 1)
|
||||
line2 = arr[1];
|
||||
line1 = line1.Replace("\"", "\"\"");
|
||||
line2 = line2.Replace("\"", "\"\"");
|
||||
sb.AppendLine(string.Format(format, Separator, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), line1, line2));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
Match m = CsvLine.Match(line);
|
||||
if (m.Success)
|
||||
{
|
||||
string[] parts = line.Substring(0, m.Length).Split(Separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 2)
|
||||
try
|
||||
{
|
||||
var start = DecodeTimeCodeFrames(parts[0], splitChars);
|
||||
var end = DecodeTimeCodeFrames(parts[1], splitChars);
|
||||
string text = ReadText(line.Remove(0, m.Length));
|
||||
var p = new Paragraph(start, end, text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string ReadText(string csv)
|
||||
{
|
||||
if (string.IsNullOrEmpty(csv))
|
||||
return string.Empty;
|
||||
|
||||
csv = csv.Replace("\"\"", "\"");
|
||||
|
||||
var sb = new StringBuilder();
|
||||
csv = csv.Trim();
|
||||
if (csv.StartsWith('"'))
|
||||
csv = csv.Remove(0, 1);
|
||||
if (csv.EndsWith('"'))
|
||||
csv = csv.Remove(csv.Length - 1, 1);
|
||||
bool isBreak = false;
|
||||
for (int i = 0; i < csv.Length; i++)
|
||||
{
|
||||
var s = csv[i];
|
||||
if (s == '"' && csv.Substring(i).StartsWith("\"\""))
|
||||
{
|
||||
sb.Append('"');
|
||||
}
|
||||
else if (s == '"')
|
||||
{
|
||||
if (isBreak)
|
||||
{
|
||||
isBreak = false;
|
||||
}
|
||||
else if (i == 0 || i == csv.Length - 1 || sb.ToString().EndsWith(Environment.NewLine))
|
||||
{
|
||||
sb.Append('"');
|
||||
}
|
||||
else
|
||||
{
|
||||
isBreak = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isBreak && s == ' ')
|
||||
{
|
||||
}
|
||||
else if (isBreak && s == ',')
|
||||
{
|
||||
sb.Append(Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
isBreak = false;
|
||||
sb.Append(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,88 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class DigiBeta : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d \d\d \d\d \d\d\t\d\d \d\d \d\d \d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "DigiBeta"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//10 01 37 23 10 01 42 01 Makkhi (newline is TAB)
|
||||
const string paragraphWriteFormat = "{0}\t{1}\t{2}";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text.Replace(Environment.NewLine, "\t")));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
var paragraph = new Paragraph();
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCode.IsMatch(line) && line.Length > 24)
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var start = DecodeTimeCode(parts);
|
||||
parts = line.Substring(12, 11).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var end = DecodeTimeCode(parts);
|
||||
paragraph = new Paragraph();
|
||||
paragraph.StartTime = start;
|
||||
paragraph.EndTime = end;
|
||||
|
||||
paragraph.Text = line.Substring(24).Trim().Replace("\t", Environment.NewLine);
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00} {1:00} {2:00} {3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class DigiBeta : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d \d\d \d\d \d\d\t\d\d \d\d \d\d \d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "DigiBeta"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//10 01 37 23 10 01 42 01 Makkhi (newline is TAB)
|
||||
const string paragraphWriteFormat = "{0}\t{1}\t{2}";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text.Replace(Environment.NewLine, "\t")));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
var paragraph = new Paragraph();
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCode.IsMatch(line) && line.Length > 24)
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var start = DecodeTimeCodeFrames(parts);
|
||||
parts = line.Substring(12, 11).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var end = DecodeTimeCodeFrames(parts);
|
||||
paragraph = new Paragraph();
|
||||
paragraph.StartTime = start;
|
||||
paragraph.EndTime = end;
|
||||
|
||||
paragraph.Text = line.Substring(24).Trim().Replace("\t", Environment.NewLine);
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00} {1:00} {2:00} {3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,102 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Dost : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".dost"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "DOST"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (!sb.ToString().Contains(Environment.NewLine + "NO\tINTIME"))
|
||||
return false;
|
||||
if (!sb.ToString().Contains("$FORMAT"))
|
||||
return false;
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
return "Not implemented";
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0001 01:25:59:21 01:26:00:20 0 0 BK02-total_0001.png 0 0
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line;
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split('\t');
|
||||
if (temp.Length > 7)
|
||||
{
|
||||
string start = temp[1];
|
||||
string end = temp[2];
|
||||
string text = temp[5];
|
||||
try
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(start.Split(':')), DecodeTimeCode(end.Split(':')), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.StartsWith("$DROP="))
|
||||
{
|
||||
s = s.Remove(0, "$DROP=".Length);
|
||||
int frameRate;
|
||||
if (int.TryParse(s, out frameRate))
|
||||
{
|
||||
double f = frameRate / TimeCode.BaseUnit;
|
||||
if (f > 10 && f < 500)
|
||||
Configuration.Settings.General.CurrentFrameRate = f;
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith('$'))
|
||||
{
|
||||
// skip empty lines or lines starting with $
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Dost : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".dost"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "DOST"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (!sb.ToString().Contains(Environment.NewLine + "NO\tINTIME"))
|
||||
return false;
|
||||
if (!sb.ToString().Contains("$FORMAT"))
|
||||
return false;
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
return "Not implemented";
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0001 01:25:59:21 01:26:00:20 0 0 BK02-total_0001.png 0 0
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line;
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split('\t');
|
||||
if (temp.Length > 7)
|
||||
{
|
||||
string start = temp[1];
|
||||
string end = temp[2];
|
||||
string text = temp[5];
|
||||
try
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(start.Split(':')), DecodeTimeCodeFrames(end.Split(':')), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.StartsWith("$DROP="))
|
||||
{
|
||||
s = s.Remove(0, "$DROP=".Length);
|
||||
int frameRate;
|
||||
if (int.TryParse(s, out frameRate))
|
||||
{
|
||||
double f = frameRate / TimeCode.BaseUnit;
|
||||
if (f > 10 && f < 500)
|
||||
Configuration.Settings.General.CurrentFrameRate = f;
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith('$'))
|
||||
{
|
||||
// skip empty lines or lines starting with $
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,93 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class DvdSubtitleSystem : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "DVD Subtitle System"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains("#INPOINT OUTPOINT PATH"))
|
||||
return false; // Pinnacle Impression
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
sb.AppendLine(string.Format("{0} {1} {2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text.Replace(Environment.NewLine, "//"), true)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is ms div 10)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
var p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount += 10;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class DvdSubtitleSystem : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "DVD Subtitle System"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains("#INPOINT OUTPOINT PATH"))
|
||||
return false; // Pinnacle Impression
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
sb.AppendLine(string.Format("{0} {1} {2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text.Replace(Environment.NewLine, "//"), true)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is ms div 10)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(12, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
var p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount += 10;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,117 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Eeg708 : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "EEG 708"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > 0;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string xmlStructure =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
|
||||
"<EEG708Captions/>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("Caption");
|
||||
XmlAttribute start = xml.CreateAttribute("timecode");
|
||||
start.InnerText = EncodeTimeCode(p.StartTime);
|
||||
paragraph.Attributes.Append(start);
|
||||
XmlNode text = xml.CreateElement("Text");
|
||||
text.InnerText = p.Text;
|
||||
paragraph.AppendChild(text);
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
|
||||
paragraph = xml.CreateElement("Caption");
|
||||
start = xml.CreateAttribute("timecode");
|
||||
start.InnerText = EncodeTimeCode(p.EndTime);
|
||||
paragraph.Attributes.Append(start);
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
}
|
||||
|
||||
return ToUtf8XmlString(xml);
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
|
||||
string allText = sb.ToString();
|
||||
if (!allText.Contains("<EEG708Captions") || !allText.Contains("<Caption"))
|
||||
return;
|
||||
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
xml.LoadXml(allText);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
Paragraph lastParagraph = null;
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("Caption"))
|
||||
{
|
||||
try
|
||||
{
|
||||
string start = node.Attributes["timecode"].InnerText;
|
||||
if (lastParagraph != null)
|
||||
lastParagraph.EndTime = DecodeTimeCode(start.Split(':'));
|
||||
XmlNode text = node.SelectSingleNode("Text");
|
||||
if (text != null)
|
||||
{
|
||||
string s = text.InnerText;
|
||||
s = s.Replace("<br />", Environment.NewLine).Replace("<br/>", Environment.NewLine);
|
||||
TimeCode startTime = DecodeTimeCode(start.Split(':'));
|
||||
lastParagraph = new Paragraph(s, startTime.TotalMilliseconds, startTime.TotalMilliseconds + 3000);
|
||||
subtitle.Paragraphs.Add(lastParagraph);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Eeg708 : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "EEG 708"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > 0;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string xmlStructure =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
|
||||
"<EEG708Captions/>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("Caption");
|
||||
XmlAttribute start = xml.CreateAttribute("timecode");
|
||||
start.InnerText = EncodeTimeCode(p.StartTime);
|
||||
paragraph.Attributes.Append(start);
|
||||
XmlNode text = xml.CreateElement("Text");
|
||||
text.InnerText = p.Text;
|
||||
paragraph.AppendChild(text);
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
|
||||
paragraph = xml.CreateElement("Caption");
|
||||
start = xml.CreateAttribute("timecode");
|
||||
start.InnerText = EncodeTimeCode(p.EndTime);
|
||||
paragraph.Attributes.Append(start);
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
}
|
||||
|
||||
return ToUtf8XmlString(xml);
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
|
||||
string allText = sb.ToString();
|
||||
if (!allText.Contains("<EEG708Captions") || !allText.Contains("<Caption"))
|
||||
return;
|
||||
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
xml.LoadXml(allText);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
Paragraph lastParagraph = null;
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("Caption"))
|
||||
{
|
||||
try
|
||||
{
|
||||
string start = node.Attributes["timecode"].InnerText;
|
||||
if (lastParagraph != null)
|
||||
lastParagraph.EndTime = DecodeTimeCodeFrames(start.Split(':'));
|
||||
XmlNode text = node.SelectSingleNode("Text");
|
||||
if (text != null)
|
||||
{
|
||||
string s = text.InnerText;
|
||||
s = s.Replace("<br />", Environment.NewLine).Replace("<br/>", Environment.NewLine);
|
||||
TimeCode startTime = DecodeTimeCodeFrames(start.Split(':'));
|
||||
lastParagraph = new Paragraph(s, startTime.TotalMilliseconds, startTime.TotalMilliseconds + 3000);
|
||||
subtitle.Paragraphs.Add(lastParagraph);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,95 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class FabSubtitler : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex regexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "FAB Subtitler"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
const string writeFormat = "{0} {1}{2}{3}{2}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:50:34:22 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
sb.AppendLine(string.Format(writeFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text)));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:50:39:13 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, regexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(13, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class FabSubtitler : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex regexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "FAB Subtitler"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
const string writeFormat = "{0} {1}{2}{3}{2}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:50:34:22 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
sb.AppendLine(string.Format(writeFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text)));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:50:39:13 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, regexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(0, 11);
|
||||
string end = temp.Substring(13, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,164 +1,164 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class FilmEditXml : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Film Edit xml"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
string xmlAsString = sb.ToString().Trim();
|
||||
if (xmlAsString.Contains("</filmeditxml>") && xmlAsString.Contains("</subtitle>"))
|
||||
{
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
xml.LoadXml(xmlAsString);
|
||||
var paragraphs = xml.DocumentElement.SelectNodes("subtitle");
|
||||
return paragraphs != null && paragraphs.Count > 0 && xml.DocumentElement.Name == "filmeditxml";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string xmlStructure =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
|
||||
"<filmeditxml>" + Environment.NewLine +
|
||||
"<font>Arial</font>" + Environment.NewLine +
|
||||
"<points>22</points>" + Environment.NewLine +
|
||||
"<width>720</width>" + Environment.NewLine +
|
||||
"<height>576</height>" + Environment.NewLine +
|
||||
"<virtualwidth>586</virtualwidth>" + Environment.NewLine +
|
||||
"<virtualheight>330</virtualheight>" + Environment.NewLine +
|
||||
"<par>1420</par>" + Environment.NewLine +
|
||||
"<fps>25</fps>" + Environment.NewLine +
|
||||
"<dropped>False</dropped>" + Environment.NewLine +
|
||||
"</filmeditxml>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
XmlNode div = xml.DocumentElement;
|
||||
int no = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("subtitle");
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
|
||||
XmlNode num = xml.CreateElement("num");
|
||||
num.InnerText = no.ToString();
|
||||
paragraph.AppendChild(num);
|
||||
|
||||
XmlNode dur = xml.CreateElement("dur");
|
||||
num.InnerText = EncodeDuration(p.Duration);
|
||||
paragraph.AppendChild(num);
|
||||
|
||||
XmlNode textNode = xml.CreateElement("text");
|
||||
textNode.InnerText = p.Text.Replace(Environment.NewLine, "\\N");
|
||||
paragraph.AppendChild(textNode);
|
||||
|
||||
XmlNode timeIn = xml.CreateElement("in");
|
||||
timeIn.InnerText = EncodeTimeCode(p.StartTime);
|
||||
paragraph.AppendChild(timeIn);
|
||||
|
||||
XmlNode timeOut = xml.CreateElement("out");
|
||||
timeOut.InnerText = EncodeTimeCode(p.EndTime);
|
||||
paragraph.AppendChild(timeOut);
|
||||
|
||||
XmlNode align = xml.CreateElement("align");
|
||||
align.InnerText = "C";
|
||||
paragraph.AppendChild(align);
|
||||
|
||||
XmlNode posx = xml.CreateElement("posx");
|
||||
posx.InnerText = "0";
|
||||
paragraph.AppendChild(posx);
|
||||
|
||||
XmlNode post = xml.CreateElement("posy");
|
||||
post.InnerText = "308";
|
||||
paragraph.AppendChild(post);
|
||||
|
||||
XmlNode memo = xml.CreateElement("memo");
|
||||
paragraph.AppendChild(memo);
|
||||
|
||||
div.AppendChild(paragraph);
|
||||
no++;
|
||||
}
|
||||
|
||||
return ToUtf8XmlString(xml);
|
||||
}
|
||||
|
||||
private static string EncodeDuration(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}", timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(sb.ToString().Trim());
|
||||
string lastKey = string.Empty;
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("subtitle"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var p = new Paragraph();
|
||||
foreach (XmlNode innerNode in node.ChildNodes)
|
||||
{
|
||||
switch (innerNode.Name)
|
||||
{
|
||||
case "text":
|
||||
p.Text = innerNode.InnerText.Replace("\\N", Environment.NewLine);
|
||||
break;
|
||||
case "in":
|
||||
p.StartTime = DecodeTimeCode(innerNode.InnerText, SplitCharColon);
|
||||
break;
|
||||
case "out":
|
||||
p.EndTime = DecodeTimeCode(innerNode.InnerText, SplitCharColon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p.StartTime.TotalSeconds >= 0 && p.EndTime.TotalMilliseconds > 0 && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class FilmEditXml : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Film Edit xml"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
string xmlAsString = sb.ToString().Trim();
|
||||
if (xmlAsString.Contains("</filmeditxml>") && xmlAsString.Contains("</subtitle>"))
|
||||
{
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
xml.LoadXml(xmlAsString);
|
||||
var paragraphs = xml.DocumentElement.SelectNodes("subtitle");
|
||||
return paragraphs != null && paragraphs.Count > 0 && xml.DocumentElement.Name == "filmeditxml";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string xmlStructure =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
|
||||
"<filmeditxml>" + Environment.NewLine +
|
||||
"<font>Arial</font>" + Environment.NewLine +
|
||||
"<points>22</points>" + Environment.NewLine +
|
||||
"<width>720</width>" + Environment.NewLine +
|
||||
"<height>576</height>" + Environment.NewLine +
|
||||
"<virtualwidth>586</virtualwidth>" + Environment.NewLine +
|
||||
"<virtualheight>330</virtualheight>" + Environment.NewLine +
|
||||
"<par>1420</par>" + Environment.NewLine +
|
||||
"<fps>25</fps>" + Environment.NewLine +
|
||||
"<dropped>False</dropped>" + Environment.NewLine +
|
||||
"</filmeditxml>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
XmlNode div = xml.DocumentElement;
|
||||
int no = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("subtitle");
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
|
||||
XmlNode num = xml.CreateElement("num");
|
||||
num.InnerText = no.ToString();
|
||||
paragraph.AppendChild(num);
|
||||
|
||||
XmlNode dur = xml.CreateElement("dur");
|
||||
num.InnerText = EncodeDuration(p.Duration);
|
||||
paragraph.AppendChild(num);
|
||||
|
||||
XmlNode textNode = xml.CreateElement("text");
|
||||
textNode.InnerText = p.Text.Replace(Environment.NewLine, "\\N");
|
||||
paragraph.AppendChild(textNode);
|
||||
|
||||
XmlNode timeIn = xml.CreateElement("in");
|
||||
timeIn.InnerText = EncodeTimeCode(p.StartTime);
|
||||
paragraph.AppendChild(timeIn);
|
||||
|
||||
XmlNode timeOut = xml.CreateElement("out");
|
||||
timeOut.InnerText = EncodeTimeCode(p.EndTime);
|
||||
paragraph.AppendChild(timeOut);
|
||||
|
||||
XmlNode align = xml.CreateElement("align");
|
||||
align.InnerText = "C";
|
||||
paragraph.AppendChild(align);
|
||||
|
||||
XmlNode posx = xml.CreateElement("posx");
|
||||
posx.InnerText = "0";
|
||||
paragraph.AppendChild(posx);
|
||||
|
||||
XmlNode post = xml.CreateElement("posy");
|
||||
post.InnerText = "308";
|
||||
paragraph.AppendChild(post);
|
||||
|
||||
XmlNode memo = xml.CreateElement("memo");
|
||||
paragraph.AppendChild(memo);
|
||||
|
||||
div.AppendChild(paragraph);
|
||||
no++;
|
||||
}
|
||||
|
||||
return ToUtf8XmlString(xml);
|
||||
}
|
||||
|
||||
private static string EncodeDuration(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}", timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(sb.ToString().Trim());
|
||||
string lastKey = string.Empty;
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("subtitle"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var p = new Paragraph();
|
||||
foreach (XmlNode innerNode in node.ChildNodes)
|
||||
{
|
||||
switch (innerNode.Name)
|
||||
{
|
||||
case "text":
|
||||
p.Text = innerNode.InnerText.Replace("\\N", Environment.NewLine);
|
||||
break;
|
||||
case "in":
|
||||
p.StartTime = DecodeTimeCodeFrames(innerNode.InnerText, SplitCharColon);
|
||||
break;
|
||||
case "out":
|
||||
p.EndTime = DecodeTimeCodeFrames(innerNode.InnerText, SplitCharColon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p.StartTime.TotalSeconds >= 0 && p.EndTime.TotalMilliseconds > 0 && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,129 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class ImageLogicAutocaption : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode1 = new Regex(@"^\s*\d+\t\d\d:\d\d:\d\d;\d\d", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Image Logic Autocaption"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00};{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#\tAppearance\tCaption\t");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}\t", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.StartTime), text));
|
||||
sb.AppendLine("\t\t\t\t");
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next == null || Math.Abs(p.EndTime.TotalMilliseconds - next.StartTime.TotalMilliseconds) > 50)
|
||||
{
|
||||
count++;
|
||||
sb.AppendLine(string.Format("{0}\t{1}", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.EndTime)));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf"))
|
||||
return;
|
||||
|
||||
lines = rtf.FromRtf().SplitToLines().ToList();
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode1.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length > 2)
|
||||
p = new Paragraph(DecodeTimeCode(arr[1], splitChars), new TimeCode(0, 0, 0, 0), arr[2].Trim());
|
||||
else
|
||||
p = new Paragraph(DecodeTimeCode(arr[1], splitChars), new TimeCode(0, 0, 0, 0), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (s.StartsWith("\t\t"))
|
||||
{
|
||||
if (p != null)
|
||||
p.Text = p.Text + Environment.NewLine + s.Trim();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
for (int j = 0; j < subtitle.Paragraphs.Count - 1; j++)
|
||||
{
|
||||
p = subtitle.Paragraphs[j];
|
||||
Paragraph next = subtitle.Paragraphs[j + 1];
|
||||
p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
p = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1];
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class ImageLogicAutocaption : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode1 = new Regex(@"^\s*\d+\t\d\d:\d\d:\d\d;\d\d", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Image Logic Autocaption"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00};{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#\tAppearance\tCaption\t");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}\t", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.StartTime), text));
|
||||
sb.AppendLine("\t\t\t\t");
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next == null || Math.Abs(p.EndTime.TotalMilliseconds - next.StartTime.TotalMilliseconds) > 50)
|
||||
{
|
||||
count++;
|
||||
sb.AppendLine(string.Format("{0}\t{1}", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.EndTime)));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf"))
|
||||
return;
|
||||
|
||||
lines = rtf.FromRtf().SplitToLines().ToList();
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode1.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length > 2)
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[1], splitChars), new TimeCode(0, 0, 0, 0), arr[2].Trim());
|
||||
else
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[1], splitChars), new TimeCode(0, 0, 0, 0), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (s.StartsWith("\t\t"))
|
||||
{
|
||||
if (p != null)
|
||||
p.Text = p.Text + Environment.NewLine + s.Trim();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
for (int j = 0; j < subtitle.Paragraphs.Count - 1; j++)
|
||||
{
|
||||
p = subtitle.Paragraphs[j];
|
||||
Paragraph next = subtitle.Paragraphs[j + 1];
|
||||
p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
p = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1];
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,217 +1,217 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class MacCaption : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".mcc"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "MacCaption 1.0"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"File Format=MacCaption_MCC V1.0
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Computer Prompting and Captioning Company
|
||||
// Ancillary Data Packet Transfer File
|
||||
//
|
||||
// Permission to generate this format is granted provided that
|
||||
// 1. This ANC Transfer file format is used on an as-is basis and no warranty is given, and
|
||||
// 2. This entire descriptive information text is included in a generated .mcc file.
|
||||
//
|
||||
// General file format:
|
||||
// HH:MM:SS:FF(tab)[Hexadecimal ANC data in groups of 2 characters]
|
||||
// Hexadecimal data starts with the Ancillary Data Packet DID (Data ID defined in S291M)
|
||||
// and concludes with the Check Sum following the User Data Words.
|
||||
// Each time code line must contain at most one complete ancillary data packet.
|
||||
// To transfer additional ANC Data successive lines may contain identical time code.
|
||||
// Time Code Rate=[24, 25, 30, 30DF, 50, 60]
|
||||
//
|
||||
// ANC data bytes may be represented by one ASCII character according to the following schema:
|
||||
// G FAh 00h 00h
|
||||
// H 2 x (FAh 00h 00h)
|
||||
// I 3 x (FAh 00h 00h)
|
||||
// J 4 x (FAh 00h 00h)
|
||||
// K 5 x (FAh 00h 00h)
|
||||
// L 6 x (FAh 00h 00h)
|
||||
// M 7 x (FAh 00h 00h)
|
||||
// N 8 x (FAh 00h 00h)
|
||||
// O 9 x (FAh 00h 00h)
|
||||
// P FBh 80h 80h
|
||||
// Q FCh 80h 80h
|
||||
// R FDh 80h 80h
|
||||
// S 96h 69h
|
||||
// T 61h 01h
|
||||
// U E1h 00h 00h
|
||||
// Z 00h
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("UUID=" + Guid.NewGuid().ToString().ToUpper());// UUID=9F6112F4-D9D0-4AAF-AA95-854710D3B57A
|
||||
sb.AppendLine("Creation Program=Subtitle Edit");
|
||||
sb.AppendLine("Creation Date=" + DateTime.Now.ToLongDateString());
|
||||
sb.AppendLine("Creation Time=" + DateTime.Now.ToShortTimeString());
|
||||
sb.AppendLine();
|
||||
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
sb.AppendLine(string.Format("{0}\t{1}", ToTimeCode(p.StartTime.TotalMilliseconds), p.Text)); // TODO: Encode text - how???
|
||||
sb.AppendLine();
|
||||
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next == null || Math.Abs(next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds) > 100)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0}\t???", ToTimeCode(p.EndTime.TotalMilliseconds))); // TODO: Some end text???
|
||||
sb.AppendLine();
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string ToTimeCode(double totalMilliseconds)
|
||||
{
|
||||
TimeSpan ts = TimeSpan.FromMilliseconds(totalMilliseconds);
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", ts.Hours, ts.Minutes, ts.Seconds, MillisecondsToFramesMaxFrameRate(ts.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var header = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
|
||||
if (s.StartsWith("//", StringComparison.Ordinal) || s.StartsWith("File Format=MacCaption_MCC", StringComparison.Ordinal) || s.StartsWith("UUID=", StringComparison.Ordinal) ||
|
||||
s.StartsWith("Creation Program=") || s.StartsWith("Creation Date=") || s.StartsWith("Creation Time=") ||
|
||||
s.StartsWith("Code Rate=", StringComparison.Ordinal) || s.StartsWith("Time Code Rate=", StringComparison.Ordinal) || string.IsNullOrEmpty(s))
|
||||
{
|
||||
header.AppendLine(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
TimeCode startTime = DecodeTimeCode(s.Substring(0, match.Length - 1), splitChars);
|
||||
string text = GetSccText(s.Substring(match.Index));
|
||||
|
||||
if (text == "942c 942c" || text == "942c")
|
||||
{
|
||||
p.EndTime = new TimeCode(startTime.TotalMilliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = new Paragraph(startTime, new TimeCode(startTime.TotalMilliseconds), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = subtitle.Paragraphs.Count - 2; i >= 0; i--)
|
||||
{
|
||||
p = subtitle.GetParagraphOrDefault(i);
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (p != null && next != null && p.EndTime.TotalMilliseconds == p.StartTime.TotalMilliseconds)
|
||||
p.EndTime = new TimeCode(next.StartTime.TotalMilliseconds);
|
||||
if (next != null && string.IsNullOrEmpty(next.Text))
|
||||
subtitle.Paragraphs.Remove(next);
|
||||
}
|
||||
p = subtitle.GetParagraphOrDefault(0);
|
||||
if (p != null && string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Remove(p);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
public static string GetSccText(string s)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var sb = new StringBuilder();
|
||||
foreach (string part in ExecuteReplacesAndGetParts(parts))
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: How to decode???
|
||||
int num = int.Parse(part, System.Globalization.NumberStyles.HexNumber);
|
||||
if (num >= 32 && num <= 255)
|
||||
{
|
||||
var encoding = Encoding.GetEncoding("ISO-8859-1");
|
||||
byte[] bytes = new byte[1];
|
||||
bytes[0] = (byte)num;
|
||||
sb.Append(encoding.GetString(bytes));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
string res = sb.ToString().Replace("<i></i>", string.Empty).Replace("</i><i>", string.Empty);
|
||||
res = res.Replace("♪♪", "♪");
|
||||
res = res.Replace("'''", "'");
|
||||
res = res.Replace(" ", " ").Replace(" ", " ").Replace(Environment.NewLine + " ", Environment.NewLine).Trim();
|
||||
return HtmlUtil.FixInvalidItalicTags(res);
|
||||
}
|
||||
|
||||
private static List<string> ExecuteReplacesAndGetParts(string[] parts)
|
||||
{
|
||||
var list = new List<string>();
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
string s = parts[1];
|
||||
s = s.Replace("G", "FA0000");
|
||||
s = s.Replace("H", "FA0000FA0000");
|
||||
s = s.Replace("I", "FA0000FA0000FA0000");
|
||||
s = s.Replace("J", "FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("K", "FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("L", "FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("M", "FA0000FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("N", "FA0000FA0000FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("O", "FA0000FA0000FA0000FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("P", "FB8080");
|
||||
s = s.Replace("Q", "FC8080");
|
||||
s = s.Replace("R", "FD80h80");
|
||||
s = s.Replace("S", "9669");
|
||||
s = s.Replace("T", "6101");
|
||||
s = s.Replace("U", "E10000");
|
||||
s = s.Replace("Z", "00");
|
||||
for (int i = 0; i < s.Length; i += 4)
|
||||
{
|
||||
string sub = s.Substring(i);
|
||||
if (sub.Length >= 2)
|
||||
list.Add(sub.Substring(0, 2));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class MacCaption : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".mcc"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "MacCaption 1.0"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"File Format=MacCaption_MCC V1.0
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Computer Prompting and Captioning Company
|
||||
// Ancillary Data Packet Transfer File
|
||||
//
|
||||
// Permission to generate this format is granted provided that
|
||||
// 1. This ANC Transfer file format is used on an as-is basis and no warranty is given, and
|
||||
// 2. This entire descriptive information text is included in a generated .mcc file.
|
||||
//
|
||||
// General file format:
|
||||
// HH:MM:SS:FF(tab)[Hexadecimal ANC data in groups of 2 characters]
|
||||
// Hexadecimal data starts with the Ancillary Data Packet DID (Data ID defined in S291M)
|
||||
// and concludes with the Check Sum following the User Data Words.
|
||||
// Each time code line must contain at most one complete ancillary data packet.
|
||||
// To transfer additional ANC Data successive lines may contain identical time code.
|
||||
// Time Code Rate=[24, 25, 30, 30DF, 50, 60]
|
||||
//
|
||||
// ANC data bytes may be represented by one ASCII character according to the following schema:
|
||||
// G FAh 00h 00h
|
||||
// H 2 x (FAh 00h 00h)
|
||||
// I 3 x (FAh 00h 00h)
|
||||
// J 4 x (FAh 00h 00h)
|
||||
// K 5 x (FAh 00h 00h)
|
||||
// L 6 x (FAh 00h 00h)
|
||||
// M 7 x (FAh 00h 00h)
|
||||
// N 8 x (FAh 00h 00h)
|
||||
// O 9 x (FAh 00h 00h)
|
||||
// P FBh 80h 80h
|
||||
// Q FCh 80h 80h
|
||||
// R FDh 80h 80h
|
||||
// S 96h 69h
|
||||
// T 61h 01h
|
||||
// U E1h 00h 00h
|
||||
// Z 00h
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("UUID=" + Guid.NewGuid().ToString().ToUpper());// UUID=9F6112F4-D9D0-4AAF-AA95-854710D3B57A
|
||||
sb.AppendLine("Creation Program=Subtitle Edit");
|
||||
sb.AppendLine("Creation Date=" + DateTime.Now.ToLongDateString());
|
||||
sb.AppendLine("Creation Time=" + DateTime.Now.ToShortTimeString());
|
||||
sb.AppendLine();
|
||||
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
sb.AppendLine(string.Format("{0}\t{1}", ToTimeCode(p.StartTime.TotalMilliseconds), p.Text)); // TODO: Encode text - how???
|
||||
sb.AppendLine();
|
||||
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next == null || Math.Abs(next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds) > 100)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0}\t???", ToTimeCode(p.EndTime.TotalMilliseconds))); // TODO: Some end text???
|
||||
sb.AppendLine();
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string ToTimeCode(double totalMilliseconds)
|
||||
{
|
||||
TimeSpan ts = TimeSpan.FromMilliseconds(totalMilliseconds);
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", ts.Hours, ts.Minutes, ts.Seconds, MillisecondsToFramesMaxFrameRate(ts.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var header = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
|
||||
if (s.StartsWith("//", StringComparison.Ordinal) || s.StartsWith("File Format=MacCaption_MCC", StringComparison.Ordinal) || s.StartsWith("UUID=", StringComparison.Ordinal) ||
|
||||
s.StartsWith("Creation Program=") || s.StartsWith("Creation Date=") || s.StartsWith("Creation Time=") ||
|
||||
s.StartsWith("Code Rate=", StringComparison.Ordinal) || s.StartsWith("Time Code Rate=", StringComparison.Ordinal) || string.IsNullOrEmpty(s))
|
||||
{
|
||||
header.AppendLine(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
TimeCode startTime = DecodeTimeCodeFrames(s.Substring(0, match.Length - 1), splitChars);
|
||||
string text = GetSccText(s.Substring(match.Index));
|
||||
|
||||
if (text == "942c 942c" || text == "942c")
|
||||
{
|
||||
p.EndTime = new TimeCode(startTime.TotalMilliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = new Paragraph(startTime, new TimeCode(startTime.TotalMilliseconds), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = subtitle.Paragraphs.Count - 2; i >= 0; i--)
|
||||
{
|
||||
p = subtitle.GetParagraphOrDefault(i);
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (p != null && next != null && p.EndTime.TotalMilliseconds == p.StartTime.TotalMilliseconds)
|
||||
p.EndTime = new TimeCode(next.StartTime.TotalMilliseconds);
|
||||
if (next != null && string.IsNullOrEmpty(next.Text))
|
||||
subtitle.Paragraphs.Remove(next);
|
||||
}
|
||||
p = subtitle.GetParagraphOrDefault(0);
|
||||
if (p != null && string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Remove(p);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
public static string GetSccText(string s)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var sb = new StringBuilder();
|
||||
foreach (string part in ExecuteReplacesAndGetParts(parts))
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: How to decode???
|
||||
int num = int.Parse(part, System.Globalization.NumberStyles.HexNumber);
|
||||
if (num >= 32 && num <= 255)
|
||||
{
|
||||
var encoding = Encoding.GetEncoding("ISO-8859-1");
|
||||
byte[] bytes = new byte[1];
|
||||
bytes[0] = (byte)num;
|
||||
sb.Append(encoding.GetString(bytes));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
string res = sb.ToString().Replace("<i></i>", string.Empty).Replace("</i><i>", string.Empty);
|
||||
res = res.Replace("♪♪", "♪");
|
||||
res = res.Replace("'''", "'");
|
||||
res = res.Replace(" ", " ").Replace(" ", " ").Replace(Environment.NewLine + " ", Environment.NewLine).Trim();
|
||||
return HtmlUtil.FixInvalidItalicTags(res);
|
||||
}
|
||||
|
||||
private static List<string> ExecuteReplacesAndGetParts(string[] parts)
|
||||
{
|
||||
var list = new List<string>();
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
string s = parts[1];
|
||||
s = s.Replace("G", "FA0000");
|
||||
s = s.Replace("H", "FA0000FA0000");
|
||||
s = s.Replace("I", "FA0000FA0000FA0000");
|
||||
s = s.Replace("J", "FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("K", "FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("L", "FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("M", "FA0000FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("N", "FA0000FA0000FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("O", "FA0000FA0000FA0000FA0000FA0000FA0000FA0000FA0000FA0000");
|
||||
s = s.Replace("P", "FB8080");
|
||||
s = s.Replace("Q", "FC8080");
|
||||
s = s.Replace("R", "FD80h80");
|
||||
s = s.Replace("S", "9669");
|
||||
s = s.Replace("T", "6101");
|
||||
s = s.Replace("U", "E10000");
|
||||
s = s.Replace("Z", "00");
|
||||
for (int i = 0; i < s.Length; i += 4)
|
||||
{
|
||||
string sub = s.Substring(i);
|
||||
if (sub.Length >= 2)
|
||||
list.Add(sub.Substring(0, 2));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,102 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class MidwayInscriberCGX : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex regexTimeCodes = new Regex(@"<\d\d:\d\d:\d\d:\d\d> <\d\d:\d\d:\d\d:\d\d>$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Midway Inscriber CG-X"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string writeFormat = "{3} <{0}> <{1}>{2}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(writeFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
//Var vi bedre end japanerne
|
||||
//eller bare mere heldige? <12:03:29:03> <12:03:35:06>
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:50:39:13 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.Append(line);
|
||||
if (!sb.ToString().Contains("> <"))
|
||||
return;
|
||||
|
||||
//Var vi bedre end japanerne
|
||||
//eller bare mere heldige? <12:03:29:03> <12:03:35:06>
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
sb.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line))
|
||||
{
|
||||
int idx = regexTimeCodes.Match(line).Index;
|
||||
string temp = line.Substring(0, idx).Trim();
|
||||
sb.AppendLine(temp);
|
||||
|
||||
string start = line.Substring(idx + 1, 11);
|
||||
string end = line.Substring(idx + 15, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
var p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), sb.ToString().Trim());
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line.Trim());
|
||||
}
|
||||
}
|
||||
if (sb.Length > 1000)
|
||||
return;
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class MidwayInscriberCGX : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex regexTimeCodes = new Regex(@"<\d\d:\d\d:\d\d:\d\d> <\d\d:\d\d:\d\d:\d\d>$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Midway Inscriber CG-X"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string writeFormat = "{3} <{0}> <{1}>{2}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(writeFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
//Var vi bedre end japanerne
|
||||
//eller bare mere heldige? <12:03:29:03> <12:03:35:06>
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:50:39:13 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.Append(line);
|
||||
if (!sb.ToString().Contains("> <"))
|
||||
return;
|
||||
|
||||
//Var vi bedre end japanerne
|
||||
//eller bare mere heldige? <12:03:29:03> <12:03:35:06>
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
sb.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line))
|
||||
{
|
||||
int idx = regexTimeCodes.Match(line).Index;
|
||||
string temp = line.Substring(0, idx).Trim();
|
||||
sb.AppendLine(temp);
|
||||
|
||||
string start = line.Substring(idx + 1, 11);
|
||||
string end = line.Substring(idx + 15, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
var p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), sb.ToString().Trim());
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line.Trim());
|
||||
}
|
||||
}
|
||||
if (sb.Length > 1000)
|
||||
return;
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,124 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Oresme : SubtitleFormat
|
||||
{
|
||||
//00:00:00:00{BC}{W2710}
|
||||
//10:00:00:15{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}
|
||||
//10:00:17:06{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}We view
|
||||
//10:00:19:06{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}Lufa Farms as{N}an agrotechnology business
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d\{", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Oresme"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}{1}{2}";
|
||||
const string tags = "{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("00:00:00:00{BC}{W2710}");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text, true);
|
||||
text = text.Replace(Environment.NewLine, "{N}");
|
||||
sb.AppendLine(string.Format(format, EncodeTimeCode(p.StartTime), tags, text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
var p = new Paragraph();
|
||||
try
|
||||
{
|
||||
p.StartTime = DecodeTimeCode(s.Substring(0, 11), splitChars);
|
||||
p.Text = GetText(line.Remove(0, 11));
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++)
|
||||
{
|
||||
var p2 = subtitle.Paragraphs[i];
|
||||
var next = subtitle.Paragraphs[i + 1];
|
||||
p2.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].EndTime.TotalMilliseconds = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].StartTime.TotalMilliseconds +
|
||||
Utilities.GetOptimalDisplayMilliseconds(subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].Text);
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string GetText(string s)
|
||||
{
|
||||
s = s.Replace("{N}", Environment.NewLine);
|
||||
var sb = new StringBuilder();
|
||||
bool tagOn = false;
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
if (s[i] == '{')
|
||||
tagOn = true;
|
||||
else if (s[i] == '}')
|
||||
tagOn = false;
|
||||
else if (!tagOn)
|
||||
sb.Append(s[i]);
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Oresme : SubtitleFormat
|
||||
{
|
||||
//00:00:00:00{BC}{W2710}
|
||||
//10:00:00:15{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}
|
||||
//10:00:17:06{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}We view
|
||||
//10:00:19:06{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}Lufa Farms as{N}an agrotechnology business
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d\{", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Oresme"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}{1}{2}";
|
||||
const string tags = "{Bottom}{Open Caption}{Center}{White}{Font Arial GVP Bold}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("00:00:00:00{BC}{W2710}");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text, true);
|
||||
text = text.Replace(Environment.NewLine, "{N}");
|
||||
sb.AppendLine(string.Format(format, EncodeTimeCode(p.StartTime), tags, text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
var p = new Paragraph();
|
||||
try
|
||||
{
|
||||
p.StartTime = DecodeTimeCodeFrames(s.Substring(0, 11), splitChars);
|
||||
p.Text = GetText(line.Remove(0, 11));
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++)
|
||||
{
|
||||
var p2 = subtitle.Paragraphs[i];
|
||||
var next = subtitle.Paragraphs[i + 1];
|
||||
p2.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].EndTime.TotalMilliseconds = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].StartTime.TotalMilliseconds +
|
||||
Utilities.GetOptimalDisplayMilliseconds(subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].Text);
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string GetText(string s)
|
||||
{
|
||||
s = s.Replace("{N}", Environment.NewLine);
|
||||
var sb = new StringBuilder();
|
||||
bool tagOn = false;
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
if (s[i] == '{')
|
||||
tagOn = true;
|
||||
else if (s[i] == '}')
|
||||
tagOn = false;
|
||||
else if (!tagOn)
|
||||
sb.Append(s[i]);
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,282 +1,282 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class OresmeDocXDocument : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Oresme Docx document"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
string xmlAsString = sb.ToString().Trim();
|
||||
if ((xmlAsString.Contains("<w:tc>")))
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private const string Layout = @"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
|
||||
<w:document xmlns:wpc='http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas' xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006' xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:r='http://schemas.openxmlformats.org/officeDocument/2006/relationships' xmlns:m='http://schemas.openxmlformats.org/officeDocument/2006/math' xmlns:v='urn:schemas-microsoft-com:vml' xmlns:wp14='http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing' xmlns:wp='http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing' xmlns:w10='urn:schemas-microsoft-com:office:word' xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' xmlns:w14='http://schemas.microsoft.com/office/word/2010/wordml' xmlns:wpg='http://schemas.microsoft.com/office/word/2010/wordprocessingGroup' xmlns:wpi='http://schemas.microsoft.com/office/word/2010/wordprocessingInk' xmlns:wne='http://schemas.microsoft.com/office/word/2006/wordml' xmlns:wps='http://schemas.microsoft.com/office/word/2010/wordprocessingShape' mc:Ignorable='w14 wp14'>
|
||||
<w:body>
|
||||
<w:tbl>
|
||||
<w:tblPr>
|
||||
<w:tblW w:w='0' w:type='auto'/>
|
||||
<w:tblBorders>
|
||||
<w:top w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:left w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:bottom w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:right w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:insideH w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:insideV w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
</w:tblBorders>
|
||||
<w:tblLayout w:type='fixed'/>
|
||||
<w:tblCellMar>
|
||||
<w:left w:w='70' w:type='dxa'/>
|
||||
<w:right w:w='70' w:type='dxa'/>
|
||||
</w:tblCellMar>
|
||||
<w:tblLook w:val='0000' w:firstRow='0' w:lastRow='0' w:firstColumn='0' w:lastColumn='0' w:noHBand='0' w:noVBand='0'/>
|
||||
</w:tblPr>
|
||||
<w:tblGrid>
|
||||
<w:gridCol w:w='1240'/>
|
||||
<w:gridCol w:w='5560'/>
|
||||
</w:tblGrid>
|
||||
</w:tbl>
|
||||
<w:p w:rsidR='00D56C9E' w:rsidRDefault='00D56C9E'/>
|
||||
<w:sectPr w:rsidR='00D56C9E'>
|
||||
<w:pgSz w:w='12240' w:h='15840'/>
|
||||
<w:pgMar w:top='1440' w:right='1440' w:bottom='1440' w:left='1440' w:header='720' w:footer='720' w:gutter='0'/>
|
||||
<w:cols w:space='720'/>
|
||||
</w:sectPr>
|
||||
</w:body>
|
||||
</w:document>";
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string xmlStructure = Layout.Replace("'", "\"");
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
var nsmgr = new XmlNamespaceManager(xml.NameTable);
|
||||
nsmgr.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
XmlNode div = xml.DocumentElement.SelectSingleNode("w:body/w:tbl", nsmgr);
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
div.AppendChild(CreateXmlParagraph(xml, p));
|
||||
|
||||
if (i < subtitle.Paragraphs.Count - 1 && Math.Abs(p.EndTime.TotalMilliseconds - subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds) > 100)
|
||||
{
|
||||
var endP = new Paragraph(string.Empty, p.EndTime.TotalMilliseconds, 0);
|
||||
div.AppendChild(CreateXmlParagraph(xml, endP));
|
||||
}
|
||||
}
|
||||
|
||||
string s = ToUtf8XmlString(xml);
|
||||
return s;
|
||||
}
|
||||
|
||||
private static XmlNode CreateXmlParagraph(XmlDocument xml, Paragraph p)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("w:tr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var tc1 = xml.CreateElement("w:tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
paragraph.AppendChild(tc1);
|
||||
|
||||
//<w:tcPr>
|
||||
// <w:tcW w:w='1240' w:type='dxa'/>
|
||||
//</w:tcPr>
|
||||
var n1 = xml.CreateElement("w:tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n1sub = xml.CreateElement("w:tcW", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); // <w:tcW w:w='1240' w:type='dxa'/>
|
||||
n1.AppendChild(n1sub);
|
||||
var n1suba1 = xml.CreateAttribute("w:w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1suba1.InnerText = "1240";
|
||||
n1sub.Attributes.Append(n1suba1);
|
||||
var n1suba2 = xml.CreateAttribute("w:type", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1suba2.InnerText = "dxa";
|
||||
n1sub.Attributes.Append(n1suba2);
|
||||
tc1.AppendChild(n1);
|
||||
|
||||
//<w:p w:rsidR='00D56C9E' w:rsidRDefault='00D56C9E'>
|
||||
// <w:pPr>
|
||||
// <w:pStyle w:val='TimeCode'/>
|
||||
// </w:pPr>
|
||||
// <w:r>
|
||||
// <w:t>[TIMECODE]</w:t>
|
||||
// </w:r>
|
||||
//</w:p>
|
||||
var n2 = xml.CreateElement("w:p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n1a1 = xml.CreateAttribute("w:rsidR", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1a1.InnerText = "00D56C9E";
|
||||
n2.Attributes.Append(n1a1);
|
||||
var n1a2 = xml.CreateAttribute("w:rsidRDefault", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1a2.InnerText = "00D56C9E";
|
||||
n2.Attributes.Append(n1a2);
|
||||
|
||||
var n2sub1 = xml.CreateElement("w:pPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n2sub1sub = xml.CreateElement("w:pStyle", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n2sub1.AppendChild(n2sub1sub);
|
||||
var n2sub1Suba1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n2sub1Suba1.InnerText = "TimeCode";
|
||||
n2sub1sub.Attributes.Append(n2sub1Suba1);
|
||||
n2.AppendChild(n2sub1);
|
||||
|
||||
var n2sub2 = xml.CreateElement("w:r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n2sub2sub = xml.CreateElement("w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n2sub2sub.InnerText = ToTimeCode(p.StartTime);
|
||||
n2sub2.AppendChild(n2sub2sub);
|
||||
n2.AppendChild(n2sub2);
|
||||
tc1.AppendChild(n2);
|
||||
|
||||
//<w:tc>
|
||||
// <w:tcPr>
|
||||
// <w:tcW w:w='5560' w:type='dxa'/>
|
||||
// <w:vAlign w:val='bottom'/>
|
||||
// </w:tcPr>
|
||||
// <w:p w:rsidR='00D56C9E' w:rsidRDefault='00D56C9E'>
|
||||
// <w:pPr>
|
||||
// <w:pStyle w:val='PopOn'/>
|
||||
// </w:pPr>
|
||||
// <w:proofErr w:type='spellStart'/>
|
||||
// </w:p>
|
||||
//</w:tc>
|
||||
var tc2 = xml.CreateElement("w:tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
paragraph.AppendChild(tc2);
|
||||
|
||||
var n3sub1 = xml.CreateElement("w:tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
tc2.AppendChild(n3sub1);
|
||||
|
||||
var n3sub1sub1 = xml.CreateElement("w:tcW", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3suba1 = xml.CreateAttribute("w:w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3suba1.InnerText = "5560";
|
||||
n3sub1sub1.Attributes.Append(n3suba1);
|
||||
var n3suba2 = xml.CreateAttribute("w:type", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3suba2.InnerText = "dxa";
|
||||
n3sub1sub1.Attributes.Append(n3suba2);
|
||||
n3sub1.AppendChild(n3sub1sub1);
|
||||
|
||||
var n3sub1sub2 = xml.CreateElement("w:vAlign", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3sub1sub2a1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub2a1.InnerText = "bottom";
|
||||
n3sub1sub2.Attributes.Append(n3sub1sub2a1);
|
||||
n3sub1.AppendChild(n3sub1sub2);
|
||||
|
||||
var n3sub1sub3 = xml.CreateElement("w:p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3sub1sub3a1 = xml.CreateAttribute("w:rsidR", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3a1.InnerText = "00D56C9E";
|
||||
n3sub1sub3.Attributes.Append(n3sub1sub3a1);
|
||||
var n3sub1sub3a2 = xml.CreateAttribute("w:rsidRDefault", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3a2.InnerText = "00D56C9E";
|
||||
n3sub1sub3.Attributes.Append(n3sub1sub3a2);
|
||||
var n3sub1sub3sub1 = xml.CreateElement("w:pPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3.AppendChild(n3sub1sub3sub1);
|
||||
var n3sub1sub3sub1sub = xml.CreateElement("w:pStyle", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3sub1sub3sub1suba1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3sub1suba1.InnerText = "PopOn";
|
||||
n3sub1sub3sub1sub.Attributes.Append(n3sub1sub3sub1suba1);
|
||||
n3sub1sub3sub1.AppendChild(n3sub1sub3sub1sub);
|
||||
|
||||
var lines = HtmlUtil.RemoveHtmlTags(p.Text, true).Replace(Environment.NewLine, "\n").Split('\n');
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
var n3sub1sub3sub2 = xml.CreateElement("w:r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3.AppendChild(n3sub1sub3sub2);
|
||||
if (i > 0)
|
||||
{
|
||||
var lineBreak = xml.CreateElement("w:br", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3sub2.AppendChild(lineBreak);
|
||||
}
|
||||
var text = xml.CreateElement("w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
text.InnerText = lines[i];
|
||||
n3sub1sub3sub2.AppendChild(text);
|
||||
}
|
||||
tc2.AppendChild(n3sub1sub3);
|
||||
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
private static string ToTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return timeCode.ToHHMMSSFF(); //10:00:07:27
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(sb.ToString().Trim());
|
||||
var nsmgr = new XmlNamespaceManager(xml.NameTable);
|
||||
nsmgr.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("//w:tr", nsmgr))
|
||||
{
|
||||
try
|
||||
{
|
||||
Paragraph p = new Paragraph();
|
||||
XmlNode t = node.SelectSingleNode("w:tc/w:p/w:r/w:t", nsmgr);
|
||||
if (t != null)
|
||||
{
|
||||
p.StartTime = DecodeTimeCode(t.InnerText.Trim(), SplitCharColon);
|
||||
sb = new StringBuilder();
|
||||
foreach (XmlNode wrNode in node.SelectNodes("w:tc/w:p/w:r", nsmgr))
|
||||
{
|
||||
foreach (XmlNode child in wrNode.ChildNodes)
|
||||
{
|
||||
if (child.Name == "w:t")
|
||||
{
|
||||
bool isTimeCode = child.InnerText.Length == 11 && child.InnerText.Replace(":", string.Empty).Length == 8;
|
||||
if (!isTimeCode)
|
||||
sb.Append(child.InnerText);
|
||||
}
|
||||
else if (child.Name == "w:br")
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
p.Text = sb.ToString();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++)
|
||||
{
|
||||
subtitle.Paragraphs[i].EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds;
|
||||
}
|
||||
subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].EndTime.TotalMilliseconds = 2500;
|
||||
subtitle.RemoveEmptyLines();
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++)
|
||||
{
|
||||
if (subtitle.Paragraphs[i].EndTime.TotalMilliseconds == subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds)
|
||||
subtitle.Paragraphs[i].EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class OresmeDocXDocument : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Oresme Docx document"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
string xmlAsString = sb.ToString().Trim();
|
||||
if ((xmlAsString.Contains("<w:tc>")))
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private const string Layout = @"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
|
||||
<w:document xmlns:wpc='http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas' xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006' xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:r='http://schemas.openxmlformats.org/officeDocument/2006/relationships' xmlns:m='http://schemas.openxmlformats.org/officeDocument/2006/math' xmlns:v='urn:schemas-microsoft-com:vml' xmlns:wp14='http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing' xmlns:wp='http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing' xmlns:w10='urn:schemas-microsoft-com:office:word' xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' xmlns:w14='http://schemas.microsoft.com/office/word/2010/wordml' xmlns:wpg='http://schemas.microsoft.com/office/word/2010/wordprocessingGroup' xmlns:wpi='http://schemas.microsoft.com/office/word/2010/wordprocessingInk' xmlns:wne='http://schemas.microsoft.com/office/word/2006/wordml' xmlns:wps='http://schemas.microsoft.com/office/word/2010/wordprocessingShape' mc:Ignorable='w14 wp14'>
|
||||
<w:body>
|
||||
<w:tbl>
|
||||
<w:tblPr>
|
||||
<w:tblW w:w='0' w:type='auto'/>
|
||||
<w:tblBorders>
|
||||
<w:top w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:left w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:bottom w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:right w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:insideH w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
<w:insideV w:val='single' w:sz='4' w:space='0' w:color='FFCC00'/>
|
||||
</w:tblBorders>
|
||||
<w:tblLayout w:type='fixed'/>
|
||||
<w:tblCellMar>
|
||||
<w:left w:w='70' w:type='dxa'/>
|
||||
<w:right w:w='70' w:type='dxa'/>
|
||||
</w:tblCellMar>
|
||||
<w:tblLook w:val='0000' w:firstRow='0' w:lastRow='0' w:firstColumn='0' w:lastColumn='0' w:noHBand='0' w:noVBand='0'/>
|
||||
</w:tblPr>
|
||||
<w:tblGrid>
|
||||
<w:gridCol w:w='1240'/>
|
||||
<w:gridCol w:w='5560'/>
|
||||
</w:tblGrid>
|
||||
</w:tbl>
|
||||
<w:p w:rsidR='00D56C9E' w:rsidRDefault='00D56C9E'/>
|
||||
<w:sectPr w:rsidR='00D56C9E'>
|
||||
<w:pgSz w:w='12240' w:h='15840'/>
|
||||
<w:pgMar w:top='1440' w:right='1440' w:bottom='1440' w:left='1440' w:header='720' w:footer='720' w:gutter='0'/>
|
||||
<w:cols w:space='720'/>
|
||||
</w:sectPr>
|
||||
</w:body>
|
||||
</w:document>";
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string xmlStructure = Layout.Replace("'", "\"");
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
var nsmgr = new XmlNamespaceManager(xml.NameTable);
|
||||
nsmgr.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
XmlNode div = xml.DocumentElement.SelectSingleNode("w:body/w:tbl", nsmgr);
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
div.AppendChild(CreateXmlParagraph(xml, p));
|
||||
|
||||
if (i < subtitle.Paragraphs.Count - 1 && Math.Abs(p.EndTime.TotalMilliseconds - subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds) > 100)
|
||||
{
|
||||
var endP = new Paragraph(string.Empty, p.EndTime.TotalMilliseconds, 0);
|
||||
div.AppendChild(CreateXmlParagraph(xml, endP));
|
||||
}
|
||||
}
|
||||
|
||||
string s = ToUtf8XmlString(xml);
|
||||
return s;
|
||||
}
|
||||
|
||||
private static XmlNode CreateXmlParagraph(XmlDocument xml, Paragraph p)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("w:tr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var tc1 = xml.CreateElement("w:tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
paragraph.AppendChild(tc1);
|
||||
|
||||
//<w:tcPr>
|
||||
// <w:tcW w:w='1240' w:type='dxa'/>
|
||||
//</w:tcPr>
|
||||
var n1 = xml.CreateElement("w:tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n1sub = xml.CreateElement("w:tcW", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); // <w:tcW w:w='1240' w:type='dxa'/>
|
||||
n1.AppendChild(n1sub);
|
||||
var n1suba1 = xml.CreateAttribute("w:w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1suba1.InnerText = "1240";
|
||||
n1sub.Attributes.Append(n1suba1);
|
||||
var n1suba2 = xml.CreateAttribute("w:type", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1suba2.InnerText = "dxa";
|
||||
n1sub.Attributes.Append(n1suba2);
|
||||
tc1.AppendChild(n1);
|
||||
|
||||
//<w:p w:rsidR='00D56C9E' w:rsidRDefault='00D56C9E'>
|
||||
// <w:pPr>
|
||||
// <w:pStyle w:val='TimeCode'/>
|
||||
// </w:pPr>
|
||||
// <w:r>
|
||||
// <w:t>[TIMECODE]</w:t>
|
||||
// </w:r>
|
||||
//</w:p>
|
||||
var n2 = xml.CreateElement("w:p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n1a1 = xml.CreateAttribute("w:rsidR", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1a1.InnerText = "00D56C9E";
|
||||
n2.Attributes.Append(n1a1);
|
||||
var n1a2 = xml.CreateAttribute("w:rsidRDefault", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n1a2.InnerText = "00D56C9E";
|
||||
n2.Attributes.Append(n1a2);
|
||||
|
||||
var n2sub1 = xml.CreateElement("w:pPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n2sub1sub = xml.CreateElement("w:pStyle", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n2sub1.AppendChild(n2sub1sub);
|
||||
var n2sub1Suba1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n2sub1Suba1.InnerText = "TimeCode";
|
||||
n2sub1sub.Attributes.Append(n2sub1Suba1);
|
||||
n2.AppendChild(n2sub1);
|
||||
|
||||
var n2sub2 = xml.CreateElement("w:r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n2sub2sub = xml.CreateElement("w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n2sub2sub.InnerText = ToTimeCode(p.StartTime);
|
||||
n2sub2.AppendChild(n2sub2sub);
|
||||
n2.AppendChild(n2sub2);
|
||||
tc1.AppendChild(n2);
|
||||
|
||||
//<w:tc>
|
||||
// <w:tcPr>
|
||||
// <w:tcW w:w='5560' w:type='dxa'/>
|
||||
// <w:vAlign w:val='bottom'/>
|
||||
// </w:tcPr>
|
||||
// <w:p w:rsidR='00D56C9E' w:rsidRDefault='00D56C9E'>
|
||||
// <w:pPr>
|
||||
// <w:pStyle w:val='PopOn'/>
|
||||
// </w:pPr>
|
||||
// <w:proofErr w:type='spellStart'/>
|
||||
// </w:p>
|
||||
//</w:tc>
|
||||
var tc2 = xml.CreateElement("w:tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
paragraph.AppendChild(tc2);
|
||||
|
||||
var n3sub1 = xml.CreateElement("w:tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
tc2.AppendChild(n3sub1);
|
||||
|
||||
var n3sub1sub1 = xml.CreateElement("w:tcW", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3suba1 = xml.CreateAttribute("w:w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3suba1.InnerText = "5560";
|
||||
n3sub1sub1.Attributes.Append(n3suba1);
|
||||
var n3suba2 = xml.CreateAttribute("w:type", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3suba2.InnerText = "dxa";
|
||||
n3sub1sub1.Attributes.Append(n3suba2);
|
||||
n3sub1.AppendChild(n3sub1sub1);
|
||||
|
||||
var n3sub1sub2 = xml.CreateElement("w:vAlign", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3sub1sub2a1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub2a1.InnerText = "bottom";
|
||||
n3sub1sub2.Attributes.Append(n3sub1sub2a1);
|
||||
n3sub1.AppendChild(n3sub1sub2);
|
||||
|
||||
var n3sub1sub3 = xml.CreateElement("w:p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3sub1sub3a1 = xml.CreateAttribute("w:rsidR", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3a1.InnerText = "00D56C9E";
|
||||
n3sub1sub3.Attributes.Append(n3sub1sub3a1);
|
||||
var n3sub1sub3a2 = xml.CreateAttribute("w:rsidRDefault", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3a2.InnerText = "00D56C9E";
|
||||
n3sub1sub3.Attributes.Append(n3sub1sub3a2);
|
||||
var n3sub1sub3sub1 = xml.CreateElement("w:pPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3.AppendChild(n3sub1sub3sub1);
|
||||
var n3sub1sub3sub1sub = xml.CreateElement("w:pStyle", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
var n3sub1sub3sub1suba1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3sub1suba1.InnerText = "PopOn";
|
||||
n3sub1sub3sub1sub.Attributes.Append(n3sub1sub3sub1suba1);
|
||||
n3sub1sub3sub1.AppendChild(n3sub1sub3sub1sub);
|
||||
|
||||
var lines = HtmlUtil.RemoveHtmlTags(p.Text, true).Replace(Environment.NewLine, "\n").Split('\n');
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
var n3sub1sub3sub2 = xml.CreateElement("w:r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3.AppendChild(n3sub1sub3sub2);
|
||||
if (i > 0)
|
||||
{
|
||||
var lineBreak = xml.CreateElement("w:br", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
n3sub1sub3sub2.AppendChild(lineBreak);
|
||||
}
|
||||
var text = xml.CreateElement("w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
text.InnerText = lines[i];
|
||||
n3sub1sub3sub2.AppendChild(text);
|
||||
}
|
||||
tc2.AppendChild(n3sub1sub3);
|
||||
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
private static string ToTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return timeCode.ToHHMMSSFF(); //10:00:07:27
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(sb.ToString().Trim());
|
||||
var nsmgr = new XmlNamespaceManager(xml.NameTable);
|
||||
nsmgr.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("//w:tr", nsmgr))
|
||||
{
|
||||
try
|
||||
{
|
||||
Paragraph p = new Paragraph();
|
||||
XmlNode t = node.SelectSingleNode("w:tc/w:p/w:r/w:t", nsmgr);
|
||||
if (t != null)
|
||||
{
|
||||
p.StartTime = DecodeTimeCodeFrames(t.InnerText.Trim(), SplitCharColon);
|
||||
sb = new StringBuilder();
|
||||
foreach (XmlNode wrNode in node.SelectNodes("w:tc/w:p/w:r", nsmgr))
|
||||
{
|
||||
foreach (XmlNode child in wrNode.ChildNodes)
|
||||
{
|
||||
if (child.Name == "w:t")
|
||||
{
|
||||
bool isTimeCode = child.InnerText.Length == 11 && child.InnerText.Replace(":", string.Empty).Length == 8;
|
||||
if (!isTimeCode)
|
||||
sb.Append(child.InnerText);
|
||||
}
|
||||
else if (child.Name == "w:br")
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
p.Text = sb.ToString();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++)
|
||||
{
|
||||
subtitle.Paragraphs[i].EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds;
|
||||
}
|
||||
subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].EndTime.TotalMilliseconds = 2500;
|
||||
subtitle.RemoveEmptyLines();
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++)
|
||||
{
|
||||
if (subtitle.Paragraphs[i].EndTime.TotalMilliseconds == subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds)
|
||||
subtitle.Paragraphs[i].EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,151 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class PE2 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCodeEnd = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
TimeStart,
|
||||
Text,
|
||||
TimeEndOrText,
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "PE2"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
string s = sb.ToString();
|
||||
if (s.Contains("[HEADER]") && s.Contains("[BODY]"))
|
||||
return false; // UnknownSubtitle17
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//#PE2 Format file
|
||||
//10:00:05:16 You will get a loan of//Rs 1.5 million in 15 minutes.
|
||||
//10:00:08:19
|
||||
//10:00:09:01 What have you brought//as the guarantee?
|
||||
//10:00:12:01
|
||||
//10:00:12:11 What?//I didn't get you.
|
||||
//10:00:14:11
|
||||
//10:00:14:15 We will sanction your loan.
|
||||
//10:00:16:00
|
||||
|
||||
const string writeFormat = "{0} {2}{3}{1}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#PE2 Format file");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text.Replace(Environment.NewLine, "//");
|
||||
sb.AppendLine(string.Format(writeFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
var paragraph = new Paragraph();
|
||||
ExpectingLine expecting = ExpectingLine.TimeStart;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
if (expecting == ExpectingLine.TimeStart)
|
||||
{
|
||||
paragraph = new Paragraph();
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
if (line.Length > 12)
|
||||
paragraph.Text = line.Substring(12).Trim().Replace("//", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RegexTimeCodeEnd.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
if (paragraph.StartTime.TotalMilliseconds < 0.001)
|
||||
_errorCount++;
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string text = line.Replace("//", Environment.NewLine);
|
||||
paragraph.Text += Environment.NewLine + text;
|
||||
expecting = ExpectingLine.TimeEndOrText;
|
||||
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && line != "#PE2 Format file")
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class PE2 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCodeEnd = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
TimeStart,
|
||||
Text,
|
||||
TimeEndOrText,
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "PE2"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
string s = sb.ToString();
|
||||
if (s.Contains("[HEADER]") && s.Contains("[BODY]"))
|
||||
return false; // UnknownSubtitle17
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//#PE2 Format file
|
||||
//10:00:05:16 You will get a loan of//Rs 1.5 million in 15 minutes.
|
||||
//10:00:08:19
|
||||
//10:00:09:01 What have you brought//as the guarantee?
|
||||
//10:00:12:01
|
||||
//10:00:12:11 What?//I didn't get you.
|
||||
//10:00:14:11
|
||||
//10:00:14:15 We will sanction your loan.
|
||||
//10:00:16:00
|
||||
|
||||
const string writeFormat = "{0} {2}{3}{1}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#PE2 Format file");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text.Replace(Environment.NewLine, "//");
|
||||
sb.AppendLine(string.Format(writeFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
var paragraph = new Paragraph();
|
||||
ExpectingLine expecting = ExpectingLine.TimeStart;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
if (expecting == ExpectingLine.TimeStart)
|
||||
{
|
||||
paragraph = new Paragraph();
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
if (line.Length > 12)
|
||||
paragraph.Text = line.Substring(12).Trim().Replace("//", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RegexTimeCodeEnd.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
if (paragraph.StartTime.TotalMilliseconds < 0.001)
|
||||
_errorCount++;
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string text = line.Replace("//", Environment.NewLine);
|
||||
paragraph.Text += Environment.NewLine + text;
|
||||
expecting = ExpectingLine.TimeEndOrText;
|
||||
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && line != "#PE2 Format file")
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,139 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class QubeMasterImport : SubtitleFormat
|
||||
{
|
||||
// ToText code by Tosil Velkoff, tosil@velkoff.net
|
||||
// Based on UnknownSubtitle44
|
||||
//SubLine1
|
||||
//SubLine2
|
||||
//10:01:04:12
|
||||
//10:01:07:09
|
||||
private readonly static Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "QubeMasterPro Import"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
if (index != 0) sb.AppendLine();
|
||||
index++;
|
||||
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime));
|
||||
sb.AppendLine(EncodeTimeCode(p.EndTime));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(':');
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (expectStartTime)
|
||||
{
|
||||
p.StartTime = DecodeTimeCode(parts);
|
||||
expectStartTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.EndTime.TotalMilliseconds < 0.01)
|
||||
_errorCount++;
|
||||
p.EndTime = DecodeTimeCode(parts);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else
|
||||
{
|
||||
expectStartTime = true;
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p.EndTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
bool allNullEndTime = true;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
if (subtitle.Paragraphs[i].EndTime.TotalMilliseconds != 0)
|
||||
allNullEndTime = false;
|
||||
}
|
||||
if (allNullEndTime)
|
||||
subtitle.Paragraphs.Clear();
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class QubeMasterImport : SubtitleFormat
|
||||
{
|
||||
// ToText code by Tosil Velkoff, tosil@velkoff.net
|
||||
// Based on UnknownSubtitle44
|
||||
//SubLine1
|
||||
//SubLine2
|
||||
//10:01:04:12
|
||||
//10:01:07:09
|
||||
private readonly static Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "QubeMasterPro Import"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
if (index != 0) sb.AppendLine();
|
||||
index++;
|
||||
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime));
|
||||
sb.AppendLine(EncodeTimeCode(p.EndTime));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(':');
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (expectStartTime)
|
||||
{
|
||||
p.StartTime = DecodeTimeCodeFrames(parts);
|
||||
expectStartTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.EndTime.TotalMilliseconds < 0.01)
|
||||
_errorCount++;
|
||||
p.EndTime = DecodeTimeCodeFrames(parts);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else
|
||||
{
|
||||
expectStartTime = true;
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p.EndTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
bool allNullEndTime = true;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
if (subtitle.Paragraphs[i].EndTime.TotalMilliseconds != 0)
|
||||
allNullEndTime = false;
|
||||
}
|
||||
if (allNullEndTime)
|
||||
subtitle.Paragraphs.Clear();
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,137 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class QuickTimeText : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\[\d\d:\d\d:\d\d.\d\d\]", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "QuickTime text"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (lines != null && lines.Count > 0 && lines[0].StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string Header = @"{QTtext} {font:Tahoma}
|
||||
{plain} {size:20}
|
||||
{timeScale:30}
|
||||
{width:160} {height:32}
|
||||
{timestamps:absolute} {language:0}";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(Header);
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//[00:00:07.12]
|
||||
//d’être perdu dans un brouillard de pensées,
|
||||
//[00:00:17.06] (this line is optional!)
|
||||
// (blank line optional too)
|
||||
//[00:00:26.26]
|
||||
//tout le temps,
|
||||
//[00:00:35.08]
|
||||
sb.AppendLine(string.Format("{0}{1}{2}", EncodeTimeCode(p.StartTime) + Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text) + Environment.NewLine, EncodeTimeCode(p.EndTime) + Environment.NewLine));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//[00:00:07.12]
|
||||
return string.Format("[{0:00}:{1:00}:{2:00}.{3:00}]", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//[00:00:07.12]
|
||||
//d’être perdu dans un brouillard de pensées,
|
||||
//[00:00:17.06] (this line is optional!)
|
||||
// (blank line optional too)
|
||||
//[00:00:26.26]
|
||||
//tout le temps,
|
||||
//[00:00:35.08]
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string[] parts = temp.Split(new[] { '.', ':', '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
if (p == null || string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = string.Empty;
|
||||
int indexOfEndTime = line.IndexOf(']');
|
||||
if (indexOfEndTime > 0 && indexOfEndTime + 1 < line.Length)
|
||||
text = line.Substring(indexOfEndTime + 1);
|
||||
p = new Paragraph(DecodeTimeCode(parts), DecodeTimeCode(parts), text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.EndTime = DecodeTimeCode(parts);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
string text = string.Empty;
|
||||
int indexOfEndTime = line.IndexOf(']');
|
||||
if (indexOfEndTime > 0 && indexOfEndTime + 1 < line.Length)
|
||||
text = line.Substring(indexOfEndTime + 1);
|
||||
p = new Paragraph(DecodeTimeCode(parts), DecodeTimeCode(parts), text);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class QuickTimeText : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\[\d\d:\d\d:\d\d.\d\d\]", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "QuickTime text"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (lines != null && lines.Count > 0 && lines[0].StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string Header = @"{QTtext} {font:Tahoma}
|
||||
{plain} {size:20}
|
||||
{timeScale:30}
|
||||
{width:160} {height:32}
|
||||
{timestamps:absolute} {language:0}";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(Header);
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//[00:00:07.12]
|
||||
//d’être perdu dans un brouillard de pensées,
|
||||
//[00:00:17.06] (this line is optional!)
|
||||
// (blank line optional too)
|
||||
//[00:00:26.26]
|
||||
//tout le temps,
|
||||
//[00:00:35.08]
|
||||
sb.AppendLine(string.Format("{0}{1}{2}", EncodeTimeCode(p.StartTime) + Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text) + Environment.NewLine, EncodeTimeCode(p.EndTime) + Environment.NewLine));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//[00:00:07.12]
|
||||
return string.Format("[{0:00}:{1:00}:{2:00}.{3:00}]", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//[00:00:07.12]
|
||||
//d’être perdu dans un brouillard de pensées,
|
||||
//[00:00:17.06] (this line is optional!)
|
||||
// (blank line optional too)
|
||||
//[00:00:26.26]
|
||||
//tout le temps,
|
||||
//[00:00:35.08]
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string[] parts = temp.Split(new[] { '.', ':', '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
if (p == null || string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = string.Empty;
|
||||
int indexOfEndTime = line.IndexOf(']');
|
||||
if (indexOfEndTime > 0 && indexOfEndTime + 1 < line.Length)
|
||||
text = line.Substring(indexOfEndTime + 1);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(parts), DecodeTimeCodeFrames(parts), text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.EndTime = DecodeTimeCodeFrames(parts);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
string text = string.Empty;
|
||||
int indexOfEndTime = line.IndexOf(']');
|
||||
if (indexOfEndTime > 0 && indexOfEndTime + 1 < line.Length)
|
||||
text = line.Substring(indexOfEndTime + 1);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(parts), DecodeTimeCodeFrames(parts), text);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,175 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class RhozetHarmonic : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Rhozet Harmonic"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > 0;
|
||||
}
|
||||
|
||||
private static string ToTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//<TitlerData>
|
||||
// <Data StartTimecode='00:00:02;21' EndTimecode='00:00:05;21' Title='CAPTIONING PROVIDED BY
|
||||
//CharSize='0.2' PosX='0.5' PosY='0.75' ColorR='245' ColorG='245' ColorB='245' Transparency='0.0' ShadowSize='0.5' BkgEnable='1' BkgExtraWidth='0.02' BkgExtraHeight='0.02'/>
|
||||
|
||||
string xmlStructure =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
|
||||
"<TitlerData></TitlerData>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
|
||||
XmlNode paragraph = xml.CreateElement("Data");
|
||||
|
||||
XmlAttribute charSize = xml.CreateAttribute("CharSize");
|
||||
charSize.InnerText = HtmlUtil.RemoveHtmlTags("0.2");
|
||||
paragraph.Attributes.Append(charSize);
|
||||
|
||||
XmlAttribute posX = xml.CreateAttribute("PosX");
|
||||
posX.InnerText = "0.5";
|
||||
paragraph.Attributes.Append(posX);
|
||||
|
||||
XmlAttribute posY = xml.CreateAttribute("PosY");
|
||||
posY.InnerText = "0.75";
|
||||
paragraph.Attributes.Append(posY);
|
||||
|
||||
XmlAttribute colorR = xml.CreateAttribute("ColorR");
|
||||
colorR.InnerText = "245";
|
||||
paragraph.Attributes.Append(colorR);
|
||||
|
||||
XmlAttribute colorG = xml.CreateAttribute("ColorG");
|
||||
colorG.InnerText = "245";
|
||||
paragraph.Attributes.Append(colorG);
|
||||
|
||||
XmlAttribute colorB = xml.CreateAttribute("ColorB");
|
||||
colorB.InnerText = "245";
|
||||
paragraph.Attributes.Append(colorB);
|
||||
|
||||
XmlAttribute transparency = xml.CreateAttribute("Transparency");
|
||||
transparency.InnerText = "0.0";
|
||||
paragraph.Attributes.Append(transparency);
|
||||
|
||||
XmlAttribute shadowSize = xml.CreateAttribute("ShadowSize");
|
||||
shadowSize.InnerText = "0.5";
|
||||
paragraph.Attributes.Append(shadowSize);
|
||||
|
||||
XmlAttribute bkgEnable = xml.CreateAttribute("BkgEnable");
|
||||
bkgEnable.InnerText = "1";
|
||||
paragraph.Attributes.Append(bkgEnable);
|
||||
|
||||
XmlAttribute bkgExtraWidth = xml.CreateAttribute("BkgExtraWidth");
|
||||
bkgExtraWidth.InnerText = "0.02";
|
||||
paragraph.Attributes.Append(bkgExtraWidth);
|
||||
|
||||
XmlAttribute bkgExtraHeight = xml.CreateAttribute("BkgExtraHeight");
|
||||
bkgExtraHeight.InnerText = "0.02";
|
||||
paragraph.Attributes.Append(bkgExtraHeight);
|
||||
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
paragraph = xml.CreateElement("Data");
|
||||
|
||||
XmlAttribute start = xml.CreateAttribute("StartTimecode");
|
||||
start.InnerText = ToTimeCode(p.StartTime);
|
||||
paragraph.Attributes.Append(start);
|
||||
|
||||
XmlAttribute end = xml.CreateAttribute("EndTimecode");
|
||||
end.InnerText = ToTimeCode(p.EndTime);
|
||||
paragraph.Attributes.Append(end);
|
||||
|
||||
XmlAttribute text = xml.CreateAttribute("Title");
|
||||
text.InnerText = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
paragraph.Attributes.Append(text);
|
||||
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
}
|
||||
|
||||
string s = "<?xml version=\"1.0\"?>" + Environment.NewLine + ToUtf8XmlString(xml, true).Replace("\"", "__@____").Replace("'", "'").Replace("__@____", "'").Replace(" />", "/>");
|
||||
while (s.Contains(Environment.NewLine + " "))
|
||||
s = s.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
return s;
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
|
||||
string allText = sb.ToString();
|
||||
if (!allText.Contains("<TitlerData") || !allText.Contains("<Data"))
|
||||
return;
|
||||
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
xml.LoadXml(allText);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (xml.DocumentElement == null)
|
||||
{
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
char[] splitChars = { ':', ';' };
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("Data"))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (node.Attributes != null)
|
||||
{
|
||||
string text = node.Attributes.GetNamedItem("Title").InnerText.Trim();
|
||||
string start = node.Attributes.GetNamedItem("StartTimecode").InnerText;
|
||||
string end = node.Attributes.GetNamedItem("EndTimecode").InnerText;
|
||||
subtitle.Paragraphs.Add(new Paragraph(DecodeTimeCode(start, splitChars), DecodeTimeCode(end, splitChars), text));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class RhozetHarmonic : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Rhozet Harmonic"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > 0;
|
||||
}
|
||||
|
||||
private static string ToTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//<TitlerData>
|
||||
// <Data StartTimecode='00:00:02;21' EndTimecode='00:00:05;21' Title='CAPTIONING PROVIDED BY
|
||||
//CharSize='0.2' PosX='0.5' PosY='0.75' ColorR='245' ColorG='245' ColorB='245' Transparency='0.0' ShadowSize='0.5' BkgEnable='1' BkgExtraWidth='0.02' BkgExtraHeight='0.02'/>
|
||||
|
||||
string xmlStructure =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
|
||||
"<TitlerData></TitlerData>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
|
||||
XmlNode paragraph = xml.CreateElement("Data");
|
||||
|
||||
XmlAttribute charSize = xml.CreateAttribute("CharSize");
|
||||
charSize.InnerText = HtmlUtil.RemoveHtmlTags("0.2");
|
||||
paragraph.Attributes.Append(charSize);
|
||||
|
||||
XmlAttribute posX = xml.CreateAttribute("PosX");
|
||||
posX.InnerText = "0.5";
|
||||
paragraph.Attributes.Append(posX);
|
||||
|
||||
XmlAttribute posY = xml.CreateAttribute("PosY");
|
||||
posY.InnerText = "0.75";
|
||||
paragraph.Attributes.Append(posY);
|
||||
|
||||
XmlAttribute colorR = xml.CreateAttribute("ColorR");
|
||||
colorR.InnerText = "245";
|
||||
paragraph.Attributes.Append(colorR);
|
||||
|
||||
XmlAttribute colorG = xml.CreateAttribute("ColorG");
|
||||
colorG.InnerText = "245";
|
||||
paragraph.Attributes.Append(colorG);
|
||||
|
||||
XmlAttribute colorB = xml.CreateAttribute("ColorB");
|
||||
colorB.InnerText = "245";
|
||||
paragraph.Attributes.Append(colorB);
|
||||
|
||||
XmlAttribute transparency = xml.CreateAttribute("Transparency");
|
||||
transparency.InnerText = "0.0";
|
||||
paragraph.Attributes.Append(transparency);
|
||||
|
||||
XmlAttribute shadowSize = xml.CreateAttribute("ShadowSize");
|
||||
shadowSize.InnerText = "0.5";
|
||||
paragraph.Attributes.Append(shadowSize);
|
||||
|
||||
XmlAttribute bkgEnable = xml.CreateAttribute("BkgEnable");
|
||||
bkgEnable.InnerText = "1";
|
||||
paragraph.Attributes.Append(bkgEnable);
|
||||
|
||||
XmlAttribute bkgExtraWidth = xml.CreateAttribute("BkgExtraWidth");
|
||||
bkgExtraWidth.InnerText = "0.02";
|
||||
paragraph.Attributes.Append(bkgExtraWidth);
|
||||
|
||||
XmlAttribute bkgExtraHeight = xml.CreateAttribute("BkgExtraHeight");
|
||||
bkgExtraHeight.InnerText = "0.02";
|
||||
paragraph.Attributes.Append(bkgExtraHeight);
|
||||
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
paragraph = xml.CreateElement("Data");
|
||||
|
||||
XmlAttribute start = xml.CreateAttribute("StartTimecode");
|
||||
start.InnerText = ToTimeCode(p.StartTime);
|
||||
paragraph.Attributes.Append(start);
|
||||
|
||||
XmlAttribute end = xml.CreateAttribute("EndTimecode");
|
||||
end.InnerText = ToTimeCode(p.EndTime);
|
||||
paragraph.Attributes.Append(end);
|
||||
|
||||
XmlAttribute text = xml.CreateAttribute("Title");
|
||||
text.InnerText = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
paragraph.Attributes.Append(text);
|
||||
|
||||
xml.DocumentElement.AppendChild(paragraph);
|
||||
}
|
||||
|
||||
string s = "<?xml version=\"1.0\"?>" + Environment.NewLine + ToUtf8XmlString(xml, true).Replace("\"", "__@____").Replace("'", "'").Replace("__@____", "'").Replace(" />", "/>");
|
||||
while (s.Contains(Environment.NewLine + " "))
|
||||
s = s.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
return s;
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
|
||||
string allText = sb.ToString();
|
||||
if (!allText.Contains("<TitlerData") || !allText.Contains("<Data"))
|
||||
return;
|
||||
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
xml.LoadXml(allText);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (xml.DocumentElement == null)
|
||||
{
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
char[] splitChars = { ':', ';' };
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("Data"))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (node.Attributes != null)
|
||||
{
|
||||
string text = node.Attributes.GetNamedItem("Title").InnerText.Trim();
|
||||
string start = node.Attributes.GetNamedItem("StartTimecode").InnerText;
|
||||
string end = node.Attributes.GetNamedItem("EndTimecode").InnerText;
|
||||
subtitle.Paragraphs.Add(new Paragraph(DecodeTimeCodeFrames(start, splitChars), DecodeTimeCodeFrames(end, splitChars), text));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,99 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Scenarist : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public const string NameOfFormat = "Scenarist";
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return NameOfFormat; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//0003 00:00:28:16 00:00:31:04 Jeg vil lære jer frygten for HERREN." (newline is \t)
|
||||
sb.AppendLine(string.Format("{0:0000}\t{1}\t{2}\t{3}", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text).Replace(Environment.NewLine, "\t")));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(5, 11);
|
||||
string end = temp.Substring(12 + 5, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("\t", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Scenarist : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public const string NameOfFormat = "Scenarist";
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return NameOfFormat; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//0003 00:00:28:16 00:00:31:04 Jeg vil lære jer frygten for HERREN." (newline is \t)
|
||||
sb.AppendLine(string.Format("{0:0000}\t{1}\t{2}\t{3}", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text).Replace(Environment.NewLine, "\t")));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(5, 11);
|
||||
string end = temp.Substring(12 + 5, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
string text = line.Remove(0, RegexTimeCodes.Match(line).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("\t", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,232 +1,232 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// SoftNi - http://www.softni.com/
|
||||
/// </summary>
|
||||
public class SoftNicolonSub : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex regexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\\\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".sub"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "SoftNi colon sub"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
sb.AppendLine("*PART 1*");
|
||||
sb.AppendLine("00:00:00:00\\00:00:00:00");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text;
|
||||
bool positionTop = false;
|
||||
|
||||
// If text starts with {\an8}, subtitle appears at the top
|
||||
if (text.StartsWith("{\\an8}", StringComparison.Ordinal))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag {\an8}.
|
||||
text = text.Remove(0, 6);
|
||||
}
|
||||
|
||||
// Split lines (split a subtitle into its lines)
|
||||
var lines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
bool nextLineInItalics = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
|
||||
tempLine = line;
|
||||
|
||||
// This line should be in italics (it was detected in previous line)
|
||||
if (nextLineInItalics)
|
||||
{
|
||||
tempLine = "<i>" + tempLine;
|
||||
nextLineInItalics = false;
|
||||
}
|
||||
|
||||
if (tempLine.StartsWith("<i>") && tempLine.EndsWith("</i>"))
|
||||
{
|
||||
// Whole line is in italics
|
||||
// Remove <i> from the beginning
|
||||
tempLine = tempLine.Remove(0, 3);
|
||||
// Remove </i> from the end
|
||||
tempLine = tempLine.Remove(tempLine.Length - 4, 4);
|
||||
// Add new italics tag at the beginning
|
||||
tempLine = "[" + tempLine;
|
||||
}
|
||||
else if (tempLine.StartsWith("<i>") && Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
{
|
||||
// Line starts with <i> but italics are not closed. So the next line should be in italics
|
||||
nextLineInItalics = true;
|
||||
}
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
|
||||
text = lineSb.ToString();
|
||||
// Replace remaining italics tags
|
||||
text = text.Replace("<i>", @"[");
|
||||
text = text.Replace("</i>", @"]");
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
}
|
||||
|
||||
// Add top-position SoftNI marker "}" at the beginning of first line.
|
||||
if (positionTop)
|
||||
text = "}" + text;
|
||||
|
||||
sb.AppendLine(string.Format("{0}{1}{2}\\{3}", text, Environment.NewLine, p.StartTime.ToHHMMSSPeriodFF().Replace(".", ":"), p.EndTime.ToHHMMSSPeriodFF().Replace(".", ":")));
|
||||
}
|
||||
sb.AppendLine(@"*END*");
|
||||
sb.AppendLine(@"...........\...........");
|
||||
sb.AppendLine(@"*CODE*");
|
||||
sb.AppendLine(@"0000000000000000");
|
||||
sb.AppendLine(@"*CAST*");
|
||||
sb.AppendLine(@"*GENERATOR*");
|
||||
sb.AppendLine(@"*FONTS*");
|
||||
sb.AppendLine(@"*READ*");
|
||||
sb.AppendLine(@"0,300 15,000 130,000 100,000 25,000");
|
||||
sb.AppendLine(@"*TIMING*");
|
||||
sb.AppendLine(@"1 25 0");
|
||||
sb.AppendLine(@"*TIMED BACKUP NAME*");
|
||||
sb.AppendLine(@"C:\");
|
||||
sb.AppendLine(@"*FORMAT SAMPLE ÅåÉéÌìÕõÛûÿ*");
|
||||
sb.AppendLine(@"*READ ADVANCED*");
|
||||
sb.AppendLine(@"< > 1 1 0,300");
|
||||
sb.AppendLine(@"*MARKERS*");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
}
|
||||
|
||||
private void DoLoadSubtitle(Subtitle subtitle, List<string> lines)
|
||||
{
|
||||
//—Peter.
|
||||
//—Estoy de licencia.
|
||||
//01:48:50.07\01:48:52.01
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (regexTimeCodes.IsMatch(s))
|
||||
{
|
||||
// Start and end time separated by "\"
|
||||
var temp = s.Split('\\');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCode(startParts);
|
||||
p.EndTime = DecodeTimeCode(endParts);
|
||||
string text = sb.ToString().Trim();
|
||||
|
||||
bool positionTop = false;
|
||||
// If text starts with "}", subtitle appears at the top
|
||||
if (text.StartsWith('}'))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag "}"
|
||||
text = text.Remove(0, 1);
|
||||
}
|
||||
// Replace tags
|
||||
text = text.Replace("[", @"<i>");
|
||||
text = text.Replace("]", @"</i>");
|
||||
|
||||
// Split subtitle lines (one subtitle has one or more lines)
|
||||
var subtitleLines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
foreach (string subtitleLine in subtitleLines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
tempLine = subtitleLine;
|
||||
// Close italics in every line (if next line is in italics, SoftNI will use "[" at the beginning)
|
||||
if (Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
tempLine = tempLine + "</i>";
|
||||
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
}
|
||||
text = lineSb.ToString();
|
||||
|
||||
// Replace "</i>line break<i>" with just a line break (SubRip does not need to close italics and open them again in the next line).
|
||||
text = text.Replace("</i>" + Environment.NewLine + "<i>", Environment.NewLine);
|
||||
|
||||
// Subtitle appears at the top (add tag)
|
||||
if (positionTop)
|
||||
text = "{\\an8}" + text;
|
||||
|
||||
p.Text = text;
|
||||
if (text.Length > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
sb.Clear();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith('*'))
|
||||
{
|
||||
// skip empty lines or start
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// SoftNi - http://www.softni.com/
|
||||
/// </summary>
|
||||
public class SoftNicolonSub : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex regexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\\\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".sub"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "SoftNi colon sub"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
sb.AppendLine("*PART 1*");
|
||||
sb.AppendLine("00:00:00:00\\00:00:00:00");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text;
|
||||
bool positionTop = false;
|
||||
|
||||
// If text starts with {\an8}, subtitle appears at the top
|
||||
if (text.StartsWith("{\\an8}", StringComparison.Ordinal))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag {\an8}.
|
||||
text = text.Remove(0, 6);
|
||||
}
|
||||
|
||||
// Split lines (split a subtitle into its lines)
|
||||
var lines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
bool nextLineInItalics = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
|
||||
tempLine = line;
|
||||
|
||||
// This line should be in italics (it was detected in previous line)
|
||||
if (nextLineInItalics)
|
||||
{
|
||||
tempLine = "<i>" + tempLine;
|
||||
nextLineInItalics = false;
|
||||
}
|
||||
|
||||
if (tempLine.StartsWith("<i>") && tempLine.EndsWith("</i>"))
|
||||
{
|
||||
// Whole line is in italics
|
||||
// Remove <i> from the beginning
|
||||
tempLine = tempLine.Remove(0, 3);
|
||||
// Remove </i> from the end
|
||||
tempLine = tempLine.Remove(tempLine.Length - 4, 4);
|
||||
// Add new italics tag at the beginning
|
||||
tempLine = "[" + tempLine;
|
||||
}
|
||||
else if (tempLine.StartsWith("<i>") && Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
{
|
||||
// Line starts with <i> but italics are not closed. So the next line should be in italics
|
||||
nextLineInItalics = true;
|
||||
}
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
|
||||
text = lineSb.ToString();
|
||||
// Replace remaining italics tags
|
||||
text = text.Replace("<i>", @"[");
|
||||
text = text.Replace("</i>", @"]");
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
}
|
||||
|
||||
// Add top-position SoftNI marker "}" at the beginning of first line.
|
||||
if (positionTop)
|
||||
text = "}" + text;
|
||||
|
||||
sb.AppendLine(string.Format("{0}{1}{2}\\{3}", text, Environment.NewLine, p.StartTime.ToHHMMSSPeriodFF().Replace(".", ":"), p.EndTime.ToHHMMSSPeriodFF().Replace(".", ":")));
|
||||
}
|
||||
sb.AppendLine(@"*END*");
|
||||
sb.AppendLine(@"...........\...........");
|
||||
sb.AppendLine(@"*CODE*");
|
||||
sb.AppendLine(@"0000000000000000");
|
||||
sb.AppendLine(@"*CAST*");
|
||||
sb.AppendLine(@"*GENERATOR*");
|
||||
sb.AppendLine(@"*FONTS*");
|
||||
sb.AppendLine(@"*READ*");
|
||||
sb.AppendLine(@"0,300 15,000 130,000 100,000 25,000");
|
||||
sb.AppendLine(@"*TIMING*");
|
||||
sb.AppendLine(@"1 25 0");
|
||||
sb.AppendLine(@"*TIMED BACKUP NAME*");
|
||||
sb.AppendLine(@"C:\");
|
||||
sb.AppendLine(@"*FORMAT SAMPLE ÅåÉéÌìÕõÛûÿ*");
|
||||
sb.AppendLine(@"*READ ADVANCED*");
|
||||
sb.AppendLine(@"< > 1 1 0,300");
|
||||
sb.AppendLine(@"*MARKERS*");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
}
|
||||
|
||||
private void DoLoadSubtitle(Subtitle subtitle, List<string> lines)
|
||||
{
|
||||
//—Peter.
|
||||
//—Estoy de licencia.
|
||||
//01:48:50.07\01:48:52.01
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (regexTimeCodes.IsMatch(s))
|
||||
{
|
||||
// Start and end time separated by "\"
|
||||
var temp = s.Split('\\');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCodeFrames(startParts);
|
||||
p.EndTime = DecodeTimeCodeFrames(endParts);
|
||||
string text = sb.ToString().Trim();
|
||||
|
||||
bool positionTop = false;
|
||||
// If text starts with "}", subtitle appears at the top
|
||||
if (text.StartsWith('}'))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag "}"
|
||||
text = text.Remove(0, 1);
|
||||
}
|
||||
// Replace tags
|
||||
text = text.Replace("[", @"<i>");
|
||||
text = text.Replace("]", @"</i>");
|
||||
|
||||
// Split subtitle lines (one subtitle has one or more lines)
|
||||
var subtitleLines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
foreach (string subtitleLine in subtitleLines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
tempLine = subtitleLine;
|
||||
// Close italics in every line (if next line is in italics, SoftNI will use "[" at the beginning)
|
||||
if (Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
tempLine = tempLine + "</i>";
|
||||
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
}
|
||||
text = lineSb.ToString();
|
||||
|
||||
// Replace "</i>line break<i>" with just a line break (SubRip does not need to close italics and open them again in the next line).
|
||||
text = text.Replace("</i>" + Environment.NewLine + "<i>", Environment.NewLine);
|
||||
|
||||
// Subtitle appears at the top (add tag)
|
||||
if (positionTop)
|
||||
text = "{\\an8}" + text;
|
||||
|
||||
p.Text = text;
|
||||
if (text.Length > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
sb.Clear();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith('*'))
|
||||
{
|
||||
// skip empty lines or start
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,233 +1,233 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// SoftNi - http://www.softni.com/
|
||||
/// </summary>
|
||||
public class SoftNiSub : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d\.\d\d\\\d\d:\d\d:\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".sub"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "SoftNi sub"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
sb.AppendLine("*PART 1*");
|
||||
sb.AppendLine("00:00:00.00\\00:00:00.00");
|
||||
const string writeFormat = "{0}{1}{2}\\{3}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text;
|
||||
bool positionTop = false;
|
||||
|
||||
// If text starts with {\an8}, subtitle appears at the top
|
||||
if (text.StartsWith("{\\an8}", StringComparison.Ordinal))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag {\an8}.
|
||||
text = text.Remove(0, 6);
|
||||
}
|
||||
|
||||
// Split lines (split a subtitle into its lines)
|
||||
var lines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
bool nextLineInItalics = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
|
||||
tempLine = line;
|
||||
|
||||
// This line should be in italics (it was detected in previous line)
|
||||
if (nextLineInItalics)
|
||||
{
|
||||
tempLine = "<i>" + tempLine;
|
||||
nextLineInItalics = false;
|
||||
}
|
||||
|
||||
if (tempLine.StartsWith("<i>") && tempLine.EndsWith("</i>"))
|
||||
{
|
||||
// Whole line is in italics
|
||||
// Remove <i> from the beginning
|
||||
tempLine = tempLine.Remove(0, 3);
|
||||
// Remove </i> from the end
|
||||
tempLine = tempLine.Remove(tempLine.Length - 4, 4);
|
||||
// Add new italics tag at the beginning
|
||||
tempLine = "[" + tempLine;
|
||||
}
|
||||
else if (tempLine.StartsWith("<i>", StringComparison.Ordinal) && Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
{
|
||||
// Line starts with <i> but italics are not closed. So the next line should be in italics
|
||||
nextLineInItalics = true;
|
||||
}
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
|
||||
text = lineSb.ToString();
|
||||
// Replace remaining italics tags
|
||||
text = text.Replace("<i>", @"[");
|
||||
text = text.Replace("</i>", @"]");
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
}
|
||||
|
||||
// Add top-position SoftNI marker "}" at the beginning of first line.
|
||||
if (positionTop)
|
||||
text = "}" + text;
|
||||
|
||||
sb.AppendLine(string.Format(writeFormat, text, Environment.NewLine, p.StartTime.ToHHMMSSPeriodFF(), p.EndTime.ToHHMMSSPeriodFF()));
|
||||
}
|
||||
sb.AppendLine(@"*END*");
|
||||
sb.AppendLine(@"...........\...........");
|
||||
sb.AppendLine(@"*CODE*");
|
||||
sb.AppendLine(@"0000000000000000");
|
||||
sb.AppendLine(@"*CAST*");
|
||||
sb.AppendLine(@"*GENERATOR*");
|
||||
sb.AppendLine(@"*FONTS*");
|
||||
sb.AppendLine(@"*READ*");
|
||||
sb.AppendLine(@"0,300 15,000 130,000 100,000 25,000");
|
||||
sb.AppendLine(@"*TIMING*");
|
||||
sb.AppendLine(@"1 25 0");
|
||||
sb.AppendLine(@"*TIMED BACKUP NAME*");
|
||||
sb.AppendLine(@"C:\");
|
||||
sb.AppendLine(@"*FORMAT SAMPLE ÅåÉéÌìÕõÛûÿ*");
|
||||
sb.AppendLine(@"*READ ADVANCED*");
|
||||
sb.AppendLine(@"< > 1 1 0,300");
|
||||
sb.AppendLine(@"*MARKERS*");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
}
|
||||
|
||||
private void DoLoadSubtitle(Subtitle subtitle, List<string> lines)
|
||||
{
|
||||
//—Peter.
|
||||
//—Estoy de licencia.
|
||||
//01:48:50.07\01:48:52.01
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
// Start and end time separated by "\"
|
||||
var temp = s.Split('\\');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCode(startParts);
|
||||
p.EndTime = DecodeTimeCode(endParts);
|
||||
string text = sb.ToString().Trim();
|
||||
|
||||
bool positionTop = false;
|
||||
// If text starts with "}", subtitle appears at the top
|
||||
if (text.StartsWith('}'))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag "{"
|
||||
text = text.Remove(0, 1);
|
||||
}
|
||||
// Replace tags
|
||||
text = text.Replace("[", @"<i>");
|
||||
text = text.Replace("]", @"</i>");
|
||||
|
||||
// Split subtitle lines (one subtitle has one or more lines)
|
||||
var subtitleLines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
foreach (string subtitleLine in subtitleLines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
tempLine = subtitleLine;
|
||||
// Close italics in every line (if next line is in italics, SoftNI will use "[" at the beginning)
|
||||
if (Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
tempLine = tempLine + "</i>";
|
||||
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
}
|
||||
text = lineSb.ToString();
|
||||
|
||||
// Replace "</i>line break<i>" with just a line break (SubRip does not need to close italics and open them again in the next line).
|
||||
text = text.Replace("</i>" + Environment.NewLine + "<i>", Environment.NewLine);
|
||||
|
||||
// Subtitle appears at the top (add tag)
|
||||
if (positionTop)
|
||||
text = "{\\an8}" + text;
|
||||
|
||||
p.Text = text;
|
||||
if (text.Length > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
sb.Clear();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith('*'))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// SoftNi - http://www.softni.com/
|
||||
/// </summary>
|
||||
public class SoftNiSub : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d\.\d\d\\\d\d:\d\d:\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".sub"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "SoftNi sub"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
sb.AppendLine("*PART 1*");
|
||||
sb.AppendLine("00:00:00.00\\00:00:00.00");
|
||||
const string writeFormat = "{0}{1}{2}\\{3}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text;
|
||||
bool positionTop = false;
|
||||
|
||||
// If text starts with {\an8}, subtitle appears at the top
|
||||
if (text.StartsWith("{\\an8}", StringComparison.Ordinal))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag {\an8}.
|
||||
text = text.Remove(0, 6);
|
||||
}
|
||||
|
||||
// Split lines (split a subtitle into its lines)
|
||||
var lines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
bool nextLineInItalics = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
|
||||
tempLine = line;
|
||||
|
||||
// This line should be in italics (it was detected in previous line)
|
||||
if (nextLineInItalics)
|
||||
{
|
||||
tempLine = "<i>" + tempLine;
|
||||
nextLineInItalics = false;
|
||||
}
|
||||
|
||||
if (tempLine.StartsWith("<i>") && tempLine.EndsWith("</i>"))
|
||||
{
|
||||
// Whole line is in italics
|
||||
// Remove <i> from the beginning
|
||||
tempLine = tempLine.Remove(0, 3);
|
||||
// Remove </i> from the end
|
||||
tempLine = tempLine.Remove(tempLine.Length - 4, 4);
|
||||
// Add new italics tag at the beginning
|
||||
tempLine = "[" + tempLine;
|
||||
}
|
||||
else if (tempLine.StartsWith("<i>", StringComparison.Ordinal) && Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
{
|
||||
// Line starts with <i> but italics are not closed. So the next line should be in italics
|
||||
nextLineInItalics = true;
|
||||
}
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
|
||||
text = lineSb.ToString();
|
||||
// Replace remaining italics tags
|
||||
text = text.Replace("<i>", @"[");
|
||||
text = text.Replace("</i>", @"]");
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
}
|
||||
|
||||
// Add top-position SoftNI marker "}" at the beginning of first line.
|
||||
if (positionTop)
|
||||
text = "}" + text;
|
||||
|
||||
sb.AppendLine(string.Format(writeFormat, text, Environment.NewLine, p.StartTime.ToHHMMSSPeriodFF(), p.EndTime.ToHHMMSSPeriodFF()));
|
||||
}
|
||||
sb.AppendLine(@"*END*");
|
||||
sb.AppendLine(@"...........\...........");
|
||||
sb.AppendLine(@"*CODE*");
|
||||
sb.AppendLine(@"0000000000000000");
|
||||
sb.AppendLine(@"*CAST*");
|
||||
sb.AppendLine(@"*GENERATOR*");
|
||||
sb.AppendLine(@"*FONTS*");
|
||||
sb.AppendLine(@"*READ*");
|
||||
sb.AppendLine(@"0,300 15,000 130,000 100,000 25,000");
|
||||
sb.AppendLine(@"*TIMING*");
|
||||
sb.AppendLine(@"1 25 0");
|
||||
sb.AppendLine(@"*TIMED BACKUP NAME*");
|
||||
sb.AppendLine(@"C:\");
|
||||
sb.AppendLine(@"*FORMAT SAMPLE ÅåÉéÌìÕõÛûÿ*");
|
||||
sb.AppendLine(@"*READ ADVANCED*");
|
||||
sb.AppendLine(@"< > 1 1 0,300");
|
||||
sb.AppendLine(@"*MARKERS*");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
DoLoadSubtitle(subtitle, lines);
|
||||
}
|
||||
|
||||
private void DoLoadSubtitle(Subtitle subtitle, List<string> lines)
|
||||
{
|
||||
//—Peter.
|
||||
//—Estoy de licencia.
|
||||
//01:48:50.07\01:48:52.01
|
||||
var sb = new StringBuilder();
|
||||
var lineSb = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
// Start and end time separated by "\"
|
||||
var temp = s.Split('\\');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCodeFrames(startParts);
|
||||
p.EndTime = DecodeTimeCodeFrames(endParts);
|
||||
string text = sb.ToString().Trim();
|
||||
|
||||
bool positionTop = false;
|
||||
// If text starts with "}", subtitle appears at the top
|
||||
if (text.StartsWith('}'))
|
||||
{
|
||||
positionTop = true;
|
||||
// Remove the tag "{"
|
||||
text = text.Remove(0, 1);
|
||||
}
|
||||
// Replace tags
|
||||
text = text.Replace("[", @"<i>");
|
||||
text = text.Replace("]", @"</i>");
|
||||
|
||||
// Split subtitle lines (one subtitle has one or more lines)
|
||||
var subtitleLines = text.SplitToLines();
|
||||
int count = 0;
|
||||
lineSb.Clear();
|
||||
string tempLine = string.Empty;
|
||||
foreach (string subtitleLine in subtitleLines)
|
||||
{
|
||||
// Append line break in every line except the first one
|
||||
if (count > 0)
|
||||
lineSb.Append(Environment.NewLine);
|
||||
tempLine = subtitleLine;
|
||||
// Close italics in every line (if next line is in italics, SoftNI will use "[" at the beginning)
|
||||
if (Utilities.CountTagInText(tempLine, "<i>") > Utilities.CountTagInText(tempLine, "</i>"))
|
||||
tempLine = tempLine + "</i>";
|
||||
|
||||
lineSb.Append(tempLine);
|
||||
count++;
|
||||
}
|
||||
text = lineSb.ToString();
|
||||
|
||||
// Replace "</i>line break<i>" with just a line break (SubRip does not need to close italics and open them again in the next line).
|
||||
text = text.Replace("</i>" + Environment.NewLine + "<i>", Environment.NewLine);
|
||||
|
||||
// Subtitle appears at the top (add tag)
|
||||
if (positionTop)
|
||||
text = "{\\an8}" + text;
|
||||
|
||||
p.Text = text;
|
||||
if (text.Length > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
sb.Clear();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith('*'))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
sb.AppendLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,97 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Son : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".son"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "SON"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
const string writeFormat = "{0:0000}\t{1}\t{2}\t{3}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(writeFormat, index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text).Replace(Environment.NewLine, "\t")));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0001 00:00:19:13 00:00:22:10 a_0001.tif
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
var regexTimeCodes = new Regex(@"^\d\d\d\d[\t]+\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t.+\.(tif|tiff|png|bmp|TIF|TIFF|PNG|BMP)", RegexOptions.Compiled);
|
||||
int index = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, regexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(5, 11);
|
||||
string end = temp.Substring(12 + 5, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
int lastIndexOfTab = line.LastIndexOf('\t');
|
||||
string text = line.Remove(0, lastIndexOfTab + 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("\t", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith("Display_Area") || line.StartsWith('#') || line.StartsWith("Color") || index < 10)
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Son : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".son"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "SON"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
const string writeFormat = "{0:0000}\t{1}\t{2}\t{3}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(writeFormat, index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text).Replace(Environment.NewLine, "\t")));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0001 00:00:19:13 00:00:22:10 a_0001.tif
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
var regexTimeCodes = new Regex(@"^\d\d\d\d[\t]+\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t.+\.(tif|tiff|png|bmp|TIF|TIFF|PNG|BMP)", RegexOptions.Compiled);
|
||||
int index = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, regexTimeCodes.Match(line).Length);
|
||||
string start = temp.Substring(5, 11);
|
||||
string end = temp.Substring(12 + 5, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
int lastIndexOfTab = line.LastIndexOf('\t');
|
||||
string text = line.Remove(0, lastIndexOfTab + 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("\t", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.StartsWith("Display_Area") || line.StartsWith('#') || line.StartsWith("Color") || index < 10)
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,136 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class StructuredTitles : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d : \d\d:\d\d:\d\d:\d\d,\d\d:\d\d:\d\d:\d\d,\d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexSomeCodes = new Regex(@"^\d\d \d\d \d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexText = new Regex(@"^[A-Z]\d[A-Z]\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Structured titles"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
sb.AppendLine(@"Structured titles
|
||||
0000 : --:--:--:--,--:--:--:--,10
|
||||
80 80 80
|
||||
");
|
||||
|
||||
//0001 : 01:07:25:08,01:07:29:00,10
|
||||
//80 80 80
|
||||
//C1Y00 Niemand zal je helpen ontsnappen.
|
||||
//C1Y00 - Een agent heeft me geholpen.
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0:0000} : {1},{2},10", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
sb.AppendLine("80 80 80");
|
||||
foreach (string line in p.Text.SplitToLines())
|
||||
sb.AppendLine("C1Y00 " + line.Trim());
|
||||
sb.AppendLine();
|
||||
index++;
|
||||
}
|
||||
sb.AppendLine(string.Format("{0:0000}", index + 1) + @" : --:--:--:--,--:--:--:--,-1
|
||||
80 80 80");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0001 : 01:07:25:08,01:07:29:00,10
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.IndexOf(':') == 5 && RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
string start = line.Substring(7, 11);
|
||||
string end = line.Substring(19, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon);
|
||||
string[] endParts = end.Split(SplitCharColon);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), string.Empty);
|
||||
}
|
||||
}
|
||||
else if (p != null && RegexText.IsMatch(line))
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line.Substring(5).Trim();
|
||||
else
|
||||
p.Text += Environment.NewLine + line.Substring(5).Trim();
|
||||
}
|
||||
else if (line.Length < 10 && RegexSomeCodes.IsMatch(line))
|
||||
{
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (p.Text != null && Utilities.GetNumberOfLines(p.Text) > 3)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!line.TrimEnd().EndsWith(": --:--:--:--,--:--:--:--,-1", StringComparison.Ordinal))
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line.Trim();
|
||||
else
|
||||
p.Text += Environment.NewLine + line.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class StructuredTitles : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\d\d : \d\d:\d\d:\d\d:\d\d,\d\d:\d\d:\d\d:\d\d,\d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexSomeCodes = new Regex(@"^\d\d \d\d \d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexText = new Regex(@"^[A-Z]\d[A-Z]\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Structured titles"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
sb.AppendLine(@"Structured titles
|
||||
0000 : --:--:--:--,--:--:--:--,10
|
||||
80 80 80
|
||||
");
|
||||
|
||||
//0001 : 01:07:25:08,01:07:29:00,10
|
||||
//80 80 80
|
||||
//C1Y00 Niemand zal je helpen ontsnappen.
|
||||
//C1Y00 - Een agent heeft me geholpen.
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0:0000} : {1},{2},10", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
sb.AppendLine("80 80 80");
|
||||
foreach (string line in p.Text.SplitToLines())
|
||||
sb.AppendLine("C1Y00 " + line.Trim());
|
||||
sb.AppendLine();
|
||||
index++;
|
||||
}
|
||||
sb.AppendLine(string.Format("{0:0000}", index + 1) + @" : --:--:--:--,--:--:--:--,-1
|
||||
80 80 80");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//0001 : 01:07:25:08,01:07:29:00,10
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.IndexOf(':') == 5 && RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
string start = line.Substring(7, 11);
|
||||
string end = line.Substring(19, 11);
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon);
|
||||
string[] endParts = end.Split(SplitCharColon);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), string.Empty);
|
||||
}
|
||||
}
|
||||
else if (p != null && RegexText.IsMatch(line))
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line.Substring(5).Trim();
|
||||
else
|
||||
p.Text += Environment.NewLine + line.Substring(5).Trim();
|
||||
}
|
||||
else if (line.Length < 10 && RegexSomeCodes.IsMatch(line))
|
||||
{
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (p.Text != null && Utilities.GetNumberOfLines(p.Text) > 3)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!line.TrimEnd().EndsWith(": --:--:--:--,--:--:--:--,-1", StringComparison.Ordinal))
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line.Trim();
|
||||
else
|
||||
p.Text += Environment.NewLine + line.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,441 +1,438 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public abstract class SubtitleFormat
|
||||
{
|
||||
private static IList<SubtitleFormat> _allSubtitleFormats;
|
||||
|
||||
protected static readonly char[] SplitCharColon = new[] { ':' };
|
||||
|
||||
/// <summary>
|
||||
/// Formats supported by Subtitle Edit
|
||||
/// </summary>
|
||||
public static IList<SubtitleFormat> AllSubtitleFormats
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_allSubtitleFormats != null)
|
||||
return _allSubtitleFormats;
|
||||
|
||||
_allSubtitleFormats = new List<SubtitleFormat>
|
||||
{
|
||||
new SubRip(),
|
||||
new AbcIViewer(),
|
||||
new AdobeAfterEffectsFTME(),
|
||||
new AdobeEncore(),
|
||||
new AdobeEncoreLineTabNewLine(),
|
||||
new AdobeEncoreTabs(),
|
||||
new AdobeEncoreWithLineNumbers(),
|
||||
new AdobeEncoreWithLineNumbersNtsc(),
|
||||
new AdvancedSubStationAlpha(),
|
||||
new AQTitle(),
|
||||
new AvidCaption(),
|
||||
new AvidDvd(),
|
||||
new BelleNuitSubtitler(),
|
||||
new CaptionAssistant(),
|
||||
new Captionate(),
|
||||
new CaptionateMs(),
|
||||
new CaraokeXml(),
|
||||
new Csv(),
|
||||
new Csv2(),
|
||||
new Csv3(),
|
||||
new DCSubtitle(),
|
||||
new DCinemaSmpte2010(),
|
||||
new DCinemaSmpte2007(),
|
||||
new DigiBeta(),
|
||||
new DvdStudioPro(),
|
||||
new DvdStudioProSpaceOne(),
|
||||
new DvdStudioProSpace(),
|
||||
new DvdSubtitle(),
|
||||
new DvdSubtitleSystem(),
|
||||
new Ebu(),
|
||||
new Eeg708(),
|
||||
new F4Text(),
|
||||
new F4Rtf(),
|
||||
new F4Xml(),
|
||||
new FabSubtitler(),
|
||||
new FilmEditXml(),
|
||||
new FinalCutProXml(),
|
||||
new FinalCutProXXml(),
|
||||
new FinalCutProXmlGap(),
|
||||
new FinalCutProXCM(),
|
||||
new FinalCutProXml13(),
|
||||
new FinalCutProXml14(),
|
||||
new FinalCutProXml14Text(),
|
||||
new FinalCutProTestXml(),
|
||||
new FinalCutProTest2Xml(),
|
||||
new FlashXml(),
|
||||
new FLVCoreCuePoints(),
|
||||
new Footage(),
|
||||
new GpacTtxt(),
|
||||
new ImageLogicAutocaption(),
|
||||
new IssXml(),
|
||||
new ItunesTimedText(),
|
||||
new Json(),
|
||||
new JsonType2(),
|
||||
new JsonType3(),
|
||||
new JsonType4(),
|
||||
new JsonType5(),
|
||||
new JsonType6(),
|
||||
new Lrc(),
|
||||
new MicroDvd(),
|
||||
new MidwayInscriberCGX(),
|
||||
new MPlayer2(),
|
||||
new NciTimedRollUpCaptions(),
|
||||
new OpenDvt(),
|
||||
new Oresme(),
|
||||
new OresmeDocXDocument(),
|
||||
new PE2(),
|
||||
new PinnacleImpression(),
|
||||
new PListCaption(),
|
||||
new QubeMasterImport(),
|
||||
new QuickTimeText(),
|
||||
new RealTime(),
|
||||
new RhozetHarmonic(),
|
||||
new Sami(),
|
||||
new SamiModern(),
|
||||
new SamiYouTube(),
|
||||
new Scenarist(),
|
||||
new ScenaristClosedCaptions(),
|
||||
new ScenaristClosedCaptionsDropFrame(),
|
||||
new SmilTimesheetData(),
|
||||
new SoftNiSub(),
|
||||
new SoftNicolonSub(),
|
||||
new SonyDVDArchitect(),
|
||||
new SonyDVDArchitectExplicitDuration(),
|
||||
new SonyDVDArchitectLineAndDuration(),
|
||||
new SonyDVDArchitectTabs(),
|
||||
new SonyDVDArchitectWithLineNumbers(),
|
||||
new Spruce(),
|
||||
new SpruceWithSpace(),
|
||||
new StructuredTitles(),
|
||||
new SubStationAlpha(),
|
||||
new SubtitleEditorProject(),
|
||||
new SubViewer10(),
|
||||
new SubViewer20(),
|
||||
new SwiftInterchange2(),
|
||||
new SwiftText(),
|
||||
new SwiftTextLineNumber(),
|
||||
new SwiftTextLineNOAndDur(),
|
||||
new Tek(),
|
||||
new TimeXml(),
|
||||
new TimeXml2(),
|
||||
new TimedText10(),
|
||||
new TimedText200604(),
|
||||
new TimedText200604CData(),
|
||||
new TimedText(),
|
||||
new TitleExchangePro(),
|
||||
new Titra(),
|
||||
new TmpegEncText(),
|
||||
new TmpegEncAW5(),
|
||||
new TmpegEncXml(),
|
||||
new TMPlayer(),
|
||||
new TranscriberXml(),
|
||||
new Tmx14(),
|
||||
new TurboTitler(),
|
||||
new UniversalSubtitleFormat(),
|
||||
new UTSubtitleXml(),
|
||||
new Utx(),
|
||||
new UtxFrames(),
|
||||
new UleadSubtitleFormat(),
|
||||
new VocapiaSplit(),
|
||||
new WebVTT(),
|
||||
new WebVTTFileWithLineNumber(),
|
||||
new Xif(),
|
||||
new YouTubeAnnotations(),
|
||||
new YouTubeSbv(),
|
||||
new YouTubeTranscript(),
|
||||
new YouTubeTranscriptOneLine(),
|
||||
new ZeroG(),
|
||||
|
||||
// new Idx(),
|
||||
new UnknownSubtitle1(),
|
||||
new UnknownSubtitle2(),
|
||||
new UnknownSubtitle3(),
|
||||
new UnknownSubtitle4(),
|
||||
new UnknownSubtitle5(),
|
||||
new UnknownSubtitle6(),
|
||||
new UnknownSubtitle7(),
|
||||
new UnknownSubtitle8(),
|
||||
new UnknownSubtitle9(),
|
||||
new UnknownSubtitle10(),
|
||||
new UnknownSubtitle11(),
|
||||
new UnknownSubtitle12(),
|
||||
new UnknownSubtitle13(),
|
||||
new UnknownSubtitle14(),
|
||||
new UnknownSubtitle15(),
|
||||
new UnknownSubtitle16(),
|
||||
new UnknownSubtitle17(),
|
||||
new UnknownSubtitle18(),
|
||||
new UnknownSubtitle19(),
|
||||
new UnknownSubtitle20(),
|
||||
new UnknownSubtitle21(),
|
||||
new UnknownSubtitle22(),
|
||||
new UnknownSubtitle23(),
|
||||
new UnknownSubtitle24(),
|
||||
new UnknownSubtitle25(),
|
||||
new UnknownSubtitle26(),
|
||||
new UnknownSubtitle27(),
|
||||
new UnknownSubtitle28(),
|
||||
new UnknownSubtitle29(),
|
||||
new UnknownSubtitle30(),
|
||||
new UnknownSubtitle31(),
|
||||
new UnknownSubtitle32(),
|
||||
new UnknownSubtitle33(),
|
||||
new UnknownSubtitle34(),
|
||||
new UnknownSubtitle35(),
|
||||
new UnknownSubtitle36(),
|
||||
new UnknownSubtitle37(),
|
||||
new UnknownSubtitle38(),
|
||||
new UnknownSubtitle39(),
|
||||
new UnknownSubtitle40(),
|
||||
new UnknownSubtitle41(),
|
||||
new UnknownSubtitle42(),
|
||||
new UnknownSubtitle43(),
|
||||
new UnknownSubtitle44(),
|
||||
new UnknownSubtitle45(),
|
||||
new UnknownSubtitle46(),
|
||||
new UnknownSubtitle47(),
|
||||
new UnknownSubtitle48(),
|
||||
new UnknownSubtitle49(),
|
||||
new UnknownSubtitle50(),
|
||||
new UnknownSubtitle51(),
|
||||
new UnknownSubtitle52(),
|
||||
new UnknownSubtitle53(),
|
||||
new UnknownSubtitle54(),
|
||||
new UnknownSubtitle55(),
|
||||
new UnknownSubtitle56(),
|
||||
new UnknownSubtitle57(),
|
||||
new UnknownSubtitle58(),
|
||||
new UnknownSubtitle59(),
|
||||
new UnknownSubtitle60(),
|
||||
new UnknownSubtitle61(),
|
||||
new UnknownSubtitle62(),
|
||||
new UnknownSubtitle63(),
|
||||
new UnknownSubtitle64(),
|
||||
new UnknownSubtitle65(),
|
||||
new UnknownSubtitle66(),
|
||||
new UnknownSubtitle67(),
|
||||
new UnknownSubtitle68(),
|
||||
new UnknownSubtitle69(),
|
||||
new UnknownSubtitle70(),
|
||||
new UnknownSubtitle71(),
|
||||
new UnknownSubtitle72(),
|
||||
new UnknownSubtitle73(),
|
||||
new UnknownSubtitle74(),
|
||||
new UnknownSubtitle75(),
|
||||
new UnknownSubtitle76(),
|
||||
new UnknownSubtitle77(),
|
||||
new UnknownSubtitle78(),
|
||||
new UnknownSubtitle79(),
|
||||
new UnknownSubtitle80(),
|
||||
};
|
||||
|
||||
string path = Configuration.PluginsDirectory;
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
string[] pluginFiles = Directory.GetFiles(path, "*.DLL");
|
||||
foreach (string pluginFileName in pluginFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.Load(FileUtil.ReadAllBytesShared(pluginFileName));
|
||||
if (assembly != null)
|
||||
{
|
||||
foreach (var exportedType in assembly.GetExportedTypes())
|
||||
{
|
||||
try
|
||||
{
|
||||
object pluginObject = Activator.CreateInstance(exportedType);
|
||||
var po = pluginObject as SubtitleFormat;
|
||||
if (po != null)
|
||||
_allSubtitleFormats.Insert(1, po);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _allSubtitleFormats;
|
||||
}
|
||||
}
|
||||
|
||||
protected int _errorCount;
|
||||
|
||||
abstract public string Extension
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
abstract public string Name
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
abstract public bool IsTimeBased
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public bool IsFrameBased
|
||||
{
|
||||
get
|
||||
{
|
||||
return !IsTimeBased;
|
||||
}
|
||||
}
|
||||
|
||||
public string FriendlyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("{0} ({1})", Name, Extension);
|
||||
}
|
||||
}
|
||||
|
||||
public int ErrorCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
abstract public bool IsMine(List<string> lines, string fileName);
|
||||
|
||||
abstract public string ToText(Subtitle subtitle, string title);
|
||||
|
||||
abstract public void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName);
|
||||
|
||||
public bool IsVobSubIndexFile
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.CompareOrdinal(Extension, ".idx") == 0;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveNativeFormatting(Subtitle subtitle, SubtitleFormat newFormat)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual List<string> AlternateExtensions
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static int MillisecondsToFrames(double milliseconds)
|
||||
{
|
||||
return (int)Math.Round(milliseconds / (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
}
|
||||
|
||||
public static int MillisecondsToFramesMaxFrameRate(double milliseconds)
|
||||
{
|
||||
int frames = (int)Math.Round(milliseconds / (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
if (frames >= Configuration.Settings.General.CurrentFrameRate)
|
||||
frames = (int)(Configuration.Settings.General.CurrentFrameRate - 0.01);
|
||||
return frames;
|
||||
}
|
||||
|
||||
public static int FramesToMilliseconds(double frames)
|
||||
{
|
||||
return (int)Math.Round(frames * (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
}
|
||||
|
||||
public static int FramesToMillisecondsMax999(double frames)
|
||||
{
|
||||
int ms = (int)Math.Round(frames * (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
return Math.Min(ms, 999);
|
||||
}
|
||||
|
||||
public virtual bool HasStyleSupport
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool BatchMode { get; set; }
|
||||
|
||||
public static string ToUtf8XmlString(XmlDocument xml, bool omitXmlDeclaration = false)
|
||||
{
|
||||
var settings = new XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
OmitXmlDeclaration = omitXmlDeclaration,
|
||||
};
|
||||
var result = new StringBuilder();
|
||||
|
||||
using (var xmlWriter = XmlWriter.Create(result, settings))
|
||||
{
|
||||
xml.Save(xmlWriter);
|
||||
}
|
||||
|
||||
return result.ToString().Replace(" encoding=\"utf-16\"", " encoding=\"utf-8\"").Trim();
|
||||
}
|
||||
|
||||
public virtual bool IsTextBased
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected static TimeCode DecodeTimeCode(string[] parts, bool msToMaxFrame = false)
|
||||
{
|
||||
if (parts == null)
|
||||
return new TimeCode(0, 0, 0, 0);
|
||||
|
||||
int hour = 0;
|
||||
int minutes = 0;
|
||||
int seconds = 0;
|
||||
int millisecondsFrames = 0;
|
||||
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
hour = int.Parse(parts[0]);
|
||||
minutes = int.Parse(parts[1]);
|
||||
seconds = int.Parse(parts[2]);
|
||||
millisecondsFrames = int.Parse(parts[3]);
|
||||
}
|
||||
else if (parts.Length == 3)
|
||||
{
|
||||
minutes = int.Parse(parts[0]);
|
||||
seconds = int.Parse(parts[1]);
|
||||
millisecondsFrames = int.Parse(parts[2]);
|
||||
}
|
||||
else if (parts.Length == 2)
|
||||
{
|
||||
seconds = int.Parse(parts[0]);
|
||||
millisecondsFrames = int.Parse(parts[1]);
|
||||
}
|
||||
|
||||
if (!msToMaxFrame)
|
||||
return new TimeCode(hour, minutes, seconds, FramesToMillisecondsMax999(millisecondsFrames));
|
||||
|
||||
return new TimeCode(hour, minutes, seconds, MillisecondsToFramesMaxFrameRate(millisecondsFrames));
|
||||
}
|
||||
|
||||
protected static TimeCode DecodeTimeCode(string part, char[] splitChars)
|
||||
{
|
||||
return DecodeTimeCode(part.Split(splitChars, StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public abstract class SubtitleFormat
|
||||
{
|
||||
private static IList<SubtitleFormat> _allSubtitleFormats;
|
||||
|
||||
protected static readonly char[] SplitCharColon = { ':' };
|
||||
|
||||
/// <summary>
|
||||
/// Formats supported by Subtitle Edit
|
||||
/// </summary>
|
||||
public static IList<SubtitleFormat> AllSubtitleFormats
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_allSubtitleFormats != null)
|
||||
return _allSubtitleFormats;
|
||||
|
||||
_allSubtitleFormats = new List<SubtitleFormat>
|
||||
{
|
||||
new SubRip(),
|
||||
new AbcIViewer(),
|
||||
new AdobeAfterEffectsFTME(),
|
||||
new AdobeEncore(),
|
||||
new AdobeEncoreLineTabNewLine(),
|
||||
new AdobeEncoreTabs(),
|
||||
new AdobeEncoreWithLineNumbers(),
|
||||
new AdobeEncoreWithLineNumbersNtsc(),
|
||||
new AdvancedSubStationAlpha(),
|
||||
new AQTitle(),
|
||||
new AvidCaption(),
|
||||
new AvidDvd(),
|
||||
new BelleNuitSubtitler(),
|
||||
new CaptionAssistant(),
|
||||
new Captionate(),
|
||||
new CaptionateMs(),
|
||||
new CaraokeXml(),
|
||||
new Csv(),
|
||||
new Csv2(),
|
||||
new Csv3(),
|
||||
new DCSubtitle(),
|
||||
new DCinemaSmpte2010(),
|
||||
new DCinemaSmpte2007(),
|
||||
new DigiBeta(),
|
||||
new DvdStudioPro(),
|
||||
new DvdStudioProSpaceOne(),
|
||||
new DvdStudioProSpace(),
|
||||
new DvdSubtitle(),
|
||||
new DvdSubtitleSystem(),
|
||||
new Ebu(),
|
||||
new Eeg708(),
|
||||
new F4Text(),
|
||||
new F4Rtf(),
|
||||
new F4Xml(),
|
||||
new FabSubtitler(),
|
||||
new FilmEditXml(),
|
||||
new FinalCutProXml(),
|
||||
new FinalCutProXXml(),
|
||||
new FinalCutProXmlGap(),
|
||||
new FinalCutProXCM(),
|
||||
new FinalCutProXml13(),
|
||||
new FinalCutProXml14(),
|
||||
new FinalCutProXml14Text(),
|
||||
new FinalCutProTestXml(),
|
||||
new FinalCutProTest2Xml(),
|
||||
new FlashXml(),
|
||||
new FLVCoreCuePoints(),
|
||||
new Footage(),
|
||||
new GpacTtxt(),
|
||||
new ImageLogicAutocaption(),
|
||||
new IssXml(),
|
||||
new ItunesTimedText(),
|
||||
new Json(),
|
||||
new JsonType2(),
|
||||
new JsonType3(),
|
||||
new JsonType4(),
|
||||
new JsonType5(),
|
||||
new JsonType6(),
|
||||
new Lrc(),
|
||||
new MicroDvd(),
|
||||
new MidwayInscriberCGX(),
|
||||
new MPlayer2(),
|
||||
new NciTimedRollUpCaptions(),
|
||||
new OpenDvt(),
|
||||
new Oresme(),
|
||||
new OresmeDocXDocument(),
|
||||
new PE2(),
|
||||
new PinnacleImpression(),
|
||||
new PListCaption(),
|
||||
new QubeMasterImport(),
|
||||
new QuickTimeText(),
|
||||
new RealTime(),
|
||||
new RhozetHarmonic(),
|
||||
new Sami(),
|
||||
new SamiModern(),
|
||||
new SamiYouTube(),
|
||||
new Scenarist(),
|
||||
new ScenaristClosedCaptions(),
|
||||
new ScenaristClosedCaptionsDropFrame(),
|
||||
new SmilTimesheetData(),
|
||||
new SoftNiSub(),
|
||||
new SoftNicolonSub(),
|
||||
new SonyDVDArchitect(),
|
||||
new SonyDVDArchitectExplicitDuration(),
|
||||
new SonyDVDArchitectLineAndDuration(),
|
||||
new SonyDVDArchitectTabs(),
|
||||
new SonyDVDArchitectWithLineNumbers(),
|
||||
new Spruce(),
|
||||
new SpruceWithSpace(),
|
||||
new StructuredTitles(),
|
||||
new SubStationAlpha(),
|
||||
new SubtitleEditorProject(),
|
||||
new SubViewer10(),
|
||||
new SubViewer20(),
|
||||
new SwiftInterchange2(),
|
||||
new SwiftText(),
|
||||
new SwiftTextLineNumber(),
|
||||
new SwiftTextLineNOAndDur(),
|
||||
new Tek(),
|
||||
new TimeXml(),
|
||||
new TimeXml2(),
|
||||
new TimedText10(),
|
||||
new TimedText200604(),
|
||||
new TimedText200604CData(),
|
||||
new TimedText(),
|
||||
new TitleExchangePro(),
|
||||
new Titra(),
|
||||
new TmpegEncText(),
|
||||
new TmpegEncAW5(),
|
||||
new TmpegEncXml(),
|
||||
new TMPlayer(),
|
||||
new TranscriberXml(),
|
||||
new Tmx14(),
|
||||
new TurboTitler(),
|
||||
new UniversalSubtitleFormat(),
|
||||
new UTSubtitleXml(),
|
||||
new Utx(),
|
||||
new UtxFrames(),
|
||||
new UleadSubtitleFormat(),
|
||||
new VocapiaSplit(),
|
||||
new WebVTT(),
|
||||
new WebVTTFileWithLineNumber(),
|
||||
new Xif(),
|
||||
new YouTubeAnnotations(),
|
||||
new YouTubeSbv(),
|
||||
new YouTubeTranscript(),
|
||||
new YouTubeTranscriptOneLine(),
|
||||
new ZeroG(),
|
||||
// new Idx(),
|
||||
new UnknownSubtitle1(),
|
||||
new UnknownSubtitle2(),
|
||||
new UnknownSubtitle3(),
|
||||
new UnknownSubtitle4(),
|
||||
new UnknownSubtitle5(),
|
||||
new UnknownSubtitle6(),
|
||||
new UnknownSubtitle7(),
|
||||
new UnknownSubtitle8(),
|
||||
new UnknownSubtitle9(),
|
||||
new UnknownSubtitle10(),
|
||||
new UnknownSubtitle11(),
|
||||
new UnknownSubtitle12(),
|
||||
new UnknownSubtitle13(),
|
||||
new UnknownSubtitle14(),
|
||||
new UnknownSubtitle15(),
|
||||
new UnknownSubtitle16(),
|
||||
new UnknownSubtitle17(),
|
||||
new UnknownSubtitle18(),
|
||||
new UnknownSubtitle19(),
|
||||
new UnknownSubtitle20(),
|
||||
new UnknownSubtitle21(),
|
||||
new UnknownSubtitle22(),
|
||||
new UnknownSubtitle23(),
|
||||
new UnknownSubtitle24(),
|
||||
new UnknownSubtitle25(),
|
||||
new UnknownSubtitle26(),
|
||||
new UnknownSubtitle27(),
|
||||
new UnknownSubtitle28(),
|
||||
new UnknownSubtitle29(),
|
||||
new UnknownSubtitle30(),
|
||||
new UnknownSubtitle31(),
|
||||
new UnknownSubtitle32(),
|
||||
new UnknownSubtitle33(),
|
||||
new UnknownSubtitle34(),
|
||||
new UnknownSubtitle35(),
|
||||
new UnknownSubtitle36(),
|
||||
new UnknownSubtitle37(),
|
||||
new UnknownSubtitle38(),
|
||||
new UnknownSubtitle39(),
|
||||
new UnknownSubtitle40(),
|
||||
new UnknownSubtitle41(),
|
||||
new UnknownSubtitle42(),
|
||||
new UnknownSubtitle43(),
|
||||
new UnknownSubtitle44(),
|
||||
new UnknownSubtitle45(),
|
||||
new UnknownSubtitle46(),
|
||||
new UnknownSubtitle47(),
|
||||
new UnknownSubtitle48(),
|
||||
new UnknownSubtitle49(),
|
||||
new UnknownSubtitle50(),
|
||||
new UnknownSubtitle51(),
|
||||
new UnknownSubtitle52(),
|
||||
new UnknownSubtitle53(),
|
||||
new UnknownSubtitle54(),
|
||||
new UnknownSubtitle55(),
|
||||
new UnknownSubtitle56(),
|
||||
new UnknownSubtitle57(),
|
||||
new UnknownSubtitle58(),
|
||||
new UnknownSubtitle59(),
|
||||
new UnknownSubtitle60(),
|
||||
new UnknownSubtitle61(),
|
||||
new UnknownSubtitle62(),
|
||||
new UnknownSubtitle63(),
|
||||
new UnknownSubtitle64(),
|
||||
new UnknownSubtitle65(),
|
||||
new UnknownSubtitle66(),
|
||||
new UnknownSubtitle67(),
|
||||
new UnknownSubtitle68(),
|
||||
new UnknownSubtitle69(),
|
||||
new UnknownSubtitle70(),
|
||||
new UnknownSubtitle71(),
|
||||
new UnknownSubtitle72(),
|
||||
new UnknownSubtitle73(),
|
||||
new UnknownSubtitle74(),
|
||||
new UnknownSubtitle75(),
|
||||
new UnknownSubtitle76(),
|
||||
new UnknownSubtitle77(),
|
||||
new UnknownSubtitle78(),
|
||||
new UnknownSubtitle79(),
|
||||
new UnknownSubtitle80(),
|
||||
};
|
||||
|
||||
string path = Configuration.PluginsDirectory;
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
string[] pluginFiles = Directory.GetFiles(path, "*.DLL");
|
||||
foreach (string pluginFileName in pluginFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.Load(FileUtil.ReadAllBytesShared(pluginFileName));
|
||||
if (assembly != null)
|
||||
{
|
||||
foreach (var exportedType in assembly.GetExportedTypes())
|
||||
{
|
||||
try
|
||||
{
|
||||
object pluginObject = Activator.CreateInstance(exportedType);
|
||||
var po = pluginObject as SubtitleFormat;
|
||||
if (po != null)
|
||||
_allSubtitleFormats.Insert(1, po);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _allSubtitleFormats;
|
||||
}
|
||||
}
|
||||
|
||||
protected int _errorCount;
|
||||
|
||||
abstract public string Extension
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
abstract public string Name
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
abstract public bool IsTimeBased
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public bool IsFrameBased
|
||||
{
|
||||
get
|
||||
{
|
||||
return !IsTimeBased;
|
||||
}
|
||||
}
|
||||
|
||||
public string FriendlyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("{0} ({1})", Name, Extension);
|
||||
}
|
||||
}
|
||||
|
||||
public int ErrorCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
abstract public bool IsMine(List<string> lines, string fileName);
|
||||
|
||||
abstract public string ToText(Subtitle subtitle, string title);
|
||||
|
||||
abstract public void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName);
|
||||
|
||||
public bool IsVobSubIndexFile
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.CompareOrdinal(Extension, ".idx") == 0;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveNativeFormatting(Subtitle subtitle, SubtitleFormat newFormat)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual List<string> AlternateExtensions
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static int MillisecondsToFrames(double milliseconds)
|
||||
{
|
||||
return (int)Math.Round(milliseconds / (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
}
|
||||
|
||||
public static int MillisecondsToFramesMaxFrameRate(double milliseconds)
|
||||
{
|
||||
int frames = (int)Math.Round(milliseconds / (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
if (frames >= Configuration.Settings.General.CurrentFrameRate)
|
||||
frames = (int)(Configuration.Settings.General.CurrentFrameRate - 0.01);
|
||||
return frames;
|
||||
}
|
||||
|
||||
public static int FramesToMilliseconds(double frames)
|
||||
{
|
||||
return (int)Math.Round(frames * (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
}
|
||||
|
||||
public static int FramesToMillisecondsMax999(double frames)
|
||||
{
|
||||
int ms = (int)Math.Round(frames * (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate));
|
||||
return Math.Min(ms, 999);
|
||||
}
|
||||
|
||||
public virtual bool HasStyleSupport
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool BatchMode { get; set; }
|
||||
|
||||
public static string ToUtf8XmlString(XmlDocument xml, bool omitXmlDeclaration = false)
|
||||
{
|
||||
var settings = new XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
OmitXmlDeclaration = omitXmlDeclaration,
|
||||
};
|
||||
var result = new StringBuilder();
|
||||
|
||||
using (var xmlWriter = XmlWriter.Create(result, settings))
|
||||
{
|
||||
xml.Save(xmlWriter);
|
||||
}
|
||||
|
||||
return result.ToString().Replace(" encoding=\"utf-16\"", " encoding=\"utf-8\"").Trim();
|
||||
}
|
||||
|
||||
public virtual bool IsTextBased
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected static TimeCode DecodeTimeCodeFrames(string[] parts)
|
||||
{
|
||||
if (parts == null)
|
||||
return new TimeCode(0, 0, 0, 0);
|
||||
|
||||
int hour = 0;
|
||||
int minutes = 0;
|
||||
int seconds = 0;
|
||||
int frames = 0;
|
||||
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
hour = int.Parse(parts[0]);
|
||||
minutes = int.Parse(parts[1]);
|
||||
seconds = int.Parse(parts[2]);
|
||||
frames = int.Parse(parts[3]);
|
||||
}
|
||||
else if (parts.Length == 3)
|
||||
{
|
||||
minutes = int.Parse(parts[0]);
|
||||
seconds = int.Parse(parts[1]);
|
||||
frames = int.Parse(parts[2]);
|
||||
}
|
||||
else if (parts.Length == 2)
|
||||
{
|
||||
seconds = int.Parse(parts[0]);
|
||||
frames = int.Parse(parts[1]);
|
||||
}
|
||||
|
||||
return new TimeCode(hour, minutes, seconds, FramesToMillisecondsMax999(frames));
|
||||
}
|
||||
|
||||
protected static TimeCode DecodeTimeCodeFrames(string part, char[] splitChars)
|
||||
{
|
||||
return DecodeTimeCodeFrames(part.Split(splitChars, StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,205 +1,205 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// Timeline Ascii export - THE MOVIE TITRE EDITOR - http://www.pld.ttu.ee/~priidu/timeline/ by priidu@pld.ttu.ee
|
||||
///
|
||||
/// Sample:
|
||||
/// 1.
|
||||
/// 00:00:43.02
|
||||
/// 00:00:47.03
|
||||
/// ±NE/SEVÎ
|
||||
/// ³ÂÍÅ/ÑÅÁß
|
||||
///
|
||||
/// 2.
|
||||
/// 00:01:36.00
|
||||
/// 00:01:37.00
|
||||
/// ±Viòð ir klât.
|
||||
/// ³Îí ïðèøåë.
|
||||
/// </summary>
|
||||
public class TimeLineAscii : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".asc"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Timeline ascii"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (fileName == null || !fileName.EndsWith(Extension, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
var expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
byte firstLineCode = 0;
|
||||
byte secondLineCode = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
IEnumerable<byte[]> byteLines = SplitBytesToLines(File.ReadAllBytes(fileName));
|
||||
foreach (byte[] bytes in byteLines)
|
||||
{
|
||||
var line = Encoding.ASCII.GetString(bytes);
|
||||
if (line.EndsWith('.') && Utilities.IsInteger(line.TrimEnd('.')))
|
||||
{
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ':', '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ':', '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (bytes.Length > 1)
|
||||
{
|
||||
// get text from encoding
|
||||
var enc = GetEncodingFromLanguage(bytes[0]);
|
||||
string s = enc.GetString(bytes, 1, bytes.Length - 1).Trim();
|
||||
|
||||
// italic text
|
||||
if (s.StartsWith('#'))
|
||||
s = "<i>" + s.Remove(0, 1) + "</i>";
|
||||
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
|
||||
if (paragraph.Text.Contains(Environment.NewLine))
|
||||
{
|
||||
if (secondLineCode == 0)
|
||||
secondLineCode = bytes[0];
|
||||
if (secondLineCode != bytes[0])
|
||||
_errorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (firstLineCode == 0)
|
||||
firstLineCode = bytes[0];
|
||||
if (firstLineCode != bytes[0])
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private IEnumerable<byte[]> SplitBytesToLines(byte[] bytes)
|
||||
{
|
||||
var list = new List<byte[]>();
|
||||
int start = 0;
|
||||
int index = 0;
|
||||
while (index < bytes.Length)
|
||||
{
|
||||
if (bytes[index] == 13)
|
||||
{
|
||||
int length = index - start;
|
||||
var lineBytes = new byte[length];
|
||||
Array.Copy(bytes, start, lineBytes, 0, length);
|
||||
list.Add(lineBytes);
|
||||
index += 2;
|
||||
start = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private Encoding GetEncodingFromLanguage(byte language)
|
||||
{
|
||||
if (language == 179) // Russian
|
||||
return Encoding.GetEncoding(1251);
|
||||
|
||||
if (language == 177) // Baltic
|
||||
return Encoding.GetEncoding(1257);
|
||||
|
||||
return Encoding.GetEncoding(1252);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// Timeline Ascii export - THE MOVIE TITRE EDITOR - http://www.pld.ttu.ee/~priidu/timeline/ by priidu@pld.ttu.ee
|
||||
///
|
||||
/// Sample:
|
||||
/// 1.
|
||||
/// 00:00:43.02
|
||||
/// 00:00:47.03
|
||||
/// ±NE/SEVÎ
|
||||
/// ³ÂÍÅ/ÑÅÁß
|
||||
///
|
||||
/// 2.
|
||||
/// 00:01:36.00
|
||||
/// 00:01:37.00
|
||||
/// ±Viòð ir klât.
|
||||
/// ³Îí ïðèøåë.
|
||||
/// </summary>
|
||||
public class TimeLineAscii : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".asc"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Timeline ascii"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (fileName == null || !fileName.EndsWith(Extension, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
var expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
byte firstLineCode = 0;
|
||||
byte secondLineCode = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
IEnumerable<byte[]> byteLines = SplitBytesToLines(File.ReadAllBytes(fileName));
|
||||
foreach (byte[] bytes in byteLines)
|
||||
{
|
||||
var line = Encoding.ASCII.GetString(bytes);
|
||||
if (line.EndsWith('.') && Utilities.IsInteger(line.TrimEnd('.')))
|
||||
{
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ':', '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ':', '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (bytes.Length > 1)
|
||||
{
|
||||
// get text from encoding
|
||||
var enc = GetEncodingFromLanguage(bytes[0]);
|
||||
string s = enc.GetString(bytes, 1, bytes.Length - 1).Trim();
|
||||
|
||||
// italic text
|
||||
if (s.StartsWith('#'))
|
||||
s = "<i>" + s.Remove(0, 1) + "</i>";
|
||||
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
|
||||
if (paragraph.Text.Contains(Environment.NewLine))
|
||||
{
|
||||
if (secondLineCode == 0)
|
||||
secondLineCode = bytes[0];
|
||||
if (secondLineCode != bytes[0])
|
||||
_errorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (firstLineCode == 0)
|
||||
firstLineCode = bytes[0];
|
||||
if (firstLineCode != bytes[0])
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private IEnumerable<byte[]> SplitBytesToLines(byte[] bytes)
|
||||
{
|
||||
var list = new List<byte[]>();
|
||||
int start = 0;
|
||||
int index = 0;
|
||||
while (index < bytes.Length)
|
||||
{
|
||||
if (bytes[index] == 13)
|
||||
{
|
||||
int length = index - start;
|
||||
var lineBytes = new byte[length];
|
||||
Array.Copy(bytes, start, lineBytes, 0, length);
|
||||
list.Add(lineBytes);
|
||||
index += 2;
|
||||
start = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private Encoding GetEncodingFromLanguage(byte language)
|
||||
{
|
||||
if (language == 179) // Russian
|
||||
return Encoding.GetEncoding(1251);
|
||||
|
||||
if (language == 177) // Baltic
|
||||
return Encoding.GetEncoding(1257);
|
||||
|
||||
return Encoding.GetEncoding(1252);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,127 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class TitleExchangePro : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d,\t[ ]?\d\d:\d\d:\d\d:\d\d,\t[ ]?", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "TitleExchange Pro"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER\tSTART\tEND\tFILE_NAME"))
|
||||
return false; // SON
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:01:48:22, 00:01:52:17, - I need those samples, fast!//- Yes, professor.
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "@Italic@");
|
||||
text = text.Replace("</i>", "@Italic@");
|
||||
text = text.Replace(Environment.NewLine, "//");
|
||||
sb.AppendLine(string.Format("{0},\t{1},\t{2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(text)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:01:48:22, 00:01:52:17, - I need those samples, fast!//- Yes, professor.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Replace(" ", "\t");
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split('\t');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0].TrimEnd(',');
|
||||
string end = temp[1].TrimEnd(',');
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = s.Remove(0, RegexTimeCodes.Match(s).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
if (text.Contains("@Italic@"))
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (text.Contains("@Italic@"))
|
||||
{
|
||||
var index = text.IndexOf("@Italic@", StringComparison.Ordinal);
|
||||
string italicTag = "<i>";
|
||||
if (italicOn)
|
||||
italicTag = "</i>";
|
||||
text = text.Remove(index, "@Italic@".Length).Insert(index, italicTag);
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
text = HtmlUtil.FixInvalidItalicTags(text);
|
||||
}
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class TitleExchangePro : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d,\t[ ]?\d\d:\d\d:\d\d:\d\d,\t[ ]?", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "TitleExchange Pro"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
if (sb.ToString().Contains(Environment.NewLine + "SP_NUMBER\tSTART\tEND\tFILE_NAME"))
|
||||
return false; // SON
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:01:48:22, 00:01:52:17, - I need those samples, fast!//- Yes, professor.
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "@Italic@");
|
||||
text = text.Replace("</i>", "@Italic@");
|
||||
text = text.Replace(Environment.NewLine, "//");
|
||||
sb.AppendLine(string.Format("{0},\t{1},\t{2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(text)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:01:48:22, 00:01:52:17, - I need those samples, fast!//- Yes, professor.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Replace(" ", "\t");
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
var temp = s.Split('\t');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0].TrimEnd(',');
|
||||
string end = temp[1].TrimEnd(',');
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = s.Remove(0, RegexTimeCodes.Match(s).Length - 1).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
if (text.Contains("@Italic@"))
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (text.Contains("@Italic@"))
|
||||
{
|
||||
var index = text.IndexOf("@Italic@", StringComparison.Ordinal);
|
||||
string italicTag = "<i>";
|
||||
if (italicOn)
|
||||
italicTag = "</i>";
|
||||
text = text.Remove(index, "@Italic@".Length).Insert(index, italicTag);
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
text = HtmlUtil.FixInvalidItalicTags(text);
|
||||
}
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,128 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Titra : SubtitleFormat
|
||||
{
|
||||
//* 1 : 01:01:31:19 01:01:33:04 22c
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\* \d+ :\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t\d+c", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Titra"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static int GetMaxCharsForDuration(double durationSeconds)
|
||||
{
|
||||
return (int)Math.Round(15.7 * durationSeconds);
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"TVS - TITRA FILM
|
||||
|
||||
Titre VO : L'heure d'été
|
||||
Titre VST :
|
||||
Création : 23/10/2009 - 16:31
|
||||
Révision : 26/10/2009 - 17:48
|
||||
Langue VO : Français
|
||||
Langue VST : Espagnol
|
||||
Bobine : e01
|
||||
|
||||
BEWARE : No more than 40 characters ON A LINE
|
||||
ATTENTION : Pas plus de 40 caractères PAR LIGNE
|
||||
|
||||
");
|
||||
const string writeFormat = "* {0} :\t{1}\t{2}\t{3}{4}{5}";
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
var text = HtmlUtil.RemoveHtmlTags(p.Text, true);
|
||||
sb.AppendLine(string.Format(writeFormat, index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), GetMaxCharsForDuration(p.Duration.TotalSeconds) + "c", Environment.NewLine, text));
|
||||
sb.AppendLine();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
try
|
||||
{
|
||||
var arr = line.Split('\t');
|
||||
string start = arr[1];
|
||||
string end = arr[2];
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount += 10;
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Titra : SubtitleFormat
|
||||
{
|
||||
//* 1 : 01:01:31:19 01:01:33:04 22c
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\* \d+ :\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t\d+c", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Titra"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static int GetMaxCharsForDuration(double durationSeconds)
|
||||
{
|
||||
return (int)Math.Round(15.7 * durationSeconds);
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"TVS - TITRA FILM
|
||||
|
||||
Titre VO : L'heure d'été
|
||||
Titre VST :
|
||||
Création : 23/10/2009 - 16:31
|
||||
Révision : 26/10/2009 - 17:48
|
||||
Langue VO : Français
|
||||
Langue VST : Espagnol
|
||||
Bobine : e01
|
||||
|
||||
BEWARE : No more than 40 characters ON A LINE
|
||||
ATTENTION : Pas plus de 40 caractères PAR LIGNE
|
||||
|
||||
");
|
||||
const string writeFormat = "* {0} :\t{1}\t{2}\t{3}{4}{5}";
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
var text = HtmlUtil.RemoveHtmlTags(p.Text, true);
|
||||
sb.AppendLine(string.Format(writeFormat, index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), GetMaxCharsForDuration(p.Duration.TotalSeconds) + "c", Environment.NewLine, text));
|
||||
sb.AppendLine();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
try
|
||||
{
|
||||
var arr = line.Split('\t');
|
||||
string start = arr[1];
|
||||
string end = arr[2];
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount += 10;
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,182 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle17 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexNumber = new Regex(@"^\[\d+\]$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 17"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
string s = sb.ToString();
|
||||
if (!s.Contains("[HEADER]") || !s.Contains("[BODY]"))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//[1]
|
||||
//01:00:21:20
|
||||
//01:00:23:17
|
||||
//[I]Pysy kanavalla,
|
||||
//[I]koska myöhemmin tänään
|
||||
|
||||
const string paragraphWriteFormat = "[{4}]{3}{0}{3}{1}{3}{2}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"[HEADER]
|
||||
SUBTITLING_COMPANY=Softitler Net, Inc.
|
||||
TIME_FORMAT=NTSC
|
||||
CLIENT=UNIVERSAL
|
||||
LANGUAGE=Finnish
|
||||
DATE=5/28/2007
|
||||
JOB_ID=89972
|
||||
JOB_TYPE=Feature
|
||||
TITLE=Notting Hill
|
||||
SUBNAME=BD TRTL
|
||||
YEAR=1999
|
||||
DIGITAL_CINEMA=YES
|
||||
[/HEADER]
|
||||
[BODY]");
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
string text = p.Text.Replace("<i>", "[I]").Replace("</i>", "[/I]");
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
sb.AppendLine("[/BODY]");
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
var expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string l in lines)
|
||||
{
|
||||
string line = l.Replace("[L]", string.Empty).Replace("[N]", string.Empty).TrimEnd();
|
||||
if (RegexNumber.IsMatch(line))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
if (line.StartsWith("[i]", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
s = "<i>" + s.Remove(0, 3);
|
||||
if (s.EndsWith("[/i]", StringComparison.OrdinalIgnoreCase))
|
||||
s = s.Remove(s.Length - 4, 4);
|
||||
s += "</i>";
|
||||
}
|
||||
s = s.Replace("[I]", "<i>");
|
||||
s = s.Replace("[/I]", "</i>");
|
||||
s = s.Replace("[P]", string.Empty);
|
||||
s = s.Replace("[/P]", string.Empty);
|
||||
s = s.Replace("\0", string.Empty);
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
subtitle.Renumber();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
{
|
||||
paragraph.Text = paragraph.Text.Replace("[/BODY]", string.Empty).Trim();
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle17 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexNumber = new Regex(@"^\[\d+\]$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 17"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
string s = sb.ToString();
|
||||
if (!s.Contains("[HEADER]") || !s.Contains("[BODY]"))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//[1]
|
||||
//01:00:21:20
|
||||
//01:00:23:17
|
||||
//[I]Pysy kanavalla,
|
||||
//[I]koska myöhemmin tänään
|
||||
|
||||
const string paragraphWriteFormat = "[{4}]{3}{0}{3}{1}{3}{2}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"[HEADER]
|
||||
SUBTITLING_COMPANY=Softitler Net, Inc.
|
||||
TIME_FORMAT=NTSC
|
||||
CLIENT=UNIVERSAL
|
||||
LANGUAGE=Finnish
|
||||
DATE=5/28/2007
|
||||
JOB_ID=89972
|
||||
JOB_TYPE=Feature
|
||||
TITLE=Notting Hill
|
||||
SUBNAME=BD TRTL
|
||||
YEAR=1999
|
||||
DIGITAL_CINEMA=YES
|
||||
[/HEADER]
|
||||
[BODY]");
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
string text = p.Text.Replace("<i>", "[I]").Replace("</i>", "[/I]");
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
sb.AppendLine("[/BODY]");
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
var expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string l in lines)
|
||||
{
|
||||
string line = l.Replace("[L]", string.Empty).Replace("[N]", string.Empty).TrimEnd();
|
||||
if (RegexNumber.IsMatch(line))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
if (line.StartsWith("[i]", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
s = "<i>" + s.Remove(0, 3);
|
||||
if (s.EndsWith("[/i]", StringComparison.OrdinalIgnoreCase))
|
||||
s = s.Remove(s.Length - 4, 4);
|
||||
s += "</i>";
|
||||
}
|
||||
s = s.Replace("[I]", "<i>");
|
||||
s = s.Replace("[/I]", "</i>");
|
||||
s = s.Replace("[P]", string.Empty);
|
||||
s = s.Replace("[/P]", string.Empty);
|
||||
s = s.Replace("\0", string.Empty);
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
subtitle.Renumber();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
{
|
||||
paragraph.Text = paragraph.Text.Replace("[/BODY]", string.Empty).Trim();
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,148 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle20 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode1 = new Regex(@"^ \d\d:\d\d:\d\d:\d\d \d\d\d\d ", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode1Empty = new Regex(@"^ \d\d:\d\d:\d\d:\d\d \d\d\d\d$", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode2 = new Regex(@"^ \d\d:\d\d:\d\d:\d\d \d\d\d\-\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".C"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 20"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int number = 1;
|
||||
int number2 = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string line1 = string.Empty;
|
||||
string line2 = string.Empty;
|
||||
string[] lines = p.Text.Replace(Environment.NewLine, "\r").Split('\r');
|
||||
if (lines.Length > 2)
|
||||
lines = Utilities.AutoBreakLine(p.Text).Replace(Environment.NewLine, "\r").Split('\r');
|
||||
if (lines.Length == 1)
|
||||
{
|
||||
line2 = lines[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
line1 = lines[0];
|
||||
line2 = lines[1];
|
||||
}
|
||||
|
||||
// line 1
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append(p.StartTime.ToHHMMSSFF());
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append(number.ToString("D4"));
|
||||
sb.Append(string.Empty.PadLeft(12, ' '));
|
||||
sb.AppendLine(line1);
|
||||
|
||||
//line 2
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append(p.EndTime.ToHHMMSSFF());
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append((number2 / 7 + 1).ToString("D3"));
|
||||
sb.Append('-');
|
||||
sb.Append((number2 % 7 + 1).ToString("D2"));
|
||||
sb.Append(string.Empty.PadLeft(10, ' '));
|
||||
sb.AppendLine(line2);
|
||||
sb.AppendLine();
|
||||
|
||||
number++;
|
||||
number2++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode1.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph(DecodeTimeCode(s.Substring(5, 11), SplitCharColon), new TimeCode(0, 0, 0, 0), s.Remove(0, 37).Trim());
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (RegexTimeCode1Empty.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph(DecodeTimeCode(s.Substring(5, 11), SplitCharColon), new TimeCode(0, 0, 0, 0), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (RegexTimeCode2.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.EndTime = DecodeTimeCode(s.Substring(5, 11), SplitCharColon);
|
||||
if (string.IsNullOrWhiteSpace(p.Text))
|
||||
p.Text = s.Remove(0, 37).Trim();
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + s.Remove(0, 37).Trim();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle20 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode1 = new Regex(@"^ \d\d:\d\d:\d\d:\d\d \d\d\d\d ", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode1Empty = new Regex(@"^ \d\d:\d\d:\d\d:\d\d \d\d\d\d$", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode2 = new Regex(@"^ \d\d:\d\d:\d\d:\d\d \d\d\d\-\d\d ", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".C"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 20"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int number = 1;
|
||||
int number2 = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string line1 = string.Empty;
|
||||
string line2 = string.Empty;
|
||||
string[] lines = p.Text.Replace(Environment.NewLine, "\r").Split('\r');
|
||||
if (lines.Length > 2)
|
||||
lines = Utilities.AutoBreakLine(p.Text).Replace(Environment.NewLine, "\r").Split('\r');
|
||||
if (lines.Length == 1)
|
||||
{
|
||||
line2 = lines[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
line1 = lines[0];
|
||||
line2 = lines[1];
|
||||
}
|
||||
|
||||
// line 1
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append(p.StartTime.ToHHMMSSFF());
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append(number.ToString("D4"));
|
||||
sb.Append(string.Empty.PadLeft(12, ' '));
|
||||
sb.AppendLine(line1);
|
||||
|
||||
//line 2
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append(p.EndTime.ToHHMMSSFF());
|
||||
sb.Append(string.Empty.PadLeft(5, ' '));
|
||||
sb.Append((number2 / 7 + 1).ToString("D3"));
|
||||
sb.Append('-');
|
||||
sb.Append((number2 % 7 + 1).ToString("D2"));
|
||||
sb.Append(string.Empty.PadLeft(10, ' '));
|
||||
sb.AppendLine(line2);
|
||||
sb.AppendLine();
|
||||
|
||||
number++;
|
||||
number2++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode1.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(s.Substring(5, 11), SplitCharColon), new TimeCode(0, 0, 0, 0), s.Remove(0, 37).Trim());
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (RegexTimeCode1Empty.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(s.Substring(5, 11), SplitCharColon), new TimeCode(0, 0, 0, 0), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (RegexTimeCode2.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.EndTime = DecodeTimeCodeFrames(s.Substring(5, 11), SplitCharColon);
|
||||
if (string.IsNullOrWhiteSpace(p.Text))
|
||||
p.Text = s.Remove(0, 37).Trim();
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + s.Remove(0, 37).Trim();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,129 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle21 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode1 = new Regex(@"^\s*\d+\t\d\d:\d\d:\d\d;\d\d", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 21"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00};{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#\tAppearance\tCaption\t");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}\t", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.StartTime), text));
|
||||
sb.AppendLine("\t\t\t\t");
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next == null || Math.Abs(p.EndTime.TotalMilliseconds - next.StartTime.TotalMilliseconds) > 50)
|
||||
{
|
||||
count++;
|
||||
sb.AppendLine(string.Format("{0}\t{1}", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.EndTime)));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf"))
|
||||
return;
|
||||
|
||||
lines = rtf.FromRtf().SplitToLines().ToList();
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
char[] splitChar = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode1.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length > 2)
|
||||
p = new Paragraph(DecodeTimeCode(arr[1], splitChar), new TimeCode(0, 0, 0, 0), arr[2].Trim());
|
||||
else
|
||||
p = new Paragraph(DecodeTimeCode(arr[1], splitChar), new TimeCode(0, 0, 0, 0), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (s.StartsWith("\t\t", StringComparison.Ordinal))
|
||||
{
|
||||
if (p != null)
|
||||
p.Text = p.Text + Environment.NewLine + s.Trim();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
for (int j = 0; j < subtitle.Paragraphs.Count - 1; j++)
|
||||
{
|
||||
p = subtitle.Paragraphs[j];
|
||||
Paragraph next = subtitle.Paragraphs[j + 1];
|
||||
p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
p = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1];
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle21 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode1 = new Regex(@"^\s*\d+\t\d\d:\d\d:\d\d;\d\d", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 21"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00};{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#\tAppearance\tCaption\t");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2}\t", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.StartTime), text));
|
||||
sb.AppendLine("\t\t\t\t");
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next == null || Math.Abs(p.EndTime.TotalMilliseconds - next.StartTime.TotalMilliseconds) > 50)
|
||||
{
|
||||
count++;
|
||||
sb.AppendLine(string.Format("{0}\t{1}", count.ToString().PadLeft(5, ' '), MakeTimeCode(p.EndTime)));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf"))
|
||||
return;
|
||||
|
||||
lines = rtf.FromRtf().SplitToLines().ToList();
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
char[] splitChar = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode1.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length > 2)
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[1], splitChar), new TimeCode(0, 0, 0, 0), arr[2].Trim());
|
||||
else
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[1], splitChar), new TimeCode(0, 0, 0, 0), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (s.StartsWith("\t\t", StringComparison.Ordinal))
|
||||
{
|
||||
if (p != null)
|
||||
p.Text = p.Text + Environment.NewLine + s.Trim();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
for (int j = 0; j < subtitle.Paragraphs.Count - 1; j++)
|
||||
{
|
||||
p = subtitle.Paragraphs[j];
|
||||
Paragraph next = subtitle.Paragraphs[j + 1];
|
||||
p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
p = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1];
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,117 +1,117 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle22 : SubtitleFormat
|
||||
{
|
||||
|
||||
//25 10:03:20:23 02:07 10:03:23:05
|
||||
//I see, on my way.
|
||||
//
|
||||
//26 10:03:31:18 02:07 10:03:34:00
|
||||
//Panessa, why didn't they give them
|
||||
//an escape route ?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 22"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#\tAppearance\tCaption\t");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
|
||||
// to avoid rounding errors in duration
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2:00}:{3:00}\t{4}\r\n{5}\r\n", count, MakeTimeCode(p.StartTime), durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds), MakeTimeCode(p.EndTime), text));
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(arr[1], splitChars), DecodeTimeCode(arr[3], splitChars), string.Empty);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle22 : SubtitleFormat
|
||||
{
|
||||
|
||||
//25 10:03:20:23 02:07 10:03:23:05
|
||||
//I see, on my way.
|
||||
//
|
||||
//26 10:03:31:18 02:07 10:03:34:00
|
||||
//Panessa, why didn't they give them
|
||||
//an escape route ?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 22"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("#\tAppearance\tCaption\t");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
|
||||
// to avoid rounding errors in duration
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
|
||||
sb.AppendLine(string.Format("{0}\t{1}\t{2:00}:{3:00}\t{4}\r\n{5}\r\n", count, MakeTimeCode(p.StartTime), durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds), MakeTimeCode(p.EndTime), text));
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[1], splitChars), DecodeTimeCodeFrames(arr[3], splitChars), string.Empty);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,138 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle26 : SubtitleFormat
|
||||
{
|
||||
|
||||
//L'Enfant d'en haut
|
||||
//1ab
|
||||
|
||||
//10/01/2012
|
||||
//10/01/2012
|
||||
//01:00:22.09
|
||||
//01:00:30.09
|
||||
//**:**:**.**
|
||||
//**:**:**.**
|
||||
//01:00:51.09
|
||||
//01:00:55.22
|
||||
//01:01:10.09
|
||||
//**:**:**.**
|
||||
//**:**:**.**
|
||||
//01:13:23.09
|
||||
//
|
||||
//1: 01:01:28.22 01:01:33.09*
|
||||
// SISTER
|
||||
//
|
||||
//2:
|
||||
//01:02:58.15 01:03:00.00
|
||||
//I'm pooping, sir.
|
||||
//Were they easy to get?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+: \d\d:\d\d:\d\d.\d\d \d\d:\d\d:\d\d.\d\d[\*]*$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 26"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(title);
|
||||
sb.AppendLine(@"1ab
|
||||
|
||||
10/01/2012
|
||||
10/01/2012
|
||||
01:00:22.09
|
||||
01:00:30.09
|
||||
**:**:**.**
|
||||
**:**:**.**
|
||||
01:00:51.09
|
||||
01:00:55.22
|
||||
01:01:10.09
|
||||
**:**:**.**
|
||||
**:**:**.**
|
||||
01:13:23.09");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}: {1} {2}\r\n{3}\r\n", count, MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text));
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
char[] splitChars = { ':', ';', ',', '.' };
|
||||
if (arr.Length == 3)
|
||||
p = new Paragraph(DecodeTimeCode(arr[1].TrimEnd('*'), splitChars), DecodeTimeCode(arr[2].TrimEnd('*'), splitChars), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle26 : SubtitleFormat
|
||||
{
|
||||
|
||||
//L'Enfant d'en haut
|
||||
//1ab
|
||||
|
||||
//10/01/2012
|
||||
//10/01/2012
|
||||
//01:00:22.09
|
||||
//01:00:30.09
|
||||
//**:**:**.**
|
||||
//**:**:**.**
|
||||
//01:00:51.09
|
||||
//01:00:55.22
|
||||
//01:01:10.09
|
||||
//**:**:**.**
|
||||
//**:**:**.**
|
||||
//01:13:23.09
|
||||
//
|
||||
//1: 01:01:28.22 01:01:33.09*
|
||||
// SISTER
|
||||
//
|
||||
//2:
|
||||
//01:02:58.15 01:03:00.00
|
||||
//I'm pooping, sir.
|
||||
//Were they easy to get?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+: \d\d:\d\d:\d\d.\d\d \d\d:\d\d:\d\d.\d\d[\*]*$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 26"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(title);
|
||||
sb.AppendLine(@"1ab
|
||||
|
||||
10/01/2012
|
||||
10/01/2012
|
||||
01:00:22.09
|
||||
01:00:30.09
|
||||
**:**:**.**
|
||||
**:**:**.**
|
||||
01:00:51.09
|
||||
01:00:55.22
|
||||
01:01:10.09
|
||||
**:**:**.**
|
||||
**:**:**.**
|
||||
01:13:23.09");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}: {1} {2}\r\n{3}\r\n", count, MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text));
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
char[] splitChars = { ':', ';', ',', '.' };
|
||||
if (arr.Length == 3)
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[1].TrimEnd('*'), splitChars), DecodeTimeCodeFrames(arr[2].TrimEnd('*'), splitChars), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,101 +1,101 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle29 : SubtitleFormat
|
||||
{
|
||||
|
||||
//00:00:30:21 00:00:35:22
|
||||
//Et c'est là que nous devions
|
||||
//passer la nuit.
|
||||
|
||||
//00:00:38:04 00:00:40:18
|
||||
//Un nouveau martyre a commencé.
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 29"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\r\n{2}\r\n", MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length == 2)
|
||||
p = new Paragraph(DecodeTimeCode(arr[0], splitChars), DecodeTimeCode(arr[1], splitChars), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle29 : SubtitleFormat
|
||||
{
|
||||
|
||||
//00:00:30:21 00:00:35:22
|
||||
//Et c'est là que nous devions
|
||||
//passer la nuit.
|
||||
|
||||
//00:00:38:04 00:00:40:18
|
||||
//Un nouveau martyre a commencé.
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 29"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}\t{1}\r\n{2}\r\n", MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.TrimEnd();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split('\t');
|
||||
if (arr.Length == 2)
|
||||
p = new Paragraph(DecodeTimeCodeFrames(arr[0], splitChars), DecodeTimeCodeFrames(arr[1], splitChars), string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,161 +1,161 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle30 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".asc"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 30"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//@ headers
|
||||
|
||||
// 1.
|
||||
// 00:00:04:12
|
||||
// 00:00:06:05
|
||||
// Berniukai, tik pažiūrėkit.
|
||||
|
||||
// 2.
|
||||
// 00:00:06:16
|
||||
// 00:00:07:20
|
||||
// Argi ne puiku?
|
||||
|
||||
// 3.
|
||||
// 00:00:08:02
|
||||
// 00:00:10:20
|
||||
// Tėti, ar galime čia paplaukioti?
|
||||
// -Aišku, kad galim.
|
||||
|
||||
const string paragraphWriteFormat = "{4}.{3}{0}{3}{1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("@ headers");
|
||||
sb.AppendLine();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.EndsWith('.') && Utilities.IsInteger(line.TrimEnd('.')))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.Length > 0 && line != "@ headers")
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle30 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".asc"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 30"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//@ headers
|
||||
|
||||
// 1.
|
||||
// 00:00:04:12
|
||||
// 00:00:06:05
|
||||
// Berniukai, tik pažiūrėkit.
|
||||
|
||||
// 2.
|
||||
// 00:00:06:16
|
||||
// 00:00:07:20
|
||||
// Argi ne puiku?
|
||||
|
||||
// 3.
|
||||
// 00:00:08:02
|
||||
// 00:00:10:20
|
||||
// Tėti, ar galime čia paplaukioti?
|
||||
// -Aišku, kad galim.
|
||||
|
||||
const string paragraphWriteFormat = "{4}.{3}{0}{3}{1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("@ headers");
|
||||
sb.AppendLine();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.EndsWith('.') && Utilities.IsInteger(line.TrimEnd('.')))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.Length > 0 && line != "@ headers")
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,153 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle31 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 31"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//1.
|
||||
//8.03
|
||||
//10.06
|
||||
//- Labai aèiû.
|
||||
//- Jûs rimtai?
|
||||
|
||||
//2.
|
||||
//16.00
|
||||
//19.06
|
||||
//Kaip reikalai ðunø grobimo versle?
|
||||
|
||||
const string paragraphWriteFormat = "{4}.{3}{0}{3}{1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.EndsWith('.') && Utilities.IsInteger(line.TrimEnd('.')))
|
||||
{
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.Length > 0 && line != "@ headers")
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}.{1:00}", (int)time.TotalSeconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle31 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 31"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//1.
|
||||
//8.03
|
||||
//10.06
|
||||
//- Labai aèiû.
|
||||
//- Jûs rimtai?
|
||||
|
||||
//2.
|
||||
//16.00
|
||||
//19.06
|
||||
//Kaip reikalai ðunø grobimo versle?
|
||||
|
||||
const string paragraphWriteFormat = "{4}.{3}{0}{3}{1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.EndsWith('.') && Utilities.IsInteger(line.TrimEnd('.')))
|
||||
{
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.Length > 0 && line != "@ headers")
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}.{1:00}", (int)time.TotalSeconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,156 +1,156 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle32 : SubtitleFormat
|
||||
{
|
||||
//1: 02:25:07.24 02:25:10.19
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\.\d\d \d\d:\d\d:\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 32"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string paragraphWriteFormat = string.Empty.PadLeft(5, ' ') + "{4}: {0} {1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"STTRIO
|
||||
Theatrical
|
||||
PAL
|
||||
SDI Media
|
||||
ENGLISH
|
||||
Sony,Sony DVD/UMD,1:85,16x9
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
#: Italics Text
|
||||
@/: Force title
|
||||
@+: reposition top
|
||||
@|: reposition middle
|
||||
");
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "#");
|
||||
text = text.Replace("</i>", "#");
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
if (text.StartsWith("{\\an8}"))
|
||||
text = text.Remove(0, 6) + "@+";
|
||||
if (text.StartsWith("{\\an5}"))
|
||||
text = text.Remove(0, 6) + "@|";
|
||||
if (text.StartsWith("{\\an") && text.Length > 6 && text[5] == '}')
|
||||
text = text.Remove(0, 6);
|
||||
|
||||
text = text.Replace(Environment.NewLine, Environment.NewLine.PadRight(Environment.NewLine.Length + 8, ' '));
|
||||
text = text.PadLeft(text.Length + 8, ' ');
|
||||
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', ';', ',', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCode.IsMatch(s.Replace("*", string.Empty)))
|
||||
{
|
||||
s = s.Replace("*", string.Empty);
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
paragraph = new Paragraph();
|
||||
try
|
||||
{
|
||||
paragraph.StartTime = DecodeTimeCode(parts[1], splitChars);
|
||||
paragraph.EndTime = DecodeTimeCode(parts[2], splitChars);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && s.Length > 0)
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (s.Contains('#'))
|
||||
{
|
||||
int index = s.IndexOf('#');
|
||||
if (italicOn)
|
||||
s = s.Remove(index, 1).Insert(index, "</i>");
|
||||
else
|
||||
s = s.Remove(index, 1).Insert(index, "<i>");
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
|
||||
// force title
|
||||
s = s.Replace("@/", string.Empty);
|
||||
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//@+: reposition top
|
||||
//@|: reposition middle
|
||||
if (p.Text.Contains("@+"))
|
||||
p.Text = "{\\an8}" + p.Text.Replace("@+", string.Empty).Replace("@|", string.Empty);
|
||||
else if (p.Text.Contains("@|"))
|
||||
p.Text = "{\\an5}" + p.Text.Replace("@+", string.Empty).Replace("@|", string.Empty);
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15.22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle32 : SubtitleFormat
|
||||
{
|
||||
//1: 02:25:07.24 02:25:10.19
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\.\d\d \d\d:\d\d:\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 32"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string paragraphWriteFormat = string.Empty.PadLeft(5, ' ') + "{4}: {0} {1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"STTRIO
|
||||
Theatrical
|
||||
PAL
|
||||
SDI Media
|
||||
ENGLISH
|
||||
Sony,Sony DVD/UMD,1:85,16x9
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
0000.00
|
||||
#: Italics Text
|
||||
@/: Force title
|
||||
@+: reposition top
|
||||
@|: reposition middle
|
||||
");
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
|
||||
string text = p.Text;
|
||||
text = text.Replace("<i>", "#");
|
||||
text = text.Replace("</i>", "#");
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
if (text.StartsWith("{\\an8}"))
|
||||
text = text.Remove(0, 6) + "@+";
|
||||
if (text.StartsWith("{\\an5}"))
|
||||
text = text.Remove(0, 6) + "@|";
|
||||
if (text.StartsWith("{\\an") && text.Length > 6 && text[5] == '}')
|
||||
text = text.Remove(0, 6);
|
||||
|
||||
text = text.Replace(Environment.NewLine, Environment.NewLine.PadRight(Environment.NewLine.Length + 8, ' '));
|
||||
text = text.PadLeft(text.Length + 8, ' ');
|
||||
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', ';', ',', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCode.IsMatch(s.Replace("*", string.Empty)))
|
||||
{
|
||||
s = s.Replace("*", string.Empty);
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
paragraph = new Paragraph();
|
||||
try
|
||||
{
|
||||
paragraph.StartTime = DecodeTimeCodeFrames(parts[1], splitChars);
|
||||
paragraph.EndTime = DecodeTimeCodeFrames(parts[2], splitChars);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && s.Length > 0)
|
||||
{
|
||||
bool italicOn = false;
|
||||
while (s.Contains('#'))
|
||||
{
|
||||
int index = s.IndexOf('#');
|
||||
if (italicOn)
|
||||
s = s.Remove(index, 1).Insert(index, "</i>");
|
||||
else
|
||||
s = s.Remove(index, 1).Insert(index, "<i>");
|
||||
italicOn = !italicOn;
|
||||
}
|
||||
|
||||
// force title
|
||||
s = s.Replace("@/", string.Empty);
|
||||
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//@+: reposition top
|
||||
//@|: reposition middle
|
||||
if (p.Text.Contains("@+"))
|
||||
p.Text = "{\\an8}" + p.Text.Replace("@+", string.Empty).Replace("@|", string.Empty);
|
||||
else if (p.Text.Contains("@|"))
|
||||
p.Text = "{\\an5}" + p.Text.Replace("@+", string.Empty).Replace("@|", string.Empty);
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15.22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,114 +1,114 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle35 : SubtitleFormat
|
||||
{
|
||||
|
||||
//0072.08-0076.05
|
||||
//Pidin täna peaaegu surma saama,
|
||||
//kuna röövisid vale koera.
|
||||
|
||||
//0076.09-0078.14
|
||||
//Mõtled seda tõsiselt või?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d\d\d\.\d\d-\d\d\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 35"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:0000}.{1:00}", (int)tc.TotalSeconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}-{1}\r\n{2}\r\n", MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split('-');
|
||||
if (arr.Length == 2)
|
||||
{
|
||||
var parts1 = arr[0].Split(splitChars);
|
||||
var parts2 = arr[1].Split(splitChars);
|
||||
|
||||
// parts1/2 most have length of 2
|
||||
if (parts1.Length + parts2.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(parts1), DecodeTimeCode(parts2), string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(new[] { parts1[0], parts1[1] }), DecodeTimeCode(new[] { parts2[0], parts2[1] }), string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle35 : SubtitleFormat
|
||||
{
|
||||
|
||||
//0072.08-0076.05
|
||||
//Pidin täna peaaegu surma saama,
|
||||
//kuna röövisid vale koera.
|
||||
|
||||
//0076.09-0078.14
|
||||
//Mõtled seda tõsiselt või?
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d\d\d\.\d\d-\d\d\d\d\.\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 35"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string MakeTimeCode(TimeCode tc)
|
||||
{
|
||||
return string.Format("{0:0000}.{1:00}", (int)tc.TotalSeconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds));
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph p = subtitle.Paragraphs[i];
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
sb.AppendLine(string.Format("{0}-{1}\r\n{2}\r\n", MakeTimeCode(p.StartTime), MakeTimeCode(p.EndTime), text));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
var sb = new StringBuilder();
|
||||
char[] splitChars = { ':', ';', ',', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
sb = new StringBuilder();
|
||||
string[] arr = s.Split('-');
|
||||
if (arr.Length == 2)
|
||||
{
|
||||
var parts1 = arr[0].Split(splitChars);
|
||||
var parts2 = arr[1].Split(splitChars);
|
||||
|
||||
// parts1/2 most have length of 2
|
||||
if (parts1.Length + parts2.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(parts1), DecodeTimeCodeFrames(parts2), string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(new[] { parts1[0], parts1[1] }), DecodeTimeCodeFrames(new[] { parts2[0], parts2[1] }), string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
sb.AppendLine(s);
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
{
|
||||
p.Text = sb.ToString().Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,140 +1,140 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle44 : SubtitleFormat
|
||||
{
|
||||
|
||||
//>>> "COMMON GROUND" IS FUNDED BY 10:01:04:12 1
|
||||
//THE MINNESOTA ARTS AND CULTURAL 10:01:07:09
|
||||
private static Regex regexTimeCodes1 = new Regex(@" \d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
private static Regex regexTimeCodes2 = new Regex(@" \d\d:\d\d:\d\d:\d\d +\d+$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 44"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
int index2 = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
var text = new StringBuilder();
|
||||
text.Append(HtmlUtil.RemoveHtmlTags(p.Text.Replace(Environment.NewLine, " ")));
|
||||
while (text.Length < 34)
|
||||
text.Append(' ');
|
||||
sb.AppendFormat("{0}{1}", text, EncodeTimeCode(p.StartTime));
|
||||
if (index % 50 == 1)
|
||||
{
|
||||
index2++;
|
||||
sb.Append(new string(' ', 25) + index2);
|
||||
}
|
||||
sb.AppendLine();
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null && next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds > 150)
|
||||
{
|
||||
text = new StringBuilder();
|
||||
while (text.Length < 34)
|
||||
text.Append(' ');
|
||||
sb.AppendLine(string.Format("{0}{1}", text, EncodeTimeCode(p.EndTime)));
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = regexTimeCodes2.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
s = s.Substring(0, match.Index + 13).Trim();
|
||||
}
|
||||
match = regexTimeCodes1.Match(s);
|
||||
if (match.Success && match.Index > 13)
|
||||
{
|
||||
string text = s.Substring(0, match.Index).Trim();
|
||||
string timeCode = s.Substring(match.Index).Trim();
|
||||
|
||||
string[] startParts = timeCode.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), new TimeCode(0, 0, 0, 0), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || regexTimeCodes1.IsMatch(" " + s))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph current = subtitle.Paragraphs[i];
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next != null)
|
||||
current.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
else
|
||||
current.EndTime.TotalMilliseconds = current.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(current.Text);
|
||||
|
||||
if (current.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
current.EndTime.TotalMilliseconds = current.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds;
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle44 : SubtitleFormat
|
||||
{
|
||||
|
||||
//>>> "COMMON GROUND" IS FUNDED BY 10:01:04:12 1
|
||||
//THE MINNESOTA ARTS AND CULTURAL 10:01:07:09
|
||||
private static Regex regexTimeCodes1 = new Regex(@" \d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
private static Regex regexTimeCodes2 = new Regex(@" \d\d:\d\d:\d\d:\d\d +\d+$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 44"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
int index2 = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
var text = new StringBuilder();
|
||||
text.Append(HtmlUtil.RemoveHtmlTags(p.Text.Replace(Environment.NewLine, " ")));
|
||||
while (text.Length < 34)
|
||||
text.Append(' ');
|
||||
sb.AppendFormat("{0}{1}", text, EncodeTimeCode(p.StartTime));
|
||||
if (index % 50 == 1)
|
||||
{
|
||||
index2++;
|
||||
sb.Append(new string(' ', 25) + index2);
|
||||
}
|
||||
sb.AppendLine();
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null && next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds > 150)
|
||||
{
|
||||
text = new StringBuilder();
|
||||
while (text.Length < 34)
|
||||
text.Append(' ');
|
||||
sb.AppendLine(string.Format("{0}{1}", text, EncodeTimeCode(p.EndTime)));
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = regexTimeCodes2.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
s = s.Substring(0, match.Index + 13).Trim();
|
||||
}
|
||||
match = regexTimeCodes1.Match(s);
|
||||
if (match.Success && match.Index > 13)
|
||||
{
|
||||
string text = s.Substring(0, match.Index).Trim();
|
||||
string timeCode = s.Substring(match.Index).Trim();
|
||||
|
||||
string[] startParts = timeCode.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), new TimeCode(0, 0, 0, 0), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || regexTimeCodes1.IsMatch(" " + s))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
Paragraph current = subtitle.Paragraphs[i];
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
|
||||
if (next != null)
|
||||
current.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
else
|
||||
current.EndTime.TotalMilliseconds = current.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(current.Text);
|
||||
|
||||
if (current.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
current.EndTime.TotalMilliseconds = current.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds;
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,119 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle45 : SubtitleFormat
|
||||
{
|
||||
//* 00001.00-00003.00 02.01 00.0 1 0001 00 16-090-090
|
||||
//* 00138.10-00143.05 00.00 00.0 1 0003 00 16-090-090
|
||||
private static Regex regexTimeCodes = new Regex(@"^\*\s+\d\d\d\d\d\.\d\d-\d\d\d\d\d\.\d\d \d\d.\d\d \d\d.\d\ \d \d\d\d\d \d\d \d\d-\d\d\d-\d\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 45"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (fileName != null && !fileName.EndsWith(Extension, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"0 2 1.0 1.0 3.0 048 0400 0040 0500 100 100 0 100 0 6600 6600 01
|
||||
CRULIC R1
|
||||
ST 0 EB 3.10
|
||||
@");
|
||||
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//1 00:50:34:22 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
index++;
|
||||
sb.AppendLine(string.Format("* {0}-{1} 00.00 00.0 1 {2} 00 16-090-090{3}{4}{3}@", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), index.ToString().PadLeft(4, '0'), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text)));
|
||||
}
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00000}.{1:00}", time.TotalSeconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//* 00001.00-00003.00 02.01 00.0 1 0001 00 16-090-090
|
||||
//CRULIC R1
|
||||
//pour Bobi
|
||||
//@
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
string[] arr = rtf.FromRtf().SplitToLines();
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in arr)
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line.Trim()))
|
||||
{
|
||||
string[] temp = line.Substring(1).Trim().Substring(0, 17).Split('-');
|
||||
if (temp.Length == 2)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 2 && endParts.Length == 2)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), string.Empty); //00119.12
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.Trim() == "@")
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
if (p.Text.Length > 2000)
|
||||
return; // wrong format
|
||||
else if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle45 : SubtitleFormat
|
||||
{
|
||||
//* 00001.00-00003.00 02.01 00.0 1 0001 00 16-090-090
|
||||
//* 00138.10-00143.05 00.00 00.0 1 0003 00 16-090-090
|
||||
private static Regex regexTimeCodes = new Regex(@"^\*\s+\d\d\d\d\d\.\d\d-\d\d\d\d\d\.\d\d \d\d.\d\d \d\d.\d\ \d \d\d\d\d \d\d \d\d-\d\d\d-\d\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 45"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (fileName != null && !fileName.EndsWith(Extension, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(@"0 2 1.0 1.0 3.0 048 0400 0040 0500 100 100 0 100 0 6600 6600 01
|
||||
CRULIC R1
|
||||
ST 0 EB 3.10
|
||||
@");
|
||||
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//1 00:50:34:22 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
index++;
|
||||
sb.AppendLine(string.Format("* {0}-{1} 00.00 00.0 1 {2} 00 16-090-090{3}{4}{3}@", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), index.ToString().PadLeft(4, '0'), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text)));
|
||||
}
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00000}.{1:00}", time.TotalSeconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//* 00001.00-00003.00 02.01 00.0 1 0001 00 16-090-090
|
||||
//CRULIC R1
|
||||
//pour Bobi
|
||||
//@
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
string[] arr = rtf.FromRtf().SplitToLines();
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in arr)
|
||||
{
|
||||
if (regexTimeCodes.IsMatch(line.Trim()))
|
||||
{
|
||||
string[] temp = line.Substring(1).Trim().Substring(0, 17).Split('-');
|
||||
if (temp.Length == 2)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 2 && endParts.Length == 2)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), string.Empty); //00119.12
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line) || line.Trim() == "@")
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && p != null)
|
||||
{
|
||||
if (p.Text.Length > 2000)
|
||||
return; // wrong format
|
||||
else if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,106 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle46 : SubtitleFormat
|
||||
{
|
||||
//7:00:01:27AM
|
||||
private static readonly Regex regexTimeCodesAM = new Regex(@"^\d\:\d\d\:\d\d\:\d\dAM", RegexOptions.Compiled);
|
||||
private static readonly Regex regexTimeCodesPM = new Regex(@"^\d\:\d\d\:\d\d\:\d\dPM", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".pst"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 46"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//OFF THE RECORD STARTS RIGHT NOW. 7:00:01:27AM
|
||||
//HERE IS THE RUNDOWN. 7:00:05:03AM
|
||||
var sb = new StringBuilder();
|
||||
const string format = "{0}{1}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, p.Text.Replace(Environment.NewLine, " ").PadRight(35), EncodeTimeCode(p.StartTime)));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0}:{1:00}:{2:00}:{3:00}AM", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
string[] arr = line.Split();
|
||||
var timeCode = arr[arr.Length - 1];
|
||||
if (regexTimeCodesAM.Match(timeCode).Success || regexTimeCodesPM.Match(timeCode).Success)
|
||||
{
|
||||
try
|
||||
{
|
||||
arr = timeCode.Substring(0, 10).Split(':');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCode(arr);
|
||||
p.Text = s.Substring(0, s.IndexOf(timeCode, StringComparison.Ordinal)).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (s.Length > 0)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
foreach (Paragraph paragraph in subtitle.Paragraphs)
|
||||
{
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
if (paragraph.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle46 : SubtitleFormat
|
||||
{
|
||||
//7:00:01:27AM
|
||||
private static readonly Regex regexTimeCodesAM = new Regex(@"^\d\:\d\d\:\d\d\:\d\dAM", RegexOptions.Compiled);
|
||||
private static readonly Regex regexTimeCodesPM = new Regex(@"^\d\:\d\d\:\d\d\:\d\dPM", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".pst"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 46"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//OFF THE RECORD STARTS RIGHT NOW. 7:00:01:27AM
|
||||
//HERE IS THE RUNDOWN. 7:00:05:03AM
|
||||
var sb = new StringBuilder();
|
||||
const string format = "{0}{1}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, p.Text.Replace(Environment.NewLine, " ").PadRight(35), EncodeTimeCode(p.StartTime)));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0}:{1:00}:{2:00}:{3:00}AM", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
string[] arr = line.Split();
|
||||
var timeCode = arr[arr.Length - 1];
|
||||
if (regexTimeCodesAM.Match(timeCode).Success || regexTimeCodesPM.Match(timeCode).Success)
|
||||
{
|
||||
try
|
||||
{
|
||||
arr = timeCode.Substring(0, 10).Split(':');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCodeFrames(arr);
|
||||
p.Text = s.Substring(0, s.IndexOf(timeCode, StringComparison.Ordinal)).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (s.Length > 0)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
foreach (Paragraph paragraph in subtitle.Paragraphs)
|
||||
{
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
if (paragraph.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,100 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle47 : SubtitleFormat
|
||||
{
|
||||
//7:00:01:27AM
|
||||
private static Regex regexTimeCodes = new Regex(@"^\d\:\d\d\:\d\d\:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 47"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0}\t{1}", EncodeTimeCode(p.StartTime), p.Text.Replace(Environment.NewLine, " ")));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0}:{1:00}:{2:00}:{3:00}", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (regexTimeCodes.Match(s).Success)
|
||||
{
|
||||
try
|
||||
{
|
||||
var arr = s.Substring(0, 10).Split(':');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
var p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCode(arr);
|
||||
p.Text = s.Remove(0, 10).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (s.Length > 0)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
foreach (Paragraph paragraph in subtitle.Paragraphs)
|
||||
{
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
if (paragraph.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle47 : SubtitleFormat
|
||||
{
|
||||
//7:00:01:27AM
|
||||
private static Regex regexTimeCodes = new Regex(@"^\d\:\d\d\:\d\d\:\d\d\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 47"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0}\t{1}", EncodeTimeCode(p.StartTime), p.Text.Replace(Environment.NewLine, " ")));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0}:{1:00}:{2:00}:{3:00}", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (regexTimeCodes.Match(s).Success)
|
||||
{
|
||||
try
|
||||
{
|
||||
var arr = s.Substring(0, 10).Split(':');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
var p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCodeFrames(arr);
|
||||
p.Text = s.Remove(0, 10).Trim();
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (s.Length > 0)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
foreach (Paragraph paragraph in subtitle.Paragraphs)
|
||||
{
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
if (paragraph.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,158 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle49 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d \d\d \d\d \d\d $", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode2 = new Regex(@"^\d\d \d\d \d\d \d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 49"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//10 04 36 02
|
||||
//10 04 37 04
|
||||
//
|
||||
//Greetings.
|
||||
//10 04 37 06
|
||||
//10 04 40 08
|
||||
//It's confirmed, after reading
|
||||
//Not Out on the poster..
|
||||
//10 04 40 15
|
||||
//10 04 44 06
|
||||
//..you have not come to pass you
|
||||
//time, in this unique story.
|
||||
|
||||
const string paragraphWriteFormat = "{0}{3}{1}{3}{2}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = Environment.NewLine + text;
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.TimeStart;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (paragraph == null && expecting == ExpectingLine.TimeStart && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
paragraph = new Paragraph();
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.Text && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
if (string.IsNullOrEmpty(paragraph.Text))
|
||||
_errorCount++;
|
||||
if (paragraph.StartTime.TotalMilliseconds < 0.1)
|
||||
_errorCount++;
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
|
||||
if (paragraph != null && expecting == ExpectingLine.TimeStart && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00} {1:00} {2:00} {3:00} ", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle49 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d \d\d \d\d \d\d $", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode2 = new Regex(@"^\d\d \d\d \d\d \d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 49"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//10 04 36 02
|
||||
//10 04 37 04
|
||||
//
|
||||
//Greetings.
|
||||
//10 04 37 06
|
||||
//10 04 40 08
|
||||
//It's confirmed, after reading
|
||||
//Not Out on the poster..
|
||||
//10 04 40 15
|
||||
//10 04 44 06
|
||||
//..you have not come to pass you
|
||||
//time, in this unique story.
|
||||
|
||||
const string paragraphWriteFormat = "{0}{3}{1}{3}{2}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = Environment.NewLine + text;
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.TimeStart;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (paragraph == null && expecting == ExpectingLine.TimeStart && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
paragraph = new Paragraph();
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.Text && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
if (string.IsNullOrEmpty(paragraph.Text))
|
||||
_errorCount++;
|
||||
if (paragraph.StartTime.TotalMilliseconds < 0.1)
|
||||
_errorCount++;
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
|
||||
if (paragraph != null && expecting == ExpectingLine.TimeStart && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line)))
|
||||
{
|
||||
string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00} {1:00} {2:00} {3:00} ", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,140 +1,140 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle52 : SubtitleFormat
|
||||
{
|
||||
//#00001 10:00:02.00 10:00:04.13 00:00:02.13 #F CC00000D0 #C
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\#\d\d\d\d\d\t\d\d:\d\d:\d\d\.\d\d\t\d\d:\d\d:\d\d\.\d\d\t\d\d:\d\d:\d\d\.\d\d\t.*$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 52"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (lines.Count > 0 && lines[0] != null && lines[0].StartsWith("{\\rtf1"))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string paragraphWriteFormat = "#{0:00000}\t{1}\t{2}\t{3}\t#F\tCC00000D0\t#C " + Environment.NewLine + "{4}";
|
||||
const string timeFormat = "{0:00}:{1:00}:{2:00}.{3:00}";
|
||||
var sb = new StringBuilder();
|
||||
string header = @"FILE_INFO_BEGIN
|
||||
VIDEOFILE:
|
||||
ORIG_TITLE: [TITLE]
|
||||
PGM_TITLE:
|
||||
EP_TITLE: 03
|
||||
PROD:
|
||||
TRANSL: SDI Media
|
||||
CLIENT: FIC-HD
|
||||
COMMENT:
|
||||
TAPE#: TN10179565
|
||||
CRE_DATE:
|
||||
REP_DATE:
|
||||
TR_DATE:
|
||||
PROG_LEN:
|
||||
SOM: 09:59:35:00
|
||||
TRA_FONT:
|
||||
LANG_CO: English
|
||||
LIST_FONT: Arial Unicode MS 450
|
||||
TV_SYS: 625/50
|
||||
TV_FPS: EBU 625/50
|
||||
LINE_LEN: 43.2
|
||||
SW_VER: 2.25
|
||||
FILE_INFO_END";
|
||||
if (subtitle.Header != null && subtitle.Header.Contains("FILE_INFO_BEGIN"))
|
||||
header = subtitle.Header;
|
||||
sb.AppendLine(header);
|
||||
int number = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
string startTime = string.Format(timeFormat, p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, startFrame);
|
||||
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
string endTime = string.Format(timeFormat, p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, endFrame);
|
||||
|
||||
// to avoid rounding errors in duration
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
string duration = string.Format(timeFormat, durationCalc.Duration.Hours, durationCalc.Duration.Minutes, durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds));
|
||||
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, number, startTime, endTime, duration, HtmlUtil.RemoveHtmlTags(p.Text)));
|
||||
number++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
bool started = false;
|
||||
var header = new StringBuilder();
|
||||
var text = new StringBuilder();
|
||||
char[] splitChar = { ':', ',', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (RegexTimeCodes.Match(line).Success)
|
||||
{
|
||||
started = true;
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
text = new StringBuilder();
|
||||
string start = line.Substring(7, 11);
|
||||
string end = line.Substring(19, 11);
|
||||
p = new Paragraph(DecodeTimeCode(start, splitChar), DecodeTimeCode(end, splitChar), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
else if (!started)
|
||||
{
|
||||
header.AppendLine(line);
|
||||
}
|
||||
else if (p != null && p.Text.Length < 200)
|
||||
{
|
||||
text.AppendLine(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
subtitle.Header = header.ToString();
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle52 : SubtitleFormat
|
||||
{
|
||||
//#00001 10:00:02.00 10:00:04.13 00:00:02.13 #F CC00000D0 #C
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\#\d\d\d\d\d\t\d\d:\d\d:\d\d\.\d\d\t\d\d:\d\d:\d\d\.\d\d\t\d\d:\d\d:\d\d\.\d\d\t.*$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 52"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (lines.Count > 0 && lines[0] != null && lines[0].StartsWith("{\\rtf1"))
|
||||
return false;
|
||||
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
string paragraphWriteFormat = "#{0:00000}\t{1}\t{2}\t{3}\t#F\tCC00000D0\t#C " + Environment.NewLine + "{4}";
|
||||
const string timeFormat = "{0:00}:{1:00}:{2:00}.{3:00}";
|
||||
var sb = new StringBuilder();
|
||||
string header = @"FILE_INFO_BEGIN
|
||||
VIDEOFILE:
|
||||
ORIG_TITLE: [TITLE]
|
||||
PGM_TITLE:
|
||||
EP_TITLE: 03
|
||||
PROD:
|
||||
TRANSL: SDI Media
|
||||
CLIENT: FIC-HD
|
||||
COMMENT:
|
||||
TAPE#: TN10179565
|
||||
CRE_DATE:
|
||||
REP_DATE:
|
||||
TR_DATE:
|
||||
PROG_LEN:
|
||||
SOM: 09:59:35:00
|
||||
TRA_FONT:
|
||||
LANG_CO: English
|
||||
LIST_FONT: Arial Unicode MS 450
|
||||
TV_SYS: 625/50
|
||||
TV_FPS: EBU 625/50
|
||||
LINE_LEN: 43.2
|
||||
SW_VER: 2.25
|
||||
FILE_INFO_END";
|
||||
if (subtitle.Header != null && subtitle.Header.Contains("FILE_INFO_BEGIN"))
|
||||
header = subtitle.Header;
|
||||
sb.AppendLine(header);
|
||||
int number = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
string startTime = string.Format(timeFormat, p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, startFrame);
|
||||
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
string endTime = string.Format(timeFormat, p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, endFrame);
|
||||
|
||||
// to avoid rounding errors in duration
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
string duration = string.Format(timeFormat, durationCalc.Duration.Hours, durationCalc.Duration.Minutes, durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds));
|
||||
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, number, startTime, endTime, duration, HtmlUtil.RemoveHtmlTags(p.Text)));
|
||||
number++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
bool started = false;
|
||||
var header = new StringBuilder();
|
||||
var text = new StringBuilder();
|
||||
char[] splitChar = { ':', ',', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (RegexTimeCodes.Match(line).Success)
|
||||
{
|
||||
started = true;
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
text = new StringBuilder();
|
||||
string start = line.Substring(7, 11);
|
||||
string end = line.Substring(19, 11);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(start, splitChar), DecodeTimeCodeFrames(end, splitChar), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
else if (!started)
|
||||
{
|
||||
header.AppendLine(line);
|
||||
}
|
||||
else if (p != null && p.Text.Length < 200)
|
||||
{
|
||||
text.AppendLine(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
subtitle.Header = header.ToString();
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,114 +1,114 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle53 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\:\d\d\:\d\d\:\d\d [^ ]+", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 53"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//10:56:54:12 FEATURING BRIAN LORENTE AND THE
|
||||
//10:56:59:18 USUAL SUSPECTS.
|
||||
//10:57:15:18 \M
|
||||
//10:57:20:07 >> HOW WE DOING TONIGHT,
|
||||
//10:57:27:17 MICHIGAN?
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text).Replace("♪", "\\M");
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime) + " " + text);
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCodes.Match(s).Success)
|
||||
{
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
|
||||
try
|
||||
{
|
||||
string[] arr = s.Substring(0, 11).Split(':');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
p.StartTime = DecodeTimeCode(arr);
|
||||
string text = s.Substring(11).Trim();
|
||||
p.Text = text;
|
||||
if (text.Length > 1 && Utilities.IsInteger(text.Substring(0, 2)))
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (s.Length > 0)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
int index = 1;
|
||||
foreach (Paragraph paragraph in subtitle.Paragraphs)
|
||||
{
|
||||
paragraph.Text = paragraph.Text.Replace("\\M", "♪");
|
||||
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle53 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d\:\d\d\:\d\d\:\d\d [^ ]+", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 53"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
Subtitle subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//10:56:54:12 FEATURING BRIAN LORENTE AND THE
|
||||
//10:56:59:18 USUAL SUSPECTS.
|
||||
//10:57:15:18 \M
|
||||
//10:57:20:07 >> HOW WE DOING TONIGHT,
|
||||
//10:57:27:17 MICHIGAN?
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text).Replace("♪", "\\M");
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime) + " " + text);
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode timeCode)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (RegexTimeCodes.Match(s).Success)
|
||||
{
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
|
||||
try
|
||||
{
|
||||
string[] arr = s.Substring(0, 11).Split(':');
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
p.StartTime = DecodeTimeCodeFrames(arr);
|
||||
string text = s.Substring(11).Trim();
|
||||
p.Text = text;
|
||||
if (text.Length > 1 && Utilities.IsInteger(text.Substring(0, 2)))
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (s.Length > 0)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
int index = 1;
|
||||
foreach (Paragraph paragraph in subtitle.Paragraphs)
|
||||
{
|
||||
paragraph.Text = paragraph.Text.Replace("\\M", "♪");
|
||||
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(index);
|
||||
if (next != null)
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,139 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle54 : SubtitleFormat
|
||||
{
|
||||
//10:00:31:01
|
||||
//10:00:33:02
|
||||
//This is the king's royal court.
|
||||
|
||||
//10:00:33:19
|
||||
//10:00:35:00
|
||||
//This is the place,
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 54"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime));
|
||||
sb.AppendLine(EncodeTimeCode(p.EndTime));
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success && s.Length == 11)
|
||||
{
|
||||
string[] parts = s.Split(':');
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (expectStartTime)
|
||||
{
|
||||
p.StartTime = DecodeTimeCode(parts);
|
||||
expectStartTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds < 0.01)
|
||||
_errorCount++;
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
_errorCount++;
|
||||
|
||||
p.EndTime = DecodeTimeCode(parts);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
expectStartTime = true;
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p.EndTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
bool allNullEndTime = true;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
if (subtitle.Paragraphs[i].EndTime.TotalMilliseconds != 0)
|
||||
allNullEndTime = false;
|
||||
}
|
||||
if (allNullEndTime)
|
||||
subtitle.Paragraphs.Clear();
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle54 : SubtitleFormat
|
||||
{
|
||||
//10:00:31:01
|
||||
//10:00:33:02
|
||||
//This is the king's royal court.
|
||||
|
||||
//10:00:33:19
|
||||
//10:00:35:00
|
||||
//This is the place,
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 54"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime));
|
||||
sb.AppendLine(EncodeTimeCode(p.EndTime));
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success && s.Length == 11)
|
||||
{
|
||||
string[] parts = s.Split(':');
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (expectStartTime)
|
||||
{
|
||||
p.StartTime = DecodeTimeCodeFrames(parts);
|
||||
expectStartTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds < 0.01)
|
||||
_errorCount++;
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
_errorCount++;
|
||||
|
||||
p.EndTime = DecodeTimeCodeFrames(parts);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
expectStartTime = true;
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p.EndTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
bool allNullEndTime = true;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
if (subtitle.Paragraphs[i].EndTime.TotalMilliseconds != 0)
|
||||
allNullEndTime = false;
|
||||
}
|
||||
if (allNullEndTime)
|
||||
subtitle.Paragraphs.Clear();
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,133 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle55 : SubtitleFormat
|
||||
{
|
||||
|
||||
// 338: 00:24:34.00 00:24:37.10 [51]
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\.\d\d\s+\d\d:\d\d:\d\d\.\d\d\s+\[\d+\]$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 55"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}: {1} {2} [{3}]";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text.Length));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return $"{time.Hours:00}:{time.Minutes:00}:{time.Seconds:00}.{MillisecondsToFramesMaxFrameRate(time.Milliseconds):00}";
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
string[] arr = rtf.FromRtf().SplitToLines();
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in arr)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCode(parts[1], splitChars);
|
||||
p.EndTime = DecodeTimeCode(parts[2], splitChars);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle55 : SubtitleFormat
|
||||
{
|
||||
|
||||
// 338: 00:24:34.00 00:24:37.10 [51]
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\.\d\d\s+\d\d:\d\d:\d\d\.\d\d\s+\[\d+\]$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 55"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}: {1} {2} [{3}]";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text.Length));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return $"{time.Hours:00}:{time.Minutes:00}:{time.Seconds:00}.{MillisecondsToFramesMaxFrameRate(time.Milliseconds):00}";
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
string[] arr = rtf.FromRtf().SplitToLines();
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in arr)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCodeFrames(parts[1], splitChars);
|
||||
p.EndTime = DecodeTimeCodeFrames(parts[2], splitChars);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,125 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle56 : SubtitleFormat
|
||||
{
|
||||
//0001 01:00:37:22 01:00:39:11
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 56"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
const string format = "{0:0000}\t{1}\t{2}";
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split('\t');
|
||||
if (parts.Length == 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCode(parts[1], splitChars);
|
||||
p.EndTime = DecodeTimeCode(parts[2], splitChars);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (p.EndTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
foreach (Paragraph temp in subtitle.Paragraphs)
|
||||
temp.Text = temp.Text.Replace("<", "@ITALIC_START").Replace(">", "</i>").Replace("@ITALIC_START", "<i>");
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle56 : SubtitleFormat
|
||||
{
|
||||
//0001 01:00:37:22 01:00:39:11
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 56"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
const string format = "{0:0000}\t{1}\t{2}";
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split('\t');
|
||||
if (parts.Length == 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCodeFrames(parts[1], splitChars);
|
||||
p.EndTime = DecodeTimeCodeFrames(parts[2], splitChars);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (p.EndTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
foreach (Paragraph temp in subtitle.Paragraphs)
|
||||
temp.Text = temp.Text.Replace("<", "@ITALIC_START").Replace(">", "</i>").Replace("@ITALIC_START", "<i>");
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,93 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle57 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d\.\d\d \d\d:\d\d:\d\d\.\d\d .+", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 57"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:00:54.08 00:00:58.06 - Saucers... - ... a dry lake bed. (newline is //)
|
||||
sb.AppendLine(string.Format("{0} {1} {2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text).Replace(Environment.NewLine, "//")));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15.22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15.22 00:03:23.10 This is line one.//This is line two.
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
var match = RegexTimeCodes.Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
string temp = line.Substring(0, match.Length);
|
||||
if (line.Length >= 23)
|
||||
{
|
||||
string text = line.Remove(0, 23).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCode(temp.Substring(0, 11), splitChars), DecodeTimeCode(temp.Substring(12, 11), splitChars), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (p.Text.Length < 200)
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle57 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d\.\d\d \d\d:\d\d:\d\d\.\d\d .+", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 57"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:00:54.08 00:00:58.06 - Saucers... - ... a dry lake bed. (newline is //)
|
||||
sb.AppendLine(string.Format("{0} {1} {2}", EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text).Replace(Environment.NewLine, "//")));
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15.22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15.22 00:03:23.10 This is line one.//This is line two.
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ':', '.' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
var match = RegexTimeCodes.Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
string temp = line.Substring(0, match.Length);
|
||||
if (line.Length >= 23)
|
||||
{
|
||||
string text = line.Remove(0, 23).Trim();
|
||||
if (!text.Contains(Environment.NewLine))
|
||||
text = text.Replace("//", Environment.NewLine);
|
||||
p = new Paragraph(DecodeTimeCodeFrames(temp.Substring(0, 11), splitChars), DecodeTimeCodeFrames(temp.Substring(12, 11), splitChars), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (p.Text.Length < 200)
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,126 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle58 : SubtitleFormat
|
||||
{
|
||||
|
||||
//[01:01:53:09]
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\[\d\d:\d\d:\d\d:\d\d]$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 58"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "[{0}]{3}{3}{2}{3}{3}[{1}]{3}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
string[] arr = rtf.FromRtf().SplitToLines();
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in arr)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (s.StartsWith('[') && s.EndsWith('>') && s.Length > 13 && s[12] == ']')
|
||||
s = s.Substring(0, 13);
|
||||
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Replace("[", string.Empty).Replace("]", string.Empty).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
p.EndTime = DecodeTimeCode(parts[0], SplitCharColon);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else
|
||||
{
|
||||
p.StartTime = DecodeTimeCode(parts[0], SplitCharColon);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle58 : SubtitleFormat
|
||||
{
|
||||
|
||||
//[01:01:53:09]
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\[\d\d:\d\d:\d\d:\d\d]$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".rtf"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 58"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "[{0}]{3}{3}{2}{3}{3}[{1}]{3}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString().ToRtf();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
string rtf = sb.ToString().Trim();
|
||||
if (!rtf.StartsWith("{\\rtf", StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
string[] arr = rtf.FromRtf().SplitToLines();
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in arr)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (s.StartsWith('[') && s.EndsWith('>') && s.Length > 13 && s[12] == ']')
|
||||
s = s.Substring(0, 13);
|
||||
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Replace("[", string.Empty).Replace("]", string.Empty).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
p.EndTime = DecodeTimeCodeFrames(parts[0], SplitCharColon);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else
|
||||
{
|
||||
p.StartTime = DecodeTimeCodeFrames(parts[0], SplitCharColon);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,151 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle60 : SubtitleFormat
|
||||
{
|
||||
//01:00:31:14
|
||||
//THE PRIME MINISTER
|
||||
//Thank you.
|
||||
|
||||
//01:00:32:06
|
||||
//STIG
|
||||
//But first we'll go to our foreign guest, welcome to the programme. It’s a great pleasure having you here. Let me start with a standard question; is this your first time in Sweden?
|
||||
|
||||
//01:00:44:16
|
||||
//FEMALE ARTIST
|
||||
//No, I was here once many years ago, and I was introduced to your ”surströmming” – is that..?
|
||||
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 60"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime));
|
||||
sb.AppendLine(EncodeTimeCode(p.EndTime));
|
||||
if (!string.IsNullOrEmpty(p.Actor))
|
||||
sb.AppendLine(p.Actor.ToUpper());
|
||||
else
|
||||
sb.AppendLine("UNKNOWN ACTOR");
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
bool expectActor = false;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success && s.Length == 11)
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds > 0)
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
_errorCount++;
|
||||
}
|
||||
|
||||
p = new Paragraph();
|
||||
string[] parts = s.Split(':');
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.StartTime = DecodeTimeCode(parts);
|
||||
expectActor = true;
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
expectStartTime = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && expectActor)
|
||||
{
|
||||
if (line == line.ToUpper())
|
||||
p.Actor = line;
|
||||
else
|
||||
_errorCount++;
|
||||
expectActor = false;
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && !expectActor && !expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 5000)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p.StartTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
bool allNullEndTime = true;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
p = subtitle.Paragraphs[i];
|
||||
if (p.EndTime.TotalMilliseconds != 0)
|
||||
allNullEndTime = false;
|
||||
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
if (i < subtitle.Paragraphs.Count - 2 && p.EndTime.TotalMilliseconds >= subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds)
|
||||
p.EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (!allNullEndTime)
|
||||
subtitle.Paragraphs.Clear();
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle60 : SubtitleFormat
|
||||
{
|
||||
//01:00:31:14
|
||||
//THE PRIME MINISTER
|
||||
//Thank you.
|
||||
|
||||
//01:00:32:06
|
||||
//STIG
|
||||
//But first we'll go to our foreign guest, welcome to the programme. It’s a great pleasure having you here. Let me start with a standard question; is this your first time in Sweden?
|
||||
|
||||
//01:00:44:16
|
||||
//FEMALE ARTIST
|
||||
//No, I was here once many years ago, and I was introduced to your ”surströmming” – is that..?
|
||||
|
||||
private static readonly Regex RegexTimeCodes1 = new Regex(@"^\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 60"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(EncodeTimeCode(p.StartTime));
|
||||
sb.AppendLine(EncodeTimeCode(p.EndTime));
|
||||
if (!string.IsNullOrEmpty(p.Actor))
|
||||
sb.AppendLine(p.Actor.ToUpper());
|
||||
else
|
||||
sb.AppendLine("UNKNOWN ACTOR");
|
||||
sb.AppendLine(HtmlUtil.RemoveHtmlTags(p.Text));
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
bool expectActor = false;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
var match = RegexTimeCodes1.Match(s);
|
||||
if (match.Success && s.Length == 11)
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds > 0)
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
_errorCount++;
|
||||
}
|
||||
|
||||
p = new Paragraph();
|
||||
string[] parts = s.Split(':');
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.StartTime = DecodeTimeCodeFrames(parts);
|
||||
expectActor = true;
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
expectStartTime = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && expectActor)
|
||||
{
|
||||
if (line == line.ToUpper())
|
||||
p.Actor = line;
|
||||
else
|
||||
_errorCount++;
|
||||
expectActor = false;
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line) && !expectActor && !expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 5000)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p.StartTime.TotalMilliseconds > 0)
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
bool allNullEndTime = true;
|
||||
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
p = subtitle.Paragraphs[i];
|
||||
if (p.EndTime.TotalMilliseconds != 0)
|
||||
allNullEndTime = false;
|
||||
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
if (i < subtitle.Paragraphs.Count - 2 && p.EndTime.TotalMilliseconds >= subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds)
|
||||
p.EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
if (!allNullEndTime)
|
||||
subtitle.Paragraphs.Clear();
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,122 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle62 : SubtitleFormat
|
||||
{
|
||||
// 338: 00:24:34.00 00:24:37.10 [51]
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\.\d\d\s+\d\d:\d\d:\d\d\.\d\d\s+\[\d+\]$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 62"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}: {1} {2} [{3}]";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text.Length));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCode(parts[1], splitChars);
|
||||
p.EndTime = DecodeTimeCode(parts[2], splitChars);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle62 : SubtitleFormat
|
||||
{
|
||||
// 338: 00:24:34.00 00:24:37.10 [51]
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\.\d\d\s+\d\d:\d\d:\d\d\.\d\d\s+\[\d+\]$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 62"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}: {1} {2} [{3}]";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(format, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text.Length));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { '.', ':' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCodeFrames(parts[1], splitChars);
|
||||
p.EndTime = DecodeTimeCodeFrames(parts[2], splitChars);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,131 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle63 : SubtitleFormat
|
||||
{
|
||||
//3: 00:00:09:23 00:00:16:21 06:23
|
||||
//Alustame sellest...
|
||||
//Siin kajab kuidagi harjumatult.
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\:\d\d \d\d:\d\d:\d\d\:\d\d \d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 63"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}: {1} {2} {3:00}:{4:00}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
// to avoid rounding errors in duration
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
|
||||
sb.AppendLine(string.Format(format, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds)));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCode(parts[1], SplitCharColon);
|
||||
p.EndTime = DecodeTimeCode(parts[2], SplitCharColon);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle63 : SubtitleFormat
|
||||
{
|
||||
//3: 00:00:09:23 00:00:16:21 06:23
|
||||
//Alustame sellest...
|
||||
//Siin kajab kuidagi harjumatult.
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\s+\d\d:\d\d:\d\d\:\d\d \d\d:\d\d:\d\d\:\d\d \d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 63"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0}: {1} {2} {3:00}:{4:00}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
// to avoid rounding errors in duration
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
|
||||
sb.AppendLine(string.Format(format, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds)));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCodeFrames(parts[1], SplitCharColon);
|
||||
p.EndTime = DecodeTimeCodeFrames(parts[2], SplitCharColon);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,157 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle64 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 64"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
// 1
|
||||
// 00:00:04:12
|
||||
// 00:00:06:05
|
||||
// Berniukai, tik pažiūrėkit.
|
||||
|
||||
// 2
|
||||
// 00:00:06:16
|
||||
// 00:00:07:20
|
||||
// Argi ne puiku?
|
||||
|
||||
// 3
|
||||
// 00:00:08:02
|
||||
// 00:00:10:20
|
||||
// Tėti, ar galime čia paplaukioti?
|
||||
// -Aišku, kad galim.
|
||||
|
||||
const string paragraphWriteFormat = "{4}{3}{0}{3}{1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.Length < 6 && Utilities.IsInteger(line))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle64 : SubtitleFormat
|
||||
{
|
||||
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 64"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
// 1
|
||||
// 00:00:04:12
|
||||
// 00:00:06:05
|
||||
// Berniukai, tik pažiūrėkit.
|
||||
|
||||
// 2
|
||||
// 00:00:06:16
|
||||
// 00:00:07:20
|
||||
// Argi ne puiku?
|
||||
|
||||
// 3
|
||||
// 00:00:08:02
|
||||
// 00:00:10:20
|
||||
// Tėti, ar galime čia paplaukioti?
|
||||
// -Aišku, kad galim.
|
||||
|
||||
const string paragraphWriteFormat = "{4}{3}{0}{3}{1}{3}{2}{3}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.Length < 6 && Utilities.IsInteger(line))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = line;
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,135 +1,135 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle66 : SubtitleFormat
|
||||
{
|
||||
// 24 10:08:57:17 10:08:59:15 01:23
|
||||
//The question is,
|
||||
//
|
||||
// 25 10:08:59:19 10:09:04:01 04:07
|
||||
//is this upside-down vision
|
||||
//permanent or only temporary?
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+\s+\d\d:\d\d:\d\d\:\d\d\s+\d\d:\d\d:\d\d\:\d\d\s+\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 66"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0} {1} {2} {3:00}:{4:00}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
// to avoid rounding errors in duration
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
|
||||
sb.AppendLine(string.Format(format, count.ToString(CultureInfo.InvariantCulture).PadLeft(5), EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds)));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().TrimEnd();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCode(parts[1], SplitCharColon);
|
||||
p.EndTime = DecodeTimeCode(parts[2], SplitCharColon);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle66 : SubtitleFormat
|
||||
{
|
||||
// 24 10:08:57:17 10:08:59:15 01:23
|
||||
//The question is,
|
||||
//
|
||||
// 25 10:08:59:19 10:09:04:01 04:07
|
||||
//is this upside-down vision
|
||||
//permanent or only temporary?
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+\s+\d\d:\d\d:\d\d\:\d\d\s+\d\d:\d\d:\d\d\:\d\d\s+\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 66"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string format = "{0} {1} {2} {3:00}:{4:00}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
// to avoid rounding errors in duration
|
||||
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
|
||||
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
|
||||
var durationCalc = new Paragraph(
|
||||
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
|
||||
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
|
||||
string.Empty);
|
||||
|
||||
sb.AppendLine(string.Format(format, count.ToString(CultureInfo.InvariantCulture).PadLeft(5), EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds)));
|
||||
sb.AppendLine(p.Text);
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().TrimEnd();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
bool expectStartTime = true;
|
||||
var p = new Paragraph();
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim().Replace("*", string.Empty);
|
||||
var match = RegexTimeCodes.Match(s);
|
||||
if (match.Success)
|
||||
{
|
||||
string[] parts = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
p.StartTime = DecodeTimeCodeFrames(parts[1], SplitCharColon);
|
||||
p.EndTime = DecodeTimeCodeFrames(parts[2], SplitCharColon);
|
||||
expectStartTime = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (p.StartTime.TotalMilliseconds == 0 && p.EndTime.TotalMilliseconds == 0)
|
||||
_errorCount++;
|
||||
else
|
||||
subtitle.Paragraphs.Add(p);
|
||||
p = new Paragraph();
|
||||
}
|
||||
else if (!expectStartTime)
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 500)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
while (p.Text.Contains(Environment.NewLine + " "))
|
||||
p.Text = p.Text.Replace(Environment.NewLine + " ", Environment.NewLine);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,185 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle68 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\dF\d\d", RegexOptions.Compiled); //10:00:02F00
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 68"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//Mais l'image utilisée pour
|
||||
//nous vendre la nourriture
|
||||
// 10:00:44F11
|
||||
//
|
||||
//est restée celle d'une Amérique
|
||||
//bucolique et agraire.
|
||||
// 10:00:46F18 10:00:50F14
|
||||
var sb = new StringBuilder();
|
||||
if (subtitle.Header != null && subtitle.Header.Contains(";» DO NOT MODIFY THE FOLLOWING 3 LINES"))
|
||||
{
|
||||
sb.AppendLine(subtitle.Header.Trim());
|
||||
sb.AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(@";» Video file: C:\Documents and Settings\video.mpg
|
||||
;» Last edited: 24 sept. 09 11:26
|
||||
;» Timing model: NTSC (30 fps)
|
||||
;» Drop frame timing: ON
|
||||
;» Number of captions: 1348
|
||||
;» Caption time codes: 10:00:02F00 - 11:32:07F00
|
||||
;» Video start time: 09:59:15F12 (Forced)
|
||||
;» Insertion disk created: NO
|
||||
;» Reading speed: 300
|
||||
;» Minimum display time: 30
|
||||
;» Maximum display time (sec.): 5
|
||||
;» Minimum erase time: 0
|
||||
;» Tab stop value: 4
|
||||
;» Sticky mode: OFF
|
||||
;» Right justification ragged left: OFF
|
||||
;» Parallelogram filter: OFF
|
||||
;» Coding standard: EIA-608" + Environment.NewLine +
|
||||
";» \"Bottom\" row: 15" + @"
|
||||
;» Lines per caption: 15
|
||||
;» Characters per line: 32
|
||||
;» Default horizontal position: Center
|
||||
;» Default vertical position: Bottom
|
||||
;» Default mode: PopOn
|
||||
;» Captioning channel: 1
|
||||
|
||||
;» DO NOT MODIFY THE FOLLOWING 3 LINES
|
||||
;»»10<210>10000001000000040?000?000100030000100?:?8;;:400685701001000100210<1509274
|
||||
;»»2000000000200500005>??????091000000014279616<6000000000000000000000000000000000000000000000000000000005000105=4641;?
|
||||
;»»0020??000000900<0<0<008000000000000<0<0<0080000000??00<0??000=200>1000;5=83<:;
|
||||
;»
|
||||
;» ************************************************************************");
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
const string paragraphWriteFormat = "{0}{1} {2} {3}{1}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text.Replace("♪", "|");
|
||||
if (text.StartsWith("<i>"))
|
||||
text = ",b" + Environment.NewLine + text;
|
||||
if (text.StartsWith("{\\an8}"))
|
||||
text = ",12" + Environment.NewLine + text;
|
||||
text = HtmlUtil.RemoveHtmlTags(text, true);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, text, Environment.NewLine, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
var text = new StringBuilder();
|
||||
var header = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
char[] splitChars = { ':', 'F' };
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
{
|
||||
string line = lines[i].Trim();
|
||||
if (subtitle.Paragraphs.Count == 0 && line.StartsWith(';') || line.Length == 0)
|
||||
{
|
||||
header.AppendLine(line);
|
||||
}
|
||||
else if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
var timeParts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (timeParts.Length == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
TimeCode start = DecodeTimeCode(timeParts[0].Substring(0, 11), splitChars);
|
||||
if (p != null && p.EndTime.TotalMilliseconds == 0)
|
||||
p.EndTime.TotalMilliseconds = start.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
TimeCode end = new TimeCode(0, 0, 0, 0);
|
||||
p = MakeTextParagraph(text, p, start, end);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
text = new StringBuilder();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (timeParts.Length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
TimeCode start = DecodeTimeCode(timeParts[0].Substring(0, 11), splitChars);
|
||||
if (p != null && p.EndTime.TotalMilliseconds == 0)
|
||||
p.EndTime.TotalMilliseconds = start.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
TimeCode end = DecodeTimeCode(timeParts[1].Substring(0, 11), splitChars);
|
||||
p = MakeTextParagraph(text, p, start, end);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
text = new StringBuilder();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
text.AppendLine(line.Trim().Replace("|", "♪"));
|
||||
if (text.Length > 5000)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = new StringBuilder();
|
||||
}
|
||||
}
|
||||
subtitle.Header = header.ToString();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static Paragraph MakeTextParagraph(StringBuilder text, Paragraph p, TimeCode start, TimeCode end)
|
||||
{
|
||||
p = new Paragraph(start, end, text.ToString().Trim());
|
||||
if (p.Text.StartsWith(",b" + Environment.NewLine))
|
||||
p.Text = "<i>" + p.Text.Remove(0, 2).Trim() + "</i>";
|
||||
else if (p.Text.StartsWith(",1" + Environment.NewLine))
|
||||
p.Text = "{\\an8}" + p.Text.Remove(0, 2).Trim();
|
||||
else if (p.Text.StartsWith(",12" + Environment.NewLine))
|
||||
p.Text = "{\\an8}" + p.Text.Remove(0, 3).Trim();
|
||||
return p;
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}F{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle68 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d\d:\d\d:\d\dF\d\d", RegexOptions.Compiled); //10:00:02F00
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 68"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//Mais l'image utilisée pour
|
||||
//nous vendre la nourriture
|
||||
// 10:00:44F11
|
||||
//
|
||||
//est restée celle d'une Amérique
|
||||
//bucolique et agraire.
|
||||
// 10:00:46F18 10:00:50F14
|
||||
var sb = new StringBuilder();
|
||||
if (subtitle.Header != null && subtitle.Header.Contains(";» DO NOT MODIFY THE FOLLOWING 3 LINES"))
|
||||
{
|
||||
sb.AppendLine(subtitle.Header.Trim());
|
||||
sb.AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(@";» Video file: C:\Documents and Settings\video.mpg
|
||||
;» Last edited: 24 sept. 09 11:26
|
||||
;» Timing model: NTSC (30 fps)
|
||||
;» Drop frame timing: ON
|
||||
;» Number of captions: 1348
|
||||
;» Caption time codes: 10:00:02F00 - 11:32:07F00
|
||||
;» Video start time: 09:59:15F12 (Forced)
|
||||
;» Insertion disk created: NO
|
||||
;» Reading speed: 300
|
||||
;» Minimum display time: 30
|
||||
;» Maximum display time (sec.): 5
|
||||
;» Minimum erase time: 0
|
||||
;» Tab stop value: 4
|
||||
;» Sticky mode: OFF
|
||||
;» Right justification ragged left: OFF
|
||||
;» Parallelogram filter: OFF
|
||||
;» Coding standard: EIA-608" + Environment.NewLine +
|
||||
";» \"Bottom\" row: 15" + @"
|
||||
;» Lines per caption: 15
|
||||
;» Characters per line: 32
|
||||
;» Default horizontal position: Center
|
||||
;» Default vertical position: Bottom
|
||||
;» Default mode: PopOn
|
||||
;» Captioning channel: 1
|
||||
|
||||
;» DO NOT MODIFY THE FOLLOWING 3 LINES
|
||||
;»»10<210>10000001000000040?000?000100030000100?:?8;;:400685701001000100210<1509274
|
||||
;»»2000000000200500005>??????091000000014279616<6000000000000000000000000000000000000000000000000000000005000105=4641;?
|
||||
;»»0020??000000900<0<0<008000000000000<0<0<0080000000??00<0??000=200>1000;5=83<:;
|
||||
;»
|
||||
;» ************************************************************************");
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
const string paragraphWriteFormat = "{0}{1} {2} {3}{1}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = p.Text.Replace("♪", "|");
|
||||
if (text.StartsWith("<i>"))
|
||||
text = ",b" + Environment.NewLine + text;
|
||||
if (text.StartsWith("{\\an8}"))
|
||||
text = ",12" + Environment.NewLine + text;
|
||||
text = HtmlUtil.RemoveHtmlTags(text, true);
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, text, Environment.NewLine, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
var text = new StringBuilder();
|
||||
var header = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
char[] splitChars = { ':', 'F' };
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
{
|
||||
string line = lines[i].Trim();
|
||||
if (subtitle.Paragraphs.Count == 0 && line.StartsWith(';') || line.Length == 0)
|
||||
{
|
||||
header.AppendLine(line);
|
||||
}
|
||||
else if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
var timeParts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (timeParts.Length == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
TimeCode start = DecodeTimeCodeFrames(timeParts[0].Substring(0, 11), splitChars);
|
||||
if (p != null && p.EndTime.TotalMilliseconds == 0)
|
||||
p.EndTime.TotalMilliseconds = start.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
TimeCode end = new TimeCode(0, 0, 0, 0);
|
||||
p = MakeTextParagraph(text, p, start, end);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
text = new StringBuilder();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (timeParts.Length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
TimeCode start = DecodeTimeCodeFrames(timeParts[0].Substring(0, 11), splitChars);
|
||||
if (p != null && p.EndTime.TotalMilliseconds == 0)
|
||||
p.EndTime.TotalMilliseconds = start.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
TimeCode end = DecodeTimeCodeFrames(timeParts[1].Substring(0, 11), splitChars);
|
||||
p = MakeTextParagraph(text, p, start, end);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
text = new StringBuilder();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
text.AppendLine(line.Trim().Replace("|", "♪"));
|
||||
if (text.Length > 5000)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = new StringBuilder();
|
||||
}
|
||||
}
|
||||
subtitle.Header = header.ToString();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static Paragraph MakeTextParagraph(StringBuilder text, Paragraph p, TimeCode start, TimeCode end)
|
||||
{
|
||||
p = new Paragraph(start, end, text.ToString().Trim());
|
||||
if (p.Text.StartsWith(",b" + Environment.NewLine))
|
||||
p.Text = "<i>" + p.Text.Remove(0, 2).Trim() + "</i>";
|
||||
else if (p.Text.StartsWith(",1" + Environment.NewLine))
|
||||
p.Text = "{\\an8}" + p.Text.Remove(0, 2).Trim();
|
||||
else if (p.Text.StartsWith(",12" + Environment.NewLine))
|
||||
p.Text = "{\\an8}" + p.Text.Remove(0, 3).Trim();
|
||||
return p;
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}:{2:00}F{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,110 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle69 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\) \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d Durée : \d\d:\d\d", RegexOptions.Compiled); //10:00:02F00
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 69"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//1) 00:00:06:14 00:00:07:07 Durée : 00:18 Lisibilité : 011 Intervalle : 06:14 Nbc : 018
|
||||
//text
|
||||
//line2
|
||||
|
||||
//2) 00:00:07:14 00:00:09:02 Durée : 01:13 Lisibilité : 023 Intervalle : 00:07 Nbc : 026
|
||||
//text
|
||||
var sb = new StringBuilder();
|
||||
string paragraphWriteFormat = "{0}) {1} {2} Durée : {3} Lisibilité : {4} Intervalle : {5} Nbc : {6}" + Environment.NewLine + "{7}";
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text, true);
|
||||
string start = p.StartTime.ToHHMMSSFF();
|
||||
string end = p.EndTime.ToHHMMSSFF();
|
||||
string duration = string.Format("{0:00}:{1:00}", p.Duration.Seconds, MillisecondsToFramesMaxFrameRate(p.Duration.Milliseconds));
|
||||
const string readability = "011";
|
||||
const string interval = "06:14";
|
||||
string nbc = text.Length.ToString().PadLeft(3, '0');
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, count, start, end, duration, readability, interval, nbc, text));
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
var text = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
char[] splitChars = { ':', 'F' };
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
{
|
||||
string line = lines[i].Trim();
|
||||
if (line.Length == 0)
|
||||
{
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
}
|
||||
else if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
var timeParts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (timeParts.Length > 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string start = timeParts[1];
|
||||
string end = timeParts[2];
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCode(start.Substring(0, 11), splitChars);
|
||||
p.EndTime = DecodeTimeCode(end.Substring(0, 11), splitChars);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
text = new StringBuilder();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text.AppendLine(line);
|
||||
if (text.Length > 5000)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle69 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\) \d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d Durée : \d\d:\d\d", RegexOptions.Compiled); //10:00:02F00
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 69"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//1) 00:00:06:14 00:00:07:07 Durée : 00:18 Lisibilité : 011 Intervalle : 06:14 Nbc : 018
|
||||
//text
|
||||
//line2
|
||||
|
||||
//2) 00:00:07:14 00:00:09:02 Durée : 01:13 Lisibilité : 023 Intervalle : 00:07 Nbc : 026
|
||||
//text
|
||||
var sb = new StringBuilder();
|
||||
string paragraphWriteFormat = "{0}) {1} {2} Durée : {3} Lisibilité : {4} Intervalle : {5} Nbc : {6}" + Environment.NewLine + "{7}";
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text, true);
|
||||
string start = p.StartTime.ToHHMMSSFF();
|
||||
string end = p.EndTime.ToHHMMSSFF();
|
||||
string duration = string.Format("{0:00}:{1:00}", p.Duration.Seconds, MillisecondsToFramesMaxFrameRate(p.Duration.Milliseconds));
|
||||
const string readability = "011";
|
||||
const string interval = "06:14";
|
||||
string nbc = text.Length.ToString().PadLeft(3, '0');
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, count, start, end, duration, readability, interval, nbc, text));
|
||||
sb.AppendLine();
|
||||
count++;
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
var text = new StringBuilder();
|
||||
Paragraph p = null;
|
||||
char[] splitChars = { ':', 'F' };
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
{
|
||||
string line = lines[i].Trim();
|
||||
if (line.Length == 0)
|
||||
{
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
}
|
||||
else if (RegexTimeCode.IsMatch(line))
|
||||
{
|
||||
var timeParts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (timeParts.Length > 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
string start = timeParts[1];
|
||||
string end = timeParts[2];
|
||||
p = new Paragraph();
|
||||
p.StartTime = DecodeTimeCodeFrames(start.Substring(0, 11), splitChars);
|
||||
p.EndTime = DecodeTimeCodeFrames(end.Substring(0, 11), splitChars);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
text = new StringBuilder();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text.AppendLine(line);
|
||||
if (text.Length > 5000)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (p != null)
|
||||
p.Text = text.ToString().Trim();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,145 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// Reported by dipa nuswantara
|
||||
/// </summary>
|
||||
public class UnknownSubtitle7 : SubtitleFormat
|
||||
{
|
||||
private enum ExpectingLine
|
||||
{
|
||||
TimeStart,
|
||||
Text,
|
||||
TimeEndOrText,
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 7"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//00:00:54:16 Bisakah kalian diam,Tolong!
|
||||
//00:00:56:07
|
||||
//00:00:57:16 Benar, tepatnya saya tidak memiliki "Anda
|
||||
//sudah mendapat 24 jam" adegan... tapi
|
||||
//00:01:02:03
|
||||
|
||||
const string paragraphWriteFormat = "{0} {2}{3}{1}\t";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
var regexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
var regexTimeCodeEnd = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t$", RegexOptions.Compiled);
|
||||
|
||||
var paragraph = new Paragraph();
|
||||
var expecting = ExpectingLine.TimeStart;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
int count = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
count++;
|
||||
if (regexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
if (expecting == ExpectingLine.TimeStart)
|
||||
{
|
||||
paragraph = new Paragraph();
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
|
||||
if (line.Length > 12)
|
||||
{
|
||||
paragraph.Text = line.Substring(12).Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regexTimeCodeEnd.IsMatch(line) || (count == lines.Count && regexTimeCodeEnd.IsMatch(line + "\t")))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string text = line.Replace("|", Environment.NewLine);
|
||||
paragraph.Text += Environment.NewLine + text;
|
||||
expecting = ExpectingLine.TimeEndOrText;
|
||||
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// Reported by dipa nuswantara
|
||||
/// </summary>
|
||||
public class UnknownSubtitle7 : SubtitleFormat
|
||||
{
|
||||
private enum ExpectingLine
|
||||
{
|
||||
TimeStart,
|
||||
Text,
|
||||
TimeEndOrText,
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 7"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//00:00:54:16 Bisakah kalian diam,Tolong!
|
||||
//00:00:56:07
|
||||
//00:00:57:16 Benar, tepatnya saya tidak memiliki "Anda
|
||||
//sudah mendapat 24 jam" adegan... tapi
|
||||
//00:01:02:03
|
||||
|
||||
const string paragraphWriteFormat = "{0} {2}{3}{1}\t";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text, Environment.NewLine));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
var regexTimeCode = new Regex(@"^\d\d:\d\d:\d\d:\d\d ", RegexOptions.Compiled);
|
||||
var regexTimeCodeEnd = new Regex(@"^\d\d:\d\d:\d\d:\d\d\t$", RegexOptions.Compiled);
|
||||
|
||||
var paragraph = new Paragraph();
|
||||
var expecting = ExpectingLine.TimeStart;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
int count = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
count++;
|
||||
if (regexTimeCode.IsMatch(line))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
if (expecting == ExpectingLine.TimeStart)
|
||||
{
|
||||
paragraph = new Paragraph();
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
|
||||
if (line.Length > 12)
|
||||
{
|
||||
paragraph.Text = line.Substring(12).Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regexTimeCodeEnd.IsMatch(line) || (count == lines.Count && regexTimeCodeEnd.IsMatch(line + "\t")))
|
||||
{
|
||||
string[] parts = line.Substring(0, 11).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string text = line.Replace("|", Environment.NewLine);
|
||||
paragraph.Text += Environment.NewLine + text;
|
||||
expecting = ExpectingLine.TimeEndOrText;
|
||||
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,207 +1,207 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle71 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^ \d \d : \d \d : \d \d : \d \d $", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode2 = new Regex(@"^\d \d : \d \d : \d \d : \d \d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 71"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string AddSpaces(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return " ";
|
||||
|
||||
var sb = new StringBuilder(@" ");
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
sb.Append(text[i]);
|
||||
sb.Append(' ');
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string RemoveSpaces(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return string.Empty;
|
||||
|
||||
text = text.Trim();
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
if (i % 2 == 1 && text[i] != ' ')
|
||||
return text;
|
||||
}
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
if (i % 2 == 0)
|
||||
sb.Append(text[i]);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
// 1 .
|
||||
// 0 0 : 0 0 : 0 4 : 1 2
|
||||
// 0 0 : 0 0 : 0 6 : 0 5
|
||||
// H a l l o !
|
||||
|
||||
// 2.
|
||||
// 0 0 : 0 0 : 0 6 : 1 6
|
||||
// 0 0 : 0 0 : 0 7 : 2 0
|
||||
// G e t i n s i d e , m o m !
|
||||
// - I w a n t t o c o m e .
|
||||
|
||||
const string paragraphWriteFormat = "{4} . {3}{3}{0}{3}{3}{1}{3}{3}{2}{3}{3}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = AddSpaces(HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont));
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (expecting == ExpectingLine.Number && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line.Trim())))
|
||||
{
|
||||
_errorCount++;
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
|
||||
if (line.TrimEnd().EndsWith('.') && Utilities.IsInteger(RemoveSpaces(line.Trim().TrimEnd('.').Trim())))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line.Trim())))
|
||||
{
|
||||
string[] parts = RemoveSpaces(line.Trim()).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line.Trim())))
|
||||
{
|
||||
string[] parts = RemoveSpaces(line.Trim()).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCode(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line == " " || line.Trim() == @"...........\...........")
|
||||
{
|
||||
}
|
||||
else if (line == "*END*")
|
||||
{
|
||||
_errorCount++;
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = RemoveSpaces(line);
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.Length > 1)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
var s = time.ToHHMMSSFF();
|
||||
return AddSpaces(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle71 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^ \d \d : \d \d : \d \d : \d \d $", RegexOptions.Compiled);
|
||||
private static readonly Regex RegexTimeCode2 = new Regex(@"^\d \d : \d \d : \d \d : \d \d$", RegexOptions.Compiled);
|
||||
|
||||
private enum ExpectingLine
|
||||
{
|
||||
Number,
|
||||
TimeStart,
|
||||
TimeEnd,
|
||||
Text
|
||||
}
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 71"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
private static string AddSpaces(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return " ";
|
||||
|
||||
var sb = new StringBuilder(@" ");
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
sb.Append(text[i]);
|
||||
sb.Append(' ');
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string RemoveSpaces(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return string.Empty;
|
||||
|
||||
text = text.Trim();
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
if (i % 2 == 1 && text[i] != ' ')
|
||||
return text;
|
||||
}
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
if (i % 2 == 0)
|
||||
sb.Append(text[i]);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
// 1 .
|
||||
// 0 0 : 0 0 : 0 4 : 1 2
|
||||
// 0 0 : 0 0 : 0 6 : 0 5
|
||||
// H a l l o !
|
||||
|
||||
// 2.
|
||||
// 0 0 : 0 0 : 0 6 : 1 6
|
||||
// 0 0 : 0 0 : 0 7 : 2 0
|
||||
// G e t i n s i d e , m o m !
|
||||
// - I w a n t t o c o m e .
|
||||
|
||||
const string paragraphWriteFormat = "{4} . {3}{3}{0}{3}{3}{1}{3}{3}{2}{3}{3}";
|
||||
var sb = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
count++;
|
||||
var text = AddSpaces(HtmlUtil.RemoveOpenCloseTags(p.Text, HtmlUtil.TagFont));
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text, Environment.NewLine, count));
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
ExpectingLine expecting = ExpectingLine.Number;
|
||||
_errorCount = 0;
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (expecting == ExpectingLine.Number && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line.Trim())))
|
||||
{
|
||||
_errorCount++;
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
|
||||
if (line.TrimEnd().EndsWith('.') && Utilities.IsInteger(RemoveSpaces(line.Trim().TrimEnd('.').Trim())))
|
||||
{
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.TimeStart;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeStart && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line.Trim())))
|
||||
{
|
||||
string[] parts = RemoveSpaces(line.Trim()).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.StartTime = tc;
|
||||
expecting = ExpectingLine.TimeEnd;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.TimeEnd && (RegexTimeCode.IsMatch(line) || RegexTimeCode2.IsMatch(line.Trim())))
|
||||
{
|
||||
string[] parts = RemoveSpaces(line.Trim()).Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tc = DecodeTimeCodeFrames(parts);
|
||||
paragraph.EndTime = tc;
|
||||
expecting = ExpectingLine.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line == " " || line.Trim() == @"...........\...........")
|
||||
{
|
||||
}
|
||||
else if (line == "*END*")
|
||||
{
|
||||
_errorCount++;
|
||||
if (paragraph != null)
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
paragraph = new Paragraph();
|
||||
expecting = ExpectingLine.Number;
|
||||
}
|
||||
else if (paragraph != null && expecting == ExpectingLine.Text)
|
||||
{
|
||||
if (line.Length > 0)
|
||||
{
|
||||
string s = RemoveSpaces(line);
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + s).Trim();
|
||||
if (paragraph.Text.Length > 2000)
|
||||
{
|
||||
_errorCount += 100;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.Length > 1)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paragraph != null && !string.IsNullOrEmpty(paragraph.Text))
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
var s = time.ToHHMMSSFF();
|
||||
return AddSpaces(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,123 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle73 : SubtitleFormat
|
||||
{
|
||||
//59:00:22:09:14 00:22:12:04 02:15
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d \d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 73"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//59:00:22:09:14 00:22:12:04 02:15
|
||||
//
|
||||
//LÕaria fresca arriva
|
||||
//
|
||||
//dai monti di Petr—polis
|
||||
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
text = text.Replace(Environment.NewLine, "\n\n");
|
||||
sb.AppendFormat("{0}:{1} {2} {3}\n{4}\n\n", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), EncodeDuration(p), text);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeDuration(Paragraph p)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}", p.Duration.Seconds, MillisecondsToFramesMaxFrameRate(p.Duration.Milliseconds));
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line;
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
s = s.Remove(0, s.IndexOf(':') + 1).Trim();
|
||||
var temp = s.Split(' ');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(':');
|
||||
string[] endParts = end.Split(':');
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p == null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 1000)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle73 : SubtitleFormat
|
||||
{
|
||||
//59:00:22:09:14 00:22:12:04 02:15
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d+:\d\d:\d\d:\d\d:\d\d \d\d:\d\d:\d\d:\d\d \d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 73"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//59:00:22:09:14 00:22:12:04 02:15
|
||||
//
|
||||
//LÕaria fresca arriva
|
||||
//
|
||||
//dai monti di Petr—polis
|
||||
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
index++;
|
||||
string text = HtmlUtil.RemoveHtmlTags(p.Text);
|
||||
text = text.Replace(Environment.NewLine, "\n\n");
|
||||
sb.AppendFormat("{0}:{1} {2} {3}\n{4}\n\n", index, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), EncodeDuration(p), text);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeDuration(Paragraph p)
|
||||
{
|
||||
return string.Format("{0:00}:{1:00}", p.Duration.Seconds, MillisecondsToFramesMaxFrameRate(p.Duration.Milliseconds));
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line;
|
||||
if (RegexTimeCodes.IsMatch(s))
|
||||
{
|
||||
s = s.Remove(0, s.IndexOf(':') + 1).Trim();
|
||||
var temp = s.Split(' ');
|
||||
if (temp.Length > 1)
|
||||
{
|
||||
string start = temp[0];
|
||||
string end = temp[1];
|
||||
|
||||
string[] startParts = start.Split(':');
|
||||
string[] endParts = end.Split(':');
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_errorCount++;
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip empty lines
|
||||
}
|
||||
else if (p == null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + line).Trim();
|
||||
if (p.Text.Length > 1000)
|
||||
{
|
||||
_errorCount += 10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,89 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle77 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\s+->\s+\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 77"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
const string writeFormat = "{0} -> {1}{2}{3}{2}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:50:34:22 -> 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
sb.AppendLine(string.Format(writeFormat, p.StartTime.ToHHMMSSFF(), p.EndTime.ToHHMMSSFF(), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 -> 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
int indexOfSeparator = temp.IndexOf("->", StringComparison.Ordinal);
|
||||
string start = temp.Substring(0, indexOfSeparator).Trim();
|
||||
string end = temp.Substring(indexOfSeparator + 2).Trim();
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCode(startParts), DecodeTimeCode(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle77 : SubtitleFormat
|
||||
{
|
||||
private static readonly Regex RegexTimeCodes = new Regex(@"^\d\d:\d\d:\d\d:\d\d\s+->\s+\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 77"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
const string writeFormat = "{0} -> {1}{2}{3}{2}";
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
//00:50:34:22 -> 00:50:39:13
|
||||
//Ich muss dafür sorgen,
|
||||
//dass die Epsteins weiterleben
|
||||
sb.AppendLine(string.Format(writeFormat, p.StartTime.ToHHMMSSFF(), p.EndTime.ToHHMMSSFF(), Environment.NewLine, HtmlUtil.RemoveHtmlTags(p.Text, true)));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//00:03:15:22 -> 00:03:23:10 This is line one.
|
||||
//This is line two.
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
_errorCount = 0;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (RegexTimeCodes.IsMatch(line))
|
||||
{
|
||||
string temp = line.Substring(0, RegexTimeCodes.Match(line).Length);
|
||||
int indexOfSeparator = temp.IndexOf("->", StringComparison.Ordinal);
|
||||
string start = temp.Substring(0, indexOfSeparator).Trim();
|
||||
string end = temp.Substring(indexOfSeparator + 2).Trim();
|
||||
|
||||
string[] startParts = start.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] endParts = end.Split(SplitCharColon, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (startParts.Length == 4 && endParts.Length == 4)
|
||||
{
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startParts), DecodeTimeCodeFrames(endParts), string.Empty);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
// skip these lines
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p.Text))
|
||||
p.Text = line;
|
||||
else
|
||||
p.Text = p.Text + Environment.NewLine + line;
|
||||
}
|
||||
}
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,216 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
internal class UnknownSubtitle78 : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 78"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string xmpTemplate = @"<?xml version='1.0' encoding='utf-8'?>
|
||||
<Document version='1.0'>
|
||||
<FileInfo>
|
||||
<FileID>CCTV Subtitle Sequence File</FileID>
|
||||
<FileVersion>1.0</FileVersion>
|
||||
<CodePage>1</CodePage>
|
||||
<Program>CG1</Program>
|
||||
<Author>Jetsen</Author>
|
||||
<Description>CCTV Subtitle Sequence Generate by Jetsen</Description>
|
||||
<CreationDate>[YYYY-MM-DD]</CreationDate>
|
||||
<RevisionDate>[YYYY-MM-DD]</RevisionDate>
|
||||
<RevisionNumber>1</RevisionNumber>
|
||||
<Language>
|
||||
<Primary>0</Primary>
|
||||
<Secondary>0</Secondary>
|
||||
</Language>
|
||||
<VideoStandard>HD_1080_25i</VideoStandard>
|
||||
<SectionCount>1</SectionCount>
|
||||
</FileInfo>
|
||||
<TextSection>
|
||||
<SectionInfo>
|
||||
<ScreenCount>1008</ScreenCount>
|
||||
<BlockCount>2</BlockCount>
|
||||
<TimeCodeMode>2</TimeCodeMode>
|
||||
<StartTimeCode>[TIME_CODE_FIRST]</StartTimeCode>
|
||||
<EndTimeCode>[TIME_CODE_LAST]</EndTimeCode>
|
||||
<TrimCodeIn>0</TrimCodeIn>
|
||||
<TrimCodeOut>66373</TrimCodeOut>
|
||||
<DisplayParameters>
|
||||
<BlockParameters version='1.0'>
|
||||
<Language></Language>
|
||||
<UnicodeBitField></UnicodeBitField>
|
||||
<Position X='125' Y='908' Width='390' Height='60'/>
|
||||
<Bound X='125' Y='908' Width='390' Height='60'/>
|
||||
<Font Name='黑体' Width='102' Height='62' Bold='0' Italic='0' Underline='0'/>
|
||||
<FontLatin Name='Arial' Width='102' Height='62' Bold='0' Italic='0' Underline='0'/>
|
||||
<LineAlign Align='0'/>
|
||||
<Layout CharSpace='1' LineSpace='2' Alignment='0' Direction='0'/>
|
||||
<TextColor R='229' G='229' B='229' A='255'/>
|
||||
<Side Width='3' Direction='8'/>
|
||||
<SideColor R='16' G='16' B='16' A='255'/>
|
||||
<Edge Angle='1' Width='0'/>
|
||||
<EdgeColor R='235' G='235' B='235' A='255'/>
|
||||
<Shadow OffsetX='0' OffsetY='0' Blur='0'/>
|
||||
<ShadowColor R='235' G='235' B='235' A='255'/>
|
||||
<Background Mode='0'/>
|
||||
<BackgroundColor R='0' G='0' B='0' A='0'/>
|
||||
</BlockParameters>
|
||||
<BlockParameters version='1.0'>
|
||||
<Language></Language>
|
||||
<UnicodeBitField></UnicodeBitField>
|
||||
<Position X='130' Y='974' Width='266' Height='47'/>
|
||||
<Bound X='130' Y='974' Width='266' Height='47'/>
|
||||
<Font Name='黑体' Width='54' Height='38' Bold='0' Italic='0' Underline='0'/>
|
||||
<FontLatin Name='Arial' Width='54' Height='38' Bold='0' Italic='0' Underline='0'/>
|
||||
<LineAlign Align='0'/>
|
||||
<Layout CharSpace='2' LineSpace='2' Alignment='0' Direction='0'/>
|
||||
<TextColor R='235' G='235' B='235' A='255'/>
|
||||
<Side Width='3' Direction='8'/>
|
||||
<SideColor R='16' G='16' B='16' A='255'/>
|
||||
<Edge Angle='0' Width='0'/>
|
||||
<EdgeColor R='235' G='235' B='235' A='255'/>
|
||||
<Shadow OffsetX='0' OffsetY='0' Blur='0'/>
|
||||
<ShadowColor R='235' G='235' B='235' A='255'/>
|
||||
<Background Mode='0'/>
|
||||
<BackgroundColor R='0' G='0' B='0' A='0'/>
|
||||
</BlockParameters>
|
||||
</DisplayParameters>
|
||||
<Private>
|
||||
<FreeCG>IsContinuousClip=FALSE</FreeCG>
|
||||
</Private>
|
||||
<ActionIn>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>0</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionIn>
|
||||
<ActionStay>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>52</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionStay>
|
||||
<ActionOut>
|
||||
<TCIn>52</TCIn>
|
||||
<TCOut>53</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionOut>
|
||||
</SectionInfo>
|
||||
</TextSection>
|
||||
</Document>";
|
||||
|
||||
const string paragraphTemplate = @"
|
||||
<TimeCodeIn>00:00:15:09</TimeCodeIn>
|
||||
<TimeCodeOut>00:00:16:14</TimeCodeOut>
|
||||
<TextBlock>
|
||||
<String></String>
|
||||
</TextBlock>
|
||||
<TextBlock>
|
||||
<String></String>
|
||||
</TextBlock>
|
||||
<ActionIn>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>0</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionIn>
|
||||
<ActionStay>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>29</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionStay>
|
||||
<ActionOut>
|
||||
<TCIn>29</TCIn>
|
||||
<TCOut>30</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionOut>";
|
||||
var xml = new XmlDocument();
|
||||
var firstTimeCode = new TimeCode(0);
|
||||
var lastTimeCode = new TimeCode(0);
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
firstTimeCode = subtitle.Paragraphs[0].StartTime;
|
||||
lastTimeCode = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].StartTime;
|
||||
}
|
||||
string today = DateTime.Now.ToString("YYYY-mm-DD");
|
||||
xml.LoadXml(xmpTemplate.Replace('\'', '"').Replace("[YYYY-MM-DD]", today).Replace("[TIME_CODE_FIRST]", firstTimeCode.ToHHMMSSFF()).Replace("[TIME_CODE_LAST]", lastTimeCode.ToHHMMSSFF()));
|
||||
|
||||
var paragraphInsertNode = xml.DocumentElement.SelectSingleNode("TextSection");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("TextScreen");
|
||||
paragraph.InnerXml = paragraphTemplate;
|
||||
paragraph.SelectSingleNode("TimeCodeIn").InnerText = p.StartTime.ToHHMMSSFF();
|
||||
paragraph.SelectSingleNode("TimeCodeOut").InnerText = p.EndTime.ToHHMMSSFF();
|
||||
var textBlockNodes = paragraph.SelectNodes("TextBlock");
|
||||
textBlockNodes[0].SelectSingleNode("String").InnerText = p.Text;
|
||||
paragraphInsertNode.AppendChild(paragraph);
|
||||
}
|
||||
return ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty);
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xmlAsText = sb.ToString().Trim();
|
||||
if (!xmlAsText.Contains("<TextSection>") || !xmlAsText.Contains("<TextScreen>"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(xmlAsText);
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("TextSection/TextScreen"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var timeCodeIn = DecodeTimeCode(node.SelectSingleNode("TimeCodeIn").InnerText, SplitCharColon);
|
||||
var timeCodeOut = DecodeTimeCode(node.SelectSingleNode("TimeCodeOut").InnerText, SplitCharColon);
|
||||
sb.Clear();
|
||||
foreach (XmlNode textBlockNode in node.SelectNodes("TextBlock"))
|
||||
{
|
||||
sb.AppendLine(textBlockNode.InnerText);
|
||||
}
|
||||
var p = new Paragraph(timeCodeIn, timeCodeOut, sb.ToString().Trim());
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
internal class UnknownSubtitle78 : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xml"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 78"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string xmpTemplate = @"<?xml version='1.0' encoding='utf-8'?>
|
||||
<Document version='1.0'>
|
||||
<FileInfo>
|
||||
<FileID>CCTV Subtitle Sequence File</FileID>
|
||||
<FileVersion>1.0</FileVersion>
|
||||
<CodePage>1</CodePage>
|
||||
<Program>CG1</Program>
|
||||
<Author>Jetsen</Author>
|
||||
<Description>CCTV Subtitle Sequence Generate by Jetsen</Description>
|
||||
<CreationDate>[YYYY-MM-DD]</CreationDate>
|
||||
<RevisionDate>[YYYY-MM-DD]</RevisionDate>
|
||||
<RevisionNumber>1</RevisionNumber>
|
||||
<Language>
|
||||
<Primary>0</Primary>
|
||||
<Secondary>0</Secondary>
|
||||
</Language>
|
||||
<VideoStandard>HD_1080_25i</VideoStandard>
|
||||
<SectionCount>1</SectionCount>
|
||||
</FileInfo>
|
||||
<TextSection>
|
||||
<SectionInfo>
|
||||
<ScreenCount>1008</ScreenCount>
|
||||
<BlockCount>2</BlockCount>
|
||||
<TimeCodeMode>2</TimeCodeMode>
|
||||
<StartTimeCode>[TIME_CODE_FIRST]</StartTimeCode>
|
||||
<EndTimeCode>[TIME_CODE_LAST]</EndTimeCode>
|
||||
<TrimCodeIn>0</TrimCodeIn>
|
||||
<TrimCodeOut>66373</TrimCodeOut>
|
||||
<DisplayParameters>
|
||||
<BlockParameters version='1.0'>
|
||||
<Language></Language>
|
||||
<UnicodeBitField></UnicodeBitField>
|
||||
<Position X='125' Y='908' Width='390' Height='60'/>
|
||||
<Bound X='125' Y='908' Width='390' Height='60'/>
|
||||
<Font Name='黑体' Width='102' Height='62' Bold='0' Italic='0' Underline='0'/>
|
||||
<FontLatin Name='Arial' Width='102' Height='62' Bold='0' Italic='0' Underline='0'/>
|
||||
<LineAlign Align='0'/>
|
||||
<Layout CharSpace='1' LineSpace='2' Alignment='0' Direction='0'/>
|
||||
<TextColor R='229' G='229' B='229' A='255'/>
|
||||
<Side Width='3' Direction='8'/>
|
||||
<SideColor R='16' G='16' B='16' A='255'/>
|
||||
<Edge Angle='1' Width='0'/>
|
||||
<EdgeColor R='235' G='235' B='235' A='255'/>
|
||||
<Shadow OffsetX='0' OffsetY='0' Blur='0'/>
|
||||
<ShadowColor R='235' G='235' B='235' A='255'/>
|
||||
<Background Mode='0'/>
|
||||
<BackgroundColor R='0' G='0' B='0' A='0'/>
|
||||
</BlockParameters>
|
||||
<BlockParameters version='1.0'>
|
||||
<Language></Language>
|
||||
<UnicodeBitField></UnicodeBitField>
|
||||
<Position X='130' Y='974' Width='266' Height='47'/>
|
||||
<Bound X='130' Y='974' Width='266' Height='47'/>
|
||||
<Font Name='黑体' Width='54' Height='38' Bold='0' Italic='0' Underline='0'/>
|
||||
<FontLatin Name='Arial' Width='54' Height='38' Bold='0' Italic='0' Underline='0'/>
|
||||
<LineAlign Align='0'/>
|
||||
<Layout CharSpace='2' LineSpace='2' Alignment='0' Direction='0'/>
|
||||
<TextColor R='235' G='235' B='235' A='255'/>
|
||||
<Side Width='3' Direction='8'/>
|
||||
<SideColor R='16' G='16' B='16' A='255'/>
|
||||
<Edge Angle='0' Width='0'/>
|
||||
<EdgeColor R='235' G='235' B='235' A='255'/>
|
||||
<Shadow OffsetX='0' OffsetY='0' Blur='0'/>
|
||||
<ShadowColor R='235' G='235' B='235' A='255'/>
|
||||
<Background Mode='0'/>
|
||||
<BackgroundColor R='0' G='0' B='0' A='0'/>
|
||||
</BlockParameters>
|
||||
</DisplayParameters>
|
||||
<Private>
|
||||
<FreeCG>IsContinuousClip=FALSE</FreeCG>
|
||||
</Private>
|
||||
<ActionIn>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>0</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionIn>
|
||||
<ActionStay>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>52</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionStay>
|
||||
<ActionOut>
|
||||
<TCIn>52</TCIn>
|
||||
<TCOut>53</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionOut>
|
||||
</SectionInfo>
|
||||
</TextSection>
|
||||
</Document>";
|
||||
|
||||
const string paragraphTemplate = @"
|
||||
<TimeCodeIn>00:00:15:09</TimeCodeIn>
|
||||
<TimeCodeOut>00:00:16:14</TimeCodeOut>
|
||||
<TextBlock>
|
||||
<String></String>
|
||||
</TextBlock>
|
||||
<TextBlock>
|
||||
<String></String>
|
||||
</TextBlock>
|
||||
<ActionIn>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>0</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionIn>
|
||||
<ActionStay>
|
||||
<TCIn>0</TCIn>
|
||||
<TCOut>29</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionStay>
|
||||
<ActionOut>
|
||||
<TCIn>29</TCIn>
|
||||
<TCOut>30</TCOut>
|
||||
<Type>0</Type>
|
||||
</ActionOut>";
|
||||
var xml = new XmlDocument();
|
||||
var firstTimeCode = new TimeCode(0);
|
||||
var lastTimeCode = new TimeCode(0);
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
firstTimeCode = subtitle.Paragraphs[0].StartTime;
|
||||
lastTimeCode = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].StartTime;
|
||||
}
|
||||
string today = DateTime.Now.ToString("YYYY-mm-DD");
|
||||
xml.LoadXml(xmpTemplate.Replace('\'', '"').Replace("[YYYY-MM-DD]", today).Replace("[TIME_CODE_FIRST]", firstTimeCode.ToHHMMSSFF()).Replace("[TIME_CODE_LAST]", lastTimeCode.ToHHMMSSFF()));
|
||||
|
||||
var paragraphInsertNode = xml.DocumentElement.SelectSingleNode("TextSection");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("TextScreen");
|
||||
paragraph.InnerXml = paragraphTemplate;
|
||||
paragraph.SelectSingleNode("TimeCodeIn").InnerText = p.StartTime.ToHHMMSSFF();
|
||||
paragraph.SelectSingleNode("TimeCodeOut").InnerText = p.EndTime.ToHHMMSSFF();
|
||||
var textBlockNodes = paragraph.SelectNodes("TextBlock");
|
||||
textBlockNodes[0].SelectSingleNode("String").InnerText = p.Text;
|
||||
paragraphInsertNode.AppendChild(paragraph);
|
||||
}
|
||||
return ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty);
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xmlAsText = sb.ToString().Trim();
|
||||
if (!xmlAsText.Contains("<TextSection>") || !xmlAsText.Contains("<TextScreen>"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(xmlAsText);
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("TextSection/TextScreen"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var timeCodeIn = DecodeTimeCodeFrames(node.SelectSingleNode("TimeCodeIn").InnerText, SplitCharColon);
|
||||
var timeCodeOut = DecodeTimeCodeFrames(node.SelectSingleNode("TimeCodeOut").InnerText, SplitCharColon);
|
||||
sb.Clear();
|
||||
foreach (XmlNode textBlockNode in node.SelectNodes("TextBlock"))
|
||||
{
|
||||
sb.AppendLine(textBlockNode.InnerText);
|
||||
}
|
||||
var p = new Paragraph(timeCodeIn, timeCodeOut, sb.ToString().Trim());
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,156 +1,156 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle79 : SubtitleFormat
|
||||
{
|
||||
|
||||
// SUB [0 N 00:00:00:00>00:00:00:00]
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^SUB \[\d [NIB] \d\d:\d\d:\d\d:\d\d>\d\d:\d\d:\d\d\:\d\d\]", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 79"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//SUB [0 N 00:00:00:00>00:00:00:00]
|
||||
//Subtitle 1
|
||||
//Subtitle 2
|
||||
|
||||
//0 = Height (0=bottom, 5=middle, 9=top)
|
||||
//N or I or B = Normal or Italic or Bold
|
||||
|
||||
const string paragraphWriteFormat = "SUB [{0} {1} {2}>{3}]{4}{5}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var text = p.Text.Trim();
|
||||
|
||||
string verticalAlignment = "0";
|
||||
if (text.StartsWith("{\\an7}") || text.StartsWith("{\\an8}") || text.StartsWith("{\\an9}"))
|
||||
{
|
||||
verticalAlignment = "9";
|
||||
}
|
||||
else if (text.StartsWith("{\\an4}") || text.StartsWith("{\\an5}") || text.StartsWith("{\\an6}"))
|
||||
{
|
||||
verticalAlignment = "5";
|
||||
}
|
||||
|
||||
text = Utilities.RemoveSsaTags(text);
|
||||
string formatting = "N";
|
||||
if (text.StartsWith("<i>"))
|
||||
formatting = "I";
|
||||
else if (text.StartsWith("<b>"))
|
||||
formatting = "B";
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, verticalAlignment, formatting, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, text));
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
_errorCount = 0;
|
||||
string formatting = "N";
|
||||
string verticalAglinment = "0";
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ' ', '>' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (s.Length == 33 && RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
var parts = s.Split(splitChars);
|
||||
if (parts.Length == 5)
|
||||
{
|
||||
AddParagraph(subtitle, paragraph, formatting, verticalAglinment);
|
||||
|
||||
try
|
||||
{
|
||||
verticalAglinment = parts[1].TrimStart('[');
|
||||
formatting = parts[2];
|
||||
paragraph = new Paragraph { StartTime = DecodeTimeCode(parts[3], SplitCharColon), EndTime = DecodeTimeCode(parts[4].TrimEnd(']'), SplitCharColon) };
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && Utilities.GetNumberOfLines(paragraph.Text) < 15)
|
||||
{
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + line).Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
if (_errorCount > 10)
|
||||
return;
|
||||
}
|
||||
}
|
||||
AddParagraph(subtitle, paragraph, formatting, verticalAglinment);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static void AddParagraph(Subtitle subtitle, Paragraph paragraph, string formatting, string verticalAglinment)
|
||||
{
|
||||
if (paragraph != null)
|
||||
{
|
||||
if (formatting == "I")
|
||||
{
|
||||
paragraph.Text = "<i>" + paragraph.Text + "</i>";
|
||||
}
|
||||
else if (formatting == "B")
|
||||
{
|
||||
paragraph.Text = "<b>" + paragraph.Text + "</b>";
|
||||
}
|
||||
|
||||
if (verticalAglinment == "7" || verticalAglinment == "8" || verticalAglinment == "9")
|
||||
{
|
||||
paragraph.Text = "{\\an8}" + paragraph.Text;
|
||||
}
|
||||
else if (verticalAglinment == "3" || verticalAglinment == "4" || verticalAglinment == "5" || verticalAglinment == "6")
|
||||
{
|
||||
paragraph.Text = "{\\an5}" + paragraph.Text;
|
||||
}
|
||||
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle79 : SubtitleFormat
|
||||
{
|
||||
|
||||
// SUB [0 N 00:00:00:00>00:00:00:00]
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^SUB \[\d [NIB] \d\d:\d\d:\d\d:\d\d>\d\d:\d\d:\d\d\:\d\d\]", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".txt"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 79"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
//SUB [0 N 00:00:00:00>00:00:00:00]
|
||||
//Subtitle 1
|
||||
//Subtitle 2
|
||||
|
||||
//0 = Height (0=bottom, 5=middle, 9=top)
|
||||
//N or I or B = Normal or Italic or Bold
|
||||
|
||||
const string paragraphWriteFormat = "SUB [{0} {1} {2}>{3}]{4}{5}";
|
||||
var sb = new StringBuilder();
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var text = p.Text.Trim();
|
||||
|
||||
string verticalAlignment = "0";
|
||||
if (text.StartsWith("{\\an7}") || text.StartsWith("{\\an8}") || text.StartsWith("{\\an9}"))
|
||||
{
|
||||
verticalAlignment = "9";
|
||||
}
|
||||
else if (text.StartsWith("{\\an4}") || text.StartsWith("{\\an5}") || text.StartsWith("{\\an6}"))
|
||||
{
|
||||
verticalAlignment = "5";
|
||||
}
|
||||
|
||||
text = Utilities.RemoveSsaTags(text);
|
||||
string formatting = "N";
|
||||
if (text.StartsWith("<i>"))
|
||||
formatting = "I";
|
||||
else if (text.StartsWith("<b>"))
|
||||
formatting = "B";
|
||||
text = HtmlUtil.RemoveHtmlTags(text);
|
||||
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, verticalAlignment, formatting, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), Environment.NewLine, text));
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
_errorCount = 0;
|
||||
string formatting = "N";
|
||||
string verticalAglinment = "0";
|
||||
|
||||
subtitle.Paragraphs.Clear();
|
||||
char[] splitChars = { ' ', '>' };
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (s.Length == 33 && RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
var parts = s.Split(splitChars);
|
||||
if (parts.Length == 5)
|
||||
{
|
||||
AddParagraph(subtitle, paragraph, formatting, verticalAglinment);
|
||||
|
||||
try
|
||||
{
|
||||
verticalAglinment = parts[1].TrimStart('[');
|
||||
formatting = parts[2];
|
||||
paragraph = new Paragraph { StartTime = DecodeTimeCodeFrames(parts[3], SplitCharColon), EndTime = DecodeTimeCodeFrames(parts[4].TrimEnd(']'), SplitCharColon) };
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && Utilities.GetNumberOfLines(paragraph.Text) < 15)
|
||||
{
|
||||
paragraph.Text = (paragraph.Text + Environment.NewLine + line).Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
if (_errorCount > 10)
|
||||
return;
|
||||
}
|
||||
}
|
||||
AddParagraph(subtitle, paragraph, formatting, verticalAglinment);
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static void AddParagraph(Subtitle subtitle, Paragraph paragraph, string formatting, string verticalAglinment)
|
||||
{
|
||||
if (paragraph != null)
|
||||
{
|
||||
if (formatting == "I")
|
||||
{
|
||||
paragraph.Text = "<i>" + paragraph.Text + "</i>";
|
||||
}
|
||||
else if (formatting == "B")
|
||||
{
|
||||
paragraph.Text = "<b>" + paragraph.Text + "</b>";
|
||||
}
|
||||
|
||||
if (verticalAglinment == "7" || verticalAglinment == "8" || verticalAglinment == "9")
|
||||
{
|
||||
paragraph.Text = "{\\an8}" + paragraph.Text;
|
||||
}
|
||||
else if (verticalAglinment == "3" || verticalAglinment == "4" || verticalAglinment == "5" || verticalAglinment == "6")
|
||||
{
|
||||
paragraph.Text = "{\\an5}" + paragraph.Text;
|
||||
}
|
||||
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,129 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle80 : SubtitleFormat
|
||||
{
|
||||
// 1<HT>01033902/01034028<HT>xxx
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\t\d+\/\d+\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".cap"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 80"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string paragraphWriteFormat = "{0}\t{1}/{2}\t{3}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Lambda字幕V4\tDF1+1\tSCENE\"和文標準\"");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var text = HtmlUtil.RemoveHtmlTags(p.Text.Trim()).Replace(Environment.NewLine, Environment.NewLine + "\t\t\t\t");
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text));
|
||||
count++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
var text = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (s.Length > 19 && RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
var lineParts = s.Split('\t');
|
||||
var parts = lineParts[1].Split('/');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
if (text.Length > 0 && paragraph != null)
|
||||
{
|
||||
paragraph.Text = text.ToString().Trim();
|
||||
}
|
||||
try
|
||||
{
|
||||
var startTime = parts[0].Trim();
|
||||
var endTime = parts[1].Trim();
|
||||
|
||||
string[] startTimeParts = { startTime.Substring(0, 2), startTime.Substring(2, 2), startTime.Substring(4, 2), startTime.Substring(6, 2) };
|
||||
string[] endTimeParts = { startTime.Substring(0, 2), startTime.Substring(2, 2), startTime.Substring(4, 2), startTime.Substring(6, 2) };
|
||||
|
||||
paragraph = new Paragraph { StartTime = DecodeTimeCode(startTimeParts), EndTime = DecodeTimeCode(endTimeParts) };
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
text = new StringBuilder();
|
||||
s = s.Remove(0, 18 + lineParts[0].Length).Trim();
|
||||
var idxA = s.IndexOf("@");
|
||||
if (idxA > 0)
|
||||
{
|
||||
s = s.Substring(0, idxA - 1).Trim();
|
||||
}
|
||||
text.Append(s);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && text.Length < 150)
|
||||
{
|
||||
var idxA = s.IndexOf("@");
|
||||
if (idxA > 0)
|
||||
{
|
||||
s = s.Substring(0, idxA - 1).Trim();
|
||||
}
|
||||
text.Append(Environment.NewLine + s);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
if (_errorCount > 10)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (text.Length > 0 && paragraph != null)
|
||||
{
|
||||
paragraph.Text = text.ToString().Trim();
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF().Replace(":", string.Empty);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class UnknownSubtitle80 : SubtitleFormat
|
||||
{
|
||||
// 1<HT>01033902/01034028<HT>xxx
|
||||
private static readonly Regex RegexTimeCode = new Regex(@"^\d+\t\d+\/\d+\t", RegexOptions.Compiled);
|
||||
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".cap"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Unknown 80"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string paragraphWriteFormat = "{0}\t{1}/{2}\t{3}";
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Lambda字幕V4\tDF1+1\tSCENE\"和文標準\"");
|
||||
sb.AppendLine();
|
||||
int count = 1;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
var text = HtmlUtil.RemoveHtmlTags(p.Text.Trim()).Replace(Environment.NewLine, Environment.NewLine + "\t\t\t\t");
|
||||
sb.AppendLine(string.Format(paragraphWriteFormat, count, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), text));
|
||||
count++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
Paragraph paragraph = null;
|
||||
_errorCount = 0;
|
||||
subtitle.Paragraphs.Clear();
|
||||
var text = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim();
|
||||
if (s.Length > 19 && RegexTimeCode.IsMatch(s))
|
||||
{
|
||||
var lineParts = s.Split('\t');
|
||||
var parts = lineParts[1].Split('/');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
if (text.Length > 0 && paragraph != null)
|
||||
{
|
||||
paragraph.Text = text.ToString().Trim();
|
||||
}
|
||||
try
|
||||
{
|
||||
var startTime = parts[0].Trim();
|
||||
var endTime = parts[1].Trim();
|
||||
|
||||
string[] startTimeParts = { startTime.Substring(0, 2), startTime.Substring(2, 2), startTime.Substring(4, 2), startTime.Substring(6, 2) };
|
||||
string[] endTimeParts = { startTime.Substring(0, 2), startTime.Substring(2, 2), startTime.Substring(4, 2), startTime.Substring(6, 2) };
|
||||
|
||||
paragraph = new Paragraph { StartTime = DecodeTimeCodeFrames(startTimeParts), EndTime = DecodeTimeCodeFrames(endTimeParts) };
|
||||
subtitle.Paragraphs.Add(paragraph);
|
||||
text = new StringBuilder();
|
||||
s = s.Remove(0, 18 + lineParts[0].Length).Trim();
|
||||
var idxA = s.IndexOf("@");
|
||||
if (idxA > 0)
|
||||
{
|
||||
s = s.Substring(0, idxA - 1).Trim();
|
||||
}
|
||||
text.Append(s);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (paragraph != null && text.Length < 150)
|
||||
{
|
||||
var idxA = s.IndexOf("@");
|
||||
if (idxA > 0)
|
||||
{
|
||||
s = s.Substring(0, idxA - 1).Trim();
|
||||
}
|
||||
text.Append(Environment.NewLine + s);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorCount++;
|
||||
if (_errorCount > 10)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (text.Length > 0 && paragraph != null)
|
||||
{
|
||||
paragraph.Text = text.ToString().Trim();
|
||||
}
|
||||
subtitle.RemoveEmptyLines();
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
return time.ToHHMMSSFF().Replace(":", string.Empty);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,108 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Wsb : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".WSB"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "WSB"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0:0000} : {1},{2},10", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
sb.AppendLine("80 80 80");
|
||||
foreach (string line in p.Text.SplitToLines())
|
||||
sb.AppendLine("C1Y00 " + line.Trim());
|
||||
sb.AppendLine();
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}{1:00}{2:00}{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//01072508010729007
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
subtitle.Header = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var indexOf7001 = line.IndexOf("7\x01\x01\0", StringComparison.Ordinal);
|
||||
var indexOfTen = line.IndexOf(" 10 ", StringComparison.Ordinal);
|
||||
if (indexOf7001 >= 0 && indexOfTen > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = line.Substring(0, indexOfTen).Trim();
|
||||
string time = line.Substring(indexOf7001 - 16, 16);
|
||||
|
||||
var starTime = time.Substring(0, 8);
|
||||
var endTime = time.Substring(8);
|
||||
|
||||
string[] startTimeParts = { starTime.Substring(0, 2), starTime.Substring(2, 2), starTime.Substring(4, 2), starTime.Substring(6, 2) };
|
||||
string[] endTimeParts = { starTime.Substring(0, 2), starTime.Substring(2, 2), starTime.Substring(4, 2), starTime.Substring(6, 2) };
|
||||
|
||||
p = new Paragraph(DecodeTimeCode(startTimeParts), DecodeTimeCode(endTimeParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Wsb : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".WSB"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "WSB"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string line in lines)
|
||||
sb.AppendLine(line);
|
||||
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
int index = 0;
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0:0000} : {1},{2},10", index + 1, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime)));
|
||||
sb.AppendLine("80 80 80");
|
||||
foreach (string line in p.Text.SplitToLines())
|
||||
sb.AppendLine("C1Y00 " + line.Trim());
|
||||
sb.AppendLine();
|
||||
index++;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeTimeCode(TimeCode time)
|
||||
{
|
||||
//00:03:15:22 (last is frame)
|
||||
return string.Format("{0:00}{1:00}{2:00}{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
//01072508010729007
|
||||
_errorCount = 0;
|
||||
Paragraph p = null;
|
||||
subtitle.Paragraphs.Clear();
|
||||
subtitle.Header = null;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var indexOf7001 = line.IndexOf("7\x01\x01\0", StringComparison.Ordinal);
|
||||
var indexOfTen = line.IndexOf(" 10 ", StringComparison.Ordinal);
|
||||
if (indexOf7001 >= 0 && indexOfTen > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = line.Substring(0, indexOfTen).Trim();
|
||||
string time = line.Substring(indexOf7001 - 16, 16);
|
||||
|
||||
var starTime = time.Substring(0, 8);
|
||||
var endTime = time.Substring(8);
|
||||
|
||||
string[] startTimeParts = { starTime.Substring(0, 2), starTime.Substring(2, 2), starTime.Substring(4, 2), starTime.Substring(6, 2) };
|
||||
string[] endTimeParts = { starTime.Substring(0, 2), starTime.Substring(2, 2), starTime.Substring(4, 2), starTime.Substring(6, 2) };
|
||||
|
||||
p = new Paragraph(DecodeTimeCodeFrames(startTimeParts), DecodeTimeCodeFrames(endTimeParts), text);
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(exception.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
else if (p != null)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
if (p != null && !string.IsNullOrEmpty(p.Text))
|
||||
subtitle.Paragraphs.Add(p);
|
||||
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,222 +1,222 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Xif : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xif"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "XIF"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string xmpTemplate = @"<XIF version='1.0' filename='file:///filename.xif'>
|
||||
<FileHeader>
|
||||
<OriginatorSoftware Name='FileConverter' Version='1.01'/>
|
||||
<GlobalFileInfo ProgrammeName='NAME' Format='Open' Language='English' StartTime='00:00:00:00' StopTime='00:00:00:00' TotalLength='00:00:00:00' ProgrammeTitle='TITLE' NumberOfCaptions='405' RevisionNumber='0' CountryIndex='0' CharacterCodeTable='0' MaxColumns='0' EpisodeNumber='0' BlinkOption='yes' CaptionService='0' CurrentVideo='2' Videosize='0' BaseOffset='0' TopOffset='0' DefaultSave='0' DisplaySafwWidth='576' SafeAreaWidthPercent='80' DisplaySafeHoriz='0' SafeAreaHorizPos='0' CurrentStyle='None' StyleDate='None' StyleTime='None' SAOLeft='72' SAORight='0' VideoStartTC='00:00:00:00' SpellLanguage='English' CGConfig='0'/>
|
||||
<ReadingSpeeds>
|
||||
<ReadingSpeed ID='0' WordsPerMinute='180' CharsPerMinute='720' CharsPerSecond='12' PTS='WPM'/>
|
||||
</ReadingSpeeds>
|
||||
<Canvases>
|
||||
<Canvas ID='0' Width='720' Height='576' SAWidth='576' SAHeight='460' SATop='57' SALeft='72'/>
|
||||
</Canvases>
|
||||
<FormattingInfo TabWidth='3'/>
|
||||
<TimingStandards>
|
||||
<TimingStandard ID='0' Type='SMPTE25'/>
|
||||
</TimingStandards>
|
||||
<Fonts>
|
||||
<Font ID='0' Type='True Type' Typeface='Courier New' Height='0' AstonFountSize='185' Ascent='268' Descent='97' IntLead='43'/>
|
||||
<Font ID='1' Type='True Type' Typeface='Courier New' Height='0' AstonFountSize='185' Ascent='268' Descent='97' IntLead='43'/>
|
||||
<Font ID='2' Type='True Type' Typeface='Hairy Helix' Height='0' AstonFountSize='12' Ascent='15' Descent='3' IntLead='2'/>
|
||||
<Font ID='3' Type='True Type' Typeface='Hairy Helix Italics' Height='0' AstonFountSize='12' Ascent='15' Descent='3' IntLead='2'/>
|
||||
<Font ID='4' Type='True Type' Typeface='Arial' Height='35' AstonFountSize='22' Ascent='28' Descent='7' IntLead='5'/>
|
||||
<Font ID='5' Type='True Type' Typeface='Arial Narrow' Height='35' AstonFountSize='25' Ascent='30' Descent='5' IntLead='0'/>
|
||||
<Font/>
|
||||
</Fonts>
|
||||
<Colours>
|
||||
<Colour ID='0' value='0x000000'/>
|
||||
<Colour ID='1' value='0xFF0000'/>
|
||||
<Colour ID='2' value='0x00FF00'/>
|
||||
<Colour ID='3' value='0xFFFF00'/>
|
||||
<Colour ID='4' value='0x0000FF'/>
|
||||
<Colour ID='5' value='0xFF00FF'/>
|
||||
<Colour ID='6' value='0x00FFFF'/>
|
||||
<Colour ID='7' value='0xFFFFFF'/>
|
||||
</Colours>
|
||||
<Threads>
|
||||
<Thread ID='0' CanvasID='0' TimingStandardID='0' ReadingSpeedID='0' Medium='Open' Name='Default'/>
|
||||
</Threads>
|
||||
<WordLists/>
|
||||
<TxStreams>
|
||||
<TxStream ID='0' Active='yes'/>
|
||||
</TxStreams>
|
||||
</FileHeader>
|
||||
<FileBody>
|
||||
<ProgrammeBlock NoOfAssociatedIDs='0'>
|
||||
<SceneBaseBlock NewsID='0' Position='0' NewsRoomInternalID='0'/>
|
||||
</ProgrammeBlock>
|
||||
<StoryBlock TimingType='Manual'>
|
||||
<SceneBaseBlock NewsID='0' Position='0' NewsRoomInternalID='0'/>
|
||||
</StoryBlock>
|
||||
|
||||
</FileBody>
|
||||
</XIF>";
|
||||
|
||||
const string paragraphTemplate = @"
|
||||
<ContentBlock TXStreamID='0' uid='B4EB0AE5-B82F-48ea-9FD4-C4194D004041'>
|
||||
<ThreadedObject ID='0' Type='BasicSubtitle' VPos='448'>
|
||||
<Note/>
|
||||
<TimingObject>
|
||||
<TimeIn value='10:00:03:06'/>
|
||||
<TimeOut value='10:00:05:09'/>
|
||||
</TimingObject>
|
||||
<Content Override='0' RaisedRowUp='0' RaisedRowDown='0' DirectionState='0' PositionState='1' ConfidenceValue='0'>
|
||||
<SubtitleText>
|
||||
<Paragraph Type='Open' Justification='Centre' LineLimit='15' CharactersPerRow='99' Alignment='None' Language='ENG' VideoLanguage='ENG' Xpercent='0.0' Ypercent='0.0'>
|
||||
<StartState Foreground='7' Background='0' Flash='No' Underline='No' Italic='No' Bold='No' Indent='0' SBOnOff='Yes' FontID='4'/>
|
||||
<Boxing Colour='0' Transparency='0' Type='None'/>
|
||||
<AntiAliasing Style='Default'/>
|
||||
</Paragraph>
|
||||
</SubtitleText>
|
||||
</Content>
|
||||
</ThreadedObject>
|
||||
</ContentBlock>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
var lastTimeCode = new TimeCode(0);
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
lastTimeCode = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].StartTime;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(title))
|
||||
title = "Unknown";
|
||||
xml.LoadXml(xmpTemplate.Replace('\'', '"'));
|
||||
var globalFileInfoNode = xml.DocumentElement.SelectSingleNode("FileHeader/GlobalFileInfo");
|
||||
globalFileInfoNode.Attributes["ProgrammeName"].InnerText = title;
|
||||
globalFileInfoNode.Attributes["ProgrammeTitle"].InnerText = title;
|
||||
globalFileInfoNode.Attributes["StopTime"].InnerText = lastTimeCode.ToHHMMSSFF();
|
||||
globalFileInfoNode.Attributes["NumberOfCaptions"].InnerText = subtitle.Paragraphs.Count.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
var fileBodyNode = xml.DocumentElement.SelectSingleNode("FileBody");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode content = xml.CreateElement("ContentBlock");
|
||||
content.InnerXml = paragraphTemplate;
|
||||
content.SelectSingleNode("ContentBlock/ThreadedObject/TimingObject/TimeIn").InnerText = p.StartTime.ToHHMMSSFF();
|
||||
content.SelectSingleNode("ContentBlock/ThreadedObject/TimingObject/TimeOut").InnerText = p.EndTime.ToHHMMSSFF();
|
||||
|
||||
var paragraphNode = content.SelectSingleNode("ContentBlock/ThreadedObject/Content/SubtitleText/Paragraph");
|
||||
var lines = HtmlUtil.RemoveHtmlTags(p.Text, true).SplitToLines();
|
||||
for (int i = 1; i < lines.Length + 1; i++)
|
||||
{
|
||||
var rowNode = xml.CreateElement("Row");
|
||||
|
||||
var attrNumber = xml.CreateAttribute("Number");
|
||||
attrNumber.InnerText = i.ToString(CultureInfo.InvariantCulture);
|
||||
rowNode.Attributes.Append(attrNumber);
|
||||
|
||||
var attrJust = xml.CreateAttribute("JustificationOverride");
|
||||
attrJust.InnerText = "Centre";
|
||||
rowNode.Attributes.Append(attrJust);
|
||||
|
||||
var attrHighlight = xml.CreateAttribute("Highlight");
|
||||
attrHighlight.InnerText = "0";
|
||||
rowNode.Attributes.Append(attrHighlight);
|
||||
|
||||
paragraphNode.AppendChild(rowNode);
|
||||
}
|
||||
for (int index = 0; index < lines.Length; index++)
|
||||
{
|
||||
var line = lines[index];
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
var hardReturnNode = xml.CreateElement("HardReturn");
|
||||
paragraphNode.AppendChild(hardReturnNode);
|
||||
}
|
||||
|
||||
var foregroundColorNode = xml.CreateElement("ForegroundColour");
|
||||
var attrColor = xml.CreateAttribute("Colour");
|
||||
attrColor.InnerText = "7";
|
||||
foregroundColorNode.Attributes.Append(attrColor);
|
||||
paragraphNode.AppendChild(foregroundColorNode);
|
||||
|
||||
var textNode = xml.CreateElement("Text");
|
||||
textNode.InnerText = line;
|
||||
paragraphNode.AppendChild(textNode);
|
||||
}
|
||||
fileBodyNode.AppendChild(content.SelectSingleNode("ContentBlock"));
|
||||
}
|
||||
return ToUtf8XmlString(xml, true).Replace(" xmlns=\"\"", string.Empty);
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xmlAsText = sb.ToString().Trim();
|
||||
if (!xmlAsText.Contains("<XIF") || !xmlAsText.Contains("<SubtitleText"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(xmlAsText);
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("FileBody/ContentBlock"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var timeCodeIn = DecodeTimeCode(node.SelectSingleNode("ThreadedObject/TimingObject/TimeIn").Attributes["value"].InnerText, SplitCharColon);
|
||||
var timeCodeOut = DecodeTimeCode(node.SelectSingleNode("ThreadedObject/TimingObject/TimeOut").Attributes["value"].InnerText, SplitCharColon);
|
||||
sb.Clear();
|
||||
foreach (XmlNode paragraphNode in node.SelectSingleNode("ThreadedObject/Content/SubtitleText/Paragraph").ChildNodes)
|
||||
{
|
||||
if (paragraphNode.Name == "Text")
|
||||
sb.Append(" " + paragraphNode.InnerText);
|
||||
else if (paragraphNode.Name == "HardReturn")
|
||||
sb.AppendLine();
|
||||
}
|
||||
var p = new Paragraph(timeCodeIn, timeCodeOut, sb.ToString().Replace(" ", " ").Trim());
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Xif : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".xif"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "XIF"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
var subtitle = new Subtitle();
|
||||
LoadSubtitle(subtitle, lines, fileName);
|
||||
return subtitle.Paragraphs.Count > _errorCount;
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
const string xmpTemplate = @"<XIF version='1.0' filename='file:///filename.xif'>
|
||||
<FileHeader>
|
||||
<OriginatorSoftware Name='FileConverter' Version='1.01'/>
|
||||
<GlobalFileInfo ProgrammeName='NAME' Format='Open' Language='English' StartTime='00:00:00:00' StopTime='00:00:00:00' TotalLength='00:00:00:00' ProgrammeTitle='TITLE' NumberOfCaptions='405' RevisionNumber='0' CountryIndex='0' CharacterCodeTable='0' MaxColumns='0' EpisodeNumber='0' BlinkOption='yes' CaptionService='0' CurrentVideo='2' Videosize='0' BaseOffset='0' TopOffset='0' DefaultSave='0' DisplaySafwWidth='576' SafeAreaWidthPercent='80' DisplaySafeHoriz='0' SafeAreaHorizPos='0' CurrentStyle='None' StyleDate='None' StyleTime='None' SAOLeft='72' SAORight='0' VideoStartTC='00:00:00:00' SpellLanguage='English' CGConfig='0'/>
|
||||
<ReadingSpeeds>
|
||||
<ReadingSpeed ID='0' WordsPerMinute='180' CharsPerMinute='720' CharsPerSecond='12' PTS='WPM'/>
|
||||
</ReadingSpeeds>
|
||||
<Canvases>
|
||||
<Canvas ID='0' Width='720' Height='576' SAWidth='576' SAHeight='460' SATop='57' SALeft='72'/>
|
||||
</Canvases>
|
||||
<FormattingInfo TabWidth='3'/>
|
||||
<TimingStandards>
|
||||
<TimingStandard ID='0' Type='SMPTE25'/>
|
||||
</TimingStandards>
|
||||
<Fonts>
|
||||
<Font ID='0' Type='True Type' Typeface='Courier New' Height='0' AstonFountSize='185' Ascent='268' Descent='97' IntLead='43'/>
|
||||
<Font ID='1' Type='True Type' Typeface='Courier New' Height='0' AstonFountSize='185' Ascent='268' Descent='97' IntLead='43'/>
|
||||
<Font ID='2' Type='True Type' Typeface='Hairy Helix' Height='0' AstonFountSize='12' Ascent='15' Descent='3' IntLead='2'/>
|
||||
<Font ID='3' Type='True Type' Typeface='Hairy Helix Italics' Height='0' AstonFountSize='12' Ascent='15' Descent='3' IntLead='2'/>
|
||||
<Font ID='4' Type='True Type' Typeface='Arial' Height='35' AstonFountSize='22' Ascent='28' Descent='7' IntLead='5'/>
|
||||
<Font ID='5' Type='True Type' Typeface='Arial Narrow' Height='35' AstonFountSize='25' Ascent='30' Descent='5' IntLead='0'/>
|
||||
<Font/>
|
||||
</Fonts>
|
||||
<Colours>
|
||||
<Colour ID='0' value='0x000000'/>
|
||||
<Colour ID='1' value='0xFF0000'/>
|
||||
<Colour ID='2' value='0x00FF00'/>
|
||||
<Colour ID='3' value='0xFFFF00'/>
|
||||
<Colour ID='4' value='0x0000FF'/>
|
||||
<Colour ID='5' value='0xFF00FF'/>
|
||||
<Colour ID='6' value='0x00FFFF'/>
|
||||
<Colour ID='7' value='0xFFFFFF'/>
|
||||
</Colours>
|
||||
<Threads>
|
||||
<Thread ID='0' CanvasID='0' TimingStandardID='0' ReadingSpeedID='0' Medium='Open' Name='Default'/>
|
||||
</Threads>
|
||||
<WordLists/>
|
||||
<TxStreams>
|
||||
<TxStream ID='0' Active='yes'/>
|
||||
</TxStreams>
|
||||
</FileHeader>
|
||||
<FileBody>
|
||||
<ProgrammeBlock NoOfAssociatedIDs='0'>
|
||||
<SceneBaseBlock NewsID='0' Position='0' NewsRoomInternalID='0'/>
|
||||
</ProgrammeBlock>
|
||||
<StoryBlock TimingType='Manual'>
|
||||
<SceneBaseBlock NewsID='0' Position='0' NewsRoomInternalID='0'/>
|
||||
</StoryBlock>
|
||||
|
||||
</FileBody>
|
||||
</XIF>";
|
||||
|
||||
const string paragraphTemplate = @"
|
||||
<ContentBlock TXStreamID='0' uid='B4EB0AE5-B82F-48ea-9FD4-C4194D004041'>
|
||||
<ThreadedObject ID='0' Type='BasicSubtitle' VPos='448'>
|
||||
<Note/>
|
||||
<TimingObject>
|
||||
<TimeIn value='10:00:03:06'/>
|
||||
<TimeOut value='10:00:05:09'/>
|
||||
</TimingObject>
|
||||
<Content Override='0' RaisedRowUp='0' RaisedRowDown='0' DirectionState='0' PositionState='1' ConfidenceValue='0'>
|
||||
<SubtitleText>
|
||||
<Paragraph Type='Open' Justification='Centre' LineLimit='15' CharactersPerRow='99' Alignment='None' Language='ENG' VideoLanguage='ENG' Xpercent='0.0' Ypercent='0.0'>
|
||||
<StartState Foreground='7' Background='0' Flash='No' Underline='No' Italic='No' Bold='No' Indent='0' SBOnOff='Yes' FontID='4'/>
|
||||
<Boxing Colour='0' Transparency='0' Type='None'/>
|
||||
<AntiAliasing Style='Default'/>
|
||||
</Paragraph>
|
||||
</SubtitleText>
|
||||
</Content>
|
||||
</ThreadedObject>
|
||||
</ContentBlock>";
|
||||
|
||||
var xml = new XmlDocument();
|
||||
var lastTimeCode = new TimeCode(0);
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
lastTimeCode = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].StartTime;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(title))
|
||||
title = "Unknown";
|
||||
xml.LoadXml(xmpTemplate.Replace('\'', '"'));
|
||||
var globalFileInfoNode = xml.DocumentElement.SelectSingleNode("FileHeader/GlobalFileInfo");
|
||||
globalFileInfoNode.Attributes["ProgrammeName"].InnerText = title;
|
||||
globalFileInfoNode.Attributes["ProgrammeTitle"].InnerText = title;
|
||||
globalFileInfoNode.Attributes["StopTime"].InnerText = lastTimeCode.ToHHMMSSFF();
|
||||
globalFileInfoNode.Attributes["NumberOfCaptions"].InnerText = subtitle.Paragraphs.Count.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
var fileBodyNode = xml.DocumentElement.SelectSingleNode("FileBody");
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode content = xml.CreateElement("ContentBlock");
|
||||
content.InnerXml = paragraphTemplate;
|
||||
content.SelectSingleNode("ContentBlock/ThreadedObject/TimingObject/TimeIn").InnerText = p.StartTime.ToHHMMSSFF();
|
||||
content.SelectSingleNode("ContentBlock/ThreadedObject/TimingObject/TimeOut").InnerText = p.EndTime.ToHHMMSSFF();
|
||||
|
||||
var paragraphNode = content.SelectSingleNode("ContentBlock/ThreadedObject/Content/SubtitleText/Paragraph");
|
||||
var lines = HtmlUtil.RemoveHtmlTags(p.Text, true).SplitToLines();
|
||||
for (int i = 1; i < lines.Length + 1; i++)
|
||||
{
|
||||
var rowNode = xml.CreateElement("Row");
|
||||
|
||||
var attrNumber = xml.CreateAttribute("Number");
|
||||
attrNumber.InnerText = i.ToString(CultureInfo.InvariantCulture);
|
||||
rowNode.Attributes.Append(attrNumber);
|
||||
|
||||
var attrJust = xml.CreateAttribute("JustificationOverride");
|
||||
attrJust.InnerText = "Centre";
|
||||
rowNode.Attributes.Append(attrJust);
|
||||
|
||||
var attrHighlight = xml.CreateAttribute("Highlight");
|
||||
attrHighlight.InnerText = "0";
|
||||
rowNode.Attributes.Append(attrHighlight);
|
||||
|
||||
paragraphNode.AppendChild(rowNode);
|
||||
}
|
||||
for (int index = 0; index < lines.Length; index++)
|
||||
{
|
||||
var line = lines[index];
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
var hardReturnNode = xml.CreateElement("HardReturn");
|
||||
paragraphNode.AppendChild(hardReturnNode);
|
||||
}
|
||||
|
||||
var foregroundColorNode = xml.CreateElement("ForegroundColour");
|
||||
var attrColor = xml.CreateAttribute("Colour");
|
||||
attrColor.InnerText = "7";
|
||||
foregroundColorNode.Attributes.Append(attrColor);
|
||||
paragraphNode.AppendChild(foregroundColorNode);
|
||||
|
||||
var textNode = xml.CreateElement("Text");
|
||||
textNode.InnerText = line;
|
||||
paragraphNode.AppendChild(textNode);
|
||||
}
|
||||
fileBodyNode.AppendChild(content.SelectSingleNode("ContentBlock"));
|
||||
}
|
||||
return ToUtf8XmlString(xml, true).Replace(" xmlns=\"\"", string.Empty);
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var sb = new StringBuilder();
|
||||
lines.ForEach(line => sb.AppendLine(line));
|
||||
var xmlAsText = sb.ToString().Trim();
|
||||
if (!xmlAsText.Contains("<XIF") || !xmlAsText.Contains("<SubtitleText"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
xml.LoadXml(xmlAsText);
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("FileBody/ContentBlock"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var timeCodeIn = DecodeTimeCodeFrames(node.SelectSingleNode("ThreadedObject/TimingObject/TimeIn").Attributes["value"].InnerText, SplitCharColon);
|
||||
var timeCodeOut = DecodeTimeCodeFrames(node.SelectSingleNode("ThreadedObject/TimingObject/TimeOut").Attributes["value"].InnerText, SplitCharColon);
|
||||
sb.Clear();
|
||||
foreach (XmlNode paragraphNode in node.SelectSingleNode("ThreadedObject/Content/SubtitleText/Paragraph").ChildNodes)
|
||||
{
|
||||
if (paragraphNode.Name == "Text")
|
||||
sb.Append(" " + paragraphNode.InnerText);
|
||||
else if (paragraphNode.Name == "HardReturn")
|
||||
sb.AppendLine();
|
||||
}
|
||||
var p = new Paragraph(timeCodeIn, timeCodeOut, sb.ToString().Replace(" ", " ").Trim());
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user