@@ -161,17 +161,38 @@ class PicoCodeToolWindowContent(private val project: Project) {
161161
162162 /* *
163163 * Convert markdown to HTML for rendering
164+ * Note: Code block backgrounds use light gray which may need adjustment for dark themes
164165 */
165166 private fun markdownToHtml (markdown : String ): String {
166167 var html = markdown
167- // Escape HTML special characters first
168+
169+ // Process markdown constructs before escaping HTML
170+ // Code blocks (```) - preserve content as-is
171+ val codeBlockPlaceholders = mutableListOf<String >()
172+ html = html.replace(Regex (" ```([\\ s\\ S]*?)```" )) { matchResult ->
173+ val content = matchResult.groupValues[1 ]
174+ val placeholder = " ###CODEBLOCK${codeBlockPlaceholders.size} ###"
175+ codeBlockPlaceholders.add(content)
176+ placeholder
177+ }
178+
179+ // Inline code (`) - preserve content
180+ val inlineCodePlaceholders = mutableListOf<String >()
181+ html = html.replace(Regex (" `([^`]+)`" )) { matchResult ->
182+ val content = matchResult.groupValues[1 ]
183+ val placeholder = " ###INLINECODE${inlineCodePlaceholders.size} ###"
184+ inlineCodePlaceholders.add(content)
185+ placeholder
186+ }
187+
188+ // Escape HTML special characters in remaining text
189+ html = html
168190 .replace(" &" , " &" )
169191 .replace(" <" , " <" )
170192 .replace(" >" , " >" )
171- // Code blocks (```)
172- .replace(Regex (" ```([\\ s\\ S]*?)```" ), " <pre style='background-color: #f5f5f5; padding: 8px; border-radius: 4px;'><code>$1</code></pre>" )
173- // Inline code (`)
174- .replace(Regex (" `([^`]+)`" ), " <code style='background-color: #f0f0f0; padding: 2px 4px; border-radius: 3px;'>$1</code>" )
193+
194+ // Apply markdown formatting
195+ html = html
175196 // Bold (**text**)
176197 .replace(Regex (" \\ *\\ *([^*]+)\\ *\\ *" ), " <strong>$1</strong>" )
177198 // Italic (*text*)
@@ -183,14 +204,35 @@ class PicoCodeToolWindowContent(private val project: Project) {
183204 // Lists
184205 .replace(Regex (" ^- (.+)$" , RegexOption .MULTILINE ), " <li>$1</li>" )
185206 .replace(Regex (" ^\\ * (.+)$" , RegexOption .MULTILINE ), " <li>$1</li>" )
186- // Line breaks
187- .replace(" \n " , " <br/>" )
188207
189- // Wrap lists in <ul> tags
190- html = html.replace(Regex (" (<li>.*?</li>)+" )) { matchResult ->
191- " <ul>${matchResult.value} </ul>"
208+ // Restore code blocks with proper styling
209+ codeBlockPlaceholders.forEachIndexed { index, content ->
210+ val escapedContent = content
211+ .replace(" &" , " &" )
212+ .replace(" <" , " <" )
213+ .replace(" >" , " >" )
214+ html = html.replace(" ###CODEBLOCK${index} ###" ,
215+ " <pre style='background-color: rgba(127, 127, 127, 0.1); padding: 8px; border-radius: 4px; overflow-x: auto; border: 1px solid rgba(127, 127, 127, 0.2);'><code>$escapedContent </code></pre>" )
192216 }
193217
218+ // Restore inline code with proper styling
219+ inlineCodePlaceholders.forEachIndexed { index, content ->
220+ val escapedContent = content
221+ .replace(" &" , " &" )
222+ .replace(" <" , " <" )
223+ .replace(" >" , " >" )
224+ html = html.replace(" ###INLINECODE${index} ###" ,
225+ " <code style='background-color: rgba(127, 127, 127, 0.15); padding: 2px 4px; border-radius: 3px;'>$escapedContent </code>" )
226+ }
227+
228+ // Wrap consecutive list items in <ul> tags
229+ html = html.replace(Regex (" (<li>.*?</li>(?:<br/>)?)+" )) { matchResult ->
230+ " <ul>${matchResult.value.replace(" <br/>" , " " )} </ul>"
231+ }
232+
233+ // Convert line breaks (but not inside pre/code tags)
234+ html = html.replace(" \n " , " <br/>" )
235+
194236 return " <html><body style='font-family: sans-serif; font-size: 12px;'>$html </body></html>"
195237 }
196238
0 commit comments