Skip to content

Commit e7119eb

Browse files
Merge pull request #138 from fortephp/sage-improvements
Sage plugin improvements
2 parents 92262f1 + 54dc6a0 commit e7119eb

File tree

18 files changed

+1225
-49
lines changed

18 files changed

+1225
-49
lines changed

readme.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,39 @@ Notes:
7676
- Array options use repeated flags in CLI (for example: `--blade-inline-intent-elements p --blade-inline-intent-elements svg --blade-inline-intent-elements svg:*`).
7777
- `bladeDirectiveCaseMap` takes a JSON object string when passed via CLI, but shell quoting is easy to get wrong. Prefer setting it in `.prettierrc`.
7878

79+
## Blade Plugins
80+
81+
Use `bladeSyntaxPlugins` to enable framework-specific or package-specific Blade behavior.
82+
83+
Available plugins:
84+
85+
- `statamic`
86+
- `log1x/sage-directives`: for improved compatibility with [https://github.com/Log1x/sage-directives](https://github.com/Log1x/sage-directives)
87+
88+
Example:
89+
90+
```json
91+
{
92+
"plugins": [
93+
"prettier-plugin-blade",
94+
"@prettier/plugin-php"
95+
],
96+
"overrides": [
97+
{
98+
"files": ["*.blade.php"],
99+
"options": {
100+
"parser": "blade",
101+
"bladePhpFormatting": "safe",
102+
"bladeSyntaxPlugins": [
103+
"statamic",
104+
"log1x/sage-directives"
105+
]
106+
}
107+
}
108+
]
109+
}
110+
```
111+
79112
## PHP Formatting
80113

81114
To format embedded PHP fragments inside Blade, install `@prettier/plugin-php` and include it in `plugins`:

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const options: Record<string, SupportOption> = {
7676
type: "string",
7777
array: true,
7878
default: [{ value: ["statamic"] }],
79-
description: "List of Blade plugins",
79+
description: "List of Blade syntax plugins, e.g. statamic or log1x/sage-directives.",
8080
},
8181
bladeDirectiveCase: {
8282
category: "Blade",

src/plugins/index.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1-
export { statamicPlugin, type BladeSyntaxPlugin } from "./statamic.js";
2-
export { resolveBladeSyntaxProfile, type BladeSyntaxProfile } from "./runtime.js";
1+
export { statamicPlugin } from "./statamic.js";
2+
export { sagePlugin, SAGE_PLUGIN_NAME } from "./sage/index.js";
3+
export {
4+
resolveBladeSyntaxPlugins,
5+
resolveBladeSyntaxProfile,
6+
type BladeSyntaxProfile,
7+
} from "./runtime.js";
8+
export type {
9+
BladeSyntaxPlugin,
10+
DirectivePhpFormatTemplate,
11+
DirectivePhpFormattingContext,
12+
DirectivePhpFormattingMode,
13+
} from "./types.js";

src/plugins/runtime.ts

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
import type { BladeSyntaxPlugin } from "./statamic.js";
1+
import type { TreeDirectiveDefinition } from "../tree/directive-definitions.js";
2+
import { SAGE_PLUGIN_NAME, sagePlugin } from "./sage/index.js";
3+
import type { BladeSyntaxPlugin } from "./types.js";
24
import { statamicPlugin } from "./statamic.js";
35

46
export interface BladeSyntaxProfile {
57
lexerDirectives: string[];
6-
treeDirectives: unknown[];
8+
treeDirectives: TreeDirectiveDefinition[];
79
verbatimStartDirectives: string[];
810
verbatimEndDirectives: string[];
911
}
1012

1113
const BUILTIN_BLADE_SYNTAX_PLUGINS = new Map<string, BladeSyntaxPlugin>([
14+
[SAGE_PLUGIN_NAME, sagePlugin],
1215
["statamic", statamicPlugin],
1316
]);
17+
const resolvedBladeSyntaxPluginsCache = new WeakMap<object, BladeSyntaxPlugin[]>();
1418

1519
function isRecord(value: unknown): value is Record<string, unknown> {
1620
return typeof value === "object" && value !== null;
@@ -66,26 +70,11 @@ function resolveBladeSyntaxPluginEntry(value: unknown): BladeSyntaxPlugin | null
6670
}
6771

6872
export function resolveBladeSyntaxProfile(options?: unknown): BladeSyntaxProfile {
69-
const optionRecord = isRecord(options) ? options : {};
70-
const rawPlugins = parseBladeSyntaxPluginTokens(optionRecord.bladeSyntaxPlugins);
71-
72-
const seenPluginNames = new Set<string>();
73-
const resolvedPlugins: BladeSyntaxPlugin[] = [];
74-
75-
for (const entry of rawPlugins) {
76-
const plugin = resolveBladeSyntaxPluginEntry(entry);
77-
if (!plugin) continue;
78-
79-
const key = plugin.name.toLowerCase();
80-
if (seenPluginNames.has(key)) continue;
81-
seenPluginNames.add(key);
82-
resolvedPlugins.push(plugin);
83-
}
84-
73+
const resolvedPlugins = resolveBladeSyntaxPlugins(options);
8574
const lexerDirectives = new Set<string>();
8675
const verbatimStartDirectives = new Set<string>();
8776
const verbatimEndDirectives = new Set<string>();
88-
const treeDirectives: unknown[] = [];
77+
const treeDirectives: TreeDirectiveDefinition[] = [];
8978

9079
for (const plugin of resolvedPlugins) {
9180
for (const directive of plugin.lexerDirectives) {
@@ -112,3 +101,29 @@ export function resolveBladeSyntaxProfile(options?: unknown): BladeSyntaxProfile
112101
verbatimEndDirectives: [...verbatimEndDirectives],
113102
};
114103
}
104+
105+
export function resolveBladeSyntaxPlugins(options?: unknown): BladeSyntaxPlugin[] {
106+
const optionRecord = isRecord(options) ? options : {};
107+
const cached = resolvedBladeSyntaxPluginsCache.get(optionRecord);
108+
if (cached) {
109+
return cached;
110+
}
111+
112+
const rawPlugins = parseBladeSyntaxPluginTokens(optionRecord.bladeSyntaxPlugins);
113+
114+
const seenPluginNames = new Set<string>();
115+
const resolvedPlugins: BladeSyntaxPlugin[] = [];
116+
117+
for (const entry of rawPlugins) {
118+
const plugin = resolveBladeSyntaxPluginEntry(entry);
119+
if (!plugin) continue;
120+
121+
const key = plugin.name.toLowerCase();
122+
if (seenPluginNames.has(key)) continue;
123+
seenPluginNames.add(key);
124+
resolvedPlugins.push(plugin);
125+
}
126+
127+
resolvedBladeSyntaxPluginsCache.set(optionRecord, resolvedPlugins);
128+
return resolvedPlugins;
129+
}

src/plugins/sage/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { SAGE_TREE_DIRECTIVES } from "./metadata.js";
2+
import { getSageDirectivePhpFormatTemplates } from "./print.js";
3+
import { type BladeSyntaxPlugin } from "../types.js";
4+
5+
export const SAGE_PLUGIN_NAME = "log1x/sage-directives";
6+
7+
export const sagePlugin: BladeSyntaxPlugin = {
8+
name: SAGE_PLUGIN_NAME,
9+
// The parser tokenizes directives permissively, so Sage only needs tree metadata.
10+
lexerDirectives: [],
11+
treeDirectives: SAGE_TREE_DIRECTIVES,
12+
verbatimStartDirectives: [],
13+
verbatimEndDirectives: [],
14+
getDirectivePhpFormatTemplates: getSageDirectivePhpFormatTemplates,
15+
};

0 commit comments

Comments
 (0)