UNPKG

megadoc-plugin-lua

Version:

A Lua documentation generator plugin for megadoc.

142 lines (117 loc) 3.81 kB
var parser = require('luaparse'); var fs = require('fs'); var _ = require('lodash'); var assign = _.assign; var findWhere = _.findWhere; var Docstring = require('megadoc-docstring'); var parseNode = require('./parseNode'); var docstringParser = new Docstring.Parser(); docstringParser.defineTag('author', 'withName'); docstringParser.defineTag('class', 'withName'); docstringParser.defineTag('copyright', 'withName'); docstringParser.defineTag('example', 'withName'); docstringParser.defineTag('field', 'withName'); docstringParser.defineTag('function', 'withName'); docstringParser.defineTag('module', 'withName'); docstringParser.defineTag('name', 'withName'); docstringParser.defineTag('param', 'withNameAndType'); docstringParser.defineTag('property', 'withNameAndType'); docstringParser.defineTag('release', 'withName'); docstringParser.defineTag('return', 'withNameAndType'); docstringParser.defineTag('see', 'withName'); docstringParser.defineTag('tparam', 'withName'); docstringParser.defineTag('treturn', 'withName'); docstringParser.defineTag('usage', 'withName'); exports.parseFile = function(filePath, config) { var sourceCode = fs.readFileSync(filePath, 'utf-8'); return exports.parseString(sourceCode, config); }; exports.parseString = function(sourceCode, config) { var docs = []; var lineNodes = {}; var ast = parser.parse(sourceCode, { comments: true, scope: true, locations: true, onCreateNode: function(node) { if (node.type !== 'Chunk' && node.type !== 'Comment') { lineNodes[node.loc.start.line] = node; } } }); var commentedNodes = ast.comments.reduce(function(set, commentNode) { var commentLine = commentNode.loc.start.line; var node; Object.keys(lineNodes).some(function(line) { if (commentLine < line) { node = lineNodes[line]; return true; } }); if (commentNode.raw.match(/^\-\-\s+vim:/)) { return set; } else if (node) { node.comments = node.comments || []; node.comments.push(commentNode.value); if (set.indexOf(node) === -1) { set.push(node); } } else { console.warn('Unable to find a matching node for comment:', commentNode.raw) } return set; }, []); commentedNodes.forEach(function(node) { if (node.comments[0][0] === '-') { var comment = node.comments.map(function(line) { return line.replace(/^\-?\s?/, ''); }).join('\n'); var docstring; try { docstring = docstringParser.parseComment(comment); } catch (e) { console.error("Unable to parse comment docstring:", comment.slice(0, 80)); console.error(e && e.message || e); return; } var nodeInfo = parseNode(node, config); assign(docstring, nodeInfo); var moduleTag = findWhere(docstring.tags, { type: 'module' }); if (moduleTag) { docstring.isModule = true; // whatever ID was specified in @module takes precedence over the // inferred entity ID if (moduleTag.name.length) { docstring.id = moduleTag.name; } if (moduleTag.description.length) { docstring.description += '\n' + moduleTag.description; } } // doc path if (docstring.isModule) { docstring.path = docstring.id; } else { var symbol; switch(docstring.ctx.type) { case 'function': symbol = '#'; break; case 'property': symbol = '@'; break; default: symbol = '.'; } docstring.symbol = symbol; docstring.path = docstring.receiver + symbol + docstring.id; } docs.push(docstring); } }); return docs; };