Files
QWERTYkez.OpenXmlProcessors/QWERTYkez.WordProcessor/Extension.cs
T

119 lines
4.2 KiB
C#
Raw Normal View History

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
}