'use strict'; const RDESCRIPTION = /^([\s\S]*?)(?=@|$)/g; const RPARAM = /^@param(?:[ \t]+(\w+))(?:[ \t]+\{(.*?)\})?(?:[ \t]+(.*?))?$/gm; const RRETURNS = /^@returns(?:[ \t]+\{(.*?)\})?(?:[ \t]+(.*?))?$/gm; const REXAMPLE = /@example\n(```[\s\S]*?\n```\n|(?:(?: {4}|\t).*?\n)+)?/g; function undecorate(txt) { txt = txt.replace(/^\s*\/\*\*|\*\/\s*$/g, ""); txt = txt.replace(/^[ \t]*\*[ \t]*|[ \t*]$/gm, ""); return txt.trim(); } function decorate(txt) { var txt = txt.trim(); if (!txt.includes("\n")) return `/** ${txt} */`; var txt = txt.split("\n").map(l => " * " + l.trim()).join("\n"); return `/**\n${txt}\n */`; } function parse(txt) { var full = txt; var txt = undecorate(txt), m = null; var description = "", params = []; var returns = null, examples = []; while ((m = RDESCRIPTION.exec(txt)) != null) description = m[1] || ""; while ((m = RPARAM.exec(txt)) != null) params.push({ full: m[0], name: m[1], type: m[2] || "", description: m[3] || "" }); while ((m = RRETURNS.exec(txt)) != null) returns = { full: m[0], type: m[1] || "", description: m[2] || "" }; while ((m = REXAMPLE.exec(txt)) != null) if (m[1]) examples.push(m[1]); return { full, description, params, returns, examples }; } function stringify(x) { var txt = x.description.trim() + "\n"; for (var p of x.params) txt += ("@param" + ` ${p.name}` + (p.type ? ` {${p.type}}` : "") + ` ${p.description}`).trim() + "\n"; for (var r of x.returns ? [x.returns] : []) txt += ("@returns" + (r.type ? ` {${r.type}}` : "") + ` ${r.description}`).trim() + "\n"; for (var e of x.examples) txt += `@example\n${e.trim()}\n`; return decorate(txt); } exports.parse = parse; exports.stringify = stringify;