agent-docs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.cursor/plans/OPTIMISE.md +379 -0
  2. package/.cursor/plans/VERSIONING.md +207 -0
  3. package/.cursor/rules/IMPORTANT.mdc +97 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +13 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  6. package/.github/dependabot.yml +38 -0
  7. package/.github/pull_request_template.md +10 -0
  8. package/.github/workflows/format.yml +35 -0
  9. package/CODE_OF_CONDUCT.md +64 -0
  10. package/CONTRIBUTING.md +52 -0
  11. package/LICENSE.md +20 -0
  12. package/PLAN.md +707 -0
  13. package/README.md +133 -0
  14. package/SECURITY.md +21 -0
  15. package/docs/APEXANNOTATIONS.md +472 -0
  16. package/docs/APEXDOC.md +198 -0
  17. package/docs/CML.md +877 -0
  18. package/docs/CODEANALYZER.md +435 -0
  19. package/docs/CONTEXTDEFINITIONS.md +617 -0
  20. package/docs/ESLINT.md +827 -0
  21. package/docs/ESLINTJSDOC.md +520 -0
  22. package/docs/FIELDSERVICE.md +4452 -0
  23. package/docs/GRAPHBINARY.md +208 -0
  24. package/docs/GRAPHENGINE.md +616 -0
  25. package/docs/GRAPHML.md +337 -0
  26. package/docs/GRAPHSON.md +302 -0
  27. package/docs/GREMLIN.md +490 -0
  28. package/docs/GRYO.md +232 -0
  29. package/docs/HUSKY.md +106 -0
  30. package/docs/JEST.md +387 -0
  31. package/docs/JORJE.md +537 -0
  32. package/docs/JSDOC.md +621 -0
  33. package/docs/PMD.md +910 -0
  34. package/docs/PNPM.md +409 -0
  35. package/docs/PRETTIER.md +716 -0
  36. package/docs/PRETTIERAPEX.md +874 -0
  37. package/docs/REVENUETRANSACTIONMANAGEMENT.md +887 -0
  38. package/docs/TINKERPOP.md +252 -0
  39. package/docs/VITEST.md +706 -0
  40. package/docs/VSCODE.md +231 -0
  41. package/docs/XPATH31.md +213 -0
  42. package/package.json +32 -0
  43. package/postinstall.mjs +51 -0
  44. package/prettier.config.js +18 -0
