diff --git a/less/prose-editor.less b/less/prose-editor.less
index 6a43c29..fc8e8ba 100644
--- a/less/prose-editor.less
+++ b/less/prose-editor.less
@@ -1,451 +1,452 @@
 body#pad.classic {
 	header {
 		display: flex;
 		justify-content: space-between;
 		align-items: center;
 	}
 	#editor {
 		top: 4em;
 	}
 	#title {
 		top: 4.25rem;
 		bottom: unset;
 		height: auto;
 		font-weight: bold;
 		font-size: 2em;
 		padding-top: 0;
 		padding-bottom: 0;
 		border: 0;
 	}
 	#tools {
 		#belt {
 			float: none;
 		}
 	}
 	#target {
 		ul {
 			a {
 				padding: 0 0.5em !important;
 			}
 		}
 	}
 }
 
 .ProseMirror {
 	position: relative;
 	height: calc(~"100% - 1.6em");
 	overflow-y: auto;
 	box-sizing: border-box;
 	-moz-box-sizing: border-box;
 	font-size: 1.2em;
 	word-wrap: break-word;
 	white-space: pre-wrap;
 	-webkit-font-variant-ligatures: none;
 	font-variant-ligatures: none;
 	padding: 0.5em 0;
 	line-height: 1.5;
 	outline: none;
 }
 
 .ProseMirror pre {
 	white-space: pre-wrap;
 }
 
 .ProseMirror li {
 	position: relative;
 }
 
 .ProseMirror-hideselection *::selection {
 	background: transparent;
 }
 
 .ProseMirror-hideselection *::-moz-selection {
 	background: transparent;
 }
 
 .ProseMirror-hideselection {
 	caret-color: transparent;
 }
 
 .ProseMirror-selectednode {
 	outline: 2px solid #8cf;
 }
 
 /* Make sure li selections wrap around markers */
 
 li.ProseMirror-selectednode {
 	outline: none;
 }
 
 li.ProseMirror-selectednode:after {
 	content: "";
 	position: absolute;
 	left: -32px;
 	right: -2px;
 	top: -2px;
 	bottom: -2px;
 	border: 2px solid #8cf;
 	pointer-events: none;
 }
 
 .ProseMirror-textblock-dropdown {
 	min-width: 3em;
 }
 
 .ProseMirror-menu {
 	margin: 0 -4px;
 	line-height: 1;
 }
 
 .ProseMirror-tooltip .ProseMirror-menu {
 	width: -webkit-fit-content;
 	width: fit-content;
 	white-space: pre;
 }
 
 .ProseMirror-menuitem {
 	margin-right: 3px;
 	display: inline-block;
 	div {
 		cursor: pointer;
 	}
 }
 
 .ProseMirror-menuseparator {
 	border-right: 1px solid #ddd;
 	margin-right: 3px;
 }
 
 .ProseMirror-menu-dropdown, .ProseMirror-menu-dropdown-menu {
 	font-size: 90%;
 	white-space: nowrap;
 }
 
 .ProseMirror-menu-dropdown {
 	vertical-align: 1px;
 	cursor: pointer;
 	position: relative;
 	padding-right: 15px;
 }
 
 .ProseMirror-menu-dropdown-wrap {
 	padding: 1px 0 1px 4px;
 	display: inline-block;
 	position: relative;
 }
 
 .ProseMirror-menu-dropdown:after {
 	content: "";
 	border-left: 4px solid transparent;
 	border-right: 4px solid transparent;
 	border-top: 4px solid currentColor;
 	opacity: .6;
 	position: absolute;
 	right: 4px;
 	top: calc(50% - 2px);
 }
 
 .ProseMirror-menu-dropdown-menu, .ProseMirror-menu-submenu {
 	position: absolute;
 	background: white;
 	color: #666;
 	border: 1px solid #aaa;
 	padding: 2px;
 }
 
 .ProseMirror-menu-dropdown-menu {
 	z-index: 15;
 	min-width: 6em;
 }
 
 .ProseMirror-menu-dropdown-item {
 	cursor: pointer;
 	padding: 2px 8px 2px 4px;
 }
 
 .ProseMirror-menu-dropdown-item:hover {
 	background: #f2f2f2;
 }
 
 .ProseMirror-menu-submenu-wrap {
 	position: relative;
 	margin-right: -4px;
 }
 
 .ProseMirror-menu-submenu-label:after {
 	content: "";
 	border-top: 4px solid transparent;
 	border-bottom: 4px solid transparent;
 	border-left: 4px solid currentColor;
 	opacity: .6;
 	position: absolute;
 	right: 4px;
 	top: calc(50% - 4px);
 }
 
 .ProseMirror-menu-submenu {
 	display: none;
 	min-width: 4em;
 	left: 100%;
 	top: -3px;
 }
 
 .ProseMirror-menu-active {
 	background: #eee;
 	border-radius: 4px;
 }
 
 .ProseMirror-menu-active {
 	background: #eee;
 	border-radius: 4px;
 }
 
 .ProseMirror-menu-disabled {
 	opacity: .3;
 }
 
 .ProseMirror-menu-submenu-wrap:hover .ProseMirror-menu-submenu, .ProseMirror-menu-submenu-wrap-active .ProseMirror-menu-submenu {
 	display: block;
 }
 
 .ProseMirror-menubar {
 	position: relative;
 	min-height: 1em;
 	color: #666;
 	padding: 0.5em;
 	top: 0;
 	left: 0;
 	right: 0;
 	background: rgba(255, 255, 255, 0.8);
 	z-index: 10;
 	-moz-box-sizing: border-box;
 	box-sizing: border-box;
 	overflow: visible;
 }
 
 .ProseMirror-icon {
 	display: inline-block;
 	line-height: .8;
 	vertical-align: -2px; /* Compensate for padding */
 	padding: 2px 8px;
 	cursor: pointer;
 }
 
 .ProseMirror-menu-disabled.ProseMirror-icon {
 	cursor: default;
 }
 
 .ProseMirror-icon svg {
 	fill: currentColor;
 	height: 1em;
 }
 
 .ProseMirror-icon span {
 	vertical-align: text-top;
 }
 
 .ProseMirror-gapcursor {
 	display: none;
 	pointer-events: none;
 	position: absolute;
 }
 
 .ProseMirror-gapcursor:after {
 	content: "";
 	display: block;
 	position: absolute;
 	top: -2px;
 	width: 20px;
 	border-top: 1px solid black;
 	animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
 }
 
 @keyframes ProseMirror-cursor-blink {
 	to {
 		visibility: hidden;
 	}
 }
 
 .ProseMirror-focused .ProseMirror-gapcursor {
 	display: block;
 }
 
 /* Add space around the hr to make clicking it easier */
 
 .ProseMirror-example-setup-style hr {
-	padding: 2px 10px;
+	padding: 4px 10px;
 	border: none;
 	margin: 1em 0;
+	background: initial;
 }
 
 .ProseMirror-example-setup-style hr:after {
 	content: "";
 	display: block;
 	height: 1px;
-	background-color: silver;
+	background-color: #ccc;
 	line-height: 2px;
 }
 
 .ProseMirror ul, .ProseMirror ol {
 	padding-left: 30px;
 }
 
 .ProseMirror blockquote {
 	padding-left: 1em;
 	border-left: 3px solid #eee;
 	margin-left: 0;
 	margin-right: 0;
 }
 
 .ProseMirror-example-setup-style img {
 	cursor: default;
 	max-width: 100%;
 }
 
 .ProseMirror-prompt {
 	background: white;
 	padding: 1em;
 	border: 1px solid silver;
 	position: fixed;
 	border-radius: 0.25em;
 	z-index: 11;
 	box-shadow: -.5px 2px 5px rgba(0, 0, 0, .2);
 }
 
 .ProseMirror-prompt h5 {
 	margin: 0 0 0.75em;
 	font-family: @sansFont;
 	font-size: 100%;
 	color: #444;
 }
 
 .ProseMirror-prompt input[type="text"],
 .ProseMirror-prompt textarea {
 	background: #eee;
 	border: none;
 	outline: none;
 }
 
 .ProseMirror-prompt input[type="text"] {
 	margin: 0.25em 0;
 }
 
 .ProseMirror-prompt-close {
 	position: absolute;
 	left: 2px;
 	top: 1px;
 	color: #666;
 	border: none;
 	background: transparent;
 	padding: 0;
 }
 
 .ProseMirror-prompt-close:after {
 	content: "✕";
 	font-size: 12px;
 }
 
 .ProseMirror-invalid {
 	background: #ffc;
 	border: 1px solid #cc7;
 	border-radius: 4px;
 	padding: 5px 10px;
 	position: absolute;
 	min-width: 10em;
 }
 
 .ProseMirror-prompt-buttons {
 	margin-top: 5px;
 	display: none;
 }
 
 #editor, .editor {
 	position: fixed;
 	top: 0;
 	right: 0;
 	bottom: 0;
 	left: 0;
 	color: black;
 	background-clip: padding-box;
 	padding: 5px 0;
 	margin: 4em auto 23px auto;
 }
 
 .ProseMirror p:first-child,
 .ProseMirror h1:first-child,
 .ProseMirror h2:first-child,
 .ProseMirror h3:first-child,
 .ProseMirror h4:first-child,
 .ProseMirror h5:first-child,
 .ProseMirror h6:first-child {
 	margin-top: 10px;
 }
 
 .ProseMirror p {
 	margin-bottom: 1em;
 }
 
 textarea {
 	width: 100%;
 	height: 123px;
 	border: 1px solid silver;
 	box-sizing: border-box;
 	-moz-box-sizing: border-box;
 	padding: 3px 10px;
 	border: none;
 	outline: none;
 	font-family: inherit;
 	font-size: inherit;
 }
 
 .ProseMirror-menubar-wrapper {
 	height: 100%;
 	box-sizing: border-box;
 }
 
 .ProseMirror-menubar-wrapper, #markdown textarea {
 	display: block;
 	margin-bottom: 4px;
 }
 
 .editorreadmore {
 	color: @textLinkColor;
 	text-decoration: underline;
 	text-align: center;
 	width: 100%;
 }
 
 @media all and (min-width: 50em) {
 	#editor {
 		margin-left: 10%;
 		margin-right: 10%;
 	}
 }
 
 @media all and (min-width: 60em) {
 	#editor {
 		margin-left: 15%;
 		margin-right: 15%;
 	}
 }
 
 @media all and (min-width: 70em) {
 	#editor {
 		margin-left: 20%;
 		margin-right: 20%;
 	}
 }
 
 @media all and (min-width: 85em) {
 	#editor {
 		margin-left: 25%;
 		margin-right: 25%;
 	}
 }
 
 @media all and (min-width: 105em) {
 	#editor {
 		margin-left: 30%;
 		margin-right: 30%;
 	}
 }
