Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9ef2a796e | ||
|
|
eccb12b83c | ||
|
|
804fc84563 | ||
|
|
282be475d5 |
File diff suppressed because it is too large
Load Diff
@@ -1,270 +0,0 @@
|
|||||||
namespace QWERTYkez.ExcelProcessor;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Внутренняя реализация <see cref="ICellText"/> для работы с богатым текстом ячейки.
|
|
||||||
/// Хранит коллекцию фрагментов <see cref="ExcelRun"/>.
|
|
||||||
/// Минимизирует аллокации, не использует рефлексию.
|
|
||||||
/// </summary>
|
|
||||||
internal sealed class ExcelCellText : ICellText
|
|
||||||
{
|
|
||||||
private List<IRun>? _runs;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public int Count => _runs?.Count ?? 0;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IEnumerable<IRun> GetRuns()
|
|
||||||
{
|
|
||||||
if (_runs is null)
|
|
||||||
return [];
|
|
||||||
// Возвращаем сам список, чтобы избежать копирования.
|
|
||||||
// Вызывающий не должен модифицировать коллекцию.
|
|
||||||
return _runs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IRun? GetRunAt(int index)
|
|
||||||
{
|
|
||||||
if (_runs is null || index < 0 || index >= _runs.Count)
|
|
||||||
return null;
|
|
||||||
return _runs[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryGetRunAt(int index, out IRun run)
|
|
||||||
{
|
|
||||||
run = GetRunAt(index)!;
|
|
||||||
return run != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IRun? First()
|
|
||||||
{
|
|
||||||
if (_runs is null || _runs.Count == 0)
|
|
||||||
return null;
|
|
||||||
return _runs[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryGetFirst(out IRun run)
|
|
||||||
{
|
|
||||||
run = First()!;
|
|
||||||
return run != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IRun? Last()
|
|
||||||
{
|
|
||||||
if (_runs is null || _runs.Count == 0)
|
|
||||||
return null;
|
|
||||||
return _runs[_runs.Count - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryGetLast(out IRun run)
|
|
||||||
{
|
|
||||||
run = Last()!;
|
|
||||||
return run != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryRemoveRun(IRun run)
|
|
||||||
{
|
|
||||||
if (run is null || _runs is null)
|
|
||||||
return false;
|
|
||||||
return _runs.Remove(run);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryRemoveRun(int index)
|
|
||||||
{
|
|
||||||
if (_runs is null || index < 0 || index >= _runs.Count)
|
|
||||||
return false;
|
|
||||||
_runs.RemoveAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryRemoveRun(int index, out IRun? removed)
|
|
||||||
{
|
|
||||||
removed = GetRunAt(index);
|
|
||||||
if (removed is null)
|
|
||||||
return false;
|
|
||||||
return TryRemoveRun(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICellText AddBreak()
|
|
||||||
{
|
|
||||||
// Добавляем символ переноса строки в последний существующий Run
|
|
||||||
if (_runs != null && _runs.Count > 0)
|
|
||||||
{
|
|
||||||
var lastRun = _runs[_runs.Count - 1];
|
|
||||||
lastRun.Text += "\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Если нет ни одного Run, создаём новый с символом переноса
|
|
||||||
AddRun("\n", null);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICellText AddRun(string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(text))
|
|
||||||
return this;
|
|
||||||
_runs ??= [];
|
|
||||||
var run = new ExcelRun { Text = text, Format = format };
|
|
||||||
_runs.Add(run);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICellText AddRunBreak(string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
AddRun(text, format);
|
|
||||||
AddBreak();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICellText AddSubRun(string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
var subFormat = format is { } fmt
|
|
||||||
? new RunFormat
|
|
||||||
{
|
|
||||||
IsBold = fmt.IsBold,
|
|
||||||
IsItalic = fmt.IsItalic,
|
|
||||||
Underline = fmt.Underline,
|
|
||||||
IsStrike = fmt.IsStrike,
|
|
||||||
Color = fmt.Color,
|
|
||||||
FontSize = fmt.FontSize,
|
|
||||||
FontFamily = fmt.FontFamily,
|
|
||||||
Vertical = VerticalTextRunAlignment.Subscript
|
|
||||||
}
|
|
||||||
: new RunFormat { Vertical = VerticalTextRunAlignment.Subscript };
|
|
||||||
return AddRun(text, subFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICellText AddSupRun(string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
var supFormat = format is { } fmt
|
|
||||||
? new RunFormat
|
|
||||||
{
|
|
||||||
IsBold = fmt.IsBold,
|
|
||||||
IsItalic = fmt.IsItalic,
|
|
||||||
Underline = fmt.Underline,
|
|
||||||
IsStrike = fmt.IsStrike,
|
|
||||||
Color = fmt.Color,
|
|
||||||
FontSize = fmt.FontSize,
|
|
||||||
FontFamily = fmt.FontFamily,
|
|
||||||
Vertical = VerticalTextRunAlignment.Subscript
|
|
||||||
}
|
|
||||||
: new RunFormat { Vertical = VerticalTextRunAlignment.Superscript };
|
|
||||||
return AddRun(text, supFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryInsertRun(int index, string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
if (index < 0 || string.IsNullOrEmpty(text))
|
|
||||||
return false;
|
|
||||||
_runs ??= [];
|
|
||||||
if (index > _runs.Count)
|
|
||||||
return false;
|
|
||||||
var run = new ExcelRun { Text = text, Format = format };
|
|
||||||
_runs.Insert(index, run);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryInsertRunBreak(int index, string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
if (!TryInsertRun(index, text, format))
|
|
||||||
return false;
|
|
||||||
// После вставленного run добавляем break на следующей позиции
|
|
||||||
AddBreak();
|
|
||||||
// Сдвигаем? Просто добавляем break в конец – неверно. Break должен быть сразу после вставленного.
|
|
||||||
// Но AddBreak добавляет в конец. Нужно вставить break на index+1.
|
|
||||||
return TryInsertRun(index + 1, "\n", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryInsertSubRun(int index, string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
var subFormat = format is { } fmt
|
|
||||||
? new RunFormat
|
|
||||||
{
|
|
||||||
IsBold = fmt.IsBold,
|
|
||||||
IsItalic = fmt.IsItalic,
|
|
||||||
Underline = fmt.Underline,
|
|
||||||
IsStrike = fmt.IsStrike,
|
|
||||||
Color = fmt.Color,
|
|
||||||
FontSize = fmt.FontSize,
|
|
||||||
FontFamily = fmt.FontFamily,
|
|
||||||
Vertical = VerticalTextRunAlignment.Subscript
|
|
||||||
}
|
|
||||||
: new RunFormat { Vertical = VerticalTextRunAlignment.Subscript };
|
|
||||||
return TryInsertRun(index, text, subFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool TryInsertSupRun(int index, string text, RunFormat? format = null)
|
|
||||||
{
|
|
||||||
var supFormat = format is { } fmt
|
|
||||||
? new RunFormat
|
|
||||||
{
|
|
||||||
IsBold = fmt.IsBold,
|
|
||||||
IsItalic = fmt.IsItalic,
|
|
||||||
Underline = fmt.Underline,
|
|
||||||
IsStrike = fmt.IsStrike,
|
|
||||||
Color = fmt.Color,
|
|
||||||
FontSize = fmt.FontSize,
|
|
||||||
FontFamily = fmt.FontFamily,
|
|
||||||
Vertical = VerticalTextRunAlignment.Subscript
|
|
||||||
}
|
|
||||||
: new RunFormat { Vertical = VerticalTextRunAlignment.Superscript };
|
|
||||||
return TryInsertRun(index, text, supFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void ApplyFormatToAllRuns(RunFormat format)
|
|
||||||
{
|
|
||||||
if (_runs is null || _runs.Count == 0)
|
|
||||||
return;
|
|
||||||
foreach (var run in _runs)
|
|
||||||
{
|
|
||||||
if (run is ExcelRun xRun)
|
|
||||||
{
|
|
||||||
// Объединение форматов: ненулевые свойства overlay заменяют значения в base.
|
|
||||||
var baseFmt = xRun.Format ?? new RunFormat();
|
|
||||||
xRun.Format = MergeRunFormat(baseFmt, format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
_runs?.Clear();
|
|
||||||
_runs = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static RunFormat MergeRunFormat(RunFormat baseFmt, RunFormat overlay)
|
|
||||||
{
|
|
||||||
return new RunFormat
|
|
||||||
{
|
|
||||||
IsBold = overlay.IsBold ?? baseFmt.IsBold,
|
|
||||||
IsItalic = overlay.IsItalic ?? baseFmt.IsItalic,
|
|
||||||
Underline = overlay.Underline ?? baseFmt.Underline,
|
|
||||||
IsStrike = overlay.IsStrike ?? baseFmt.IsStrike,
|
|
||||||
Color = overlay.Color ?? baseFmt.Color,
|
|
||||||
FontSize = overlay.FontSize ?? baseFmt.FontSize,
|
|
||||||
FontFamily = overlay.FontFamily ?? baseFmt.FontFamily,
|
|
||||||
Vertical = overlay.Vertical ?? baseFmt.Vertical
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -560,6 +560,69 @@ public interface IRange
|
|||||||
/// <summary>Представляет одну ячейку на листе.</summary>
|
/// <summary>Представляет одну ячейку на листе.</summary>
|
||||||
public interface ICell
|
public interface ICell
|
||||||
{
|
{
|
||||||
|
/// <summary>Количество фрагментов (Run) в тексте.</summary>
|
||||||
|
int RunsCount { get; }
|
||||||
|
|
||||||
|
/// <summary>Возвращает все фрагменты.</summary>
|
||||||
|
IEnumerable<IRun> GetRuns();
|
||||||
|
|
||||||
|
/// <summary>Возвращает фрагмент по индексу или null.</summary>
|
||||||
|
IRun? GetRunAt(int index);
|
||||||
|
|
||||||
|
/// <summary>Пытается получить фрагмент по индексу.</summary>
|
||||||
|
bool TryGetRunAt(int index, out IRun run);
|
||||||
|
|
||||||
|
/// <summary>Первый фрагмент или null.</summary>
|
||||||
|
IRun? First();
|
||||||
|
|
||||||
|
/// <summary>Пытается получить первый фрагмент.</summary>
|
||||||
|
bool TryGetFirst(out IRun run);
|
||||||
|
|
||||||
|
/// <summary>Последний фрагмент или null.</summary>
|
||||||
|
IRun? Last();
|
||||||
|
|
||||||
|
/// <summary>Пытается получить последний фрагмент.</summary>
|
||||||
|
bool TryGetLast(out IRun run);
|
||||||
|
|
||||||
|
/// <summary>Пытается удалить фрагмент.</summary>
|
||||||
|
bool TryRemoveRun(IRun run);
|
||||||
|
|
||||||
|
/// <summary>Удаляет фрагмент по индексу.</summary>
|
||||||
|
bool TryRemoveRun(int index);
|
||||||
|
|
||||||
|
/// <summary>Удаляет фрагмент по индексу и возвращает удалённый.</summary>
|
||||||
|
bool TryRemoveRun(int index, out IRun? removed);
|
||||||
|
|
||||||
|
/// <summary>Добавляет разрыв строки (перенос внутри ячейки).</summary>
|
||||||
|
ICell Break();
|
||||||
|
|
||||||
|
/// <summary>Добавляет обычный текстовый фрагмент.</summary>
|
||||||
|
ICell Run(string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Добавляет фрагмент с последующим разрывом строки.</summary>
|
||||||
|
ICell RunBreak(string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Добавляет подстрочный фрагмент (эквивалентно AddRun с Vertical = Subscript).</summary>
|
||||||
|
ICell Sub(string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Добавляет надстрочный фрагмент.</summary>
|
||||||
|
ICell Sup(string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Вставляет фрагмент по индексу.</summary>
|
||||||
|
bool TryInsertRun(int index, string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Вставляет фрагмент с последующим разрывом строки по индексу.</summary>
|
||||||
|
bool TryInsertRunBreak(int index, string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Вставляет подстрочный фрагмент по индексу.</summary>
|
||||||
|
bool TryInsertSub(int index, string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Вставляет надстрочный фрагмент по индексу.</summary>
|
||||||
|
bool TryInsertSup(int index, string text, RunFormat? format = null);
|
||||||
|
|
||||||
|
/// <summary>Применяет заданный формат ко всем существующим фрагментам (поверх их текущего форматирования, заменяя неуказанные свойства).</summary>
|
||||||
|
void ApplyFormatToAllRuns(RunFormat format);
|
||||||
|
|
||||||
/// <summary>Проверяет, входит ли ячейка в объединённый диапазон.</summary>
|
/// <summary>Проверяет, входит ли ячейка в объединённый диапазон.</summary>
|
||||||
bool IsMerged { get; }
|
bool IsMerged { get; }
|
||||||
|
|
||||||
@@ -699,15 +762,6 @@ public interface ICell
|
|||||||
/// <summary>Устанавливает шрифт ячейки.</summary>
|
/// <summary>Устанавливает шрифт ячейки.</summary>
|
||||||
ICell Set(CellFont format);
|
ICell Set(CellFont format);
|
||||||
|
|
||||||
/// <summary>Устанавливает богатый текст (форматированный) с помощью делегата.</summary>
|
|
||||||
ICell Text(Action<ICellText> value);
|
|
||||||
|
|
||||||
/// <summary>Возвращает объект для редактирования богатого текста ячейки (если ячейка содержит InlineString).</summary>
|
|
||||||
bool TryText(out ICellText cellText);
|
|
||||||
|
|
||||||
/// <summary>Возвращает объект для редактирования богатого текста ячейки (если ячейка содержит InlineString).</summary>
|
|
||||||
ICellText? Text();
|
|
||||||
|
|
||||||
/// <summary>Устанавливает простое текстовое значение (без форматирования).</summary>
|
/// <summary>Устанавливает простое текстовое значение (без форматирования).</summary>
|
||||||
ICell Set(string value);
|
ICell Set(string value);
|
||||||
|
|
||||||
@@ -742,76 +796,6 @@ public interface ICell
|
|||||||
void Clear();
|
void Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Представляет богатый текст внутри ячейки (несколько форматированных фрагментов).</summary>
|
|
||||||
public interface ICellText
|
|
||||||
{
|
|
||||||
/// <summary>Количество фрагментов (Run) в тексте.</summary>
|
|
||||||
int Count { get; }
|
|
||||||
|
|
||||||
/// <summary>Возвращает все фрагменты.</summary>
|
|
||||||
IEnumerable<IRun> GetRuns();
|
|
||||||
|
|
||||||
/// <summary>Возвращает фрагмент по индексу или null.</summary>
|
|
||||||
IRun? GetRunAt(int index);
|
|
||||||
|
|
||||||
/// <summary>Пытается получить фрагмент по индексу.</summary>
|
|
||||||
bool TryGetRunAt(int index, out IRun run);
|
|
||||||
|
|
||||||
/// <summary>Первый фрагмент или null.</summary>
|
|
||||||
IRun? First();
|
|
||||||
|
|
||||||
/// <summary>Пытается получить первый фрагмент.</summary>
|
|
||||||
bool TryGetFirst(out IRun run);
|
|
||||||
|
|
||||||
/// <summary>Последний фрагмент или null.</summary>
|
|
||||||
IRun? Last();
|
|
||||||
|
|
||||||
/// <summary>Пытается получить последний фрагмент.</summary>
|
|
||||||
bool TryGetLast(out IRun run);
|
|
||||||
|
|
||||||
/// <summary>Пытается удалить фрагмент.</summary>
|
|
||||||
bool TryRemoveRun(IRun run);
|
|
||||||
|
|
||||||
/// <summary>Удаляет фрагмент по индексу.</summary>
|
|
||||||
bool TryRemoveRun(int index);
|
|
||||||
|
|
||||||
/// <summary>Удаляет фрагмент по индексу и возвращает удалённый.</summary>
|
|
||||||
bool TryRemoveRun(int index, out IRun? removed);
|
|
||||||
|
|
||||||
/// <summary>Добавляет разрыв строки (перенос внутри ячейки).</summary>
|
|
||||||
ICellText AddBreak();
|
|
||||||
|
|
||||||
/// <summary>Добавляет обычный текстовый фрагмент.</summary>
|
|
||||||
ICellText AddRun(string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Добавляет фрагмент с последующим разрывом строки.</summary>
|
|
||||||
ICellText AddRunBreak(string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Добавляет подстрочный фрагмент (эквивалентно AddRun с Vertical = Subscript).</summary>
|
|
||||||
ICellText AddSubRun(string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Добавляет надстрочный фрагмент.</summary>
|
|
||||||
ICellText AddSupRun(string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Вставляет фрагмент по индексу.</summary>
|
|
||||||
bool TryInsertRun(int index, string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Вставляет фрагмент с последующим разрывом строки по индексу.</summary>
|
|
||||||
bool TryInsertRunBreak(int index, string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Вставляет подстрочный фрагмент по индексу.</summary>
|
|
||||||
bool TryInsertSubRun(int index, string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Вставляет надстрочный фрагмент по индексу.</summary>
|
|
||||||
bool TryInsertSupRun(int index, string text, RunFormat? format = null);
|
|
||||||
|
|
||||||
/// <summary>Применяет заданный формат ко всем существующим фрагментам (поверх их текущего форматирования, заменяя неуказанные свойства).</summary>
|
|
||||||
void ApplyFormatToAllRuns(RunFormat format);
|
|
||||||
|
|
||||||
/// <summary>Удаляет все фрагменты, очищая текст ячейки.</summary>
|
|
||||||
void Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Представляет один форматированный фрагмент текста внутри ячейки.</summary>
|
/// <summary>Представляет один форматированный фрагмент текста внутри ячейки.</summary>
|
||||||
public interface IRun
|
public interface IRun
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
using Base = DocumentFormat.OpenXml.Math.Base;
|
using MathBase = DocumentFormat.OpenXml.Math.Base;
|
||||||
using ControlProperties = DocumentFormat.OpenXml.Math.ControlProperties;
|
using MathControlProperties = DocumentFormat.OpenXml.Math.ControlProperties;
|
||||||
using Degree = DocumentFormat.OpenXml.Math.Degree;
|
using MathDegree = DocumentFormat.OpenXml.Math.Degree;
|
||||||
using Denominator = DocumentFormat.OpenXml.Math.Denominator;
|
using MathDenominator = DocumentFormat.OpenXml.Math.Denominator;
|
||||||
using Fraction = DocumentFormat.OpenXml.Math.Fraction;
|
using MathFraction = DocumentFormat.OpenXml.Math.Fraction;
|
||||||
using FractionProperties = DocumentFormat.OpenXml.Math.FractionProperties;
|
using MathFractionProperties = DocumentFormat.OpenXml.Math.FractionProperties;
|
||||||
using HideDegree = DocumentFormat.OpenXml.Math.HideDegree;
|
using MathHideDegree = DocumentFormat.OpenXml.Math.HideDegree;
|
||||||
using MathRun = DocumentFormat.OpenXml.Math.Run;
|
using MathRun = DocumentFormat.OpenXml.Math.Run;
|
||||||
using MathRunProperties = DocumentFormat.OpenXml.Math.RunProperties;
|
using MathRunProperties = DocumentFormat.OpenXml.Math.RunProperties;
|
||||||
using MathText = DocumentFormat.OpenXml.Math.Text;
|
using MathText = DocumentFormat.OpenXml.Math.Text;
|
||||||
using Numerator = DocumentFormat.OpenXml.Math.Numerator;
|
using MathNumerator = DocumentFormat.OpenXml.Math.Numerator;
|
||||||
using Radical = DocumentFormat.OpenXml.Math.Radical;
|
using MathRadical = DocumentFormat.OpenXml.Math.Radical;
|
||||||
using RadicalProperties = DocumentFormat.OpenXml.Math.RadicalProperties;
|
using MathRadicalProperties = DocumentFormat.OpenXml.Math.RadicalProperties;
|
||||||
using SubArgument = DocumentFormat.OpenXml.Math.SubArgument;
|
using MathSubArgument = DocumentFormat.OpenXml.Math.SubArgument;
|
||||||
using Subscript = DocumentFormat.OpenXml.Math.Subscript;
|
using MathSubscript = DocumentFormat.OpenXml.Math.Subscript;
|
||||||
using SubSuperscript = DocumentFormat.OpenXml.Math.SubSuperscript;
|
using MathSubSuperscript = DocumentFormat.OpenXml.Math.SubSuperscript;
|
||||||
using SuperArgument = DocumentFormat.OpenXml.Math.SuperArgument;
|
using MathSuperArgument = DocumentFormat.OpenXml.Math.SuperArgument;
|
||||||
using Superscript = DocumentFormat.OpenXml.Math.Superscript;
|
using MathSuperscript = DocumentFormat.OpenXml.Math.Superscript;
|
||||||
|
|
||||||
namespace QWERTYkez.WordProcessor;
|
namespace QWERTYkez.WordProcessor;
|
||||||
|
|
||||||
@@ -59,19 +59,19 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Fraction CreateFraction(
|
public static MathFraction CreateFraction(
|
||||||
Action<IFormula> numeratorBuilder,
|
Action<IFormula> numeratorBuilder,
|
||||||
Action<IFormula> denominatorBuilder,
|
Action<IFormula> denominatorBuilder,
|
||||||
IFormula builder)
|
IFormula builder)
|
||||||
{
|
{
|
||||||
var fraction = new Fraction();
|
var fraction = new MathFraction();
|
||||||
var font = builder.BaseFont;
|
var font = builder.BaseFont;
|
||||||
|
|
||||||
// Добавляем свойства дроби с форматированием (для черты дроби)
|
// Добавляем свойства дроби с форматированием (для черты дроби)
|
||||||
var fPr = new FractionProperties();
|
var fPr = new MathFractionProperties();
|
||||||
if (font.TryExtractWithoutFamily(out var wordElements))
|
if (font.TryExtractWithoutFamily(out var wordElements))
|
||||||
{
|
{
|
||||||
var ctrlPr = new ControlProperties();
|
var ctrlPr = new MathControlProperties();
|
||||||
var rPr = new RunProperties();
|
var rPr = new RunProperties();
|
||||||
foreach (var elem in wordElements)
|
foreach (var elem in wordElements)
|
||||||
rPr.AppendChild(elem.CloneNode(true));
|
rPr.AppendChild(elem.CloneNode(true));
|
||||||
@@ -82,14 +82,14 @@ internal static class FormulaHelper
|
|||||||
fraction.AppendChild(fPr);
|
fraction.AppendChild(fPr);
|
||||||
|
|
||||||
// Числитель
|
// Числитель
|
||||||
var numeratorElem = new Numerator();
|
var numeratorElem = new MathNumerator();
|
||||||
fraction.AppendChild(numeratorElem);
|
fraction.AppendChild(numeratorElem);
|
||||||
builder.PushContext(numeratorElem);
|
builder.PushContext(numeratorElem);
|
||||||
numeratorBuilder(builder);
|
numeratorBuilder(builder);
|
||||||
builder.PopContext();
|
builder.PopContext();
|
||||||
|
|
||||||
// Знаменатель
|
// Знаменатель
|
||||||
var denominatorElem = new Denominator();
|
var denominatorElem = new MathDenominator();
|
||||||
fraction.AppendChild(denominatorElem);
|
fraction.AppendChild(denominatorElem);
|
||||||
builder.PushContext(denominatorElem);
|
builder.PushContext(denominatorElem);
|
||||||
denominatorBuilder(builder);
|
denominatorBuilder(builder);
|
||||||
@@ -98,20 +98,20 @@ internal static class FormulaHelper
|
|||||||
return fraction;
|
return fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Radical CreateRadical(
|
public static MathRadical CreateRadical(
|
||||||
Action<IFormula> radicandBuilder,
|
Action<IFormula> radicandBuilder,
|
||||||
Action<IFormula>? degreeBuilder,
|
Action<IFormula>? degreeBuilder,
|
||||||
IFormula builder)
|
IFormula builder)
|
||||||
{
|
{
|
||||||
var radical = new Radical();
|
var radical = new MathRadical();
|
||||||
var font = builder.BaseFont;
|
var font = builder.BaseFont;
|
||||||
|
|
||||||
var radPr = new RadicalProperties();
|
var radPr = new MathRadicalProperties();
|
||||||
|
|
||||||
// Цвет, размер и подчёркивание для знака корня (ControlProperties)
|
// Цвет, размер и подчёркивание для знака корня (ControlProperties)
|
||||||
if (font is not null && font.TryExtractWithoutFamily(out var wordElements))
|
if (font is not null && font.TryExtractWithoutFamily(out var wordElements))
|
||||||
{
|
{
|
||||||
var ctrlPr = new ControlProperties();
|
var ctrlPr = new MathControlProperties();
|
||||||
var rPr = new RunProperties();
|
var rPr = new RunProperties();
|
||||||
foreach (var elem in wordElements)
|
foreach (var elem in wordElements)
|
||||||
rPr.AppendChild(elem.CloneNode(true));
|
rPr.AppendChild(elem.CloneNode(true));
|
||||||
@@ -123,7 +123,7 @@ internal static class FormulaHelper
|
|||||||
// Если степень не задана, скрываем её
|
// Если степень не задана, скрываем её
|
||||||
if (degreeBuilder is null)
|
if (degreeBuilder is null)
|
||||||
{
|
{
|
||||||
radPr.HideDegree = new HideDegree { Val = DocumentFormat.OpenXml.Math.BooleanValues.One };
|
radPr.HideDegree = new MathHideDegree { Val = DocumentFormat.OpenXml.Math.BooleanValues.One };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Добавляем свойства радикала (с цветом)
|
// Добавляем свойства радикала (с цветом)
|
||||||
@@ -132,7 +132,7 @@ internal static class FormulaHelper
|
|||||||
// Степень (если есть)
|
// Степень (если есть)
|
||||||
if (degreeBuilder is not null)
|
if (degreeBuilder is not null)
|
||||||
{
|
{
|
||||||
var degree = new Degree();
|
var degree = new MathDegree();
|
||||||
radical.AppendChild(degree);
|
radical.AppendChild(degree);
|
||||||
builder.PushContext(degree);
|
builder.PushContext(degree);
|
||||||
degreeBuilder(builder);
|
degreeBuilder(builder);
|
||||||
@@ -140,7 +140,7 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Подкоренное выражение
|
// Подкоренное выражение
|
||||||
var radicand = new Base();
|
var radicand = new MathBase();
|
||||||
radical.AppendChild(radicand);
|
radical.AppendChild(radicand);
|
||||||
builder.PushContext(radicand);
|
builder.PushContext(radicand);
|
||||||
radicandBuilder(builder);
|
radicandBuilder(builder);
|
||||||
@@ -179,10 +179,10 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var integralWithLimits = new SubSuperscript();
|
var integralWithLimits = new MathSubSuperscript();
|
||||||
currentContext.AppendChild(integralWithLimits);
|
currentContext.AppendChild(integralWithLimits);
|
||||||
|
|
||||||
var baseElem = new Base();
|
var baseElem = new MathBase();
|
||||||
var integralRun = CreateMathRun(font);
|
var integralRun = CreateMathRun(font);
|
||||||
integralRun.AppendChild(new MathText("∫"));
|
integralRun.AppendChild(new MathText("∫"));
|
||||||
baseElem.AppendChild(integralRun);
|
baseElem.AppendChild(integralRun);
|
||||||
@@ -190,7 +190,7 @@ internal static class FormulaHelper
|
|||||||
|
|
||||||
if (lowerLimitBuilder is not null)
|
if (lowerLimitBuilder is not null)
|
||||||
{
|
{
|
||||||
var subArg = new SubArgument();
|
var subArg = new MathSubArgument();
|
||||||
integralWithLimits.AppendChild(subArg);
|
integralWithLimits.AppendChild(subArg);
|
||||||
builder.PushContext(subArg);
|
builder.PushContext(subArg);
|
||||||
lowerLimitBuilder(builder);
|
lowerLimitBuilder(builder);
|
||||||
@@ -198,7 +198,7 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
if (upperLimitBuilder is not null)
|
if (upperLimitBuilder is not null)
|
||||||
{
|
{
|
||||||
var superArg = new SuperArgument();
|
var superArg = new MathSuperArgument();
|
||||||
integralWithLimits.AppendChild(superArg);
|
integralWithLimits.AppendChild(superArg);
|
||||||
builder.PushContext(superArg);
|
builder.PushContext(superArg);
|
||||||
upperLimitBuilder(builder);
|
upperLimitBuilder(builder);
|
||||||
@@ -242,10 +242,10 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var sumWithLimits = new SubSuperscript();
|
var sumWithLimits = new MathSubSuperscript();
|
||||||
currentContext.AppendChild(sumWithLimits);
|
currentContext.AppendChild(sumWithLimits);
|
||||||
|
|
||||||
var baseElem = new Base();
|
var baseElem = new MathBase();
|
||||||
var sumRun = CreateMathRun(font);
|
var sumRun = CreateMathRun(font);
|
||||||
sumRun.AppendChild(new MathText("∑"));
|
sumRun.AppendChild(new MathText("∑"));
|
||||||
baseElem.AppendChild(sumRun);
|
baseElem.AppendChild(sumRun);
|
||||||
@@ -253,7 +253,7 @@ internal static class FormulaHelper
|
|||||||
|
|
||||||
if (lowerLimitBuilder is not null)
|
if (lowerLimitBuilder is not null)
|
||||||
{
|
{
|
||||||
var subArg = new SubArgument();
|
var subArg = new MathSubArgument();
|
||||||
sumWithLimits.AppendChild(subArg);
|
sumWithLimits.AppendChild(subArg);
|
||||||
builder.PushContext(subArg);
|
builder.PushContext(subArg);
|
||||||
lowerLimitBuilder(builder);
|
lowerLimitBuilder(builder);
|
||||||
@@ -261,7 +261,7 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
if (upperLimitBuilder is not null)
|
if (upperLimitBuilder is not null)
|
||||||
{
|
{
|
||||||
var superArg = new SuperArgument();
|
var superArg = new MathSuperArgument();
|
||||||
sumWithLimits.AppendChild(superArg);
|
sumWithLimits.AppendChild(superArg);
|
||||||
builder.PushContext(superArg);
|
builder.PushContext(superArg);
|
||||||
upperLimitBuilder(builder);
|
upperLimitBuilder(builder);
|
||||||
@@ -278,22 +278,22 @@ internal static class FormulaHelper
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>Создаёт степень.</summary>
|
/// <summary>Создаёт степень.</summary>
|
||||||
public static Superscript CreateSuperscript(
|
public static MathSuperscript CreateSuperscript(
|
||||||
Action<IFormula> baseBuilder,
|
Action<IFormula> baseBuilder,
|
||||||
Action<IFormula> supBuilder,
|
Action<IFormula> supBuilder,
|
||||||
IFormula builder)
|
IFormula builder)
|
||||||
{
|
{
|
||||||
var superscript = new Superscript();
|
var superscript = new MathSuperscript();
|
||||||
|
|
||||||
// Основание
|
// Основание
|
||||||
var baseElem = new Base();
|
var baseElem = new MathBase();
|
||||||
superscript.AppendChild(baseElem);
|
superscript.AppendChild(baseElem);
|
||||||
builder.PushContext(baseElem);
|
builder.PushContext(baseElem);
|
||||||
baseBuilder(builder);
|
baseBuilder(builder);
|
||||||
builder.PopContext();
|
builder.PopContext();
|
||||||
|
|
||||||
// Показатель
|
// Показатель
|
||||||
var superArg = new SuperArgument();
|
var superArg = new MathSuperArgument();
|
||||||
superscript.AppendChild(superArg);
|
superscript.AppendChild(superArg);
|
||||||
builder.PushContext(superArg);
|
builder.PushContext(superArg);
|
||||||
supBuilder(builder);
|
supBuilder(builder);
|
||||||
@@ -303,20 +303,20 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Создаёт нижний индекс.</summary>
|
/// <summary>Создаёт нижний индекс.</summary>
|
||||||
public static Subscript CreateSubscript(
|
public static MathSubscript CreateSubscript(
|
||||||
Action<IFormula> baseBuilder,
|
Action<IFormula> baseBuilder,
|
||||||
Action<IFormula> subBuilder,
|
Action<IFormula> subBuilder,
|
||||||
IFormula builder)
|
IFormula builder)
|
||||||
{
|
{
|
||||||
var subscript = new Subscript();
|
var subscript = new MathSubscript();
|
||||||
|
|
||||||
var baseElem = new Base();
|
var baseElem = new MathBase();
|
||||||
subscript.AppendChild(baseElem);
|
subscript.AppendChild(baseElem);
|
||||||
builder.PushContext(baseElem);
|
builder.PushContext(baseElem);
|
||||||
baseBuilder(builder);
|
baseBuilder(builder);
|
||||||
builder.PopContext();
|
builder.PopContext();
|
||||||
|
|
||||||
var subArg = new SubArgument();
|
var subArg = new MathSubArgument();
|
||||||
subscript.AppendChild(subArg);
|
subscript.AppendChild(subArg);
|
||||||
builder.PushContext(subArg);
|
builder.PushContext(subArg);
|
||||||
subBuilder(builder);
|
subBuilder(builder);
|
||||||
@@ -326,27 +326,27 @@ internal static class FormulaHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Создаёт одновременные нижний и верхний индексы.</summary>
|
/// <summary>Создаёт одновременные нижний и верхний индексы.</summary>
|
||||||
public static SubSuperscript CreateSubSuperscript(
|
public static MathSubSuperscript CreateSubSuperscript(
|
||||||
Action<IFormula> baseBuilder,
|
Action<IFormula> baseBuilder,
|
||||||
Action<IFormula> subBuilder,
|
Action<IFormula> subBuilder,
|
||||||
Action<IFormula> supBuilder,
|
Action<IFormula> supBuilder,
|
||||||
IFormula builder)
|
IFormula builder)
|
||||||
{
|
{
|
||||||
var subSup = new SubSuperscript();
|
var subSup = new MathSubSuperscript();
|
||||||
|
|
||||||
var baseElem = new Base();
|
var baseElem = new MathBase();
|
||||||
subSup.AppendChild(baseElem);
|
subSup.AppendChild(baseElem);
|
||||||
builder.PushContext(baseElem);
|
builder.PushContext(baseElem);
|
||||||
baseBuilder(builder);
|
baseBuilder(builder);
|
||||||
builder.PopContext();
|
builder.PopContext();
|
||||||
|
|
||||||
var subArg = new SubArgument();
|
var subArg = new MathSubArgument();
|
||||||
subSup.AppendChild(subArg);
|
subSup.AppendChild(subArg);
|
||||||
builder.PushContext(subArg);
|
builder.PushContext(subArg);
|
||||||
subBuilder(builder);
|
subBuilder(builder);
|
||||||
builder.PopContext();
|
builder.PopContext();
|
||||||
|
|
||||||
var superArg = new SuperArgument();
|
var superArg = new MathSuperArgument();
|
||||||
subSup.AppendChild(superArg);
|
subSup.AppendChild(superArg);
|
||||||
builder.PushContext(superArg);
|
builder.PushContext(superArg);
|
||||||
supBuilder(builder);
|
supBuilder(builder);
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace QWERTYkez.WordProcessor;
|
using MathOfficeMath = DocumentFormat.OpenXml.Math.OfficeMath;
|
||||||
|
|
||||||
|
namespace QWERTYkez.WordProcessor;
|
||||||
|
|
||||||
abstract class ParagraphBuilderBase : IParagraph, IFormula
|
abstract class ParagraphBuilderBase : IParagraph, IFormula
|
||||||
{
|
{
|
||||||
@@ -176,7 +178,7 @@ abstract class ParagraphBuilderBase : IParagraph, IFormula
|
|||||||
// Метод AddFormula для IParagraphBuilder
|
// Метод AddFormula для IParagraphBuilder
|
||||||
IParagraph IParagraph.AddFormula(Action<IFormula> configure)
|
IParagraph IParagraph.AddFormula(Action<IFormula> configure)
|
||||||
{
|
{
|
||||||
var math = new OfficeMath();
|
var math = new MathOfficeMath();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_mathContextStack.Push(math);
|
_mathContextStack.Push(math);
|
||||||
@@ -196,7 +198,7 @@ abstract class ParagraphBuilderBase : IParagraph, IFormula
|
|||||||
// Метод AddFormula для IParagraphBuilder
|
// Метод AddFormula для IParagraphBuilder
|
||||||
IParagraph IParagraph.AddFormulaBreak(Action<IFormula> configure)
|
IParagraph IParagraph.AddFormulaBreak(Action<IFormula> configure)
|
||||||
{
|
{
|
||||||
var math = new OfficeMath();
|
var math = new MathOfficeMath();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_mathContextStack.Push(math);
|
_mathContextStack.Push(math);
|
||||||
|
|||||||
Reference in New Issue
Block a user