package songbook.chordpro;
import songbook.chordpro.Song.PositionedData;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
/**
* Created by laurent on 09/05/2014.
*/
public class SongParser {
protected ParserInput input;
public static final Map<String, String> aliases = new HashMap<>();
static {
aliases.put("t", "title");
aliases.put("c", "comment");
}
public Song parse(String id, Reader reader) throws IOException {
input = new ParserInput(reader);
char c = input.peek();
StringBuilder sb = new StringBuilder();
Song song = new Song(id);
while (c != ParserInput.EOS) {
if (c == '{') {
// directive
song.directives.add(new PositionedData<>(parseDirective(), sb.length()));
} else if (c == '[') {
// chord
song.chords.add(new PositionedData<>(parseChord(), sb.length()));
} else {
sb.append(c);
input.skip(1);
}
c = input.peek();
}
song.lyrics = sb.toString();
return song;
}
protected Chord parseChord() throws IOException {
input.skip(1);
StringBuilder sb = new StringBuilder();
while (true) {
char c = input.peek();
input.skip(1);
if (c == ParserInput.EOS) {
return new Chord("");
} else if (c == ']') {
return new Chord(sb.toString());
} else {
sb.append(c);
}
}
}
protected Directive parseDirective() throws IOException {
input.skip(1);
StringBuilder sb = new StringBuilder();
String name = null;
String value = null;
while (true) {
char c = input.peek();
input.skip(1);
if (c == ParserInput.EOS) {
return new Directive(null, null);
} else if (c == ':') {
name = sb.toString();
sb.setLength(0);
} else if (c == '}') {
if (name == null) {
name = sb.toString();
} else {
value = sb.toString();
}
name = name.toLowerCase();
String alias = aliases.get(name);
if (alias != null) {
name = alias;
}
return new Directive(name, value);
} else {
sb.append(c);
}
}
}
public static void main(String[] args) throws IOException {
final Path path = Paths.get("data/songs/houseoftherisingsun.song");
BufferedReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
try {
new SongParser().parse(path.getFileName().toString(), reader);
} finally {
reader.close();
}
}
}