mathjs icon indicating copy to clipboard operation
mathjs copied to clipboard

Define custom help objects

Open bornova opened this issue 3 years ago • 9 comments

For example, if I import a function as follows:

math.import({
  area: function (x, y) {
    return x*y
  }
})

I would like to then define a help object for this new function so I can call math.help("area"). Is this possible?

bornova avatar Dec 01 '20 23:12 bornova

That is a good question, there is is currently no solution for that.

Here is a workaround:

import { create, all, docs } from 'mathjs'

const math = create(all)

math.import({
  area: function (x, y) {
    return x*y
  }
})

const areaDocs = {
  name: 'area',
  category: 'Utils',
  syntax: [
    'area(x, y)'
  ],
  description: 'Calculate the area of a rectangle with width x and height y',
  examples: [
    'area(2, 3)',
    'area(2.5, 5)'
  ],
  seealso: ['multiply']
}

// Workaround: this will add docs to the static, global docs object
docs.area = areaDocs

console.log('area(2, 3) = ' + math.evaluate('area(2, 3)'))
// area(2, 3) = 6

console.log(math.format(math.evaluate('help(area)')))
// Name: area
//
// Category: Utils
//
// Description:
//     Calculate the area of a rectangle with width x and height y
//
// Syntax:
//     area(x, y)
//
// Examples:
//     area(2, 3)
//         6
//     area(2.5, 5)
//         12.5
//
// See also: multiply

Would be nice to create a function like createDocs for this. Anyone interested to pick this up?

josdejong avatar Dec 03 '20 17:12 josdejong

Thanks @josdejong! A createDocs function would be a nice feature.

In the meantime, any way to make the workaround work in browser environment?

bornova avatar Dec 03 '20 17:12 bornova

In the meantime, any way to make the workaround work in browser environment?

hm, I'm afraid these docs are simply not exposed in the pre-baked browser bundle.

josdejong avatar Dec 03 '20 19:12 josdejong

Hello. Voluntaring to pick up the createDocs not-for-browser implementation. [Edit] Looks trickier than expected. First idea was to append to embeddedDocs, but it seems that this object will be shared between different instances of math created via

import math from 'src/defaultInstance.js'
const newMathInstance = math.create()

=> in particular, unit testing is not "unit" anymore. Did I missed something in creating different instances of math?

rnd-debug avatar Dec 05 '20 09:12 rnd-debug

Thanks @rnd-debug . Currently the embeddedDocs are a static, singleton object, not touched by anything, and shared by all mathjs instances. This indeed needs to become a copy per mathjs instance, where we then can create (and maybe also delete?) functions.

josdejong avatar Dec 05 '20 11:12 josdejong

I saw that the PR for this stalled for whatever reasons, but it still seems like a worthy goal. In particular, I just wanted to say that if something along these lines would allow the embedded docs for mathjs builtin functions to be specified in the same source file as the function itself, that would seem to be to be a real plus for mathjs internal code organization (or should that be a separate issue?). Even better is if the online and embedded docs could be fully unified -- the current system is not very "DRY". Presumably the unified doc object would have to have both "short" and "long" descriptions, because the embedded docs are generally much more terse, but if the other common stuff like name, syntax, examples, seealso, etc. could be specified just once that would be a win.

gwhitney avatar Feb 07 '22 17:02 gwhitney

Putting the embedded docs alongside the functions is an interesting idea @gwhitney ! What may be tricky though is that when a user does not need the embedded docs, it will not be bundled with his (frontend) application, since it adds a serious amount of bytes. I'm afraid that achieving both will result in a lot of extra plumbing and overhead in the library 🤔

josdejong avatar Feb 16 '22 10:02 josdejong

Well, could it work for docgenerator.js to extract the JSON for the embedded docs (all those src/expression/embeddedDocs/**.js files) from the jsdoc-style comments in the main source files? Then the information wouldn't affect the size of a bundle that doesn't include the embedded docs, since the comments aren't included in the bundled js anyway. But then there would only be one source of information. This seems feasible given that docgenerator is running in the build process anyway. We'd likely need to add a "Summary" or "Brief Description" section to the comments, because the embedded help is often just a summary. But almost everything else can be reused as-is. If this sounds like it might be reasonable to you, I would be happy to try to make a PR for it, just let me know. (And since this has gotten somewhat far from the original question in this issue, if you want me to move this concept into a different issue just let me know.)

gwhitney avatar Feb 16 '22 21:02 gwhitney

Yes good point, getting off-topic here. I've opened a separate issue in #2454

josdejong avatar Feb 28 '22 09:02 josdejong