示例#1
0
	/// <exception cref="UnknownSubtitleFormatException">Thrown if the subtitle format could not be detected.</exception>
	internal string Read (string path, Encoding encoding, out SubtitleFormat format) {
		/* Open file */
		FileStream fileStream = FileInputOutput.OpenFileForReading(path);

		/* Read the text */
		return TestEncoding(fileStream, encoding, out format);
	}
示例#2
0
	private string ClearComments (string text, SubtitleFormat format) {
		if (format.HasComments) {
			Regex regex = new Regex(format.Comments);
			string clearText = regex.Replace(text, String.Empty);
			return clearText;
		}
		else
			return text;
	}
示例#3
0
	/// <summary>Parses the specified text, using the specified format.</summary>
	/// <remarks>The created <see cref="SubtitleCollection" /> will have its <see cref="SubtitleProperties" /> property set to null.
	/// It is mandatory to use <see cref="SubtitleCollection.SetPropertiesForAll" /> after.</remarks>
	internal ParsingProperties Parse (string text, SubtitleFormat format, float inputFrameRate,
			out SubtitleCollection collection, out IncompleteSubtitleCollection incompleteSubtitles){

		collection = new SubtitleCollection();
		incompleteSubtitles = new IncompleteSubtitleCollection();
		ParsingProperties properties = new ParsingProperties();
		properties.InputFrameRate = inputFrameRate;

		Regex subtitleRegex = null;
		int bodyIndex = 0;

		text = ClearComments(text, format);

		/* Read the headers if available */
		if (format.Mode == SubtitleMode.Both) {
			//Read headers to know if format is using Times or Frames
			bodyIndex = text.Length;
			int lastIndex = ReadHeaders(text, bodyIndex, format, properties);
			subtitleRegex = CreateSubtitleRegex(format, properties.TimingMode);

			/* Detect body index from matching the first subtitle or the end of headers */
			bodyIndex = FindBodyIndex(text, format, subtitleRegex);
			if (lastIndex > bodyIndex)
				bodyIndex = lastIndex;
		}
		else {
			//End of headers is detected by start of subtitles' body
			properties.TimingMode = format.ModeAsTimingMode;
			subtitleRegex = CreateSubtitleRegex(format);
			bodyIndex = FindBodyIndex(text, format, subtitleRegex);
			ReadHeaders(text, bodyIndex, format, properties);
		}

		/* Get properties from the whole input, if available */
		format.GlobalInputGetProperties(text, properties);

		int textLength = text.Length;

		/* Read the subtitles */
		bodyIndex = ReadSubtitles(text, bodyIndex, textLength, subtitleRegex, format,
			properties, collection, incompleteSubtitles);

    	/* Read the end text of the subtitles */
    	bodyIndex = ReadBodyEnd(text, bodyIndex, format, collection, incompleteSubtitles);

		/* Check if there's still text remaining */
    	if ((bodyIndex < textLength) && includeIncompleteSubtitles)
    		AddIncompleteSubtitle(incompleteSubtitles, text.Substring(bodyIndex), collection.Count);

    	return properties;
	}
示例#4
0
	/// <exception cref="EncodingNotSupportedException">Thrown if the encoding is not supported by the platform.</exception>
	/// <exception cref="UnknownSubtitleFormatException">Thrown if the subtitle format could not be detected.</exception>
	internal string Read (string path, out Encoding encoding, out SubtitleFormat format) {
		/* Open file */
		FileStream fileStream = FileInputOutput.OpenFileForReading(path);

		return ReadSubtitleText(true, fileStream, out encoding, out format);
	}
示例#5
0
	/// <exception cref="UnknownSubtitleFormatException">Thrown if the subtitle format could not be detected.</exception>
	private string TestEncoding (FileStream fileStream, Encoding encoding, out SubtitleFormat format) {
		/* Get the text */
		string text = TestEncoding(fileStream, encoding);

		/* Check the subtitle format */
		format = GetSubtitleFormat(text);

		return text;
	}
示例#6
0
	/// <exception cref="EncodingNotSupportedException">Thrown if the encoding is not supported by the platform.</exception>
	/// <exception cref="UnknownSubtitleFormatException">Thrown if the subtitle format could not be detected.</exception>
	private string TestCodePage (FileStream fileStream, int codePage, out Encoding encoding, out SubtitleFormat format) {
		/* Check the encoding */
		TestCodePageCommon(codePage, out encoding);
		return TestEncoding(fileStream, encoding, out format);
	}
 private static bool TrySubtitleFormat (SubtitleFormat format, string subtitleText, int length) {
 		Regex expression = new Regex(format.Format, RegexOptions.IgnoreCase);
 		Match match = expression.Match(subtitleText, 0, length);
 		return match.Success;
 }
