coursemap/
lib.rs

1//! Course Map - A tool to visualize course dependencies from Quarto/Markdown documents
2//!
3//! This library provides functionality to parse Quarto/Markdown documents and generate
4//! visual dependency graphs showing the relationships between courses. It's designed to
5//! help educators and course designers understand and visualize curriculum structures.
6//!
7//! ## Multi-Language Support
8//!
9//! This Rust library serves as the core for bindings in multiple languages:
10//! - 🦀 **Rust**: Core library and command-line tool
11//! - 🐍 **Python**: `pip install coursemap` - Object-oriented API with `CourseMap.show()` and `CourseMap.save()`
12//! - 📊 **R**: `install.packages("coursemap")` - R package with Quarto integration
13//!
14//! ## Rust API Example
15//!
16//! ```rust,no_run
17//! use coursemap::{Config, App};
18//!
19//! // Load configuration
20//! let config = Config::load_default().unwrap();
21//!
22//! // Create app instance
23//! let app = App::new(config);
24//!
25//! // Generate course map
26//! app.run("./courses", "course_map.svg", "svg").unwrap();
27//! ```
28//!
29//! ## Python API (Recommended)
30//!
31//! ```python
32//! import coursemap
33//!
34//! # Quick display (like matplotlib.pyplot.show())
35//! coursemap.show("./courses")
36//!
37//! # Object-oriented approach (recommended)
38//! cm = coursemap.CourseMap("./courses")
39//! cm.show()  # Display inline in Jupyter/Quarto
40//! cm.save("course_map.svg")  # Save to file
41//! ```
42//!
43//! ## R API
44//!
45//! ```r
46//! library(coursemap)
47//!
48//! # Object-oriented approach (recommended)
49//! cm <- coursemap("./courses")
50//! plot(cm)  # Display in RStudio/knitr
51//! write_map(cm, "course_map.svg")  # Save to file
52//! ```
53//!
54//! ## Document Format
55//!
56//! Course documents should include frontmatter with course metadata:
57//!
58//! ```yaml
59//! ---
60//! title: "Introduction to Economics"
61//! course-map:
62//!   id: intro
63//!   phase: Pre
64//!   prerequisites: []
65//! ---
66//! ```
67
68pub mod cli;
69pub mod config;
70pub mod graph;
71pub mod parser;
72pub mod renderer;
73
74pub use anyhow::{Error, Result};
75pub use config::Config;
76
77/// The main application structure
78pub struct App {
79    pub config: config::Config,
80}
81
82impl App {
83    /// Create a new App instance with the given configuration
84    pub fn new(config: config::Config) -> Self {
85        Self { config }
86    }
87
88    /// Run the course map generation process
89    pub fn run(&self, input_dir: &str, output_path: &str, format: &str) -> Result<()> {
90        // Parse all documents in the input directory
91        let documents = parser::parse_directory(input_dir, &self.config)?;
92
93        // Build the dependency graph
94        let graph = graph::build_graph(documents)?;
95
96        // Render the graph to the specified format
97        renderer::render_graph(&graph, output_path, format, &self.config)?;
98
99        Ok(())
100    }
101
102    /// Generate DOT content as a string (for R/Python bindings)
103    pub fn generate_dot_string(&self, input_dir: &str) -> Result<String> {
104        // Parse all documents in the input directory
105        let documents = parser::parse_directory(input_dir, &self.config)?;
106
107        // Build the dependency graph
108        let graph = graph::build_graph(documents)?;
109
110        // Generate DOT content
111        renderer::generate_dot_content(&graph, &self.config)
112    }
113}