-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
convenient way to define latex for a custom function #276
Comments
Thanks, nice idea |
I tried to implement this and it's kind of possible but not really. I don't even know if it's actually possible to do this properly. What I'm doing right now:
if (fn && (typeof fn.toTex === 'function')) {
this.customToTex = fn.toTex;
} else {
delete this.customToTex;
}
FunctionNode.prototype.toTex = function() {
if (typeof this.customToTex === 'function') {
return this.customToTex(this.args);
}
return latex.toArgs(this);
}; The Problem with this approach is, that it requires the Do you have any idea how this could be done properly? Compiling once after the parser is done parsing an expression maybe? |
hm. We could:
Not yet sure, but I may like option 3 most, as there are no "magic" things happening and there are no side effects like possible conflicts in some global namespace. |
The problem with 1 and 3 is, that it isn't transparent to the user. Ideally I'd do an import once and after that What Here's what I mean: //implementing this in Node.js would require every node to follow the convention
//of using this.args to store it's children. Alternatively this function could be
//implemented for every single node separately.
Node.prototype.setDefs = function (defs) {
this.defs = defs;
this.args.forEach(function (arg) {
arg.setDefs(defs);
});
}; Then, once parsing is done, this function would get called for the root node thereby updating the definitions for every single node in the tree. A side effect of this would be, that every expression, once parsed, would be completely independent. So you could do a When calling And you could always update the definitions manually by calling Do you think this is a good idea or is this too invasive? |
We could move passing the The internal function Downside is that the Nodes become more coupled with the math namespace, but on the other hand... they already are. Shall I experiment with this and see if it works out nicely? |
Nice idea to use the constructors for that. Yes, it would be nice if you would experiment with this, but I would also be willing to do it myself if you can't find the time. Mathjs has been a great learning experience so far. |
So math.parse = function parse (expr, options) {
return _parse.apply(_parse, [math].concat(arguments));
}
return _parse(math, expression).compile(); and return _parse(math, expression).compile().eval(scope);
function parse (math, expr, options) {
... ...
} Every node would then store a reference to
Node.prototype.compile = function (math) {
if ((typeof math !== 'undefined') && !(math instanceof ) {
throw new TypeError('Object expected for parameter math');
} else if (typeof math === 'undefined') {
math = this.math;
}
... ...
... ...
var code = this._compile(math, defs);
}; Every nodes What I don't really understand right now is what this code does: var defs = {
math: _transform(math),
_validateScope: _validateScope
}; I assume that this code somehow copies parts of the math namespace to a new object. Maybe the Leaving This could be solved by copying When doing all of this, the only change in mathjs's interface would be that it wouldn't be necessary anymore to pass This would enable Is my understanding of the matter accurate? And do you think this is something that could be done? |
I have been following the discussion on this thread and I have noticed that changes I am doing to implement Sparse Matrix would affect the solution you are working on (see #275). As part of the change I am implementing Matrix is aware of the "math" instance (actually math.config) it is defined on. As a cascade effect, collection get the same definition: module.exports = function (math, config) { var Matrix = .... Following the cascade we get to lib/expression/parse and lib/expression/Parser. Since some of the files in the expression namespace will be defined for a given math instance there will be no need to pass the "math" instance as parameter as you are proposing in this thread. Maybe it is time to do the change for all files defining types for the math instance. Right now types are statically defined. |
I'm not sure this is really conflicting with what you are doing. The 'only' thing that my proposal does is adding a Let's wait what Jos has to say about this ( meanwhile I'll continue working on a proof of concept of what I've been proposing, see https://github.com/FSMaxB/mathjs/tree/math-namespace-prototype ). |
It is related, the lib/expression/parse.js definition I have is like: module.exports = function (math) { So, there is no need to add the "math" parameter to the parse function as you have in your branch. You can use the local "math" for your needs (from exports function). The same happens with lib/expression/Parser.js, in this case we can remove the "math" parameter. see https://github.com/rjbaucells/mathjs/tree/matrix2 |
Now I see what you're doing. This means that This is imcompatible with what I've been doing, yes, but my only goal is that I can access I think we need a general solution for passing The solution of passing Let's see what Jos has to say, because I'm not familiar enough with mathjs to see the full impact of changes like this. |
I've experimented with passing the I've in mind that in the future we are going to do algebra, start juggling around with node trees. It's terrible to have to pass the math instance everywhere, makes using the Nodes on a low level quite hard. I think that it's helpful to keep the expression parsing stuff (Nodes, toString, toTex) as good as possible separated from the evaluation stuff (math.*). Here is the (working) experiment: https://github.com/josdejong/mathjs/tree/namespace_via_constructor @FSMaxB This would be a breaking change anyway, as the API of the Nodes is public as well. The So to summarize the options:
None of these makes me very happy :( A few more thoughts:
|
That seems reasonable. Then I wouldn't want to implement custom toTex functions for version 1 and postpone this idea to version 2, because all of the possiblities on how to implement this feature right now aren't really that nice and/or useful in my opinion. |
Yes, this will be for v2 I think. Since we want to support multiple instances of mathjs, I think in the end we need factory functions for (almost) every function and prototype of math.js. The functions needs it, BigNumber needs it, Unit will need it, the Nodes need it, Chain needs it. Etc. Time to think through a neat architecture for this: factory functions, passing configuration, passing constructors of data types. But without this big |
We can close this issue I think, the things discussed have been implemented by @FSMaxB |
Currently it is possible to define the Latex output for a custom function as described here in #258 but this isn't very convenient.
It would be nice to be able to just add a toTex-Function to custom functions without having to modify the FunctionNode, like with the rawArgs-Flag. This would also enable using different Scopes with different LaTeX representations for the same function as I understand it.
Example:
The text was updated successfully, but these errors were encountered: