UNPKG

eslint-plugin-react-pug

Version:

Add supporting of pugjs with react

119 lines (97 loc) 3.52 kB
/** * @fileoverview Inherit pug-lint to validate pug * @author Eugene Zhlobo */ const Linter = require('pug-lint') const common = require('common-prefix') const { isReactPugReference, buildLocation, docsUrl } = require('../util/eslint') const getTemplate = require('../util/getTemplate') //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ const buildMessage = actual => ( `Invalid indentation, found "${actual}" spaces` ) module.exports = { meta: { docs: { description: 'Inherit pug-lint to validate pug (experimental)', category: 'Stylistic Issues', recommended: false, url: docsUrl('pug-lint'), }, schema: [ { type: 'object', }, ], }, create: function (context) { return { TaggedTemplateExpression: function (node) { if (isReactPugReference(node)) { const template = getTemplate(node) const lines = template.split('\n') const linter = new Linter() linter.configure(context.options[0]) const firstTokenInLine = context .getSourceCode() .getTokensBefore(node, { filter: token => token.loc.end.line === node.loc.start.line, })[0] const minimalIndent = firstTokenInLine ? firstTokenInLine.loc.start.column : node.loc.start.column const desiredIndent = lines.length > 1 ? minimalIndent + 2 : 0 const amountOfUselessSpaces = common(lines.filter(item => item.trim() !== '')) .replace(/^(\s*).*/, '$1') .length if (amountOfUselessSpaces > 0 && amountOfUselessSpaces < desiredIndent) { context.report({ node, message: buildMessage(amountOfUselessSpaces), loc: buildLocation( [(node.loc.start.line + 1), 0], [(node.loc.start.line + 1), amountOfUselessSpaces], ), }) return null } // We need to pass the template without not valuable spaces in the // beginning of each line const preparedTemplate = lines .map(item => item.slice(desiredIndent)) .join('\n') const result = linter.checkString(preparedTemplate, 'testfile') if (result.length) { result.forEach((error) => { const delta = error.line === 1 // When template starts plus backtick ? node.quasi.quasis[0].loc.start.column + 1 : desiredIndent - 1 let columnStart = error.column + delta let columnEnd = error.column + delta let message = error.msg if (error.msg === 'Invalid indentation') { columnStart = 0 columnEnd = preparedTemplate.split('\n')[error.line - 1].replace(/^(\s*).*/, '$1').length + desiredIndent message = buildMessage(columnEnd) } context.report({ node, message, loc: buildLocation( [(node.loc.start.line + error.line) - 1, columnStart], [(node.loc.start.line + error.line) - 1, columnEnd], ), }) }) } } return null }, } }, }