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 @@
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 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': '空數學公式', + }, +};