Diff of /experimental/trunk/graphing-calc/mathml.cc [r12394] .. [r12395] Maximize Restore

  Switch to unified view

a/experimental/trunk/graphing-calc/mathml.cc b/experimental/trunk/graphing-calc/mathml.cc
...
...
33
33
34
xmlNodePtr Doc::add_identifier(xmlNodePtr node, const char *name) {
34
xmlNodePtr Doc::add_identifier(xmlNodePtr node, const char *name) {
35
    return xmlNewChild(node, ns, BAD_CAST "mi", BAD_CAST name);
35
    return xmlNewChild(node, ns, BAD_CAST "mi", BAD_CAST name);
36
}
36
}
37
37
38
xmlNodePtr Doc::add_number(xmlNodePtr node, int d) {
39
    std::ostringstream s;
40
    s << d;
41
    return xmlNewChild(node, ns, BAD_CAST "mn", BAD_CAST s.str().c_str());
42
}
43
38
xmlNodePtr Doc::add_number(xmlNodePtr node, double d) {
44
xmlNodePtr Doc::add_number(xmlNodePtr node, double d) {
39
    std::ostringstream s;
45
    std::ostringstream s;
40
    s << d;
46
    s << d;
41
    return xmlNewChild(node, ns, BAD_CAST "mn", BAD_CAST s.str().c_str());
47
    return xmlNewChild(node, ns, BAD_CAST "mn", BAD_CAST s.str().c_str());
42
}
48
}
...
...
78
84
79
xmlNodePtr Doc::add_root(xmlNodePtr node) {
85
xmlNodePtr Doc::add_root(xmlNodePtr node) {
80
    return xmlNewChild(node, ns, BAD_CAST "mroot", NULL);
86
    return xmlNewChild(node, ns, BAD_CAST "mroot", NULL);
81
}
87
}
82
88
89
xmlNodePtr Doc::add_parenthesis(xmlNodePtr node) {
90
    return add_row(xmlNewChild(node, ns, BAD_CAST "mfenced", NULL));
91
}
92
83
xmlNodePtr Doc::add_subscript(xmlNodePtr node) {
93
xmlNodePtr Doc::add_subscript(xmlNodePtr node) {
84
    return xmlNewChild(node, ns, BAD_CAST "msub", NULL);
94
    return xmlNewChild(node, ns, BAD_CAST "msub", NULL);
85
}
95
}
86
96
87
xmlNodePtr Doc::add_superscript(xmlNodePtr node) {
97
xmlNodePtr Doc::add_superscript(xmlNodePtr node) {
...
...
101
        add_number(t, -1);
111
        add_number(t, -1);
102
    }
112
    }
103
    else {
113
    else {
104
        add_identifier(n, name);
114
        add_identifier(n, name);
105
    }
115
    }
106
116
    add_operator(n, "&ApplyFunction;");
107
    return xmlNewChild(n, ns, BAD_CAST "mfenced", NULL);
117
    return xmlNewChild(n, ns, BAD_CAST "mfenced", NULL);
108
}
118
}
109
119
110
using namespace Eval;
120
using namespace Eval;
111
121
...
...
116
    }
126
    }
117
    return f;
127
    return f;
118
}
128
}
119
129
120
static void mathml_populate(Doc* d, xmlNodePtr n, Function f);
130
static void mathml_populate(Doc* d, xmlNodePtr n, Function f);
131
132
//1     addition, subtraction
133
//2     multiplication, negation
134
//3     division
135
//4     powers
136
//5     functions, literals, variables
137
static int get_precedence(Function f) {
138
    if(f.f) {
139
        switch(f.f->type()) {
140
        case APPLY:
141
            return get_precedence(get_operator(f));
142
        case FLOAT:
143
        case AFFINE:
144
        case NAME:
145
            return 5;
146
        case UNARY_BUILTIN:
147
            if(static_cast<UnaryBuiltin const *>(f.f)->function() == UnaryBuiltin::NEGATE)
148
                return 2;
149
            else
150
                return 5;
151
        case BINARY_BUILTIN: {
152
            switch (static_cast<BinaryBuiltin const *>(f.f)->function()) {
153
            case BinaryBuiltin::ADD:
154
                return 1;
155
            case BinaryBuiltin::SUB:
156
                return 1;
157
            case BinaryBuiltin::MUL:
158
                return 2;
159
            case BinaryBuiltin::DIV:
160
                return 3;
161
            case BinaryBuiltin::POW:
162
                return 4;
163
            case BinaryBuiltin::HYPOT:
164
                return 5;
165
            case BinaryBuiltin::ATAN2:
166
                return 5;
167
            }
168
        }
169
        }
170
    }
171
    return 0;
172
}
173
174
//Handles mrow, parenthesis
175
static void add_operand(Doc* d, xmlNodePtr n, Function parent, Function f) {
176
    if(get_precedence(parent) > get_precedence(f))
177
        n = d->add_parenthesis(n);
178
    mathml_populate(d, d->add_row(n), f);
179
}
121
180
122
static void handle_apply(Doc* d, xmlNodePtr n, Function f) {
181
static void handle_apply(Doc* d, xmlNodePtr n, Function f) {
123
    Apply const *apply = static_cast<Apply const *>(f.f);
182
    Apply const *apply = static_cast<Apply const *>(f.f);
124
    Function op = get_operator(f);
183
    Function op = get_operator(f);
125
184
...
...
137
                functions.push(apply->argument());
196
                functions.push(apply->argument());
138
                f = apply->f();
197
                f = apply->f();
139
            }
198
            }