示例#8
0
	private int ReadSubtitles (string text, int bodyIndex, int textLength, Regex subtitleRegex, SubtitleFormat format,
		ParsingProperties properties, SubtitleCollection collection, IncompleteSubtitleCollection incompleteSubtitles) {

		Subtitle previousSubtitle = null;

		/* Read the subtitles. BodyIndex points to the start of the subtitles, skipping its possible beginning text*/
		while (bodyIndex < textLength) {
			Match match = subtitleRegex.Match(text, bodyIndex);
			if (match.Success) {
    			Subtitle subtitle = ParseSubtitle(match, format, properties, previousSubtitle);
    			collection.Add(subtitle);
				AddIncompleteSubtitleIfExists(text, match, bodyIndex, collection.Count, incompleteSubtitles);
	    		bodyIndex = match.Index + match.Length;
				previousSubtitle = subtitle;
   			}
   			else
    			break;
   		}
   		return bodyIndex;
   	}
示例#9
0
	private string GetSubtitleExpression (SubtitleFormat format, SubtitleProperties subtitleProperties, FileProperties fileProperties) {
		if (format.Mode == SubtitleMode.Both) {
			if (fileProperties.TimingMode == TimingMode.Times)
				return format.SubtitleOutTimesMode;
			else
				return format.SubtitleOutFramesMode;
		}
		else {
			if (format.SubtitleOut != null)
				return format.SubtitleOut;
			else
				return format.GetDynamicSubtitleOut(subtitleProperties);
		}
	}
示例#10
0
	private int FindBodyIndex (string text, SubtitleFormat format, Regex subtitleRegex) {
		if (format.HasHeaders || format.HasBodyBegin) {
			Match subtitleMatch = subtitleRegex.Match(text);
			if (subtitleMatch.Success) {
				return subtitleMatch.Index;
			}
		}
		return 0;
	}
示例#11
0
    private int ReadBodyEnd (string text, int bodyIndex, SubtitleFormat format,
    		SubtitleCollection collection, IncompleteSubtitleCollection incompleteSubtitles) {

    	Regex bodyEnd = new Regex(format.BodyEndIn + @"\s*", RegexOptions.IgnoreCase);
    	Match bodyEndMatch = bodyEnd.Match(text, bodyIndex);
    	if (bodyEndMatch.Success) {
	   		AddIncompleteSubtitleIfExists(text, bodyEndMatch, bodyIndex, collection.Count, incompleteSubtitles);
    		bodyIndex = bodyEndMatch.Index + bodyEndMatch.Length;
    	}
    	return bodyIndex;
	}
示例#12
0
	private Style ParseStyle (Match match, SubtitleFormat subtitleFormat) {
		string styleText = String.Empty;
		if (ParseGroup(match, "Style", ref styleText))
			return subtitleFormat.StringToStyle(styleText);
		else
			return new Style();
	}
示例#13
0
	private SubtitleText ParseSubtitleText (Match match, SubtitleFormat subtitleFormat) {
		string text = String.Empty;
		if (ParseGroup(match, "Text", ref text))
			return new SubtitleText(text, subtitleFormat.LineBreak, true);
		else
			return new SubtitleText();
	}
示例#14
0
	private Subtitle ParseSubtitle (Match match, SubtitleFormat format, ParsingProperties properties, Subtitle previousSubtitle){
		SubtitleText text = ParseSubtitleText(match, format);
		Style style = ParseStyle(match, format);

		Subtitle subtitle = new Subtitle(null, text, style);

		if (properties.TimingMode == TimingMode.Frames) {
			Frames previousFrames = (previousSubtitle == null ? null : previousSubtitle.Frames);
			ParseFrames(match, subtitle.Frames, previousFrames);
		}
		else {
			Times previousTimes = (previousSubtitle == null ? null : previousSubtitle.Times);
			ParseTimes(match, subtitle.Times, previousTimes, properties);
		}

		format.SubtitleInputPostProcess(subtitle);
		return subtitle;
	}
