| 218 | } |
| 219 | |
| 220 | QList<MessagePart> ChatModel::processMessageContent(const QString &content) const |
| 221 | { |
| 222 | QList<MessagePart> parts; |
| 223 | QRegularExpression codeBlockRegex("```(\\w*)\\n?([\\s\\S]*?)```"); |
| 224 | int lastIndex = 0; |
| 225 | auto blockMatches = codeBlockRegex.globalMatch(content); |
| 226 | |
| 227 | while (blockMatches.hasNext()) { |
| 228 | auto match = blockMatches.next(); |
| 229 | if (match.capturedStart() > lastIndex) { |
| 230 | QString textBetween |
| 231 | = content.mid(lastIndex, match.capturedStart() - lastIndex).trimmed(); |
| 232 | if (!textBetween.isEmpty()) { |
| 233 | MessagePart part; |
| 234 | part.type = MessagePartType::Text; |
| 235 | part.text = textBetween; |
| 236 | parts.append(part); |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | MessagePart codePart; |
| 241 | codePart.type = MessagePartType::Code; |
| 242 | codePart.text = match.captured(2).trimmed(); |
| 243 | codePart.language = match.captured(1); |
| 244 | parts.append(codePart); |
| 245 | |
| 246 | lastIndex = match.capturedEnd(); |
| 247 | } |
| 248 | |
| 249 | if (lastIndex < content.length()) { |
| 250 | QString remainingText = content.mid(lastIndex).trimmed(); |
| 251 | |
| 252 | QRegularExpression unclosedBlockRegex("```(\\w*)\\n?([\\s\\S]*)$"); |
| 253 | auto unclosedMatch = unclosedBlockRegex.match(remainingText); |
| 254 | |
| 255 | if (unclosedMatch.hasMatch()) { |
| 256 | QString beforeCodeBlock = remainingText.left(unclosedMatch.capturedStart()).trimmed(); |
| 257 | if (!beforeCodeBlock.isEmpty()) { |
| 258 | MessagePart part; |
| 259 | part.type = MessagePartType::Text; |
| 260 | part.text = beforeCodeBlock; |
| 261 | parts.append(part); |
| 262 | } |
| 263 | |
| 264 | MessagePart codePart; |
| 265 | codePart.type = MessagePartType::Code; |
| 266 | codePart.text = unclosedMatch.captured(2).trimmed(); |
| 267 | codePart.language = unclosedMatch.captured(1); |
| 268 | parts.append(codePart); |
| 269 | } else if (!remainingText.isEmpty()) { |
| 270 | MessagePart part; |
| 271 | part.type = MessagePartType::Text; |
| 272 | part.text = remainingText; |
| 273 | parts.append(part); |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | return parts; |