<commit_before>'use strict';

var util = require('../util/index');
var object = util.object;
var string = util.string;

/**
 * Documentation object
 * @param {Object} doc  Object containing properties:
 *                      {String} name
 *                      {String} category
 *                      {String} description
 *                      {String[]} syntax
 *                      {String[]} examples
 *                      {String[]} seealso
 * @constructor
 */
function Help (doc) {
  if (!(this instanceof Help)) {
    throw new SyntaxError('Constructor must be called with the new operator');
  }

  if (!doc)  throw new Error('Argument "doc" missing');

  this.doc = doc;
}

/**
 * Test whether a value is an instance of Help
 * @param {*} value
 * @return {Boolean} isHelp
 */
Help.isHelp = function (value) {
  return (value instanceof Help);
};

/**
 * Generate readable description from a Help object
 * @param {Object} [math]   A math instance, used to evaluate the examples
 * @return {String} readableDoc
 * @private
 */
Help.prototype.toText = function (math) {
  var doc = this.doc || {};
  var desc = '\n';

  if (doc.name) {
    desc += 'Name: ' + doc.name + '\n\n';
  }
  if (doc.category) {
    desc += 'Category: ' + doc.category + '\n\n';
  }
  if (doc.description) {
    desc += 'Description:\n    ' + doc.description + '\n\n';
  }
  if (doc.syntax) {
    desc += 'Syntax:\n    ' + doc.syntax.join('\n    ') + '\n\n';
  }
  if (doc.examples) {
    var parser = math && math.parser();
    desc += 'Examples:\n';
    for (var i = 0; i < doc.examples.length; i++) {
      var expr = doc.examples[i];
      desc += '    ' + expr + '\n';

      if (parser) {
        var res;
        try {
          res = parser.eval(expr);
        }
        catch (e) {
          res = e;
        }
        if (res !== undefined && !(res instanceof Help)) {
          desc += '        ' + string.format(res, {precision: 14}) + '\n';
        }
      }
    }
    desc += '\n';
  }
  if (doc.seealso) {
    desc += 'See also: ' + doc.seealso.join(', ') + '\n';
  }

  return desc;
};

/**
 * Generate a string representation of the Help object
 * @return {String} Returns a string
 * @private
 */
Help.prototype.toString = function () {
  return this.toText();
};

/**
 * Export the help object to JSON
 */
Help.prototype.toJSON = function () {
  var obj = object.clone(this.doc);
  obj['@type'] = 'Help';
  return obj;
};

/**
 * Instantiate a Help object from a JSON object
 * @param {Object} json
 * @returns {Help} Returns a new Help object
 */
Help.fromJSON = function (json) {
  var doc = object.clone(json);
  delete doc['@type'];
  return new Help(doc);<commit_msg>Fixed Help.fromJSON<commit_after>'use strict';

var util = require('../util/index');
var object = util.object;
var string = util.string;

/**
 * Documentation object
 * @param {Object} doc  Object containing properties:
 *                      {String} name
 *                      {String} category
 *                      {String} description
 *                      {String[]} syntax
 *                      {String[]} examples
 *                      {String[]} seealso
 * @constructor
 */
function Help (doc) {
  if (!(this instanceof Help)) {
    throw new SyntaxError('Constructor must be called with the new operator');
  }

  if (!doc)  throw new Error('Argument "doc" missing');

  this.doc = doc;
}

/**
 * Test whether a value is an instance of Help
 * @param {*} value
 * @return {Boolean} isHelp
 */
Help.isHelp = function (value) {
  return (value instanceof Help);
};

/**
 * Generate readable description from a Help object
 * @param {Object} [math]   A math instance, used to evaluate the examples
 * @return {String} readableDoc
 * @private
 */
Help.prototype.toText = function (math) {
  var doc = this.doc || {};
  var desc = '\n';

  if (doc.name) {
    desc += 'Name: ' + doc.name + '\n\n';
  }
  if (doc.category) {
    desc += 'Category: ' + doc.category + '\n\n';
  }
  if (doc.description) {
    desc += 'Description:\n    ' + doc.description + '\n\n';
  }
  if (doc.syntax) {
    desc += 'Syntax:\n    ' + doc.syntax.join('\n    ') + '\n\n';
  }
  if (doc.examples) {
    var parser = math && math.parser();
    desc += 'Examples:\n';
    for (var i = 0; i < doc.examples.length; i++) {
      var expr = doc.examples[i];
      desc += '    ' + expr + '\n';

      if (parser) {
        var res;
        try {
          res = parser.eval(expr);
        }
        catch (e) {
          res = e;
        }
        if (res !== undefined && !(res instanceof Help)) {
          desc += '        ' + string.format(res, {precision: 14}) + '\n';
        }
      }
    }
    desc += '\n';
  }
  if (doc.seealso) {
    desc += 'See also: ' + doc.seealso.join(', ') + '\n';
  }

  return desc;
};

/**
 * Generate a string representation of the Help object
 * @return {String} Returns a string
 * @private
 */
Help.prototype.toString = function () {
  return this.toText();
};

/**
 * Export the help object to JSON
 */
Help.prototype.toJSON = function () {
  var obj = object.clone(this.doc);
  obj['@type'] = 'Help';
  return obj;
};

/**
 * Instantiate a Help object from a JSON object
 * @param {Object} json
 * @returns {Help} Returns a new Help object
 */
Help.fromJSON = function (json) {
  var doc = {};
  for (var prop in json) {
    if (prop !== '@type') { // ignore @type field
      doc[prop] = json[prop];
    }
  }
  return new Help(doc);
{'fraction_non_alphanumeric': 0.1652604548789435, 'fraction_numerical': 0.0011005135730007337, 'mean_word_length': 2.1483833718244805, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3777994', 'n_tokens_mistral': 1746, 'n_tokens_neox': 1699, 'n_words': 510}