Created
April 15, 2022 06:56
-
-
Save iwasakishuto/e83352abe05bed1ea10c30738b6177b9 to your computer and use it in GitHub Desktop.
Bookmarklet that converts the contents of note to markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file Bookmarklet that converts the contents of note to markdown | |
* @author Shuto Iwasaki <cabernet.rock@gmail.com> | |
* @copyright Iwasaki Shuto 2022 | |
* @license MIT | |
*/ | |
(function () { | |
/** <--- Utility Functions --- */ | |
const br2n = (text) => | |
text !== undefined ? text.split(/<br.*?>/).join("\n") : ""; | |
const quote = (text) => | |
text !== undefined ? `> ${text.split("\n").join("\n> ")}` : ""; | |
const getLast = (lst) => lst[lst.length - 1]; | |
const img2text = (img) => `![${img?.alt}](${img?.src})`; | |
/** --- End Utility Functions ---> */ | |
/* <--- Get Note Editor --- */ | |
let nb = getLast(document.querySelectorAll("div[contenteditable=true]")); | |
if (!nb) { | |
alert("Noteの編集画面が正しく表示されているかどうか確認してください。"); | |
return; | |
} | |
/* <--- End Get Note Editor --- */ | |
/* <--- Note Basic Information --- */ | |
let title = document.getElementById("note-name")?.innerText; | |
let header_img = document.querySelector('img[alt="見出し画像"]'); | |
let header = header_img && img2text(header_img); | |
/* --- End Note Basic Information ---> */ | |
/* <--- Note Content --- */ | |
var lines = [header]; | |
nb.childNodes.forEach((item) => { | |
let text = br2n(item.innerHTML); | |
switch (item.nodeName) { | |
case "P": | |
if ( | |
item.childNodes && | |
item.childNodes[0] && | |
item.childNodes[0].nodeName == "IMG" | |
) { | |
lines.push(img2text(item.childNodes[0])); | |
} else { | |
text = text.replace( | |
/<a.[^>]*href="([^"]+)"[^>]*>(.*?)<\/a>/g, | |
"[$2]($1)" | |
); | |
text = text | |
.replace(/<b>(.*?)<\/b>/g, " **$1** ") | |
.replace(/<strong>(.*?)<\/strong>/g, " **$1** "); | |
lines.push(text); | |
} | |
break; | |
case "H2": | |
lines.push(`## ${text}`); | |
break; | |
case "H3": | |
lines.push(`### ${text}`); | |
break; | |
case "BLOCKQUOTE": | |
lines.push(quote(text)); | |
break; | |
case "PRE": | |
lines.push(text.replace(/<code>(.*?)<\/code>/g, "```\n$1\n```")); | |
break; | |
case "FIGURE": | |
let img = item.querySelector("img"); | |
lines.push(img2text(img)); | |
let caption = item.querySelector("figcaption"); | |
if (caption) lines.push(quote(br2n(caption.innerHTML))); | |
break; | |
} | |
}); | |
/* --- End Note Content ---> */ | |
const ID_DLG = "note2infty_dialog"; | |
const ID_MD = `${ID_DLG}_markdown`; | |
var dialog; | |
dialog = document.getElementById(ID_DLG); | |
if (!dialog) { | |
dialog = document.createElement("dialog"); | |
} | |
dialog.innerHTML = ""; | |
let mdview = document.createElement("div"); | |
let mdlabel = document.createElement("label"); | |
let mdtext = document.createElement("textarea"); | |
let titleview = document.createElement("div"); | |
let titletext = document.createElement("div"); | |
let closeBtn = document.createElement("button"); | |
let copyWrapper = document.createElement("div"); | |
let copyBtn = document.createElement("button"); | |
dialog.id = ID_DLG; | |
dialog.style.width = "60vw"; | |
dialog.style.height = "70vh"; | |
dialog.style.margin = "auto"; | |
mdview.style.padding = "30px 5px 10px"; | |
mdtext.value = lines.join("\n\n"); | |
// mdtext.readOnly = true; | |
mdtext.id = ID_MD; | |
mdtext.style.padding = "10px"; | |
mdtext.style.display = "block"; | |
mdtext.style.width = "100%"; | |
mdtext.style.minHeight = "20em"; | |
mdtext.addEventListener("focus", () => { | |
mdtext.select(); | |
}); | |
mdlabel.textContent = "【Markdown】"; | |
mdlabel.appendChild(mdtext); | |
mdview.appendChild(mdlabel); | |
titleview.style.display = "flex"; | |
titleview.style.alignItems = "center"; | |
titleview.style.borderBottom = "1px solid #333"; | |
titleview.style.padding = "10px"; | |
titletext.style.marginRight = "auto"; | |
titletext.style.width = "calc(100% - 50px)"; | |
titletext.style.wordBreak = "break-all"; | |
titletext.innerHTML = title; | |
closeBtn.style.marginLeft = "auto"; | |
closeBtn.style.padding = "10px 14px"; | |
closeBtn.style.borderRadius = "50%"; | |
closeBtn.style.cursor = "pointer"; | |
closeBtn.textContent = "x"; | |
closeBtn.style.width = "40px"; | |
closeBtn.addEventListener("click", () => { | |
dialog.close(); | |
}); | |
titleview.appendChild(titletext); | |
titleview.appendChild(closeBtn); | |
copyBtn.textContent = "Copy"; | |
copyBtn.style.marginLeft = "auto"; | |
copyBtn.style.padding = "5px 10px"; | |
copyBtn.addEventListener("click", () => { | |
navigator.clipboard.writeText(document.getElementById(ID_MD).value); | |
console.log(document.getElementById(ID_MD).value); | |
alert("クリップボードにコピーしました。"); | |
}); | |
copyWrapper.style.display = "flex"; | |
copyWrapper.appendChild(copyBtn); | |
dialog.appendChild(titleview); | |
dialog.appendChild(mdview); | |
dialog.appendChild(copyWrapper); | |
document.body.appendChild(dialog); | |
dialog.showModal(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Closure Compilerでコンパイルした後