Skip to content

Commit

Permalink
* Added "als PDF exportieren" command.
Browse files Browse the repository at this point in the history
* Improved plantuml rendering speed by > 5x by using a concurrent preflight rendering step.
* Added in-depth uml rendering (if it makes sense) and added a switch button to toggle
  • Loading branch information
torbenschinke committed Sep 20, 2023
1 parent 9e5d2bc commit be031c0
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 42 deletions.
17 changes: 15 additions & 2 deletions compiler/html/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"embed"
"github.com/worldiety/dddl/linter"
"github.com/worldiety/dddl/parser"
"github.com/worldiety/dddl/plantuml"
"github.com/worldiety/dddl/resolver"
"github.com/worldiety/hg"
"log"
"net/http"
"net/http/httptest"
"os"
Expand All @@ -28,10 +30,21 @@ func init() {

func RenderViewHtml(ws *parser.Workspace, model PreviewModel) string {
rslv := resolver.NewResolver(ws)
model.Doc = transform(rslv, model)
preflight := &plantuml.PreflightContext{}
model.Doc = transform(preflight, rslv, model)
model.ProjectPlan = newProjectPlan(preflight, rslv, model)
if preflight.RequiresRendering() {
if err := preflight.Render(); err != nil {
log.Println(err)
}

// once more, we are now complete
model.Doc = transform(preflight, rslv, model)
model.ProjectPlan = newProjectPlan(preflight, rslv, model)
}

lintHints := linter.Lint(rslv)
model = transformLintHints(rslv, lintHints, model)
model.ProjectPlan = newProjectPlan(rslv, model)

w := httptest.NewRecorder()

Expand Down
1 change: 1 addition & 0 deletions compiler/html/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ type Type struct {
Ref string
Definition template.HTML
SVG template.HTML
SVGExtended template.HTML
Usages []Usage
WorkPackageName string
WorkPackageRequires []string
Expand Down
15 changes: 8 additions & 7 deletions compiler/html/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ package html

import (
"github.com/worldiety/dddl/parser"
"github.com/worldiety/dddl/plantuml"
"github.com/worldiety/dddl/resolver"
)

func transform(rslv *resolver.Resolver, model PreviewModel) *Doc {
func transform(pctx *plantuml.PreflightContext, rslv *resolver.Resolver, model PreviewModel) *Doc {

doc := &Doc{}
for _, rCtx := range rslv.Contexts() {
ctx := &Context{Name: rCtx.Name}
ctx.ShortDef = markdown(rCtx.ShortString(), model)
ctx.Ref = resolver.NewQualifiedNameFromNamedType(rCtx.Fragments[0]).String()
ctx.Aggregates = append(ctx.Aggregates, newTypesFromAggregate(ctx, rslv, model, resolver.CollectFromContext[*parser.Aggregate](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromRecords(ctx, rslv, model, resolver.CollectFromContext[*parser.Struct](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromChoice(ctx, rslv, model, resolver.CollectFromContext[*parser.Choice](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromTypes(ctx, rslv, model, resolver.CollectFromContext[*parser.Type](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromAlias(ctx, rslv, model, resolver.CollectFromContext[*parser.Alias](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromFuncs(ctx, rslv, model, resolver.CollectFromContext[*parser.Function](rCtx))...)
ctx.Aggregates = append(ctx.Aggregates, newTypesFromAggregate(pctx, ctx, rslv, model, resolver.CollectFromContext[*parser.Aggregate](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromRecords(pctx, ctx, rslv, model, resolver.CollectFromContext[*parser.Struct](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromChoice(pctx, ctx, rslv, model, resolver.CollectFromContext[*parser.Choice](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromTypes(pctx, ctx, rslv, model, resolver.CollectFromContext[*parser.Type](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromAlias(pctx, ctx, rslv, model, resolver.CollectFromContext[*parser.Alias](rCtx))...)
ctx.Types = append(ctx.Types, newTypesFromFuncs(pctx, ctx, rslv, model, resolver.CollectFromContext[*parser.Function](rCtx))...)

postCategorizeByAnnotations(ctx.Types)
ctx.Definition = markdown(rCtx.Description, model)
Expand Down
17 changes: 9 additions & 8 deletions compiler/html/transformaggregate.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
package html

import (
"github.com/worldiety/dddl/plantuml"
"html/template"

"github.com/worldiety/dddl/parser"
"github.com/worldiety/dddl/resolver"
)

func newTypesFromAggregate(context *Context, r *resolver.Resolver, model PreviewModel, aggregates []*parser.Aggregate) []*Aggregate {
func newTypesFromAggregate(ctx *plantuml.PreflightContext, context *Context, r *resolver.Resolver, model PreviewModel, aggregates []*parser.Aggregate) []*Aggregate {
var res []*Aggregate
for _, aggregate := range aggregates {
a := newTypeFromAggregate(context, r, model, aggregate)
a := newTypeFromAggregate(ctx, context, r, model, aggregate)
postCategorizeByAnnotations(a.Types)
res = append(res, a)
}

return res
}

func newTypeFromAggregate(context *Context, r *resolver.Resolver, model PreviewModel, aggregate *parser.Aggregate) *Aggregate {
func newTypeFromAggregate(ctx *plantuml.PreflightContext, context *Context, r *resolver.Resolver, model PreviewModel, aggregate *parser.Aggregate) *Aggregate {
typeDef := parser.TypeDefinitionFrom(aggregate)
var def template.HTML
if typeDef.Description != nil {
Expand All @@ -36,11 +37,11 @@ func newTypeFromAggregate(context *Context, r *resolver.Resolver, model PreviewM
WorkPackageDuration: parser.FindAnnotation[*parser.WorkPackageAnnotation](aggregate).GetDuration(),
}

data.Types = append(data.Types, newTypesFromRecords(data, r, model, resolver.CollectFromAggregate[*parser.Struct](aggregate))...)
data.Types = append(data.Types, newTypesFromChoice(data, r, model, resolver.CollectFromAggregate[*parser.Choice](aggregate))...)
data.Types = append(data.Types, newTypesFromTypes(data, r, model, resolver.CollectFromAggregate[*parser.Type](aggregate))...)
data.Types = append(data.Types, newTypesFromAlias(data, r, model, resolver.CollectFromAggregate[*parser.Alias](aggregate))...)
data.Types = append(data.Types, newTypesFromFuncs(data, r, model, resolver.CollectFromAggregate[*parser.Function](aggregate))...)
data.Types = append(data.Types, newTypesFromRecords(ctx, data, r, model, resolver.CollectFromAggregate[*parser.Struct](aggregate))...)
data.Types = append(data.Types, newTypesFromChoice(ctx, data, r, model, resolver.CollectFromAggregate[*parser.Choice](aggregate))...)
data.Types = append(data.Types, newTypesFromTypes(ctx, data, r, model, resolver.CollectFromAggregate[*parser.Type](aggregate))...)
data.Types = append(data.Types, newTypesFromAlias(ctx, data, r, model, resolver.CollectFromAggregate[*parser.Alias](aggregate))...)
data.Types = append(data.Types, newTypesFromFuncs(ctx, data, r, model, resolver.CollectFromAggregate[*parser.Function](aggregate))...)

return data
}
17 changes: 13 additions & 4 deletions compiler/html/transformalias.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (
"golang.org/x/exp/slog"
)

func newTypesFromAlias(parent any, r *resolver.Resolver, model PreviewModel, aliases []*parser.Alias) []*Type {
func newTypesFromAlias(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, aliases []*parser.Alias) []*Type {
var res []*Type
for _, alias := range aliases {
res = append(res, newTypeFromAlias(parent, r, model, alias))
res = append(res, newTypeFromAlias(ctx, parent, r, model, alias))
}

return res
}

func newTypeFromAlias(parent any, r *resolver.Resolver, model PreviewModel, typ *parser.Alias) *Type {
func newTypeFromAlias(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, typ *parser.Alias) *Type {
typeDef := parser.TypeDefinitionFrom(typ)
var def template.HTML
if typeDef.Description != nil {
Expand All @@ -39,12 +39,21 @@ func newTypeFromAlias(parent any, r *resolver.Resolver, model PreviewModel, typ
WorkPackageDuration: parser.FindAnnotation[*parser.WorkPackageAnnotation](typ).GetDuration(),
}

svg, err := plantuml.RenderLocal("svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ)))
svg, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ)))
if err != nil {
slog.Error("failed to convert alias to puml", slog.Any("err", err))
}

svgX, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ).WithMaxDepth()))
if err != nil {
slog.Error("failed to convert alias to puml", slog.Any("err", err))
}

data.SVGExtended = template.HTML(svgX)
data.SVG = template.HTML(svg)
if data.SVGExtended == data.SVG {
data.SVGExtended = ""
}
data.Usages = newUsages(r, typ)

return data
Expand Down
18 changes: 14 additions & 4 deletions compiler/html/transformchoice.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (
"golang.org/x/exp/slog"
)

func newTypesFromChoice(parent any, r *resolver.Resolver, model PreviewModel, choices []*parser.Choice) []*Type {
func newTypesFromChoice(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, choices []*parser.Choice) []*Type {
var res []*Type
for _, choice := range choices {
res = append(res, newTypeFromChoice(parent, r, model, choice))
res = append(res, newTypeFromChoice(ctx, parent, r, model, choice))
}

return res
}

func newTypeFromChoice(parent any, r *resolver.Resolver, model PreviewModel, choice *parser.Choice) *Type {
func newTypeFromChoice(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, choice *parser.Choice) *Type {
typeDef := parser.TypeDefinitionFrom(choice)
var def template.HTML
if typeDef.Description != nil {
Expand All @@ -39,12 +39,22 @@ func newTypeFromChoice(parent any, r *resolver.Resolver, model PreviewModel, cho
WorkPackageDuration: parser.FindAnnotation[*parser.WorkPackageAnnotation](choice).GetDuration(),
}

svg, err := plantuml.RenderLocal("svg", puml.RenderNamedType(r, choice, puml.NewRFlags(choice)))
svg, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, choice, puml.NewRFlags(choice)))
if err != nil {
slog.Error("failed to convert choice to puml", slog.Any("err", err))
}

svgX, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, choice, puml.NewRFlags(choice).WithMaxDepth()))
if err != nil {
slog.Error("failed to convert alias to puml", slog.Any("err", err))
}

data.SVGExtended = template.HTML(svgX)
data.SVG = template.HTML(svg)
if data.SVGExtended == data.SVG {
data.SVGExtended = ""
}

data.Usages = newUsages(r, choice)

return data
Expand Down
8 changes: 4 additions & 4 deletions compiler/html/transformfunc.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (
"golang.org/x/exp/slog"
)

func newTypesFromFuncs(parent any, r *resolver.Resolver, model PreviewModel, funcs []*parser.Function) []*Type {
func newTypesFromFuncs(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, funcs []*parser.Function) []*Type {
var res []*Type
for _, f := range funcs {
res = append(res, newTypeFromFunc(parent, r, model, f))
res = append(res, newTypeFromFunc(ctx, parent, r, model, f))
}

return res
}

func newTypeFromFunc(parent any, r *resolver.Resolver, model PreviewModel, typ *parser.Function) *Type {
func newTypeFromFunc(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, typ *parser.Function) *Type {
typeDef := parser.TypeDefinitionFrom(typ)
var def template.HTML
if typeDef.Description != nil {
Expand All @@ -39,7 +39,7 @@ func newTypeFromFunc(parent any, r *resolver.Resolver, model PreviewModel, typ *
WorkPackageDuration: parser.FindAnnotation[*parser.WorkPackageAnnotation](typ).GetDuration(),
}

svg, err := plantuml.RenderLocal("svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ)))
svg, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ)))
if err != nil {
slog.Error("failed to convert func to puml", slog.Any("err", err))
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/html/transformgantt.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"math"
)

func newProjectPlan(r *resolver.Resolver, model PreviewModel) *ProjectPlan {
func newProjectPlan(ctx *plantuml.PreflightContext, r *resolver.Resolver, model PreviewModel) *ProjectPlan {
pp := &ProjectPlan{}
tmp := map[string]ProjectTask{}
parser.MustWalk(r.Workspace(), func(n parser.Node) error {
Expand Down Expand Up @@ -67,7 +67,7 @@ func newProjectPlan(r *resolver.Resolver, model PreviewModel) *ProjectPlan {
pp.Tasks = append(pp.Tasks, &task)
}

svg, err := plantuml.RenderLocal("svg", RenderGantt(pp))
svg, err := plantuml.RenderLocalWithPreflight(ctx, "svg", RenderGantt(pp))
if err != nil {
slog.Error("failed to convert choice to puml", slog.Any("err", err))
}
Expand Down
18 changes: 14 additions & 4 deletions compiler/html/transformrecord.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (
"golang.org/x/exp/slog"
)

func newTypesFromRecords(parent any, r *resolver.Resolver, model PreviewModel, records []*parser.Struct) []*Type {
func newTypesFromRecords(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, records []*parser.Struct) []*Type {
var res []*Type
for _, record := range records {
res = append(res, newTypeFromRecord(parent, r, model, record))
res = append(res, newTypeFromRecord(ctx, parent, r, model, record))
}

return res
}

func newTypeFromRecord(parent any, r *resolver.Resolver, model PreviewModel, record *parser.Struct) *Type {
func newTypeFromRecord(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, record *parser.Struct) *Type {
typeDef := parser.TypeDefinitionFrom(record)
var def template.HTML
if typeDef.Description != nil {
Expand All @@ -39,12 +39,22 @@ func newTypeFromRecord(parent any, r *resolver.Resolver, model PreviewModel, rec
WorkPackageDuration: parser.FindAnnotation[*parser.WorkPackageAnnotation](record).GetDuration(),
}

svg, err := plantuml.RenderLocal("svg", puml.RenderNamedType(r, record, puml.NewRFlags(record)))
svg, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, record, puml.NewRFlags(record)))
if err != nil {
slog.Error("failed to convert data to puml", slog.Any("err", err))
}

svgX, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, record, puml.NewRFlags(record).WithMaxDepth()))
if err != nil {
slog.Error("failed to convert alias to puml", slog.Any("err", err))
}

data.SVGExtended = template.HTML(svgX)
data.SVG = template.HTML(svg)
if data.SVGExtended == data.SVG {
data.SVGExtended = ""
}

data.Usages = newUsages(r, record)

return data
Expand Down
18 changes: 14 additions & 4 deletions compiler/html/transformtype.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (
"golang.org/x/exp/slog"
)

func newTypesFromTypes(parent any, r *resolver.Resolver, model PreviewModel, types []*parser.Type) []*Type {
func newTypesFromTypes(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, types []*parser.Type) []*Type {
var res []*Type
for _, typ := range types {
res = append(res, newTypeFromType(parent, r, model, typ))
res = append(res, newTypeFromType(ctx, parent, r, model, typ))
}

return res
}

func newTypeFromType(parent any, r *resolver.Resolver, model PreviewModel, typ *parser.Type) *Type {
func newTypeFromType(ctx *plantuml.PreflightContext, parent any, r *resolver.Resolver, model PreviewModel, typ *parser.Type) *Type {
typeDef := parser.TypeDefinitionFrom(typ)
var def template.HTML
if typeDef.Description != nil {
Expand All @@ -39,12 +39,22 @@ func newTypeFromType(parent any, r *resolver.Resolver, model PreviewModel, typ *
WorkPackageDuration: parser.FindAnnotation[*parser.WorkPackageAnnotation](typ).GetDuration(),
}

svg, err := plantuml.RenderLocal("svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ)))
svg, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ)))
if err != nil {
slog.Error("failed to convert type to puml", slog.Any("err", err))
}

svgX, err := plantuml.RenderLocalWithPreflight(ctx, "svg", puml.RenderNamedType(r, typ, puml.NewRFlags(typ).WithMaxDepth()))
if err != nil {
slog.Error("failed to convert alias to puml", slog.Any("err", err))
}

data.SVGExtended = template.HTML(svgX)
data.SVG = template.HTML(svg)
if data.SVGExtended == data.SVG {
data.SVGExtended = ""
}

data.Usages = newUsages(r, typ)

return data
Expand Down
34 changes: 33 additions & 1 deletion compiler/html/type.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,42 @@
</div>
</div>
<div class="pl-2">
{{if .SVGExtended}}
<div id="svg_x_{{.Ref}}" class="hidden flex flex-col">


<div class="flex justify-center items-center">
{{.SVGExtended}}

</div>
<button class="m-4 print:hidden bg-transparent hover:bg-green-500 text-green-700 font-semibold hover:text-white py-2 px-4 border border-green-500 hover:border-transparent rounded"
onclick="(function(){
document.getElementById('svg_x_{{.Ref}}').classList.add('hidden');
document.getElementById('svg_n_{{.Ref}}').classList.remove('hidden');
})();">Kompakte Version zeigen
</button>
</div>
<div id="svg_n_{{.Ref}}" class="flex flex-col">
<div class="flex justify-center items-center">
{{.SVG}}

</div>
<button class="m-4 print:hidden bg-transparent hover:bg-green-500 text-green-700 font-semibold hover:text-white py-2 px-4 border border-green-500 hover:border-transparent rounded"
onclick="(function(){
document.getElementById('svg_n_{{.Ref}}').classList.add('hidden');
document.getElementById('svg_x_{{.Ref}}').classList.remove('hidden');
})();">Erweiterte Version zeigen
</button>
</div>

</div>
{{else}}
<div class="flex justify-center items-center">
{{.SVG}}

</div>
</div>
{{end}}

{{if .Usages}}
direkt verwendet von
<div class="xl:px-2">
Expand Down
Loading

0 comments on commit be031c0

Please sign in to comment.