diff --git a/src/SIL.Machine/Corpora/UpdateUsfmParserHandler.cs b/src/SIL.Machine/Corpora/UpdateUsfmParserHandler.cs index 00c1f719..6236daaa 100644 --- a/src/SIL.Machine/Corpora/UpdateUsfmParserHandler.cs +++ b/src/SIL.Machine/Corpora/UpdateUsfmParserHandler.cs @@ -413,10 +413,16 @@ protected override void EndNonVerseText(UsfmParserState state, ScriptureRef scri protected override void EndEmbedText(UsfmParserState state, ScriptureRef scriptureRef) { + // If this embed is outside an update block, create an update block just for this embed + bool embedOutsideOfBlock = _updateBlocks.Count == 0; + if (embedOutsideOfBlock) + StartUpdateBlock(new[] { scriptureRef }); _updateBlocks .Peek() .AddEmbed(_embedTokens, markedForRemoval: _embedBehavior == UpdateUsfmMarkerBehavior.Strip); _embedTokens.Clear(); + if (embedOutsideOfBlock) + EndUpdateBlock(state, new[] { scriptureRef }); } public string GetUsfm(string stylesheetFileName = "usfm.sty") diff --git a/tests/SIL.Machine.Tests/Corpora/UpdateUsfmParserHandlerTests.cs b/tests/SIL.Machine.Tests/Corpora/UpdateUsfmParserHandlerTests.cs index 77c9f7cc..1ae20315 100644 --- a/tests/SIL.Machine.Tests/Corpora/UpdateUsfmParserHandlerTests.cs +++ b/tests/SIL.Machine.Tests/Corpora/UpdateUsfmParserHandlerTests.cs @@ -1408,6 +1408,91 @@ public void GetUsfm_PreferExisting_AddRemark() AssertUsfmEquals(target, result); } + [Test] + public void UpdateBlock_FootnoteInPublishedChapterNumber() + { + List rows = [new UpdateUsfmRow(ScrRef("ESG 1:0/2:s"), "Update 1")]; + string usfm = + @"\id ESG - Test +\c 1 +\cp A \f + \fr A.1-3: \ft Some note.\f* +\s Heading 1 +"; + var usfmUpdateBlockHandler = new TestUsfmUpdateBlockHandler(); + string target = UpdateUsfm( + rows, + usfm, + usfmUpdateBlockHandlers: [usfmUpdateBlockHandler], + textBehavior: UpdateUsfmTextBehavior.StripExisting, + paragraphBehavior: UpdateUsfmMarkerBehavior.Preserve, + embedBehavior: UpdateUsfmMarkerBehavior.Preserve, + styleBehavior: UpdateUsfmMarkerBehavior.Preserve + ); + + string result = + @"\id ESG +\c 1 +\cp A \f + \fr A.1-3: \ft Some note.\f* +\s Update 1 +"; + AssertUsfmEquals(target, result); + + Assert.That(usfmUpdateBlockHandler.Blocks.Count, Is.EqualTo(2)); + AssertUpdateBlockEquals( + usfmUpdateBlockHandler.Blocks[0], + ["ESG 1:0/1:f"], + (UsfmUpdateBlockElementType.Embed, @"\f + \fr A.1-3: \ft Some note.\f*", false) + ); + AssertUpdateBlockEquals( + usfmUpdateBlockHandler.Blocks[1], + ["ESG 1:0/2:s"], + (UsfmUpdateBlockElementType.Text, "Update 1 ", false), + (UsfmUpdateBlockElementType.Text, "Heading 1 ", true) + ); + } + + [Test] + public void UpdateBlock_FootnoteAtStartOfChapterWithPrecedingText() + { + List rows = [new UpdateUsfmRow(ScrRef("ESG 1:0/2:s"), "Update 1")]; + string usfm = + @"\id ESG - Test +\c 1 +Text 1\f + \fr A.1-3: \ft Some note.\f* +\s Heading 1 +"; + var usfmUpdateBlockHandler = new TestUsfmUpdateBlockHandler(); + string target = UpdateUsfm( + rows, + usfm, + usfmUpdateBlockHandlers: [usfmUpdateBlockHandler], + textBehavior: UpdateUsfmTextBehavior.PreferNew, + paragraphBehavior: UpdateUsfmMarkerBehavior.Preserve, + embedBehavior: UpdateUsfmMarkerBehavior.Preserve, + styleBehavior: UpdateUsfmMarkerBehavior.Preserve + ); + + string result = + @"\id ESG - Test +\c 1 Text 1\f + \fr A.1-3: \ft Some note.\f* +\s Update 1 +"; + AssertUsfmEquals(target, result); + + Assert.That(usfmUpdateBlockHandler.Blocks.Count, Is.EqualTo(2)); + AssertUpdateBlockEquals( + usfmUpdateBlockHandler.Blocks[0], + ["ESG 1:0/1:f"], + (UsfmUpdateBlockElementType.Embed, @"\f + \fr A.1-3: \ft Some note.\f*", false) + ); + AssertUpdateBlockEquals( + usfmUpdateBlockHandler.Blocks[1], + ["ESG 1:0/2:s"], + (UsfmUpdateBlockElementType.Text, "Update 1 ", false), + (UsfmUpdateBlockElementType.Text, "Heading 1 ", true) + ); + } + private static ScriptureRef[] ScrRef(params string[] refs) { return refs.Select(r => ScriptureRef.Parse(r)).ToArray();