Copy HTML to Anki

Copy specific parts of HTML and send them to Anki, converting relative URLs to absolute URLs. Trigger with Ctrl+Shift+Y or via Tampermonkey menu.

当前为 2024-07-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Copy HTML to Anki
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.2
  5. // @description Copy specific parts of HTML and send them to Anki, converting relative URLs to absolute URLs. Trigger with Ctrl+Shift+Y or via Tampermonkey menu.
  6. // @author nabe
  7. // @match *://*/*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_registerMenuCommand
  10. // @connect localhost
  11. // @run-at document-end
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. function copyHtmlToAnki() {
  19. // Function to convert relative URLs to absolute URLs
  20. function makeAbsolute(url) {
  21. return new URL(url, document.baseURI).href;
  22. }
  23.  
  24. // Clone the document to manipulate it
  25. let docClone = document.documentElement.cloneNode(true);
  26.  
  27. // Convert all relative URLs to absolute URLs
  28. let elements = docClone.querySelectorAll('[src], [href]');
  29. elements.forEach(function(element) {
  30. if (element.hasAttribute('src')) {
  31. element.setAttribute('src', makeAbsolute(element.getAttribute('src')));
  32. }
  33. if (element.hasAttribute('href')) {
  34. element.setAttribute('href', makeAbsolute(element.getAttribute('href')));
  35. }
  36. });
  37.  
  38. // Extract the specific parts needed
  39. let questionField = docClone.querySelector('.container.card')?.innerHTML || '';
  40. let hintField = Array.from(docClone.querySelectorAll('.options')).map(option => option.outerHTML).join('') || '';
  41. let answerField = Array.from(docClone.querySelectorAll('.options.correct')).map(option => option.outerHTML).join('') || '';
  42. let additionalInfoField = docClone.querySelector('.feedback')?.innerText || '';
  43.  
  44. // Create the note fields
  45. let noteFields = {
  46. "Front": questionField,
  47. "Hint": hintField,
  48. "Back": answerField,
  49. "Extra": additionalInfoField
  50. };
  51.  
  52. console.log("Note fields extracted:", noteFields);
  53.  
  54. GM_xmlhttpRequest({
  55. method: "POST",
  56. url: "http://localhost:8765",
  57. data: JSON.stringify({
  58. "action": "addNote",
  59. "version": 6,
  60. "params": {
  61. "note": {
  62. "deckName": "Default",
  63. "modelName": "Basic Build",
  64. "fields": noteFields,
  65. "tags": ["newimport"]
  66. }
  67. }
  68. }),
  69. headers: {
  70. "Content-Type": "application/json"
  71. },
  72. onload: function(response) {
  73. console.log("Response from AnkiConnect:", response);
  74. if (response.status === 200) {
  75. console.log("Note fields sent to Anki!");
  76. } else {
  77. alert("Failed to send note fields to Anki.");
  78. }
  79. }
  80. });
  81. }
  82.  
  83. // Add event listener for the keyboard shortcut (Ctrl+Shift+Y)
  84. document.addEventListener('keydown', function(event) {
  85. if (event.ctrlKey && event.shiftKey && event.code === 'KeyY') {
  86. copyHtmlToAnki();
  87. }
  88. });
  89.  
  90. // Register the menu command to Tampermonkey menu
  91. GM_registerMenuCommand("Copy HTML to Anki", copyHtmlToAnki);
  92. })();