diff --git a/prose/markdownParser.js b/prose/markdownParser.js
index bd81590..1ee5a07 100644
--- a/prose/markdownParser.js
+++ b/prose/markdownParser.js
@@ -1,57 +1,57 @@
 import { MarkdownParser } from "prosemirror-markdown";
 import markdownit from "markdown-it";
 
 import { writeFreelySchema } from "./schema";
 
 export const writeFreelyMarkdownParser = new MarkdownParser(
   writeFreelySchema,
   markdownit("commonmark", { html: true }),
   {
     // blockquote: { block: "blockquote" },
     paragraph: { block: "paragraph" },
     list_item: { block: "list_item" },
     bullet_list: { block: "bullet_list" },
     ordered_list: {
       block: "ordered_list",
       getAttrs: (tok) => ({ order: +tok.attrGet("start") || 1 }),
     },
     heading: {
       block: "heading",
       getAttrs: (tok) => ({ level: +tok.tag.slice(1) }),
     },
     code_block: { block: "code_block", noCloseToken: true },
     fence: {
       block: "code_block",
       getAttrs: (tok) => ({ params: tok.info || "" }),
       noCloseToken: true,
     },
-    // hr: { node: "horizontal_rule" },
+    hr: { node: "horizontal_rule" },
     image: {
       node: "image",
       getAttrs: (tok) => ({
         src: tok.attrGet("src"),
         title: tok.attrGet("title") || null,
         alt: (tok.children !== null && typeof tok.children[0] !== 'undefined' ? tok.children[0].content : null),
       }),
     },
     hardbreak: { node: "hard_break" },
 
     em: { mark: "em" },
     strong: { mark: "strong" },
     link: {
       mark: "link",
       getAttrs: (tok) => ({
         href: tok.attrGet("href"),
         title: tok.attrGet("title") || null,
       }),
     },
     code_inline: { mark: "code", noCloseToken: true },
     html_block: {
       node: "readmore",
       getAttrs(token) {
         // TODO: Give different attributes depending on the token content
         return {};
       },
     },
   }
 );
