diff --git a/README.md b/README.md
index e619c0bf..4beae517 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
- **Diagrams & rich content**: [KaTeX](https://katex.org/) math, [Mermaid](https://mermaid.js.org/), [Vega/Vega-Lite](https://vega.github.io/), [PlantUML](https://plantuml.com/), and [Prism](https://prismjs.com/) syntax highlighting in code blocks.
- **Markdown ↔ HTML** round-trip via [`marked`](https://github.com/markedjs/marked) (read path) and [`turndown`](https://github.com/mixmark-io/turndown) + `joplin-turndown-plugin-gfm` (write path). `MarkdownToHtml` is exposed as a standalone utility; output passes through [DOMPurify](https://github.com/cure53/DOMPurify) (`sanitizeHyperlink` + `isValidAttribute`) for XSS-safe rendering.
- **Search and replace** with regex support, plus undo/redo history.
-- **i18n** out of the box: English, Chinese, and Japanese locales ship with the package.
+- **i18n** out of the box: 9 locales ship with the package — English, Simplified and Traditional Chinese, Japanese, Korean, Spanish, French, German, Portuguese.
- **JSON state model** built on [`ot-json1`](https://github.com/ottypes/json1) / [`ot-text-unicode`](https://github.com/ottypes/text-unicode) — wire it up to your own transport for collaborative editing.
- **TypeScript first** — types ship in the package, no extra `@types/*` install needed.
@@ -48,7 +48,7 @@ import {
TableColumnToolbar,
TableDragBar,
TableRowColumMenu,
- zh,
+ zhCN,
} from '@muyajs/core';
import '@muyajs/core/lib/style.css';
@@ -88,7 +88,7 @@ const muya = new Muya(container, {
});
// 3. Optional: switch the UI language before init.
-muya.locale(zh);
+muya.locale(zhCN);
// 4. Boot. Nothing renders until init() runs.
muya.init();
@@ -103,7 +103,7 @@ The `Muya` instance returned from `new Muya(el, options)` exposes:
| Method | Purpose |
| --- | --- |
| `init()` | Mount the editor and instantiate registered UI plugins. |
-| `locale(localeObject)` | Switch the UI locale. Use the bundled `en`, `zh`, `ja` exports or supply your own. |
+| `locale(localeObject)` | Switch the UI locale. Use one of the bundled exports (`en`, `zhCN`, `zhTW`, `ja`, `ko`, `es`, `fr`, `de`, `pt`) or supply your own. |
| `getMarkdown()` | Serialize the current document to Markdown. |
| `getState()` | Return the underlying JSON state (the source of truth). |
| `setContent(content, autoFocus?)` | Replace the document with Markdown (`string`) or `TState[]`. |
diff --git a/e2e/host/index.html b/e2e/host/index.html
index 492c19fc..b256c70f 100644
--- a/e2e/host/index.html
+++ b/e2e/host/index.html
@@ -9,8 +9,14 @@
English
- 中文
+ 简体中文
+ 繁體中文
日本語
+ 한국어
+ Español
+ Français
+ Deutsch
+ Português
Undo
Redo
diff --git a/e2e/host/main.ts b/e2e/host/main.ts
index 98529ec5..ce2ed695 100644
--- a/e2e/host/main.ts
+++ b/e2e/host/main.ts
@@ -1,15 +1,19 @@
/* eslint-disable antfu/no-top-level-await */
-import type { IMuyaOptions, TState } from '@muyajs/core';
+import type { ILocale, IMuyaOptions, TState } from '@muyajs/core';
import {
CodeBlockLanguageSelector,
+ de,
EmojiSelector,
en,
+ es,
FootnoteTool,
+ fr,
ImageEditTool,
ImageResizeBar,
ImageToolBar,
InlineFormatToolbar,
ja,
+ ko,
LinkTools,
MarkdownToHtml,
Muya,
@@ -17,10 +21,12 @@ import {
ParagraphFrontMenu,
ParagraphQuickInsertMenu,
PreviewToolBar,
+ pt,
TableColumnToolbar,
TableDragBar,
TableRowColumMenu,
- zh,
+ zhCN,
+ zhTW,
} from '@muyajs/core';
import './style.css';
@@ -130,14 +136,23 @@ window.__e2e = {
// Toolbar wiring (mirrors the buttons declared in index.html).
const $ = (id: string): T => document.querySelector(id)!;
+// Keys MUST match the `value` attributes in #language-select (e2e/host/index.html).
+const LOCALES: Record = {
+ 'en': en,
+ 'zh-CN': zhCN,
+ 'zh-TW': zhTW,
+ 'ja': ja,
+ 'ko': ko,
+ 'es': es,
+ 'fr': fr,
+ 'de': de,
+ 'pt': pt,
+};
+
$('#language-select').addEventListener('change', (event) => {
- const lang = (event.target as HTMLSelectElement).value;
- if (lang === 'en')
- muya.locale(en);
- else if (lang === 'ja')
- muya.locale(ja);
- else if (lang === 'zh')
- muya.locale(zh);
+ const locale = LOCALES[(event.target as HTMLSelectElement).value];
+ if (locale)
+ muya.locale(locale);
});
$('#undo').addEventListener('click', () => muya.undo());
diff --git a/e2e/tests/i18n/locale-switch.spec.ts b/e2e/tests/i18n/locale-switch.spec.ts
index 01d00512..31ad4d5d 100644
--- a/e2e/tests/i18n/locale-switch.spec.ts
+++ b/e2e/tests/i18n/locale-switch.spec.ts
@@ -2,12 +2,12 @@ import { expect, test } from '../fixtures/muya';
import { editor, floats, toolbar } from '../helpers/selectors';
test.describe('locale switch', () => {
- test('switching to zh flips muya.i18n.lang', async ({ page }) => {
+ test('switching to zh-CN flips muya.i18n.lang', async ({ page }) => {
const initial = await page.evaluate(() => window.muya!.i18n.lang);
expect(initial).toBe('en');
- await page.locator(toolbar.languageSelect).selectOption('zh');
+ await page.locator(toolbar.languageSelect).selectOption('zh-CN');
const after = await page.evaluate(() => window.muya!.i18n.lang);
- expect(after).toBe('zh');
+ expect(after).toBe('zh-CN');
});
test('switching to ja flips muya.i18n.lang', async ({ page }) => {
@@ -17,7 +17,7 @@ test.describe('locale switch', () => {
});
test('locale change is reflected in slash menu item labels', async ({ page }) => {
- await page.locator(toolbar.languageSelect).selectOption('zh');
+ await page.locator(toolbar.languageSelect).selectOption('zh-CN');
await page.evaluate(() => window.muya!.setContent(''));
await page.locator(editor.paragraph).first().click();
await page.keyboard.type('/');
diff --git a/e2e/tests/smoke/public-api.spec.ts b/e2e/tests/smoke/public-api.spec.ts
index 3f25c5cc..41f6b9fd 100644
--- a/e2e/tests/smoke/public-api.spec.ts
+++ b/e2e/tests/smoke/public-api.spec.ts
@@ -29,8 +29,8 @@ test.describe('public api', () => {
test('locale switch flips muya.i18n.lang', async ({ page }) => {
const before = await page.evaluate(() => window.muya!.i18n.lang);
expect(before).toBe('en');
- await page.locator('#language-select').selectOption('zh');
+ await page.locator('#language-select').selectOption('zh-CN');
const after = await page.evaluate(() => window.muya!.i18n.lang);
- expect(after).toBe('zh');
+ expect(after).toBe('zh-CN');
});
});
diff --git a/examples/index.html b/examples/index.html
index a4a025d1..96c3dcf8 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -15,9 +15,15 @@
Locale
Language:
- 中文
English
+ 简体中文
+ 繁體中文
日本語
+ 한국어
+ Español
+ Français
+ Deutsch
+ Português
diff --git a/examples/src/main.ts b/examples/src/main.ts
index 98fc6e48..64419264 100644
--- a/examples/src/main.ts
+++ b/examples/src/main.ts
@@ -2,14 +2,18 @@
import type { IMuyaOptions, TState } from '@muyajs/core';
import {
CodeBlockLanguageSelector,
+ de,
EmojiSelector,
en,
+ es,
FootnoteTool,
+ fr,
ImageEditTool,
ImageResizeBar,
ImageToolBar,
InlineFormatToolbar,
ja,
+ ko,
LinkTools,
MarkdownToHtml,
Muya,
@@ -17,10 +21,12 @@ import {
ParagraphFrontMenu,
ParagraphQuickInsertMenu,
PreviewToolBar,
+ pt,
TableColumnToolbar,
TableDragBar,
TableRowColumMenu,
- zh,
+ zhCN,
+ zhTW,
} from '@muyajs/core';
import { DEFAULT_MARKDOWN } from './data';
@@ -29,6 +35,7 @@ import './style.css';
// ---------- Firefox Intl.Segmenter polyfill ----------
+// eslint-disable-next-line no-restricted-syntax -- structural widening over the const Intl namespace; alternative is augmenting global Intl which leaks polyfill semantics into every consumer
const intlNs = Intl as unknown as { Segmenter?: typeof Intl.Segmenter };
if (!intlNs.Segmenter) {
const polyfill = await import('intl-segmenter-polyfill/dist/bundled');
@@ -73,10 +80,21 @@ Muya.use(PreviewToolBar);
// ---------- Mutable runtime state ----------
-const LOCALES = { zh, en, ja } as const;
+// Keys MUST match the `value` attributes in #language-select (examples/index.html).
+const LOCALES = {
+ 'en': en,
+ 'zh-CN': zhCN,
+ 'zh-TW': zhTW,
+ 'ja': ja,
+ 'ko': ko,
+ 'es': es,
+ 'fr': fr,
+ 'de': de,
+ 'pt': pt,
+} as const;
type TLocaleKey = keyof typeof LOCALES;
-let currentLocale: TLocaleKey = 'zh';
+let currentLocale: TLocaleKey = 'en';
// `satisfies` lets the literal stay structurally typed (Record-like for the form-driven mutation below) while still failing
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 632cd5eb..d3e0c3b3 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -1,4 +1,5 @@
-export { en, ja, zh } from './locales';
+export type { ILocale } from './i18n/types';
+export { de, en, es, fr, ja, ko, pt, zhCN, zhTW } from './locales';
export { Muya } from './muya';
export type { ITocItem } from './state/getTOC';
diff --git a/packages/core/src/locales/de.ts b/packages/core/src/locales/de.ts
new file mode 100644
index 00000000..b69c523e
--- /dev/null
+++ b/packages/core/src/locales/de.ts
@@ -0,0 +1,88 @@
+export const de = {
+ name: 'de',
+ resource: {
+ // tableTools
+ 'Insert Row Above': 'Zeile oberhalb einfügen',
+ 'Insert Row Below': 'Zeile unterhalb einfügen',
+ 'Remove Row': 'Zeile entfernen',
+ // tableColumnTools
+ 'Align Left': 'Linksbündig',
+ 'Align Center': 'Zentriert',
+ 'Align Right': 'Rechtsbündig',
+ 'Insert Column left': 'Spalte links einfügen',
+ 'Insert Column right': 'Spalte rechts einfügen',
+ 'Remove Column': 'Spalte entfernen',
+ // quickInsert
+ 'Paragraph': 'Absatz',
+ 'Horizontal Line': 'Horizontale Linie',
+ 'Front Matter': 'Front Matter',
+ 'Header 1': 'Überschrift 1',
+ 'Header 2': 'Überschrift 2',
+ 'Header 3': 'Überschrift 3',
+ 'Header 4': 'Überschrift 4',
+ 'Header 5': 'Überschrift 5',
+ 'Header 6': 'Überschrift 6',
+ 'Table Block': 'Tabelle',
+ 'Display Math': 'Mathematische Formel',
+ 'HTML Block': 'HTML-Block',
+ 'Code Block': 'Codeblock',
+ 'Quote Block': 'Zitat',
+ 'Order List': 'Nummerierte Liste',
+ 'Bullet List': 'Aufzählung',
+ 'To-do List': 'Aufgabenliste',
+ 'Vega Chart': 'Vega-Diagramm',
+ 'Mermaid': 'Mermaid',
+ 'Plantuml': 'Plantuml',
+ 'basic blocks': 'Grundblöcke',
+ 'headers': 'Überschriften',
+ 'advanced blocks': 'Erweiterte Blöcke',
+ 'list blocks': 'Listen',
+ 'diagrams': 'Diagramme',
+ 'No result': 'Kein Ergebnis',
+ 'Search keyword...': 'Suchbegriff...',
+ 'Type / to insert...': '/ eingeben zum Einfügen...',
+ // formatPicker
+ 'Emphasize': 'Fett',
+ 'Italic': 'Kursiv',
+ 'Underline': 'Unterstrichen',
+ 'Strikethrough': 'Durchgestrichen',
+ 'Highlight': 'Hervorheben',
+ 'Inline Code': 'Inline-Code',
+ 'Inline Math': 'Inline-Formel',
+ 'Link': 'Link',
+ 'Image': 'Bild',
+ 'Eliminate': 'Formatierung entfernen',
+ // Code block
+ 'Copy content': 'Inhalt kopieren',
+ 'Input Language Identifier...': 'Sprachkennung eingeben...',
+ // emojiPicker
+ 'Smileys & Emotion': 'Smileys & Emotionen',
+ 'People & Body': 'Menschen & Körper',
+ 'Animals & Nature': 'Tiere & Natur',
+ 'Food & Drink': 'Essen & Trinken',
+ 'Travel & Places': 'Reisen & Orte',
+ 'Activities': 'Aktivitäten',
+ 'Objects': 'Objekte',
+ 'Symbols': 'Symbole',
+ 'Flags': 'Flaggen',
+ // frontMenu
+ 'Duplicate': 'Duplizieren',
+ 'New Paragraph': 'Neuer Absatz',
+ 'Delete': 'Löschen',
+ // imageToolbar
+ 'Edit Image': 'Bild bearbeiten',
+ 'Inline Image': 'Inline-Bild',
+ 'Remove Image': 'Bild entfernen',
+ // ImageSelector
+ 'Image src placeholder': 'Bild-URL',
+ 'Confirm Text': 'OK',
+ // preview block
+ 'Loading...': 'Wird geladen...',
+ 'Invalid Diagram Code': 'Ungültiger Diagramm-Code',
+ 'Empty Diagram': 'Leeres Diagramm',
+ 'Input Mathematical Formula...': 'Mathematische Formel eingeben...',
+ 'Input Front Matter...': 'Front Matter eingeben...',
+ 'Invalid Mathematical Formula': 'Ungültige mathematische Formel',
+ 'Empty Mathematical Formula': 'Leere mathematische Formel',
+ },
+};
diff --git a/packages/core/src/locales/es.ts b/packages/core/src/locales/es.ts
new file mode 100644
index 00000000..09eb69ea
--- /dev/null
+++ b/packages/core/src/locales/es.ts
@@ -0,0 +1,88 @@
+export const es = {
+ name: 'es',
+ resource: {
+ // tableTools
+ 'Insert Row Above': 'Insertar fila arriba',
+ 'Insert Row Below': 'Insertar fila abajo',
+ 'Remove Row': 'Eliminar fila',
+ // tableColumnTools
+ 'Align Left': 'Alinear a la izquierda',
+ 'Align Center': 'Centrar',
+ 'Align Right': 'Alinear a la derecha',
+ 'Insert Column left': 'Insertar columna a la izquierda',
+ 'Insert Column right': 'Insertar columna a la derecha',
+ 'Remove Column': 'Eliminar columna',
+ // quickInsert
+ 'Paragraph': 'Párrafo',
+ 'Horizontal Line': 'Línea horizontal',
+ 'Front Matter': 'Front Matter',
+ 'Header 1': 'Encabezado 1',
+ 'Header 2': 'Encabezado 2',
+ 'Header 3': 'Encabezado 3',
+ 'Header 4': 'Encabezado 4',
+ 'Header 5': 'Encabezado 5',
+ 'Header 6': 'Encabezado 6',
+ 'Table Block': 'Tabla',
+ 'Display Math': 'Fórmula matemática',
+ 'HTML Block': 'Bloque HTML',
+ 'Code Block': 'Bloque de código',
+ 'Quote Block': 'Cita',
+ 'Order List': 'Lista ordenada',
+ 'Bullet List': 'Lista con viñetas',
+ 'To-do List': 'Lista de tareas',
+ 'Vega Chart': 'Gráfico Vega',
+ 'Mermaid': 'Mermaid',
+ 'Plantuml': 'Plantuml',
+ 'basic blocks': 'bloques básicos',
+ 'headers': 'encabezados',
+ 'advanced blocks': 'bloques avanzados',
+ 'list blocks': 'listas',
+ 'diagrams': 'diagramas',
+ 'No result': 'Sin resultados',
+ 'Search keyword...': 'Buscar palabra clave...',
+ 'Type / to insert...': 'Escribe / para insertar...',
+ // formatPicker
+ 'Emphasize': 'Negrita',
+ 'Italic': 'Cursiva',
+ 'Underline': 'Subrayado',
+ 'Strikethrough': 'Tachado',
+ 'Highlight': 'Resaltar',
+ 'Inline Code': 'Código en línea',
+ 'Inline Math': 'Fórmula en línea',
+ 'Link': 'Enlace',
+ 'Image': 'Imagen',
+ 'Eliminate': 'Quitar formato',
+ // Code block
+ 'Copy content': 'Copiar contenido',
+ 'Input Language Identifier...': 'Introducir identificador de lenguaje...',
+ // emojiPicker
+ 'Smileys & Emotion': 'Caras y emoción',
+ 'People & Body': 'Personas y cuerpo',
+ 'Animals & Nature': 'Animales y naturaleza',
+ 'Food & Drink': 'Comida y bebida',
+ 'Travel & Places': 'Viajes y lugares',
+ 'Activities': 'Actividades',
+ 'Objects': 'Objetos',
+ 'Symbols': 'Símbolos',
+ 'Flags': 'Banderas',
+ // frontMenu
+ 'Duplicate': 'Duplicar',
+ 'New Paragraph': 'Nuevo párrafo',
+ 'Delete': 'Eliminar',
+ // imageToolbar
+ 'Edit Image': 'Editar imagen',
+ 'Inline Image': 'Imagen en línea',
+ 'Remove Image': 'Eliminar imagen',
+ // ImageSelector
+ 'Image src placeholder': 'URL de la imagen',
+ 'Confirm Text': 'Aceptar',
+ // preview block
+ 'Loading...': 'Cargando...',
+ 'Invalid Diagram Code': 'Código de diagrama no válido',
+ 'Empty Diagram': 'Diagrama vacío',
+ 'Input Mathematical Formula...': 'Introducir fórmula matemática...',
+ 'Input Front Matter...': 'Introducir Front Matter...',
+ 'Invalid Mathematical Formula': 'Fórmula matemática no válida',
+ 'Empty Mathematical Formula': 'Fórmula matemática vacía',
+ },
+};
diff --git a/packages/core/src/locales/fr.ts b/packages/core/src/locales/fr.ts
new file mode 100644
index 00000000..63a49e6f
--- /dev/null
+++ b/packages/core/src/locales/fr.ts
@@ -0,0 +1,88 @@
+export const fr = {
+ name: 'fr',
+ resource: {
+ // tableTools
+ 'Insert Row Above': 'Insérer une ligne au-dessus',
+ 'Insert Row Below': 'Insérer une ligne en dessous',
+ 'Remove Row': 'Supprimer la ligne',
+ // tableColumnTools
+ 'Align Left': 'Aligner à gauche',
+ 'Align Center': 'Centrer',
+ 'Align Right': 'Aligner à droite',
+ 'Insert Column left': 'Insérer une colonne à gauche',
+ 'Insert Column right': 'Insérer une colonne à droite',
+ 'Remove Column': 'Supprimer la colonne',
+ // quickInsert
+ 'Paragraph': 'Paragraphe',
+ 'Horizontal Line': 'Ligne horizontale',
+ 'Front Matter': 'Front Matter',
+ 'Header 1': 'Titre 1',
+ 'Header 2': 'Titre 2',
+ 'Header 3': 'Titre 3',
+ 'Header 4': 'Titre 4',
+ 'Header 5': 'Titre 5',
+ 'Header 6': 'Titre 6',
+ 'Table Block': 'Tableau',
+ 'Display Math': 'Formule mathématique',
+ 'HTML Block': 'Bloc HTML',
+ 'Code Block': 'Bloc de code',
+ 'Quote Block': 'Citation',
+ 'Order List': 'Liste ordonnée',
+ 'Bullet List': 'Liste à puces',
+ 'To-do List': 'Liste de tâches',
+ 'Vega Chart': 'Graphique Vega',
+ 'Mermaid': 'Mermaid',
+ 'Plantuml': 'Plantuml',
+ 'basic blocks': 'blocs de base',
+ 'headers': 'titres',
+ 'advanced blocks': 'blocs avancés',
+ 'list blocks': 'listes',
+ 'diagrams': 'diagrammes',
+ 'No result': 'Aucun résultat',
+ 'Search keyword...': 'Rechercher un mot-clé...',
+ 'Type / to insert...': 'Tapez / pour insérer...',
+ // formatPicker
+ 'Emphasize': 'Gras',
+ 'Italic': 'Italique',
+ 'Underline': 'Souligné',
+ 'Strikethrough': 'Barré',
+ 'Highlight': 'Surligner',
+ 'Inline Code': 'Code en ligne',
+ 'Inline Math': 'Formule en ligne',
+ 'Link': 'Lien',
+ 'Image': 'Image',
+ 'Eliminate': 'Effacer le formatage',
+ // Code block
+ 'Copy content': 'Copier le contenu',
+ 'Input Language Identifier...': 'Saisir l\'identifiant de langage...',
+ // emojiPicker
+ 'Smileys & Emotion': 'Émoticônes & émotions',
+ 'People & Body': 'Personnes & corps',
+ 'Animals & Nature': 'Animaux & nature',
+ 'Food & Drink': 'Nourriture & boisson',
+ 'Travel & Places': 'Voyages & lieux',
+ 'Activities': 'Activités',
+ 'Objects': 'Objets',
+ 'Symbols': 'Symboles',
+ 'Flags': 'Drapeaux',
+ // frontMenu
+ 'Duplicate': 'Dupliquer',
+ 'New Paragraph': 'Nouveau paragraphe',
+ 'Delete': 'Supprimer',
+ // imageToolbar
+ 'Edit Image': 'Modifier l\'image',
+ 'Inline Image': 'Image en ligne',
+ 'Remove Image': 'Supprimer l\'image',
+ // ImageSelector
+ 'Image src placeholder': 'URL de l\'image',
+ 'Confirm Text': 'OK',
+ // preview block
+ 'Loading...': 'Chargement...',
+ 'Invalid Diagram Code': 'Code de diagramme invalide',
+ 'Empty Diagram': 'Diagramme vide',
+ 'Input Mathematical Formula...': 'Saisir la formule mathématique...',
+ 'Input Front Matter...': 'Saisir le Front Matter...',
+ 'Invalid Mathematical Formula': 'Formule mathématique invalide',
+ 'Empty Mathematical Formula': 'Formule mathématique vide',
+ },
+};
diff --git a/packages/core/src/locales/index.ts b/packages/core/src/locales/index.ts
index a159654d..d4ffd178 100644
--- a/packages/core/src/locales/index.ts
+++ b/packages/core/src/locales/index.ts
@@ -1,3 +1,9 @@
+export { de } from './de';
export { en } from './en';
+export { es } from './es';
+export { fr } from './fr';
export { ja } from './ja';
-export { zh } from './zh';
+export { ko } from './ko';
+export { pt } from './pt';
+export { zhCN } from './zh-CN';
+export { zhTW } from './zh-TW';
diff --git a/packages/core/src/locales/ja.ts b/packages/core/src/locales/ja.ts
index 6f19ff5c..6122691e 100644
--- a/packages/core/src/locales/ja.ts
+++ b/packages/core/src/locales/ja.ts
@@ -74,8 +74,8 @@ export const ja = {
'Inline Image': '行内画像',
'Remove Image': '画像を削除する',
// ImageSelector
- 'Image src placeholder': '图片链接',
- 'Confirm Text': '确定',
+ 'Image src placeholder': '画像のURL',
+ 'Confirm Text': 'OK',
// preview block
'Loading...': 'ロード中...',
'Invalid Diagram Code': 'グラフのレンダリングが失敗しました',
diff --git a/packages/core/src/locales/ko.ts b/packages/core/src/locales/ko.ts
new file mode 100644
index 00000000..d01c6486
--- /dev/null
+++ b/packages/core/src/locales/ko.ts
@@ -0,0 +1,88 @@
+export const ko = {
+ name: 'ko',
+ resource: {
+ // tableTools
+ 'Insert Row Above': '위에 행 삽입',
+ 'Insert Row Below': '아래에 행 삽입',
+ 'Remove Row': '행 삭제',
+ // tableColumnTools
+ 'Align Left': '왼쪽 정렬',
+ 'Align Center': '가운데 정렬',
+ 'Align Right': '오른쪽 정렬',
+ 'Insert Column left': '왼쪽에 열 삽입',
+ 'Insert Column right': '오른쪽에 열 삽입',
+ 'Remove Column': '열 삭제',
+ // quickInsert
+ 'Paragraph': '단락',
+ 'Horizontal Line': '수평선',
+ 'Front Matter': '머리말 블록',
+ 'Header 1': '제목 1',
+ 'Header 2': '제목 2',
+ 'Header 3': '제목 3',
+ 'Header 4': '제목 4',
+ 'Header 5': '제목 5',
+ 'Header 6': '제목 6',
+ 'Table Block': '표',
+ 'Display Math': '수식',
+ 'HTML Block': 'HTML 블록',
+ 'Code Block': '코드 블록',
+ 'Quote Block': '인용',
+ 'Order List': '번호 목록',
+ 'Bullet List': '글머리 기호 목록',
+ 'To-do List': '할 일 목록',
+ 'Vega Chart': 'Vega 차트',
+ 'Mermaid': 'Mermaid',
+ 'Plantuml': 'Plantuml',
+ 'basic blocks': '기본 블록',
+ 'headers': '제목',
+ 'advanced blocks': '고급 블록',
+ 'list blocks': '목록',
+ 'diagrams': '다이어그램',
+ 'No result': '결과 없음',
+ 'Search keyword...': '키워드 검색...',
+ 'Type / to insert...': '/ 입력하여 삽입...',
+ // formatPicker
+ 'Emphasize': '굵게',
+ 'Italic': '기울임',
+ 'Underline': '밑줄',
+ 'Strikethrough': '취소선',
+ 'Highlight': '강조',
+ 'Inline Code': '인라인 코드',
+ 'Inline Math': '인라인 수식',
+ 'Link': '링크',
+ 'Image': '이미지',
+ 'Eliminate': '서식 지우기',
+ // Code block
+ 'Copy content': '내용 복사',
+ 'Input Language Identifier...': '언어 식별자 입력...',
+ // emojiPicker
+ 'Smileys & Emotion': '스마일 & 감정',
+ 'People & Body': '사람 & 신체',
+ 'Animals & Nature': '동물 & 자연',
+ 'Food & Drink': '음식 & 음료',
+ 'Travel & Places': '여행 & 장소',
+ 'Activities': '활동',
+ 'Objects': '사물',
+ 'Symbols': '기호',
+ 'Flags': '국기',
+ // frontMenu
+ 'Duplicate': '단락 복제',
+ 'New Paragraph': '새 단락',
+ 'Delete': '단락 삭제',
+ // imageToolbar
+ 'Edit Image': '이미지 편집',
+ 'Inline Image': '인라인 이미지',
+ 'Remove Image': '이미지 삭제',
+ // ImageSelector
+ 'Image src placeholder': '이미지 URL',
+ 'Confirm Text': '확인',
+ // preview block
+ 'Loading...': '로딩 중...',
+ 'Invalid Diagram Code': '잘못된 다이어그램 코드',
+ 'Empty Diagram': '빈 다이어그램',
+ 'Input Mathematical Formula...': '수식 입력...',
+ 'Input Front Matter...': '머리말 입력...',
+ 'Invalid Mathematical Formula': '잘못된 수식',
+ 'Empty Mathematical Formula': '빈 수식',
+ },
+};
diff --git a/packages/core/src/locales/pt.ts b/packages/core/src/locales/pt.ts
new file mode 100644
index 00000000..dfada506
--- /dev/null
+++ b/packages/core/src/locales/pt.ts
@@ -0,0 +1,88 @@
+export const pt = {
+ name: 'pt',
+ resource: {
+ // tableTools
+ 'Insert Row Above': 'Inserir linha acima',
+ 'Insert Row Below': 'Inserir linha abaixo',
+ 'Remove Row': 'Remover linha',
+ // tableColumnTools
+ 'Align Left': 'Alinhar à esquerda',
+ 'Align Center': 'Centralizar',
+ 'Align Right': 'Alinhar à direita',
+ 'Insert Column left': 'Inserir coluna à esquerda',
+ 'Insert Column right': 'Inserir coluna à direita',
+ 'Remove Column': 'Remover coluna',
+ // quickInsert
+ 'Paragraph': 'Parágrafo',
+ 'Horizontal Line': 'Linha horizontal',
+ 'Front Matter': 'Front Matter',
+ 'Header 1': 'Título 1',
+ 'Header 2': 'Título 2',
+ 'Header 3': 'Título 3',
+ 'Header 4': 'Título 4',
+ 'Header 5': 'Título 5',
+ 'Header 6': 'Título 6',
+ 'Table Block': 'Tabela',
+ 'Display Math': 'Fórmula matemática',
+ 'HTML Block': 'Bloco HTML',
+ 'Code Block': 'Bloco de código',
+ 'Quote Block': 'Citação',
+ 'Order List': 'Lista ordenada',
+ 'Bullet List': 'Lista com marcadores',
+ 'To-do List': 'Lista de tarefas',
+ 'Vega Chart': 'Gráfico Vega',
+ 'Mermaid': 'Mermaid',
+ 'Plantuml': 'Plantuml',
+ 'basic blocks': 'blocos básicos',
+ 'headers': 'títulos',
+ 'advanced blocks': 'blocos avançados',
+ 'list blocks': 'listas',
+ 'diagrams': 'diagramas',
+ 'No result': 'Sem resultados',
+ 'Search keyword...': 'Buscar palavra-chave...',
+ 'Type / to insert...': 'Digite / para inserir...',
+ // formatPicker
+ 'Emphasize': 'Negrito',
+ 'Italic': 'Itálico',
+ 'Underline': 'Sublinhado',
+ 'Strikethrough': 'Tachado',
+ 'Highlight': 'Destacar',
+ 'Inline Code': 'Código em linha',
+ 'Inline Math': 'Fórmula em linha',
+ 'Link': 'Link',
+ 'Image': 'Imagem',
+ 'Eliminate': 'Limpar formatação',
+ // Code block
+ 'Copy content': 'Copiar conteúdo',
+ 'Input Language Identifier...': 'Inserir identificador de linguagem...',
+ // emojiPicker
+ 'Smileys & Emotion': 'Sorrisos & emoções',
+ 'People & Body': 'Pessoas & corpo',
+ 'Animals & Nature': 'Animais & natureza',
+ 'Food & Drink': 'Comida & bebida',
+ 'Travel & Places': 'Viagens & lugares',
+ 'Activities': 'Atividades',
+ 'Objects': 'Objetos',
+ 'Symbols': 'Símbolos',
+ 'Flags': 'Bandeiras',
+ // frontMenu
+ 'Duplicate': 'Duplicar',
+ 'New Paragraph': 'Novo parágrafo',
+ 'Delete': 'Excluir',
+ // imageToolbar
+ 'Edit Image': 'Editar imagem',
+ 'Inline Image': 'Imagem em linha',
+ 'Remove Image': 'Remover imagem',
+ // ImageSelector
+ 'Image src placeholder': 'URL da imagem',
+ 'Confirm Text': 'OK',
+ // preview block
+ 'Loading...': 'Carregando...',
+ 'Invalid Diagram Code': 'Código de diagrama inválido',
+ 'Empty Diagram': 'Diagrama vazio',
+ 'Input Mathematical Formula...': 'Inserir fórmula matemática...',
+ 'Input Front Matter...': 'Inserir Front Matter...',
+ 'Invalid Mathematical Formula': 'Fórmula matemática inválida',
+ 'Empty Mathematical Formula': 'Fórmula matemática vazia',
+ },
+};
diff --git a/packages/core/src/locales/zh.ts b/packages/core/src/locales/zh-CN.ts
similarity index 98%
rename from packages/core/src/locales/zh.ts
rename to packages/core/src/locales/zh-CN.ts
index 772b871c..af263e6f 100644
--- a/packages/core/src/locales/zh.ts
+++ b/packages/core/src/locales/zh-CN.ts
@@ -1,5 +1,5 @@
-export const zh = {
- name: 'zh',
+export const zhCN = {
+ name: 'zh-CN',
resource: {
// tableTools
'Insert Row Above': '上面插入行',
diff --git a/packages/core/src/locales/zh-TW.ts b/packages/core/src/locales/zh-TW.ts
new file mode 100644
index 00000000..18967914
--- /dev/null
+++ b/packages/core/src/locales/zh-TW.ts
@@ -0,0 +1,88 @@
+export const zhTW = {
+ name: 'zh-TW',
+ resource: {
+ // tableTools
+ 'Insert Row Above': '在上方插入列',
+ 'Insert Row Below': '在下方插入列',
+ 'Remove Row': '刪除所在列',
+ // tableColumnTools
+ 'Align Left': '靠左對齊',
+ 'Align Center': '置中對齊',
+ 'Align Right': '靠右對齊',
+ 'Insert Column left': '在左邊插入欄',
+ 'Insert Column right': '在右邊插入欄',
+ 'Remove Column': '刪除所在欄',
+ // quickInsert
+ 'Paragraph': '一般段落',
+ 'Horizontal Line': '水平分隔線',
+ 'Front Matter': '頂部資訊區塊',
+ 'Header 1': '標題 1',
+ 'Header 2': '標題 2',
+ 'Header 3': '標題 3',
+ 'Header 4': '標題 4',
+ 'Header 5': '標題 5',
+ 'Header 6': '標題 6',
+ 'Table Block': '表格',
+ 'Display Math': '數學公式',
+ 'HTML Block': 'HTML 區塊',
+ 'Code Block': '程式碼區塊',
+ 'Quote Block': '引言',
+ 'Order List': '有序清單',
+ 'Bullet List': '無序清單',
+ 'To-do List': '待辦清單',
+ 'Vega Chart': 'Vega 圖',
+ 'Mermaid': 'Mermaid',
+ 'Plantuml': 'Plantuml',
+ 'basic blocks': '基礎區塊',
+ 'headers': '標題',
+ 'advanced blocks': '進階區塊',
+ 'list blocks': '清單',
+ 'diagrams': '圖表',
+ 'No result': '無結果',
+ 'Search keyword...': '搜尋關鍵字...',
+ 'Type / to insert...': '輸入 / 插入段落',
+ // formatPicker
+ 'Emphasize': '粗體',
+ 'Italic': '斜體',
+ 'Underline': '底線',
+ 'Strikethrough': '刪除線',
+ 'Highlight': '醒目提示',
+ 'Inline Code': '行內程式碼',
+ 'Inline Math': '行內數學公式',
+ 'Link': '超連結',
+ 'Image': '圖片',
+ 'Eliminate': '清除樣式',
+ // Code block
+ 'Copy content': '複製內容',
+ 'Input Language Identifier...': '輸入程式語言識別碼...',
+ // emojiPicker
+ 'Smileys & Emotion': '笑臉 & 情緒',
+ 'People & Body': '人物 & 身體',
+ 'Animals & Nature': '動物 & 自然',
+ 'Food & Drink': '食物 & 飲料',
+ 'Travel & Places': '旅遊 & 地點',
+ 'Activities': '活動',
+ 'Objects': '物件',
+ 'Symbols': '符號',
+ 'Flags': '旗幟',
+ // frontMenu
+ 'Duplicate': '複製段落',
+ 'New Paragraph': '新增段落',
+ 'Delete': '刪除段落',
+ // imageToolbar
+ 'Edit Image': '編輯圖片',
+ 'Inline Image': '行內圖片',
+ 'Remove Image': '刪除圖片',
+ // ImageSelector
+ 'Image src placeholder': '圖片連結',
+ 'Confirm Text': '確定',
+ // preview block
+ 'Loading...': '載入中...',
+ 'Invalid Diagram Code': '圖表渲染失敗',
+ 'Empty Diagram': '空圖表',
+ 'Input Mathematical Formula...': '輸入數學公式...',
+ 'Input Front Matter...': '輸入頁首資訊...',
+ 'Invalid Mathematical Formula': '數學公式錯誤',
+ 'Empty Mathematical Formula': '空數學公式',
+ },
+};