diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d84f13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/Cargo.lock +.idea/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..6a40671 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "simple-mermaid" +description = "Simple Mermaid diagrams RustDoc integration" +version = "0.1.0" +edition = "2021" +homepage = "https://github.com/glueball/simple-mermaid" +repository = "https://github.com/glueball/simple-mermaid" +keywords = ["documentation", "mermaid", "diagrams"] +license = "MIT" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/README.md b/README.md new file mode 100644 index 0000000..51d994e --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# simple-mermaid + +Simple Mermaid diagrams RustDoc integration + +This crate provides a simple declarative macro to include [mermaid] diagrams in your rustdoc documentation. +Lookup the great [mermaid documentation] for details on the diagram syntax. + +## Usage +1. Create your [mermaid] diagrams in their own files (usually with `.mmd` or `.mermaid` extension). +2. Call the [mermaid!] macro in a `#[doc]` attribute. Specify the route to the diagram file as a + string literal. Note that the path is interpreted relative to the file where the macro is called, + as it happens with the underlying [include_str]. +3. Done! + +# Alternatives +## aquamarine +The [aquamarine] introduces a procedural macro that converts regular code blocks marked with the +[mermaid] language tag. It also allows including the diagram from external files, but that comes with some limitations: +* Only one external diagram can be added to a single doc block. +* The external diagram will always appear at the end of the doc block. + +Those limitations made [aquamarine] a non-option for me, since I strongly prefer leaving the diagrams in external files for several reasons: +clutter, maintainability, IDE support, and, re-usability of the diagrams. + +Besides, the declarative macro used in this crate should be easier on compile times. And it comes with no dependencies at all! + +## rsdoc +The [rsdoc] crate provides procedural macros to embed [PlantUML] and images in doc coments. +It can be used with code-blocks (similar to aquamarine) or with external files (similar to this crate). +So, in this case, for me it was just a matter of personal taste, both [PlantUML] and [mermaid] are fantastic +opensource projects. But PlantUML is Java... and my plants always die (_even a cactus I once had! How can a cactus die? The thing should not need water!_). + +# Disclaimer +Neither this crate nor it's autor have any relation or affiliation with the [mermaid] project, other that being an user of this magnific library. + +All the examples in this documentation have been extracted, verbatim or with minor updates, from the [mermaid documentation]. + +[mermaid]: https://mermaid.js.org/ +[include_str]: https://doc.rust-lang.org/std/macro.include_str.html +[mermaid documentation]: https://mermaid.js.org/intro/n00b-gettingStarted.html +[aquamarine]: https://crates.io/crates/aquamarine +[rsdoc]: https://crates.io/crates/rsdoc +[PlantUML]: https://plantuml.com/ + +License: MIT diff --git a/src/er.mmd b/src/er.mmd new file mode 100644 index 0000000..2919716 --- /dev/null +++ b/src/er.mmd @@ -0,0 +1,13 @@ +erDiagram + CAR ||--o{ NAMED-DRIVER : allows + CAR { + string registrationNumber + string make + string model + } + PERSON ||--o{ NAMED-DRIVER : is + PERSON { + string firstName + string lastName + int age + } \ No newline at end of file diff --git a/src/flowchart.mmd b/src/flowchart.mmd new file mode 100644 index 0000000..5271ddf --- /dev/null +++ b/src/flowchart.mmd @@ -0,0 +1,6 @@ +flowchart TD + A[Start] --> B{Is it?} + B -- Yes --> C[OK] + C --> D[Rethink] + D --> B + B -- No ----> E[End] \ No newline at end of file diff --git a/src/graph.mmd b/src/graph.mmd new file mode 100644 index 0000000..c2c900f --- /dev/null +++ b/src/graph.mmd @@ -0,0 +1,8 @@ +graph TD + A[Enter Chart Definition] --> B(Preview) + B --> C{decide} + C --> D[Keep] + C --> E[Edit Definition] + E --> B + D --> F[Save Image and Code] + F --> B \ No newline at end of file diff --git a/src/larger.mmd b/src/larger.mmd new file mode 100644 index 0000000..7dcb2d4 --- /dev/null +++ b/src/larger.mmd @@ -0,0 +1,28 @@ +sequenceDiagram + participant web as Web Browser + participant blog as Blog Service + participant account as Account Service + participant mail as Mail Service + participant db as Storage + + Note over web,db: The user must be logged in to submit blog posts + web->>+account: Logs in using credentials + account->>db: Query stored accounts + db->>account: Respond with query result + + alt Credentials not found + account->>web: Invalid credentials + else Credentials found + account->>-web: Successfully logged in + + Note over web,db: When the user is authenticated, they can now submit new posts + web->>+blog: Submit new post + blog->>db: Store post data + + par Notifications + blog--)mail: Send mail to blog subscribers + blog--)db: Store in-site notifications + and Response + blog-->>-web: Successfully posted + end + end \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..48ff804 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,147 @@ +//! Simple Mermaid diagrams RustDoc integration +//! +//! This crate provides a simple declarative macro to include [mermaid] diagrams in your rustdoc documentation. +//! Lookup the great [mermaid documentation] for details on the diagram syntax. +//! +//! # Usage +//! 1. Create your [mermaid] diagrams in their own files (usually with `.mmd` or `.mermaid` extension). +//! 2. Call the [mermaid!] macro in a `#[doc]` attribute. Specify the route to the diagram file as a +//! string literal. Note that the path is interpreted relative to the file where the macro is called, +//! as it happens with the underlying [include_str]. +//! 3. Done! +//! +//! Diagrams can be intermixed freely with regular documentation comments. +//! +//! ```rust +//! # use simple_mermaid::mermaid; +//! /// A sequence diagram +//! #[doc = mermaid!("sequence.mmd")] +//! /// +//! /// Then a flowchart +//! #[doc = mermaid!("flowchart.mmd")] +//! /// +//! /// And some more regular text to end this block +//! # fn function() {} +//! ``` +//! Outputs: +//! +//!
+//! A sequence diagram
+#![doc = mermaid!("sequence.mmd")]
+//! Then a flowchart
+#![doc = mermaid!("flowchart.mmd")]
+//! And some more regular text to end this block
+//! 
+//! +//! # Options +//! By default, diagrams will be centered and have a transparent background. This behaviour can be +//! controlled with the following keywords after the path to the [mermaid] file: +//! +//! * **left**, left align the diagram. +//! * **right**, right align the diagram. +//! * **center**, has not effect, but it\"s accepted for completeness. +//! * **framed**, add a gray frame to the diagram. +//! * **transparent**, do not add the gray frame to the diagram. +//! +//! *Left*, *center* and *right* are, of course, mutually exclusive; but either can be combined with *framed*. +//! +//! ```rust +//! # use simple_mermaid::mermaid; +//! #[doc = mermaid!("er.mmd" left)] +//! #[doc = mermaid!("graph.mmd" framed)] +//! #[doc = mermaid!("timeline.mmd" right)] +//! #[doc = mermaid!("larger.mmd" center framed)] +//! # fn function() {} +//! ``` +#![doc = mermaid!("er.mmd" left)] +#![doc = mermaid!("graph.mmd" framed)] +#![doc = mermaid!("timeline.mmd" right)] +#![doc = mermaid!("larger.mmd" center)] +//! +//! # Alternatives +//! ## aquamarine +//! The [aquamarine] introduces a procedural macro that converts regular code blocks marked with the +//! [mermaid] language tag. It also allows including the diagram from external files, but that comes with some limitations: +//! * Only one external diagram can be added to a single doc block. +//! * The external diagram will always appear at the end of the doc block. +//! +//! Those limitations made [aquamarine] a non-option for me, since I strongly prefer leaving the diagrams in external files for several reasons: +//! clutter, maintainability, IDE support, and, re-usability of the diagrams. +//! +//! Besides, the declarative macro used in this crate should be easier on compile times. And it comes with no dependencies at all! +//! +//! ## rsdoc +//! The [rsdoc] crate provides procedural macros to embed [PlantUML] and images in doc coments. +//! It can be used with code-blocks (similar to aquamarine) or with external files (similar to this crate). +//! So, in this case, for me it was just a matter of personal taste, both [PlantUML] and [mermaid] are fantastic +//! opensource projects. But PlantUML is Java... and my plants always die (_even a cactus I once had! How can a cactus die? The thing should not need water!_). +//! +//! # Disclaimer +//! Neither this crate nor it's autor have any relation or affiliation with the [mermaid] project, other that being an user of this magnific library. +//! +//! All the examples in this documentation have been extracted, verbatim or with minor updates, from the [mermaid documentation]. +//! +//! [mermaid]: https://mermaid.js.org/ +//! [include_str]: https://doc.rust-lang.org/std/macro.include_str.html +//! [mermaid documentation]: https://mermaid.js.org/intro/n00b-gettingStarted.html +//! [aquamarine]: https://crates.io/crates/aquamarine +//! [rsdoc]: https://crates.io/crates/rsdoc +//! [PlantUML]: https://plantuml.com/ + +/// Include a mermaid diagram in the documentation. +/// +/// This macro is meant to be used as argument of the `#[doc]` attribute. +/// +/// ```rust +/// # use simple_mermaid::mermaid; +/// /// Some documentation about a function +/// /// Then include a diagram: +/// #[doc = mermaid!("netflix.mmd")] +/// fn a_function() {} +/// ``` +/// +/// This would produce: +/// +/// > Some documentation +/// > +/// > Then include a diagram: +#[doc = mermaid!("netflix.mmd" framed)] +/// +/// Look at the crate level documentation for all the options. +#[macro_export] +macro_rules! mermaid { + ($file:literal) => { $crate::_mermaid_inner!($file center transparent) }; + ($file:literal left framed) => { $crate::_mermaid_inner!($file left framed) }; + ($file:literal framed left) => { $crate::_mermaid_inner!($file left framed) }; + ($file:literal center framed) => { $crate::_mermaid_inner!($file center framed) }; + ($file:literal framed center) => { $crate::_mermaid_inner!($file center framed) }; + ($file:literal right framed) => { $crate::_mermaid_inner!($file right framed) }; + ($file:literal framed right) => { $crate::_mermaid_inner!($file right framed) }; + ($file:literal framed) => { $crate::_mermaid_inner!($file center framed) }; + ($file:literal left) => { $crate::_mermaid_inner!($file left transparent) }; + ($file:literal right) => { $crate::_mermaid_inner!($file right transparent) }; + ($file:literal center) => { $crate::_mermaid_inner!($file center transparent) }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! _mermaid_inner { + ($file:literal $pos:ident $style:ident) => + { + concat!("
\n",
+                    include_str!($file), "\n",
+                "
", + "") + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! _mermaid_background { + (framed) => { "" }; + (transparent) => { "background: transparent;" }; +} \ No newline at end of file diff --git a/src/netflix.mmd b/src/netflix.mmd new file mode 100644 index 0000000..61c7d4f --- /dev/null +++ b/src/netflix.mmd @@ -0,0 +1,3 @@ +pie title NETFLIX + "Time spent in menu" : 90 + "Time watching content" : 10 \ No newline at end of file diff --git a/src/sequence.mmd b/src/sequence.mmd new file mode 100644 index 0000000..87d4075 --- /dev/null +++ b/src/sequence.mmd @@ -0,0 +1,11 @@ +sequenceDiagram + Alice->>Bob: Hello Bob, how are you ? + Bob->>Alice: Fine, thank you. And you? + create participant Carl + Alice->>Carl: Hi Carl! + create actor D as Donald + Carl->>D: Hi! + destroy Carl + Alice-xCarl: We are too many + destroy Bob + Bob->>Alice: I agree \ No newline at end of file diff --git a/src/timeline.mmd b/src/timeline.mmd new file mode 100644 index 0000000..8dd1e30 --- /dev/null +++ b/src/timeline.mmd @@ -0,0 +1,9 @@ +timeline + title Timeline of Industrial Revolution + section 17th-20th century + Industry 1.0 : Machinery, Water power, Steam
power + Industry 2.0 : Electricity, Internal combustion engine, Mass production + Industry 3.0 : Electronics, Computers, Automation + section 21st century + Industry 4.0 : Internet, Robotics, Internet of Things + Industry 5.0 : Artificial intelligence, Big data,3D printing \ No newline at end of file