Example #1
0
 [InlineData(InvariantDialoguePrefix + "start {\\fnFont Name}text1 {\\fs10}text2{\\fs}{\\fn} {\\1c&H112233}text3{\\1c} end", "start <font face=\"Font Name\">text1 <font size=\"10\">text2</font></font> <font color=\"#332211\">text3</font> end")] // nested formatting
 public void Parse(string ssa, string expectedText)
 {
     using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(ssa)))
     {
         SubtitleTrackInfo  subtitleTrackInfo = parser.Parse(stream, CancellationToken.None);
         SubtitleTrackEvent actual            = subtitleTrackInfo.TrackEvents[0];
         Assert.Equal(expectedText, actual.Text);
     }
 }
Example #2
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();
            using ( var reader = new StreamReader(stream))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    var subEvent = new SubtitleTrackEvent {Id = line};
                    line = reader.ReadLine();

                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    
                    var time = Regex.Split(line, @"[\t ]*-->[\t ]*");

                    if (time.Length < 2)
                    {
                        // This occurs when subtitle text has an empty line as part of the text.
                        // Need to adjust the break statement below to resolve this.
                        _logger.Warn("Unrecognized line in srt: {0}", line);
                        continue;
                    }
                    subEvent.StartPositionTicks = GetTicks(time[0]);
                    var endTime = time[1];
                    var idx = endTime.IndexOf(" ", StringComparison.Ordinal);
                    if (idx > 0)
                        endTime = endTime.Substring(0, idx);
                    subEvent.EndPositionTicks = GetTicks(endTime);
                    var multiline = new List<string>();
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrEmpty(line))
                        {
                            break;
                        }
                        multiline.Add(line);
                    }
                    subEvent.Text = string.Join(ParserValues.NewLine, multiline);
                    subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, "<", "&lt;", RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, ">", "&gt;", RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, "&lt;(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)&gt;", "<$1$3$7>", RegexOptions.IgnoreCase);
                    trackInfo.TrackEvents.Add(subEvent);
                }
            }
            return trackInfo;
        }
Example #3
0
        public void Parse_MultipleDialogues(string ssa, IReadOnlyList <SubtitleTrackEvent> expectedSubtitleTrackEvents)
        {
            using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(ssa)))
            {
                SubtitleTrackInfo subtitleTrackInfo = parser.Parse(stream, CancellationToken.None);

                Assert.Equal(expectedSubtitleTrackEvents.Count, subtitleTrackInfo.TrackEvents.Count);

                for (int i = 0; i < expectedSubtitleTrackEvents.Count; ++i)
                {
                    SubtitleTrackEvent expected = expectedSubtitleTrackEvents[i];
                    SubtitleTrackEvent actual   = subtitleTrackInfo.TrackEvents[i];

                    Assert.Equal(expected.StartPositionTicks, actual.StartPositionTicks);
                    Assert.Equal(expected.EndPositionTicks, actual.EndPositionTicks);
                    Assert.Equal(expected.Text, actual.Text);
                }
            }
        }
Example #4
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();
            var eventIndex = 1;
            using (var reader = new StreamReader(stream))
            {
                string line;
                while (reader.ReadLine() != "[Events]")
                {}
                var headers = ParseFieldHeaders(reader.ReadLine());

                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    if(line.StartsWith("["))
                        break;
                    if(string.IsNullOrEmpty(line))
                        continue;
                    var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) };
                    eventIndex++;
                    var sections = line.Substring(10).Split(',');

                    subEvent.StartPositionTicks = GetTicks(sections[headers["Start"]]);
                    subEvent.EndPositionTicks = GetTicks(sections[headers["End"]]);

                    subEvent.Text = string.Join(",", sections.Skip(headers["Text"]));
                    RemoteNativeFormatting(subEvent);

                    subEvent.Text = subEvent.Text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
                    
                    subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);

                    trackInfo.TrackEvents.Add(subEvent);
                }
            }
            return trackInfo;
        }
