package gsingh.learnkirtan.parser; import gsingh.learnkirtan.keys.LabelManager.Octave; import gsingh.learnkirtan.note.Note; import gsingh.learnkirtan.note.Note.Length; import gsingh.learnkirtan.note.Note.Modifier; import gsingh.learnkirtan.shabad.Shabad; import gsingh.learnkirtan.shabad.ShabadNotes; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Used for parsing raw shabad text into a {@link Shabad} object * * @author Gulshan * */ public class Parser { /** The regex defining a modifier */ private static final String modifierRegex = "(?:\\.|'|\\.'|'\\.)"; /** The regex defining a note */ private static final String noteRegex = String.format( "(?:(%s?)(sa|re|ga|ma|pa|dha|ni)(%s?))", modifierRegex, modifierRegex); /** The regex defining a shabad */ private static final String completeNoteRegex = String.format("(?:%s(?:-%s)? ?)", noteRegex, noteRegex); /** The pattern defining a shabad */ private static final Pattern completeNotePattern = Pattern.compile(completeNoteRegex, Pattern.CASE_INSENSITIVE); /** * Parses text into a {@link Shabad} object * * @param shabadText * the text to parse * @return a {@link Shabad} object representing the text */ public ShabadNotes parse(String shabadText) { shabadText = shabadText.trim(); ShabadNotes shabad = new ShabadNotes(); List<String> tokenList = Arrays.asList(shabadText.split("\\s")); for (int i = 0; i < tokenList.size(); i++) { String word = tokenList.get(i); Matcher matcher = completeNotePattern.matcher(word); if (word.equals("null") || word.equals("")) { shabad.addNote(null); } else if (matcher.matches()) { // Get the captured groups of the first note String prefix1 = matcher.group(1); String name1 = matcher.group(2); String suffix1 = matcher.group(3); // Get the captured groups of the second optional note String prefix2 = matcher.group(4); String name2 = matcher.group(5); String suffix2 = matcher.group(6); // If the second note was supplied, add two half notes, // else add one full note if (name2 != null) { Note note1 = buildNote(prefix1, name1, suffix1, Length.HALF); Note note2 = buildNote(prefix2, name2, suffix2, Length.HALF); shabad.addNote(note1); shabad.addNote(note2); } else { Note note1 = buildNote(prefix1, name1, suffix1, Length.FULL); shabad.addNote(note1); } } else if (word.equals("-")) { shabad.addLongNote(); } else { // TODO An unknown note was found System.out.println("Unknown note"); } } return shabad; } /** * Parses a note string to a {@link Note} object * * @param noteText * the text to parse * @return a {@link Note} object representing the text */ public Note parseNote(String noteText) { Note note = null; Matcher matcher = completeNotePattern.matcher(noteText); if (matcher.matches()) { String prefix = matcher.group(1); String name = matcher.group(2); String suffix = matcher.group(3); note = buildNote(prefix, name, suffix, Length.HALF); } return note; } /** * Builds a note * * @param prefix * the text before the note name * @param name * the name of the note * @param suffix * the text after the note name * @param length * the length the note should be played in milliseconds * @return a {@link Note} object built from the parameters */ private Note buildNote(String prefix, String name, String suffix, Length length) { Octave octave = Octave.MIDDLE; Modifier modifier = Modifier.NONE; if (prefix.contains(".")) octave = Octave.LOWER; else if (suffix.contains(".")) octave = Octave.UPPER; if (prefix.contains("'")) modifier = Modifier.KOMAL; else if (suffix.contains("'")) modifier = Modifier.THEEVRA; return new Note(name, octave, modifier, length); } }