Esempio n. 1
0
        private void AddPart()
        {
            var res = ShowRenamePartDialog(null);

            if (res.DialogResult.HasValue && res.DialogResult.Value)
            {
                var newPart = song.AddPart(res.PartName);
                this.StructureTree.SelectItem(newPart.Slides.First());
                song.AddPartToOrder(newPart);
            }
        }
        public void Read(Song song, Stream stream)
        {
            if (song == null)
                throw new ArgumentNullException("song");

            if (stream == null)
                throw new ArgumentNullException("stream");

            var doc = XDocument.Load(stream);

            if (doc.Root.Name != ns + "song")
            {
                throw new SongFormatException("File is not a valid OpenLyrics song.");
            }

            //var openLyricsVersion = new Version(doc.Root.Attribute("version").Value);
            //bool versionPre08 = openLyricsVersion < new Version(0, 8);

            var prop = doc.Root.Element(ns + "properties");

            song.Title = prop.Element(ns + "titles").Elements(ns + "title").First().Value;
            var authors = prop.Elements(ns + "authors");
            song.Copyright = authors.Any() ? String.Join(", ", authors.Single().Elements(ns + "author").Select(e => e.Value)) : String.Empty;
            if (prop.Elements(ns + "publisher").Any())
            {
                var publisher = "Publisher: " + prop.Element(ns + "publisher").Value;
                song.Copyright = String.IsNullOrEmpty(song.Copyright) ? publisher : song.Copyright + "\n" + publisher;
            }

            if (prop.Elements(ns + "copyright").Any())
            {
                var copyright = prop.Element(ns + "copyright").Value;
                if (!copyright.StartsWith("©") && !copyright.StartsWith("(c)"))
                    copyright = "© " + copyright;

                song.Copyright = String.IsNullOrEmpty(song.Copyright) ? copyright : song.Copyright + "\n" + copyright;
            }

            song.CcliNumber = prop.Elements(ns + "ccliNo").Any() ? int.Parse(prop.Element(ns + "ccliNo").Value) : (int?)null;
            song.Category = prop.Elements(ns + "themes").Any() ? String.Join("; ", prop.Element(ns + "themes").Elements(ns + "theme").Select(e => e.Value)) : String.Empty;
            song.Comment = prop.Elements(ns + "comments").Any() ? String.Join("\n", prop.Element(ns + "comments").Elements(ns + "comment").Select(e => e.Value)) : String.Empty;

            if (prop.Elements(ns + "songbooks").Any())
            {
                int number;
                song.SetSources(prop.Element(ns + "songbooks").Elements(ns + "songbook").Select(e => new SongSource(song) {
                    Songbook = e.Attribute("name").Value,
                    Number = e.Attributes("entry").Any() ? (int.TryParse(e.Attribute("entry").Value, out number) ? number : (int?)null) : null
                }));
            }

            var mappings = new Dictionary<string, string>();

            foreach (var verse in doc.Root.Element(ns + "lyrics").Elements(ns + "verse"))
            {
                string originalName = verse.Attribute("name").Value;
                // add language key to part name (we don't know which one is the translation
                // and we can not automatically deal with more than 2 languages)
                string name = originalName + (verse.Attributes("lang").Any() ? " (" + verse.Attribute("lang").Value + ")" : String.Empty);

                if (!mappings.ContainsKey(originalName))
                {
                    // keep a mapping from original name to name with appended language to be used for the verse order
                    mappings.Add(originalName, name);
                }

                var slides = verse.Elements(ns + "lines").Select(lines =>
                {
                    StringBuilder str = new StringBuilder();
                    ParseLines(lines, str);
                    return new SongSlide(song) { Text = str.ToString() };
                });

                song.AddPart(new SongPart(song, name, slides));
            }

            if (prop.Elements(ns + "verseOrder").Any())
            {
                song.SetOrder(prop.Element(ns + "verseOrder").Value.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries).Select(n => mappings[n]));
            }
            else
            {
                // if we have no verseOrder element, use all verses from the mappings dictionary
                // (so multiple translations will appear only once)
                song.SetOrder(mappings.Values);
            }
        }
