-
Notifications
You must be signed in to change notification settings - Fork 784
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
json formatting in code-block plugin
- Loading branch information
1 parent
016b7ee
commit 1383899
Showing
9 changed files
with
177 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
apps/www/src/registry/default/plate-ui/code-block-format-button.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
'use client'; | ||
|
||
import type { TElement } from '@udecode/plate'; | ||
|
||
import { useCodeBlockFormat } from '@udecode/plate-code-block/react'; | ||
import { BracesIcon } from 'lucide-react'; | ||
|
||
import { Button } from './button'; | ||
|
||
export function CodeBlockFormatButton({ element }: { element: TElement }) { | ||
const { format, isSupported, validSyntax } = useCodeBlockFormat({ | ||
element, | ||
}); | ||
|
||
if (!isSupported) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Button | ||
size="xs" | ||
variant="ghost" | ||
className="h-5 justify-between px-1 text-xs" | ||
disabled={!validSyntax} | ||
onClick={() => format()} | ||
title="Format code" | ||
> | ||
<BracesIcon className="text-gray-500" /> | ||
</Button> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { JsonFormatter } from './jsonFormatter'; | ||
|
||
export interface IFormatter { | ||
format: (code: string) => string; | ||
validSyntax: (code: string) => boolean; | ||
} | ||
|
||
const supportedLanguages = new Set(['json']); | ||
|
||
export class Formatter { | ||
format(code: string, lang?: string) { | ||
if (!lang || !supportedLanguages.has(lang)) { | ||
return ''; | ||
} | ||
|
||
switch (lang) { | ||
case 'json': { | ||
return new JsonFormatter().format(code); | ||
} | ||
} | ||
|
||
return code; | ||
} | ||
|
||
isLangSupported(lang?: string) { | ||
return lang && supportedLanguages.has(lang); | ||
} | ||
|
||
validSyntax(code: string, lang?: string) { | ||
if (!lang || !supportedLanguages.has(lang)) { | ||
return false; | ||
} | ||
|
||
switch (lang) { | ||
case 'json': { | ||
return new JsonFormatter().validSyntax(code); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* @file Automatically generated by barrelsby. | ||
*/ | ||
|
||
export * from './formatter'; | ||
export * from './jsonFormatter'; |
42 changes: 42 additions & 0 deletions
42
packages/code-block/src/lib/formatter/jsonFormatter.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { createEditor } from '@udecode/plate'; | ||
import { createPlateEditor } from '@udecode/plate/react'; | ||
|
||
import { JsonFormatter } from './jsonFormatter'; | ||
|
||
describe('JsonFormatter', () => { | ||
const formatter = new JsonFormatter(); | ||
|
||
it('should detect valid JSON', () => { | ||
const json = '{ "name": "ChatGPT", "type": "AI" }'; | ||
const isValid = formatter.validSyntax(json); | ||
expect(isValid).toBe(true); | ||
}); | ||
|
||
it('should detect invalid JSON', () => { | ||
const editor = createEditor(); | ||
const plateEditor = createPlateEditor({ editor }); | ||
const json = '{ name: "ChatGPT", type: AI }'; | ||
const isValid = formatter.validSyntax(json); | ||
expect(isValid).toBe(false); | ||
}); | ||
|
||
it('should format JSON', () => { | ||
const editor = createEditor(); | ||
const plateEditor = createPlateEditor({ editor }); | ||
const json = '{"name":"ChatGPT","type":"AI"}'; | ||
const formattedJson = formatter.format(json); | ||
const expected = `{ | ||
"name": "ChatGPT", | ||
"type": "AI" | ||
}`; | ||
expect(formattedJson).toBe(expected); | ||
}); | ||
|
||
it('should not format invalid JSON', () => { | ||
const editor = createEditor(); | ||
const plateEditor = createPlateEditor({ editor }); | ||
const json = '{ name: "ChatGPT", type: AI }'; | ||
const formattedJson = formatter.format(json); | ||
expect(formattedJson).toBe(json); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import type { IFormatter } from './formatter'; | ||
|
||
export class JsonFormatter implements IFormatter { | ||
format(code: string) { | ||
try { | ||
return JSON.stringify(JSON.parse(code), null, 2); | ||
} catch (error) { | ||
return code; | ||
} | ||
} | ||
|
||
validSyntax(code: string) { | ||
try { | ||
JSON.parse(code); | ||
|
||
return true; | ||
} catch (error) { | ||
return false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { useEditorRef } from '@udecode/plate/react'; | ||
|
||
import type { TCodeBlockElement } from '../../lib'; | ||
|
||
import { Formatter } from '../../lib/formatter/formatter'; | ||
|
||
export const useCodeBlockFormat = ({ | ||
element, | ||
}: { | ||
element: TCodeBlockElement; | ||
}) => { | ||
const editor = useEditorRef(); | ||
|
||
const { lang: language } = element; | ||
const code = editor.api.string(element); | ||
|
||
const formatter = new Formatter(); | ||
const isSupported = formatter.isLangSupported(language); | ||
|
||
const format = () => { | ||
const validSyntax = formatter.validSyntax(code, language); | ||
|
||
if (validSyntax) { | ||
const formattedCode = formatter.format(code, language); | ||
editor.tf.insertText(formattedCode, { at: element }); | ||
} | ||
}; | ||
|
||
const validSyntax = formatter.validSyntax(code, language); | ||
|
||
return { format, isSupported, validSyntax }; | ||
}; |