* Extract content from ChatGPT message with proper formula conversion * Converts KaTeX formulas to standard Markdown format
(container)
| 163 | * Converts KaTeX formulas to standard Markdown format |
| 164 | */ |
| 165 | function extractContentWithFormulas(container) { |
| 166 | const markdownDivs = container.querySelectorAll('.markdown'); |
| 167 | if (markdownDivs.length === 0) return ''; |
| 168 | |
| 169 | let result = ''; |
| 170 | |
| 171 | const getCodeBlockText = (codeNode) => { |
| 172 | let text = ''; |
| 173 | |
| 174 | const appendNodeText = (currentNode) => { |
| 175 | if (currentNode.nodeType === Node.TEXT_NODE) { |
| 176 | text += currentNode.textContent; |
| 177 | return; |
| 178 | } |
| 179 | |
| 180 | if (currentNode.nodeType !== Node.ELEMENT_NODE) { |
| 181 | return; |
| 182 | } |
| 183 | |
| 184 | if (currentNode.tagName === 'BR') { |
| 185 | text += '\n'; |
| 186 | return; |
| 187 | } |
| 188 | |
| 189 | currentNode.childNodes.forEach(appendNodeText); |
| 190 | }; |
| 191 | |
| 192 | codeNode.childNodes.forEach(appendNodeText); |
| 193 | return text.replace(/\n$/, ''); |
| 194 | }; |
| 195 | |
| 196 | const normalizeCodeLanguage = (language) => { |
| 197 | const normalized = (language || '').trim().toLowerCase(); |
| 198 | const aliases = { |
| 199 | 'c++': 'cpp', |
| 200 | 'c#': 'csharp', |
| 201 | 'js': 'javascript', |
| 202 | 'ts': 'typescript', |
| 203 | 'shell': 'bash', |
| 204 | 'zsh': 'bash', |
| 205 | }; |
| 206 | |
| 207 | if (aliases[normalized]) return aliases[normalized]; |
| 208 | return /^[a-z0-9_+-]+$/.test(normalized) ? normalized : ''; |
| 209 | }; |
| 210 | |
| 211 | const getCodeBlockLanguage = (preNode, codeNode) => { |
| 212 | const classLanguage = codeNode.className.match(/language-([a-zA-Z0-9_+-]+)/)?.[1]; |
| 213 | if (classLanguage) { |
| 214 | return normalizeCodeLanguage(classLanguage); |
| 215 | } |
| 216 | |
| 217 | const labels = Array.from(preNode.querySelectorAll('div')) |
| 218 | .filter(element => !element.contains(codeNode)) |
| 219 | .map(element => element.textContent?.trim() || '') |
| 220 | .filter(text => text && text.length <= 30 && !/复制|copy/i.test(text)); |
| 221 | |
| 222 | for (const label of labels) { |
no test coverage detected