@@ -0,0 +1,716 @@
1
+ # Prettier Reference
2
+
3
+ > **Version**: 1.0.0
4
+
5
+ > **Architecture**: Parse → AST → Doc → Format. Plugins extend via
6
+ > parsers/printers. **Philosophy**: Opinionated, correctness over
7
+ > configurability, consistency across codebase.
8
+
9
+ ---
10
+
11
+ ## Core APIs
12
+
13
+ All APIs are **async**. For sync:
14
+ [@prettier/sync](https://github.com/prettier/prettier-synchronized)
15
+
16
+ | Function | Signature | Purpose |
17
+ | ------------------- | -------------------------------------------------------- | ------------------------------- |
18
+ | `format` | `(source, options?) → Promise<string>` | Format text |
19
+ | `formatWithCursor` | `(source, options) → Promise<{formatted, cursorOffset}>` | Format + track cursor |
20
+ | `check` | `(source, options?) → Promise<boolean>` | Check if formatted |
21
+ | `resolveConfig` | `(path, options?) → Promise<Options\|null>` | Resolve config for file |
22
+ | `resolveConfigFile` | `(path?) → Promise<string\|null>` | Find config file path |
23
+ | `clearConfigCache` | `() → Promise<void>` | Clear config cache |
24
+ | `getFileInfo` | `(file, options?) → Promise<{ignored, inferredParser}>` | Get file info |
25
+ | `getSupportInfo` | `(options?) → Promise<SupportInfo>` | Get supported languages/options |
26
+ | `version` | `string` | Prettier version |
27
+
28
+ ### Key Options
29
+
30
+ ```typescript
31
+ {
32
+ parser: string, // Required unless filepath provided
33
+ filepath?: string, // For parser inference
34
+ plugins?: Plugin[], // Plugins to use
35
+ printWidth?: number, // Default: 80
36
+ tabWidth?: number, // Default: 2
37
+ useTabs?: boolean, // Default: false
38
+ // ...all formatting options
39
+ }
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Debug APIs
45
+
46
+ Via `prettier.__debug` namespace (internal/testing):
47
+
48
+ | Function | Signature | Purpose |
49
+ | ------------------ | ----------------------------------------------------------------- | ----------------------------- |
50
+ | `parse` | `(text, options, devOptions?) → {ast, text}` | Parse to AST |
51
+ | `formatAST` | `(ast, options) → string` | Format AST directly |
52
+ | `formatDoc` | `(doc, options) → string` | Format Doc to string |
53
+ | `printToDoc` | `(text, options) → Doc` | Parse+print to Doc |
54
+ | `printDocToString` | `(doc, options) → {formatted, cursorNodeStart?, cursorNodeText?}` | Doc to string |
55
+ | `printDocToDebug` | `(doc) → string` | Doc to readable JS expression |
56
+
57
+ ### CLI Debug Options
58
+
59
+ ```bash
60
+ --debug-print-doc # Print Doc representation
61
+ --debug-print-ast # Print AST as JSON
62
+ --debug-print-comments # Print comments array
63
+ --debug-check # Verify idempotency
64
+ --debug-repeat N # Repeat N times, measure duration
65
+ --debug-benchmark # Performance mode
66
+ ```
67
+
68
+ ---
69
+
70
+ ## CLI
71
+
72
+ ```bash
73
+ prettier [options] [file/dir/glob ...]
74
+ ```
75
+
76
+ ### Exit Codes
77
+
78
+ | Code | Meaning |
79
+ | ---- | ----------------------- |
80
+ | 0 | Everything formatted |
81
+ | 1 | Unformatted files found |
82
+ | 2 | Prettier error |
83
+
84
+ ### Key Options
85
+
86
+ | Option | Description |
87
+ | ------------------------- | -------------------------- |
88
+ | `--write` (`-w`) | Format in-place |
89
+ | `--check` (`-c`) | Check formatting |
90
+ | `--list-different` (`-l`) | List unformatted files |
91
+ | `--debug-check` | Verify code correctness |
92
+ | `--config <path>` | Specify config file |
93
+ | `--no-config` | Ignore config files |
94
+ | `--ignore-path <path>` | Path to ignore file |
95
+ | `--cache` | Enable caching |
96
+ | `--cache-strategy` | `metadata` or `content` |
97
+ | `--stdin-filepath <path>` | Parser inference for stdin |
98
+
99
+ ---
100
+
101
+ ## Plugin API
102
+
103
+ ### Plugin Interface
104
+
105
+ ```typescript
106
+ interface Plugin<T = any> {
107
+ languages?: SupportLanguage[];
108
+ parsers?: { [name: string]: Parser<T> };
109
+ printers?: { [astFormat: string]: Printer<T> };
110
+ options?: SupportOptions;
111
+ defaultOptions?: Partial<RequiredOptions>;
112
+ }
113
+ ```
114
+
115
+ ### Parser Interface
116
+
117
+ ```typescript
118
+ interface Parser<T = any> {
119
+ parse: (text: string, options: ParserOptions<T>) => T | Promise<T>;
120
+ astFormat: string; // Must match printer key
121
+ locStart: (node: T) => number; // Required
122
+ locEnd: (node: T) => number; // Required
123
+ hasPragma?: (text: string) => boolean; // Detect @format/@prettier
124
+ hasIgnorePragma?: (text: string) => boolean; // Detect @prettier-ignore
125
+ preprocess?: (text: string, options) => string | Promise<string>;
126
+ }
127
+ ```
128
+
129
+ ### Printer Interface
130
+
131
+ ```typescript
132
+ interface Printer<T = any> {
133
+ // Required
134
+ print: (
135
+ path: AstPath<T>,
136
+ options: ParserOptions<T>,
137
+ print: (path) => Doc,
138
+ args?,
139
+ ) => Doc;
140
+
141
+ // Optional
142
+ embed?: (
143
+ path,
144
+ options,
145
+ ) => ((textToDoc, print, path, options) => Doc | Promise<Doc>) | Doc | null;
146
+ preprocess?: (ast: T, options) => T | Promise<T>;
147
+ massageAstNode?: (original, cloned, parent) => any;
148
+ hasPrettierIgnore?: (path: AstPath<T>) => boolean;
149
+ printPrettierIgnored?: (path, options, print, args?) => Doc;
150
+ insertPragma?: (text: string) => string;
151
+
152
+ // Comment handling
153
+ canAttachComment?: (node: T, ancestors: T[]) => boolean;
154
+ isBlockComment?: (node: T) => boolean;
155
+ printComment?: (commentPath: AstPath<T>, options) => Doc;
156
+ willPrintOwnComments?: (path: AstPath<T>) => boolean;
157
+ getCommentChildNodes?: (node: T, options) => T[] | undefined;
158
+ handleComments?: {
159
+ ownLine?: (comment, text, options, ast, isLast) => boolean;
160
+ endOfLine?: (comment, text, options, ast, isLast) => boolean;
161
+ remaining?: (comment, text, options, ast, isLast) => boolean;
162
+ };
163
+
164
+ // Traversal
165
+ getVisitorKeys?: (node: T, nonTraversableKeys: Set<string>) => string[];
166
+
167
+ // Features
168
+ features?: {
169
+ experimental_avoidAstMutation?: boolean;
170
+ experimental_frontMatterSupport?: { massageAstNode?; embed?; print? };
171
+ };
172
+ }
173
+ ```
174
+
175
+ ### SupportLanguage
176
+
177
+ ```typescript
178
+ interface SupportLanguage {
179
+ name: string; // Required
180
+ parsers: string[]; // Required
181
+ extensions?: string[]; // e.g., [".cls", ".trigger"]
182
+ filenames?: string[]; // e.g., ["Dockerfile"]
183
+ aliases?: string[];
184
+ interpreters?: string[]; // Shebang detection
185
+ group?: string;
186
+ tmScope?: string;
187
+ aceMode?: string;
188
+ codemirrorMode?: string;
189
+ codemirrorMimeType?: string;
190
+ linguistLanguageId?: number;
191
+ vscodeLanguageIds?: string[];
192
+ isSupported?: (options: { filepath: string }) => boolean;
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## AstPath API
199
+
200
+ ```typescript
201
+ class AstPath<T = any> {
202
+ // Properties
203
+ get key(): string | null; // Property key in parent
204
+ get index(): number | null; // Array index if in array
205
+ get node(): T; // Current node
206
+ get parent(): T | null; // Direct parent
207
+ get grandparent(): T | null;
208
+ get isInArray(): boolean;
209
+ get siblings(): T[] | null;
210
+ get next(): T | null;
211
+ get previous(): T | null;
212
+ get isFirst(): boolean;
213
+ get isLast(): boolean;
214
+ get isRoot(): boolean;
215
+ get root(): T;
216
+ get ancestors(): T[];
217
+
218
+ // Methods
219
+ call<U>(callback: (path) => U, ...props: PropertyKey[]): U;
220
+ each(callback: (path) => void, ...props: PropertyKey[]): void;
221
+ map<U>(callback: (path) => U, ...props: PropertyKey[]): U[];
222
+ callParent<U>(callback: (path) => U, count?: number): U;
223
+ getNode(count?: number): T | null;
224
+ getParentNode(count?: number): T | null;
225
+ match(...predicates: ((node, key, index) => boolean)[]): boolean;
226
+ }
227
+ ```
228
+
229
+ ### Usage Examples
230
+
231
+ ```typescript
232
+ // Print child property
233
+ path.call(print, 'body');
234
+
235
+ // Print nested property
236
+ path.call(print, 'dottedExpr', 'value');
237
+
238
+ // Map over array property
239
+ path.map(print, 'parameters'); // Returns Doc[]
240
+
241
+ // Get parent node
242
+ const parent = path.getParentNode();
243
+
244
+ // Check ancestry
245
+ path.match((node) => node.type === 'Function');
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Doc Builders
251
+
252
+ Via `prettier.doc.builders`:
253
+
254
+ ### Line Breaks
255
+
256
+ | Builder | Description |
257
+ | ------------- | ----------------------------------- |
258
+ | `line` | Soft break (breaks if group breaks) |
259
+ | `softline` | Soft break (prefer single line) |
260
+ | `hardline` | Always breaks |
261
+ | `literalline` | Preserves indentation |
262
+ | `breakParent` | Forces parent group to break |
263
+
264
+ ### Grouping & Indentation
265
+
266
+ | Builder | Signature | Description |
267
+ | ------------------ | ------------------------------ | --------------------------- |
268
+ | `group` | `(contents, options?) → Group` | Group with break behavior |
269
+ | `conditionalGroup` | `(states[], options?) → Doc` | Try states until one fits |
270
+ | `indent` | `(contents) → Indent` | Add one indent level |
271
+ | `dedent` | `(contents) → Doc` | Remove one indent level |
272
+ | `dedentToRoot` | `(contents) → Doc` | Remove all indentation |
273
+ | `align` | `(width, contents) → Align` | Align to column/string/root |
274
+ | `markAsRoot` | `(contents) → Align` | Mark alignment root |
275
+
276
+ ### Conditional
277
+
278
+ | Builder | Signature | Description |
279
+ | --------------- | ------------------------------------------------------ | ---------------------------- |
280
+ | `ifBreak` | `(breakContents, flatContents?, {groupId?}) → IfBreak` | Content based on break state |
281
+ | `indentIfBreak` | `(contents, {groupId, negate?}) → IndentIfBreak` | Indent if group breaks |
282
+
283
+ ### Layout
284
+
285
+ | Builder | Signature | Description |
286
+ | -------------------- | ----------------------------- | ------------------------ |
287
+ | `join` | `(separator, docs[]) → Doc[]` | Join with separator |
288
+ | `fill` | `(docs[]) → Fill` | Wrap like text |
289
+ | `lineSuffix` | `(contents) → LineSuffix` | Append after line break |
290
+ | `lineSuffixBoundary` | constant | Boundary for line suffix |
291
+ | `trim` | constant | Trim whitespace |
292
+ | `cursor` | constant | Cursor position marker |
293
+
294
+ ### Group Options
295
+
296
+ ```typescript
297
+ interface GroupOptions {
298
+ id?: symbol; // For ifBreak/indentIfBreak reference
299
+ shouldBreak?: boolean; // Force break
300
+ expandedStates?: Doc[]; // Alternative states
301
+ }
302
+ ```
303
+
304
+ ### Doc Type
305
+
306
+ ```typescript
307
+ type Doc = string | Doc[] | Group | Indent | Align | Line | IfBreak | Fill | ...
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Doc Utilities
313
+
314
+ Via `prettier.doc.utils`:
315
+
316
+ | Function | Signature | Description |
317
+ | ----------------------- | ------------------------------------------------------- | ------------------------ |
318
+ | `willBreak` | `(doc) → boolean` | Check if doc will break |
319
+ | `canBreak` | `(doc) → boolean` | Check if doc can break |
320
+ | `traverseDoc` | `(doc, onEnter?, onExit?, traverseConditional?) → void` | Traverse doc tree |
321
+ | `findInDoc` | `(doc, callback, defaultValue) → T` | Find value in doc |
322
+ | `mapDoc` | `(doc, callback) → T` | Map doc tree |
323
+ | `removeLines` | `(doc) → Doc` | Remove line breaks |
324
+ | `stripTrailingHardline` | `(doc) → Doc` | Remove trailing hardline |
325
+ | `replaceEndOfLine` | `(doc, replacement?) → Doc` | Replace end of line |
326
+
327
+ ---
328
+
329
+ ## Doc Printer
330
+
331
+ ```typescript
332
+ printDocToString(doc: Doc, options: {
333
+ printWidth: number;
334
+ tabWidth: number;
335
+ useTabs: boolean;
336
+ parentParser?: string;
337
+ }): { formatted: string; cursorNodeStart?: number; cursorNodeText?: string }
338
+ ```
339
+
340
+ ---
341
+
342
+ ## Options
343
+
344
+ ### RequiredOptions
345
+
346
+ | Option | Type | Default | Description |
347
+ | ---------------------------- | --------------------------------------- | ----------- | ------------------------- |
348
+ | `printWidth` | number | 80 | Max line width |
349
+ | `tabWidth` | number | 2 | Spaces per tab |
350
+ | `useTabs` | boolean | false | Use tabs |
351
+ | `semi` | boolean | true | Add semicolons |
352
+ | `singleQuote` | boolean | false | Use single quotes |
353
+ | `jsxSingleQuote` | boolean | false | Single quotes in JSX |
354
+ | `trailingComma` | `'none'\|'es5'\|'all'` | 'all' | Trailing commas |
355
+ | `bracketSpacing` | boolean | true | Spaces in object literals |
356
+ | `bracketSameLine` | boolean | false | `>` on same line in JSX |
357
+ | `arrowParens` | `'avoid'\|'always'` | 'always' | Arrow function parens |
358
+ | `proseWrap` | `'always'\|'never'\|'preserve'` | 'preserve' | Prose wrapping |
359
+ | `htmlWhitespaceSensitivity` | `'css'\|'strict'\|'ignore'` | 'css' | HTML whitespace |
360
+ | `endOfLine` | `'auto'\|'lf'\|'crlf'\|'cr'` | 'lf' | Line ending |
361
+ | `quoteProps` | `'as-needed'\|'consistent'\|'preserve'` | 'as-needed' | Object prop quotes |
362
+ | `embeddedLanguageFormatting` | `'auto'\|'off'` | 'auto' | Embedded languages |
363
+ | `singleAttributePerLine` | boolean | false | HTML/JSX attributes |
364
+ | `parser` | string | — | Parser name |
365
+ | `filepath` | string | — | File path (for inference) |
366
+ | `plugins` | Plugin[] | [] | Plugins |
367
+ | `requirePragma` | boolean | false | Require @format pragma |
368
+ | `insertPragma` | boolean | false | Insert pragma |
369
+
370
+ ### ParserOptions (extends RequiredOptions)
371
+
372
+ | Property | Type | Description |
373
+ | ---------------- | ------------------- | ---------------- |
374
+ | `locStart` | `(node) → number` | Node start index |
375
+ | `locEnd` | `(node) → number` | Node end index |
376
+ | `originalText` | string | Original source |
377
+ | `getVisitorKeys` | `(node) → string[]` | Keys to traverse |
378
+ | `printer` | Printer | Printer instance |
379
+
380
+ ### SupportOption
381
+
382
+ ```typescript
383
+ interface SupportOption {
384
+ type: 'int' | 'string' | 'boolean' | 'choice' | 'path';
385
+ category: string;
386
+ default?: Value | Array<{ value: Value }>;
387
+ description?: string;
388
+ deprecated?: true | string;
389
+ range?: { start: number; end: number };
390
+ choices?: Array<{ value: Value; description: string }>;
391
+ array?: boolean;
392
+ oppositeDescription?: string;
393
+ }
394
+ ```
395
+
396
+ ---
397
+
398
+ ## Config
399
+
400
+ ### Config Interface
401
+
402
+ ```typescript
403
+ interface Config extends Options {
404
+ overrides?: Array<{
405
+ files: string | string[]; // Glob patterns
406
+ excludeFiles?: string | string[];
407
+ options?: Options;
408
+ }>;
409
+ }
410
+ ```
411
+
412
+ ### Resolution Order
413
+
414
+ 1. `package.json` → `"prettier"` key
415
+ 2. `.prettierrc` (JSON/YAML)
416
+ 3. `.prettierrc.json`, `.prettierrc.yml`, `.prettierrc.yaml`,
417
+ `.prettierrc.json5`
418
+ 4. `.prettierrc.js`, `prettier.config.js`, `.prettierrc.ts`,
419
+ `prettier.config.ts`
420
+ 5. `.prettierrc.mjs`, `prettier.config.mjs`, `.prettierrc.mts`,
421
+ `prettier.config.mts`
422
+ 6. `.prettierrc.cjs`, `prettier.config.cjs`, `.prettierrc.cts`,
423
+ `prettier.config.cts`
424
+ 7. `.prettierrc.toml`
425
+
426
+ Search walks up directory tree. No global config.
427
+
428
+ ### EditorConfig Mapping
429
+
430
+ | EditorConfig | Prettier |
431
+ | ------------------------- | ------------ |
432
+ | `end_of_line` | `endOfLine` |
433
+ | `indent_style` | `useTabs` |
434
+ | `indent_size`/`tab_width` | `tabWidth` |
435
+ | `max_line_length` | `printWidth` |
436
+
437
+ ---
438
+
439
+ ## Utilities
440
+
441
+ Via `prettier.util`:
442
+
443
+ ### String
444
+
445
+ | Function | Signature | Description |
446
+ | ------------------ | ---------------------------------------- | ---------------------------- |
447
+ | `getStringWidth` | `(text) → number` | Visual width (Unicode-aware) |
448
+ | `getAlignmentSize` | `(text, tabWidth, startIndex?) → number` | Alignment size |
449
+ | `getIndentSize` | `(value, tabWidth) → number` | Indent size in spaces |
450
+ | `makeString` | `(rawText, quote, unescape?) → string` | Escape for quotes |
451
+
452
+ ### Skip Functions
453
+
454
+ All return `number | false`:
455
+
456
+ | Function | Purpose |
457
+ | --------------------------------------------------- | ------------------------------- |
458
+ | `skipWhitespace(text, idx, {backwards?})` | Skip whitespace |
459
+ | `skipSpaces(text, idx, {backwards?})` | Skip spaces |
460
+ | `skipNewline(text, idx, {backwards?})` | Skip newline |
461
+ | `skipInlineComment(text, idx)` | Skip `//` comment |
462
+ | `skipTrailingComment(text, idx)` | Skip trailing comment |
463
+ | `skipToLineEnd(text, idx, {backwards?})` | Skip to line end |
464
+ | `skipEverythingButNewLine(text, idx, {backwards?})` | Skip to newline |
465
+ | `skip(chars)` | Returns skip function for chars |
466
+
467
+ ### Check Functions
468
+
469
+ | Function | Signature | Returns |
470
+ | --------------------- | --------------------------- | ------- |
471
+ | `hasNewline` | `(text, idx, {backwards?})` | boolean |
472
+ | `hasNewlineInRange` | `(text, start, end)` | boolean |
473
+ | `hasSpaces` | `(text, idx, {backwards?})` | boolean |
474
+ | `isNextLineEmpty` | `(text, idx)` | boolean |
475
+ | `isPreviousLineEmpty` | `(text, idx)` | boolean |
476
+
477
+ ### Character
478
+
479
+ | Function | Signature | Returns |
480
+ | ----------------------------------------- | ---------------------- | --------------- |
481
+ | `getNextNonSpaceNonCommentCharacterIndex` | `(text, idx)` | number \| false |
482
+ | `getNextNonSpaceNonCommentCharacter` | `(text, idx)` | string |
483
+ | `getMaxContinuousCount` | `(text, searchString)` | number |
484
+
485
+ ### Quote
486
+
487
+ | Function | Signature | Returns |
488
+ | ------------------- | ------------------- | -------------- |
489
+ | `getPreferredQuote` | `(text, preferred)` | `'"'` or `"'"` |
490
+
491
+ ### Comment Attachment
492
+
493
+ | Function | Signature | Description |
494
+ | -------------------- | ------------------------- | -------------------- |
495
+ | `addLeadingComment` | `(node, comment)` | Add leading comment |
496
+ | `addTrailingComment` | `(node, comment)` | Add trailing comment |
497
+ | `addDanglingComment` | `(node, comment, marker)` | Add dangling comment |
498
+
499
+ ---
500
+
501
+ ## Architecture
502
+
503
+ ### Formatting Pipeline
504
+
505
+ 1. **Normalize** → BOM, EOL, indexes
506
+ 2. **Check pragmas** → requirePragma, checkIgnorePragma
507
+ 3. **Parse** → `parser.preprocess()` → `parser.parse()` → AST
508
+ 4. **Prepare** → Extract comments, attach to nodes, `printer.preprocess()`
509
+ 5. **Massage** → `printer.massageAstNode()` clones/transforms AST
510
+ 6. **Embed** → `printer.embed()` processes embedded languages
511
+ 7. **Print** → `printer.print()` → Doc (with caching)
512
+ 8. **Format** → `printDocToString()` → string
513
+ 9. **Insert pragma** → `printer.insertPragma()` if option set
514
+ 10. **Restore BOM**
515
+
516
+ ### Plugin Loading
517
+
518
+ - String/URL paths resolved via import
519
+ - Plugins cached by name + cwd
520
+ - Last plugin wins (override order)
521
+ - Parser/Printer can be lazy (function returns Parser/Printer)
522
+
523
+ ### Parser Resolution
524
+
525
+ 1. Search plugins in reverse order
526
+ 2. Match by parser name
527
+ 3. Parser must have matching printer via `astFormat`
528
+
529
+ ### Parser Inference
530
+
531
+ From filepath: extension → filename → shebang → isSupported function
532
+
533
+ ---
534
+
535
+ ## Symbols
536
+
537
+ ### Global (Symbol.for)
538
+
539
+ | Symbol | Purpose |
540
+ | ---------------------------------------- | ----------------------------- |
541
+ | `Symbol.for("comments")` | All comments array in options |
542
+ | `Symbol.for("printedComments")` | Set of printed comments |
543
+ | `Symbol.for("PRETTIER_IS_FRONT_MATTER")` | Front matter node marker |
544
+
545
+ ### Internal
546
+
547
+ | Symbol | Purpose |
548
+ | ------------------ | ----------------------------------- |
549
+ | `Symbol("cursor")` | Cursor marker in diff algorithm |
550
+ | Group ID Symbols | For ifBreak/indentIfBreak reference |
551
+
552
+ ---
553
+
554
+ ## Ignored Regions
555
+
556
+ ### Pragma Comments
557
+
558
+ | Language | Format |
559
+ | ------------- | -------------------------- |
560
+ | JavaScript | `// prettier-ignore` |
561
+ | JSX | `{/* prettier-ignore */}` |
562
+ | HTML/Markdown | `<!-- prettier-ignore -->` |
563
+ | CSS | `/* prettier-ignore */` |
564
+ | YAML/GraphQL | `# prettier-ignore` |
565
+ | Handlebars | `{{! prettier-ignore }}` |
566
+
567
+ ### Special
568
+
569
+ - HTML attributes: `<!-- prettier-ignore-attribute -->` or
570
+ `<!-- prettier-ignore-attribute (name) -->`
571
+ - Markdown range: `<!-- prettier-ignore-start -->` ...
572
+ `<!-- prettier-ignore-end -->`
573
+ - `.prettierignore` uses gitignore syntax
574
+
575
+ ### Default Ignores
576
+
577
+ `.git`, `.jj`, `.sl`, `.svn`, `.hg`, `node_modules`
578
+
579
+ ---
580
+
581
+ ## Comment Handling
582
+
583
+ ### Flow
584
+
585
+ 1. Extract from `AST.comments` array
586
+ 2. Attach via `decorateComment` (leading, trailing, dangling)
587
+ 3. Store in `options[Symbol.for("comments")]`
588
+ 4. Track printed in `options[Symbol.for("printedComments")]`
589
+ 5. Print via `printComments()` after node (unless `willPrintOwnComments`)
590
+
591
+ ### handleComments Parameters
592
+
593
+ Each handler receives:
594
+
595
+ ```typescript
596
+ (
597
+ comment: {
598
+ value: string;
599
+ location: { startIndex: number; endIndex: number };
600
+ trailing?: boolean;
601
+ leading?: boolean;
602
+ printed?: boolean;
603
+ enclosingNode?: any;
604
+ followingNode?: any;
605
+ precedingNode?: any;
606
+ placement: 'ownLine' | 'endOfLine' | 'remaining';
607
+ },
608
+ text: string,
609
+ options: ParserOptions,
610
+ ast: any,
611
+ isLastComment: boolean,
612
+ ) => boolean; // true = handled, false = let Prettier handle
613
+ ```
614
+
615
+ ---
616
+
617
+ ## Error Types
618
+
619
+ | Error | Description |
620
+ | ---------------------- | ----------------------------------------------- |
621
+ | `ConfigError` | Configuration errors (parser/printer not found) |
622
+ | `UndefinedParserError` | Parser could not be inferred |
623
+ | `InvalidDocError` | Invalid document structure |
624
+
625
+ ---
626
+
627
+ ## Browser/Standalone
628
+
629
+ ```typescript
630
+ import * as prettier from 'prettier/standalone';
631
+ import * as apexPlugin from 'prettier-plugin-apex';
632
+
633
+ await prettier.format(code, {
634
+ parser: 'apex',
635
+ plugins: [apexPlugin], // REQUIRED in standalone
636
+ });
637
+ ```
638
+
639
+ Plugins: `https://unpkg.com/prettier@VERSION/plugins/PLUGIN.mjs`
640
+
641
+ ---
642
+
643
+ ## Patterns
644
+
645
+ ### Plugin Structure
646
+
647
+ ```typescript
648
+ const plugin: Plugin = {
649
+ languages: [
650
+ { name: 'MyLang', parsers: ['my-parser'], extensions: ['.ext'] },
651
+ ],
652
+ parsers: {
653
+ 'my-parser': {
654
+ parse: (text, options) => parseToAST(text),
655
+ astFormat: 'my-ast',
656
+ locStart: (node) => node.start,
657
+ locEnd: (node) => node.end,
658
+ },
659
+ },
660
+ printers: {
661
+ 'my-ast': {
662
+ print: (path, options, print) => {
663
+ const node = path.node;
664
+ return doc.builders.group([
665
+ /* ... */
666
+ ]);
667
+ },
668
+ },
669
+ },
670
+ options: {
671
+ myOption: {
672
+ type: 'boolean',
673
+ category: 'Format',
674
+ default: false,
675
+ description: 'My option',
676
+ },
677
+ },
678
+ };
679
+ ```
680
+
681
+ ### Print Function
682
+
683
+ ```typescript
684
+ print: (path, options, print) => {
685
+ const node = path.node;
686
+ if (node.type === 'TypeA') return printTypeA(path, options, print);
687
+ return print('children');
688
+ };
689
+ ```
690
+
691
+ ### Embed Function
692
+
693
+ ```typescript
694
+ embed: (path, options) => {
695
+ const node = path.node;
696
+ if (isEmbeddedCode(node)) {
697
+ return async (textToDoc, print, path, options) => {
698
+ return await textToDoc(extractCode(node), { parser: 'javascript' });
699
+ };
700
+ }
701
+ return null;
702
+ };
703
+ ```
704
+
705
+ ---
706
+
707
+ ## Formatting Behavior Notes
708
+
709
+ | Behavior | Rule |
710
+ | ---------------------------- | ----------------------------------------------------------------- |
711
+ | **Quotes** | Fewest escapes wins; tie → double quotes |
712
+ | **Empty lines** | Preserved, multiple collapsed to one, removed at block boundaries |
713
+ | **Multi-line objects** | Preserved if newline exists between `{` and first key |
714
+ | **Print width** | Guideline, not hard rule; some exceptions allowed |
715
+ | **Comments** | Content unchanged, placement preserved roughly |
716
+ | **What Prettier doesn't do** | No transforms (quote conversion, string breaking, sorting) |