Copy Markdown Quote Alt+C

Press Alt+C to copy title and url as markdown style link `> ${SELECTION} [${TITLE}]( ${URL} )`

  1. // ==UserScript==
  2. // @name Copy Markdown Quote Alt+C
  3. // @name:zh Alt+C 复制Markdown格式标题和地址快速分享
  4. // @name:en Alt+C Copy Title and Link as Markdown Style
  5. // @description Press Alt+C to copy title and url as markdown style link `> ${SELECTION} [${TITLE}]( ${URL} )`
  6. // @description:zh 按 Alt+C 复制 Markdown 格式的链接 `> ${SELECTION} [${TITLE}]( ${URL} )`
  7. // @namespace https://userscript.snomiao.com/
  8. // @version 0.8.4
  9. // @author snomiao@gmail.com
  10. // @match *://*/*
  11. // @grant none
  12. // ==/UserScript==
  13. "use strict";
  14. (() => {
  15. // ../node_modules/hotkey-mapper/dist/index.mjs
  16. var { keys } = Object;
  17. function mapObject(fn, obj) {
  18. if (arguments.length === 1) {
  19. return (_obj) => mapObject(fn, _obj);
  20. }
  21. let index = 0;
  22. const objKeys = keys(obj);
  23. const len = objKeys.length;
  24. const willReturn = {};
  25. while (index < len) {
  26. const key = objKeys[index];
  27. willReturn[key] = fn(
  28. obj[key],
  29. key,
  30. obj
  31. );
  32. index++;
  33. }
  34. return willReturn;
  35. }
  36. var mapObjIndexed = mapObject;
  37. function hotkeyMapper(mapping, options) {
  38. const handler = (event) => {
  39. if (!event.key)
  40. throw new Error("Invalid KeyboardEvent");
  41. if (!event.code)
  42. throw new Error("Invalid KeyboardEvent");
  43. const key = event.key?.toLowerCase();
  44. const code = event.code?.toLowerCase();
  45. const simp = event.code?.replace(/^(?:Key|Digit|Numpad)/, "").toLowerCase();
  46. const map = new Proxy(event, {
  47. get: (target2, p) => Boolean(
  48. {
  49. [`${key}Key`]: true,
  50. [`${code}Key`]: true,
  51. [`${simp}Key`]: true
  52. }[p] ?? target2[p]
  53. )
  54. });
  55. const mods = "meta+alt+shift+ctrl";
  56. mapObjIndexed((fn, hotkey) => {
  57. const conds = `${mods}+${hotkey.toLowerCase()}`.replace(/win|command|search/, "meta").replace(/control/, "ctrl").split("+").map((key2) => key2.toLowerCase().trim()).map((k, i) => [k, i >= 4 === map[`${k}Key`]]);
  58. if (!Object.entries(Object.fromEntries(conds)).every(([, ok]) => ok))
  59. return;
  60. event.stopPropagation?.();
  61. event.preventDefault?.();
  62. return fn(event);
  63. }, mapping);
  64. };
  65. const target = options?.target ?? globalThis;
  66. target.addEventListener(options?.on ?? "keydown", handler, options);
  67. return function unload() {
  68. target.removeEventListener(options?.on ?? "keydown", handler, options);
  69. };
  70. }
  71.  
  72. // ../node_modules/.pnpm/clipboardy@3.0.0/node_modules/clipboardy/browser.js
  73. var clipboard = {};
  74. clipboard.write = async (text) => {
  75. await navigator.clipboard.writeText(text);
  76. };
  77. clipboard.read = async () => navigator.clipboard.readText();
  78. clipboard.readSync = () => {
  79. throw new Error("`.readSync()` is not supported in browsers!");
  80. };
  81. clipboard.writeSync = () => {
  82. throw new Error("`.writeSync()` is not supported in browsers!");
  83. };
  84. var browser_default = clipboard;
  85.  
  86. // ../ts/CopyMarkdownQuote.user.ts
  87. {
  88. main();
  89. }
  90. function main() {
  91. globalThis.cmqa ||= {};
  92. globalThis.cmqa.unload?.();
  93. globalThis.cmqa.unload = hotkeyMapper({
  94. "alt+c": async (e) => {
  95. e.preventDefault?.();
  96. e.stopPropagation?.();
  97. const selected = window?.getSelection()?.toString().trim() || "";
  98. const quoted = selected && selected.replace(/.*/g, (s) => `> ${s}`);
  99. const href = location.href;
  100. const content = `- [${longestTitleGet()?.replace(
  101. /([|])/,
  102. (e2) => "\\" + e2
  103. )}]( ${href} )
  104. ${quoted}`.trim();
  105. await browser_default.write(content);
  106. alert(`copied:
  107. ${content}`);
  108. }
  109. });
  110. }
  111. function longestTitleGet() {
  112. const LongestTitle = [
  113. document.title,
  114. document.querySelector("h1")?.innerText || ""
  115. ].map((str) => str.replace(/\r?\n.*/g, "")).sort((a, b) => a.length - b.length).pop();
  116. return LongestTitle;
  117. }
  118. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址