using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace Nikse.SubtitleEdit.Core.SubtitleFormats { /// /// Implements https://web.archive.org/web/20080213213927/http://trac.annodex.net/wiki/PJS /// https://github.com/SubtitleEdit/subtitleedit/pull/1964#issuecomment-249379407 /// 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 lines, string fileName) { if (fileName?.EndsWith(".pjs", StringComparison.OrdinalIgnoreCase) == false) { return false; } return base.IsMine(lines, fileName); } public override void LoadSubtitle(Subtitle subtitle, List 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(); } } }