diff --git a/.gitignore b/.gitignore
index 69aab94..a0cf010 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
 dist/
 node_modules/
 publish/
-WIP/
\ No newline at end of file
+WIP/
diff --git a/.npmignore b/.npmignore
index 3dfd160..109de0c 100644
--- a/.npmignore
+++ b/.npmignore
@@ -6,4 +6,4 @@
 /dist
 tsconfig.json
 webpack.config.js
-/WIP
\ No newline at end of file
+/WIP
diff --git a/README.md b/README.md
index dfa7ef1..769f3df 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,67 @@
-# Joplin Plugin - Spoiler cards
+# Joplin Plugin - Spoilers
 
-This Joplin plugin allows you to create cards with title and extendable body.
+This Joplin plugin allows you to create inline spoilers and spoiler blocks with title and extendable body.
 
-**Note**: Requires Joplin 1.7.0+
+**Note**: Requires Joplin 1.7.11+
 
-**Version**: 0.3.1
+**Version**: 1.0.0
 
-![](./docs/cards-plugin-preview.gif)
+**Spoilers (inline)**
+
+![](./docs/inline-spoiler-preview.gif)
+
+**Spoiler blocks**
+
+![](./docs/spoiler-block-preview.gif)
+
+
+
+## Installation
+
+- Open Joplin and navigate to `Preferences > Plugins`
+- Search for `Spoilers` and click install
+- Restart Joplin
+
+### Uninstall
+
+- Open Joplin and navigate to `Tools > Options > Plugins`
+- Search for `Spoilers` plugin
+- Press `Delete` to remove the plugin or `Disable` to disable it
+- Restart Joplin
 
 ## Usage
 
-In order to create a card, you need to write in this format:
+### Spoiler (inline)
+
+In order to create a spoiler (inline), you can:
+- press on the `Spoiler` button or
+- use the shortcut `Ctrl + Alt + O`
+- or write in the following format:
+
+```
+%%spoiler%%
+```
+
+### Spoiler block
+
+In order to create a spoiler block, you can:
+- press on the `Spoiler block` button or
+- use the shortcut `Ctrl + Alt + P`
+- or write in the following format:
 
 ```
 :[
-Card name here...
+Spoiler title here...
 
-Card body text here...
+Spoiler body text here...
 
 ]:
 ```
 
-Please note, that the empty line above and below card body text is **needed**.
-Card body supports markdown formatting as well.
-
-### Example
+Please note, that the empty line above and below spoiler body text is **needed**.
+Spoiler title and body supports markdown formatting as well.
 
+**Example**:
 ```
 :[
 3 ways to check if an Object has a property in JS
@@ -46,31 +82,58 @@ hero.toString; // => function() {...}
 hero.hasOwnProperty('toString'); // => false
 ~~~
 * * *
-....
 
 ]:
 ```
 
-## Custom styling of cards
+## Custom styles
 
-If you would like to style the spoiler cards to your preference, use the following in your `userstyle.css` file:
+If you would like to style the spoiler blocks to your preference, use the following in your `userstyle.css` file:
 
 
 ```css
-/* Styling of the card title */
+/* Styling of the spoiler block title */
 .summary-title {
   
 }
 
-/* Styling of the card body */
+/* Styling of the spoiler block body */
 .summary-content {
   
 }
 ```
 
+### Exporting styles
+
+By default when exporting with spoiler blocks, the blocks get extended, show the body and hides the arrows. Inline spoilers stay hidden.
+
+Alternately, if you would like to style the spoiler blocks to your liking when exporting, use the following in you `userstyle.css` file:
+```css
+@media print {
+
+  /* Hides the side arrow */
+  .summary-title:before {
+      content: "";
+  }
+
+  /* Container for spoiler blocks */
+  .spoiler-block {}
+
+  /* Container for spoiler title */
+  #spoiler-block-title {}
+  
+  /* Container for spoiler body */
+  #spoiler-block-body {
+      /* Shows the body contents */
+      display: block;
+      animation: none;
+  }
+
+}
+```
+
 ## Notes
 