140
199
141
            while(!functions.empty()) {
200
            while(!functions.empty()) {
142
                mathml_populate(d, n, functions.top());
201
                mathml_populate(d, d->add_row(n), functions.top());
143
                functions.pop();
202
                functions.pop();
144
            }
203
            }
145
204
146
            break;
205
            break;
147
        }
206
        }
...
...
161
            case UnaryBuiltin::COS: no = d->add_function(n, "cos"); break;
220
            case UnaryBuiltin::COS: no = d->add_function(n, "cos"); break;
162
            case UnaryBuiltin::TAN: no = d->add_function(n, "tan"); break;
221
            case UnaryBuiltin::TAN: no = d->add_function(n, "tan"); break;
163
            case UnaryBuiltin::ASIN: no = d->add_function(n, "sin", true); break;       //True makes it inverse notation
222
            case UnaryBuiltin::ASIN: no = d->add_function(n, "sin", true); break;       //True makes it inverse notation
164
            case UnaryBuiltin::ACOS: no = d->add_function(n, "cos", true); break;
223
            case UnaryBuiltin::ACOS: no = d->add_function(n, "cos", true); break;
165
            case UnaryBuiltin::ATAN: no = d->add_function(n, "tan", true); break;
224
            case UnaryBuiltin::ATAN: no = d->add_function(n, "tan", true); break;
166
            //case UnaryBuiltin::GAMMA: std::cout << "#gamma"; break;
225
            case UnaryBuiltin::GAMMA: no = d->add_function(n, "&Gamma;"); break;
167
            //case UnaryBuiltin::LNGAMMA: std::cout << "#lngamma"; break;
226
            case UnaryBuiltin::LNGAMMA: d->add_identifier(n, "ln"); no = d->add_function(n, "&Gamma;"); break;
168
            //case UnaryBuiltin::ZETA: std::cout << "#zeta"; break;
227
            //case UnaryBuiltin::ZETA: std::cout << "#zeta"; break;
169
            case UnaryBuiltin::NEGATE: no = d->add_operator(n, "-", true); break;       //True makes it prefix notation
228
            case UnaryBuiltin::NEGATE: no = d->add_operator(n, "-", true); break;       //True makes it prefix notation
170
            //case UnaryBuiltin::CENTER: std::cout << "#center"; break;
229
            //case UnaryBuiltin::CENTER: std::cout << "#center"; break;
171
            //case UnaryBuiltin::GD: std::cout << "#gd"; break;
230
            //case UnaryBuiltin::GD: std::cout << "#gd"; break;
172
            //case UnaryBuiltin::LAMBERTW: std::cout << "#W"; break;
231
            //case UnaryBuiltin::LAMBERTW: std::cout << "#W"; break;
173
            //default: std::cout << "#unary:" << (int)builtin->function();
232
            //default: std::cout << "#unary:" << (int)builtin->function();
174
            }
233
            }
175
234
176
            mathml_populate(d, d->add_row(n), apply->argument());
235
            add_operand(d, no, f, apply->argument());
177
            break;
236
            break;
178
        }
237
        }
