aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-08-16 08:24:18 +0800
committer魏曹先生 <1992414357@qq.com>2026-08-16 08:24:18 +0800
commit4bf7a9bad2931766e3383d907d6f4ab138e39b66 (patch)
tree474d750f3b608818b3bc5a8b9278b543dad8b9b5 /docs
parent08116538a79875621dcd05ce6f6569cc62443b95 (diff)
feat(landing): enhance landing page with terminal hero and scroll snap
Add a fixed navigation bar, full-height hero section with tiled grid background, and an animated command carousel terminal. Style download links as interactive buttons and incorporate syntax highlighting styles. Introduce MlingDisplay JS parser for rendering display.rs-style markup with colors, headings, and formatting. Update version file config to include dist/index.html.
Diffstat (limited to 'docs')
-rw-r--r--docs/scripts/display-parse.js269
1 files changed, 269 insertions, 0 deletions
diff --git a/docs/scripts/display-parse.js b/docs/scripts/display-parse.js
new file mode 100644
index 0000000..ca7b391
--- /dev/null
+++ b/docs/scripts/display-parse.js
@@ -0,0 +1,269 @@
+/*!
+ * MlingDisplay — client-side port of mingling_cli/src/utils/display.rs
+ *
+ * Parses the same markdown-ish markup used by `display.rs` and returns HTML
+ * with the equivalent ANSI styling applied as CSS classes / inline colors.
+ *
+ * Supported syntax:
+ * - Bold: **text**
+ * - Italic: *text*
+ * - Underline: _text_
+ * - Cyan: <text>
+ * - Inline code: `text` (green)
+ * - Colors: [[color_name]] ... [[/]] (nested)
+ * - Escapes: \* \< \> \` \_
+ * - Headings: # Heading 1 ... ###### Heading 6
+ * - Blockquote: > text
+ *
+ * Exposes: window.MlingDisplay.parse(text) -> HTML string
+ */
+(function () {
+ "use strict";
+
+ function findMatch(chars, start, delimiter) {
+ var len = delimiter.length;
+ for (var j = start; j < chars.length; j++) {
+ if (len === 1) {
+ if (chars[j] === delimiter) return j;
+ } else if (
+ j + 1 < chars.length &&
+ chars[j] === delimiter[0] &&
+ chars[j + 1] === delimiter[1]
+ ) {
+ return j;
+ }
+ }
+ return -1;
+ }
+
+ var COLOR_MAP = {
+ black: "#000",
+ red: "#ff7b72",
+ green: "#7ee787",
+ yellow: "#d4a84b",
+ blue: "#79c0ff",
+ magenta: "#d2a8ff",
+ cyan: "#79c0ff",
+ white: "#e8ddd0",
+ b_white: "#e8ddd0",
+ bright_gray: "#6a5a4a",
+ bright_grey: "#6a5a4a",
+ b_gray: "#6a5a4a",
+ b_grey: "#6a5a4a",
+ bright_black: "#6a5a4a",
+ b_black: "#6a5a4a",
+ gray: "#6a5a4a",
+ grey: "#6a5a4a",
+ bright_red: "#ff7b72",
+ b_red: "#ff7b72",
+ bright_green: "#7ee787",
+ b_green: "#7ee787",
+ bright_yellow: "#d4a84b",
+ b_yellow: "#d4a84b",
+ bright_blue: "#79c0ff",
+ b_blue: "#79c0ff",
+ bright_magenta: "#d2a8ff",
+ b_magenta: "#d2a8ff",
+ bright_cyan: "#79c0ff",
+ b_cyan: "#79c0ff",
+ bright_white: "#e8ddd0",
+ };
+
+ function applyColorStack(text, stack) {
+ var wrapped = text;
+ for (var k = stack.length - 1; k >= 0; k--) {
+ var css = COLOR_MAP[stack[k]];
+ if (css) {
+ wrapped =
+ '<span style="color:' + css + '">' + wrapped + "</span>";
+ }
+ }
+ return wrapped;
+ }
+
+ function escapeHtml(s) {
+ return s
+ .replace(/&/g, "&amp;")
+ .replace(/</g, "&lt;")
+ .replace(/>/g, "&gt;");
+ }
+
+ function processLine(line) {
+ var chars = Array.from(line);
+ var result = "";
+ var colorStack = [];
+ var i = 0;
+
+ while (i < chars.length) {
+ var c = chars[i];
+
+ // Escape sequences \\* \\< \\> \\` \\_
+ if (
+ c === "\\" &&
+ i + 1 < chars.length &&
+ ["*", "<", ">", "`", "_"].indexOf(chars[i + 1]) !== -1
+ ) {
+ result += escapeHtml(chars[i + 1]);
+ i += 2;
+ continue;
+ }
+
+ // Color tags [[color]] / [[/]]
+ if (c === "[" && chars[i + 1] === "[") {
+ var tagEnd = -1;
+ for (var t = i + 2; t + 1 < chars.length; t++) {
+ if (chars[t] === "]" && chars[t + 1] === "]") {
+ tagEnd = t;
+ break;
+ }
+ }
+ if (tagEnd !== -1) {
+ var tag = chars.slice(i + 2, tagEnd).join("");
+ if (tag === "/") colorStack.pop();
+ else colorStack.push(tag);
+ i = tagEnd + 2;
+ continue;
+ }
+ }
+
+ // **bold**
+ if (c === "*" && chars[i + 1] === "*") {
+ var bEnd = findMatch(chars, i + 2, "**");
+ if (bEnd !== -1) {
+ var inner = processLine(chars.slice(i + 2, bEnd).join(""));
+ result += applyColorStack(
+ "<b>" + inner + "</b>",
+ colorStack,
+ );
+ i = bEnd + 2;
+ continue;
+ }
+ }
+
+ // *italic*
+ if (c === "*") {
+ var iEnd = findMatch(chars, i + 1, "*");
+ if (iEnd !== -1) {
+ var italic = processLine(chars.slice(i + 1, iEnd).join(""));
+ result += applyColorStack(
+ "<i>" + italic + "</i>",
+ colorStack,
+ );
+ i = iEnd + 1;
+ continue;
+ }
+ }
+
+ // _underline_
+ if (c === "_") {
+ var uEnd = findMatch(chars, i + 1, "_");
+ if (uEnd !== -1) {
+ var uText = processLine(chars.slice(i + 1, uEnd).join(""));
+ result += applyColorStack(
+ "<u>" + uText + "</u>",
+ colorStack,
+ );
+ i = uEnd + 1;
+ continue;
+ }
+ }
+
+ // <angle> cyan
+ if (c === "<") {
+ var cEnd = findMatch(chars, i + 1, ">");
+ if (cEnd !== -1) {
+ var angle = chars.slice(i, cEnd + 1).join("");
+ result += applyColorStack(
+ '<span class="t-cyan">' + escapeHtml(angle) + "</span>",
+ colorStack,
+ );
+ i = cEnd + 1;
+ continue;
+ }
+ }
+
+ // `code` green
+ if (c === "`") {
+ var gEnd = findMatch(chars, i + 1, "`");
+ if (gEnd !== -1) {
+ var codeText = chars.slice(i, gEnd + 1).join("");
+ result += applyColorStack(
+ '<span class="t-green">' +
+ escapeHtml(codeText) +
+ "</span>",
+ colorStack,
+ );
+ i = gEnd + 1;
+ continue;
+ }
+ }
+
+ // Regular character
+ result += applyColorStack(escapeHtml(c), colorStack);
+ i += 1;
+ }
+ return result;
+ }
+
+ function processLineWithQuote(line) {
+ var chars = Array.from(line);
+ if (chars.length && chars[0] === ">") {
+ if (chars.length > 1 && chars[1] === "\\") {
+ return processLine(line);
+ }
+ var rest = chars.length > 1 ? chars.slice(1).join("") : "";
+ return '<span class="t-quote"> </span>' + processLine(rest);
+ }
+ return processLine(line);
+ }
+
+ /**
+ * Parse display.rs-flavored markup into HTML.
+ * @param {string} text - Raw markup text.
+ * @returns {string} HTML with t-cyan / t-green / t-heading / t-quote classes
+ * and inline colors for [[color]] tags.
+ */
+ function parse(text) {
+ var lines = String(text).split("\n");
+ var result = "";
+ var contentIndent = 0;
+ for (var n = 0; n < lines.length; n++) {
+ var line = lines[n];
+ var trimmed = line.trim();
+ var ls = line.trimStart();
+ var lineResult = "";
+
+ if (ls.startsWith("#")) {
+ var level = 0;
+ while (level < ls.length && level < 7 && ls[level] === "#") {
+ level++;
+ }
+ var effective = level > 6 ? 6 : level;
+ var start = level;
+ while (
+ start < ls.length &&
+ (ls[start] === " " || ls[start] === "\t")
+ ) {
+ start++;
+ }
+ var content = start < ls.length ? ls.slice(start) : "";
+ var heading =
+ '<span class="t-heading"> ' +
+ processLine(content) +
+ " </span>";
+ var indent = " ".repeat(effective > 0 ? effective - 1 : 0);
+ lineResult = indent + heading;
+ contentIndent = effective;
+ } else if (trimmed !== "") {
+ lineResult =
+ " ".repeat(contentIndent) + processLineWithQuote(trimmed);
+ } else {
+ lineResult = " ";
+ }
+ result += lineResult + "\n";
+ }
+ return result;
+ }
+
+ window.MlingDisplay = { parse: parse };
+})();