Linux.do 下崽器

备份你珍贵的水贴为Markdown。

  1. // ==UserScript==
  2. // @name Linux.do 下崽器
  3. // @namespace http://linux.do/
  4. // @source https://github.com/
  5. // @version 1.1.1
  6. // @description 备份你珍贵的水贴为Markdown。
  7. // @author xdd
  8. // @match https://www.linux.do/t/topic/*
  9. // @match https://linux.do/t/topic/*
  10. // @license MIT
  11. // @icon https://cdn.linux.do/uploads/default/optimized/1X/3a18b4b0da3e8cf96f7eea15241c3d251f28a39b_2_32x32.png
  12. // @grant none
  13. // @require https://unpkg.com/turndown@7.1.3/dist/turndown.js
  14. // ==/UserScript==
  15.  
  16. /** 更新日志
  17. * 1: 脚本开写
  18. *
  19. *
  20. *
  21. */
  22.  
  23. (function () {
  24. "use strict";
  25.  
  26. console.log("Starting watering…");
  27.  
  28. /**
  29. * Make a button element.
  30. */
  31. function makeButton(buttonText) {
  32. var $button = document.createElement("button");
  33. $button.setAttribute("type", "button");
  34. $button.classList.add("linuxdocopier-button");
  35. $button.innerText = buttonText; // Set the button text to the passed argument
  36. // $button.style.position = "fixed";
  37. // $button.style.bottom = "10px";
  38. // $button.style.right = "10px";
  39. $button.style.top = "-2em";
  40. $button.style.zIndex = "999";
  41. // $button.style.width = "120px";
  42. $button.style.height = "2em";
  43. $button.style.backgroundColor = "rgba(85, 85, 85, 0.9)";
  44. $button.style.color = "white";
  45. $button.style.outline = "none";
  46. $button.style.cursor = "pointer";
  47. $button.style.borderRadius = "1em";
  48. // $button.style.margin = "0 .2em 1em .2em";
  49. $button.style.fontSize = "1.2em";
  50. $button.style.padding = ".4em";
  51. return $button;
  52. }
  53.  
  54.  
  55. // 插入按钮到页面
  56. const button = makeButton(" 下载为Markdown ")
  57. document.querySelector("#topic-title > div > div").appendChild(button);
  58.  
  59. // 点击事件的处理函数
  60. button.addEventListener("click", function () {
  61. // 使用Turndown库将HTML转换成Markdown
  62. const turndownService = new TurndownService();
  63. // Use Turndown service to convert target element's HTML to Markdown
  64. const articleDom = document.querySelector("#ember48");
  65. if (articleDom) {
  66.  
  67. // 创建targetElement的副本
  68. const articleContent = articleDom.cloneNode(true);
  69.  
  70. const titleElement = document.querySelector("#topic-title > div > div > h1 > a.fancy-title > span");
  71. let repliesElement = document.querySelector("#post_1 > div > div.topic-body.clearfix > div.topic-map > section > ul > li.replies > span");
  72.  
  73.  
  74. // Check if the elements exist
  75. if (!titleElement) {
  76.  
  77. console.log("未找到 titleElement ")
  78. alert("论坛更新了 脚本没更新 可能不适配 ");
  79. return;
  80. }
  81. if (!repliesElement) {
  82. repliesElement = "0";
  83. } else {
  84.  
  85. }
  86.  
  87. articleContent.querySelector(".post-menu-area")?.remove();
  88. articleContent.querySelector(".topic-map")?.remove();
  89. articleContent.querySelector(".linuxdocopier-button")?.remove();
  90. articleContent.querySelector(".selected-posts")?.remove();
  91. articleContent.querySelector(".topic-navigation")?.remove();
  92. articleContent.querySelector(".with-timeline")?.remove();
  93. articleContent.querySelector(".more-topics__container")?.remove();
  94. articleContent.querySelector("#topic-footer-buttons")?.remove();
  95.  
  96. // 初始化一个数组来存储所有Markdown列表项
  97. let markdownList = [];
  98. markdownList.push(`\n\n## ${repliesElement.innerText.trim()}个回复 \n\n`);
  99. let nodes = articleContent.querySelectorAll("#ember63 > div > div");
  100. nodes.forEach((element, index) => {
  101. // 如果不是第一个元素,则移除
  102. if (index !== 0) {
  103.  
  104.  
  105. // 查找用户名
  106. const username = element.querySelector(".full-name")?.innerText.trim() + " " + element.querySelector(".username")?.innerText.trim();
  107.  
  108. // 查找回复时间
  109. let timeele = element.querySelector(".relative-date");
  110. const timestamp = timeele ? timeele.title : "未知时间";
  111.  
  112.  
  113. // 查找回复内容,这里假设回复内容是放在 <p dir="ltr"> 标签内的
  114. const content = element.querySelector(".cooked")?.innerText.trim();
  115. const contentMd = turndownService.turndown(content)
  116.  
  117.  
  118. // 如果用户名和内容都存在,则将它们格式化为Markdown列表项
  119. if (username && content) {
  120. markdownList.push(`- **${username}** - ${timestamp}\n > ${contentMd}`);
  121. }
  122.  
  123. element.remove();
  124. }
  125. });
  126.  
  127. // 将所有Markdown列表项合并成一个字符串
  128. const markdownReply = markdownList.join("\n\n");
  129. const markdown = turndownService.turndown(articleContent.innerHTML) + "\n\n " + markdownReply;
  130.  
  131.  
  132. // Retrieve the text contents of the elements
  133. const titleText = titleElement.innerText.trim();
  134. const repliesText = repliesElement.innerText.trim();
  135.  
  136.  
  137. // Form the filename
  138. const filename = `【Linux.c${titleText} - 含水量${repliesText}.md`;
  139.  
  140.  
  141. // 创建一个blob并生成一个下载链接
  142. const blob = new Blob([markdown], {type: "text/markdown;charset=utf-8"});
  143. const downloadLink = document.createElement("a");
  144. downloadLink.href = URL.createObjectURL(blob);
  145. downloadLink.download = filename;
  146.  
  147. // 触发下载
  148. downloadLink.click();
  149.  
  150. // 清理创建的URL对象
  151.  
  152. URL.revokeObjectURL(downloadLink.href);
  153. } else {
  154. console.log("未找到 articleContent")
  155. alert("论坛更新了 脚本没更新 可能不适配 ");
  156. }
  157.  
  158. });
  159. })();

QingJ © 2025

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