generate-readme-jsdoc.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. const stream = require('stream');
  2. const reader = require('./reader.js');
  3. const header = `
  4. ## Documentation
  5. `;
  6. class JSDocCGenerator extends stream.Transform {
  7. constructor() {
  8. super({ objectMode: true });
  9. this.push(header);
  10. this._previuseCategory = '';
  11. }
  12. _transform(data, encoding, done) {
  13. const {
  14. category, description,
  15. returnType, functionName, functionArgs
  16. } = data;
  17. // Check if there is extra data returned
  18. const extraReturn = functionArgs.some((arg) => arg.isPointer);
  19. //
  20. // Start code generation
  21. //
  22. let code = '';
  23. //
  24. // Add category header
  25. //
  26. if (this._previuseCategory !== category) {
  27. this._previuseCategory = category;
  28. code += `### ${category}\n`;
  29. code += '\n';
  30. }
  31. //
  32. // function header
  33. //
  34. // function name
  35. if (extraReturn) {
  36. code += `#### [${returnType}, extra] = cephes.${functionName}(`;
  37. } else {
  38. code += `#### ${returnType} = cephes.${functionName}(`;
  39. }
  40. // function arguments
  41. for (const {type, isPointer, isArray, fullType, name} of functionArgs) {
  42. if (isPointer) continue;
  43. if (isArray && type === 'double') {
  44. code += `${name}: Float64Array, `;
  45. } else if (!isArray) {
  46. code += `${name}: ${type}, `;
  47. } else {
  48. throw new Error(`unsupported type: ${fullType}`);
  49. }
  50. }
  51. // Remove training comma
  52. code = code.slice(0, -2);
  53. // finish function header
  54. code += ')\n';
  55. code += '\n';
  56. //
  57. // Documentation content
  58. //
  59. // Description
  60. code += `\`${functionName}\` is the "${description}". `;
  61. code += `You can read the full documentation at http://www.netlib.org/cephes/doubldoc.html#${functionName}.`;
  62. code += '\n';
  63. code += '\n';
  64. // Example
  65. code += '```js\n';
  66. if (extraReturn) {
  67. code += 'const [ret, extra] = ';
  68. } else {
  69. code += 'const ret = ';
  70. }
  71. code += `cephes.${functionName}(`;
  72. // function arguments
  73. for (const {type, isPointer, isArray, fullType, name} of functionArgs) {
  74. if (isPointer) continue;
  75. if (isArray && type === 'double') {
  76. code += `new Float64Array(${name}), `;
  77. } else if (!isArray) {
  78. code += `${name}, `;
  79. } else {
  80. throw new Error(`unsupported type: ${fullType}`);
  81. }
  82. }
  83. code = code.slice(0, -2);
  84. code += ');\n';
  85. code += '```\n';
  86. code += '\n';
  87. // extra return
  88. if (extraReturn) {
  89. code += 'The `extra` object contains the following values: \n';
  90. code += '\n';
  91. code += '```js\n';
  92. code += 'const {\n';
  93. for (const { isPointer, name, type } of functionArgs) {
  94. if (!isPointer) continue;
  95. code += ` ${name}: ${type},\n`;
  96. }
  97. code = code.slice(0, -2) + '\n';
  98. code += '} = extra;\n';
  99. code += '```\n';
  100. code += '\n';
  101. }
  102. done(null, code);
  103. }
  104. }
  105. process.stdin
  106. .pipe(reader())
  107. .pipe(new JSDocCGenerator())
  108. .pipe(process.stdout)