private LinterResult ValidateVerse(VMarker input)
        {
            if (string.IsNullOrWhiteSpace(input.VerseNumber))
            {
                return(new LinterResult(LinterLevel.Error, $"Verse number is missing", input.Position));
            }

            if (!ValidRegex.IsMatch(input.VerseNumber))
            {
                return(new LinterResult(LinterLevel.Error, $"Verse number is invalid", input.Position));
            }

            return(null);
        }
        public void TestIgnoredTags()
        {
            parser = new USFMToolsSharp.USFMParser(new List <string> {
                "bd", "bd*"
            });
            USFMDocument doc = parser.ParseFromString("\\v 1 In the beginning \\bd God \\bd*");

            Assert.AreEqual(1, doc.Contents.Count);
            VMarker vm = (VMarker)doc.Contents[0];

            Assert.AreEqual(1, vm.Contents.Count);
            TextBlock tb = (TextBlock)vm.Contents[0];

            Assert.AreEqual(0, tb.Contents.Count);
            Assert.AreEqual("In the beginning ", tb.Text);
        }
        /// <summary>
        /// Generate a list of Markers from a string
        /// </summary>
        /// <param name="input">USFM String to tokenize</param>
        /// <returns>A List of Markers based upon the string</returns>
        private List <Marker> TokenizeFromString(string input)
        {
            List <Marker> output         = new List <Marker>();
            bool          isInVMarkerNow = false;

            foreach (Match match in splitRegex.Matches(input))
            {
                if (IgnoredTags.Contains(match.Groups[1].Value))
                {
                    continue;
                }
                ConvertToMarkerResult result = ConvertToMarker(match.Groups[1].Value, match.Groups[2].Value);
                result.marker.Position = match.Index;
                output.Add(result.marker);

                //Conditions for the spaces between tags to be included as whitespace in a verse
                var  vMarker             = new VMarker();
                bool isAllowedByVMarker  = vMarker.AllowedContents.Contains(result.marker.GetType());
                bool doesNotAllowVMarker = !result.marker.AllowedContents.Contains(typeof(VMarker));
                if (result.marker is VMarker)
                {
                    isInVMarkerNow = true;
                }
                if (!isAllowedByVMarker && !(result.marker is VMarker))
                {
                    isInVMarkerNow = false;
                }

                //deciding when to include textblocks
                //whitespace textblocks is added to the list when the tag is a Allowed by VMarker, does not allow VMarker, and is current in a VMarker
                //this solves the problem of \v 1 \tl hello \tl* \tl hello \tl* appearing as hellohello instead of hello hello
                if (!string.IsNullOrWhiteSpace(result.remainingText) ||
                    (!string.IsNullOrEmpty(result.remainingText) && isAllowedByVMarker && doesNotAllowVMarker && isInVMarkerNow))
                {
                    output.Add(new TextBlock(result.remainingText));
                }
            }

            return(output);
        }
        public void TestChapterParse()
        {
            Assert.AreEqual(1, ((CMarker)parser.ParseFromString("\\c 1").Contents[0]).Number);
            Assert.AreEqual(1000, ((CMarker)parser.ParseFromString("\\c 1000").Contents[0]).Number);
            Assert.AreEqual(0, ((CMarker)parser.ParseFromString("\\c 0").Contents[0]).Number);

            // Chapter Labels
            Assert.AreEqual("Chapter One", ((CLMarker)parser.ParseFromString("\\c 1 \\cl Chapter One").Contents[0].Contents[0]).Label);
            Assert.AreEqual("Chapter One", ((CLMarker)parser.ParseFromString("\\cl Chapter One \\c 1").Contents[0]).Label);
            Assert.AreEqual("Chapter Two", ((CLMarker)parser.ParseFromString("\\c 1 \\cl Chapter One \\c 2 \\cl Chapter Two").Contents[1].Contents[0]).Label);

            USFMDocument doc = parser.ParseFromString("\\cp Q");

            Assert.IsInstanceOfType(doc.Contents[0], typeof(CPMarker));
            Assert.AreEqual("Q", ((CPMarker)doc.Contents[0]).PublishedChapterMarker);

            doc = parser.ParseFromString("\\ca 53 \\ca*");
            Assert.AreEqual(2, doc.Contents.Count);
            CAMarker    caBegin = (CAMarker)doc.Contents[0];
            CAEndMarker caEnd   = (CAEndMarker)doc.Contents[1];

            Assert.AreEqual("53", caBegin.AltChapterNumber);

            doc = parser.ParseFromString("\\va 22 \\va*");
            Assert.AreEqual(2, doc.Contents.Count);
            VAMarker    vaBegin = (VAMarker)doc.Contents[0];
            VAEndMarker vaEnd   = (VAEndMarker)doc.Contents[1];

            Assert.AreEqual("22", vaBegin.AltVerseNumber);

            doc = parser.ParseFromString("\\p In the beginning God created the heavens and the earth.");
            Assert.IsInstanceOfType(doc.Contents[0], typeof(PMarker));
            Assert.AreEqual("In the beginning God created the heavens and the earth.", ((TextBlock)doc.Contents[0].Contents[0]).Text);

            doc = parser.ParseFromString("\\pc In the beginning God created the heavens and the earth.");
            Assert.IsInstanceOfType(doc.Contents[0], typeof(PCMarker));
            Assert.AreEqual("In the beginning God created the heavens and the earth.", ((TextBlock)doc.Contents[0].Contents[0]).Text);

            doc = parser.ParseFromString("\\p \\v 1 In the beginning God created the heavens and the earth.");
            Assert.IsInstanceOfType(doc.Contents[0], typeof(PMarker));
            PMarker pm = (PMarker)doc.Contents[0];
            VMarker vm = (VMarker)pm.Contents[0];

            Assert.AreEqual("In the beginning God created the heavens and the earth.", ((TextBlock)vm.Contents[0]).Text);

            doc = parser.ParseFromString("\\mi");
            Assert.AreEqual(1, doc.Contents.Count);
            Assert.IsInstanceOfType(doc.Contents[0], typeof(MIMarker));

            doc = parser.ParseFromString("\\d A Psalm of David");
            Assert.AreEqual("A Psalm of David", ((DMarker)doc.Contents[0]).Description);

            doc = parser.ParseFromString("\\nb");
            Assert.IsInstanceOfType(doc.Contents[0], typeof(NBMarker));

            doc = parser.ParseFromString("\\fq the Son of God");
            Assert.IsInstanceOfType(doc.Contents[0], typeof(FQMarker));
            Assert.AreEqual("the Son of God", ((TextBlock)doc.Contents[0].Contents[0]).Text);

            doc = parser.ParseFromString("\\pi The one who scattered");
            Assert.IsInstanceOfType(doc.Contents[0], typeof(PIMarker));
            Assert.AreEqual(1, doc.Contents.Count);
            Assert.AreEqual("The one who scattered", ((TextBlock)doc.Contents[0].Contents[0]).Text);
            Assert.AreEqual(1, ((PIMarker)parser.ParseFromString("\\pi").Contents[0]).Depth);
            Assert.AreEqual(1, ((PIMarker)parser.ParseFromString("\\pi1").Contents[0]).Depth);
            Assert.AreEqual(2, ((PIMarker)parser.ParseFromString("\\pi2").Contents[0]).Depth);
            Assert.AreEqual(3, ((PIMarker)parser.ParseFromString("\\pi3").Contents[0]).Depth);

            doc = parser.ParseFromString("\\m \\v 37 David himself called him 'Lord';");
            Assert.AreEqual(1, doc.Contents.Count);
            MMarker mm = (MMarker)doc.Contents[0];

            Assert.AreEqual(1, mm.Contents.Count);
            vm = (VMarker)mm.Contents[0];
            Assert.AreEqual("David himself called him 'Lord';", ((TextBlock)vm.Contents[0]).Text);

            doc = parser.ParseFromString("\\b");
            Assert.AreEqual(1, doc.Contents.Count);
            Assert.IsInstanceOfType(doc.Contents[0], typeof(BMarker));
        }