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 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 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(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 (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)); } private static TimeCode DecodeTimeCode(string[] parts) { string hour = parts[0]; string minutes = parts[1]; string seconds = parts[2]; string frames = parts[3]; return new TimeCode(int.Parse(hour), int.Parse(minutes), int.Parse(seconds), FramesToMillisecondsMax999(int.Parse(frames))); } } }