[RT]
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user