@takazudo/mdx-formatter 0.4.2 → 0.5.0-next.1
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.
- package/dist/hybrid-formatter.js +13 -3
- package/dist/index.js +13 -2
- package/dist/rust-formatter.d.ts +15 -0
- package/dist/rust-formatter.js +35 -0
- package/package.json +5 -22
package/dist/hybrid-formatter.js
CHANGED
|
@@ -941,14 +941,24 @@ export class HybridFormatter {
|
|
|
941
941
|
}
|
|
942
942
|
return;
|
|
943
943
|
}
|
|
944
|
+
// Find the actual end of the opening tag (may span multiple lines
|
|
945
|
+
// for elements with attributes like <Danger\n title="..."\n>)
|
|
946
|
+
let openingTagEndLine = startLine;
|
|
947
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
948
|
+
const trimmed = this.lines[i].trim();
|
|
949
|
+
if (trimmed.endsWith('>') && !trimmed.endsWith('/>') && !trimmed.startsWith('</')) {
|
|
950
|
+
openingTagEndLine = i;
|
|
951
|
+
break;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
944
954
|
// Check if there's an empty line after the opening tag
|
|
945
|
-
if (
|
|
946
|
-
const lineAfterOpening = this.lines[
|
|
955
|
+
if (openingTagEndLine + 1 < this.lines.length) {
|
|
956
|
+
const lineAfterOpening = this.lines[openingTagEndLine + 1];
|
|
947
957
|
if (lineAfterOpening.trim() !== '') {
|
|
948
958
|
// Add empty line after opening tag
|
|
949
959
|
operations.push({
|
|
950
960
|
type: 'insertLine',
|
|
951
|
-
startLine:
|
|
961
|
+
startLine: openingTagEndLine + 1,
|
|
952
962
|
content: '',
|
|
953
963
|
});
|
|
954
964
|
}
|
package/dist/index.js
CHANGED
|
@@ -19,8 +19,19 @@ export function detectMdx(content) {
|
|
|
19
19
|
export async function format(content, options = {}) {
|
|
20
20
|
try {
|
|
21
21
|
const settings = loadConfig(options);
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
let result = content;
|
|
23
|
+
// Some rule interactions (e.g., list indent normalization + addEmptyLinesInBlockJsx)
|
|
24
|
+
// may require multiple passes to converge. 3 iterations is sufficient for all known
|
|
25
|
+
// cases (most files converge in 1, edge cases in 2).
|
|
26
|
+
const MAX_ITERATIONS = 3;
|
|
27
|
+
for (let i = 0; i < MAX_ITERATIONS; i++) {
|
|
28
|
+
const formatter = new HybridFormatter(result, settings);
|
|
29
|
+
const formatted = await formatter.format();
|
|
30
|
+
if (formatted === result)
|
|
31
|
+
break;
|
|
32
|
+
result = formatted;
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
24
35
|
}
|
|
25
36
|
catch {
|
|
26
37
|
// Silently return original content if formatting fails
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper for the Rust napi formatter.
|
|
3
|
+
* This module loads the native Rust formatter compiled via napi-rs
|
|
4
|
+
* and exposes the same format() API as the TypeScript implementation.
|
|
5
|
+
*/
|
|
6
|
+
import type { FormatOptions } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Check if the Rust formatter is available
|
|
9
|
+
*/
|
|
10
|
+
export declare function isRustFormatterAvailable(): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Format markdown/MDX content using the Rust formatter
|
|
13
|
+
* API-compatible with the TypeScript format() function
|
|
14
|
+
*/
|
|
15
|
+
export declare function format(content: string, options?: FormatOptions): Promise<string>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper for the Rust napi formatter.
|
|
3
|
+
* This module loads the native Rust formatter compiled via napi-rs
|
|
4
|
+
* and exposes the same format() API as the TypeScript implementation.
|
|
5
|
+
*/
|
|
6
|
+
import { createRequire } from 'module';
|
|
7
|
+
import { loadConfig } from './load-config.js';
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
// Try to load the native module
|
|
10
|
+
let nativeFormat = null;
|
|
11
|
+
try {
|
|
12
|
+
const native = require('../crates/mdx-formatter-napi/mdx-formatter-napi.node');
|
|
13
|
+
nativeFormat = native.format;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Native module not available - not built yet or wrong platform
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if the Rust formatter is available
|
|
20
|
+
*/
|
|
21
|
+
export function isRustFormatterAvailable() {
|
|
22
|
+
return nativeFormat !== null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Format markdown/MDX content using the Rust formatter
|
|
26
|
+
* API-compatible with the TypeScript format() function
|
|
27
|
+
*/
|
|
28
|
+
export async function format(content, options = {}) {
|
|
29
|
+
if (!nativeFormat) {
|
|
30
|
+
throw new Error('Rust formatter not available. Build it first with: cd crates/mdx-formatter-napi && cargo build');
|
|
31
|
+
}
|
|
32
|
+
const settings = loadConfig(options);
|
|
33
|
+
const settingsJson = JSON.stringify(settings);
|
|
34
|
+
return nativeFormat(content, settingsJson);
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takazudo/mdx-formatter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-next.1",
|
|
4
4
|
"description": "AST-based markdown and MDX formatter with Japanese text support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,29 +33,13 @@
|
|
|
33
33
|
"lint:fix": "eslint --fix .",
|
|
34
34
|
"check": "prettier --check . && eslint .",
|
|
35
35
|
"check:fix": "prettier --write . && eslint --fix .",
|
|
36
|
+
"test:rust": "vitest run --config vitest.rust.config.ts",
|
|
37
|
+
"build:rust": "cd crates/mdx-formatter-napi && cargo build",
|
|
38
|
+
"build:rust:release": "cd crates/mdx-formatter-napi && cargo build --release",
|
|
36
39
|
"b4push": "./scripts/run-b4push.sh",
|
|
37
40
|
"doc:start": "pnpm --dir doc start",
|
|
38
|
-
"prepare": "husky",
|
|
39
41
|
"prepublishOnly": "tsc && vitest run"
|
|
40
42
|
},
|
|
41
|
-
"lint-staged": {
|
|
42
|
-
"*.{js,mjs,ts}": [
|
|
43
|
-
"prettier --write",
|
|
44
|
-
"eslint --fix"
|
|
45
|
-
],
|
|
46
|
-
"*.{json,yml,yaml}": [
|
|
47
|
-
"prettier --write"
|
|
48
|
-
],
|
|
49
|
-
".claude/**/*.md": [
|
|
50
|
-
"prettier --write"
|
|
51
|
-
],
|
|
52
|
-
"doc/src/**/*.{ts,tsx,js,jsx,css}": [
|
|
53
|
-
"prettier --write"
|
|
54
|
-
],
|
|
55
|
-
"doc/docs/**/*.{md,mdx}": [
|
|
56
|
-
"npx tsx src/cli.ts --write"
|
|
57
|
-
]
|
|
58
|
-
},
|
|
59
43
|
"keywords": [
|
|
60
44
|
"markdown",
|
|
61
45
|
"mdx",
|
|
@@ -102,8 +86,7 @@
|
|
|
102
86
|
"@types/unist": "^3.0.3",
|
|
103
87
|
"@vitest/coverage-v8": "^4.0.17",
|
|
104
88
|
"eslint": "^9.39.2",
|
|
105
|
-
"
|
|
106
|
-
"lint-staged": "^16.2.7",
|
|
89
|
+
"lefthook": "^2.1.4",
|
|
107
90
|
"typescript": "^5.9.3",
|
|
108
91
|
"typescript-eslint": "^8.54.0",
|
|
109
92
|
"vfile": "^6.0.3",
|