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

98 lines
3.6 KiB
C#
Raw Normal View History

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-а, содержащего совпадение
2026-09-24 14:09:37 +07:00
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);
}
}