aboutsummaryrefslogtreecommitdiff
path: root/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'index.html')
-rw-r--r--index.html921
1 files changed, 921 insertions, 0 deletions
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..da42f99
--- /dev/null
+++ b/index.html
@@ -0,0 +1,921 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Mìng Lìng — Macro magician in your CLI</title>
+ <link rel="icon" type="image/png" href="docs/res/icon_shadow.png" />
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
+ <link
+ href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&display=swap"
+ rel="stylesheet"
+ />
+ <link
+ rel="stylesheet"
+ href="docs/scripts/highlight/github-dark.min.css"
+ />
+ <style>
+ *,
+ *::before,
+ *::after {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+
+ html {
+ scroll-behavior: smooth;
+ }
+
+ body {
+ font-family: "Noto Serif SC", Georgia, "Times New Roman", serif;
+ background-color: #1a1410;
+ color: #e8ddd0;
+ line-height: 1.6;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ overflow-x: hidden;
+ }
+
+ a {
+ color: #d4a84b;
+ text-decoration: none;
+ transition: color 0.2s;
+ }
+ a:hover {
+ color: #e8c46a;
+ }
+
+ img {
+ max-width: 100%;
+ height: auto;
+ }
+
+ .container {
+ max-width: 1080px;
+ margin: 0 auto;
+ padding: 0 1.5rem;
+ }
+
+ .section-title {
+ font-size: 1.75rem;
+ font-weight: 700;
+ text-align: center;
+ margin-bottom: 3rem;
+ color: #e8ddd0;
+ }
+
+ .section-title span {
+ color: #d4a84b;
+ }
+
+ nav {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 100;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.8rem 2rem;
+ background: rgba(26, 20, 16, 0.88);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border-bottom: 1px solid rgba(212, 168, 75, 0.12);
+ }
+
+ nav .logo {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-weight: 700;
+ font-size: 1.1rem;
+ color: #e8ddd0;
+ }
+
+ nav .logo img {
+ width: 28px;
+ height: 28px;
+ filter: brightness(0) invert(1);
+ }
+
+ nav .nav-links {
+ display: flex;
+ gap: 1.5rem;
+ align-items: center;
+ font-size: 0.9rem;
+ }
+
+ nav .nav-links a {
+ color: #9a8a7a;
+ transition: color 0.2s;
+ }
+
+ nav .nav-links a:hover {
+ color: #d4a84b;
+ }
+
+ nav .nav-links .btn-nav {
+ display: inline-block;
+ padding: 0.35rem 1rem;
+ border: 1px solid #d4a84b;
+ border-radius: 20px;
+ color: #d4a84b;
+ font-weight: 600;
+ font-size: 0.85rem;
+ transition:
+ background 0.2s,
+ color 0.2s;
+ }
+
+ nav .nav-links .btn-nav:hover {
+ background: #d4a84b;
+ color: #1a1410;
+ }
+
+ .hero {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 6rem 1.5rem 4rem;
+ position: relative;
+ overflow: hidden;
+ }
+
+ /* subtle glow behind the title — now a warm golden halo */
+ .hero::before {
+ content: "";
+ position: absolute;
+ top: 20%;
+ left: 50%;
+ width: 600px;
+ height: 600px;
+ transform: translate(-50%, -50%);
+ background: radial-gradient(
+ circle,
+ rgba(212, 168, 75, 0.07) 0%,
+ transparent 70%
+ );
+ pointer-events: none;
+ }
+
+ .hero-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ gap: 1.5rem;
+ max-width: 820px;
+ position: relative;
+ z-index: 1;
+ }
+
+ .hero h1 {
+ font-size: 5rem;
+ font-weight: 800;
+ letter-spacing: 2px;
+ color: #e8ddd0;
+ opacity: 0;
+ animation: fadeInDown 0.8s ease 0.2s forwards;
+ line-height: 1.2;
+ }
+
+ .hero .slogan {
+ font-size: 2.2rem;
+ color: #c43931;
+ font-weight: 400;
+ opacity: 0;
+ animation: fadeInDown 0.8s ease 0.3s forwards;
+ min-height: 3rem;
+ }
+
+ .hero .slogan .cursor {
+ display: inline-block;
+ width: 2px;
+ height: 1.2em;
+ background: #c43931;
+ margin-left: 2px;
+ vertical-align: text-bottom;
+ animation: blink 0.8s step-end infinite;
+ }
+
+ @keyframes blink {
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0;
+ }
+ }
+
+ .hero .desc {
+ font-size: 1rem;
+ color: #9a8a7a;
+ max-width: 560px;
+ line-height: 1.6;
+ opacity: 0;
+ animation: fadeInDown 0.8s ease 0.4s forwards;
+ }
+
+ .hero .cta-row {
+ display: flex;
+ gap: 1rem;
+ flex-wrap: wrap;
+ justify-content: center;
+ margin-top: 1rem;
+ opacity: 0;
+ animation: fadeInDown 0.8s ease 0.6s forwards;
+ }
+
+ .btn-primary {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.75rem 2rem;
+ background: #c43931;
+ color: #e8ddd0;
+ font-weight: 700;
+ font-size: 1rem;
+ border-radius: 2px;
+ border: none;
+ cursor: pointer;
+ transition:
+ background 0.25s,
+ transform 0.15s;
+ }
+ .btn-primary:hover {
+ background: #d44a42;
+ color: #e8ddd0;
+ transform: translateY(-2px);
+ }
+
+ .btn-secondary {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.75rem 2rem;
+ background: transparent;
+ color: #d4a84b;
+ font-weight: 600;
+ font-size: 1rem;
+ border-radius: 2px;
+ border: 1px solid #d4a84b;
+ cursor: pointer;
+ transition:
+ background 0.25s,
+ color 0.25s,
+ transform 0.15s;
+ }
+ .btn-secondary:hover {
+ background: rgba(212, 168, 75, 0.1);
+ color: #e8c46a;
+ transform: translateY(-2px);
+ }
+
+ @keyframes fadeInDown {
+ 0% {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ .scroll-indicator {
+ position: absolute;
+ bottom: 2rem;
+ left: 50%;
+ transform: translateX(-50%);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.3rem;
+ color: #6a5a4a;
+ font-size: 0.75rem;
+ opacity: 0;
+ animation: fadeInUp 0.8s ease 1s forwards;
+ }
+
+ @keyframes watermarkIn {
+ 0% {
+ opacity: 0;
+ top: 30%;
+ }
+ 100% {
+ opacity: 0.3;
+ top: 15%;
+ }
+ }
+
+ @keyframes fadeInUp {
+ 0% {
+ opacity: 0;
+ bottom: 0;
+ }
+ 100% {
+ opacity: 1;
+ bottom: 2rem;
+ }
+ }
+
+ .scroll-indicator .arrow {
+ width: 20px;
+ height: 20px;
+ border-right: 2px solid #6a5a4a;
+ border-bottom: 2px solid #6a5a4a;
+ transform: rotate(45deg);
+ animation: bounceArrow 2s ease-in-out infinite;
+ }
+
+ @keyframes bounceArrow {
+ 0%,
+ 100% {
+ transform: rotate(45deg) translateY(0);
+ }
+ 50% {
+ transform: rotate(45deg) translateY(6px);
+ }
+ }
+
+ .code-demo {
+ padding: 5rem 1.5rem;
+ background: #241c16;
+ }
+
+ .code-demo .code-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 3rem;
+ align-items: center;
+ }
+
+ .code-demo .code-text h2 {
+ font-size: 1.75rem;
+ font-weight: 700;
+ color: #e8ddd0;
+ margin-bottom: 1rem;
+ }
+
+ .code-demo .code-text h2 span {
+ color: #c43931;
+ }
+
+ .code-demo .code-text p {
+ color: #9a8a7a;
+ font-size: 1rem;
+ margin-bottom: 1.5rem;
+ }
+
+ .code-demo .code-text .features-list {
+ list-style: none;
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+ }
+
+ .code-demo .code-text .features-list li {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.6rem;
+ color: #c0b0a0;
+ font-size: 0.95rem;
+ }
+
+ .code-demo .code-text .features-list li::before {
+ content: "▸";
+ color: #d4a84b;
+ font-weight: 700;
+ flex-shrink: 0;
+ }
+
+ .code-block {
+ background: #241c16;
+ border: 1px solid #3a2e24;
+ border-radius: 2px;
+ padding: 2rem 1.5rem 1.5rem;
+ overflow-x: auto;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
+ position: relative;
+ }
+
+ .code-block pre {
+ margin: 0;
+ padding: 0;
+ background: transparent;
+ }
+
+ .code-block code {
+ font-family:
+ "Cascadia Code", "Fira Code", "JetBrains Mono", "Consolas",
+ monospace;
+ font-size: 0.85rem;
+ line-height: 1.65;
+ background: transparent !important;
+ padding: 0 !important;
+ }
+
+ .code-block::before {
+ content: "▲ example-basic";
+ position: absolute;
+ top: 0.5rem;
+ right: 1rem;
+ font-size: 0.7rem;
+ color: #6a5a4a;
+ font-family: "Segoe UI", sans-serif;
+ letter-spacing: 0.5px;
+ }
+
+ .features {
+ padding: 5rem 1.5rem;
+ }
+
+ .features-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: 1.5rem;
+ }
+
+ .feature-card {
+ background: #241c16;
+ border: 1px solid #3a2e24;
+ border-radius: 2px;
+ padding: 1.75rem 1.5rem;
+ transition:
+ border-color 0.25s,
+ transform 0.2s;
+ }
+
+ .feature-card:hover {
+ border-color: #c43931;
+ transform: translateY(-4px);
+ }
+
+ .feature-card .icon {
+ font-size: 1.6rem;
+ margin-bottom: 0.75rem;
+ display: block;
+ }
+
+ .feature-card h3 {
+ font-size: 1.1rem;
+ font-weight: 700;
+ color: #e8ddd0;
+ margin-bottom: 0.5rem;
+ }
+
+ .feature-card p {
+ font-size: 0.9rem;
+ color: #9a8a7a;
+ line-height: 1.6;
+ }
+
+ .feature-card a {
+ font-size: 0.85rem;
+ font-weight: 600;
+ }
+
+ .cta-banner {
+ padding: 4rem 1.5rem;
+ text-align: center;
+ background: linear-gradient(
+ 135deg,
+ rgba(212, 168, 75, 0.06),
+ transparent
+ );
+ border-top: 1px solid rgba(212, 168, 75, 0.1);
+ border-bottom: 1px solid rgba(212, 168, 75, 0.1);
+ }
+
+ .cta-banner h2 {
+ font-size: 1.75rem;
+ font-weight: 700;
+ color: #e8ddd0;
+ margin-bottom: 0.75rem;
+ }
+
+ .cta-banner p {
+ color: #9a8a7a;
+ margin-bottom: 1.5rem;
+ font-size: 1.05rem;
+ }
+
+ .cta-banner .cta-row {
+ display: flex;
+ gap: 1rem;
+ justify-content: center;
+ flex-wrap: wrap;
+ }
+
+ .cta-banner code {
+ display: inline-block;
+ background: #241c16;
+ padding: 0.4rem 1rem;
+ border-radius: 8px;
+ font-size: 0.95rem;
+ color: #d4a84b;
+ border: 1px solid #3a2e24;
+ margin-top: 0.5rem;
+ }
+
+ footer {
+ padding: 2rem 1.5rem;
+ text-align: center;
+ color: #6a5a4a;
+ font-size: 0.85rem;
+ border-top: 1px solid #2a1e14;
+ }
+
+ footer a {
+ color: #7a6a5a;
+ }
+
+ footer a:hover {
+ color: #d4a84b;
+ }
+
+ /* ── Ink drop effect ── */
+ .ink-drop {
+ position: fixed;
+ pointer-events: none;
+ border-radius: 50%;
+ background: radial-gradient(
+ circle,
+ rgba(212, 168, 75, 0.15) 0%,
+ rgba(196, 57, 49, 0.06) 50%,
+ transparent 100%
+ );
+ width: 0;
+ height: 0;
+ transform: translate(-50%, -50%);
+ animation: inkSpread 0.9s ease-out forwards;
+ z-index: 9999;
+ }
+
+ @keyframes inkSpread {
+ 0% {
+ width: 0;
+ height: 0;
+ opacity: 1;
+ }
+ 100% {
+ width: 500px;
+ height: 500px;
+ opacity: 0;
+ }
+ }
+
+ @media (max-width: 768px) {
+ nav {
+ padding: 0.6rem 1rem;
+ }
+
+ nav .nav-links {
+ gap: 1rem;
+ font-size: 0.8rem;
+ }
+
+ nav .nav-links .btn-nav {
+ padding: 0.25rem 0.75rem;
+ font-size: 0.75rem;
+ }
+
+ .hero h1 {
+ font-size: 2.2rem;
+ }
+
+ .hero .slogan {
+ font-size: 1.4rem;
+ }
+
+ .hero .desc {
+ font-size: 0.9rem;
+ }
+
+ .code-demo .code-grid {
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ }
+
+ .code-block {
+ font-size: 0.75rem;
+ padding: 1rem;
+ }
+ }
+
+ @media (max-width: 480px) {
+ .hero h1 {
+ font-size: 1.8rem;
+ }
+
+ .hero .cta-row {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .features-grid {
+ grid-template-columns: 1fr;
+ }
+ }
+ </style>
+ </head>
+ <body>
+ <!-- Navigation -->
+ <nav>
+ <a href="#" class="logo" aria-label="Home">
+ <img
+ src="docs/res/icon.png"
+ alt="Mingling icon"
+ width="28"
+ height="28"
+ />
+ Mìng Lìng
+ </a>
+ <div class="nav-links">
+ <a href="docs/doc.html">Docs</a>
+ <a href="docs/examples.html">Examples</a>
+ <a href="https://github.com/catilgrass/mingling" target="_blank"
+ >GitHub</a
+ >
+ <a
+ href="https://crates.io/crates/mingling"
+ target="_blank"
+ class="btn-nav"
+ >cargo add mingling</a
+ >
+ </div>
+ </nav>
+
+ <!-- Hero -->
+ <section class="hero">
+ <div class="hero-content">
+ <img
+ src="docs/res/icon.png"
+ alt=""
+ style="
+ position: absolute;
+ top: 30%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 600px;
+ aspect-ratio: 1 / 1;
+ height: auto;
+ opacity: 0;
+ pointer-events: none;
+ user-select: none;
+ z-index: -1;
+ animation: watermarkIn 2.5s ease-out 2s forwards;
+ "
+ />
+
+ <h1>#[Mìng&nbsp;Lìng]</h1>
+ <p class="slogan" id="typewriter"></p>
+
+ <p class="desc">A <b>proc-macro based</b> Rust CLI framework</p>
+
+ <div class="cta-row">
+ <a href="docs/doc.html" class="btn-primary">
+ 📖 Read The Docs
+ </a>
+ <a
+ href="https://github.com/catilgrass/mingling"
+ target="_blank"
+ class="btn-secondary"
+ >
+ GitHub →
+ </a>
+ </div>
+ </div>
+
+ <div class="scroll-indicator">
+ <span>scroll</span>
+ <div class="arrow"></div>
+ </div>
+ </section>
+
+ <!-- Code Demo -->
+ <section class="code-demo">
+ <div class="container code-grid">
+ <div class="code-text">
+ <h2>
+ Dispatch, Parse<br />
+ Then <span>Render</span>
+ </h2>
+ <p>
+ A proc-macro &amp; type-system CLI framework for
+ building complex command-line programs with many
+ subcommands.
+ </p>
+ <ul class="features-list">
+ <li>
+ Separation of concerns: parsing, logic, rendering
+ </li>
+ <li>
+ Compile-time prefix-tree routing
+ <a
+ href="docs/example-viewer.html?name=example-dispatch-tree"
+ >(optional)</a
+ >
+ </li>
+ <li>
+ Dynamic shell completion out of the box
+ <a
+ href="docs/example-viewer.html?name=example-completion"
+ >(optional)</a
+ >
+ </li>
+ </ul>
+ </div>
+
+ <div class="code-block">
+ <pre><code class="language-rust">
+use mingling::prelude::*;
+
+dispatcher!("greet", CMDGreet => EntryGreet);
+
+fn main() {
+ let mut program = ThisProgram::new();
+ program.with_dispatcher(CMDGreet);
+ program.exec_and_exit();
+}
+
+pack!(ResultGreeting = String);
+
+#[chain]
+fn handle_greet(args: EntryGreet) -> Next {
+ let name =
+ args.pick_or((), "World").unpack();
+ ResultGreeting::new(name)
+}
+
+#[renderer]
+fn render_greeting(greeting: ResultGreeting) {
+ r_println!("Hello, {}!", *greeting);
+}
+
+gen_program!();
+ </code></pre>
+ </div>
+ </div>
+ </section>
+
+ <!-- Features -->
+ <section class="features">
+ <div class="container">
+ <h2 class="section-title">
+ <span>Mìng&nbsp;Lìng</span> — Build Complex CLIs, For You!
+ </h2>
+
+ <div class="features-grid">
+ <div class="feature-card">
+ <span class="icon">🧩</span>
+ <h3>Separation of Concerns</h3>
+ <p>
+ Decouple parsing, business logic, rendering, help
+ text, and completion — each is just a function with
+ the right attribute macro.
+ </p>
+ </div>
+
+ <div class="feature-card">
+ <span class="icon">⚡</span>
+ <h3>Blazing Dispatch</h3>
+ <p>
+ With the <code>dispatch_tree</code> feature, your
+ subcommand structure is hardened into a prefix tree
+ at compile time. O(len) lookup.
+ </p>
+ </div>
+
+ <div class="feature-card">
+ <span class="icon">🔄</span>
+ <h3>Dynamic Completion</h3>
+ <p>
+ Enable <code>comp</code> and get smart,
+ context-aware shell completions for bash, zsh, fish,
+ and pwsh — no manual registration.
+ </p>
+ </div>
+
+ <div class="feature-card">
+ <span class="icon">📦</span>
+ <h3>Lightweight &amp; Modular</h3>
+ <p>
+ Minimal core dependencies. Pull in advanced features
+ (REPL, structured output, Clap binding) only when
+ you need them via feature flags.
+ </p>
+ </div>
+
+ <div class="feature-card">
+ <span class="icon">📤</span>
+ <h3>Structured Output</h3>
+ <p>
+ Add <code>general_renderer</code> and your program
+ gains <code>--json</code> /
+ <code>--yaml</code> flags automatically. Great for
+ scripting and pipe workflows.
+ </p>
+ </div>
+
+ <div class="feature-card">
+ <span class="icon">🔁</span>
+ <h3>REPL Mode</h3>
+ <p>
+ Call <code>program.exec_repl()</code> and your CLI
+ becomes an interactive shell — perfect for debugging
+ and exploration.
+ </p>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- CTA Banner -->
+ <section class="cta-banner">
+ <h2>Ready to command your CLI?</h2>
+ <p>
+ Add Mingling to your project in one line, or dive straight into
+ the docs.
+ </p>
+ <code>cargo add mingling</code>
+ <div class="cta-row" style="margin-top: 1.5rem">
+ <a href="docs/doc.html" class="btn-primary">
+ 📖 Read The Docs
+ </a>
+ <a
+ href="https://github.com/catilgrass/mingling"
+ target="_blank"
+ class="btn-secondary"
+ >
+ GitHub →
+ </a>
+ </div>
+ </section>
+
+ <!-- Footer -->
+ <script src="docs/scripts/highlight/highlight.min.js"></script>
+ <script src="docs/scripts/highlight/rust.min.js"></script>
+ <script>
+ hljs.highlightAll();
+ </script>
+
+ <script>
+ (function () {
+ var text = '"Macro magician in your CLI."';
+ var el = document.getElementById("typewriter");
+ var i = 0;
+ var timer = null;
+
+ function type() {
+ if (i < text.length) {
+ el.innerHTML =
+ text.substring(0, i + 1) +
+ '<span class="cursor"></span>';
+ i++;
+ var delay =
+ text[i - 1] === "." || text[i - 1] === ","
+ ? 200
+ : 55;
+ timer = setTimeout(type, delay);
+ } else {
+ el.innerHTML = text + '<span class="cursor"></span>';
+ }
+ }
+
+ // Start typing after page settles
+ setTimeout(type, 2000);
+ })();
+ </script>
+
+ <script>
+ document.addEventListener("click", function (e) {
+ var drop = document.createElement("div");
+ drop.className = "ink-drop";
+ drop.style.left = e.clientX + "px";
+ drop.style.top = e.clientY + "px";
+ document.body.appendChild(drop);
+ setTimeout(function () {
+ drop.remove();
+ }, 1000);
+ });
+ </script>
+
+ <footer>
+ <p>
+ Built With ❤️ by
+ <a href="https://github.com/Weicao-CatilGrass" target="_blank"
+ >Weicao-CatilGrass</a
+ >
+ &middot; Licensed under
+ <a href="LICENSE-MIT" target="_blank">MIT</a> /
+ <a href="LICENSE-APACHE" target="_blank">Apache-2.0</a>
+ </p>
+ </footer>
+ </body>
+</html>