├── .gitignore ├── CHANGELOG.md ├── docs └── images │ ├── info.png │ ├── remaining.png │ ├── info-no-title.png │ ├── spoiler-closed.png │ ├── spoiler-open.png │ ├── abstract-spoiler.png │ └── complex-content.png ├── keymaps └── admonition.json ├── .babelrc ├── .eslintrc.yml ├── menus └── admonition.json ├── lib ├── admonition-config.js └── admonition.js ├── package.json ├── LICENSE.md ├── README-mobile.md ├── README.md └── styles └── admonition.less /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules/ 4 | .vscode/ 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 - First Release 2 | * Every feature added 3 | * Every bug fixed 4 | -------------------------------------------------------------------------------- /docs/images/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libeanim/inkdrop-admonition/HEAD/docs/images/info.png -------------------------------------------------------------------------------- /keymaps/admonition.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": { 3 | "ctrl-alt-a": "admonition:add-note" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /docs/images/remaining.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libeanim/inkdrop-admonition/HEAD/docs/images/remaining.png -------------------------------------------------------------------------------- /docs/images/info-no-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libeanim/inkdrop-admonition/HEAD/docs/images/info-no-title.png -------------------------------------------------------------------------------- /docs/images/spoiler-closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libeanim/inkdrop-admonition/HEAD/docs/images/spoiler-closed.png -------------------------------------------------------------------------------- /docs/images/spoiler-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libeanim/inkdrop-admonition/HEAD/docs/images/spoiler-open.png -------------------------------------------------------------------------------- /docs/images/abstract-spoiler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libeanim/inkdrop-admonition/HEAD/docs/images/abstract-spoiler.png -------------------------------------------------------------------------------- /docs/images/complex-content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libeanim/inkdrop-admonition/HEAD/docs/images/complex-content.png -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { 4 | "targets": { "electron": "6.0.11" } 5 | }], 6 | "@babel/preset-react" 7 | ], 8 | "plugins": [ 9 | "@babel/plugin-proposal-class-properties" 10 | ] 11 | } -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | root: true 2 | plugins: 3 | - react 4 | - prettier 5 | extends: 6 | - plugin:react/recommended 7 | - plugin:prettier/recommended 8 | parser: babel-eslint 9 | env: {} 10 | globals: 11 | inkdrop: readonly 12 | rules: 13 | no-useless-escape: 0 14 | prettier/prettier: 15 | - 2 16 | - 17 | trailingComma: none 18 | singleQuote: true 19 | semi: false 20 | prefer-const: 2 21 | no-unused-vars: 22 | - 2 23 | - 24 | argsIgnorePattern: ^_ 25 | varsIgnorePattern: ^_ 26 | -------------------------------------------------------------------------------- /menus/admonition.json: -------------------------------------------------------------------------------- 1 | { 2 | "menu": [ 3 | { 4 | "label": "Plugins", 5 | "submenu": [ 6 | { 7 | "label": "Admonition", 8 | "submenu": [ 9 | { 10 | "label": "Add Note Admonition", 11 | "command": "admonition:add-note" 12 | }, 13 | { 14 | "label": "Add Success Admonition", 15 | "command": "admonition:add-success" 16 | }, 17 | { 18 | "label": "Add Failure Admonition", 19 | "command": "admonition:add-fail" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /lib/admonition-config.js: -------------------------------------------------------------------------------- 1 | const admonitionConfig = {} 2 | 3 | const admonitionTypes = [ 4 | 'abstract', 5 | 'note', 6 | 'danger', 7 | 'warning', 8 | 'info', 9 | 'success', 10 | 'fail', 11 | 'question', 12 | 'example' 13 | ] 14 | 15 | admonitionTypes.forEach(type => { 16 | admonitionConfig[type] = { 17 | classes: `admonition-${type}`, 18 | title: 'optional' 19 | } 20 | admonitionConfig[`${type}-spoiler`] = { 21 | classes: `admonition-${type}`, 22 | title: 'required', 23 | details: true 24 | } 25 | }) 26 | 27 | admonitionConfig['spoiler'] = { 28 | classes: 'admonition-spoiler', 29 | title: 'required', 30 | details: true 31 | } 32 | 33 | module.exports = admonitionConfig 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "admonition", 3 | "main": "./lib/admonition", 4 | "version": "1.0.2", 5 | "description": "Allows to add block-styled side content to your notes", 6 | "keywords": [ 7 | "inkdrop", 8 | "plugin", 9 | "admonition", 10 | "notes" 11 | ], 12 | "repository": "https://github.com/libeanim/inkdrop-admonition.git", 13 | "license": "MIT", 14 | "engines": { 15 | "inkdrop": "^4.x" 16 | }, 17 | "dependencies": { 18 | "remark-custom-blocks": "^2.5.0" 19 | }, 20 | "devDependencies": { 21 | "babel-eslint": "^10.1.0", 22 | "eslint": "^6.1.0", 23 | "eslint-config-prettier": "^6.14.0", 24 | "eslint-plugin-prettier": "^3.1.4", 25 | "eslint-plugin-react": "^7.21.5", 26 | "prettier": "^1.18.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 libeanim 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /lib/admonition.js: -------------------------------------------------------------------------------- 1 | 'use babel' 2 | 3 | import remarkCustomBlocks from 'remark-custom-blocks' 4 | import admonitionConfig from './admonition-config' 5 | import { markdownRenderer } from 'inkdrop' 6 | 7 | class Admonition { 8 | constructor() { 9 | this.plugin = [remarkCustomBlocks, admonitionConfig] 10 | } 11 | 12 | addAdmontioin(type, title) { 13 | return () => { 14 | const { cm } = inkdrop.getActiveEditor() 15 | if (cm.somethingSelected()) { 16 | const selection = cm.getSelection() 17 | cm.replaceSelection( 18 | `[[${type} | ${title}]]\n| ` + selection.replace(/\n/g, '\n| '), 19 | 'around' 20 | ) 21 | } else { 22 | const { line } = cm.getCursor() 23 | cm.replaceSelection(`[[${type} | ${title}]]\n| `, 'start') 24 | cm.setCursor({ line: line + 1, ch: 2 }) 25 | } 26 | } 27 | } 28 | 29 | subsribe() { 30 | this.subscription = inkdrop.commands.add(document.body, { 31 | 'admonition:add-note': this.addAdmontioin('note', 'Note'), 32 | 'admonition:add-success': this.addAdmontioin('success', 'Success'), 33 | 'admonition:add-fail': this.addAdmontioin('fail', 'Failure') 34 | }) 35 | } 36 | 37 | unsubscribe() { 38 | if (this.subscription) { 39 | this.subscription.dispose() 40 | } 41 | } 42 | } 43 | 44 | const admonition = new Admonition() 45 | 46 | module.exports = { 47 | activate() { 48 | admonition.subsribe() 49 | if (markdownRenderer) { 50 | return markdownRenderer.remarkPlugins.push(admonition.plugin) 51 | } 52 | }, 53 | 54 | deactivate() { 55 | admonition.unsubscribe() 56 | if (markdownRenderer) { 57 | markdownRenderer.remarkPlugins = markdownRenderer.remarkPlugins.filter( 58 | function(plugin) { 59 | return plugin !== admonition.plugin 60 | } 61 | ) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /README-mobile.md: -------------------------------------------------------------------------------- 1 | # Inkdrop Admonition 2 | 3 | Allows to add block-styled side content to your [Inkdrop](https://www.inkdrop.info/) notes. 4 | 5 | ## Motivation 6 | 7 | As I mainly write my notes in markdown using Inkdrop, admonitions help me to write a more structured content and collapsible blocks can make my notes easier to read. 8 | 9 | _The inspiration came from the MkDocs [admonition extension](https://squidfunk.github.io/mkdocs-material/extensions/admonition/)._ 10 | 11 | ## Usage 12 | 13 | There are currently 10 different admonition types: `note`, `info`, `question`, `abstract`, `danger`, `warning`, `success`, `fail`, `example` and `spoiler`. 14 | 15 | In order to create a new `info` admonition with the title "Info" you can use following syntax: 16 | ``` 17 | [[info | Info]] 18 | | **markdown** content 19 | ``` 20 | 21 | ![Picture of an info admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/info.png) 22 | 23 | In order to create a block without a title just leave it out: 24 | ``` 25 | [[info]] 26 | | This is an `info` admonition without a title. 27 | ``` 28 | 29 | ![Picture of an info admonition without a title](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/info-no-title.png) 30 | 31 | ### Spoiler 32 | 33 | The `spoiler` admonition is special as it is collapsible, doesn't have an icon and always requires a title: 34 | ``` 35 | [[spoiler | Spoiler]] 36 | | **markdown** content 37 | ``` 38 | 39 | ![Picture of an open spoiler admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/spoiler-open.png) 40 | 41 | ![Picture of a closed spoiler admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/spoiler-closed.png) 42 | 43 | 44 | To make a "normal" admontion collapsible just add `-spoiler` to the type e.g. `abstract-spoiler`. 45 | 46 | ``` 47 | [[abstract-spoiler | Abstract]] 48 | | **markdown** content 49 | ``` 50 | ![Picture of an abstract spoiler admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/abstract-spoiler.png) 51 | 52 | _As soon as one makes a "normal" admonition collapsible the title becomes mandatory._ 53 | 54 | ### Complex Content 55 | 56 | You can add any kind of markdown content inside of an admonition, e.g.: 57 | 58 | ``` 59 | [[note | Note]] 60 | | My note content 61 | | 62 | | | This | is | 63 | | |:-----|:-----| 64 | | | a | test | 65 | | 66 | | ```js 67 | | const s = "test"; 68 | | ``` 69 | | [[info | Info]] 70 | | | another block 71 | ``` 72 | 73 | ![Picture of an admonition with markdown content](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/complex-content.png) 74 | 75 | ### Keymapping 76 | 77 | By default the shortcut Ctrl + Alt + a will add a new (note) admonition and everything that is selected with the cursor will be automatically placed inside of it. 78 | 79 | ## Screenshots 80 | Remaining admonitions: 81 | 82 | ![Picture of remaining admonitions](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/remaining.png) 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Inkdrop Admonition 2 | 3 | Allows to add block-styled side content to your [Inkdrop](https://www.inkdrop.info/) notes. 4 | 5 | ## Motivation 6 | 7 | As I mainly write my notes in markdown using Inkdrop, admonitions help me to write a more structured content and collapsible blocks can make my notes easier to read. 8 | 9 | _The inspiration came from the MkDocs [admonition extension](https://squidfunk.github.io/mkdocs-material/extensions/admonition/)._ 10 | 11 | ## Install 12 | 13 | ``` 14 | ipm install admonition 15 | ``` 16 | 17 | ## Usage 18 | 19 | There are currently 10 different admonition types: `note`, `info`, `question`, `abstract`, `danger`, `warning`, `success`, `fail`, `example` and `spoiler`. 20 | 21 | In order to create a new `info` admonition with the title "Info" you can use following syntax: 22 | ``` 23 | [[info | Info]] 24 | | **markdown** content 25 | ``` 26 | 27 | ![Picture of an info admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/info.png) 28 | 29 | In order to create a block without a title just leave it out: 30 | ``` 31 | [[info]] 32 | | This is an `info` admonition without a title. 33 | ``` 34 | 35 | ![Picture of an info admonition without a title](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/info-no-title.png) 36 | 37 | ### Spoiler 38 | 39 | The `spoiler` admonition is special as it is collapsible, doesn't have an icon and always requires a title: 40 | ``` 41 | [[spoiler | Spoiler]] 42 | | **markdown** content 43 | ``` 44 | 45 | ![Picture of an open spoiler admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/spoiler-open.png) 46 | 47 | ![Picture of a closed spoiler admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/spoiler-closed.png) 48 | 49 | 50 | To make a "normal" admontion collapsible just add `-spoiler` to the type e.g. `abstract-spoiler`. 51 | 52 | ``` 53 | [[abstract-spoiler | Abstract]] 54 | | **markdown** content 55 | ``` 56 | ![Picture of an abstract spoiler admonition](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/abstract-spoiler.png) 57 | 58 | _As soon as one makes a "normal" admonition collapsible the title becomes mandatory._ 59 | 60 | ### Complex Content 61 | 62 | You can add any kind of markdown content inside of an admonition, e.g.: 63 | 64 | ``` 65 | [[note | Note]] 66 | | My note content 67 | | 68 | | | This | is | 69 | | |:-----|:-----| 70 | | | a | test | 71 | | 72 | | ```js 73 | | const s = "test"; 74 | | ``` 75 | | [[info | Info]] 76 | | | another block 77 | ``` 78 | 79 | ![Picture of an admonition with markdown content](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/complex-content.png) 80 | 81 | ### Keymapping 82 | 83 | By default the shortcut Ctrl + Alt + a will add a new (note) admonition and everything that is selected with the cursor will be automatically placed inside of it. 84 | 85 | ## Screenshots 86 | Remaining admonitions: 87 | 88 | ![Picture of remaining admonitions](https://github.com/libeanim/inkdrop-admonition/raw/master/docs/images/remaining.png) 89 | -------------------------------------------------------------------------------- /styles/admonition.less: -------------------------------------------------------------------------------- 1 | .admonition { 2 | box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2); 3 | position: relative; 4 | margin: 1.5625em 0; 5 | padding: 0 1.2rem; 6 | border-left: .4rem solid #448aff; 7 | border-radius: .2rem; 8 | overflow: auto; 9 | 10 | &>summary { 11 | cursor: pointer; 12 | } 13 | 14 | &>.custom-block-body { 15 | margin: 1em 0; 16 | } 17 | } 18 | 19 | .admonition-icon { 20 | position: absolute; 21 | left: 1.2rem; 22 | font-family: "FontAwesome"; 23 | font-style: normal; 24 | font-weight: 400; 25 | font-size: 24px; 26 | // font-size: 1.7rem; 27 | // width: 1.8rem; 28 | width: 24px; 29 | display: inline-block; 30 | line-height: 1; 31 | text-transform: none; 32 | letter-spacing: normal; 33 | text-align: center; 34 | word-wrap: normal; 35 | white-space: nowrap; 36 | direction: ltr; 37 | /* Support for all WebKit browsers. */ 38 | -webkit-font-smoothing: antialiased; 39 | /* Support for Safari and Chrome. */ 40 | text-rendering: optimizeLegibility; 41 | /* Support for Firefox. */ 42 | -moz-osx-font-smoothing: grayscale; 43 | /* Support for IE. */ 44 | font-feature-settings: 'liga'; 45 | } 46 | 47 | .admonition-title { 48 | margin: 0 -1.2rem; 49 | padding: .8rem 1.2rem .8rem 4rem; 50 | border-bottom: .1rem solid rgba(68,138,255,.1); 51 | background-color: rgba(68,138,255,.1); 52 | font-weight: 700; 53 | } 54 | 55 | .admonition-note { 56 | @color: #448aff; 57 | @icon: "\f249"; 58 | 59 | .admonition; 60 | border-left-color: @color; 61 | 62 | &>.custom-block-heading { 63 | &:extend(.admonition-title); 64 | background-color: fade(@color, 10%); 65 | 66 | &:before { 67 | &:extend(.admonition-icon); 68 | color: @color; 69 | content: @icon; 70 | } 71 | } 72 | } 73 | 74 | .admonition-info { 75 | @color: #009688; 76 | @icon: "\f05a"; 77 | 78 | .admonition; 79 | border-left-color: @color; 80 | 81 | &>.custom-block-heading { 82 | &:extend(.admonition-title); 83 | background-color: fade(@color, 10%); 84 | 85 | &:before { 86 | &:extend(.admonition-icon); 87 | color: @color; 88 | content: @icon; 89 | } 90 | } 91 | } 92 | 93 | .admonition-danger { 94 | @color: #c2185b; 95 | @icon: "\f0e7"; 96 | 97 | .admonition; 98 | // .admonition; 99 | border-left-color: @color; 100 | 101 | &>.custom-block-heading { 102 | &:extend(.admonition-title); 103 | background-color: fade(@color, 10%); 104 | 105 | &:before { 106 | &:extend(.admonition-icon); 107 | color: @color; 108 | content: @icon; 109 | } 110 | } 111 | } 112 | 113 | .admonition-warning { 114 | @color: #ff9100; 115 | @icon: "\f071"; 116 | 117 | .admonition; 118 | border-left-color: @color; 119 | 120 | &>.custom-block-heading { 121 | &:extend(.admonition-title); 122 | background-color: fade(@color, 10%); 123 | 124 | &:before { 125 | &:extend(.admonition-icon); 126 | color: @color; 127 | content: @icon; 128 | } 129 | } 130 | } 131 | 132 | .admonition-success { 133 | @color: #00c853; 134 | @icon: "\f00c"; 135 | 136 | .admonition; 137 | border-left-color: @color; 138 | 139 | &>.custom-block-heading { 140 | &:extend(.admonition-title); 141 | background-color: fade(@color, 10%); 142 | 143 | &:before { 144 | &:extend(.admonition-icon); 145 | color: @color; 146 | content: @icon; 147 | } 148 | } 149 | } 150 | 151 | .admonition-fail { 152 | @color: #d32f2f; 153 | @icon: "\f00d"; 154 | 155 | .admonition; 156 | border-left-color: @color; 157 | 158 | &>.custom-block-heading { 159 | &:extend(.admonition-title); 160 | background-color: fade(@color, 10%); 161 | 162 | &:before { 163 | &:extend(.admonition-icon); 164 | color: @color; 165 | content: @icon; 166 | } 167 | } 168 | } 169 | 170 | .admonition-question { 171 | @color: #64dd17; 172 | @icon: "\f059"; 173 | 174 | .admonition; 175 | border-left-color: @color; 176 | 177 | &>.custom-block-heading { 178 | &:extend(.admonition-title); 179 | background-color: fade(@color, 10%); 180 | 181 | &:before { 182 | &:extend(.admonition-icon); 183 | color: @color; 184 | content: @icon; 185 | } 186 | } 187 | } 188 | 189 | .admonition-abstract { 190 | @color: #00b0ff; 191 | @icon: "\f02d"; 192 | 193 | .admonition; 194 | border-left-color: @color; 195 | 196 | &>.custom-block-heading { 197 | &:extend(.admonition-title); 198 | background-color: fade(@color, 10%); 199 | 200 | &:before { 201 | &:extend(.admonition-icon); 202 | color: @color; 203 | content: @icon; 204 | } 205 | } 206 | } 207 | 208 | .admonition-example { 209 | @color: #651fff; 210 | @icon: "\f0cb"; 211 | 212 | .admonition; 213 | border-left-color: @color; 214 | 215 | &>.custom-block-heading { 216 | &:extend(.admonition-title); 217 | background-color: fade(@color, 10%); 218 | 219 | &:before { 220 | &:extend(.admonition-icon); 221 | color: @color; 222 | content: @icon; 223 | } 224 | } 225 | } 226 | 227 | .admonition-spoiler { 228 | @color: #455a64; 229 | 230 | .admonition; 231 | border-left-color: @color; 232 | 233 | &>.custom-block-heading { 234 | &:extend(.admonition-title); 235 | padding-left: 1rem; 236 | background-color: fade(@color, 10%); 237 | } 238 | } 239 | --------------------------------------------------------------------------------