diff --git a/QWERTYkez.WordProcessor/MultiReplace.cs b/QWERTYkez.WordProcessor/MultiReplace.cs index abc3eb1..496fdd2 100644 --- a/QWERTYkez.WordProcessor/MultiReplace.cs +++ b/QWERTYkez.WordProcessor/MultiReplace.cs @@ -415,6 +415,17 @@ internal static class MultiReplaceExt { var body = original.Ancestors().FirstOrDefault(); + // Определяем, есть ли пустые параграфы перед original + bool hasEmptyParagraphsBefore = false; + var prevPara = original.PreviousSibling(); + while (prevPara is not null) + { + if (!string.IsNullOrEmpty(prevPara.InnerText)) + break; + hasEmptyParagraphsBefore = true; + prevPara = prevPara.PreviousSibling(); + } + // 1. Сбор определений var definitions = new List(); if (stringReplacements is not null) @@ -490,6 +501,7 @@ internal static class MultiReplaceExt bool firstSplitMarkerHandled = false; int textCount = 0; Paragraph? lastTextPara = null; + bool emptyParagraphCreated = false; // был ли создан пустой параграф для not set for (int i = 0; i < matches.Count; i++) { @@ -535,20 +547,31 @@ internal static class MultiReplaceExt firstSplitMarkerHandled = false; textCount = 0; lastTextPara = null; + emptyParagraphCreated = false; foreach (var item in values) { if (!string.IsNullOrEmpty(item.Text)) { - // Если есть отложенная ориентация — применяем её к этому тексту + // Если есть отложенная ориентация — применяем её if (pendingOrientation.HasValue) { var newPara = CloneParagraphWithoutSection(original); resultParas.Add(newPara); currentPara = newPara; - // Для маркера перед текстом всегда addPageSize = true - bool addPageSize = true; + // Определяем addPageSize: + // - если был создан пустой параграф для not set (emptyParagraphCreated == true), то первый текст получает addPageSize = true для landscape, false для portrait + // - иначе addPageSize = (pendingOrientation == BreakType.NewLandscapeSection) + bool addPageSize; + if (emptyParagraphCreated) + { + addPageSize = (pendingOrientation.Value == BreakType.NewLandscapeSection); + } + else + { + addPageSize = (pendingOrientation.Value == BreakType.NewLandscapeSection); + } AddSectionProperties(currentPara, pendingOrientation.Value, addPageSize, sourceSection, portraitSection); lastOrientation = pendingOrientation; sectionChangeInsideGroup = true; @@ -603,18 +626,35 @@ internal static class MultiReplaceExt } else if (breakType == BreakType.NewLandscapeSection || breakType == BreakType.NewPortraitSection) { - if (currentPara is null) + // Если это первый маркер в группе и перед original есть пустые параграфы, + // создаём пустой параграф с not set + if (currentPara is null && hasEmptyParagraphsBefore && !firstSplitMarkerHandled) { - // Маркер перед первым текстом — просто запоминаем - pendingOrientation = breakType; - // Не создаём пустой параграф - firstSplitMarkerHandled = true; // чтобы не обрабатывать как первый после текста + var newPara = CloneParagraphWithoutSection(original); + resultParas.Add(newPara); + currentPara = newPara; + // Добавляем секцию not set (без PageSize) + AddSectionProperties(currentPara, breakType, false, sourceSection, portraitSection); + lastOrientation = breakType; + sectionChangeInsideGroup = true; + firstSplitMarkerHandled = true; + emptyParagraphCreated = true; + pendingOrientation = null; + textCount = 0; + lastTextPara = null; } - else + else if (currentPara is null && !hasEmptyParagraphsBefore && !firstSplitMarkerHandled) + { + // Нет пустых параграфов, нет текущего параграфа — запоминаем ориентацию для первого текста + pendingOrientation = breakType; + firstSplitMarkerHandled = true; + // emptyParagraphCreated остаётся false + } + else if (currentPara is not null) { if (!firstSplitMarkerHandled) { - // Это первый маркер после текста — применяем к последнему текстовому параграфу + // Это первый маркер смены в группе (после текста) if (lastTextPara is not null) { if (lastTextPara.ParagraphProperties?.GetFirstChild() is null) @@ -625,23 +665,19 @@ internal static class MultiReplaceExt if (sourcePageSize is not null) { lastTextPara.ParagraphProperties.AppendChild(sourceSection.CloneNode(true)); - lastOrientation = breakType; - sectionChangeInsideGroup = true; } else { - // Если нет sourcePageSize, добавляем без PageSize (not set) AddSectionProperties(lastTextPara, breakType, false, sourceSection, portraitSection); - lastOrientation = breakType; - sectionChangeInsideGroup = true; } + lastOrientation = breakType; + sectionChangeInsideGroup = true; } firstSplitMarkerHandled = true; pendingOrientation = null; } else { - // Если нет lastTextPara, применяем к текущему AddSectionProperties(currentPara, breakType, false, sourceSection, portraitSection); lastOrientation = breakType; sectionChangeInsideGroup = true; @@ -684,7 +720,7 @@ internal static class MultiReplaceExt { var breakRun = new Run(new Break { Type = BreakValues.Page }); remainderPara.InsertAt(breakRun, 0); - bool addPageSize = true; // для остатка всегда с PageSize + bool addPageSize = (pendingOrientation.Value == BreakType.NewLandscapeSection); AddSectionProperties(remainderPara, pendingOrientation.Value, addPageSize, sourceSection, portraitSection); pendingOrientation = null; }