diff --git a/prose/markdownSerializer.js b/prose/markdownSerializer.js
index d14deab..9615633 100644
--- a/prose/markdownSerializer.js
+++ b/prose/markdownSerializer.js
@@ -1,124 +1,128 @@
 import { MarkdownSerializer } from "prosemirror-markdown";
 
 function backticksFor(node, side) {
   const ticks = /`+/g;
   let m;
   let len = 0;
   if (node.isText)
     while ((m = ticks.exec(node.text))) len = Math.max(len, m[0].length);
   let result = len > 0 && side > 0 ? " `" : "`";
   for (let i = 0; i < len; i++) result += "`";
   if (len > 0 && side < 0) result += " ";
   return result;
 }
 
 function isPlainURL(link, parent, index, side) {
   if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) return false;
   const content = parent.child(index + (side < 0 ? -1 : 0));
   if (
     !content.isText ||
     content.text != link.attrs.href ||
     content.marks[content.marks.length - 1] != link
   )
     return false;
   if (index == (side < 0 ? 1 : parent.childCount - 1)) return true;
   const next = parent.child(index + (side < 0 ? -2 : 1));
   return !link.isInSet(next.marks);
 }
 
 export const writeFreelyMarkdownSerializer = new MarkdownSerializer(
   {
     readmore(state, node) {
       state.write("<!--more-->\n");
       state.closeBlock(node);
     },
     // blockquote(state, node) {
     //   state.wrapBlock("> ", undefined, node, () => state.renderContent(node));
     // },
     code_block(state, node) {
       state.write(`\`\`\`${node.attrs.params || ""}\n`);
       state.text(node.textContent, false);
       state.ensureNewLine();
       state.write("```");
       state.closeBlock(node);
     },
     heading(state, node) {
       state.write(`${state.repeat("#", node.attrs.level)} `);
       state.renderInline(node);
       state.closeBlock(node);
     },
+    horizontal_rule: function horizontal_rule(state, node) {
+      state.write(node.attrs.markup || "---");
+      state.closeBlock(node);
+    },
     bullet_list(state, node) {
       node.attrs.tight = true;
       state.renderList(node, "  ", () => `${node.attrs.bullet || "*"} `);
     },
     ordered_list(state, node) {
       const start = node.attrs.order || 1;
       const maxW = String(start + node.childCount - 1).length;
       const space = state.repeat(" ", maxW + 2);
       state.renderList(node, space, (i) => {
         const nStr = String(start + i);
         return `${state.repeat(" ", maxW - nStr.length) + nStr}. `;
       });
     },
     list_item(state, node) {
       state.renderContent(node);
     },
     paragraph(state, node) {
       state.renderInline(node);
       state.closeBlock(node);
     },
 
     image(state, node) {
       state.write(
         `![${state.esc(node.attrs.alt || "")}](${state.esc(node.attrs.src)}${
           node.attrs.title ? ` ${state.quote(node.attrs.title)}` : ""
         })`
       );
     },
     hard_break(state, node, parent, index) {
       for (let i = index + 1; i < parent.childCount; i += 1)
         if (parent.child(i).type !== node.type) {
           state.write("\\\n");
           return;
         }
     },
     text(state, node) {
       state.text(node.text || "");
     },
   },
   {
     em: {
       open: "*",
       close: "*",
       mixable: true,
       expelEnclosingWhitespace: true,
     },
     strong: {
       open: "**",
       close: "**",
       mixable: true,
       expelEnclosingWhitespace: true,
     },
     link: {
       open(_state, mark, parent, index) {
         return isPlainURL(mark, parent, index, 1) ? "<" : "[";
       },
       close(state, mark, parent, index) {
         return isPlainURL(mark, parent, index, -1)
           ? ">"
           : `](${state.esc(mark.attrs.href)}${
               mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ""
             })`;
       },
     },
     code: {
       open(_state, _mark, parent, index) {
         return backticksFor(parent.child(index), -1);
       },
       close(_state, _mark, parent, index) {
         return backticksFor(parent.child(index - 1), 1);
       },
       escape: false,
     },
   }
 );