Esempio n. 3
0
        private void FinishPart(Song song, string key, List<LineGroup> lineGroups, LineGroup lastLineGroup)
        {
            if (lastLineGroup != null)
                lineGroups.Add(lastLineGroup);

            if (lineGroups.Count == 0)
                throw new SongFormatException("File is not a valid OpenSong song: Empty part");

            foreach (var lg in lineGroups)
            {
                if (lg.Lines.Count == 0)
                    lg.Lines.Add(new Line { Text = "" });
            }

            var noNumbers = !lineGroups[0].Lines[0].Number.HasValue;

            if (noNumbers && lineGroups.Any(lg => lg.Lines.Any(l => l.Number.HasValue)))
                throw new SongFormatException("File is not a valid OpenSong song: Found mixed numbered and unnumbered lines.");

            int maxVerseNumber;
            if (noNumbers)
            {
                maxVerseNumber = 1;
            }
            else
            {
                maxVerseNumber = lineGroups.Max(lg => lg.Lines.Max(l => l.Number.Value));
            }

            for (int i = 1; i <= maxVerseNumber; i++)
            {
                if (!noNumbers && !lineGroups.Any(lg => lg.Lines.Any(l => l.Number == i)))
                    continue;

                string name;
                if (noNumbers)
                    name = GetPartName(key);
                else
                    name = GetPartName(key + i.ToString());

                var part = new SongPart(song, name);
                var slide = new SongSlide(song);
                slide.Text = String.Join("\n", lineGroups.
                    Where(lg => lg.Lines.Any(l => noNumbers || l.Number == i)).
                    Select(lg => PrepareLine(lg.Lines.Where(l => noNumbers || l.Number == i).Single().Text, lg.Chords)));
                part.AddSlide(slide);

                // apply slide breaks
                int ind;
                while ((ind = slide.Text.IndexOf("||")) >= 0)
                {
                    slide.Text = slide.Text.Remove(ind, 2);
                    part.SplitSlide(slide, ind);
                }

                // apply line breaks
                foreach (var s in part.Slides)
                {
                    s.Text = s.Text.Replace("|", "\n");
                }

                song.AddPart(part);
            }
        }
        /// <summary>
        /// Reads the song data from a stream.
        /// </summary>
        /// <param name="song">The song.</param>
        /// <param name="stream">The stream.</param>
        public void Read(Song song, Stream stream)
        {
            if (song == null)
                throw new ArgumentNullException("song");

            if (stream == null)
                throw new ArgumentNullException("stream");

            using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.Default, true))
            {
                SongPart currentPart = null;
                string currentText = null;
                string currentTrans = null;

                string line;
                Dictionary<string, string> properties = new Dictionary<string, string>();
                int langcount = 1;
                int linenum = 0;

                while ((line = reader.ReadLine()) != null)
                {
                    if (currentPart == null)
                    {
                        line = line.Trim();
                        if (line.StartsWith("#"))
                        {
                            int i = line.IndexOf('=');
                            string key = line.Substring(1, i - 1).ToLower();
                            string value = line.Substring(i + 1);
                            properties.Add(key, value);
                        }
                        else if (line == "---")
                        {
                            PreProcessSongBeamerProperties(song, properties, out langcount); // langcount > 2 is not supported (text will be ignored)
                            currentPart = new SongPart(song, FindUnusedPartName(song));
                        }
                    }
                    else
                    {
                        if (line == "---")
                        {
                            currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans });
                            currentText = null;
                            song.AddPart(currentPart);
                            currentPart = new SongPart(song, FindUnusedPartName(song));
                            linenum = 0;
                        }
                        else if (line == "--" || line == "--A")
                        {
                            currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans });
                            currentText = "";
                            linenum = 0;
                        }
                        else
                        {
                            if (currentText == null) // at the beginning of a new part
                            {
                                string name;
                                if (IsSongBeamerPartName(line, out name))
                                {
                                    currentPart.Name = name;
                                    currentText = "";
                                    linenum = 0;
                                }
                                else
                                {
                                    currentText = line;
                                    linenum = 1;
                                }
                            }
                            else
                            {
                                if (linenum % langcount == 0) // add line to text
                                {
                                    if (linenum == 0)
                                        currentText = line;
                                    else
                                        currentText += "\n" + line;
                                }
                                else if (linenum % langcount == 1) // add line to translation
                                {
                                    if (linenum == 1)
                                        currentTrans = line;
                                    else
                                        currentTrans += "\n" + line;
                                }

                                linenum++;
                            }
                        }
                    }
                }

                currentPart.AddSlide(new SongSlide(song) { Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans });
                song.AddPart(currentPart);

                PostProcessSongBeamerProperties(song, properties);
            }
        }
        public override void Read(Song song, Stream stream)
        {
            if (song == null)
            {
                throw new ArgumentNullException("song");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                string        line;
                int           lineType       = 0;
                List <string> verseLineList  = null;
                string        verseType      = null;
                bool          checkFirstLine = false;
                string        copyright      = null;

                while ((line = reader.ReadLine()) != null)
                {
                    var cleanLine = line.Trim();
                    if (String.IsNullOrEmpty(cleanLine))
                    {
                        if (lineType == 0)
                        {
                            continue;
                        }
                        else if (verseLineList != null)                         // empty line and there were lyrics before -> create part
                        {
                            var part  = new SongPart(song, verseType);
                            var slide = new SongSlide(song);
                            slide.Text = String.Join("\n", verseLineList.ToArray());
                            part.AddSlide(slide);
                            song.AddPart(part);
                            song.AddPartToOrder(part);

                            verseLineList = null;
                        }
                    }
                    else                     // not an empty line
                    {
                        if (lineType == 0)   // very first line -> song title
                        {
                            song.Title = cleanLine;
                            lineType++;
                        }
                        else if (lineType == 1)                         // lyrics/parts
                        {
                            if (cleanLine.StartsWith("CCLI"))           // end of lyrics, start of copyright information
                            {
                                lineType++;
                                string num = cleanLine.Split(' ').Last();
                                song.CcliNumber = int.Parse(num);
                            }
                            else if (verseLineList == null)
                            {
                                verseType     = GetPartName(cleanLine, out checkFirstLine);
                                verseLineList = new List <string>();
                            }
                            else
                            {
                                if (checkFirstLine)
                                {
                                    if (!CheckFirstLine(cleanLine, ref verseType))
                                    {
                                        // add text if it was not a part name
                                        verseLineList.Add(line);
                                    }
                                    checkFirstLine = false;
                                }
                                else
                                {
                                    verseLineList.Add(line);
                                }
                            }
                        }
                        else if (lineType == 2)                         // copyright information
                        {
                            if (copyright == null)
                            {
                                copyright = cleanLine;
                            }
                            else
                            {
                                copyright += "\n" + cleanLine;
                            }
                        }
                    }
                }

                song.Copyright = copyright;
            }
        }
        // documentation taken from http://bazaar.launchpad.net/~openlp-core/openlp/trunk/view/head:/openlp/plugins/songs/lib/cclifileimport.py
        // [File]
        // USR file format first line
        // Type=
        // Indicates the file type
        // e.g. Type=SongSelect Import File
        // Version=3.0
        // File format version
        // [S A2672885]
        // Contains the CCLI Song number e.g. 2672885
        // Title=
        // Contains the song title (e.g. Title=Above All)
        // Author=
        // Contains a | delimited list of the song authors
        // e.g. Author=LeBlanc, Lenny | Baloche, Paul
        // Copyright=
        // Contains a | delimited list of the song copyrights
        // e.g. Copyright=1999 Integrity's Hosanna! Music |
        // LenSongs Publishing (Verwaltet von Gerth Medien
        // Musikverlag)
        // Admin=
        // Contains the song administrator
        // e.g. Admin=Gerth Medien Musikverlag
        // Themes=
        // Contains a /t delimited list of the song themes
        // e.g. Themes=Cross/tKingship/tMajesty/tRedeemer
        // Keys=
        // Contains the keys in which the music is played??
        // e.g. Keys=A
        // Fields=
        // Contains a list of the songs fields in order /t delimited
        // e.g. Fields=Vers 1/tVers 2/tChorus 1/tAndere 1
        // Words=
        // Contains the songs various lyrics in order as shown by the
        // Fields description
        // e.g. Words=Above all powers.... [/n = CR, /n/t = CRLF]
        public override void Read(Song song, Stream stream)
        {
            if (song == null)
                throw new ArgumentNullException("song");

            if (stream == null)
                throw new ArgumentNullException("stream");

            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                string line;
                string authors = null;
                string copyright = null;
                string[] fieldsList = null;
                string[] wordsList = null;

                while ((line = reader.ReadLine()) != null)
                {
                    if (line.StartsWith("[S "))
                    {
                        // CCLI Song number
                        int end = line.IndexOf(']');
                        if (end > 1)
                        {
                            string num = line.Substring(3, end - 3);
                            if (num.StartsWith("A"))
                                num = num.Substring(1);

                            song.CcliNumber = int.Parse(num);
                        }
                    }
                    else if (line.StartsWith("Title="))
                    {
                        song.Title = line.Substring("Title=".Length).Trim();
                    }
                    else if (line.StartsWith("Author="))
                    {
                        var authorList = line.Substring("Author=".Length).Trim().Split('|').Select(s => s.Trim()).ToArray();
                        authors = String.Join(", ", authorList);
                    }
                    else if (line.StartsWith("Copyright="))
                    {
                        copyright = line.Substring("Copyright=".Length).Trim();
                    }
                    else if (line.StartsWith("Themes="))
                    {
                        var themesList = line.Substring("Themes=".Length).Trim().Replace(" | ", "/t").
                            Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
                         song.Category = String.Join(", ", themesList);
                    }
                    else if (line.StartsWith("Fields="))
                    {
                        fieldsList = line.Substring("Fields=".Length).Trim().Split(new string[] {"/t"}, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
                    }
                    else if (line.StartsWith("Words="))
                    {
                        wordsList = line.Substring("Words=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
                    }

                    //	Unhandled usr keywords: Type, Version, Admin, Keys
                }

                if (fieldsList == null || wordsList == null || authors == null || copyright == null)
                {
                    throw new SongFormatException("Missing field in USR file.");
                }

                var partNum = (fieldsList.Length < wordsList.Length) ? fieldsList.Length : wordsList.Length;

                for (int i = 0; i < partNum; i++)
                {
                    bool checkFirstLine;
                    var partName = GetPartName(fieldsList[i], out checkFirstLine);

                    string text = wordsList[i].Replace("/n", "\n").Replace(" | ", "\n").TrimEnd();

                    if (checkFirstLine)
                    {
                        var lines = text.Split('\n');
                        var firstLine = lines[0].Trim();
                        if (CheckFirstLine(firstLine, ref partName))
                        {
                            text = text.Substring(text.IndexOf('\n') + 1);
                        }
                    }

                    var part = new SongPart(song, partName);
                    var slide = new SongSlide(song);
                    slide.Text = text;
                    part.AddSlide(slide);
                    song.AddPart(part);
                    song.AddPartToOrder(part);
                }

                song.Copyright = authors + "\n© " + copyright;
            }
        }
        /// <summary>
        /// Reads the song data from a stream.
        /// </summary>
        /// <param name="song">The song.</param>
        /// <param name="stream">The stream.</param>
        public void Read(Song song, Stream stream)
        {
            XDocument doc = XDocument.Load(stream);
            XElement root = doc.Element("ppl");
            song.Title = root.Element("general").Element("title").Value;

            var formatting = root.Element("formatting");

            var video = root.Element("formatting").Element("background").Attribute("video");
            if (video != null)
            {
                song.AddBackground(new SongBackground(video.Value, true), true);
            }
            else
            {
                foreach (var bg in root.Element("formatting").Element("background").Elements("file"))
                {
                    song.AddBackground(ReadBackground(bg.Value), true);
                }
            }

            song.Formatting = new SongFormatting
            {
                MainText = ReadTextFormatting(formatting.Element("font").Element("maintext")),
                TranslationText = ReadTextFormatting(formatting.Element("font").Element("translationtext")),
                SourceText = ReadTextFormatting(formatting.Element("font").Element("sourcetext")),
                CopyrightText = ReadTextFormatting(formatting.Element("font").Element("copyrighttext")),
                TextLineSpacing = int.Parse(formatting.Element("linespacing").Element("main").Value),
                TranslationLineSpacing = int.Parse(formatting.Element("linespacing").Element("translation").Value),
                SourceBorderRight = int.Parse(formatting.Element("borders").Element("sourceright").Value),
                SourceBorderTop = int.Parse(formatting.Element("borders").Element("sourcetop").Value),
                CopyrightBorderBottom = int.Parse(formatting.Element("borders").Element("copyrightbottom").Value),
                HorizontalOrientation = (HorizontalTextOrientation)Enum.Parse(typeof(HorizontalTextOrientation), formatting.Element("textorientation").Element("horizontal").Value, true),
                VerticalOrientation = (VerticalTextOrientation)Enum.Parse(typeof(VerticalTextOrientation), formatting.Element("textorientation").Element("vertical").Value, true),
                BorderBottom = int.Parse(formatting.Element("borders").Element("mainbottom").Value),
                BorderTop = int.Parse(formatting.Element("borders").Element("maintop").Value),
                BorderLeft = int.Parse(formatting.Element("borders").Element("mainleft").Value),
                BorderRight = int.Parse(formatting.Element("borders").Element("mainright").Value),
                IsOutlineEnabled = bool.Parse(formatting.Element("font").Element("outline").Element("enabled").Value),
                OutlineColor = ParseColor(formatting.Element("font").Element("outline").Element("color").Value),
                IsShadowEnabled = bool.Parse(formatting.Element("font").Element("shadow").Element("enabled").Value),
                ShadowColor = ParseColor(formatting.Element("font").Element("shadow").Element("color").Value),
                ShadowDirection = int.Parse(formatting.Element("font").Element("shadow").Element("direction").Value),
                TranslationPosition = formatting.Element("textorientation").Element("transpos") != null ?
                    (TranslationPosition)Enum.Parse(typeof(TranslationPosition), formatting.Element("textorientation").Element("transpos").Value, true) : TranslationPosition.Inline,
                CopyrightDisplayPosition = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("copyright").Element("position").Value, true),
                SourceDisplayPosition = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("source").Element("position").Value, true)
            };

            var general = root.Element("general");

            if (general.Element("category") != null)
                song.Category = general.Element("category").Value;

            if (general.Element("language") != null)
                song.Language = general.Element("language").Value;

            if (general.Element("translationlanguage") != null)
                song.TranslationLanguage = general.Element("translationlanguage").Value;

            if (general.Element("comment") != null)
                song.Comment = general.Element("comment").Value;
            else
                song.Comment = String.Empty;

            int ccli;
            if (general.Element("ccli") != null && int.TryParse(general.Element("ccli").Value, out ccli))
                song.CcliNumber = ccli;
            else
                song.CcliNumber = null;

            foreach (var part in root.Element("songtext").Elements("part"))
            {
                song.AddPart(new SongPart(song,
                                part.Attribute("caption").Value,
                                from slide in part.Elements("slide")
                                select new SongSlide(song)
                                {
                                    Text = String.Join("\n", slide.Elements("line").Select(line => line.Value).ToArray())/*.Trim()*/,
                                    Translation = String.Join("\n", slide.Elements("translation").Select(line => line.Value).ToArray())/*.Trim()*/,
                                    BackgroundIndex = slide.Attribute("backgroundnr") != null ? int.Parse(slide.Attribute("backgroundnr").Value) : 0,
                                    Size = slide.Attribute("mainsize") != null ? int.Parse(slide.Attribute("mainsize").Value) : song.Formatting.MainText.Size
                                }
                            ));
            }

            song.SetOrder(from item in root.Element("order").Elements("item") select item.Value);

            song.Copyright = String.Join("\n", root.Element("information").Element("copyright").Element("text").Elements("line").Select(line => line.Value).ToArray());

            song.SetSources(root.Element("information").Element("source").Element("text").Elements("line").Select(line => line.Value));
        }
