This commit is contained in:
melekhin
2026-08-10 14:59:18 +07:00
parent 2811a40c6d
commit b023d2755e
+53 -17
View File
@@ -415,6 +415,17 @@ internal static class MultiReplaceExt
{
var body = original.Ancestors<Body>().FirstOrDefault();
// Определяем, есть ли пустые параграфы перед original
bool hasEmptyParagraphsBefore = false;
var prevPara = original.PreviousSibling<Paragraph>();
while (prevPara is not null)
{
if (!string.IsNullOrEmpty(prevPara.InnerText))
break;
hasEmptyParagraphsBefore = true;
prevPara = prevPara.PreviousSibling<Paragraph>();
}
// 1. Сбор определений
var definitions = new List<MatchDefinition>();
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<SectionProperties>() 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;
}