ToLogseq Markdown格式转换器 for ChatGPT

将 Markdown 文本转换为 Logseq 格式的 Markdown 文本,可用于 ChatGPT 和其他使用 md 格式的类似工具。

  1. // ==UserScript==
  2. // @name ToLogseq Format Converter for ChatGPT
  3. // @name:zh-CN ToLogseq Markdown格式转换器 for ChatGPT
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.2.5
  6. // @description Convert markdown text to Logseq formatted Markdown text, which is available for ChatGPT and other similar tools using md format.
  7. // @description:zh-cn 将 Markdown 文本转换为 Logseq 格式的 Markdown 文本,可用于 ChatGPT 和其他使用 md 格式的类似工具。
  8. // @author Another_Ghost
  9. // @match https://*chat.openai.com/*
  10. // @match https://*chatgpt.com/*
  11. // @icon https://img.icons8.com/?size=50&id=1759&format=png
  12. // @grant GM_registerMenuCommand
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. // Create the button element
  20. const button = document.createElement('button');
  21. button.textContent = 'ToLogseq'; // Text displayed on the button
  22. button.style.position = 'fixed'; // Make button position fixed
  23. button.style.bottom = '100px'; // Distance from the bottom of the viewport
  24. button.style.right = '20px'; // Distance from the right of the viewport
  25. button.style.zIndex = '1000'; // Ensure the button is on top of other elements
  26.  
  27. // Button click event
  28. button.onclick = ConvertCopy;
  29.  
  30. // Append the button to the page
  31. document.body.appendChild(button);
  32.  
  33. async function ConvertCopy() {
  34. try {
  35. let mark = "<!--Converted by ToLogseq-->";
  36. const clipboardText = await navigator.clipboard.readText(); // Read text from clipboard
  37. if(clipboardText.includes(mark))
  38. {
  39. showAlert('Already converted to Logseq!', 'orange');
  40. }
  41. else
  42. {
  43. let newText = ChatGPTToLogseq(clipboardText);
  44. newText = newText + "\n<!--Converted by ToLogseq-->";
  45. await navigator.clipboard.writeText(newText); // Write new text back to clipboard
  46. showAlert('Converted to Logseq!');
  47. }
  48. } catch (err) {
  49. console.error('Error converting to logseq:', err);
  50. showAlert('Failed to access clipboard', 'lightcoral');
  51. }
  52. }
  53.  
  54. function showAlert(message, backgroundColor = 'lightgreen') {
  55. const alertBox = document.createElement('div');
  56. alertBox.textContent = message;
  57. alertBox.style.position = 'fixed';
  58. alertBox.style.bottom = '130px';
  59. alertBox.style.right = '20px';
  60. alertBox.style.backgroundColor = backgroundColor;
  61. alertBox.style.padding = '10px';
  62. alertBox.style.borderRadius = '5px';
  63. alertBox.style.zIndex = '1001';
  64.  
  65. document.body.appendChild(alertBox);
  66.  
  67. setTimeout(() => {
  68. document.body.removeChild(alertBox);
  69. }, 3000); // Alert box will disappear after 3 seconds
  70. }
  71. })();
  72.  
  73. function ChatGPTToLogseq(text) {
  74.  
  75. text = text.replace(/\\\[([\s\S]*?)\\\]/g, function(match, p1) { // 匹配单行公式
  76. return '$$' + p1.trim() + '$$';
  77. });
  78. text = text.replace(/^( *)- /gm, '$1 - '); // 在别的添加 - 操作之前
  79. text = text.replace(/^### \d+\. ?(.*)/gm, '- ### $1 \nlogseq.order-list-type:: number');
  80. text = text.replace(/^### (.*)/gm, '- ### $1');
  81. text = text.replace(/^( *)\d+\. ?(.*)/gm, '$1 - $2\nlogseq.order-list-type:: number');
  82. //替换所有代码块,删除空白行后再替换回来
  83. let codeMap = {};
  84. let codeIndex = 0;
  85. text = text.replace(/\n? *```([\s\S]*?)```/g, function(match, p1) {
  86. codeMap[codeIndex] = p1;
  87. return '```' + codeIndex++ + '```';
  88. });
  89. text = text.replace(/\n\s*\n( *- )?/g, function(match, p1) {
  90. if(match.match(/- $/)){
  91. return '\n'+ p1;
  92. }
  93. else{
  94. return '\n- ';
  95. }
  96. });
  97. text = text.replace(/```(\d+)```/g, function(match, p1) {
  98. return '```' + codeMap[p1] + '```';
  99. });
  100. return text;
  101. }