Esempio n. 8
0
        /// <summary>
        /// Reads the song data from a stream.
        /// </summary>
        /// <param name="song">The song.</param>
        /// <param name="stream">The stream.</param>
        public void Read(Song song, Stream stream)
        {
            XDocument doc  = XDocument.Load(stream);
            XElement  root = doc.Element("ppl");

            song.Title = root.Element("general").Element("title").Value;

            var formatting = root.Element("formatting");

            var video = root.Element("formatting").Element("background").Attribute("video");

            if (video != null)
            {
                song.AddBackground(new SongBackground(video.Value, true), true);
            }
            else
            {
                foreach (var bg in root.Element("formatting").Element("background").Elements("file"))
                {
                    song.AddBackground(ReadBackground(bg.Value), true);
                }
            }

            song.Formatting = new SongFormatting
            {
                MainText               = ReadTextFormatting(formatting.Element("font").Element("maintext")),
                TranslationText        = ReadTextFormatting(formatting.Element("font").Element("translationtext")),
                SourceText             = ReadTextFormatting(formatting.Element("font").Element("sourcetext")),
                CopyrightText          = ReadTextFormatting(formatting.Element("font").Element("copyrighttext")),
                TextLineSpacing        = int.Parse(formatting.Element("linespacing").Element("main").Value),
                TranslationLineSpacing = int.Parse(formatting.Element("linespacing").Element("translation").Value),
                SourceBorderRight      = int.Parse(formatting.Element("borders").Element("sourceright").Value),
                SourceBorderTop        = int.Parse(formatting.Element("borders").Element("sourcetop").Value),
                CopyrightBorderBottom  = int.Parse(formatting.Element("borders").Element("copyrightbottom").Value),
                HorizontalOrientation  = (HorizontalTextOrientation)Enum.Parse(typeof(HorizontalTextOrientation), formatting.Element("textorientation").Element("horizontal").Value, true),
                VerticalOrientation    = (VerticalTextOrientation)Enum.Parse(typeof(VerticalTextOrientation), formatting.Element("textorientation").Element("vertical").Value, true),
                BorderBottom           = int.Parse(formatting.Element("borders").Element("mainbottom").Value),
                BorderTop              = int.Parse(formatting.Element("borders").Element("maintop").Value),
                BorderLeft             = int.Parse(formatting.Element("borders").Element("mainleft").Value),
                BorderRight            = int.Parse(formatting.Element("borders").Element("mainright").Value),
                IsOutlineEnabled       = bool.Parse(formatting.Element("font").Element("outline").Element("enabled").Value),
                OutlineColor           = ParseColor(formatting.Element("font").Element("outline").Element("color").Value),
                IsShadowEnabled        = bool.Parse(formatting.Element("font").Element("shadow").Element("enabled").Value),
                ShadowColor            = ParseColor(formatting.Element("font").Element("shadow").Element("color").Value),
                ShadowDirection        = int.Parse(formatting.Element("font").Element("shadow").Element("direction").Value),
                TranslationPosition    = formatting.Element("textorientation").Element("transpos") != null ?
                                         (TranslationPosition)Enum.Parse(typeof(TranslationPosition), formatting.Element("textorientation").Element("transpos").Value, true) : TranslationPosition.Inline,
                CopyrightDisplayPosition = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("copyright").Element("position").Value, true),
                SourceDisplayPosition    = (MetadataDisplayPosition)Enum.Parse(typeof(MetadataDisplayPosition), root.Element("information").Element("source").Element("position").Value, true)
            };

            var general = root.Element("general");

            if (general.Element("category") != null)
            {
                song.Category = general.Element("category").Value;
            }

            if (general.Element("language") != null)
            {
                song.Language = general.Element("language").Value;
            }

            if (general.Element("translationlanguage") != null)
            {
                song.TranslationLanguage = general.Element("translationlanguage").Value;
            }

            if (general.Element("comment") != null)
            {
                song.Comment = general.Element("comment").Value;
            }
            else
            {
                song.Comment = String.Empty;
            }

            int ccli;

            if (general.Element("ccli") != null && int.TryParse(general.Element("ccli").Value, out ccli))
            {
                song.CcliNumber = ccli;
            }
            else
            {
                song.CcliNumber = null;
            }

            foreach (var part in root.Element("songtext").Elements("part"))
            {
                song.AddPart(new SongPart(song,
                                          part.Attribute("caption").Value,
                                          from slide in part.Elements("slide")
                                          select new SongSlide(song)
                {
                    Text            = String.Join("\n", slide.Elements("line").Select(line => line.Value).ToArray()) /*.Trim()*/,
                    Translation     = String.Join("\n", slide.Elements("translation").Select(line => line.Value).ToArray()) /*.Trim()*/,
                    BackgroundIndex = slide.Attribute("backgroundnr") != null ? int.Parse(slide.Attribute("backgroundnr").Value) : 0,
                    Size            = slide.Attribute("mainsize") != null ? int.Parse(slide.Attribute("mainsize").Value) : song.Formatting.MainText.Size
                }
                                          ));
            }

            song.SetOrder(from item in root.Element("order").Elements("item") select item.Value);

            song.Copyright = String.Join("\n", root.Element("information").Element("copyright").Element("text").Elements("line").Select(line => line.Value).ToArray());

            song.SetSources(root.Element("information").Element("source").Element("text").Elements("line").Select(line => line.Value));
        }
    IEnumerator WaitAndPlay()
    {
        // TODO: Rename Song to SongDefinition and add Song as a new class.
        // Each SongDefinition describes how a song is played for ONE instrument only. The Song contains all the definitions.
        // Else, it is not possible to have different parts playing for the same instrument type. For example; There can be
        // multiple djembe's, krins or even multiple douns of the same type playing different parts.
        //var song = Soro.LoadSong();
        ISong song;

        if (_customNotationEnabled)
        {
            var instrumentType = InstrumentType.Dununba;
            var customNotation = Notation.Notation.Parse("Custom", _customNotation, BeatType.Unknown, instrumentType);
            song = new Song();
            song.AddPart(_customNotationRepeatCount > 0 ? _customNotationRepeatCount : 0, customNotation);
        }
        else
        {
            var songName = _songs.Keys.ToArray()[_selectedSongIndex];
            song = _songs[songName]();
        }

        var players = new Dictionary <InstrumentType, InstrumentPlayer[]>
        {
            { InstrumentType.Djembe, new[] { _djembePlayer1, _djembePlayer2 } },
            { InstrumentType.Kenkeni, new[] { _kenkeniPlayer } },
            { InstrumentType.Sangban, new[] { _sangbanPlayer } },
            { InstrumentType.Dununba, new[] { _dununbaPlayer } },
        };

        var noteIndex           = 0f;
        var songPartIndex       = 0;
        var songPartRepeatIndex = 0;
        var totalTime           = 0f;
        var totalNotesSong      = song.Parts.Sum(p => p.Notations.Max(n => n.TotalNotes));

        while (true)
        {
            var interval    = ((60000f / _bpm / song.NotesPerBeat) / 2f) / 1000f;
            var songPart    = song.Parts[songPartIndex];
            var notations   = songPart.Notations;
            var djembeIndex = 0;
            foreach (var notation in notations)
            {
                var player      = players[notation.InstrumentType];
                var playerIndex = notation.InstrumentType == InstrumentType.Djembe ? djembeIndex : 0;
                var index       = noteIndex % notation.TotalNotes;
                var note        = notation.NoteAt(index);
                if (note != null && player[playerIndex].enabled)
                {
                    foreach (var sound in note.Sounds)
                    {
                        player[playerIndex].PlaySound(sound);
                    }
                }

                if (notation.InstrumentType == InstrumentType.Djembe)
                {
                    djembeIndex++;
                }
            }

            if (noteIndex % song.NotesPerBeat == 0 && _metronomePlayer.enabled)
            {
                _metronomePlayer.PlaySound();
            }

            yield return(new WaitForSecondsRealtime(interval));

            totalTime += interval;

            if (noteIndex > songPart.TotalNotes - 1f)
            {
                noteIndex = 0f;

                if (songPartRepeatIndex >= songPart.RepeatCount)
                {
                    songPartIndex++;
                    songPartRepeatIndex = 0;
                }
                else
                {
                    songPartRepeatIndex++;
                }

                if (songPartIndex >= song.Parts.Length)
                {
                    StopCoroutine(_coroutine);
                    _coroutine = null;
                    break;
                }
            }
            else
            {
                noteIndex += .5f;
            }
        }
    }