-- I have not thoroughly tested the plugin, so note that **there might be bugs**.
-- I might have to change formatting in the future to be more convenient, but nothing significant from now on.
+- **There might be bugs**, [report them here](https://github.com/martinkorelic/joplin-plugin-spoilers/issues) and I'll try to fix them when I'll find time.
 
 > Created on 12th April 2021
\ No newline at end of file
diff --git a/docs/cards-plugin-preview.gif b/docs/cards-plugin-preview.gif
deleted file mode 100644
index d1ff015..0000000
Binary files a/docs/cards-plugin-preview.gif and /dev/null differ
diff --git a/docs/inline-spoiler-preview.gif b/docs/inline-spoiler-preview.gif
new file mode 100644
index 0000000..dcdb234
Binary files /dev/null and b/docs/inline-spoiler-preview.gif differ
diff --git a/docs/spoiler-block-preview.gif b/docs/spoiler-block-preview.gif
new file mode 100644
index 0000000..7e0fff6
Binary files /dev/null and b/docs/spoiler-block-preview.gif differ
diff --git a/package-lock.json b/package-lock.json
index a29d239..e0b0134 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -47,9 +47,9 @@
       "dev": true
     },
     "@types/node": {
-      "version": "14.14.37",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
-      "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==",
+      "version": "14.14.44",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.44.tgz",
+      "integrity": "sha512-+gaugz6Oce6ZInfI/tK4Pq5wIIkJMEJUu92RB3Eu93mtj4wjjjz9EB5mLp5s1pSsLXdC/CPut/xF20ZzAQJbTA==",
       "dev": true
     },
     "@webassemblyjs/ast": {
@@ -694,9 +694,9 @@
       "dev": true
     },
     "chalk": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
