From d3db4400c8cac98967e48d2c49c466adc1658f85 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Fri, 16 Apr 2021 12:36:36 -0500 Subject: [PATCH] feat(prettier): first pass --- prettier-plugin-astro/index.js | 65 +++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/prettier-plugin-astro/index.js b/prettier-plugin-astro/index.js index a22a7c43e7786..9599a82ced1fb 100644 --- a/prettier-plugin-astro/index.js +++ b/prettier-plugin-astro/index.js @@ -1,3 +1,5 @@ +const { doc: { builders: { concat, hardline } } } = require("prettier"); + /** @type {Partial[]} */ module.exports.languages = [ { @@ -11,13 +13,55 @@ module.exports.languages = [ /** @type {Record} */ module.exports.parsers = { astro: { - parse: (text, parsers) => { + parse: (text, parsers, options) => { + const children = []; + let frontmatter = text; + let content = text; + + if (frontmatter.indexOf('---') > -1) { + const delimiterStart = frontmatter.indexOf('---') + 3; + frontmatter = frontmatter.slice(delimiterStart); + const delimiterEnd = frontmatter.indexOf('---'); + content = frontmatter.slice(0).slice(delimiterEnd + 3); + frontmatter = frontmatter.slice(0, delimiterEnd); + + children.push({ + type: 'AstroFrontmatter', + children: [ + { type: 'DelimiterStart', value: '---' }, + { + type: 'AstroEmbed', + parser: 'babel-ts', + value: frontmatter + }, + { type: 'DelimiterEnd', value: '---' } + ] + }) + } + + children.push({ + type: 'AstroContent', + children: [ + { + type: 'AstroEmbed', + // TODO: handle JSX-like expressions + parser: 'html', + value: content + } + ] + }); + return { + type: 'AstroRoot', + children + }; }, locEnd(node) { + // TODO: actually track this return node.locEnd }, locStart(node) { + // TODO: actually track this return node.locStart }, astFormat: 'astro-ast', @@ -27,10 +71,21 @@ module.exports.parsers = { /** @type {Record} */ module.exports.printers = { 'astro-ast': { - print() { - /** @type {any} */ - const doc = {}; - return doc; + print(path, opts, print) { + const node = path.getValue(); + if (Array.isArray(node)) return concat(path.map(print)); + if (node.type === 'AstroEmbed') return concat([node]); + if (Array.isArray(node.children)) return concat(path.map(print, 'children')); + + if (node.type === 'DelimiterStart') return concat([node.value, hardline]); + if (node.type === 'DelimiterEnd') return concat([node.value, hardline, hardline]); + return concat([node.value]); + }, + embed(path, print, textToDoc, options) { + const node = path.getValue(); + if (node.type !== 'AstroEmbed') return null; + + return textToDoc(node.value, { ...options, parser: node.parser }); } }, };