Esempio n. 10
0
        // documentation taken from http://bazaar.launchpad.net/~openlp-core/openlp/trunk/view/head:/openlp/plugins/songs/lib/cclifileimport.py

        // [File]
        // USR file format first line

        // Type=
        // Indicates the file type
        // e.g. Type=SongSelect Import File

        // Version=3.0
        // File format version

        // [S A2672885]
        // Contains the CCLI Song number e.g. 2672885

        // Title=
        // Contains the song title (e.g. Title=Above All)

        // Author=
        // Contains a | delimited list of the song authors
        // e.g. Author=LeBlanc, Lenny | Baloche, Paul

        // Copyright=
        // Contains a | delimited list of the song copyrights
        // e.g. Copyright=1999 Integrity's Hosanna! Music |
        // LenSongs Publishing (Verwaltet von Gerth Medien
        // Musikverlag)

        // Admin=
        // Contains the song administrator
        // e.g. Admin=Gerth Medien Musikverlag

        // Themes=
        // Contains a /t delimited list of the song themes
        // e.g. Themes=Cross/tKingship/tMajesty/tRedeemer

        // Keys=
        // Contains the keys in which the music is played??
        // e.g. Keys=A

        // Fields=
        // Contains a list of the songs fields in order /t delimited
        // e.g. Fields=Vers 1/tVers 2/tChorus 1/tAndere 1

        // Words=
        // Contains the songs various lyrics in order as shown by the
        // Fields description
        // e.g. Words=Above all powers.... [/n = CR, /n/t = CRLF]

        public override void Read(Song song, Stream stream)
        {
            if (song == null)
            {
                throw new ArgumentNullException("song");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                string   line;
                string   authors    = null;
                string   copyright  = null;
                string[] fieldsList = null;
                string[] wordsList  = null;

                while ((line = reader.ReadLine()) != null)
                {
                    if (line.StartsWith("[S "))
                    {
                        // CCLI Song number
                        int end = line.IndexOf(']');
                        if (end > 1)
                        {
                            string num = line.Substring(3, end - 3);
                            if (num.StartsWith("A"))
                            {
                                num = num.Substring(1);
                            }

                            song.CcliNumber = int.Parse(num);
                        }
                    }
                    else if (line.StartsWith("Title="))
                    {
                        song.Title = line.Substring("Title=".Length).Trim();
                    }
                    else if (line.StartsWith("Author="))
                    {
                        var authorList = line.Substring("Author=".Length).Trim().Split('|').Select(s => s.Trim()).ToArray();
                        authors = String.Join(", ", authorList);
                    }
                    else if (line.StartsWith("Copyright="))
                    {
                        copyright = line.Substring("Copyright=".Length).Trim();
                    }
                    else if (line.StartsWith("Themes="))
                    {
                        var themesList = line.Substring("Themes=".Length).Trim().Replace(" | ", "/t").
                                         Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
                        song.Category = String.Join(", ", themesList);
                    }
                    else if (line.StartsWith("Fields="))
                    {
                        fieldsList = line.Substring("Fields=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
                    }
                    else if (line.StartsWith("Words="))
                    {
                        wordsList = line.Substring("Words=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
                    }

                    //	Unhandled usr keywords: Type, Version, Admin, Keys
                }

                if (fieldsList == null || wordsList == null || authors == null || copyright == null)
                {
                    throw new SongFormatException("Missing field in USR file.");
                }

                var partNum = (fieldsList.Length < wordsList.Length) ? fieldsList.Length : wordsList.Length;

                for (int i = 0; i < partNum; i++)
                {
                    bool checkFirstLine;
                    var  partName = GetPartName(fieldsList[i], out checkFirstLine);

                    string text = wordsList[i].Replace("/n", "\n").Replace(" | ", "\n").TrimEnd();

                    if (checkFirstLine)
                    {
                        var lines     = text.Split('\n');
                        var firstLine = lines[0].Trim();
                        if (CheckFirstLine(firstLine, ref partName))
                        {
                            text = text.Substring(text.IndexOf('\n') + 1);
                        }
                    }

                    var part  = new SongPart(song, partName);
                    var slide = new SongSlide(song);
                    slide.Text = text;
                    part.AddSlide(slide);
                    song.AddPart(part);
                    song.AddPartToOrder(part);
                }

                song.Copyright = authors + "\n© " + copyright;
            }
        }
Esempio n. 11
0
        public override void Read(Song song, Stream stream)
        {
            if (song == null)
                throw new ArgumentNullException("song");

            if (stream == null)
                throw new ArgumentNullException("stream");

            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                string line;
                int lineType = 0;
                List<string> verseLineList = null;
                string verseType = null;
                bool checkFirstLine = false;
                string copyright = null;

                while ((line = reader.ReadLine()) != null)
                {
                    var cleanLine = line.Trim();
                    if (String.IsNullOrEmpty(cleanLine))
                    {
                        if (lineType == 0)
                        {
                            continue;
                        }
                        else if (verseLineList != null) // empty line and there were lyrics before -> create part
                        {
                            var part = new SongPart(song, verseType);
                            var slide = new SongSlide(song);
                            slide.Text = String.Join("\n", verseLineList.ToArray());
                            part.AddSlide(slide);
                            song.AddPart(part);
                            song.AddPartToOrder(part);

                            verseLineList = null;
                        }
                    }
                    else // not an empty line
                    {
                        if (lineType == 0) // very first line -> song title
                        {
                            song.Title = cleanLine;
                            lineType++;
                        }
                        else if (lineType == 1) // lyrics/parts
                        {
                            if (cleanLine.StartsWith("CCLI")) // end of lyrics, start of copyright information
                            {
                                lineType++;
                                string num = cleanLine.Split(' ').Last();
                                song.CcliNumber = int.Parse(num);
                            }
                            else if (verseLineList == null)
                            {
                                verseType = GetPartName(cleanLine, out checkFirstLine);
                                verseLineList = new List<string>();
                            }
                            else
                            {
                                if (checkFirstLine)
                                {
                                    if (!CheckFirstLine(cleanLine, ref verseType))
                                    {
                                        // add text if it was not a part name
                                        verseLineList.Add(line);
                                    }
                                    checkFirstLine = false;
                                }
                                else
                                {
                                    verseLineList.Add(line);
                                }
                            }
                        }
                        else if (lineType == 2) // copyright information
                        {
                            if (copyright == null)
                            {
                                copyright = cleanLine;
                            }
                            else
                            {
                                copyright += "\n" + cleanLine;
                            }
                        }
                    }
                }

                song.Copyright = copyright;
            }
        }
        private void FinishPart(Song song, string key, List <LineGroup> lineGroups, LineGroup lastLineGroup)
        {
            if (lastLineGroup != null)
            {
                lineGroups.Add(lastLineGroup);
            }

            if (lineGroups.Count == 0)
            {
                throw new SongFormatException("File is not a valid OpenSong song: Empty part");
            }

            foreach (var lg in lineGroups)
            {
                if (lg.Lines.Count == 0)
                {
                    lg.Lines.Add(new Line {
                        Text = ""
                    });
                }
            }

            var noNumbers = !lineGroups[0].Lines[0].Number.HasValue;

            if (noNumbers && lineGroups.Any(lg => lg.Lines.Any(l => l.Number.HasValue)))
            {
                throw new SongFormatException("File is not a valid OpenSong song: Found mixed numbered and unnumbered lines.");
            }

            int maxVerseNumber;

            if (noNumbers)
            {
                maxVerseNumber = 1;
            }
            else
            {
                maxVerseNumber = lineGroups.Max(lg => lg.Lines.Max(l => l.Number.Value));
            }

            for (int i = 1; i <= maxVerseNumber; i++)
            {
                if (!noNumbers && !lineGroups.Any(lg => lg.Lines.Any(l => l.Number == i)))
                {
                    continue;
                }

                string name;
                if (noNumbers)
                {
                    name = GetPartName(key);
                }
                else
                {
                    name = GetPartName(key + i.ToString());
                }

                var part  = new SongPart(song, name);
                var slide = new SongSlide(song);
                slide.Text = String.Join("\n", lineGroups.
                                         Where(lg => lg.Lines.Any(l => noNumbers || l.Number == i)).
                                         Select(lg => PrepareLine(lg.Lines.Where(l => noNumbers || l.Number == i).Single().Text, lg.Chords)));
                part.AddSlide(slide);

                // apply slide breaks
                int ind;
                while ((ind = slide.Text.IndexOf("||")) >= 0)
                {
                    slide.Text = slide.Text.Remove(ind, 2);
                    part.SplitSlide(slide, ind);
                }

                // apply line breaks
                foreach (var s in part.Slides)
                {
                    s.Text = s.Text.Replace("|", "\n");
                }

                song.AddPart(part);
            }
        }
Esempio n. 13
0
        public void Read(Song song, Stream stream)
        {
            if (song == null)
            {
                throw new ArgumentNullException("song");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            var doc = XDocument.Load(stream);

            if (doc.Root.Name != ns + "song")
            {
                throw new SongFormatException("File is not a valid OpenLyrics song.");
            }

            //var openLyricsVersion = new Version(doc.Root.Attribute("version").Value);
            //bool versionPre08 = openLyricsVersion < new Version(0, 8);

            var prop = doc.Root.Element(ns + "properties");

            song.Title = prop.Element(ns + "titles").Elements(ns + "title").First().Value;
            var authors = prop.Elements(ns + "authors");

            song.Copyright = authors.Any() ? String.Join(", ", authors.Single().Elements(ns + "author").Select(e => e.Value)) : String.Empty;
            if (prop.Elements(ns + "publisher").Any())
            {
                var publisher = "Publisher: " + prop.Element(ns + "publisher").Value;
                song.Copyright = String.IsNullOrEmpty(song.Copyright) ? publisher : song.Copyright + "\n" + publisher;
            }

            if (prop.Elements(ns + "copyright").Any())
            {
                var copyright = prop.Element(ns + "copyright").Value;
                if (!copyright.StartsWith("©") && !copyright.StartsWith("(c)"))
                {
                    copyright = "© " + copyright;
                }

                song.Copyright = String.IsNullOrEmpty(song.Copyright) ? copyright : song.Copyright + "\n" + copyright;
            }

            song.CcliNumber = prop.Elements(ns + "ccliNo").Any() ? int.Parse(prop.Element(ns + "ccliNo").Value) : (int?)null;
            song.Category   = prop.Elements(ns + "themes").Any() ? String.Join("; ", prop.Element(ns + "themes").Elements(ns + "theme").Select(e => e.Value)) : String.Empty;
            song.Comment    = prop.Elements(ns + "comments").Any() ? String.Join("\n", prop.Element(ns + "comments").Elements(ns + "comment").Select(e => e.Value)) : String.Empty;

            if (prop.Elements(ns + "songbooks").Any())
            {
                int number;
                song.SetSources(prop.Element(ns + "songbooks").Elements(ns + "songbook").Select(e => new SongSource(song)
                {
                    Songbook = e.Attribute("name").Value,
                    Number   = e.Attributes("entry").Any() ? (int.TryParse(e.Attribute("entry").Value, out number) ? number : (int?)null) : null
                }));
            }

            var mappings = new Dictionary <string, string>();

            foreach (var verse in doc.Root.Element(ns + "lyrics").Elements(ns + "verse"))
            {
                string originalName = verse.Attribute("name").Value;
                // add language key to part name (we don't know which one is the translation
                // and we can not automatically deal with more than 2 languages)
                string name = originalName + (verse.Attributes("lang").Any() ? " (" + verse.Attribute("lang").Value + ")" : String.Empty);

                if (!mappings.ContainsKey(originalName))
                {
                    // keep a mapping from original name to name with appended language to be used for the verse order
                    mappings.Add(originalName, name);
                }

                var slides = verse.Elements(ns + "lines").Select(lines =>
                {
                    StringBuilder str = new StringBuilder();
                    ParseLines(lines, str);
                    return(new SongSlide(song)
                    {
                        Text = str.ToString()
                    });
                });

                song.AddPart(new SongPart(song, name, slides));
            }

            if (prop.Elements(ns + "verseOrder").Any())
            {
                song.SetOrder(prop.Element(ns + "verseOrder").Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => mappings[n]));
            }
            else
            {
                // if we have no verseOrder element, use all verses from the mappings dictionary
                // (so multiple translations will appear only once)
                song.SetOrder(mappings.Values);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Reads the song data from a stream.
        /// </summary>
        /// <param name="song">The song.</param>
        /// <param name="stream">The stream.</param>
        public void Read(Song song, Stream stream)
        {
            if (song == null)
            {
                throw new ArgumentNullException("song");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.Default, true))
            {
                SongPart currentPart  = null;
                string   currentText  = null;
                string   currentTrans = null;

                string line;
                Dictionary <string, string> properties = new Dictionary <string, string>();
                int langcount = 1;
                int linenum   = 0;

                while ((line = reader.ReadLine()) != null)
                {
                    if (currentPart == null)
                    {
                        line = line.Trim();
                        if (line.StartsWith("#"))
                        {
                            int    i     = line.IndexOf('=');
                            string key   = line.Substring(1, i - 1).ToLower();
                            string value = line.Substring(i + 1);
                            properties.Add(key, value);
                        }
                        else if (line == "---")
                        {
                            PreProcessSongBeamerProperties(song, properties, out langcount);                             // langcount > 2 is not supported (text will be ignored)
                            currentPart = new SongPart(song, FindUnusedPartName(song));
                        }
                    }
                    else
                    {
                        if (line == "---")
                        {
                            currentPart.AddSlide(new SongSlide(song)
                            {
                                Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans
                            });
                            currentText = null;
                            song.AddPart(currentPart);
                            currentPart = new SongPart(song, FindUnusedPartName(song));
                            linenum     = 0;
                        }
                        else if (line == "--" || line == "--A")
                        {
                            currentPart.AddSlide(new SongSlide(song)
                            {
                                Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans
                            });
                            currentText = "";
                            linenum     = 0;
                        }
                        else
                        {
                            if (currentText == null)                             // at the beginning of a new part
                            {
                                string name;
                                if (IsSongBeamerPartName(line, out name))
                                {
                                    currentPart.Name = name;
                                    currentText      = "";
                                    linenum          = 0;
                                }
                                else
                                {
                                    currentText = line;
                                    linenum     = 1;
                                }
                            }
                            else
                            {
                                if (linenum % langcount == 0)                                 // add line to text
                                {
                                    if (linenum == 0)
                                    {
                                        currentText = line;
                                    }
                                    else
                                    {
                                        currentText += "\n" + line;
                                    }
                                }
                                else if (linenum % langcount == 1)                                 // add line to translation
                                {
                                    if (linenum == 1)
                                    {
                                        currentTrans = line;
                                    }
                                    else
                                    {
                                        currentTrans += "\n" + line;
                                    }
                                }

                                linenum++;
                            }
                        }
                    }
                }

                currentPart.AddSlide(new SongSlide(song)
                {
                    Size = song.Formatting.MainText.Size, Text = currentText, Translation = currentTrans
                });
                song.AddPart(currentPart);

                PostProcessSongBeamerProperties(song, properties);
            }
        }
        public void Read(Song song, Stream stream)
        {
            if (song == null)
            {
                throw new ArgumentNullException("song");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            using (StreamReader reader = new StreamReader(stream, Encoding.Default, true))
            {
                string   line;
                bool     inTab           = false;
                SongPart chorusPart      = null;
                string   currentText     = null;
                string   nextPartName    = null;
                string   currentPartName = null;

                while ((line = reader.ReadLine()) != null)
                {
                    var trimmed = line.Trim();
                    if (trimmed.StartsWith("#"))
                    {
                        continue;                         // ignore comment line
                    }

                    if (trimmed.StartsWith("{") && trimmed.EndsWith("}"))
                    {
                        var tag = trimmed.Substring(1, trimmed.Length - 2);
                        if (tag.StartsWith("title:") || tag.StartsWith("t:"))
                        {
                            song.Title   = tag.Substring(tag.IndexOf(':') + 1);
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("subtitle:") || tag.StartsWith("st:"))
                        {
                            song.Copyright = tag.Substring(tag.IndexOf(':') + 1);
                            nextPartName   = null;
                            continue;
                        }
                        else if (tag.StartsWith("comment:") || tag.StartsWith("c:") ||
                                 tag.StartsWith("comment_italic:") || tag.StartsWith("ci:") ||
                                 tag.StartsWith("comment_box:") || tag.StartsWith("cb:"))
                        {
                            if (tag.EndsWith(":") && chorusPart == null)
                            {
                                // we found a comment that might be a part name and we're not in the chorus
                                // -> remember it for later use
                                var name = tag.Substring(tag.IndexOf(':') + 1);
                                nextPartName = name.Substring(0, name.Length - 1);
                            }
                            continue;
                        }
                        else if (tag.StartsWith("start_of_tab") || tag.StartsWith("sot"))
                        {
                            inTab        = true;
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("end_of_tab") || tag.StartsWith("eot"))
                        {
                            inTab        = false;
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("start_of_chorus") || tag.StartsWith("soc"))
                        {
                            var chorusName = "Chorus";
                            if (song.FindPartByName(chorusName) != null)
                            {
                                int i = 2;
                                while (song.FindPartByName(chorusName + " " + i.ToString()) != null)
                                {
                                    i++;
                                }
                                chorusName = chorusName + " " + i.ToString();
                            }

                            chorusPart   = new SongPart(song, chorusName);
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("end_of_chorus") || tag.StartsWith("eoc"))
                        {
                            if (chorusPart != null)
                            {
                                // commit slide and part
                                if (currentText != null)
                                {
                                    chorusPart.AddSlide(new SongSlide(song)
                                    {
                                        Text = currentText
                                    });
                                    currentText = null;
                                }

                                song.AddPart(chorusPart);
                                chorusPart = null;
                            }
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("define"))
                        {
                            // ignore
                            nextPartName = null;
                            continue;
                        }

                        // else accept {...} as normal text
                    }

                    if (!inTab)
                    {
                        if (trimmed == String.Empty)
                        {
                            nextPartName = null;

                            if (currentText != null)
                            {
                                if (chorusPart != null)                                 // in chorus
                                {
                                    // commit slide
                                    chorusPart.AddSlide(new SongSlide(song)
                                    {
                                        Text = currentText
                                    });
                                    currentText = null;
                                }
                                else
                                {
                                    // commit part
                                    var partName = currentPartName == null?FindUnusedPartName(song) : currentPartName;

                                    var part = new SongPart(song, partName);
                                    part.AddSlide(new SongSlide(song)
                                    {
                                        Text = currentText
                                    });
                                    song.AddPart(part);
                                    currentText = null;
                                }
                            }
                        }
                        else
                        {
                            // actual text/chord line -> add to current text
                            // need no further parsing because chords are already in correct format (square brackets)
                            if (currentText == null)
                            {
                                currentText = trimmed;

                                // use previously remembered part name for this part
                                currentPartName = nextPartName;
                                nextPartName    = null;
                            }
                            else
                            {
                                currentText += "\n" + trimmed;
                            }
                        }
                    }
                }

                // TODO: get rid of code duplication
                if (currentText != null)
                {
                    if (chorusPart != null)                     // in chorus
                    {
                        // commit slide and part
                        chorusPart.AddSlide(new SongSlide(song)
                        {
                            Text = currentText
                        });
                        currentText = null;
                        song.AddPart(chorusPart);
                    }
                    else
                    {
                        // commit part
                        var partName = currentPartName == null?FindUnusedPartName(song) : currentPartName;

                        var part = new SongPart(song, partName);
                        part.AddSlide(new SongSlide(song)
                        {
                            Text = currentText
                        });
                        song.AddPart(part);
                        currentText = null;
                    }
                }
            }

            // add each part to order
            foreach (SongPart part in song.Parts)
            {
                song.AddPartToOrder(part);
            }
        }
Esempio n. 16
0
        public void Read(Song song, Stream stream)
        {
            if (song == null)
                throw new ArgumentNullException("song");

            if (stream == null)
                throw new ArgumentNullException("stream");

            using (StreamReader reader = new StreamReader(stream, Encoding.Default, true))
            {
                string line;
                bool inTab = false;
                SongPart chorusPart = null;
                string currentText = null;
                string nextPartName = null;
                string currentPartName = null;

                while ((line = reader.ReadLine()) != null)
                {
                    var trimmed = line.Trim();
                    if (trimmed.StartsWith("#"))
                    {
                        continue; // ignore comment line
                    }

                    if (trimmed.StartsWith("{") && trimmed.EndsWith("}"))
                    {
                        var tag = trimmed.Substring(1, trimmed.Length - 2);
                        if (tag.StartsWith("title:") || tag.StartsWith("t:"))
                        {
                            song.Title = tag.Substring(tag.IndexOf(':') + 1);
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("subtitle:") || tag.StartsWith("st:"))
                        {
                            song.Copyright = tag.Substring(tag.IndexOf(':') + 1);
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("comment:") || tag.StartsWith("c:") ||
                            tag.StartsWith("comment_italic:") || tag.StartsWith("ci:") ||
                            tag.StartsWith("comment_box:") || tag.StartsWith("cb:"))
                        {
                            if (tag.EndsWith(":") && chorusPart == null)
                            {
                                // we found a comment that might be a part name and we're not in the chorus
                                // -> remember it for later use
                                var name = tag.Substring(tag.IndexOf(':') + 1);
                                nextPartName = name.Substring(0, name.Length - 1);
                            }
                            continue;
                        }
                        else if (tag.StartsWith("start_of_tab") || tag.StartsWith("sot"))
                        {
                            inTab = true;
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("end_of_tab") || tag.StartsWith("eot"))
                        {
                            inTab = false;
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("start_of_chorus") || tag.StartsWith("soc"))
                        {
                            var chorusName = "Chorus";
                            if (song.FindPartByName(chorusName) != null)
                            {
                                int i = 2;
                                while (song.FindPartByName(chorusName + " " + i.ToString()) != null)
                                {
                                    i++;
                                }
                                chorusName = chorusName + " " + i.ToString();
                            }

                            chorusPart = new SongPart(song, chorusName);
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("end_of_chorus") || tag.StartsWith("eoc"))
                        {
                            if (chorusPart != null)
                            {
                                // commit slide and part
                                if (currentText != null)
                                {
                                    chorusPart.AddSlide(new SongSlide(song) { Text = currentText });
                                    currentText = null;
                                }

                                song.AddPart(chorusPart);
                                chorusPart = null;
                            }
                            nextPartName = null;
                            continue;
                        }
                        else if (tag.StartsWith("define"))
                        {
                            // ignore
                            nextPartName = null;
                            continue;
                        }

                        // else accept {...} as normal text
                    }

                    if (!inTab)
                    {
                        if (trimmed == String.Empty)
                        {
                            nextPartName = null;

                            if (currentText != null)
                            {
                                if (chorusPart != null) // in chorus
                                {
                                    // commit slide
                                    chorusPart.AddSlide(new SongSlide(song) { Text = currentText });
                                    currentText = null;
                                }
                                else
                                {
                                    // commit part
                                    var partName = currentPartName == null ? FindUnusedPartName(song) : currentPartName;
                                    var part = new SongPart(song, partName);
                                    part.AddSlide(new SongSlide(song) { Text = currentText });
                                    song.AddPart(part);
                                    currentText = null;
                                }
                            }
                        }
                        else
                        {
                            // actual text/chord line -> add to current text
                            // need no further parsing because chords are already in correct format (square brackets)
                            if (currentText == null)
                            {
                                currentText = trimmed;

                                // use previously remembered part name for this part
                                currentPartName = nextPartName;
                                nextPartName = null;
                            }
                            else
                            {
                                currentText += "\n" + trimmed;
                            }
                        }
                    }
                }

                // TODO: get rid of code duplication
                if (currentText != null)
                {
                    if (chorusPart != null) // in chorus
                    {
                        // commit slide and part
                        chorusPart.AddSlide(new SongSlide(song) { Text = currentText });
                        currentText = null;
                        song.AddPart(chorusPart);
                    }
                    else
                    {
                        // commit part
                        var partName = currentPartName == null ? FindUnusedPartName(song) : currentPartName;
                        var part = new SongPart(song, partName);
                        part.AddSlide(new SongSlide(song) { Text = currentText });
                        song.AddPart(part);
                        currentText = null;
                    }
                }
            }

            // add each part to order
            foreach (SongPart part in song.Parts)
            {
                song.AddPartToOrder(part);
            }
        }