-      "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+      "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
       "dev": true,
       "requires": {
         "ansi-styles": "^4.1.0",
diff --git a/package.json b/package.json
index 9b0c995..1e20b20 100644
--- a/package.json
+++ b/package.json
@@ -1,15 +1,15 @@
 {
   "name": "joplin-plugin-spoiler-cards",
-  "version": "0.3.1",
-  "description": "Joplin plugin allows you to create cards with title and extendable body.",
+  "version": "1.0.0",
+  "description": "Joplin plugin for creating inline spoilers and spoiler blocks.",
   "author": "martinkorelic",
-  "homepage": "https://github.com/martinkorelic/joplin-plugin-spoiler-cards",
+  "homepage": "https://github.com/martinkorelic/joplin-plugin-spoilers",
   "bugs": {
-    "url": "https://github.com/martinkorelic/joplin-plugin-spoiler-cards/issues"
+    "url": "https://github.com/martinkorelic/joplin-plugin-spoilers/issues"
   },
   "repository": {
     "type": "git",
-    "url": "git+https://github.com/martinkorelic/joplin-plugin-spoiler-cards.git"
+    "url": "git+https://github.com/martinkorelic/joplin-plugin-spoilers.git"
   },
   "scripts": {
     "dist": "webpack --joplin-plugin-config buildMain && webpack --joplin-plugin-config buildExtraScripts && webpack --joplin-plugin-config createArchive",
@@ -18,11 +18,14 @@
   },
   "license": "MIT",
   "keywords": [
-    "joplin-plugin"
+    "joplin",
+    "joplin-plugin",
+    "markdown",
+    "markdownit"
   ],
   "devDependencies": {
-    "@types/node": "^14.0.14",
-    "chalk": "^4.1.0",
+    "@types/node": "^14.14.44",
+    "chalk": "^4.1.1",
     "copy-webpack-plugin": "^6.1.0",
     "fs-extra": "^9.0.1",
     "glob": "^7.1.6",
diff --git a/src/cards.js b/src/cards.js
deleted file mode 100644
index bd3cc9b..0000000
--- a/src/cards.js
+++ /dev/null
@@ -1,144 +0,0 @@
-module.exports = {
-    default: function(context) {
-        return {
-            plugin: async function(markdownIt, _options) {
-                const pluginId = context.pluginId;
-                const contentScriptId = _options.contentScriptId;
-
-                markdownIt.block.ruler.after('fence', 'spoiler_card', spoiler_card, {alt: ['paragraph', 'reference', 'blockquote', 'list']});
-                
-                /*
-                const defaultRender = markdownIt.renderer.rules.fence || function(tokens, idx, options, env, self) {
-                    return self.renderToken(tokens, idx, options, env, self);
-                };
-                markdownIt.renderer.rules.fence = function (tokens, idx, options, env, self) {
-                    let token = tokens[idx];
-
-                    // We detect if card block
-                    if (token.info !== 'card') return defaultRender(tokens, idx, options, env, self);
-
-                    // Split the card title and body by :[]:
-                    let card = token.content.match(/(?<title>.+)\n:\[(?<body>(?:.|\n)*?)\]:/i);
-
-                    // Return default renderer if formatted wrong
-                    if (!card) return defaultRender(tokens, idx, options, env, self);
-
-                    let { title, body } = card.groups;
-
-                    if (!title || !body) return defaultRender(tokens, idx, options, env, self);
-
-                     // Re render markdown content within
-                    return `
-                    <details> \
-                        <summary class="summary-title">${title}</summary>
-                        <div class="summary-content">
-                        ${markdownIt.render(body)}
-                        </div>
-                    </details>`;
-                }*/
-            },
-            // Assests such as JS or CSS that should be loaded in the rendered HTML document
-            assets: function() {
-                return [
-                    {
-                        name: "./cards.css"
-                    } 
-                ];
-            },
-        }
-    }
-}
-
-function spoiler_card(state, start, end, silent) {
-
-    let lastPos, found = false,
-    pos = state.bMarks[start]+ state.tShift[start],
-    max = state.eMarks[start],
-    next;
-
-    var token;
-    let curLine = start;
-
-    if (pos + 2 > max) return false;
-
-    // Check when it starts with ':['
-    if (state.src.slice(pos, pos+2) !== ':[') return false;  
-    pos += 2;
-
-    // We don't accept empty card formats
-    if (state.src.slice(pos, pos+2) == ']:') return false;
-    pos += 2;
-
-    if (silent) return true;    
-
-    curLine++;
-    // Correct formatting of the title
-    if (state.isEmpty(curLine)) return false;
-
-    let title = curLine;
-
-    curLine++;
-    // Needs to be atleast one empty line in between for better formatting
-    if (!state.isEmpty(curLine)) return false;
-
-    curLine++;
-    // Now there needs to be atleast some content before we render the card
-    if (state.isEmpty(curLine)) return false;
-
-    // If the formatting is okay, we create new tokens
-    /*
-    1 means the tag is opening
-    0 means the tag is self-closing
-    -1 means the tag is closing
-    */
-    
-    state.push('details_open', 'details', 1);
-
-    token = state.push('summary_open', 'summary', 1);
-    token.attrs = [[ 'class', 'summary-title' ]];
-
-    token = state.push('inline', '', 0);
-    token.map = [ title, title ];
-    token.content = state.getLines(title, title+1, state.tShift[title], false).trim();
-    token.children = [];
-
-    state.push('summary_close', 'summary', -1);
-
-    token = state.push('spoiler_card_body', 'div', 1);
-    token.attrs = token.attr = [[ 'class', 'summary-content' ]];
-
-    // Content starts
-    for (next = curLine; !found;) {
-        next++;
-        
-        if (next >= end) {
-            break;
-        }
-        
-        pos = state.bMarks[next] + state.tShift[next];
-        max = state.eMarks[next];
-        
-        if (pos < max && state.tShift[next] < state.blkIndent) {
-            break;
-        }
-
-        // Check if there's only ']:' on the line
-        if (state.src.slice(pos, max).length == 2 && state.src.slice(pos, max).trim().slice(-2) == ']:') {
-            lastPos = state.src.slice(0, max).lastIndexOf(']:');
-            lastLine = state.src.slice(pos, lastPos);
-            found = true;
-        }
-    }
-
-    // We use to render markdown within
-    state.md.block.tokenize(state, curLine, next, false);
-    
-    state.line = next + 1;
-
-    // Finalize body
-    state.push('spoiler_body_close', 'div', -1);
-
-    // Finalize details    
-    state.push('details_close', 'details', -1);
-    return true;
-}
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index 9d10381..ae25bbe 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,134 +1,57 @@
 import joplin from 'api';
 import { ContentScriptType, ToolbarButtonLocation } from 'api/types';
 
-// const uslug = require('uslug');
-
 joplin.plugins.register({
 	onStart: async function() {
 
-		/*
-		// Panel legacy (might upgrade and create table of cards panel)
-
-		const panels = joplin.views.panels;
-		const view = await panels.create('tod-panel');
-
-		// Create a toolbar button
+		// Create a spoiler block command
 		await joplin.commands.register({
-			name: 'toggleTOD',
-			label: 'Toggle Table of definitions',
-			iconName: 'fas fa-scroll',
+			name: 'insert_spoiler_block',
+			label: 'Spoiler block',
+			iconName: 'fas fa-angle-right',
 			execute: async () => {
-				const visible = await panels.visible(view);
-				panels.show(view, !visible);
+				await joplin.commands.execute('insertText',':[\nTitle...\n\nBody...\n\n]:');
 			}
 		});
 
-		await joplin.views.toolbarButtons.create('todButton', 'toggleTOD', ToolbarButtonLocation.NoteToolbar);
+		// Create a spoiler block toolbar button
+		await joplin.views.toolbarButtons.create('insert_spoiler_block', 'insert_spoiler_block', ToolbarButtonLocation.EditorToolbar);
 		
-		// Building the panel
-		await joplin.views.panels.setHtml(view, 'Loading...');
-		await joplin.views.panels.addScript(view, './webview.css');
-		await joplin.views.panels.addScript(view, './table-tod.js');	
-		
-		// Message handler
-		panels.onMessage(view, async (message: any) => {
-			console.info(message);
-
-			if (message.name == "fetchData") {
-				joplin.views.panels.setHtml(view, "Loud and clear!");
-				return await fetchDefCards();
-			} else if (message.name == "tokens") {
-				console.info(message.token);
-				console.info(message.tokens);
-				return;
+		// Create a spoiler block command shortcut
+		await joplin.views.menus.create('spoiler_block', 'Insert spoiler block', [
+			{
+				commandName: 'insert_spoiler_block',
+				accelerator: 'Ctrl+Alt+P'
 			}
+		]);
 
-		});
-
-		// Structure the panel
-		await panels.setHtml(view, `
-			<div class="container">Click to generate cards</div>
-		`);
-
-		// Scans and fetches all the definitions made
-		async function fetchDefCards() {
-
-			const { body } = await joplin.workspace.selectedNote();
-
-			if (!body) return body;
-
-			var cards = body.match(/(.+)\n:\[((?:.|\n)*?)\]:/gi);
-			
-			const allCards = [];
-			for (var card in cards) {
-				allCards.push(cards[card].match(/(?<title>.+)\n:\[(?<body>(?:.|\n)*?)\]:/i).groups);
+		// Create a inline spoiler command
+		await joplin.commands.register({
+			name: 'insert_inline_spoiler',
+			label: 'Spoiler',
+			iconName: 'fas fa-low-vision',
+			execute: async () => {
+				await joplin.commands.execute('insertText','%%spoiler%%');
 			}
-
-			return allCards;
-		}
-
-		// This event will be triggered when the user selects a different note
-		await joplin.workspace.onNoteSelectionChange(() => {
-			updateToDView();
 		});
 
-		// This event will be triggered when the content of the note changes
-		// as you also want to update the TOC in this case.
-		await joplin.workspace.onNoteChange(() => {
-			updateToDView();
-		});
-
-		// Also update the TOC when the plugin starts
-		updateToDView();
-
-		async function updateToDView() {
-			
-			// Get the current note in the workspace
-			const cards = await fetchDefCards();
-			slugs = {};
+		// Create a inline spoiler toolbar button
+		await joplin.views.toolbarButtons.create('insert_inline_spoiler', 'insert_inline_spoiler', ToolbarButtonLocation.EditorToolbar);
 
-			// Keep in mind that it can be `null` if nothing is currently selected!
-			if (cards) {
-								
-				console.info(cards);
-				console.info('Note content has changed!');
-
-			} else {
-				console.info('No note is selected.');
+		// Create a inline spoiler command shortcut
+		await joplin.views.menus.create('inline_spoiler', 'Insert spoiler', [
+			{
+				commandName: 'insert_inline_spoiler',
+				accelerator: 'Ctrl+Alt+O'
 			}
-
-		}
-		*/
+		]);
 
 		// Here we register new Markdown plugin
 		await joplin.contentScripts.register(
 			ContentScriptType.MarkdownItPlugin,
-			'table-tod',
-			'./cards.js'
+			'Spoilers',
+			'./spoilers.js'
 		);
 
 	},
-});
-
-/* Helper functions
-
-let slugs = {};
-
-function headerSlug(headerText) {
-	const s = uslug(headerText);
-	let num = slugs[s] ? slugs[s] : 1;
-	const output = [s];
-	if (num > 1) output.push(num);
-	slugs[s] = num + 1;
-	return output.join('-');
-}
-
-function escapeHtml(unsafe:string) {
-	return unsafe
-		.replace(/&/g, "&amp;")
-		.replace(/</g, "&lt;")
-		.replace(/>/g, "&gt;")
-		.replace(/"/g, "&quot;")
-		.replace(/'/g, "&#039;");
-}
-*/
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/src/manifest.json b/src/manifest.json
index 7038fe6..4627797 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -2,11 +2,11 @@
 	"manifest_version": 1,
 	"id": "joplin.plugin.spoiler.cards",
 	"app_min_version": "1.7",
-	"version": "0.3.1",
-	"name": "Spoiler cards",
-	"description": "Create spoiler cards with title and extendable body.",
+	"version": "1.0.0",
+	"name": "Spoilers",
+	"description": "Create inline spoilers and spoiler blocks with title and extendable body.",
 	"author": "Martin Korelič",
-	"homepage_url": "https://github.com/martinkorelic/joplin-plugin-spoiler-cards",
-	"repository_url": "https://github.com/martinkorelic/joplin-plugin-spoiler-cards",
-	"keywords": ["joplin", "plugin", "cards", "spoiler"]
+	"homepage_url": "https://github.com/martinkorelic/joplin-plugin-spoilers",
+	"repository_url": "https://github.com/martinkorelic/joplin-plugin-spoilers",
+	"keywords": ["joplin", "plugin", "spoiler", "blocks"]
 }
