diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f489f73..5982a31c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- Fixed markdown preview rendering fenced code blocks indented inside list items outside the list instead of nested within their list item - Fixed .md files in the Files panel losing all standard context menu items (Open, Cut, Copy, Delete, etc.) after installing the plugin — only "Preview Markdown" was shown - Fixed Bypass Permissions edit mode not suppressing the file diff dialog: the edit mode was lost from the registry because it was set before the working directory was assigned at session start diff --git a/pom.xml b/pom.xml index 436368b1..816fba30 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.nbclaudecodegui netbeans-claude-code-gui - 0.22.51-SNAPSHOT + 0.22.53-SNAPSHOT nbm Netbeans Plugin Claude Code GUI NetBeans plugin that provides a GUI for Claude Code CLI — run claude code sessions directly inside the IDE. diff --git a/src/main/java/io/github/nbclaudecodegui/ui/common/MarkdownRenderer.java b/src/main/java/io/github/nbclaudecodegui/ui/common/MarkdownRenderer.java index ecfc8957..17e2906d 100644 --- a/src/main/java/io/github/nbclaudecodegui/ui/common/MarkdownRenderer.java +++ b/src/main/java/io/github/nbclaudecodegui/ui/common/MarkdownRenderer.java @@ -228,6 +228,7 @@ public static String toHtml(String markdown) { StringBuilder html = new StringBuilder(); // Split on fenced code blocks; odd-indexed segments are code content. String[] parts = markdown.split("```[^\\n]*\\n", -1); + boolean continueList = false; for (int i = 0; i < parts.length; i++) { if (i % 2 == 0) { // regular text segment @@ -236,19 +237,46 @@ public static String toHtml(String markdown) { if (i > 0 && seg.startsWith("```")) { seg = seg.substring(3); } - html.append(convertSegment(seg)); + String converted = convertSegment(seg); + if (continueList) { + // strip the new
    ...
wrapper and continue inside the open list + converted = converted.replaceFirst("^
    ", "") + .replaceFirst("
$", ""); + continueList = false; + html.append(converted).append(""); + } else { + html.append(converted); + } } else { - // code block content (strip trailing ```) + // code block content String code = parts[i]; if (code.endsWith("```")) { code = code.substring(0, code.length() - 3); } - if (code.endsWith("\n")) { - code = code.substring(0, code.length() - 1); + code = code.stripTrailing(); + code = dedent(code); + String preHtml = "
" + esc(code) + "
"; + // An indented fence (spaces before ```) means the code block belongs to a list item + boolean indented = i > 0 && parts[i - 1].matches("(?s).*[ \t]+$"); + if (indented) { + // Remove the list closure emitted by the previous segment, then + // embed the code block inside the last
  • before re-closing it. + if (html.toString().endsWith("")) { + html.delete(html.length() - 5, html.length()); + } + if (html.toString().endsWith("
  • ")) { + html.delete(html.length() - 5, html.length()); + } + html.append(preHtml).append(""); + continueList = true; + } else { + html.append(preHtml); } - html.append("
    ").append(esc(code)).append("
    "); } } + if (continueList) { + html.append(""); + } return html.toString(); } @@ -533,13 +561,13 @@ private static int renderNestedList(String[] lines, int start, StringBuilder htm boolean ordered = isOrdered(line); if (indentStack.isEmpty()) { - html.append(ordered ? "
      " : "