├── .eslintignore ├── .eslintrc.cjs ├── .github └── workflows │ └── release.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_zh_CN.md ├── asset └── action.png ├── icon.png ├── package-lock.json ├── package.json ├── plugin.json ├── preview.png ├── scripts ├── .gitignore └── make_dev_link.js ├── src ├── components │ ├── dialog │ │ ├── notebook-dialog.svelte │ │ └── template-dialog.svelte │ ├── setting copy 2.svelte │ ├── setting copy.svelte │ ├── setting-item.svelte │ ├── setting.svelte │ ├── tab │ │ ├── extra-tab.svelte │ │ ├── normal-tab.svelte │ │ └── template-tab.svelte │ ├── template-index-tab.svelte │ ├── template-item.svelte │ ├── template-none.svelte │ └── template-outline-tab.svelte ├── creater │ ├── createIndex.ts │ ├── createnotebookindex.ts │ └── createtemplate.ts ├── event │ ├── blockiconevent.ts │ ├── eventbus.ts │ └── protyleevent.ts ├── i18n │ ├── en_US.json │ └── zh_CN.json ├── index.ts ├── indexnode.ts ├── settings.ts ├── slash.ts ├── topbar.ts └── utils.ts ├── svelte.config.js ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | "eslint:recommended", 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:svelte/recommended", 6 | "turbo", 7 | "prettier", 8 | ], 9 | 10 | parser: "@typescript-eslint/parser", 11 | 12 | overrides: [ 13 | { 14 | files: ["*.svelte"], 15 | parser: "svelte-eslint-parser", 16 | // Parse the script in `.svelte` as TypeScript by adding the following configuration. 17 | parserOptions: { 18 | parser: "@typescript-eslint/parser", 19 | }, 20 | }, 21 | ], 22 | 23 | plugins: ["@typescript-eslint", "prettier"], 24 | 25 | rules: { 26 | // Note: you must disable the base rule as it can report incorrect errors 27 | semi: "off", 28 | quotes: "off", 29 | "no-undef": "off", 30 | "@typescript-eslint/no-var-requires": "off", 31 | "@typescript-eslint/no-this-alias": "off", 32 | "@typescript-eslint/no-non-null-assertion": "off", 33 | "@typescript-eslint/no-unused-vars": "off", 34 | "@typescript-eslint/no-explicit-any": "off", 35 | "turbo/no-undeclared-env-vars": "off", 36 | "prettier/prettier": "error", 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release on Tag Push 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | steps: 14 | # Checkout 15 | - name: Checkout 16 | uses: actions/checkout@v3 17 | 18 | # Install Node.js 19 | - name: Install Node.js 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: 18 23 | registry-url: "https://registry.npmjs.org" 24 | 25 | # Install pnpm 26 | - name: Install pnpm 27 | uses: pnpm/action-setup@v4 28 | id: pnpm-install 29 | with: 30 | version: 8 31 | run_install: false 32 | 33 | # Get pnpm store directory 34 | - name: Get pnpm store directory 35 | id: pnpm-cache 36 | shell: bash 37 | run: | 38 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT 39 | 40 | # Setup pnpm cache 41 | - name: Setup pnpm cache 42 | uses: actions/cache@v3 43 | with: 44 | path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} 45 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 46 | restore-keys: | 47 | ${{ runner.os }}-pnpm-store- 48 | 49 | # Install dependencies 50 | - name: Install dependencies 51 | run: pnpm install 52 | 53 | # Build for production, 这一步会生成一个 package.zip 54 | - name: Build for production 55 | run: pnpm build 56 | 57 | - name: Release 58 | uses: ncipollo/release-action@v1 59 | with: 60 | allowUpdates: true 61 | artifactErrorsFailBuild: true 62 | artifacts: 'package.zip' 63 | token: ${{ secrets.GITHUB_TOKEN }} 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | .DS_Store 4 | pnpm-lock.yaml 5 | package.zip 6 | node_modules 7 | dev 8 | dist 9 | build 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | - v1.5.6 3 | - bug修复,更好地处理特殊字符 4 | - v1.5.5 5 | - 支持生成笔记本目录 6 | - v1.5.2 7 | - 为搜索界面禁用自动更新以防止内容块变化,影响搜索结果 8 | - v1.5.1 9 | - 继续优化设置界面,增加更多大纲设置项 10 | - v1.5.0 11 | - 优化设置界面,所有按钮都移动到右键中 12 | - v1.4.9 13 | - 支持设置大纲前缀 14 | - 支持大纲自动更新 15 | - 修复插入目录及大纲失效的bug 16 | - 添加设置项按钮 17 | - 支持单独设置大纲样式 18 | - 大纲样式改为引用块包裹 19 | - v1.4.8 20 | - 修复文档构建器并提升使用体验 21 | - v1.4.7 22 | - 重新支持自动更新,并修复聚焦bug 23 | - v1.4.6 24 | - 移除自动更新 25 | - v1.4.0 26 | - 优化界面,支持模板设置 27 | - v1.3.1 28 | - 支持设置默认目录折叠层级,如要保存手动修改的折叠状态,需要禁用自动更新 29 | - v1.2.9 30 | - 支持分列 31 | - v1.2.8 32 | - 支持插入大纲 33 | - v1.2.6 34 | - 支持设置自动更新目录 35 | - v1.2.5 36 | - 文档构建器重新开放,谨慎使用 37 | - v1.2.4 38 | - 文档构建器bug,先下架 39 | - v1.2.2 40 | - 添加文档构建器,便于批量创建文档 41 | - v1.2.1 42 | - 支持设置块链接类型,双链或超链接(块链接或块引用),避免docker或网页端跳转 43 | - v1.2.0 44 | - 支持设置列表类型,支持快捷键 45 | - v1.1.3 46 | - 支持tab界面设置 47 | - v1.1.1 48 | - 修复bug 49 | - v1.1.0 50 | - 支持设置是否插入图标 51 | - 清洁代码 52 | - 适配移动端 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 SiYuan 思源笔记 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [中文](https://github.com/TinkMingKing/siyuan-plugins-index/blob/main/README_zh_CN.md) 2 | 3 | # Index Plugin 4 | 5 | After enabling the plugin, a plugin icon will be generated on the right side of the topbar 6 | 7 | Left click on the plugin icon , insert a index list to current document 8 | 9 | Right click on the plugin icon, show more actions 10 | 11 | `CTRL+ALT+I` Quick Insert 12 | 13 | `CTRL + ALT + O`Insert Subdocument Index and Outline 14 | 15 | `CTRL + ALT + P`Insert current document outline 16 | 17 | `CTRL + ALT + N`Insert notebook Index 18 | 19 | # Feedback 20 | 21 | [Feedback](https://ld246.com/article/1698684433007) 22 | 23 | # Changelog 24 | 25 | [CHANGELOG](https://github.com/TinkMingKing/siyuan-plugins-index/blob/main/CHANGELOG.md) -------------------------------------------------------------------------------- /README_zh_CN.md: -------------------------------------------------------------------------------- 1 | [English](https://github.com/TinkMingKing/siyuan-plugins-index/blob/main/README.md) 2 | 3 | # 目录插件 4 | 5 | # 没有时间和精力维护了,求个大佬来接手 6 | 7 | 启用插件后,会在顶栏右侧生成一个插件图标 8 | 9 | 左键点击插件图标,在当前文档下插入目录列表 10 | 11 | 右键点击插件图标,显示更多操作 12 | 13 | `CTRL + ALT + I`插入目录 14 | 15 | `CTRL + ALT + O`插入子文档目录及大纲 16 | 17 | `CTRL + ALT + P`插入当前文档大纲 18 | 19 | `CTRL + ALT + N`插入笔记本目录 20 | 21 | # 反馈地址 22 | 23 | [反馈地址](https://ld246.com/article/1698684433007) 24 | 25 | # 更新日志 26 | 27 | [CHANGELOG](https://github.com/TinkMingKing/siyuan-plugins-index/blob/main/CHANGELOG.md) 28 | -------------------------------------------------------------------------------- /asset/action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TinkMingKing/siyuan-plugins-index/dbf655dd0855bfbca0ca157761e326a236d1dbe7/asset/action.png -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TinkMingKing/siyuan-plugins-index/dbf655dd0855bfbca0ca157761e326a236d1dbe7/icon.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "siyuan-plugins-index", 3 | "version": "0.0.3", 4 | "type": "module", 5 | "description": "", 6 | "repository": "", 7 | "homepage": "", 8 | "author": "", 9 | "license": "GPL-3.0", 10 | "scripts": { 11 | "make-link": "node --no-warnings ./scripts/make_dev_link.js", 12 | "dev": "vite build --watch", 13 | "build": "vite build", 14 | "update": "pnpm update -L" 15 | }, 16 | "devDependencies": { 17 | "@sveltejs/vite-plugin-svelte": "^3.1.1", 18 | "@tsconfig/svelte": "^5.0.4", 19 | "@types/node": "^22.0.0", 20 | "fast-glob": "^3.3.2", 21 | "glob": "^11.0.0", 22 | "minimist": "^1.2.8", 23 | "rollup-plugin-livereload": "^2.0.5", 24 | "sass": "^1.77.8", 25 | "siyuan": "^1.0.2", 26 | "svelte": "^4.2.18", 27 | "ts-node": "^10.9.2", 28 | "typescript": "^5.5.4", 29 | "vite": "^5.3.5", 30 | "vite-plugin-static-copy": "^1.0.6", 31 | "vite-plugin-zip-pack": "^1.2.3" 32 | }, 33 | "dependencies": { 34 | "@siyuan-community/siyuan-sdk": "^0.3.12", 35 | "pnpm": "^9.6.0" 36 | } 37 | } -------------------------------------------------------------------------------- /plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "siyuan-plugins-index", 3 | "author": "TinkMingKing", 4 | "url": "https://github.com/TinkMingKing/siyuan-plugins-index", 5 | "version": "1.5.8", 6 | "minAppVersion": "2.10.12", 7 | "backends": ["all"], 8 | "frontends": ["all"], 9 | "displayName": { 10 | "default": "Index Plugin", 11 | "zh_CN": "目录插件" 12 | }, 13 | "description": { 14 | "default": "One click insert a index list in document", 15 | "zh_CN": "一键在文档中插入目录或大纲列表" 16 | }, 17 | "readme": { 18 | "default": "README.md", 19 | "zh_CN": "README_zh_CN.md" 20 | }, 21 | "i18n": [ 22 | "en_US", 23 | "zh_CN" 24 | ], 25 | "funding": { 26 | "openCollective": "", 27 | "patreon": "", 28 | "github": "", 29 | "custom": [ 30 | "https://afdian.net/a/MingKing" 31 | ] 32 | }, 33 | "keywords": [ 34 | "index", "目录" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TinkMingKing/siyuan-plugins-index/dbf655dd0855bfbca0ca157761e326a236d1dbe7/preview.png -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | .venv 2 | build 3 | dist 4 | *.exe 5 | *.spec 6 | -------------------------------------------------------------------------------- /scripts/make_dev_link.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import readline from 'node:readline'; 3 | 4 | 5 | //************************************ Write you dir here ************************************ 6 | 7 | //Please write the "workspace/data/plugins" directory here 8 | //请在这里填写你的 "workspace/data/plugins" 目录 9 | let targetDir = ''; 10 | //Like this 11 | // const targetDir = `H:\\SiYuanDevSpace\\data\\plugins`; 12 | //******************************************************************************************** 13 | 14 | const log = console.log; 15 | 16 | async function getSiYuanDir() { 17 | let url = 'http://127.0.0.1:6806/api/system/getWorkspaces'; 18 | let header = { 19 | // "Authorization": `Token ${token}`, 20 | "Content-Type": "application/json", 21 | } 22 | let conf = {}; 23 | try { 24 | let response = await fetch(url, { 25 | method: 'POST', 26 | headers: header 27 | }); 28 | if (response.ok) { 29 | conf = await response.json(); 30 | } else { 31 | log(`HTTP-Error: ${response.status}`); 32 | return null; 33 | } 34 | } catch (e) { 35 | log("Error:", e); 36 | log("Please make sure SiYuan is running!!!"); 37 | return null; 38 | } 39 | return conf.data; 40 | } 41 | 42 | async function chooseTarget(workspaces) { 43 | let count = workspaces.length; 44 | log(`Got ${count} SiYuan ${count > 1 ? 'workspaces' : 'workspace'}`) 45 | for (let i = 0; i < workspaces.length; i++) { 46 | log(`[${i}] ${workspaces[i].path}`); 47 | } 48 | 49 | if (count == 1) { 50 | return `${workspaces[0].path}/data/plugins`; 51 | } else { 52 | const rl = readline.createInterface({ 53 | input: process.stdin, 54 | output: process.stdout 55 | }); 56 | let index = await new Promise((resolve, reject) => { 57 | rl.question(`Please select a workspace[0-${count-1}]: `, (answer) => { 58 | resolve(answer); 59 | }); 60 | }); 61 | rl.close(); 62 | return `${workspaces[index].path}/data/plugins`; 63 | } 64 | } 65 | 66 | if (targetDir === '') { 67 | log('"targetDir" is empty, try to get SiYuan directory automatically....') 68 | let res = await getSiYuanDir(); 69 | 70 | if (res === null) { 71 | log('Failed! You can set the plugin directory in scripts/make_dev_link.js and try again'); 72 | process.exit(1); 73 | } 74 | 75 | targetDir = await chooseTarget(res); 76 | log(`Got target directory: ${targetDir}`); 77 | } 78 | 79 | //Check 80 | if (!fs.existsSync(targetDir)) { 81 | log(`Failed! plugin directory not exists: "${targetDir}"`); 82 | log(`Please set the plugin directory in scripts/make_dev_link.js`); 83 | process.exit(1); 84 | } 85 | 86 | 87 | //check if plugin.json exists 88 | if (!fs.existsSync('./plugin.json')) { 89 | console.error('Failed! plugin.json not found'); 90 | process.exit(1); 91 | } 92 | 93 | //load plugin.json 94 | const plugin = JSON.parse(fs.readFileSync('./plugin.json', 'utf8')); 95 | const name = plugin?.name; 96 | if (!name || name === '') { 97 | log('Failed! Please set plugin name in plugin.json'); 98 | process.exit(1); 99 | } 100 | 101 | //dev directory 102 | const devDir = `./dev`; 103 | //mkdir if not exists 104 | if (!fs.existsSync(devDir)) { 105 | fs.mkdirSync(devDir); 106 | } 107 | 108 | const targetPath = `${targetDir}/${name}`; 109 | //如果已经存在,就退出 110 | if (fs.existsSync(targetPath)) { 111 | log(`Failed! Target directory ${targetPath} already exists`); 112 | } else { 113 | //创建软链接 114 | fs.symlinkSync(`${process.cwd()}/dev`, targetPath, 'junction'); 115 | log(`Done! Created symlink ${targetPath}`); 116 | } 117 | 118 | -------------------------------------------------------------------------------- /src/components/dialog/notebook-dialog.svelte: -------------------------------------------------------------------------------- 1 | 51 | 52 | 95 | 96 |
97 | 100 |
101 | -------------------------------------------------------------------------------- /src/components/dialog/template-dialog.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |