Добавьте файлы проекта.
This commit is contained in:
431
QWERTYkez.WordProcessor/Builders/ParagraphBuilderBase.cs
Normal file
431
QWERTYkez.WordProcessor/Builders/ParagraphBuilderBase.cs
Normal file
@@ -0,0 +1,431 @@
|
||||
namespace QWERTYkez.WordProcessor.Builders;
|
||||
|
||||
abstract class ParagraphBuilderBase : IParagraph, IFormula
|
||||
{
|
||||
public FontProps BaseFont { get; internal set; }
|
||||
|
||||
// Конструктор для установки базового шрифта
|
||||
protected ParagraphBuilderBase(FontProps? baseFont = null)
|
||||
{
|
||||
BaseFont = baseFont is not null && baseFont.SubSup.HasValue
|
||||
? baseFont with { SubSup = null }
|
||||
: baseFont ?? new FontProps();
|
||||
}
|
||||
|
||||
|
||||
internal FontProps GetEffectiveFont(FontProps? overrideFont) => overrideFont ?? BaseFont;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected Paragraph _paragraph = null!;
|
||||
protected List<Run> _runs = null!;
|
||||
|
||||
internal IParagraph ParagraphBuilder => CreateParagraphBuilder();
|
||||
protected virtual IParagraph CreateParagraphBuilder()
|
||||
{
|
||||
_paragraph = new Paragraph
|
||||
{
|
||||
ParagraphProperties = new ParagraphProperties(
|
||||
new Justification { Val = JustificationValues.Center },
|
||||
new SpacingBetweenLines
|
||||
{
|
||||
After = "0",
|
||||
Before = "0",
|
||||
LineRule = LineSpacingRuleValues.Auto
|
||||
},
|
||||
new Indentation
|
||||
{
|
||||
Left = "0",
|
||||
Right = "0",
|
||||
FirstLine = "0",
|
||||
Hanging = "0"
|
||||
}
|
||||
)
|
||||
};
|
||||
_runs = [];
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Paragraph IParagraph.Build()
|
||||
{
|
||||
foreach (var run in _runs)
|
||||
{
|
||||
_paragraph.AppendChild(run);
|
||||
}
|
||||
return _paragraph;
|
||||
}
|
||||
|
||||
// Настройка выравнивания
|
||||
public IParagraph SetAlignment(JustificationValues alignment)
|
||||
{
|
||||
var props = _paragraph.ParagraphProperties;
|
||||
props?.Justification = new Justification { Val = alignment };
|
||||
return this;
|
||||
}
|
||||
|
||||
// Добавление текста
|
||||
public IParagraph AddRun(string text, FontProps? font = null)
|
||||
{
|
||||
// Заменяем обычные пробелы на неразрывные для сохранения видимости
|
||||
string processedText = text.Replace(' ', '\u00A0');
|
||||
|
||||
var effectiveFont = GetEffectiveFont(font);
|
||||
Run run;
|
||||
|
||||
if (effectiveFont.TryExtract(out var elements))
|
||||
{
|
||||
run = new Run(new RunProperties(elements), new Text(processedText));
|
||||
}
|
||||
else
|
||||
{
|
||||
run = new Run(new Text(processedText));
|
||||
}
|
||||
|
||||
_runs.Add(run);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Добавление текста
|
||||
public IParagraph AddRunBreak(string text, FontProps? font = null)
|
||||
{
|
||||
// Заменяем обычные пробелы на неразрывные для сохранения видимости
|
||||
string processedText = text.Replace(' ', '\u00A0');
|
||||
|
||||
var effectiveFont = GetEffectiveFont(font);
|
||||
Run run;
|
||||
|
||||
if (effectiveFont.TryExtract(out var elements))
|
||||
{
|
||||
run = new Run(new RunProperties(elements), new Text(processedText));
|
||||
}
|
||||
else
|
||||
{
|
||||
run = new Run(new Text(processedText));
|
||||
}
|
||||
|
||||
_runs.Add(run);
|
||||
|
||||
_runs.Add(new Run(new Break()));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Добавление текста
|
||||
public IParagraph AddSupRun(string text, FontProps? font = null)
|
||||
{
|
||||
var effectiveFont = GetEffectiveFont(font);
|
||||
Run run;
|
||||
|
||||
if (effectiveFont.TrySupExtract(out var elements))
|
||||
{
|
||||
run = new Run(new RunProperties(elements), new Text(text));
|
||||
}
|
||||
else
|
||||
{
|
||||
run = new Run(new Text(text));
|
||||
}
|
||||
|
||||
_runs.Add(run);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Добавление текста
|
||||
public IParagraph AddSubRun(string text, FontProps? font = null)
|
||||
{
|
||||
var effectiveFont = GetEffectiveFont(font);
|
||||
Run run;
|
||||
|
||||
if (effectiveFont.TrySubExtract(out var elements))
|
||||
{
|
||||
run = new Run(new RunProperties(elements), new Text(text));
|
||||
}
|
||||
else
|
||||
{
|
||||
run = new Run(new Text(text));
|
||||
}
|
||||
|
||||
_runs.Add(run);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IParagraph AddRunWithCustomProps(string text, Action<RunProperties> configure)
|
||||
{
|
||||
var props = new RunProperties();
|
||||
configure(props);
|
||||
_runs.Add(new Run(props, new Text(text)));
|
||||
return this;
|
||||
}
|
||||
|
||||
// Добавление разрыва строки
|
||||
public IParagraph Break()
|
||||
{
|
||||
_runs.Add(new Run(new Break()));
|
||||
return this;
|
||||
}
|
||||
|
||||
// Добавление разрыва строки
|
||||
public IParagraph BreakPage()
|
||||
{
|
||||
_runs.Add(new Run(new Break() { Type = BreakValues.Page }));
|
||||
return this;
|
||||
}
|
||||
|
||||
// Метод AddFormula для IParagraphBuilder
|
||||
IParagraph IParagraph.AddFormula(Action<IFormula> configure)
|
||||
{
|
||||
var math = new OfficeMath();
|
||||
try
|
||||
{
|
||||
_mathContextStack.Push(math);
|
||||
configure(this);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mathContextStack.Pop();
|
||||
}
|
||||
|
||||
var run = new Run(); // без RunProperties
|
||||
run.AppendChild(math);
|
||||
_runs.Add(run);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Метод AddFormula для IParagraphBuilder
|
||||
IParagraph IParagraph.AddFormulaBreak(Action<IFormula> configure)
|
||||
{
|
||||
var math = new OfficeMath();
|
||||
try
|
||||
{
|
||||
_mathContextStack.Push(math);
|
||||
configure(this);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mathContextStack.Pop();
|
||||
}
|
||||
|
||||
var run = new Run(); // без RunProperties
|
||||
run.AppendChild(math);
|
||||
_runs.Add(run);
|
||||
_runs.Add(new Run(new Break()));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Стек для вложенных математических конструкций
|
||||
private readonly Stack<OpenXmlElement> _mathContextStack = new();
|
||||
bool TryGetCurrentMathContext(out OpenXmlElement element)
|
||||
{
|
||||
if (_mathContextStack.Count > 0)
|
||||
{
|
||||
element = _mathContextStack.Peek();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
element = null!;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Вспомогательные методы для стека (используются FormulaHelper)
|
||||
void IFormula.PushContext(OpenXmlElement element) => _mathContextStack.Push(element);
|
||||
void IFormula.PopContext() => _mathContextStack.Pop();
|
||||
|
||||
|
||||
// Реализация IFormulaBuilder
|
||||
public IFormula Text(string text)
|
||||
{
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
FormulaHelper.AddText(element, text, BaseFont);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Division
|
||||
public IFormula Division(string numerator, string denominator) =>
|
||||
Division(ToAction(numerator), ToAction(denominator));
|
||||
public IFormula Division(string numerator, Action<IFormula> denominator) =>
|
||||
Division(ToAction(numerator), denominator);
|
||||
public IFormula Division(Action<IFormula> numerator, string denominator) =>
|
||||
Division(numerator, ToAction(denominator));
|
||||
public IFormula Division(Action<IFormula> numerator, Action<IFormula> denominator)
|
||||
{
|
||||
var fraction = FormulaHelper.CreateFraction(numerator, denominator, this);
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
element.AppendChild(fraction);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Sup
|
||||
public IFormula Sup(string baseText, string supText) =>
|
||||
Sup(ToAction(baseText), ToAction(supText));
|
||||
public IFormula Sup(string baseText, Action<IFormula> supText) =>
|
||||
Sup(ToAction(baseText), supText);
|
||||
public IFormula Sup(Action<IFormula> baseText, string supText) =>
|
||||
Sup(baseText, ToAction(supText));
|
||||
public IFormula Sup(Action<IFormula> baseText, Action<IFormula> supText)
|
||||
{
|
||||
var superscript = FormulaHelper.CreateSuperscript(baseText, supText, this);
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
element.AppendChild(superscript);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Sub
|
||||
public IFormula Sub(string baseText, string subText) =>
|
||||
Sub(ToAction(baseText), ToAction(subText));
|
||||
public IFormula Sub(string baseText, Action<IFormula> subText) =>
|
||||
Sub(ToAction(baseText), subText);
|
||||
public IFormula Sub(Action<IFormula> baseText, string subText) =>
|
||||
Sub(baseText, ToAction(subText));
|
||||
public IFormula Sub(Action<IFormula> baseText, Action<IFormula> subText)
|
||||
{
|
||||
var subscript = FormulaHelper.CreateSubscript(baseText, subText, this);
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
element.AppendChild(subscript);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// SubSup
|
||||
public IFormula SubSup(string baseText, string subText, string supText) =>
|
||||
SubSup(ToAction(baseText), ToAction(subText), ToAction(supText));
|
||||
public IFormula SubSup(string baseText, string subText, Action<IFormula> supText) =>
|
||||
SubSup(ToAction(baseText), ToAction(subText), supText);
|
||||
public IFormula SubSup(string baseText, Action<IFormula> subText, string supText) =>
|
||||
SubSup(ToAction(baseText), subText, ToAction(supText));
|
||||
public IFormula SubSup(string baseText, Action<IFormula> subText, Action<IFormula> supText) =>
|
||||
SubSup(ToAction(baseText), subText, supText);
|
||||
public IFormula SubSup(Action<IFormula> baseText, string subText, string supText) =>
|
||||
SubSup(baseText, ToAction(subText), ToAction(supText));
|
||||
public IFormula SubSup(Action<IFormula> baseText, string subText, Action<IFormula> supText) =>
|
||||
SubSup(baseText, ToAction(subText), supText);
|
||||
public IFormula SubSup(Action<IFormula> baseText, Action<IFormula> subText, string supText) =>
|
||||
SubSup(baseText, subText, ToAction(supText));
|
||||
public IFormula SubSup(Action<IFormula> baseText, Action<IFormula> subText, Action<IFormula> supText)
|
||||
{
|
||||
var subSup = FormulaHelper.CreateSubSuperscript(baseText, subText, supText, this);
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
element.AppendChild(subSup);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Root
|
||||
public IFormula Root(string radicand) => Root(ToAction(radicand));
|
||||
public IFormula Root(Action<IFormula> radicand)
|
||||
{
|
||||
var radical = FormulaHelper.CreateRadical(radicand, null, this);
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
element.AppendChild(radical);
|
||||
return this;
|
||||
}
|
||||
public IFormula Root(string radicand, string degree) =>
|
||||
Root(ToAction(radicand), ToAction(degree));
|
||||
public IFormula Root(string radicand, Action<IFormula> degree) =>
|
||||
Root(ToAction(radicand), degree);
|
||||
public IFormula Root(Action<IFormula> radicand, string degree) =>
|
||||
Root(radicand, ToAction(degree));
|
||||
public IFormula Root(Action<IFormula> radicand, Action<IFormula> degree)
|
||||
{
|
||||
var radical = FormulaHelper.CreateRadical(radicand, degree, this);
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
element.AppendChild(radical);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private void AddIntegralCore(
|
||||
Action<IFormula> function,
|
||||
Action<IFormula> differential,
|
||||
Action<IFormula>? lowerLimit,
|
||||
Action<IFormula>? upperLimit)
|
||||
{
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
FormulaHelper.AddIntegral(element, function, differential, lowerLimit, upperLimit, this);
|
||||
}
|
||||
|
||||
public IFormula Integral(string function, string differential, string? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(ToAction(function), ToAction(differential), ToNullableAction(lowerLimit), ToNullableAction(upperLimit));
|
||||
public IFormula Integral(string function, string differential, string? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Integral(ToAction(function), ToAction(differential), ToNullableAction(lowerLimit), upperLimit);
|
||||
public IFormula Integral(string function, string differential, Action<IFormula>? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(ToAction(function), ToAction(differential), lowerLimit, ToNullableAction(upperLimit));
|
||||
public IFormula Integral(string function, string differential, Action<IFormula>? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Integral(ToAction(function), ToAction(differential), lowerLimit, upperLimit);
|
||||
public IFormula Integral(string function, Action<IFormula> differential, string? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(ToAction(function), differential, ToNullableAction(lowerLimit), ToNullableAction(upperLimit));
|
||||
public IFormula Integral(string function, Action<IFormula> differential, string? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Integral(ToAction(function), differential, ToNullableAction(lowerLimit), upperLimit);
|
||||
public IFormula Integral(string function, Action<IFormula> differential, Action<IFormula>? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(ToAction(function), differential, lowerLimit, ToNullableAction(upperLimit));
|
||||
public IFormula Integral(string function, Action<IFormula> differential, Action<IFormula>? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Integral(ToAction(function), differential, lowerLimit, upperLimit);
|
||||
public IFormula Integral(Action<IFormula> function, string differential, string? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(function, ToAction(differential), ToNullableAction(lowerLimit), ToNullableAction(upperLimit));
|
||||
public IFormula Integral(Action<IFormula> function, string differential, string? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Integral(function, ToAction(differential), ToNullableAction(lowerLimit), upperLimit);
|
||||
public IFormula Integral(Action<IFormula> function, string differential, Action<IFormula>? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(function, ToAction(differential), lowerLimit, ToNullableAction(upperLimit));
|
||||
public IFormula Integral(Action<IFormula> function, string differential, Action<IFormula>? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Integral(function, ToAction(differential), lowerLimit, upperLimit);
|
||||
public IFormula Integral(Action<IFormula> function, Action<IFormula> differential, string? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(function, differential, ToNullableAction(lowerLimit), ToNullableAction(upperLimit));
|
||||
public IFormula Integral(Action<IFormula> function, Action<IFormula> differential, string? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Integral(function, differential, ToNullableAction(lowerLimit), upperLimit);
|
||||
public IFormula Integral(Action<IFormula> function, Action<IFormula> differential, Action<IFormula>? lowerLimit = null, string? upperLimit = null) =>
|
||||
Integral(function, differential, lowerLimit, ToNullableAction(upperLimit));
|
||||
public IFormula Integral(Action<IFormula> function, Action<IFormula> differential, Action<IFormula>? lowerLimit = null, Action<IFormula>? upperLimit = null)
|
||||
{
|
||||
AddIntegralCore(function, differential, lowerLimit, upperLimit);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Sum
|
||||
private void AddSumCore(
|
||||
Action<IFormula> expression,
|
||||
Action<IFormula>? lowerLimit,
|
||||
Action<IFormula>? upperLimit)
|
||||
{
|
||||
if (TryGetCurrentMathContext(out var element))
|
||||
FormulaHelper.AddSum(element, expression, lowerLimit, upperLimit, this);
|
||||
}
|
||||
|
||||
public IFormula Sum(string expression, string? lowerLimit = null, string? upperLimit = null) =>
|
||||
Sum(ToAction(expression), ToNullableAction(lowerLimit), ToNullableAction(upperLimit));
|
||||
public IFormula Sum(string expression, string? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Sum(ToAction(expression), ToNullableAction(lowerLimit), upperLimit);
|
||||
public IFormula Sum(string expression, Action<IFormula>? lowerLimit = null, string? upperLimit = null) =>
|
||||
Sum(ToAction(expression), lowerLimit, ToNullableAction(upperLimit));
|
||||
public IFormula Sum(string expression, Action<IFormula>? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Sum(ToAction(expression), lowerLimit, upperLimit);
|
||||
public IFormula Sum(Action<IFormula> expression, string? lowerLimit = null, string? upperLimit = null) =>
|
||||
Sum(expression, ToNullableAction(lowerLimit), ToNullableAction(upperLimit));
|
||||
public IFormula Sum(Action<IFormula> expression, string? lowerLimit = null, Action<IFormula>? upperLimit = null) =>
|
||||
Sum(expression, ToNullableAction(lowerLimit), upperLimit);
|
||||
public IFormula Sum(Action<IFormula> expression, Action<IFormula>? lowerLimit = null, string? upperLimit = null) =>
|
||||
Sum(expression, lowerLimit, ToNullableAction(upperLimit));
|
||||
public IFormula Sum(Action<IFormula> expression, Action<IFormula>? lowerLimit = null, Action<IFormula>? upperLimit = null)
|
||||
{
|
||||
AddSumCore(expression, lowerLimit, upperLimit);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Вспомогательный метод для преобразования строки в делегат
|
||||
private static Action<IFormula>? ToNullableAction(string? text) => text is null ? null : (b => b.Text(text));
|
||||
private static Action<IFormula> ToAction(string text) => b => b.Text(text);
|
||||
}
|
||||
Reference in New Issue
Block a user