strune 0.1.0

A simple, directional knowledge structure library for building linked references and word books
Documentation
# Strune

A simple, directional knowledge structure library for building linked references and word books.

more about: https://project-starlivia.github.io/Strune/

## Features

- **Core Data Structure**: Generic `Node<T>` with label, description, dependencies, and customizable options
- **Markdown & JSON Loaders**: Parse knowledge nodes from Markdown or JSON files
- **Graph Operations**: Calculate reverse dependencies (dependents) and slug mappings
- **Static Site Generation**: Render knowledge graphs to HTML using Tera templates
- **Type-Safe**: Leverages Rust's type system with generic options support

## Installation

Add Strune to your `Cargo.toml`:

```toml
[dependencies]
strune = "0.1.0"
```

## Quick Start

Loading Nodes from Markdown
```rust
// define custom options
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub struct MyOpts<T>
{
    #[serde(flatten)]
    pub base: T,
    #[serde(default)]
    pub slug: Option<String>,
    #[serde(default)]
    pub dependents: Option<Vec<String>>,
}

impl_maybe_slug!(MyOpts);
impl_maybe_dependents!(MyOpts);

fn main() -> Result<()> {
    // Load nodes from Markdown file
    let base_path = Path::new(env!("CARGO_MANIFEST_DIR"));
    let nodes: Vec<Node<MyOpts<Value>>> = load_nodes_from_markdown(base_path.join("content/sample.md"))?;

    // Calculate dependents
    let nodes = fill_dependents(nodes);

    println!("nodes: {}", nodes.len());

    // Clear dist directory
    let dist_path = base_path.join("dist");
    if dist_path.exists() {
        fs::remove_dir_all(&dist_path)?;
    }
    fs::create_dir_all(&dist_path)?;

    // Render static site
    render(
        "strune/templates/**/*.html",
        &dist_path,
        "/projects/Strune/sample/dist/",
        nodes.as_slice(),
    )
    .map_err(|e| {
        eprintln!("render error: {:?}", e);
        e
    })?;

    // Copy public directory to dist/public
    let public_path = base_path.join("public");
    if public_path.exists() {
        let dist_public = dist_path.join("public");
        copy_dir_all(public_path, &dist_public)?;
        println!("Copied public directory to dist/public");
    }

    Ok(())
}
```

## Markdown Syntax

Strune uses an extended Markdown syntax for defining knowledge nodes:

```markdown
# NodeLabel
## description
A short explanation of this concept.

## dependencies
- ParentConcept1
- ParentConcept2

## options
Additional metadata as needed
```

All fields except the label (h1) are optional.

## Core Concepts

### Node Structure

```rust
pub struct Node<T = Value> {
    pub label: String,           // Node identifier
    pub description: String,     // Explanation text
    pub dependencies: Vec<String>, // Parent concepts
    pub options: T,              // Custom metadata
}
```

### Dependencies

Dependencies represent directional relationships. A node's dependencies are concepts that compose or contain it:

- `Unity` → depends on `GameEngine`
- `Blender``FBX` (mutual dependencies)

## Sample

See the [sample directory](https://github.com/your-username/Strune/tree/main/sample) for complete usage examples.

https://project-starlivia.github.io/Strune/

## License

MIT License - see [LICENSE](../LICENSE) for details.