Skip to content

Commit

Permalink
Fix source assignment for BigOperatorAtom (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Apr 15, 2018
1 parent a1777b2 commit e88f620
Show file tree
Hide file tree
Showing 28 changed files with 136 additions and 65 deletions.
24 changes: 22 additions & 2 deletions src/WpfMath.Tests/BoxTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,35 @@ let ``ScriptsAtom should set Shift on the created box when creating box without
Assert.Equal(expectedShift, box.Shift)

[<Fact>]
let ``RowAtom creates a boxes with proper sources``() =
let ``RowAtom creates boxes with proper sources``() =
let source = "2+2"
let src = src source
let parser = TexFormulaParser()
let formula = parser.Parse source
let box = formula.CreateBox environment :?> HorizontalBox
let chars = box.Children.filter(fun x -> x :? CharBox)
Assert.Collection<Box>(
Assert.Collection(
chars,
Action<_>(fun (x : Box) -> Assert.Equal(src 0 1, x.Source)),
Action<_>(fun (x : Box) -> Assert.Equal(src 1 1, x.Source)),
Action<_>(fun (x : Box) -> Assert.Equal(src 2 1, x.Source)))

[<Fact>]
let ``BigOperatorAtom creates a box with proper sources``() =
let source = @"\int_a^b"
let src = src source
let parser = TexFormulaParser()
let formula = parser.Parse source
let box = formula.CreateBox environment :?> VerticalBox

let charBoxes =
box.Children
.filter(fun x -> x :? HorizontalBox)
.collect(fun x -> x.Children.filter(fun y -> y :? CharBox))
.toList()

Assert.Collection(
charBoxes,
Action<_>(fun (x : Box) -> Assert.Equal(src 7 1, x.Source)),
Action<_>(fun (x : Box) -> Assert.Equal(src 1 3, x.Source)),
Action<_>(fun (x : Box) -> Assert.Equal(src 5 1, x.Source)))
8 changes: 4 additions & 4 deletions src/WpfMath.Tests/ParserTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ let ``\lim should be parsed properly`` () =
assertParseResult
<| @"\lim_{n} x"
<| (formula <| row [
opWithScripts ``\lim`` (char 'n') null (System.Nullable true);
opWithScripts ``\lim`` (char 'n') null (Some true)
char 'x'
])

Expand All @@ -129,7 +129,7 @@ let ``{\lim} x should be parsed properly`` () =
assertParseResult
<| @"{\lim} x"
<| (formula <| row [
group (op ``\lim`` (System.Nullable true));
group (op ``\lim`` (Some true))
char 'x'
])

Expand All @@ -138,7 +138,7 @@ let ``\sin should be parsed properly`` () =
assertParseResult
<| @"\sin^{n} x"
<| (formula <| row [
opWithScripts ``\sin`` null (char 'n') (System.Nullable false);
opWithScripts ``\sin`` null (char 'n') (Some false)
char 'x'
])

Expand All @@ -147,7 +147,7 @@ let ``\int f should be parser properly`` () =
assertParseResult
<| @"\int f"
<| (formula <| row [
op (symbolOp "int") (System.Nullable ())
op (symbolOp "int") (None)
char 'f'
])

Expand Down
18 changes: 17 additions & 1 deletion src/WpfMath.Tests/SourceDetectionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,23 @@ open WpfMath.Tests.Utils
let ``2+2 should be parsed properly`` () =
let source = "2+2"
let src = src source
let tree = rowSrc [charSrc '2' (src 0 1); symbolSrc "plus" (src 1 1); charSrc '2' (src 2 1)] (src 0 3)
let tree = rowSrc [ charSrc '2' (src 0 1)
symbolSrc "plus" TexAtomType.BinaryOperator (src 1 1)
charSrc '2' (src 2 1) ]
(src 0 3)
assertParseResultWithSource
<| source
<| formula tree

[<Fact>]
let ``integral expression should be parsed properly`` () =
let source = @"\int_a^b"
let src = src source
let tree = opWithScriptsSrc (symbolSrc "int" TexAtomType.BigOperator (src 1 3))
(charSrc 'a' (src 5 1))
(charSrc 'b' (src 7 1))
None
(src 0 8)
assertParseResultWithSource
<| source
<| formula tree
23 changes: 17 additions & 6 deletions src/WpfMath.Tests/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,19 @@ let assertParseThrows<'ex when 'ex :> exn> formula =

let src (string : string) (start : int) (len : int) = SourceSpan(string, start, len)

let private toNullable = function
| Some x -> Nullable x
| None -> Nullable()

let charSrc (c : char) (source : SourceSpan) : CharAtom = CharAtom(source, c)
let symbolSrc (name : string) (source : SourceSpan) : SymbolAtom =
SymbolAtom(source, name, TexAtomType.BinaryOperator, false)
let symbolSrc (name : string) (aType : TexAtomType) (source : SourceSpan) : SymbolAtom =
SymbolAtom(source, name, aType, false)
let opWithScriptsSrc (baseAtom : Atom)
(subscript : Atom)
(superscript : Atom)
(useVertScripts : bool option)
(source : SourceSpan)
: BigOperatorAtom = BigOperatorAtom(source, baseAtom, subscript, superscript, toNullable useVertScripts)
let rowSrc (children : Atom seq) (source : SourceSpan) : RowAtom =
children
|> Seq.fold (fun row atom -> row.Add atom) (RowAtom(source))
Expand All @@ -57,13 +67,14 @@ let space = SpaceAtom(null)
let char (c : char) : CharAtom = charSrc c null
let styledChar (c : char) (style : string) : CharAtom = CharAtom(null, c, style)
let textChar c = styledChar c textStyle
let op (baseAtom : Atom) (useVertScripts : System.Nullable<bool>) : BigOperatorAtom = BigOperatorAtom(baseAtom, null, null, useVertScripts)
let opWithScripts (baseAtom : Atom) (subscript : Atom) (superscript : Atom) (useVertScripts : System.Nullable<bool>)
: BigOperatorAtom = BigOperatorAtom(baseAtom, subscript, superscript, useVertScripts)
let opWithScripts (baseAtom : Atom) (subscript : Atom) (superscript : Atom) (useVertScripts : bool option)
: BigOperatorAtom = opWithScriptsSrc baseAtom subscript superscript useVertScripts null
let op (baseAtom : Atom) (useVertScripts : bool option) : BigOperatorAtom =
opWithScripts baseAtom null null useVertScripts
let scripts (baseAtom : Atom) (subscript : Atom) (superscript : Atom)
: ScriptsAtom = ScriptsAtom(null, baseAtom, subscript, superscript)
let group (groupedAtom: Atom) : TypedAtom = TypedAtom(null, groupedAtom, TexAtomType.Ordinary, TexAtomType.Ordinary)
let symbol (name : string) : SymbolAtom = symbolSrc name null
let symbol (name : string) : SymbolAtom = symbolSrc name TexAtomType.BinaryOperator null
let symbolOp (name : string) : SymbolAtom = SymbolAtom(null, name, TexAtomType.BigOperator, false)
let row (children : Atom seq) : RowAtom = rowSrc children null
let fenced left body right : FencedAtom = FencedAtom(null, body, left, right)
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/AccentedAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public AccentedAtom(SourceSpan source, Atom baseAtom, TexFormula accent)
// Atom representing accent symbol to place over base atom.
public SymbolAtom AccentAtom { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
CharSymbol GetBaseChar()
{
Expand Down
13 changes: 12 additions & 1 deletion src/WpfMath/Atom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,18 @@ protected Atom(SourceSpan source, TexAtomType type = TexAtomType.Ordinary)

public SourceSpan Source { get; }

public abstract Box CreateBox(TexEnvironment environment);
public Box CreateBox(TexEnvironment environment)
{
var box = this.CreateBoxCore(environment);
if (box.Source == null)
{
box.Source = this.Source;
}

return box;
}

protected abstract Box CreateBoxCore(TexEnvironment environment);

// Gets type of leftmost child item.
public virtual TexAtomType GetLeftType()
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/BigDelimeterAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public BigDelimeterAtom(SourceSpan source, Atom delimeterAtom, int size)

public int Size { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
// TODO
var resultBox = (Box)null; // DelimiterFactory.CreateBox(this.DelimeterAtom, this.Size, environment);
Expand Down
17 changes: 11 additions & 6 deletions src/WpfMath/BigOperatorAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ private static Box ChangeWidth(Box box, double maxWidth)
return box;
}

public BigOperatorAtom(Atom baseAtom, Atom lowerLimitAtom, Atom upperLimitAtom, bool? useVerticalLimits = null)
: this(baseAtom, lowerLimitAtom, upperLimitAtom)
public BigOperatorAtom(
SourceSpan source,
Atom baseAtom,
Atom lowerLimitAtom,
Atom upperLimitAtom,
bool? useVerticalLimits = null)
: this(source, baseAtom, lowerLimitAtom, upperLimitAtom)
{
this.UseVerticalLimits = useVerticalLimits;
}

public BigOperatorAtom(Atom baseAtom, Atom lowerLimitAtom, Atom upperLimitAtom)
: base(baseAtom.Source, TexAtomType.BigOperator)
public BigOperatorAtom(SourceSpan source, Atom baseAtom, Atom lowerLimitAtom, Atom upperLimitAtom)
: base(source, TexAtomType.BigOperator)
{
this.BaseAtom = baseAtom;
this.LowerLimitAtom = lowerLimitAtom;
Expand All @@ -40,7 +45,7 @@ public BigOperatorAtom(Atom baseAtom, Atom lowerLimitAtom, Atom upperLimitAtom)
// True if limits should be drawn over and under the base atom; false if they should be drawn as scripts.
public bool? UseVerticalLimits { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var texFont = environment.MathFont;
var style = environment.Style;
Expand All @@ -61,7 +66,7 @@ public override Box CreateBox(TexEnvironment environment)
var opChar = texFont.GetCharInfo(((SymbolAtom)this.BaseAtom).Name, style);
if (style < TexStyle.Text && texFont.HasNextLarger(opChar))
opChar = texFont.GetNextLargerCharInfo(opChar, style);
var charBox = new CharBox(environment, opChar) { Source = Source };
var charBox = new CharBox(environment, opChar) { Source = this.BaseAtom.Source };
charBox.Shift = -(charBox.Height + charBox.Depth) / 2 -
environment.MathFont.GetAxisHeight(environment.Style);
baseBox = new HorizontalBox(charBox);
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/CharAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public CharAtom(SourceSpan source, char character, string textStyle = null)
// Null means default text style.
public string TextStyle { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var font = GetStyledFont(environment);
var charInfo = GetCharInfo(font, environment.Style);
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/DummyAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public CharFont GetCharFont(ITeXFont texFont)
return ((CharSymbol)this.Atom).GetCharFont(texFont);
}

public override Box CreateBox(TexEnvironment environment) =>
protected override Box CreateBoxCore(TexEnvironment environment) =>
this.Atom.CreateBox(environment);

public override TexAtomType GetLeftType()
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/FencedAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public FencedAtom(SourceSpan source, Atom baseAtom, SymbolAtom leftDelimeter, Sy

private SymbolAtom RightDelimeter { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var texFont = environment.MathFont;
var style = environment.Style;
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/FixedCharAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public override CharFont GetCharFont(ITeXFont texFont)
return this.CharFont;
}

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var charInfo = environment.MathFont.GetCharInfo(this.CharFont, environment.Style);
return new CharBox(environment, charInfo);
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/FractionAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ protected FractionAtom(

public Atom Denominator { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var texFont = environment.MathFont;
var style = environment.Style;
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/OverUnderDelimiter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public OverUnderDelimiter(
// True to place delimeter symbol Over base; false to place delimeter symbol under base.
public bool Over { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
// Create boxes for base, delimeter, and script atoms.
var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment);
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/OverlinedAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public OverlinedAtom(SourceSpan source, Atom baseAtom)

public Atom BaseAtom { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
// Create box for base atom, in cramped style.
var baseBox = this.BaseAtom == null ? StrutBox.Empty : this.BaseAtom.CreateBox(environment.GetCrampedStyle());
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/PhantomAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Atom WithPreviousAtom(DummyAtom previousAtom) =>

public RowAtom RowAtom { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var resultBox = this.RowAtom.CreateBox(environment);
return new StrutBox((this.useWidth ? resultBox.Width : 0), (this.useHeight ? resultBox.Height : 0),
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/Radical.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public Radical(SourceSpan source, Atom baseAtom, Atom degreeAtom = null)

public Atom DegreeAtom { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var texFont = environment.MathFont;
var style = environment.Style;
Expand Down
3 changes: 1 addition & 2 deletions src/WpfMath/RowAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private static DummyAtom ChangeAtomToOrdinary(DummyAtom currentAtom, DummyAtom p
return currentAtom;
}

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
// Create result box.
var resultBox = new HorizontalBox(environment.Foreground, environment.Background);
Expand Down Expand Up @@ -154,7 +154,6 @@ public override Box CreateBox(TexEnvironment environment)

// Create and add box for atom.
var curBox = curAtom.WithPreviousAtom(previousAtom).CreateBox(environment);
curBox.Source = curAtom.Source;

resultBox.Add(curBox);
environment.LastFontId = curBox.GetLastFontId();
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/ScriptsAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ScriptsAtom(SourceSpan source, Atom baseAtom, Atom subscriptAtom, Atom su

public Atom SuperscriptAtom { get; }

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var texFont = environment.MathFont;
var style = environment.Style;
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/SpaceAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public SpaceAtom(SourceSpan source)
this.isHardSpace = true;
}

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
if (isHardSpace)
return new StrutBox(environment.MathFont.GetSpace(environment.Style), 0, 0, 0);
Expand Down
2 changes: 1 addition & 1 deletion src/WpfMath/StyledAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public Atom WithPreviousAtom(DummyAtom previousAtom)
return new StyledAtom(this.Source, rowAtom, this.Background, this.Foreground);
}

public override Box CreateBox(TexEnvironment environment)
protected override Box CreateBoxCore(TexEnvironment environment)
{
var newEnvironment = environment.Clone();
if (this.Background != null)
Expand Down
6 changes: 2 additions & 4 deletions src/WpfMath/SymbolAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ public SymbolAtom(SourceSpan source, string name, TexAtomType type, bool isDelim

public string Name { get; }

public override Box CreateBox(TexEnvironment environment)
{
return new CharBox(environment, environment.MathFont.GetCharInfo(this.Name, environment.Style));
}
protected override Box CreateBoxCore(TexEnvironment environment) =>
new CharBox(environment, environment.MathFont.GetCharInfo(this.Name, environment.Style));

public override CharFont GetCharFont(ITeXFont texFont)
{
Expand Down
24 changes: 17 additions & 7 deletions src/WpfMath/TexFormulaHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,27 @@ public void AddOperator(string operatorFormula, bool useVerticalLimits)

public void AddOperator(TexFormula operatorFormula, TexFormula lowerLimitFormula, TexFormula upperLimitFormula)
{
Add(new BigOperatorAtom(operatorFormula == null ? null : operatorFormula.RootAtom,
lowerLimitFormula == null ? null : lowerLimitFormula.RootAtom,
upperLimitFormula == null ? null : upperLimitFormula.RootAtom));
this.Add(
new BigOperatorAtom(
operatorFormula?.RootAtom?.Source,
operatorFormula?.RootAtom,
lowerLimitFormula?.RootAtom,
upperLimitFormula?.RootAtom));
}

public void AddOperator(TexFormula operatorFormula, TexFormula lowerLimitFormula, TexFormula upperLimitFormula,
public void AddOperator(
TexFormula operatorFormula,
TexFormula lowerLimitFormula,
TexFormula upperLimitFormula,
bool useVerticalLimits)
{
Add(new BigOperatorAtom(operatorFormula == null ? null : operatorFormula.RootAtom,
lowerLimitFormula == null ? null : lowerLimitFormula.RootAtom,
upperLimitFormula == null ? null : upperLimitFormula.RootAtom, useVerticalLimits));
this.Add(
new BigOperatorAtom(
operatorFormula?.RootAtom?.Source,
operatorFormula?.RootAtom,
lowerLimitFormula?.RootAtom,
upperLimitFormula?.RootAtom,
useVerticalLimits));
}

public void AddPhantom(string formula)
Expand Down
Loading

0 comments on commit e88f620

Please sign in to comment.