Example #5
0
        /// <summary>
        /// Credit: https://github.com/SubtitleEdit/subtitleedit/blob/master/src/Logic/SubtitleFormats/AdvancedSubStationAlpha.cs
        /// </summary>
        private void RemoteNativeFormatting(SubtitleTrackEvent p)
        {
            int indexOfBegin = p.Text.IndexOf('{');
            string pre = string.Empty;
            while (indexOfBegin >= 0 && p.Text.IndexOf('}') > indexOfBegin)
            {
                string s = p.Text.Substring(indexOfBegin);
                if (s.StartsWith("{\\an1}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an2}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an3}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an4}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an5}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an6}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an7}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an8}", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an9}", StringComparison.Ordinal))
                {
                    pre = s.Substring(0, 6);
                }
                else if (s.StartsWith("{\\an1\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an2\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an3\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an4\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an5\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an6\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an7\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an8\\", StringComparison.Ordinal) ||
                    s.StartsWith("{\\an9\\", StringComparison.Ordinal))
                {
                    pre = s.Substring(0, 5) + "}";
                }
                int indexOfEnd = p.Text.IndexOf('}');
                p.Text = p.Text.Remove(indexOfBegin, (indexOfEnd - indexOfBegin) + 1);

                indexOfBegin = p.Text.IndexOf('{');
            }
            p.Text = pre + p.Text;
        }
Example #6
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();

            using (var reader = new StreamReader(stream))
            {
                bool eventsStarted = false;

                string[] format = "Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text".Split(',');
                int indexLayer = 0;
                int indexStart = 1;
                int indexEnd = 2;
                int indexStyle = 3;
                int indexName = 4;
                int indexEffect = 8;
                int indexText = 9;
                int lineNumber = 0;

                var header = new StringBuilder();

                string line;

                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    lineNumber++;
                    if (!eventsStarted)
                        header.AppendLine(line);

                    if (line.Trim().ToLower() == "[events]")
                    {
                        eventsStarted = true;
                    }
                    else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";"))
                    {
                        // skip comment lines
                    }
                    else if (eventsStarted && line.Trim().Length > 0)
                    {
                        string s = line.Trim().ToLower();
                        if (s.StartsWith("format:"))
                        {
                            if (line.Length > 10)
                            {
                                format = line.ToLower().Substring(8).Split(',');
                                for (int i = 0; i < format.Length; i++)
                                {
                                    if (format[i].Trim().ToLower() == "layer")
                                        indexLayer = i;
                                    else if (format[i].Trim().ToLower() == "start")
                                        indexStart = i;
                                    else if (format[i].Trim().ToLower() == "end")
                                        indexEnd = i;
                                    else if (format[i].Trim().ToLower() == "text")
                                        indexText = i;
                                    else if (format[i].Trim().ToLower() == "effect")
                                        indexEffect = i;
                                    else if (format[i].Trim().ToLower() == "style")
                                        indexStyle = i;
                                }
                            }
                        }
                        else if (!string.IsNullOrEmpty(s))
                        {
                            string text = string.Empty;
                            string start = string.Empty;
                            string end = string.Empty;
                            string style = string.Empty;
                            string layer = string.Empty;
                            string effect = string.Empty;
                            string name = string.Empty;

                            string[] splittedLine;

                            if (s.StartsWith("dialogue:"))
                                splittedLine = line.Substring(10).Split(',');
                            else
                                splittedLine = line.Split(',');

                            for (int i = 0; i < splittedLine.Length; i++)
                            {
                                if (i == indexStart)
                                    start = splittedLine[i].Trim();
                                else if (i == indexEnd)
                                    end = splittedLine[i].Trim();
                                else if (i == indexLayer)
                                    layer = splittedLine[i];
                                else if (i == indexEffect)
                                    effect = splittedLine[i];
                                else if (i == indexText)
                                    text = splittedLine[i];
                                else if (i == indexStyle)
                                    style = splittedLine[i];
                                else if (i == indexName)
                                    name = splittedLine[i];
                                else if (i > indexText)
                                    text += "," + splittedLine[i];
                            }

                            try
                            {
                                var p = new SubtitleTrackEvent();

                                p.StartPositionTicks = GetTimeCodeFromString(start);
                                p.EndPositionTicks = GetTimeCodeFromString(end);
                                p.Text = GetFormattedText(text);

                                trackInfo.TrackEvents.Add(p);
                            }
                            catch
                            {
                            }
                        }
                    }
                } 
                
                //if (header.Length > 0)
                    //subtitle.Header = header.ToString();

                //subtitle.Renumber(1);
            }
            return trackInfo;
        }