├── .npmrc ├── .prettierignore ├── .eslintignore ├── global.d.ts ├── images └── demo.gif ├── src ├── settings.ts ├── settings_tab.ts ├── morpher.ts ├── main.ts └── aliasater.ts ├── versions.json ├── .prettierrc.json ├── test_vault ├── мост.md ├── системное мышление.md └── спортивное программирование.md ├── TODO.md ├── styles.css ├── scripts └── install.sh ├── .editorconfig ├── manifest.json ├── .github └── workflows │ ├── lint.yml │ └── release.yml ├── .gitignore ├── tsconfig.json ├── version-bump.mjs ├── .eslintrc ├── package.json ├── LICENSE ├── esbuild.config.mjs ├── README.md └── CONTRIBUTING.md /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="" -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | main.js 4 | -------------------------------------------------------------------------------- /global.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'morpher-ws3-client'; 2 | -------------------------------------------------------------------------------- /images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanadium23/obsidian-cyrillic-morpher/HEAD/images/demo.gif -------------------------------------------------------------------------------- /src/settings.ts: -------------------------------------------------------------------------------- 1 | export interface CyrillicMorperSettings { 2 | morpherApiKey: string | null; 3 | } 4 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "0.0.1": "0.15.0", 3 | "0.0.2": "0.15.0", 4 | "0.0.3": "0.15.0", 5 | "0.0.4": "0.15.0" 6 | } 7 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "semi": true, 4 | "singleQuote": true, 5 | "bracketSpacing": true 6 | } 7 | -------------------------------------------------------------------------------- /test_vault/мост.md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: 3 | - мост 4 | - мосту 5 | - моста 6 | - мостом 7 | - мосте 8 | --- 9 | 10 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - [ ] Обновить readme.md 2 | - [ ] Дописать что делает плагин 3 | - [ ] Дописать установку через BRAT 4 | - [ ] Настроить github actions для релиза 5 | -------------------------------------------------------------------------------- /test_vault/системное мышление.md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: 3 | - системное мышление 4 | - системному мышлению 5 | - системного мышления 6 | - системным мышлением 7 | - системном мышлении 8 | --- 9 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This CSS file will be included with your plugin, and 4 | available in the app when your plugin is enabled. 5 | 6 | If your plugin does not need CSS, delete this file. 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /test_vault/спортивное программирование.md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: 3 | - спортивному программированию 4 | - спортивного программирования 5 | - спортивным программированием 6 | - спортивном программировании 7 | --- 8 | -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp main.js .obsidian/plugins/obsidian-cyrillic-morpher/ 4 | cp manifest.json .obsidian/plugins/obsidian-cyrillic-morpher/ 5 | cp styles.css .obsidian/plugins/obsidian-cyrillic-morpher/ 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | indent_style = tab 9 | indent_size = 4 10 | tab_width = 4 11 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cyrillic-morpher", 3 | "name": "Cyrillic Morpher", 4 | "version": "0.0.4", 5 | "minAppVersion": "0.15.0", 6 | "description": "This is a plugin to generate cases for cyrillic named files. Update your aliases with command.", 7 | "author": "vanadium23", 8 | "authorUrl": "https://vanadium23.me", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: 8 | - "*" 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Install modules 17 | run: npm install 18 | 19 | - name: Lint 20 | run: npm run lint 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # vscode 2 | .vscode 3 | 4 | # Intellij 5 | *.iml 6 | .idea 7 | 8 | # npm 9 | node_modules 10 | 11 | # Don't include the compiled main.js file in the repo. 12 | # They should be uploaded to GitHub releases instead. 13 | main.js 14 | 15 | # Exclude sourcemaps 16 | *.map 17 | 18 | # obsidian 19 | data.json 20 | 21 | # Exclude macOS Finder (System Explorer) View States 22 | .DS_Store 23 | .obsidian 24 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "inlineSourceMap": true, 5 | "inlineSources": true, 6 | "module": "ESNext", 7 | "target": "ES6", 8 | "allowJs": true, 9 | "noImplicitAny": true, 10 | "moduleResolution": "node", 11 | "importHelpers": true, 12 | "isolatedModules": true, 13 | "strictNullChecks": true, 14 | "lib": [ 15 | "DOM", 16 | "ES5", 17 | "ES6", 18 | "ES7" 19 | ] 20 | }, 21 | "include": [ 22 | "**/*.ts" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /version-bump.mjs: -------------------------------------------------------------------------------- 1 | import { readFileSync, writeFileSync } from "fs"; 2 | 3 | const targetVersion = process.env.npm_package_version; 4 | 5 | // read minAppVersion from manifest.json and bump version to target version 6 | let manifest = JSON.parse(readFileSync("manifest.json", "utf8")); 7 | const { minAppVersion } = manifest; 8 | manifest.version = targetVersion; 9 | writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t")); 10 | 11 | // update versions.json with target version and minAppVersion from manifest.json 12 | let versions = JSON.parse(readFileSync("versions.json", "utf8")); 13 | versions[targetVersion] = minAppVersion; 14 | writeFileSync("versions.json", JSON.stringify(versions, null, "\t")); 15 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "env": { "node": true }, 5 | "plugins": [ 6 | "@typescript-eslint" 7 | ], 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:@typescript-eslint/eslint-recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "parserOptions": { 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "no-unused-vars": "off", 18 | "@typescript-eslint/no-unused-vars": ["error", { "args": "none" }], 19 | "@typescript-eslint/ban-ts-comment": "off", 20 | "no-prototype-builtins": "off", 21 | "@typescript-eslint/no-empty-function": "off" 22 | } 23 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-cyrillic-morpher", 3 | "version": "0.0.4", 4 | "description": "This is a plugin to generate cases for cyrillic named files. Update your aliases with command.", 5 | "main": "main.js", 6 | "scripts": { 7 | "lint": "eslint . --ext .ts && tsc --noEmit && prettier --check src/", 8 | "dev": "node esbuild.config.mjs", 9 | "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", 10 | "version": "node version-bump.mjs && git add manifest.json versions.json" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "@types/node": "^16.11.6", 17 | "@typescript-eslint/eslint-plugin": "5.29.0", 18 | "@typescript-eslint/parser": "5.29.0", 19 | "builtin-modules": "3.3.0", 20 | "esbuild": "0.17.3", 21 | "obsidian": "latest", 22 | "prettier": "^2.8.8", 23 | "tslib": "2.4.0", 24 | "typescript": "4.7.4" 25 | }, 26 | "dependencies": { 27 | "morpher-ws3-client": "^1.0.8" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 @vanadium23 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 | -------------------------------------------------------------------------------- /src/settings_tab.ts: -------------------------------------------------------------------------------- 1 | import { PluginSettingTab, App, Setting } from 'obsidian'; 2 | import ObsidianCyrillicMorper from './main'; 3 | 4 | export class CyrillicMorperSettingTab extends PluginSettingTab { 5 | plugin: ObsidianCyrillicMorper; 6 | 7 | constructor(app: App, plugin: ObsidianCyrillicMorper) { 8 | super(app, plugin); 9 | this.plugin = plugin; 10 | } 11 | 12 | display(): void { 13 | const { containerEl } = this; 14 | 15 | containerEl.empty(); 16 | 17 | containerEl.createEl('h2', { 18 | text: 'Settings for obsidian cyrillic morpher.', 19 | }); 20 | 21 | new Setting(containerEl) 22 | .setName('Morper API key') 23 | .setDesc('You can buy API at https://morpher.ru/ws3/buy/') 24 | .addText((text) => 25 | text 26 | .setPlaceholder('Enter your secret') 27 | .setValue(this.plugin.settings.morpherApiKey || '') 28 | .onChange(async (value) => { 29 | if (value === '') { 30 | this.plugin.settings.morpherApiKey = null; 31 | } else { 32 | this.plugin.settings.morpherApiKey = value; 33 | } 34 | await this.plugin.saveSettings(); 35 | }) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /esbuild.config.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import process from "process"; 3 | import builtins from "builtin-modules"; 4 | 5 | const banner = 6 | `/* 7 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD 8 | if you want to view the source, please visit the github repository of this plugin 9 | */ 10 | `; 11 | 12 | const prod = (process.argv[2] === "production"); 13 | 14 | const context = await esbuild.context({ 15 | banner: { 16 | js: banner, 17 | }, 18 | entryPoints: ["src/main.ts"], 19 | bundle: true, 20 | external: [ 21 | "obsidian", 22 | "electron", 23 | "@codemirror/autocomplete", 24 | "@codemirror/collab", 25 | "@codemirror/commands", 26 | "@codemirror/language", 27 | "@codemirror/lint", 28 | "@codemirror/search", 29 | "@codemirror/state", 30 | "@codemirror/view", 31 | "@lezer/common", 32 | "@lezer/highlight", 33 | "@lezer/lr", 34 | ...builtins], 35 | format: "cjs", 36 | target: "es2018", 37 | logLevel: "info", 38 | sourcemap: prod ? false : "inline", 39 | treeShaking: true, 40 | outfile: "main.js", 41 | }); 42 | 43 | if (prod) { 44 | await context.rebuild(); 45 | process.exit(0); 46 | } else { 47 | await context.watch(); 48 | } 49 | -------------------------------------------------------------------------------- /src/morpher.ts: -------------------------------------------------------------------------------- 1 | import { CyrillicMorperSettings } from './settings'; 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-var-requires 4 | const ws3Morpher = require('morpher-ws3-client'); 5 | 6 | interface Morpher { 7 | generateCases(string: string): Promise; 8 | } 9 | 10 | export class CyrillicMorpher implements Morpher { 11 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 12 | morpher: any; 13 | 14 | constructor(settings: CyrillicMorperSettings) { 15 | this.morpher = new ws3Morpher({ 16 | token: settings.morpherApiKey, 17 | }); 18 | } 19 | 20 | async generateCases(string: string, plural = false): Promise { 21 | const result = await this.morpher.russian.declension(string); 22 | // TODO: move to settings 23 | const cases = [ 24 | 'accusative', 25 | 'dative', 26 | 'genitive', 27 | 'instrumental', 28 | 'prepositional', 29 | ]; 30 | let aliases = cases.map((caseName) => { 31 | return result[caseName]; 32 | }); 33 | if (plural) { 34 | aliases = aliases.concat( 35 | cases.map((caseName) => { 36 | return result['plural'][caseName]; 37 | }) 38 | ); 39 | } 40 | return aliases; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Obsidian Cyrillic Morpher 2 | 3 | The plugin generates aliases, based on filename and cases in russian language. Based on cloud service https://morpher.ru/ws3/. 4 | 5 | --- 6 | 7 | Плагин помогает автоматически сгенерировать алиасы на основе названия файла и всех падежей. Плагин использует бесплатную версию https://morpher.ru/ws3/. Если вам понравилось, то купите у ребят полную версию. (: 8 | 9 | ## Feature 10 | 11 | Spawn a command pallete, and choose command `generate aliases based on filename`. 12 | 13 | **Hint:** you can make it as a shortcut. 14 | 15 | ![demo](/images/demo.gif) 16 | 17 | ## Installation 18 | 19 | The plugin is not yet available in the plugin library, will be soon. Stay tunned. 20 | 21 | ### Manual 22 | 23 | 1. Go to the [releases](https://github.com/vanadium23/obsidian-cyrillic-morpher/releases) and download `main.js`, `manifest.json`, and `styles.css` of the latest version. 24 | 2. Put the files in `YourObsidianVault/.obsidian/plugins/cyrillic-morpher/` 25 | 3. Reload the plugins in Obsidian settings or restart the program. 26 | 4. The plugin can now be enabled in the plugins menu. 27 | 28 | ### Brat 29 | 30 | You can also install Cyrillic Morpher using the community plugin [obsidian42-brat](https://github.com/TfTHacker/obsidian42-brat). 31 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { Plugin, Editor, MarkdownView, MarkdownFileInfo } from 'obsidian'; 2 | import { CyrillicGenerator } from './aliasater'; 3 | import { CyrillicMorperSettings } from './settings'; 4 | import { CyrillicMorperSettingTab } from './settings_tab'; 5 | 6 | // Remember to rename these classes and interfaces! 7 | const DEFAULT_SETTINGS: CyrillicMorperSettings = { 8 | morpherApiKey: null, 9 | }; 10 | 11 | export default class ObsidianCyrillicMorper extends Plugin { 12 | settings: CyrillicMorperSettings; 13 | 14 | async onload() { 15 | await this.loadSettings(); 16 | 17 | const generator = new CyrillicGenerator(this.app, this.settings); 18 | 19 | // This adds a simple command that can be triggered anywhere 20 | this.addCommand({ 21 | id: 'cirillic-morper-generate-aliases-filename', 22 | name: 'Generate aliases based on filename', 23 | editorCallback: ( 24 | editor: Editor, 25 | ctx: MarkdownView | MarkdownFileInfo 26 | ) => { 27 | generator.writeCyrillicCases(ctx); 28 | }, 29 | }); 30 | // This adds a simple command that can be triggered anywhere 31 | this.addCommand({ 32 | id: 'cirillic-morper-generate-aliases-filename-plural', 33 | name: 'Generate aliases based on filename (with plural)', 34 | editorCallback: ( 35 | editor: Editor, 36 | ctx: MarkdownView | MarkdownFileInfo 37 | ) => { 38 | generator.writeCyrillicCases(ctx, true); 39 | }, 40 | }); 41 | 42 | // This adds a settings tab so the user can configure various aspects of the plugin 43 | this.addSettingTab(new CyrillicMorperSettingTab(this.app, this)); 44 | } 45 | 46 | onunload() {} 47 | 48 | async loadSettings() { 49 | this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); 50 | } 51 | 52 | async saveSettings() { 53 | await this.saveData(this.settings); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/aliasater.ts: -------------------------------------------------------------------------------- 1 | import { App, MarkdownFileInfo } from 'obsidian'; 2 | import { CyrillicMorpher } from './morpher'; 3 | import { CyrillicMorperSettings } from './settings'; 4 | 5 | interface CyrillicAliasater { 6 | writeCyrillicCases(ctx: MarkdownFileInfo): void; 7 | } 8 | 9 | function mergeAliases( 10 | newAliases: string[], 11 | currentAliases: string[] | undefined, 12 | alias: string | undefined 13 | ): string[] { 14 | const mergedAliases = newAliases; 15 | if (currentAliases) { 16 | for (const alias of currentAliases) { 17 | if (mergedAliases.includes(alias)) { 18 | continue; 19 | } 20 | mergedAliases.push(alias); 21 | } 22 | } 23 | if (alias) { 24 | if (mergedAliases.includes(alias)) { 25 | return mergedAliases; 26 | } 27 | mergedAliases.push(alias); 28 | } 29 | return mergedAliases; 30 | } 31 | 32 | export class CyrillicGenerator implements CyrillicAliasater { 33 | app: App; 34 | morpher: CyrillicMorpher; 35 | 36 | constructor(app: App, settings: CyrillicMorperSettings) { 37 | this.app = app; 38 | this.morpher = new CyrillicMorpher(settings); 39 | } 40 | 41 | async writeCyrillicCases(ctx: MarkdownFileInfo, plural = false) { 42 | // get current file 43 | if (!ctx?.file) { 44 | console.log('No file in context'); 45 | return; 46 | } 47 | const filename = ctx.file?.basename; 48 | const cases = await this.morpher.generateCases(filename, plural); 49 | const newAliases = cases.filter((alias) => alias !== filename); 50 | // update frontmatter aliases 51 | await this.app.fileManager.processFrontMatter(ctx.file, (frontmatter) => { 52 | const mergedAliases = mergeAliases( 53 | newAliases, 54 | frontmatter.aliases, 55 | frontmatter.alias 56 | ); 57 | frontmatter['aliases'] = mergedAliases; 58 | if (frontmatter['alias']) { 59 | delete frontmatter['alias']; 60 | } 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build obsidian plugin 2 | 3 | on: 4 | push: 5 | # Sequence of patterns matched against refs/tags 6 | tags: 7 | - "*" # Push events to matching any tag format, i.e. 1.0, 20.15.10 8 | 9 | env: 10 | PLUGIN_NAME: obsidian-advanced-new-file # Change this to the name of your plugin-id folder 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Use Node.js 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: "14.x" # You might need to adjust this value to your own version 22 | - name: Build 23 | id: build 24 | run: | 25 | npm install 26 | npm run build 27 | mkdir ${{ env.PLUGIN_NAME }} 28 | cp main.js manifest.json ${{ env.PLUGIN_NAME }} 29 | zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }} 30 | ls 31 | echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)" 32 | - name: Create Release 33 | id: create_release 34 | uses: actions/create-release@v1 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | VERSION: ${{ github.ref }} 38 | with: 39 | tag_name: ${{ github.ref }} 40 | release_name: ${{ github.ref }} 41 | draft: false 42 | prerelease: false 43 | - name: Upload zip file 44 | id: upload-zip 45 | uses: actions/upload-release-asset@v1 46 | env: 47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 48 | with: 49 | upload_url: ${{ steps.create_release.outputs.upload_url }} 50 | asset_path: ./${{ env.PLUGIN_NAME }}.zip 51 | asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip 52 | asset_content_type: application/zip 53 | - name: Upload main.js 54 | id: upload-main 55 | uses: actions/upload-release-asset@v1 56 | env: 57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 | with: 59 | upload_url: ${{ steps.create_release.outputs.upload_url }} 60 | asset_path: ./main.js 61 | asset_name: main.js 62 | asset_content_type: text/javascript 63 | - name: Upload manifest.json 64 | id: upload-manifest 65 | uses: actions/upload-release-asset@v1 66 | env: 67 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 68 | with: 69 | upload_url: ${{ steps.create_release.outputs.upload_url }} 70 | asset_path: ./manifest.json 71 | asset_name: manifest.json 72 | asset_content_type: application/json 73 | - name: Upload versions.json 74 | id: upload-versions 75 | uses: actions/upload-release-asset@v1 76 | env: 77 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 78 | with: 79 | upload_url: ${{ steps.create_release.outputs.upload_url }} 80 | asset_path: ./versions.json 81 | asset_name: versions.json 82 | asset_content_type: application/json 83 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Obsidian Sample Plugin 2 | 3 | This is a sample plugin for Obsidian (https://obsidian.md). 4 | 5 | This project uses Typescript to provide type checking and documentation. 6 | The repo depends on the latest plugin API (obsidian.d.ts) in Typescript Definition format, which contains TSDoc comments describing what it does. 7 | 8 | **Note:** The Obsidian API is still in early alpha and is subject to change at any time! 9 | 10 | This sample plugin demonstrates some of the basic functionality the plugin API can do. 11 | - Adds a ribbon icon, which shows a Notice when clicked. 12 | - Adds a command "Open Sample Modal" which opens a Modal. 13 | - Adds a plugin setting tab to the settings page. 14 | - Registers a global click event and output 'click' to the console. 15 | - Registers a global interval which logs 'setInterval' to the console. 16 | 17 | ## First time developing plugins? 18 | 19 | Quick starting guide for new plugin devs: 20 | 21 | - Check if [someone already developed a plugin for what you want](https://obsidian.md/plugins)! There might be an existing plugin similar enough that you can partner up with. 22 | - Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it). 23 | - Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder. 24 | - Install NodeJS, then run `npm i` in the command line under your repo folder. 25 | - Run `npm run dev` to compile your plugin from `main.ts` to `main.js`. 26 | - Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`. 27 | - Reload Obsidian to load the new version of your plugin. 28 | - Enable plugin in settings window. 29 | - For updates to the Obsidian API run `npm update` in the command line under your repo folder. 30 | 31 | ## Releasing new releases 32 | 33 | - Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release. 34 | - Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible. 35 | - Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases 36 | - Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments. Note: The manifest.json file must be in two places, first the root path of your repository and also in the release. 37 | - Publish the release. 38 | 39 | > You can simplify the version bump process by running `npm version patch`, `npm version minor` or `npm version major` after updating `minAppVersion` manually in `manifest.json`. 40 | > The command will bump version in `manifest.json` and `package.json`, and add the entry for the new version to `versions.json` 41 | 42 | ## Adding your plugin to the community plugin list 43 | 44 | - Check https://github.com/obsidianmd/obsidian-releases/blob/master/plugin-review.md 45 | - Publish an initial version. 46 | - Make sure you have a `README.md` file in the root of your repo. 47 | - Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin. 48 | 49 | ## How to use 50 | 51 | - Clone this repo. 52 | - `npm i` or `yarn` to install dependencies 53 | - `npm run dev` to start compilation in watch mode. 54 | 55 | ## Manually installing the plugin 56 | 57 | - Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`. 58 | 59 | ## Improve code quality with eslint (optional) 60 | - [ESLint](https://eslint.org/) is a tool that analyzes your code to quickly find problems. You can run ESLint against your plugin to find common bugs and ways to improve your code. 61 | - To use eslint with this project, make sure to install eslint from terminal: 62 | - `npm install -g eslint` 63 | - To use eslint to analyze this project use this command: 64 | - `eslint main.ts` 65 | - eslint will then create a report with suggestions for code improvement by file and line number. 66 | - If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder: 67 | - `eslint .\src\` 68 | 69 | ## Funding URL 70 | 71 | You can include funding URLs where people who use your plugin can financially support it. 72 | 73 | The simple way is to set the `fundingUrl` field to your link in your `manifest.json` file: 74 | 75 | ```json 76 | { 77 | "fundingUrl": "https://buymeacoffee.com" 78 | } 79 | ``` 80 | 81 | If you have multiple URLs, you can also do: 82 | 83 | ```json 84 | { 85 | "fundingUrl": { 86 | "Buy Me a Coffee": "https://buymeacoffee.com", 87 | "GitHub Sponsor": "https://github.com/sponsors", 88 | "Patreon": "https://www.patreon.com/" 89 | } 90 | } 91 | ``` 92 | 93 | ## API Documentation 94 | 95 | See https://github.com/obsidianmd/obsidian-api 96 | --------------------------------------------------------------------------------