filebot/source/net/filebot/subtitle/SubStationAlphaReader.java

99 lines
2.7 KiB
Java

package net.filebot.subtitle;
import static java.util.Arrays.*;
import java.text.DateFormat;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
public class SubStationAlphaReader extends SubtitleReader {
private final DateFormat timeFormat = new SubtitleTimeFormat();
private final Pattern newline = Pattern.compile(Pattern.quote("\\n"), Pattern.CASE_INSENSITIVE);
private final Pattern tags = Pattern.compile("[{]\\\\[^}]+[}]");
private final Pattern drawingTags = Pattern.compile("\\\\[p][0-4]"); // ignore drawing commands (http://docs.aegisub.org/3.2/ASS_Tags/#drawing-commands)
private String[] format;
private int formatIndexStart;
private int formatIndexEnd;
private int formatIndexText;
public SubStationAlphaReader(Scanner scanner) {
super(scanner);
}
private void readFormat() throws Exception {
// read format line (e.g. Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text)
String line = scanner.nextLine();
String[] event = line.split(":", 2);
// sanity check
if (!event[0].equals("Format"))
throw new InputMismatchException("Illegal format header: " + line);
// read columns
format = event[1].split(",");
// normalize column names
for (int i = 0; i < format.length; i++) {
format[i] = format[i].trim().toLowerCase();
}
List<String> lookup = asList(format);
formatIndexStart = lookup.indexOf("start");
formatIndexEnd = lookup.indexOf("end");
formatIndexText = lookup.indexOf("text");
}
@Override
public SubtitleElement readNext() throws Exception {
if (format == null) {
// move to [Events] sections
boolean found = false;
while (!found && scanner.hasNextLine()) {
found = scanner.nextLine().equals("[Events]");
}
if (!found) {
throw new InputMismatchException("Cannot find [Events] section");
}
// read format header
readFormat();
}
// read next dialogue line
String[] event = scanner.nextLine().split(":", 2);
// ignore non-dialog lines
if (event.length < 2 || !event[0].equals("Dialogue"))
return null;
// extract information
String[] values = event[1].split(",", format.length);
long start = timeFormat.parse(values[formatIndexStart].trim()).getTime();
long end = timeFormat.parse(values[formatIndexEnd].trim()).getTime();
String text = values[formatIndexText].trim();
// ignore drawing instructions
if (drawingTags.matcher(text).find())
return null;
return new SubtitleElement(start, end, resolve(text));
}
protected String resolve(String text) {
// remove tags
text = tags.matcher(text).replaceAll("");
// resolve line breaks
return newline.matcher(text).replaceAll("\n");
}
}