Skip to content

Commit

Permalink
Introduce mermaid entity relationship diagram
Browse files Browse the repository at this point in the history
  • Loading branch information
nao1215 committed May 5, 2024
1 parent 9405b5a commit 4a0f152
Show file tree
Hide file tree
Showing 11 changed files with 845 additions and 2 deletions.
179 changes: 178 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# What is markdown package
The Package markdown is a simple markdown builder in golang. The markdown package assembles Markdown using method chaining, not uses a template engine like [html/template](https://pkg.go.dev/html/template). The syntax of Markdown follows **GitHub Markdown**.

The markdown package was initially developed to save test results in [nao1215/spectest](https://github.com/nao1215/spectest). Therefore, the markdown package implements the features required by spectest. For example, the markdown package supports **mermaid sequence diagrams**, which was a necessary feature in spectest.
The markdown package was initially developed to save test results in [nao1215/spectest](https://github.com/nao1215/spectest). Therefore, the markdown package implements the features required by spectest. For example, the markdown package supports **mermaid sequence diagrams (entity relationship diagram, sequence diagram, pie chart)**, which was a necessary feature in spectest.

Additionally, complex code that increases the complexity of the library, such as generating nested lists, will not be added. I want to keep this library as simple as possible.

Expand All @@ -33,6 +33,7 @@ Additionally, complex code that increases the complexity of the library, such as
- [x] Details
- [x] Alerts; NOTE, TIP, IMPORTANT, CAUTION, WARNING
- [x] mermaid sequence diagram
- [x] mermaid entity relationship diagram
- [x] mermaid pie chart

### Features not in Markdown syntax
Expand Down Expand Up @@ -411,6 +412,182 @@ pie showData
"C" : 30
```

### Entity Relationship Diagram syntax

```go
package main

import (
"os"

"github.com/nao1215/markdown"
"github.com/nao1215/markdown/mermaid/er"
)

//go:generate go run main.go

func main() {
f, err := os.Create("generated.md")
if err != nil {
panic(err)
}

teachers := er.NewEntity(
"teachers",
[]*er.Attribute{
{
Type: "int",
Name: "id",
IsPrimaryKey: true,
IsForeignKey: false,
IsUniqueKey: true,
Comment: "Teacher ID",
},
{
Type: "string",
Name: "name",
IsPrimaryKey: false,
IsForeignKey: false,
IsUniqueKey: false,
Comment: "Teacher Name",
},
},
)
students := er.NewEntity(
"students",
[]*er.Attribute{
{
Type: "int",
Name: "id",
IsPrimaryKey: true,
IsForeignKey: false,
IsUniqueKey: true,
Comment: "Student ID",
},
{
Type: "string",
Name: "name",
IsPrimaryKey: false,
IsForeignKey: false,
IsUniqueKey: false,
Comment: "Student Name",
},
{
Type: "int",
Name: "teacher_id",
IsPrimaryKey: false,
IsForeignKey: true,
IsUniqueKey: true,
Comment: "Teacher ID",
},
},
)
schools := er.NewEntity(
"schools",
[]*er.Attribute{
{
Type: "int",
Name: "id",
IsPrimaryKey: true,
IsForeignKey: false,
IsUniqueKey: true,
Comment: "School ID",
},
{
Type: "string",
Name: "name",
IsPrimaryKey: false,
IsForeignKey: false,
IsUniqueKey: false,
Comment: "School Name",
},
{
Type: "int",
Name: "teacher_id",
IsPrimaryKey: false,
IsForeignKey: true,
IsUniqueKey: true,
Comment: "Teacher ID",
},
},
)

erString := er.NewDiagram(f).
Relationship(
teachers,
students,
er.ExactlyOneRelationship, // "||"
er.ZeroToMoreRelationship, // "}o"
er.Identifying, // "--"
"Teacher has many students",
).
Relationship(
teachers,
schools,
er.OneToMoreRelationship, // "|}"
er.ExactlyOneRelationship, // "||"
er.NonIdentifying, // ".."
"School has many teachers",
).
String()

err = markdown.NewMarkdown(f).
H2("Entity Relationship Diagram").
CodeBlocks(markdown.SyntaxHighlightMermaid, erString).
Build()

if err != nil {
panic(err)
}
}
```

Plain text output: [markdown is here](./doc/er/generated.md)
````
## Entity Relationship Diagram
```mermaid
erDiagram
teachers ||--o{ students : "Teacher has many students"
teachers }|..|| schools : "School has many teachers"
schools {
int id PK,UK "School ID"
string name "School Name"
int teacher_id FK,UK "Teacher ID"
}
students {
int id PK,UK "Student ID"
string name "Student Name"
int teacher_id FK,UK "Teacher ID"
}
teachers {
int id PK,UK "Teacher ID"
string name "Teacher Name"
}
```
````

Mermaid output:
```mermaid
erDiagram
teachers ||--o{ students : "Teacher has many students"
teachers }|..|| schools : "School has many teachers"
schools {
int id PK,UK "School ID"
string name "School Name"
int teacher_id FK,UK "Teacher ID"
}
students {
int id PK,UK "Student ID"
string name "Student Name"
int teacher_id FK,UK "Teacher ID"
}
teachers {
int id PK,UK "Teacher ID"
string name "Teacher Name"
}
```

## Creating an index for a directory full of markdown files
The markdown package can create an index for Markdown files within the specified directory. This feature was added to generate indexes for Markdown documents produced by [nao1215/spectest](https://github.com/nao1215/spectest).

Expand Down
21 changes: 21 additions & 0 deletions doc/er/generated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## Entity Relationship Diagram
```mermaid
erDiagram
teachers ||--o{ students : "Teacher has many students"
teachers }|..|| schools : "School has many teachers"
schools {
int id PK,UK "School ID"
string name "School Name"
int teacher_id FK,UK "Teacher ID"
}
students {
int id PK,UK "Student ID"
string name "Student Name"
int teacher_id FK,UK "Teacher ID"
}
teachers {
int id PK,UK "Teacher ID"
string name "Teacher Name"
}
```
128 changes: 128 additions & 0 deletions doc/er/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//go:build linux || darwin

// Package main is generating entity relationship diagram.
package main

import (
"os"

"github.com/nao1215/markdown"
"github.com/nao1215/markdown/mermaid/er"
)

//go:generate go run main.go

func main() {
f, err := os.Create("generated.md")
if err != nil {
panic(err)
}

teachers := er.NewEntity(
"teachers",
[]*er.Attribute{
{
Type: "int",
Name: "id",
IsPrimaryKey: true,
IsForeignKey: false,
IsUniqueKey: true,
Comment: "Teacher ID",
},
{
Type: "string",
Name: "name",
IsPrimaryKey: false,
IsForeignKey: false,
IsUniqueKey: false,
Comment: "Teacher Name",
},
},
)
students := er.NewEntity(
"students",
[]*er.Attribute{
{
Type: "int",
Name: "id",
IsPrimaryKey: true,
IsForeignKey: false,
IsUniqueKey: true,
Comment: "Student ID",
},
{
Type: "string",
Name: "name",
IsPrimaryKey: false,
IsForeignKey: false,
IsUniqueKey: false,
Comment: "Student Name",
},
{
Type: "int",
Name: "teacher_id",
IsPrimaryKey: false,
IsForeignKey: true,
IsUniqueKey: true,
Comment: "Teacher ID",
},
},
)
schools := er.NewEntity(
"schools",
[]*er.Attribute{
{
Type: "int",
Name: "id",
IsPrimaryKey: true,
IsForeignKey: false,
IsUniqueKey: true,
Comment: "School ID",
},
{
Type: "string",
Name: "name",
IsPrimaryKey: false,
IsForeignKey: false,
IsUniqueKey: false,
Comment: "School Name",
},
{
Type: "int",
Name: "teacher_id",
IsPrimaryKey: false,
IsForeignKey: true,
IsUniqueKey: true,
Comment: "Teacher ID",
},
},
)

erString := er.NewDiagram(f).
Relationship(
teachers,
students,
er.ExactlyOneRelationship, // "||"
er.ZeroToMoreRelationship, // "}o"
er.Identifying, // "--"
"Teacher has many students",
).
Relationship(
teachers,
schools,
er.OneToMoreRelationship, // "|}"
er.ExactlyOneRelationship, // "||"
er.NonIdentifying, // ".."
"School has many teachers",
).
String()

err = markdown.NewMarkdown(f).
H2("Entity Relationship Diagram").
CodeBlocks(markdown.SyntaxHighlightMermaid, erString).
Build()

if err != nil {
panic(err)
}
}
2 changes: 1 addition & 1 deletion doc/piechart/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build linux || darwin

// Package main is generating mermaid sequence diagram.
// Package main is generating pie chart.
package main

import (
Expand Down
12 changes: 12 additions & 0 deletions mermaid/er/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package er

// config is the configuration for the entity relationship diagram.
type config struct{}

// newConfig returns a new config.
func newConfig() *config {
return &config{}
}

// Option sets the options for the PieChart struct.
type Option func(*config)
Loading

0 comments on commit 4a0f152

Please sign in to comment.