diff --git a/prose/prose.js b/prose/prose.js
index 7c361a0..3096c9e 100644
--- a/prose/prose.js
+++ b/prose/prose.js
@@ -1,118 +1,118 @@
 // class MarkdownView {
 //   constructor(target, content) {
 //     this.textarea = target.appendChild(document.createElement("textarea"))
 //     this.textarea.value = content
 //   }
 
 //   get content() { return this.textarea.value }
 //   focus() { this.textarea.focus() }
 //   destroy() { this.textarea.remove() }
 // }
 
 import { EditorView } from "prosemirror-view";
 import { EditorState, TextSelection } from "prosemirror-state";
 import { exampleSetup } from "prosemirror-example-setup";
 import { keymap } from "prosemirror-keymap";
 
 import { writeFreelyMarkdownParser } from "./markdownParser";
 import { writeFreelyMarkdownSerializer } from "./markdownSerializer";
 import { writeFreelySchema } from "./schema";
 import { getMenu } from "./menu";
 
 let $title = document.querySelector("#title");
 let $content = document.querySelector("#content");
 
 // Bugs:
 // 1. When there's just an empty line and a hard break is inserted with shift-enter then two enters are inserted
 // which do not show up in the markdown ( maybe bc. they are training enters )
 
 class ProseMirrorView {
   constructor(target, content) {
     let typingTimer;
     let localDraft = localStorage.getItem(window.draftKey);
     if (localDraft != null) {
       content = localDraft;
     }
     if (content.indexOf("# ") === 0) {
       let eol = content.indexOf("\n");
       let title = content.substring("# ".length, eol);
       content = content.substring(eol + "\n\n".length);
       $title.value = title;
     }
 
     const doc = writeFreelyMarkdownParser.parse(
       // Replace all "solo" \n's with \\\n for correct markdown parsing
       // Can't use lookahead or lookbehind because it's not supported on Safari
       content.replace(/([^]{0,1})(\n)([^]{0,1})/g, (match, p1, p2, p3) => {
         return p1 !== "\n" && p3 !== "\n" ? p1 + "\\\n" + p3 : match;
       })
     );
 
     this.view = new EditorView(target, {
       state: EditorState.create({
         doc,
         plugins: [
           keymap({
             "Mod-Enter": () => {
               document.getElementById("publish").click();
               return true;
             },
             "Mod-k": () => {
               const linkButton = document.querySelector(
                 ".ProseMirror-icon[title='Add or remove link']"
               );
               linkButton.dispatchEvent(new Event("mousedown"));
               return true;
             },
           }),
           ...exampleSetup({
             schema: writeFreelySchema,
             menuContent: getMenu(),
           }),
         ],
       }),
       dispatchTransaction(transaction) {
         let newState = this.state.apply(transaction);
         const newContent = writeFreelyMarkdownSerializer
           .serialize(newState.doc)
           // Replace all \\\ns ( not followed by a \n ) with \n
           .replace(/(\\\n)(\n{0,1})/g, (match, p1, p2) =>
             p2 !== "\n" ? "\n" + p2 : match
           );
         $content.value = newContent;
         let draft = "";
         if ($title.value != null && $title.value !== "") {
           draft = "# " + $title.value + "\n\n";
         }
         draft += newContent;
         clearTimeout(typingTimer);
         typingTimer = setTimeout(doneTyping, doneTypingInterval);
         this.updateState(newState);
       },
     });
     // Editor is focused to the last position. This is a workaround for a bug:
     // 1. 1 type something in an existing entry
     // 2. reload - works fine, the draft is reloaded
     // 3. reload again - the draft is somehow removed from localStorage and the original content is loaded
     // When the editor is focused the content is re-saved to localStorage
 
     // This is also useful for editing, so it's not a bad thing even
     const lastPosition = this.view.state.doc.content.size;
     const selection = TextSelection.create(this.view.state.doc, lastPosition);
     this.view.dispatch(this.view.state.tr.setSelection(selection));
     this.view.focus();
   }
 
   get content() {
-    return defaultMarkdownSerializer.serialize(this.view.state.doc);
+    return writeFreelyMarkdownSerializer.serialize(this.view.state.doc);
   }
   focus() {
     this.view.focus();
   }
   destroy() {
     this.view.destroy();
   }
 }
 
 let place = document.querySelector("#editor");
 let view = new ProseMirrorView(place, $content.value);
diff --git a/prose/schema.js b/prose/schema.js
index 67302df..0a87662 100644
--- a/prose/schema.js
+++ b/prose/schema.js
@@ -1,21 +1,20 @@
 import { schema } from "prosemirror-markdown";
 import { Schema } from "prosemirror-model";
 
 export const writeFreelySchema = new Schema({
   nodes: schema.spec.nodes
     .remove("blockquote")
-    .remove("horizontal_rule")
     .addToEnd("readmore", {
       inline: false,
       content: "",
       group: "block",
       draggable: true,
       toDOM: (node) => [
         "div",
         { class: "editorreadmore" },
         "Read more...",
       ],
       parseDOM: [{ tag: "div.editorreadmore" }],
     }),
   marks: schema.spec.marks,
 });