\ No newline at end of file
diff --git a/src/cards.css b/src/spoiler-style.css
similarity index 91%
rename from src/cards.css
rename to src/spoiler-style.css
index 5ba0bb9..5dca960 100644
--- a/src/cards.css
+++ b/src/spoiler-style.css
@@ -70,4 +70,8 @@ details {
   padding: 1em;
   font-weight: 300;
   line-height: 1.5;
+}
+
+.spoiler-inline {
+  color: red;
 }
\ No newline at end of file
diff --git a/src/spoilers.js b/src/spoilers.js
new file mode 100644
index 0000000..5c55706
--- /dev/null
+++ b/src/spoilers.js
@@ -0,0 +1,428 @@
+module.exports =  {
+    default: function(context) {
+        return {
+            plugin: async function(markdownIt, _options) {
+                const pluginId = context.pluginId;
+                const contentScriptId = _options.contentScriptId;
+
+                markdownIt.block.ruler.after('fence', 'spoiler_block', spoiler_block, {alt: ['paragraph', 'reference', 'blockquote', 'list']});
+
+                markdownIt.inline.ruler.after('escape', 'spoiler_inline', tokenize_spoiler);
+                markdownIt.inline.ruler2.after('emphasis', 'spoiler_inline', function (state) {
+                    var curr,
+                        tokens_meta = state.tokens_meta,
+                        max = (state.tokens_meta || []).length;
+
+                    postProcess(state, state.delimiters);
+
+                    for (curr = 0; curr < max; curr++) {
+                        if (tokens_meta[curr] && tokens_meta[curr].delimiters) {
+                            postProcess(state, tokens_meta[curr].delimiters);
+                        }
+                    }
+                });
+
+                // Inline spoiler open renderer
+                const spoiler_open_defaultRender = markdownIt.renderer.rules.spoiler_open || function(tokens, idx, options, env, self) {
+                    return self.renderToken(tokens, idx, options, env, self);
+                };
+                
+                const spoiler_inline_open = function(tokens, idx, options, env, self) {
+
+                    const token = tokens[idx];
+
+                    if (token.type !== 'spoiler_open') return spoiler_open_defaultRender(tokens, idx, options, env, self);
+                    
+                    // Generate a random id to distinguish between events
+                    let ranhex = genRanHex(8);
+                    // We use a checkbox hack to implement a clickable event
+                    return `<input type="checkbox" class="spoiler-inline" id=${ranhex}><label class="spoiler-inline" for=${ranhex}><span class="spoiler-inline">`;
+                };
+
+                markdownIt.renderer.rules.spoiler_open = spoiler_inline_open;
+
+                // Inline spoiler close renderer
+                const spoiler_close_defaultRender = markdownIt.renderer.rules.spoiler_close || function(tokens, idx, options, env, self) {
+                    return self.renderToken(tokens, idx, options, env, self);
+                };
+
+                const spoiler_inline_close = function(tokens, idx, options, env, self) {
+
+                    const token = tokens[idx];
+
+                    if (token.type !== 'spoiler_close') return spoiler_close_defaultRender(tokens, idx, options, env, self);
+                    
+                    return `</span></label>`;
+                };
+
+                markdownIt.renderer.rules.spoiler_close = spoiler_inline_close;
+                
+            },
+            // Assests such as JS or CSS that should be loaded in the rendered HTML document
+            assets: function() {
+                return [
+
+                    /* For some reason this fails when exporting (cannot find the css file in assets)
+                    {
+                        name: 'spoiler-style.css'
+                    }
+                    */
+
+                    // Styling of spoiler blocks
+                    {
+                        inline: true,
+                        mime: 'text/css',
+                        text: `
+                        .spoiler-block {
+                            font-size: 1rem;
+                            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
+                                        0 10px 10px -5px rgba(0, 0, 0, 0.04);
+                            width: 100%;
+                            color: black;
+                            background: #c2c2c2;
+                            border-radius: 8px;
+                            border: 1px solid #7a7a7a;
+                            position: relative;
+                            margin-top: 1em;
+                            margin-bottom: 1em;
+                            display: grid;
+                        }
+
+                        .spoiler-block-input {
+                            display: none;
+                        }
+
+                        label.spoiler-block-title {
+                            cursor: pointer;
+                        }
+
+                        .summary-title {
+                            user-select: none;
+                            padding: 0.8em;
+                            font-family: monospace;
+                            border-radius: 8px;
+                            font-size: 18px;
+                        }
+
+                        .summary-title:hover {
+                            opacity: 0.7;
+                        }
+                        
+                        .summary-title:before {
+                            margin-right: 0.3em;
+                            font-size: 1.6em;
+                            vertical-align: text-top;
+                            content: "\u2B9E  ";
+                            display: inline-block;
+                            transform-origin: center;
+                            transition: 200ms linear;
+                        }
+
+                        @keyframes open {
+                            0% {
+                              opacity: 0;
+                            }
+                            100% {
+                              opacity: 1;
+                            }
+                          }
+
+                        div#spoiler-block-body {
+                            display: none;
+                            animation: open 0.3s ease-in-out;
+                        }
+
+                        input.spoiler-block-input:checked ~ label ~ div#spoiler-block-body {
+                            display: block;
+                        }
+
+                        input.spoiler-block-input:checked ~ label#spoiler-block-title:before {
+                            transform: rotate(90deg);
+                        }
+
+                        .summary-content {
+                            border-top: 1px solid #7a7a7a;
+                            cursor: default;
+                            padding: 1em;
+                            font-weight: 300;
+                            line-height: 1.5;
+                        }
+
+                        /* Styles for exporting */
+                        @media print {
+
+                            div#spoiler-block-body {
+                                display: block;
+                                animation: none;
+                            }
+
+                            .summary-title:before {
+                                content: "";
+                            }
+                        }
+                        `
+                    },
+
+                    // Styling of inline spoilers
+                    {
+                        inline: true,
+                        mime: 'text/css',
+                        text: `
+                        input.spoiler-inline {
+                            display: none;
+                        }
+
+                        input.spoiler-inline + label.spoiler-inline {
+                            cursor: pointer;
+                            background: #000;
+                            border-radius: 3px;
+                            box-shadow: 0 0 1px #ffffff;
+                            color: #000;
+                            user-select: none;
+                            display: inline-flex;
+                        }
+                        
+                        input.spoiler-inline + label.spoiler-inline > span.spoiler-inline {
+                            opacity: 0;
+                        }
+
+                        input.spoiler-inline:checked + label.spoiler-inline > span.spoiler-inline {
+                            background: #0001;
+                            color: inherit;
+                            box-shadow: none;
+                            user-select: text;
+                            opacity: 1;
+                        }
+
+                        input.spoiler-inline:checked + label.spoiler-inline {
+                            background: #0001;
+                            color: inherit;
+                            box-shadow: none;
+                            user-select: text;
+                            display: inline-flex;
+                        }
+                        `
+                    }
+                ];
+            },
+        }
+    }
+}
+
+// Tokenizing the spoiler blocks
+function spoiler_block(state, start, end, silent) {
+
+    let found = false,
+    pos = state.bMarks[start]+ state.tShift[start],
+    max = state.eMarks[start],
+    next;
+
+    var token;
+    let curLine = start;
+
+    if (pos + 2 > max) return false;
+
+    // Check when it starts with ':['
+    if (state.src.slice(pos, pos+2) !== ':[') return false;  
+    pos += 2;
+
+    // We don't accept empty card formats
+    if (state.src.slice(pos, pos+2) == ']:') return false;
+    pos += 2;
+
+    if (silent) return true;    
+
+    curLine++;
+    // Correct formatting of the title
+    if (state.isEmpty(curLine)) return false;
+
+    let title = curLine;
+
+    curLine++;
+    // Needs to be atleast one empty line in between for better formatting
+    if (!state.isEmpty(curLine)) return false;
+
+    curLine++;
+    // Now there needs to be atleast some content before we render the card
+    if (state.isEmpty(curLine)) return false;
+
+    // If the formatting is okay, we create new tokens
+    /*
+    1 means the tag is opening
+    0 means the tag is self-closing
+    -1 means the tag is closing
+    */
+    
+    // Spoiler block
+    token = state.push('spoiler_block_open', 'div', 1);
+    token.attrs = [[ 'class', 'spoiler-block']];
+
+    // We generate a random id to distinguish between events
+    let ranhex = genRanHex(8);
+
+    // Input
+    token = state.push('spoiler_title_input', 'input', 0);
+    token.attrs = [[ 'class', 'spoiler-block-input' ], [ 'type', 'checkbox' ], [ 'id', ranhex ]];
+
+    // Spoiler title - label
+    token = state.push('spoiler_title_open', 'label', 1);
+    token.attrs = [[ 'class', 'summary-title' ], [ 'id', 'spoiler-block-title' ], [ 'for', ranhex ]];
+
+    token = state.push('inline', '', 0);
+    token.map = [ title, title ];
+    token.content = state.getLines(title, title+1, state.tShift[title], false).trim();
+    token.children = [];
+
+    token = state.push('spoiler_title_close', 'label', -1);
+
+    // Spoiler body - div
+    token = state.push('spoiler_body_open', 'div', 1);
+    token.attrs = [[ 'class', 'summary-content' ], [ 'id', 'spoiler-block-body' ]];
+
+    // Content starts
+    for (next = curLine; !found;) {
+        next++;
+        
+        if (next >= end) {
+            break;
+        }
+        
+        pos = state.bMarks[next] + state.tShift[next];
+        max = state.eMarks[next];
+        
+        if (pos < max && state.tShift[next] < state.blkIndent) {
+            break;
+        }
+
+        // Check if there's only ']:' on the line
+        if (state.src.slice(pos, max).length == 2 && state.src.slice(pos, max).trim().slice(-2) == ']:') {
+            found = true;
+        }
+    }
+
+    // We use to render markdown within
+    state.md.block.tokenize(state, curLine, next, false);
+    
+    state.line = next + 1;
+
+    // Finalize body
+    state.push('spoiler_body_close', 'div', -1);
+
+    // Finalize details    
+    state.push('spoiler_block_close', 'div', -1);
+
+    return true;
+}
+
+// Insert each marker as a separate text token, and add it to delimiter list
+function tokenize_spoiler(state, silent) {
+    var i, scanned, token, len, ch,
+        start = state.pos,
+        marker = state.src.charCodeAt(start);
+
+    if (silent) { return false; }
+
+    if (marker !== 0x25/* % */) { return false; }
+
+    scanned = state.scanDelims(state.pos, true);
+    len = scanned.length;
+    ch = String.fromCharCode(marker);
+
+    if (len < 2) { return false; }
+
+    if (len % 2) {
+        token         = state.push('text', '', 0);
+        token.content = ch;
+        len--;
+    }
+
+    for (i = 0; i < len; i += 2) {
+        token         = state.push('text', '', 0);
+        token.content = ch + ch;
+
+        if (!scanned.can_open && !scanned.can_close) { continue; }
+
+        state.delimiters.push({
+            marker: marker,
+            length: 0,     // disable "rule of 3" length checks meant for emphasis
+            jump:   i / 2, // 1 delimiter = 2 characters
+            token:  state.tokens.length - 1,
+            end:    -1,
+            open:   scanned.can_open,
+            close:  scanned.can_close
+        });
+    }
+
+    state.pos += scanned.length;
+
+    return true;
+}
+
+// Walk through delimiter list and replace text tokens with tags
+function postProcess(state, delimiters) {
+    var i, j,
+        startDelim,
+        endDelim,
+        token,
+        loneMarkers = [],
+        max = delimiters.length;
+
+    for (i = 0; i < max; i++) {
+        startDelim = delimiters[i];
+
+        if (startDelim.marker !== 0x25/* % */) {
+            continue;
+        }
+
+        if (startDelim.end === -1) {
+            continue;
+        }
+
+        endDelim = delimiters[startDelim.end];
+
+        token         = state.tokens[startDelim.token];
+        token.type    = 'spoiler_open';
+        token.tag     = 'spoiler';
+        token.nesting = 1;
+        token.markup  = '%%';
+        token.content = '';
+
+        token         = state.tokens[endDelim.token];
+        token.type    = 'spoiler_close';
+        token.tag     = 'spoiler';
+        token.nesting = -1;
+        token.markup  = '%';
+        token.content = '';
+
+        if (state.tokens[endDelim.token - 1].type === 'text' &&
+            state.tokens[endDelim.token - 1].content === '%') {
+
+            loneMarkers.push(endDelim.token - 1);
+        }
+    }
+
+    // If a marker sequence has an odd number of characters, it's splitted
+    // like this: `%%%%` -> `%` + `%%` + `%%`, leaving one marker at the
+    // start of the sequence.
+    //
+    // So, we have to move all those markers after subsequent s_close tags.
+    //
+    while (loneMarkers.length) {
+        i = loneMarkers.pop();
+        j = i + 1;
+
+        while (j < state.tokens.length && state.tokens[j].type === 'spoiler_close') {
+            j++;
+        }
+
+        j--;
+
+        if (i !== j) {
+            token = state.tokens[j];
+            state.tokens[j] = state.tokens[i];
+            state.tokens[i] = token;
+        }
+    }
+}
+
+const genRanHex = size => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 4474cab..85284e9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,4 +7,4 @@
 		"allowJs": true,
 		"baseUrl": "."
 	}
-}
+}
\ No newline at end of file