Skip to content

Commit 19b4e39

Browse files
janfrlantfu
andauthoredMay 13, 2024··
feat: support xml (#472)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
1 parent 76443cc commit 19b4e39

File tree

11 files changed

+141
-9
lines changed

11 files changed

+141
-9
lines changed
 

‎.vscode/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"json",
4040
"jsonc",
4141
"yaml",
42-
"toml"
42+
"toml",
43+
"xml"
4344
],
4445

4546
"pair-diff.patterns": [

‎README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
- Opinionated, but [very customizable](#customization)
99
- [ESLint Flat config](https://eslint.org/docs/latest/use/configure/configuration-files-new), compose easily!
1010
- Optional [React](#react), [Svelte](#svelte), [UnoCSS](#unocss), [Astro](#astro), [Solid](#solid) support
11-
- Optional [formatters](#formatters) support for formatting CSS, HTML, etc.
11+
- Optional [formatters](#formatters) support for formatting CSS, HTML, XML, etc.
1212
- **Style principle**: Minimal for reading, stable for diff, consistent
1313
- Sorted imports, dangling commas
1414
- Single quotes, no semi
@@ -143,6 +143,7 @@ Add the following settings to your `.vscode/settings.json`:
143143
"jsonc",
144144
"yaml",
145145
"toml",
146+
"xml",
146147
"gql",
147148
"graphql",
148149
"astro"

‎fixtures/input/xml.xml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<store>
2+
<product id= "01" category="books" stock="available"><name>Effective Java</name><price currency='USD'>45.00</price></product>
3+
<product id="02" category="electronics" stock="unavailable" ><name>Bluetooth Speaker</name><price currency='USD'>120.00</price></product>
4+
<product id="03" category="books" stock="available" ><name>Clean Code</name>
5+
<price currency='USD'>33.50</price>
6+
</product>
7+
<membership level="gold" id="001"> <user Name="John Doe"/> </membership>
8+
<membership level="silver" id="002"> <user Name="Jane Smith"></user> </membership>
9+
</store>
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<store>
2+
<product id="01" category="books" stock="available">
3+
<name>Effective Java</name>
4+
<price currency="USD">45.00</price>
5+
</product>
6+
<product id="02" category="electronics" stock="unavailable">
7+
<name>Bluetooth Speaker</name>
8+
<price currency="USD">120.00</price>
9+
</product>
10+
<product id="03" category="books" stock="available">
11+
<name>Clean Code</name>
12+
<price currency="USD">33.50</price>
13+
</product>
14+
<membership level="gold" id="001">
15+
<user Name="John Doe" />
16+
</membership>
17+
<membership level="silver" id="002">
18+
<user Name="Jane Smith" />
19+
</membership>
20+
</store>

‎package.json

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
},
4141
"peerDependencies": {
4242
"@eslint-react/eslint-plugin": "^1.5.8",
43+
"@prettier/plugin-xml": "^3.4.1",
4344
"@unocss/eslint-plugin": ">=0.50.0",
4445
"astro-eslint-parser": "^0.16.3",
4546
"eslint": ">=8.40.0",
@@ -57,6 +58,9 @@
5758
"@eslint-react/eslint-plugin": {
5859
"optional": true
5960
},
61+
"@prettier/plugin-xml": {
62+
"optional": true
63+
},
6064
"@unocss/eslint-plugin": {
6165
"optional": true
6266
},
@@ -133,6 +137,7 @@
133137
"@antfu/ni": "^0.21.12",
134138
"@eslint-react/eslint-plugin": "^1.5.11",
135139
"@eslint/config-inspector": "^0.4.8",
140+
"@prettier/plugin-xml": "^3.4.1",
136141
"@stylistic/eslint-plugin-migrate": "^2.1.0",
137142
"@types/eslint": "^8.56.10",
138143
"@types/fs-extra": "^11.0.4",

‎pnpm-lock.yaml

+36-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/cli/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export const vscodeSettingsString = `
4646
"jsonc",
4747
"yaml",
4848
"toml",
49+
"xml",
4950
"gql",
5051
"graphql",
5152
"astro"

‎src/configs/formatters.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { isPackageExists } from 'local-pkg'
2-
import { GLOB_ASTRO, GLOB_CSS, GLOB_GRAPHQL, GLOB_HTML, GLOB_LESS, GLOB_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS } from '../globs'
2+
import { GLOB_ASTRO, GLOB_CSS, GLOB_GRAPHQL, GLOB_HTML, GLOB_LESS, GLOB_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_XML } from '../globs'
33
import type { VendoredPrettierOptions } from '../vender/prettier-types'
44
import { ensurePackages, interopDefault, parserPlain } from '../utils'
55
import type { OptionsFormatters, StylisticConfig, TypedFlatConfigItem } from '../types'
@@ -17,13 +17,15 @@ export async function formatters(
1717
html: true,
1818
markdown: true,
1919
slidev: isPackageExists('@slidev/cli'),
20+
xml: isPackageExists('@prettier/plugin-xml'),
2021
}
2122
}
2223

2324
await ensurePackages([
2425
'eslint-plugin-format',
2526
options.markdown && options.slidev ? 'prettier-plugin-slidev' : undefined,
2627
options.astro ? 'prettier-plugin-astro' : undefined,
28+
options.xml ? '@prettier/plugin-xml' : undefined,
2729
])
2830

2931
if (options.slidev && options.markdown !== true && options.markdown !== 'prettier')
@@ -50,6 +52,13 @@ export async function formatters(
5052
options.prettierOptions || {},
5153
)
5254

55+
const prettierXmlOptions = {
56+
xmlQuoteAttributes: 'double',
57+
xmlSelfClosingSpace: true,
58+
xmlSortAttributesByKey: false,
59+
xmlWhitespaceSensitivity: 'ignore',
60+
}
61+
5362
const dprintOptions = Object.assign(
5463
{
5564
indentWidth: typeof indent === 'number' ? indent : 2,
@@ -142,6 +151,29 @@ export async function formatters(
142151
})
143152
}
144153

154+
if (options.xml) {
155+
configs.push({
156+
files: [GLOB_XML],
157+
languageOptions: {
158+
parser: parserPlain,
159+
},
160+
name: 'antfu/formatter/xml',
161+
rules: {
162+
'format/prettier': [
163+
'error',
164+
{
165+
...prettierXmlOptions,
166+
...prettierOptions,
167+
parser: 'xml',
168+
plugins: [
169+
'@prettier/plugin-xml',
170+
],
171+
},
172+
],
173+
},
174+
})
175+
}
176+
145177
if (options.markdown) {
146178
const formater = options.markdown === true
147179
? 'prettier'

‎src/globs.ts

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export const GLOB_SVELTE = '**/*.svelte'
2323
export const GLOB_VUE = '**/*.vue'
2424
export const GLOB_YAML = '**/*.y?(a)ml'
2525
export const GLOB_TOML = '**/*.toml'
26+
export const GLOB_XML = '**/*.xml'
2627
export const GLOB_HTML = '**/*.htm?(l)'
2728
export const GLOB_ASTRO = '**/*.astro'
2829
export const GLOB_GRAPHQL = '**/*.{g,graph}ql'
@@ -46,6 +47,7 @@ export const GLOB_ALL_SRC = [
4647
GLOB_SVELTE,
4748
GLOB_VUE,
4849
GLOB_YAML,
50+
GLOB_XML,
4951
GLOB_HTML,
5052
]
5153

‎src/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ export interface OptionsFormatters {
6565
*/
6666
html?: 'prettier' | boolean
6767

68+
/**
69+
* Enable formatting support for XML.
70+
*
71+
* Currently only support Prettier.
72+
*/
73+
xml?: 'prettier' | boolean
74+
6875
/**
6976
* Enable formatting support for Markdown.
7077
*

‎src/vender/prettier-types.ts

+24-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export interface VendoredPrettierOptionsRequired {
3939
*/
4040
bracketSpacing: boolean
4141
/**
42-
* Put the `>` of a multi-line HTML (HTML, JSX, Vue, Angular) element at the end of the last line instead of being
42+
* Put the `>` of a multi-line HTML (HTML, XML, JSX, Vue, Angular) element at the end of the last line instead of being
4343
* alone on the next line (does not apply to self closing elements).
4444
*/
4545
bracketSameLine: boolean
@@ -93,10 +93,31 @@ export interface VendoredPrettierOptionsRequired {
9393
*/
9494
vueIndentScriptAndStyle: boolean
9595
/**
96-
* Enforce single attribute per line in HTML, Vue and JSX.
96+
* Enforce single attribute per line in HTML, XML, Vue and JSX.
9797
* @default false
9898
*/
9999
singleAttributePerLine: boolean
100+
101+
/**
102+
* How to handle whitespaces in XML.
103+
* @default "preserve"
104+
*/
105+
xmlQuoteAttributes: 'single' | 'double' | 'preserve'
106+
/**
107+
* Whether to put a space inside the brackets of self-closing XML elements.
108+
* @default true
109+
*/
110+
xmlSelfClosingSpace: boolean
111+
/**
112+
* Whether to sort attributes by key in XML elements.
113+
* @default false
114+
*/
115+
xmlSortAttributesByKey: boolean
116+
/**
117+
* How to handle whitespaces in XML.
118+
* @default "ignore"
119+
*/
120+
xmlWhitespaceSensitivity: 'ignore' | 'strict' | 'preserve'
100121
}
101122

102123
export type BuiltInParserName =
@@ -122,6 +143,7 @@ export type BuiltInParserName =
122143
| 'scss'
123144
| 'typescript'
124145
| 'vue'
146+
| 'xml'
125147
| 'yaml'
126148

127149
// This utility is here to handle the case where you have an explicit union

0 commit comments

Comments
 (0)
Please sign in to comment.