示例#1
0
        public static bool TryReadPreNoteConnection(Scanner scanner, ILogger logger,
                                                    out LiteralNode <PreNoteConnection> connection)
        {
            switch (scanner.ReadAnyPatternOf(@"\/", @"\\", @"\.\/", @"\`\\", "h", "p", "s"))
            {
            case @"/":
            case @"\":
            case "s":
                connection = new LiteralNode <PreNoteConnection>(PreNoteConnection.Slide, scanner.LastReadRange);
                return(true);

            case @"./":
                connection = new LiteralNode <PreNoteConnection>(PreNoteConnection.SlideInFromLower, scanner.LastReadRange);
                return(true);

            case @"`\":
                connection = new LiteralNode <PreNoteConnection>(PreNoteConnection.SlideInFromHigher, scanner.LastReadRange);
                return(true);

            case @"h":
                connection = new LiteralNode <PreNoteConnection>(PreNoteConnection.Hammer, scanner.LastReadRange);
                return(true);

            case @"p":
                connection = new LiteralNode <PreNoteConnection>(PreNoteConnection.Pull, scanner.LastReadRange);
                return(true);
            }

            connection = null;
            return(false);
        }
示例#2
0
        public static bool TryReadNoteRepetition(Scanner scanner, ILogger logger,
                                                 out LiteralNode <NoteRepetition> ornament)
        {
            switch (scanner.ReadAnyPatternOf("tremolo"))
            {
            case "tremolo":
                ornament = new LiteralNode <NoteRepetition>(NoteRepetition.Tremolo, scanner.LastReadRange);
                return(true);
            }

            ornament = null;
            return(false);
        }
示例#3
0
        public static bool TryReadAccidental(Scanner scanner, ILogger logger,
                                             out LiteralNode <Accidental> accidentalNode)
        {
            var        accidentalText = scanner.ReadAnyPatternOf(@"\#\#", "bb", "♯♯", "♭♭", @"\#", "♯", "b", "♭", "\u1d12a", "\u1d12b");
            Accidental accidental;

            if (!Accidentals.TryParse(accidentalText, out accidental))
            {
                accidentalNode = null;
                return(false);
            }

            accidentalNode = new LiteralNode <Accidental>(accidental, scanner.LastReadRange);
            return(true);
        }
示例#4
0
        public static bool TryReadOrnament(Scanner scanner, ILogger logger,
                                           out LiteralNode <Ornament> ornament, out LiteralNode <double> argument)
        {
            argument = null;

            switch (scanner.ReadAnyPatternOf("trill", "tr"))
            {
            case "tr":
            case "trill":
                ornament = new LiteralNode <Ornament>(Ornament.Trill, scanner.LastReadRange);
                return(true);
            }

            ornament = null;
            return(false);
        }
示例#5
0
        public static bool TryReadBeatAccent(Scanner scanner, ILogger logger, out LiteralNode <BeatAccent> accent)
        {
            switch (scanner.ReadAnyPatternOf("accented", "heavy", "marcato"))
            {
            case "accented":
                accent = new LiteralNode <BeatAccent>(BeatAccent.Accented, scanner.LastReadRange);
                return(true);

            case "heavy":
            case "marcato":
                accent = new LiteralNode <BeatAccent>(BeatAccent.Marcato, scanner.LastReadRange);
                return(true);
            }

            accent = null;
            return(false);
        }
示例#6
0
        public static bool TryReadPostNoteConnection(Scanner scanner, ILogger logger,
                                                     out LiteralNode <PostNoteConnection> connection)
        {
            switch (scanner.ReadAnyPatternOf(@"\/\`", @"\\\.").ToLowerInvariant())
            {
            case @"/`":
                connection = new LiteralNode <PostNoteConnection>(PostNoteConnection.SlideOutToHigher, scanner.LastReadRange);
                return(true);

            case @"\.":
                connection = new LiteralNode <PostNoteConnection>(PostNoteConnection.SlideOutToLower, scanner.LastReadRange);
                return(true);
            }

            connection = null;
            return(false);
        }
示例#7
0
        public static bool TryReadNoteHoldAndPause(Scanner scanner, ILogger logger,
                                                   out LiteralNode <HoldAndPause> holdAndPause)
        {
            switch (scanner.ReadAnyPatternOf("fermata", "staccato", "tenuto"))
            {
            case "fermata":
                holdAndPause = new LiteralNode <HoldAndPause>(HoldAndPause.Fermata, scanner.LastReadRange);
                return(true);

            case "staccato":
                holdAndPause = new LiteralNode <HoldAndPause>(HoldAndPause.Staccato, scanner.LastReadRange);
                return(true);

            case "tenuto":
                holdAndPause = new LiteralNode <HoldAndPause>(HoldAndPause.Tenuto, scanner.LastReadRange);
                return(true);
            }

            holdAndPause = null;
            return(false);
        }
