Skip to content

Commit

Permalink
(feat) support singleAttributePerLine (#313)
Browse files Browse the repository at this point in the history
Closes  #305
  • Loading branch information
david-ding authored Oct 6, 2022
1 parent 781bdd2 commit db2543f
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 73 deletions.
21 changes: 12 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@types/node": "^10.12.18",
"@types/prettier": "^2.4.1",
"ava": "3.15.0",
"prettier": "^2.4.1",
"prettier": "^2.7.1",
"rollup": "2.36.0",
"rollup-plugin-typescript": "1.0.1",
"svelte": "^3.47.0",
Expand Down
31 changes: 16 additions & 15 deletions src/embed.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Doc, doc, FastPath, ParserOptions } from 'prettier';
import { getText } from './lib/getText';
import { snippedTagContentAttribute } from './lib/snipTagContent';
import { isBracketSameLine } from './options';
import { PrintFn } from './print';
import { isLine, removeParentheses, trimRight } from './print/doc-helpers';
import { groupConcat, printWithPrependedAttributeLine } from './print/helpers';
import {
getAttributeTextValue,
getLeadingComment,
Expand All @@ -12,10 +14,10 @@ import {
isTypeScript,
printRaw,
} from './print/node-helpers';
import { ElementNode, Node } from './print/nodes';
import { ElementNode, Node, ScriptNode, StyleNode } from './print/nodes';

const {
builders: { concat, hardline, group, indent, literalline },
builders: { concat, hardline, softline, indent, dedent, literalline },
utils: { removeLines },
} = doc;

Expand Down Expand Up @@ -188,7 +190,7 @@ function embedTag(
isTopLevel: boolean,
options: ParserOptions,
) {
const node: Node = path.getNode();
const node: ScriptNode | StyleNode | ElementNode = path.getNode();
const content =
tag === 'template' ? printRaw(node as ElementNode, text) : getSnippedContent(node);
const previousComment = getLeadingComment(path);
Expand All @@ -208,19 +210,18 @@ function embedTag(
: hardline
: preformattedBody(content);

const attributes = concat(
path.map(
(childPath) =>
childPath.getNode().name !== snippedTagContentAttribute
? childPath.call(print)
: '',
'attributes',
const openingTag = groupConcat([
'<',
tag,
indent(
groupConcat([
...path.map(printWithPrependedAttributeLine(node, options, print), 'attributes'),
isBracketSameLine(options) ? '' : dedent(softline),
]),
),
);

let result: Doc = group(
concat(['<', tag, indent(group(attributes)), '>', body, '</', tag, '>']),
);
'>',
]);
let result = groupConcat([openingTag, body, '</', tag, '>']);

if (isTopLevel) {
// top level embedded nodes have been moved from their normal position in the
Expand Down
4 changes: 2 additions & 2 deletions src/lib/extractAttributes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AttributeNode, TextNode } from '../print/nodes';

export function extractAttributes(html: string): AttributeNode[] {
const extractAttributesRegex = /<[a-z]+\s*(.*?)>/i;
const attributeRegex = /([^\s=]+)(?:=("|')(.*?)\2)?/gi;
const extractAttributesRegex = /<[a-z]+[\s\n]*([\s\S]*?)>/im;
const attributeRegex = /([^\s=]+)(?:=("|')([\s\S]*?)\2)?/gim;

const [, attributesString] = html.match(extractAttributesRegex)!;

Expand Down
77 changes: 75 additions & 2 deletions src/print/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import { ASTNode, Node } from './nodes';
import { Doc, FastPath } from 'prettier';
import {
ASTNode,
AttributeNode,
BodyNode,
ElementNode,
HeadNode,
InlineComponentNode,
Node,
OptionsNode,
ScriptNode,
SlotNode,
SlotTemplateNode,
StyleNode,
TitleNode,
WindowNode,
} from './nodes';
import { Doc, doc, FastPath, ParserOptions } from 'prettier';
import { formattableAttributes } from '../lib/elements';
import { PrintFn } from '.';
import { snippedTagContentAttribute } from '../lib/snipTagContent';

/**
* Determines whether or not given node
Expand Down Expand Up @@ -48,3 +65,59 @@ export function replaceEndOfLineWith(text: string, replacement: Doc) {
}
return parts;
}

export function groupConcat(contents: doc.builders.Doc[]): doc.builders.Doc {
const { concat, group } = doc.builders;
return group(concat(contents));
}

export function getAttributeLine(
node:
| ElementNode
| InlineComponentNode
| SlotNode
| WindowNode
| HeadNode
| TitleNode
| StyleNode
| ScriptNode
| BodyNode
| OptionsNode
| SlotTemplateNode,
options: ParserOptions,
) {
const { hardline, line } = doc.builders;
const hasThisBinding =
(node.type === 'InlineComponent' && !!node.expression) ||
(node.type === 'Element' && !!node.tag);

const attributes = (node.attributes as Array<AttributeNode>).filter(
(attribute) => attribute.name !== snippedTagContentAttribute,
);
return options.singleAttributePerLine &&
(attributes.length > 1 || (attributes.length && hasThisBinding))
? hardline
: line;
}

export function printWithPrependedAttributeLine(
node:
| ElementNode
| InlineComponentNode
| SlotNode
| WindowNode
| HeadNode
| TitleNode
| StyleNode
| ScriptNode
| BodyNode
| OptionsNode
| SlotTemplateNode,
options: ParserOptions,
print: PrintFn,
): PrintFn {
return (path) =>
path.getNode().name !== snippedTagContentAttribute
? doc.builders.concat([getAttributeLine(node, options), path.call(print)])
: '';
}
Loading

0 comments on commit db2543f

Please sign in to comment.