private static LinkedList <LilypondToken> GetTokensFromLilypond(string content) { var tokens = new LinkedList <LilypondToken>(); foreach (string s in content.Split(' ').Where(item => item.Length > 0)) { LilypondToken token = new LilypondToken() { Value = s }; //token = CheckTokenKind(s, token); //token = CheckTokenKindIsNote(s, token); token.TokenKind = new LilypondTokenFactory(s).getTokenKind(); if (tokens.Last != null) { tokens.Last.Value.NextToken = token; token.PreviousToken = tokens.Last.Value; } tokens.AddLast(token); } return(tokens); }
public void Solve(LilypondContext context, LilypondToken token) { token = token.NextToken; var times = token.Value.Split('/'); var timeSignature = new PSAMControlLibrary.TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1])); context.Symbols.Add(timeSignature); }
private LinkedList <LilypondToken> getTokensFromLilypond(string lilyPondText) { var tokens = new LinkedList <LilypondToken>(); foreach (string substring in lilyPondText.Split(' ').Where(item => item.Length > 0)) { var sanitizedString = substring.Replace("\r\n", string.Empty); LilypondToken token = new LilypondToken { Value = sanitizedString }; switch (sanitizedString) { case "\\relative": token.TokenKind = LilypondTokenKind.Staff; break; case "\\clef": token.TokenKind = LilypondTokenKind.Clef; break; case "\\time": token.TokenKind = LilypondTokenKind.Time; break; case "\\tempo": token.TokenKind = LilypondTokenKind.Tempo; break; case "\\repeat": token.TokenKind = LilypondTokenKind.Repeat; break; case "\\alternative": token.TokenKind = LilypondTokenKind.Alternative; break; case "{": token.TokenKind = LilypondTokenKind.SectionStart; break; case "}": token.TokenKind = LilypondTokenKind.SectionEnd; break; case "|": token.TokenKind = LilypondTokenKind.Bar; break; default: token.TokenKind = LilypondTokenKind.Unknown; break; } switch (token.TokenKind) { case LilypondTokenKind.Unknown when new Regex(@"[a-g][,'eis]*[0-9]+[~]?[.]*", RegexOptions.IgnoreCase).IsMatch(token.Value): token.TokenKind = LilypondTokenKind.Note; break; case LilypondTokenKind.Unknown when new Regex(@"r.*?[0-9][.]*").IsMatch(substring): token.TokenKind = LilypondTokenKind.Rest; break; } if (tokens.Last != null) { tokens.Last.Value.NextToken = token; token.PreviousToken = tokens.Last.Value; } tokens.AddLast(token); } return(tokens); }
private static LinkedList <LilypondToken> GetTokensFromLilypond(string content) { var tokens = new LinkedList <LilypondToken>(); foreach (string s in content.Split(' ').Where(item => item.Length > 0)) { LilypondToken token = new LilypondToken() { Value = s }; switch (s) { case "\\relative": token.TokenKind = LilypondTokenKind.Staff; break; case "\\clef": token.TokenKind = LilypondTokenKind.Clef; break; case "\\time": token.TokenKind = LilypondTokenKind.Time; break; case "\\tempo": token.TokenKind = LilypondTokenKind.Tempo; break; case "\\repeat": token.TokenKind = LilypondTokenKind.Repeat; break; case "\\alternative": token.TokenKind = LilypondTokenKind.Alternative; break; case "{": token.TokenKind = LilypondTokenKind.SectionStart; break; case "}": token.TokenKind = LilypondTokenKind.SectionEnd; break; case "|": token.TokenKind = LilypondTokenKind.Bar; break; default: token.TokenKind = LilypondTokenKind.Unknown; break; } if (token.TokenKind == LilypondTokenKind.Unknown && new Regex(@"[~]?[a-g][,'eis]*[0-9]+[.]*").IsMatch(s)) { token.TokenKind = LilypondTokenKind.Note; } else if (token.TokenKind == LilypondTokenKind.Unknown && new Regex(@"r.*?[0-9][.]*").IsMatch(s)) { token.TokenKind = LilypondTokenKind.Rest; } if (tokens.Last != null) { tokens.Last.Value.NextToken = token; token.PreviousToken = tokens.Last.Value; } tokens.AddLast(token); } return(tokens); }
public void Solve(LilypondContext context, LilypondToken token) { // Length int noteLength = Int32.Parse(Regex.Match(token.Value, @"\d+").Value); // Crosses and Moles int alter = 0; alter += Regex.Matches(token.Value, "is").Count; alter -= Regex.Matches(token.Value, "es|as").Count; // Octaves int distanceWithPreviousNote = notesorder.IndexOf(token.Value[0]) - notesorder.IndexOf(context.PreviousNote); if (distanceWithPreviousNote > 3) // Shorter path possible the other way around { distanceWithPreviousNote -= 7; // The number of notes in an octave } else if (distanceWithPreviousNote < -3) { distanceWithPreviousNote += 7; // The number of notes in an octave } if (distanceWithPreviousNote + notesorder.IndexOf(context.PreviousNote) >= 7) { context.PreviousOctave++; } else if (distanceWithPreviousNote + notesorder.IndexOf(context.PreviousNote) < 0) { context.PreviousOctave--; } // Force up or down. context.PreviousOctave += token.Value.Count(c => c == '\''); context.PreviousOctave -= token.Value.Count(c => c == ','); context.PreviousNote = token.Value[0]; var note = new Note(token.Value[0].ToString().ToUpper(), alter, context.PreviousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, NoteTieType.None, new List <NoteBeamType>() { NoteBeamType.Single }); note.NumberOfDots += token.Value.Count(c => c.Equals('.')); context.Symbols.Add(note); }
public IEnumerable <MusicalSymbol> Solve() { LilypondToken currentToken = tokens.First?.Value; while (currentToken != null) { var handler = new ExpressionFactory().Get(currentToken.TokenKind.ToString()); if (handler != null) { handler.Solve(context, currentToken); } currentToken = currentToken.NextToken; } return(context.Symbols); }
public LilypondToken Tokenize(string s) { var token = new LilypondToken() { Value = s }; foreach (var handler in handlers) { if (handler.canHandle(s)) { token.TokenKind = handler.handle(s); return(token); } } return(token); // never reached, but it's needed for the compiler. }
public void Solve(LilypondContext context, LilypondToken token) { token = token.NextToken; if (token == null) { return; } if (token.Value == "treble") { context.CurrentClef = new PSAMControlLibrary.Clef(ClefType.GClef, 2); } else if (token.Value == "bass") { context.CurrentClef = new PSAMControlLibrary.Clef(ClefType.FClef, 4); } //else // throw new NotSupportedException($"Clef {token.Value} is not supported."); context.Symbols.Add(context.CurrentClef); }
private static LinkedList <LilypondToken> GetTokensFromLilypond(string content) { var tokens = new LinkedList <LilypondToken>(); var tokenizer = new Tokenizer(); content = content.Trim().ToLower().Replace("\r\n", " ").Replace("\n", " ").Replace(" ", " "); foreach (string s in content.Split(' ')) { LilypondToken token = tokenizer.Tokenize(s); if (tokens.Last != null) { tokens.Last.Value.NextToken = token; token.PreviousToken = tokens.Last.Value; } tokens.AddLast(token); } return(tokens); }
private static IEnumerable <MusicalSymbol> GetStaffsFromTokens(LinkedList <LilypondToken> tokens) { List <MusicalSymbol> symbols = new List <MusicalSymbol>(); Clef currentClef = null; int previousOctave = 4; char previousNote = 'c'; bool inRepeat = false; bool inAlternative = false; int alternativeRepeatNumber = 0; LilypondToken currentToken = tokens.First(); while (currentToken != null) { // TODO: There are a lot of switches based on LilypondTokenKind, can't those be eliminated en delegated? // HINT: Command, Decorator, Factory etc. // TODO: Repeats are somewhat weirdly done. Can we replace this with the COMPOSITE pattern? switch (currentToken.TokenKind) { case LilypondTokenKind.Unknown: break; case LilypondTokenKind.Repeat: inRepeat = true; symbols.Add(new Barline() { RepeatSign = RepeatSignType.Forward }); break; case LilypondTokenKind.SectionEnd: if (inRepeat && currentToken.NextToken?.TokenKind != LilypondTokenKind.Alternative) { inRepeat = false; symbols.Add(new Barline() { RepeatSign = RepeatSignType.Backward, AlternateRepeatGroup = alternativeRepeatNumber }); } else if (inAlternative && alternativeRepeatNumber == 1) { alternativeRepeatNumber++; symbols.Add(new Barline() { RepeatSign = RepeatSignType.Backward, AlternateRepeatGroup = alternativeRepeatNumber }); } else if (inAlternative && currentToken.NextToken.TokenKind == LilypondTokenKind.SectionEnd) { inAlternative = false; alternativeRepeatNumber = 0; } break; case LilypondTokenKind.SectionStart: if (inAlternative && currentToken.PreviousToken.TokenKind != LilypondTokenKind.SectionEnd) { alternativeRepeatNumber++; symbols.Add(new Barline() { AlternateRepeatGroup = alternativeRepeatNumber }); } break; case LilypondTokenKind.Alternative: inAlternative = true; inRepeat = false; currentToken = currentToken.NextToken; // Skip the first bracket open. break; case LilypondTokenKind.Note: // Tied // TODO: A tie, like a dot and cross or mole are decorations on notes. Is the DECORATOR pattern of use here? NoteTieType tie = NoteTieType.None; if (currentToken.Value.StartsWith("~")) { tie = NoteTieType.Stop; var lastNote = symbols.Last(s => s is Note) as Note; if (lastNote != null) { lastNote.TieType = NoteTieType.Start; } currentToken.Value = currentToken.Value.Substring(1); } // Length int noteLength = Int32.Parse(Regex.Match(currentToken.Value, @"\d+").Value); // Crosses and Moles int alter = 0; alter += Regex.Matches(currentToken.Value, "is").Count; alter -= Regex.Matches(currentToken.Value, "es|as").Count; // Octaves int distanceWithPreviousNote = notesorder.IndexOf(currentToken.Value[0]) - notesorder.IndexOf(previousNote); if (distanceWithPreviousNote > 3) // Shorter path possible the other way around { distanceWithPreviousNote -= 7; // The number of notes in an octave } else if (distanceWithPreviousNote < -3) { distanceWithPreviousNote += 7; // The number of notes in an octave } if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) >= 7) { previousOctave++; } else if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) < 0) { previousOctave--; } // Force up or down. previousOctave += currentToken.Value.Count(c => c == '\''); previousOctave -= currentToken.Value.Count(c => c == ','); previousNote = currentToken.Value[0]; var note = new Note(currentToken.Value[0].ToString().ToUpper(), alter, previousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, tie, new List <NoteBeamType>() { NoteBeamType.Single }); note.NumberOfDots += currentToken.Value.Count(c => c.Equals('.')); symbols.Add(note); break; case LilypondTokenKind.Rest: var restLength = Int32.Parse(currentToken.Value[1].ToString()); symbols.Add(new Rest((MusicalSymbolDuration)restLength)); break; case LilypondTokenKind.Bar: symbols.Add(new Barline() { AlternateRepeatGroup = alternativeRepeatNumber }); break; case LilypondTokenKind.Clef: currentToken = currentToken.NextToken; if (currentToken.Value == "treble") { currentClef = new Clef(ClefType.GClef, 2); } else if (currentToken.Value == "bass") { currentClef = new Clef(ClefType.FClef, 4); } else { throw new NotSupportedException($"Clef {currentToken.Value} is not supported."); } symbols.Add(currentClef); break; case LilypondTokenKind.Time: currentToken = currentToken.NextToken; var times = currentToken.Value.Split('/'); symbols.Add(new TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1]))); break; case LilypondTokenKind.Tempo: // Tempo not supported break; default: break; } currentToken = currentToken.NextToken; } return(symbols); }
public void Solve(LilypondContext context, LilypondToken token) { var restLength = Int32.Parse(token.Value[1].ToString()); context.Symbols.Add(new Rest((MusicalSymbolDuration)restLength)); }
public void Solve(LilypondContext context, LilypondToken token) { context.Symbols.Add(new Barline()); }
public void Solve(LilypondContext context, LilypondToken token) { // Tempo not supported }
private static IEnumerable <MusicalSymbol> GetStaffsFromTokens(LinkedList <LilypondToken> tokens, out string message) { List <MusicalSymbol> symbols = new List <MusicalSymbol>(); message = ""; try { Clef currentClef = null; int previousOctave = 4; char previousNote = 'c'; LilypondToken currentToken = tokens.First(); while (currentToken != null) { switch (currentToken.TokenKind) { case LilypondTokenKind.Unknown: break; case LilypondTokenKind.Note: // Length int noteLength = Int32.Parse(Regex.Match(currentToken.Value, @"\d+").Value); // Crosses and Moles int alter = 0; alter += Regex.Matches(currentToken.Value, "is").Count; alter -= Regex.Matches(currentToken.Value, "es|as").Count; // Octaves int distanceWithPreviousNote = notesorder.IndexOf(currentToken.Value[0]) - notesorder.IndexOf(previousNote); if (distanceWithPreviousNote > 3) // Shorter path possible the other way around { distanceWithPreviousNote -= 7; // The number of notes in an octave } else if (distanceWithPreviousNote < -3) { distanceWithPreviousNote += 7; // The number of notes in an octave } if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) >= 7) { previousOctave++; } else if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) < 0) { previousOctave--; } // Force up or down. previousOctave += currentToken.Value.Count(c => c == '\''); previousOctave -= currentToken.Value.Count(c => c == ','); previousNote = currentToken.Value[0]; var note = new PSAMControlLibrary.Note(currentToken.Value[0].ToString().ToUpper(), alter, previousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, NoteTieType.None, new List <NoteBeamType>() { NoteBeamType.Single }); note.NumberOfDots += currentToken.Value.Count(c => c.Equals('.')); symbols.Add(note); break; case LilypondTokenKind.Rest: var restLength = Int32.Parse(currentToken.Value[1].ToString()); symbols.Add(new Rest((MusicalSymbolDuration)restLength)); break; case LilypondTokenKind.Bar: symbols.Add(new Barline()); break; case LilypondTokenKind.Clef: currentToken = currentToken.NextToken; if (currentToken.Value == "treble") { currentClef = new Clef(ClefType.GClef, 2); } else if (currentToken.Value == "bass") { currentClef = new Clef(ClefType.FClef, 4); } else { throw new NotSupportedException($"Clef {currentToken.Value} is not supported."); } symbols.Add(currentClef); break; case LilypondTokenKind.Time: currentToken = currentToken.NextToken; var times = currentToken.Value.Split('/'); symbols.Add(new TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1]))); break; case LilypondTokenKind.Tempo: // Tempo not supported break; default: break; } currentToken = currentToken.NextToken; } } catch (Exception ex) { message = ex.Message; } return(symbols); }