Skip to content

Instantly share code, notes, and snippets.

@Spike-Leung
Last active September 28, 2025 09:17
Show Gist options
  • Select an option

  • Save Spike-Leung/19986df42333b6419b2eadaa73526d7b to your computer and use it in GitHub Desktop.

Select an option

Save Spike-Leung/19986df42333b6419b2eadaa73526d7b to your computer and use it in GitHub Desktop.
org-protocol.user.js
// ==UserScript==
// @name org-protocol
// @namespace https://gist.github.com/Spike-Leung/19986df42333b6419b2eadaa73526d7b
// @version 0.0
// @description Use Alt + l for Org: capture and use Alt + h for Org: capture-html
// @author Spike-Leung
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
function generateMusic163Table() {
const songRows = document.querySelectorAll('.m-record .j-flag ul li');
if (songRows.length === 0) return null;
const baseURL = 'https://music.163.com';
let table = [
'| 歌曲 | 歌手 | 播放次数 |',
'|------+----------+------|'
];
songRows.forEach(row => {
const songLink = row.querySelector('.ttc .txt a');
const artistLink = row.querySelector('.ar a');
const playCountSpan = row.querySelector('.tops .times');
if (songLink && artistLink && playCountSpan) {
const songTitle = songLink.querySelector('b').title;
const songUrl = baseURL + songLink.getAttribute('href');
const artistName = artistLink.textContent;
const artistUrl = baseURL + artistLink.getAttribute('href');
const playCount = playCountSpan.textContent.trim();
table.push(`| [[${songUrl}][${songTitle}]] | [[${artistUrl}][${artistName}]] | ${playCount} |`);
}
});
return table.join('\n');
}
document.addEventListener('keydown', function(e) {
// Alt + s: store-link
// @see: https://orgmode.org/org.html#Protocols
if (e.code === 'KeyS' && e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
location.href = `org-protocol://store-link?${new URLSearchParams({url:location.href, title:document.title})}`
}
// Alt + m: 获取网易云听歌排行
if (e.code === 'KeyM' && e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
if (location.hostname === 'music.163.com') {
const table = generateMusic163Table();
if (table) {
const params = new URLSearchParams({
template: 'm', // Use 'm' template
url: window.location.href,
title: document.title,
body: table
});
location.href = `org-protocol://capture?${params.toString()}`;
} else {
alert('未找到听歌排行数据,请确保在正确的页面使用此功能。');
}
}
}
// Alt + l: capture
if (e.code === 'KeyL' && e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
location.href = `org-protocol://capture?${new URLSearchParams({
// you may need to change the template
template: 'x',
url: window.location.href,
title: document.title,
body: window.getSelection()
})}
`;
}
// Alt + h: capture html
// @see: https://github.com/alphapapa/org-protocol-capture-html
if (e.code === 'KeyH' && e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
const params = new URLSearchParams();
params.set('template', 'w');
params.set('url', location.href);
params.set('title', document.title || "[untitled page]");
params.set('body', (() => {
let html = "";
if (typeof window.getSelection !== "undefined") {
const sel = window.getSelection();
if (sel.rangeCount) {
const container = document.createElement("div");
for (let i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
html = container.innerHTML;
}
} else if (typeof document.selection !== "undefined") {
if (document.selection.type === "Text") {
html = document.selection.createRange().htmlText;
}
}
const relToAbs = (href) => {
const a = document.createElement("a");
a.href = href;
const abs = `${a.protocol}//${a.host}${a.pathname}${a.search}${a.hash}`;
a.remove();
return abs;
};
const elementTypes = [['a', 'href'], ['img', 'src']];
const div = document.createElement('div');
div.innerHTML = html;
elementTypes.forEach(([tag, attr]) => {
const elements = div.getElementsByTagName(tag);
for (let i = 0; i < elements.length; i++) {
elements[i].setAttribute(attr, relToAbs(elements[i].getAttribute(attr)));
}
});
return div.innerHTML;
})());
location.href = `org-protocol://capture-html?${params.toString()}`;
}
}, false);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment