Skip to content

Commit

Permalink
First version
Browse files Browse the repository at this point in the history
  • Loading branch information
glueball committed Sep 24, 2023
1 parent 92d3301 commit f4b1d77
Show file tree
Hide file tree
Showing 11 changed files with 286 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
/Cargo.lock
.idea/
13 changes: 13 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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]
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions src/er.mmd
Original file line number Diff line number Diff line change
@@ -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
}
6 changes: 6 additions & 0 deletions src/flowchart.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
flowchart TD
A[Start] --> B{Is it?}
B -- Yes --> C[OK]
C --> D[Rethink]
D --> B
B -- No ----> E[End]
8 changes: 8 additions & 0 deletions src/graph.mmd
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions src/larger.mmd
Original file line number Diff line number Diff line change
@@ -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
147 changes: 147 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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:
//!
//! <pre>
//! A sequence diagram
#![doc = mermaid!("sequence.mmd")]
//! Then a flowchart
#![doc = mermaid!("flowchart.mmd")]
//! And some more regular text to end this block
//! </pre>
//!
//! # 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!("<pre class=\"mermaid\" style=\"text-align:", stringify!($pos), ";", $crate::_mermaid_background!($style), "\">\n",
include_str!($file), "\n",
"</pre>",
"<script type=\"module\">",
"import mermaid from \"https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs\";",
"var doc_theme = localStorage.getItem(\"rustdoc-theme\");",
"if (doc_theme === \"dark\" || doc_theme === \"ayu\") mermaid.initialize({theme: \"dark\"});",
"</script>")
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! _mermaid_background {
(framed) => { "" };
(transparent) => { "background: transparent;" };
}
3 changes: 3 additions & 0 deletions src/netflix.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pie title NETFLIX
"Time spent in menu" : 90
"Time watching content" : 10
11 changes: 11 additions & 0 deletions src/sequence.mmd
Original file line number Diff line number Diff line change
@@ -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
9 changes: 9 additions & 0 deletions src/timeline.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
timeline
title Timeline of Industrial Revolution
section 17th-20th century
Industry 1.0 : Machinery, Water power, Steam <br>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

0 comments on commit f4b1d77

Please sign in to comment.