示例#8
0
        public static bool TryReadNoteEffectTechnique(Scanner scanner, ILogger logger,
                                                      out LiteralNode <NoteEffectTechnique> technique, out LiteralNode <double> argument)
        {
            argument = null;

            switch (scanner.ReadAnyPatternOf("dead", "bend", "x", "b"))
            {
            case "dead":
            case "x":
                technique = new LiteralNode <NoteEffectTechnique>(NoteEffectTechnique.DeadNote, scanner.LastReadRange);
                return(true);

            case "bend":
            case "b":
                // todo: bend args
                technique = new LiteralNode <NoteEffectTechnique>(NoteEffectTechnique.Bend, scanner.LastReadRange);
                return(true);
            }

            technique = null;
            return(false);
        }
示例#9
0
        public static bool TryReadStrumTechnique(Scanner scanner, ILogger logger, out LiteralNode <StrumTechnique> technique)
        {
            switch (scanner.ReadAnyPatternOf("rasg", "ad", "au", "pu", "pd", "d", "D", "↑", "u", "U", "↓"))
            {
            case "d":
            case "↑":
                technique = new LiteralNode <StrumTechnique>(StrumTechnique.BrushDown, scanner.LastReadRange);
                return(true);

            case "u":
            case "↓":
                technique = new LiteralNode <StrumTechnique>(StrumTechnique.BrushUp, scanner.LastReadRange);
                return(true);

            case "ad":
                technique = new LiteralNode <StrumTechnique>(StrumTechnique.ArpeggioDown, scanner.LastReadRange);
                return(true);

            case "au":
                technique = new LiteralNode <StrumTechnique>(StrumTechnique.ArpeggioUp, scanner.LastReadRange);
                return(true);

            case "rasg":
                technique = new LiteralNode <StrumTechnique>(StrumTechnique.Rasgueado, scanner.LastReadRange);
                return(true);

            case "pu":
                technique = new LiteralNode <StrumTechnique>(StrumTechnique.PickstrokeUp, scanner.LastReadRange);
                return(true);

            case "pd":
                technique = new LiteralNode <StrumTechnique>(StrumTechnique.PickstrokeDown, scanner.LastReadRange);
                return(true);
            }

            technique = null;
            return(false);
        }
示例#10
0
        public static bool TryReadTie(Scanner scanner, ILogger logger, out ExistencyNode tie,
                                      out LiteralNode <VerticalDirection> tiePosition)
        {
            switch (scanner.ReadAnyPatternOf(@"⁀", @"‿", @"~\^", @"~v", @"~"))
            {
            case @"~":
                tie = new ExistencyNode()
                {
                    Range = scanner.LastReadRange
                };
                tiePosition = null;
                return(true);

            case @"⁀":
            case @"~^":
                tie = new ExistencyNode()
                {
                    Range = scanner.LastReadRange
                };
                tiePosition = new LiteralNode <VerticalDirection>(VerticalDirection.Above, scanner.LastReadRange);
                return(true);

            case @"‿":
            case @"~v":
                tie = new ExistencyNode()
                {
                    Range = scanner.LastReadRange
                };
                tiePosition = new LiteralNode <VerticalDirection>(VerticalDirection.Under, scanner.LastReadRange);
                return(true);
            }

            tie         = null;
            tiePosition = null;
            return(false);
        }
示例#11
0
        public static bool TryReadChordStrumTechnique(Scanner scanner, ILogger logger,
                                                      out LiteralNode <ChordStrumTechnique> technique)
        {
            switch (scanner.ReadAnyPatternOf("rasg", "ad", "au", @"\|", "x", "d", "↑", "u", "↓"))
            {
            case "|":
            case "x":
                technique = new LiteralNode <ChordStrumTechnique>(ChordStrumTechnique.None, scanner.LastReadRange);
                return(true);

            case "d":
            case "↑":
                technique = new LiteralNode <ChordStrumTechnique>(ChordStrumTechnique.BrushDown, scanner.LastReadRange);
                return(true);

            case "u":
            case "↓":
                technique = new LiteralNode <ChordStrumTechnique>(ChordStrumTechnique.BrushUp, scanner.LastReadRange);
                return(true);

            case "ad":
                technique = new LiteralNode <ChordStrumTechnique>(ChordStrumTechnique.ArpeggioDown, scanner.LastReadRange);
                return(true);

            case "au":
                technique = new LiteralNode <ChordStrumTechnique>(ChordStrumTechnique.ArpeggioUp, scanner.LastReadRange);
                return(true);

            case "rasg":
                technique = new LiteralNode <ChordStrumTechnique>(ChordStrumTechnique.Rasgueado, scanner.LastReadRange);
                return(true);
            }

            technique = null;
            return(false);
        }
