mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-20 18:08:05 +02:00
Add files via upload
This commit is contained in:
+195
@@ -0,0 +1,195 @@
|
||||
package burp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Minimal Markdown -> HTML renderer for Burp UI.
|
||||
* Supports: headings (#..######), fenced code blocks (```), inline code (`),
|
||||
* bold (**), lists (-/*), paragraphs, and basic escaping.
|
||||
*
|
||||
* Not a full CommonMark implementation; kept dependency-free on purpose.
|
||||
*/
|
||||
final class MarkdownRenderer {
|
||||
private MarkdownRenderer() {}
|
||||
|
||||
static String toHtml(String markdown) {
|
||||
if (markdown == null) markdown = "";
|
||||
|
||||
List<String> lines = splitLines(markdown);
|
||||
StringBuilder out = new StringBuilder(4096);
|
||||
out.append("<html><head><meta charset='utf-8'>")
|
||||
.append("<style>")
|
||||
.append("body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Arial,sans-serif;font-size:12px;line-height:1.4;margin:10px;}")
|
||||
.append("code,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;}")
|
||||
.append("pre{background:#f6f8fa;border:1px solid #e5e7eb;border-radius:6px;padding:10px;overflow:auto;}")
|
||||
.append("h1,h2,h3{margin:0.8em 0 0.4em 0;}")
|
||||
.append("ul{margin:0.4em 0 0.6em 1.2em;padding:0;}")
|
||||
.append("</style></head><body>");
|
||||
|
||||
boolean inCode = false;
|
||||
boolean inList = false;
|
||||
StringBuilder codeBuf = new StringBuilder();
|
||||
|
||||
for (String raw : lines) {
|
||||
String line = raw == null ? "" : raw;
|
||||
|
||||
if (line.trim().startsWith("```")) {
|
||||
if (!inCode) {
|
||||
inCode = true;
|
||||
codeBuf.setLength(0);
|
||||
} else {
|
||||
// close code
|
||||
out.append("<pre><code>")
|
||||
.append(escapeHtml(codeBuf.toString()))
|
||||
.append("</code></pre>");
|
||||
inCode = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inCode) {
|
||||
codeBuf.append(line).append("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
String trimmed = line.trim();
|
||||
if (trimmed.isEmpty()) {
|
||||
if (inList) {
|
||||
out.append("</ul>");
|
||||
inList = false;
|
||||
}
|
||||
out.append("<div style='height:6px'></div>");
|
||||
continue;
|
||||
}
|
||||
|
||||
// headings
|
||||
int h = headingLevel(trimmed);
|
||||
if (h > 0) {
|
||||
if (inList) {
|
||||
out.append("</ul>");
|
||||
inList = false;
|
||||
}
|
||||
String text = trimmed.substring(h).trim();
|
||||
out.append("<h").append(h).append(">")
|
||||
.append(inlineFormat(text))
|
||||
.append("</h").append(h).append(">");
|
||||
continue;
|
||||
}
|
||||
|
||||
// list items
|
||||
if (trimmed.startsWith("- ") || trimmed.startsWith("* ")) {
|
||||
if (!inList) {
|
||||
out.append("<ul>");
|
||||
inList = true;
|
||||
}
|
||||
String item = trimmed.substring(2).trim();
|
||||
out.append("<li>").append(inlineFormat(item)).append("</li>");
|
||||
continue;
|
||||
}
|
||||
|
||||
// normal paragraph
|
||||
if (inList) {
|
||||
out.append("</ul>");
|
||||
inList = false;
|
||||
}
|
||||
out.append("<p>").append(inlineFormat(trimmed)).append("</p>");
|
||||
}
|
||||
|
||||
if (inCode) {
|
||||
out.append("<pre><code>")
|
||||
.append(escapeHtml(codeBuf.toString()))
|
||||
.append("</code></pre>");
|
||||
}
|
||||
if (inList) {
|
||||
out.append("</ul>");
|
||||
}
|
||||
|
||||
out.append("</body></html>");
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static int headingLevel(String s) {
|
||||
int i = 0;
|
||||
while (i < s.length() && s.charAt(i) == '#') i++;
|
||||
if (i >= 1 && i <= 6 && i < s.length() && Character.isWhitespace(s.charAt(i))) return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static String inlineFormat(String text) {
|
||||
// escape first, then apply simple replacements using placeholders
|
||||
String escaped = escapeHtml(text);
|
||||
|
||||
// inline code: `code`
|
||||
escaped = replaceInlineCode(escaped);
|
||||
|
||||
// bold: **text**
|
||||
escaped = replaceBold(escaped);
|
||||
|
||||
return escaped;
|
||||
}
|
||||
|
||||
private static String replaceInlineCode(String s) {
|
||||
StringBuilder out = new StringBuilder(s.length() + 16);
|
||||
boolean in = false;
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '`') {
|
||||
if (!in) {
|
||||
in = true;
|
||||
buf.setLength(0);
|
||||
} else {
|
||||
out.append("<code>").append(buf).append("</code>");
|
||||
in = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (in) buf.append(c);
|
||||
else out.append(c);
|
||||
}
|
||||
if (in) {
|
||||
// unmatched backtick: keep as literal
|
||||
out.append("`").append(buf);
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static String replaceBold(String s) {
|
||||
// simple non-nested **...**
|
||||
StringBuilder out = new StringBuilder(s.length() + 16);
|
||||
int i = 0;
|
||||
while (i < s.length()) {
|
||||
int start = s.indexOf("**", i);
|
||||
if (start < 0) {
|
||||
out.append(s.substring(i));
|
||||
break;
|
||||
}
|
||||
int end = s.indexOf("**", start + 2);
|
||||
if (end < 0) {
|
||||
out.append(s.substring(i));
|
||||
break;
|
||||
}
|
||||
out.append(s.substring(i, start));
|
||||
out.append("<b>").append(s, start + 2, end).append("</b>");
|
||||
i = end + 2;
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static String escapeHtml(String s) {
|
||||
if (s == null) return "";
|
||||
return s.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("\"", """);
|
||||
}
|
||||
|
||||
private static List<String> splitLines(String s) {
|
||||
String[] parts = s.split("\\r?\\n", -1);
|
||||
List<String> lines = new ArrayList<>(parts.length);
|
||||
for (String p : parts) lines.add(p);
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user