From 91deda2a723086b702d333334a2d6907d85e1053 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 5 Apr 2024 22:41:07 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=94=A7=20build:=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20yaml=20i18n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++- README_zh_CN.md | 5 ++- package.json | 1 + public/i18n/en_US.yaml | 0 public/i18n/zh_CN.json | 21 ------------- public/i18n/zh_CN.yaml | 21 +++++++++++++ vite.config.ts | 11 +++++-- yaml-plugin.js | 69 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 108 insertions(+), 25 deletions(-) create mode 100644 public/i18n/en_US.yaml delete mode 100644 public/i18n/zh_CN.json create mode 100644 public/i18n/zh_CN.yaml create mode 100644 yaml-plugin.js diff --git a/README.md b/README.md index 981ca43..3a6e717 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,11 @@ complete the following tasks: * Meta information about the plugin itself, such as plugin description and readme * `description` and `readme` fields in plugin.json, and the corresponding README*.md file * Text used in the plugin, such as button text and tooltips - * src/i18n/*.json language configuration files + * public/i18n/*.json language configuration files * Use `this.i18.key` to get the text in the code +* YAML Support + * This template specifically supports I18n based on YAML syntax, see `public/i18n/zh_CN.yaml` + * During compilation, the defined YAML files will be automatically translated into JSON files and placed in the dist or dev directory. It is recommended that the plugin supports at least English and Simplified Chinese, so that more people can use it more conveniently. diff --git a/README_zh_CN.md b/README_zh_CN.md index b2d3ad3..6b46f16 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -62,9 +62,12 @@ * 插件自身的元信息,比如插件描述和自述文件 * plugin.json 中的 `description` 和 `readme` 字段,以及对应的 README*.md 文件 * 插件中使用的文本,比如按钮文字和提示信息 - * src/i18n/*.json 语言配置文件 + * public/i18n/*.json 语言配置文件 * 代码中使用 `this.i18.key` 获取文本 * 最后在 plugin.json 中的 `i18n` 字段中声明该插件支持的语言 +* yaml 支持 + * 本模板特别支持基于 Yaml 语法的 I18n,见 `public/i18n/zh_CN.yaml` + * 编译时,会自动把定义的 yaml 文件翻译成 json 文件放到 dist 或 dev 目录下 建议插件至少支持英文和简体中文,这样可以方便更多人使用。 diff --git a/package.json b/package.json index 3b29e49..fdcce30 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "eslint": "^8.42.0", "fast-glob": "^3.2.12", "glob": "^7.2.3", + "js-yaml": "^4.1.0", "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.63.3", diff --git a/public/i18n/en_US.yaml b/public/i18n/en_US.yaml new file mode 100644 index 0000000..e69de29 diff --git a/public/i18n/zh_CN.json b/public/i18n/zh_CN.json deleted file mode 100644 index 9b6231e..0000000 --- a/public/i18n/zh_CN.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "addTopBarIcon": "使用插件添加一个顶栏按钮", - "cancel": "取消", - "save": "保存", - "byeMenu": "再见,菜单!", - "helloPlugin": "你好,插件!", - "byePlugin": "再见,插件!", - "showDialog": "弹出一个对话框", - "removedData": "数据已删除", - "confirmRemove": "确认删除 ${name} 中的数据?", - "insertEmoji": "插入表情", - "removeSpace": "移除空格", - "getTab": "在日志中打印出已打开的所有自定义页签", - "name": "思源", - "hello": { - "makesure": "使用这个模板之前,请阅读官方教程, 确保自己已经理解了插件的基本开发流程。" - }, - "hintTitle":"关于", - "hintDesc":"🔗 plugin-sample-vite-svelte
💻 @frostime
💻 @88250
💻 @zxkmm" - -} \ No newline at end of file diff --git a/public/i18n/zh_CN.yaml b/public/i18n/zh_CN.yaml new file mode 100644 index 0000000..16099a3 --- /dev/null +++ b/public/i18n/zh_CN.yaml @@ -0,0 +1,21 @@ +--- +addTopBarIcon: 使用插件添加一个顶栏按钮 +cancel: 取消 +save: 保存 +byeMenu: 再见,菜单! +helloPlugin: 你好,插件! +byePlugin: 再见,插件! +showDialog: 弹出一个对话框 +removedData: 数据已删除 +confirmRemove: 确认删除 ${name} 中的数据? +insertEmoji: 插入表情 +removeSpace: 移除空格 +getTab: 在日志中打印出已打开的所有自定义页签 +name: 思源 +hello: + makesure: 使用这个模板之前,请阅读官方教程, + 确保自己已经理解了插件的基本开发流程。 +hintTitle: 关于 +hintDesc: "\U0001F517 + plugin-sample-vite-svelte
\U0001F4BB @frostime
\U0001F4BB @88250
\U0001F4BB + @zxkmm" diff --git a/vite.config.ts b/vite.config.ts index 4da8c11..31fc585 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,10 +7,12 @@ import { svelte } from "@sveltejs/vite-plugin-svelte" import zipPack from "vite-plugin-zip-pack"; import fg from 'fast-glob'; +import vitePluginYamlI18n from './yaml-plugin'; + const args = minimist(process.argv.slice(2)) const isWatch = args.watch || args.w || false -const devDistDir = "./dev" -const distDir = isWatch ? devDistDir : "./dist" +const devDistDir = "dev" +const distDir = isWatch ? devDistDir : "dist" console.log("isWatch=>", isWatch) console.log("distDir=>", distDir) @@ -25,6 +27,11 @@ export default defineConfig({ plugins: [ svelte(), + vitePluginYamlI18n({ + inDir: 'public/i18n', + outDir: `${distDir}/i18n` + }), + viteStaticCopy({ targets: [ { diff --git a/yaml-plugin.js b/yaml-plugin.js new file mode 100644 index 0000000..48c88f1 --- /dev/null +++ b/yaml-plugin.js @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 by frostime. All Rights Reserved. + * @Author : frostime + * @Date : 2024-04-05 21:27:55 + * @FilePath : /yaml-plugin.js + * @LastEditTime : 2024-04-05 22:37:40 + * @Description : 去妮玛的 json 格式,我就是要用 yaml 写 i18n + */ +// plugins/vite-plugin-parse-yaml.js +import fs from 'fs'; +import yaml from 'js-yaml'; +import { resolve } from 'path'; + +export default function vitePluginYamlI18n(options = {}) { + // Default options with a fallback + const DefaultOptions = { + inDir: 'src/i18n', + outDir: 'dist/i18n', + }; + + const finalOptions = { ...DefaultOptions, ...options }; + + return { + name: 'vite-plugin-yaml-i18n', + buildStart() { + console.log('🌈 Parse I18n: YAML to JSON..'); + const inDir = finalOptions.inDir; + const outDir = finalOptions.outDir + + if (!fs.existsSync(outDir)) { + fs.mkdirSync(outDir, { recursive: true }); + } + + //Remove yaml under outDir, which is auto-moved by vite + const outFiles = fs.readdirSync(outDir); + for (const file of outFiles) { + if (file.endsWith('.yaml') || file.endsWith('.yml')) { + console.log(`-- Remove yaml file ${file} under dist`); + fs.unlinkSync(resolve(outDir, file)); + } + } + + //Parse yaml file, output to json + const files = fs.readdirSync(inDir); + for (const file of files) { + if (file.endsWith('.yaml') || file.endsWith('.yml')) { + console.log(`-- Parsing ${file}`) + //检查是否有同名的json文件 + const jsonFile = file.replace(/\.(yaml|yml)$/, '.json'); + if (files.includes(jsonFile)) { + console.log(`---- File ${jsonFile} already exists, skipping...`); + continue; + } + try { + const filePath = resolve(inDir, file); + const fileContents = fs.readFileSync(filePath, 'utf8'); + const parsed = yaml.load(fileContents); + const jsonContent = JSON.stringify(parsed, null, 2); + const outputFilePath = resolve(outDir, file.replace(/\.(yaml|yml)$/, '.json')); + console.log(`---- Writing to ${outputFilePath}`); + fs.writeFileSync(outputFilePath, jsonContent); + } catch (error) { + this.error(`---- Error parsing YAML file ${file}: ${error.message}`); + } + } + } + }, + }; +} From a50c61efafbdfd35c3719430056ec6d2c5ec1ed2 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 5 Apr 2024 22:42:00 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=94=A5=20rm:=20en=5FUS.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/i18n/en_US.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/i18n/en_US.yaml diff --git a/public/i18n/en_US.yaml b/public/i18n/en_US.yaml deleted file mode 100644 index e69de29..0000000 From 762ae2197b4d868b751c7f4ba3ed519e48baa888 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 5 Apr 2024 22:54:18 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=94=A7=20build:=20yaml-plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yaml-plugin.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/yaml-plugin.js b/yaml-plugin.js index 48c88f1..01c85e2 100644 --- a/yaml-plugin.js +++ b/yaml-plugin.js @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2024-04-05 21:27:55 * @FilePath : /yaml-plugin.js - * @LastEditTime : 2024-04-05 22:37:40 + * @LastEditTime : 2024-04-05 22:53:34 * @Description : 去妮玛的 json 格式,我就是要用 yaml 写 i18n */ // plugins/vite-plugin-parse-yaml.js @@ -31,15 +31,6 @@ export default function vitePluginYamlI18n(options = {}) { fs.mkdirSync(outDir, { recursive: true }); } - //Remove yaml under outDir, which is auto-moved by vite - const outFiles = fs.readdirSync(outDir); - for (const file of outFiles) { - if (file.endsWith('.yaml') || file.endsWith('.yml')) { - console.log(`-- Remove yaml file ${file} under dist`); - fs.unlinkSync(resolve(outDir, file)); - } - } - //Parse yaml file, output to json const files = fs.readdirSync(inDir); for (const file of files) { From 4286a49a0b852e278506c713dc39ab8daba301af Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 19 Apr 2024 18:52:39 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20update=20svelte=20deps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 12 ++++++------ src/setting-example.svelte | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index fdcce30..df94e90 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ "make-link": "node --no-warnings ./scripts/make_dev_link.js", "dev": "vite build --watch", "build": "vite build", - "install": "vite build && node --no-warnings ./scripts/make_install.js" + "make-install": "vite build && node --no-warnings ./scripts/make_install.js" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^2.4.1", + "@sveltejs/vite-plugin-svelte": "^3.0.0", "@tsconfig/svelte": "^4.0.1", "@types/node": "^20.3.0", "eslint": "^8.42.0", @@ -24,12 +24,12 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.63.3", - "siyuan": "0.9.4", - "svelte": "^3.59.1", + "siyuan": "0.9.7", + "svelte": "^4.2.0", "ts-node": "^10.9.1", "typescript": "^5.1.3", - "vite": "^4.5.2", - "vite-plugin-static-copy": "^0.15.0", + "vite": "^5.0.0", + "vite-plugin-static-copy": "^1.0.2", "vite-plugin-zip-pack": "^1.0.5" } } diff --git a/src/setting-example.svelte b/src/setting-example.svelte index 3ae156a..5f8958b 100644 --- a/src/setting-example.svelte +++ b/src/setting-example.svelte @@ -63,6 +63,7 @@
    {#each groups as group} +
  • Date: Fri, 19 Apr 2024 19:09:15 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=94=A7=20config=20svelte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- svelte.config.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/svelte.config.js b/svelte.config.js index 7c8df62..d62a343 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,7 +1,26 @@ +/* + * Copyright (c) 2024 by frostime. All Rights Reserved. + * @Author : frostime + * @Date : 2023-05-19 19:49:13 + * @FilePath : /svelte.config.js + * @LastEditTime : 2024-04-19 19:01:55 + * @Description : + */ import { vitePreprocess } from "@sveltejs/vite-plugin-svelte" +const NoWarns = new Set([ + "a11y-click-events-have-key-events", + "a11y-no-static-element-interactions", + "a11y-no-noninteractive-element-interactions" +]); + export default { // Consult https://svelte.dev/docs#compile-time-svelte-preprocess // for more information about preprocessors preprocess: vitePreprocess(), + onwarn: (warning, handler) => { + // suppress warnings on `vite dev` and `vite build`; but even without this, things still work + if (NoWarns.has(warning.code)) return; + handler(warning); + } } From 3b47436806f5ed0074674d0ab2a8ad5bf8c72910 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 19 Apr 2024 19:17:49 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=93=9D=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 37 +++---------------------------------- README_zh_CN.md | 40 ++++------------------------------------ 2 files changed, 7 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 3a6e717..3c233a7 100644 --- a/README.md +++ b/README.md @@ -249,43 +249,12 @@ Related APIs can be found at: `/api/file/*` (e.g., `/api/file/getFile`). ### 2. Daily Note Attribute Specifications -When creating a diary in SiYuan, a custom-dailynote-yyyymmdd attribute will be automatically added to the document to distinguish it from regular documents. +When creating a daily note in SiYuan, a custom-dailynote-yyyymmdd attribute will be automatically added to the document to distinguish it from regular documents. > For more details, please refer to [Github Issue #9807](https://github.com/siyuan-note/siyuan/issues/9807). Developers should pay attention to the following when developing the functionality to manually create Daily Notes: -- If `/api/filetree/createDailyNote` is called to create a diary, the attribute will be automatically added to the document, and developers do not need to handle it separately. -- If a document is created manually by developer's code (e.g., using the `createDocWithMd` API to create a diary), please manually add this attribute to the document. +* If `/api/filetree/createDailyNote` is called to create a daily note, the attribute will be automatically added to the document, and developers do not need to handle it separately +* If a document is created manually by developer's code (e.g., using the `createDocWithMd` API to create a daily note), please manually add this attribute to the document -Here is a reference code: - -```ts -/* - * Copyright (c) 2023 by frostime. All Rights Reserved. - * @Author : frostime - * @Url : https://github.com/frostime/siyuan-dailynote-today/blob/v1.3.0/src/func/dailynote/dn-attr.ts - */ - -export function formatDate(date?: Date, sep=''): string { - date = date === undefined ? new Date() : date; - let year = date.getFullYear(); - let month = date.getMonth() + 1; - let day = date.getDate(); - return `${year}${sep}${month < 10 ? '0' + month : month}${sep}${day < 10 ? '0' + day : day}`; -} - -/** - * Set custom attribute: `custom-dailynote-yyyyMMdd`: yyyyMMdd - * https://github.com/siyuan-note/siyuan/issues/9807 - * @param doc_id Id of daily note - */ -export function setCustomDNAttr(doc_id: string, date?: Date) { - let td = formatDate(date); - let attr = `custom-dailynote-${td}`; - // 构建 attr: td - let attrs: { [key: string]: string } = {}; - attrs[attr] = td; - serverApi.setBlockAttrs(doc_id, attrs); -} -``` diff --git a/README_zh_CN.md b/README_zh_CN.md index 6b46f16..1510f9b 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -237,47 +237,15 @@ PR 社区集市仓库。 插件或者外部扩展如果有直接读取或者写入 data 下文件的需求,请通过调用内核 API 来实现,**不要自行调用 `fs` 或者其他 electron、nodejs API**,否则可能会导致数据同步时分块丢失,造成云端数据损坏。 -相关 API 见: `/api/file/*`(例如 `/api/file/getFile` 等)。 +相关 API 见 `/api/file/*`(例如 `/api/file/getFile` 等)。 ### 2. Daily Note 属性规范 -思源在创建日记的时候会自动为文档添加 custom-dailynote-yyyymmdd 属性, 以方便将日记文档同普通文档区分。 +思源在创建日记的时候会自动为文档添加 custom-dailynote-yyyymmdd 属性,以方便将日记文档同普通文档区分。 > 详情请见 [Github Issue #9807](https://github.com/siyuan-note/siyuan/issues/9807)。 开发者在开发手动创建 Daily Note 的功能时请注意: -- 如果调用了 `/api/filetree/createDailyNote` 创建日记,那么文档会自动添加这个属性,无需开发者特别处理。 -- 如果是开发者代码手动创建文档(例如使用 `createDocWithMd` API 创建日记),请手动为文档添加该属性。 - -参考代码: - -```ts -/* - * Copyright (c) 2023 by frostime. All Rights Reserved. - * @Author : frostime - * @Url : https://github.com/frostime/siyuan-dailynote-today/blob/v1.3.0/src/func/dailynote/dn-attr.ts - */ - -export function formatDate(date?: Date, sep=''): string { - date = date === undefined ? new Date() : date; - let year = date.getFullYear(); - let month = date.getMonth() + 1; - let day = date.getDate(); - return `${year}${sep}${month < 10 ? '0' + month : month}${sep}${day < 10 ? '0' + day : day}`; -} - -/** - * Set custom attribute: `custom-dailynote-yyyyMMdd`: yyyyMMdd - * https://github.com/siyuan-note/siyuan/issues/9807 - * @param doc_id Id of daily note - */ -export function setCustomDNAttr(doc_id: string, date?: Date) { - let td = formatDate(date); - let attr = `custom-dailynote-${td}`; - // 构建 attr: td - let attrs: { [key: string]: string } = {}; - attrs[attr] = td; - serverApi.setBlockAttrs(doc_id, attrs); -} -``` +* 如果调用了 `/api/filetree/createDailyNote` 创建日记,那么文档会自动添加这个属性,无需开发者特别处理 +* 如果是开发者代码手动创建文档(例如使用 `createDocWithMd` API 创建日记),请手动为文档添加该属性