This commit is contained in:
melekhin
2026-09-24 14:09:37 +07:00
parent ebec7f724c
commit fab3528e57
7 changed files with 357 additions and 280 deletions
+68
View File
@@ -48,4 +48,72 @@ internal static class Extension
}
return -1;
}
/// <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();
}
}