SubtitleEdit/libse/SubtitleFormats/PhoenixSubtitle.cs
2019-12-09 15:38:46 +01:00

108 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
{
/// <summary>
/// Implements https://web.archive.org/web/20080213213927/http://trac.annodex.net/wiki/PJS
/// https://github.com/SubtitleEdit/subtitleedit/pull/1964#issuecomment-249379407
/// </summary>
public class PhoenixSubtitle : SubtitleFormat
{
//2447, 2513, "You should come to the Drama Club, too."
//2513, 2594, "Yeah. The Drama Club is worried|that you haven't been coming."
//2603, 2675, "I see. Sorry, I'll drop by next time."
private static readonly Regex RegexTimeCodes = new Regex(@"^(\d+),\s*(\d+),", RegexOptions.Compiled);
private static readonly char[] TrimChars = { ' ', '"' };
public override string Extension => ".pjs";
public override bool IsTimeBased => false;
public override string Name => "Phoenix Subtitle";
public override bool IsMine(List<string> lines, string fileName)
{
if (fileName?.EndsWith(".pjs", StringComparison.OrdinalIgnoreCase) == false)
{
return false;
}
return base.IsMine(lines, fileName);
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
subtitle.Paragraphs.Clear();
_errorCount = 0;
for (int i = 0; i < lines.Count; i++)
{
string line = lines[i].Trim();
// too short line
if (line.Length < 4)
{
_errorCount++;
continue;
}
var match = RegexTimeCodes.Match(line);
if (match.Success)
{
try
{
var startMs = (double)FramesToMilliseconds(int.Parse(match.Groups[1].Value));
var endMs = (double)FramesToMilliseconds(int.Parse(match.Groups[2].Value));
var paragraph = new Paragraph
{
Number = subtitle.Paragraphs.Count + 1,
StartTime = new TimeCode(startMs),
EndTime = new TimeCode(endMs)
};
// Decode text.
line = line.Substring(match.Value.Length).Trim();
// Read quote (") if there are more than one.
if (line.Length > 2 && line[0] == '"' && line[1] == '"')
{
line = "\"" + line.Trim(TrimChars) + "\"";
}
else
{
line = line.Trim(TrimChars);
}
paragraph.Text = string.Join(Environment.NewLine, line.Split('|'));
subtitle.Paragraphs.Add(paragraph);
}
catch
{
_errorCount++;
}
}
else
{
_errorCount++;
}
}
}
public override string ToText(Subtitle subtitle, string title)
{
const string writeFormat = "{0},{1},\"{2}\"{3}";
var sb = new StringBuilder();
foreach (var p in subtitle.Paragraphs)
{
string text = HtmlUtil.RemoveHtmlTags(p.Text, true);
// Pipe character for forced line breaks.
text = text.Replace(Environment.NewLine, "|");
sb.AppendFormat(writeFormat, MillisecondsToFrames(p.StartTime.TotalMilliseconds), MillisecondsToFrames(p.EndTime.TotalMilliseconds), text, Environment.NewLine);
}
return sb.ToString();
}
}
}