-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.ts
126 lines (123 loc) · 4.15 KB
/
lib.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
export function extractMarkdown() {
// Export Chatlog To Markdown
// Select all chat messages
const chatMessages = document.querySelectorAll(".text-base")
const pageTitle = document.title
const now = new Date()
const dateString = `${now.getFullYear()}-${(now.getMonth() + 1)
.toString()
.padStart(2, "0")}-${now.getDate().toString().padStart(2, "0")}-${now
.getHours()
.toString()
.padStart(2, "0")}-${now.getMinutes().toString().padStart(2, "0")}-${now
.getSeconds()
.toString()
.padStart(2, "0")}`
// Loop through each chat message and extract the content
let markdownContent = ""
for (const message of chatMessages) {
if (message.querySelector(".whitespace-pre-wrap")) {
// Extract the message text and format it
let messageText = message.querySelector(".whitespace-pre-wrap").innerHTML
// ID Who
const sender = message.querySelector("img") ? "You" : "ChatGPT"
if (sender === "ChatGPT") {
} else {
}
// Pre Escapes
messageText = messageText
.replace(/_/gs, "_")
.replace(/\*/gs, "*")
.replace(/\^/gs, "^")
.replace(/~/gs, "~") // I debated adding #, > (blockquotes), and | (table)
// <p> element and everything in-line or inside
messageText = messageText.replace(/<p>(.*?)<\/p>/g, function (match, p1) {
return (
"\n" +
p1
.replace(/<b>(.*?)<\/b>/g, "**$1**")
.replace(/<\/?b>/g, "**")
.replace(/<\/?i>/g, "_")
.replace(/<code>/g, " `")
.replace(/<\/code>/g, "` ") +
"\n"
)
})
// Add message to markdown content
markdownContent += `**${sender}:** ${messageText.trim()}\n\n`
}
}
// Remove Span with only class declaration, there is nesting? If there is more than 5 layers, just do it manually
const repeatSpan = /<span class="[^"]*">([^<]*?)<\/span>/gs
markdownContent = markdownContent
.replace(repeatSpan, "$1")
.replace(repeatSpan, "$1")
.replace(repeatSpan, "$1")
.replace(repeatSpan, "$1")
.replace(repeatSpan, "$1")
// Code Blocks, `text` is the default catch-all (because some commands/code-blocks aren't styled/identified by ChatGPT yet)
markdownContent = markdownContent.replace(
/<pre>.*?<code[^>]*>(.*?)<\/code>.*?<\/pre>/gs,
function (match, p1) {
const language = match.match(/class="[^"]*language-([^"\s]*)[^"]*"/)
const languageIs = language ? language[1] : "text"
return (
"\n``` " +
languageIs +
"\n" +
p1 +
// .replace(/>/gs, ">")
// .replace(/</gs, "<")
// .replace(/>/gs, "&")
"```\n"
)
}
)
markdownContent = markdownContent.replace(
/<p>(.*?)<\/p>/g,
function (match, p1) {
return (
"\n" +
p1
.replace(/<b>(.*?)<\/b>/g, "**$1**")
.replace(/<\/?b>/g, "**")
.replace(/<\/?i>/g, "_")
.replace(/<code>/g, " `")
.replace(/<\/code>/g, "` ") +
"\n"
)
}
)
// Finalize and tweaks and remove extra stuff
// Convert text stuff
markdownContent = markdownContent
.replace(
/<div class="markdown prose w-full break-words dark:prose-invert dark">/gs,
""
)
.replace(/\r?\n?<\/div>\r?\n?/gs, "\n")
.replace(/\*\*ChatGPT:\*\* <(ol|ul)/gs, "**ChatGPT:**\n<$1")
.replace(/>/gs, ">")
.replace(/</gs, "<")
.replace(/&/gs, "&")
return { pageTitle, dateString, markdownContent }
}
export function copy(content: string) {
navigator.clipboard.writeText(content)
}
export function download(mdWithMeta: {
pageTitle: string
dateString: string
markdownContent: string
}) {
const { pageTitle, dateString, markdownContent } = mdWithMeta
// Create and download the markdown file
const downloadLink = document.createElement("a")
downloadLink.download = "ChatLog - " + pageTitle + " - " + dateString + ".md"
downloadLink.href = URL.createObjectURL(
new Blob([markdownContent], { type: "text/markdown" })
)
downloadLink.style.display = "none"
document.body.appendChild(downloadLink)
downloadLink.click()
}