2026-08-03 16:11:54 +07:00
|
|
|
namespace QWERTYkez.WordProcessor;
|
|
|
|
|
|
|
|
|
|
internal static class Extension
|
|
|
|
|
{
|
|
|
|
|
public static void SwapBottomRight(this PageMargin margin)
|
|
|
|
|
{
|
|
|
|
|
if (margin.Right is { } r)
|
|
|
|
|
{
|
|
|
|
|
margin.Right = margin.Bottom is not null ? new((uint)margin.Bottom.Value) : null;
|
|
|
|
|
margin.Bottom = new((int)r.Value);
|
|
|
|
|
}
|
|
|
|
|
else if(margin.Bottom is { } b)
|
|
|
|
|
{
|
|
|
|
|
margin.Bottom = null;
|
|
|
|
|
margin.Right = new((uint)b.Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public static void SwapValues(this PageSize size)
|
|
|
|
|
{
|
|
|
|
|
if (size.Width is { } w)
|
|
|
|
|
{
|
|
|
|
|
size.Width = size.Height is not null ? new(size.Height.Value) : null;
|
|
|
|
|
size.Height = new(w.Value);
|
|
|
|
|
}
|
|
|
|
|
else if (size.Height is { } h)
|
|
|
|
|
{
|
|
|
|
|
size.Height = null;
|
|
|
|
|
size.Width = new(h.Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-09-07 15:52:23 +07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Возвращает индекс указанного элемента в коллекции.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="list">Коллекция элементов.</param>
|
|
|
|
|
/// <param name="element">Элемент для поиска.</param>
|
|
|
|
|
/// <returns>Индекс элемента, или -1, если элемент не найден.</returns>
|
|
|
|
|
public static int IndexOf(this OpenXmlElementList list, OpenXmlElement element)
|
|
|
|
|
{
|
|
|
|
|
if (list == null || element == null)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < list.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (list[i] == element)
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2026-09-24 14:09:37 +07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Извлекает свойства шрифта (FontProps) из Run, содержащего указанный текст в параграфе.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static FontProps? ExtractFontProps(this Paragraph paragraph, string searchText)
|
|
|
|
|
{
|
|
|
|
|
if (paragraph is null || string.IsNullOrEmpty(searchText))
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var runs = paragraph.Descendants<Run>().ToList();
|
|
|
|
|
if (runs.Count == 0)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
// Собираем полный текст параграфа и позиции каждого Run для анализа
|
|
|
|
|
var runInfos = new List<(Run Run, int Start, int End, string Text)>();
|
|
|
|
|
int currentPosition = 0;
|
|
|
|
|
|
|
|
|
|
foreach (var run in runs)
|
|
|
|
|
{
|
|
|
|
|
var runText = GetRunText(run);
|
|
|
|
|
if (!string.IsNullOrEmpty(runText))
|
|
|
|
|
{
|
|
|
|
|
runInfos.Add((run, currentPosition, currentPosition + runText.Length, runText));
|
|
|
|
|
currentPosition += runText.Length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ищем Run, который содержит искомый текст (регистронезависимо)
|
|
|
|
|
foreach (var (run, start, end, text) in runInfos)
|
|
|
|
|
{
|
|
|
|
|
// Проверяем, содержится ли искомый текст в этом Run
|
|
|
|
|
if (text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0)
|
|
|
|
|
return FontPropsExtractor.CreateFontPropsFromRun(run, paragraph);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Если точное вхождение не найдено, ищем пересечение текста
|
|
|
|
|
var fullText = string.Concat(runInfos.Select(r => r.Text));
|
|
|
|
|
int textIndex = fullText.IndexOf(searchText, StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
if (textIndex >= 0)
|
|
|
|
|
{
|
|
|
|
|
// Находим первый Run, который пересекается с найденным текстом
|
|
|
|
|
var intersectingRun = runInfos.FirstOrDefault(r =>
|
|
|
|
|
r.Start <= textIndex && r.End > textIndex);
|
|
|
|
|
|
|
|
|
|
if (intersectingRun.Run is not null)
|
|
|
|
|
return FontPropsExtractor.CreateFontPropsFromRun(intersectingRun.Run, paragraph);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null; // Не удалось найти подходящий Run
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Вспомогательный метод для получения текста из Run.
|
|
|
|
|
/// </summary>
|
|
|
|
|
static string GetRunText(Run run)
|
|
|
|
|
{
|
|
|
|
|
if (run is null) return string.Empty;
|
|
|
|
|
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
foreach (var text in run.Elements<Text>())
|
|
|
|
|
{
|
|
|
|
|
sb.Append(text.Text ?? string.Empty);
|
|
|
|
|
}
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
2026-08-03 16:11:54 +07:00
|
|
|
}
|