├── styles.css ├── versions.json ├── .DS_Store ├── assets └── obsidian-steno.gif ├── .gitignore ├── manifest.json ├── tsconfig.json ├── README.md ├── rollup.config.js ├── package.json ├── LICENSE ├── .github └── workflows │ └── release.yml └── main.ts /styles.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.0.1": "0.9.12", 3 | "1.0.0": "0.9.7" 4 | } 5 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bramses/stenography-obsidian/HEAD/.DS_Store -------------------------------------------------------------------------------- /assets/obsidian-steno.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bramses/stenography-obsidian/HEAD/assets/obsidian-steno.gif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Intellij 2 | *.iml 3 | .idea 4 | 5 | # npm 6 | node_modules 7 | package-lock.json 8 | 9 | # build 10 | main.js 11 | *.js.map 12 | 13 | # obsidian 14 | data.json 15 | 16 | .env -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "stenography-obsidian", 3 | "name": "Stenography", 4 | "version": "1.0.3", 5 | "minAppVersion": "0.9.12", 6 | "description": "Auto Describe your code with machine learning using the Stenography API", 7 | "author": "bramses", 8 | "authorUrl": "https://stenography.dev/", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /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 | "lib": [ 13 | "dom", 14 | "es5", 15 | "scripthost", 16 | "es2015" 17 | ] 18 | }, 19 | "include": [ 20 | "**/*.ts" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Stenography Obsidian Plugin 2 | 3 | For [Obsidian October 2021](https://publish.obsidian.md/hub/11+-+Events/Obsidian+October+2021) 4 | 5 | This plugin uses [Stenography](https://stenography.dev/) to translate selected code blocks into simple English and guess at the language it is written in. 6 | 7 | ## Installation 8 | 9 | Install from the `Community Plugin list` by searching `Stenography` 10 | 11 | ## Running 12 | 13 | Go into Stenography settings and set your API key. You can get an API key [here](https://stenography.dev/dashboard) 14 | To run, highlight an unedited code block and click the Stenography Ribbon Icon (`code-glyph`) 15 | 16 | See gif below! 17 | 18 | ![gif of plugin running](./assets/obsidian-steno.gif) 19 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from '@rollup/plugin-typescript'; 2 | import {nodeResolve} from '@rollup/plugin-node-resolve'; 3 | import commonjs from '@rollup/plugin-commonjs'; 4 | 5 | const isProd = (process.env.BUILD === 'production'); 6 | 7 | const banner = 8 | `/* 9 | THIS IS A GENERATED/BUNDLED FILE BY ROLLUP 10 | if you want to view the source visit the plugins github repository 11 | */ 12 | `; 13 | 14 | export default { 15 | input: 'main.ts', 16 | output: { 17 | dir: '.', 18 | sourcemap: 'inline', 19 | sourcemapExcludeSources: isProd, 20 | format: 'cjs', 21 | exports: 'default', 22 | banner, 23 | }, 24 | external: ['obsidian'], 25 | plugins: [ 26 | typescript(), 27 | nodeResolve({browser: true}), 28 | commonjs({ 29 | include: "node_modules/**", 30 | }), 31 | ] 32 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stenography-obsidian", 3 | "version": "1.0.3", 4 | "description": "This plugin calls the [Stenography API](https://stenography.dev/) to translate code blocks into simple English with Machine Learning", 5 | "main": "main.js", 6 | "scripts": { 7 | "dev": "rollup --config rollup.config.js -w", 8 | "build": "rollup --config rollup.config.js --environment BUILD:production" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "@rollup/plugin-commonjs": "^18.0.0", 15 | "@rollup/plugin-node-resolve": "^11.2.1", 16 | "@rollup/plugin-typescript": "^8.2.1", 17 | "@types/node": "^14.14.37", 18 | "@types/turndown": "^5.0.1", 19 | "obsidian": "^0.12.0", 20 | "rollup": "^2.32.1", 21 | "tslib": "^2.2.0", 22 | "typescript": "^4.2.4" 23 | }, 24 | "dependencies": { 25 | "@types/node-fetch": "^3.0.3", 26 | "assert-never": "^1.2.1", 27 | "file-url": "^4.0.0", 28 | "node-fetch": "^3.0.0", 29 | "turndown": "^7.1.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Bram Adams 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 | -------------------------------------------------------------------------------- /.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: stenography-obsidian # 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 --if-present 27 | mkdir ${{ env.PLUGIN_NAME }} 28 | cp main.js manifest.json styles.css ${{ 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 styles.css 74 | id: upload-css 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: ./styles.css 81 | asset_name: styles.css 82 | asset_content_type: text/css -------------------------------------------------------------------------------- /main.ts: -------------------------------------------------------------------------------- 1 | import { App, Plugin, PluginSettingTab, Setting, MarkdownView, Notice } from 'obsidian'; 2 | 3 | interface StenographyPluginSettings { 4 | apiKey: string; 5 | } 6 | 7 | const DEFAULT_SETTINGS: StenographyPluginSettings = { 8 | apiKey: '' 9 | } 10 | 11 | export default class StenographyPlugin extends Plugin { 12 | settings: StenographyPluginSettings; 13 | 14 | /* 15 | This code is adding a new ribbon icon to the editor. The code will run when the user clicks on it. 16 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 17 | */ 18 | async onload() { 19 | console.log('loading stenography plugin'); 20 | await this.loadSettings(); 21 | 22 | this.addRibbonIcon('code-glyph', 'Stenography', async () => { 23 | await this.stenographyWorkflow(); 24 | }); 25 | 26 | this.addCommand({ 27 | id: 'run-stenograpy', 28 | name: 'Run Stenography', 29 | callback: async () => { 30 | await this.stenographyWorkflow(); 31 | } 32 | }); 33 | 34 | this.addSettingTab(new StenographyPluginTab(this.app, this)); 35 | 36 | 37 | } 38 | 39 | /* 40 | This code is a simple extension that adds the ability to convert selected text into stenography. 41 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 42 | */ 43 | async stenographyWorkflow() { 44 | try { 45 | if (this.app.workspace.getActiveViewOfType(MarkdownView)) { 46 | const editor = this.app.workspace.getActiveViewOfType(MarkdownView).editor; 47 | const selectedText = editor.getSelection(); // Get selected text 48 | if (selectedText && selectedText.length > 0) { 49 | const res = await this.fetchStenography(selectedText) 50 | editor.replaceSelection(`${res.res}\n\n\`\`\`${res.language}\n${selectedText}\n\`\`\`\n\n`) 51 | } 52 | } else { 53 | throw new Error('MarkdownView is null'); 54 | } 55 | } catch (err) { 56 | new Notice(err.message); 57 | } 58 | } 59 | 60 | /* 61 | This code is fetching the markdown from Stenography. 62 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 63 | */ 64 | async fetchStenography(code: string): Promise { 65 | const statusHTML = this.addStatusBarItem() 66 | statusHTML.setText('Loading from Stenography...'); 67 | try { 68 | const res = await fetch('https://stenography-worker.stenography.workers.dev', 69 | { 70 | method: 'POST', 71 | headers: { 'Content-Type': 'application/json;charset=UTF-8' }, 72 | body: JSON.stringify({ 73 | code: code, 74 | api_key: this.settings.apiKey, 75 | audience: 'pm', 76 | populate: false, 77 | stackoverflow: false 78 | }) 79 | }) 80 | const data = await res.json(); 81 | const markdown = data.pm 82 | const language = data.metadata.language || '' 83 | if (markdown && Object.keys(markdown).length === 0 && Object.getPrototypeOf(markdown) === Object.prototype) { 84 | return { res: `Stenography response empty!`, language: '' } 85 | } 86 | return { res: markdown, language: language } 87 | } catch(err) { 88 | if (err.message.includes('Failed to fetch')) { return { res: `Error loading from Stenography! API key error, did you set it in settings?`, language: '' } } 89 | else return { res: `Error loading from Stenography! Error: ${err}`, language: '' } 90 | } finally { 91 | statusHTML.remove(); 92 | } 93 | 94 | } 95 | 96 | /* 97 | This code is a JavaScript function that will be called when the browser unloads. 98 | It's used to log messages in the console, which can be seen by opening Developer Tools and clicking on Console tab. 99 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 100 | */ 101 | onunload() { 102 | console.log('unloading stenography plugin'); 103 | } 104 | 105 | /* 106 | This code is loading the settings from a file. 107 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 108 | */ 109 | async loadSettings() { 110 | this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); 111 | } 112 | 113 | /* 114 | This code is saving the settings object to a file. 115 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 116 | */ 117 | async saveSettings() { 118 | await this.saveData(this.settings); 119 | } 120 | } 121 | 122 | class StenographyPluginTab extends PluginSettingTab { 123 | plugin: StenographyPlugin; 124 | 125 | /* 126 | This code is creating a new instance of the Stenography class. 127 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 128 | */ 129 | constructor(app: App, plugin: StenographyPlugin) { 130 | super(app, plugin); 131 | this.plugin = plugin; 132 | } 133 | 134 | /* 135 | This code is creating a new Setting object. The first parameter to the constructor is the container element that will hold this setting. 136 | - generated by stenography autopilot [ 🚗👩‍✈️ ] 137 | */ 138 | display(): void { 139 | let { containerEl } = this; 140 | 141 | containerEl.empty(); 142 | 143 | containerEl.createEl('h2', { text: 'Settings for Stenography.' }); 144 | 145 | // for api key 146 | new Setting(containerEl) 147 | .setName('API Key') 148 | .setDesc('Get your API key here: https://stenography.dev/dashboard') 149 | .addText(text => text 150 | .setPlaceholder('xxxx-xxxx-xxxx-xxxx') 151 | .setValue('') 152 | .onChange(async (value) => { 153 | this.plugin.settings.apiKey = value; 154 | await this.plugin.saveSettings(); 155 | new Notice('Saved API key!'); 156 | })); 157 | } 158 | } 159 | --------------------------------------------------------------------------------