示例#12
0
        public override bool TryParse(Scanner scanner, out ChordFingeringNode result)
        {
            result = new ChordFingeringNode();
            var anchor                       = scanner.MakeAnchor();
            var remainingLine                = scanner.RemainingLine.Trim();
            var containsDelimiter            = remainingLine.Any(char.IsWhiteSpace);
            var containsFingerIndexSpecifier = remainingLine.Any(c => c == '<' || c == '>');
            var isShortForm                  = !containsDelimiter && !containsFingerIndexSpecifier;

            while (!_terminatorPredicate(scanner))
            {
                var noteAnchor = scanner.MakeAnchor();

                var str = isShortForm ? scanner.ReadPattern(@"[\dxX\-]") : scanner.ReadAnyPatternOf(@"\d+", @"[xX\-]");

                if (string.IsNullOrEmpty(str))
                {
                    this.Report(LogLevel.Warning, scanner.LastReadRange,
                                Messages.Error_ChordFingeringInvalidFingering);
                    result = null;
                    return(false);
                }

                switch (str)
                {
                case "x":
                case "X":
                case "-":
                {
                    var fret = new LiteralNode <int>(Chord.FingeringSkipString, scanner.LastReadRange);
                    result.Fingerings.Add(new ChordFingeringNoteNode {
                            Fret = fret, Range = scanner.LastReadRange
                        });
                    break;
                }

                default:
                    int fretNumber;
                    if (!int.TryParse(str, out fretNumber))     // todo: prevent too large fret number
                    {
                        this.Report(LogLevel.Warning, scanner.LastReadRange,
                                    Messages.Error_ChordFingeringInvalidFingering);
                        result = null;
                        return(false);
                    }

                    if (fretNumber > 24)
                    {
                        this.Report(LogLevel.Warning, scanner.LastReadRange,
                                    Messages.Warning_ChordFingeringFretTooHigh);
                    }

                    var note = new ChordFingeringNoteNode
                    {
                        Fret  = new LiteralNode <int>(fretNumber, scanner.LastReadRange),
                        Range = scanner.LastReadRange
                    };

                    if (fretNumber != 0)
                    {
                        scanner.SkipWhitespaces();
                        if (scanner.Expect('<'))
                        {
                            scanner.SkipWhitespaces();

                            var fingerIndexString = scanner.ReadPattern(@"[\dtT]");
                            if (string.IsNullOrEmpty(fingerIndexString))
                            {
                                this.Report(LogLevel.Error, scanner.Pointer.AsRange(),
                                            Messages.Error_ChordFingerIndexExpected);
                                return(false);
                            }


                            LeftHandFingerIndex fingerIndex;
                            switch (fingerIndexString)
                            {
                            case "t":
                            case "T":
                                fingerIndex = LeftHandFingerIndex.Thumb; break;

                            case "1":
                                fingerIndex = LeftHandFingerIndex.Index; break;

                            case "2":
                                fingerIndex = LeftHandFingerIndex.Middle; break;

                            case "3":
                                fingerIndex = LeftHandFingerIndex.Ring; break;

                            case "4":
                                fingerIndex = LeftHandFingerIndex.Pinky; break;

                            default:
                                this.Report(LogLevel.Error, scanner.LastReadRange,
                                            Messages.Error_UnrecognizableFingerIndex);
                                return(false);
                            }


                            note.FingerIndex = new LiteralNode <LeftHandFingerIndex>(fingerIndex,
                                                                                     scanner.LastReadRange);

                            scanner.SkipWhitespaces();

                            ExistencyNode importancy;
                            if (new CharExistencyParser('!').TryParse(scanner, out importancy))
                            {
                                note.Importancy = importancy;
                                scanner.SkipWhitespaces();
                            }

                            if (!scanner.Expect('>'))
                            {
                                this.Report(LogLevel.Error, scanner.Pointer.AsRange(),
                                            Messages.Error_ChordFingerIndexNotEnclosed);
                                return(false);
                            }
                        }
                    }

                    note.Range = noteAnchor.Range;
                    result.Fingerings.Add(note);

                    break;
                }

                scanner.SkipWhitespaces();
            }

            if (result.Fingerings.Count != Defaults.Strings)
            {
                this.Report(LogLevel.Error, scanner.LastReadRange,
                            Messages.Error_ChordFingeringNotMatchingStringCount, Defaults.Strings);
                result = null;
                return(false);
            }

            result.Range = anchor.Range;
            return(true);
        }