179
        case BINARY_BUILTIN: {
238
        case BINARY_BUILTIN: {
180
            BinaryBuiltin const *bop = static_cast<BinaryBuiltin const *>(op.f);
239
            BinaryBuiltin const *bop = static_cast<BinaryBuiltin const *>(op.f);
181
240
...
...
186
245
187
            xmlNodePtr r = d->add_row(n);
246
            xmlNodePtr r = d->add_row(n);
188
247
189
            switch (bop->function()) {
248
            switch (bop->function()) {
190
            case BinaryBuiltin::ADD: {
249
            case BinaryBuiltin::ADD: {
191
                mathml_populate(d, d->add_row(r), o1);
250
                add_operand(d, r, op, o1);
192
                d->add_operator(r, "+");
251
                d->add_operator(r, "+");
193
                mathml_populate(d, d->add_row(r), o2);
252
                add_operand(d, r, op, o2);
194
                break;
253
                break;
195
            }
254
            }
196
            case BinaryBuiltin::SUB: {
255
            case BinaryBuiltin::SUB: {
197
                mathml_populate(d, d->add_row(r), o1);
256
                add_operand(d, r, op, o1);
198
                d->add_operator(r, "-"); 
257
                d->add_operator(r, "-"); 
199
                mathml_populate(d, d->add_row(r), o2);
258
                add_operand(d, r, op, o2);
200
                break;
259
                break;
201
            }
260
            }
202
            case BinaryBuiltin::MUL:
261
            case BinaryBuiltin::MUL:
203
            {
262
            {
204
                //TODO: intelligent juxtaposition multiply
263
                //TODO: intelligent juxtaposition multiply
205
                mathml_populate(d, d->add_row(r), o1);
264
                add_operand(d, r, op, o1);
206
                d->add_operator(r, "*"); 
265
                d->add_operator(r, "*"); 
207
                mathml_populate(d, d->add_row(r), o2);
266
                add_operand(d, r, op, o2);
208
                break;
267
                break;
209
            }
268
            }
210
            case BinaryBuiltin::DIV: {
269
            case BinaryBuiltin::DIV: {
211
                n = d->add_fraction(r);
270
                n = d->add_fraction(r);
212
                mathml_populate(d, d->add_row(n), o1);
271
                add_operand(d, n, op, o1);
213
                mathml_populate(d, d->add_row(n), o2);
272
                add_operand(d, n, op, o2);
214
                break;
273
                break;
215
            }
274
            }
216
            case BinaryBuiltin::POW: {
275
            case BinaryBuiltin::POW: {
217
                n = d->add_superscript(r);
276
                n = d->add_superscript(r);
218
                mathml_populate(d, d->add_row(n), o1);
277
                add_operand(d, n, op, o1);
219
                mathml_populate(d, d->add_row(n), o2);
278
                add_operand(d, n, op, o2);
220
                break;
279
                break;
221
            }
280
            }
222
            case BinaryBuiltin::HYPOT: {
281
            case BinaryBuiltin::HYPOT: {
223
                n = d->add_sqrt(r);
282
                n = d->add_sqrt(r);
224
                  xmlNodePtr p = d->add_superscript(n);
283
                  xmlNodePtr p = d->add_superscript(n);
225
                    mathml_populate(d, d->add_row(p), o1);
284
                    add_operand(d, p, op, o1);
226
                    d->add_number(p, 2);
285
                    d->add_number(p, 2);
227
                  d->add_operator(n, "+");
286
                  d->add_operator(n, "+");
228
                  p = d->add_superscript(n);
287
                  p = d->add_superscript(n);
229
                    mathml_populate(d, d->add_row(p), o2);
288
                    add_operand(d, p, op, o2);
230
                    d->add_number(p, 2);
289
                    d->add_number(p, 2);
231
                break;
290
                break;
232
            }
291
            }
233
            case BinaryBuiltin::ATAN2: {
292
            case BinaryBuiltin::ATAN2: {
234
                n = d->add_function(r, "tan", true);
293
                n = d->add_function(r, "tan", true);
235
                n = d->add_fraction(n);
294
                n = d->add_fraction(n);
236
                mathml_populate(d, d->add_row(n), o1);
295
                add_operand(d, n, op, o1);
237
                mathml_populate(d, d->add_row(n), o2);
296
                add_operand(d, n, op, o2);
238
                break;
297
                break;
239
            }
298
            }
240
            //case BinaryBuiltin::INTERVAL: std::cout << "#interval"; break;
299
            //case BinaryBuiltin::INTERVAL: std::cout << "#interval"; break;
241
            //default: std::cout << "#binary:" << (int)builtin->function();
300
            //default: std::cout << "#binary:" << (int)builtin->function();
242
            }
301
            }
243
            break;
302
            break;
244
          }
303
          }
304
        default:
305
            //TODO: Better error stuff
306
            std::cout << "Invalid eval tree - Unexpected literal function used as operator: ";
307
            dump_sexp(op);
308
            std::cout << "\n";
245
        }
309
        }
246
    }
310
    }
247
}
311
}
248
312
249
static void mathml_populate(Doc* d, xmlNodePtr n, Function f) {
313
static void mathml_populate(Doc* d, xmlNodePtr n, Function f) {
...
...
265
        case AFFINE: {
329
        case AFFINE: {
266
            Affine const *f2=static_cast<Affine const *>(f.f);
330
            Affine const *f2=static_cast<Affine const *>(f.f);
267
            interval i=f2->value().convert();
331
            interval i=f2->value().convert();
268
            break;
332
            break;
269
        }
333
        }
334
        default:
335
            //TODO: Better error stuff
336
            std::cout << "Invalid eval tree - Unexpected operator function";
337
            dump_sexp(f);
338
            std::cout << "\n";
270
        }
339
        }
271
    }
340
    }
272
}
341
}
273
342
274
Doc* doc_from_func(Function func) {
343
Doc* doc_from_func(Function func) {