UNPKG

gdscriptify

Version:

A magical documentation tool for GDScript.

336 lines (269 loc) 9.32 kB
const config = require('../../config') const fs = require('fs') const parseConstant = require('./parseConstant') const parseDocstring = require('./parseDocstring') const parseEnum = require('./parseEnum') const parseExample = require('./parseExample') const parseFunctionAndSignal = require('./parseFunctionAndSignal') const parseVariable = require('./parseVariable') const path = require('path') const regex = require('../regex') const token = require('../token') module.exports = filePath => { let file = {} let lines = fs.readFileSync(filePath, 'utf8').split(/\r?\n/) switch (path.extname(filePath)) { case '.cfg': for (let index = 0; index < lines.length; index++) { const line = lines[index] if (line.lastIndexOf('name', 0) === 0) { file.name = line.split('"')[1] } if (line.lastIndexOf('description', 0) === 0) { if (line.slice(-1) !== '"') { file.description = `${line}\n` let lineIndex = index while (lines[lineIndex].slice(-1) !== '"') { lineIndex += 1 file.description += `${lines[lineIndex]}\n` continue } file.description = file.description.match( /"([^"\\]*(?:\\.[^"\\]*)*)"/ )[1] } else { file.description = line.match(/"([^"\\]*(?:\\.[^"\\]*)*)"/)[1] } } if (line.lastIndexOf('author', 0) === 0) { file.author = line.split('"')[1] } if (line.lastIndexOf('version', 0) === 0) { file.version = line.split('"')[1] } } break case '.godot': for (let index = 0; index < lines.length; index++) { const line = lines[index] if (line.lastIndexOf('config/name', 0) === 0) { file.name = line.split('"')[1] } if (line.lastIndexOf('config/description', 0) === 0) { if (line.slice(-1) !== '"') { file.description = `${line}\n` let lineIndex = index while (lines[lineIndex].slice(-1) !== '"') { lineIndex += 1 file.description += `${lines[lineIndex]}\n` continue } file.description = file.description.match( /"([^"\\]*(?:\\.[^"\\]*)*)"/ )[1] } else { file.description = line.match(/"([^"\\]*(?:\\.[^"\\]*)*)"/)[1] } } if (line.lastIndexOf('config/version', 0) === 0) { file.version = line.split('"')[1] } if (line.lastIndexOf('config/godot_version', 0) === 0) { file.godotVersion = line.split('"')[1] } if (line.lastIndexOf('config/license', 0) === 0) { file.license = line.split('"')[1] } if (line.lastIndexOf('config/author', 0) === 0) { file.author = line.split('"')[1] } if (line.lastIndexOf('config/repository', 0) === 0) { file.repository = line.split('"')[1] } if (line.lastIndexOf('config/banner', 0) === 0) { file.banner = line.split('"')[1] } if (line.lastIndexOf('config/patreon', 0) === 0) { file.support = file.support || {} file.support['patreon'] = line.split('"')[1] } if (line.lastIndexOf('config/ko-fi', 0) === 0) { file.support = file.support || {} file.support['ko-fi'] = line.split('"')[1] } if (line.lastIndexOf('config/buy_me_a_coffee', 0) === 0) { file.support = file.support || {} file.support['buy_me_a_coffee'] = line.split('"')[1] } if (line.lastIndexOf('config/paypal', 0) === 0) { file.support = file.support || {} file.support['paypal'] = line.split('"')[1] } if (line.lastIndexOf('[autoload]', 0) === 0) { file.singletons = [] let lineIndex = index lineIndex += 1 while (lines[lineIndex].charAt(0) !== '[') { lineIndex += 1 if ( lines[lineIndex].length === 0 || lines[lineIndex].charAt(0) === '[' ) { continue } let singletonName = lines[lineIndex].split('=')[0].trim() let singletonPath = lines[lineIndex] .split('=')[1] .trim() .replace(/\*|"/g, '') file.singletons.push({ name: singletonName, path: singletonPath }) } } } break case '.gd': file = { name: null, description: null, path: `${filePath.replace(config.projectDir + '/', '')}`, icon: null, tool: false, extends: null, singleton: false, sections: { signals: [], enums: [], constants: [], variables: [], functions: [] } } for (let index = 0; index < lines.length; index++) { let section = { name: null, description: null, code: null, table: [] } switch (lines[index].split(' ')[0]) { case token.tool: file.tool = true break case token.className: let properties = lines[index] .match(regex.className) .pop() .split(',') file.name = properties[0].trim() if (properties[1]) { file.icon = properties[1].replace(/"/g, '').trim() } break case token.extends: file.extends = lines[index].match(regex.extends).pop() break case token.docstring: if (regex.at.example.test(lines[index])) { section.example = parseExample(lines, index) } section.description = parseDocstring(lines[index]) let i = 1 while (lines[index + i].lastIndexOf(token.docstring, 0) === 0) { if (lines[index + i].trim() === token.docstring) { section.description += '\n\n' } else if ( lines[index + i] .replace(token.docstring, '') .trim() .match(regex.markdown.list) ) { section.description += '\n' } else { section.description += ' ' } if (regex.at.example.test(lines[index + i])) { section.example = parseExample(lines, index + i) } section.description += parseDocstring(lines[index + i]) i++ } if (section.example) { section.description = section.description.trim() } if (!lines[index + i]) { index += i continue } if (lines[index + i].split(' ')[0] === '#') { index += i } let line = lines[index + i] section.code = line line = line.replace(/#(.*)/, '') switch (line.split(/\s|\(/)[0]) { case token.className: let properties = line .match(regex.className) .pop() .split(',') file.name = properties[0].trim() if (properties[1]) { file.icon = properties[1].replace(/"/g, '').trim() } file.description = section.description break case token.enum: section = parseEnum(section, line) if (section) { file.sections.enums.push(section) } break case token.constant: section = parseConstant(section, line) if (section) { file.sections.constants.push(section) } break case token.variable: case token.exportVariable: case token.onreadyVariable: section = parseVariable(section, lines, index + i) if (section) { file.sections.variables.push(section) } break case token.function: case token.staticFunction: case token.signal: section = parseFunctionAndSignal(section, line) if (section) { if (line.split(' ')[0] === token.signal) { file.sections.signals.push(section) } else { file.sections.functions.push(section) } } break } index += i break } } if (!file.name) { let fileExt = path.extname(filePath) let fileName = path.basename(filePath, fileExt) //(?=[A-Z]) file.name = fileName .split(/\s|\_|\-/) .map(word => { return word[0].toUpperCase() + word.substring(1) }) .join(' ') } break } return file }