NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Copy Markdown from HTML
// @namespace http://tampermonkey.net/
// @version 0.5
// @description 按ctrl + z将选中内容转换为Markdown格式并加入剪贴板
// @description:en Press ctrl + z to convert the selected HTML to Markdown format and add to the clipboard
// @copyright 2019, zhanyaha
// @license MIT
// @author zhanyaha
// @match *://*/*
// @require https://unpkg.com/turndown/dist/turndown.js
// @require https://unpkg.com/turndown-plugin-gfm/dist/turndown-plugin-gfm.js
// @grant GM_setClipboard
// ==/UserScript==
(function() {
'use strict';
function commonParentNode(oNode1, oNode2) {
if(oNode1===oNode2){
return oNode1.parentNode;
}
for(;;oNode1=oNode1.parentNode) {
if(oNode1.contains(oNode2)){
return oNode1;
}
}
}
document.addEventListener("keydown", function(e) {
if(e.ctrlKey && e.keyCode == 90 ){
var sel=document.getSelection();
var relative_pos=sel.anchorNode.compareDocumentPosition(sel.focusNode);
var content = commonParentNode(sel.anchorNode,sel.focusNode);
let fragment = document.createDocumentFragment();
if(content.children.length===0){
fragment.appendChild(content.cloneNode(true));
}
for(let item of content.children){
var p1 = item.compareDocumentPosition(sel.anchorNode);
var p2 = item.compareDocumentPosition(sel.focusNode);
if(relative_pos!==2){
if(p1===4 || p2===2){
continue;
}
}else{
if(p1===2 || p2===4){
continue;
}
}
fragment.appendChild(item.cloneNode(true));
}
var imgDatas = '';
var count = 0;
function getMarkdown(container){
var turndownService = new TurndownService({ codeBlockStyle: 'fenced' });
var gfm = turndownPluginGfm.gfm;
turndownService.use(gfm)
turndownService.keep(['pre']);
turndownService.remove('script')
turndownService.addRule('image', {
filter: 'img',
replacement: function (content, node) {
return '!['+ node.alt+ '][' + node.id + ']';
}
})
var markdown = turndownService.turndown(container);
markdown = '> From ['+location.href+']('+location.href+')\n\n'+markdown+imgDatas;
GM_setClipboard(markdown);
}
var imgs = fragment.querySelectorAll('img');
if(imgs.length){
imgs.forEach(function(item,index){
GM_xmlhttpRequest({
method: 'GET',
url:item.src,
responseType:'blob',
headers: {
referer:location.href
},
onload: function(res) {
let reader = new FileReader();
reader.onloadend = (function (i){
return function(){
imgDatas += '\n\n[img'+i+']:'+reader.result;
count++;
if(count === imgs.length){
getMarkdown(fragment);
}
};
})(index);
let blob = res.response.slice(0,res.response.size,/(?:content-type:\s*)(.*)/g.exec(res.responseHeaders)[1]);
reader.readAsDataURL(blob);
item.id = 'img'+index;
},
onerror: function(e) {
console.error(e);
}
});
});
}else{
getMarkdown(fragment);
}
}
})
})();