Skip to content

Commit

Permalink
Merge pull request #181 from corywalker/corywalker
Browse files Browse the repository at this point in the history
TeXForm for the notebook interface.
  • Loading branch information
corywalker committed Oct 15, 2018
2 parents c09c1bd + 36e8541 commit 4a91670
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 26 deletions.
8 changes: 6 additions & 2 deletions expreduce/builtin_arithmetic.go
Expand Up @@ -322,8 +322,12 @@ func getArithmeticDefinitions() (defs []Definition) {
Name: "Times",
Default: "1",
toString: func(this *Expression, params ToStringParams) (bool, string) {
ok, res := ToStringInfix(this.Parts[1:], "*", "System`Times", params)
if ok && strings.HasPrefix(res, "(-1)*") {
delim := "*"
if params.form == "TeXForm" {
delim = " "
}
ok, res := ToStringInfix(this.Parts[1:], delim, "System`Times", params)
if ok && strings.HasPrefix(res, "(-1)" + delim) {
return ok, "-" + res[5:]
}
return ok, res
Expand Down
17 changes: 14 additions & 3 deletions expreduce/builtin_list.go
Expand Up @@ -10,15 +10,26 @@ func (this *Expression) ToStringList(params ToStringParams) (bool, string) {
return false, ""
}
var buffer bytes.Buffer
buffer.WriteString("{")
if params.form == "TeXForm" {
buffer.WriteString("\\left\\{")
} else {
buffer.WriteString("{")
}
for i, e := range this.Parts[1:] {
params.previousHead = "<TOPLEVEL>"
buffer.WriteString(e.StringForm(params))
if i != len(this.Parts[1:])-1 {
buffer.WriteString(", ")
buffer.WriteString(",")
if params.form != "TeXForm" {
buffer.WriteString(" ")
}
}
}
buffer.WriteString("}")
if params.form == "TeXForm" {
buffer.WriteString("\\right\\}")
} else {
buffer.WriteString("}")
}
return true, buffer.String()
}

Expand Down
1 change: 1 addition & 0 deletions expreduce/builtin_power.go
Expand Up @@ -315,6 +315,7 @@ func GetPowerDefinitions() (defs []Definition) {
defs = append(defs, Definition{Name: "ExpandAll"})
defs = append(defs, Definition{
Name: "Log",
toString: simpleTeXToString("log"),
legacyEvalFn: bigMathFnOneParam(mathbigext.Log, true),
})
defs = append(defs, Definition{Name: "Sqrt"})
Expand Down
12 changes: 10 additions & 2 deletions expreduce/builtin_replacement.go
Expand Up @@ -155,7 +155,11 @@ func getReplacementDefinitions() (defs []Definition) {
if len(this.Parts) != 3 {
return false, ""
}
return ToStringInfixAdvanced(this.Parts[1:], " -> ", "System`Rule", false, "", "", params)
delim := " -> "
if params.form == "TeXForm" {
delim = "\\to "
}
return ToStringInfixAdvanced(this.Parts[1:], delim, "System`Rule", false, "", "", params)
},
})
defs = append(defs, Definition{
Expand All @@ -164,7 +168,11 @@ func getReplacementDefinitions() (defs []Definition) {
if len(this.Parts) != 3 {
return false, ""
}
return ToStringInfixAdvanced(this.Parts[1:], " :> ", "System`RuleDelayed", false, "", "", params)
delim := " :> "
if params.form == "TeXForm" {
delim = ":\\to "
}
return ToStringInfixAdvanced(this.Parts[1:], delim, "System`RuleDelayed", false, "", "", params)
},
})
defs = append(defs, Definition{
Expand Down
2 changes: 2 additions & 0 deletions expreduce/builtin_system.go
Expand Up @@ -798,5 +798,7 @@ func GetSystemDefinitions() (defs []Definition) {
OmitDocumentation: true,
})
defs = append(defs, Definition{Name: "Information"})
defs = append(defs, Definition{Name: "OutputStream"})
defs = append(defs, Definition{Name: "WriteString"})
return
}
3 changes: 3 additions & 0 deletions expreduce/ex_integer.go
Expand Up @@ -21,6 +21,9 @@ func (f *Integer) Eval(es *EvalState) Ex {
func (i *Integer) StringForm(params ToStringParams) string {
if i.Val.Cmp(big.NewInt(0)) < 0 {
if needsParens("System`Times", params.previousHead) {
if params.form == "TeXForm" {
return fmt.Sprintf("{(%d)}", i.Val)
}
return fmt.Sprintf("(%d)", i.Val)
}
}
Expand Down
4 changes: 3 additions & 1 deletion expreduce/ex_rational.go
Expand Up @@ -57,7 +57,9 @@ func (this *Rational) StringForm(params ToStringParams) string {
if params.form == "FullForm" {
return fmt.Sprintf("Rational[%d, %d]", this.Num, this.Den)
}
//if params.previousHead == "System`Power" {
if params.form == "TeXForm" {
return fmt.Sprintf("\\frac{%d}{%d}", this.Num, this.Den)
}
if needsParens("System`Times", params.previousHead) {
return fmt.Sprintf("(%d/%d)", this.Num, this.Den)
}
Expand Down
6 changes: 6 additions & 0 deletions expreduce/ex_real.go
Expand Up @@ -21,6 +21,9 @@ func (f *Flt) StringForm(params ToStringParams) string {
if f.Val.Cmp(big.NewFloat(0)) < 0 {
if needsParens("System`Times", params.previousHead) {
useParens = true
if params.form == "TeXForm" {
buffer.WriteString("{")
}
buffer.WriteString("(")
}
}
Expand All @@ -30,6 +33,9 @@ func (f *Flt) StringForm(params ToStringParams) string {
}
if useParens {
buffer.WriteString(")")
if params.form == "TeXForm" {
buffer.WriteString("}")
}
}
return buffer.String()
}
Expand Down
24 changes: 21 additions & 3 deletions expreduce/ex_symbol.go
Expand Up @@ -34,20 +34,38 @@ func (this *Symbol) Eval(es *EvalState) Ex {
return this
}

func formatSymName(name string, params ToStringParams) string {
if params.form == "TeXForm" {
if name == "E" {
return "e"
}
if name == "Pi" {
return "\\pi"
}
if name == "Infinity" {
return "\\infty"
}
if len(name) > 1 {
return fmt.Sprintf("\\text{%v}", name)
}
}
return fmt.Sprintf("%v", name)
}

func (this *Symbol) StringForm(params ToStringParams) string {
if len(this.Name) == 0 {
return "<EMPTYSYM>"
}
if strings.HasPrefix(this.Name, params.context.Val) {
return fmt.Sprintf("%v", this.Name[len(params.context.Val):])
return formatSymName(this.Name[len(params.context.Val):], params)
}
for _, pathPart := range params.contextPath.Parts[1:] {
path := pathPart.(*String).Val
if strings.HasPrefix(this.Name, path) {
return fmt.Sprintf("%v", this.Name[len(path):])
return formatSymName(this.Name[len(path):], params)
}
}
return fmt.Sprintf("%v", this.Name)
return formatSymName(this.Name, params)
}

func (this *Symbol) String(es *EvalState) string {
Expand Down
8 changes: 4 additions & 4 deletions expreduce/resources.go

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions expreduce/resources/string.m
Expand Up @@ -4,11 +4,11 @@
Tests`ToString = {
ESimpleExamples[
ESameTest["a^2", ToString[Global`a^2, InputForm]],
ESameTest["\sin (1)", ToString[Sin[1], TeXForm]],
ESameTest["\sin \\left(1\\right)", ToString[Sin[1], TeXForm]],
ESameTest["Hello World", "Hello World" // ToString]
], ETests[
ESameTest["\sin ()", ToString[Sin[], TeXForm]],
ESameTest["\sin (1,2)", ToString[Sin[1, 2], TeXForm]],
ESameTest["\sin \\left(\\right)", ToString[Sin[], TeXForm]],
ESameTest["\sin \\left(1,2\\right)", ToString[Sin[1, 2], TeXForm]],
]
};

Expand Down
4 changes: 4 additions & 0 deletions expreduce/resources/system.m
Expand Up @@ -336,3 +336,7 @@
);
Information[sym_Symbol] := Information[sym, LongForm->True];
Attributes[Information] = {HoldAll, Protected, ReadProtected};

Attributes[OutputStream] = {Protected, ReadProtected};
Attributes[WriteString] = {Protected};
WriteString[OutputStream["stdout", 1], str_String] := Print[str];
32 changes: 24 additions & 8 deletions expreduce/string.go
Expand Up @@ -31,7 +31,7 @@ func needsParens(thisHead string, previousHead string) bool {
}

func ToStringInfix(parts []Ex, delim string, thisHead string, p ToStringParams) (bool, string) {
if p.form != "InputForm" && p.form != "OutputForm" {
if p.form != "InputForm" && p.form != "OutputForm" && p.form != "TeXForm" {
return false, ""
}
if len(parts) < 2 {
Expand All @@ -40,7 +40,11 @@ func ToStringInfix(parts []Ex, delim string, thisHead string, p ToStringParams)
addParens := needsParens(thisHead, p.previousHead)
var buffer bytes.Buffer
if addParens {
buffer.WriteString("(")
if p.form == "TeXForm" {
buffer.WriteString("{\\left(")
} else {
buffer.WriteString("(")
}
}
nextParams := p
nextParams.previousHead = thisHead
Expand All @@ -51,7 +55,11 @@ func ToStringInfix(parts []Ex, delim string, thisHead string, p ToStringParams)
}
}
if addParens {
buffer.WriteString(")")
if p.form == "TeXForm" {
buffer.WriteString("\\right)}")
} else {
buffer.WriteString(")")
}
}
return true, buffer.String()
}
Expand All @@ -70,7 +78,7 @@ func (this *Expression) ToStringInfix(p ToStringParams) (bool, string) {

// TODO(corywalker): Remove start, end. No users of these values.
func ToStringInfixAdvanced(parts []Ex, delim string, thisHead string, surroundEachArg bool, start string, end string, params ToStringParams) (bool, string) {
if params.form != "InputForm" && params.form != "OutputForm" {
if params.form != "InputForm" && params.form != "OutputForm" && params.form != "TeXForm" {
return false, ""
}
if len(parts) < 2 {
Expand All @@ -79,7 +87,11 @@ func ToStringInfixAdvanced(parts []Ex, delim string, thisHead string, surroundEa
var buffer bytes.Buffer
addParens := needsParens(thisHead, params.previousHead)
if addParens {
buffer.WriteString("(")
if params.form == "TeXForm" {
buffer.WriteString("{\\left(")
} else {
buffer.WriteString("(")
}
}
if !surroundEachArg {
buffer.WriteString(start)
Expand All @@ -102,7 +114,11 @@ func ToStringInfixAdvanced(parts []Ex, delim string, thisHead string, surroundEa
buffer.WriteString(end)
}
if addParens {
buffer.WriteString(")")
if params.form == "TeXForm" {
buffer.WriteString("\\right)}")
} else {
buffer.WriteString(")")
}
}
return true, buffer.String()
}
Expand Down Expand Up @@ -145,14 +161,14 @@ func simpleTeXToString(fnName string) func(*Expression, ToStringParams) (bool, s
return false, ""
}
var buffer bytes.Buffer
buffer.WriteString("\\sin (")
buffer.WriteString("\\" + fnName + " \\left(")
for i := 1; i < len(this.Parts); i++ {
buffer.WriteString(this.Parts[i].StringForm(params))
if i != len(this.Parts)-1 {
buffer.WriteString(",")
}
}
buffer.WriteString(")")
buffer.WriteString("\\right)")
return true, buffer.String()
})
}

0 comments on commit 4a91670

Please sign in to comment.