示例#15
0
	/* Private methods */

	/// <summary>Checks the encoding of a file.</summary>
	/// <param name="isSubtitleFile">If it is a subtitle file or a plain text one.</param>
	/// <param name="fileStream">The stream for reading the file.</param>
	/// <param name="usedEncoding">The encoding supposedly used.</param>
	/// <param name="usedFormat">The subtitle format used.</param>
	/// <exception cref="EncodingNotSupportedException">Thrown if the encoding is not supported by the platform.</exception>
	/// <exception cref="UnknownSubtitleFormatException">Thrown if the subtitle format could not be detected.</exception>
	private string ReadSubtitleText (bool isSubtitleFile, FileStream fileStream, out Encoding usedEncoding, out SubtitleFormat usedFormat) {
		/* Init the out arguments */
		usedEncoding = null;
		usedFormat = null;

		/* Detect code pages */
		int[] codePages = FileInputOutput.DetectCodePages(fileStream);

		/* Check if no codepage was detected */
		if (codePages.Length == 0) {
			VerboseConsole.WriteLine("No encoding was automatically detected. Using the fall-back encoding \"" + fallbackEncoding.WebName + "\"");
			string text;
			if (isSubtitleFile)
				text = TestEncoding(fileStream, fallbackEncoding, out usedFormat);
			else
				text = TestEncoding(fileStream, fallbackEncoding);
			usedEncoding = fallbackEncoding;
			return text;
		}

		/* The first code page represents the most probable encoding. If any problem occurs when trying to use
		 * that code page, this problem is registered. The remaining code pages are then tried, and if none works,
		 * the first occuring error is the one to be reported. */
		Exception firstEncodingException = null;
		Exception firstSubtitleFormatException = null;
		int firstCodePage = codePages[0];
		try {
			string text;
			if (isSubtitleFile)
				text = TestCodePage(fileStream, firstCodePage, out usedEncoding, out usedFormat);
			else
				text = TestCodePagePlain(fileStream, firstCodePage, out usedEncoding);
			return text;
		}
		catch (EncodingNotSupportedException e) {
			firstEncodingException = e;
		}
		catch (UnknownSubtitleFormatException e) {
			firstSubtitleFormatException = e;
		}

		/* Problems were found, going to try additional code pages */
		for (int count = 1 ; count < codePages.Length ; count++) {
			try {
				int codePage = codePages[count];
				string text;
				if (isSubtitleFile)
					text = TestCodePage(fileStream, codePage, out usedEncoding, out usedFormat);
				else
					text = TestCodePagePlain(fileStream, codePage, out usedEncoding);
				return text;
			}
			catch (Exception) {
				//Don't do anything, will try the next code page
			}
		}

		/* No code page worked, throwing the exceptions caught for the first (more probable) code page */
		if (firstEncodingException != null)
			throw firstEncodingException;
		else
			throw firstSubtitleFormatException;

	}
示例#16
0
	private Regex CreateSubtitleRegex(SubtitleFormat format) {
		string subtitleInExpression = format.SubtitleIn + @"\s*"; //Ignore spaces between subtitles
		return new Regex(subtitleInExpression, RegexOptions.IgnoreCase);
	}
示例#17
0
	/* Internal members */

	internal SubtitleTypeInfo (SubtitleFormat format) : this(format.Name, format.Type, format.Mode, format.Extensions) {
	}
示例#18
0
	// Used when a subtitle format suppports both times and frames
	private Regex CreateSubtitleRegex(SubtitleFormat format, TimingMode timingMode) {
		string subtitleInExpression;
		if (timingMode == TimingMode.Times)
			subtitleInExpression = format.SubtitleInTimesMode + @"\s*";   //Ignore spaces between subtitles
		else
			subtitleInExpression = format.SubtitleInFramesMode + @"\s*";  //Ignore spaces between subtitles

		return new Regex(subtitleInExpression, RegexOptions.IgnoreCase);
	}
示例#19
0
	internal SubtitleOutput (SubtitleFormat format, SubtitleTextType textType) {
		this.format = format;
		this.textType = textType;
	}
示例#20
0
	/// <returns>The index where subtitles start.</returns>
	private int ReadHeaders (string text, int bodyIndex, SubtitleFormat format, ParsingProperties properties) {
		if (!(format.HasHeaders && (bodyIndex > 0)))
			return 0;

		ParseHeaderDelegate headerParser = GetHeaderParser(format.Type);

		int lastIndex = 0; //the last index with header text
		string headerText = text.Substring(0, bodyIndex);
		foreach (string headerExpression in format.Headers) {
			Regex expression = new Regex(headerExpression, RegexOptions.IgnoreCase);
			Match match = expression.Match(headerText, 0, bodyIndex);
			if (match.Success) {
				/* Update the last index based on the header match */
				int matchLastIndex = match.Index + match.Length;
				if (matchLastIndex > lastIndex)
					lastIndex = matchLastIndex;

				headerParser(match, properties);
			}
		}
		return lastIndex;
	}