This bookmark adds support to Overleaf for real-time compilation of Markdown and LaTeX (via KaTeX). To use, open or create a project with Markdown files (make sure to use .md
as a file extension) then click on this bookmark.
LaTeX expressions like $x=3$
are compiled via KaTeX. For inline math, use one dollar sign $x=3$
. For display mode, use two dollar signs $$x=3$$
.
On a desktop computer, drag this bookmarklet link to your bookmarks toolbar. To use it, visit your Overleaf project with markdown files and click on the bookmark.
On iOS,
javascript:(function(){function%20isValidDelim%28state%2C%20pos%29%20%7Bvar%20prevChar%2C%20nextChar%2Cmax%20%3D%20state.posMax%2Ccan_open%20%3D%20true%2Ccan_close%20%3D%20true%3BprevChar%20%3D%20pos%20%3E%200%20%3F%20state.src.charCodeAt%28pos%20-%201%29%20%3A%20-1%3BnextChar%20%3D%20pos%20%2B%201%20%3C%3D%20max%20%3F%20state.src.charCodeAt%28pos%20%2B%201%29%20%3A%20-1%3Bif%20%28prevChar%20%3D%3D%3D%200x20/%2A%20%22%20%22%20%2A/%20%7C%7C%20prevChar%20%3D%3D%3D%200x09/%2A%20%5Ct%20%2A/%20%7C%7C%28nextChar%20%3E%3D%200x30/%2A%20%220%22%20%2A/%20%26%26%20nextChar%20%3C%3D%200x39/%2A%20%229%22%20%2A/%29%29%20%7Bcan_close%20%3D%20false%3B%7Dif%20%28nextChar%20%3D%3D%3D%200x20/%2A%20%22%20%22%20%2A/%20%7C%7C%20nextChar%20%3D%3D%3D%200x09/%2A%20%5Ct%20%2A/%29%20%7Bcan_open%20%3D%20false%3B%7Dreturn%20%7Bcan_open%3A%20can_open%2Ccan_close%3A%20can_close%2C%7D%3B%7Dfunction%20math_inline%28state%2C%20silent%29%20%7Bvar%20start%2C%20match%2C%20token%2C%20res%2C%20pos%2C%20esc_count%3Bif%20%28state.src%5Bstate.pos%5D%20%21%3D%3D%20%22%24%22%29%20%7B%20return%20false%3B%20%7Dres%20%3D%20isValidDelim%28state%2C%20state.pos%29%3Bif%20%28%21res.can_open%29%20%7Bif%20%28%21silent%29%20%7B%20state.pending%20%2B%3D%20%22%24%22%3B%20%7Dstate.pos%20%2B%3D%201%3Breturn%20true%3B%7Dstart%20%3D%20state.pos%20%2B%201%3Bmatch%20%3D%20start%3Bwhile%20%28%20%28match%20%3D%20state.src.indexOf%28%22%24%22%2C%20match%29%29%20%21%3D%3D%20-1%29%20%7Bpos%20%3D%20match%20-%201%3Bwhile%20%28state.src%5Bpos%5D%20%3D%3D%3D%20%22%5C%5C%22%29%20%7B%20pos%20-%3D%201%3B%20%7Dif%20%28%20%28%28match%20-%20pos%29%20%25%202%29%20%3D%3D%201%20%29%20%7B%20break%3B%20%7Dmatch%20%2B%3D%201%3B%7Dif%20%28match%20%3D%3D%3D%20-1%29%20%7Bif%20%28%21silent%29%20%7B%20state.pending%20%2B%3D%20%22%24%22%3B%20%7Dstate.pos%20%3D%20start%3Breturn%20true%3B%7Dif%20%28match%20-%20start%20%3D%3D%3D%200%29%20%7Bif%20%28%21silent%29%20%7B%20state.pending%20%2B%3D%20%22%24%24%22%3B%20%7Dstate.pos%20%3D%20start%20%2B%201%3Breturn%20true%3B%7Dres%20%3D%20isValidDelim%28state%2C%20match%29%3Bif%20%28%21res.can_close%29%20%7Bif%20%28%21silent%29%20%7B%20state.pending%20%2B%3D%20%22%24%22%3B%20%7Dstate.pos%20%3D%20start%3Breturn%20true%3B%7Dif%20%28%21silent%29%20%7Btoken%20%20%20%20%20%20%20%20%20%3D%20state.push%28%27math_inline%27%2C%20%27math%27%2C%200%29%3Btoken.markup%20%20%3D%20%22%24%22%3Btoken.content%20%3D%20state.src.slice%28start%2C%20match%29%3B%7Dstate.pos%20%3D%20match%20%2B%201%3Breturn%20true%3B%7Dfunction%20math_block%28state%2C%20start%2C%20end%2C%20silent%29%7Bvar%20firstLine%2C%20lastLine%2C%20next%2C%20lastPos%2C%20found%20%3D%20false%2C%20token%2Cpos%20%3D%20state.bMarks%5Bstart%5D%20%2B%20state.tShift%5Bstart%5D%2Cmax%20%3D%20state.eMarks%5Bstart%5D%3Bif%28pos%20%2B%202%20%3E%20max%29%7B%20return%20false%3B%20%7Dif%28state.src.slice%28pos%2Cpos%2B2%29%21%3D%3D%27%24%24%27%29%7B%20return%20false%3B%20%7Dpos%20%2B%3D%202%3BfirstLine%20%3D%20state.src.slice%28pos%2Cmax%29%3Bif%28silent%29%7B%20return%20true%3B%20%7Dif%28firstLine.trim%28%29.slice%28-2%29%3D%3D%3D%27%24%24%27%29%7BfirstLine%20%3D%20firstLine.trim%28%29.slice%280%2C%20-2%29%3Bfound%20%3D%20true%3B%7Dfor%28next%20%3D%20start%3B%20%21found%3B%20%29%7Bnext%2B%2B%3Bif%28next%20%3E%3D%20end%29%7B%20break%3B%20%7Dpos%20%3D%20state.bMarks%5Bnext%5D%2Bstate.tShift%5Bnext%5D%3Bmax%20%3D%20state.eMarks%5Bnext%5D%3Bif%28pos%20%3C%20max%20%26%26%20state.tShift%5Bnext%5D%20%3C%20state.blkIndent%29%7Bbreak%3B%7Dif%28state.src.slice%28pos%2Cmax%29.trim%28%29.slice%28-2%29%3D%3D%3D%27%24%24%27%29%7BlastPos%20%3D%20state.src.slice%280%2Cmax%29.lastIndexOf%28%27%24%24%27%29%3BlastLine%20%3D%20state.src.slice%28pos%2ClastPos%29%3Bfound%20%3D%20true%3B%7D%7Dstate.line%20%3D%20next%20%2B%201%3Btoken%20%3D%20state.push%28%27math_block%27%2C%20%27math%27%2C%200%29%3Btoken.block%20%3D%20true%3Btoken.content%20%3D%20%28firstLine%20%26%26%20firstLine.trim%28%29%20%3F%20firstLine%20%2B%20%27%5Cn%27%20%3A%20%27%27%29%2B%20state.getLines%28start%20%2B%201%2C%20next%2C%20state.tShift%5Bstart%5D%2C%20true%29%2B%20%28lastLine%20%26%26%20lastLine.trim%28%29%20%3F%20lastLine%20%3A%20%27%27%29%3Btoken.map%20%3D%20%5B%20start%2C%20state.line%20%5D%3Btoken.markup%20%3D%20%27%24%24%27%3Breturn%20true%3B%7Dfunction%20math_plugin%28md%2C%20options%29%20%7Boptions%20%3D%20options%20%7C%7C%20%7B%7D%3Bvar%20katexInline%20%3D%20function%28latex%29%7Boptions.displayMode%20%3D%20false%3Btry%7Breturn%20katex.renderToString%28latex%2C%20options%29%3B%7Dcatch%28error%29%7Bif%28options.throwOnError%29%7B%20console.log%28error%29%3B%20%7Dreturn%20latex%3B%7D%7D%3Bvar%20inlineRenderer%20%3D%20function%28tokens%2C%20idx%29%7Breturn%20katexInline%28tokens%5Bidx%5D.content%29%3B%7D%3Bvar%20katexBlock%20%3D%20function%28latex%29%7Boptions.displayMode%20%3D%20true%3Btry%7Breturn%20%22%3Cp%3E%22%20%2B%20katex.renderToString%28latex%2C%20options%29%20%2B%20%22%3C/p%3E%22%3B%7Dcatch%28error%29%7Bif%28options.throwOnError%29%7B%20console.log%28error%29%3B%20%7Dreturn%20latex%3B%7D%7D%3Bvar%20blockRenderer%20%3D%20function%28tokens%2C%20idx%29%7Breturn%20%20katexBlock%28tokens%5Bidx%5D.content%29%20%2B%20%27%5Cn%27%3B%7D%3Bmd.inline.ruler.after%28%27escape%27%2C%20%27math_inline%27%2C%20math_inline%29%3Bmd.block.ruler.after%28%27blockquote%27%2C%20%27math_block%27%2C%20math_block%2C%20%7Balt%3A%20%5B%20%27paragraph%27%2C%20%27reference%27%2C%20%27blockquote%27%2C%20%27list%27%20%5D%2C%7D%29%3Bmd.renderer.rules.math_inline%20%3D%20inlineRenderer%3Bmd.renderer.rules.math_block%20%3D%20blockRenderer%3B%7D%3Bfunction%20addCSS%28href%29%20%7B%20ss%3Ddocument.createElement%28%27link%27%29%3Bss.rel%3D%27stylesheet%27%3Bss.href%3Dhref%3Bdocument.body.appendChild%28ss%29%3B%20%7Dfunction%20addJS%28src%29%20%7Breturn%20new%20Promise%28%28resolve%2C%20reject%29%20%3D%3E%20%7Bconst%20ss%3Ddocument.createElement%28%27script%27%29%3Bss.src%3Dsrc%3Bss.async%3Dfalse%3Bdocument.body.appendChild%28ss%29%3Bss.addEventListener%28%27load%27%2C%20%28%29%20%3D%3E%20resolve%28%29%29%3Bss.addEventListener%28%27error%27%2C%20%28%29%20%3D%3E%20reject%28new%20Error%28%60%24%7Bthis.src%7D%20failed%20to%20load.%60%29%29%29%3B%7D%29%3B%7DaddCSS%28%27https%3A//cdnjs.cloudflare.com/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css%27%29%3BaddCSS%28%27https%3A//cdn.jsdelivr.net/npm/katex%400.11.1/dist/katex.min.css%27%29%3Bconst%20sourceLoading%20%3D%20%5BaddJS%28%27https%3A//cdnjs.cloudflare.com/ajax/libs/markdown-it/11.0.0/markdown-it.min.js%27%29%2CaddJS%28%27https%3A//cdn.jsdelivr.net/npm/katex%400.11.1/dist/katex.min.js%27%29%2C%5D%3Bfunction%20divided%28items%2C%20divider%29%20%7Blet%20idx%20%3D%200%3Bconst%20result%20%3D%20%5B%5D%3Bwhile%20%28idx%20%3C%20items.length%29%20%7Blet%20next%20%3D%20items.indexOf%28divider%2C%20idx%29%3Bif%20%28next%20%3D%3D%20-1%29%20%7Bnext%20%3D%20items.length%3B%7Dconst%20section%20%3D%20items.slice%28idx%2C%20next%29%3Bif%20%28section.length%29%20%7Bresult.push%28section%29%3B%7Didx%20%3D%20next%20%2B%201%3B%7Dreturn%20result%3B%7D/%2Aconsole.log%28divided%28%5B%27%27%2C%20%27f%27%2C%20%27g%27%2C%20%27%27%2C%20%27j%27%5D%2C%20%27%27%29%29console.log%28divided%28%5B%27f%27%2C%20%27g%27%2C%20%27%27%2C%20%27%27%2C%20%27j%27%2C%20%27k%27%2C%20%27%27%5D%2C%20%27%27%29%29%2A/function%20edits%28prev%2C%20value%29%20%7Bfunction%20remove%28end%29%20%7Bfor%20%28let%20remove%20%3D%20previdx%3B%20remove%20%3C%20end%3B%20remove%2B%2B%29%20%7Bedits.push%28%7Bop%3A%20%27remove%27%2C%20previdx%3A%20remove%7D%29%3B%7D%7Dlet%20previdx%20%3D%200%3Bconst%20edits%20%3D%20%5B%5D%3Bvalue.forEach%28%28item%2C%20idx%29%20%3D%3E%20%7Bconst%20found%20%3D%20prev.indexOf%28item%2C%20previdx%29%3Bif%20%28found%20%3D%3D%20-1%29%20%7Bedits.push%28%7Bop%3A%20%27insertBefore%27%2C%20previdx%2C%20idx%7D%29%3Breturn%3B%7Dremove%28found%29%3Bprevidx%20%3D%20found%20%2B%201%3B%7D%29%3Bremove%28prev.length%29%3Bedits.reverse%28%29%3Breturn%20edits%3B%7Dfunction%20applyEditsString%28prev%2C%20value%2C%20edits%29%20%7Bprev%20%3D%20prev.slice%28%29%3Bfor%20%28const%20edit%20of%20edits%29%20%7Bif%20%28edit.op%20%3D%3D%20%27insertBefore%27%29%20%7Bprev.splice%28edit.previdx%2C%200%2C%20value%5Bedit.idx%5D%29%3B%7D%20else%20%7Bprev.splice%28edit.previdx%2C%201%29%3B%7D%7Dreturn%20prev%3B%7D/%2Aconst%20prev%20%3D%20%5B%27f%27%2C%20%27g%27%2C%20%27a%27%2C%20%27b%27%2C%20%27j%27%2C%20%27k%27%5D%3Blet%20value%20%3D%20%5B%27x%27%2C%20%27g%27%2C%20%27c%27%2C%20%27b%27%2C%20%27j%27%5D%3Bconsole.log%28edits%28prev%2C%20value%29%29%3Bconsole.log%28%27matches%20expected%3A%27%2C%20JSON.stringify%28applyEditsString%28prev%2C%20value%2C%20edits%28prev%2C%20value%29%29%29%3D%3DJSON.stringify%28value%29%29%3Bvalue%20%3D%20%5B%27f%27%2C%20%27g%27%2C%20%27a%27%2C%20%27b%27%2C%20%27j%27%2C%20%27k%27%2C%20%27h%27%5D%3Bconsole.log%28%27matches%20expected%3A%27%2C%20JSON.stringify%28applyEditsString%28prev%2C%20value%2C%20edits%28prev%2C%20value%29%29%29%3D%3DJSON.stringify%28value%29%29%3B%2A/function%20applyEditsDOM%28parent%2C%20prev%2C%20value%2C%20edits%2C%20render%29%20%7Bconst%20nodes%20%3D%20parent.children%3Bif%20%28nodes.length%20%21%3D%20prev.length%29%20%7Bconsole.log%28nodes.length%2C%20prev%29%3Balert%28%27Nodes%20mismatch%21%27%20%2B%20navigator.userAgent%29%3B%7Dfor%20%28const%20edit%20of%20edits%29%20%7Bif%20%28edit.op%20%3D%3D%20%27insertBefore%27%29%20%7Bconst%20n%20%3D%20nodes%5Bedit.previdx%5D%3Bif%20%28n%29%20%7Bn.insertAdjacentHTML%28%27beforebegin%27%2C%20render%28value%5Bedit.idx%5D%29%29%3B%7D%20else%20%7Bparent.insertAdjacentHTML%28%27beforeend%27%2C%20render%28value%5Bedit.idx%5D%29%29%3B%7D%7D%20else%20%7Bnodes%5Bedit.previdx%5D.remove%28%29%3B%7D%7D%7Dconst%20content%20%3D%20document.createElement%28%27div%27%29%3Bdocument.querySelector%28%27.pdf%27%29.appendChild%28content%29%3Bcontent.classList.add%28%27markdown-body%27%29%3BObject.assign%28content.style%2C%20%7Bposition%3A%20%27absolute%27%2Cwidth%3A%20%27100%25%27%2Cheight%3A%20%27100%25%27%2Cbackground%3A%20%27white%27%2Cpadding%3A%20%271rem%201rem%203rem%201rem%27%2Coverflow%3A%20%27scroll%27%2CboxSizing%3A%20%27border-box%27%2C%7D%29%3Bfunction%20getAceEditor%28%29%20%7Breturn%20ace.edit%28%24%28%27.ace-editor-body%27%29%5B0%5D%29%3B%7Dlet%20prevInputs%20%3D%20%5B%5D%3Bfunction%20update%28e%29%20%7Bconst%20md%20%3D%20markdownit%28%7Bhtml%3A%20true%2C%7D%29%3Bmath_plugin%28md%29%3Bconst%20editor%20%3D%20getAceEditor%28%29%3Bconst%20lines%20%3D%20editor.getSession%28%29.getDocument%28%29.getAllLines%28%29%3Bconst%20inputs%20%3D%20divided%28lines%2C%20%27%27%29.map%28block%20%3D%3E%20block.join%28%27%5Cn%27%29%29%3Bfunction%20render%28text%29%20%7Breturn%20%27%3Cdiv%3E%27%2Bmd.render%28text%29%2B%27%3C/div%3E%27%3B%7Dconst%20ed%20%3D%20edits%28prevInputs%2C%20inputs%29%3Bconsole.log%28%60Applying%20%24%7Bed.length%7D%20edits%60%29%3BapplyEditsDOM%28content%2C%20prevInputs%2C%20inputs%2C%20ed%2C%20render%29%3Bfor%20%28const%20img%20of%20content.querySelectorAll%28%27img%27%29%29%20%7Bconst%20newSrc%20%3D%20getImage%28img.getAttribute%28%27src%27%29%29%3Bif%20%28newSrc%29%20%7Bimg.src%20%3D%20newSrc%3B%7D%7DprevInputs%20%3D%20inputs%3B%7Dfunction%20init%28%29%20%7Bconst%20appState%20%3D%20angular.element%28document.querySelector%28%27%23ide-body%27%29%29.scope%28%29%3Bconst%20isMD%20%3D%20appState.docs.find%28d%20%3D%3E%20d.doc.id%20%3D%3D%20appState.editor.open_doc_id%29.path.endsWith%28%27.md%27%29%3Bconst%20validationProblems%20%3D%20document.querySelector%28%27.pdf-validation-problems%27%29%3Bif%20%28isMD%29%20%7Bcontent.style.display%20%3D%20%27block%27%3Bif%28validationProblems%29%20validationProblems.style.display%20%3D%20%27none%27%3Bupdate%28%29%3BgetAceEditor%28%29.getSession%28%29.getDocument%28%29.on%28%27change%27%2C%20update%29%3B%7D%20else%20%7Bcontent.style.display%20%3D%20%27none%27%3Bif%28validationProblems%29%20validationProblems.style.display%20%3D%20%27block%27%3B%7D%7DPromise.all%28sourceLoading%29.then%28%28%29%20%3D%3E%20init%28%29%29%3Bangular.element%28document.querySelector%28%27%23editor%27%29%29.scope%28%29.%24on%28%27doc%3Aopened%27%2C%20function%28e%29%20%7BsetTimeout%28%28%29%20%3D%3E%20%7Bconsole.log%28e%29%3Binit%28%29%3B%7D%2C%200%29%3B%7D%29%3Bfunction%20get%24scope%28%29%20%7Breturn%20angular.element%28document.querySelector%28%27%23ide-body%27%29%29.scope%28%29%3B%7Dfunction%20getImage%28src%29%20%7Bif%20%28src.startsWith%28%27http%27%29%29%20%7Breturn%3B%7Dconst%20%24scope%20%3D%20angular.element%28document.querySelector%28%27.ui-layout-pane-west%27%29%29.scope%28%29%3Bconst%20root%20%3D%20%24scope.rootFolder%3Bconst%20fileToEntity%20%3D%20flattenFolderTree%28root%29%3Bconst%20entity%20%3D%20fileToEntity%5Bsrc%5D%3Bif%20%28%21entity%29%20%7Breturn%3B%7Dconst%20base%20%3D%20%5Blocation.protocol%2C%20%27/%27%2C%20%27/%27%2C%20location.host%2C%20location.pathname%5D.join%28%27%27%29%3Breturn%20%60%24%7Bbase%7D/file/%24%7Bentity.id%7D%60%3B%7Dfunction%20getEntityForHref%28href%29%20%7Bconst%20docs%20%3D%20angular.element%28document.querySelector%28%27%23ide-body%27%29%29.scope%28%29.docs%3Bconst%20doc%20%3D%20docs.find%28d%20%3D%3E%20d.path%20%3D%3D%20href%29%3Breturn%20doc%20%26%26%20doc.doc%3Bconst%20%24scope%20%3D%20angular.element%28document.querySelector%28%27.ui-layout-pane-west%27%29%29.scope%28%29%3Bconst%20fileToEntity%20%3D%20flattenFolderTree%28%24scope.rootFolder%29%3Breturn%20fileToEntity%5Bhref%5D%3B%7Dcontent.addEventListener%28%27click%27%2C%20function%28e%29%20%7Bconst%20target%20%3D%20e.target%3Bif%20%28target.tagName%20%3D%3D%20%27A%27%29%20%7Bconst%20href%20%3D%20target.getAttribute%28%27href%27%29%3Bif%20%28href.startsWith%28%27http%27%29%29%20%7Breturn%3B%7De.preventDefault%28%29%3Bconst%20entity%20%3D%20getEntityForHref%28href%29%3Bif%20%28entity%29%20%7Bconst%20%24scope%20%3D%20angular.element%28document.querySelector%28%27.ui-layout-pane-west%27%29%29.scope%28%29%3B%24scope.%24emit%28%27entity%3Aselected%27%2C%20entity%29%3B%7D%7D%7D%29%3Bcontent.addEventListener%28%27dblclick%27%2C%20function%28e%29%20%7Blet%20el%20%3D%20e.target%3Bif%20%28el%20%3D%3D%20content%29%20%7Breturn%3B%7Dwhile%20%28el.parentElement%20%21%3D%3D%20content%29%20%7Bel%20%3D%20el.parentElement%3B%7Dconst%20idx%20%3D%20Array.from%28content.children%29.indexOf%28el%29%3Bconst%20linesBefore%20%3D%20prevInputs.slice%280%2C%20idx%29.reduce%28%28acc%2C%20val%29%20%3D%3E%20%7Breturn%20acc%20%2B%20val.split%28%27%5Cn%27%29.length%3B%7D%2C%200%29%3Bconst%20editor%20%3D%20getAceEditor%28%29%3Bconst%20lines%20%3D%20editor.getSession%28%29.getDocument%28%29.getAllLines%28%29%3Bconst%20line%20%3D%20lines.map%28%28l%2C%20i%29%20%3D%3E%20%5Bl%2C%20i%5D%29.filter%28%28%5Bl%2C%20i%5D%29%20%3D%3E%20l%20%21%3D%20%27%27%29%5BlinesBefore%5D%5B1%5D%3Beditor.gotoLine%28line%2B1%29%3B%7D%29%3Bfunction%20flattenFolderTree%28folder%2C%20prefix%29%20%7B/%2A%2A%20Returns%20a%20flattened%20version%20of%20the%20files%20in%20the%20folder%20tree%2C%20a%20dictionary%2A%20with%20full%20path%20to%20file%20as%20key%20and%20file%20object%20as%20value.%2A/prefix%20%3D%20prefix%20%7C%7C%20%27%27%3Blet%20result%20%3D%20%7B%7D%3Bfor%20%28const%20f%20of%20folder.children%29%20%7Bif%20%28f.type%20%3D%3D%20%27folder%27%29%20%7BObject.assign%28result%2C%20flattenFolderTree%28f%2C%20prefix%20%2B%20f.name%20%2B%20%27/%27%29%29%3B%7D%20else%20%7Bresult%5Bprefix%2Bf.name%5D%20%3D%20f%3B%7D%7Dreturn%20result%3B%7D})();