Files
QWERTYkez.OpenXmlProcessors/QWERTYkez.WordProcessor/DynamicReplaceToTableExt.cs
T
2026-09-24 14:09:37 +07:00

98 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace QWERTYkez.WordProcessor;
/// <summary>
/// Динамическая замена параграфа, содержащего "$key|param$", на таблицу.
/// Логика построения и подмены — 1:1 копия из <see cref="ReplaceToTableExt"/>,
/// плюс извлечение параметра.
/// </summary>
internal static class DynamicReplaceToTableExt
{
/// <summary>
/// Заменяет все параграфы, содержащие шаблон "$key|...$", на таблицы.
/// </summary>
/// <param name="buildTable">Делегат (param, tableBuilder) — параметр из "$key|param$" и билдер таблицы.</param>
internal static void ReplaceParagraphsContainingTextToTableDynamic(
Body body,
string oldValue,
Action<string, ITable> buildTable,
FontProps? baseFont = null)
{
if (body is null || string.IsNullOrEmpty(oldValue) || buildTable is null)
return;
DynamicReplaceExt.ParsePattern(oldValue, out var prefix, out var suffix);
var paragraphs = body.Elements<Paragraph>().ToList();
if (paragraphs.Count == 0)
return;
for (int i = paragraphs.Count - 1; i >= 0; i--)
{
var paragraph = paragraphs[i];
if (paragraph is null) continue;
var paraText = paragraph.InnerText;
if (string.IsNullOrEmpty(paraText)) continue;
int pStart = paraText.IndexOf(prefix, StringComparison.OrdinalIgnoreCase);
if (pStart < 0) continue;
int paramStart = pStart + prefix.Length;
int pEnd = string.IsNullOrEmpty(suffix)
? paraText.Length
: paraText.IndexOf(suffix, paramStart, StringComparison.OrdinalIgnoreCase);
if (pEnd < 0) continue;
string param = paraText.Substring(paramStart, pEnd - paramStart);
string matchedText = paraText.Substring(pStart, pEnd + suffix.Length - pStart);
// Извлекаем свойства шрифта из Run-а, содержащего совпадение
var fontProps = paragraph.ExtractFontProps(matchedText);
if (fontProps is { } props)
fontProps = props.Override(baseFont);
else if (baseFont is not null)
fontProps = baseFont;
ReplaceWithTableBuilderDynamic(paragraph, param, buildTable, fontProps);
}
}
/// <summary>
/// Создаёт TableBuilder, вызывает пользовательский делегат, заменяет параграф таблицей.
/// (Копия <see cref="ReplaceToTableExt.ReplaceWithTableBuilder"/> с добавленным param.)
/// </summary>
private static void ReplaceWithTableBuilderDynamic(
Paragraph paragraph,
string param,
Action<string, ITable> buildTable,
FontProps? baseFont)
{
if (paragraph is null || paragraph.Parent is null || buildTable is null)
return;
var parent = paragraph.Parent;
var builder = TableBuilder.Create(baseFont);
buildTable(param, builder);
var table = builder.Build();
int paraIndex = -1;
var children = parent.ChildElements;
for (int i = 0; i < children.Count; i++)
{
if (children[i] == paragraph)
{
paraIndex = i;
break;
}
}
if (paraIndex == -1)
return;
parent.RemoveChild(paragraph);
parent.InsertAt(table, paraIndex);
}
}