-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathformula.go
More file actions
105 lines (84 loc) · 3.21 KB
/
formula.go
File metadata and controls
105 lines (84 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package result
import (
"strconv"
"strings"
"github.com/MathWebSearch/mwsapi/utils"
"github.com/pkg/errors"
)
// MathFormula represents information about a single located math formula
// It supports JSON Marshal + Unmarshal (for reading it from mws results and sending it to the user)
// And XML Un-Marshelling (for reading it as part of raw harvest data)
type MathFormula struct {
Source string `json:"source,omitempty" xml:",chardata"` // MathML Element Representing entire formula
DocumentURL string `json:"durl,omitempty"` // document url (if any)
LocalID string `json:"url" xml:"local_id,attr"` // local formula id
XPath string `json:"xpath,omitempty"` // XPath from the formula -> query
SubTerm string `json:"subterm,omitempty"` // MathML Element representing matching subterm
Substitution map[string]string `json:"subst,omitempty"` // MathML Elements representing values for the subsituted terms
}
// MathML returns a MathML object representing this MathFormula
func (formula *MathFormula) MathML() (*utils.MathML, error) {
if formula.Source == "" {
return nil, errors.New("[MathFormula.MathML] No Source available")
}
return utils.ParseMathML(formula.Source)
}
// SetURL sets the url of a MathInfo object
func (formula *MathFormula) SetURL(url string) {
idx := strings.LastIndex(url, "#")
// if we have no '#' we only have a local id
if idx == -1 {
formula.DocumentURL = ""
formula.LocalID = url
return
}
// set the appropriate parts of the url
formula.DocumentURL = url[:idx]
formula.LocalID = url[idx+1:]
}
// RealMathID returns the math id used for this object in dictionaries
func (formula *MathFormula) RealMathID() string {
mathid := formula.LocalID
if _, err := strconv.Atoi(mathid); err == nil {
return "math" + mathid
}
return mathid
}
// PopulateSubsitutions populates the subsitutions field of this MathFormula, given a hit and a result
func (formula *MathFormula) PopulateSubsitutions(hit *Hit, res *Result) (err error) {
if len(formula.Substitution) > 0 {
return errors.Errorf("[MathFormula.PopulateSubsitutions] Substiution already populated ")
}
if formula.Source == "" {
return errors.Errorf("[MathFormula.PopulateSubsitutions] Missing formula source, can not populate subsitutions")
}
// parse the mathml
mathml, err := formula.MathML()
err = errors.Wrap(err, "formula.MathML failed")
if err != nil {
return
}
// find the term representing the entire found term
err = mathml.NavigateAnnotation(".." + formula.XPath)
err = errors.Wrapf(err, "Navigating to match XPath %q in %q failed", formula.XPath, mathml.OutputXML())
if err != nil {
return err
}
// store the subterm that matches
formula.SubTerm = mathml.OutputXML()
formula.Substitution = make(map[string]string, len(res.Variables))
// iterate over the variables
for _, variable := range res.Variables {
// make a copy of the mathml object
copy := mathml.Copy()
// navigate to the xpath
err = copy.NavigateAnnotation("." + variable.XPath)
err = errors.Wrapf(err, "Navigating to Query Variable %s with XPath %q failed in %q", variable.Name, variable.XPath, copy.OutputXML())
if err != nil {
return err
}
// and output the xml
formula.Substitution[variable.Name] = copy.OutputXML()
}
return
}