Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for text contained in shapes #25

Merged
merged 6 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Excalidraw Converter
**A command line tool for porting Excalidraw diagrams to Gliffy.**
**A command line tool for porting Excalidraw diagrams to Gliffy.**

[Excalidraw](https://excalidraw.com/) is great for sketching diagrams as part of a design process, but chances are that you have to redo those sketches for documentation. This tool is made to bridge those tasks.

Expand All @@ -9,8 +9,8 @@ Excalidraw Converter ports Excalidraw diagrams to a Gliffy compatible format, wh

## Getting started

### Installation
#### MacOS with [Homebrew](https://brew.sh/)
### Installation
#### MacOS with [Homebrew](https://brew.sh/)
```shell
brew install sindrel/tap/excalidraw-converter
```
Expand All @@ -20,14 +20,14 @@ Download a compatible binary from the [Releases](https://github.com/sindrel/exca

If you're a Linux or MacOS user, move it to your local bin folder to make it available in your environment (optional).

### How to convert diagrams
### How to convert diagrams
First save your Excalidraw diagram to a file.

Then, to do a conversion, simply execute the binary by specifying the `gliffy` command, the path to your Excalidraw save file, and the path to where you want your converted file to be saved.
Then, to do a conversion, simply execute the binary by specifying the `gliffy` command, the path to your Excalidraw save file, and the path to where you want your converted file to be saved.

<details>
<summary>MacOS example</summary>

```
$ exconv gliffy -i ~/Downloads/my-diagram.excalidraw -o /tmp/my-ported-diagram.gliffy
Parsing input file: ~/Downloads/my-diagram.excalidraw
Expand All @@ -48,7 +48,7 @@ Then, to do a conversion, simply execute the binary by specifying the `gliffy` c

<details>
<summary>Linux example</summary>

```
$ ./exconv gliffy -i ~/Downloads/my-diagram.excalidraw -o /tmp/my-ported-diagram.gliffy
Parsing input file: ~/Downloads/my-diagram.excalidraw
Expand All @@ -69,7 +69,7 @@ Then, to do a conversion, simply execute the binary by specifying the `gliffy` c

<details>
<summary>Windows example</summary>

```
C:\> exconv.exe gliffy -i C:\Downloads\my-diagram.excalidraw -o C:\tmp\my-ported-diagram.gliffy
Parsing input file: C:\Downloads\my-diagram.excalidraw
Expand All @@ -92,7 +92,7 @@ Then, to do a conversion, simply execute the binary by specifying the `gliffy` c

After converting your diagram(s), import them into Gliffy using the standard Import dialog.

## Commands
## Commands
```sh
Available Commands:
completion Generate the autocompletion script for the specified shell
Expand All @@ -104,58 +104,56 @@ Flags:
-h, --help help for exconv
```

## Features
## Features

All fixed shapes and most styling and text options are supported.

### Shapes
### Shapes
* Rectangle
* Rounded rectangle
* Diamond
* Ellipse
* Arrow
* Line

### Text

### Text
* Font family (Normal and Code)
* Font size
* Font color
* Horizontal alignment
* Text contained in shapes

### Styling

* Canvas background color
### Styling
* Canvas background color
* Fill color
* Fill style (hachure and cross-hatch translate to gradients)
* Fill style (hachure and cross-hatch translate to gradients)
* Stroke color
* Stroke width
* Opacity

Free hand drawings and library graphics are currently not supported.

## Contributing

See something you'd like to improve? Feel free to add a pull request. If it's a major change, it's probably best to describe it in an [issue](https://github.com/sindrel/excalidraw-converter/issues/new) first.

## Development
<details>
<summary>Instructions</summary>

### Prerequisites:
* Go (see version in `go.mod`)
### Prerequisites:
* Go (see version in `go.mod`)

### Download dependencies
### Download dependencies
```shell
go mod download
```

### Run tests
### Run tests
```shell
go test -v ./cmd
```

### Compile and run
### Compile and run
```shell
go run ./cmd/main.go <command> <input> <output>
```
Expand Down
156 changes: 105 additions & 51 deletions internal/conversion/gliffy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
internal "diagram-converter/internal"
datastr "diagram-converter/internal/datastructures"
"encoding/json"
"errors"
"fmt"
"os"
"strconv"
Expand Down Expand Up @@ -31,10 +32,87 @@ func ConvertExcalidrawToGliffy(importPath string, exportPath string) error {

var output datastr.GliffyScene
var objects []datastr.GliffyObject
objectIDs := map[string]int{}

objects, objectIDs, err = AddElements(false, input, objects, objectIDs)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to add element(s): %s\n", err)
os.Exit(1)
}

objects, _, err = AddElements(true, input, objects, objectIDs)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to add element(s) with parent(s): %s\n", err)
os.Exit(1)
}

priorityGraphics := []string{
//"Line",
//"Text",
}

objects = OrderGliffyObjectsByPriority(objects, priorityGraphics)

var layer datastr.GliffyLayer
layer.Active = true
layer.GUID = "dR5PnMr9lIuu"
layer.Name = "Layer 0"
layer.NodeIndex = 11
layer.Visible = true

output.ContentType = "application/gliffy+json"
output.EmbeddedResources.Resources = []string{}
output.Version = "1.3"
output.Metadata.LastSerialized = timestamp
output.Metadata.Libraries = []string{
"com.gliffy.libraries.basic.basic_v1.default",
"com.gliffy.libraries.flowchart.flowchart_v1.default",
}
output.Metadata.LoadPosition = "default"
output.Metadata.Revision = 0
output.Metadata.Title = "Import"
output.Stage.Background = input.AppState.ViewBackgroundColor
output.Stage.DrawingGuidesOn = true
output.Stage.GridOn = true
output.Stage.Height = 1024
output.Stage.Layers = append(output.Stage.Layers, layer)
output.Stage.MaxWidth = 5000
output.Stage.MaxHeight = 5000
output.Stage.Objects = objects
output.Stage.PrintModel.PageSize = "Letter"
output.Stage.PrintModel.Portrait = true
output.Stage.SnapToGrid = true
output.Stage.ViewportType = "default"
output.Stage.Width = 1024

outputJson, err := json.Marshal(output)
if err != nil {
fmt.Fprintf(os.Stderr, "Error occured during JSON marshaling: %s", err)
os.Exit(1)
}

err = internal.WriteToFile(exportPath, string(outputJson))
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to write diagram to file: %s", err)
os.Exit(1)
}

fmt.Printf("Converted diagram saved to file: %s\n", exportPath)

return nil
}

func AddElements(addChildren bool, input datastr.ExcalidrawScene, objects []datastr.GliffyObject, objectIDs map[string]int) ([]datastr.GliffyObject, map[string]int, error) {
graphics := internal.MapGraphics()

for i, element := range input.Elements {
if len(element.ContainerId) > 0 && !addChildren {
continue
}
if len(element.ContainerId) == 0 && addChildren {
continue
}

var object datastr.GliffyObject
var shape datastr.GliffyShape
var text datastr.GliffyText
Expand Down Expand Up @@ -144,66 +222,42 @@ func ConvertExcalidrawToGliffy(importPath string, exportPath string) error {
continue
}

fmt.Printf(" Adding object: %s\n", object.UID)

object.ID = i
objects = append(objects, object)
}
objectIDs[element.ID] = object.ID

priorityGraphics := []string{
//"Line",
//"Text",
}
fmt.Printf(" Adding object: %s (%s,%d,%d)\n", object.UID, element.ID, object.ID, object.Order)

objects = OrderGliffyObjectsByPriority(objects, priorityGraphics)
if len(element.ContainerId) > 0 {
var parent int = 999999
for obj_k, obj := range objects {
if obj.ID == objectIDs[element.ContainerId] {
parent = obj_k
}
}

var layer datastr.GliffyLayer
layer.Active = true
layer.GUID = "dR5PnMr9lIuu"
layer.Name = "Layer 0"
layer.NodeIndex = 11
layer.Visible = true
if parent == 999999 {
return nil, nil, errors.New("unable to find object parent")
}

output.ContentType = "application/gliffy+json"
output.EmbeddedResources.Resources = []string{}
output.Version = "1.3"
output.Metadata.LastSerialized = timestamp
output.Metadata.Libraries = []string{
"com.gliffy.libraries.basic.basic_v1.default",
"com.gliffy.libraries.flowchart.flowchart_v1.default",
}
output.Metadata.LoadPosition = "default"
output.Metadata.Revision = 0
output.Metadata.Title = "Import"
output.Stage.Background = input.AppState.ViewBackgroundColor
output.Stage.DrawingGuidesOn = true
output.Stage.GridOn = true
output.Stage.Height = 1024
output.Stage.Layers = append(output.Stage.Layers, layer)
output.Stage.MaxWidth = 5000
output.Stage.MaxHeight = 5000
output.Stage.Objects = objects
output.Stage.PrintModel.PageSize = "Letter"
output.Stage.PrintModel.Portrait = true
output.Stage.SnapToGrid = true
output.Stage.ViewportType = "default"
output.Stage.Width = 1024
object.X = 2
object.Y = 0
object.Rotation = 0
object.UID = ""
object.Width = objects[parent].Width - 4
object.Height = objects[parent].Height - 4

outputJson, err := json.Marshal(output)
if err != nil {
fmt.Fprintf(os.Stderr, "Error occured during JSON marshaling: %s", err)
os.Exit(1)
}
fmt.Printf(" - Adding as child of %d\n", parent)

err = internal.WriteToFile(exportPath, string(outputJson))
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to write diagram to file: %s", err)
os.Exit(1)
}
children := append(objects[parent].Children, object)
objects[parent].Children = children

fmt.Printf("Converted diagram saved to file: %s\n", exportPath)
continue
}

return nil
objects = append(objects, object)
}

return objects, objectIDs, nil
}

func StrokeStyleConvExcGliffy(style string) string {
Expand Down
1 change: 1 addition & 0 deletions internal/datastructures/excalidraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type ExcalidrawScene struct {
BackgroundColor string `json:"backgroundColor"`
Baseline float64 `json:"baseline"`
BoundElementIds []string `json:"boundElementIds"`
ContainerId string `json:"containerId"`
EndArrowhead string `json:"endArrowhead"`
FillStyle string `json:"fillStyle"`
FontFamily int64 `json:"fontFamily"`
Expand Down
2 changes: 1 addition & 1 deletion internal/datastructures/gliffy.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type GliffyScene struct {
}

type GliffyObject struct {
Children interface{} `json:"children"`
Children []GliffyObject `json:"children"`
Graphic struct {
Shape *GliffyShape `json:",omitempty"`
Text *GliffyText `json:",omitempty"`
Expand Down
Loading